1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_comphelper.hxx"
30 #include <comphelper/accimplaccess.hxx>
31 #include <com/sun/star/accessibility/XAccessible.hpp>
32 #include <com/sun/star/accessibility/XAccessibleContext.hpp>
33 #include <cppuhelper/typeprovider.hxx>
34 
35 #include <set>
36 
37 //.........................................................................
38 namespace comphelper
39 {
40 //.........................................................................
41 
42 #define BITFIELDSIZE	( sizeof( sal_Int64 ) * 8 )
43 	// maximum number of bits we have in a sal_Int64
44 
45 	using ::com::sun::star::uno::Reference;
46 	using ::com::sun::star::uno::Sequence;
47 	using ::com::sun::star::uno::Exception;
48 	using ::com::sun::star::uno::UNO_QUERY;
49 	using ::com::sun::star::uno::RuntimeException;
50 	using ::com::sun::star::lang::XUnoTunnel;
51 	using ::com::sun::star::accessibility::XAccessible;
52 	using ::com::sun::star::accessibility::XAccessibleContext;
53 
54 	//=====================================================================
55 	//= OAccImpl_Impl
56 	//=====================================================================
57 	struct OAccImpl_Impl
58 	{
59 		Reference< XAccessible >	m_xAccParent;
60 		sal_Int64					m_nForeignControlledStates;
61 	};
62 
63 
64 	//=====================================================================
65 	//= OAccessibleImplementationAccess
66 	//=====================================================================
67 	//---------------------------------------------------------------------
68 	OAccessibleImplementationAccess::OAccessibleImplementationAccess( )
69 		:m_pImpl( new OAccImpl_Impl	)
70 	{
71 	}
72 
73 	//---------------------------------------------------------------------
74 	OAccessibleImplementationAccess::~OAccessibleImplementationAccess( )
75 	{
76 		delete m_pImpl;
77 		m_pImpl = NULL;
78 	}
79 
80 	//---------------------------------------------------------------------
81 	Reference< XAccessible > OAccessibleImplementationAccess::implGetForeignControlledParent( ) const
82 	{
83 		return m_pImpl->m_xAccParent;
84 	}
85 
86 	//---------------------------------------------------------------------
87 	void OAccessibleImplementationAccess::setAccessibleParent( const Reference< XAccessible >& _rxAccParent )
88 	{
89 		m_pImpl->m_xAccParent = _rxAccParent;
90 	}
91 
92 	//---------------------------------------------------------------------
93 	sal_Int64 OAccessibleImplementationAccess::implGetForeignControlledStates( ) const
94 	{
95 		return m_pImpl->m_nForeignControlledStates;
96 	}
97 
98 	//---------------------------------------------------------------------
99 	void OAccessibleImplementationAccess::setStateBit( const sal_Int16 _nState, const sal_Bool _bSet )
100 	{
101 		OSL_ENSURE( _nState >= 0 && static_cast< sal_uInt16 >(_nState) < BITFIELDSIZE, "OAccessibleImplementationAccess::setStateBit: no more bits (shutting down the universe now)!" );
102 
103 		sal_uInt64 nBitMask( 1 );
104 		nBitMask <<= _nState;
105 		if ( _bSet )
106 			m_pImpl->m_nForeignControlledStates |= nBitMask;
107 		else
108 			m_pImpl->m_nForeignControlledStates &= ~nBitMask;
109 	}
110 
111 	//---------------------------------------------------------------------
112 	sal_Bool OAccessibleImplementationAccess::setForeignControlledState( const Reference< XAccessibleContext >& _rxComponent, const sal_Int16 _nState,
113 		const sal_Bool	_bSet )
114 	{
115 		OAccessibleImplementationAccess* pImplementation = getImplementation( _rxComponent );
116 
117 		if ( pImplementation )
118 			pImplementation->setStateBit( _nState, _bSet );
119 
120 		return ( NULL != pImplementation );
121 	}
122 
123 	//---------------------------------------------------------------------
124 	const Sequence< sal_Int8 >& OAccessibleImplementationAccess::getUnoTunnelImplementationId()
125 	{
126 		static Sequence< sal_Int8 > aId;
127 		if ( !aId.getLength() )
128 		{
129 			::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
130 			if ( !aId.getLength() )
131 			{
132 				static ::cppu::OImplementationId aImplId;
133 				// unfortunately, the OImplementationId::getImplementationId returns a copy, not a static reference ...
134 				aId = aImplId.getImplementationId();
135 			}
136 		}
137 		return aId;
138 	}
139 
140 	//---------------------------------------------------------------------
141 	sal_Int64 SAL_CALL OAccessibleImplementationAccess::getSomething( const Sequence< sal_Int8 >& _rIdentifier ) throw (RuntimeException)
142 	{
143 		sal_Int64 nReturn( 0 );
144 
145 		if	(	( _rIdentifier.getLength() == 16 )
146 			&&	( 0 == rtl_compareMemory( getUnoTunnelImplementationId().getConstArray(), _rIdentifier.getConstArray(), 16 ) )
147 			)
148 			nReturn = reinterpret_cast< sal_Int64 >( this );
149 
150 		return nReturn;
151 	}
152 
153 	//---------------------------------------------------------------------
154 	OAccessibleImplementationAccess* OAccessibleImplementationAccess::getImplementation( const Reference< XAccessibleContext >& _rxComponent )
155 	{
156 		OAccessibleImplementationAccess* pImplementation = NULL;
157 		try
158 		{
159 			Reference< XUnoTunnel > xTunnel( _rxComponent, UNO_QUERY );
160 			if ( xTunnel.is() )
161 			{
162 				pImplementation = reinterpret_cast< OAccessibleImplementationAccess* >(
163 						xTunnel->getSomething( getUnoTunnelImplementationId() ) );
164 			}
165 		}
166 		catch( const Exception& )
167 		{
168 			OSL_ENSURE( sal_False, "OAccessibleImplementationAccess::setAccessibleParent: caught an exception while retrieving the implementation!" );
169 		}
170 		return pImplementation;
171 	}
172 
173 	//---------------------------------------------------------------------
174 	sal_Bool OAccessibleImplementationAccess::setAccessibleParent(
175 			const Reference< XAccessibleContext >& _rxComponent, const Reference< XAccessible >& _rxNewParent )
176 	{
177 		OAccessibleImplementationAccess* pImplementation = getImplementation( _rxComponent );
178 
179 		if ( pImplementation )
180 			pImplementation->setAccessibleParent( _rxNewParent );
181 
182 		return ( NULL != pImplementation );
183 	}
184 
185 //.........................................................................
186 }	// namespace comphelper
187 //.........................................................................
188 
189 
190