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 <standard/accessiblemenuitemcomponent.hxx>
23 #include <toolkit/helper/convert.hxx>
25 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
26 #include <com/sun/star/accessibility/AccessibleRole.hpp>
27 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
28 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
29 #include <unotools/accessiblerelationsethelper.hxx>
30 #include <comphelper/accessiblecontexthelper.hxx>
31 #include <comphelper/accessibletexthelper.hxx>
32 #include <vcl/svapp.hxx>
33 #include <vcl/window.hxx>
34 #include <vcl/menu.hxx>
35 #include <vcl/mnemonic.hxx>
36 #include <vcl/settings.hxx>
37 #include <i18nlangtag/languagetag.hxx>
39 using namespace ::com::sun::star::accessibility
;
40 using namespace ::com::sun::star::uno
;
41 using namespace ::com::sun::star::beans
;
42 using namespace ::com::sun::star::lang
;
43 using namespace ::com::sun::star
;
44 using namespace ::comphelper
;
49 OAccessibleMenuItemComponent::OAccessibleMenuItemComponent( Menu
* pParent
, sal_uInt16 nItemPos
, Menu
* pMenu
)
50 :OAccessibleMenuBaseComponent( pMenu
)
52 ,m_nItemPos( nItemPos
)
54 m_sAccessibleName
= GetAccessibleName();
55 m_sItemText
= GetItemText();
58 OAccessibleMenuItemComponent::~OAccessibleMenuItemComponent()
62 bool OAccessibleMenuItemComponent::IsEnabled()
64 OExternalLockGuard
aGuard( this );
66 bool bEnabled
= false;
68 bEnabled
= m_pParent
->IsItemEnabled( m_pParent
->GetItemId( m_nItemPos
) );
74 bool OAccessibleMenuItemComponent::IsVisible()
76 bool bVisible
= false;
79 bVisible
= m_pParent
->IsItemPosVisible( m_nItemPos
);
85 void OAccessibleMenuItemComponent::Select()
87 // open the parent menu
88 Reference
< XAccessible
> xParent( getAccessibleParent() );
91 OAccessibleMenuBaseComponent
* pComp
= static_cast< OAccessibleMenuBaseComponent
* >( xParent
.get() );
92 if ( pComp
&& pComp
->getAccessibleRole() == AccessibleRole::MENU
&& !pComp
->IsPopupMenuOpen() )
96 // highlight the menu item
98 m_pParent
->HighlightItem( m_nItemPos
);
102 void OAccessibleMenuItemComponent::DeSelect()
104 if ( m_pParent
&& IsSelected() )
105 m_pParent
->DeHighlight();
109 void OAccessibleMenuItemComponent::Click()
111 // open the parent menu
112 Reference
< XAccessible
> xParent( getAccessibleParent() );
115 OAccessibleMenuBaseComponent
* pComp
= static_cast< OAccessibleMenuBaseComponent
* >( xParent
.get() );
116 if ( pComp
&& pComp
->getAccessibleRole() == AccessibleRole::MENU
&& !pComp
->IsPopupMenuOpen() )
120 // click the menu item
124 vcl::Window
* pWindow
= m_pParent
->GetWindow();
128 // #102438# Menu items are not selectable
129 // Popup menus are executed asynchronously, triggered by a timer.
130 // As Menu::SelectItem only works, if the corresponding menu window is
131 // already created, we have to set the menu delay to 0, so
132 // that the popup menus are executed synchronously.
133 AllSettings aSettings
= pWindow
->GetSettings();
134 MouseSettings aMouseSettings
= aSettings
.GetMouseSettings();
135 sal_Int32 nDelay
= aMouseSettings
.GetMenuDelay();
136 aMouseSettings
.SetMenuDelay( 0 );
137 aSettings
.SetMouseSettings( aMouseSettings
);
138 pWindow
->SetSettings( aSettings
);
140 m_pParent
->SelectItem( m_pParent
->GetItemId( m_nItemPos
) );
142 // meanwhile the window pointer may be invalid
143 pWindow
= m_pParent
->GetWindow();
146 // set the menu delay back to the old value
147 aSettings
= pWindow
->GetSettings();
148 aMouseSettings
= aSettings
.GetMouseSettings();
149 aMouseSettings
.SetMenuDelay( nDelay
);
150 aSettings
.SetMouseSettings( aMouseSettings
);
151 pWindow
->SetSettings( aSettings
);
156 void OAccessibleMenuItemComponent::SetItemPos( sal_uInt16 nItemPos
)
158 m_nItemPos
= nItemPos
;
162 void OAccessibleMenuItemComponent::SetAccessibleName( const OUString
& sAccessibleName
)
164 if ( m_sAccessibleName
!= sAccessibleName
)
166 Any aOldValue
, aNewValue
;
167 aOldValue
<<= m_sAccessibleName
;
168 aNewValue
<<= sAccessibleName
;
169 m_sAccessibleName
= sAccessibleName
;
170 NotifyAccessibleEvent( AccessibleEventId::NAME_CHANGED
, aOldValue
, aNewValue
);
175 OUString
OAccessibleMenuItemComponent::GetAccessibleName()
180 sal_uInt16 nItemId
= m_pParent
->GetItemId( m_nItemPos
);
181 sName
= m_pParent
->GetAccessibleName( nItemId
);
182 if ( sName
.isEmpty() )
183 sName
= m_pParent
->GetItemText( nItemId
);
184 sName
= removeMnemonicFromString( sName
);
186 if ( m_pParent
->GetAccelKey( nItemId
).GetName().getLength() )
187 sName
+= "\t" + m_pParent
->GetAccelKey(nItemId
).GetName();
195 void OAccessibleMenuItemComponent::SetItemText( const OUString
& sItemText
)
197 Any aOldValue
, aNewValue
;
198 if ( OCommonAccessibleText::implInitTextChangedEvent( m_sItemText
, sItemText
, aOldValue
, aNewValue
) )
200 m_sItemText
= sItemText
;
201 NotifyAccessibleEvent( AccessibleEventId::TEXT_CHANGED
, aOldValue
, aNewValue
);
206 OUString
OAccessibleMenuItemComponent::GetItemText()
210 sText
= removeMnemonicFromString( m_pParent
->GetItemText( m_pParent
->GetItemId( m_nItemPos
) ) );
216 void OAccessibleMenuItemComponent::FillAccessibleStateSet( sal_Int64
& rStateSet
)
218 bool bEnabled
= IsEnabled();
221 rStateSet
|= AccessibleStateType::ENABLED
;
222 rStateSet
|= AccessibleStateType::SENSITIVE
;
227 rStateSet
|= AccessibleStateType::SHOWING
;
228 if( !IsMenuHideDisabledEntries() || bEnabled
)
229 rStateSet
|= AccessibleStateType::VISIBLE
;
231 rStateSet
|= AccessibleStateType::OPAQUE
;
235 // OCommonAccessibleComponent
238 awt::Rectangle
OAccessibleMenuItemComponent::implGetBounds()
240 awt::Rectangle
aBounds( 0, 0, 0, 0 );
244 // get bounding rectangle of the item relative to the containing window
245 aBounds
= AWTRectangle( m_pParent
->GetBoundingRectangle( m_nItemPos
) );
247 // get position of containing window in screen coordinates
248 vcl::Window
* pWindow
= m_pParent
->GetWindow();
251 tools::Rectangle aRect
= pWindow
->GetWindowExtentsRelative( nullptr );
252 awt::Point aWindowScreenLoc
= AWTPoint( aRect
.TopLeft() );
254 // get position of accessible parent in screen coordinates
255 Reference
< XAccessible
> xParent
= getAccessibleParent();
258 Reference
< XAccessibleComponent
> xParentComponent( xParent
->getAccessibleContext(), UNO_QUERY
);
259 if ( xParentComponent
.is() )
261 awt::Point aParentScreenLoc
= xParentComponent
->getLocationOnScreen();
263 // calculate bounding rectangle of the item relative to the accessible parent
264 aBounds
.X
+= aWindowScreenLoc
.X
- aParentScreenLoc
.X
;
265 aBounds
.Y
+= aWindowScreenLoc
.Y
- aParentScreenLoc
.Y
;
278 void SAL_CALL
OAccessibleMenuItemComponent::disposing()
280 OAccessibleMenuBaseComponent::disposing();
283 m_sAccessibleName
.clear();
288 // XAccessibleContext
291 sal_Int64
OAccessibleMenuItemComponent::getAccessibleChildCount()
293 OExternalLockGuard
aGuard( this );
299 Reference
< XAccessible
> OAccessibleMenuItemComponent::getAccessibleChild( sal_Int64 i
)
301 OExternalLockGuard
aGuard( this );
303 if ( i
< 0 || i
>= getAccessibleChildCount() )
304 throw IndexOutOfBoundsException();
306 return Reference
< XAccessible
>();
310 Reference
< XAccessible
> OAccessibleMenuItemComponent::getAccessibleParent( )
312 OExternalLockGuard
aGuard( this );
314 return m_pParent
->GetAccessible();
318 sal_Int64
OAccessibleMenuItemComponent::getAccessibleIndexInParent( )
320 OExternalLockGuard
aGuard( this );
326 sal_Int16
OAccessibleMenuItemComponent::getAccessibleRole( )
328 OExternalLockGuard
aGuard( this );
330 return AccessibleRole::UNKNOWN
;
334 OUString
OAccessibleMenuItemComponent::getAccessibleDescription( )
336 OExternalLockGuard
aGuard( this );
338 OUString sDescription
;
340 sDescription
= m_pParent
->GetAccessibleDescription( m_pParent
->GetItemId( m_nItemPos
) );
346 OUString
OAccessibleMenuItemComponent::getAccessibleName( )
348 OExternalLockGuard
aGuard( this );
350 return m_sAccessibleName
;
354 Reference
< XAccessibleRelationSet
> OAccessibleMenuItemComponent::getAccessibleRelationSet( )
356 OExternalLockGuard
aGuard( this );
358 return new utl::AccessibleRelationSetHelper
;
362 Locale
OAccessibleMenuItemComponent::getLocale( )
364 OExternalLockGuard
aGuard( this );
366 return Application::GetSettings().GetLanguageTag().getLocale();
370 // XAccessibleComponent
373 Reference
< XAccessible
> OAccessibleMenuItemComponent::getAccessibleAtPoint( const awt::Point
& )
375 OExternalLockGuard
aGuard( this );
377 return Reference
< XAccessible
>();
381 void OAccessibleMenuItemComponent::grabFocus( )
383 // no focus for items
387 sal_Int32
OAccessibleMenuItemComponent::getForeground( )
389 OExternalLockGuard
aGuard( this );
391 sal_Int32 nColor
= 0;
392 Reference
< XAccessible
> xParent
= getAccessibleParent();
395 Reference
< XAccessibleComponent
> xParentComp( xParent
->getAccessibleContext(), UNO_QUERY
);
396 if ( xParentComp
.is() )
397 nColor
= xParentComp
->getForeground();
404 sal_Int32
OAccessibleMenuItemComponent::getBackground( )
406 OExternalLockGuard
aGuard( this );
408 sal_Int32 nColor
= 0;
409 Reference
< XAccessible
> xParent
= getAccessibleParent();
412 Reference
< XAccessibleComponent
> xParentComp( xParent
->getAccessibleContext(), UNO_QUERY
);
413 if ( xParentComp
.is() )
414 nColor
= xParentComp
->getBackground();
421 // XAccessibleExtendedComponent
424 Reference
< awt::XFont
> OAccessibleMenuItemComponent::getFont( )
426 OExternalLockGuard
aGuard( this );
428 Reference
< awt::XFont
> xFont
;
429 Reference
< XAccessible
> xParent
= getAccessibleParent();
432 Reference
< XAccessibleExtendedComponent
> xParentComp( xParent
->getAccessibleContext(), UNO_QUERY
);
433 if ( xParentComp
.is() )
434 xFont
= xParentComp
->getFont();
441 OUString
OAccessibleMenuItemComponent::getTitledBorderText( )
443 OExternalLockGuard
aGuard( this );
449 OUString
OAccessibleMenuItemComponent::getToolTipText( )
451 OExternalLockGuard
aGuard( this );
455 sRet
= m_pParent
->GetTipHelpText( m_pParent
->GetItemId( m_nItemPos
) );
461 bool OAccessibleMenuItemComponent::IsMenuHideDisabledEntries()
465 if( m_pParent
->GetMenuFlags() & MenuFlags::HideDisabledEntries
)
473 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */