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 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
32 #include <com/sun/star/accessibility/AccessibleRole.hpp>
33 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
34 
35 #include <unotools/accessiblestatesethelper.hxx>
36 
37 #include <vcl/svapp.hxx>
38 
39 #include "svtools/toolbarmenu.hxx"
40 
41 #include "toolbarmenuimp.hxx"
42 
43 using ::rtl::OUString;
44 
45 using namespace ::com::sun::star;
46 using namespace ::com::sun::star::uno;
47 using namespace ::com::sun::star::lang;
48 using namespace ::com::sun::star::accessibility;
49 
50 namespace svtools {
51 
52 // ------------------
53 // - ToolbarMenuAcc -
54 // ------------------
55 
56 ToolbarMenuAcc::ToolbarMenuAcc( ToolbarMenu_Impl& rParent )
57 : ToolbarMenuAccComponentBase(m_aMutex)
58 , mpParent( &rParent )
59 , mbIsFocused(false)
60 {
61 	mpParent->mrMenu.AddEventListener( LINK( this, ToolbarMenuAcc, WindowEventListener ) );
62 }
63 
64 // -----------------------------------------------------------------------------
65 
66 ToolbarMenuAcc::~ToolbarMenuAcc()
67 {
68 	if( mpParent )
69 		mpParent->mrMenu.RemoveEventListener( LINK( this, ToolbarMenuAcc, WindowEventListener ) );
70 }
71 
72 // -----------------------------------------------------------------------
73 
74 IMPL_LINK( ToolbarMenuAcc, WindowEventListener, VclSimpleEvent*, pEvent )
75 {
76 	DBG_ASSERT( pEvent && pEvent->ISA( VclWindowEvent ), "Unknown WindowEvent!" );
77 
78     /* Ignore VCLEVENT_WINDOW_ENDPOPUPMODE, because the UNO accessibility wrapper
79      * might have been destroyed by the previous VCLEventListener (if no AT tool
80      * is running), e.g. sub-toolbars in impress.
81      */
82 	if ( mpParent && pEvent && pEvent->ISA( VclWindowEvent ) && (pEvent->GetId() != VCLEVENT_WINDOW_ENDPOPUPMODE) )
83 	{
84 		DBG_ASSERT( ((VclWindowEvent*)pEvent)->GetWindow(), "Window???" );
85         if( !((VclWindowEvent*)pEvent)->GetWindow()->IsAccessibilityEventsSuppressed() || ( pEvent->GetId() == VCLEVENT_OBJECT_DYING ) )
86 		{
87 		    ProcessWindowEvent( *(VclWindowEvent*)pEvent );
88 		}
89 	}
90 	return 0;
91 }
92 
93 // -----------------------------------------------------------------------
94 
95 void ToolbarMenuAcc::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
96 {
97 	Any aOldValue, aNewValue;
98 
99 	switch ( rVclWindowEvent.GetId() )
100 	{
101         case VCLEVENT_OBJECT_DYING:
102         {
103 		    mpParent->mrMenu.RemoveEventListener( LINK( this, ToolbarMenuAcc, WindowEventListener ) );
104 	        mpParent = 0;
105         }
106         break;
107 
108 		case VCLEVENT_WINDOW_GETFOCUS:
109 		{
110 			if( !mbIsFocused )
111 			{
112 				mpParent->notifyHighlightedEntry();
113 				mbIsFocused = true;
114 			}
115 		}
116 		break;
117 		case VCLEVENT_WINDOW_LOSEFOCUS:
118 		{
119 			if( mbIsFocused )
120 			{
121 				mbIsFocused = false;
122 			}
123 		}
124 		break;
125 		default:
126 		{
127 		}
128 		break;
129 	}
130 }
131 
132 // -----------------------------------------------------------------------
133 
134 void ToolbarMenuAcc::FireAccessibleEvent( short nEventId, const Any& rOldValue, const Any& rNewValue )
135 {
136     if( nEventId )
137     {
138         EventListenerVector                  aTmpListeners( mxEventListeners );
139         EventListenerVector::const_iterator  aIter( aTmpListeners.begin() );
140         AccessibleEventObject aEvtObject;
141 
142         aEvtObject.EventId = nEventId;
143         aEvtObject.Source = static_cast<XWeak*>(this);
144         aEvtObject.NewValue = rNewValue;
145 	    aEvtObject.OldValue = rOldValue;
146 
147 		while( aIter != aTmpListeners.end() )
148         {
149 			try
150 			{
151 				(*aIter)->notifyEvent( aEvtObject );
152 			}
153 			catch( Exception& )
154 			{
155 			}
156 
157             aIter++;
158         }
159     }
160 }
161 
162 // -----------------------------------------------------------------------------
163 
164 Reference< XAccessibleContext > SAL_CALL ToolbarMenuAcc::getAccessibleContext() throw (RuntimeException)
165 {
166     ThrowIfDisposed();
167     return this;
168 }
169 
170 // -----------------------------------------------------------------------------
171 
172 sal_Int32 SAL_CALL ToolbarMenuAcc::getAccessibleChildCount() throw (RuntimeException)
173 {
174     const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
175     ThrowIfDisposed();
176 
177     return mpParent->getAccessibleChildCount();
178 }
179 
180 // -----------------------------------------------------------------------------
181 
182 Reference< XAccessible > SAL_CALL ToolbarMenuAcc::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException)
183 {
184     const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
185     ThrowIfDisposed();
186 
187 	return mpParent->getAccessibleChild(i);
188 }
189 
190 // -----------------------------------------------------------------------------
191 
192 Reference< XAccessible > SAL_CALL ToolbarMenuAcc::getAccessibleParent() throw (RuntimeException)
193 {
194     ThrowIfDisposed();
195     const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
196 
197 	Reference< XAccessible > xRet;
198 
199     Window* pParent = mpParent->mrMenu.GetParent();
200     if( pParent )
201         xRet = pParent->GetAccessible();
202 
203     return xRet;
204 }
205 
206 // -----------------------------------------------------------------------------
207 
208 sal_Int32 SAL_CALL ToolbarMenuAcc::getAccessibleIndexInParent() throw (RuntimeException)
209 {
210     const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
211     ThrowIfDisposed();
212 
213 	Window* pParent = mpParent->mrMenu.GetParent();
214     if( pParent )
215     {
216         for( sal_uInt16 i = 0, nCount = pParent->GetChildCount(); i < nCount ; i++ )
217         {
218             if( pParent->GetChild( i ) == &mpParent->mrMenu )
219 				return i;
220         }
221     }
222 
223     return 0;
224 }
225 
226 // -----------------------------------------------------------------------------
227 
228 sal_Int16 SAL_CALL ToolbarMenuAcc::getAccessibleRole() throw (RuntimeException)
229 {
230     ThrowIfDisposed();
231     return AccessibleRole::LIST;
232 }
233 
234 // -----------------------------------------------------------------------------
235 
236 OUString SAL_CALL ToolbarMenuAcc::getAccessibleDescription() throw (RuntimeException)
237 {
238     ThrowIfDisposed();
239     return OUString( RTL_CONSTASCII_USTRINGPARAM( "ToolbarMenu" ) );
240 }
241 
242 // -----------------------------------------------------------------------------
243 
244 OUString SAL_CALL ToolbarMenuAcc::getAccessibleName() throw (RuntimeException)
245 {
246     ThrowIfDisposed();
247     const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
248     OUString aRet;
249 
250     if( mpParent )
251 		aRet = mpParent->mrMenu.GetAccessibleName();
252 
253     if( !aRet.getLength() )
254     {
255         Window* pLabel = mpParent->mrMenu.GetAccessibleRelationLabeledBy();
256         if( pLabel && pLabel != &mpParent->mrMenu )
257 			aRet = OutputDevice::GetNonMnemonicString( pLabel->GetText() );
258     }
259 
260     return aRet;
261 }
262 
263 // -----------------------------------------------------------------------------
264 
265 Reference< XAccessibleRelationSet > SAL_CALL ToolbarMenuAcc::getAccessibleRelationSet() throw (RuntimeException)
266 {
267     ThrowIfDisposed();
268     return Reference< XAccessibleRelationSet >();
269 }
270 
271 // -----------------------------------------------------------------------------
272 
273 Reference< XAccessibleStateSet > SAL_CALL ToolbarMenuAcc::getAccessibleStateSet() throw (RuntimeException)
274 {
275     ThrowIfDisposed();
276     ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper();
277 
278     // Set some states.
279     pStateSet->AddState (AccessibleStateType::ENABLED);
280     pStateSet->AddState (AccessibleStateType::SENSITIVE);
281     pStateSet->AddState (AccessibleStateType::SHOWING);
282     pStateSet->AddState (AccessibleStateType::VISIBLE);
283 	pStateSet->AddState (AccessibleStateType::MANAGES_DESCENDANTS);
284     pStateSet->AddState (AccessibleStateType::FOCUSABLE);
285     if (mbIsFocused)
286         pStateSet->AddState (AccessibleStateType::FOCUSED);
287 
288     return pStateSet;
289 }
290 
291 // -----------------------------------------------------------------------------
292 
293 Locale SAL_CALL ToolbarMenuAcc::getLocale() throw (IllegalAccessibleComponentStateException, RuntimeException)
294 {
295     ThrowIfDisposed();
296     const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
297     const ::rtl::OUString aEmptyStr;
298     Reference< XAccessible > xParent( getAccessibleParent() );
299     Locale aRet( aEmptyStr, aEmptyStr, aEmptyStr );
300 
301     if( xParent.is() )
302     {
303         Reference< XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
304 
305         if( xParentContext.is() )
306             aRet = xParentContext->getLocale ();
307     }
308 
309     return aRet;
310 }
311 
312 // -----------------------------------------------------------------------------
313 
314 void SAL_CALL ToolbarMenuAcc::addEventListener( const Reference< XAccessibleEventListener >& rxListener ) throw (RuntimeException)
315 {
316     ThrowIfDisposed();
317     ::osl::MutexGuard aGuard(m_aMutex);
318 
319 	if( rxListener.is() )
320     {
321        	EventListenerVector::const_iterator aIter = mxEventListeners.begin();
322 		bool bFound = false;
323 
324 		while( !bFound && ( aIter != mxEventListeners.end() ) )
325         {
326 			if( *aIter == rxListener )
327                 bFound = true;
328             else
329                 aIter++;
330         }
331 
332 		if (!bFound)
333             mxEventListeners.push_back( rxListener );
334     }
335 }
336 
337 // -----------------------------------------------------------------------------
338 
339 void SAL_CALL ToolbarMenuAcc::removeEventListener( const Reference< XAccessibleEventListener >& rxListener ) throw (RuntimeException)
340 {
341     ThrowIfDisposed();
342     ::osl::MutexGuard aGuard(m_aMutex);
343 
344 	if( rxListener.is() )
345     {
346        	EventListenerVector::iterator aIter = mxEventListeners.begin();
347 		bool bFound = false;
348 
349 		while( !bFound && ( aIter != mxEventListeners.end() ) )
350         {
351 			if( *aIter == rxListener )
352             {
353                 mxEventListeners.erase( aIter );
354                 bFound = true;
355             }
356             else
357                 aIter++;
358         }
359     }
360 }
361 
362 // -----------------------------------------------------------------------------
363 
364 sal_Bool SAL_CALL ToolbarMenuAcc::containsPoint( const awt::Point& aPoint ) throw (RuntimeException)
365 {
366     ThrowIfDisposed();
367     const awt::Rectangle aRect( getBounds() );
368     const Point aSize( aRect.Width, aRect.Height );
369     const Point aNullPoint, aTestPoint( aPoint.X, aPoint.Y );
370 
371     return Rectangle( aNullPoint, aSize ).IsInside( aTestPoint );
372 }
373 
374 // -----------------------------------------------------------------------------
375 
376 Reference< XAccessible > SAL_CALL ToolbarMenuAcc::getAccessibleAtPoint( const awt::Point& aPoint ) throw (RuntimeException)
377 {
378     const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
379     ThrowIfDisposed();
380 
381 	Reference< XAccessible > xRet;
382 
383 	const Point aVclPoint( aPoint.X, aPoint.Y );
384 
385 	const int nEntryCount = mpParent->maEntryVector.size();
386 	for( int nEntry = 0; (nEntry < nEntryCount) && !xRet.is(); nEntry++ )
387 	{
388 		ToolbarMenuEntry* pEntry = mpParent->maEntryVector[nEntry];
389 		if( pEntry && pEntry->maRect.IsInside( aVclPoint ) )
390 		{
391 			if( pEntry->mpControl )
392 			{
393 				awt::Point aChildPoint( aPoint.X - pEntry->maRect.Left(), aPoint.Y - pEntry->maRect.Top() );
394 				Reference< XAccessibleComponent > xComp( pEntry->GetAccessible(true), UNO_QUERY_THROW );
395 				xRet = xComp->getAccessibleAtPoint(aChildPoint);
396 			}
397 			else
398 			{
399 				xRet = Reference< XAccessible >( pEntry->GetAccessible(true), UNO_QUERY );
400 			}
401 		}
402 	}
403 	return xRet;
404 }
405 
406 // -----------------------------------------------------------------------------
407 
408 awt::Rectangle SAL_CALL ToolbarMenuAcc::getBounds() throw (RuntimeException)
409 {
410     ThrowIfDisposed();
411     const vos::OGuard   aSolarGuard( Application::GetSolarMutex() );
412     const Point         aOutPos( mpParent->mrMenu.GetPosPixel() );
413     const Size          aOutSize( mpParent->mrMenu.GetOutputSizePixel() );
414     awt::Rectangle      aRet;
415 
416     aRet.X = aOutPos.X();
417     aRet.Y = aOutPos.Y();
418     aRet.Width = aOutSize.Width();
419     aRet.Height = aOutSize.Height();
420 
421     return aRet;
422 }
423 
424 // -----------------------------------------------------------------------------
425 
426 awt::Point SAL_CALL ToolbarMenuAcc::getLocation() throw (RuntimeException)
427 {
428     ThrowIfDisposed();
429     const vos::OGuard   aSolarGuard( Application::GetSolarMutex() );
430     const Point aOutPos( mpParent->mrMenu.GetPosPixel() );
431     return awt::Point( aOutPos.X(), aOutPos.Y() );
432 }
433 
434 // -----------------------------------------------------------------------------
435 
436 awt::Point SAL_CALL ToolbarMenuAcc::getLocationOnScreen()  throw (RuntimeException)
437 {
438     ThrowIfDisposed();
439     const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
440     const Point aScreenPos( mpParent->mrMenu.OutputToAbsoluteScreenPixel( Point() ) );
441     return awt::Point( aScreenPos.X(), aScreenPos.Y() );
442 }
443 
444 // -----------------------------------------------------------------------------
445 
446 awt::Size SAL_CALL ToolbarMenuAcc::getSize() throw (RuntimeException)
447 {
448     ThrowIfDisposed();
449     const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
450     const Size aOutSize( mpParent->mrMenu.GetOutputSizePixel() );
451     return awt::Size( aOutSize.Width(), aOutSize.Height() );
452 }
453 
454 // -----------------------------------------------------------------------------
455 
456 void SAL_CALL ToolbarMenuAcc::grabFocus() throw (RuntimeException)
457 {
458     ThrowIfDisposed();
459     const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
460     mpParent->mrMenu.GrabFocus();
461 }
462 
463 // -----------------------------------------------------------------------------
464 
465 Any SAL_CALL ToolbarMenuAcc::getAccessibleKeyBinding() throw (RuntimeException)
466 {
467     ThrowIfDisposed();
468     return Any();
469 }
470 
471 // -----------------------------------------------------------------------------
472 
473 sal_Int32 SAL_CALL ToolbarMenuAcc::getForeground() throw (RuntimeException)
474 {
475     ThrowIfDisposed();
476     sal_uInt32 nColor = Application::GetSettings().GetStyleSettings().GetMenuTextColor().GetColor();
477     return static_cast<sal_Int32>(nColor);
478 }
479 
480 // -----------------------------------------------------------------------------
481 
482 sal_Int32 SAL_CALL ToolbarMenuAcc::getBackground() throw (RuntimeException)
483 {
484     ThrowIfDisposed();
485     sal_uInt32 nColor = Application::GetSettings().GetStyleSettings().GetMenuColor().GetColor();
486     return static_cast<sal_Int32>(nColor);
487 }
488 
489 // -----------------------------------------------------------------------------
490 
491 void SAL_CALL ToolbarMenuAcc::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
492 {
493     const vos::OGuard   aSolarGuard( Application::GetSolarMutex() );
494     ThrowIfDisposed();
495 
496 	mpParent->selectAccessibleChild( nChildIndex );
497 }
498 
499 // -----------------------------------------------------------------------------
500 
501 sal_Bool SAL_CALL ToolbarMenuAcc::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
502 {
503     const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
504     ThrowIfDisposed();
505 	return mpParent->isAccessibleChildSelected( nChildIndex );
506 }
507 
508 // -----------------------------------------------------------------------------
509 
510 void SAL_CALL ToolbarMenuAcc::clearAccessibleSelection() throw (RuntimeException)
511 {
512     const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
513     ThrowIfDisposed();
514     mpParent->clearAccessibleSelection();
515 }
516 
517 // -----------------------------------------------------------------------------
518 
519 void SAL_CALL ToolbarMenuAcc::selectAllAccessibleChildren() throw (RuntimeException)
520 {
521     ThrowIfDisposed();
522     // unsupported due to single selection only
523 }
524 
525 // -----------------------------------------------------------------------------
526 
527 sal_Int32 SAL_CALL ToolbarMenuAcc::getSelectedAccessibleChildCount() throw (RuntimeException)
528 {
529     const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
530     ThrowIfDisposed();
531 
532 	return mpParent->mnHighlightedEntry != -1 ? 1 : 0;
533 }
534 
535 // -----------------------------------------------------------------------------
536 
537 Reference< XAccessible > SAL_CALL ToolbarMenuAcc::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
538 {
539     ThrowIfDisposed();
540     const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
541 
542 	if( (mpParent->mnHighlightedEntry != -1) && (nSelectedChildIndex == 0) )
543 	{
544 		ToolbarMenuEntry* pEntry = mpParent->maEntryVector[ mpParent->mnHighlightedEntry ];
545 		if( pEntry )
546 		{
547 			if( pEntry->mpControl )
548 			{
549 				Reference< XAccessibleSelection > xSel( pEntry->GetAccessible(true), UNO_QUERY_THROW );
550 				return xSel->getSelectedAccessibleChild(0);
551 			}
552 			else
553 				return Reference< XAccessible >( pEntry->GetAccessible(true), UNO_QUERY );
554 		}
555 	}
556 
557 	throw IndexOutOfBoundsException();
558 }
559 
560 // -----------------------------------------------------------------------------
561 
562 void SAL_CALL ToolbarMenuAcc::deselectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
563 {
564     ThrowIfDisposed();
565     const vos::OGuard   aSolarGuard( Application::GetSolarMutex() );
566     // Because of the single selection we can reset the whole selection when
567     // the specified child is currently selected.
568     if (isAccessibleChildSelected(nChildIndex))
569         mpParent->clearAccessibleSelection();
570 }
571 
572 // -----------------------------------------------------------------------------
573 
574 void SAL_CALL ToolbarMenuAcc::disposing (void)
575 {
576     EventListenerVector aListenerListCopy;
577 
578     {
579         // Make a copy of the list and clear the original.
580         const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
581         ::osl::MutexGuard aGuard (m_aMutex);
582         aListenerListCopy = mxEventListeners;
583         mxEventListeners.clear();
584 
585         // Reset the pointer to the parent.  It has to be the one who has
586         // disposed us because he is dying.
587         mpParent = NULL;
588     }
589 
590     // Inform all listeners that this objects is disposing.
591     EventListenerVector::const_iterator aListenerIterator (aListenerListCopy.begin());
592     EventObject aEvent (static_cast<XAccessible*>(this));
593     while(aListenerIterator != aListenerListCopy.end())
594     {
595         try
596         {
597             (*aListenerIterator)->disposing (aEvent);
598         }
599         catch( Exception& )
600         {
601             // Ignore exceptions.
602         }
603 
604         ++aListenerIterator;
605     }
606 }
607 
608 void ToolbarMenuAcc::ThrowIfDisposed (void) throw (DisposedException)
609 {
610     if(rBHelper.bDisposed || rBHelper.bInDispose || !mpParent)
611     {
612         throw DisposedException ( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("object has been already disposed")), static_cast<XWeak*>(this));
613     }
614 }
615 
616 // -----------------------
617 // - ToolbarMenuEntryAcc -
618 // -----------------------
619 
620 ToolbarMenuEntryAcc::ToolbarMenuEntryAcc( ToolbarMenuEntry* pParent )
621 : ToolbarMenuEntryAccBase( m_aMutex )
622 , mpParent( pParent )
623 {
624 }
625 
626 // -----------------------------------------------------------------------------
627 
628 ToolbarMenuEntryAcc::~ToolbarMenuEntryAcc()
629 {
630 }
631 
632 // -----------------------------------------------------------------------
633 
634 void ToolbarMenuEntryAcc::FireAccessibleEvent( short nEventId, const Any& rOldValue, const Any& rNewValue )
635 {
636     if( nEventId )
637     {
638         EventListenerVector aTmpListeners( mxEventListeners );
639         ::std::vector< Reference< XAccessibleEventListener > >::const_iterator  aIter( aTmpListeners.begin() );
640         AccessibleEventObject aEvtObject;
641 
642         aEvtObject.EventId = nEventId;
643         aEvtObject.Source = static_cast<XWeak*>(this);
644         aEvtObject.NewValue = rNewValue;
645 	    aEvtObject.OldValue = rOldValue;
646 
647 		while( aIter != aTmpListeners.end() )
648         {
649             (*aIter)->notifyEvent( aEvtObject );
650             aIter++;
651         }
652     }
653 }
654 
655 
656 // -----------------------------------------------------------------------------
657 
658 void SAL_CALL ToolbarMenuEntryAcc::disposing (void)
659 {
660     EventListenerVector aListenerListCopy;
661 
662     {
663         // Make a copy of the list and clear the original.
664         const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
665         ::osl::MutexGuard aGuard (m_aMutex);
666         aListenerListCopy = mxEventListeners;
667         mxEventListeners.clear();
668 
669         // Reset the pointer to the parent.  It has to be the one who has
670         // disposed us because he is dying.
671         mpParent = NULL;
672     }
673 
674     // Inform all listeners that this objects is disposing.
675     EventListenerVector::const_iterator aListenerIterator (aListenerListCopy.begin());
676     EventObject aEvent (static_cast<XAccessible*>(this));
677     while(aListenerIterator != aListenerListCopy.end())
678     {
679         try
680         {
681             (*aListenerIterator)->disposing (aEvent);
682         }
683         catch( Exception& )
684         {
685             // Ignore exceptions.
686         }
687 
688         ++aListenerIterator;
689     }
690 }
691 // -----------------------------------------------------------------------------
692 
693 Reference< XAccessibleContext > SAL_CALL ToolbarMenuEntryAcc::getAccessibleContext() throw (RuntimeException)
694 {
695     return this;
696 }
697 
698 // -----------------------------------------------------------------------------
699 
700 sal_Int32 SAL_CALL ToolbarMenuEntryAcc::getAccessibleChildCount() throw (RuntimeException)
701 {
702     return 0;
703 }
704 
705 // -----------------------------------------------------------------------------
706 
707 Reference< XAccessible > SAL_CALL ToolbarMenuEntryAcc::getAccessibleChild( sal_Int32 ) throw (IndexOutOfBoundsException, RuntimeException)
708 {
709 	throw IndexOutOfBoundsException();
710 }
711 
712 // -----------------------------------------------------------------------------
713 
714 Reference< XAccessible > SAL_CALL ToolbarMenuEntryAcc::getAccessibleParent() throw (RuntimeException)
715 {
716     const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
717     Reference< XAccessible > xRet;
718 
719     if( mpParent )
720         xRet = mpParent->mrMenu.GetAccessible();
721 
722     return xRet;
723 }
724 
725 // -----------------------------------------------------------------------------
726 
727 sal_Int32 SAL_CALL ToolbarMenuEntryAcc::getAccessibleIndexInParent() throw (RuntimeException)
728 {
729     const vos::OGuard   aSolarGuard( Application::GetSolarMutex() );
730     // The index defaults to -1 to indicate the child does not belong to its
731     // parent.
732     sal_Int32 nIndexInParent = -1;
733 
734     if( mpParent )
735     {
736 		Reference< XAccessibleContext > xParent( mpParent->mrMenu.GetAccessible(), UNO_QUERY );
737 
738 		if( xParent.is() )
739 		{
740 			Reference< XAccessible > xThis( this );
741 
742 			const sal_Int32 nCount = xParent->getAccessibleChildCount();
743 			for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
744 			{
745 				if( xParent->getAccessibleChild(nIndex) == xThis )
746 				{
747 					nIndexInParent = nIndex;
748 					break;
749 				}
750 			}
751 		}
752     }
753 
754     return nIndexInParent;
755 }
756 
757 // -----------------------------------------------------------------------------
758 
759 sal_Int16 SAL_CALL ToolbarMenuEntryAcc::getAccessibleRole() throw (RuntimeException)
760 {
761     return AccessibleRole::LIST_ITEM;
762 }
763 
764 // -----------------------------------------------------------------------------
765 
766 ::rtl::OUString SAL_CALL ToolbarMenuEntryAcc::getAccessibleDescription() throw (RuntimeException)
767 {
768 	return ::rtl::OUString();
769 }
770 
771 // -----------------------------------------------------------------------------
772 
773 ::rtl::OUString SAL_CALL ToolbarMenuEntryAcc::getAccessibleName() throw (RuntimeException)
774 {
775     const vos::OGuard   aSolarGuard( Application::GetSolarMutex() );
776     String              aRet;
777 
778     if( mpParent )
779     {
780         aRet = mpParent->maText;
781 
782         if( !aRet.Len() )
783         {
784             aRet = String( RTL_CONSTASCII_USTRINGPARAM( "Item " ) );
785             aRet += String::CreateFromInt32( mpParent->mnEntryId );
786         }
787     }
788 
789     return aRet;
790 }
791 
792 // -----------------------------------------------------------------------------
793 
794 Reference< XAccessibleRelationSet > SAL_CALL ToolbarMenuEntryAcc::getAccessibleRelationSet() throw (RuntimeException)
795 {
796     return Reference< XAccessibleRelationSet >();
797 }
798 
799 // -----------------------------------------------------------------------------
800 
801 Reference< XAccessibleStateSet > SAL_CALL ToolbarMenuEntryAcc::getAccessibleStateSet() throw (RuntimeException)
802 {
803     const vos::OGuard                   aSolarGuard( Application::GetSolarMutex() );
804     ::utl::AccessibleStateSetHelper*    pStateSet = new ::utl::AccessibleStateSetHelper;
805 
806     if( mpParent )
807     {
808         pStateSet->AddState (AccessibleStateType::ENABLED);
809         pStateSet->AddState (AccessibleStateType::SENSITIVE);
810         pStateSet->AddState (AccessibleStateType::SHOWING);
811         pStateSet->AddState (AccessibleStateType::VISIBLE);
812         pStateSet->AddState (AccessibleStateType::TRANSIENT);
813 		if( mpParent->mnEntryId != TITLE_ID )
814 		{
815 			pStateSet->AddState( AccessibleStateType::SELECTABLE );
816 
817 			// SELECTED
818 			if( mpParent->mrMenu.getHighlightedEntryId() == mpParent->mnEntryId )
819 				pStateSet->AddState( AccessibleStateType::SELECTED );
820 		}
821     }
822 
823     return pStateSet;
824 }
825 
826 // -----------------------------------------------------------------------------
827 
828 Locale SAL_CALL ToolbarMenuEntryAcc::getLocale() throw (IllegalAccessibleComponentStateException, RuntimeException)
829 {
830     const ::rtl::OUString aEmptyStr;
831     Locale aRet( aEmptyStr, aEmptyStr, aEmptyStr );
832 
833 	Reference< XAccessible > xParent( getAccessibleParent() );
834     if( xParent.is() )
835     {
836         Reference< XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
837 
838         if( xParentContext.is() )
839             aRet = xParentContext->getLocale();
840     }
841 
842     return aRet;
843 }
844 
845 // -----------------------------------------------------------------------------
846 
847 void SAL_CALL ToolbarMenuEntryAcc::addEventListener( const Reference< XAccessibleEventListener >& rxListener ) throw (RuntimeException)
848 {
849     const ::vos::OGuard aGuard( maMutex );
850 
851 	if( rxListener.is() )
852     {
853        	EventListenerVector::const_iterator aIter( mxEventListeners.begin() );
854 		bool bFound = false;
855 
856 		while( !bFound && ( aIter != mxEventListeners.end() ) )
857         {
858 			if( *aIter == rxListener )
859                 bFound = true;
860             else
861                 aIter++;
862         }
863 
864 		if (!bFound)
865             mxEventListeners.push_back( rxListener );
866     }
867 }
868 
869 // -----------------------------------------------------------------------------
870 
871 void SAL_CALL ToolbarMenuEntryAcc::removeEventListener( const Reference< XAccessibleEventListener >& rxListener ) throw (RuntimeException)
872 {
873     const ::vos::OGuard aGuard( maMutex );
874 
875 	if( rxListener.is() )
876     {
877        	EventListenerVector::iterator aIter = mxEventListeners.begin();
878 		bool bFound = false;
879 
880 		while( !bFound && ( aIter != mxEventListeners.end() ) )
881         {
882 			if( *aIter == rxListener )
883             {
884                 mxEventListeners.erase( aIter );
885                 bFound = true;
886             }
887             else
888                 aIter++;
889         }
890     }
891 }
892 
893 // -----------------------------------------------------------------------------
894 
895 sal_Bool SAL_CALL ToolbarMenuEntryAcc::containsPoint( const awt::Point& aPoint ) throw (RuntimeException)
896 {
897     const awt::Rectangle    aRect( getBounds() );
898     const Point             aSize( aRect.Width, aRect.Height );
899     const Point             aNullPoint, aTestPoint( aPoint.X, aPoint.Y );
900 
901     return Rectangle( aNullPoint, aSize ).IsInside( aTestPoint );
902 }
903 
904 // -----------------------------------------------------------------------------
905 
906 Reference< XAccessible > SAL_CALL ToolbarMenuEntryAcc::getAccessibleAtPoint( const awt::Point& ) throw (RuntimeException)
907 {
908     Reference< XAccessible > xRet;
909     return xRet;
910 }
911 
912 // -----------------------------------------------------------------------------
913 
914 awt::Rectangle SAL_CALL ToolbarMenuEntryAcc::getBounds() throw (RuntimeException)
915 {
916     const vos::OGuard   aSolarGuard( Application::GetSolarMutex() );
917     awt::Rectangle      aRet;
918 
919     if( mpParent )
920     {
921         Rectangle   aRect( mpParent->maRect );
922         Point       aOrigin;
923         Rectangle   aParentRect( aOrigin, mpParent->mrMenu.GetOutputSizePixel() );
924 
925         aRect.Intersection( aParentRect );
926 
927         aRet.X = aRect.Left();
928         aRet.Y = aRect.Top();
929         aRet.Width = aRect.GetWidth();
930         aRet.Height = aRect.GetHeight();
931     }
932 
933     return aRet;
934 }
935 
936 // -----------------------------------------------------------------------------
937 
938 awt::Point SAL_CALL ToolbarMenuEntryAcc::getLocation() throw (RuntimeException)
939 {
940     const awt::Rectangle aRect( getBounds() );
941     return awt::Point( aRect.X, aRect.Y );
942 }
943 
944 // -----------------------------------------------------------------------------
945 
946 awt::Point SAL_CALL ToolbarMenuEntryAcc::getLocationOnScreen() throw (RuntimeException)
947 {
948     const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
949     awt::Point aRet;
950 
951     if( mpParent )
952     {
953         const Point aScreenPos( mpParent->mrMenu.OutputToAbsoluteScreenPixel( mpParent->maRect.TopLeft() ) );
954 
955         aRet.X = aScreenPos.X();
956         aRet.Y = aScreenPos.Y();
957     }
958 
959     return aRet;
960 }
961 
962 // -----------------------------------------------------------------------------
963 
964 awt::Size SAL_CALL ToolbarMenuEntryAcc::getSize() throw (RuntimeException)
965 {
966     const awt::Rectangle aRect( getBounds() );
967     awt::Size aRet;
968 
969     aRet.Width = aRect.Width;
970     aRet.Height = aRect.Height;
971 
972     return aRet;
973 }
974 
975 // -----------------------------------------------------------------------------
976 
977 void SAL_CALL ToolbarMenuEntryAcc::grabFocus() throw (RuntimeException)
978 {
979     // nothing to do
980 }
981 
982 // -----------------------------------------------------------------------------
983 
984 Any SAL_CALL ToolbarMenuEntryAcc::getAccessibleKeyBinding() throw (RuntimeException)
985 {
986     return Any();
987 }
988 
989 // -----------------------------------------------------------------------------
990 
991 sal_Int32 SAL_CALL ToolbarMenuEntryAcc::getForeground(  ) throw (RuntimeException)
992 {
993     return static_cast<sal_Int32>(Application::GetSettings().GetStyleSettings().GetMenuTextColor().GetColor());
994 }
995 
996 // -----------------------------------------------------------------------------
997 
998 sal_Int32 SAL_CALL ToolbarMenuEntryAcc::getBackground(  )  throw (RuntimeException)
999 {
1000     return static_cast<sal_Int32>(Application::GetSettings().GetStyleSettings().GetMenuColor().GetColor());
1001 }
1002 
1003 }
1004