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