Bump version to 4.1-6
[LibreOffice.git] / editeng / source / accessibility / AccessibleParaManager.cxx
blob08d6bf05698f2f49e040f57e706deb07fd073491
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 //------------------------------------------------------------------------
23 // Global header
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>
32 //------------------------------------------------------------------------
34 // Project-local header
36 //------------------------------------------------------------------------
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"
45 using namespace ::com::sun::star;
46 using namespace ::com::sun::star::accessibility;
50 namespace accessibility
52 AccessibleParaManager::AccessibleParaManager() :
53 maChildren(1),
54 maEEOffset( 0, 0 ),
55 mnFocusedChild( -1 ),
56 mbActive( sal_False )
60 AccessibleParaManager::~AccessibleParaManager()
62 // owner is responsible for possible child defuncs
65 void AccessibleParaManager::SetAdditionalChildStates( const VectorOfStates& rChildStates )
67 maChildStates = rChildStates;
70 void AccessibleParaManager::SetNum( sal_Int32 nNumParas )
72 if( (size_t)nNumParas < maChildren.size() )
73 Release( nNumParas, maChildren.size() );
75 maChildren.resize( nNumParas );
77 if( mnFocusedChild >= nNumParas )
78 mnFocusedChild = -1;
81 sal_Int32 AccessibleParaManager::GetNum() const
83 size_t nSize = maChildren.size();
84 if (nSize > SAL_MAX_INT32)
86 SAL_WARN( "editeng", "AccessibleParaManager::GetNum - overflow " << nSize);
87 return SAL_MAX_INT32;
89 return static_cast<sal_Int32>(nSize);
92 AccessibleParaManager::VectorOfChildren::iterator AccessibleParaManager::begin()
94 return maChildren.begin();
97 AccessibleParaManager::VectorOfChildren::iterator AccessibleParaManager::end()
99 return maChildren.end();
102 AccessibleParaManager::VectorOfChildren::const_iterator AccessibleParaManager::begin() const
104 return maChildren.begin();
107 AccessibleParaManager::VectorOfChildren::const_iterator AccessibleParaManager::end() const
109 return maChildren.end();
112 void AccessibleParaManager::Release( sal_Int32 nPara )
114 DBG_ASSERT( 0 <= nPara && maChildren.size() > static_cast<size_t>(nPara),
115 "AccessibleParaManager::Release: invalid index" );
117 if( 0 <= nPara && maChildren.size() > static_cast<size_t>(nPara) )
119 ShutdownPara( GetChild( nPara ) );
121 // clear reference and rect
122 maChildren[ nPara ] = WeakChild();
126 void AccessibleParaManager::FireEvent( sal_Int32 nPara,
127 const sal_Int16 nEventId,
128 const uno::Any& rNewValue,
129 const uno::Any& rOldValue ) const
131 DBG_ASSERT( 0 <= nPara && maChildren.size() > static_cast<size_t>(nPara),
132 "AccessibleParaManager::FireEvent: invalid index" );
134 if( 0 <= nPara && maChildren.size() > static_cast<size_t>(nPara) )
136 WeakPara::HardRefType maChild( GetChild( nPara ).first.get() );
137 if( maChild.is() )
138 maChild->FireEvent( nEventId, rNewValue, rOldValue );
142 sal_Bool AccessibleParaManager::IsReferencable( WeakPara::HardRefType aChild )
144 return aChild.is();
147 sal_Bool AccessibleParaManager::IsReferencable( sal_Int32 nChild ) const
149 DBG_ASSERT( 0 <= nChild && maChildren.size() > static_cast<size_t>(nChild),
150 "AccessibleParaManager::IsReferencable: invalid index" );
152 if( 0 <= nChild && maChildren.size() > static_cast<size_t>(nChild) )
154 // retrieve hard reference from weak one
155 return IsReferencable( GetChild( nChild ).first.get() );
157 else
159 return sal_False;
163 AccessibleParaManager::WeakChild AccessibleParaManager::GetChild( sal_Int32 nParagraphIndex ) const
165 DBG_ASSERT( 0 <= nParagraphIndex && maChildren.size() > static_cast<size_t>(nParagraphIndex),
166 "AccessibleParaManager::GetChild: invalid index" );
168 if( 0 <= nParagraphIndex && maChildren.size() > static_cast<size_t>(nParagraphIndex) )
170 return maChildren[ nParagraphIndex ];
172 else
174 return WeakChild();
178 AccessibleParaManager::Child AccessibleParaManager::CreateChild( sal_Int32 nChild,
179 const uno::Reference< XAccessible >& xFrontEnd,
180 SvxEditSourceAdapter& rEditSource,
181 sal_Int32 nParagraphIndex )
183 DBG_ASSERT( 0 <= nParagraphIndex && maChildren.size() > static_cast<size_t>(nParagraphIndex),
184 "AccessibleParaManager::CreateChild: invalid index" );
186 if( 0 <= nParagraphIndex && maChildren.size() > static_cast<size_t>(nParagraphIndex) )
188 // retrieve hard reference from weak one
189 WeakPara::HardRefType aChild( GetChild( nParagraphIndex ).first.get() );
191 if( !IsReferencable( nParagraphIndex ) )
193 // there is no hard reference available, create object then
194 // #i27138#
195 AccessibleEditableTextPara* pChild = new AccessibleEditableTextPara( xFrontEnd, this );
196 uno::Reference< XAccessible > xChild( static_cast< ::cppu::OWeakObject* > (pChild), uno::UNO_QUERY );
198 if( !xChild.is() )
199 throw uno::RuntimeException("Child creation failed", xFrontEnd);
201 aChild = WeakPara::HardRefType( xChild, pChild );
203 InitChild( *aChild, rEditSource, nChild, nParagraphIndex );
205 maChildren[ nParagraphIndex ] = WeakChild( aChild, pChild->getBounds() );
208 return Child( aChild.getRef(), GetChild( nParagraphIndex ).second );
210 else
212 return Child();
216 void AccessibleParaManager::SetEEOffset( const Point& rOffset )
218 maEEOffset = rOffset;
220 MemFunAdapter< const Point& > aAdapter( &::accessibility::AccessibleEditableTextPara::SetEEOffset, rOffset );
221 ::std::for_each( begin(), end(), aAdapter );
224 void AccessibleParaManager::SetActive( sal_Bool bActive )
226 mbActive = bActive;
228 if( bActive )
230 SetState( AccessibleStateType::ACTIVE );
231 SetState( AccessibleStateType::EDITABLE );
233 else
235 UnSetState( AccessibleStateType::ACTIVE );
236 UnSetState( AccessibleStateType::EDITABLE );
240 void AccessibleParaManager::SetFocus( sal_Int32 nChild )
242 if( mnFocusedChild != -1 )
243 UnSetState( mnFocusedChild, AccessibleStateType::FOCUSED );
245 mnFocusedChild = nChild;
247 if( mnFocusedChild != -1 )
248 SetState( mnFocusedChild, AccessibleStateType::FOCUSED );
251 void AccessibleParaManager::InitChild( AccessibleEditableTextPara& rChild,
252 SvxEditSourceAdapter& rEditSource,
253 sal_Int32 nChild,
254 sal_Int32 nParagraphIndex ) const
256 rChild.SetEditSource( &rEditSource );
257 rChild.SetIndexInParent( nChild );
258 rChild.SetParagraphIndex( nParagraphIndex );
260 rChild.SetEEOffset( maEEOffset );
262 if( mbActive )
264 rChild.SetState( AccessibleStateType::ACTIVE );
265 rChild.SetState( AccessibleStateType::EDITABLE );
268 if( mnFocusedChild == nParagraphIndex )
269 rChild.SetState( AccessibleStateType::FOCUSED );
271 // add states passed from outside
272 for( VectorOfStates::const_iterator aIt = maChildStates.begin(), aEnd = maChildStates.end(); aIt != aEnd; ++aIt )
273 rChild.SetState( *aIt );
276 void AccessibleParaManager::SetState( sal_Int32 nChild, const sal_Int16 nStateId )
278 MemFunAdapter< const sal_Int16 > aFunc( &AccessibleEditableTextPara::SetState,
279 nStateId );
280 aFunc( GetChild(nChild) );
283 void AccessibleParaManager::SetState( const sal_Int16 nStateId )
285 ::std::for_each( begin(), end(),
286 MemFunAdapter< const sal_Int16 >( &AccessibleEditableTextPara::SetState,
287 nStateId ) );
290 void AccessibleParaManager::UnSetState( sal_Int32 nChild, const sal_Int16 nStateId )
292 MemFunAdapter< const sal_Int16 > aFunc( &AccessibleEditableTextPara::UnSetState,
293 nStateId );
294 aFunc( GetChild(nChild) );
297 void AccessibleParaManager::UnSetState( const sal_Int16 nStateId )
299 ::std::for_each( begin(), end(),
300 MemFunAdapter< const sal_Int16 >( &AccessibleEditableTextPara::UnSetState,
301 nStateId ) );
304 // not generic yet, no arguments...
305 class AccessibleParaManager_DisposeChildren : public ::std::unary_function< ::accessibility::AccessibleEditableTextPara&, void >
307 public:
308 AccessibleParaManager_DisposeChildren() {}
309 void operator()( ::accessibility::AccessibleEditableTextPara& rPara )
311 rPara.Dispose();
315 void AccessibleParaManager::Dispose()
317 AccessibleParaManager_DisposeChildren aFunctor;
319 ::std::for_each( begin(), end(),
320 WeakChildAdapter< AccessibleParaManager_DisposeChildren > (aFunctor) );
323 // not generic yet, too many method arguments...
324 class StateChangeEvent : public ::std::unary_function< ::accessibility::AccessibleEditableTextPara&, void >
326 public:
327 typedef void return_type;
328 StateChangeEvent( const sal_Int16 nEventId,
329 const uno::Any& rNewValue,
330 const uno::Any& rOldValue ) :
331 mnEventId( nEventId ),
332 mrNewValue( rNewValue ),
333 mrOldValue( rOldValue ) {}
334 void operator()( ::accessibility::AccessibleEditableTextPara& rPara )
336 rPara.FireEvent( mnEventId, mrNewValue, mrOldValue );
339 private:
340 const sal_Int16 mnEventId;
341 const uno::Any& mrNewValue;
342 const uno::Any& mrOldValue;
345 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
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" );
356 if( 0 <= nStartPara && 0 <= nEndPara &&
357 maChildren.size() > static_cast<size_t>(nStartPara) &&
358 maChildren.size() >= static_cast<size_t>(nEndPara) )
360 VectorOfChildren::const_iterator front = maChildren.begin();
361 VectorOfChildren::const_iterator back = front;
363 ::std::advance( front, nStartPara );
364 ::std::advance( back, nEndPara );
366 StateChangeEvent aFunctor( nEventId, rNewValue, rOldValue );
368 ::std::for_each( front, back, AccessibleParaManager::WeakChildAdapter< StateChangeEvent >( aFunctor ) );
372 class ReleaseChild : public ::std::unary_function< const AccessibleParaManager::WeakChild&, AccessibleParaManager::WeakChild >
374 public:
375 AccessibleParaManager::WeakChild operator()( const AccessibleParaManager::WeakChild& rPara )
377 AccessibleParaManager::ShutdownPara( rPara );
379 // clear reference
380 return AccessibleParaManager::WeakChild();
384 void AccessibleParaManager::Release( sal_Int32 nStartPara, sal_Int32 nEndPara )
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" );
391 if( 0 <= nStartPara && 0 <= nEndPara &&
392 maChildren.size() > static_cast<size_t>(nStartPara) &&
393 maChildren.size() >= static_cast<size_t>(nEndPara) )
395 VectorOfChildren::iterator front = maChildren.begin();
396 VectorOfChildren::iterator back = front;
398 ::std::advance( front, nStartPara );
399 ::std::advance( back, nEndPara );
401 ::std::transform( front, back, front, ReleaseChild() );
405 void AccessibleParaManager::ShutdownPara( const WeakChild& rChild )
407 WeakPara::HardRefType aChild( rChild.first.get() );
409 if( IsReferencable( aChild ) )
410 aChild->SetEditSource( NULL );
415 //------------------------------------------------------------------------
417 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */