Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / accessibility / source / standard / vclxaccessiblemenuitem.cxx
blob2c4e8043c00b57cd37e09a171eca7abd454d2c13
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <standard/vclxaccessiblemenuitem.hxx>
21 #include <toolkit/helper/convert.hxx>
22 #include <helper/characterattributeshelper.hxx>
23 #include <comphelper/accessiblecontexthelper.hxx>
24 #include <comphelper/accessiblekeybindinghelper.hxx>
25 #include <com/sun/star/awt/KeyModifier.hpp>
27 #include <com/sun/star/accessibility/AccessibleRole.hpp>
28 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
29 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
30 #include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
31 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
32 #include <comphelper/sequence.hxx>
33 #include <i18nlangtag/languagetag.hxx>
34 #include <vcl/event.hxx>
35 #include <vcl/svapp.hxx>
36 #include <vcl/window.hxx>
37 #include <vcl/menu.hxx>
38 #include <vcl/unohelp2.hxx>
39 #include <vcl/settings.hxx>
40 #include <strings.hxx>
42 using namespace ::com::sun::star::accessibility;
43 using namespace ::com::sun::star::uno;
44 using namespace ::com::sun::star::beans;
45 using namespace ::com::sun::star::lang;
46 using namespace ::com::sun::star;
47 using namespace ::comphelper;
52 VCLXAccessibleMenuItem::VCLXAccessibleMenuItem( Menu* pParent, sal_uInt16 nItemPos, Menu* pMenu )
53 :ImplInheritanceHelper( pParent, nItemPos, pMenu )
58 bool VCLXAccessibleMenuItem::IsFocused()
60 return IsHighlighted();
64 bool VCLXAccessibleMenuItem::IsSelected()
66 return IsHighlighted();
70 bool VCLXAccessibleMenuItem::IsChecked()
72 bool bChecked = false;
74 if ( m_pParent )
76 sal_uInt16 nItemId = m_pParent->GetItemId( m_nItemPos );
77 if ( m_pParent->IsItemChecked( nItemId ) )
78 bChecked = true;
81 return bChecked;
85 bool VCLXAccessibleMenuItem::IsHighlighted()
87 bool bHighlighted = false;
89 if ( m_pParent && m_pParent->IsHighlighted( m_nItemPos ) )
90 bHighlighted = true;
92 return bHighlighted;
96 void VCLXAccessibleMenuItem::FillAccessibleStateSet( sal_Int64& rStateSet )
98 OAccessibleMenuItemComponent::FillAccessibleStateSet( rStateSet );
100 rStateSet |= AccessibleStateType::FOCUSABLE;
102 if ( IsFocused() )
103 rStateSet |= AccessibleStateType::FOCUSED;
105 rStateSet |= AccessibleStateType::SELECTABLE;
107 if ( IsSelected() )
108 rStateSet |= AccessibleStateType::SELECTED;
110 if ( IsChecked() )
111 rStateSet |= AccessibleStateType::CHECKED;
115 // OCommonAccessibleText
118 OUString VCLXAccessibleMenuItem::implGetText()
120 return m_sItemText;
124 Locale VCLXAccessibleMenuItem::implGetLocale()
126 return Application::GetSettings().GetLanguageTag().getLocale();
130 void VCLXAccessibleMenuItem::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex )
132 nStartIndex = 0;
133 nEndIndex = 0;
137 // XServiceInfo
140 OUString VCLXAccessibleMenuItem::getImplementationName()
142 return "com.sun.star.comp.toolkit.AccessibleMenuItem";
146 Sequence< OUString > VCLXAccessibleMenuItem::getSupportedServiceNames()
148 return { "com.sun.star.awt.AccessibleMenuItem" };
152 // XAccessibleContext
155 sal_Int16 VCLXAccessibleMenuItem::getAccessibleRole( )
157 OExternalLockGuard aGuard( this );
158 // IA2 CWS. MT: We had the additional roles in UAA for ever, but never used them anywhere.
159 // Looks reasonable, but need to verify in Orca and VoiceOver.
160 sal_Int16 nRole = AccessibleRole::MENU_ITEM;
161 if ( m_pParent )
163 sal_uInt16 nItemId = m_pParent->GetItemId( m_nItemPos );
164 MenuItemBits nItemBits = m_pParent->GetItemBits(nItemId);
165 if( nItemBits & MenuItemBits::RADIOCHECK)
166 nRole = AccessibleRole::RADIO_MENU_ITEM;
167 else if( nItemBits & MenuItemBits::CHECKABLE)
168 nRole = AccessibleRole::CHECK_MENU_ITEM;
170 return nRole;
174 // XAccessibleText
177 sal_Int32 VCLXAccessibleMenuItem::getCaretPosition()
179 return -1;
183 sal_Bool VCLXAccessibleMenuItem::setCaretPosition( sal_Int32 nIndex )
186 OExternalLockGuard aGuard( this );
188 if ( !implIsValidRange( nIndex, nIndex, m_sItemText.getLength() ) )
189 throw IndexOutOfBoundsException();
191 return false;
195 sal_Unicode VCLXAccessibleMenuItem::getCharacter( sal_Int32 nIndex )
197 OExternalLockGuard aGuard( this );
199 return OCommonAccessibleText::implGetCharacter( implGetText(), nIndex );
203 Sequence< PropertyValue > VCLXAccessibleMenuItem::getCharacterAttributes( sal_Int32 nIndex, const Sequence< OUString >& aRequestedAttributes )
205 OExternalLockGuard aGuard( this );
207 if ( !implIsValidIndex( nIndex, m_sItemText.getLength() ) )
208 throw IndexOutOfBoundsException();
210 vcl::Font aFont = Application::GetSettings().GetStyleSettings().GetMenuFont();
211 sal_Int32 nBackColor = getBackground();
212 sal_Int32 nColor = getForeground();
213 return CharacterAttributesHelper( aFont, nBackColor, nColor )
214 .GetCharacterAttributes( aRequestedAttributes );
218 awt::Rectangle VCLXAccessibleMenuItem::getCharacterBounds( sal_Int32 nIndex )
220 OExternalLockGuard aGuard( this );
222 if ( !implIsValidIndex( nIndex, m_sItemText.getLength() ) )
223 throw IndexOutOfBoundsException();
225 awt::Rectangle aBounds( 0, 0, 0, 0 );
226 if ( m_pParent )
228 sal_uInt16 nItemId = m_pParent->GetItemId( m_nItemPos );
229 tools::Rectangle aItemRect = m_pParent->GetBoundingRectangle( m_nItemPos );
230 tools::Rectangle aCharRect = m_pParent->GetCharacterBounds( nItemId, nIndex );
231 aCharRect.Move( -aItemRect.Left(), -aItemRect.Top() );
232 aBounds = AWTRectangle( aCharRect );
235 return aBounds;
239 sal_Int32 VCLXAccessibleMenuItem::getCharacterCount()
241 OExternalLockGuard aGuard( this );
243 return m_sItemText.getLength();
247 sal_Int32 VCLXAccessibleMenuItem::getIndexAtPoint( const awt::Point& aPoint )
249 OExternalLockGuard aGuard( this );
251 sal_Int32 nIndex = -1;
252 if ( m_pParent )
254 sal_uInt16 nItemId = 0;
255 tools::Rectangle aItemRect = m_pParent->GetBoundingRectangle( m_nItemPos );
256 Point aPnt( VCLPoint( aPoint ) );
257 aPnt += aItemRect.TopLeft();
258 sal_Int32 nI = m_pParent->GetIndexForPoint( aPnt, nItemId );
259 if ( nI != -1 && m_pParent->GetItemId( m_nItemPos ) == nItemId )
260 nIndex = nI;
263 return nIndex;
267 OUString VCLXAccessibleMenuItem::getSelectedText()
269 OExternalLockGuard aGuard( this );
271 return OUString();
275 sal_Int32 VCLXAccessibleMenuItem::getSelectionStart()
277 OExternalLockGuard aGuard( this );
279 return 0;
283 sal_Int32 VCLXAccessibleMenuItem::getSelectionEnd()
285 OExternalLockGuard aGuard( this );
287 return 0;
291 sal_Bool VCLXAccessibleMenuItem::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
293 OExternalLockGuard aGuard( this );
295 if ( !implIsValidRange( nStartIndex, nEndIndex, m_sItemText.getLength() ) )
296 throw IndexOutOfBoundsException();
298 return false;
302 OUString VCLXAccessibleMenuItem::getText()
304 OExternalLockGuard aGuard( this );
306 return m_sItemText;
310 OUString VCLXAccessibleMenuItem::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
312 OExternalLockGuard aGuard( this );
314 return OCommonAccessibleText::implGetTextRange( implGetText(), nStartIndex, nEndIndex );
318 css::accessibility::TextSegment VCLXAccessibleMenuItem::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType )
320 OExternalLockGuard aGuard( this );
322 return OCommonAccessibleText::getTextAtIndex( nIndex, aTextType );
326 css::accessibility::TextSegment VCLXAccessibleMenuItem::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType )
328 OExternalLockGuard aGuard( this );
330 return OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType );
334 css::accessibility::TextSegment VCLXAccessibleMenuItem::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType )
336 OExternalLockGuard aGuard( this );
338 return OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType );
342 sal_Bool VCLXAccessibleMenuItem::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
344 OExternalLockGuard aGuard( this );
346 bool bReturn = false;
348 if ( m_pParent )
350 vcl::Window* pWindow = m_pParent->GetWindow();
351 if ( pWindow )
353 Reference< datatransfer::clipboard::XClipboard > xClipboard = pWindow->GetClipboard();
354 if ( xClipboard.is() )
356 OUString sText( getTextRange( nStartIndex, nEndIndex ) );
358 rtl::Reference<vcl::unohelper::TextDataObject> pDataObj = new vcl::unohelper::TextDataObject( sText );
360 SolarMutexReleaser aReleaser;
361 xClipboard->setContents( pDataObj, nullptr );
362 Reference< datatransfer::clipboard::XFlushableClipboard > xFlushableClipboard( xClipboard, uno::UNO_QUERY );
363 if( xFlushableClipboard.is() )
364 xFlushableClipboard->flushClipboard();
366 bReturn = true;
371 return bReturn;
374 sal_Bool VCLXAccessibleMenuItem::scrollSubstringTo( sal_Int32, sal_Int32, AccessibleScrollType )
376 return false;
380 // XAccessibleAction
383 sal_Int32 VCLXAccessibleMenuItem::getAccessibleActionCount( )
385 return 1;
389 sal_Bool VCLXAccessibleMenuItem::doAccessibleAction ( sal_Int32 nIndex )
391 OExternalLockGuard aGuard( this );
393 if ( nIndex != 0 )
394 throw IndexOutOfBoundsException();
396 Click();
398 return true;
402 OUString VCLXAccessibleMenuItem::getAccessibleActionDescription ( sal_Int32 nIndex )
404 OExternalLockGuard aGuard( this );
406 if ( nIndex != 0 )
407 throw IndexOutOfBoundsException();
409 return RID_STR_ACC_ACTION_SELECT;
413 Reference< XAccessibleKeyBinding > VCLXAccessibleMenuItem::getAccessibleActionKeyBinding( sal_Int32 nIndex )
415 OExternalLockGuard aGuard( this );
417 if ( nIndex != 0 )
418 throw IndexOutOfBoundsException();
420 rtl::Reference<OAccessibleKeyBindingHelper> pKeyBindingHelper = new OAccessibleKeyBindingHelper();
422 if ( m_pParent )
424 // create auto mnemonics
425 if (!(m_pParent->GetMenuFlags() & MenuFlags::NoAutoMnemonics))
426 m_pParent->CreateAutoMnemonics();
428 // activation key
429 KeyEvent aKeyEvent = m_pParent->GetActivationKey( m_pParent->GetItemId( m_nItemPos ) );
430 vcl::KeyCode aKeyCode = aKeyEvent.GetKeyCode();
431 Sequence< awt::KeyStroke > aSeq1
434 0, // Modifiers
435 static_cast< sal_Int16 >(aKeyCode.GetCode()),
436 aKeyEvent.GetCharCode(),
437 static_cast< sal_Int16 >( aKeyCode.GetFunction())
440 Reference< XAccessible > xParent( getAccessibleParent() );
441 if ( xParent.is() )
443 Reference< XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
444 if ( xParentContext.is() && xParentContext->getAccessibleRole() == AccessibleRole::MENU_BAR )
445 aSeq1.getArray()[0].Modifiers |= awt::KeyModifier::MOD2;
447 pKeyBindingHelper->AddKeyBinding( aSeq1 );
449 // complete menu activation key sequence
450 Sequence< awt::KeyStroke > aSeq;
451 if ( xParent.is() )
453 Reference< XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
454 if ( xParentContext.is() && xParentContext->getAccessibleRole() == AccessibleRole::MENU )
456 Reference< XAccessibleAction > xAction( xParentContext, UNO_QUERY );
457 if ( xAction.is() && xAction->getAccessibleActionCount() > 0 )
459 Reference< XAccessibleKeyBinding > xKeyB( xAction->getAccessibleActionKeyBinding( 0 ) );
460 if ( xKeyB.is() && xKeyB->getAccessibleKeyBindingCount() > 1 )
461 aSeq = xKeyB->getAccessibleKeyBinding( 1 );
465 Sequence< awt::KeyStroke > aSeq2 = ::comphelper::concatSequences( aSeq, aSeq1 );
466 pKeyBindingHelper->AddKeyBinding( aSeq2 );
468 // accelerator key
469 vcl::KeyCode aAccelKeyCode = m_pParent->GetAccelKey( m_pParent->GetItemId( m_nItemPos ) );
470 if ( aAccelKeyCode.GetCode() != 0 )
472 Sequence< awt::KeyStroke > aSeq3
475 0, // Modifiers
476 static_cast< sal_Int16 >(aAccelKeyCode.GetCode()),
477 aKeyEvent.GetCharCode(),
478 static_cast< sal_Int16 >(aAccelKeyCode.GetFunction())
481 if (aAccelKeyCode.GetModifier() != 0)
483 auto pSeq3 = aSeq3.getArray();
484 if ( aAccelKeyCode.IsShift() )
485 pSeq3[0].Modifiers |= awt::KeyModifier::SHIFT;
486 if ( aAccelKeyCode.IsMod1() )
487 pSeq3[0].Modifiers |= awt::KeyModifier::MOD1;
488 if ( aAccelKeyCode.IsMod2() )
489 pSeq3[0].Modifiers |= awt::KeyModifier::MOD2;
490 if ( aAccelKeyCode.IsMod3() )
491 pSeq3[0].Modifiers |= awt::KeyModifier::MOD3;
493 pKeyBindingHelper->AddKeyBinding( aSeq3 );
497 return pKeyBindingHelper;
501 // XAccessibleValue
504 Any VCLXAccessibleMenuItem::getCurrentValue( )
506 OExternalLockGuard aGuard( this );
508 Any aValue;
509 if ( IsSelected() )
510 aValue <<= sal_Int32(1);
511 else
512 aValue <<= sal_Int32(0);
514 return aValue;
518 sal_Bool VCLXAccessibleMenuItem::setCurrentValue( const Any& aNumber )
520 OExternalLockGuard aGuard( this );
522 bool bReturn = false;
523 sal_Int32 nValue = 0;
524 OSL_VERIFY( aNumber >>= nValue );
526 if ( nValue <= 0 )
528 DeSelect();
529 bReturn = true;
531 else if ( nValue >= 1 )
533 Select();
534 bReturn = true;
537 return bReturn;
541 Any VCLXAccessibleMenuItem::getMaximumValue( )
543 Any aValue;
544 aValue <<= sal_Int32(1);
546 return aValue;
550 Any VCLXAccessibleMenuItem::getMinimumValue( )
552 Any aValue;
553 aValue <<= sal_Int32(0);
555 return aValue;
558 Any VCLXAccessibleMenuItem::getMinimumIncrement( )
560 Any aValue;
561 aValue <<= sal_Int32(1);
563 return aValue;
567 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */