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