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