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 	//IAccessibility2 Implementation 2009-----
195 	return meBorder == FRAMEBORDER_NONE ? AccessibleRole::OPTION_PANE : AccessibleRole::CHECK_BOX;
196 	//-----IAccessibility2 Implementation 2009
197 }
198 
199 // ----------------------------------------------------------------------------
200 
201 OUString AccFrameSelector::getAccessibleDescription(  )
202     throw (RuntimeException)
203 {
204     vos::OGuard aGuard(Application::GetSolarMutex());
205     IsValid();
206     return maDescriptions.GetString(meBorder);
207 }
208 
209 // ----------------------------------------------------------------------------
210 
211 OUString AccFrameSelector::getAccessibleName(  )
212     throw (RuntimeException)
213 {
214     vos::OGuard aGuard(Application::GetSolarMutex());
215     IsValid();
216     return maNames.GetString(meBorder);
217 }
218 
219 // ----------------------------------------------------------------------------
220 
221 Reference< XAccessibleRelationSet > AccFrameSelector::getAccessibleRelationSet(  )
222     throw (RuntimeException)
223 {
224     vos::OGuard aGuard(Application::GetSolarMutex());
225     IsValid();
226     utl::AccessibleRelationSetHelper* pHelper;
227     Reference< XAccessibleRelationSet > xRet = pHelper = new utl::AccessibleRelationSetHelper;
228     //if(meBorder == FRAMEBORDER_NONE)
229     //{
230     //    //add the label relation
231     //    Window* pPrev = mpFrameSel->GetWindow( WINDOW_PREV );
232     //    if(pPrev && WINDOW_FIXEDTEXT == pPrev->GetType())
233     //    {
234     //        AccessibleRelation aLabelRelation;
235     //        aLabelRelation.RelationType = AccessibleRelationType::LABELED_BY;
236     //        aLabelRelation.TargetSet.realloc(1);
237     //        aLabelRelation.TargetSet.getArray()[0]  = pPrev->GetAccessible();
238     //        pHelper->AddRelation(aLabelRelation);
239     //    }
240     //}
241 	//IAccessibility2 Implementation 2009-----
242     if(meBorder == FRAMEBORDER_NONE)
243     {
244         //add the label relation
245 		Window *pLabeledBy = mpFrameSel->GetAccessibleRelationLabeledBy();
246 		if ( pLabeledBy && pLabeledBy != mpFrameSel )
247 		{
248 			AccessibleRelation aLabelRelation;
249             aLabelRelation.RelationType = AccessibleRelationType::LABELED_BY;
250             aLabelRelation.TargetSet.realloc(1);
251             aLabelRelation.TargetSet.getArray()[0]  = pLabeledBy->GetAccessible();
252             pHelper->AddRelation(aLabelRelation);
253 		}
254 		Window* pMemberOf = mpFrameSel->GetAccessibleRelationMemberOf();
255 		if ( pMemberOf && pMemberOf != mpFrameSel )
256 		{
257 			AccessibleRelation aMemberOfRelation;
258             aMemberOfRelation.RelationType = AccessibleRelationType::MEMBER_OF;
259             aMemberOfRelation.TargetSet.realloc(1);
260             aMemberOfRelation.TargetSet.getArray()[0]  = pMemberOf->GetAccessible();
261             pHelper->AddRelation(aMemberOfRelation);
262 		}
263     }
264 	//-----IAccessibility2 Implementation 2009
265     return xRet;
266 }
267 
268 // ----------------------------------------------------------------------------
269 
270 Reference< XAccessibleStateSet > AccFrameSelector::getAccessibleStateSet(  )
271     throw (RuntimeException)
272 {
273     vos::OGuard aGuard(Application::GetSolarMutex());
274     utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper;
275     Reference< XAccessibleStateSet > xRet = pStateSetHelper;
276 
277     if(!mpFrameSel)
278         pStateSetHelper->AddState(AccessibleStateType::DEFUNC);
279     else
280     {
281         const sal_Int16 aStandardStates[] =
282         {
283             AccessibleStateType::EDITABLE,
284             AccessibleStateType::FOCUSABLE,
285             AccessibleStateType::MULTI_SELECTABLE,
286             AccessibleStateType::SELECTABLE,
287             AccessibleStateType::SHOWING,
288             AccessibleStateType::VISIBLE,
289             AccessibleStateType::OPAQUE,
290             0};
291         sal_Int16 nState = 0;
292         while(aStandardStates[nState])
293         {
294             pStateSetHelper->AddState(aStandardStates[nState++]);
295         }
296         if(mpFrameSel->IsEnabled())
297         {
298             pStateSetHelper->AddState(AccessibleStateType::ENABLED);
299             pStateSetHelper->AddState(AccessibleStateType::SENSITIVE);
300         }
301 
302         sal_Bool bIsParent = meBorder == FRAMEBORDER_NONE;
303         if(mpFrameSel->HasFocus() &&
304             (bIsParent || mpFrameSel->IsBorderSelected(meBorder)))
305         {
306             pStateSetHelper->AddState(AccessibleStateType::ACTIVE);
307             pStateSetHelper->AddState(AccessibleStateType::FOCUSED);
308             pStateSetHelper->AddState(AccessibleStateType::SELECTED);
309         }
310     }
311     return xRet;
312 }
313 
314 // ----------------------------------------------------------------------------
315 
316 Locale AccFrameSelector::getLocale(  )
317     throw (IllegalAccessibleComponentStateException, RuntimeException)
318 {
319     Locale aRet;
320     SvxLanguageToLocale( aRet, Application::GetSettings().GetUILanguage() );
321     return aRet;
322 }
323 
324 // ----------------------------------------------------------------------------
325 
326 void AccFrameSelector::addPropertyChangeListener(
327     const Reference< XPropertyChangeListener >& xListener )
328         throw (RuntimeException)
329 {
330     maPropertyListeners.addInterface( xListener );
331 }
332 
333 // ----------------------------------------------------------------------------
334 
335 void AccFrameSelector::removePropertyChangeListener( const Reference< XPropertyChangeListener >& xListener )
336     throw (RuntimeException)
337 {
338     maPropertyListeners.removeInterface( xListener );
339 }
340 
341 // ----------------------------------------------------------------------------
342 
343 sal_Bool AccFrameSelector::containsPoint( const AwtPoint& aPt )
344     throw (RuntimeException)
345 {
346     vos::OGuard aGuard(Application::GetSolarMutex());
347     IsValid();
348     //aPt is relative to the frame selector
349     return mpFrameSel->ContainsClickPoint( Point( aPt.X, aPt.Y ) );
350 }
351 
352 // ----------------------------------------------------------------------------
353 
354 Reference< XAccessible > AccFrameSelector::getAccessibleAtPoint(
355     const AwtPoint& aPt )
356         throw (RuntimeException)
357 {
358     vos::OGuard aGuard(Application::GetSolarMutex());
359     IsValid();
360     //aPt is relative to the frame selector
361     return mpFrameSel->GetChildAccessible( Point( aPt.X, aPt.Y ) );
362 }
363 
364 AwtRectangle AccFrameSelector::getBounds(  ) throw (RuntimeException)
365 {
366     vos::OGuard aGuard(Application::GetSolarMutex());
367     IsValid();
368     Size aSz;
369     Point aPos;
370     switch(meBorder)
371     {
372         case FRAMEBORDER_NONE:
373             aSz = mpFrameSel->GetSizePixel();
374             aPos = mpFrameSel->GetPosPixel();
375         break;
376         default:
377             const Rectangle aSpot = mpFrameSel->GetClickBoundRect( meBorder );
378             aPos = aSpot.TopLeft();
379             aSz = aSpot.GetSize();
380     }
381     AwtRectangle aRet;
382     aRet.X = aPos.X();
383     aRet.Y = aPos.Y();
384     aRet.Width = aSz.Width();
385     aRet.Height = aSz.Height();
386     return aRet;
387 }
388 
389 // ----------------------------------------------------------------------------
390 
391 AwtPoint AccFrameSelector::getLocation(  ) throw (RuntimeException)
392 {
393     vos::OGuard aGuard(Application::GetSolarMutex());
394     IsValid();
395     Point aPos;
396     switch(meBorder)
397     {
398         case FRAMEBORDER_NONE:
399             aPos = mpFrameSel->GetPosPixel();
400         break;
401         default:
402             const Rectangle aSpot = mpFrameSel->GetClickBoundRect( meBorder );
403             aPos = aSpot.TopLeft();
404     }
405     AwtPoint aRet(aPos.X(), aPos.Y());
406     return aRet;
407 }
408 
409 // ----------------------------------------------------------------------------
410 
411 AwtPoint AccFrameSelector::getLocationOnScreen(  ) throw (RuntimeException)
412 {
413     vos::OGuard aGuard(Application::GetSolarMutex());
414     IsValid();
415     Point aPos;
416     switch(meBorder)
417     {
418         case FRAMEBORDER_NONE:
419             aPos = mpFrameSel->GetPosPixel();
420         break;
421         default:
422             const Rectangle aSpot = mpFrameSel->GetClickBoundRect( meBorder );
423             aPos = aSpot.TopLeft();
424     }
425     aPos = mpFrameSel->OutputToAbsoluteScreenPixel( aPos );
426     AwtPoint aRet(aPos.X(), aPos.Y());
427     return aRet;
428 }
429 
430 // ----------------------------------------------------------------------------
431 
432 AwtSize AccFrameSelector::getSize(  ) throw (RuntimeException)
433 {
434     vos::OGuard aGuard(Application::GetSolarMutex());
435     IsValid();
436     Size aSz;
437     switch(meBorder)
438     {
439         case FRAMEBORDER_NONE:
440             aSz = mpFrameSel->GetSizePixel();
441         break;
442         default:
443             const Rectangle aSpot = mpFrameSel->GetClickBoundRect( meBorder );
444             aSz = aSpot.GetSize();
445     }
446     AwtSize aRet(aSz.Width(), aSz.Height());
447     return aRet;
448 }
449 
450 // ----------------------------------------------------------------------------
451 
452 sal_Bool AccFrameSelector::isShowing(  ) throw (RuntimeException)
453 {
454     vos::OGuard aGuard(Application::GetSolarMutex());
455     IsValid();
456     return sal_True;
457 }
458 
459 // ----------------------------------------------------------------------------
460 
461 sal_Bool AccFrameSelector::isVisible(  ) throw (RuntimeException)
462 {
463     vos::OGuard aGuard(Application::GetSolarMutex());
464     IsValid();
465     return sal_True;
466 }
467 
468 // ----------------------------------------------------------------------------
469 
470 sal_Bool AccFrameSelector::isFocusTraversable(  ) throw (RuntimeException)
471 {
472     vos::OGuard aGuard(Application::GetSolarMutex());
473     IsValid();
474     return sal_True;
475 }
476 
477 // ----------------------------------------------------------------------------
478 
479 void AccFrameSelector::addFocusListener( const Reference< XFocusListener >& xListener ) throw (RuntimeException)
480 {
481     maFocusListeners.addInterface( xListener );
482 }
483 
484 // ----------------------------------------------------------------------------
485 
486 void AccFrameSelector::removeFocusListener( const Reference< XFocusListener >& xListener ) throw (RuntimeException)
487 {
488     maFocusListeners.removeInterface( xListener );
489 }
490 
491 // ----------------------------------------------------------------------------
492 
493 void AccFrameSelector::grabFocus(  ) throw (RuntimeException)
494 {
495     vos::OGuard aGuard(Application::GetSolarMutex());
496     IsValid();
497     mpFrameSel->GrabFocus();
498 }
499 
500 // ----------------------------------------------------------------------------
501 
502 Any AccFrameSelector::getAccessibleKeyBinding(  ) throw (RuntimeException)
503 {
504     Any aRet;
505     vos::OGuard aGuard(Application::GetSolarMutex());
506     IsValid();
507     utl::AccessibleRelationSetHelper* pHelper;
508     Reference< XAccessibleRelationSet > xRet = pHelper = new utl::AccessibleRelationSetHelper;
509     if(meBorder == FRAMEBORDER_NONE)
510     {
511         Window* pPrev = mpFrameSel->GetWindow( WINDOW_PREV );
512         if(pPrev && WINDOW_FIXEDTEXT == pPrev->GetType())
513         {
514             String sText = pPrev->GetText();
515             xub_StrLen nFound = sText.Search( MNEMONIC_CHAR );
516             if(STRING_NOTFOUND != nFound && ++nFound < sText.Len())
517             {
518                 sText.ToUpperAscii();
519                 sal_Unicode cChar = sText.GetChar(nFound);
520                 AwtKeyEvent aEvent;
521 
522                 aEvent.KeyCode = 0;
523                 aEvent.KeyChar = cChar;
524                 aEvent.KeyFunc = 0;
525                 if(cChar >= 'A' && cChar <= 'Z')
526                 {
527                      aEvent.KeyCode = AwtKey::A + cChar - 'A';
528                 }
529                 aEvent.Modifiers = AwtKeyModifier::MOD2;
530                 aRet <<= aEvent;
531             }
532         }
533     }
534     return aRet;
535 }
536 
537 // ----------------------------------------------------------------------------
538 
539 sal_Int32 AccFrameSelector::getForeground(  )
540         throw (RuntimeException)
541 {
542     Any aRet;
543     vos::OGuard aGuard(Application::GetSolarMutex());
544     IsValid();
545     return mpFrameSel->GetControlForeground().GetColor();
546 }
547 
548 // ----------------------------------------------------------------------------
549 
550 sal_Int32 AccFrameSelector::getBackground(  )
551         throw (RuntimeException)
552 {
553     Any aRet;
554     vos::OGuard aGuard(Application::GetSolarMutex());
555     IsValid();
556     return mpFrameSel->GetControlBackground().GetColor();
557 }
558 
559 // ----------------------------------------------------------------------------
560 
561 void AccFrameSelector::addEventListener( const Reference< XAccessibleEventListener >& xListener ) throw (RuntimeException)
562 {
563     vos::OGuard aGuard( Application::GetSolarMutex() );
564 
565     if ( xListener.is() )
566     {
567         if ( !mnClientId )
568         {
569             mnClientId = ::comphelper::AccessibleEventNotifier::registerClient();
570         }
571         ::comphelper::AccessibleEventNotifier::addEventListener( mnClientId, xListener );
572     }
573 }
574 
575 // ----------------------------------------------------------------------------
576 
577 void AccFrameSelector::removeEventListener( const Reference< XAccessibleEventListener >& xListener ) throw (RuntimeException)
578 {
579     vos::OGuard aGuard( Application::GetSolarMutex() );
580 
581     if ( xListener.is() && mnClientId != 0 &&
582          ::comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, xListener ) == 0 )
583     {
584         // no listeners anymore
585         // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
586         // and at least to us not firing any events anymore, in case somebody calls
587         // NotifyAccessibleEvent, again
588         ::comphelper::AccessibleEventNotifier::TClientId nId( mnClientId );
589         mnClientId = 0;
590         ::comphelper::AccessibleEventNotifier::revokeClient( nId );
591     }
592 }
593 
594 // ----------------------------------------------------------------------------
595 
596 OUString AccFrameSelector::getImplementationName(  ) throw (RuntimeException)
597 {
598     return OUString::createFromAscii("AccFrameSelector");
599 }
600 
601 // ----------------------------------------------------------------------------
602 
603 const sal_Char sAccessible[]          = "Accessible";
604 const sal_Char sAccessibleContext[]   = "AccessibleContext";
605 const sal_Char sAccessibleComponent[] = "AccessibleComponent";
606 
607 sal_Bool AccFrameSelector::supportsService( const OUString& rServiceName )
608     throw (RuntimeException)
609 {
610     return  rServiceName.equalsAsciiL( sAccessible         , sizeof(sAccessible         )-1 ) ||
611             rServiceName.equalsAsciiL( sAccessibleContext  , sizeof(sAccessibleContext  )-1 ) ||
612             rServiceName.equalsAsciiL( sAccessibleComponent, sizeof(sAccessibleComponent)-1 );
613 }
614 
615 // ----------------------------------------------------------------------------
616 
617 Sequence< OUString > AccFrameSelector::getSupportedServiceNames(  )
618     throw (RuntimeException)
619 {
620     Sequence< OUString > aRet(3);
621 	OUString* pArray = aRet.getArray();
622     pArray[0] = OUString( RTL_CONSTASCII_USTRINGPARAM(sAccessible         ) );
623     pArray[1] = OUString( RTL_CONSTASCII_USTRINGPARAM(sAccessibleContext  ) );
624     pArray[2] = OUString( RTL_CONSTASCII_USTRINGPARAM(sAccessibleComponent) );
625     return aRet;
626 }
627 
628 // ----------------------------------------------------------------------------
629 
630 void AccFrameSelector::IsValid() throw (RuntimeException)
631 {
632     if(!mpFrameSel)
633         throw RuntimeException();
634 }
635 
636 // ----------------------------------------------------------------------------
637 
638 void    AccFrameSelector::NotifyFocusListeners(sal_Bool bGetFocus)
639 {
640     vos::OGuard aGuard(Application::GetSolarMutex());
641     AwtFocusEvent aEvent;
642     aEvent.FocusFlags = 0;
643     if(bGetFocus)
644     {
645         sal_uInt16 nFocusFlags = mpFrameSel->GetGetFocusFlags();
646         if(nFocusFlags&GETFOCUS_TAB)
647             aEvent.FocusFlags |= AwtFocusChangeReason::TAB;
648         if(nFocusFlags&GETFOCUS_CURSOR)
649             aEvent.FocusFlags |= AwtFocusChangeReason::CURSOR;
650         if(nFocusFlags&GETFOCUS_MNEMONIC)
651             aEvent.FocusFlags |= AwtFocusChangeReason::MNEMONIC;
652         if(nFocusFlags&GETFOCUS_FORWARD)
653             aEvent.FocusFlags |= AwtFocusChangeReason::FORWARD;
654         if(nFocusFlags&GETFOCUS_BACKWARD)
655             aEvent.FocusFlags |= AwtFocusChangeReason::BACKWARD;
656         if(nFocusFlags&GETFOCUS_AROUND)
657             aEvent.FocusFlags |= AwtFocusChangeReason::AROUND;
658         if(nFocusFlags&GETFOCUS_UNIQUEMNEMONIC)
659             aEvent.FocusFlags |= AwtFocusChangeReason::UNIQUEMNEMONIC;
660     //        if(nFocusFlags&GETFOCUS_INIT)
661     //            aEvent.FocusFlags |= AwtFocusChangeReason::
662     }
663 //    else
664     //how can I find the current focus window?
665 //        aEvent.NextFocus = ;
666     aEvent.Temporary = sal_False;
667 
668     Reference < XAccessibleContext > xThis( this );
669     aEvent.Source = xThis;
670 
671     ::cppu::OInterfaceIteratorHelper aIter( maFocusListeners );
672 	while( aIter.hasMoreElements() )
673 	{
674         Reference < XFocusListener > xListener( aIter.next(), UNO_QUERY );
675         if(bGetFocus)
676             xListener->focusGained( aEvent );
677         else
678             xListener->focusLost( aEvent );
679     }
680 }
681 
682 // ----------------------------------------------------------------------------
683 
684 IMPL_LINK( AccFrameSelector, WindowEventListener, VclSimpleEvent*, pEvent )
685 {
686     VclWindowEvent* pWinEvent = dynamic_cast< VclWindowEvent* >( pEvent );
687     DBG_ASSERT( pWinEvent, "AccFrameSelector::WindowEventListener - unknown window event" );
688     if ( pWinEvent )
689     {
690         Window* pWindow = pWinEvent->GetWindow();
691         DBG_ASSERT( pWindow, "AccFrameSelector::WindowEventListener: no window!" );
692         if ( !pWindow->IsAccessibilityEventsSuppressed() || ( pWinEvent->GetId() == VCLEVENT_OBJECT_DYING ) )
693         {
694             ProcessWindowEvent( *pWinEvent );
695         }
696     }
697 
698     return 0;
699 }
700 
701 // ----------------------------------------------------------------------------
702 
703 void AccFrameSelector::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
704 {
705     switch ( rVclWindowEvent.GetId() )
706     {
707 		case VCLEVENT_WINDOW_GETFOCUS:
708 		{
709             if ( meBorder == FRAMEBORDER_NONE )
710             {
711                 Any aOldValue, aNewValue;
712                 aNewValue <<= AccessibleStateType::FOCUSED;
713                 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
714             }
715 		}
716 		break;
717 		case VCLEVENT_WINDOW_LOSEFOCUS:
718 		{
719             if ( meBorder == FRAMEBORDER_NONE )
720             {
721                 Any aOldValue, aNewValue;
722                 aOldValue <<= AccessibleStateType::FOCUSED;
723                 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
724             }
725 		}
726 		break;
727         default:
728 		{
729 		}
730 		break;
731 	}
732 }
733 
734 // ----------------------------------------------------------------------------
735 
736 void AccFrameSelector::NotifyAccessibleEvent( const sal_Int16 _nEventId,
737     const Any& _rOldValue, const Any& _rNewValue )
738 {
739     if ( mnClientId )
740     {
741         Reference< XInterface > xSource( *this );
742         AccessibleEventObject aEvent( xSource, _nEventId, _rNewValue, _rOldValue );
743         ::comphelper::AccessibleEventNotifier::addEvent( mnClientId, aEvent );
744     }
745 }
746 
747 // ----------------------------------------------------------------------------
748 
749 void AccFrameSelector::Invalidate()
750 {
751 	if ( mpFrameSel )
752     {
753         mpFrameSel->RemoveEventListener( LINK( this, AccFrameSelector, WindowEventListener ) );
754     }
755     mpFrameSel = 0;
756     EventObject aEvent;
757     Reference < XAccessibleContext > xThis( this );
758 	aEvent.Source = xThis;
759     maFocusListeners.disposeAndClear( aEvent );
760     maPropertyListeners.disposeAndClear( aEvent );
761 }
762 
763 // ============================================================================
764 
765 } // namespace a11y
766 } // namespace svx
767 
768