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