merge the formfield patch from ooo-build
[ooovba.git] / sw / source / core / access / accselectionhelper.cxx
blobaf05960348961af1a90d520f5afa3923c9550344
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: accselectionhelper.cxx,v $
10 * $Revision: 1.14 $
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>
40 #endif
41 #include <accmap.hxx>
42 #include <svx/AccessibleShape.hxx>
43 #include <viewsh.hxx>
44 #include "fesh.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 ) :
60 rContext( 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 );
81 return pFEShell;
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") ),
91 xSelThis ); \
92 throw aExcept;
96 //===== XAccessibleSelection ============================================
98 void SwAccessibleSelectionHelper::selectAccessibleChild(
99 sal_Int32 nChildIndex )
100 throw ( lang::IndexOutOfBoundsException,
101 RuntimeException )
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();
117 if( pObj )
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
124 // return bRet;
127 sal_Bool SwAccessibleSelectionHelper::isAccessibleChildSelected(
128 sal_Int32 nChildIndex )
129 throw ( lang::IndexOutOfBoundsException,
130 RuntimeException )
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();
142 if( pFEShell )
144 if( aChild.GetSwFrm() != 0 )
146 bRet = (pFEShell->GetCurrFlyFrm() == aChild.GetSwFrm());
148 else
150 bRet = pFEShell->IsObjSelected( *aChild.GetSdrObject() );
154 return bRet;
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();
172 if( pFEShell )
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 );
187 if( pFrm )
188 break;
190 ++aIter;
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();
204 if( pFEShell != 0 )
206 const SwFlyFrm *pFlyFrm = pFEShell->GetCurrFlyFrm();
207 if( pFlyFrm )
209 if( rContext.GetParent(pFlyFrm, rContext.IsInPagePreview()) ==
210 rContext.GetFrm() )
212 nCount = 1;
215 else
217 sal_uInt16 nSelObjs = pFEShell->IsObjSelected();
218 if( nSelObjs > 0 )
220 ::std::list< SwFrmOrObj > aChildren;
221 rContext.GetChildren( aChildren );
223 ::std::list< SwFrmOrObj >::const_iterator aIter =
224 aChildren.begin();
225 ::std::list< SwFrmOrObj >::const_iterator aEndIter =
226 aChildren.end();
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() ) )
235 nCount++;
237 ++aIter;
242 return nCount;
245 Reference<XAccessible> SwAccessibleSelectionHelper::getSelectedAccessibleChild(
246 sal_Int32 nSelectedChildIndex )
247 throw ( lang::IndexOutOfBoundsException,
248 RuntimeException)
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();
257 if( 0 == pFEShell )
258 throwIndexOutOfBoundsException();
260 SwFrmOrObj aChild;
261 const SwFlyFrm *pFlyFrm = pFEShell->GetCurrFlyFrm();
262 if( pFlyFrm )
264 if( 0 == nSelectedChildIndex &&
265 rContext.GetParent(pFlyFrm, rContext.IsInPagePreview()) ==
266 rContext.GetFrm() )
268 aChild = pFlyFrm;
271 else
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()) ==
287 rContext.GetFrm() &&
288 pFEShell->IsObjSelected( *rChild.GetSdrObject() ) )
290 if( 0 == nSelectedChildIndex )
291 aChild = rChild;
292 else
293 --nSelectedChildIndex;
295 ++aIter;
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(),
308 sal_True ) );
309 if( xChildImpl.isValid() )
311 xChildImpl->SetParent( &rContext );
312 xChild = xChildImpl.getBodyPtr();
315 else
317 ::vos::ORef < ::accessibility::AccessibleShape > xChildImpl(
318 rContext.GetMap()->GetContextImpl( aChild.GetSdrObject(),
319 &rContext, sal_True ) );
320 if( xChildImpl.isValid() )
321 xChild = xChildImpl.getBodyPtr();
323 return xChild;
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,
330 RuntimeException )
332 // return sal_False // we can't deselect
333 if( nChildIndex < 0 ||
334 nChildIndex >= rContext.GetChildCount() )
335 throwIndexOutOfBoundsException();