1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 #include "AccessibleFrameSelector.hxx"
31 #include <com/sun/star/awt/KeyEvent.hpp>
32 #include <com/sun/star/awt/KeyModifier.hpp>
33 #include <com/sun/star/awt/Key.hpp>
34 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLESTATETYPE_HDL_
35 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
36 #endif
37 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLERELATIONTYPE_HDL_
38 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
39 #endif
40 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLEROLE_HDL_
41 #include <com/sun/star/accessibility/AccessibleRole.hpp>
42 #endif
43 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
44 #include <com/sun/star/awt/FocusChangeReason.hpp>
45 #include <unotools/accessiblestatesethelper.hxx>
46 #include <unotools/accessiblerelationsethelper.hxx>
47 #include <vos/mutex.hxx>
48 #include <vcl/svapp.hxx>
49 #include <svx/frmsel.hxx>
50 #include <svx/dialmgr.hxx>
51 #include "editeng/unolingu.hxx"
52 
53 #ifndef _SVX_DIALOGS_HRC
54 #include <svx/dialogs.hrc>
55 #endif
56 #ifndef SVX_FRMSEL_HRC
57 #include "frmsel.hrc"
58 #endif
59 
60 #ifndef MNEMONIC_CHAR
61 #define MNEMONIC_CHAR ((sal_Unicode)'~')
62 #endif
63 
64 namespace svx {
65 namespace a11y {
66 
67 using ::rtl::OUString;
68 using ::com::sun::star::uno::Any;
69 using ::com::sun::star::uno::UNO_QUERY;
70 using ::com::sun::star::uno::Reference;
71 using ::com::sun::star::uno::Sequence;
72 using ::com::sun::star::uno::RuntimeException;
73 using ::com::sun::star::uno::XInterface;
74 using ::com::sun::star::lang::Locale;
75 using ::com::sun::star::lang::EventObject;
76 using ::com::sun::star::beans::XPropertyChangeListener;
77 using ::com::sun::star::awt::XFocusListener;
78 
79 using namespace ::com::sun::star::accessibility;
80 
81 namespace AwtKey                    = ::com::sun::star::awt::Key;
82 namespace AwtKeyModifier            = ::com::sun::star::awt::KeyModifier;
83 namespace AwtFocusChangeReason      = ::com::sun::star::awt::FocusChangeReason;
84 
85 typedef ::com::sun::star::awt::Point        AwtPoint;
86 typedef ::com::sun::star::awt::Size         AwtSize;
87 typedef ::com::sun::star::awt::Rectangle    AwtRectangle;
88 typedef ::com::sun::star::awt::KeyEvent     AwtKeyEvent;
89 typedef ::com::sun::star::awt::FocusEvent   AwtFocusEvent;
90 
91 // ============================================================================
92 
93 AccFrameSelector::AccFrameSelector( FrameSelector& rFrameSel, FrameBorderType eBorder ) :
94     Resource( SVX_RES( RID_SVXSTR_BORDER_CONTROL ) ),
95     mpFrameSel( &rFrameSel ),
96     meBorder( eBorder ),
97     maFocusListeners( maFocusMutex ),
98     maPropertyListeners( maPropertyMutex ),
99     maNames( SVX_RES( ARR_TEXTS ) ),
100     maDescriptions( SVX_RES(ARR_DESCRIPTIONS ) ),
101     mnClientId( 0 )
102 {
103     FreeResource();
104 
105     if ( mpFrameSel )
106     {
107         mpFrameSel->AddEventListener( LINK( this, AccFrameSelector, WindowEventListener ) );
108     }
109 }
110 
111 // ----------------------------------------------------------------------------
112 
113 AccFrameSelector::~AccFrameSelector()
114 {
115     if ( mpFrameSel )
116     {
117         mpFrameSel->RemoveEventListener( LINK( this, AccFrameSelector, WindowEventListener ) );
118     }
119 }
120 
121 // ----------------------------------------------------------------------------
122 
123 Reference< XAccessibleContext > AccFrameSelector::getAccessibleContext(  )
124     throw (RuntimeException)
125 {
126     return this;
127 }
128 
129 // ----------------------------------------------------------------------------
130 
131 sal_Int32 AccFrameSelector::getAccessibleChildCount(  ) throw (RuntimeException)
132 {
133     vos::OGuard aGuard(Application::GetSolarMutex());
134     IsValid();
135     return (meBorder == FRAMEBORDER_NONE) ? mpFrameSel->GetEnabledBorderCount() : 0;
136 }
137 
138 // ----------------------------------------------------------------------------
139 
140 Reference< XAccessible > AccFrameSelector::getAccessibleChild( sal_Int32 i )
141     throw (RuntimeException)
142 {
143     vos::OGuard aGuard(Application::GetSolarMutex());
144     IsValid();
145     Reference< XAccessible > xRet;
146     if( meBorder == FRAMEBORDER_NONE )
147         xRet = mpFrameSel->GetChildAccessible( i );
148     if( !xRet.is() )
149         throw RuntimeException();
150     return xRet;
151 }
152 
153 // ----------------------------------------------------------------------------
154 
155 Reference< XAccessible > AccFrameSelector::getAccessibleParent(  )
156     throw (RuntimeException)
157 {
158     vos::OGuard aGuard(Application::GetSolarMutex());
159     IsValid();
160     Reference< XAccessible > xRet;
161     if(meBorder == FRAMEBORDER_NONE)
162         xRet = mpFrameSel->GetParent()->GetAccessible( sal_True );
163     else
164         xRet = mpFrameSel->CreateAccessible();
165     return xRet;
166 }
167 
168 // ----------------------------------------------------------------------------
169 
170 sal_Int32 AccFrameSelector::getAccessibleIndexInParent(  )
171     throw (RuntimeException)
172 {
173     vos::OGuard aGuard(Application::GetSolarMutex());
174     IsValid();
175 
176     sal_Int32 nIdx = 0;
177     if( meBorder == FRAMEBORDER_NONE )
178     {
179         Window* pTabPage = mpFrameSel->GetParent();
180         sal_Int32 nChildren = pTabPage->GetChildCount();
181         for( nIdx = 0; nIdx < nChildren; ++nIdx )
182             if( pTabPage->GetChild( static_cast< sal_uInt16 >( nIdx ) ) == mpFrameSel )
183                 break;
184     }
185     else
186         nIdx = mpFrameSel->GetEnabledBorderIndex( meBorder );
187 
188     if( nIdx < 0 )
189         throw RuntimeException();
190     return nIdx;
191 }
192 
193 // ----------------------------------------------------------------------------
194 
195 sal_Int16 AccFrameSelector::getAccessibleRole(  ) throw (RuntimeException)
196 {
197     return AccessibleRole::OPTION_PANE;
198 }
199 
200 // ----------------------------------------------------------------------------
201 
202 OUString AccFrameSelector::getAccessibleDescription(  )
203     throw (RuntimeException)
204 {
205     vos::OGuard aGuard(Application::GetSolarMutex());
206     IsValid();
207     return maDescriptions.GetString(meBorder);
208 }
209 
210 // ----------------------------------------------------------------------------
211 
212 OUString AccFrameSelector::getAccessibleName(  )
213     throw (RuntimeException)
214 {
215     vos::OGuard aGuard(Application::GetSolarMutex());
216     IsValid();
217     return maNames.GetString(meBorder);
218 }
219 
220 // ----------------------------------------------------------------------------
221 
222 Reference< XAccessibleRelationSet > AccFrameSelector::getAccessibleRelationSet(  )
223     throw (RuntimeException)
224 {
225     vos::OGuard aGuard(Application::GetSolarMutex());
226     IsValid();
227     utl::AccessibleRelationSetHelper* pHelper;
228     Reference< XAccessibleRelationSet > xRet = pHelper = new utl::AccessibleRelationSetHelper;
229     if(meBorder == FRAMEBORDER_NONE)
230     {
231         //add the label relation
232         Window* pPrev = mpFrameSel->GetWindow( WINDOW_PREV );
233         if(pPrev && WINDOW_FIXEDTEXT == pPrev->GetType())
234         {
235             AccessibleRelation aLabelRelation;
236             aLabelRelation.RelationType = AccessibleRelationType::LABELED_BY;
237             aLabelRelation.TargetSet.realloc(1);
238             aLabelRelation.TargetSet.getArray()[0]  = pPrev->GetAccessible();
239             pHelper->AddRelation(aLabelRelation);
240         }
241     }
242     return xRet;
243 }
244 
245 // ----------------------------------------------------------------------------
246 
247 Reference< XAccessibleStateSet > AccFrameSelector::getAccessibleStateSet(  )
248     throw (RuntimeException)
249 {
250     vos::OGuard aGuard(Application::GetSolarMutex());
251     utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper;
252     Reference< XAccessibleStateSet > xRet = pStateSetHelper;
253 
254     if(!mpFrameSel)
255         pStateSetHelper->AddState(AccessibleStateType::DEFUNC);
256     else
257     {
258         const sal_Int16 aStandardStates[] =
259         {
260             AccessibleStateType::EDITABLE,
261             AccessibleStateType::FOCUSABLE,
262             AccessibleStateType::MULTI_SELECTABLE,
263             AccessibleStateType::SELECTABLE,
264             AccessibleStateType::SHOWING,
265             AccessibleStateType::VISIBLE,
266             AccessibleStateType::OPAQUE,
267             0};
268         sal_Int16 nState = 0;
269         while(aStandardStates[nState])
270         {
271             pStateSetHelper->AddState(aStandardStates[nState++]);
272         }
273         if(mpFrameSel->IsEnabled())
274         {
275             pStateSetHelper->AddState(AccessibleStateType::ENABLED);
276             pStateSetHelper->AddState(AccessibleStateType::SENSITIVE);
277         }
278 
279         sal_Bool bIsParent = meBorder == FRAMEBORDER_NONE;
280         if(mpFrameSel->HasFocus() &&
281             (bIsParent || mpFrameSel->IsBorderSelected(meBorder)))
282         {
283             pStateSetHelper->AddState(AccessibleStateType::ACTIVE);
284             pStateSetHelper->AddState(AccessibleStateType::FOCUSED);
285             pStateSetHelper->AddState(AccessibleStateType::SELECTED);
286         }
287     }
288     return xRet;
289 }
290 
291 // ----------------------------------------------------------------------------
292 
293 Locale AccFrameSelector::getLocale(  )
294     throw (IllegalAccessibleComponentStateException, RuntimeException)
295 {
296     Locale aRet;
297     SvxLanguageToLocale( aRet, Application::GetSettings().GetUILanguage() );
298     return aRet;
299 }
300 
301 // ----------------------------------------------------------------------------
302 
303 void AccFrameSelector::addPropertyChangeListener(
304     const Reference< XPropertyChangeListener >& xListener )
305         throw (RuntimeException)
306 {
307     maPropertyListeners.addInterface( xListener );
308 }
309 
310 // ----------------------------------------------------------------------------
311 
312 void AccFrameSelector::removePropertyChangeListener( const Reference< XPropertyChangeListener >& xListener )
313     throw (RuntimeException)
314 {
315     maPropertyListeners.removeInterface( xListener );
316 }
317 
318 // ----------------------------------------------------------------------------
319 
320 sal_Bool AccFrameSelector::containsPoint( const AwtPoint& aPt )
321     throw (RuntimeException)
322 {
323     vos::OGuard aGuard(Application::GetSolarMutex());
324     IsValid();
325     //aPt is relative to the frame selector
326     return mpFrameSel->ContainsClickPoint( Point( aPt.X, aPt.Y ) );
327 }
328 
329 // ----------------------------------------------------------------------------
330 
331 Reference< XAccessible > AccFrameSelector::getAccessibleAtPoint(
332     const AwtPoint& aPt )
333         throw (RuntimeException)
334 {
335     vos::OGuard aGuard(Application::GetSolarMutex());
336     IsValid();
337     //aPt is relative to the frame selector
338     return mpFrameSel->GetChildAccessible( Point( aPt.X, aPt.Y ) );
339 }
340 
341 AwtRectangle AccFrameSelector::getBounds(  ) throw (RuntimeException)
342 {
343     vos::OGuard aGuard(Application::GetSolarMutex());
344     IsValid();
345     Size aSz;
346     Point aPos;
347     switch(meBorder)
348     {
349         case FRAMEBORDER_NONE:
350             aSz = mpFrameSel->GetSizePixel();
351             aPos = mpFrameSel->GetPosPixel();
352         break;
353         default:
354             const Rectangle aSpot = mpFrameSel->GetClickBoundRect( meBorder );
355             aPos = aSpot.TopLeft();
356             aSz = aSpot.GetSize();
357     }
358     AwtRectangle aRet;
359     aRet.X = aPos.X();
360     aRet.Y = aPos.Y();
361     aRet.Width = aSz.Width();
362     aRet.Height = aSz.Height();
363     return aRet;
364 }
365 
366 // ----------------------------------------------------------------------------
367 
368 AwtPoint AccFrameSelector::getLocation(  ) throw (RuntimeException)
369 {
370     vos::OGuard aGuard(Application::GetSolarMutex());
371     IsValid();
372     Point aPos;
373     switch(meBorder)
374     {
375         case FRAMEBORDER_NONE:
376             aPos = mpFrameSel->GetPosPixel();
377         break;
378         default:
379             const Rectangle aSpot = mpFrameSel->GetClickBoundRect( meBorder );
380             aPos = aSpot.TopLeft();
381     }
382     AwtPoint aRet(aPos.X(), aPos.Y());
383     return aRet;
384 }
385 
386 // ----------------------------------------------------------------------------
387 
388 AwtPoint AccFrameSelector::getLocationOnScreen(  ) throw (RuntimeException)
389 {
390     vos::OGuard aGuard(Application::GetSolarMutex());
391     IsValid();
392     Point aPos;
393     switch(meBorder)
394     {
395         case FRAMEBORDER_NONE:
396             aPos = mpFrameSel->GetPosPixel();
397         break;
398         default:
399             const Rectangle aSpot = mpFrameSel->GetClickBoundRect( meBorder );
400             aPos = aSpot.TopLeft();
401     }
402     aPos = mpFrameSel->OutputToAbsoluteScreenPixel( aPos );
403     AwtPoint aRet(aPos.X(), aPos.Y());
404     return aRet;
405 }
406 
407 // ----------------------------------------------------------------------------
408 
409 AwtSize AccFrameSelector::getSize(  ) throw (RuntimeException)
410 {
411     vos::OGuard aGuard(Application::GetSolarMutex());
412     IsValid();
413     Size aSz;
414     switch(meBorder)
415     {
416         case FRAMEBORDER_NONE:
417             aSz = mpFrameSel->GetSizePixel();
418         break;
419         default:
420             const Rectangle aSpot = mpFrameSel->GetClickBoundRect( meBorder );
421             aSz = aSpot.GetSize();
422     }
423     AwtSize aRet(aSz.Width(), aSz.Height());
424     return aRet;
425 }
426 
427 // ----------------------------------------------------------------------------
428 
429 sal_Bool AccFrameSelector::isShowing(  ) throw (RuntimeException)
430 {
431     vos::OGuard aGuard(Application::GetSolarMutex());
432     IsValid();
433     return sal_True;
434 }
435 
436 // ----------------------------------------------------------------------------
437 
438 sal_Bool AccFrameSelector::isVisible(  ) throw (RuntimeException)
439 {
440     vos::OGuard aGuard(Application::GetSolarMutex());
441     IsValid();
442     return sal_True;
443 }
444 
445 // ----------------------------------------------------------------------------
446 
447 sal_Bool AccFrameSelector::isFocusTraversable(  ) throw (RuntimeException)
448 {
449     vos::OGuard aGuard(Application::GetSolarMutex());
450     IsValid();
451     return sal_True;
452 }
453 
454 // ----------------------------------------------------------------------------
455 
456 void AccFrameSelector::addFocusListener( const Reference< XFocusListener >& xListener ) throw (RuntimeException)
457 {
458     maFocusListeners.addInterface( xListener );
459 }
460 
461 // ----------------------------------------------------------------------------
462 
463 void AccFrameSelector::removeFocusListener( const Reference< XFocusListener >& xListener ) throw (RuntimeException)
464 {
465     maFocusListeners.removeInterface( xListener );
466 }
467 
468 // ----------------------------------------------------------------------------
469 
470 void AccFrameSelector::grabFocus(  ) throw (RuntimeException)
471 {
472     vos::OGuard aGuard(Application::GetSolarMutex());
473     IsValid();
474     mpFrameSel->GrabFocus();
475 }
476 
477 // ----------------------------------------------------------------------------
478 
479 Any AccFrameSelector::getAccessibleKeyBinding(  ) throw (RuntimeException)
480 {
481     Any aRet;
482     vos::OGuard aGuard(Application::GetSolarMutex());
483     IsValid();
484     utl::AccessibleRelationSetHelper* pHelper;
485     Reference< XAccessibleRelationSet > xRet = pHelper = new utl::AccessibleRelationSetHelper;
486     if(meBorder == FRAMEBORDER_NONE)
487     {
488         Window* pPrev = mpFrameSel->GetWindow( WINDOW_PREV );
489         if(pPrev && WINDOW_FIXEDTEXT == pPrev->GetType())
490         {
491             String sText = pPrev->GetText();
492             xub_StrLen nFound = sText.Search( MNEMONIC_CHAR );
493             if(STRING_NOTFOUND != nFound && ++nFound < sText.Len())
494             {
495                 sText.ToUpperAscii();
496                 sal_Unicode cChar = sText.GetChar(nFound);
497                 AwtKeyEvent aEvent;
498 
499                 aEvent.KeyCode = 0;
500                 aEvent.KeyChar = cChar;
501                 aEvent.KeyFunc = 0;
502                 if(cChar >= 'A' && cChar <= 'Z')
503                 {
504                      aEvent.KeyCode = AwtKey::A + cChar - 'A';
505                 }
506                 aEvent.Modifiers = AwtKeyModifier::MOD2;
507                 aRet <<= aEvent;
508             }
509         }
510     }
511     return aRet;
512 }
513 
514 // ----------------------------------------------------------------------------
515 
516 sal_Int32 AccFrameSelector::getForeground(  )
517         throw (RuntimeException)
518 {
519     Any aRet;
520     vos::OGuard aGuard(Application::GetSolarMutex());
521     IsValid();
522     return mpFrameSel->GetControlForeground().GetColor();
523 }
524 
525 // ----------------------------------------------------------------------------
526 
527 sal_Int32 AccFrameSelector::getBackground(  )
528         throw (RuntimeException)
529 {
530     Any aRet;
531     vos::OGuard aGuard(Application::GetSolarMutex());
532     IsValid();
533     return mpFrameSel->GetControlBackground().GetColor();
534 }
535 
536 // ----------------------------------------------------------------------------
537 
538 void AccFrameSelector::addEventListener( const Reference< XAccessibleEventListener >& xListener ) throw (RuntimeException)
539 {
540     vos::OGuard aGuard( Application::GetSolarMutex() );
541 
542     if ( xListener.is() )
543     {
544         if ( !mnClientId )
545         {
546             mnClientId = ::comphelper::AccessibleEventNotifier::registerClient();
547         }
548         ::comphelper::AccessibleEventNotifier::addEventListener( mnClientId, xListener );
549     }
550 }
551 
552 // ----------------------------------------------------------------------------
553 
554 void AccFrameSelector::removeEventListener( const Reference< XAccessibleEventListener >& xListener ) throw (RuntimeException)
555 {
556     vos::OGuard aGuard( Application::GetSolarMutex() );
557 
558     if ( xListener.is() && mnClientId != 0 &&
559          ::comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, xListener ) == 0 )
560     {
561         // no listeners anymore
562         // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
563         // and at least to us not firing any events anymore, in case somebody calls
564         // NotifyAccessibleEvent, again
565         ::comphelper::AccessibleEventNotifier::TClientId nId( mnClientId );
566         mnClientId = 0;
567         ::comphelper::AccessibleEventNotifier::revokeClient( nId );
568     }
569 }
570 
571 // ----------------------------------------------------------------------------
572 
573 OUString AccFrameSelector::getImplementationName(  ) throw (RuntimeException)
574 {
575     return OUString::createFromAscii("AccFrameSelector");
576 }
577 
578 // ----------------------------------------------------------------------------
579 
580 const sal_Char sAccessible[]          = "Accessible";
581 const sal_Char sAccessibleContext[]   = "AccessibleContext";
582 const sal_Char sAccessibleComponent[] = "AccessibleComponent";
583 
584 sal_Bool AccFrameSelector::supportsService( const OUString& rServiceName )
585     throw (RuntimeException)
586 {
587     return  rServiceName.equalsAsciiL( sAccessible         , sizeof(sAccessible         )-1 ) ||
588             rServiceName.equalsAsciiL( sAccessibleContext  , sizeof(sAccessibleContext  )-1 ) ||
589             rServiceName.equalsAsciiL( sAccessibleComponent, sizeof(sAccessibleComponent)-1 );
590 }
591 
592 // ----------------------------------------------------------------------------
593 
594 Sequence< OUString > AccFrameSelector::getSupportedServiceNames(  )
595     throw (RuntimeException)
596 {
597     Sequence< OUString > aRet(3);
598 	OUString* pArray = aRet.getArray();
599     pArray[0] = OUString( RTL_CONSTASCII_USTRINGPARAM(sAccessible         ) );
600     pArray[1] = OUString( RTL_CONSTASCII_USTRINGPARAM(sAccessibleContext  ) );
601     pArray[2] = OUString( RTL_CONSTASCII_USTRINGPARAM(sAccessibleComponent) );
602     return aRet;
603 }
604 
605 // ----------------------------------------------------------------------------
606 
607 void AccFrameSelector::IsValid() throw (RuntimeException)
608 {
609     if(!mpFrameSel)
610         throw RuntimeException();
611 }
612 
613 // ----------------------------------------------------------------------------
614 
615 void    AccFrameSelector::NotifyFocusListeners(sal_Bool bGetFocus)
616 {
617     vos::OGuard aGuard(Application::GetSolarMutex());
618     AwtFocusEvent aEvent;
619     aEvent.FocusFlags = 0;
620     if(bGetFocus)
621     {
622         sal_uInt16 nFocusFlags = mpFrameSel->GetGetFocusFlags();
623         if(nFocusFlags&GETFOCUS_TAB)
624             aEvent.FocusFlags |= AwtFocusChangeReason::TAB;
625         if(nFocusFlags&GETFOCUS_CURSOR)
626             aEvent.FocusFlags |= AwtFocusChangeReason::CURSOR;
627         if(nFocusFlags&GETFOCUS_MNEMONIC)
628             aEvent.FocusFlags |= AwtFocusChangeReason::MNEMONIC;
629         if(nFocusFlags&GETFOCUS_FORWARD)
630             aEvent.FocusFlags |= AwtFocusChangeReason::FORWARD;
631         if(nFocusFlags&GETFOCUS_BACKWARD)
632             aEvent.FocusFlags |= AwtFocusChangeReason::BACKWARD;
633         if(nFocusFlags&GETFOCUS_AROUND)
634             aEvent.FocusFlags |= AwtFocusChangeReason::AROUND;
635         if(nFocusFlags&GETFOCUS_UNIQUEMNEMONIC)
636             aEvent.FocusFlags |= AwtFocusChangeReason::UNIQUEMNEMONIC;
637     //        if(nFocusFlags&GETFOCUS_INIT)
638     //            aEvent.FocusFlags |= AwtFocusChangeReason::
639     }
640 //    else
641     //how can I find the current focus window?
642 //        aEvent.NextFocus = ;
643     aEvent.Temporary = sal_False;
644 
645     Reference < XAccessibleContext > xThis( this );
646     aEvent.Source = xThis;
647 
648     ::cppu::OInterfaceIteratorHelper aIter( maFocusListeners );
649 	while( aIter.hasMoreElements() )
650 	{
651         Reference < XFocusListener > xListener( aIter.next(), UNO_QUERY );
652         if(bGetFocus)
653             xListener->focusGained( aEvent );
654         else
655             xListener->focusLost( aEvent );
656     }
657 }
658 
659 // ----------------------------------------------------------------------------
660 
661 IMPL_LINK( AccFrameSelector, WindowEventListener, VclSimpleEvent*, pEvent )
662 {
663     VclWindowEvent* pWinEvent = dynamic_cast< VclWindowEvent* >( pEvent );
664     DBG_ASSERT( pWinEvent, "AccFrameSelector::WindowEventListener - unknown window event" );
665     if ( pWinEvent )
666     {
667         Window* pWindow = pWinEvent->GetWindow();
668         DBG_ASSERT( pWindow, "AccFrameSelector::WindowEventListener: no window!" );
669         if ( !pWindow->IsAccessibilityEventsSuppressed() || ( pWinEvent->GetId() == VCLEVENT_OBJECT_DYING ) )
670         {
671             ProcessWindowEvent( *pWinEvent );
672         }
673     }
674 
675     return 0;
676 }
677 
678 // ----------------------------------------------------------------------------
679 
680 void AccFrameSelector::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
681 {
682     switch ( rVclWindowEvent.GetId() )
683     {
684 		case VCLEVENT_WINDOW_GETFOCUS:
685 		{
686             if ( meBorder == FRAMEBORDER_NONE )
687             {
688                 Any aOldValue, aNewValue;
689                 aNewValue <<= AccessibleStateType::FOCUSED;
690                 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
691             }
692 		}
693 		break;
694 		case VCLEVENT_WINDOW_LOSEFOCUS:
695 		{
696             if ( meBorder == FRAMEBORDER_NONE )
697             {
698                 Any aOldValue, aNewValue;
699                 aOldValue <<= AccessibleStateType::FOCUSED;
700                 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
701             }
702 		}
703 		break;
704         default:
705 		{
706 		}
707 		break;
708 	}
709 }
710 
711 // ----------------------------------------------------------------------------
712 
713 void AccFrameSelector::NotifyAccessibleEvent( const sal_Int16 _nEventId,
714     const Any& _rOldValue, const Any& _rNewValue )
715 {
716     if ( mnClientId )
717     {
718         Reference< XInterface > xSource( *this );
719         AccessibleEventObject aEvent( xSource, _nEventId, _rNewValue, _rOldValue );
720         ::comphelper::AccessibleEventNotifier::addEvent( mnClientId, aEvent );
721     }
722 }
723 
724 // ----------------------------------------------------------------------------
725 
726 void AccFrameSelector::Invalidate()
727 {
728     mpFrameSel = 0;
729     EventObject aEvent;
730     Reference < XAccessibleContext > xThis( this );
731 	aEvent.Source = xThis;
732     maFocusListeners.disposeAndClear( aEvent );
733     maPropertyListeners.disposeAndClear( aEvent );
734 }
735 
736 // ============================================================================
737 
738 } // namespace a11y
739 } // namespace svx
740 
741