xref: /AOO41X/main/svtools/source/control/toolbarmenuacc.cxx (revision 5900e8ec128faec89519683efce668ccd8cc6084)
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