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 .
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() :
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::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() );
124 maChild
->FireEvent( nEventId
, rNewValue
, rOldValue
);
128 bool AccessibleParaManager::IsReferencable( WeakPara::HardRefType aChild
)
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() );
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
];
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
181 AccessibleEditableTextPara
* pChild
= new AccessibleEditableTextPara( xFrontEnd
, this );
182 uno::Reference
< XAccessible
> xChild( static_cast< ::cppu::OWeakObject
* > (pChild
), uno::UNO_QUERY
);
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
);
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
)
216 SetState( AccessibleStateType::ACTIVE
);
217 SetState( AccessibleStateType::EDITABLE
);
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
,
240 sal_Int32 nParagraphIndex
) const
242 rChild
.SetEditSource( &rEditSource
);
243 rChild
.SetIndexInParent( nChild
);
244 rChild
.SetParagraphIndex( nParagraphIndex
);
246 rChild
.SetEEOffset( maEEOffset
);
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
,
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
,
276 void AccessibleParaManager::UnSetState( sal_Int32 nChild
, const sal_Int16 nStateId
)
278 MemFunAdapter
< const sal_Int16
> aFunc( &AccessibleEditableTextPara::UnSetState
,
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
,
290 // not generic yet, no arguments...
291 class AccessibleParaManager_DisposeChildren
: public ::std::unary_function
< ::accessibility::AccessibleEditableTextPara
&, void >
294 AccessibleParaManager_DisposeChildren() {}
295 void operator()( ::accessibility::AccessibleEditableTextPara
& rPara
)
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 >
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
);
326 const sal_Int16 mnEventId
;
327 const uno::Any
& mrNewValue
;
328 const uno::Any
& mrOldValue
;
331 void AccessibleParaManager::FireEvent( sal_Int32 nStartPara
,
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
>
364 AccessibleParaManager::WeakChild
operator()( const AccessibleParaManager::WeakChild
& rPara
)
366 AccessibleParaManager::ShutdownPara( rPara
);
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: */