1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 //------------------------------------------------------------------------
34 //------------------------------------------------------------------------
35 #include <com/sun/star/uno/Any.hxx>
36 #include <com/sun/star/uno/Reference.hxx>
37 #include <cppuhelper/weakref.hxx>
38 #include <com/sun/star/accessibility/XAccessible.hpp>
39 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
41 //------------------------------------------------------------------------
43 // Project-local header
45 //------------------------------------------------------------------------
47 #include <editeng/unoedhlp.hxx>
48 #include <editeng/unopracc.hxx>
49 #include <editeng/unoedsrc.hxx>
50 #include "editeng/AccessibleParaManager.hxx"
51 #include "editeng/AccessibleEditableTextPara.hxx"
54 using namespace ::com::sun::star
;
55 using namespace ::com::sun::star::accessibility
;
59 namespace accessibility
61 AccessibleParaManager::AccessibleParaManager() :
69 AccessibleParaManager::~AccessibleParaManager()
71 // owner is responsible for possible child defuncs
74 void AccessibleParaManager::SetAdditionalChildStates( const VectorOfStates
& rChildStates
)
76 maChildStates
= rChildStates
;
79 void AccessibleParaManager::SetNum( sal_Int32 nNumParas
)
81 if( (size_t)nNumParas
< maChildren
.size() )
82 Release( nNumParas
, maChildren
.size() );
84 maChildren
.resize( nNumParas
);
86 if( mnFocusedChild
>= nNumParas
)
90 sal_uInt32
AccessibleParaManager::GetNum() const
92 return maChildren
.size();
95 AccessibleParaManager::VectorOfChildren::iterator
AccessibleParaManager::begin()
97 return maChildren
.begin();
100 AccessibleParaManager::VectorOfChildren::iterator
AccessibleParaManager::end()
102 return maChildren
.end();
105 AccessibleParaManager::VectorOfChildren::const_iterator
AccessibleParaManager::begin() const
107 return maChildren
.begin();
110 AccessibleParaManager::VectorOfChildren::const_iterator
AccessibleParaManager::end() const
112 return maChildren
.end();
115 void AccessibleParaManager::Release( sal_uInt32 nPara
)
117 DBG_ASSERT( maChildren
.size() > nPara
, "AccessibleParaManager::Release: invalid index" );
119 if( maChildren
.size() > nPara
)
121 ShutdownPara( GetChild( nPara
) );
123 // clear reference and rect
124 maChildren
[ nPara
] = WeakChild();
128 void AccessibleParaManager::FireEvent( sal_uInt32 nPara
,
129 const sal_Int16 nEventId
,
130 const uno::Any
& rNewValue
,
131 const uno::Any
& rOldValue
) const
133 DBG_ASSERT( maChildren
.size() > nPara
, "AccessibleParaManager::FireEvent: invalid index" );
135 if( maChildren
.size() > nPara
)
137 WeakPara::HardRefType
maChild( GetChild( nPara
).first
.get() );
139 maChild
->FireEvent( nEventId
, rNewValue
, rOldValue
);
143 sal_Bool
AccessibleParaManager::IsReferencable( WeakPara::HardRefType aChild
)
148 sal_Bool
AccessibleParaManager::IsReferencable( sal_uInt32 nChild
) const
150 DBG_ASSERT( maChildren
.size() > nChild
, "AccessibleParaManager::IsReferencable: invalid index" );
152 if( maChildren
.size() > nChild
)
154 // retrieve hard reference from weak one
155 return IsReferencable( GetChild( nChild
).first
.get() );
163 AccessibleParaManager::WeakChild
AccessibleParaManager::GetChild( sal_uInt32 nParagraphIndex
) const
165 DBG_ASSERT( maChildren
.size() > nParagraphIndex
, "AccessibleParaManager::GetChild: invalid index" );
167 if( maChildren
.size() > nParagraphIndex
)
169 return maChildren
[ nParagraphIndex
];
177 AccessibleParaManager::Child
AccessibleParaManager::CreateChild( sal_Int32 nChild
,
178 const uno::Reference
< XAccessible
>& xFrontEnd
,
179 SvxEditSourceAdapter
& rEditSource
,
180 sal_uInt32 nParagraphIndex
)
182 DBG_ASSERT( maChildren
.size() > nParagraphIndex
, "AccessibleParaManager::CreateChild: invalid index" );
184 if( maChildren
.size() > nParagraphIndex
)
186 // retrieve hard reference from weak one
187 WeakPara::HardRefType
aChild( GetChild( nParagraphIndex
).first
.get() );
189 if( !IsReferencable( nParagraphIndex
) )
191 // there is no hard reference available, create object then
193 AccessibleEditableTextPara
* pChild
= new AccessibleEditableTextPara( xFrontEnd
, this );
194 uno::Reference
< XAccessible
> xChild( static_cast< ::cppu::OWeakObject
* > (pChild
), uno::UNO_QUERY
);
197 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Child creation failed")), xFrontEnd
);
199 aChild
= WeakPara::HardRefType( xChild
, pChild
);
201 InitChild( *aChild
, rEditSource
, nChild
, nParagraphIndex
);
203 maChildren
[ nParagraphIndex
] = WeakChild( aChild
, pChild
->getBounds() );
206 return Child( aChild
.getRef(), GetChild( nParagraphIndex
).second
);
214 void AccessibleParaManager::SetEEOffset( const Point
& rOffset
)
216 maEEOffset
= rOffset
;
218 MemFunAdapter
< const Point
& > aAdapter( &::accessibility::AccessibleEditableTextPara::SetEEOffset
, rOffset
);
219 ::std::for_each( begin(), end(), aAdapter
);
222 void AccessibleParaManager::SetActive( sal_Bool bActive
)
228 SetState( AccessibleStateType::ACTIVE
);
229 SetState( AccessibleStateType::EDITABLE
);
233 UnSetState( AccessibleStateType::ACTIVE
);
234 UnSetState( AccessibleStateType::EDITABLE
);
238 void AccessibleParaManager::SetFocus( sal_Int32 nChild
)
240 if( mnFocusedChild
!= -1 )
241 UnSetState( mnFocusedChild
, AccessibleStateType::FOCUSED
);
243 mnFocusedChild
= nChild
;
245 if( mnFocusedChild
!= -1 )
246 SetState( mnFocusedChild
, AccessibleStateType::FOCUSED
);
249 void AccessibleParaManager::InitChild( AccessibleEditableTextPara
& rChild
,
250 SvxEditSourceAdapter
& rEditSource
,
252 sal_uInt32 nParagraphIndex
) const
254 rChild
.SetEditSource( &rEditSource
);
255 rChild
.SetIndexInParent( nChild
);
256 rChild
.SetParagraphIndex( nParagraphIndex
);
258 rChild
.SetEEOffset( maEEOffset
);
262 rChild
.SetState( AccessibleStateType::ACTIVE
);
263 rChild
.SetState( AccessibleStateType::EDITABLE
);
266 if( mnFocusedChild
== static_cast<sal_Int32
>(nParagraphIndex
) )
267 rChild
.SetState( AccessibleStateType::FOCUSED
);
269 // add states passed from outside
270 for( VectorOfStates::const_iterator aIt
= maChildStates
.begin(), aEnd
= maChildStates
.end(); aIt
!= aEnd
; ++aIt
)
271 rChild
.SetState( *aIt
);
274 void AccessibleParaManager::SetState( sal_Int32 nChild
, const sal_Int16 nStateId
)
276 MemFunAdapter
< const sal_Int16
> aFunc( &AccessibleEditableTextPara::SetState
,
278 aFunc( GetChild(nChild
) );
281 void AccessibleParaManager::SetState( const sal_Int16 nStateId
)
283 ::std::for_each( begin(), end(),
284 MemFunAdapter
< const sal_Int16
>( &AccessibleEditableTextPara::SetState
,
288 void AccessibleParaManager::UnSetState( sal_Int32 nChild
, const sal_Int16 nStateId
)
290 MemFunAdapter
< const sal_Int16
> aFunc( &AccessibleEditableTextPara::UnSetState
,
292 aFunc( GetChild(nChild
) );
295 void AccessibleParaManager::UnSetState( const sal_Int16 nStateId
)
297 ::std::for_each( begin(), end(),
298 MemFunAdapter
< const sal_Int16
>( &AccessibleEditableTextPara::UnSetState
,
302 // not generic yet, no arguments...
303 class AccessibleParaManager_DisposeChildren
: public ::std::unary_function
< ::accessibility::AccessibleEditableTextPara
&, void >
306 AccessibleParaManager_DisposeChildren() {}
307 void operator()( ::accessibility::AccessibleEditableTextPara
& rPara
)
313 void AccessibleParaManager::Dispose()
315 AccessibleParaManager_DisposeChildren aFunctor
;
317 ::std::for_each( begin(), end(),
318 WeakChildAdapter
< AccessibleParaManager_DisposeChildren
> (aFunctor
) );
321 // not generic yet, too many method arguments...
322 class StateChangeEvent
: public ::std::unary_function
< ::accessibility::AccessibleEditableTextPara
&, void >
325 typedef void return_type
;
326 StateChangeEvent( const sal_Int16 nEventId
,
327 const uno::Any
& rNewValue
,
328 const uno::Any
& rOldValue
) :
329 mnEventId( nEventId
),
330 mrNewValue( rNewValue
),
331 mrOldValue( rOldValue
) {}
332 void operator()( ::accessibility::AccessibleEditableTextPara
& rPara
)
334 rPara
.FireEvent( mnEventId
, mrNewValue
, mrOldValue
);
338 const sal_Int16 mnEventId
;
339 const uno::Any
& mrNewValue
;
340 const uno::Any
& mrOldValue
;
343 void AccessibleParaManager::FireEvent( sal_uInt32 nStartPara
,
345 const sal_Int16 nEventId
,
346 const uno::Any
& rNewValue
,
347 const uno::Any
& rOldValue
) const
349 DBG_ASSERT( maChildren
.size() > nStartPara
&&
350 maChildren
.size() >= nEndPara
, "AccessibleParaManager::FireEvent: invalid index" );
352 if( maChildren
.size() > nStartPara
&&
353 maChildren
.size() >= nEndPara
)
355 VectorOfChildren::const_iterator front
= maChildren
.begin();
356 VectorOfChildren::const_iterator back
= front
;
358 ::std::advance( front
, nStartPara
);
359 ::std::advance( back
, nEndPara
);
361 StateChangeEvent
aFunctor( nEventId
, rNewValue
, rOldValue
);
363 ::std::for_each( front
, back
, AccessibleParaManager::WeakChildAdapter
< StateChangeEvent
>( aFunctor
) );
367 class ReleaseChild
: public ::std::unary_function
< const AccessibleParaManager::WeakChild
&, AccessibleParaManager::WeakChild
>
370 AccessibleParaManager::WeakChild
operator()( const AccessibleParaManager::WeakChild
& rPara
)
372 AccessibleParaManager::ShutdownPara( rPara
);
375 return AccessibleParaManager::WeakChild();
379 void AccessibleParaManager::Release( sal_uInt32 nStartPara
, sal_uInt32 nEndPara
)
381 DBG_ASSERT( maChildren
.size() > nStartPara
&&
382 maChildren
.size() >= nEndPara
, "AccessibleParaManager::Release: invalid index" );
384 if( maChildren
.size() > nStartPara
&&
385 maChildren
.size() >= 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 WeakPara::HardRefType
aChild( rChild
.first
.get() );
401 if( IsReferencable( aChild
) )
402 aChild
->SetEditSource( NULL
);
407 //------------------------------------------------------------------------
409 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */