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 .
24 #include <com/sun/star/uno/Any.hxx>
25 #include <com/sun/star/uno/Reference.hxx>
26 #include <o3tl/safeint.hxx>
27 #include <sal/log.hxx>
28 #include <tools/debug.hxx>
29 #include <com/sun/star/accessibility/XAccessible.hpp>
30 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
33 // Project-local header
36 #include <editeng/AccessibleParaManager.hxx>
37 #include <editeng/AccessibleEditableTextPara.hxx>
40 using namespace ::com::sun::star
;
41 using namespace ::com::sun::star::accessibility
;
44 namespace accessibility
46 AccessibleParaManager::AccessibleParaManager() :
55 AccessibleParaManager::~AccessibleParaManager()
57 // owner is responsible for possible child death
60 void AccessibleParaManager::SetAdditionalChildStates( sal_Int64 nChildStates
)
62 mnChildStates
= nChildStates
;
65 void AccessibleParaManager::SetNum( sal_Int32 nNumParas
)
67 if( o3tl::make_unsigned(nNumParas
) < maChildren
.size() )
68 Release( nNumParas
, maChildren
.size() );
70 maChildren
.resize( nNumParas
);
72 if( mnFocusedChild
>= nNumParas
)
76 sal_Int32
AccessibleParaManager::GetNum() const
78 size_t nSize
= maChildren
.size();
79 if (nSize
> SAL_MAX_INT32
)
81 SAL_WARN( "editeng", "AccessibleParaManager::GetNum - overflow " << nSize
);
84 return static_cast<sal_Int32
>(nSize
);
87 AccessibleParaManager::VectorOfChildren::iterator
AccessibleParaManager::begin()
89 return maChildren
.begin();
92 AccessibleParaManager::VectorOfChildren::iterator
AccessibleParaManager::end()
94 return maChildren
.end();
97 void AccessibleParaManager::FireEvent( sal_Int32 nPara
,
98 const sal_Int16 nEventId
) const
100 DBG_ASSERT( 0 <= nPara
&& maChildren
.size() > o3tl::make_unsigned(nPara
),
101 "AccessibleParaManager::FireEvent: invalid index" );
103 if( 0 <= nPara
&& maChildren
.size() > o3tl::make_unsigned(nPara
) )
105 auto aChild( GetChild( nPara
).first
.get() );
107 aChild
->FireEvent( nEventId
);
111 bool AccessibleParaManager::IsReferencable(
112 rtl::Reference
<AccessibleEditableTextPara
> const & aChild
)
117 bool AccessibleParaManager::IsReferencable( sal_Int32 nChild
) const
119 DBG_ASSERT( 0 <= nChild
&& maChildren
.size() > o3tl::make_unsigned(nChild
),
120 "AccessibleParaManager::IsReferencable: invalid index" );
122 if( 0 <= nChild
&& maChildren
.size() > o3tl::make_unsigned(nChild
) )
124 // retrieve hard reference from weak one
125 return IsReferencable( GetChild( nChild
).first
.get() );
133 AccessibleParaManager::WeakChild
AccessibleParaManager::GetChild( sal_Int32 nParagraphIndex
) const
135 DBG_ASSERT( 0 <= nParagraphIndex
&& maChildren
.size() > o3tl::make_unsigned(nParagraphIndex
),
136 "AccessibleParaManager::GetChild: invalid index" );
138 if( 0 <= nParagraphIndex
&& maChildren
.size() > o3tl::make_unsigned(nParagraphIndex
) )
140 return maChildren
[ nParagraphIndex
];
148 bool AccessibleParaManager::HasCreatedChild( sal_Int32 nParagraphIndex
) const
150 if( 0 <= nParagraphIndex
&& maChildren
.size() > o3tl::make_unsigned(nParagraphIndex
) )
152 auto const & rChild
= maChildren
[ nParagraphIndex
];
153 return rChild
.second
.Width
!= 0 || rChild
.second
.Height
!= 0;
159 AccessibleParaManager::Child
AccessibleParaManager::CreateChild( sal_Int32 nChild
,
160 const uno::Reference
< XAccessible
>& xFrontEnd
,
161 SvxEditSourceAdapter
& rEditSource
,
162 sal_Int32 nParagraphIndex
)
164 DBG_ASSERT( 0 <= nParagraphIndex
&& maChildren
.size() > o3tl::make_unsigned(nParagraphIndex
),
165 "AccessibleParaManager::CreateChild: invalid index" );
167 if( 0 <= nParagraphIndex
&& maChildren
.size() > o3tl::make_unsigned(nParagraphIndex
) )
169 // retrieve hard reference from weak one
170 auto aChild( GetChild( nParagraphIndex
).first
.get() );
172 if( !IsReferencable( nParagraphIndex
) )
174 // there is no hard reference available, create object then
176 aChild
= new AccessibleEditableTextPara(xFrontEnd
, this);
178 InitChild( *aChild
, rEditSource
, nChild
, nParagraphIndex
);
180 maChildren
[ nParagraphIndex
] = WeakChild( aChild
, aChild
->getBounds() );
183 return Child( aChild
.get(), GetChild( nParagraphIndex
).second
);
191 void AccessibleParaManager::SetEEOffset( const Point
& rOffset
)
193 maEEOffset
= rOffset
;
195 MemFunAdapter
< const Point
& > aAdapter( &::accessibility::AccessibleEditableTextPara::SetEEOffset
, rOffset
);
196 std::for_each( begin(), end(), aAdapter
);
199 void AccessibleParaManager::SetActive( bool bActive
)
205 SetState( AccessibleStateType::ACTIVE
);
206 SetState( AccessibleStateType::EDITABLE
);
210 UnSetState( AccessibleStateType::ACTIVE
);
211 UnSetState( AccessibleStateType::EDITABLE
);
215 void AccessibleParaManager::SetFocus( sal_Int32 nChild
)
217 if( mnFocusedChild
!= -1 )
218 UnSetState( mnFocusedChild
, AccessibleStateType::FOCUSED
);
220 mnFocusedChild
= nChild
;
222 if( mnFocusedChild
!= -1 )
223 SetState( mnFocusedChild
, AccessibleStateType::FOCUSED
);
226 void AccessibleParaManager::InitChild( AccessibleEditableTextPara
& rChild
,
227 SvxEditSourceAdapter
& rEditSource
,
229 sal_Int32 nParagraphIndex
) const
231 rChild
.SetEditSource( &rEditSource
);
232 rChild
.SetIndexInParent( nChild
);
233 rChild
.SetParagraphIndex( nParagraphIndex
);
235 rChild
.SetEEOffset( maEEOffset
);
239 rChild
.SetState( AccessibleStateType::ACTIVE
);
240 rChild
.SetState( AccessibleStateType::EDITABLE
);
243 if( mnFocusedChild
== nParagraphIndex
)
244 rChild
.SetState( AccessibleStateType::FOCUSED
);
246 // add states passed from outside
247 for (int i
=0; i
<63; i
++)
249 sal_Int64 nState
= sal_Int64(1) << i
;
250 if ( nState
& mnChildStates
)
251 rChild
.SetState( nState
);
255 void AccessibleParaManager::SetState( sal_Int32 nChild
, const sal_Int64 nStateId
)
257 MemFunAdapter
< const sal_Int64
> aFunc( &AccessibleEditableTextPara::SetState
,
259 aFunc( GetChild(nChild
) );
262 void AccessibleParaManager::SetState( const sal_Int64 nStateId
)
264 std::for_each( begin(), end(),
265 MemFunAdapter
< const sal_Int64
>( &AccessibleEditableTextPara::SetState
,
269 void AccessibleParaManager::UnSetState( sal_Int32 nChild
, const sal_Int64 nStateId
)
271 MemFunAdapter
< const sal_Int64
> aFunc( &AccessibleEditableTextPara::UnSetState
,
273 aFunc( GetChild(nChild
) );
276 void AccessibleParaManager::UnSetState( const sal_Int64 nStateId
)
278 std::for_each( begin(), end(),
279 MemFunAdapter
< const sal_Int64
>( &AccessibleEditableTextPara::UnSetState
,
285 // not generic yet, no arguments...
286 class AccessibleParaManager_DisposeChildren
289 AccessibleParaManager_DisposeChildren() {}
290 void operator()( ::accessibility::AccessibleEditableTextPara
& rPara
)
298 void AccessibleParaManager::Dispose()
300 AccessibleParaManager_DisposeChildren aFunctor
;
302 std::for_each( begin(), end(),
303 WeakChildAdapter
< AccessibleParaManager_DisposeChildren
> (aFunctor
) );
308 // not generic yet, too many method arguments...
309 class StateChangeEvent
312 StateChangeEvent( const sal_Int16 nEventId
,
313 const uno::Any
& rNewValue
,
314 const uno::Any
& rOldValue
) :
315 mnEventId( nEventId
),
316 mrNewValue( rNewValue
),
317 mrOldValue( rOldValue
) {}
318 void operator()( ::accessibility::AccessibleEditableTextPara
const & rPara
)
320 rPara
.FireEvent( mnEventId
, mrNewValue
, mrOldValue
);
324 const sal_Int16 mnEventId
;
325 const uno::Any
& mrNewValue
;
326 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() > o3tl::make_unsigned(nStartPara
) &&
339 maChildren
.size() >= o3tl::make_unsigned(nEndPara
) &&
340 nEndPara
>= nStartPara
, "AccessibleParaManager::FireEvent: invalid index" );
343 if( 0 <= nStartPara
&& 0 <= nEndPara
&&
344 maChildren
.size() > o3tl::make_unsigned(nStartPara
) &&
345 maChildren
.size() >= o3tl::make_unsigned(nEndPara
) &&
346 nEndPara
>= nStartPara
)
348 VectorOfChildren::const_iterator front
= maChildren
.begin();
349 VectorOfChildren::const_iterator back
= front
;
351 std::advance( front
, nStartPara
);
352 std::advance( back
, nEndPara
);
354 StateChangeEvent
aFunctor( nEventId
, rNewValue
, rOldValue
);
356 std::for_each( front
, back
, AccessibleParaManager::WeakChildAdapter
< StateChangeEvent
>( aFunctor
) );
365 AccessibleParaManager::WeakChild
operator()( const AccessibleParaManager::WeakChild
& rPara
)
367 AccessibleParaManager::ShutdownPara( rPara
);
370 return AccessibleParaManager::WeakChild();
376 void AccessibleParaManager::Release( sal_Int32 nStartPara
, sal_Int32 nEndPara
)
378 DBG_ASSERT( 0 <= nStartPara
&& 0 <= nEndPara
&&
379 maChildren
.size() > o3tl::make_unsigned(nStartPara
) &&
380 maChildren
.size() >= o3tl::make_unsigned(nEndPara
),
381 "AccessibleParaManager::Release: invalid index" );
383 if( 0 <= nStartPara
&& 0 <= nEndPara
&&
384 maChildren
.size() > o3tl::make_unsigned(nStartPara
) &&
385 maChildren
.size() >= o3tl::make_unsigned(nEndPara
) )
387 VectorOfChildren::iterator front
= maChildren
.begin();
388 VectorOfChildren::iterator back
= front
;
390 std::advance( front
, nStartPara
);
391 std::advance( back
, nEndPara
);
393 std::transform( front
, back
, front
, ReleaseChild() );
397 void AccessibleParaManager::ShutdownPara( const WeakChild
& rChild
)
399 auto aChild( rChild
.first
.get() );
401 if( IsReferencable( aChild
) )
402 aChild
->SetEditSource( nullptr );
408 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */