Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <com/sun/star/accessibility/XAccessibleSelection.hpp>
30 : : #include <accselectionhelper.hxx>
31 : :
32 : : #include <acccontext.hxx>
33 : : #include <accmap.hxx>
34 : : #include <svx/AccessibleShape.hxx>
35 : : #include <viewsh.hxx>
36 : : #include <fesh.hxx>
37 : : #include <vcl/svapp.hxx> // for SolarMutex
38 : : #include <flyfrm.hxx>
39 : :
40 : :
41 : : using namespace ::com::sun::star;
42 : : using namespace ::com::sun::star::uno;
43 : :
44 : : using ::com::sun::star::accessibility::XAccessible;
45 : : using ::com::sun::star::accessibility::XAccessibleContext;
46 : : using ::com::sun::star::accessibility::XAccessibleSelection;
47 : :
48 : : using namespace ::sw::access;
49 : :
50 : 57 : SwAccessibleSelectionHelper::SwAccessibleSelectionHelper(
51 : : SwAccessibleContext& rCtxt ) :
52 : 57 : rContext( rCtxt )
53 : : {
54 : 57 : }
55 : :
56 : 57 : SwAccessibleSelectionHelper::~SwAccessibleSelectionHelper()
57 : : {
58 : 57 : }
59 : :
60 : 20 : SwFEShell* SwAccessibleSelectionHelper::GetFEShell()
61 : : {
62 : : OSL_ENSURE( rContext.GetMap() != NULL, "no map?" );
63 : 20 : ViewShell* pViewShell = rContext.GetMap()->GetShell();
64 : : OSL_ENSURE( pViewShell != NULL,
65 : : "No view shell? Then what are you looking at?" );
66 : :
67 : 20 : SwFEShell* pFEShell = NULL;
68 [ + - ]: 20 : if( pViewShell->ISA( SwFEShell ) )
69 : : {
70 : 20 : pFEShell = static_cast<SwFEShell*>( pViewShell );
71 : : }
72 : :
73 : 20 : return pFEShell;
74 : : }
75 : :
76 : 16 : void SwAccessibleSelectionHelper::throwIndexOutOfBoundsException()
77 : : throw ( lang::IndexOutOfBoundsException )
78 : : {
79 [ + - ]: 16 : Reference < XAccessibleContext > xThis( &rContext );
80 [ + - ]: 16 : Reference < XAccessibleSelection >xSelThis( xThis, UNO_QUERY );
81 : : lang::IndexOutOfBoundsException aExcept(
82 : : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("index out of bounds") ),
83 [ + - ][ + - ]: 16 : xSelThis ); \
84 [ + - ]: 16 : throw aExcept;
85 : : }
86 : :
87 : :
88 : : //===== XAccessibleSelection ============================================
89 : :
90 : 4 : void SwAccessibleSelectionHelper::selectAccessibleChild(
91 : : sal_Int32 nChildIndex )
92 : : throw ( lang::IndexOutOfBoundsException,
93 : : RuntimeException )
94 : : {
95 [ + - ]: 4 : SolarMutexGuard aGuard;
96 : :
97 : : // Get the respective child as SwFrm (also do index checking), ...
98 : 4 : const SwAccessibleChild aChild = rContext.GetChild( *(rContext.GetMap()),
99 [ + - ]: 4 : nChildIndex );
100 [ + - ][ + - ]: 4 : if( !aChild.IsValid() )
101 [ - + ]: 4 : throwIndexOutOfBoundsException();
102 : :
103 : : // we can only select fly frames, so we ignore (should: return
104 : : // false) all other attempts at child selection
105 [ # # ]: 0 : SwFEShell* pFEShell = GetFEShell();
106 [ # # ]: 0 : if( pFEShell != NULL )
107 : : {
108 [ # # ]: 0 : const SdrObject *pObj = aChild.GetDrawObject();
109 [ # # ]: 0 : if( pObj )
110 [ # # ][ # # ]: 0 : rContext.Select( const_cast< SdrObject *>( pObj ), 0==aChild.GetSwFrm());
111 [ # # ]: 4 : }
112 : : // no frame shell, or no frame, or no fly frame -> can't select
113 : 0 : }
114 : :
115 : 4 : sal_Bool SwAccessibleSelectionHelper::isAccessibleChildSelected(
116 : : sal_Int32 nChildIndex )
117 : : throw ( lang::IndexOutOfBoundsException,
118 : : RuntimeException )
119 : : {
120 [ + - ]: 4 : SolarMutexGuard aGuard;
121 : :
122 : : // Get the respective child as SwFrm (also do index checking), ...
123 : 4 : const SwAccessibleChild aChild = rContext.GetChild( *(rContext.GetMap()),
124 [ + - ]: 4 : nChildIndex );
125 [ + - ][ + - ]: 4 : if( !aChild.IsValid() )
126 [ - + ]: 4 : throwIndexOutOfBoundsException();
127 : :
128 : : // ... and compare to the currently selected frame
129 : 0 : sal_Bool bRet = sal_False;
130 [ # # ]: 0 : SwFEShell* pFEShell = GetFEShell();
131 [ # # ]: 0 : if( pFEShell )
132 : : {
133 [ # # ][ # # ]: 0 : if ( aChild.GetSwFrm() != 0 )
134 : : {
135 [ # # ][ # # ]: 0 : bRet = (pFEShell->GetCurrFlyFrm() == aChild.GetSwFrm());
136 : : }
137 [ # # ][ # # ]: 0 : else if ( aChild.GetDrawObject() )
138 : : {
139 [ # # ][ # # ]: 0 : bRet = pFEShell->IsObjSelected( *aChild.GetDrawObject() );
140 : : }
141 : : }
142 : :
143 [ # # ]: 4 : return bRet;
144 : : }
145 : :
146 : 4 : void SwAccessibleSelectionHelper::clearAccessibleSelection( )
147 : : throw ( RuntimeException )
148 : : {
149 : : // return sal_False // we can't deselect
150 : 4 : }
151 : :
152 : 6 : void SwAccessibleSelectionHelper::selectAllAccessibleChildren( )
153 : : throw ( RuntimeException )
154 : : {
155 [ + - ]: 6 : SolarMutexGuard aGuard;
156 : :
157 : : // We can select only one. So iterate over the children to find
158 : : // the first we can select, and select it.
159 : :
160 [ + - ]: 6 : SwFEShell* pFEShell = GetFEShell();
161 [ + - ]: 6 : if( pFEShell )
162 : : {
163 [ + - ]: 6 : ::std::list< SwAccessibleChild > aChildren;
164 [ + - ]: 6 : rContext.GetChildren( *(rContext.GetMap()), aChildren );
165 : :
166 : 6 : ::std::list< SwAccessibleChild >::const_iterator aIter = aChildren.begin();
167 : 6 : ::std::list< SwAccessibleChild >::const_iterator aEndIter = aChildren.end();
168 [ - + ]: 6 : while( aIter != aEndIter )
169 : : {
170 : 0 : const SwAccessibleChild& rChild = *aIter;
171 [ # # ]: 0 : const SdrObject* pObj = rChild.GetDrawObject();
172 [ # # ]: 0 : const SwFrm* pFrm = rChild.GetSwFrm();
173 [ # # ][ # # ]: 0 : if( pObj && !(pFrm != 0 && pFEShell->IsObjSelected()) )
[ # # ][ # # ]
[ # # ]
174 : : {
175 [ # # ]: 0 : rContext.Select( const_cast< SdrObject *>( pObj ), 0==pFrm );
176 [ # # ]: 0 : if( pFrm )
177 : 0 : break;
178 : : }
179 : 0 : ++aIter;
180 : 6 : }
181 [ + - ]: 6 : }
182 : 6 : }
183 : :
184 : 10 : sal_Int32 SwAccessibleSelectionHelper::getSelectedAccessibleChildCount( )
185 : : throw ( RuntimeException )
186 : : {
187 [ + - ]: 10 : SolarMutexGuard aGuard;
188 : :
189 : 10 : sal_Int32 nCount = 0;
190 : : // Only one frame can be selected at a time, and we only frames
191 : : // for selectable children.
192 [ + - ]: 10 : SwFEShell* pFEShell = GetFEShell();
193 [ + - ]: 10 : if( pFEShell != 0 )
194 : : {
195 [ + - ]: 10 : const SwFlyFrm* pFlyFrm = pFEShell->GetCurrFlyFrm();
196 [ - + ]: 10 : if( pFlyFrm )
197 : : {
198 [ # # ]: 0 : if( rContext.GetParent( SwAccessibleChild(pFlyFrm), rContext.IsInPagePreview()) ==
[ # # # # ]
199 : 0 : rContext.GetFrm() )
200 : : {
201 : 0 : nCount = 1;
202 : : }
203 : : }
204 : : else
205 : : {
206 [ + - ]: 10 : sal_uInt16 nSelObjs = pFEShell->IsObjSelected();
207 [ - + ]: 10 : if( nSelObjs > 0 )
208 : : {
209 [ # # ]: 0 : ::std::list< SwAccessibleChild > aChildren;
210 [ # # ]: 0 : rContext.GetChildren( *(rContext.GetMap()), aChildren );
211 : :
212 : : ::std::list< SwAccessibleChild >::const_iterator aIter =
213 : 0 : aChildren.begin();
214 : : ::std::list< SwAccessibleChild >::const_iterator aEndIter =
215 : 0 : aChildren.end();
216 [ # # ][ # # ]: 0 : while( aIter != aEndIter && nCount < nSelObjs )
[ # # ]
217 : : {
218 : 0 : const SwAccessibleChild& rChild = *aIter;
219 [ # # ][ # # ]: 0 : if( rChild.GetDrawObject() && !rChild.GetSwFrm() &&
[ # # # # ]
[ # # ][ # # ]
[ # # ]
220 [ # # ]: 0 : rContext.GetParent(rChild, rContext.IsInPagePreview())
221 : 0 : == rContext.GetFrm() &&
222 [ # # ][ # # ]: 0 : pFEShell->IsObjSelected( *rChild.GetDrawObject() ) )
223 : : {
224 : 0 : nCount++;
225 : : }
226 : 0 : ++aIter;
227 : 0 : }
228 : : }
229 : : }
230 : : }
231 [ + - ]: 10 : return nCount;
232 : : }
233 : :
234 : 4 : Reference<XAccessible> SwAccessibleSelectionHelper::getSelectedAccessibleChild(
235 : : sal_Int32 nSelectedChildIndex )
236 : : throw ( lang::IndexOutOfBoundsException,
237 : : RuntimeException)
238 : : {
239 [ + - ]: 4 : SolarMutexGuard aGuard;
240 : :
241 : : // Since the index is relative to the selected children, and since
242 : : // there can be at most one selected frame child, the index must
243 : : // be 0, and a selection must exist, otherwise we have to throw an
244 : : // lang::IndexOutOfBoundsException
245 [ + - ]: 4 : SwFEShell* pFEShell = GetFEShell();
246 [ - + ]: 4 : if( 0 == pFEShell )
247 [ # # ]: 0 : throwIndexOutOfBoundsException();
248 : :
249 [ + - ]: 4 : SwAccessibleChild aChild;
250 [ + - ]: 4 : const SwFlyFrm *pFlyFrm = pFEShell->GetCurrFlyFrm();
251 [ - + ]: 4 : if( pFlyFrm )
252 : : {
253 [ # # # # ]: 0 : if( 0 == nSelectedChildIndex &&
[ # # ]
254 [ # # ][ # # ]: 0 : rContext.GetParent( SwAccessibleChild(pFlyFrm), rContext.IsInPagePreview()) ==
[ # # ][ # # ]
255 : 0 : rContext.GetFrm() )
256 : : {
257 [ # # ]: 0 : aChild = pFlyFrm;
258 : : }
259 : : }
260 : : else
261 : : {
262 [ + - ]: 4 : sal_uInt16 nSelObjs = pFEShell->IsObjSelected();
263 [ - + ][ # # ]: 4 : if( 0 == nSelObjs || nSelectedChildIndex >= nSelObjs )
264 [ - + ]: 4 : throwIndexOutOfBoundsException();
265 : :
266 [ # # ]: 0 : ::std::list< SwAccessibleChild > aChildren;
267 [ # # ]: 0 : rContext.GetChildren( *(rContext.GetMap()), aChildren );
268 : :
269 : 0 : ::std::list< SwAccessibleChild >::const_iterator aIter = aChildren.begin();
270 : 0 : ::std::list< SwAccessibleChild >::const_iterator aEndIter = aChildren.end();
271 [ # # ][ # # ]: 0 : while( aIter != aEndIter && !aChild.IsValid() )
[ # # ][ # # ]
272 : : {
273 : 0 : const SwAccessibleChild& rChild = *aIter;
274 [ # # ][ # # ]: 0 : if( rChild.GetDrawObject() && !rChild.GetSwFrm() &&
[ # # # # ]
[ # # ][ # # ]
[ # # ]
275 [ # # ]: 0 : rContext.GetParent(rChild, rContext.IsInPagePreview()) ==
276 : 0 : rContext.GetFrm() &&
277 [ # # ][ # # ]: 0 : pFEShell->IsObjSelected( *rChild.GetDrawObject() ) )
278 : : {
279 [ # # ]: 0 : if( 0 == nSelectedChildIndex )
280 [ # # ]: 0 : aChild = rChild;
281 : : else
282 : 0 : --nSelectedChildIndex;
283 : : }
284 : 0 : ++aIter;
285 : 4 : }
286 : : }
287 : :
288 [ # # ][ # # ]: 0 : if( !aChild.IsValid() )
289 [ # # ]: 0 : throwIndexOutOfBoundsException();
290 : :
291 : : OSL_ENSURE( rContext.GetMap() != NULL, "We need the map." );
292 : 0 : Reference< XAccessible > xChild;
293 [ # # ][ # # ]: 0 : if( aChild.GetSwFrm() )
294 : : {
295 : : ::rtl::Reference < SwAccessibleContext > xChildImpl(
296 : : rContext.GetMap()->GetContextImpl( aChild.GetSwFrm(),
297 [ # # ][ # # ]: 0 : sal_True ) );
298 [ # # ]: 0 : if( xChildImpl.is() )
299 : : {
300 [ # # ]: 0 : xChildImpl->SetParent( &rContext );
301 [ # # ][ # # ]: 0 : xChild = xChildImpl.get();
302 : 0 : }
303 : : }
304 [ # # ][ # # ]: 0 : else if ( aChild.GetDrawObject() )
305 : : {
306 : : ::rtl::Reference < ::accessibility::AccessibleShape > xChildImpl(
307 : : rContext.GetMap()->GetContextImpl( aChild.GetDrawObject(),
308 [ # # ][ # # ]: 0 : &rContext, sal_True ) );
309 [ # # ]: 0 : if( xChildImpl.is() )
310 [ # # ][ # # ]: 0 : xChild = xChildImpl.get();
311 : : }
312 [ # # ]: 4 : return xChild;
313 : : }
314 : :
315 : : // index has to be treated as global child index.
316 : 4 : void SwAccessibleSelectionHelper::deselectAccessibleChild(
317 : : sal_Int32 nChildIndex )
318 : : throw ( lang::IndexOutOfBoundsException,
319 : : RuntimeException )
320 : : {
321 : : // return sal_False // we can't deselect
322 [ + + + - ]: 6 : if( nChildIndex < 0 ||
[ + - ]
323 : 2 : nChildIndex >= rContext.GetChildCount( *(rContext.GetMap()) ) )
324 : 4 : throwIndexOutOfBoundsException();
325 : 0 : }
326 : :
327 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|