xref: /trunk/main/accessibility/source/standard/accessiblemenubasecomponent.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb) !
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_accessibility.hxx"
30 
31 // includes --------------------------------------------------------------
32 #include <accessibility/standard/accessiblemenubasecomponent.hxx>
33 #include <accessibility/standard/vclxaccessiblemenu.hxx>
34 #include <accessibility/standard/vclxaccessiblemenuitem.hxx>
35 #include <accessibility/standard/vclxaccessiblemenuseparator.hxx>
36 #include <toolkit/helper/externallock.hxx>
37 #include <toolkit/helper/convert.hxx>
38 
39 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
40 #include <com/sun/star/accessibility/AccessibleRole.hpp>
41 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
42 
43 #include <unotools/accessiblestatesethelper.hxx>
44 #include <vcl/svapp.hxx>
45 #include <vcl/window.hxx>
46 #include <vcl/menu.hxx>
47 #include <tools/debug.hxx>
48 
49 using namespace ::com::sun::star;
50 using namespace ::com::sun::star::lang;
51 using namespace ::com::sun::star::uno;
52 using namespace ::com::sun::star::accessibility;
53 using namespace ::comphelper;
54 
55 
56 // -----------------------------------------------------------------------------
57 // OAccessibleMenuBaseComponent
58 // -----------------------------------------------------------------------------
59 
60 OAccessibleMenuBaseComponent::OAccessibleMenuBaseComponent( Menu* pMenu )
61     :AccessibleExtendedComponentHelper_BASE( new VCLExternalSolarLock() )
62     ,m_pMenu( pMenu )
63     ,m_bEnabled( sal_False )
64     ,m_bFocused( sal_False )
65     ,m_bVisible( sal_False )
66     ,m_bSelected( sal_False )
67     ,m_bChecked( sal_False )
68 {
69     m_pExternalLock = static_cast< VCLExternalSolarLock* >( getExternalLock() );
70 
71     if ( m_pMenu )
72     {
73         m_aAccessibleChildren.assign( m_pMenu->GetItemCount(), Reference< XAccessible >() );
74         m_pMenu->AddEventListener( LINK( this, OAccessibleMenuBaseComponent, MenuEventListener ) );
75     }
76 }
77 
78 // -----------------------------------------------------------------------------
79 
80 OAccessibleMenuBaseComponent::~OAccessibleMenuBaseComponent()
81 {
82     if ( m_pMenu )
83         m_pMenu->RemoveEventListener( LINK( this, OAccessibleMenuBaseComponent, MenuEventListener ) );
84 
85     delete m_pExternalLock;
86     m_pExternalLock = NULL;
87 }
88 
89 // -----------------------------------------------------------------------------
90 
91 sal_Bool OAccessibleMenuBaseComponent::IsEnabled()
92 {
93     return sal_False;
94 }
95 
96 // -----------------------------------------------------------------------------
97 
98 sal_Bool OAccessibleMenuBaseComponent::IsFocused()
99 {
100     return sal_False;
101 }
102 
103 // -----------------------------------------------------------------------------
104 
105 sal_Bool OAccessibleMenuBaseComponent::IsVisible()
106 {
107     return sal_False;
108 }
109 
110 // -----------------------------------------------------------------------------
111 
112 sal_Bool OAccessibleMenuBaseComponent::IsSelected()
113 {
114     return sal_False;
115 }
116 
117 // -----------------------------------------------------------------------------
118 
119 sal_Bool OAccessibleMenuBaseComponent::IsChecked()
120 {
121     return sal_False;
122 }
123 
124 // -----------------------------------------------------------------------------
125 
126 void OAccessibleMenuBaseComponent::SetStates()
127 {
128     m_bEnabled = IsEnabled();
129     m_bFocused = IsFocused();
130     m_bVisible = IsVisible();
131     m_bSelected = IsSelected();
132     m_bChecked = IsChecked();
133 }
134 
135 // -----------------------------------------------------------------------------
136 
137 void OAccessibleMenuBaseComponent::SetEnabled( sal_Bool bEnabled )
138 {
139     if ( m_bEnabled != bEnabled )
140     {
141         Any aOldValue[2], aNewValue[2];
142         if ( m_bEnabled )
143         {
144             aOldValue[0] <<= AccessibleStateType::SENSITIVE;
145             aOldValue[1] <<= AccessibleStateType::ENABLED;
146         }
147         else
148         {
149             aNewValue[0] <<= AccessibleStateType::ENABLED;
150             aNewValue[1] <<= AccessibleStateType::SENSITIVE;
151         }
152         m_bEnabled = bEnabled;
153         NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue[0], aNewValue[0] );
154         NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue[1], aNewValue[1] );
155     }
156 }
157 
158 // -----------------------------------------------------------------------------
159 
160 void OAccessibleMenuBaseComponent::SetFocused( sal_Bool bFocused )
161 {
162     if ( m_bFocused != bFocused )
163     {
164         Any aOldValue, aNewValue;
165         if ( m_bFocused )
166             aOldValue <<= AccessibleStateType::FOCUSED;
167         else
168             aNewValue <<= AccessibleStateType::FOCUSED;
169         m_bFocused = bFocused;
170         NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
171     }
172 }
173 
174 // -----------------------------------------------------------------------------
175 
176 void OAccessibleMenuBaseComponent::SetVisible( sal_Bool bVisible )
177 {
178     if ( m_bVisible != bVisible )
179     {
180         Any aOldValue, aNewValue;
181         if ( m_bVisible )
182             aOldValue <<= AccessibleStateType::VISIBLE;
183         else
184             aNewValue <<= AccessibleStateType::VISIBLE;
185         m_bVisible = bVisible;
186         NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
187     }
188 }
189 
190 // -----------------------------------------------------------------------------
191 
192 void OAccessibleMenuBaseComponent::SetSelected( sal_Bool bSelected )
193 {
194     if ( m_bSelected != bSelected )
195     {
196         Any aOldValue, aNewValue;
197         if ( m_bSelected )
198             aOldValue <<= AccessibleStateType::SELECTED;
199         else
200             aNewValue <<= AccessibleStateType::SELECTED;
201         m_bSelected = bSelected;
202         NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
203     }
204 }
205 
206 // -----------------------------------------------------------------------------
207 
208 void OAccessibleMenuBaseComponent::SetChecked( sal_Bool bChecked )
209 {
210     if ( m_bChecked != bChecked )
211     {
212         Any aOldValue, aNewValue;
213         if ( m_bChecked )
214             aOldValue <<= AccessibleStateType::CHECKED;
215         else
216             aNewValue <<= AccessibleStateType::CHECKED;
217         m_bChecked = bChecked;
218         NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
219     }
220 }
221 
222 // -----------------------------------------------------------------------------
223 
224 void OAccessibleMenuBaseComponent::UpdateEnabled( sal_Int32 i, sal_Bool bEnabled )
225 {
226     if ( i >= 0 && i < (sal_Int32)m_aAccessibleChildren.size() )
227     {
228         Reference< XAccessible > xChild( m_aAccessibleChildren[i] );
229         if ( xChild.is() )
230         {
231             OAccessibleMenuBaseComponent* pComp = static_cast< OAccessibleMenuBaseComponent* >( xChild.get() );
232             if ( pComp )
233                 pComp->SetEnabled( bEnabled );
234         }
235     }
236 }
237 
238 // -----------------------------------------------------------------------------
239 
240 void OAccessibleMenuBaseComponent::UpdateFocused( sal_Int32 i, sal_Bool bFocused )
241 {
242     if ( i >= 0 && i < (sal_Int32)m_aAccessibleChildren.size() )
243     {
244         Reference< XAccessible > xChild( m_aAccessibleChildren[i] );
245         if ( xChild.is() )
246         {
247             OAccessibleMenuBaseComponent* pComp = static_cast< OAccessibleMenuBaseComponent* >( xChild.get() );
248             if ( pComp )
249                 pComp->SetFocused( bFocused );
250         }
251     }
252 }
253 
254 // -----------------------------------------------------------------------------
255 
256 void OAccessibleMenuBaseComponent::UpdateVisible()
257 {
258     SetVisible( IsVisible() );
259     for ( sal_uInt32 i = 0; i < m_aAccessibleChildren.size(); ++i )
260     {
261         Reference< XAccessible > xChild( m_aAccessibleChildren[i] );
262         if ( xChild.is() )
263         {
264             OAccessibleMenuBaseComponent* pComp = static_cast< OAccessibleMenuBaseComponent* >( xChild.get() );
265             if ( pComp )
266                 pComp->SetVisible( pComp->IsVisible() );
267         }
268     }
269 }
270 
271 // -----------------------------------------------------------------------------
272 
273 void OAccessibleMenuBaseComponent::UpdateSelected( sal_Int32 i, sal_Bool bSelected )
274 {
275     NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() );
276 
277     if ( i >= 0 && i < (sal_Int32)m_aAccessibleChildren.size() )
278     {
279         Reference< XAccessible > xChild( m_aAccessibleChildren[i] );
280         if ( xChild.is() )
281         {
282             OAccessibleMenuBaseComponent* pComp = static_cast< OAccessibleMenuBaseComponent* >( xChild.get() );
283             if ( pComp )
284                 pComp->SetSelected( bSelected );
285         }
286     }
287 }
288 
289 // -----------------------------------------------------------------------------
290 
291 void OAccessibleMenuBaseComponent::UpdateChecked( sal_Int32 i, sal_Bool bChecked )
292 {
293     if ( i >= 0 && i < (sal_Int32)m_aAccessibleChildren.size() )
294     {
295         Reference< XAccessible > xChild( m_aAccessibleChildren[i] );
296         if ( xChild.is() )
297         {
298             OAccessibleMenuBaseComponent* pComp = static_cast< OAccessibleMenuBaseComponent* >( xChild.get() );
299             if ( pComp )
300                 pComp->SetChecked( bChecked );
301         }
302     }
303 }
304 
305 // -----------------------------------------------------------------------------
306 
307 void OAccessibleMenuBaseComponent::UpdateAccessibleName( sal_Int32 i )
308 {
309     if ( i >= 0 && i < (sal_Int32)m_aAccessibleChildren.size() )
310     {
311         Reference< XAccessible > xChild( m_aAccessibleChildren[i] );
312         if ( xChild.is() )
313         {
314             OAccessibleMenuItemComponent* pComp = static_cast< OAccessibleMenuItemComponent* >( xChild.get() );
315             if ( pComp )
316                 pComp->SetAccessibleName( pComp->GetAccessibleName() );
317         }
318     }
319 }
320 
321 // -----------------------------------------------------------------------------
322 
323 void OAccessibleMenuBaseComponent::UpdateItemText( sal_Int32 i )
324 {
325     if ( i >= 0 && i < (sal_Int32)m_aAccessibleChildren.size() )
326     {
327         Reference< XAccessible > xChild( m_aAccessibleChildren[i] );
328         if ( xChild.is() )
329         {
330             OAccessibleMenuItemComponent* pComp = static_cast< OAccessibleMenuItemComponent* >( xChild.get() );
331             if ( pComp )
332                 pComp->SetItemText( pComp->GetItemText() );
333         }
334     }
335 }
336 
337 // -----------------------------------------------------------------------------
338 
339 sal_Int32 OAccessibleMenuBaseComponent::GetChildCount()
340 {
341     return m_aAccessibleChildren.size();
342 }
343 
344 // -----------------------------------------------------------------------------
345 
346 Reference< XAccessible > OAccessibleMenuBaseComponent::GetChild( sal_Int32 i )
347 {
348     Reference< XAccessible > xChild = m_aAccessibleChildren[i];
349     if ( !xChild.is() )
350     {
351         if ( m_pMenu )
352         {
353             // create a new child
354             OAccessibleMenuBaseComponent* pChild;
355 
356             if ( m_pMenu->GetItemType( (sal_uInt16)i ) == MENUITEM_SEPARATOR )
357             {
358                 pChild = new VCLXAccessibleMenuSeparator( m_pMenu, (sal_uInt16)i );
359             }
360             else
361             {
362                 PopupMenu* pPopupMenu = m_pMenu->GetPopupMenu( m_pMenu->GetItemId( (sal_uInt16)i ) );
363                 if ( pPopupMenu )
364                 {
365                     pChild = new VCLXAccessibleMenu( m_pMenu, (sal_uInt16)i, pPopupMenu );
366                     pPopupMenu->SetAccessible( pChild );
367                 }
368                 else
369                 {
370                     pChild = new VCLXAccessibleMenuItem( m_pMenu, (sal_uInt16)i );
371                 }
372             }
373 
374             // set states
375             pChild->SetStates();
376 
377             xChild = pChild;
378 
379             // insert into menu item list
380             m_aAccessibleChildren[i] = xChild;
381         }
382     }
383 
384     return xChild;
385 }
386 
387 // -----------------------------------------------------------------------------
388 
389 Reference< XAccessible > OAccessibleMenuBaseComponent::GetChildAt( const awt::Point& rPoint )
390 {
391     Reference< XAccessible > xChild;
392     for ( sal_uInt32 i = 0, nCount = getAccessibleChildCount(); i < nCount; ++i )
393     {
394         Reference< XAccessible > xAcc = getAccessibleChild( i );
395         if ( xAcc.is() )
396         {
397             Reference< XAccessibleComponent > xComp( xAcc->getAccessibleContext(), UNO_QUERY );
398             if ( xComp.is() )
399             {
400                 Rectangle aRect = VCLRectangle( xComp->getBounds() );
401                 Point aPos = VCLPoint( rPoint );
402                 if ( aRect.IsInside( aPos ) )
403                 {
404                     xChild = xAcc;
405                     break;
406                 }
407             }
408         }
409     }
410 
411     return xChild;
412 }
413 
414 // -----------------------------------------------------------------------------
415 
416 void OAccessibleMenuBaseComponent::InsertChild( sal_Int32 i )
417 {
418     if ( i > (sal_Int32)m_aAccessibleChildren.size() )
419         i = m_aAccessibleChildren.size();
420 
421     if ( i >= 0 )
422     {
423         // insert entry in child list
424         m_aAccessibleChildren.insert( m_aAccessibleChildren.begin() + i, Reference< XAccessible >() );
425 
426         // update item position of accessible children
427         for ( sal_uInt32 j = i, nCount = m_aAccessibleChildren.size(); j < nCount; ++j )
428         {
429             Reference< XAccessible > xAcc( m_aAccessibleChildren[j] );
430             if ( xAcc.is() )
431             {
432                 OAccessibleMenuItemComponent* pComp = static_cast< OAccessibleMenuItemComponent* >( xAcc.get() );
433                 if ( pComp )
434                     pComp->SetItemPos( (sal_uInt16)j );
435             }
436         }
437 
438         // send accessible child event
439         Reference< XAccessible > xChild( GetChild( i ) );
440         if ( xChild.is() )
441         {
442             Any aOldValue, aNewValue;
443             aNewValue <<= xChild;
444             NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue );
445         }
446     }
447 }
448 
449 // -----------------------------------------------------------------------------
450 
451 void OAccessibleMenuBaseComponent::RemoveChild( sal_Int32 i )
452 {
453     if ( i >= 0 && i < (sal_Int32)m_aAccessibleChildren.size() )
454     {
455         // keep the accessible of the removed item
456         Reference< XAccessible > xChild( m_aAccessibleChildren[i] );
457 
458         // remove entry in child list
459         m_aAccessibleChildren.erase( m_aAccessibleChildren.begin() + i );
460 
461         // update item position of accessible children
462         for ( sal_uInt32 j = i, nCount = m_aAccessibleChildren.size(); j < nCount; ++j )
463         {
464             Reference< XAccessible > xAcc( m_aAccessibleChildren[j] );
465             if ( xAcc.is() )
466             {
467                 OAccessibleMenuItemComponent* pComp = static_cast< OAccessibleMenuItemComponent* >( xAcc.get() );
468                 if ( pComp )
469                     pComp->SetItemPos( (sal_uInt16)j );
470             }
471         }
472 
473         // send accessible child event
474         if ( xChild.is() )
475         {
476             Any aOldValue, aNewValue;
477             aOldValue <<= xChild;
478             NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue );
479 
480             Reference< XComponent > xComponent( xChild, UNO_QUERY );
481             if ( xComponent.is() )
482                 xComponent->dispose();
483         }
484     }
485 }
486 
487 // -----------------------------------------------------------------------------
488 
489 sal_Bool OAccessibleMenuBaseComponent::IsHighlighted()
490 {
491     return sal_False;
492 }
493 
494 // -----------------------------------------------------------------------------
495 
496 sal_Bool OAccessibleMenuBaseComponent::IsChildHighlighted()
497 {
498     sal_Bool bChildHighlighted = sal_False;
499 
500     for ( sal_uInt32 i = 0; i < m_aAccessibleChildren.size(); ++i )
501     {
502         Reference< XAccessible > xChild( m_aAccessibleChildren[i] );
503         if ( xChild.is() )
504         {
505             OAccessibleMenuBaseComponent* pComp = static_cast< OAccessibleMenuBaseComponent* >( xChild.get() );
506             if ( pComp && pComp->IsHighlighted() )
507             {
508                 bChildHighlighted = sal_True;
509                 break;
510             }
511         }
512     }
513 
514     return bChildHighlighted;
515 }
516 
517 // -----------------------------------------------------------------------------
518 
519 void OAccessibleMenuBaseComponent::SelectChild( sal_Int32 i )
520 {
521     // open the menu
522     if ( getAccessibleRole() == AccessibleRole::MENU && !IsPopupMenuOpen() )
523         Click();
524 
525     // highlight the child
526     if ( m_pMenu )
527         m_pMenu->HighlightItem( (sal_uInt16)i );
528 }
529 
530 // -----------------------------------------------------------------------------
531 
532 void OAccessibleMenuBaseComponent::DeSelectAll()
533 {
534     if ( m_pMenu )
535         m_pMenu->DeHighlight();
536 }
537 
538 // -----------------------------------------------------------------------------
539 
540 sal_Bool OAccessibleMenuBaseComponent::IsChildSelected( sal_Int32 i )
541 {
542     sal_Bool bSelected = sal_False;
543 
544     if ( m_pMenu && m_pMenu->IsHighlighted( (sal_uInt16)i ) )
545         bSelected = sal_True;
546 
547     return bSelected;
548 }
549 
550 // -----------------------------------------------------------------------------
551 
552 void OAccessibleMenuBaseComponent::Select()
553 {
554 }
555 
556 // -----------------------------------------------------------------------------
557 
558 void OAccessibleMenuBaseComponent::DeSelect()
559 {
560 }
561 
562 // -----------------------------------------------------------------------------
563 
564 void OAccessibleMenuBaseComponent::Click()
565 {
566 }
567 
568 // -----------------------------------------------------------------------------
569 
570 sal_Bool OAccessibleMenuBaseComponent::IsPopupMenuOpen()
571 {
572     return sal_False;
573 }
574 
575 // -----------------------------------------------------------------------------
576 
577 IMPL_LINK( OAccessibleMenuBaseComponent, MenuEventListener, VclSimpleEvent*, pEvent )
578 {
579     DBG_ASSERT( pEvent && pEvent->ISA( VclMenuEvent ), "OAccessibleMenuBaseComponent - Unknown MenuEvent!" );
580     if ( pEvent && pEvent->ISA( VclMenuEvent ) )
581     {
582         DBG_ASSERT( ((VclMenuEvent*)pEvent)->GetMenu(), "OAccessibleMenuBaseComponent - Menu?" );
583         ProcessMenuEvent( *(VclMenuEvent*)pEvent );
584     }
585     return 0;
586 }
587 
588 // -----------------------------------------------------------------------------
589 
590 void OAccessibleMenuBaseComponent::ProcessMenuEvent( const VclMenuEvent& rVclMenuEvent )
591 {
592     sal_uInt16 nItemPos = rVclMenuEvent.GetItemPos();
593 
594     switch ( rVclMenuEvent.GetId() )
595     {
596         case VCLEVENT_MENU_SHOW:
597         case VCLEVENT_MENU_HIDE:
598         {
599             UpdateVisible();
600         }
601         break;
602         case VCLEVENT_MENU_HIGHLIGHT:
603         {
604             SetFocused( sal_False );
605             UpdateFocused( nItemPos, sal_True );
606             UpdateSelected( nItemPos, sal_True );
607         }
608         break;
609         case VCLEVENT_MENU_DEHIGHLIGHT:
610         {
611             UpdateFocused( nItemPos, sal_False );
612             UpdateSelected( nItemPos, sal_False );
613         }
614         break;
615         case VCLEVENT_MENU_SUBMENUACTIVATE:
616         {
617         }
618         break;
619         case VCLEVENT_MENU_SUBMENUDEACTIVATE:
620         {
621             UpdateFocused( nItemPos, sal_True );
622         }
623         break;
624         case VCLEVENT_MENU_ENABLE:
625         {
626             UpdateEnabled( nItemPos, sal_True );
627         }
628         break;
629         case VCLEVENT_MENU_DISABLE:
630         {
631             UpdateEnabled( nItemPos, sal_False );
632         }
633         break;
634         case VCLEVENT_MENU_SUBMENUCHANGED:
635         {
636             RemoveChild( nItemPos );
637             InsertChild( nItemPos );
638         }
639         break;
640         case VCLEVENT_MENU_INSERTITEM:
641         {
642             InsertChild( nItemPos );
643         }
644         break;
645         case VCLEVENT_MENU_REMOVEITEM:
646         {
647             RemoveChild( nItemPos );
648         }
649         break;
650         case VCLEVENT_MENU_ACCESSIBLENAMECHANGED:
651         {
652             UpdateAccessibleName( nItemPos );
653         }
654         break;
655         case VCLEVENT_MENU_ITEMTEXTCHANGED:
656         {
657             UpdateAccessibleName( nItemPos );
658             UpdateItemText( nItemPos );
659         }
660         break;
661         case VCLEVENT_MENU_ITEMCHECKED:
662         {
663             UpdateChecked( nItemPos, sal_True );
664         }
665         break;
666         case VCLEVENT_MENU_ITEMUNCHECKED:
667         {
668             UpdateChecked( nItemPos, sal_False );
669         }
670         break;
671         case VCLEVENT_OBJECT_DYING:
672         {
673             if ( m_pMenu )
674             {
675                 m_pMenu->RemoveEventListener( LINK( this, OAccessibleMenuBaseComponent, MenuEventListener ) );
676 
677                 m_pMenu = NULL;
678 
679                 // dispose all menu items
680                 for ( sal_uInt32 i = 0; i < m_aAccessibleChildren.size(); ++i )
681                 {
682                     Reference< XComponent > xComponent( m_aAccessibleChildren[i], UNO_QUERY );
683                     if ( xComponent.is() )
684                         xComponent->dispose();
685                 }
686                 m_aAccessibleChildren.clear();
687             }
688         }
689         break;
690         default:
691         {
692         }
693         break;
694     }
695 }
696 
697 // -----------------------------------------------------------------------------
698 // XInterface
699 // -----------------------------------------------------------------------------
700 
701 IMPLEMENT_FORWARD_XINTERFACE2( OAccessibleMenuBaseComponent, AccessibleExtendedComponentHelper_BASE, OAccessibleMenuBaseComponent_BASE )
702 
703 // -----------------------------------------------------------------------------
704 // XTypeProvider
705 // -----------------------------------------------------------------------------
706 
707 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleMenuBaseComponent, AccessibleExtendedComponentHelper_BASE, OAccessibleMenuBaseComponent_BASE )
708 
709 // -----------------------------------------------------------------------------
710 // XComponent
711 // -----------------------------------------------------------------------------
712 
713 void OAccessibleMenuBaseComponent::disposing()
714 {
715     AccessibleExtendedComponentHelper_BASE::disposing();
716 
717     if ( m_pMenu )
718     {
719         m_pMenu->RemoveEventListener( LINK( this, OAccessibleMenuBaseComponent, MenuEventListener ) );
720 
721         m_pMenu = NULL;
722 
723         // dispose all menu items
724         for ( sal_uInt32 i = 0; i < m_aAccessibleChildren.size(); ++i )
725         {
726             Reference< XComponent > xComponent( m_aAccessibleChildren[i], UNO_QUERY );
727             if ( xComponent.is() )
728                 xComponent->dispose();
729         }
730         m_aAccessibleChildren.clear();
731     }
732 }
733 
734 // -----------------------------------------------------------------------------
735 // XServiceInfo
736 // -----------------------------------------------------------------------------
737 
738 sal_Bool OAccessibleMenuBaseComponent::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException)
739 {
740     Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() );
741     const ::rtl::OUString* pNames = aNames.getConstArray();
742     const ::rtl::OUString* pEnd = pNames + aNames.getLength();
743     for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames )
744         ;
745 
746     return pNames != pEnd;
747 }
748 
749 // -----------------------------------------------------------------------------
750 // XAccessible
751 // -----------------------------------------------------------------------------
752 
753 Reference< XAccessibleContext > OAccessibleMenuBaseComponent::getAccessibleContext(  ) throw (RuntimeException)
754 {
755     OExternalLockGuard aGuard( this );
756 
757     return this;
758 }
759 
760 // -----------------------------------------------------------------------------
761 // XAccessibleContext
762 // -----------------------------------------------------------------------------
763 
764 Reference< XAccessibleStateSet > OAccessibleMenuBaseComponent::getAccessibleStateSet(  ) throw (RuntimeException)
765 {
766     OExternalLockGuard aGuard( this );
767 
768     utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper;
769     Reference< XAccessibleStateSet > xSet = pStateSetHelper;
770 
771     if ( !rBHelper.bDisposed && !rBHelper.bInDispose )
772     {
773         FillAccessibleStateSet( *pStateSetHelper );
774     }
775     else
776     {
777         pStateSetHelper->AddState( AccessibleStateType::DEFUNC );
778     }
779 
780     return xSet;
781 }
782 
783 // -----------------------------------------------------------------------------
784