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