1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svtools.hxx"
26 
27 #define _SV_VALUESET_CXX
28 
29 #include <unotools/accessiblestatesethelper.hxx>
30 #include <vcl/svapp.hxx>
31 #include <svtools/valueset.hxx>
32 #include "valueimp.hxx"
33 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
34 #include <com/sun/star/accessibility/AccessibleRole.hpp>
35 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
36 
37 //IAccessibility2 Implementation 2009-----
38 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
39 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLERELATIONTYPE_HPP_
40 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
41 #endif
42 #ifndef _UTL_ACCESSIBLERELATIONSETHELPER_HXX_
43 #include <unotools/accessiblerelationsethelper.hxx>
44 #endif
45 //-----IAccessibility2 Implementation 2009
46 using namespace ::com::sun::star;
47 
48 // ----------------
49 // - ValueSetItem -
50 // ----------------
51 
52 ValueSetItem::ValueSetItem( ValueSet& rParent ) :
53     mrParent( rParent ),
54     mnId( 0 ),
55 	mnBits( 0 ),
56 	mpData( NULL ),
57     mpxAcc( NULL )
58 {
59 }
60 
61 // -----------------------------------------------------------------------
62 
63 ValueSetItem::~ValueSetItem()
64 {
65     if( mpxAcc )
66     {
67         static_cast< ValueItemAcc* >( mpxAcc->get() )->ParentDestroyed();
68         delete mpxAcc;
69     }
70 }
71 
72 // -----------------------------------------------------------------------
73 
74 uno::Reference< accessibility::XAccessible > ValueSetItem::GetAccessible( bool bIsTransientChildrenDisabled )
75 {
76     if( !mpxAcc )
77         mpxAcc = new uno::Reference< accessibility::XAccessible >( new ValueItemAcc( this, bIsTransientChildrenDisabled ) );
78 
79     return *mpxAcc;
80 }
81 
82 // -----------------------------------------------------------------------
83 
84 void ValueSetItem::ClearAccessible()
85 {
86     if( mpxAcc )
87         delete mpxAcc, mpxAcc = NULL;
88 }
89 
90 
91 // ---------------
92 // - ValueSetAcc -
93 // ---------------
94 
95 ValueSetAcc::ValueSetAcc( ValueSet* pParent, bool bIsTransientChildrenDisabled ) :
96     ValueSetAccComponentBase (m_aMutex),
97     mpParent( pParent ),
98     mbIsTransientChildrenDisabled( bIsTransientChildrenDisabled ),
99     mbIsFocused(false)
100 {
101 }
102 
103 // -----------------------------------------------------------------------------
104 
105 ValueSetAcc::~ValueSetAcc()
106 {
107 }
108 
109 // -----------------------------------------------------------------------
110 
111 void ValueSetAcc::FireAccessibleEvent( short nEventId, const uno::Any& rOldValue, const uno::Any& rNewValue )
112 {
113     if( nEventId )
114     {
115         ::std::vector< uno::Reference< accessibility::XAccessibleEventListener > >                  aTmpListeners( mxEventListeners );
116         ::std::vector< uno::Reference< accessibility::XAccessibleEventListener > >::const_iterator  aIter( aTmpListeners.begin() );
117         accessibility::AccessibleEventObject                                                        aEvtObject;
118 
119         aEvtObject.EventId = nEventId;
120         aEvtObject.Source = static_cast<uno::XWeak*>(this);
121         aEvtObject.NewValue = rNewValue;
122 	    aEvtObject.OldValue = rOldValue;
123 
124 		while( aIter != aTmpListeners.end() )
125         {
126 			try
127 			{
128 				(*aIter)->notifyEvent( aEvtObject );
129 			}
130 			catch( uno::Exception& )
131 			{
132 			}
133 
134             aIter++;
135         }
136     }
137 }
138 
139 // -----------------------------------------------------------------------------
140 
141 const uno::Sequence< sal_Int8 >& ValueSetAcc::getUnoTunnelId()
142 {
143     static uno::Sequence< sal_Int8 > aSeq;
144 
145 	if( !aSeq.getLength() )
146 	{
147 		static osl::Mutex           aCreateMutex;
148     	osl::Guard< osl::Mutex >    aGuard( aCreateMutex );
149 
150 		aSeq.realloc( 16 );
151     	rtl_createUuid( reinterpret_cast< sal_uInt8* >( aSeq.getArray() ), 0, sal_True );
152 	}
153 
154     return aSeq;
155 }
156 
157 // -----------------------------------------------------------------------------
158 
159 ValueSetAcc* ValueSetAcc::getImplementation( const uno::Reference< uno::XInterface >& rxData )
160     throw()
161 {
162     try
163     {
164 	    uno::Reference< lang::XUnoTunnel > xUnoTunnel( rxData, uno::UNO_QUERY );
165         return( xUnoTunnel.is() ? reinterpret_cast<ValueSetAcc*>(sal::static_int_cast<sal_IntPtr>(xUnoTunnel->getSomething( ValueSetAcc::getUnoTunnelId() ))) : NULL );
166     }
167     catch( const ::com::sun::star::uno::Exception& )
168 	{
169         return NULL;
170 	}
171 }
172 
173 
174 // -----------------------------------------------------------------------------
175 
176 void ValueSetAcc::GetFocus (void)
177 {
178     mbIsFocused = true;
179 
180     // Boradcast the state change.
181     ::com::sun::star::uno::Any aOldState, aNewState;
182     aNewState <<= ::com::sun::star::accessibility::AccessibleStateType::FOCUSED;
183     FireAccessibleEvent(
184         ::com::sun::star::accessibility::AccessibleEventId::STATE_CHANGED,
185         aOldState, aNewState);
186 }
187 
188 // -----------------------------------------------------------------------------
189 
190 void ValueSetAcc::LoseFocus (void)
191 {
192     mbIsFocused = false;
193 
194     // Boradcast the state change.
195     ::com::sun::star::uno::Any aOldState, aNewState;
196     aOldState <<= ::com::sun::star::accessibility::AccessibleStateType::FOCUSED;
197     FireAccessibleEvent(
198         ::com::sun::star::accessibility::AccessibleEventId::STATE_CHANGED,
199         aOldState, aNewState);
200 }
201 
202 // -----------------------------------------------------------------------------
203 
204 uno::Reference< accessibility::XAccessibleContext > SAL_CALL ValueSetAcc::getAccessibleContext()
205     throw (uno::RuntimeException)
206 {
207     ThrowIfDisposed();
208     return this;
209 }
210 
211 // -----------------------------------------------------------------------------
212 
213 sal_Int32 SAL_CALL ValueSetAcc::getAccessibleChildCount()
214     throw (uno::RuntimeException)
215 {
216     const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
217     ThrowIfDisposed();
218 
219     sal_Int32 nCount = mpParent->ImplGetVisibleItemCount();
220     if (HasNoneField())
221         nCount += 1;
222     return nCount;
223 }
224 
225 // -----------------------------------------------------------------------------
226 
227 uno::Reference< accessibility::XAccessible > SAL_CALL ValueSetAcc::getAccessibleChild( sal_Int32 i )
228     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
229 {
230     ThrowIfDisposed();
231     const vos::OGuard                               aSolarGuard( Application::GetSolarMutex() );
232     uno::Reference< accessibility::XAccessible >    xRet;
233     ValueSetItem* pItem = getItem (sal::static_int_cast< sal_uInt16 >(i));
234 
235     if( pItem )
236         xRet = pItem->GetAccessible( mbIsTransientChildrenDisabled );
237     else
238         throw lang::IndexOutOfBoundsException();
239 
240     return xRet;
241 }
242 
243 // -----------------------------------------------------------------------------
244 
245 uno::Reference< accessibility::XAccessible > SAL_CALL ValueSetAcc::getAccessibleParent()
246     throw (uno::RuntimeException)
247 {
248     ThrowIfDisposed();
249     const vos::OGuard                               aSolarGuard( Application::GetSolarMutex() );
250     Window*                                         pParent = mpParent->GetParent();
251     uno::Reference< accessibility::XAccessible >    xRet;
252 
253     if( pParent )
254         xRet = pParent->GetAccessible();
255 
256     return xRet;
257 }
258 
259 // -----------------------------------------------------------------------------
260 
261 sal_Int32 SAL_CALL ValueSetAcc::getAccessibleIndexInParent()
262     throw (uno::RuntimeException)
263 {
264     ThrowIfDisposed();
265     const vos::OGuard       aSolarGuard( Application::GetSolarMutex() );
266     Window*                 pParent = mpParent->GetParent();
267     sal_Int32               nRet = 0;
268 
269     if( pParent )
270     {
271         sal_Bool bFound = sal_False;
272 
273         for( sal_uInt16 i = 0, nCount = pParent->GetChildCount(); ( i < nCount ) && !bFound; i++ )
274         {
275             if( pParent->GetChild( i ) == mpParent )
276             {
277                 nRet = i;
278                 bFound = sal_True;
279             }
280         }
281     }
282 
283     return nRet;
284 }
285 
286 // -----------------------------------------------------------------------------
287 
288 sal_Int16 SAL_CALL ValueSetAcc::getAccessibleRole()
289     throw (uno::RuntimeException)
290 {
291     ThrowIfDisposed();
292     // #i73746# As the Java Access Bridge (v 2.0.1) uses "managesDescendants"
293     // always if the role is LIST, we need a different role in this case
294     return (mbIsTransientChildrenDisabled
295             ? accessibility::AccessibleRole::PANEL
296             : accessibility::AccessibleRole::LIST );
297 }
298 
299 // -----------------------------------------------------------------------------
300 
301 ::rtl::OUString SAL_CALL ValueSetAcc::getAccessibleDescription()
302     throw (uno::RuntimeException)
303 {
304     ThrowIfDisposed();
305     const vos::OGuard   aSolarGuard( Application::GetSolarMutex() );
306     String              aRet( RTL_CONSTASCII_USTRINGPARAM( "ValueSet" ) );
307 
308     return aRet;
309 }
310 
311 // -----------------------------------------------------------------------------
312 
313 ::rtl::OUString SAL_CALL ValueSetAcc::getAccessibleName()
314     throw (uno::RuntimeException)
315 {
316     ThrowIfDisposed();
317     const vos::OGuard   aSolarGuard( Application::GetSolarMutex() );
318     String              aRet;
319 
320     if ( mpParent )
321         aRet = mpParent->GetAccessibleName();
322 
323     if ( !aRet.Len() )
324     {
325         Window* pLabel = mpParent->GetAccessibleRelationLabeledBy();
326         if ( pLabel && pLabel != mpParent )
327             aRet = OutputDevice::GetNonMnemonicString( pLabel->GetText() );
328 
329         if ( !aRet.Len() )
330          	aRet = mpParent->GetQuickHelpText();
331     }
332 
333     return aRet;
334 }
335 
336 // -----------------------------------------------------------------------------
337 
338 uno::Reference< accessibility::XAccessibleRelationSet > SAL_CALL ValueSetAcc::getAccessibleRelationSet()
339     throw (uno::RuntimeException)
340 {
341     ThrowIfDisposed();
342 //IAccessibility2 Implementation 2009-----
343 	uno::Reference< accessibility::XAccessibleRelationSet > xRelSet;
344 	Window* pWindow = (Window*)mpParent;
345 	if ( pWindow )
346 	{
347 		utl::AccessibleRelationSetHelper* pRelationSet = new utl::AccessibleRelationSetHelper;
348 		xRelSet = pRelationSet;
349 
350 		Window *pLabeledBy = pWindow->GetAccessibleRelationLabeledBy();
351 		if ( pLabeledBy && pLabeledBy != pWindow )
352 		{
353 			uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1);
354 			aSequence[0] = pLabeledBy->GetAccessible();
355 			pRelationSet->AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::LABELED_BY, aSequence ) );
356 		}
357 
358 		Window* pMemberOf = pWindow->GetAccessibleRelationMemberOf();
359 		if ( pMemberOf && pMemberOf != pWindow )
360 		{
361 			uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1);
362 			aSequence[0] = pMemberOf->GetAccessible();
363 			pRelationSet->AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::MEMBER_OF, aSequence ) );
364 		}
365 	}
366     return xRelSet;
367 //-----IAccessibility2 Implementation 2009
368 }
369 
370 // -----------------------------------------------------------------------------
371 
372 uno::Reference< accessibility::XAccessibleStateSet > SAL_CALL ValueSetAcc::getAccessibleStateSet()
373     throw (uno::RuntimeException)
374 {
375     ThrowIfDisposed();
376     ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper();
377 
378     // Set some states.
379     pStateSet->AddState (accessibility::AccessibleStateType::ENABLED);
380     pStateSet->AddState (accessibility::AccessibleStateType::SENSITIVE);
381     pStateSet->AddState (accessibility::AccessibleStateType::SHOWING);
382     pStateSet->AddState (accessibility::AccessibleStateType::VISIBLE);
383     if ( !mbIsTransientChildrenDisabled )
384         pStateSet->AddState (accessibility::AccessibleStateType::MANAGES_DESCENDANTS);
385     pStateSet->AddState (accessibility::AccessibleStateType::FOCUSABLE);
386     if (mbIsFocused)
387         pStateSet->AddState (accessibility::AccessibleStateType::FOCUSED);
388 
389     return pStateSet;
390 }
391 
392 // -----------------------------------------------------------------------------
393 
394 lang::Locale SAL_CALL ValueSetAcc::getLocale()
395     throw (accessibility::IllegalAccessibleComponentStateException, uno::RuntimeException)
396 {
397     ThrowIfDisposed();
398     const vos::OGuard                               aSolarGuard( Application::GetSolarMutex() );
399     const ::rtl::OUString                           aEmptyStr;
400     uno::Reference< accessibility::XAccessible >    xParent( getAccessibleParent() );
401     lang::Locale                                    aRet( aEmptyStr, aEmptyStr, aEmptyStr );
402 
403     if( xParent.is() )
404     {
405         uno::Reference< accessibility::XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
406 
407         if( xParentContext.is() )
408             aRet = xParentContext->getLocale ();
409     }
410 
411     return aRet;
412 }
413 
414 // -----------------------------------------------------------------------------
415 
416 void SAL_CALL ValueSetAcc::addEventListener( const uno::Reference< accessibility::XAccessibleEventListener >& rxListener )
417     throw (uno::RuntimeException)
418 {
419     ThrowIfDisposed();
420     ::osl::MutexGuard aGuard (m_aMutex);
421 
422 	if( rxListener.is() )
423     {
424        	::std::vector< uno::Reference< accessibility::XAccessibleEventListener > >::const_iterator aIter = mxEventListeners.begin();
425 		sal_Bool bFound = sal_False;
426 
427 		while( !bFound && ( aIter != mxEventListeners.end() ) )
428         {
429 			if( *aIter == rxListener )
430                 bFound = sal_True;
431             else
432                 aIter++;
433         }
434 
435 		if (!bFound)
436             mxEventListeners.push_back( rxListener );
437     }
438 }
439 
440 // -----------------------------------------------------------------------------
441 
442 void SAL_CALL ValueSetAcc::removeEventListener( const uno::Reference< accessibility::XAccessibleEventListener >& rxListener )
443     throw (uno::RuntimeException)
444 {
445     ThrowIfDisposed();
446     ::osl::MutexGuard aGuard (m_aMutex);
447 
448 	if( rxListener.is() )
449     {
450        	::std::vector< uno::Reference< accessibility::XAccessibleEventListener > >::iterator aIter = mxEventListeners.begin();
451 		sal_Bool bFound = sal_False;
452 
453 		while( !bFound && ( aIter != mxEventListeners.end() ) )
454         {
455 			if( *aIter == rxListener )
456             {
457                 mxEventListeners.erase( aIter );
458                 bFound = sal_True;
459             }
460             else
461                 aIter++;
462         }
463     }
464 }
465 
466 // -----------------------------------------------------------------------------
467 
468 sal_Bool SAL_CALL ValueSetAcc::containsPoint( const awt::Point& aPoint )
469     throw (uno::RuntimeException)
470 {
471     ThrowIfDisposed();
472     const awt::Rectangle    aRect( getBounds() );
473     const Point             aSize( aRect.Width, aRect.Height );
474     const Point             aNullPoint, aTestPoint( aPoint.X, aPoint.Y );
475 
476     return Rectangle( aNullPoint, aSize ).IsInside( aTestPoint );
477 }
478 
479 // -----------------------------------------------------------------------------
480 
481 uno::Reference< accessibility::XAccessible > SAL_CALL ValueSetAcc::getAccessibleAtPoint( const awt::Point& aPoint )
482     throw (uno::RuntimeException)
483 {
484     ThrowIfDisposed();
485     const vos::OGuard                               aSolarGuard( Application::GetSolarMutex() );
486     const sal_uInt16                                    nItemId = mpParent->GetItemId( Point( aPoint.X, aPoint.Y ) );
487     uno::Reference< accessibility::XAccessible >    xRet;
488 
489     if( VALUESET_ITEM_NOTFOUND != nItemId )
490     {
491         const sal_uInt16 nItemPos = mpParent->GetItemPos( nItemId );
492 
493 	    if( VALUESET_ITEM_NONEITEM != nItemPos )
494         {
495             ValueSetItem* pItem = mpParent->mpImpl->mpItemList->GetObject( nItemPos );
496 
497             if( ( pItem->meType != VALUESETITEM_SPACE ) && !pItem->maRect.IsEmpty() )
498                xRet = pItem->GetAccessible( mbIsTransientChildrenDisabled );
499         }
500     }
501 
502     return xRet;
503 }
504 
505 // -----------------------------------------------------------------------------
506 
507 awt::Rectangle SAL_CALL ValueSetAcc::getBounds()
508     throw (uno::RuntimeException)
509 {
510     ThrowIfDisposed();
511     const vos::OGuard   aSolarGuard( Application::GetSolarMutex() );
512     const Point         aOutPos( mpParent->GetPosPixel() );
513     const Size          aOutSize( mpParent->GetOutputSizePixel() );
514     awt::Rectangle      aRet;
515 
516     aRet.X = aOutPos.X();
517     aRet.Y = aOutPos.Y();
518     aRet.Width = aOutSize.Width();
519     aRet.Height = aOutSize.Height();
520 
521     return aRet;
522 }
523 
524 // -----------------------------------------------------------------------------
525 
526 awt::Point SAL_CALL ValueSetAcc::getLocation()
527     throw (uno::RuntimeException)
528 {
529     ThrowIfDisposed();
530     const awt::Rectangle    aRect( getBounds() );
531     awt::Point              aRet;
532 
533     aRet.X = aRect.X;
534     aRet.Y = aRect.Y;
535 
536     return aRet;
537 }
538 
539 // -----------------------------------------------------------------------------
540 
541 awt::Point SAL_CALL ValueSetAcc::getLocationOnScreen()
542     throw (uno::RuntimeException)
543 {
544     ThrowIfDisposed();
545     const vos::OGuard   aSolarGuard( Application::GetSolarMutex() );
546     const Point         aScreenPos( mpParent->OutputToAbsoluteScreenPixel( Point() ) );
547     awt::Point          aRet;
548 
549     aRet.X = aScreenPos.X();
550     aRet.Y = aScreenPos.Y();
551 
552     return aRet;
553 }
554 
555 // -----------------------------------------------------------------------------
556 
557 awt::Size SAL_CALL ValueSetAcc::getSize()
558     throw (uno::RuntimeException)
559 {
560     ThrowIfDisposed();
561     const awt::Rectangle    aRect( getBounds() );
562     awt::Size               aRet;
563 
564     aRet.Width = aRect.Width;
565     aRet.Height = aRect.Height;
566 
567     return aRet;
568 }
569 
570 // -----------------------------------------------------------------------------
571 
572 void SAL_CALL ValueSetAcc::grabFocus()
573     throw (uno::RuntimeException)
574 {
575     ThrowIfDisposed();
576     const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
577     mpParent->GrabFocus();
578 }
579 
580 // -----------------------------------------------------------------------------
581 
582 uno::Any SAL_CALL ValueSetAcc::getAccessibleKeyBinding()
583     throw (uno::RuntimeException)
584 {
585     ThrowIfDisposed();
586     return uno::Any();
587 }
588 
589 // -----------------------------------------------------------------------------
590 
591 sal_Int32 SAL_CALL ValueSetAcc::getForeground(  )
592     throw (uno::RuntimeException)
593 {
594     ThrowIfDisposed();
595     sal_uInt32 nColor = Application::GetSettings().GetStyleSettings().GetWindowTextColor().GetColor();
596     return static_cast<sal_Int32>(nColor);
597 }
598 
599 // -----------------------------------------------------------------------------
600 
601 sal_Int32 SAL_CALL ValueSetAcc::getBackground(  )
602     throw (uno::RuntimeException)
603 {
604     ThrowIfDisposed();
605     sal_uInt32 nColor = Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor();
606     return static_cast<sal_Int32>(nColor);
607 }
608 
609 // -----------------------------------------------------------------------------
610 
611 void SAL_CALL ValueSetAcc::selectAccessibleChild( sal_Int32 nChildIndex )
612     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
613 {
614     ThrowIfDisposed();
615     const vos::OGuard   aSolarGuard( Application::GetSolarMutex() );
616     ValueSetItem* pItem = getItem (sal::static_int_cast< sal_uInt16 >(nChildIndex));
617 
618     if(pItem != NULL)
619     {
620         mpParent->SelectItem( pItem->mnId );
621         mpParent->Select ();
622     }
623     else
624         throw lang::IndexOutOfBoundsException();
625 }
626 
627 // -----------------------------------------------------------------------------
628 
629 sal_Bool SAL_CALL ValueSetAcc::isAccessibleChildSelected( sal_Int32 nChildIndex )
630     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
631 {
632     ThrowIfDisposed();
633     const vos::OGuard   aSolarGuard( Application::GetSolarMutex() );
634     ValueSetItem* pItem = getItem (sal::static_int_cast< sal_uInt16 >(nChildIndex));
635     sal_Bool            bRet = sal_False;
636 
637     if (pItem != NULL)
638         bRet = mpParent->IsItemSelected( pItem->mnId );
639     else
640         throw lang::IndexOutOfBoundsException();
641 
642     return bRet;
643 }
644 
645 // -----------------------------------------------------------------------------
646 
647 void SAL_CALL ValueSetAcc::clearAccessibleSelection()
648     throw (uno::RuntimeException)
649 {
650     ThrowIfDisposed();
651     const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
652     mpParent->SetNoSelection();
653 }
654 
655 // -----------------------------------------------------------------------------
656 
657 void SAL_CALL ValueSetAcc::selectAllAccessibleChildren()
658     throw (uno::RuntimeException)
659 {
660     ThrowIfDisposed();
661     // unsupported due to single selection only
662 }
663 
664 // -----------------------------------------------------------------------------
665 
666 sal_Int32 SAL_CALL ValueSetAcc::getSelectedAccessibleChildCount()
667     throw (uno::RuntimeException)
668 {
669     ThrowIfDisposed();
670     const vos::OGuard   aSolarGuard( Application::GetSolarMutex() );
671     sal_Int32           nRet = 0;
672 
673     for( sal_uInt16 i = 0, nCount = getItemCount(); i < nCount; i++ )
674     {
675         ValueSetItem* pItem = getItem (i);
676 
677         if( pItem && mpParent->IsItemSelected( pItem->mnId ) )
678             ++nRet;
679     }
680 
681     return nRet;
682 }
683 
684 // -----------------------------------------------------------------------------
685 
686 uno::Reference< accessibility::XAccessible > SAL_CALL ValueSetAcc::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
687     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
688 {
689     ThrowIfDisposed();
690     const vos::OGuard                               aSolarGuard( Application::GetSolarMutex() );
691     uno::Reference< accessibility::XAccessible >    xRet;
692 
693     for( sal_uInt16 i = 0, nCount = getItemCount(), nSel = 0; ( i < nCount ) && !xRet.is(); i++ )
694     {
695         ValueSetItem* pItem = getItem(i);
696 
697         if( pItem && mpParent->IsItemSelected( pItem->mnId ) && ( nSelectedChildIndex == static_cast< sal_Int32 >( nSel++ ) ) )
698             xRet = pItem->GetAccessible( mbIsTransientChildrenDisabled );
699     }
700 
701     return xRet;
702 }
703 
704 // -----------------------------------------------------------------------------
705 
706 void SAL_CALL ValueSetAcc::deselectAccessibleChild( sal_Int32 nChildIndex )
707     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
708 {
709     ThrowIfDisposed();
710     const vos::OGuard   aSolarGuard( Application::GetSolarMutex() );
711     // Because of the single selection we can reset the whole selection when
712     // the specified child is currently selected.
713     if (isAccessibleChildSelected(nChildIndex))
714         mpParent->SetNoSelection();
715 }
716 
717 // -----------------------------------------------------------------------------
718 
719 sal_Int64 SAL_CALL ValueSetAcc::getSomething( const uno::Sequence< sal_Int8 >& rId ) throw( uno::RuntimeException )
720 {
721     sal_Int64 nRet;
722 
723     if( ( rId.getLength() == 16 ) && ( 0 == rtl_compareMemory( ValueSetAcc::getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) )
724         nRet = reinterpret_cast< sal_Int64 >( this );
725     else
726         nRet = 0;
727 
728 	return nRet;
729 }
730 
731 
732 
733 
734 void SAL_CALL ValueSetAcc::disposing (void)
735 {
736     ::std::vector<uno::Reference<accessibility::XAccessibleEventListener> > aListenerListCopy;
737 
738     {
739         // Make a copy of the list and clear the original.
740         const vos::OGuard   aSolarGuard( Application::GetSolarMutex() );
741         ::osl::MutexGuard aGuard (m_aMutex);
742         aListenerListCopy = mxEventListeners;
743         mxEventListeners.clear();
744 
745         // Reset the pointer to the parent.  It has to be the one who has
746         // disposed us because he is dying.
747         mpParent = NULL;
748     }
749 
750     // Inform all listeners that this objects is disposing.
751     ::std::vector<uno::Reference<accessibility::XAccessibleEventListener> >::const_iterator
752           aListenerIterator (aListenerListCopy.begin());
753     lang::EventObject aEvent (static_cast<accessibility::XAccessible*>(this));
754     while (aListenerIterator != aListenerListCopy.end())
755     {
756         try
757         {
758             (*aListenerIterator)->disposing (aEvent);
759         }
760         catch( uno::Exception& )
761         {
762             // Ignore exceptions.
763         }
764 
765         ++aListenerIterator;
766     }
767 }
768 
769 
770 sal_uInt16 ValueSetAcc::getItemCount (void) const
771 {
772     sal_uInt16 nCount = mpParent->ImplGetVisibleItemCount();
773     // When the None-Item is visible then increase the number of items by
774     // one.
775     if (HasNoneField())
776         nCount += 1;
777     return nCount;
778 }
779 
780 
781 ValueSetItem* ValueSetAcc::getItem (sal_uInt16 nIndex) const
782 {
783     ValueSetItem* pItem = NULL;
784 
785     if (HasNoneField())
786     {
787         if (nIndex == 0)
788             // When present the first item is the then allways visible none field.
789             pItem = mpParent->ImplGetItem (VALUESET_ITEM_NONEITEM);
790         else
791             // Shift down the index to compensate for the none field.
792             nIndex -= 1;
793     }
794     if (pItem == NULL)
795 //IAccessibility2 Implementation 2009-----
796         //pItem = mpParent->ImplGetVisibleItem (static_cast<sal_uInt16>(nIndex));
797 	pItem = mpParent->ImplGetItem (static_cast<sal_uInt16>(nIndex));
798 //-----IAccessibility2 Implementation 2009
799 
800     return pItem;
801 }
802 
803 
804 
805 
806 void ValueSetAcc::ThrowIfDisposed (void)
807     throw (::com::sun::star::lang::DisposedException)
808 {
809     if (rBHelper.bDisposed || rBHelper.bInDispose)
810     {
811         OSL_TRACE ("Calling disposed object. Throwing exception:");
812         throw lang::DisposedException (
813             ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("object has been already disposed")),
814             static_cast<uno::XWeak*>(this));
815     }
816     else
817     {
818         DBG_ASSERT (mpParent!=NULL, "ValueSetAcc not disposed but mpParent == NULL");
819     }
820 }
821 
822 
823 
824 sal_Bool ValueSetAcc::IsDisposed (void)
825 {
826 	return (rBHelper.bDisposed || rBHelper.bInDispose);
827 }
828 
829 
830 
831 
832 bool ValueSetAcc::HasNoneField (void) const
833 {
834     DBG_ASSERT (mpParent!=NULL, "ValueSetAcc::HasNoneField called with mpParent==NULL");
835     return ((mpParent->GetStyle() & WB_NONEFIELD) != 0);
836 }
837 
838 
839 
840 
841 // ----------------
842 // - ValueItemAcc -
843 // ----------------
844 
845 ValueItemAcc::ValueItemAcc( ValueSetItem* pParent, bool bIsTransientChildrenDisabled ) :
846     mpParent( pParent ),
847     mbIsTransientChildrenDisabled( bIsTransientChildrenDisabled )
848 {
849 }
850 
851 // -----------------------------------------------------------------------------
852 
853 ValueItemAcc::~ValueItemAcc()
854 {
855 }
856 
857 // -----------------------------------------------------------------------
858 
859 void ValueItemAcc::FireAccessibleEvent( short nEventId, const uno::Any& rOldValue, const uno::Any& rNewValue )
860 {
861     if( nEventId )
862     {
863         ::std::vector< uno::Reference< accessibility::XAccessibleEventListener > >                  aTmpListeners( mxEventListeners );
864         ::std::vector< uno::Reference< accessibility::XAccessibleEventListener > >::const_iterator  aIter( aTmpListeners.begin() );
865         accessibility::AccessibleEventObject                                                        aEvtObject;
866 
867         aEvtObject.EventId = nEventId;
868         aEvtObject.Source = static_cast<uno::XWeak*>(this);
869         aEvtObject.NewValue = rNewValue;
870 	    aEvtObject.OldValue = rOldValue;
871 
872 		while( aIter != aTmpListeners.end() )
873         {
874             (*aIter)->notifyEvent( aEvtObject );
875             aIter++;
876         }
877     }
878 }
879 
880 // -----------------------------------------------------------------------------
881 
882 void ValueItemAcc::ParentDestroyed()
883 {
884     const ::vos::OGuard aGuard( maMutex );
885     mpParent = NULL;
886 }
887 
888 // -----------------------------------------------------------------------------
889 
890 const uno::Sequence< sal_Int8 >& ValueItemAcc::getUnoTunnelId()
891 {
892     static uno::Sequence< sal_Int8 > aSeq;
893 
894 	if( !aSeq.getLength() )
895 	{
896 		static osl::Mutex           aCreateMutex;
897     	osl::Guard< osl::Mutex >    aGuard( aCreateMutex );
898 
899 		aSeq.realloc( 16 );
900     	rtl_createUuid( reinterpret_cast< sal_uInt8* >( aSeq.getArray() ), 0, sal_True );
901 	}
902 
903     return aSeq;
904 }
905 
906 // -----------------------------------------------------------------------------
907 
908 ValueItemAcc* ValueItemAcc::getImplementation( const uno::Reference< uno::XInterface >& rxData )
909     throw()
910 {
911     try
912     {
913 	    uno::Reference< lang::XUnoTunnel > xUnoTunnel( rxData, uno::UNO_QUERY );
914         return( xUnoTunnel.is() ? reinterpret_cast<ValueItemAcc*>(sal::static_int_cast<sal_IntPtr>(xUnoTunnel->getSomething( ValueItemAcc::getUnoTunnelId() ))) : NULL );
915     }
916     catch( const ::com::sun::star::uno::Exception& )
917 	{
918         return NULL;
919 	}
920 }
921 
922 // -----------------------------------------------------------------------------
923 
924 uno::Reference< accessibility::XAccessibleContext > SAL_CALL ValueItemAcc::getAccessibleContext()
925     throw (uno::RuntimeException)
926 {
927     return this;
928 }
929 
930 // -----------------------------------------------------------------------------
931 
932 sal_Int32 SAL_CALL ValueItemAcc::getAccessibleChildCount()
933     throw (uno::RuntimeException)
934 {
935     return 0;
936 }
937 
938 // -----------------------------------------------------------------------------
939 
940 uno::Reference< accessibility::XAccessible > SAL_CALL ValueItemAcc::getAccessibleChild( sal_Int32 )
941     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
942 {
943     throw lang::IndexOutOfBoundsException();
944 }
945 
946 // -----------------------------------------------------------------------------
947 
948 uno::Reference< accessibility::XAccessible > SAL_CALL ValueItemAcc::getAccessibleParent()
949     throw (uno::RuntimeException)
950 {
951     const vos::OGuard                               aSolarGuard( Application::GetSolarMutex() );
952     uno::Reference< accessibility::XAccessible >    xRet;
953 
954     if( mpParent )
955         xRet = mpParent->mrParent.GetAccessible();
956 
957     return xRet;
958 }
959 
960 // -----------------------------------------------------------------------------
961 
962 sal_Int32 SAL_CALL ValueItemAcc::getAccessibleIndexInParent()
963     throw (uno::RuntimeException)
964 {
965     const vos::OGuard   aSolarGuard( Application::GetSolarMutex() );
966     // The index defaults to -1 to indicate the child does not belong to its
967     // parent.
968     sal_Int32 nIndexInParent = -1;
969 
970     if( mpParent )
971     {
972         bool bDone = false;
973 
974         sal_uInt16 nCount = mpParent->mrParent.ImplGetVisibleItemCount();
975         ValueSetItem* pItem;
976         for (sal_uInt16 i=0; i<nCount && !bDone; i++)
977         {
978             // Guard the retrieval of the i-th child with a try/catch block
979             // just in case the number of children changes in the mean time.
980             try
981             {
982 //IAccessibility2 Implementation 2009-----
983                 //pItem = mpParent->mrParent.ImplGetVisibleItem (i);
984                 pItem = mpParent->mrParent.ImplGetItem(i);
985 //-----IAccessibility2 Implementation 2009
986             }
987             catch (lang::IndexOutOfBoundsException aException)
988             {
989                 pItem = NULL;
990             }
991 
992             // Do not create an accessible object for the test.
993             if (pItem != NULL && pItem->mpxAcc != NULL)
994                 if (pItem->GetAccessible( mbIsTransientChildrenDisabled ).get() == this )
995                 {
996                     nIndexInParent = i;
997                     bDone = true;
998                 }
999         }
1000     }
1001 
1002 //IAccessibility2 Implementation 2009-----
1003 	//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.
1004 	if ( mpParent && ( (mpParent->mrParent.GetStyle() & WB_NONEFIELD) != 0 ) )
1005 	{
1006 		ValueSetItem* pFirstItem = mpParent->mrParent.ImplGetItem (VALUESET_ITEM_NONEITEM);
1007 		if( pFirstItem && pFirstItem ->GetAccessible(mbIsTransientChildrenDisabled).get() == this )
1008 			nIndexInParent = 0;
1009 		else
1010 			nIndexInParent++;
1011 	}
1012 //-----IAccessibility2 Implementation 2009
1013     return nIndexInParent;
1014 }
1015 
1016 // -----------------------------------------------------------------------------
1017 
1018 sal_Int16 SAL_CALL ValueItemAcc::getAccessibleRole()
1019     throw (uno::RuntimeException)
1020 {
1021     return accessibility::AccessibleRole::LIST_ITEM;
1022 }
1023 
1024 // -----------------------------------------------------------------------------
1025 
1026 ::rtl::OUString SAL_CALL ValueItemAcc::getAccessibleDescription()
1027     throw (uno::RuntimeException)
1028 {
1029 	return ::rtl::OUString();
1030 }
1031 
1032 // -----------------------------------------------------------------------------
1033 
1034 ::rtl::OUString SAL_CALL ValueItemAcc::getAccessibleName()
1035     throw (uno::RuntimeException)
1036 {
1037     const vos::OGuard   aSolarGuard( Application::GetSolarMutex() );
1038     String              aRet;
1039 
1040     if( mpParent )
1041     {
1042         aRet = mpParent->maText;
1043 
1044         if( !aRet.Len() )
1045         {
1046             aRet = String( RTL_CONSTASCII_USTRINGPARAM( "Item " ) );
1047             aRet += String::CreateFromInt32( mpParent->mnId );
1048         }
1049     }
1050 
1051     return aRet;
1052 }
1053 
1054 // -----------------------------------------------------------------------------
1055 
1056 uno::Reference< accessibility::XAccessibleRelationSet > SAL_CALL ValueItemAcc::getAccessibleRelationSet()
1057     throw (uno::RuntimeException)
1058 {
1059     return uno::Reference< accessibility::XAccessibleRelationSet >();
1060 }
1061 
1062 // -----------------------------------------------------------------------------
1063 
1064 uno::Reference< accessibility::XAccessibleStateSet > SAL_CALL ValueItemAcc::getAccessibleStateSet()
1065     throw (uno::RuntimeException)
1066 {
1067     const vos::OGuard                   aSolarGuard( Application::GetSolarMutex() );
1068     ::utl::AccessibleStateSetHelper*    pStateSet = new ::utl::AccessibleStateSetHelper;
1069 
1070     if( mpParent )
1071     {
1072         pStateSet->AddState (accessibility::AccessibleStateType::ENABLED);
1073         pStateSet->AddState (accessibility::AccessibleStateType::SENSITIVE);
1074         pStateSet->AddState (accessibility::AccessibleStateType::SHOWING);
1075         pStateSet->AddState (accessibility::AccessibleStateType::VISIBLE);
1076         if ( !mbIsTransientChildrenDisabled )
1077             pStateSet->AddState (accessibility::AccessibleStateType::TRANSIENT);
1078 
1079 	    // SELECTABLE
1080 	    pStateSet->AddState( accessibility::AccessibleStateType::SELECTABLE );
1081         //	    pStateSet->AddState( accessibility::AccessibleStateType::FOCUSABLE );
1082 
1083 	    // SELECTED
1084         if( mpParent->mrParent.GetSelectItemId() == mpParent->mnId )
1085         {
1086             pStateSet->AddState( accessibility::AccessibleStateType::SELECTED );
1087             //       	    pStateSet->AddState( accessibility::AccessibleStateType::FOCUSED );
1088         }
1089     }
1090 
1091     return pStateSet;
1092 }
1093 
1094 // -----------------------------------------------------------------------------
1095 
1096 lang::Locale SAL_CALL ValueItemAcc::getLocale()
1097     throw (accessibility::IllegalAccessibleComponentStateException, uno::RuntimeException)
1098 {
1099     const vos::OGuard                               aSolarGuard( Application::GetSolarMutex() );
1100     const ::rtl::OUString                           aEmptyStr;
1101     uno::Reference< accessibility::XAccessible >    xParent( getAccessibleParent() );
1102     lang::Locale                                    aRet( aEmptyStr, aEmptyStr, aEmptyStr );
1103 
1104     if( xParent.is() )
1105     {
1106         uno::Reference< accessibility::XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
1107 
1108         if( xParentContext.is() )
1109             aRet = xParentContext->getLocale();
1110     }
1111 
1112     return aRet;
1113 }
1114 
1115 // -----------------------------------------------------------------------------
1116 
1117 void SAL_CALL ValueItemAcc::addEventListener( const uno::Reference< accessibility::XAccessibleEventListener >& rxListener )
1118     throw (uno::RuntimeException)
1119 {
1120     const ::vos::OGuard aGuard( maMutex );
1121 
1122 	if( rxListener.is() )
1123     {
1124        	::std::vector< uno::Reference< accessibility::XAccessibleEventListener > >::const_iterator aIter = mxEventListeners.begin();
1125 		sal_Bool bFound = sal_False;
1126 
1127 		while( !bFound && ( aIter != mxEventListeners.end() ) )
1128         {
1129 			if( *aIter == rxListener )
1130                 bFound = sal_True;
1131             else
1132                 aIter++;
1133         }
1134 
1135 		if (!bFound)
1136             mxEventListeners.push_back( rxListener );
1137     }
1138 }
1139 
1140 // -----------------------------------------------------------------------------
1141 
1142 void SAL_CALL ValueItemAcc::removeEventListener( const uno::Reference< accessibility::XAccessibleEventListener >& rxListener )
1143     throw (uno::RuntimeException)
1144 {
1145     const ::vos::OGuard aGuard( maMutex );
1146 
1147 	if( rxListener.is() )
1148     {
1149        	::std::vector< uno::Reference< accessibility::XAccessibleEventListener > >::iterator aIter = mxEventListeners.begin();
1150 		sal_Bool bFound = sal_False;
1151 
1152 		while( !bFound && ( aIter != mxEventListeners.end() ) )
1153         {
1154 			if( *aIter == rxListener )
1155             {
1156                 mxEventListeners.erase( aIter );
1157                 bFound = sal_True;
1158             }
1159             else
1160                 aIter++;
1161         }
1162     }
1163 }
1164 
1165 // -----------------------------------------------------------------------------
1166 
1167 sal_Bool SAL_CALL ValueItemAcc::containsPoint( const awt::Point& aPoint )
1168     throw (uno::RuntimeException)
1169 {
1170     const awt::Rectangle    aRect( getBounds() );
1171     const Point             aSize( aRect.Width, aRect.Height );
1172     const Point             aNullPoint, aTestPoint( aPoint.X, aPoint.Y );
1173 
1174     return Rectangle( aNullPoint, aSize ).IsInside( aTestPoint );
1175 }
1176 
1177 // -----------------------------------------------------------------------------
1178 
1179 uno::Reference< accessibility::XAccessible > SAL_CALL ValueItemAcc::getAccessibleAtPoint( const awt::Point& )
1180     throw (uno::RuntimeException)
1181 {
1182     uno::Reference< accessibility::XAccessible > xRet;
1183     return xRet;
1184 }
1185 
1186 // -----------------------------------------------------------------------------
1187 
1188 awt::Rectangle SAL_CALL ValueItemAcc::getBounds()
1189     throw (uno::RuntimeException)
1190 {
1191     const vos::OGuard   aSolarGuard( Application::GetSolarMutex() );
1192     awt::Rectangle      aRet;
1193 
1194     if( mpParent )
1195     {
1196         Rectangle   aRect( mpParent->maRect );
1197         Point       aOrigin;
1198         Rectangle   aParentRect( aOrigin, mpParent->mrParent.GetOutputSizePixel() );
1199 
1200         aRect.Intersection( aParentRect );
1201 
1202         aRet.X = aRect.Left();
1203         aRet.Y = aRect.Top();
1204         aRet.Width = aRect.GetWidth();
1205         aRet.Height = aRect.GetHeight();
1206     }
1207 
1208     return aRet;
1209 }
1210 
1211 // -----------------------------------------------------------------------------
1212 
1213 awt::Point SAL_CALL ValueItemAcc::getLocation()
1214     throw (uno::RuntimeException)
1215 {
1216     const awt::Rectangle    aRect( getBounds() );
1217     awt::Point              aRet;
1218 
1219     aRet.X = aRect.X;
1220     aRet.Y = aRect.Y;
1221 
1222     return aRet;
1223 }
1224 
1225 // -----------------------------------------------------------------------------
1226 
1227 awt::Point SAL_CALL ValueItemAcc::getLocationOnScreen()
1228     throw (uno::RuntimeException)
1229 {
1230     const vos::OGuard   aSolarGuard( Application::GetSolarMutex() );
1231     awt::Point          aRet;
1232 
1233     if( mpParent )
1234     {
1235         const Point aScreenPos( mpParent->mrParent.OutputToAbsoluteScreenPixel( mpParent->maRect.TopLeft() ) );
1236 
1237         aRet.X = aScreenPos.X();
1238         aRet.Y = aScreenPos.Y();
1239     }
1240 
1241     return aRet;
1242 }
1243 
1244 // -----------------------------------------------------------------------------
1245 
1246 awt::Size SAL_CALL ValueItemAcc::getSize()
1247     throw (uno::RuntimeException)
1248 {
1249     const awt::Rectangle    aRect( getBounds() );
1250     awt::Size               aRet;
1251 
1252     aRet.Width = aRect.Width;
1253     aRet.Height = aRect.Height;
1254 
1255     return aRet;
1256 }
1257 
1258 // -----------------------------------------------------------------------------
1259 
1260 void SAL_CALL ValueItemAcc::grabFocus()
1261     throw (uno::RuntimeException)
1262 {
1263     // nothing to do
1264 }
1265 
1266 // -----------------------------------------------------------------------------
1267 
1268 uno::Any SAL_CALL ValueItemAcc::getAccessibleKeyBinding()
1269     throw (uno::RuntimeException)
1270 {
1271     return uno::Any();
1272 }
1273 
1274 // -----------------------------------------------------------------------------
1275 
1276 sal_Int32 SAL_CALL ValueItemAcc::getForeground(  )
1277     throw (uno::RuntimeException)
1278 {
1279     sal_uInt32 nColor = Application::GetSettings().GetStyleSettings().GetWindowTextColor().GetColor();
1280     return static_cast<sal_Int32>(nColor);
1281 }
1282 
1283 // -----------------------------------------------------------------------------
1284 
1285 sal_Int32 SAL_CALL ValueItemAcc::getBackground(  )
1286     throw (uno::RuntimeException)
1287 {
1288     sal_uInt32 nColor;
1289     if (mpParent && mpParent->meType == VALUESETITEM_COLOR)
1290         nColor = mpParent->maColor.GetColor();
1291     else
1292         nColor = Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor();
1293     return static_cast<sal_Int32>(nColor);
1294 }
1295 
1296 // -----------------------------------------------------------------------------
1297 
1298 sal_Int64 SAL_CALL ValueItemAcc::getSomething( const uno::Sequence< sal_Int8 >& rId ) throw( uno::RuntimeException )
1299 {
1300     sal_Int64 nRet;
1301 
1302     if( ( rId.getLength() == 16 ) && ( 0 == rtl_compareMemory( ValueItemAcc::getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) )
1303         nRet = reinterpret_cast< sal_Int64 >( this );
1304     else
1305         nRet = 0;
1306 
1307 	return nRet;
1308 }
1309