1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: vclxaccessiblemenuitem.cxx,v $
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>
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
;
100 sal_uInt16 nItemId
= m_pParent
->GetItemId( m_nItemPos
);
101 if ( m_pParent
->IsItemChecked( nItemId
) )
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
;
120 // -----------------------------------------------------------------------------
122 void VCLXAccessibleMenuItem::FillAccessibleStateSet( utl::AccessibleStateSetHelper
& rStateSet
)
124 OAccessibleMenuItemComponent::FillAccessibleStateSet( rStateSet
);
126 rStateSet
.AddState( AccessibleStateType::FOCUSABLE
);
129 rStateSet
.AddState( AccessibleStateType::FOCUSED
);
131 rStateSet
.AddState( AccessibleStateType::SELECTABLE
);
134 rStateSet
.AddState( AccessibleStateType::SELECTED
);
137 rStateSet
.AddState( AccessibleStateType::CHECKED
);
140 // -----------------------------------------------------------------------------
141 // OCommonAccessibleText
142 // -----------------------------------------------------------------------------
144 ::rtl::OUString
VCLXAccessibleMenuItem::implGetText()
149 // -----------------------------------------------------------------------------
151 Locale
VCLXAccessibleMenuItem::implGetLocale()
153 return Application::GetSettings().GetLocale();
156 // -----------------------------------------------------------------------------
158 void VCLXAccessibleMenuItem::implGetSelection( sal_Int32
& nStartIndex
, sal_Int32
& nEndIndex
)
164 // -----------------------------------------------------------------------------
166 // -----------------------------------------------------------------------------
168 IMPLEMENT_FORWARD_XINTERFACE2( VCLXAccessibleMenuItem
, OAccessibleMenuItemComponent
, VCLXAccessibleMenuItem_BASE
)
170 // -----------------------------------------------------------------------------
172 // -----------------------------------------------------------------------------
174 IMPLEMENT_FORWARD_XTYPEPROVIDER2( VCLXAccessibleMenuItem
, OAccessibleMenuItemComponent
, VCLXAccessibleMenuItem_BASE
)
176 // -----------------------------------------------------------------------------
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" );
194 // -----------------------------------------------------------------------------
195 // XAccessibleContext
196 // -----------------------------------------------------------------------------
198 sal_Int16
VCLXAccessibleMenuItem::getAccessibleRole( ) throw (RuntimeException
)
200 OExternalLockGuard
aGuard( this );
202 return AccessibleRole::MENU_ITEM
;
205 // -----------------------------------------------------------------------------
207 // -----------------------------------------------------------------------------
209 sal_Int32
VCLXAccessibleMenuItem::getCaretPosition() throw (RuntimeException
)
211 OExternalLockGuard
aGuard( this );
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();
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
);
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 );
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
);
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;
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
)
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();
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
;
405 Window
* pWindow
= m_pParent
->GetWindow();
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
);
431 // -----------------------------------------------------------------------------
433 // -----------------------------------------------------------------------------
435 sal_Int32
VCLXAccessibleMenuItem::getAccessibleActionCount( ) throw (RuntimeException
)
437 OExternalLockGuard
aGuard( this );
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();
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
;
482 // create auto mnemonics
483 if ( Application::GetSettings().GetStyleSettings().GetAutoMnemonic() && !( m_pParent
->GetMenuFlags() & MENU_FLAG_NOAUTOMNEMONICS
) )
484 m_pParent
->CreateAutoMnemonics();
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() );
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
;
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
);
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
);
545 // -----------------------------------------------------------------------------
547 // -----------------------------------------------------------------------------
549 Any
VCLXAccessibleMenuItem::getCurrentValue( ) throw (RuntimeException
)
551 OExternalLockGuard
aGuard( this );
555 aValue
<<= (sal_Int32
) 1;
557 aValue
<<= (sal_Int32
) 0;
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
);
577 else if ( nValue
>= 1 )
586 // -----------------------------------------------------------------------------
588 Any
VCLXAccessibleMenuItem::getMaximumValue( ) throw (RuntimeException
)
590 OExternalLockGuard
aGuard( this );
593 aValue
<<= (sal_Int32
) 1;
598 // -----------------------------------------------------------------------------
600 Any
VCLXAccessibleMenuItem::getMinimumValue( ) throw (RuntimeException
)
602 OExternalLockGuard
aGuard( this );
605 aValue
<<= (sal_Int32
) 0;
610 // -----------------------------------------------------------------------------