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