1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <accessibility/standard/accessiblemenuitemcomponent.hxx>
23 #include <accessibility/helper/accresmgr.hxx>
24 #include <accessibility/helper/accessiblestrings.hrc>
25 #include <toolkit/awt/vclxwindows.hxx>
26 #include <toolkit/helper/externallock.hxx>
27 #include <toolkit/helper/convert.hxx>
29 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
30 #include <com/sun/star/accessibility/AccessibleRole.hpp>
31 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
32 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
33 #include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
35 #include <unotools/accessiblestatesethelper.hxx>
36 #include <unotools/accessiblerelationsethelper.hxx>
37 #include <cppuhelper/typeprovider.hxx>
38 #include <comphelper/sequence.hxx>
39 #include <comphelper/accessibletexthelper.hxx>
40 #include <vcl/svapp.hxx>
41 #include <vcl/window.hxx>
42 #include <vcl/menu.hxx>
43 #include <vcl/unohelp2.hxx>
44 #include <vcl/settings.hxx>
46 using namespace ::com::sun::star::accessibility
;
47 using namespace ::com::sun::star::uno
;
48 using namespace ::com::sun::star::beans
;
49 using namespace ::com::sun::star::lang
;
50 using namespace ::com::sun::star
;
51 using namespace ::comphelper
;
55 // class OAccessibleMenuItemComponent
58 OAccessibleMenuItemComponent::OAccessibleMenuItemComponent( Menu
* pParent
, sal_uInt16 nItemPos
, Menu
* pMenu
)
59 :OAccessibleMenuBaseComponent( pMenu
)
61 ,m_nItemPos( nItemPos
)
63 m_sAccessibleName
= GetAccessibleName();
64 m_sItemText
= GetItemText();
69 OAccessibleMenuItemComponent::~OAccessibleMenuItemComponent()
75 bool OAccessibleMenuItemComponent::IsEnabled()
77 OExternalLockGuard
aGuard( this );
79 bool bEnabled
= false;
81 bEnabled
= m_pParent
->IsItemEnabled( m_pParent
->GetItemId( m_nItemPos
) );
88 bool OAccessibleMenuItemComponent::IsVisible()
90 bool bVisible
= false;
93 bVisible
= m_pParent
->IsItemPosVisible( m_nItemPos
);
100 void OAccessibleMenuItemComponent::Select()
102 // open the parent menu
103 Reference
< XAccessible
> xParent( getAccessibleParent() );
106 OAccessibleMenuBaseComponent
* pComp
= static_cast< OAccessibleMenuBaseComponent
* >( xParent
.get() );
107 if ( pComp
&& pComp
->getAccessibleRole() == AccessibleRole::MENU
&& !pComp
->IsPopupMenuOpen() )
111 // highlight the menu item
113 m_pParent
->HighlightItem( m_nItemPos
);
118 void OAccessibleMenuItemComponent::DeSelect()
120 if ( m_pParent
&& IsSelected() )
121 m_pParent
->DeHighlight();
126 void OAccessibleMenuItemComponent::Click()
128 // open the parent menu
129 Reference
< XAccessible
> xParent( getAccessibleParent() );
132 OAccessibleMenuBaseComponent
* pComp
= static_cast< OAccessibleMenuBaseComponent
* >( xParent
.get() );
133 if ( pComp
&& pComp
->getAccessibleRole() == AccessibleRole::MENU
&& !pComp
->IsPopupMenuOpen() )
137 // click the menu item
140 vcl::Window
* pWindow
= m_pParent
->GetWindow();
143 // #102438# Menu items are not selectable
144 // Popup menus are executed asynchronously, triggered by a timer.
145 // As Menu::SelectItem only works, if the corresponding menu window is
146 // already created, we have to set the menu delay to 0, so
147 // that the popup menus are executed synchronously.
148 AllSettings aSettings
= pWindow
->GetSettings();
149 MouseSettings aMouseSettings
= aSettings
.GetMouseSettings();
150 sal_uLong nDelay
= aMouseSettings
.GetMenuDelay();
151 aMouseSettings
.SetMenuDelay( 0 );
152 aSettings
.SetMouseSettings( aMouseSettings
);
153 pWindow
->SetSettings( aSettings
);
155 m_pParent
->SelectItem( m_pParent
->GetItemId( m_nItemPos
) );
157 // meanwhile the window pointer may be invalid
158 pWindow
= m_pParent
->GetWindow();
161 // set the menu delay back to the old value
162 aSettings
= pWindow
->GetSettings();
163 aMouseSettings
= aSettings
.GetMouseSettings();
164 aMouseSettings
.SetMenuDelay( nDelay
);
165 aSettings
.SetMouseSettings( aMouseSettings
);
166 pWindow
->SetSettings( aSettings
);
174 void OAccessibleMenuItemComponent::SetItemPos( sal_uInt16 nItemPos
)
176 m_nItemPos
= nItemPos
;
181 void OAccessibleMenuItemComponent::SetAccessibleName( const OUString
& sAccessibleName
)
183 if ( !m_sAccessibleName
.equals( sAccessibleName
) )
185 Any aOldValue
, aNewValue
;
186 aOldValue
<<= m_sAccessibleName
;
187 aNewValue
<<= sAccessibleName
;
188 m_sAccessibleName
= sAccessibleName
;
189 NotifyAccessibleEvent( AccessibleEventId::NAME_CHANGED
, aOldValue
, aNewValue
);
195 OUString
OAccessibleMenuItemComponent::GetAccessibleName()
200 sal_uInt16 nItemId
= m_pParent
->GetItemId( m_nItemPos
);
201 sName
= m_pParent
->GetAccessibleName( nItemId
);
202 if ( sName
.isEmpty() )
203 sName
= m_pParent
->GetItemText( nItemId
);
204 sName
= OutputDevice::GetNonMnemonicString( sName
);
206 if ( m_pParent
->GetAccelKey( nItemId
).GetName().getLength() )
207 sName
= sName
+ "\t" + m_pParent
->GetAccelKey(nItemId
).GetName();
216 void OAccessibleMenuItemComponent::SetItemText( const OUString
& sItemText
)
218 Any aOldValue
, aNewValue
;
219 if ( OCommonAccessibleText::implInitTextChangedEvent( m_sItemText
, sItemText
, aOldValue
, aNewValue
) )
221 m_sItemText
= sItemText
;
222 NotifyAccessibleEvent( AccessibleEventId::TEXT_CHANGED
, aOldValue
, aNewValue
);
228 OUString
OAccessibleMenuItemComponent::GetItemText()
232 sText
= OutputDevice::GetNonMnemonicString( m_pParent
->GetItemText( m_pParent
->GetItemId( m_nItemPos
) ) );
239 void OAccessibleMenuItemComponent::FillAccessibleStateSet( utl::AccessibleStateSetHelper
& rStateSet
)
241 bool bEnabled
= IsEnabled();
244 rStateSet
.AddState( AccessibleStateType::ENABLED
);
245 rStateSet
.AddState( AccessibleStateType::SENSITIVE
);
250 rStateSet
.AddState( AccessibleStateType::SHOWING
);
251 if( !IsMenuHideDisabledEntries() || bEnabled
)
252 rStateSet
.AddState( AccessibleStateType::VISIBLE
);
254 rStateSet
.AddState( AccessibleStateType::OPAQUE
);
258 // OCommonAccessibleComponent
261 awt::Rectangle
OAccessibleMenuItemComponent::implGetBounds() throw (RuntimeException
)
263 awt::Rectangle
aBounds( 0, 0, 0, 0 );
267 // get bounding rectangle of the item relative to the containing window
268 aBounds
= AWTRectangle( m_pParent
->GetBoundingRectangle( m_nItemPos
) );
270 // get position of containing window in screen coordinates
271 vcl::Window
* pWindow
= m_pParent
->GetWindow();
274 Rectangle aRect
= pWindow
->GetWindowExtentsRelative( NULL
);
275 awt::Point aWindowScreenLoc
= AWTPoint( aRect
.TopLeft() );
277 // get position of accessible parent in screen coordinates
278 Reference
< XAccessible
> xParent
= getAccessibleParent();
281 Reference
< XAccessibleComponent
> xParentComponent( xParent
->getAccessibleContext(), UNO_QUERY
);
282 if ( xParentComponent
.is() )
284 awt::Point aParentScreenLoc
= xParentComponent
->getLocationOnScreen();
286 // calculate bounding rectangle of the item relative to the accessible parent
287 aBounds
.X
+= aWindowScreenLoc
.X
- aParentScreenLoc
.X
;
288 aBounds
.Y
+= aWindowScreenLoc
.Y
- aParentScreenLoc
.Y
;
301 void SAL_CALL
OAccessibleMenuItemComponent::disposing()
303 OAccessibleMenuBaseComponent::disposing();
306 m_sAccessibleName
.clear();
311 // XAccessibleContext
314 sal_Int32
OAccessibleMenuItemComponent::getAccessibleChildCount() throw (RuntimeException
, std::exception
)
316 OExternalLockGuard
aGuard( this );
323 Reference
< XAccessible
> OAccessibleMenuItemComponent::getAccessibleChild( sal_Int32 i
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
325 OExternalLockGuard
aGuard( this );
327 if ( i
< 0 || i
>= getAccessibleChildCount() )
328 throw IndexOutOfBoundsException();
330 return Reference
< XAccessible
>();
335 Reference
< XAccessible
> OAccessibleMenuItemComponent::getAccessibleParent( ) throw (RuntimeException
, std::exception
)
337 OExternalLockGuard
aGuard( this );
339 return m_pParent
->GetAccessible();
344 sal_Int32
OAccessibleMenuItemComponent::getAccessibleIndexInParent( ) throw (RuntimeException
, std::exception
)
346 OExternalLockGuard
aGuard( this );
353 sal_Int16
OAccessibleMenuItemComponent::getAccessibleRole( ) throw (RuntimeException
, std::exception
)
355 OExternalLockGuard
aGuard( this );
357 return AccessibleRole::UNKNOWN
;
362 OUString
OAccessibleMenuItemComponent::getAccessibleDescription( ) throw (RuntimeException
, std::exception
)
364 OExternalLockGuard
aGuard( this );
366 OUString sDescription
;
368 sDescription
= m_pParent
->GetHelpText( m_pParent
->GetItemId( m_nItemPos
) );
375 OUString
OAccessibleMenuItemComponent::getAccessibleName( ) throw (RuntimeException
, std::exception
)
377 OExternalLockGuard
aGuard( this );
379 return m_sAccessibleName
;
384 Reference
< XAccessibleRelationSet
> OAccessibleMenuItemComponent::getAccessibleRelationSet( ) throw (RuntimeException
, std::exception
)
386 OExternalLockGuard
aGuard( this );
388 utl::AccessibleRelationSetHelper
* pRelationSetHelper
= new utl::AccessibleRelationSetHelper
;
389 Reference
< XAccessibleRelationSet
> xSet
= pRelationSetHelper
;
395 Locale
OAccessibleMenuItemComponent::getLocale( ) throw (IllegalAccessibleComponentStateException
, RuntimeException
, std::exception
)
397 OExternalLockGuard
aGuard( this );
399 return Application::GetSettings().GetLanguageTag().getLocale();
403 // XAccessibleComponent
406 Reference
< XAccessible
> OAccessibleMenuItemComponent::getAccessibleAtPoint( const awt::Point
& ) throw (RuntimeException
, std::exception
)
408 OExternalLockGuard
aGuard( this );
410 return Reference
< XAccessible
>();
415 void OAccessibleMenuItemComponent::grabFocus( ) throw (RuntimeException
, std::exception
)
417 // no focus for items
422 sal_Int32
OAccessibleMenuItemComponent::getForeground( ) throw (RuntimeException
, std::exception
)
424 OExternalLockGuard
aGuard( this );
426 sal_Int32 nColor
= 0;
427 Reference
< XAccessible
> xParent
= getAccessibleParent();
430 Reference
< XAccessibleComponent
> xParentComp( xParent
->getAccessibleContext(), UNO_QUERY
);
431 if ( xParentComp
.is() )
432 nColor
= xParentComp
->getForeground();
440 sal_Int32
OAccessibleMenuItemComponent::getBackground( ) throw (RuntimeException
, std::exception
)
442 OExternalLockGuard
aGuard( this );
444 sal_Int32 nColor
= 0;
445 Reference
< XAccessible
> xParent
= getAccessibleParent();
448 Reference
< XAccessibleComponent
> xParentComp( xParent
->getAccessibleContext(), UNO_QUERY
);
449 if ( xParentComp
.is() )
450 nColor
= xParentComp
->getBackground();
457 // XAccessibleExtendedComponent
460 Reference
< awt::XFont
> OAccessibleMenuItemComponent::getFont( ) throw (RuntimeException
, std::exception
)
462 OExternalLockGuard
aGuard( this );
464 Reference
< awt::XFont
> xFont
;
465 Reference
< XAccessible
> xParent
= getAccessibleParent();
468 Reference
< XAccessibleExtendedComponent
> xParentComp( xParent
->getAccessibleContext(), UNO_QUERY
);
469 if ( xParentComp
.is() )
470 xFont
= xParentComp
->getFont();
478 OUString
OAccessibleMenuItemComponent::getTitledBorderText( ) throw (RuntimeException
, std::exception
)
480 OExternalLockGuard
aGuard( this );
487 OUString
OAccessibleMenuItemComponent::getToolTipText( ) throw (RuntimeException
, std::exception
)
489 OExternalLockGuard
aGuard( this );
493 sRet
= m_pParent
->GetTipHelpText( m_pParent
->GetItemId( m_nItemPos
) );
500 bool OAccessibleMenuItemComponent::IsMenuHideDisabledEntries()
504 if( m_pParent
->GetMenuFlags() & MenuFlags::HideDisabledEntries
)
512 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */