xref: /trunk/main/svtools/source/control/accessibleruler.cxx (revision ca62e2c2083b5d0995f1245bad6c2edfb455fbec)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright IBM Corporation 2010.
6  * Copyright 2000, 2010 Oracle and/or its affiliates.
7  *
8  * OpenOffice.org - a multi-platform office productivity suite
9  *
10  * This file is part of OpenOffice.org.
11  *
12  * OpenOffice.org is free software: you can redistribute it and/or modify
13  * it under the terms of the GNU Lesser General Public License version 3
14  * only, as published by the Free Software Foundation.
15  *
16  * OpenOffice.org is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU Lesser General Public License version 3 for more details
20  * (a copy is included in the LICENSE file that accompanied this code).
21  *
22  * You should have received a copy of the GNU Lesser General Public License
23  * version 3 along with OpenOffice.org.  If not, see
24  * <http://www.openoffice.org/license.html>
25  * for a copy of the LGPLv3 License.
26  *
27  ************************************************************************/
28 
29 // MARKER(update_precomp.py): autogen include statement, do not remove
30 #include "precompiled_svtools.hxx"
31 
32 //add by duan mei hua, 2006/09/04, for issue 174
33 #ifndef _SVTRULERACCESSIBLE_HXX
34 #include <svtools/accessibleruler.hxx>
35 #endif
36 //end add by duan mei hua, 2006/09/04, for issue 174
37 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLEROLE_HPP_
38 #include <com/sun/star/accessibility/AccessibleRole.hpp>
39 #endif
40 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLEEVENTID_HPP_
41 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
42 #endif
43 #ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX_
44 #include <unotools/accessiblestatesethelper.hxx>
45 #endif
46 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLESTATETYPE_HPP_
47 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
48 #endif
49 
50 #ifndef _COM_SUN_STAR_BEANS_PROPERTYCHANGEEVENT_HPP_
51 #include <com/sun/star/beans/PropertyChangeEvent.hpp>
52 #endif
53 
54 #ifndef _COM_SUN_STAR_AWT_XWINDOW_HPP_
55 #include <com/sun/star/awt/XWindow.hpp>
56 #endif
57 
58 #ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
59 #include <cppuhelper/typeprovider.hxx>
60 #endif
61 
62 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
63 #include <toolkit/helper/vclunohelper.hxx>
64 #endif
65 #ifndef _TOOLKIT_HELPER_CONVERT_HXX_
66 #include <toolkit/helper/convert.hxx>
67 #endif
68 
69 #ifndef _SV_SVAPP_HXX
70 #include <vcl/svapp.hxx>
71 #endif
72 
73 #ifndef _OSL_MUTEX_HXX_
74 #include <osl/mutex.hxx>
75 #endif
76 #ifndef _RTL_UUID_H_
77 #include <rtl/uuid.h>
78 #endif
79 #ifndef _TOOLS_DEBUG_HXX
80 #include <tools/debug.hxx>
81 #endif
82 #ifndef _SV_GEN_HXX
83 #include <tools/gen.hxx>
84 #endif
85 
86 #include "ruler.hxx"
87 
88 #ifndef COMPHELPER_ACCESSIBLE_EVENT_NOTIFIER
89 #include <comphelper/accessibleeventnotifier.hxx>
90 #endif
91 
92 using namespace ::cppu;
93 using namespace ::osl;
94 using namespace ::rtl;
95 using namespace ::com::sun::star;
96 using namespace ::com::sun::star::uno;
97 using namespace ::com::sun::star::accessibility;
98 
99 DBG_NAME( SvtRulerAccessible )
100 
101 
102 //=====  internal  ============================================================
103 
104 SvtRulerAccessible::SvtRulerAccessible(
105     const uno::Reference< XAccessible >& rxParent, Ruler& rRepr, const OUString& rName ) :
106 
107     SvtRulerAccessible_Base( m_aMutex ),
108     msName( rName ),
109     mxParent( rxParent ),
110     mpRepr( &rRepr ),
111     mnClientId( 0 )
112 {
113     DBG_CTOR( SvtRulerAccessible, NULL );
114 }
115 
116 SvtRulerAccessible::~SvtRulerAccessible()
117 {
118     DBG_DTOR( SvtRulerAccessible, NULL );
119 
120     if( IsAlive() )
121     {
122         osl_incrementInterlockedCount( &m_refCount );
123         dispose();      // set mpRepr = NULL & release all childs
124     }
125 }
126 
127 //=====  XAccessible  =========================================================
128 
129 uno::Reference< XAccessibleContext > SAL_CALL SvtRulerAccessible::getAccessibleContext( void ) throw( RuntimeException )
130 {
131     return this;
132 }
133 
134 //=====  XAccessibleComponent  ================================================
135 
136 sal_Bool SAL_CALL SvtRulerAccessible::containsPoint( const awt::Point& rPoint ) throw( RuntimeException )
137 {
138     // no guard -> done in getBounds()
139 //  return GetBoundingBox().IsInside( VCLPoint( rPoint ) );
140     return Rectangle( Point( 0, 0 ), GetBoundingBox().GetSize() ).IsInside( VCLPoint( rPoint ) );
141 }
142 
143 uno::Reference< XAccessible > SAL_CALL SvtRulerAccessible::getAccessibleAtPoint( const awt::Point& ) throw( RuntimeException )
144 {
145     ::osl::MutexGuard           aGuard( m_aMutex );
146 
147     ThrowExceptionIfNotAlive();
148 
149     uno::Reference< XAccessible >   xRet;
150 
151 
152     return xRet;
153 }
154 
155 awt::Rectangle SAL_CALL SvtRulerAccessible::getBounds() throw( RuntimeException )
156 {
157     // no guard -> done in GetBoundingBox()
158     return AWTRectangle( GetBoundingBox() );
159 }
160 
161 awt::Point SAL_CALL SvtRulerAccessible::getLocation() throw( RuntimeException )
162 {
163     // no guard -> done in GetBoundingBox()
164     return AWTPoint( GetBoundingBox().TopLeft() );
165 }
166 
167 awt::Point SAL_CALL SvtRulerAccessible::getLocationOnScreen() throw( RuntimeException )
168 {
169     // no guard -> done in GetBoundingBoxOnScreen()
170     return AWTPoint( GetBoundingBoxOnScreen().TopLeft() );
171 }
172 
173 awt::Size SAL_CALL SvtRulerAccessible::getSize() throw( RuntimeException )
174 {
175     // no guard -> done in GetBoundingBox()
176     return AWTSize( GetBoundingBox().GetSize() );
177 }
178 
179 sal_Bool SAL_CALL SvtRulerAccessible::isShowing() throw( RuntimeException )
180 {
181     return sal_True;
182 }
183 
184 sal_Bool SAL_CALL SvtRulerAccessible::isVisible() throw( RuntimeException )
185 {
186     ::osl::MutexGuard           aGuard( m_aMutex );
187 
188     ThrowExceptionIfNotAlive();
189 
190     return mpRepr->IsVisible();
191 }
192 
193 sal_Bool SAL_CALL SvtRulerAccessible::isFocusTraversable() throw( RuntimeException )
194 {
195     return sal_True;
196 }
197 
198 //=====  XAccessibleContext  ==================================================
199 
200 sal_Int32 SAL_CALL SvtRulerAccessible::getAccessibleChildCount( void ) throw( RuntimeException )
201 {
202     ::osl::MutexGuard   aGuard( m_aMutex );
203 
204     ThrowExceptionIfNotAlive();
205 
206     return 0;
207 }
208 
209 uno::Reference< XAccessible > SAL_CALL SvtRulerAccessible::getAccessibleChild( sal_Int32 )
210     throw( RuntimeException, lang::IndexOutOfBoundsException )
211 {
212     uno::Reference< XAccessible >   xChild ;
213 
214     return xChild;
215 }
216 
217 uno::Reference< XAccessible > SAL_CALL SvtRulerAccessible::getAccessibleParent( void ) throw( RuntimeException )
218 {
219     return mxParent;
220 }
221 
222 sal_Int32 SAL_CALL SvtRulerAccessible::getAccessibleIndexInParent( void ) throw( RuntimeException )
223 {
224     ::osl::MutexGuard   aGuard( m_aMutex );
225     //  Use a simple but slow solution for now.  Optimize later.
226 
227     //  Iterate over all the parent's children and search for this object.
228     if( mxParent.is() )
229     {
230         uno::Reference< XAccessibleContext >        xParentContext( mxParent->getAccessibleContext() );
231         if( xParentContext.is() )
232         {
233             sal_Int32                       nChildCount = xParentContext->getAccessibleChildCount();
234             for( sal_Int32 i = 0 ; i < nChildCount ; ++i )
235             {
236                 uno::Reference< XAccessible >   xChild( xParentContext->getAccessibleChild( i ) );
237                 if( xChild.get() == ( XAccessible* ) this )
238                     return i;
239             }
240         }
241    }
242 
243    //   Return -1 to indicate that this object's parent does not know about the
244    //   object.
245    return -1;
246 }
247 
248 sal_Int16 SAL_CALL SvtRulerAccessible::getAccessibleRole( void ) throw( RuntimeException )
249 {
250     return AccessibleRole::RULER;
251 }
252 
253 OUString SAL_CALL SvtRulerAccessible::getAccessibleDescription( void ) throw( RuntimeException )
254 {
255     ::osl::MutexGuard   aGuard( m_aMutex );
256     return msDescription;
257 }
258 
259 OUString SAL_CALL SvtRulerAccessible::getAccessibleName( void ) throw( RuntimeException )
260 {
261     ::osl::MutexGuard   aGuard( m_aMutex );
262     return msName;
263 }
264 
265 /** Return empty uno::Reference to indicate that the relation set is not
266     supported.
267 */
268 uno::Reference< XAccessibleRelationSet > SAL_CALL SvtRulerAccessible::getAccessibleRelationSet( void ) throw( RuntimeException )
269 {
270     return uno::Reference< XAccessibleRelationSet >();
271 }
272 
273 
274 uno::Reference< XAccessibleStateSet > SAL_CALL SvtRulerAccessible::getAccessibleStateSet( void ) throw( RuntimeException )
275 {
276     ::osl::MutexGuard                       aGuard( m_aMutex );
277     utl::AccessibleStateSetHelper*          pStateSetHelper = new utl::AccessibleStateSetHelper;
278 
279     if( IsAlive() )
280     {
281         pStateSetHelper->AddState( AccessibleStateType::ENABLED );
282 
283         if( isShowing() )
284             pStateSetHelper->AddState( AccessibleStateType::SHOWING );
285 
286         if( isVisible() )
287             pStateSetHelper->AddState( AccessibleStateType::VISIBLE );
288 
289 
290         if ( mpRepr )
291         {
292             if ( mpRepr->GetStyle() & WB_HORZ )
293                 pStateSetHelper->AddState( AccessibleStateType::HORIZONTAL );
294             else
295                 pStateSetHelper->AddState( AccessibleStateType::VERTICAL );
296         }
297         if(pStateSetHelper->contains(AccessibleStateType::FOCUSABLE))
298         {
299             pStateSetHelper->RemoveState( AccessibleStateType::FOCUSABLE );
300         }
301 
302     }
303 
304 
305     return pStateSetHelper;
306 }
307 
308 lang::Locale SAL_CALL SvtRulerAccessible::getLocale( void ) throw( IllegalAccessibleComponentStateException, RuntimeException )
309 {
310     ::osl::MutexGuard                           aGuard( m_aMutex );
311     if( mxParent.is() )
312     {
313         uno::Reference< XAccessibleContext >    xParentContext( mxParent->getAccessibleContext() );
314         if( xParentContext.is() )
315             return xParentContext->getLocale();
316     }
317 
318     //  No parent.  Therefore throw exception to indicate this cluelessness.
319     throw IllegalAccessibleComponentStateException();
320 }
321 
322 void SAL_CALL SvtRulerAccessible::addEventListener( const uno::Reference< XAccessibleEventListener >& xListener )
323     throw( RuntimeException )
324 {
325     if (xListener.is())
326     {
327         ::osl::MutexGuard   aGuard( m_aMutex );
328         if (!mnClientId)
329             mnClientId = comphelper::AccessibleEventNotifier::registerClient( );
330         comphelper::AccessibleEventNotifier::addEventListener( mnClientId, xListener );
331     }
332 }
333 
334 void SAL_CALL SvtRulerAccessible::removeEventListener( const uno::Reference< XAccessibleEventListener >& xListener )
335     throw( RuntimeException )
336 {
337     if (xListener.is())
338     {
339         ::osl::MutexGuard   aGuard( m_aMutex );
340 
341         sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, xListener );
342         if ( !nListenerCount )
343         {
344             // no listeners anymore
345             // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
346             // and at least to us not firing any events anymore, in case somebody calls
347             // NotifyAccessibleEvent, again
348             comphelper::AccessibleEventNotifier::revokeClient( mnClientId );
349             mnClientId = 0;
350         }
351     }
352 }
353 
354 void SAL_CALL SvtRulerAccessible::addFocusListener( const uno::Reference< awt::XFocusListener >& xListener )
355     throw( RuntimeException )
356 {
357     if( xListener.is() )
358     {
359         ::osl::MutexGuard   aGuard( m_aMutex );
360 
361         ThrowExceptionIfNotAlive();
362 
363         uno::Reference< awt::XWindow >  xWindow = VCLUnoHelper::GetInterface( mpRepr );
364         if( xWindow.is() )
365             xWindow->addFocusListener( xListener );
366     }
367 }
368 
369 void SAL_CALL SvtRulerAccessible::removeFocusListener( const uno::Reference< awt::XFocusListener >& xListener )
370     throw (RuntimeException)
371 {
372     if( xListener.is() )
373     {
374         ::osl::MutexGuard   aGuard( m_aMutex );
375 
376         ThrowExceptionIfNotAlive();
377 
378         uno::Reference< awt::XWindow >  xWindow = VCLUnoHelper::GetInterface( mpRepr );
379         if( xWindow.is() )
380             xWindow->removeFocusListener( xListener );
381     }
382 }
383 
384 void SAL_CALL SvtRulerAccessible::grabFocus() throw( RuntimeException )
385 {
386     ::vos::OGuard       aSolarGuard( Application::GetSolarMutex() );
387     ::osl::MutexGuard   aGuard( m_aMutex );
388 
389     ThrowExceptionIfNotAlive();
390 
391     mpRepr->GrabFocus();
392 }
393 
394 Any SAL_CALL SvtRulerAccessible::getAccessibleKeyBinding() throw( RuntimeException )
395 {
396     // here is no implementation, because here are no KeyBindings for every object
397     return Any();
398 }
399 
400 sal_Int32 SvtRulerAccessible::getForeground(  )
401         throw (::com::sun::star::uno::RuntimeException)
402 {
403     ::vos::OGuard       aSolarGuard( Application::GetSolarMutex() );
404     ::osl::MutexGuard   aGuard( m_aMutex );
405     ThrowExceptionIfNotAlive();
406 
407     return mpRepr->GetControlForeground().GetColor();
408 }
409 sal_Int32 SvtRulerAccessible::getBackground(  )
410         throw (::com::sun::star::uno::RuntimeException)
411 {
412     ::vos::OGuard       aSolarGuard( Application::GetSolarMutex() );
413     ::osl::MutexGuard   aGuard( m_aMutex );
414     ThrowExceptionIfNotAlive();
415 
416     return mpRepr->GetControlBackground().GetColor();
417 }
418 
419 //=====  XServiceInfo  ========================================================
420 
421 OUString SAL_CALL SvtRulerAccessible::getImplementationName( void ) throw( RuntimeException )
422 {
423     return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.ui.SvtRulerAccessible" ) );
424 }
425 
426 sal_Bool SAL_CALL SvtRulerAccessible::supportsService( const OUString& sServiceName ) throw( RuntimeException )
427 {
428     ::osl::MutexGuard   aGuard( m_aMutex );
429     //  Iterate over all supported service names and return true if on of them
430     //  matches the given name.
431     Sequence< OUString >    aSupportedServices( getSupportedServiceNames() );
432     int                     nLength = aSupportedServices.getLength();
433     const OUString*         pStr = aSupportedServices.getConstArray();
434 
435     for( int i = nLength ; i ; --i, ++pStr )
436     {
437         if( sServiceName == *pStr )
438             return sal_True;
439     }
440 
441     return sal_False;
442 }
443 
444 Sequence< OUString > SAL_CALL SvtRulerAccessible::getSupportedServiceNames( void ) throw( RuntimeException )
445 {
446     const OUString sServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleContext" ) );
447     return Sequence< OUString >( &sServiceName, 1 );
448 }
449 
450 //=====  XTypeProvider  =======================================================
451 
452 Sequence< sal_Int8 > SAL_CALL SvtRulerAccessible::getImplementationId( void ) throw( RuntimeException )
453 {
454     return getUniqueId();
455 }
456 
457 
458 //=====  internals ========================================================
459 
460 void SvtRulerAccessible::setName( const OUString& rName )
461 {
462         msName = rName;
463 
464 }
465 
466 void SvtRulerAccessible::setDescription( const OUString& rDescr )
467 {
468 
469         msDescription = rDescr;
470 
471 }
472 
473 
474 
475 void SAL_CALL SvtRulerAccessible::disposing()
476 {
477     if( !rBHelper.bDisposed )
478     {
479         {
480             ::osl::MutexGuard   aGuard( m_aMutex );
481             mpRepr = NULL;      // object dies with representation
482 
483         }
484 
485         {
486             ::osl::MutexGuard   aGuard( m_aMutex );
487 
488             // Send a disposing to all listeners.
489             if ( mnClientId )
490             {
491                 comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId, *this );
492                 mnClientId =  0;
493             }
494             mxParent = uno::Reference< XAccessible >();
495         }
496     }
497 }
498 
499 Rectangle SvtRulerAccessible::GetBoundingBoxOnScreen( void ) throw( RuntimeException )
500 {
501     ::vos::OGuard       aSolarGuard( Application::GetSolarMutex() );
502     ::osl::MutexGuard   aGuard( m_aMutex );
503 
504     ThrowExceptionIfNotAlive();
505 //IAccessibility2 Implementation 2009-----
506     //Modified by Li Xing, 2007/03/26, SODC_7333, the absolute on screen pixel is wrong
507     //return Rectangle( mpRepr->GetParent()->OutputToScreenPixel( mpRepr->GetPosPixel() ), mpRepr->GetSizePixel() );
508     return Rectangle( mpRepr->GetParent()->OutputToAbsoluteScreenPixel( mpRepr->GetPosPixel() ), mpRepr->GetSizePixel() );
509     //Ended by Li Xing, 2007/03/26, SODC_7333.
510 //-----IAccessibility2 Implementation 2009
511 }
512 
513 Rectangle SvtRulerAccessible::GetBoundingBox( void ) throw( RuntimeException )
514 {
515     ::vos::OGuard       aSolarGuard( Application::GetSolarMutex() );
516     ::osl::MutexGuard   aGuard( m_aMutex );
517 
518     ThrowExceptionIfNotAlive();
519 
520     return Rectangle( mpRepr->GetPosPixel(), mpRepr->GetSizePixel() );
521 }
522 
523 Sequence< sal_Int8 > SvtRulerAccessible::getUniqueId( void )
524 {
525     static OImplementationId*   pId = 0;
526     if( !pId )
527     {
528         MutexGuard                      aGuard( Mutex::getGlobalMutex() );
529         if( !pId)
530         {
531             static OImplementationId    aId;
532             pId = &aId;
533         }
534     }
535     return pId->getImplementationId();
536 }
537 
538 void SvtRulerAccessible::ThrowExceptionIfNotAlive( void ) throw( lang::DisposedException )
539 {
540     if( IsNotAlive() )
541         throw lang::DisposedException();
542 }
543 
544 void SvtRulerAccessible::addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener )throw( com::sun::star::uno::RuntimeException )
545 {
546     cppu::WeakAggComponentImplHelperBase::addEventListener( xListener );
547 }
548 
549 void SvtRulerAccessible::removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw( com::sun::star::uno::RuntimeException )
550 {
551     cppu::WeakAggComponentImplHelperBase::removeEventListener( xListener );
552 }
553 
554 
555 // -------------------------------------------------------------------------------------------------
556 
557