1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 //------------------------------------------------------------------------
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() :
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
)
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
);
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() );
138 maChild
->FireEvent( nEventId
, rNewValue
, rOldValue
);
142 sal_Bool
AccessibleParaManager::IsReferencable( WeakPara::HardRefType aChild
)
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() );
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
];
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
195 AccessibleEditableTextPara
* pChild
= new AccessibleEditableTextPara( xFrontEnd
, this );
196 uno::Reference
< XAccessible
> xChild( static_cast< ::cppu::OWeakObject
* > (pChild
), uno::UNO_QUERY
);
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
);
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
)
230 SetState( AccessibleStateType::ACTIVE
);
231 SetState( AccessibleStateType::EDITABLE
);
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
,
254 sal_Int32 nParagraphIndex
) const
256 rChild
.SetEditSource( &rEditSource
);
257 rChild
.SetIndexInParent( nChild
);
258 rChild
.SetParagraphIndex( nParagraphIndex
);
260 rChild
.SetEEOffset( maEEOffset
);
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
,
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
,
290 void AccessibleParaManager::UnSetState( sal_Int32 nChild
, const sal_Int16 nStateId
)
292 MemFunAdapter
< const sal_Int16
> aFunc( &AccessibleEditableTextPara::UnSetState
,
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
,
304 // not generic yet, no arguments...
305 class AccessibleParaManager_DisposeChildren
: public ::std::unary_function
< ::accessibility::AccessibleEditableTextPara
&, void >
308 AccessibleParaManager_DisposeChildren() {}
309 void operator()( ::accessibility::AccessibleEditableTextPara
& rPara
)
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 >
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
);
340 const sal_Int16 mnEventId
;
341 const uno::Any
& mrNewValue
;
342 const uno::Any
& mrOldValue
;
345 void AccessibleParaManager::FireEvent( sal_Int32 nStartPara
,
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
>
375 AccessibleParaManager::WeakChild
operator()( const AccessibleParaManager::WeakChild
& rPara
)
377 AccessibleParaManager::ShutdownPara( rPara
);
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: */