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 .
23 #include <com/sun/star/uno/Any.hxx>
24 #include <com/sun/star/uno/Reference.hxx>
25 #include <o3tl/safeint.hxx>
26 #include <sal/log.hxx>
27 #include <tools/debug.hxx>
28 #include <com/sun/star/accessibility/XAccessible.hpp>
29 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
31 // Project-local header
32 #include <editeng/AccessibleParaManager.hxx>
33 #include <editeng/AccessibleEditableTextPara.hxx>
36 using namespace ::com::sun::star
;
37 using namespace ::com::sun::star::accessibility
;
40 namespace accessibility
42 AccessibleParaManager::AccessibleParaManager() :
51 AccessibleParaManager::~AccessibleParaManager()
53 // owner is responsible for possible child death
56 void AccessibleParaManager::SetAdditionalChildStates( sal_Int64 nChildStates
)
58 mnChildStates
= nChildStates
;
61 void AccessibleParaManager::SetNum( sal_Int32 nNumParas
)
63 if( o3tl::make_unsigned(nNumParas
) < maChildren
.size() )
64 Release( nNumParas
, maChildren
.size() );
66 maChildren
.resize( nNumParas
);
68 if( mnFocusedChild
>= nNumParas
)
72 sal_Int32
AccessibleParaManager::GetNum() const
74 size_t nSize
= maChildren
.size();
75 if (nSize
> SAL_MAX_INT32
)
77 SAL_WARN( "editeng", "AccessibleParaManager::GetNum - overflow " << nSize
);
80 return static_cast<sal_Int32
>(nSize
);
83 AccessibleParaManager::VectorOfChildren::iterator
AccessibleParaManager::begin()
85 return maChildren
.begin();
88 AccessibleParaManager::VectorOfChildren::iterator
AccessibleParaManager::end()
90 return maChildren
.end();
93 void AccessibleParaManager::FireEvent( sal_Int32 nPara
,
94 const sal_Int16 nEventId
) const
96 DBG_ASSERT( 0 <= nPara
&& maChildren
.size() > o3tl::make_unsigned(nPara
),
97 "AccessibleParaManager::FireEvent: invalid index" );
99 if( 0 <= nPara
&& maChildren
.size() > o3tl::make_unsigned(nPara
) )
101 auto aChild( GetChild( nPara
).first
.get() );
103 aChild
->FireEvent( nEventId
);
107 bool AccessibleParaManager::IsReferencable(
108 rtl::Reference
<AccessibleEditableTextPara
> const & aChild
)
113 bool AccessibleParaManager::IsReferencable( sal_Int32 nChild
) const
115 assert(0 <= nChild
&& maChildren
.size() > o3tl::make_unsigned(nChild
)
116 && "AccessibleParaManager::IsReferencable: invalid index");
118 if( 0 <= nChild
&& maChildren
.size() > o3tl::make_unsigned(nChild
) )
120 // retrieve hard reference from weak one
121 return IsReferencable( GetChild( nChild
).first
.get() );
129 AccessibleParaManager::WeakChild
AccessibleParaManager::GetChild( sal_Int32 nParagraphIndex
) const
131 DBG_ASSERT( 0 <= nParagraphIndex
&& maChildren
.size() > o3tl::make_unsigned(nParagraphIndex
),
132 "AccessibleParaManager::GetChild: invalid index" );
134 if( 0 <= nParagraphIndex
&& maChildren
.size() > o3tl::make_unsigned(nParagraphIndex
) )
136 return maChildren
[ nParagraphIndex
];
144 bool AccessibleParaManager::HasCreatedChild( sal_Int32 nParagraphIndex
) const
146 if( 0 <= nParagraphIndex
&& maChildren
.size() > o3tl::make_unsigned(nParagraphIndex
) )
148 auto const & rChild
= maChildren
[ nParagraphIndex
];
149 return rChild
.second
.Width
!= 0 || rChild
.second
.Height
!= 0;
155 AccessibleParaManager::Child
AccessibleParaManager::CreateChild( sal_Int32 nChild
,
156 const uno::Reference
< XAccessible
>& xFrontEnd
,
157 SvxEditSourceAdapter
& rEditSource
,
158 sal_Int32 nParagraphIndex
)
160 DBG_ASSERT( 0 <= nParagraphIndex
&& maChildren
.size() > o3tl::make_unsigned(nParagraphIndex
),
161 "AccessibleParaManager::CreateChild: invalid index" );
163 if( 0 <= nParagraphIndex
&& maChildren
.size() > o3tl::make_unsigned(nParagraphIndex
) )
165 // retrieve hard reference from weak one
166 auto aChild( GetChild( nParagraphIndex
).first
.get() );
168 if( !IsReferencable( nParagraphIndex
) )
170 // there is no hard reference available, create object then
172 aChild
= new AccessibleEditableTextPara(xFrontEnd
, this);
174 InitChild( *aChild
, rEditSource
, nChild
, nParagraphIndex
);
176 maChildren
[ nParagraphIndex
] = WeakChild( aChild
, aChild
->getBounds() );
179 return Child( aChild
.get(), GetChild( nParagraphIndex
).second
);
187 void AccessibleParaManager::SetEEOffset( const Point
& rOffset
)
189 maEEOffset
= rOffset
;
191 MemFunAdapter
< const Point
& > aAdapter( &::accessibility::AccessibleEditableTextPara::SetEEOffset
, rOffset
);
192 std::for_each( begin(), end(), aAdapter
);
195 void AccessibleParaManager::SetActive( bool bActive
)
201 SetState( AccessibleStateType::ACTIVE
);
202 SetState( AccessibleStateType::EDITABLE
);
206 UnSetState( AccessibleStateType::ACTIVE
);
207 UnSetState( AccessibleStateType::EDITABLE
);
211 void AccessibleParaManager::SetFocus( sal_Int32 nChild
)
213 if( mnFocusedChild
!= -1 )
214 UnSetState( mnFocusedChild
, AccessibleStateType::FOCUSED
);
216 mnFocusedChild
= nChild
;
218 if( mnFocusedChild
!= -1 )
219 SetState( mnFocusedChild
, AccessibleStateType::FOCUSED
);
222 void AccessibleParaManager::InitChild( AccessibleEditableTextPara
& rChild
,
223 SvxEditSourceAdapter
& rEditSource
,
225 sal_Int32 nParagraphIndex
) const
227 rChild
.SetEditSource( &rEditSource
);
228 rChild
.SetIndexInParent( nChild
);
229 rChild
.SetParagraphIndex( nParagraphIndex
);
231 rChild
.SetEEOffset( maEEOffset
);
235 rChild
.SetState( AccessibleStateType::ACTIVE
);
236 rChild
.SetState( AccessibleStateType::EDITABLE
);
239 if( mnFocusedChild
== nParagraphIndex
)
240 rChild
.SetState( AccessibleStateType::FOCUSED
);
242 // add states passed from outside
243 for (int i
=0; i
<63; i
++)
245 sal_Int64 nState
= sal_Int64(1) << i
;
246 if ( nState
& mnChildStates
)
247 rChild
.SetState( nState
);
251 void AccessibleParaManager::SetState( sal_Int32 nChild
, const sal_Int64 nStateId
)
253 MemFunAdapter
< const sal_Int64
> aFunc( &AccessibleEditableTextPara::SetState
,
255 aFunc( GetChild(nChild
) );
258 void AccessibleParaManager::SetState( const sal_Int64 nStateId
)
260 std::for_each( begin(), end(),
261 MemFunAdapter
< const sal_Int64
>( &AccessibleEditableTextPara::SetState
,
265 void AccessibleParaManager::UnSetState( sal_Int32 nChild
, const sal_Int64 nStateId
)
267 MemFunAdapter
< const sal_Int64
> aFunc( &AccessibleEditableTextPara::UnSetState
,
269 aFunc( GetChild(nChild
) );
272 void AccessibleParaManager::UnSetState( const sal_Int64 nStateId
)
274 std::for_each( begin(), end(),
275 MemFunAdapter
< const sal_Int64
>( &AccessibleEditableTextPara::UnSetState
,
281 // not generic yet, no arguments...
282 class AccessibleParaManager_DisposeChildren
285 AccessibleParaManager_DisposeChildren() {}
286 void operator()( ::accessibility::AccessibleEditableTextPara
& rPara
)
294 void AccessibleParaManager::Dispose()
296 AccessibleParaManager_DisposeChildren aFunctor
;
298 std::for_each( begin(), end(),
299 WeakChildAdapter
< AccessibleParaManager_DisposeChildren
> (aFunctor
) );
304 // not generic yet, too many method arguments...
305 class StateChangeEvent
308 StateChangeEvent( const sal_Int16 nEventId
,
309 const uno::Any
& rNewValue
,
310 const uno::Any
& rOldValue
) :
311 mnEventId( nEventId
),
312 mrNewValue( rNewValue
),
313 mrOldValue( rOldValue
) {}
314 void operator()( ::accessibility::AccessibleEditableTextPara
const & rPara
)
316 rPara
.FireEvent( mnEventId
, mrNewValue
, mrOldValue
);
320 const sal_Int16 mnEventId
;
321 const uno::Any
& mrNewValue
;
322 const uno::Any
& mrOldValue
;
327 void AccessibleParaManager::FireEvent( sal_Int32 nStartPara
,
329 const sal_Int16 nEventId
,
330 const uno::Any
& rNewValue
,
331 const uno::Any
& rOldValue
) const
333 DBG_ASSERT( 0 <= nStartPara
&& 0 <= nEndPara
&&
334 maChildren
.size() > o3tl::make_unsigned(nStartPara
) &&
335 maChildren
.size() >= o3tl::make_unsigned(nEndPara
) &&
336 nEndPara
>= nStartPara
, "AccessibleParaManager::FireEvent: invalid index" );
339 if( 0 <= nStartPara
&& 0 <= nEndPara
&&
340 maChildren
.size() > o3tl::make_unsigned(nStartPara
) &&
341 maChildren
.size() >= o3tl::make_unsigned(nEndPara
) &&
342 nEndPara
>= nStartPara
)
344 VectorOfChildren::const_iterator front
= maChildren
.begin();
345 VectorOfChildren::const_iterator back
= front
;
347 std::advance( front
, nStartPara
);
348 std::advance( back
, nEndPara
);
350 StateChangeEvent
aFunctor( nEventId
, rNewValue
, rOldValue
);
352 std::for_each( front
, back
, AccessibleParaManager::WeakChildAdapter
< StateChangeEvent
>( aFunctor
) );
361 AccessibleParaManager::WeakChild
operator()( const AccessibleParaManager::WeakChild
& rPara
)
363 AccessibleParaManager::ShutdownPara( rPara
);
366 return AccessibleParaManager::WeakChild();
372 void AccessibleParaManager::Release( sal_Int32 nStartPara
, sal_Int32 nEndPara
)
374 DBG_ASSERT( 0 <= nStartPara
&& 0 <= nEndPara
&&
375 maChildren
.size() > o3tl::make_unsigned(nStartPara
) &&
376 maChildren
.size() >= o3tl::make_unsigned(nEndPara
),
377 "AccessibleParaManager::Release: invalid index" );
379 if( 0 <= nStartPara
&& 0 <= nEndPara
&&
380 maChildren
.size() > o3tl::make_unsigned(nStartPara
) &&
381 maChildren
.size() >= o3tl::make_unsigned(nEndPara
) )
383 VectorOfChildren::iterator front
= maChildren
.begin();
384 VectorOfChildren::iterator back
= front
;
386 std::advance( front
, nStartPara
);
387 std::advance( back
, nEndPara
);
389 std::transform( front
, back
, front
, ReleaseChild() );
393 void AccessibleParaManager::ShutdownPara( const WeakChild
& rChild
)
395 auto aChild( rChild
.first
.get() );
397 if( IsReferencable( aChild
) )
398 aChild
->SetEditSource( nullptr );
404 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */