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