1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: accselectionhelper.cxx,v $
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"
35 #include <com/sun/star/accessibility/XAccessibleSelection.hpp>
36 #include <accselectionhelper.hxx>
38 #ifndef _ACCCONTEXT_HXX
39 #include <acccontext.hxx>
42 #include <svx/AccessibleShape.hxx>
45 #include <vcl/svapp.hxx> // for SolarMutex
46 #include <tools/debug.hxx>
49 using namespace ::com::sun::star
;
50 using namespace ::com::sun::star::uno
;
52 using ::com::sun::star::accessibility::XAccessible
;
53 using ::com::sun::star::accessibility::XAccessibleContext
;
54 using ::com::sun::star::accessibility::XAccessibleSelection
;
58 SwAccessibleSelectionHelper::SwAccessibleSelectionHelper(
59 SwAccessibleContext
& rCtxt
) :
64 SwAccessibleSelectionHelper::~SwAccessibleSelectionHelper()
68 SwFEShell
* SwAccessibleSelectionHelper::GetFEShell()
70 DBG_ASSERT( rContext
.GetMap() != NULL
, "no map?" );
71 ViewShell
* pViewShell
= rContext
.GetMap()->GetShell();
72 DBG_ASSERT( pViewShell
!= NULL
,
73 "No view shell? Then what are you looking at?" );
75 SwFEShell
* pFEShell
= NULL
;
76 if( pViewShell
->ISA( SwFEShell
) )
78 pFEShell
= static_cast<SwFEShell
*>( pViewShell
);
84 void SwAccessibleSelectionHelper::throwIndexOutOfBoundsException()
85 throw ( lang::IndexOutOfBoundsException
)
87 Reference
< XAccessibleContext
> xThis( &rContext
);
88 Reference
< XAccessibleSelection
>xSelThis( xThis
, UNO_QUERY
);
89 lang::IndexOutOfBoundsException
aExcept(
90 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("index out of bounds") ),
96 //===== XAccessibleSelection ============================================
98 void SwAccessibleSelectionHelper::selectAccessibleChild(
99 sal_Int32 nChildIndex
)
100 throw ( lang::IndexOutOfBoundsException
,
103 vos::OGuard
aGuard(Application::GetSolarMutex());
105 // Get the respective child as SwFrm (also do index checking), ...
106 const SwFrmOrObj aChild
= rContext
.GetChild( nChildIndex
);
107 if( !aChild
.IsValid() )
108 throwIndexOutOfBoundsException();
110 // we can only select fly frames, so we ignore (should: return
111 // false) all other attempts at child selection
112 sal_Bool bRet
= sal_False
;
113 SwFEShell
* pFEShell
= GetFEShell();
114 if( pFEShell
!= NULL
)
116 const SdrObject
*pObj
= aChild
.GetSdrObject();
119 bRet
= rContext
.Select( const_cast< SdrObject
*>( pObj
), 0==aChild
.GetSwFrm());
122 // no frame shell, or no frame, or no fly frame -> can't select
127 sal_Bool
SwAccessibleSelectionHelper::isAccessibleChildSelected(
128 sal_Int32 nChildIndex
)
129 throw ( lang::IndexOutOfBoundsException
,
132 vos::OGuard
aGuard(Application::GetSolarMutex());
134 // Get the respective child as SwFrm (also do index checking), ...
135 const SwFrmOrObj aChild
= rContext
.GetChild( nChildIndex
);
136 if( !aChild
.IsValid() )
137 throwIndexOutOfBoundsException();
139 // ... and compare to the currently selected frame
140 sal_Bool bRet
= sal_False
;
141 SwFEShell
* pFEShell
= GetFEShell();
144 if( aChild
.GetSwFrm() != 0 )
146 bRet
= (pFEShell
->GetCurrFlyFrm() == aChild
.GetSwFrm());
150 bRet
= pFEShell
->IsObjSelected( *aChild
.GetSdrObject() );
157 void SwAccessibleSelectionHelper::clearAccessibleSelection( )
158 throw ( RuntimeException
)
160 // return sal_False // we can't deselect
163 void SwAccessibleSelectionHelper::selectAllAccessibleChildren( )
164 throw ( RuntimeException
)
166 vos::OGuard
aGuard(Application::GetSolarMutex());
168 // We can select only one. So iterate over the children to find
169 // the first we can select, and select it.
171 SwFEShell
* pFEShell
= GetFEShell();
174 ::std::list
< SwFrmOrObj
> aChildren
;
175 rContext
.GetChildren( aChildren
);
177 ::std::list
< SwFrmOrObj
>::const_iterator aIter
= aChildren
.begin();
178 ::std::list
< SwFrmOrObj
>::const_iterator aEndIter
= aChildren
.end();
179 while( aIter
!= aEndIter
)
181 const SwFrmOrObj
& rChild
= *aIter
;
182 const SdrObject
*pObj
= rChild
.GetSdrObject();
183 const SwFrm
* pFrm
= rChild
.GetSwFrm();
184 if( pObj
&& !(pFrm
!= 0 && pFEShell
->IsObjSelected()) )
186 rContext
.Select( const_cast< SdrObject
*>( pObj
), 0==pFrm
);
195 sal_Int32
SwAccessibleSelectionHelper::getSelectedAccessibleChildCount( )
196 throw ( RuntimeException
)
198 vos::OGuard
aGuard(Application::GetSolarMutex());
200 sal_Int32 nCount
= 0;
201 // Only one frame can be selected at a time, and we only frames
202 // for selectable children.
203 SwFEShell
* pFEShell
= GetFEShell();
206 const SwFlyFrm
*pFlyFrm
= pFEShell
->GetCurrFlyFrm();
209 if( rContext
.GetParent(pFlyFrm
, rContext
.IsInPagePreview()) ==
217 sal_uInt16 nSelObjs
= pFEShell
->IsObjSelected();
220 ::std::list
< SwFrmOrObj
> aChildren
;
221 rContext
.GetChildren( aChildren
);
223 ::std::list
< SwFrmOrObj
>::const_iterator aIter
=
225 ::std::list
< SwFrmOrObj
>::const_iterator aEndIter
=
227 while( aIter
!= aEndIter
&& nCount
< nSelObjs
)
229 const SwFrmOrObj
& rChild
= *aIter
;
230 if( rChild
.GetSdrObject() && !rChild
.GetSwFrm() &&
231 rContext
.GetParent(rChild
, rContext
.IsInPagePreview())
232 == rContext
.GetFrm() &&
233 pFEShell
->IsObjSelected( *rChild
.GetSdrObject() ) )
245 Reference
<XAccessible
> SwAccessibleSelectionHelper::getSelectedAccessibleChild(
246 sal_Int32 nSelectedChildIndex
)
247 throw ( lang::IndexOutOfBoundsException
,
250 vos::OGuard
aGuard(Application::GetSolarMutex());
252 // Since the index is relative to the selected children, and since
253 // there can be at most one selected frame child, the index must
254 // be 0, and a selection must exist, otherwise we have to throw an
255 // lang::IndexOutOfBoundsException
256 SwFEShell
* pFEShell
= GetFEShell();
258 throwIndexOutOfBoundsException();
261 const SwFlyFrm
*pFlyFrm
= pFEShell
->GetCurrFlyFrm();
264 if( 0 == nSelectedChildIndex
&&
265 rContext
.GetParent(pFlyFrm
, rContext
.IsInPagePreview()) ==
273 sal_uInt16 nSelObjs
= pFEShell
->IsObjSelected();
274 if( 0 == nSelObjs
|| nSelectedChildIndex
>= nSelObjs
)
275 throwIndexOutOfBoundsException();
277 ::std::list
< SwFrmOrObj
> aChildren
;
278 rContext
.GetChildren( aChildren
);
280 ::std::list
< SwFrmOrObj
>::const_iterator aIter
= aChildren
.begin();
281 ::std::list
< SwFrmOrObj
>::const_iterator aEndIter
= aChildren
.end();
282 while( aIter
!= aEndIter
&& !aChild
.IsValid() )
284 const SwFrmOrObj
& rChild
= *aIter
;
285 if( rChild
.GetSdrObject() && !rChild
.GetSwFrm() &&
286 rContext
.GetParent(rChild
, rContext
.IsInPagePreview()) ==
288 pFEShell
->IsObjSelected( *rChild
.GetSdrObject() ) )
290 if( 0 == nSelectedChildIndex
)
293 --nSelectedChildIndex
;
299 if( !aChild
.IsValid() )
300 throwIndexOutOfBoundsException();
302 DBG_ASSERT( rContext
.GetMap() != NULL
, "We need the map." );
303 Reference
< XAccessible
> xChild
;
304 if( aChild
.GetSwFrm() )
306 ::vos::ORef
< SwAccessibleContext
> xChildImpl(
307 rContext
.GetMap()->GetContextImpl( aChild
.GetSwFrm(),
309 if( xChildImpl
.isValid() )
311 xChildImpl
->SetParent( &rContext
);
312 xChild
= xChildImpl
.getBodyPtr();
317 ::vos::ORef
< ::accessibility::AccessibleShape
> xChildImpl(
318 rContext
.GetMap()->GetContextImpl( aChild
.GetSdrObject(),
319 &rContext
, sal_True
) );
320 if( xChildImpl
.isValid() )
321 xChild
= xChildImpl
.getBodyPtr();
326 // --> OD 2004-11-16 #111714# - index has to be treated as global child index.
327 void SwAccessibleSelectionHelper::deselectAccessibleChild(
328 sal_Int32 nChildIndex
)
329 throw ( lang::IndexOutOfBoundsException
,
332 // return sal_False // we can't deselect
333 if( nChildIndex
< 0 ||
334 nChildIndex
>= rContext
.GetChildCount() )
335 throwIndexOutOfBoundsException();