Update ooo320-m1
[ooovba.git] / sw / source / core / access / accdoc.cxx
blobfe6df813ff5ad8c1bd6267d1ffa487179d860fb8
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: accdoc.cxx,v $
10 * $Revision: 1.34 $
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_sw.hxx"
33 #include <vcl/window.hxx>
34 #include <rootfrm.hxx>
37 #include <com/sun/star/accessibility/AccessibleRole.hpp>
38 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
39 #include <com/sun/star/beans/XPropertyChangeListener.hpp>
40 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
41 #include <unotools/accessiblestatesethelper.hxx>
42 #include <tools/link.hxx>
43 #include <sfx2/viewsh.hxx>
44 #include <vos/mutex.hxx>
45 #include <vcl/svapp.hxx>
46 #include <viewsh.hxx>
47 #include <doc.hxx>
48 #include <accmap.hxx>
49 #include <accdoc.hxx>
50 #ifndef _ACCESS_HRC
51 #include "access.hrc"
52 #endif
53 #include <pagefrm.hxx>
55 const sal_Char sServiceName[] = "com.sun.star.text.AccessibleTextDocumentView";
56 const sal_Char sImplementationName[] = "com.sun.star.comp.Writer.SwAccessibleDocumentView";
59 using namespace ::com::sun::star;
60 using namespace ::com::sun::star::accessibility;
61 using ::rtl::OUString;
63 using lang::IndexOutOfBoundsException;
68 // SwAccessibleDocumentBase: base class for SwAccessibleDocument and
69 // SwAccessiblePreview
72 SwAccessibleDocumentBase::SwAccessibleDocumentBase ( SwAccessibleMap* pInitMap ) :
73 SwAccessibleContext( pInitMap, AccessibleRole::DOCUMENT,
74 pInitMap->GetShell()->getIDocumentLayoutAccess()->GetRootFrm() ),
75 mxParent( pInitMap->GetShell()->GetWin()->GetAccessibleParentWindow()->GetAccessible() ),
76 mpChildWin( 0 )
80 SwAccessibleDocumentBase::~SwAccessibleDocumentBase()
84 void SwAccessibleDocumentBase::SetVisArea()
86 vos::OGuard aGuard(Application::GetSolarMutex());
88 SwRect aOldVisArea( GetVisArea() );
89 const SwRect& rNewVisArea = GetMap()->GetVisArea();
90 if( aOldVisArea != rNewVisArea )
92 SwAccessibleFrame::SetVisArea( GetMap()->GetVisArea() );
93 // --> OD 2007-12-07 #i58139#
94 // showing state of document view needs also be updated.
95 // Thus, call method <Scrolled(..)> instead of <ChildrenScrolled(..)>
96 // ChildrenScrolled( GetFrm(), aOldVisArea );
97 Scrolled( aOldVisArea );
98 // <--
102 void SwAccessibleDocumentBase::AddChild( Window *pWin, sal_Bool bFireEvent )
104 vos::OGuard aGuard(Application::GetSolarMutex());
106 ASSERT( !mpChildWin, "only one child window is supported" );
107 if( !mpChildWin )
109 mpChildWin = pWin;
111 if( bFireEvent )
113 AccessibleEventObject aEvent;
114 aEvent.EventId = AccessibleEventId::CHILD;
115 aEvent.NewValue <<= mpChildWin->GetAccessible();
116 FireAccessibleEvent( aEvent );
121 void SwAccessibleDocumentBase::RemoveChild( Window *pWin )
123 vos::OGuard aGuard(Application::GetSolarMutex());
125 ASSERT( !mpChildWin || pWin == mpChildWin, "invalid child window to remove" );
126 if( mpChildWin && pWin == mpChildWin )
128 AccessibleEventObject aEvent;
129 aEvent.EventId = AccessibleEventId::CHILD;
130 aEvent.OldValue <<= mpChildWin->GetAccessible();
131 FireAccessibleEvent( aEvent );
133 mpChildWin = 0;
137 sal_Int32 SAL_CALL SwAccessibleDocumentBase::getAccessibleChildCount( void )
138 throw (uno::RuntimeException)
140 vos::OGuard aGuard(Application::GetSolarMutex());
142 // CHECK_FOR_DEFUNC is called by parent
144 sal_Int32 nChildren = SwAccessibleContext::getAccessibleChildCount();
145 if( !IsDisposing() && mpChildWin )
146 nChildren++;
148 return nChildren;
151 uno::Reference< XAccessible> SAL_CALL
152 SwAccessibleDocumentBase::getAccessibleChild( sal_Int32 nIndex )
153 throw (uno::RuntimeException,
154 lang::IndexOutOfBoundsException)
156 vos::OGuard aGuard(Application::GetSolarMutex());
158 if( mpChildWin )
160 CHECK_FOR_DEFUNC( XAccessibleContext )
161 if( nIndex == GetChildCount() )
162 return mpChildWin->GetAccessible();
165 return SwAccessibleContext::getAccessibleChild( nIndex );
169 uno::Reference< XAccessible> SAL_CALL SwAccessibleDocumentBase::getAccessibleParent (void)
170 throw (uno::RuntimeException)
172 return mxParent;
175 sal_Int32 SAL_CALL SwAccessibleDocumentBase::getAccessibleIndexInParent (void)
176 throw (uno::RuntimeException)
178 vos::OGuard aGuard(Application::GetSolarMutex());
180 uno::Reference < XAccessibleContext > xAcc( mxParent->getAccessibleContext() );
181 uno::Reference < XAccessible > xThis( this );
182 sal_Int32 nCount = xAcc->getAccessibleChildCount();
184 for( sal_Int32 i=0; i < nCount; i++ )
186 if( xAcc->getAccessibleChild( i ) == xThis )
187 return i;
189 return -1L;
192 OUString SAL_CALL SwAccessibleDocumentBase::getAccessibleDescription (void)
193 throw (uno::RuntimeException)
195 return GetResource( STR_ACCESS_DOC_DESC );
198 awt::Rectangle SAL_CALL SwAccessibleDocumentBase::getBounds()
199 throw (uno::RuntimeException)
201 vos::OGuard aGuard(Application::GetSolarMutex());
203 Window *pWin = GetWindow();
205 CHECK_FOR_WINDOW( XAccessibleComponent, pWin )
207 Rectangle aPixBounds( pWin->GetWindowExtentsRelative( pWin->GetAccessibleParentWindow() ) );
208 awt::Rectangle aBox( aPixBounds.Left(), aPixBounds.Top(),
209 aPixBounds.GetWidth(), aPixBounds.GetHeight() );
211 return aBox;
215 awt::Point SAL_CALL SwAccessibleDocumentBase::getLocation()
216 throw (uno::RuntimeException)
218 vos::OGuard aGuard(Application::GetSolarMutex());
220 Window *pWin = GetWindow();
222 CHECK_FOR_WINDOW( XAccessibleComponent, pWin )
224 Point aPixPos( pWin->GetWindowExtentsRelative( pWin->GetAccessibleParentWindow() ).TopLeft() );
225 awt::Point aLoc( aPixPos.X(), aPixPos.Y() );
227 return aLoc;
231 ::com::sun::star::awt::Point SAL_CALL SwAccessibleDocumentBase::getLocationOnScreen()
232 throw (uno::RuntimeException)
234 vos::OGuard aGuard(Application::GetSolarMutex());
236 Window *pWin = GetWindow();
238 CHECK_FOR_WINDOW( XAccessibleComponent, pWin )
240 Point aPixPos( pWin->GetWindowExtentsRelative( 0 ).TopLeft() );
241 awt::Point aLoc( aPixPos.X(), aPixPos.Y() );
243 return aLoc;
247 ::com::sun::star::awt::Size SAL_CALL SwAccessibleDocumentBase::getSize()
248 throw (uno::RuntimeException)
250 vos::OGuard aGuard(Application::GetSolarMutex());
252 Window *pWin = GetWindow();
254 CHECK_FOR_WINDOW( XAccessibleComponent, pWin )
256 Size aPixSize( pWin->GetWindowExtentsRelative( 0 ).GetSize() );
257 awt::Size aSize( aPixSize.Width(), aPixSize.Height() );
259 return aSize;
262 sal_Bool SAL_CALL SwAccessibleDocumentBase::containsPoint(
263 const awt::Point& aPoint )
264 throw (uno::RuntimeException)
266 vos::OGuard aGuard(Application::GetSolarMutex());
268 Window *pWin = GetWindow();
270 CHECK_FOR_WINDOW( XAccessibleComponent, pWin )
272 Rectangle aPixBounds( pWin->GetWindowExtentsRelative( 0 ) );
273 aPixBounds.Move(-aPixBounds.Left(), -aPixBounds.Top());
275 Point aPixPoint( aPoint.X, aPoint.Y );
276 return aPixBounds.IsInside( aPixPoint );
279 uno::Reference< XAccessible > SAL_CALL SwAccessibleDocumentBase::getAccessibleAtPoint(
280 const awt::Point& aPoint )
281 throw (uno::RuntimeException)
283 vos::OGuard aGuard(Application::GetSolarMutex());
285 if( mpChildWin )
287 CHECK_FOR_DEFUNC( XAccessibleComponent )
289 Window *pWin = GetWindow();
290 CHECK_FOR_WINDOW( XAccessibleComponent, pWin )
292 Point aPixPoint( aPoint.X, aPoint.Y ); // px rel to window
293 if( mpChildWin->GetWindowExtentsRelative( pWin ).IsInside( aPixPoint ) )
294 return mpChildWin->GetAccessible();
297 return SwAccessibleContext::getAccessibleAtPoint( aPoint );
301 // SwAccessibeDocument
304 void SwAccessibleDocument::GetStates(
305 ::utl::AccessibleStateSetHelper& rStateSet )
307 SwAccessibleContext::GetStates( rStateSet );
309 // MULTISELECTABLE
310 rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE );
314 SwAccessibleDocument::SwAccessibleDocument ( SwAccessibleMap* pInitMap ) :
315 SwAccessibleDocumentBase( pInitMap ),
316 maSelectionHelper( *this )
318 SetName( GetResource( STR_ACCESS_DOC_NAME ) );
319 Window *pWin = pInitMap->GetShell()->GetWin();
320 if( pWin )
322 pWin->AddChildEventListener( LINK( this, SwAccessibleDocument, WindowChildEventListener ));
323 USHORT nCount = pWin->GetChildCount();
324 for( sal_uInt16 i=0; i < nCount; i++ )
326 Window* pChildWin = pWin->GetChild( i );
327 if( pChildWin &&
328 AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
329 AddChild( pChildWin, sal_False );
334 SwAccessibleDocument::~SwAccessibleDocument()
336 Window *pWin = GetMap() ? GetMap()->GetShell()->GetWin() : 0;
337 if( pWin )
338 pWin->RemoveChildEventListener( LINK( this, SwAccessibleDocument, WindowChildEventListener ));
341 void SwAccessibleDocument::Dispose( sal_Bool bRecursive )
343 ASSERT( GetFrm() && GetMap(), "already disposed" );
345 Window *pWin = GetMap() ? GetMap()->GetShell()->GetWin() : 0;
346 if( pWin )
347 pWin->RemoveChildEventListener( LINK( this, SwAccessibleDocument, WindowChildEventListener ));
348 SwAccessibleContext::Dispose( bRecursive );
351 IMPL_LINK( SwAccessibleDocument, WindowChildEventListener, VclSimpleEvent*, pEvent )
353 DBG_ASSERT( pEvent && pEvent->ISA( VclWindowEvent ), "Unknown WindowEvent!" );
354 if ( pEvent && pEvent->ISA( VclWindowEvent ) )
356 VclWindowEvent *pVclEvent = static_cast< VclWindowEvent * >( pEvent );
357 DBG_ASSERT( pVclEvent->GetWindow(), "Window???" );
358 switch ( pVclEvent->GetId() )
360 case VCLEVENT_WINDOW_SHOW: // send create on show for direct accessible children
362 Window* pChildWin = static_cast< Window* >( pVclEvent->GetData() );
363 if( pChildWin && AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
365 AddChild( pChildWin );
368 break;
369 case VCLEVENT_WINDOW_HIDE: // send destroy on hide for direct accessible children
371 Window* pChildWin = static_cast< Window* >( pVclEvent->GetData() );
372 if( pChildWin && AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
374 RemoveChild( pChildWin );
377 break;
378 case VCLEVENT_OBJECT_DYING: // send destroy on hide for direct accessible children
380 Window* pChildWin = pVclEvent->GetWindow();
381 if( pChildWin && AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
383 RemoveChild( pChildWin );
386 break;
389 return 0;
393 OUString SAL_CALL SwAccessibleDocument::getImplementationName()
394 throw( uno::RuntimeException )
396 return OUString(RTL_CONSTASCII_USTRINGPARAM(sImplementationName));
399 sal_Bool SAL_CALL SwAccessibleDocument::supportsService(
400 const ::rtl::OUString& sTestServiceName)
401 throw (uno::RuntimeException)
403 return sTestServiceName.equalsAsciiL( sServiceName,
404 sizeof(sServiceName)-1 ) ||
405 sTestServiceName.equalsAsciiL( sAccessibleServiceName,
406 sizeof(sAccessibleServiceName)-1 );
409 uno::Sequence< OUString > SAL_CALL SwAccessibleDocument::getSupportedServiceNames()
410 throw( uno::RuntimeException )
412 uno::Sequence< OUString > aRet(2);
413 OUString* pArray = aRet.getArray();
414 pArray[0] = OUString( RTL_CONSTASCII_USTRINGPARAM(sServiceName) );
415 pArray[1] = OUString( RTL_CONSTASCII_USTRINGPARAM(sAccessibleServiceName) );
416 return aRet;
419 //===== XInterface ======================================================
421 uno::Any SwAccessibleDocument::queryInterface(
422 const uno::Type& rType )
423 throw ( uno::RuntimeException )
425 uno::Any aRet;
426 if ( rType == ::getCppuType( static_cast< uno::Reference< XAccessibleSelection > * >( 0 ) ) )
428 uno::Reference<XAccessibleSelection> aSelect = this;
429 aRet <<= aSelect;
431 else
432 aRet = SwAccessibleContext::queryInterface( rType );
433 return aRet;
436 //====== XTypeProvider ====================================================
437 uno::Sequence< uno::Type > SAL_CALL SwAccessibleDocument::getTypes()
438 throw(uno::RuntimeException)
440 uno::Sequence< uno::Type > aTypes( SwAccessibleDocumentBase::getTypes() );
442 sal_Int32 nIndex = aTypes.getLength();
443 aTypes.realloc( nIndex + 1 );
445 uno::Type* pTypes = aTypes.getArray();
446 pTypes[nIndex] = ::getCppuType( static_cast< uno::Reference< XAccessibleSelection > * >( 0 ) );
448 return aTypes;
451 uno::Sequence< sal_Int8 > SAL_CALL SwAccessibleDocument::getImplementationId()
452 throw(uno::RuntimeException)
454 vos::OGuard aGuard(Application::GetSolarMutex());
455 static uno::Sequence< sal_Int8 > aId( 16 );
456 static sal_Bool bInit = sal_False;
457 if(!bInit)
459 rtl_createUuid( (sal_uInt8 *)(aId.getArray() ), 0, sal_True );
460 bInit = sal_True;
462 return aId;
465 //===== XAccessibleSelection ============================================
467 void SwAccessibleDocument::selectAccessibleChild(
468 sal_Int32 nChildIndex )
469 throw ( lang::IndexOutOfBoundsException,
470 uno::RuntimeException )
472 maSelectionHelper.selectAccessibleChild(nChildIndex);
475 sal_Bool SwAccessibleDocument::isAccessibleChildSelected(
476 sal_Int32 nChildIndex )
477 throw ( lang::IndexOutOfBoundsException,
478 uno::RuntimeException )
480 return maSelectionHelper.isAccessibleChildSelected(nChildIndex);
483 void SwAccessibleDocument::clearAccessibleSelection( )
484 throw ( uno::RuntimeException )
486 maSelectionHelper.clearAccessibleSelection();
489 void SwAccessibleDocument::selectAllAccessibleChildren( )
490 throw ( uno::RuntimeException )
492 maSelectionHelper.selectAllAccessibleChildren();
495 sal_Int32 SwAccessibleDocument::getSelectedAccessibleChildCount( )
496 throw ( uno::RuntimeException )
498 return maSelectionHelper.getSelectedAccessibleChildCount();
501 uno::Reference<XAccessible> SwAccessibleDocument::getSelectedAccessibleChild(
502 sal_Int32 nSelectedChildIndex )
503 throw ( lang::IndexOutOfBoundsException,
504 uno::RuntimeException)
506 return maSelectionHelper.getSelectedAccessibleChild(nSelectedChildIndex);
509 // --> OD 2004-11-16 #111714# - index has to be treated as global child index.
510 void SwAccessibleDocument::deselectAccessibleChild(
511 sal_Int32 nChildIndex )
512 throw ( lang::IndexOutOfBoundsException,
513 uno::RuntimeException )
515 maSelectionHelper.deselectAccessibleChild( nChildIndex );