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 <extended/accessibleiconchoicectrlentry.hxx>
21 #include <vcl/toolkit/ivctrl.hxx>
22 #include <com/sun/star/awt/Rectangle.hpp>
23 #include <com/sun/star/accessibility/AccessibleRole.hpp>
24 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
25 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
26 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
27 #include <vcl/svapp.hxx>
28 #include <vcl/settings.hxx>
29 #include <vcl/unohelp.hxx>
30 #include <vcl/unohelp2.hxx>
31 #include <unotools/accessiblerelationsethelper.hxx>
32 #include <cppuhelper/supportsservice.hxx>
33 #include <comphelper/accessibleeventnotifier.hxx>
34 #include <i18nlangtag/languagetag.hxx>
36 constexpr sal_Int32 ACCESSIBLE_ACTION_COUNT
= 1;
40 /// @throws css::lang::IndexOutOfBoundsException
41 void checkActionIndex_Impl( sal_Int32 _nIndex
)
43 if ( _nIndex
< 0 || _nIndex
>= ACCESSIBLE_ACTION_COUNT
)
44 throw css::lang::IndexOutOfBoundsException();
49 namespace accessibility
53 using namespace ::com::sun::star::accessibility
;
54 using namespace ::com::sun::star::uno
;
55 using namespace ::com::sun::star::lang
;
56 using namespace ::com::sun::star
;
61 AccessibleIconChoiceCtrlEntry::AccessibleIconChoiceCtrlEntry( SvtIconChoiceCtrl
& _rIconCtrl
,
63 const Reference
< XAccessible
>& _xParent
) :
64 m_pIconCtrl ( &_rIconCtrl
),
66 m_xParent ( _xParent
)
69 osl_atomic_increment( &m_refCount
);
71 Reference
< XComponent
> xComp( m_xParent
, UNO_QUERY
);
73 xComp
->addEventListener( this );
75 osl_atomic_decrement( &m_refCount
);
78 void AccessibleIconChoiceCtrlEntry::disposing( const css::lang::EventObject
& _rSource
)
80 if ( _rSource
.Source
== m_xParent
)
83 OSL_ENSURE( !m_xParent
.is() && ( m_pIconCtrl
== nullptr ), "" );
87 AccessibleIconChoiceCtrlEntry::~AccessibleIconChoiceCtrlEntry()
91 // increment ref count to prevent double call of Dtor
92 osl_atomic_increment( &m_refCount
);
97 tools::Rectangle
AccessibleIconChoiceCtrlEntry::GetBoundingBox_Impl() const
99 tools::Rectangle aRect
;
100 SvxIconChoiceCtrlEntry
* pEntry
= m_pIconCtrl
->GetEntry( m_nIndex
);
102 aRect
= m_pIconCtrl
->GetBoundingBox( pEntry
);
107 AbsoluteScreenPixelRectangle
AccessibleIconChoiceCtrlEntry::GetBoundingBoxOnScreen_Impl() const
109 SvxIconChoiceCtrlEntry
* pEntry
= m_pIconCtrl
->GetEntry( m_nIndex
);
111 return AbsoluteScreenPixelRectangle();
112 tools::Rectangle aRect
= m_pIconCtrl
->GetBoundingBox( pEntry
);
113 AbsoluteScreenPixelPoint aTopLeft
= m_pIconCtrl
->GetWindowExtentsAbsolute().TopLeft();
114 aTopLeft
+= AbsoluteScreenPixelPoint(aRect
.TopLeft());
115 return AbsoluteScreenPixelRectangle( aTopLeft
, aRect
.GetSize() );
118 bool AccessibleIconChoiceCtrlEntry::IsAlive_Impl() const
120 return ( !rBHelper
.bDisposed
&& !rBHelper
.bInDispose
&& m_pIconCtrl
);
123 bool AccessibleIconChoiceCtrlEntry::IsShowing_Impl() const
125 bool bShowing
= false;
126 Reference
< XAccessibleContext
> xParentContext
=
127 m_xParent
.is() ? m_xParent
->getAccessibleContext() : Reference
< XAccessibleContext
>();
128 if( xParentContext
.is() )
130 Reference
< XAccessibleComponent
> xParentComp( xParentContext
, uno::UNO_QUERY
);
131 if( xParentComp
.is() )
132 bShowing
= GetBoundingBox_Impl().Overlaps(
133 vcl::unohelper::ConvertToVCLRect(xParentComp
->getBounds()));
139 AbsoluteScreenPixelRectangle
AccessibleIconChoiceCtrlEntry::GetBoundingBoxOnScreen()
141 SolarMutexGuard aSolarGuard
;
142 ::osl::MutexGuard
aGuard( m_aMutex
);
145 return GetBoundingBoxOnScreen_Impl();
148 void AccessibleIconChoiceCtrlEntry::EnsureIsAlive() const
150 if ( !IsAlive_Impl() )
151 throw lang::DisposedException();
154 css::awt::Rectangle
AccessibleIconChoiceCtrlEntry::implGetBounds()
156 return vcl::unohelper::ConvertToAWTRect(GetBoundingBox_Impl());
159 OUString
AccessibleIconChoiceCtrlEntry::implGetText()
161 SvxIconChoiceCtrlEntry
* pEntry
= m_pIconCtrl
->GetEntry( m_nIndex
);
163 return pEntry
->GetDisplayText();
167 Locale
AccessibleIconChoiceCtrlEntry::implGetLocale()
169 return Application::GetSettings().GetUILanguageTag().getLocale();
171 void AccessibleIconChoiceCtrlEntry::implGetSelection( sal_Int32
& nStartIndex
, sal_Int32
& nEndIndex
)
180 Sequence
< sal_Int8
> AccessibleIconChoiceCtrlEntry::getImplementationId()
182 return css::uno::Sequence
<sal_Int8
>();
187 void SAL_CALL
AccessibleIconChoiceCtrlEntry::disposing()
189 ::osl::MutexGuard
aGuard( m_aMutex
);
191 comphelper::OAccessibleComponentHelper::disposing();
193 Reference
< XComponent
> xComp( m_xParent
, UNO_QUERY
);
195 xComp
->removeEventListener( this );
197 m_pIconCtrl
= nullptr;
203 OUString SAL_CALL
AccessibleIconChoiceCtrlEntry::getImplementationName()
205 return u
"com.sun.star.comp.svtools.AccessibleIconChoiceControlEntry"_ustr
;
208 Sequence
< OUString
> SAL_CALL
AccessibleIconChoiceCtrlEntry::getSupportedServiceNames()
210 return {u
"com.sun.star.accessibility.AccessibleContext"_ustr
,
211 u
"com.sun.star.accessibility.AccessibleComponent"_ustr
,
212 u
"com.sun.star.awt.AccessibleIconChoiceControlEntry"_ustr
};
215 sal_Bool SAL_CALL
AccessibleIconChoiceCtrlEntry::supportsService( const OUString
& _rServiceName
)
217 return cppu::supportsService(this, _rServiceName
);
222 Reference
< XAccessibleContext
> SAL_CALL
AccessibleIconChoiceCtrlEntry::getAccessibleContext( )
228 // XAccessibleContext
230 sal_Int64 SAL_CALL
AccessibleIconChoiceCtrlEntry::getAccessibleChildCount( )
232 return 0; // no children
235 Reference
< XAccessible
> SAL_CALL
AccessibleIconChoiceCtrlEntry::getAccessibleChild( sal_Int64
)
237 throw IndexOutOfBoundsException();
240 Reference
< XAccessible
> SAL_CALL
AccessibleIconChoiceCtrlEntry::getAccessibleParent( )
242 ::osl::MutexGuard
aGuard( m_aMutex
);
248 sal_Int64 SAL_CALL
AccessibleIconChoiceCtrlEntry::getAccessibleIndexInParent( )
253 sal_Int16 SAL_CALL
AccessibleIconChoiceCtrlEntry::getAccessibleRole( )
255 //return AccessibleRole::LABEL;
256 return AccessibleRole::LIST_ITEM
;
259 OUString SAL_CALL
AccessibleIconChoiceCtrlEntry::getAccessibleDescription( )
261 // no description for every item
265 OUString SAL_CALL
AccessibleIconChoiceCtrlEntry::getAccessibleName( )
267 ::osl::MutexGuard
aGuard( m_aMutex
);
270 return implGetText();
273 Reference
< XAccessibleRelationSet
> SAL_CALL
AccessibleIconChoiceCtrlEntry::getAccessibleRelationSet( )
275 return new utl::AccessibleRelationSetHelper
;
278 sal_Int64 SAL_CALL
AccessibleIconChoiceCtrlEntry::getAccessibleStateSet( )
280 SolarMutexGuard aSolarGuard
;
281 ::osl::MutexGuard
aGuard( m_aMutex
);
283 sal_Int64 nStateSet
= 0;
285 if ( IsAlive_Impl() )
287 nStateSet
|= AccessibleStateType::FOCUSABLE
;
288 nStateSet
|= AccessibleStateType::TRANSIENT
;
289 nStateSet
|= AccessibleStateType::SELECTABLE
;
290 nStateSet
|= AccessibleStateType::ENABLED
;
291 nStateSet
|= AccessibleStateType::SENSITIVE
;
292 if ( IsShowing_Impl() )
294 nStateSet
|= AccessibleStateType::SHOWING
;
295 nStateSet
|= AccessibleStateType::VISIBLE
;
298 if ( m_pIconCtrl
&& m_pIconCtrl
->GetCursor() == m_pIconCtrl
->GetEntry( m_nIndex
) )
300 nStateSet
|= AccessibleStateType::SELECTED
;
301 if (m_pIconCtrl
->HasChildPathFocus())
302 nStateSet
|= AccessibleStateType::FOCUSED
;
306 nStateSet
|= AccessibleStateType::DEFUNC
;
311 Locale SAL_CALL
AccessibleIconChoiceCtrlEntry::getLocale( )
313 SolarMutexGuard aSolarGuard
;
314 ::osl::MutexGuard
aGuard( m_aMutex
);
316 return implGetLocale();
319 // XAccessibleComponent
321 Reference
< XAccessible
> SAL_CALL
AccessibleIconChoiceCtrlEntry::getAccessibleAtPoint( const awt::Point
& )
323 return Reference
< XAccessible
>();
326 awt::Point SAL_CALL
AccessibleIconChoiceCtrlEntry::getLocationOnScreen( )
328 return vcl::unohelper::ConvertToAWTPoint( GetBoundingBoxOnScreen().TopLeft() );
331 void SAL_CALL
AccessibleIconChoiceCtrlEntry::grabFocus( )
333 // do nothing, because no focus for each item
336 sal_Int32
AccessibleIconChoiceCtrlEntry::getForeground( )
338 SolarMutexGuard aSolarGuard
;
339 ::osl::MutexGuard
aGuard( m_aMutex
);
341 sal_Int32 nColor
= 0;
342 Reference
< XAccessible
> xParent
= getAccessibleParent();
345 Reference
< XAccessibleComponent
> xParentComp( xParent
->getAccessibleContext(), UNO_QUERY
);
346 if ( xParentComp
.is() )
347 nColor
= xParentComp
->getForeground();
353 sal_Int32
AccessibleIconChoiceCtrlEntry::getBackground( )
355 SolarMutexGuard aSolarGuard
;
356 ::osl::MutexGuard
aGuard( m_aMutex
);
358 sal_Int32 nColor
= 0;
359 Reference
< XAccessible
> xParent
= getAccessibleParent();
362 Reference
< XAccessibleComponent
> xParentComp( xParent
->getAccessibleContext(), UNO_QUERY
);
363 if ( xParentComp
.is() )
364 nColor
= xParentComp
->getBackground();
373 awt::Rectangle SAL_CALL
AccessibleIconChoiceCtrlEntry::getCharacterBounds( sal_Int32 _nIndex
)
375 SolarMutexGuard aSolarGuard
;
376 ::osl::MutexGuard
aGuard( m_aMutex
);
378 if ( ( 0 > _nIndex
) || ( implGetText().getLength() <= _nIndex
) )
379 throw IndexOutOfBoundsException();
381 awt::Rectangle
aBounds( 0, 0, 0, 0 );
384 tools::Rectangle aItemRect
= GetBoundingBox_Impl();
385 tools::Rectangle aCharRect
= m_pIconCtrl
->GetEntryCharacterBounds( m_nIndex
, _nIndex
);
386 aCharRect
.Move( -aItemRect
.Left(), -aItemRect
.Top() );
387 aBounds
= vcl::unohelper::ConvertToAWTRect(aCharRect
);
393 sal_Int32 SAL_CALL
AccessibleIconChoiceCtrlEntry::getIndexAtPoint( const awt::Point
& aPoint
)
395 SolarMutexGuard aSolarGuard
;
396 ::osl::MutexGuard
aGuard( m_aMutex
);
398 sal_Int32 nIndex
= -1;
401 vcl::ControlLayoutData aLayoutData
;
402 tools::Rectangle aItemRect
= GetBoundingBox_Impl();
403 m_pIconCtrl
->RecordLayoutData( &aLayoutData
, aItemRect
);
404 Point
aPnt(vcl::unohelper::ConvertToVCLPoint(aPoint
));
405 aPnt
+= aItemRect
.TopLeft();
406 nIndex
= aLayoutData
.GetIndexForPoint( aPnt
);
408 tools::Long nLen
= aLayoutData
.m_aUnicodeBoundRects
.size();
409 for ( tools::Long i
= 0; i
< nLen
; ++i
)
411 tools::Rectangle aRect
= aLayoutData
.GetCharacterBounds(i
);
412 bool bInside
= aRect
.Contains( aPnt
);
422 sal_Bool SAL_CALL
AccessibleIconChoiceCtrlEntry::copyText( sal_Int32 nStartIndex
, sal_Int32 nEndIndex
)
424 SolarMutexGuard aSolarGuard
;
425 ::osl::MutexGuard
aGuard( m_aMutex
);
428 OUString sText
= implGetText();
429 if ( ( 0 > nStartIndex
) || ( sText
.getLength() <= nStartIndex
)
430 || ( 0 > nEndIndex
) || ( sText
.getLength() <= nEndIndex
) )
431 throw IndexOutOfBoundsException();
436 sal_Int32 nLen
= nEndIndex
- nStartIndex
+ 1;
437 css::uno::Reference
<css::datatransfer::clipboard::XClipboard
> xClipBoard
= m_pIconCtrl
->GetClipboard();
438 vcl::unohelper::TextDataObject::CopyStringTo(sText
.copy(nStartIndex
, nLen
), xClipBoard
);
443 sal_Bool SAL_CALL
AccessibleIconChoiceCtrlEntry::scrollSubstringTo( sal_Int32
, sal_Int32
, AccessibleScrollType
)
448 // XAccessibleEventBroadcaster
450 sal_Int32 SAL_CALL
AccessibleIconChoiceCtrlEntry::getCaretPosition( )
454 sal_Bool SAL_CALL
AccessibleIconChoiceCtrlEntry::setCaretPosition ( sal_Int32 nIndex
)
456 SolarMutexGuard aSolarGuard
;
457 ::osl::MutexGuard
aGuard( m_aMutex
);
460 if ( !implIsValidRange( nIndex
, nIndex
, implGetText().getLength() ) )
461 throw IndexOutOfBoundsException();
465 sal_Unicode SAL_CALL
AccessibleIconChoiceCtrlEntry::getCharacter( sal_Int32 nIndex
)
467 SolarMutexGuard aSolarGuard
;
468 ::osl::MutexGuard
aGuard( m_aMutex
);
470 return OCommonAccessibleText::implGetCharacter( implGetText(), nIndex
);
472 css::uno::Sequence
< css::beans::PropertyValue
> SAL_CALL
AccessibleIconChoiceCtrlEntry::getCharacterAttributes( sal_Int32 nIndex
, const css::uno::Sequence
< OUString
>& )
474 SolarMutexGuard aSolarGuard
;
475 ::osl::MutexGuard
aGuard( m_aMutex
);
478 OUString
sText( implGetText() );
480 if ( !implIsValidIndex( nIndex
, sText
.getLength() ) )
481 throw IndexOutOfBoundsException();
483 return css::uno::Sequence
< css::beans::PropertyValue
>();
485 sal_Int32 SAL_CALL
AccessibleIconChoiceCtrlEntry::getCharacterCount( )
487 SolarMutexGuard aSolarGuard
;
488 ::osl::MutexGuard
aGuard( m_aMutex
);
490 return implGetText().getLength();
493 OUString SAL_CALL
AccessibleIconChoiceCtrlEntry::getSelectedText( )
495 SolarMutexGuard aSolarGuard
;
496 ::osl::MutexGuard
aGuard( m_aMutex
);
500 sal_Int32 SAL_CALL
AccessibleIconChoiceCtrlEntry::getSelectionStart( )
502 SolarMutexGuard aSolarGuard
;
503 ::osl::MutexGuard
aGuard( m_aMutex
);
507 sal_Int32 SAL_CALL
AccessibleIconChoiceCtrlEntry::getSelectionEnd( )
509 SolarMutexGuard aSolarGuard
;
510 ::osl::MutexGuard
aGuard( m_aMutex
);
514 sal_Bool SAL_CALL
AccessibleIconChoiceCtrlEntry::setSelection( sal_Int32 nStartIndex
, sal_Int32 nEndIndex
)
516 SolarMutexGuard aSolarGuard
;
517 ::osl::MutexGuard
aGuard( m_aMutex
);
520 if ( !implIsValidRange( nStartIndex
, nEndIndex
, implGetText().getLength() ) )
521 throw IndexOutOfBoundsException();
525 OUString SAL_CALL
AccessibleIconChoiceCtrlEntry::getText( )
527 SolarMutexGuard aSolarGuard
;
528 ::osl::MutexGuard
aGuard( m_aMutex
);
530 return implGetText( );
532 OUString SAL_CALL
AccessibleIconChoiceCtrlEntry::getTextRange( sal_Int32 nStartIndex
, sal_Int32 nEndIndex
)
534 SolarMutexGuard aSolarGuard
;
535 ::osl::MutexGuard
aGuard( m_aMutex
);
537 return OCommonAccessibleText::implGetTextRange( implGetText(), nStartIndex
, nEndIndex
);
539 css::accessibility::TextSegment SAL_CALL
AccessibleIconChoiceCtrlEntry::getTextAtIndex( sal_Int32 nIndex
, sal_Int16 aTextType
)
541 SolarMutexGuard aSolarGuard
;
542 ::osl::MutexGuard
aGuard( m_aMutex
);
544 return OCommonAccessibleText::getTextAtIndex( nIndex
,aTextType
);
546 css::accessibility::TextSegment SAL_CALL
AccessibleIconChoiceCtrlEntry::getTextBeforeIndex( sal_Int32 nIndex
, sal_Int16 aTextType
)
548 SolarMutexGuard aSolarGuard
;
549 ::osl::MutexGuard
aGuard( m_aMutex
);
551 return OCommonAccessibleText::getTextBeforeIndex( nIndex
,aTextType
);
553 css::accessibility::TextSegment SAL_CALL
AccessibleIconChoiceCtrlEntry::getTextBehindIndex( sal_Int32 nIndex
, sal_Int16 aTextType
)
555 SolarMutexGuard aSolarGuard
;
556 ::osl::MutexGuard
aGuard( m_aMutex
);
559 return OCommonAccessibleText::getTextBehindIndex( nIndex
,aTextType
);
565 sal_Int32 SAL_CALL
AccessibleIconChoiceCtrlEntry::getAccessibleActionCount( )
567 // three actions supported
568 return ACCESSIBLE_ACTION_COUNT
;
571 sal_Bool SAL_CALL
AccessibleIconChoiceCtrlEntry::doAccessibleAction( sal_Int32 nIndex
)
573 SolarMutexGuard aSolarGuard
;
574 ::osl::MutexGuard
aGuard( m_aMutex
);
577 checkActionIndex_Impl( nIndex
);
580 SvxIconChoiceCtrlEntry
* pEntry
= m_pIconCtrl
->GetEntry( m_nIndex
);
581 if ( pEntry
&& !pEntry
->IsSelected() )
583 m_pIconCtrl
->SetCursor( pEntry
);
590 OUString SAL_CALL
AccessibleIconChoiceCtrlEntry::getAccessibleActionDescription( sal_Int32 nIndex
)
592 SolarMutexGuard aSolarGuard
;
593 ::osl::MutexGuard
aGuard( m_aMutex
);
595 checkActionIndex_Impl( nIndex
);
598 return u
"Select"_ustr
;
601 Reference
< XAccessibleKeyBinding
> AccessibleIconChoiceCtrlEntry::getAccessibleActionKeyBinding( sal_Int32 nIndex
)
603 Reference
< XAccessibleKeyBinding
> xRet
;
604 checkActionIndex_Impl( nIndex
);
609 }// namespace accessibility
612 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */