update dev300-m58
[ooovba.git] / accessibility / source / standard / vclxaccessiblemenuitem.cxx
blob4ba4cd7d94db99b2e88b47c5dceab8bb2a8ad722
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: vclxaccessiblemenuitem.cxx,v $
10 * $Revision: 1.3 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_accessibility.hxx"
33 #include <accessibility/standard/vclxaccessiblemenuitem.hxx>
34 #include <accessibility/helper/accresmgr.hxx>
35 #include <accessibility/helper/accessiblestrings.hrc>
36 #include <toolkit/helper/convert.hxx>
37 #include <accessibility/helper/characterattributeshelper.hxx>
38 #include <comphelper/accessiblekeybindinghelper.hxx>
39 #include <com/sun/star/awt/KeyModifier.hpp>
41 #include <com/sun/star/accessibility/AccessibleRole.hpp>
42 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
43 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
44 #include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
45 #include <unotools/accessiblestatesethelper.hxx>
46 #include <comphelper/sequence.hxx>
47 #include <vcl/svapp.hxx>
48 #include <vcl/window.hxx>
49 #include <vcl/menu.hxx>
50 #include <vcl/unohelp2.hxx>
52 #include <memory>
55 using namespace ::com::sun::star::accessibility;
56 using namespace ::com::sun::star::uno;
57 using namespace ::com::sun::star::beans;
58 using namespace ::com::sun::star::lang;
59 using namespace ::com::sun::star;
60 using namespace ::comphelper;
63 // -----------------------------------------------------------------------------
64 // class VCLXAccessibleMenuItem
65 // -----------------------------------------------------------------------------
67 VCLXAccessibleMenuItem::VCLXAccessibleMenuItem( Menu* pParent, sal_uInt16 nItemPos, Menu* pMenu )
68 :OAccessibleMenuItemComponent( pParent, nItemPos, pMenu )
72 // -----------------------------------------------------------------------------
74 VCLXAccessibleMenuItem::~VCLXAccessibleMenuItem()
78 // -----------------------------------------------------------------------------
80 sal_Bool VCLXAccessibleMenuItem::IsFocused()
82 return IsHighlighted();
85 // -----------------------------------------------------------------------------
87 sal_Bool VCLXAccessibleMenuItem::IsSelected()
89 return IsHighlighted();
92 // -----------------------------------------------------------------------------
94 sal_Bool VCLXAccessibleMenuItem::IsChecked()
96 sal_Bool bChecked = sal_False;
98 if ( m_pParent )
100 sal_uInt16 nItemId = m_pParent->GetItemId( m_nItemPos );
101 if ( m_pParent->IsItemChecked( nItemId ) )
102 bChecked = sal_True;
105 return bChecked;
108 // -----------------------------------------------------------------------------
110 sal_Bool VCLXAccessibleMenuItem::IsHighlighted()
112 sal_Bool bHighlighted = sal_False;
114 if ( m_pParent && m_pParent->IsHighlighted( m_nItemPos ) )
115 bHighlighted = sal_True;
117 return bHighlighted;
120 // -----------------------------------------------------------------------------
122 void VCLXAccessibleMenuItem::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet )
124 OAccessibleMenuItemComponent::FillAccessibleStateSet( rStateSet );
126 rStateSet.AddState( AccessibleStateType::FOCUSABLE );
128 if ( IsFocused() )
129 rStateSet.AddState( AccessibleStateType::FOCUSED );
131 rStateSet.AddState( AccessibleStateType::SELECTABLE );
133 if ( IsSelected() )
134 rStateSet.AddState( AccessibleStateType::SELECTED );
136 if ( IsChecked() )
137 rStateSet.AddState( AccessibleStateType::CHECKED );
140 // -----------------------------------------------------------------------------
141 // OCommonAccessibleText
142 // -----------------------------------------------------------------------------
144 ::rtl::OUString VCLXAccessibleMenuItem::implGetText()
146 return m_sItemText;
149 // -----------------------------------------------------------------------------
151 Locale VCLXAccessibleMenuItem::implGetLocale()
153 return Application::GetSettings().GetLocale();
156 // -----------------------------------------------------------------------------
158 void VCLXAccessibleMenuItem::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex )
160 nStartIndex = 0;
161 nEndIndex = 0;
164 // -----------------------------------------------------------------------------
165 // XInterface
166 // -----------------------------------------------------------------------------
168 IMPLEMENT_FORWARD_XINTERFACE2( VCLXAccessibleMenuItem, OAccessibleMenuItemComponent, VCLXAccessibleMenuItem_BASE )
170 // -----------------------------------------------------------------------------
171 // XTypeProvider
172 // -----------------------------------------------------------------------------
174 IMPLEMENT_FORWARD_XTYPEPROVIDER2( VCLXAccessibleMenuItem, OAccessibleMenuItemComponent, VCLXAccessibleMenuItem_BASE )
176 // -----------------------------------------------------------------------------
177 // XServiceInfo
178 // -----------------------------------------------------------------------------
180 ::rtl::OUString VCLXAccessibleMenuItem::getImplementationName() throw (RuntimeException)
182 return ::rtl::OUString::createFromAscii( "com.sun.star.comp.toolkit.AccessibleMenuItem" );
185 // -----------------------------------------------------------------------------
187 Sequence< ::rtl::OUString > VCLXAccessibleMenuItem::getSupportedServiceNames() throw (RuntimeException)
189 Sequence< ::rtl::OUString > aNames(1);
190 aNames[0] = ::rtl::OUString::createFromAscii( "com.sun.star.awt.AccessibleMenuItem" );
191 return aNames;
194 // -----------------------------------------------------------------------------
195 // XAccessibleContext
196 // -----------------------------------------------------------------------------
198 sal_Int16 VCLXAccessibleMenuItem::getAccessibleRole( ) throw (RuntimeException)
200 OExternalLockGuard aGuard( this );
202 return AccessibleRole::MENU_ITEM;
205 // -----------------------------------------------------------------------------
206 // XAccessibleText
207 // -----------------------------------------------------------------------------
209 sal_Int32 VCLXAccessibleMenuItem::getCaretPosition() throw (RuntimeException)
211 OExternalLockGuard aGuard( this );
213 return -1;
216 // -----------------------------------------------------------------------------
218 sal_Bool VCLXAccessibleMenuItem::setCaretPosition( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
221 OExternalLockGuard aGuard( this );
223 if ( !implIsValidRange( nIndex, nIndex, implGetText().getLength() ) )
224 throw IndexOutOfBoundsException();
226 return sal_False;
229 // -----------------------------------------------------------------------------
231 sal_Unicode VCLXAccessibleMenuItem::getCharacter( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
233 OExternalLockGuard aGuard( this );
235 return OCommonAccessibleText::getCharacter( nIndex );
238 // -----------------------------------------------------------------------------
240 Sequence< PropertyValue > VCLXAccessibleMenuItem::getCharacterAttributes( sal_Int32 nIndex, const Sequence< ::rtl::OUString >& aRequestedAttributes ) throw (IndexOutOfBoundsException, RuntimeException)
242 OExternalLockGuard aGuard( this );
244 Sequence< PropertyValue > aValues;
245 ::rtl::OUString sText( implGetText() );
247 if ( !implIsValidIndex( nIndex, sText.getLength() ) )
248 throw IndexOutOfBoundsException();
250 Font aFont = Application::GetSettings().GetStyleSettings().GetMenuFont();
251 sal_Int32 nBackColor = getBackground();
252 sal_Int32 nColor = getForeground();
253 ::std::auto_ptr< CharacterAttributesHelper > pHelper( new CharacterAttributesHelper( aFont, nBackColor, nColor ) );
254 aValues = pHelper->GetCharacterAttributes( aRequestedAttributes );
256 return aValues;
259 // -----------------------------------------------------------------------------
261 awt::Rectangle VCLXAccessibleMenuItem::getCharacterBounds( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
263 OExternalLockGuard aGuard( this );
265 if ( !implIsValidIndex( nIndex, implGetText().getLength() ) )
266 throw IndexOutOfBoundsException();
268 awt::Rectangle aBounds( 0, 0, 0, 0 );
269 if ( m_pParent )
271 sal_uInt16 nItemId = m_pParent->GetItemId( m_nItemPos );
272 Rectangle aItemRect = m_pParent->GetBoundingRectangle( m_nItemPos );
273 Rectangle aCharRect = m_pParent->GetCharacterBounds( nItemId, nIndex );
274 aCharRect.Move( -aItemRect.Left(), -aItemRect.Top() );
275 aBounds = AWTRectangle( aCharRect );
278 return aBounds;
281 // -----------------------------------------------------------------------------
283 sal_Int32 VCLXAccessibleMenuItem::getCharacterCount() throw (RuntimeException)
285 OExternalLockGuard aGuard( this );
287 return OCommonAccessibleText::getCharacterCount();
290 // -----------------------------------------------------------------------------
292 sal_Int32 VCLXAccessibleMenuItem::getIndexAtPoint( const awt::Point& aPoint ) throw (RuntimeException)
294 OExternalLockGuard aGuard( this );
296 sal_Int32 nIndex = -1;
297 if ( m_pParent )
299 sal_uInt16 nItemId = 0;
300 Rectangle aItemRect = m_pParent->GetBoundingRectangle( m_nItemPos );
301 Point aPnt( VCLPoint( aPoint ) );
302 aPnt += aItemRect.TopLeft();
303 sal_Int32 nI = m_pParent->GetIndexForPoint( aPnt, nItemId );
304 if ( nI != -1 && m_pParent->GetItemId( m_nItemPos ) == nItemId )
305 nIndex = nI;
308 return nIndex;
311 // -----------------------------------------------------------------------------
313 ::rtl::OUString VCLXAccessibleMenuItem::getSelectedText() throw (RuntimeException)
315 OExternalLockGuard aGuard( this );
317 return OCommonAccessibleText::getSelectedText();
320 // -----------------------------------------------------------------------------
322 sal_Int32 VCLXAccessibleMenuItem::getSelectionStart() throw (RuntimeException)
324 OExternalLockGuard aGuard( this );
326 return OCommonAccessibleText::getSelectionStart();
329 // -----------------------------------------------------------------------------
331 sal_Int32 VCLXAccessibleMenuItem::getSelectionEnd() throw (RuntimeException)
333 OExternalLockGuard aGuard( this );
335 return OCommonAccessibleText::getSelectionEnd();
338 // -----------------------------------------------------------------------------
340 sal_Bool VCLXAccessibleMenuItem::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (IndexOutOfBoundsException, RuntimeException)
342 OExternalLockGuard aGuard( this );
344 if ( !implIsValidRange( nStartIndex, nEndIndex, implGetText().getLength() ) )
345 throw IndexOutOfBoundsException();
347 return sal_False;
350 // -----------------------------------------------------------------------------
352 ::rtl::OUString VCLXAccessibleMenuItem::getText() throw (RuntimeException)
354 OExternalLockGuard aGuard( this );
356 return OCommonAccessibleText::getText();
359 // -----------------------------------------------------------------------------
361 ::rtl::OUString VCLXAccessibleMenuItem::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (IndexOutOfBoundsException, RuntimeException)
363 OExternalLockGuard aGuard( this );
365 return OCommonAccessibleText::getTextRange( nStartIndex, nEndIndex );
368 // -----------------------------------------------------------------------------
370 ::com::sun::star::accessibility::TextSegment VCLXAccessibleMenuItem::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
372 OExternalLockGuard aGuard( this );
374 return OCommonAccessibleText::getTextAtIndex( nIndex, aTextType );
377 // -----------------------------------------------------------------------------
379 ::com::sun::star::accessibility::TextSegment VCLXAccessibleMenuItem::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
381 OExternalLockGuard aGuard( this );
383 return OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType );
386 // -----------------------------------------------------------------------------
388 ::com::sun::star::accessibility::TextSegment VCLXAccessibleMenuItem::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
390 OExternalLockGuard aGuard( this );
392 return OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType );
395 // -----------------------------------------------------------------------------
397 sal_Bool VCLXAccessibleMenuItem::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (IndexOutOfBoundsException, RuntimeException)
399 OExternalLockGuard aGuard( this );
401 sal_Bool bReturn = sal_False;
403 if ( m_pParent )
405 Window* pWindow = m_pParent->GetWindow();
406 if ( pWindow )
408 Reference< datatransfer::clipboard::XClipboard > xClipboard = pWindow->GetClipboard();
409 if ( xClipboard.is() )
411 ::rtl::OUString sText( getTextRange( nStartIndex, nEndIndex ) );
413 ::vcl::unohelper::TextDataObject* pDataObj = new ::vcl::unohelper::TextDataObject( sText );
414 const sal_uInt32 nRef = Application::ReleaseSolarMutex();
415 xClipboard->setContents( pDataObj, NULL );
417 Reference< datatransfer::clipboard::XFlushableClipboard > xFlushableClipboard( xClipboard, uno::UNO_QUERY );
418 if( xFlushableClipboard.is() )
419 xFlushableClipboard->flushClipboard();
421 Application::AcquireSolarMutex( nRef );
423 bReturn = sal_True;
428 return bReturn;
431 // -----------------------------------------------------------------------------
432 // XAccessibleAction
433 // -----------------------------------------------------------------------------
435 sal_Int32 VCLXAccessibleMenuItem::getAccessibleActionCount( ) throw (RuntimeException)
437 OExternalLockGuard aGuard( this );
439 return 1;
442 // -----------------------------------------------------------------------------
444 sal_Bool VCLXAccessibleMenuItem::doAccessibleAction ( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
446 OExternalLockGuard aGuard( this );
448 if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
449 throw IndexOutOfBoundsException();
451 Click();
453 return sal_True;
456 // -----------------------------------------------------------------------------
458 ::rtl::OUString VCLXAccessibleMenuItem::getAccessibleActionDescription ( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
460 OExternalLockGuard aGuard( this );
462 if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
463 throw IndexOutOfBoundsException();
465 return ::rtl::OUString( TK_RES_STRING( RID_STR_ACC_ACTION_CLICK ) );
468 // -----------------------------------------------------------------------------
470 Reference< XAccessibleKeyBinding > VCLXAccessibleMenuItem::getAccessibleActionKeyBinding( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
472 OExternalLockGuard aGuard( this );
474 if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
475 throw IndexOutOfBoundsException();
477 OAccessibleKeyBindingHelper* pKeyBindingHelper = new OAccessibleKeyBindingHelper();
478 Reference< XAccessibleKeyBinding > xKeyBinding = pKeyBindingHelper;
480 if ( m_pParent )
482 // create auto mnemonics
483 if ( Application::GetSettings().GetStyleSettings().GetAutoMnemonic() && !( m_pParent->GetMenuFlags() & MENU_FLAG_NOAUTOMNEMONICS ) )
484 m_pParent->CreateAutoMnemonics();
486 // activation key
487 KeyEvent aKeyEvent = m_pParent->GetActivationKey( m_pParent->GetItemId( m_nItemPos ) );
488 KeyCode aKeyCode = aKeyEvent.GetKeyCode();
489 Sequence< awt::KeyStroke > aSeq1(1);
490 aSeq1[0].Modifiers = 0;
491 Reference< XAccessible > xParent( getAccessibleParent() );
492 if ( xParent.is() )
494 Reference< XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
495 if ( xParentContext.is() && xParentContext->getAccessibleRole() == AccessibleRole::MENU_BAR )
496 aSeq1[0].Modifiers |= awt::KeyModifier::MOD2;
498 aSeq1[0].KeyCode = aKeyCode.GetCode();
499 aSeq1[0].KeyChar = aKeyEvent.GetCharCode();
500 aSeq1[0].KeyFunc = static_cast< sal_Int16 >( aKeyCode.GetFunction() );
501 pKeyBindingHelper->AddKeyBinding( aSeq1 );
503 // complete menu activation key sequence
504 Sequence< awt::KeyStroke > aSeq;
505 if ( xParent.is() )
507 Reference< XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
508 if ( xParentContext.is() && xParentContext->getAccessibleRole() == AccessibleRole::MENU )
510 Reference< XAccessibleAction > xAction( xParentContext, UNO_QUERY );
511 if ( xAction.is() && xAction->getAccessibleActionCount() > 0 )
513 Reference< XAccessibleKeyBinding > xKeyB( xAction->getAccessibleActionKeyBinding( 0 ) );
514 if ( xKeyB.is() && xKeyB->getAccessibleKeyBindingCount() > 1 )
515 aSeq = xKeyB->getAccessibleKeyBinding( 1 );
519 Sequence< awt::KeyStroke > aSeq2 = ::comphelper::concatSequences( aSeq, aSeq1 );
520 pKeyBindingHelper->AddKeyBinding( aSeq2 );
522 // accelerator key
523 KeyCode aAccelKeyCode = m_pParent->GetAccelKey( m_pParent->GetItemId( m_nItemPos ) );
524 if ( aAccelKeyCode.GetCode() != 0 )
526 Sequence< awt::KeyStroke > aSeq3(1);
527 aSeq3[0].Modifiers = 0;
528 if ( aAccelKeyCode.IsShift() )
529 aSeq3[0].Modifiers |= awt::KeyModifier::SHIFT;
530 if ( aAccelKeyCode.IsMod1() )
531 aSeq3[0].Modifiers |= awt::KeyModifier::MOD1;
532 if ( aAccelKeyCode.IsMod2() )
533 aSeq3[0].Modifiers |= awt::KeyModifier::MOD2;
534 if ( aAccelKeyCode.IsMod3() )
535 aSeq3[0].Modifiers |= awt::KeyModifier::MOD3;
536 aSeq3[0].KeyCode = aAccelKeyCode.GetCode();
537 aSeq3[0].KeyFunc = static_cast< sal_Int16 >( aAccelKeyCode.GetFunction() );
538 pKeyBindingHelper->AddKeyBinding( aSeq3 );
542 return xKeyBinding;
545 // -----------------------------------------------------------------------------
546 // XAccessibleValue
547 // -----------------------------------------------------------------------------
549 Any VCLXAccessibleMenuItem::getCurrentValue( ) throw (RuntimeException)
551 OExternalLockGuard aGuard( this );
553 Any aValue;
554 if ( IsSelected() )
555 aValue <<= (sal_Int32) 1;
556 else
557 aValue <<= (sal_Int32) 0;
559 return aValue;
562 // -----------------------------------------------------------------------------
564 sal_Bool VCLXAccessibleMenuItem::setCurrentValue( const Any& aNumber ) throw (RuntimeException)
566 OExternalLockGuard aGuard( this );
568 sal_Bool bReturn = sal_False;
569 sal_Int32 nValue = 0;
570 OSL_VERIFY( aNumber >>= nValue );
572 if ( nValue <= 0 )
574 DeSelect();
575 bReturn = sal_True;
577 else if ( nValue >= 1 )
579 Select();
580 bReturn = sal_True;
583 return bReturn;
586 // -----------------------------------------------------------------------------
588 Any VCLXAccessibleMenuItem::getMaximumValue( ) throw (RuntimeException)
590 OExternalLockGuard aGuard( this );
592 Any aValue;
593 aValue <<= (sal_Int32) 1;
595 return aValue;
598 // -----------------------------------------------------------------------------
600 Any VCLXAccessibleMenuItem::getMinimumValue( ) throw (RuntimeException)
602 OExternalLockGuard aGuard( this );
604 Any aValue;
605 aValue <<= (sal_Int32) 0;
607 return aValue;
610 // -----------------------------------------------------------------------------