Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : //------------------------------------------------------------------------
22 : //
23 : // Global header
24 : //
25 : //------------------------------------------------------------------------
26 : #include <com/sun/star/uno/Any.hxx>
27 : #include <com/sun/star/uno/Reference.hxx>
28 : #include <cppuhelper/weakref.hxx>
29 : #include <com/sun/star/accessibility/XAccessible.hpp>
30 : #include <com/sun/star/accessibility/AccessibleStateType.hpp>
31 :
32 : //------------------------------------------------------------------------
33 : //
34 : // Project-local header
35 : //
36 : //------------------------------------------------------------------------
37 :
38 : #include <editeng/unoedhlp.hxx>
39 : #include <editeng/unopracc.hxx>
40 : #include <editeng/unoedsrc.hxx>
41 : #include "editeng/AccessibleParaManager.hxx"
42 : #include "editeng/AccessibleEditableTextPara.hxx"
43 :
44 :
45 : using namespace ::com::sun::star;
46 : using namespace ::com::sun::star::accessibility;
47 :
48 :
49 :
50 : namespace accessibility
51 : {
52 31 : AccessibleParaManager::AccessibleParaManager() :
53 : maChildren(1),
54 : maEEOffset( 0, 0 ),
55 : mnFocusedChild( -1 ),
56 31 : mbActive( sal_False )
57 : {
58 31 : }
59 :
60 23 : AccessibleParaManager::~AccessibleParaManager()
61 : {
62 : // owner is responsible for possible child defuncs
63 23 : }
64 :
65 7 : void AccessibleParaManager::SetAdditionalChildStates( const VectorOfStates& rChildStates )
66 : {
67 7 : maChildStates = rChildStates;
68 7 : }
69 :
70 64 : void AccessibleParaManager::SetNum( sal_Int32 nNumParas )
71 : {
72 64 : if( (size_t)nNumParas < maChildren.size() )
73 33 : Release( nNumParas, maChildren.size() );
74 :
75 64 : maChildren.resize( nNumParas );
76 :
77 64 : if( mnFocusedChild >= nNumParas )
78 0 : mnFocusedChild = -1;
79 64 : }
80 :
81 7 : sal_Int32 AccessibleParaManager::GetNum() const
82 : {
83 7 : size_t nSize = maChildren.size();
84 7 : if (nSize > SAL_MAX_INT32)
85 : {
86 : SAL_WARN( "editeng", "AccessibleParaManager::GetNum - overflow " << nSize);
87 0 : return SAL_MAX_INT32;
88 : }
89 7 : return static_cast<sal_Int32>(nSize);
90 : }
91 :
92 100 : AccessibleParaManager::VectorOfChildren::iterator AccessibleParaManager::begin()
93 : {
94 100 : return maChildren.begin();
95 : }
96 :
97 81 : AccessibleParaManager::VectorOfChildren::iterator AccessibleParaManager::end()
98 : {
99 81 : return maChildren.end();
100 : }
101 :
102 0 : AccessibleParaManager::VectorOfChildren::const_iterator AccessibleParaManager::begin() const
103 : {
104 0 : return maChildren.begin();
105 : }
106 :
107 0 : AccessibleParaManager::VectorOfChildren::const_iterator AccessibleParaManager::end() const
108 : {
109 0 : return maChildren.end();
110 : }
111 :
112 1 : void AccessibleParaManager::Release( sal_Int32 nPara )
113 : {
114 : DBG_ASSERT( 0 <= nPara && maChildren.size() > static_cast<size_t>(nPara),
115 : "AccessibleParaManager::Release: invalid index" );
116 :
117 1 : if( 0 <= nPara && maChildren.size() > static_cast<size_t>(nPara) )
118 : {
119 1 : ShutdownPara( GetChild( nPara ) );
120 :
121 : // clear reference and rect
122 1 : maChildren[ nPara ] = WeakChild();
123 : }
124 1 : }
125 :
126 0 : void AccessibleParaManager::FireEvent( sal_Int32 nPara,
127 : const sal_Int16 nEventId,
128 : const uno::Any& rNewValue,
129 : const uno::Any& rOldValue ) const
130 : {
131 : DBG_ASSERT( 0 <= nPara && maChildren.size() > static_cast<size_t>(nPara),
132 : "AccessibleParaManager::FireEvent: invalid index" );
133 :
134 0 : if( 0 <= nPara && maChildren.size() > static_cast<size_t>(nPara) )
135 : {
136 0 : WeakPara::HardRefType maChild( GetChild( nPara ).first.get() );
137 0 : if( maChild.is() )
138 0 : maChild->FireEvent( nEventId, rNewValue, rOldValue );
139 : }
140 0 : }
141 :
142 76 : sal_Bool AccessibleParaManager::IsReferencable( WeakPara::HardRefType aChild )
143 : {
144 76 : return aChild.is();
145 : }
146 :
147 42 : sal_Bool AccessibleParaManager::IsReferencable( sal_Int32 nChild ) const
148 : {
149 : DBG_ASSERT( 0 <= nChild && maChildren.size() > static_cast<size_t>(nChild),
150 : "AccessibleParaManager::IsReferencable: invalid index" );
151 :
152 42 : if( 0 <= nChild && maChildren.size() > static_cast<size_t>(nChild) )
153 : {
154 : // retrieve hard reference from weak one
155 42 : return IsReferencable( GetChild( nChild ).first.get() );
156 : }
157 : else
158 : {
159 0 : return sal_False;
160 : }
161 : }
162 :
163 151 : AccessibleParaManager::WeakChild AccessibleParaManager::GetChild( sal_Int32 nParagraphIndex ) const
164 : {
165 : DBG_ASSERT( 0 <= nParagraphIndex && maChildren.size() > static_cast<size_t>(nParagraphIndex),
166 : "AccessibleParaManager::GetChild: invalid index" );
167 :
168 151 : if( 0 <= nParagraphIndex && maChildren.size() > static_cast<size_t>(nParagraphIndex) )
169 : {
170 151 : return maChildren[ nParagraphIndex ];
171 : }
172 : else
173 : {
174 0 : return WeakChild();
175 : }
176 : }
177 :
178 33 : AccessibleParaManager::Child AccessibleParaManager::CreateChild( sal_Int32 nChild,
179 : const uno::Reference< XAccessible >& xFrontEnd,
180 : SvxEditSourceAdapter& rEditSource,
181 : sal_Int32 nParagraphIndex )
182 : {
183 : DBG_ASSERT( 0 <= nParagraphIndex && maChildren.size() > static_cast<size_t>(nParagraphIndex),
184 : "AccessibleParaManager::CreateChild: invalid index" );
185 :
186 33 : if( 0 <= nParagraphIndex && maChildren.size() > static_cast<size_t>(nParagraphIndex) )
187 : {
188 : // retrieve hard reference from weak one
189 33 : WeakPara::HardRefType aChild( GetChild( nParagraphIndex ).first.get() );
190 :
191 33 : if( !IsReferencable( nParagraphIndex ) )
192 : {
193 : // there is no hard reference available, create object then
194 : // #i27138#
195 25 : AccessibleEditableTextPara* pChild = new AccessibleEditableTextPara( xFrontEnd, this );
196 25 : uno::Reference< XAccessible > xChild( static_cast< ::cppu::OWeakObject* > (pChild), uno::UNO_QUERY );
197 :
198 25 : if( !xChild.is() )
199 0 : throw uno::RuntimeException("Child creation failed", xFrontEnd);
200 :
201 25 : aChild = WeakPara::HardRefType( xChild, pChild );
202 :
203 25 : InitChild( *aChild, rEditSource, nChild, nParagraphIndex );
204 :
205 25 : maChildren[ nParagraphIndex ] = WeakChild( aChild, pChild->getBounds() );
206 : }
207 :
208 33 : return Child( aChild.getRef(), GetChild( nParagraphIndex ).second );
209 : }
210 : else
211 : {
212 0 : return Child();
213 : }
214 : }
215 :
216 0 : void AccessibleParaManager::SetEEOffset( const Point& rOffset )
217 : {
218 0 : maEEOffset = rOffset;
219 :
220 0 : MemFunAdapter< const Point& > aAdapter( &::accessibility::AccessibleEditableTextPara::SetEEOffset, rOffset );
221 0 : ::std::for_each( begin(), end(), aAdapter );
222 0 : }
223 :
224 0 : void AccessibleParaManager::SetActive( sal_Bool bActive )
225 : {
226 0 : mbActive = bActive;
227 :
228 0 : if( bActive )
229 : {
230 0 : SetState( AccessibleStateType::ACTIVE );
231 0 : SetState( AccessibleStateType::EDITABLE );
232 : }
233 : else
234 : {
235 0 : UnSetState( AccessibleStateType::ACTIVE );
236 0 : UnSetState( AccessibleStateType::EDITABLE );
237 : }
238 0 : }
239 :
240 0 : void AccessibleParaManager::SetFocus( sal_Int32 nChild )
241 : {
242 0 : if( mnFocusedChild != -1 )
243 0 : UnSetState( mnFocusedChild, AccessibleStateType::FOCUSED );
244 :
245 0 : mnFocusedChild = nChild;
246 :
247 0 : if( mnFocusedChild != -1 )
248 0 : SetState( mnFocusedChild, AccessibleStateType::FOCUSED );
249 0 : }
250 :
251 25 : void AccessibleParaManager::InitChild( AccessibleEditableTextPara& rChild,
252 : SvxEditSourceAdapter& rEditSource,
253 : sal_Int32 nChild,
254 : sal_Int32 nParagraphIndex ) const
255 : {
256 25 : rChild.SetEditSource( &rEditSource );
257 25 : rChild.SetIndexInParent( nChild );
258 25 : rChild.SetParagraphIndex( nParagraphIndex );
259 :
260 25 : rChild.SetEEOffset( maEEOffset );
261 :
262 25 : if( mbActive )
263 : {
264 0 : rChild.SetState( AccessibleStateType::ACTIVE );
265 0 : rChild.SetState( AccessibleStateType::EDITABLE );
266 : }
267 :
268 25 : if( mnFocusedChild == nParagraphIndex )
269 0 : rChild.SetState( AccessibleStateType::FOCUSED );
270 :
271 : // add states passed from outside
272 31 : for( VectorOfStates::const_iterator aIt = maChildStates.begin(), aEnd = maChildStates.end(); aIt != aEnd; ++aIt )
273 6 : rChild.SetState( *aIt );
274 25 : }
275 :
276 0 : void AccessibleParaManager::SetState( sal_Int32 nChild, const sal_Int16 nStateId )
277 : {
278 : MemFunAdapter< const sal_Int16 > aFunc( &AccessibleEditableTextPara::SetState,
279 0 : nStateId );
280 0 : aFunc( GetChild(nChild) );
281 0 : }
282 :
283 0 : void AccessibleParaManager::SetState( const sal_Int16 nStateId )
284 : {
285 : ::std::for_each( begin(), end(),
286 : MemFunAdapter< const sal_Int16 >( &AccessibleEditableTextPara::SetState,
287 0 : nStateId ) );
288 0 : }
289 :
290 0 : void AccessibleParaManager::UnSetState( sal_Int32 nChild, const sal_Int16 nStateId )
291 : {
292 : MemFunAdapter< const sal_Int16 > aFunc( &AccessibleEditableTextPara::UnSetState,
293 0 : nStateId );
294 0 : aFunc( GetChild(nChild) );
295 0 : }
296 :
297 0 : void AccessibleParaManager::UnSetState( const sal_Int16 nStateId )
298 : {
299 : ::std::for_each( begin(), end(),
300 : MemFunAdapter< const sal_Int16 >( &AccessibleEditableTextPara::UnSetState,
301 0 : nStateId ) );
302 0 : }
303 :
304 : // not generic yet, no arguments...
305 : class AccessibleParaManager_DisposeChildren : public ::std::unary_function< ::accessibility::AccessibleEditableTextPara&, void >
306 : {
307 : public:
308 62 : AccessibleParaManager_DisposeChildren() {}
309 17 : void operator()( ::accessibility::AccessibleEditableTextPara& rPara )
310 : {
311 17 : rPara.Dispose();
312 17 : }
313 : };
314 :
315 62 : void AccessibleParaManager::Dispose()
316 : {
317 62 : AccessibleParaManager_DisposeChildren aFunctor;
318 :
319 : ::std::for_each( begin(), end(),
320 62 : WeakChildAdapter< AccessibleParaManager_DisposeChildren > (aFunctor) );
321 62 : }
322 :
323 : // not generic yet, too many method arguments...
324 : class StateChangeEvent : public ::std::unary_function< ::accessibility::AccessibleEditableTextPara&, void >
325 : {
326 : public:
327 : typedef void return_type;
328 0 : StateChangeEvent( const sal_Int16 nEventId,
329 : const uno::Any& rNewValue,
330 : const uno::Any& rOldValue ) :
331 : mnEventId( nEventId ),
332 : mrNewValue( rNewValue ),
333 0 : mrOldValue( rOldValue ) {}
334 0 : void operator()( ::accessibility::AccessibleEditableTextPara& rPara )
335 : {
336 0 : rPara.FireEvent( mnEventId, mrNewValue, mrOldValue );
337 0 : }
338 :
339 : private:
340 : const sal_Int16 mnEventId;
341 : const uno::Any& mrNewValue;
342 : const uno::Any& mrOldValue;
343 : };
344 :
345 0 : void AccessibleParaManager::FireEvent( sal_Int32 nStartPara,
346 : sal_Int32 nEndPara,
347 : const sal_Int16 nEventId,
348 : const uno::Any& rNewValue,
349 : const uno::Any& rOldValue ) const
350 : {
351 : DBG_ASSERT( 0 <= nStartPara && 0 <= nEndPara &&
352 : maChildren.size() > static_cast<size_t>(nStartPara) &&
353 : maChildren.size() >= static_cast<size_t>(nEndPara) ,
354 : "AccessibleParaManager::FireEvent: invalid index" );
355 :
356 0 : if( 0 <= nStartPara && 0 <= nEndPara &&
357 0 : maChildren.size() > static_cast<size_t>(nStartPara) &&
358 0 : maChildren.size() >= static_cast<size_t>(nEndPara) )
359 : {
360 0 : VectorOfChildren::const_iterator front = maChildren.begin();
361 0 : VectorOfChildren::const_iterator back = front;
362 :
363 0 : ::std::advance( front, nStartPara );
364 0 : ::std::advance( back, nEndPara );
365 :
366 0 : StateChangeEvent aFunctor( nEventId, rNewValue, rOldValue );
367 :
368 0 : ::std::for_each( front, back, AccessibleParaManager::WeakChildAdapter< StateChangeEvent >( aFunctor ) );
369 : }
370 0 : }
371 :
372 : class ReleaseChild : public ::std::unary_function< const AccessibleParaManager::WeakChild&, AccessibleParaManager::WeakChild >
373 : {
374 : public:
375 33 : AccessibleParaManager::WeakChild operator()( const AccessibleParaManager::WeakChild& rPara )
376 : {
377 33 : AccessibleParaManager::ShutdownPara( rPara );
378 :
379 : // clear reference
380 33 : return AccessibleParaManager::WeakChild();
381 : }
382 : };
383 :
384 33 : void AccessibleParaManager::Release( sal_Int32 nStartPara, sal_Int32 nEndPara )
385 : {
386 : DBG_ASSERT( 0 <= nStartPara && 0 <= nEndPara &&
387 : maChildren.size() > static_cast<size_t>(nStartPara) &&
388 : maChildren.size() >= static_cast<size_t>(nEndPara),
389 : "AccessibleParaManager::Release: invalid index" );
390 :
391 99 : if( 0 <= nStartPara && 0 <= nEndPara &&
392 99 : maChildren.size() > static_cast<size_t>(nStartPara) &&
393 33 : maChildren.size() >= static_cast<size_t>(nEndPara) )
394 : {
395 33 : VectorOfChildren::iterator front = maChildren.begin();
396 33 : VectorOfChildren::iterator back = front;
397 :
398 33 : ::std::advance( front, nStartPara );
399 33 : ::std::advance( back, nEndPara );
400 :
401 33 : ::std::transform( front, back, front, ReleaseChild() );
402 : }
403 33 : }
404 :
405 34 : void AccessibleParaManager::ShutdownPara( const WeakChild& rChild )
406 : {
407 34 : WeakPara::HardRefType aChild( rChild.first.get() );
408 :
409 34 : if( IsReferencable( aChild ) )
410 3 : aChild->SetEditSource( NULL );
411 34 : }
412 :
413 : }
414 :
415 : //------------------------------------------------------------------------
416 :
417 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|