sync master with lastest vba changes
[ooovba.git] / toolkit / source / controls / accessiblecontrolcontext.cxx
blobbfbe9eeb9621f4cc60d5a8507a171c2c62c6e5db
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: accessiblecontrolcontext.cxx,v $
10 * $Revision: 1.10 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_toolkit.hxx"
33 #include <toolkit/controls/accessiblecontrolcontext.hxx>
34 #include <unotools/accessiblestatesethelper.hxx>
35 #include <com/sun/star/awt/XControl.hpp>
36 #include <com/sun/star/awt/XWindow.hpp>
37 #include <vcl/svapp.hxx>
38 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
39 #include <com/sun/star/accessibility/AccessibleRole.hpp>
40 #include <toolkit/helper/vclunohelper.hxx>
41 #include <vcl/window.hxx>
43 //........................................................................
44 namespace toolkit
46 //........................................................................
48 using ::comphelper::OContextEntryGuard;
49 using namespace ::com::sun::star;
50 using namespace ::com::sun::star::uno;
51 using namespace ::com::sun::star::lang;
52 using namespace ::com::sun::star::beans;
53 using namespace ::com::sun::star::accessibility;
55 //====================================================================
56 //= OAccessibleControlContext
57 //====================================================================
58 //--------------------------------------------------------------------
59 OAccessibleControlContext::OAccessibleControlContext()
60 :OAccessibleControlContext_Base( )
62 // nothing to do here, we have a late ctor
65 //--------------------------------------------------------------------
66 OAccessibleControlContext::~OAccessibleControlContext()
68 ensureDisposed();
71 //--------------------------------------------------------------------
72 IMPLEMENT_FORWARD_XINTERFACE3( OAccessibleControlContext, OAccessibleControlContext_Base, OAccessibleImplementationAccess, OAccessibleControlContext_IBase )
73 IMPLEMENT_FORWARD_XTYPEPROVIDER3( OAccessibleControlContext, OAccessibleControlContext_Base, OAccessibleImplementationAccess, OAccessibleControlContext_IBase )
74 // (order matters: the first is the class name, the second is the class doing the ref counting)
76 //--------------------------------------------------------------------
77 void OAccessibleControlContext::Init( const Reference< XAccessible >& _rxCreator ) SAL_THROW( ( Exception ) )
79 OContextEntryGuard aGuard( this );
81 // retrieve the model of the control
82 OSL_ENSURE( !m_xControlModel.is(), "OAccessibleControlContext::Init: already know a control model....!???" );
84 Reference< awt::XControl > xControl( _rxCreator, UNO_QUERY );
85 if ( xControl.is() )
86 m_xControlModel = m_xControlModel.query( xControl->getModel() );
87 OSL_ENSURE( m_xControlModel.is(), "OAccessibleControlContext::Init: invalid creator (no control, or control without model!" );
88 if ( !m_xControlModel.is() )
89 throw DisposedException(); // caught by the caller (the create method)
91 // start listening at the model
92 startModelListening();
94 // announce the XAccessible to our base class
95 OAccessibleControlContext_Base::lateInit( _rxCreator );
98 //--------------------------------------------------------------------
99 OAccessibleControlContext* OAccessibleControlContext::create( const Reference< XAccessible >& _rxCreator ) SAL_THROW( ( ) )
101 OAccessibleControlContext* pNew = NULL;
104 pNew = new OAccessibleControlContext;
105 pNew->Init( _rxCreator );
107 catch( const Exception& )
109 OSL_ENSURE( sal_False, "OAccessibleControlContext::create: caught an exception from the late ctor!" );
111 return pNew;
114 //--------------------------------------------------------------------
115 void OAccessibleControlContext::startModelListening( ) SAL_THROW( ( Exception ) )
117 Reference< XComponent > xModelComp( m_xControlModel, UNO_QUERY );
118 OSL_ENSURE( xModelComp.is(), "OAccessibleControlContext::startModelListening: invalid model!" );
119 if ( xModelComp.is() )
120 xModelComp->addEventListener( this );
123 //--------------------------------------------------------------------
124 void OAccessibleControlContext::stopModelListening( ) SAL_THROW( ( Exception ) )
126 Reference< XComponent > xModelComp( m_xControlModel, UNO_QUERY );
127 OSL_ENSURE( xModelComp.is(), "OAccessibleControlContext::stopModelListening: invalid model!" );
128 if ( xModelComp.is() )
129 xModelComp->removeEventListener( this );
132 //--------------------------------------------------------------------
133 sal_Int32 SAL_CALL OAccessibleControlContext::getAccessibleChildCount( ) throw (RuntimeException)
135 // we do not have children
136 return 0;
139 //--------------------------------------------------------------------
140 Reference< XAccessible > SAL_CALL OAccessibleControlContext::getAccessibleChild( sal_Int32 ) throw (IndexOutOfBoundsException, RuntimeException)
142 // we do not have children
143 throw IndexOutOfBoundsException();
146 //--------------------------------------------------------------------
147 Reference< XAccessible > SAL_CALL OAccessibleControlContext::getAccessibleParent( ) throw (RuntimeException)
149 OContextEntryGuard aGuard( this );
150 OSL_ENSURE( implGetForeignControlledParent().is(), "OAccessibleControlContext::getAccessibleParent: somebody forgot to set a parent!" );
151 // this parent of us is foreign controlled - somebody has to set it using the OAccessibleImplementationAccess
152 // class, before integrating our instance into an AccessibleDocumentModel
153 return implGetForeignControlledParent();
156 //--------------------------------------------------------------------
157 sal_Int16 SAL_CALL OAccessibleControlContext::getAccessibleRole( ) throw (RuntimeException)
159 return AccessibleRole::SHAPE;
162 //--------------------------------------------------------------------
163 ::rtl::OUString SAL_CALL OAccessibleControlContext::getAccessibleDescription( ) throw (RuntimeException)
165 OContextEntryGuard aGuard( this );
166 return getModelStringProperty( "HelpText" );
169 //--------------------------------------------------------------------
170 ::rtl::OUString SAL_CALL OAccessibleControlContext::getAccessibleName( ) throw (RuntimeException)
172 OContextEntryGuard aGuard( this );
173 return getModelStringProperty( "Name" );
176 //--------------------------------------------------------------------
177 Reference< XAccessibleRelationSet > SAL_CALL OAccessibleControlContext::getAccessibleRelationSet( ) throw (RuntimeException)
179 return NULL;
182 //--------------------------------------------------------------------
183 Reference< XAccessibleStateSet > SAL_CALL OAccessibleControlContext::getAccessibleStateSet( ) throw (RuntimeException)
185 ::osl::MutexGuard aGuard( GetMutex() );
186 // no OContextEntryGuard here, as we do not want to throw an exception in case we're not alive anymore
188 ::utl::AccessibleStateSetHelper* pStateSet = NULL;
189 if ( isAlive() )
191 // no own states, only the ones which are foreign controlled
192 pStateSet = new ::utl::AccessibleStateSetHelper( implGetForeignControlledStates() );
194 else
195 { // only the DEFUNC state if we're already disposed
196 pStateSet = new ::utl::AccessibleStateSetHelper;
197 pStateSet->AddState( AccessibleStateType::DEFUNC );
199 return pStateSet;
202 //--------------------------------------------------------------------
203 void SAL_CALL OAccessibleControlContext::disposing( const EventObject&
204 #if OSL_DEBUG_LEVEL > 0
205 _rSource
206 #endif
207 ) throw ( RuntimeException )
209 OSL_ENSURE( Reference< XPropertySet >( _rSource.Source, UNO_QUERY ).get() == m_xControlModel.get(),
210 "OAccessibleControlContext::disposing: where did this come from?" );
212 stopModelListening( );
213 m_xControlModel.clear();
214 m_xModelPropsInfo.clear();
216 OAccessibleControlContext_Base::disposing();
219 //--------------------------------------------------------------------
220 ::rtl::OUString OAccessibleControlContext::getModelStringProperty( const sal_Char* _pPropertyName )
222 ::rtl::OUString sReturn;
225 if ( !m_xModelPropsInfo.is() && m_xControlModel.is() )
226 m_xModelPropsInfo = m_xControlModel->getPropertySetInfo();
228 ::rtl::OUString sPropertyName( ::rtl::OUString::createFromAscii( _pPropertyName ) );
229 if ( m_xModelPropsInfo.is() && m_xModelPropsInfo->hasPropertyByName( sPropertyName ) )
230 m_xControlModel->getPropertyValue( sPropertyName ) >>= sReturn;
232 catch( const Exception& )
234 OSL_ENSURE( sal_False, "OAccessibleControlContext::getModelStringProperty: caught an exception!" );
236 return sReturn;
239 //--------------------------------------------------------------------
240 Window* OAccessibleControlContext::implGetWindow( Reference< awt::XWindow >* _pxUNOWindow ) const
242 Reference< awt::XControl > xControl( getAccessibleCreator(), UNO_QUERY );
243 Reference< awt::XWindow > xWindow;
244 if ( xControl.is() )
245 xWindow = xWindow.query( xControl->getPeer() );
247 Window* pWindow = xWindow.is() ? VCLUnoHelper::GetWindow( xWindow ) : NULL;
249 if ( _pxUNOWindow )
250 *_pxUNOWindow = xWindow;
251 return pWindow;
254 //--------------------------------------------------------------------
255 awt::Rectangle SAL_CALL OAccessibleControlContext::implGetBounds( ) throw (RuntimeException)
257 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
258 // want to do some VCL stuff here ...
259 OContextEntryGuard aGuard( this );
261 OSL_ENSURE( sal_False, "OAccessibleControlContext::implGetBounds: performance issue: forced to calc the size myself!" );
262 // In design mode (and this is what this class is for), the surrounding shape (if any) should handle this call
263 // The problem is that in design mode, our size may not be correct (in the drawing layer, controls are
264 // positioned/sized for painting only), and that calculation of our position is expensive
266 // what we know (or can obtain from somewhere):
267 // * the PosSize of our peer, relative to it's parent window
268 // * the parent window which the PosSize is relative to
269 // * our foreign controlled accessible parent
270 // from this info, we can determine the the position of our peer relative to the foreign parent
272 // our control
273 Reference< awt::XWindow > xWindow;
274 Window* pVCLWindow = implGetWindow( &xWindow );
276 awt::Rectangle aBounds( 0, 0, 0, 0 );
277 if ( xWindow.is() )
279 // ugly, but .... though the XWindow has a getPosSize, it is impossible to determine the
280 // parent which this position/size is relative to. This means we must tunnel UNO and ask the
281 // implementation
282 Window* pVCLParent = pVCLWindow ? pVCLWindow->GetParent() : NULL;
284 // the relative location of the window
285 ::Point aWindowRelativePos( 0, 0);
286 if ( pVCLWindow )
287 aWindowRelativePos = pVCLWindow->GetPosPixel();
289 // the screnn position of the "window parent" of the control
290 ::Point aVCLParentScreenPos( 0, 0 );
291 if ( pVCLParent )
292 aVCLParentScreenPos = pVCLParent->GetPosPixel();
294 // the screen position of the "accessible parent" of the control
295 Reference< XAccessible > xParentAcc( implGetForeignControlledParent() );
296 Reference< XAccessibleComponent > xParentAccComponent;
297 if ( xParentAcc.is() )
298 xParentAccComponent = xParentAccComponent.query( xParentAcc->getAccessibleContext() );
299 awt::Point aAccParentScreenPos( 0, 0 );
300 if ( xParentAccComponent.is() )
301 aAccParentScreenPos = xParentAccComponent->getLocationOnScreen();
303 // now the size of the control
304 aBounds = xWindow->getPosSize();
306 // correct the pos
307 aBounds.X = aWindowRelativePos.X() + aVCLParentScreenPos.X() - aAccParentScreenPos.X;
308 aBounds.Y = aWindowRelativePos.Y() + aVCLParentScreenPos.Y() - aAccParentScreenPos.Y;
311 return aBounds;
314 //--------------------------------------------------------------------
315 Reference< XAccessible > SAL_CALL OAccessibleControlContext::getAccessibleAtPoint( const awt::Point& /* _rPoint */ ) throw (RuntimeException)
317 // no children at all
318 return NULL;
321 //--------------------------------------------------------------------
322 void SAL_CALL OAccessibleControlContext::grabFocus( ) throw (RuntimeException)
324 OSL_ENSURE( sal_False, "OAccessibleControlContext::grabFocus: !isFocusTraversable, but grabFocus!" );
327 //--------------------------------------------------------------------
328 Any SAL_CALL OAccessibleControlContext::getAccessibleKeyBinding( ) throw (RuntimeException)
330 // we do not have any key bindings to activate a UNO control in design mode
331 return Any();
334 //--------------------------------------------------------------------
335 sal_Int32 SAL_CALL OAccessibleControlContext::getForeground( ) throw (::com::sun::star::uno::RuntimeException)
337 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
338 // want to do some VCL stuff here ...
339 OContextEntryGuard aGuard( this );
341 Window* pWindow = implGetWindow( );
342 sal_Int32 nColor = 0;
343 if ( pWindow )
345 if ( pWindow->IsControlForeground() )
346 nColor = pWindow->GetControlForeground().GetColor();
347 else
349 Font aFont;
350 if ( pWindow->IsControlFont() )
351 aFont = pWindow->GetControlFont();
352 else
353 aFont = pWindow->GetFont();
354 nColor = aFont.GetColor().GetColor();
357 return nColor;
360 //--------------------------------------------------------------------
361 sal_Int32 SAL_CALL OAccessibleControlContext::getBackground( ) throw (::com::sun::star::uno::RuntimeException)
363 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
364 // want to do some VCL stuff here ...
365 OContextEntryGuard aGuard( this );
367 Window* pWindow = implGetWindow( );
368 sal_Int32 nColor = 0;
369 if ( pWindow )
371 if ( pWindow->IsControlBackground() )
372 nColor = pWindow->GetControlBackground().GetColor();
373 else
374 nColor = pWindow->GetBackground().GetColor().GetColor();
377 return nColor;
380 //........................................................................
381 } //namespace toolkit
382 //........................................................................