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