| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_editeng.hxx" |
| |
| //------------------------------------------------------------------------ |
| // |
| // Global header |
| // |
| //------------------------------------------------------------------------ |
| #include <com/sun/star/uno/Any.hxx> |
| #include <com/sun/star/uno/Reference.hxx> |
| #include <cppuhelper/weakref.hxx> |
| #include <com/sun/star/accessibility/XAccessible.hpp> |
| #include <com/sun/star/accessibility/AccessibleStateType.hpp> |
| |
| //------------------------------------------------------------------------ |
| // |
| // Project-local header |
| // |
| //------------------------------------------------------------------------ |
| |
| #include <editeng/unoedhlp.hxx> |
| #include <editeng/unopracc.hxx> |
| #include <editeng/unoedsrc.hxx> |
| #include "editeng/AccessibleParaManager.hxx" |
| #include "editeng/AccessibleEditableTextPara.hxx" |
| |
| |
| using namespace ::com::sun::star; |
| using namespace ::com::sun::star::accessibility; |
| |
| |
| |
| namespace accessibility |
| { |
| AccessibleParaManager::AccessibleParaManager() : |
| maChildren(1), |
| maEEOffset( 0, 0 ), |
| mnFocusedChild( -1 ), |
| mbActive( sal_False ) |
| { |
| } |
| |
| AccessibleParaManager::~AccessibleParaManager() |
| { |
| // owner is responsible for possible child defuncs |
| } |
| |
| void AccessibleParaManager::SetAdditionalChildStates( const VectorOfStates& rChildStates ) |
| { |
| maChildStates = rChildStates; |
| } |
| |
| const AccessibleParaManager::VectorOfStates& AccessibleParaManager::GetAdditionalChildStates() const |
| { |
| return maChildStates; |
| } |
| |
| void AccessibleParaManager::SetNum( sal_Int32 nNumParas ) |
| { |
| if( (size_t)nNumParas < maChildren.size() ) |
| Release( nNumParas, maChildren.size() ); |
| |
| maChildren.resize( nNumParas ); |
| |
| if( mnFocusedChild >= nNumParas ) |
| mnFocusedChild = -1; |
| } |
| |
| sal_uInt32 AccessibleParaManager::GetNum() const |
| { |
| return maChildren.size(); |
| } |
| |
| AccessibleParaManager::VectorOfChildren::iterator AccessibleParaManager::begin() |
| { |
| return maChildren.begin(); |
| } |
| |
| AccessibleParaManager::VectorOfChildren::iterator AccessibleParaManager::end() |
| { |
| return maChildren.end(); |
| } |
| |
| AccessibleParaManager::VectorOfChildren::const_iterator AccessibleParaManager::begin() const |
| { |
| return maChildren.begin(); |
| } |
| |
| AccessibleParaManager::VectorOfChildren::const_iterator AccessibleParaManager::end() const |
| { |
| return maChildren.end(); |
| } |
| |
| void AccessibleParaManager::Release( sal_uInt32 nPara ) |
| { |
| DBG_ASSERT( maChildren.size() > nPara, "AccessibleParaManager::Release: invalid index" ); |
| |
| if( maChildren.size() > nPara ) |
| { |
| ShutdownPara( GetChild( nPara ) ); |
| |
| // clear reference and rect |
| maChildren[ nPara ] = WeakChild(); |
| } |
| } |
| |
| void AccessibleParaManager::FireEvent( sal_uInt32 nPara, |
| const sal_Int16 nEventId, |
| const uno::Any& rNewValue, |
| const uno::Any& rOldValue ) const |
| { |
| DBG_ASSERT( maChildren.size() > nPara, "AccessibleParaManager::FireEvent: invalid index" ); |
| |
| if( maChildren.size() > nPara ) |
| { |
| WeakPara::HardRefType maChild( GetChild( nPara ).first.get() ); |
| if( maChild.is() ) |
| maChild->FireEvent( nEventId, rNewValue, rOldValue ); |
| } |
| } |
| |
| sal_Bool AccessibleParaManager::IsReferencable( WeakPara::HardRefType aChild ) |
| { |
| return aChild.is(); |
| } |
| |
| sal_Bool AccessibleParaManager::IsReferencable( sal_uInt32 nChild ) const |
| { |
| DBG_ASSERT( maChildren.size() > nChild, "AccessibleParaManager::IsReferencable: invalid index" ); |
| |
| if( maChildren.size() > nChild ) |
| { |
| // retrieve hard reference from weak one |
| return IsReferencable( GetChild( nChild ).first.get() ); |
| } |
| else |
| { |
| return sal_False; |
| } |
| } |
| |
| AccessibleParaManager::WeakChild AccessibleParaManager::GetChild( sal_uInt32 nParagraphIndex ) const |
| { |
| DBG_ASSERT( maChildren.size() > nParagraphIndex, "AccessibleParaManager::GetChild: invalid index" ); |
| |
| if( maChildren.size() > nParagraphIndex ) |
| { |
| return maChildren[ nParagraphIndex ]; |
| } |
| else |
| { |
| return WeakChild(); |
| } |
| } |
| |
| AccessibleParaManager::Child AccessibleParaManager::CreateChild( sal_Int32 nChild, |
| const uno::Reference< XAccessible >& xFrontEnd, |
| SvxEditSourceAdapter& rEditSource, |
| sal_uInt32 nParagraphIndex ) |
| { |
| DBG_ASSERT( maChildren.size() > nParagraphIndex, "AccessibleParaManager::CreateChild: invalid index" ); |
| |
| if( maChildren.size() > nParagraphIndex ) |
| { |
| // retrieve hard reference from weak one |
| WeakPara::HardRefType aChild( GetChild( nParagraphIndex ).first.get() ); |
| |
| if( !IsReferencable( nParagraphIndex ) ) |
| { |
| // there is no hard reference available, create object then |
| // --> OD 2006-01-11 #i27138# |
| AccessibleEditableTextPara* pChild = new AccessibleEditableTextPara( xFrontEnd, this ); |
| // <-- |
| uno::Reference< XAccessible > xChild( static_cast< ::cppu::OWeakObject* > (pChild), uno::UNO_QUERY ); |
| |
| if( !xChild.is() ) |
| throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Child creation failed")), xFrontEnd); |
| |
| aChild = WeakPara::HardRefType( xChild, pChild ); |
| |
| InitChild( *aChild, rEditSource, nChild, nParagraphIndex ); |
| |
| maChildren[ nParagraphIndex ] = WeakChild( aChild, pChild->getBounds() ); |
| } |
| |
| return Child( aChild.getRef(), GetChild( nParagraphIndex ).second ); |
| } |
| else |
| { |
| return Child(); |
| } |
| } |
| |
| void AccessibleParaManager::SetEEOffset( const Point& rOffset ) |
| { |
| maEEOffset = rOffset; |
| |
| MemFunAdapter< const Point& > aAdapter( &::accessibility::AccessibleEditableTextPara::SetEEOffset, rOffset ); |
| ::std::for_each( begin(), end(), aAdapter ); |
| } |
| |
| void AccessibleParaManager::SetActive( sal_Bool bActive ) |
| { |
| mbActive = bActive; |
| |
| if( bActive ) |
| { |
| SetState( AccessibleStateType::ACTIVE ); |
| SetState( AccessibleStateType::EDITABLE ); |
| } |
| else |
| { |
| UnSetState( AccessibleStateType::ACTIVE ); |
| UnSetState( AccessibleStateType::EDITABLE ); |
| } |
| } |
| |
| void AccessibleParaManager::SetFocus( sal_Int32 nChild ) |
| { |
| if( mnFocusedChild != -1 ) |
| UnSetState( mnFocusedChild, AccessibleStateType::FOCUSED ); |
| |
| mnFocusedChild = nChild; |
| |
| if( mnFocusedChild != -1 ) |
| SetState( mnFocusedChild, AccessibleStateType::FOCUSED ); |
| } |
| |
| void AccessibleParaManager::InitChild( AccessibleEditableTextPara& rChild, |
| SvxEditSourceAdapter& rEditSource, |
| sal_Int32 nChild, |
| sal_uInt32 nParagraphIndex ) const |
| { |
| rChild.SetEditSource( &rEditSource ); |
| rChild.SetIndexInParent( nChild ); |
| rChild.SetParagraphIndex( nParagraphIndex ); |
| |
| rChild.SetEEOffset( maEEOffset ); |
| |
| if( mbActive ) |
| { |
| rChild.SetState( AccessibleStateType::ACTIVE ); |
| rChild.SetState( AccessibleStateType::EDITABLE ); |
| } |
| |
| if( mnFocusedChild == static_cast<sal_Int32>(nParagraphIndex) ) |
| rChild.SetState( AccessibleStateType::FOCUSED ); |
| |
| // add states passed from outside |
| for( VectorOfStates::const_iterator aIt = maChildStates.begin(), aEnd = maChildStates.end(); aIt != aEnd; ++aIt ) |
| rChild.SetState( *aIt ); |
| } |
| |
| void AccessibleParaManager::SetState( sal_Int32 nChild, const sal_Int16 nStateId ) |
| { |
| MemFunAdapter< const sal_Int16 > aFunc( &AccessibleEditableTextPara::SetState, |
| nStateId ); |
| aFunc( GetChild(nChild) ); |
| } |
| |
| void AccessibleParaManager::SetState( const sal_Int16 nStateId ) |
| { |
| ::std::for_each( begin(), end(), |
| MemFunAdapter< const sal_Int16 >( &AccessibleEditableTextPara::SetState, |
| nStateId ) ); |
| } |
| |
| void AccessibleParaManager::UnSetState( sal_Int32 nChild, const sal_Int16 nStateId ) |
| { |
| MemFunAdapter< const sal_Int16 > aFunc( &AccessibleEditableTextPara::UnSetState, |
| nStateId ); |
| aFunc( GetChild(nChild) ); |
| } |
| |
| void AccessibleParaManager::UnSetState( const sal_Int16 nStateId ) |
| { |
| ::std::for_each( begin(), end(), |
| MemFunAdapter< const sal_Int16 >( &AccessibleEditableTextPara::UnSetState, |
| nStateId ) ); |
| } |
| |
| void AccessibleParaManager::SetEditSource( SvxEditSourceAdapter* pEditSource ) |
| { |
| MemFunAdapter< SvxEditSourceAdapter* > aAdapter( &::accessibility::AccessibleEditableTextPara::SetEditSource, pEditSource ); |
| ::std::for_each( begin(), end(), aAdapter ); |
| } |
| |
| // not generic yet, no arguments... |
| class AccessibleParaManager_DisposeChildren : public ::std::unary_function< ::accessibility::AccessibleEditableTextPara&, void > |
| { |
| public: |
| AccessibleParaManager_DisposeChildren() {} |
| void operator()( ::accessibility::AccessibleEditableTextPara& rPara ) |
| { |
| rPara.Dispose(); |
| } |
| }; |
| |
| void AccessibleParaManager::Dispose() |
| { |
| AccessibleParaManager_DisposeChildren aFunctor; |
| |
| ::std::for_each( begin(), end(), |
| WeakChildAdapter< AccessibleParaManager_DisposeChildren > (aFunctor) ); |
| } |
| |
| // not generic yet, too many method arguments... |
| class StateChangeEvent : public ::std::unary_function< ::accessibility::AccessibleEditableTextPara&, void > |
| { |
| public: |
| typedef void return_type; |
| StateChangeEvent( const sal_Int16 nEventId, |
| const uno::Any& rNewValue, |
| const uno::Any& rOldValue ) : |
| mnEventId( nEventId ), |
| mrNewValue( rNewValue ), |
| mrOldValue( rOldValue ) {} |
| void operator()( ::accessibility::AccessibleEditableTextPara& rPara ) |
| { |
| rPara.FireEvent( mnEventId, mrNewValue, mrOldValue ); |
| } |
| |
| private: |
| const sal_Int16 mnEventId; |
| const uno::Any& mrNewValue; |
| const uno::Any& mrOldValue; |
| }; |
| |
| void AccessibleParaManager::FireEvent( sal_uInt32 nStartPara, |
| sal_uInt32 nEndPara, |
| const sal_Int16 nEventId, |
| const uno::Any& rNewValue, |
| const uno::Any& rOldValue ) const |
| { |
| DBG_ASSERT( maChildren.size() > nStartPara && |
| maChildren.size() >= nEndPara && |
| nEndPara >= nStartPara , "AccessibleParaManager::FireEvent: invalid index" ); |
| |
| if( maChildren.size() > nStartPara && maChildren.size() >= nEndPara && nEndPara >= nStartPara) |
| { |
| VectorOfChildren::const_iterator front = maChildren.begin(); |
| VectorOfChildren::const_iterator back = front; |
| |
| ::std::advance( front, nStartPara ); |
| ::std::advance( back, nEndPara ); |
| |
| StateChangeEvent aFunctor( nEventId, rNewValue, rOldValue ); |
| |
| ::std::for_each( front, back, AccessibleParaManager::WeakChildAdapter< StateChangeEvent >( aFunctor ) ); |
| } |
| } |
| |
| class ReleaseChild : public ::std::unary_function< const AccessibleParaManager::WeakChild&, AccessibleParaManager::WeakChild > |
| { |
| public: |
| AccessibleParaManager::WeakChild operator()( const AccessibleParaManager::WeakChild& rPara ) |
| { |
| AccessibleParaManager::ShutdownPara( rPara ); |
| |
| // clear reference |
| return AccessibleParaManager::WeakChild(); |
| } |
| }; |
| |
| void AccessibleParaManager::Release( sal_uInt32 nStartPara, sal_uInt32 nEndPara ) |
| { |
| DBG_ASSERT( maChildren.size() > nStartPara && |
| maChildren.size() >= nEndPara, "AccessibleParaManager::Release: invalid index" ); |
| |
| if( maChildren.size() > nStartPara && |
| maChildren.size() >= nEndPara ) |
| { |
| VectorOfChildren::iterator front = maChildren.begin(); |
| VectorOfChildren::iterator back = front; |
| |
| ::std::advance( front, nStartPara ); |
| ::std::advance( back, nEndPara ); |
| |
| ::std::transform( front, back, front, ReleaseChild() ); |
| } |
| } |
| |
| void AccessibleParaManager::ShutdownPara( const WeakChild& rChild ) |
| { |
| WeakPara::HardRefType aChild( rChild.first.get() ); |
| |
| if( IsReferencable( aChild ) ) |
| aChild->SetEditSource( NULL ); |
| } |
| |
| } |
| |
| //------------------------------------------------------------------------ |