bump product version to 7.6.3.2-android
[LibreOffice.git] / svtools / source / control / valueacc.cxx
blobcdf759621042b69fcdee3bbebcb96e96b1766bf9
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <vcl/svapp.hxx>
21 #include <vcl/settings.hxx>
22 #include <sal/log.hxx>
23 #include <tools/debug.hxx>
24 #include <comphelper/diagnose_ex.hxx>
25 #include <svtools/valueset.hxx>
26 #include "valueimp.hxx"
27 #include <comphelper/servicehelper.hxx>
28 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
29 #include <com/sun/star/accessibility/AccessibleRole.hpp>
30 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
31 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
33 using namespace ::com::sun::star;
36 ValueSetItem::ValueSetItem( ValueSet& rParent )
37 : mrParent(rParent)
38 , mpData(nullptr)
39 , mxAcc()
40 , mnId(0)
41 , meType(VALUESETITEM_NONE)
42 , mbVisible(true)
47 ValueSetItem::~ValueSetItem()
49 if( mxAcc.is() )
51 mxAcc->ParentDestroyed();
55 uno::Reference< accessibility::XAccessible > ValueSetItem::GetAccessible( bool bIsTransientChildrenDisabled )
57 if( !mxAcc.is() )
58 mxAcc = new ValueItemAcc( this, bIsTransientChildrenDisabled );
60 return mxAcc;
63 ValueItemAcc::ValueItemAcc( ValueSetItem* pParent, bool bIsTransientChildrenDisabled ) :
64 mpParent( pParent ),
65 mbIsTransientChildrenDisabled( bIsTransientChildrenDisabled )
69 ValueItemAcc::~ValueItemAcc()
73 void ValueItemAcc::ParentDestroyed()
75 std::scoped_lock aGuard( maMutex );
76 mpParent = nullptr;
79 ValueItemAcc* ValueItemAcc::getImplementation( const uno::Reference< uno::XInterface >& rxData )
80 noexcept
82 return dynamic_cast<ValueItemAcc*>(rxData.get());
86 uno::Reference< accessibility::XAccessibleContext > SAL_CALL ValueItemAcc::getAccessibleContext()
88 return this;
92 sal_Int64 SAL_CALL ValueItemAcc::getAccessibleChildCount()
94 return 0;
98 uno::Reference< accessibility::XAccessible > SAL_CALL ValueItemAcc::getAccessibleChild( sal_Int64 )
100 throw lang::IndexOutOfBoundsException();
104 uno::Reference< accessibility::XAccessible > SAL_CALL ValueItemAcc::getAccessibleParent()
106 const SolarMutexGuard aSolarGuard;
107 uno::Reference< accessibility::XAccessible > xRet;
109 if( mpParent )
110 xRet = mpParent->mrParent.mxAccessible;
112 return xRet;
116 sal_Int64 SAL_CALL ValueItemAcc::getAccessibleIndexInParent()
118 const SolarMutexGuard aSolarGuard;
119 // The index defaults to -1 to indicate the child does not belong to its
120 // parent.
121 sal_Int64 nIndexInParent = -1;
123 if( mpParent )
125 bool bDone = false;
127 sal_uInt16 nCount = mpParent->mrParent.ImplGetVisibleItemCount();
128 ValueSetItem* pItem;
129 for (sal_uInt16 i=0; i<nCount && !bDone; i++)
131 // Guard the retrieval of the i-th child with a try/catch block
132 // just in case the number of children changes in the meantime.
135 pItem = mpParent->mrParent.ImplGetItem(i);
137 catch (const lang::IndexOutOfBoundsException&)
139 pItem = nullptr;
142 // Do not create an accessible object for the test.
143 if (pItem != nullptr && pItem->mxAcc.is())
144 if (pItem->GetAccessible( mbIsTransientChildrenDisabled ).get() == this )
146 nIndexInParent = i;
147 bDone = true;
152 //if this valueset contain a none field(common value is default), then we should increase the real index and set the noitem index value equal 0.
153 if ( mpParent && ( (mpParent->mrParent.GetStyle() & WB_NONEFIELD) != 0 ) )
155 ValueSetItem* pFirstItem = mpParent->mrParent.ImplGetItem (VALUESET_ITEM_NONEITEM);
156 if( pFirstItem && pFirstItem ->GetAccessible(mbIsTransientChildrenDisabled).get() == this )
157 nIndexInParent = 0;
158 else
159 nIndexInParent++;
161 return nIndexInParent;
165 sal_Int16 SAL_CALL ValueItemAcc::getAccessibleRole()
167 return accessibility::AccessibleRole::LIST_ITEM;
171 OUString SAL_CALL ValueItemAcc::getAccessibleDescription()
173 return OUString();
177 OUString SAL_CALL ValueItemAcc::getAccessibleName()
179 const SolarMutexGuard aSolarGuard;
181 if( mpParent )
183 if (mpParent->maText.isEmpty())
184 return "Item " + OUString::number(static_cast<sal_Int32>(mpParent->mnId));
185 else
186 return mpParent->maText;
189 return OUString();
193 uno::Reference< accessibility::XAccessibleRelationSet > SAL_CALL ValueItemAcc::getAccessibleRelationSet()
195 return uno::Reference< accessibility::XAccessibleRelationSet >();
199 sal_Int64 SAL_CALL ValueItemAcc::getAccessibleStateSet()
201 const SolarMutexGuard aSolarGuard;
202 sal_Int64 nStateSet = 0;
204 if( mpParent )
206 nStateSet |= accessibility::AccessibleStateType::ENABLED;
207 nStateSet |= accessibility::AccessibleStateType::SENSITIVE;
208 nStateSet |= accessibility::AccessibleStateType::SHOWING;
209 nStateSet |= accessibility::AccessibleStateType::VISIBLE;
210 if ( !mbIsTransientChildrenDisabled )
211 nStateSet |= accessibility::AccessibleStateType::TRANSIENT;
213 nStateSet |= accessibility::AccessibleStateType::SELECTABLE;
214 nStateSet |= accessibility::AccessibleStateType::FOCUSABLE;
216 if( mpParent->mrParent.GetSelectedItemId() == mpParent->mnId )
219 nStateSet |= accessibility::AccessibleStateType::SELECTED;
220 if (mpParent->mrParent.HasChildFocus())
221 nStateSet |= accessibility::AccessibleStateType::FOCUSED;
225 return nStateSet;
229 lang::Locale SAL_CALL ValueItemAcc::getLocale()
231 const SolarMutexGuard aSolarGuard;
232 uno::Reference< accessibility::XAccessible > xParent( getAccessibleParent() );
233 lang::Locale aRet( "", "", "" );
235 if( xParent.is() )
237 uno::Reference< accessibility::XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
239 if( xParentContext.is() )
240 aRet = xParentContext->getLocale();
243 return aRet;
247 void SAL_CALL ValueItemAcc::addAccessibleEventListener( const uno::Reference< accessibility::XAccessibleEventListener >& rxListener )
249 std::scoped_lock aGuard( maMutex );
251 if( !rxListener.is() )
252 return;
254 bool bFound = false;
256 for (auto const& eventListener : mxEventListeners)
258 if(eventListener == rxListener)
260 bFound = true;
261 break;
265 if (!bFound)
266 mxEventListeners.push_back( rxListener );
270 void SAL_CALL ValueItemAcc::removeAccessibleEventListener( const uno::Reference< accessibility::XAccessibleEventListener >& rxListener )
272 std::scoped_lock aGuard( maMutex );
274 if( rxListener.is() )
276 ::std::vector< uno::Reference< accessibility::XAccessibleEventListener > >::iterator aIter =
277 std::find(mxEventListeners.begin(), mxEventListeners.end(), rxListener);
279 if (aIter != mxEventListeners.end())
280 mxEventListeners.erase(aIter);
285 sal_Bool SAL_CALL ValueItemAcc::containsPoint( const awt::Point& aPoint )
287 const awt::Rectangle aRect( getBounds() );
288 const Point aSize( aRect.Width, aRect.Height );
289 const Point aNullPoint, aTestPoint( aPoint.X, aPoint.Y );
291 return tools::Rectangle( aNullPoint, aSize ).Contains( aTestPoint );
294 uno::Reference< accessibility::XAccessible > SAL_CALL ValueItemAcc::getAccessibleAtPoint( const awt::Point& )
296 uno::Reference< accessibility::XAccessible > xRet;
297 return xRet;
300 awt::Rectangle SAL_CALL ValueItemAcc::getBounds()
302 const SolarMutexGuard aSolarGuard;
303 awt::Rectangle aRet;
305 if( mpParent )
307 tools::Rectangle aRect( mpParent->mrParent.GetItemRect(mpParent->mnId) );
308 tools::Rectangle aParentRect( Point(), mpParent->mrParent.GetOutputSizePixel() );
310 aRect.Intersection( aParentRect );
312 aRet.X = aRect.Left();
313 aRet.Y = aRect.Top();
314 aRet.Width = aRect.GetWidth();
315 aRet.Height = aRect.GetHeight();
318 return aRet;
321 awt::Point SAL_CALL ValueItemAcc::getLocation()
323 const awt::Rectangle aRect( getBounds() );
324 awt::Point aRet;
326 aRet.X = aRect.X;
327 aRet.Y = aRect.Y;
329 return aRet;
332 awt::Point SAL_CALL ValueItemAcc::getLocationOnScreen()
334 const SolarMutexGuard aSolarGuard;
335 awt::Point aRet;
337 if( mpParent )
339 const Point aPos = mpParent->mrParent.GetItemRect(mpParent->mnId).TopLeft();
340 const Point aScreenPos(mpParent->mrParent.GetDrawingArea()->get_accessible_location_on_screen());
342 aRet.X = aPos.X() + aScreenPos.X();
343 aRet.Y = aPos.Y() + aScreenPos.Y();
346 return aRet;
349 awt::Size SAL_CALL ValueItemAcc::getSize()
351 const awt::Rectangle aRect( getBounds() );
352 awt::Size aRet;
354 aRet.Width = aRect.Width;
355 aRet.Height = aRect.Height;
357 return aRet;
360 void SAL_CALL ValueItemAcc::grabFocus()
362 // nothing to do
365 sal_Int32 SAL_CALL ValueItemAcc::getForeground( )
367 Color nColor = Application::GetSettings().GetStyleSettings().GetWindowTextColor();
368 return static_cast<sal_Int32>(nColor);
371 sal_Int32 SAL_CALL ValueItemAcc::getBackground( )
373 Color nColor;
374 if (mpParent && mpParent->meType == VALUESETITEM_COLOR)
375 nColor = mpParent->maColor;
376 else
377 nColor = Application::GetSettings().GetStyleSettings().GetWindowColor();
378 return static_cast<sal_Int32>(nColor);
381 void ValueItemAcc::FireAccessibleEvent( short nEventId, const uno::Any& rOldValue, const uno::Any& rNewValue )
383 if( !nEventId )
384 return;
386 ::std::vector< uno::Reference< accessibility::XAccessibleEventListener > > aTmpListeners( mxEventListeners );
387 accessibility::AccessibleEventObject aEvtObject;
389 aEvtObject.EventId = nEventId;
390 aEvtObject.Source = getXWeak();
391 aEvtObject.NewValue = rNewValue;
392 aEvtObject.OldValue = rOldValue;
394 for (auto const& tmpListener : aTmpListeners)
396 tmpListener->notifyEvent( aEvtObject );
400 ValueSetAcc::ValueSetAcc( ValueSet* pParent ) :
401 mpParent( pParent ),
402 mbIsFocused(false)
407 ValueSetAcc::~ValueSetAcc()
412 void ValueSetAcc::FireAccessibleEvent( short nEventId, const uno::Any& rOldValue, const uno::Any& rNewValue )
414 if( !nEventId )
415 return;
417 ::std::vector< uno::Reference< accessibility::XAccessibleEventListener > > aTmpListeners( mxEventListeners );
418 accessibility::AccessibleEventObject aEvtObject;
420 aEvtObject.EventId = nEventId;
421 aEvtObject.Source = getXWeak();
422 aEvtObject.NewValue = rNewValue;
423 aEvtObject.OldValue = rOldValue;
424 aEvtObject.IndexHint = -1;
426 for (auto const& tmpListener : aTmpListeners)
430 tmpListener->notifyEvent( aEvtObject );
432 catch(const uno::Exception&)
438 ValueSetAcc* ValueSetAcc::getImplementation( const uno::Reference< uno::XInterface >& rxData )
439 noexcept
441 return dynamic_cast<ValueSetAcc*>(rxData.get());
445 void ValueSetAcc::GetFocus()
447 mbIsFocused = true;
449 // Broadcast the state change.
450 css::uno::Any aOldState, aNewState;
451 aNewState <<= css::accessibility::AccessibleStateType::FOCUSED;
452 FireAccessibleEvent(
453 css::accessibility::AccessibleEventId::STATE_CHANGED,
454 aOldState, aNewState);
458 void ValueSetAcc::LoseFocus()
460 mbIsFocused = false;
462 // Broadcast the state change.
463 css::uno::Any aOldState, aNewState;
464 aOldState <<= css::accessibility::AccessibleStateType::FOCUSED;
465 FireAccessibleEvent(
466 css::accessibility::AccessibleEventId::STATE_CHANGED,
467 aOldState, aNewState);
471 uno::Reference< accessibility::XAccessibleContext > SAL_CALL ValueSetAcc::getAccessibleContext()
473 ThrowIfDisposed();
474 return this;
478 sal_Int64 SAL_CALL ValueSetAcc::getAccessibleChildCount()
480 const SolarMutexGuard aSolarGuard;
481 ThrowIfDisposed();
483 sal_Int64 nCount = mpParent->ImplGetVisibleItemCount();
484 if (HasNoneField())
485 nCount += 1;
486 return nCount;
490 uno::Reference< accessibility::XAccessible > SAL_CALL ValueSetAcc::getAccessibleChild( sal_Int64 i )
492 ThrowIfDisposed();
493 const SolarMutexGuard aSolarGuard;
495 if (i < 0 || i >= getAccessibleChildCount())
496 throw lang::IndexOutOfBoundsException();
498 ValueSetItem* pItem = getItem (sal::static_int_cast< sal_uInt16 >(i));
500 if( !pItem )
501 throw lang::IndexOutOfBoundsException();
503 uno::Reference< accessibility::XAccessible > xRet = pItem->GetAccessible( false/*bIsTransientChildrenDisabled*/ );
504 return xRet;
507 uno::Reference< accessibility::XAccessible > SAL_CALL ValueSetAcc::getAccessibleParent()
509 ThrowIfDisposed();
510 const SolarMutexGuard aSolarGuard;
511 return mpParent->GetDrawingArea()->get_accessible_parent();
514 sal_Int64 SAL_CALL ValueSetAcc::getAccessibleIndexInParent()
516 ThrowIfDisposed();
517 const SolarMutexGuard aSolarGuard;
519 // -1 for child not found/no parent (according to specification)
520 sal_Int64 nRet = -1;
522 uno::Reference<accessibility::XAccessible> xParent(getAccessibleParent());
523 if (!xParent)
524 return nRet;
528 uno::Reference<accessibility::XAccessibleContext> xParentContext(xParent->getAccessibleContext());
530 // iterate over parent's children and search for this object
531 if ( xParentContext.is() )
533 sal_Int64 nChildCount = xParentContext->getAccessibleChildCount();
534 for ( sal_Int64 nChild = 0; ( nChild < nChildCount ) && ( -1 == nRet ); ++nChild )
536 uno::Reference<XAccessible> xChild(xParentContext->getAccessibleChild(nChild));
537 if ( xChild.get() == this )
538 nRet = nChild;
542 catch (const uno::Exception&)
544 TOOLS_WARN_EXCEPTION( "svtools", "ValueSetAcc::getAccessibleIndexInParent" );
547 return nRet;
550 sal_Int16 SAL_CALL ValueSetAcc::getAccessibleRole()
552 ThrowIfDisposed();
553 return accessibility::AccessibleRole::LIST;
557 OUString SAL_CALL ValueSetAcc::getAccessibleDescription()
559 ThrowIfDisposed();
560 const SolarMutexGuard aSolarGuard;
561 OUString aRet;
563 if (mpParent)
565 aRet = mpParent->GetAccessibleDescription();
568 return aRet;
572 OUString SAL_CALL ValueSetAcc::getAccessibleName()
574 ThrowIfDisposed();
575 const SolarMutexGuard aSolarGuard;
576 OUString aRet;
578 if (mpParent)
580 aRet = mpParent->GetAccessibleName();
583 return aRet;
586 uno::Reference< accessibility::XAccessibleRelationSet > SAL_CALL ValueSetAcc::getAccessibleRelationSet()
588 ThrowIfDisposed();
589 SolarMutexGuard g;
590 return mpParent->GetDrawingArea()->get_accessible_relation_set();
593 sal_Int64 SAL_CALL ValueSetAcc::getAccessibleStateSet()
595 ThrowIfDisposed();
596 sal_Int64 nStateSet = 0;
598 // Set some states.
599 nStateSet |= accessibility::AccessibleStateType::ENABLED;
600 nStateSet |= accessibility::AccessibleStateType::SENSITIVE;
601 nStateSet |= accessibility::AccessibleStateType::SHOWING;
602 nStateSet |= accessibility::AccessibleStateType::VISIBLE;
603 nStateSet |= accessibility::AccessibleStateType::MANAGES_DESCENDANTS;
604 nStateSet |= accessibility::AccessibleStateType::FOCUSABLE;
605 if (mbIsFocused)
606 nStateSet |= accessibility::AccessibleStateType::FOCUSED;
608 return nStateSet;
612 lang::Locale SAL_CALL ValueSetAcc::getLocale()
614 ThrowIfDisposed();
615 const SolarMutexGuard aSolarGuard;
616 uno::Reference< accessibility::XAccessible > xParent( getAccessibleParent() );
617 lang::Locale aRet( "", "", "" );
619 if( xParent.is() )
621 uno::Reference< accessibility::XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
623 if( xParentContext.is() )
624 aRet = xParentContext->getLocale ();
627 return aRet;
631 void SAL_CALL ValueSetAcc::addAccessibleEventListener( const uno::Reference< accessibility::XAccessibleEventListener >& rxListener )
633 ThrowIfDisposed();
634 std::unique_lock aGuard (m_aMutex);
636 if( !rxListener.is() )
637 return;
639 bool bFound = false;
641 for (auto const& eventListener : mxEventListeners)
643 if(eventListener == rxListener)
645 bFound = true;
646 break;
650 if (!bFound)
651 mxEventListeners.push_back( rxListener );
655 void SAL_CALL ValueSetAcc::removeAccessibleEventListener( const uno::Reference< accessibility::XAccessibleEventListener >& rxListener )
657 ThrowIfDisposed();
658 std::unique_lock aGuard (m_aMutex);
660 if( rxListener.is() )
662 ::std::vector< uno::Reference< accessibility::XAccessibleEventListener > >::iterator aIter =
663 std::find(mxEventListeners.begin(), mxEventListeners.end(), rxListener);
665 if (aIter != mxEventListeners.end())
666 mxEventListeners.erase(aIter);
671 sal_Bool SAL_CALL ValueSetAcc::containsPoint( const awt::Point& aPoint )
673 ThrowIfDisposed();
674 const awt::Rectangle aRect( getBounds() );
675 const Point aSize( aRect.Width, aRect.Height );
676 const Point aNullPoint, aTestPoint( aPoint.X, aPoint.Y );
678 return tools::Rectangle( aNullPoint, aSize ).Contains( aTestPoint );
682 uno::Reference< accessibility::XAccessible > SAL_CALL ValueSetAcc::getAccessibleAtPoint( const awt::Point& aPoint )
684 ThrowIfDisposed();
685 const SolarMutexGuard aSolarGuard;
686 const sal_uInt16 nItemId = mpParent->GetItemId( Point( aPoint.X, aPoint.Y ) );
687 uno::Reference< accessibility::XAccessible > xRet;
689 if ( nItemId )
691 const size_t nItemPos = mpParent->GetItemPos( nItemId );
693 if( VALUESET_ITEM_NONEITEM != nItemPos )
695 ValueSetItem *const pItem = mpParent->mItemList[nItemPos].get();
696 xRet = pItem->GetAccessible( false/*bIsTransientChildrenDisabled*/ );
700 return xRet;
704 awt::Rectangle SAL_CALL ValueSetAcc::getBounds()
706 ThrowIfDisposed();
707 const SolarMutexGuard aSolarGuard;
708 const Point aOutPos;
709 const Size aOutSize( mpParent->GetOutputSizePixel() );
710 awt::Rectangle aRet;
712 aRet.X = aOutPos.X();
713 aRet.Y = aOutPos.Y();
714 aRet.Width = aOutSize.Width();
715 aRet.Height = aOutSize.Height();
717 return aRet;
720 awt::Point SAL_CALL ValueSetAcc::getLocation()
722 ThrowIfDisposed();
723 const awt::Rectangle aRect( getBounds() );
724 awt::Point aRet;
726 aRet.X = aRect.X;
727 aRet.Y = aRect.Y;
729 return aRet;
732 awt::Point SAL_CALL ValueSetAcc::getLocationOnScreen()
734 ThrowIfDisposed();
735 const SolarMutexGuard aSolarGuard;
736 awt::Point aScreenLoc(0, 0);
738 uno::Reference<accessibility::XAccessible> xParent(getAccessibleParent());
739 if (xParent)
741 uno::Reference<accessibility::XAccessibleContext> xParentContext(xParent->getAccessibleContext());
742 uno::Reference<accessibility::XAccessibleComponent> xParentComponent(xParentContext, css::uno::UNO_QUERY);
743 OSL_ENSURE( xParentComponent.is(), "ValueSetAcc::getLocationOnScreen: no parent component!" );
744 if ( xParentComponent.is() )
746 awt::Point aParentScreenLoc( xParentComponent->getLocationOnScreen() );
747 awt::Point aOwnRelativeLoc( getLocation() );
748 aScreenLoc.X = aParentScreenLoc.X + aOwnRelativeLoc.X;
749 aScreenLoc.Y = aParentScreenLoc.Y + aOwnRelativeLoc.Y;
753 return aScreenLoc;
756 awt::Size SAL_CALL ValueSetAcc::getSize()
758 ThrowIfDisposed();
759 const awt::Rectangle aRect( getBounds() );
760 awt::Size aRet;
762 aRet.Width = aRect.Width;
763 aRet.Height = aRect.Height;
765 return aRet;
768 void SAL_CALL ValueSetAcc::grabFocus()
770 ThrowIfDisposed();
771 const SolarMutexGuard aSolarGuard;
772 mpParent->GrabFocus();
775 sal_Int32 SAL_CALL ValueSetAcc::getForeground( )
777 ThrowIfDisposed();
778 Color nColor = Application::GetSettings().GetStyleSettings().GetWindowTextColor();
779 return static_cast<sal_Int32>(nColor);
782 sal_Int32 SAL_CALL ValueSetAcc::getBackground( )
784 ThrowIfDisposed();
785 Color nColor = Application::GetSettings().GetStyleSettings().GetWindowColor();
786 return static_cast<sal_Int32>(nColor);
789 void SAL_CALL ValueSetAcc::selectAccessibleChild( sal_Int64 nChildIndex )
791 ThrowIfDisposed();
792 const SolarMutexGuard aSolarGuard;
794 if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount())
795 throw lang::IndexOutOfBoundsException();
797 ValueSetItem* pItem = getItem (sal::static_int_cast< sal_uInt16 >(nChildIndex));
799 if(pItem == nullptr)
800 throw lang::IndexOutOfBoundsException();
802 mpParent->SelectItem( pItem->mnId );
806 sal_Bool SAL_CALL ValueSetAcc::isAccessibleChildSelected( sal_Int64 nChildIndex )
808 ThrowIfDisposed();
809 const SolarMutexGuard aSolarGuard;
811 if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount())
812 throw lang::IndexOutOfBoundsException();
814 ValueSetItem* pItem = getItem (sal::static_int_cast< sal_uInt16 >(nChildIndex));
816 if (pItem == nullptr)
817 throw lang::IndexOutOfBoundsException();
819 bool bRet = mpParent->IsItemSelected( pItem->mnId );
820 return bRet;
824 void SAL_CALL ValueSetAcc::clearAccessibleSelection()
826 ThrowIfDisposed();
827 const SolarMutexGuard aSolarGuard;
828 mpParent->SetNoSelection();
832 void SAL_CALL ValueSetAcc::selectAllAccessibleChildren()
834 ThrowIfDisposed();
835 // unsupported due to single selection only
839 sal_Int64 SAL_CALL ValueSetAcc::getSelectedAccessibleChildCount()
841 ThrowIfDisposed();
842 const SolarMutexGuard aSolarGuard;
843 sal_Int64 nRet = 0;
845 for( sal_uInt16 i = 0, nCount = getItemCount(); i < nCount; i++ )
847 ValueSetItem* pItem = getItem (i);
849 if( pItem && mpParent->IsItemSelected( pItem->mnId ) )
850 ++nRet;
853 return nRet;
857 uno::Reference< accessibility::XAccessible > SAL_CALL ValueSetAcc::getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex )
859 ThrowIfDisposed();
860 const SolarMutexGuard aSolarGuard;
861 uno::Reference< accessibility::XAccessible > xRet;
863 for( sal_uInt16 i = 0, nCount = getItemCount(), nSel = 0; ( i < nCount ) && !xRet.is(); i++ )
865 ValueSetItem* pItem = getItem(i);
867 if( pItem && mpParent->IsItemSelected( pItem->mnId ) && ( nSelectedChildIndex == static_cast< sal_Int64 >( nSel++ ) ) )
868 xRet = pItem->GetAccessible( false/*bIsTransientChildrenDisabled*/ );
871 return xRet;
875 void SAL_CALL ValueSetAcc::deselectAccessibleChild( sal_Int64 nChildIndex )
877 ThrowIfDisposed();
878 const SolarMutexGuard aSolarGuard;
880 if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount())
881 throw lang::IndexOutOfBoundsException();
883 // Because of the single selection we can reset the whole selection when
884 // the specified child is currently selected.
885 if (isAccessibleChildSelected(nChildIndex))
886 mpParent->SetNoSelection();
890 void ValueSetAcc::disposing(std::unique_lock<std::mutex>& rGuard)
892 // Make a copy of the list and clear the original.
893 ::std::vector<uno::Reference<accessibility::XAccessibleEventListener> > aListenerListCopy = std::move(mxEventListeners);
895 // Reset the pointer to the parent. It has to be the one who has
896 // disposed us because he is dying.
897 mpParent = nullptr;
899 if (aListenerListCopy.empty())
900 return;
902 rGuard.unlock();
903 // Inform all listeners that this objects is disposing.
904 lang::EventObject aEvent (static_cast<accessibility::XAccessible*>(this));
905 for (auto const& listenerCopy : aListenerListCopy)
909 listenerCopy->disposing (aEvent);
911 catch(const uno::Exception&)
913 // Ignore exceptions.
919 sal_uInt16 ValueSetAcc::getItemCount() const
921 sal_uInt16 nCount = mpParent->ImplGetVisibleItemCount();
922 // When the None-Item is visible then increase the number of items by
923 // one.
924 if (HasNoneField())
925 nCount += 1;
926 return nCount;
929 ValueSetItem* ValueSetAcc::getItem (sal_uInt16 nIndex) const
931 ValueSetItem* pItem = nullptr;
933 if (HasNoneField())
935 if (nIndex == 0)
936 // When present the first item is the then always visible none field.
937 pItem = mpParent->ImplGetItem (VALUESET_ITEM_NONEITEM);
938 else
939 // Shift down the index to compensate for the none field.
940 nIndex -= 1;
942 if (pItem == nullptr)
943 pItem = mpParent->ImplGetItem (nIndex);
945 return pItem;
949 void ValueSetAcc::ThrowIfDisposed()
951 if (m_bDisposed)
953 SAL_WARN("svx", "Calling disposed object. Throwing exception:");
954 throw lang::DisposedException (
955 "object has been already disposed",
956 getXWeak());
958 else
960 DBG_ASSERT (mpParent!=nullptr, "ValueSetAcc not disposed but mpParent == NULL");
964 bool ValueSetAcc::HasNoneField() const
966 assert(mpParent && "ValueSetAcc::HasNoneField called with mpParent==NULL");
967 return ((mpParent->GetStyle() & WB_NONEFIELD) != 0);
970 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */