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