bump product version to 5.0.4.1
[LibreOffice.git] / editeng / source / accessibility / AccessibleParaManager.cxx
blobed36be0c825a911dcb805368d9f62b1c3dc90d76
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 .
23 // Global header
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>
34 // Project-local header
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( 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::FireEvent( sal_Int32 nPara,
113 const sal_Int16 nEventId,
114 const uno::Any& rNewValue,
115 const uno::Any& rOldValue ) const
117 DBG_ASSERT( 0 <= nPara && maChildren.size() > static_cast<size_t>(nPara),
118 "AccessibleParaManager::FireEvent: invalid index" );
120 if( 0 <= nPara && maChildren.size() > static_cast<size_t>(nPara) )
122 WeakPara::HardRefType maChild( GetChild( nPara ).first.get() );
123 if( maChild.is() )
124 maChild->FireEvent( nEventId, rNewValue, rOldValue );
128 bool AccessibleParaManager::IsReferencable( WeakPara::HardRefType aChild )
130 return aChild.is();
133 bool AccessibleParaManager::IsReferencable( sal_Int32 nChild ) const
135 DBG_ASSERT( 0 <= nChild && maChildren.size() > static_cast<size_t>(nChild),
136 "AccessibleParaManager::IsReferencable: invalid index" );
138 if( 0 <= nChild && maChildren.size() > static_cast<size_t>(nChild) )
140 // retrieve hard reference from weak one
141 return IsReferencable( GetChild( nChild ).first.get() );
143 else
145 return false;
149 AccessibleParaManager::WeakChild AccessibleParaManager::GetChild( sal_Int32 nParagraphIndex ) const
151 DBG_ASSERT( 0 <= nParagraphIndex && maChildren.size() > static_cast<size_t>(nParagraphIndex),
152 "AccessibleParaManager::GetChild: invalid index" );
154 if( 0 <= nParagraphIndex && maChildren.size() > static_cast<size_t>(nParagraphIndex) )
156 return maChildren[ nParagraphIndex ];
158 else
160 return WeakChild();
164 AccessibleParaManager::Child AccessibleParaManager::CreateChild( sal_Int32 nChild,
165 const uno::Reference< XAccessible >& xFrontEnd,
166 SvxEditSourceAdapter& rEditSource,
167 sal_Int32 nParagraphIndex )
169 DBG_ASSERT( 0 <= nParagraphIndex && maChildren.size() > static_cast<size_t>(nParagraphIndex),
170 "AccessibleParaManager::CreateChild: invalid index" );
172 if( 0 <= nParagraphIndex && maChildren.size() > static_cast<size_t>(nParagraphIndex) )
174 // retrieve hard reference from weak one
175 WeakPara::HardRefType aChild( GetChild( nParagraphIndex ).first.get() );
177 if( !IsReferencable( nParagraphIndex ) )
179 // there is no hard reference available, create object then
180 // #i27138#
181 AccessibleEditableTextPara* pChild = new AccessibleEditableTextPara( xFrontEnd, this );
182 uno::Reference< XAccessible > xChild( static_cast< ::cppu::OWeakObject* > (pChild), uno::UNO_QUERY );
184 if( !xChild.is() )
185 throw uno::RuntimeException("Child creation failed", xFrontEnd);
187 aChild = WeakPara::HardRefType( xChild, pChild );
189 InitChild( *aChild, rEditSource, nChild, nParagraphIndex );
191 maChildren[ nParagraphIndex ] = WeakChild( aChild, pChild->getBounds() );
194 return Child( aChild.getRef(), GetChild( nParagraphIndex ).second );
196 else
198 return Child();
202 void AccessibleParaManager::SetEEOffset( const Point& rOffset )
204 maEEOffset = rOffset;
206 MemFunAdapter< const Point& > aAdapter( &::accessibility::AccessibleEditableTextPara::SetEEOffset, rOffset );
207 ::std::for_each( begin(), end(), aAdapter );
210 void AccessibleParaManager::SetActive( bool bActive )
212 mbActive = bActive;
214 if( bActive )
216 SetState( AccessibleStateType::ACTIVE );
217 SetState( AccessibleStateType::EDITABLE );
219 else
221 UnSetState( AccessibleStateType::ACTIVE );
222 UnSetState( AccessibleStateType::EDITABLE );
226 void AccessibleParaManager::SetFocus( sal_Int32 nChild )
228 if( mnFocusedChild != -1 )
229 UnSetState( mnFocusedChild, AccessibleStateType::FOCUSED );
231 mnFocusedChild = nChild;
233 if( mnFocusedChild != -1 )
234 SetState( mnFocusedChild, AccessibleStateType::FOCUSED );
237 void AccessibleParaManager::InitChild( AccessibleEditableTextPara& rChild,
238 SvxEditSourceAdapter& rEditSource,
239 sal_Int32 nChild,
240 sal_Int32 nParagraphIndex ) const
242 rChild.SetEditSource( &rEditSource );
243 rChild.SetIndexInParent( nChild );
244 rChild.SetParagraphIndex( nParagraphIndex );
246 rChild.SetEEOffset( maEEOffset );
248 if( mbActive )
250 rChild.SetState( AccessibleStateType::ACTIVE );
251 rChild.SetState( AccessibleStateType::EDITABLE );
254 if( mnFocusedChild == nParagraphIndex )
255 rChild.SetState( AccessibleStateType::FOCUSED );
257 // add states passed from outside
258 for( VectorOfStates::const_iterator aIt = maChildStates.begin(), aEnd = maChildStates.end(); aIt != aEnd; ++aIt )
259 rChild.SetState( *aIt );
262 void AccessibleParaManager::SetState( sal_Int32 nChild, const sal_Int16 nStateId )
264 MemFunAdapter< const sal_Int16 > aFunc( &AccessibleEditableTextPara::SetState,
265 nStateId );
266 aFunc( GetChild(nChild) );
269 void AccessibleParaManager::SetState( const sal_Int16 nStateId )
271 ::std::for_each( begin(), end(),
272 MemFunAdapter< const sal_Int16 >( &AccessibleEditableTextPara::SetState,
273 nStateId ) );
276 void AccessibleParaManager::UnSetState( sal_Int32 nChild, const sal_Int16 nStateId )
278 MemFunAdapter< const sal_Int16 > aFunc( &AccessibleEditableTextPara::UnSetState,
279 nStateId );
280 aFunc( GetChild(nChild) );
283 void AccessibleParaManager::UnSetState( const sal_Int16 nStateId )
285 ::std::for_each( begin(), end(),
286 MemFunAdapter< const sal_Int16 >( &AccessibleEditableTextPara::UnSetState,
287 nStateId ) );
290 // not generic yet, no arguments...
291 class AccessibleParaManager_DisposeChildren : public ::std::unary_function< ::accessibility::AccessibleEditableTextPara&, void >
293 public:
294 AccessibleParaManager_DisposeChildren() {}
295 void operator()( ::accessibility::AccessibleEditableTextPara& rPara )
297 rPara.Dispose();
301 void AccessibleParaManager::Dispose()
303 AccessibleParaManager_DisposeChildren aFunctor;
305 ::std::for_each( begin(), end(),
306 WeakChildAdapter< AccessibleParaManager_DisposeChildren > (aFunctor) );
309 // not generic yet, too many method arguments...
310 class StateChangeEvent : public ::std::unary_function< ::accessibility::AccessibleEditableTextPara&, void >
312 public:
313 typedef void return_type;
314 StateChangeEvent( const sal_Int16 nEventId,
315 const uno::Any& rNewValue,
316 const uno::Any& rOldValue ) :
317 mnEventId( nEventId ),
318 mrNewValue( rNewValue ),
319 mrOldValue( rOldValue ) {}
320 void operator()( ::accessibility::AccessibleEditableTextPara& rPara )
322 rPara.FireEvent( mnEventId, mrNewValue, mrOldValue );
325 private:
326 const sal_Int16 mnEventId;
327 const uno::Any& mrNewValue;
328 const uno::Any& mrOldValue;
331 void AccessibleParaManager::FireEvent( sal_Int32 nStartPara,
332 sal_Int32 nEndPara,
333 const sal_Int16 nEventId,
334 const uno::Any& rNewValue,
335 const uno::Any& rOldValue ) const
337 DBG_ASSERT( 0 <= nStartPara && 0 <= nEndPara &&
338 maChildren.size() > static_cast<size_t>(nStartPara) &&
339 maChildren.size() >= static_cast<size_t>(nEndPara) &&
340 nEndPara >= nStartPara, "AccessibleParaManager::FireEvent: invalid index" );
344 if( 0 <= nStartPara && 0 <= nEndPara &&
345 maChildren.size() > static_cast<size_t>(nStartPara) &&
346 maChildren.size() >= static_cast<size_t>(nEndPara) &&
347 nEndPara >= nStartPara )
349 VectorOfChildren::const_iterator front = maChildren.begin();
350 VectorOfChildren::const_iterator back = front;
352 ::std::advance( front, nStartPara );
353 ::std::advance( back, nEndPara );
355 StateChangeEvent aFunctor( nEventId, rNewValue, rOldValue );
357 ::std::for_each( front, back, AccessibleParaManager::WeakChildAdapter< StateChangeEvent >( aFunctor ) );
361 class ReleaseChild : public ::std::unary_function< const AccessibleParaManager::WeakChild&, AccessibleParaManager::WeakChild >
363 public:
364 AccessibleParaManager::WeakChild operator()( const AccessibleParaManager::WeakChild& rPara )
366 AccessibleParaManager::ShutdownPara( rPara );
368 // clear reference
369 return AccessibleParaManager::WeakChild();
373 void AccessibleParaManager::Release( sal_Int32 nStartPara, sal_Int32 nEndPara )
375 DBG_ASSERT( 0 <= nStartPara && 0 <= nEndPara &&
376 maChildren.size() > static_cast<size_t>(nStartPara) &&
377 maChildren.size() >= static_cast<size_t>(nEndPara),
378 "AccessibleParaManager::Release: invalid index" );
380 if( 0 <= nStartPara && 0 <= nEndPara &&
381 maChildren.size() > static_cast<size_t>(nStartPara) &&
382 maChildren.size() >= static_cast<size_t>(nEndPara) )
384 VectorOfChildren::iterator front = maChildren.begin();
385 VectorOfChildren::iterator back = front;
387 ::std::advance( front, nStartPara );
388 ::std::advance( back, nEndPara );
390 ::std::transform( front, back, front, ReleaseChild() );
394 void AccessibleParaManager::ShutdownPara( const WeakChild& rChild )
396 WeakPara::HardRefType aChild( rChild.first.get() );
398 if( IsReferencable( aChild ) )
399 aChild->SetEditSource( NULL );
406 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */