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