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