diff options
author | Thorsten Behrens <thb@openoffice.org> | 2002-05-16 15:12:20 +0000 |
---|---|---|
committer | Thorsten Behrens <thb@openoffice.org> | 2002-05-16 15:12:20 +0000 |
commit | a909acb7009acadffa53e74ea05ddb88803490f1 (patch) | |
tree | 47338072bd088875da7188034c6a334494d0d2fa | |
parent | 87f258d7f501a03df821480a4a0bac20675a852a (diff) |
#98735# Refactored unoedit/unoedacc.cxx
-rw-r--r-- | svx/source/accessibility/AccessibleEditableTextPara.cxx | 1610 | ||||
-rw-r--r-- | svx/source/accessibility/AccessibleEditableTextPara.hxx | 403 | ||||
-rw-r--r-- | svx/source/accessibility/AccessibleImageBullet.cxx | 582 | ||||
-rw-r--r-- | svx/source/accessibility/AccessibleImageBullet.hxx | 304 | ||||
-rw-r--r-- | svx/source/accessibility/AccessibleParaManager.cxx | 306 | ||||
-rw-r--r-- | svx/source/accessibility/AccessibleParaManager.hxx | 276 | ||||
-rw-r--r-- | svx/source/accessibility/AccessibleTextHelper.cxx | 1204 | ||||
-rw-r--r-- | svx/source/inc/unoedprx.hxx | 196 | ||||
-rw-r--r-- | svx/source/inc/unopracc.hxx | 113 | ||||
-rw-r--r-- | svx/source/unoedit/unoedprx.cxx | 1175 | ||||
-rw-r--r-- | svx/source/unoedit/unopracc.cxx | 227 |
11 files changed, 6396 insertions, 0 deletions
diff --git a/svx/source/accessibility/AccessibleEditableTextPara.cxx b/svx/source/accessibility/AccessibleEditableTextPara.cxx new file mode 100644 index 000000000000..193a2caf9afc --- /dev/null +++ b/svx/source/accessibility/AccessibleEditableTextPara.cxx @@ -0,0 +1,1610 @@ +/************************************************************************* + * + * $RCSfile: AccessibleEditableTextPara.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: thb $ $Date: 2002-05-16 16:10:05 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#pragma hdrstop + +//------------------------------------------------------------------------ +// +// Global header +// +//------------------------------------------------------------------------ + +#include <limits.h> +#include <vector> +#include <algorithm> + +#ifndef _VOS_MUTEX_HXX_ +#include <vos/mutex.hxx> +#endif + +#ifndef _SV_WINDOW_HXX +#include <vcl/window.hxx> +#endif + +#ifndef _SV_SVAPP_HXX +#include <vcl/svapp.hxx> +#endif + +#ifndef _COM_SUN_STAR_UNO_ANY_HXX_ +#include <com/sun/star/uno/Any.hxx> +#endif + +#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_ +#include <com/sun/star/uno/Reference.hxx> +#endif + +#ifndef _COM_SUN_STAR_AWT_POINT_HPP_ +#include <com/sun/star/awt/Point.hpp> +#endif + +#ifndef _COM_SUN_STAR_AWT_RECTANGLE_HPP_ +#include <com/sun/star/awt/Rectangle.hpp> +#endif + +#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLEROLE_HPP_ +#include <drafts/com/sun/star/accessibility/AccessibleRole.hpp> +#endif + +#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLETEXTTYPE_HPP_ +#include <drafts/com/sun/star/accessibility/AccessibleTextType.hpp> +#endif + +#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLESTATETYPE_HPP_ +#include <drafts/com/sun/star/accessibility/AccessibleStateType.hpp> +#endif + +#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLEEVENTID_HPP_ +#include <drafts/com/sun/star/accessibility/AccessibleEventId.hpp> +#endif + +#ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX_ +#include <unotools/accessiblestatesethelper.hxx> +#endif + +//------------------------------------------------------------------------ +// +// Project-local header +// +//------------------------------------------------------------------------ + +#ifndef _SVX_UNOSHAPE_HXX +#include "unoshape.hxx" +#endif + +#ifndef _UNO_LINGU_HXX +#include "unolingu.hxx" +#endif + +#ifndef _SVX_UNOPRACC_HXX +#include "unopracc.hxx" +#endif + +#ifndef _SVX_ACCESSIBLE_EDITABLE_TEXT_PARA_HXX +#include "AccessibleEditableTextPara.hxx" +#endif + + +using namespace ::com::sun::star; +using namespace ::drafts::com::sun::star::accessibility; + + +//------------------------------------------------------------------------ +// +// AccessibleEditableTextPara implementation +// +//------------------------------------------------------------------------ + +namespace accessibility +{ + + AccessibleEditableTextPara::AccessibleEditableTextPara( const uno::Reference< XAccessible >& rParent ) : + mnParagraphIndex( 0 ), + mnIndexInParent( 0 ), + mpEditSource( NULL ), + maEEOffset( 0, 0 ), + mxParent( rParent ), + maStateListeners( maMutex ) + { + } + + AccessibleEditableTextPara::~AccessibleEditableTextPara() + { + } + + void AccessibleEditableTextPara::SetIndexInParent( sal_Int32 nIndex ) + { + mnIndexInParent = nIndex; + } + + sal_Int32 AccessibleEditableTextPara::GetIndexInParent() const + { + return mnIndexInParent; + } + + void AccessibleEditableTextPara::SetParagraphIndex( sal_Int32 nIndex ) + { + sal_Int32 nOldIndex = mnParagraphIndex; + + if( nOldIndex != nIndex ) + { + // index and therefore description changed + LostPropertyEvent( uno::makeAny( getAccessibleDescription() ), AccessibleEventId::ACCESSIBLE_DESCRIPTION_EVENT ); + LostPropertyEvent( uno::makeAny( getAccessibleName() ), AccessibleEventId::ACCESSIBLE_NAME_EVENT ); + } + + mnParagraphIndex = nIndex; + + try + { + if( HaveChildren() ) + { + WeakBullet::HardRefType aChild( maImageBullet.get() ); + + if( aChild.is() ) + aChild->SetParagraphIndex(mnParagraphIndex); + } + } + catch( const uno::RuntimeException& ) {} + + if( nOldIndex != nIndex ) + { + // index and therefore description changed + GotPropertyEvent( uno::makeAny( getAccessibleDescription() ), AccessibleEventId::ACCESSIBLE_DESCRIPTION_EVENT ); + GotPropertyEvent( uno::makeAny( getAccessibleName() ), AccessibleEventId::ACCESSIBLE_NAME_EVENT ); + } + } + + sal_Int32 AccessibleEditableTextPara::GetParagraphIndex() const throw (uno::RuntimeException) + { + return mnParagraphIndex; + } + + void AccessibleEditableTextPara::SetEditSource( SvxEditSourceAdapter* pEditSource ) + { + mpEditSource = pEditSource; + + try + { + if( HaveChildren() ) + { + WeakBullet::HardRefType aChild( maImageBullet.get() ); + + if( aChild.is() ) + aChild->SetEditSource(pEditSource); + } + } + catch( const uno::RuntimeException& ) {} + + if( !mpEditSource ) + { + // going defunc + FireEvent( AccessibleEventId::ACCESSIBLE_STATE_EVENT ); + + try + { + uno::Reference < XAccessibleContext > xThis = getAccessibleContext(); + + lang::EventObject aEvent (xThis); + maStateListeners.disposeAndClear( aEvent ); + } + catch( const uno::RuntimeException& ) {} + } + } + + ESelection AccessibleEditableTextPara::MakeSelection( sal_Int32 nStartEEIndex, sal_Int32 nEndEEIndex ) + { + // check overflow + DBG_ASSERT(nStartEEIndex >= 0 && nStartEEIndex <= USHRT_MAX && + nEndEEIndex >= 0 && nEndEEIndex <= USHRT_MAX && + GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, + "AccessibleEditableTextPara::MakeSelection: index value overflow"); + + return ESelection( static_cast< USHORT >( GetParagraphIndex() ), static_cast< USHORT >( nStartEEIndex ), + static_cast< USHORT >( GetParagraphIndex() ), static_cast< USHORT >( nEndEEIndex ) ); + } + + ESelection AccessibleEditableTextPara::MakeSelection( sal_Int32 nEEIndex ) + { + return MakeSelection( nEEIndex, nEEIndex+1 ); + } + + void AccessibleEditableTextPara::CheckIndex( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) + { + if( nIndex < 0 || nIndex >= getCharacterCount() ) + throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleEditableTextPara: character index out of bounds")), + uno::Reference< uno::XInterface > + ( static_cast< ::cppu::OWeakObject* > (this) ) ); // disambiguate hierarchy + } + + void AccessibleEditableTextPara::CheckPosition( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) + { + if( nIndex < 0 || nIndex > getCharacterCount() ) + throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleEditableTextPara: character position out of bounds")), + uno::Reference< uno::XInterface > + ( static_cast< ::cppu::OWeakObject* > (this) ) ); // disambiguate hierarchy + } + + void AccessibleEditableTextPara::CheckRange( sal_Int32 nStart, sal_Int32 nEnd ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) + { + CheckPosition( nStart ); + CheckPosition( nEnd ); + } + + String AccessibleEditableTextPara::GetText( sal_Int32 nIndex ) throw (uno::RuntimeException) + { + return GetTextForwarder().GetText( MakeSelection(nIndex) ); + } + + String AccessibleEditableTextPara::GetTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (uno::RuntimeException) + { + return GetTextForwarder().GetText( MakeSelection(nStartIndex, nEndIndex) ); + } + + USHORT AccessibleEditableTextPara::GetTextLen() const throw (uno::RuntimeException) + { + return GetTextForwarder().GetTextLen( static_cast< USHORT >( GetParagraphIndex() ) ); + } + + sal_Bool AccessibleEditableTextPara::IsVisible() const + { + return mpEditSource ? sal_True : sal_False ; + } + + uno::Reference< XAccessibleText > AccessibleEditableTextPara::GetParaInterface( sal_Int32 nIndex ) + { + uno::Reference< XAccessible > xParent = getAccessibleParent(); + if( xParent.is() ) + { + uno::Reference< XAccessibleContext > xParentContext = xParent->getAccessibleContext(); + if( xParentContext.is() ) + { + uno::Reference< XAccessible > xPara = xParentContext->getAccessibleChild( nIndex ); + if( xPara.is() ) + return uno::Reference< XAccessibleText > ( xPara, uno::UNO_QUERY ); + } + } + + return uno::Reference< XAccessibleText >(); + } + + SvxEditSourceAdapter& AccessibleEditableTextPara::GetEditSource() const throw (uno::RuntimeException) + { + if( mpEditSource ) + return *mpEditSource; + else + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("No edit source, object is defunct")), + uno::Reference< uno::XInterface > + ( static_cast< ::cppu::OWeakObject* > + ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy + } + + SvxAccessibleTextAdapter& AccessibleEditableTextPara::GetTextForwarder() const throw (uno::RuntimeException) + { + SvxEditSourceAdapter& rEditSource = GetEditSource(); + SvxAccessibleTextAdapter* pTextForwarder = rEditSource.GetTextForwarderAdapter(); + + if( !pTextForwarder ) + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch text forwarder, object is defunct")), + uno::Reference< uno::XInterface > + ( static_cast< ::cppu::OWeakObject* > + ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy + + if( pTextForwarder->IsValid() ) + return *pTextForwarder; + else + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Text forwarder is invalid, object is defunct")), + uno::Reference< uno::XInterface > + ( static_cast< ::cppu::OWeakObject* > + ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy + } + + SvxViewForwarder& AccessibleEditableTextPara::GetViewForwarder() const throw (uno::RuntimeException) + { + SvxEditSource& rEditSource = GetEditSource(); + SvxViewForwarder* pViewForwarder = rEditSource.GetViewForwarder(); + + if( !pViewForwarder ) + { + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch view forwarder, object is defunct")), + uno::Reference< uno::XInterface > + ( static_cast< ::cppu::OWeakObject* > + ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy + } + + if( pViewForwarder->IsValid() ) + return *pViewForwarder; + else + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("View forwarder is invalid, object is defunct")), + uno::Reference< uno::XInterface > + ( static_cast< ::cppu::OWeakObject* > + ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy + } + + SvxAccessibleTextEditViewAdapter& AccessibleEditableTextPara::GetEditViewForwarder( sal_Bool bCreate ) const throw (uno::RuntimeException) + { + SvxEditSourceAdapter& rEditSource = GetEditSource(); + SvxAccessibleTextEditViewAdapter* pTextEditViewForwarder = rEditSource.GetEditViewForwarderAdapter( bCreate ); + + if( !pTextEditViewForwarder ) + { + if( bCreate ) + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch view forwarder, object is defunct")), + uno::Reference< uno::XInterface > + ( static_cast< ::cppu::OWeakObject* > + ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy + else + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("No view forwarder, object not in edit mode")), + uno::Reference< uno::XInterface > + ( static_cast< ::cppu::OWeakObject* > + ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy + } + + if( pTextEditViewForwarder->IsValid() ) + return *pTextEditViewForwarder; + else + { + if( bCreate ) + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("View forwarder is invalid, object is defunct")), + uno::Reference< uno::XInterface > + ( static_cast< ::cppu::OWeakObject* > + ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy + else + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("View forwarder is invalid, object not in edit mode")), + uno::Reference< uno::XInterface > + ( static_cast< ::cppu::OWeakObject* > + ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy + } + } + + sal_Bool AccessibleEditableTextPara::HaveEditView() const + { + SvxEditSource& rEditSource = GetEditSource(); + SvxEditViewForwarder* pViewForwarder = rEditSource.GetEditViewForwarder(); + + if( !pViewForwarder ) + return sal_False; + + if( !pViewForwarder->IsValid() ) + return sal_False; + + return sal_True; + } + + sal_Bool AccessibleEditableTextPara::HaveChildren() + { + DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, + "AccessibleEditableTextPara::HaveChildren: paragraph index value overflow"); + + return GetTextForwarder().HaveImageBullet( static_cast< USHORT >(GetParagraphIndex()) ); + } + + sal_Bool AccessibleEditableTextPara::IsActive() const throw (uno::RuntimeException) + { + SvxEditSource& rEditSource = GetEditSource(); + SvxEditViewForwarder* pViewForwarder = rEditSource.GetEditViewForwarder(); + + if( !pViewForwarder ) + return sal_False; + + if( pViewForwarder->IsValid() ) + return sal_False; + else + return sal_True; + } + + Rectangle AccessibleEditableTextPara::LogicToPixel( const Rectangle& rRect, const MapMode& rMapMode, SvxViewForwarder& rForwarder ) + { + // convert to screen coordinates + return Rectangle( rForwarder.LogicToPixel( rRect.TopLeft(), rMapMode ), + rForwarder.LogicToPixel( rRect.BottomRight(), rMapMode ) ); + } + + const Point& AccessibleEditableTextPara::GetEEOffset() const + { + return maEEOffset; + } + + void AccessibleEditableTextPara::SetEEOffset( const Point& rOffset ) + { + if( HaveChildren() ) + { + WeakBullet::HardRefType aChild( maImageBullet.get() ); + + if( aChild.is() ) + aChild->SetEEOffset(rOffset); + } + + maEEOffset = rOffset; + } + + void AccessibleEditableTextPara::FireEvent(const sal_Int16 nEventId, const uno::Any& rNewValue, const uno::Any& rOldValue) const + { + uno::Reference < XAccessibleContext > xThis( const_cast< AccessibleEditableTextPara* > (this)->getAccessibleContext() ); + + AccessibleEventObject aEvent(xThis, nEventId, rNewValue, rOldValue); + + // no locking necessary, OInterfaceIteratorHelper copies listeners if someone removes/adds in between + ::cppu::OInterfaceIteratorHelper aIter( const_cast< AccessibleEditableTextPara* >(this)->maStateListeners ); + while( aIter.hasMoreElements() ) + { + uno::Reference < XAccessibleEventListener > xListener( aIter.next(), uno::UNO_QUERY ); + + if( xListener.is() ) + { + try + { + xListener->notifyEvent( aEvent ); + } + catch( const uno::RuntimeException& ) + { +#ifdef DBG_UTIL + DBG_ERROR("AccessibleEditableTextPara::FireEvent: Caught runtime exception from listener, removing object (bridge/listener dead?)"); +#endif + } + } + } + } + + void AccessibleEditableTextPara::GotPropertyEvent( const uno::Any& rNewValue, const sal_Int16 nEventId ) const + { + FireEvent( nEventId, rNewValue ); + } + + void AccessibleEditableTextPara::LostPropertyEvent( const uno::Any& rOldValue, const sal_Int16 nEventId ) const + { + FireEvent( nEventId, uno::Any(), rOldValue ); + } + + uno::Any SAL_CALL AccessibleEditableTextPara::queryInterface (const uno::Type & rType) throw (uno::RuntimeException) + { + uno::Any aRet; + + // must provide XAccesibleText by hand, since it comes publicly inherited by XAccessibleEditableText + if ( rType == ::getCppuType((uno::Reference< XAccessibleText > *)0) ) + { + uno::Reference< XAccessibleText > aAccText = this; + aRet <<= aAccText; + } + else if ( rType == ::getCppuType((uno::Reference< XAccessibleEditableText > *)0) ) + { + uno::Reference< XAccessibleEditableText > aAccEditText = this; + aRet <<= aAccEditText; + } + else + { + aRet = AccessibleTextParaInterfaceBase::queryInterface(rType); + } + + return aRet; + } + + // XAccessible + uno::Reference< XAccessibleContext > SAL_CALL AccessibleEditableTextPara::getAccessibleContext() throw (uno::RuntimeException) + { + // We implement the XAccessibleContext interface in the same object + return uno::Reference< XAccessibleContext > ( this ); + } + + // XAccessibleContext + sal_Int32 SAL_CALL AccessibleEditableTextPara::getAccessibleChildCount() throw (uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + return HaveChildren() ? 1 : 0; + } + + uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleChild( sal_Int32 i ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + if( !HaveChildren() ) + throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("No childs available")), + uno::Reference< uno::XInterface > + ( static_cast< ::cppu::OWeakObject* > (this) ) ); // static_cast: disambiguate hierarchy + + if( i != 0 ) + throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Invalid child index")), + uno::Reference< uno::XInterface > + ( static_cast< ::cppu::OWeakObject* > (this) ) ); // static_cast: disambiguate hierarchy + + WeakBullet::HardRefType aChild( maImageBullet.get() ); + + if( !aChild.is() ) + { + // there is no hard reference available, create object then + AccessibleImageBullet* pChild = new AccessibleImageBullet( uno::Reference< XAccessible >( 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")), + uno::Reference< uno::XInterface > + ( static_cast< ::cppu::OWeakObject* > (this) ) ); + + aChild = WeakBullet::HardRefType( xChild, pChild ); + + aChild->SetEditSource( &GetEditSource() ); + aChild->SetParagraphIndex( GetParagraphIndex() ); + aChild->SetIndexInParent( i ); + + maImageBullet = aChild; + } + + return aChild.getRef(); + } + + uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleParent() throw (uno::RuntimeException) + { + return mxParent; + } + + sal_Int32 SAL_CALL AccessibleEditableTextPara::getAccessibleIndexInParent() throw (uno::RuntimeException) + { + return mnIndexInParent; + } + + sal_Int16 SAL_CALL AccessibleEditableTextPara::getAccessibleRole() throw (uno::RuntimeException) + { + // TODO + return AccessibleRole::TEXT; + } + + ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getAccessibleDescription() throw (uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + ::rtl::OUString aStr( RTL_CONSTASCII_USTRINGPARAM("Paragraph containing: ") ); + + // append first 40 characters from text, or first line, if shorter + // (writer takes first sentence here, but that's not supported + // from EditEngine) + ::rtl::OUString aLine = getTextAtIndex(0, AccessibleTextType::LINE); + + if( aLine.getLength() > MaxDescriptionLen ) + { + ::rtl::OUString aCurrWord; + sal_Int32 i; + + // search backward from MaxDescriptionLen for previous word start + for( aCurrWord=getTextAtIndex(MaxDescriptionLen, AccessibleTextType::WORD), + i=MaxDescriptionLen, + aLine=::rtl::OUString(); + i>=0; + --i ) + { + if( getTextAtIndex(i, AccessibleTextType::WORD) != aCurrWord ) + { + if( i == 0 ) + // prevent completely empty string + aLine = getTextAtIndex(0, AccessibleTextType::WORD); + else + aLine = getTextRange(0, i); + } + } + } + + return aStr + aLine; + } + + ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getAccessibleName() throw (uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + ::rtl::OUString aStr( RTL_CONSTASCII_USTRINGPARAM("Paragraph ") ); + + aStr += ::rtl::OUString::valueOf( GetParagraphIndex() ); + + return aStr; + } + + uno::Reference< XAccessibleRelationSet > SAL_CALL AccessibleEditableTextPara::getAccessibleRelationSet() throw (uno::RuntimeException) + { + // no relations, therefore empty + return uno::Reference< XAccessibleRelationSet >(); + } + + uno::Reference< XAccessibleStateSet > SAL_CALL AccessibleEditableTextPara::getAccessibleStateSet() throw (uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + utl::AccessibleStateSetHelper* aStateSet = new utl::AccessibleStateSetHelper(); + uno::Reference< XAccessibleStateSet > xStateSet( static_cast< cppu::OWeakObject* > (aStateSet), uno::UNO_QUERY ); + + // are we defunc? + if( !mpEditSource ) + { + aStateSet->AddState( AccessibleStateType::DEFUNC ); + aStateSet->AddState( AccessibleStateType::INVALID ); + } + + // are we editable? + if( IsActive() ) + { + aStateSet->AddState( AccessibleStateType::ACTIVE ); + aStateSet->AddState( AccessibleStateType::SELECTED ); + aStateSet->AddState( AccessibleStateType::EDITABLE ); + } + + if( isFocusTraversable() ) + { + aStateSet->AddState( AccessibleStateType::FOCUSABLE ); + } + + // TODO: handle focus state + // AccessibleStateType::FOCUSED + + // these are always on + aStateSet->AddState( AccessibleStateType::MULTILINE ); + // meaningful only for XAccessibleSelection interface + // aStateSet->AddState( AccessibleStateType::SELECTABLE ); + + // are we visible? + if( IsVisible() ) + { + aStateSet->AddState( AccessibleStateType::SHOWING ); + aStateSet->AddState( AccessibleStateType::VISIBLE ); + } + + return xStateSet; + } + + lang::Locale SAL_CALL AccessibleEditableTextPara::getLocale() throw (IllegalAccessibleComponentStateException, uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + lang::Locale aLocale; + + DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, + "AccessibleEditableTextPara::getLocale: paragraph index value overflow"); + + // return locale of first character in the paragraph + return SvxLanguageToLocale(aLocale, GetTextForwarder().GetLanguage( static_cast< USHORT >( GetParagraphIndex() ), 0 )); + } + + void SAL_CALL AccessibleEditableTextPara::addEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException) + { + maStateListeners.addInterface( xListener ); + } + + void SAL_CALL AccessibleEditableTextPara::removeEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException) + { + maStateListeners.removeInterface( xListener ); + } + + // XAccessibleComponent + sal_Bool SAL_CALL AccessibleEditableTextPara::contains( const awt::Point& aTmpPoint ) throw (uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, + "AccessibleEditableTextPara::contains: index value overflow"); + + awt::Rectangle aTmpRect = getBounds(); + Rectangle aRect( Point(aTmpRect.X, aTmpRect.Y), Size(aTmpRect.Width, aTmpRect.Height) ); + Point aPoint( aTmpPoint.X, aTmpPoint.Y ); + + return aRect.IsInside( aPoint ); + } + + uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleAt( const awt::Point& aPoint ) throw (uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + if( HaveChildren() ) + { + // create accessible object for bitmap bullet + // TODO + return uno::Reference< XAccessible >(); + } + else + { + // as we have no children, empty reference + return uno::Reference< XAccessible >(); + } + } + + awt::Rectangle SAL_CALL AccessibleEditableTextPara::getBounds() throw (uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, + "AccessibleEditableTextPara::getBounds: index value overflow"); + + SvxTextForwarder& rCacheTF = GetTextForwarder(); + Rectangle aRect = rCacheTF.GetParaBounds( static_cast< USHORT >( GetParagraphIndex() ) ); + + // convert to screen coordinates + Rectangle aScreenRect = AccessibleEditableTextPara::LogicToPixel( aRect, + rCacheTF.GetMapMode(), + GetViewForwarder() ); + + // offset from shape/cell + Point aOffset = GetEEOffset(); + + return awt::Rectangle( aScreenRect.Left() + aOffset.X(), + aScreenRect.Top() + aOffset.Y(), + aScreenRect.GetSize().Width(), + aScreenRect.GetSize().Height() ); + } + + awt::Point SAL_CALL AccessibleEditableTextPara::getLocation( ) throw (uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + awt::Rectangle aRect = getBounds(); + + return awt::Point( aRect.X, aRect.Y ); + } + + awt::Point SAL_CALL AccessibleEditableTextPara::getLocationOnScreen( ) throw (uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + // relate us to parent + uno::Reference< XAccessible > xParent = getAccessibleParent(); + if( xParent.is() ) + { + uno::Reference< XAccessibleComponent > xParentComponent( xParent, uno::UNO_QUERY ); + if( xParentComponent.is() ) + { + awt::Point aRefPoint = xParentComponent->getLocationOnScreen(); + awt::Point aPoint = getLocation(); + aPoint.X += aRefPoint.X; + aPoint.Y += aRefPoint.Y; + + return aPoint; + } + } + + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Cannot access parent")), + uno::Reference< uno::XInterface > + ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy + } + + awt::Size SAL_CALL AccessibleEditableTextPara::getSize( ) throw (uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + awt::Rectangle aRect = getBounds(); + + return awt::Size( aRect.Width, aRect.Height ); + } + + sal_Bool SAL_CALL AccessibleEditableTextPara::isShowing( ) throw (uno::RuntimeException) + { + return IsVisible(); + } + + sal_Bool SAL_CALL AccessibleEditableTextPara::isVisible( ) throw (uno::RuntimeException) + { + return IsVisible(); + } + + sal_Bool SAL_CALL AccessibleEditableTextPara::isFocusTraversable( ) throw (uno::RuntimeException) + { + return IsActive(); + } + + void SAL_CALL AccessibleEditableTextPara::addFocusListener( const uno::Reference< awt::XFocusListener >& xListener ) throw (uno::RuntimeException) + { + // TODO: remove + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Not focusable")), + uno::Reference< uno::XInterface > + ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy + } + + void SAL_CALL AccessibleEditableTextPara::removeFocusListener( const uno::Reference< awt::XFocusListener >& xListener ) throw (uno::RuntimeException) + { + // TODO: remove + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Not focusable")), + uno::Reference< uno::XInterface > + ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy + } + + void SAL_CALL AccessibleEditableTextPara::grabFocus( ) throw (uno::RuntimeException) + { + // set cursor to this paragraph + setSelection(0,0); + } + + uno::Any SAL_CALL AccessibleEditableTextPara::getAccessibleKeyBinding( ) throw (uno::RuntimeException) + { + // AFAIK, none. + return uno::Any(); + } + + // XAccessibleText + sal_Int32 SAL_CALL AccessibleEditableTextPara::getCaretPosition() throw (uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + if( !HaveEditView() ) + return -1; + + ESelection aSelection; + if( GetEditViewForwarder().GetSelection( aSelection ) && + GetParagraphIndex() == aSelection.nEndPara ) + { + // caret is always nEndPara,nEndPos + return aSelection.nEndPos; + } + + // not within this paragraph + return -1; + } + + sal_Unicode SAL_CALL AccessibleEditableTextPara::getCharacter( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, + "AccessibleEditableTextPara::getCharacter: index value overflow"); + + CheckIndex( nIndex ); + + return GetText( nIndex ).GetChar(0); + } + + uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getCharacterAttributes( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); + USHORT nPara = static_cast< USHORT >( GetParagraphIndex() ); + + DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, + "AccessibleEditableTextPara::getCharacterAttributes: index value overflow"); + + CheckIndex(nIndex); + + // use the portion property map, we're working on single characters + // TODO: hold it as a member? + SvxAccessibleTextPropertySet aPropSet( &GetEditSource(), + ImplGetSvxTextPortionPropertyMap() ); + + aPropSet.SetSelection( MakeSelection( nIndex ) ); + + // fetch property names + uno::Reference< beans::XPropertySetInfo > xPropSetInfo = aPropSet.getPropertySetInfo(); + + // convert from Any to PropertyValue + if( !xPropSetInfo.is() ) + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Cannot query XPropertySetInfo")), + uno::Reference< uno::XInterface > + ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy + + uno::Sequence< beans::Property > aPropertyNames = xPropSetInfo->getProperties(); + sal_Int32 i, nLength( aPropertyNames.getLength() ); + uno::Sequence< beans::PropertyValue > aOutSequence(nLength); + const beans::Property* pPropArray = aPropertyNames.getConstArray(); + beans::PropertyValue* pOutArray = aOutSequence.getArray(); + for(i=0; i<nLength; ++i) + { + pOutArray->Name = pPropArray->Name; + pOutArray->Handle = pPropArray->Handle; + pOutArray->Value = aPropSet.getPropertyValue( pPropArray->Name ); + pOutArray->State = aPropSet.getPropertyState( pPropArray->Name ); + + ++pPropArray; + ++pOutArray; + } + + return aOutSequence; + } + + awt::Rectangle SAL_CALL AccessibleEditableTextPara::getCharacterBounds( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, + "AccessibleEditableTextPara::getCharacterBounds: index value overflow"); + + CheckIndex( nIndex ); + + SvxTextForwarder& rCacheTF = GetTextForwarder(); + Rectangle aRect = rCacheTF.GetCharBounds( static_cast< USHORT >( GetParagraphIndex() ), static_cast< USHORT >( nIndex ) ); + + // convert to screen + Rectangle aScreenRect = AccessibleEditableTextPara::LogicToPixel( aRect, + rCacheTF.GetMapMode(), + GetViewForwarder() ); + // offset from shape/cell + Point aOffset = GetEEOffset(); + + return awt::Rectangle( aScreenRect.Left() + aOffset.X(), + aScreenRect.Top() + aOffset.Y(), + aScreenRect.GetSize().Width(), + aScreenRect.GetSize().Height() ); + } + + sal_Int32 SAL_CALL AccessibleEditableTextPara::getCharacterCount() throw (uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, + "AccessibleEditableTextPara::getCharacterCount: index value overflow"); + + return GetTextLen(); + } + + sal_Int32 SAL_CALL AccessibleEditableTextPara::getIndexAtPoint( const awt::Point& rPoint ) throw (uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + USHORT nPara, nIndex; + + // offset from surrounding cell/shape + Point aOffset( GetEEOffset() ); + Point aPoint( rPoint.X - aOffset.X(), rPoint.Y - aOffset.Y() ); + + // convert to logical coordinates + SvxTextForwarder& rCacheTF = GetTextForwarder(); + Point aLogPoint( GetViewForwarder().PixelToLogic( aPoint, rCacheTF.GetMapMode() ) ); + + if( rCacheTF.GetIndexAtPoint( aLogPoint, nPara, nIndex ) && + GetParagraphIndex() == nPara ) + { + return nIndex; + } + else + { + // not within our paragraph + return -1; + } + } + + sal_Bool AccessibleEditableTextPara::GetSelection( USHORT& nStartPos, USHORT& nEndPos ) throw (uno::RuntimeException) + { + ESelection aSelection; + USHORT nPara = static_cast< USHORT > ( GetParagraphIndex() ); + if( !GetEditViewForwarder().GetSelection( aSelection ) ) + return sal_False; + + if( aSelection.nStartPara < aSelection.nEndPara ) + { + if( aSelection.nStartPara > nPara || + aSelection.nEndPara < nPara ) + return sal_False; + + if( nPara == aSelection.nStartPara ) + nStartPos = aSelection.nStartPos; + else + nStartPos = 0; + + if( nPara == aSelection.nEndPara ) + nEndPos = aSelection.nEndPos; + else + nEndPos = GetTextLen(); + } + else + { + if( aSelection.nStartPara < nPara || + aSelection.nEndPara > nPara ) + return sal_False; + + if( nPara == aSelection.nStartPara ) + nStartPos = aSelection.nStartPos; + else + nStartPos = GetTextLen(); + + if( nPara == aSelection.nEndPara ) + nEndPos = aSelection.nEndPos; + else + nEndPos = 0; + } + + return sal_True; + } + + ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getSelectedText() throw (uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, + "AccessibleEditableTextPara::getSelectedText: index value overflow"); + + if( !HaveEditView() ) + return ::rtl::OUString(); + + USHORT nStartPos, nEndPos; + if( GetSelection( nStartPos, nEndPos ) ) + return GetTextRange( nStartPos, nEndPos ); + + return ::rtl::OUString(); + } + + sal_Int32 SAL_CALL AccessibleEditableTextPara::getSelectionStart() throw (uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, + "AccessibleEditableTextPara::getSelectionStart: index value overflow"); + + if( !HaveEditView() ) + return -1; + + USHORT nStartPos, nEndPos; + if( GetSelection( nStartPos, nEndPos) ) + return nStartPos; + else + return -1; + } + + sal_Int32 SAL_CALL AccessibleEditableTextPara::getSelectionEnd() throw (uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, + "AccessibleEditableTextPara::getSelectionEnd: index value overflow"); + + if( !HaveEditView() ) + return -1; + + USHORT nStartPos, nEndPos; + if( GetSelection( nStartPos, nEndPos) ) + return nEndPos; + else + return -1; + } + + sal_Bool SAL_CALL AccessibleEditableTextPara::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, + "AccessibleEditableTextPara::setSelection: paragraph index value overflow"); + + CheckRange(nStartIndex, nEndIndex); + + return GetEditViewForwarder( sal_True ).SetSelection( MakeSelection(nStartIndex, nEndIndex) ); + } + + ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getText() throw (uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, + "AccessibleEditableTextPara::getText: paragraph index value overflow"); + + return GetTextRange( 0, GetTextLen() ); + } + + ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, + "AccessibleEditableTextPara::getTextRange: paragraph index value overflow"); + + CheckRange(nStartIndex, nEndIndex); + + return GetTextRange(nStartIndex, nEndIndex); + } + + ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + SvxTextForwarder& rCacheTF = GetTextForwarder(); + sal_Int32 nParaIndex = GetParagraphIndex(); + + DBG_ASSERT(nParaIndex >= 0 && nParaIndex <= USHRT_MAX, + "AccessibleEditableTextPara::getTextAtIndex: paragraph index value overflow"); + + sal_Int32 nTextLen = rCacheTF.GetTextLen( static_cast< USHORT >( nParaIndex ) ); + + CheckIndex(nIndex); + + ::rtl::OUString aRetVal; + + switch( aTextType ) + { + case AccessibleTextType::GLYPH: + // TODO + break; + + case AccessibleTextType::ATTRIBUTE_RUN: + // GetCharAttribs( USHORT nPara, EECharAttribArray& rLst ) const; + // beware: array is sorted in start positions, the end positions can overlap! + // TODO + break; + + case AccessibleTextType::CHARACTER: + aRetVal = String( getCharacter( nIndex ) ); + break; + + case AccessibleTextType::WORD: + { + USHORT nStart, nEnd; + if( rCacheTF.GetWordIndices( static_cast< USHORT >( nParaIndex ), static_cast< USHORT >( nIndex ), nStart, nEnd ) ) + aRetVal = GetTextRange( nStart, nEnd ); + break; + } + + case AccessibleTextType::LINE: + { + USHORT nLine, nLineCount=rCacheTF.GetLineCount( static_cast< USHORT >( nParaIndex ) ); + sal_Int32 nCurIndex; + for( nLine=0, nCurIndex=0; nLine<nLineCount; ++nLine ) + { + nCurIndex += rCacheTF.GetLineLen( static_cast< USHORT >( nParaIndex ), nLine); + + if( nCurIndex > nIndex ) + { + aRetVal = GetTextRange( nCurIndex - rCacheTF.GetLineLen(static_cast< USHORT >( nParaIndex ), nLine), nCurIndex ); + break; + } + } + break; + } + + case AccessibleTextType::SENTENCE: + // TODO. currently fallback to paragraph. + case AccessibleTextType::PARAGRAPH: + aRetVal = getText(); + break; + + default: + throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Text type value out of range")), + uno::Reference< uno::XInterface > + ( static_cast< ::cppu::OWeakObject* > (this) ) ); // disambiguate hierarchy + } /* end of switch( aTextType ) */ + + return aRetVal; + } + + ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + SvxTextForwarder& rCacheTF = GetTextForwarder(); + sal_Int32 nParaIndex = GetParagraphIndex(); + + DBG_ASSERT(nParaIndex >= 0 && nParaIndex <= USHRT_MAX, + "AccessibleEditableTextPara::getTextBeforeIndex: paragraph index value overflow"); + + sal_Int32 nTextLen( rCacheTF.GetTextLen( static_cast< USHORT >( nParaIndex ) ) ); + + CheckIndex(nIndex); + + ::rtl::OUString aRetVal; + + switch( aTextType ) + { + case AccessibleTextType::GLYPH: + // TODO + break; + + case AccessibleTextType::ATTRIBUTE_RUN: + // TODO + break; + + case AccessibleTextType::CHARACTER: + aRetVal = nIndex > 0 ? String(getCharacter( nIndex-1 )) : String(); + break; + + case AccessibleTextType::WORD: + { + USHORT nStart, nEnd; + if( rCacheTF.GetWordIndices( static_cast< USHORT >( nParaIndex ), static_cast< USHORT >( nIndex ), nStart, nEnd ) ) + { + // semantics: + // + // word w|ord word # word |word word # word| word + // ^^^^ ^^^^ ^^^^ + // + + // already at the left border + if( nStart == 0 ) + break; + + // one word to the left + if( rCacheTF.GetWordIndices( static_cast< USHORT >( nParaIndex ), static_cast< USHORT >( nStart ), nStart, nEnd ) ) + aRetVal = GetTextRange(nStart, nEnd); + + break; + } + } + + case AccessibleTextType::LINE: + { + USHORT nLine, nLineCount=rCacheTF.GetLineCount( static_cast< USHORT >( nParaIndex ) ); + sal_Int32 nCurIndex, nLastIndex, nCurLineLen; + // get the line before the line the index points into + for( nLine=0, nCurIndex=0, nLastIndex=0; nLine<nLineCount; ++nLine ) + { + nLastIndex = nCurIndex; + nCurLineLen = rCacheTF.GetLineLen(static_cast< USHORT >( nParaIndex ), nLine); + nCurIndex += nCurLineLen; + + if( nCurIndex > nIndex && + nLastIndex > nCurLineLen ) + { + aRetVal = GetTextRange( nLastIndex - nCurLineLen, static_cast< USHORT >( nLastIndex ) ); + break; + } + } + break; + } + + case AccessibleTextType::SENTENCE: + // TODO. currently fallback to paragraph. + case AccessibleTextType::PARAGRAPH: + // get paragraph before (convenience? bug? feature?) + if( nParaIndex && + GetParaInterface( nParaIndex - 1 ).is() ) + { + aRetVal = GetParaInterface( nParaIndex - 1 )->getText(); + } + break; + + default: + throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Text type value out of range")), + uno::Reference< uno::XInterface > + ( static_cast< ::cppu::OWeakObject* > (this) ) ); // disambiguate hierarchy + } /* end of switch( aTextType ) */ + + return aRetVal; + } + + ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + SvxTextForwarder& rCacheTF = GetTextForwarder(); + sal_Int32 nParaIndex = GetParagraphIndex(); + + DBG_ASSERT(nParaIndex >= 0 && nParaIndex <= USHRT_MAX, + "AccessibleEditableTextPara::getTextBehindIndex: paragraph index value overflow"); + + sal_Int32 nTextLen( rCacheTF.GetTextLen( static_cast< USHORT >( nParaIndex ) ) ); + + CheckIndex(nIndex); + + ::rtl::OUString aRetVal; + + switch( aTextType ) + { + case AccessibleTextType::GLYPH: + // TODO + break; + + case AccessibleTextType::ATTRIBUTE_RUN: + // TODO + break; + + case AccessibleTextType::CHARACTER: + aRetVal = nIndex < nTextLen-1 ? String(getCharacter( nIndex+1 )) : String(); + break; + + case AccessibleTextType::WORD: + { + USHORT nStart, nEnd; + if( rCacheTF.GetWordIndices( static_cast< USHORT >( nParaIndex ), static_cast< USHORT >( nIndex ), nStart, nEnd ) ) + { + // semantics: + // + // word w|ord word # word |word # word word| word + // ^^^^ ^^^^ ^^^^ + // + + // already at the right border + if( nEnd >= nTextLen-2 ) + break; + + // one word to the right + if( rCacheTF.GetWordIndices( static_cast< USHORT >( nParaIndex ), nEnd+1, nStart, nEnd ) ) + aRetVal = GetTextRange(nStart, nEnd); + + break; + } + } + + case AccessibleTextType::LINE: + { + USHORT nLine, nLineCount=rCacheTF.GetLineCount( static_cast< USHORT >( nParaIndex ) ); + sal_Int32 nCurIndex; + // get the line after the line the index points into + for( nLine=0, nCurIndex=0; nLine<nLineCount; ++nLine ) + { + nCurIndex += rCacheTF.GetLineLen(static_cast< USHORT >( nParaIndex ), nLine); + + if( nCurIndex > nIndex && + nLine < nLineCount-1 ) + { + aRetVal = GetTextRange( nCurIndex, nCurIndex + rCacheTF.GetLineLen(static_cast< USHORT >( nParaIndex ), nLine+1) ); + break; + } + } + break; + } + + case AccessibleTextType::SENTENCE: + // TODO. currently fallback to paragraph. + case AccessibleTextType::PARAGRAPH: + // get paragraph behind (convenience? bug? feature?) + if( nParaIndex < rCacheTF.GetParagraphCount() - 1 && + GetParaInterface( nParaIndex + 1 ).is() ) + { + aRetVal = GetParaInterface( nParaIndex + 1 )->getText(); + } + break; + + default: + throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Text type value out of range")), + uno::Reference< uno::XInterface > + ( static_cast< ::cppu::OWeakObject* > (this) ) ); // disambiguate hierarchy + } /* end of switch( aTextType ) */ + + return aRetVal; + } + + sal_Bool SAL_CALL AccessibleEditableTextPara::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True ); + SvxTextForwarder& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs + sal_Bool aRetVal; + + DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, + "AccessibleEditableTextPara::copyText: index value overflow"); + + CheckRange(nStartIndex, nEndIndex); + + // save current selection + ESelection aOldSelection; + + rCacheVF.GetSelection( aOldSelection ); + rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) ); + aRetVal = rCacheVF.Copy(); + rCacheVF.SetSelection( aOldSelection ); // restore + + return aRetVal; + } + + // XAccessibleEditableText + sal_Bool SAL_CALL AccessibleEditableTextPara::cutText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True ); + SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs + + DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, + "AccessibleEditableTextPara::cutText: index value overflow"); + + CheckRange(nStartIndex, nEndIndex); + + if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) ) + return sal_False; // non-editable area selected + + // don't save selection, might become invalid after cut! + rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) ); + + return rCacheVF.Cut(); + } + + sal_Bool SAL_CALL AccessibleEditableTextPara::pasteText( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True ); + SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs + + DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, + "AccessibleEditableTextPara::pasteText: index value overflow"); + + CheckPosition(nIndex); + + if( !rCacheTF.IsEditable( MakeSelection(nIndex) ) ) + return sal_False; // non-editable area selected + + // set empty selection (=> cursor) to given index + rCacheVF.SetSelection( MakeSelection(nIndex) ); + + return rCacheVF.Paste(); + } + + sal_Bool SAL_CALL AccessibleEditableTextPara::deleteText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); + + DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, + "AccessibleEditableTextPara::deleteText: index value overflow"); + + CheckRange(nStartIndex, nEndIndex); + + if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) ) + return sal_False; // non-editable area selected + + sal_Bool nRet = rCacheTF.Delete( MakeSelection(nStartIndex, nEndIndex) ); + + GetEditSource().UpdateData(); + + return nRet; + } + + sal_Bool SAL_CALL AccessibleEditableTextPara::insertText( const ::rtl::OUString& sText, sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); + + DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, + "AccessibleEditableTextPara::insertText: index value overflow"); + + CheckPosition(nIndex); + + if( !rCacheTF.IsEditable( MakeSelection(nIndex) ) ) + return sal_False; // non-editable area selected + + // insert given text at empty selection (=> cursor) + sal_Bool nRet = rCacheTF.InsertText( sText, MakeSelection(nIndex) ); + + rCacheTF.QuickFormatDoc(); + GetEditSource().UpdateData(); + + return nRet; + } + + sal_Bool SAL_CALL AccessibleEditableTextPara::replaceText( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const ::rtl::OUString& sReplacement ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); + + DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, + "AccessibleEditableTextPara::replaceText: index value overflow"); + + CheckRange(nStartIndex, nEndIndex); + + if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) ) + return sal_False; // non-editable area selected + + // insert given text into given range => replace + sal_Bool nRet = rCacheTF.InsertText( sReplacement, MakeSelection(nStartIndex, nEndIndex) ); + + rCacheTF.QuickFormatDoc(); + GetEditSource().UpdateData(); + + return nRet; + } + + sal_Bool SAL_CALL AccessibleEditableTextPara::setAttributes( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const uno::Sequence< beans::PropertyValue >& aAttributeSet ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); + USHORT nPara = static_cast< USHORT >( GetParagraphIndex() ); + + DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, + "AccessibleEditableTextPara::setAttributes: index value overflow"); + + CheckRange(nStartIndex, nEndIndex); + + if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) ) + return sal_False; // non-editable area selected + + // do the indices span the whole paragraph? Then use the outliner map + // TODO: hold it as a member? + SvxAccessibleTextPropertySet aPropSet( &GetEditSource(), + 0 == nStartIndex && + rCacheTF.GetTextLen(nPara) == nEndIndex ? + ImplGetSvxUnoOutlinerTextCursorPropertyMap() : + ImplGetSvxTextPortionPropertyMap() ); + + aPropSet.SetSelection( MakeSelection(nStartIndex, nEndIndex) ); + + // convert from PropertyValue to Any + sal_Int32 i, nLength( aAttributeSet.getLength() ); + const beans::PropertyValue* pPropArray = aAttributeSet.getConstArray(); + for(i=0; i<nLength; ++i) + { + try + { + aPropSet.setPropertyValue(pPropArray->Name, pPropArray->Value); + } + catch( const uno::Exception& ) + { + DBG_ERROR("AccessibleEditableTextPara::setAttributes exception in setPropertyValue"); + } + + ++pPropArray; + } + + rCacheTF.QuickFormatDoc(); + GetEditSource().UpdateData(); + + return sal_True; + } + + sal_Bool SAL_CALL AccessibleEditableTextPara::setText( const ::rtl::OUString& sText ) throw (uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + return replaceText(0, getCharacterCount(), sText); + } + + // XServiceInfo + ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getImplementationName (void) throw (uno::RuntimeException) + { + return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("AccessibleEditableTextPara")); + } + + sal_Bool SAL_CALL AccessibleEditableTextPara::supportsService (const ::rtl::OUString& sServiceName) throw (uno::RuntimeException) + { + // Iterate over all supported service names and return true if on of them + // matches the given name. + uno::Sequence< ::rtl::OUString> aSupportedServices ( + getSupportedServiceNames ()); + for (int i=0; i<aSupportedServices.getLength(); i++) + if (sServiceName == aSupportedServices[i]) + return sal_True; + return sal_False; + } + + uno::Sequence< ::rtl::OUString> SAL_CALL AccessibleEditableTextPara::getSupportedServiceNames (void) throw (uno::RuntimeException) + { + const ::rtl::OUString sServiceName (RTL_CONSTASCII_USTRINGPARAM ("drafts.com.sun.star.accessibility.AccessibleContext")); + return uno::Sequence< ::rtl::OUString > (&sServiceName, 1); + } + + // XServiceName + ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getServiceName (void) throw (uno::RuntimeException) + { + return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("drafts.com.sun.star.accessibility.AccessibleContext")); + } + +} // end of namespace accessibility + +//------------------------------------------------------------------------ diff --git a/svx/source/accessibility/AccessibleEditableTextPara.hxx b/svx/source/accessibility/AccessibleEditableTextPara.hxx new file mode 100644 index 000000000000..3968465921ad --- /dev/null +++ b/svx/source/accessibility/AccessibleEditableTextPara.hxx @@ -0,0 +1,403 @@ +/************************************************************************* + * + * $RCSfile: AccessibleEditableTextPara.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: thb $ $Date: 2002-05-16 16:10:17 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _SVX_ACCESSIBLE_EDITABLE_TEXT_PARA_HXX +#define _SVX_ACCESSIBLE_EDITABLE_TEXT_PARA_HXX + +#ifndef _SV_GEN_HXX +#include <tools/gen.hxx> +#endif + +#ifndef _CPPUHELPER_WEAKREF_HXX_ +#include <cppuhelper/weakref.hxx> +#endif + +#ifndef _CPPUHELPER_IMPLBASE6_HXX_ +#include <cppuhelper/implbase6.hxx> +#endif + +#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_ +#include <cppuhelper/typeprovider.hxx> +#endif + +#ifndef _CPPUHELPER_INTERFACECONTAINER_H_ +#include <cppuhelper/interfacecontainer.hxx> +#endif + +#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_ +#include <com/sun/star/uno/Reference.hxx> +#endif + +#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_ +#include <com/sun/star/lang/XServiceInfo.hpp> +#endif + +#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLE_HPP_ +#include <drafts/com/sun/star/accessibility/XAccessible.hpp> +#endif + +#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLECONTEXT_HPP_ +#include <drafts/com/sun/star/accessibility/XAccessibleContext.hpp> +#endif + +#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLECOMPONENT_HPP_ +#include <drafts/com/sun/star/accessibility/XAccessibleComponent.hpp> +#endif + +#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEEDITABLETEXT_HPP_ +#include <drafts/com/sun/star/accessibility/XAccessibleEditableText.hpp> +#endif + +#ifndef _SVX_ACCESSIBLE_PARA_MANAGER_HXX +#include "AccessibleParaManager.hxx" +#endif + +#ifndef _SVX_ACCESSIBLE_IMAGE_BULLET_HXX +#include "AccessibleImageBullet.hxx" +#endif + +#ifndef _SVX_UNOEDPRX_HXX +#include "unoedprx.hxx" +#endif + + +namespace accessibility +{ + + typedef ::cppu::WeakImplHelper6< ::drafts::com::sun::star::accessibility::XAccessible, + ::drafts::com::sun::star::accessibility::XAccessibleContext, + ::drafts::com::sun::star::accessibility::XAccessibleComponent, + ::drafts::com::sun::star::accessibility::XAccessibleEditableText, + ::drafts::com::sun::star::accessibility::XAccessibleEventBroadcaster, + ::com::sun::star::lang::XServiceInfo > AccessibleTextParaInterfaceBase; + + /** This class implements the actual text paragraphs for the EditEngine/Outliner UAA + */ + class AccessibleEditableTextPara : public AccessibleTextParaInterfaceBase + { + + public: + /// Create accessible object for given parent + AccessibleEditableTextPara ( const ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessible >& rParent ); + + virtual ~AccessibleEditableTextPara (); + + // XInterface + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface (const ::com::sun::star::uno::Type & rType) throw (::com::sun::star::uno::RuntimeException); + + // XAccessible + virtual ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) throw (::com::sun::star::uno::RuntimeException); + + // XAccessibleContext + virtual sal_Int32 SAL_CALL getAccessibleChildCount() throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleParent() throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getAccessibleIndexInParent() throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int16 SAL_CALL getAccessibleRole() throw (::com::sun::star::uno::RuntimeException); + /// Maximal length of text returned by getAccessibleDescription() + enum { MaxDescriptionLen = 40 }; + virtual ::rtl::OUString SAL_CALL getAccessibleDescription() throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getAccessibleName() throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet() throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet() throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::lang::Locale SAL_CALL getLocale() throw (::drafts::com::sun::star::accessibility::IllegalAccessibleComponentStateException, ::com::sun::star::uno::RuntimeException); + + // XAccessibleEventBroadcaster + virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + + // XAccessibleComponent + virtual sal_Bool SAL_CALL contains( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleAt( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Rectangle SAL_CALL getBounds( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Point SAL_CALL getLocation( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Point SAL_CALL getLocationOnScreen( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Size SAL_CALL getSize( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isShowing( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isVisible( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isFocusTraversable( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addFocusListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFocusListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeFocusListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFocusListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL grabFocus( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getAccessibleKeyBinding( ) throw (::com::sun::star::uno::RuntimeException); + + // XAccessibleText (this comes implicitely inherited by XAccessibleEditableText) + virtual sal_Int32 SAL_CALL getCaretPosition() throw (::com::sun::star::uno::RuntimeException); + virtual sal_Unicode SAL_CALL getCharacter( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getCharacterAttributes( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Rectangle SAL_CALL getCharacterBounds( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getCharacterCount() throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getIndexAtPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getSelectedText() throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getSelectionStart() throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getSelectionEnd() throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getText() throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + /// Does not support AccessibleTextType::SENTENCE (missing feature in EditEngine) + virtual ::rtl::OUString SAL_CALL getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + /// Does not support AccessibleTextType::SENTENCE (missing feature in EditEngine) + virtual ::rtl::OUString SAL_CALL getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + /// Does not support AccessibleTextType::SENTENCE (missing feature in EditEngine) + virtual ::rtl::OUString SAL_CALL getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + + // XAccessibleEditableText + virtual sal_Bool SAL_CALL cutText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL pasteText( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL deleteText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL insertText( const ::rtl::OUString& sText, sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL replaceText( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const ::rtl::OUString& sReplacement ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL setAttributes( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aAttributeSet ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL setText( const ::rtl::OUString& sText ) throw (::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName (void) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService (const ::rtl::OUString& sServiceName) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL getSupportedServiceNames (void) throw (::com::sun::star::uno::RuntimeException); + + // XServiceName + virtual ::rtl::OUString SAL_CALL getServiceName (void) throw (::com::sun::star::uno::RuntimeException); + + /** Set the current index in the accessibility parent + + @attention This method does not lock the SolarMutex, + leaving that to the calling code. This is because only + there potential deadlock situations can be resolved. Thus, + make sure SolarMutex is locked when calling this. + */ + void SetIndexInParent( sal_Int32 nIndex ); + + /** Get the current index in the accessibility parent + + @attention This method does not lock the SolarMutex, + leaving that to the calling code. This is because only + there potential deadlock situations can be resolved. Thus, + make sure SolarMutex is locked when calling this. + */ + sal_Int32 GetIndexInParent() const; + + /** Set the current paragraph number + + @attention This method does not lock the SolarMutex, + leaving that to the calling code. This is because only + there potential deadlock situations can be resolved. Thus, + make sure SolarMutex is locked when calling this. + */ + void SetParagraphIndex( sal_Int32 nIndex ); + + /** Query the current paragraph number (0 - nParas-1) + + @attention This method does not lock the SolarMutex, + leaving that to the calling code. This is because only + there potential deadlock situations can be resolved. Thus, + make sure SolarMutex is locked when calling this. + */ + sal_Int32 GetParagraphIndex() const throw (::com::sun::star::uno::RuntimeException); + + /** Set the edit engine offset + + @attention This method does not lock the SolarMutex, + leaving that to the calling code. This is because only + there potential deadlock situations can be resolved. Thus, + make sure SolarMutex is locked when calling this. + */ + void SetEEOffset( const Point& rOffset ); + + /** Set the EditEngine offset + + @attention This method does not lock the SolarMutex, + leaving that to the calling code. This is because only + there potential deadlock situations can be resolved. Thus, + make sure SolarMutex is locked when calling this. + */ + void SetEditSource( SvxEditSourceAdapter* pEditSource ); + + /// Calls all Listener objects to tell them the change. Don't hold locks when calling this! + virtual void FireEvent(const sal_Int16 nEventId, const ::com::sun::star::uno::Any& rNewValue = ::com::sun::star::uno::Any(), const ::com::sun::star::uno::Any& rOldValue = ::com::sun::star::uno::Any() ) const; + + static Rectangle LogicToPixel( const Rectangle& rRect, const MapMode& rMapMode, SvxViewForwarder& rForwarder ); + + private: + + // declared, but not defined + AccessibleEditableTextPara( const AccessibleEditableTextPara& ); + AccessibleEditableTextPara& operator= ( const AccessibleEditableTextPara& ); + + // syntactic sugar for FireEvent + void GotPropertyEvent( const ::com::sun::star::uno::Any& rNewValue, const sal_Int16 nEventId ) const; + void LostPropertyEvent( const ::com::sun::star::uno::Any& rOldValue, const sal_Int16 nEventId ) const; + + /** Query the visibility state + + @attention This method does not lock the SolarMutex, + leaving that to the calling code. This is because only + there potential deadlock situations can be resolved. Thus, + make sure SolarMutex is locked when calling this. + + @return the visibility state. Per definition, a defunc object is no longer visible + */ + sal_Bool IsVisible() const; + + // retrieve text interface for given paragraph index + ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessibleText > GetParaInterface( sal_Int32 nIndex ); + + SvxEditSourceAdapter& GetEditSource() const throw (::com::sun::star::uno::RuntimeException); + + /** Query the SvxTextForwarder for EditEngine access. + + @attention This method does not lock the SolarMutex, + leaving that to the calling code. This is because only + there potential deadlock situations can be resolved. Thus, + make sure SolarMutex is locked when calling this. + */ + SvxAccessibleTextAdapter& GetTextForwarder() const throw (::com::sun::star::uno::RuntimeException); + + /** Query the SvxViewForwarder for EditEngine access. + + @attention This method does not lock the SolarMutex, + leaving that to the calling code. This is because only + there potential deadlock situations can be resolved. Thus, + make sure SolarMutex is locked when calling this. + */ + SvxViewForwarder& GetViewForwarder() const throw (::com::sun::star::uno::RuntimeException); + + /** Query whether a GetEditViewForwarder( sal_False ) will return a forwarder + + @attention This method does not lock the SolarMutex, + leaving that to the calling code. This is because only + there potential deadlock situations can be resolved. Thus, + make sure SolarMutex is locked when calling this. + */ + sal_Bool HaveEditView() const; + + /** Query the SvxEditViewForwarder for EditEngine access. + + @attention This method does not lock the SolarMutex, + leaving that to the calling code. This is because only + there potential deadlock situations can be resolved. Thus, + make sure SolarMutex is locked when calling this. + */ + SvxAccessibleTextEditViewAdapter& GetEditViewForwarder( sal_Bool bCreate = sal_False ) const throw (::com::sun::star::uno::RuntimeException); + + /// Do we have children? This is the case for image bullets + sal_Bool HaveChildren(); + + /// Is the underlying object in edit mode + sal_Bool IsActive() const throw (::com::sun::star::uno::RuntimeException); + + const Point& GetEEOffset() const; + + // Get text from forwarder + String GetText( sal_Int32 nIndex ) throw (::com::sun::star::uno::RuntimeException); + String GetTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::uno::RuntimeException); + USHORT GetTextLen() const throw (::com::sun::star::uno::RuntimeException); + + /** Get the current selection of this paragraph + + @return sal_False, if nothing in this paragraph is selected + */ + sal_Bool GetSelection( USHORT& nStartPos, USHORT& nEndPos ) throw (::com::sun::star::uno::RuntimeException); + + /** create selection from Accessible selection. + + */ + ESelection MakeSelection( sal_Int32 nStartEEIndex, sal_Int32 nEndEEIndex ); + ESelection MakeSelection( sal_Int32 nEEIndex ); + + // check whether index value is within permitted range + + /// Check whether 0<=nIndex<=n-1 + void CheckIndex( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + /// Check whether 0<=nIndex<=n + void CheckPosition( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + /// Check whether 0<=nStart<=n and 0<=nEnd<=n + void CheckRange( sal_Int32 nStart, sal_Int32 nEnd ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + + // the paragraph index in the edit engine (guarded by solar mutex) + sal_Int32 mnParagraphIndex; + + // our current index in the parent (guarded by solar mutex) + sal_Int32 mnIndexInParent; + + // the current edit source (guarded by solar mutex) + SvxEditSourceAdapter* mpEditSource; + + // the possible child (for image bullets, guarded by solar mutex) + typedef WeakCppRef < ::drafts::com::sun::star::accessibility::XAccessible, AccessibleImageBullet > WeakBullet; + WeakBullet maImageBullet; + + // the offset of the underlying EditEngine from the shape/cell (guarded by solar mutex) + Point maEEOffset; + + mutable osl::Mutex maMutex; + + /// The shape we're the accessible for (unguarded) + ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessible > mxParent; + + /// Our listeners (guarded by maMutex) + ::cppu::OInterfaceContainerHelper maStateListeners; + }; + +} // end of namespace accessibility + +#endif + diff --git a/svx/source/accessibility/AccessibleImageBullet.cxx b/svx/source/accessibility/AccessibleImageBullet.cxx new file mode 100644 index 000000000000..912172baec56 --- /dev/null +++ b/svx/source/accessibility/AccessibleImageBullet.cxx @@ -0,0 +1,582 @@ +/************************************************************************* + * + * $RCSfile: AccessibleImageBullet.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: thb $ $Date: 2002-05-16 16:10:32 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _SV_GEN_HXX +#include <tools/gen.hxx> +#endif + +#ifndef _VOS_MUTEX_HXX_ +#include <vos/mutex.hxx> +#endif + +#ifndef _SV_SVAPP_HXX +#include <vcl/svapp.hxx> +#endif + +#ifndef _RTL_USTRING_HXX_ +#include <rtl/ustring.hxx> +#endif + +#ifndef _COM_SUN_STAR_AWT_POINT_HPP_ +#include <com/sun/star/awt/Point.hpp> +#endif + +#ifndef _COM_SUN_STAR_AWT_RECTANGLE_HPP_ +#include <com/sun/star/awt/Rectangle.hpp> +#endif + +#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLEROLE_HPP_ +#include <drafts/com/sun/star/accessibility/AccessibleRole.hpp> +#endif + +#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLETEXTTYPE_HPP_ +#include <drafts/com/sun/star/accessibility/AccessibleTextType.hpp> +#endif + +#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLESTATETYPE_HPP_ +#include <drafts/com/sun/star/accessibility/AccessibleStateType.hpp> +#endif + +#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLEEVENTID_HPP_ +#include <drafts/com/sun/star/accessibility/AccessibleEventId.hpp> +#endif + +#ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX_ +#include <unotools/accessiblestatesethelper.hxx> +#endif + +#ifndef _UNO_LINGU_HXX +#include "unolingu.hxx" +#endif + +#ifndef _SVX_ACCESSIBLE_EDITABLE_TEXT_PARA_HXX +#include "AccessibleEditableTextPara.hxx" +#endif + +#ifndef _SVX_ACCESSIBLE_IMAGE_BULLET_HXX +#include "AccessibleImageBullet.hxx" +#endif + +#include "editdata.hxx" +#include "editeng.hxx" +#include "outliner.hxx" + + +using namespace ::com::sun::star; +using namespace ::drafts::com::sun::star::accessibility; + +namespace accessibility +{ + + AccessibleImageBullet::AccessibleImageBullet ( const uno::Reference< XAccessible >& rParent ) : + mnParagraphIndex( 0 ), + mnIndexInParent( 0 ), + mpEditSource( NULL ), + maEEOffset( 0, 0 ), + mxParent( rParent ), + maStateListeners( maMutex ) + { + } + + AccessibleImageBullet::~AccessibleImageBullet() + { + } + + uno::Any SAL_CALL AccessibleImageBullet::queryInterface (const uno::Type & rType) throw (uno::RuntimeException) + { + return AccessibleImageBulletInterfaceBase::queryInterface(rType); + } + + uno::Reference< XAccessibleContext > SAL_CALL AccessibleImageBullet::getAccessibleContext( ) throw (uno::RuntimeException) + { + // We implement the XAccessibleContext interface in the same object + return uno::Reference< XAccessibleContext > ( this ); + } + + sal_Int32 SAL_CALL AccessibleImageBullet::getAccessibleChildCount() throw (uno::RuntimeException) + { + return 0; + } + + uno::Reference< XAccessible > SAL_CALL AccessibleImageBullet::getAccessibleChild( sal_Int32 i ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) + { + throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("No childs available")), + uno::Reference< uno::XInterface > + ( static_cast< ::cppu::OWeakObject* > (this) ) ); // static_cast: disambiguate hierarchy + } + + uno::Reference< XAccessible > SAL_CALL AccessibleImageBullet::getAccessibleParent() throw (uno::RuntimeException) + { + return mxParent; + } + + sal_Int32 SAL_CALL AccessibleImageBullet::getAccessibleIndexInParent() throw (uno::RuntimeException) + { + return mnIndexInParent; + } + + sal_Int16 SAL_CALL AccessibleImageBullet::getAccessibleRole() throw (uno::RuntimeException) + { + // TODO + return AccessibleRole::GRAPHIC; + } + + ::rtl::OUString SAL_CALL AccessibleImageBullet::getAccessibleDescription() throw (uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + ::rtl::OUString aStr( RTL_CONSTASCII_USTRINGPARAM("Image bullet in paragraph ") ); + + aStr += ::rtl::OUString::valueOf( GetParagraphIndex() ); + + return aStr; + } + + ::rtl::OUString SAL_CALL AccessibleImageBullet::getAccessibleName() throw (uno::RuntimeException) + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Image bullet") ); + } + + uno::Reference< XAccessibleRelationSet > SAL_CALL AccessibleImageBullet::getAccessibleRelationSet() throw (uno::RuntimeException) + { + // no relations, therefore empty + return uno::Reference< XAccessibleRelationSet >(); + } + + uno::Reference< XAccessibleStateSet > SAL_CALL AccessibleImageBullet::getAccessibleStateSet() throw (uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + utl::AccessibleStateSetHelper* aStateSet = new utl::AccessibleStateSetHelper(); + uno::Reference< XAccessibleStateSet > xStateSet( static_cast< cppu::OWeakObject* > (aStateSet), uno::UNO_QUERY ); + + // are we defunc? + if( !mpEditSource ) + { + aStateSet->AddState( AccessibleStateType::DEFUNC ); + aStateSet->AddState( AccessibleStateType::INVALID ); + } + + // are we visible? + if( IsVisible() ) + { + aStateSet->AddState( AccessibleStateType::SHOWING ); + aStateSet->AddState( AccessibleStateType::VISIBLE ); + } + + return xStateSet; + } + + lang::Locale SAL_CALL AccessibleImageBullet::getLocale() throw (IllegalAccessibleComponentStateException, uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + lang::Locale aLocale; + + DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, + "AccessibleImageBullet::getLocale: paragraph index value overflow"); + + // return locale of first character in the paragraph + return SvxLanguageToLocale(aLocale, GetTextForwarder().GetLanguage( static_cast< USHORT >( GetParagraphIndex() ), 0 )); + } + + void SAL_CALL AccessibleImageBullet::addEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException) + { + maStateListeners.addInterface( xListener ); + } + + void SAL_CALL AccessibleImageBullet::removeEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException) + { + maStateListeners.removeInterface( xListener ); + } + + sal_Bool SAL_CALL AccessibleImageBullet::contains( const awt::Point& rPoint ) throw (uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, + "AccessibleEditableTextPara::contains: index value overflow"); + + awt::Rectangle aTmpRect = getBounds(); + Rectangle aRect( Point(aTmpRect.X, aTmpRect.Y), Size(aTmpRect.Width, aTmpRect.Height) ); + Point aPoint( rPoint.X, rPoint.Y ); + + return aRect.IsInside( aPoint ); + } + + uno::Reference< XAccessible > SAL_CALL AccessibleImageBullet::getAccessibleAt( const awt::Point& aPoint ) throw (uno::RuntimeException) + { + // as we have no children, empty reference + return uno::Reference< XAccessible >(); + } + + awt::Rectangle SAL_CALL AccessibleImageBullet::getBounds( ) throw (uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, + "AccessibleEditableTextPara::getBounds: index value overflow"); + + SvxTextForwarder& rCacheTF = GetTextForwarder(); + EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( static_cast< USHORT > (GetParagraphIndex()) ); + + if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && + aBulletInfo.bVisible && + aBulletInfo.nType == SVX_NUM_BITMAP ) + { + Rectangle aRect = aBulletInfo.aBounds; + + // convert to screen coordinates + Rectangle aScreenRect = AccessibleEditableTextPara::LogicToPixel( aRect, + rCacheTF.GetMapMode(), + GetViewForwarder() ); + + // offset from shape/cell + Point aOffset = GetEEOffset(); + + return awt::Rectangle( aScreenRect.Left() + aOffset.X(), + aScreenRect.Top() + aOffset.Y(), + aScreenRect.GetSize().Width(), + aScreenRect.GetSize().Height() ); + } + + return awt::Rectangle(); + } + + awt::Point SAL_CALL AccessibleImageBullet::getLocation( ) throw (uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + awt::Rectangle aRect = getBounds(); + + return awt::Point( aRect.X, aRect.Y ); + } + + awt::Point SAL_CALL AccessibleImageBullet::getLocationOnScreen( ) throw (uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + // relate us to parent + uno::Reference< XAccessible > xParent = getAccessibleParent(); + if( xParent.is() ) + { + uno::Reference< XAccessibleComponent > xParentComponent( xParent, uno::UNO_QUERY ); + if( xParentComponent.is() ) + { + awt::Point aRefPoint = xParentComponent->getLocationOnScreen(); + awt::Point aPoint = getLocation(); + aPoint.X += aRefPoint.X; + aPoint.Y += aRefPoint.Y; + + return aPoint; + } + } + + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Cannot access parent")), + uno::Reference< uno::XInterface > + ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy + } + + awt::Size SAL_CALL AccessibleImageBullet::getSize( ) throw (uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + awt::Rectangle aRect = getBounds(); + + return awt::Size( aRect.Width, aRect.Height ); + } + + sal_Bool SAL_CALL AccessibleImageBullet::isShowing( ) throw (uno::RuntimeException) + { + return IsVisible(); + } + + sal_Bool SAL_CALL AccessibleImageBullet::isVisible( ) throw (uno::RuntimeException) + { + return IsVisible(); + } + + sal_Bool SAL_CALL AccessibleImageBullet::isFocusTraversable( ) throw (uno::RuntimeException) + { + return sal_False; + } + + void SAL_CALL AccessibleImageBullet::addFocusListener( const uno::Reference< awt::XFocusListener >& xListener ) throw (uno::RuntimeException) + { + // TODO: remove + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Not focusable")), + uno::Reference< uno::XInterface > + ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy + } + + void SAL_CALL AccessibleImageBullet::removeFocusListener( const uno::Reference< awt::XFocusListener >& xListener ) throw (uno::RuntimeException) + { + // TODO: remove + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Not focusable")), + uno::Reference< uno::XInterface > + ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy + } + + void SAL_CALL AccessibleImageBullet::grabFocus( ) throw (uno::RuntimeException) + { + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Not focusable")), + uno::Reference< uno::XInterface > + ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy + } + + uno::Any SAL_CALL AccessibleImageBullet::getAccessibleKeyBinding( ) throw (uno::RuntimeException) + { + // AFAIK, none. + return uno::Any(); + } + + ::rtl::OUString SAL_CALL AccessibleImageBullet::getImplementationName (void) throw (uno::RuntimeException) + { + return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("AccessibleImageBullet")); + } + + sal_Bool SAL_CALL AccessibleImageBullet::supportsService (const ::rtl::OUString& sServiceName) throw (uno::RuntimeException) + { + // Iterate over all supported service names and return true if on of them + // matches the given name. + uno::Sequence< ::rtl::OUString> aSupportedServices ( + getSupportedServiceNames ()); + for (int i=0; i<aSupportedServices.getLength(); i++) + if (sServiceName == aSupportedServices[i]) + return sal_True; + return sal_False; + } + + uno::Sequence< ::rtl::OUString> SAL_CALL AccessibleImageBullet::getSupportedServiceNames (void) throw (uno::RuntimeException) + { + const ::rtl::OUString sServiceName (RTL_CONSTASCII_USTRINGPARAM ("drafts.com.sun.star.accessibility.AccessibleContext")); + return uno::Sequence< ::rtl::OUString > (&sServiceName, 1); + } + + ::rtl::OUString SAL_CALL AccessibleImageBullet::getServiceName (void) throw (uno::RuntimeException) + { + return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("drafts.com.sun.star.accessibility.AccessibleContext")); + } + + void AccessibleImageBullet::SetIndexInParent( sal_Int32 nIndex ) + { + mnIndexInParent = nIndex; + } + + sal_Int32 AccessibleImageBullet::GetIndexInParent() const + { + return mnIndexInParent; + } + + void AccessibleImageBullet::SetEEOffset( const Point& rOffset ) + { + maEEOffset = rOffset; + } + + void AccessibleImageBullet::SetEditSource( SvxEditSource* pEditSource ) + { + mpEditSource = pEditSource; + + if( !mpEditSource ) + { + // going defunc + FireEvent( AccessibleEventId::ACCESSIBLE_STATE_EVENT ); + + try + { + uno::Reference < XAccessibleContext > xThis = getAccessibleContext(); + + lang::EventObject aEvent (xThis); + maStateListeners.disposeAndClear( aEvent ); + } + catch( const uno::RuntimeException& ) {} + } + } + + void AccessibleImageBullet::FireEvent(const sal_Int16 nEventId, const uno::Any& rNewValue, const uno::Any& rOldValue ) const + { + uno::Reference < XAccessibleContext > xThis( const_cast< AccessibleImageBullet* > (this)->getAccessibleContext() ); + + AccessibleEventObject aEvent(xThis, nEventId, rNewValue, rOldValue); + + // no locking necessary, OInterfaceIteratorHelper copies listeners if someone removes/adds in between + ::cppu::OInterfaceIteratorHelper aIter( const_cast< AccessibleImageBullet* >(this)->maStateListeners ); + while( aIter.hasMoreElements() ) + { + uno::Reference < XAccessibleEventListener > xListener( aIter.next(), uno::UNO_QUERY ); + + if( xListener.is() ) + { + try + { + xListener->notifyEvent( aEvent ); + } + catch( const uno::RuntimeException& ) + { +#ifdef DBG_UTIL + DBG_ERROR("AccessibleImageBullet::FireEvent: Caught runtime exception from listener, removing object (bridge/listener dead?)"); +#endif + } + } + } + } + + void AccessibleImageBullet::GotPropertyEvent( const uno::Any& rNewValue, const sal_Int16 nEventId ) const + { + FireEvent( nEventId, rNewValue ); + } + + void AccessibleImageBullet::LostPropertyEvent( const uno::Any& rOldValue, const sal_Int16 nEventId ) const + { + FireEvent( nEventId, uno::Any(), rOldValue ); + } + + sal_Bool AccessibleImageBullet::IsVisible() const + { + return mpEditSource ? sal_True : sal_False ; + } + + void AccessibleImageBullet::SetParagraphIndex( sal_Int32 nIndex ) + { + sal_Int32 nOldIndex = mnParagraphIndex; + + if( nOldIndex != nIndex ) + { + // index and therefore description changed + LostPropertyEvent( uno::makeAny( getAccessibleDescription() ), AccessibleEventId::ACCESSIBLE_DESCRIPTION_EVENT ); + LostPropertyEvent( uno::makeAny( getAccessibleName() ), AccessibleEventId::ACCESSIBLE_NAME_EVENT ); + } + + mnParagraphIndex = nIndex; + + if( nOldIndex != nIndex ) + { + // index and therefore description changed + GotPropertyEvent( uno::makeAny( getAccessibleDescription() ), AccessibleEventId::ACCESSIBLE_DESCRIPTION_EVENT ); + GotPropertyEvent( uno::makeAny( getAccessibleName() ), AccessibleEventId::ACCESSIBLE_NAME_EVENT ); + } + } + + sal_Int32 AccessibleImageBullet::GetParagraphIndex() const throw (uno::RuntimeException) + { + return mnParagraphIndex; + } + + SvxEditSource& AccessibleImageBullet::GetEditSource() const throw (uno::RuntimeException) + { + if( mpEditSource ) + return *mpEditSource; + else + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("No edit source, object is defunct")), + uno::Reference< uno::XInterface > + ( static_cast< ::cppu::OWeakObject* > + ( const_cast< AccessibleImageBullet* > (this) ) ) ); // disambiguate hierarchy + } + + SvxTextForwarder& AccessibleImageBullet::GetTextForwarder() const throw (uno::RuntimeException) + { + SvxEditSource& rEditSource = GetEditSource(); + SvxTextForwarder* pTextForwarder = rEditSource.GetTextForwarder(); + + if( !pTextForwarder ) + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch text forwarder, object is defunct")), + uno::Reference< uno::XInterface > + ( static_cast< ::cppu::OWeakObject* > + ( const_cast< AccessibleImageBullet* > (this) ) ) ); // disambiguate hierarchy + + if( pTextForwarder->IsValid() ) + return *pTextForwarder; + else + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Text forwarder is invalid, object is defunct")), + uno::Reference< uno::XInterface > + ( static_cast< ::cppu::OWeakObject* > + ( const_cast< AccessibleImageBullet* > (this) ) ) ); // disambiguate hierarchy + } + + SvxViewForwarder& AccessibleImageBullet::GetViewForwarder() const throw (uno::RuntimeException) + { + SvxEditSource& rEditSource = GetEditSource(); + SvxViewForwarder* pViewForwarder = rEditSource.GetViewForwarder(); + + if( !pViewForwarder ) + { + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch view forwarder, object is defunct")), + uno::Reference< uno::XInterface > + ( static_cast< ::cppu::OWeakObject* > + ( const_cast< AccessibleImageBullet* > (this) ) ) ); // disambiguate hierarchy + } + + if( pViewForwarder->IsValid() ) + return *pViewForwarder; + else + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("View forwarder is invalid, object is defunct")), + uno::Reference< uno::XInterface > + ( static_cast< ::cppu::OWeakObject* > + ( const_cast< AccessibleImageBullet* > (this) ) ) ); // disambiguate hierarchy + } + + const Point& AccessibleImageBullet::GetEEOffset() const + { + return maEEOffset; + } + +} // end of namespace accessibility + diff --git a/svx/source/accessibility/AccessibleImageBullet.hxx b/svx/source/accessibility/AccessibleImageBullet.hxx new file mode 100644 index 000000000000..bd5d882bd1f3 --- /dev/null +++ b/svx/source/accessibility/AccessibleImageBullet.hxx @@ -0,0 +1,304 @@ +/************************************************************************* + * + * $RCSfile: AccessibleImageBullet.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: thb $ $Date: 2002-05-16 16:10:25 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _SVX_ACCESSIBLE_IMAGE_BULLET_HXX +#define _SVX_ACCESSIBLE_IMAGE_BULLET_HXX + +#ifndef _SV_GEN_HXX +#include <tools/gen.hxx> +#endif + +#ifndef _CPPUHELPER_WEAKREF_HXX_ +#include <cppuhelper/weakref.hxx> +#endif + +#ifndef _CPPUHELPER_IMPLBASE5_HXX_ +#include <cppuhelper/implbase5.hxx> +#endif + +#ifndef _CPPUHELPER_INTERFACECONTAINER_H_ +#include <cppuhelper/interfacecontainer.hxx> +#endif + +#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_ +#include <com/sun/star/uno/Reference.hxx> +#endif + +#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_ +#include <com/sun/star/lang/XServiceInfo.hpp> +#endif + +#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLE_HPP_ +#include <drafts/com/sun/star/accessibility/XAccessible.hpp> +#endif + +#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLECONTEXT_HPP_ +#include <drafts/com/sun/star/accessibility/XAccessibleContext.hpp> +#endif + +#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLECOMPONENT_HPP_ +#include <drafts/com/sun/star/accessibility/XAccessibleComponent.hpp> +#endif + +#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEEVENTBROADCASTER_HPP_ +#include <drafts/com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> +#endif + +#ifndef _SVX_ACCESSIBLE_PARA_MANAGER_HXX +#include "AccessibleParaManager.hxx" +#endif + +#ifndef _SVX_UNOEDSRC_HXX +#include "unoedsrc.hxx" +#endif + +namespace accessibility +{ + + typedef ::cppu::WeakImplHelper5< ::drafts::com::sun::star::accessibility::XAccessible, + ::drafts::com::sun::star::accessibility::XAccessibleContext, + ::drafts::com::sun::star::accessibility::XAccessibleComponent, + ::drafts::com::sun::star::accessibility::XAccessibleEventBroadcaster, + ::com::sun::star::lang::XServiceInfo > AccessibleImageBulletInterfaceBase; + + /** This class implements the image bullets for the EditEngine/Outliner UAA + */ + class AccessibleImageBullet : public AccessibleImageBulletInterfaceBase + { + + public: + /// Create accessible object for given parent + AccessibleImageBullet ( const ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessible >& rParent ); + + virtual ~AccessibleImageBullet (); + + // XInterface + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface (const ::com::sun::star::uno::Type & rType) throw (::com::sun::star::uno::RuntimeException); + + // XAccessible + virtual ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) throw (::com::sun::star::uno::RuntimeException); + + // XAccessibleContext + virtual sal_Int32 SAL_CALL getAccessibleChildCount() throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleParent() throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getAccessibleIndexInParent() throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int16 SAL_CALL getAccessibleRole() throw (::com::sun::star::uno::RuntimeException); + /// Maximal length of text returned by getAccessibleDescription() + enum { MaxDescriptionLen = 40 }; + virtual ::rtl::OUString SAL_CALL getAccessibleDescription() throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getAccessibleName() throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet() throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet() throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::lang::Locale SAL_CALL getLocale() throw (::drafts::com::sun::star::accessibility::IllegalAccessibleComponentStateException, ::com::sun::star::uno::RuntimeException); + + // XAccessibleEventBroadcaster + virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + + // XAccessibleComponent + virtual sal_Bool SAL_CALL contains( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleAt( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Rectangle SAL_CALL getBounds( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Point SAL_CALL getLocation( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Point SAL_CALL getLocationOnScreen( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Size SAL_CALL getSize( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isShowing( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isVisible( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isFocusTraversable( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addFocusListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFocusListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeFocusListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFocusListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL grabFocus( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getAccessibleKeyBinding( ) throw (::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName (void) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService (const ::rtl::OUString& sServiceName) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL getSupportedServiceNames (void) throw (::com::sun::star::uno::RuntimeException); + + // XServiceName + virtual ::rtl::OUString SAL_CALL getServiceName (void) throw (::com::sun::star::uno::RuntimeException); + + /** Set the current index in the accessibility parent + + @attention This method does not lock the SolarMutex, + leaving that to the calling code. This is because only + there potential deadlock situations can be resolved. Thus, + make sure SolarMutex is locked when calling this. + */ + void SetIndexInParent( sal_Int32 nIndex ); + + /** Get the current index in the accessibility parent + + @attention This method does not lock the SolarMutex, + leaving that to the calling code. This is because only + there potential deadlock situations can be resolved. Thus, + make sure SolarMutex is locked when calling this. + */ + sal_Int32 GetIndexInParent() const; + + /** Set the edit engine offset + + @attention This method does not lock the SolarMutex, + leaving that to the calling code. This is because only + there potential deadlock situations can be resolved. Thus, + make sure SolarMutex is locked when calling this. + */ + void SetEEOffset( const Point& rOffset ); + + /** Set the EditEngine offset + + @attention This method does not lock the SolarMutex, + leaving that to the calling code. This is because only + there potential deadlock situations can be resolved. Thus, + make sure SolarMutex is locked when calling this. + */ + void SetEditSource( SvxEditSource* pEditSource ); + + /** Set the current paragraph number + + @attention This method does not lock the SolarMutex, + leaving that to the calling code. This is because only + there potential deadlock situations can be resolved. Thus, + make sure SolarMutex is locked when calling this. + */ + void SetParagraphIndex( sal_Int32 nIndex ); + + /** Query the current paragraph number (0 - nParas-1) + + @attention This method does not lock the SolarMutex, + leaving that to the calling code. This is because only + there potential deadlock situations can be resolved. Thus, + make sure SolarMutex is locked when calling this. + */ + sal_Int32 GetParagraphIndex() const throw (::com::sun::star::uno::RuntimeException); + + /// Calls all Listener objects to tell them the change. Don't hold locks when calling this! + virtual void FireEvent(const sal_Int16 nEventId, const ::com::sun::star::uno::Any& rNewValue = ::com::sun::star::uno::Any(), const ::com::sun::star::uno::Any& rOldValue = ::com::sun::star::uno::Any() ) const; + + private: + + // declared, but not defined + AccessibleImageBullet( const AccessibleImageBullet& ); + AccessibleImageBullet& operator= ( const AccessibleImageBullet& ); + + // syntactic sugar for FireEvent + void GotPropertyEvent( const ::com::sun::star::uno::Any& rNewValue, const sal_Int16 nEventId ) const; + void LostPropertyEvent( const ::com::sun::star::uno::Any& rOldValue, const sal_Int16 nEventId ) const; + + /** Query the visibility state + + @attention This method does not lock the SolarMutex, + leaving that to the calling code. This is because only + there potential deadlock situations can be resolved. Thus, + make sure SolarMutex is locked when calling this. + + @return the visibility state. Per definition, a defunc object is no longer visible + */ + sal_Bool IsVisible() const; + + SvxEditSource& GetEditSource() const throw (::com::sun::star::uno::RuntimeException); + + /** Query the SvxTextForwarder for EditEngine access. + + @attention This method does not lock the SolarMutex, + leaving that to the calling code. This is because only + there potential deadlock situations can be resolved. Thus, + make sure SolarMutex is locked when calling this. + */ + SvxTextForwarder& GetTextForwarder() const throw (::com::sun::star::uno::RuntimeException); + + /** Query the SvxViewForwarder for EditEngine access. + + @attention This method does not lock the SolarMutex, + leaving that to the calling code. This is because only + there potential deadlock situations can be resolved. Thus, + make sure SolarMutex is locked when calling this. + */ + SvxViewForwarder& GetViewForwarder() const throw (::com::sun::star::uno::RuntimeException); + + const Point& GetEEOffset() const; + + // the paragraph index in the edit engine (guarded by solar mutex) + sal_Int32 mnParagraphIndex; + + // our current index in the parent (guarded by solar mutex) + sal_Int32 mnIndexInParent; + + // the current edit source (guarded by solar mutex) + SvxEditSource* mpEditSource; + + // the offset of the underlying EditEngine from the shape/cell (guarded by solar mutex) + Point maEEOffset; + + mutable osl::Mutex maMutex; + + /// The shape we're the accessible for (unguarded) + ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessible > mxParent; + + /// Our listeners (guarded by maMutex) + ::cppu::OInterfaceContainerHelper maStateListeners; + }; + +} // end of namespace accessibility + +#endif + diff --git a/svx/source/accessibility/AccessibleParaManager.cxx b/svx/source/accessibility/AccessibleParaManager.cxx new file mode 100644 index 000000000000..0a6db1175de3 --- /dev/null +++ b/svx/source/accessibility/AccessibleParaManager.cxx @@ -0,0 +1,306 @@ +/************************************************************************* + * + * $RCSfile: AccessibleParaManager.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: thb $ $Date: 2002-05-16 16:10:49 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#pragma hdrstop + +//------------------------------------------------------------------------ +// +// Global header +// +//------------------------------------------------------------------------ + +#ifndef _COM_SUN_STAR_UNO_ANY_HXX_ +#include <com/sun/star/uno/Any.hxx> +#endif + +#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_ +#include <com/sun/star/uno/Reference.hxx> +#endif + +#ifndef _CPPUHELPER_WEAKREF_HXX_ +#include <cppuhelper/weakref.hxx> +#endif + +#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLE_HPP_ +#include <drafts/com/sun/star/accessibility/XAccessible.hpp> +#endif + +//------------------------------------------------------------------------ +// +// Project-local header +// +//------------------------------------------------------------------------ + +#include "unoedhlp.hxx" +#include "unopracc.hxx" +#include "unoedsrc.hxx" +#include "AccessibleParaManager.hxx" +#include "AccessibleEditableTextPara.hxx" + + +using namespace ::com::sun::star; +using namespace ::drafts::com::sun::star::accessibility; + + + +namespace accessibility +{ + AccessibleParaManager::AccessibleParaManager() + { + } + + AccessibleParaManager::~AccessibleParaManager() + { + // owner is responsible for possible child defuncs + } + + void AccessibleParaManager::SetNum( sal_Int32 nNumParas ) + { + maChildren.resize( nNumParas ); + } + + 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_Int32 nPara ) + { + ShutdownPara( maChildren[ nPara ] ); + + // clear reference and rect + maChildren[ nPara ] = WeakChild(); + } + + void AccessibleParaManager::FireEvent( sal_Int32 nPara, + const sal_Int16 nEventId, + const uno::Any& rNewValue, + const uno::Any& rOldValue ) const + { + WeakPara::HardRefType maChild( maChildren[ 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_Int32 nChild ) const + { + // retrieve hard reference from weak one + return IsReferencable( maChildren[ nChild ].first.get() ); + } + + AccessibleParaManager::Child AccessibleParaManager::GetChild( sal_Int32 nChild, + const uno::Reference< XAccessible >& xFrontEnd, + SvxEditSourceAdapter& rEditSource, + sal_Int32 nParagraphIndex ) + { + // retrieve hard reference from weak one + WeakPara::HardRefType aChild( maChildren[ nChild ].first.get() ); + + if( !IsReferencable( nChild ) ) + { + // there is no hard reference available, create object then + AccessibleEditableTextPara* pChild = new AccessibleEditableTextPara( xFrontEnd ); + 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 ); + + aChild->SetEditSource( &rEditSource ); + aChild->SetIndexInParent( nChild ); + aChild->SetParagraphIndex( nParagraphIndex ); + + maChildren[ nChild ] = WeakChild( aChild, pChild->getBounds() ); + } + + return Child( aChild.getRef(), maChildren[ nChild ].second ); + } + + // TODO: refactor these functors to a single template + class SetChildrenEEOffset : public ::std::unary_function< accessibility::AccessibleEditableTextPara&, void > + { + public: + SetChildrenEEOffset( const Point& rOffset ) : mrOffset( rOffset ) {} + void operator()( accessibility::AccessibleEditableTextPara& rPara ) + { + rPara.SetEEOffset( mrOffset ); + } + + private: + const Point& mrOffset; + }; + + void AccessibleParaManager::SetEEOffset( const Point& rOffset ) + { + ForEach( SetChildrenEEOffset( rOffset ) ); + } + + // TODO: refactor these functors to a single template + class SetChildrenEditSource : public ::std::unary_function< accessibility::AccessibleEditableTextPara&, void > + { + public: + SetChildrenEditSource( SvxEditSourceAdapter* pEditSource ) : mpEditSource( pEditSource ) {} + void operator()( accessibility::AccessibleEditableTextPara& rPara ) + { + rPara.SetEditSource( mpEditSource ); + } + + private: + SvxEditSourceAdapter* mpEditSource; + }; + + void AccessibleParaManager::SetEditSource( SvxEditSourceAdapter* pEditSource ) + { + ForEach( SetChildrenEditSource( pEditSource ) ); + } + + // TODO: refactor these functors to a single template (EffSTL or MExC++) + 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_Int32 nStartPara, + sal_Int32 nEndPara, + const sal_Int16 nEventId, + const uno::Any& rNewValue, + const uno::Any& rOldValue ) const + { + VectorOfChildren::const_iterator begin = maChildren.begin(); + VectorOfChildren::const_iterator end = begin; + + ::std::advance< VectorOfChildren::const_iterator, sal_Int32 >( begin, nStartPara ); + ::std::advance< VectorOfChildren::const_iterator, sal_Int32 >( end, nEndPara ); + + ::std::for_each( begin, end, AccessibleParaManager::WeakChildAdapter< StateChangeEvent > (StateChangeEvent( nEventId, rNewValue, rOldValue )) ); + } + + 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_Int32 nStartPara, sal_Int32 nEndPara ) + { + VectorOfChildren::iterator begin = maChildren.begin(); + VectorOfChildren::iterator end = begin; + + ::std::advance< VectorOfChildren::iterator, sal_Int32 >( begin, nStartPara ); + ::std::advance< VectorOfChildren::iterator, sal_Int32 >( end, nEndPara ); + + ::std::transform( begin, end, begin, ReleaseChild() ); + } + + void AccessibleParaManager::ShutdownPara( const WeakChild& rChild ) + { + WeakPara::HardRefType aChild( rChild.first.get() ); + + if( IsReferencable( aChild ) ) + aChild->SetEditSource( NULL ); + } + +} + +//------------------------------------------------------------------------ diff --git a/svx/source/accessibility/AccessibleParaManager.hxx b/svx/source/accessibility/AccessibleParaManager.hxx new file mode 100644 index 000000000000..1a6aa59733b9 --- /dev/null +++ b/svx/source/accessibility/AccessibleParaManager.hxx @@ -0,0 +1,276 @@ +/************************************************************************* + * + * $RCSfile: AccessibleParaManager.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: thb $ $Date: 2002-05-16 16:10:41 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _SVX_ACCESSIBLE_PARA_MANAGER_HXX +#define _SVX_ACCESSIBLE_PARA_MANAGER_HXX + +#include <vector> +#include <algorithm> +#include <functional> +#include <utility> + +#ifndef _SV_GEN_HXX +#include <tools/gen.hxx> +#endif + +#ifndef _COM_SUN_STAR_AWT_RECTANGLE_HPP_ +#include <com/sun/star/awt/Rectangle.hpp> +#endif + +#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_ +#include <com/sun/star/uno/Reference.hxx> +#endif +#ifndef _CPPUHELPER_WEAKREF_HXX_ +#include <cppuhelper/weakref.hxx> +#endif + +#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLECONTEXT_HPP_ +#include <drafts/com/sun/star/accessibility/XAccessibleContext.hpp> +#endif + +class SvxEditSourceAdapter; + +namespace accessibility +{ + class AccessibleEditableTextPara; + + /** Helper class for WeakCppRef + + This class is returned by WeakChild::get() and contains a hard + reference and a reference to the c++ object. This combination + prevents the c++ object from destruction during usage. Hold + this object only as long as absolutely necessary, prevents + referenced object from vanishing otherwise + */ + template < class UnoType, class CppType > class HardCppRef + { + public: + + typedef UnoType UnoInterfaceType; + typedef CppType InterfaceType; + + HardCppRef( const ::com::sun::star::uno::WeakReference< UnoInterfaceType >& xRef, InterfaceType* rImpl ) : + mxRef( xRef ), + mpImpl( rImpl ) + { + } + + /** Query whether the reference is still valid. + + Hands off also from the implementation pointer if this + returns sal_False! + */ + sal_Bool is() const { return mxRef.is(); } + InterfaceType* operator->() const { return mpImpl; } + InterfaceType& operator*() const { return *mpImpl; } + ::com::sun::star::uno::Reference< UnoInterfaceType >& getRef() { return mxRef; } + const ::com::sun::star::uno::Reference< UnoInterfaceType >& getRef() const { return mxRef; } + + // default copy constructor and assignment will do + // HardCppRef( const HardCppRef& ); + // HardCppRef& operator= ( const HardCppRef& ); + + private: + + // the interface, hard reference to prevent object from vanishing + ::com::sun::star::uno::Reference< UnoInterfaceType > mxRef; + + // the c++ object, for our internal stuff + InterfaceType* mpImpl; + + }; + + /** Helper class for weak object references plus implementation + + This class combines a weak reference (to facilitate automatic + object disposal if user drops last reference) and hard + reference to the c++ class (for fast access and bypassing of + the UNO interface) + */ + template < class UnoType, class CppType > class WeakCppRef + { + public: + + typedef UnoType UnoInterfaceType; + typedef CppType InterfaceType; + typedef HardCppRef< UnoInterfaceType, InterfaceType > HardRefType; + + WeakCppRef() : maWeakRef(), maUnsafeRef( NULL ) {} + WeakCppRef( InterfaceType& rImpl ) : + maWeakRef( ::com::sun::star::uno::Reference< UnoInterfaceType >( rImpl, uno::UNO_QUERY ) ), + maUnsafeRef( &rImpl ) + { + } + + WeakCppRef( HardRefType& rImpl ) : + maWeakRef( rImpl.getRef() ), + maUnsafeRef( rImpl.operator->() ) + { + } + + // get object with c++ object and hard reference (which + // prevents the c++ object from destruction during use) + HardRefType get() const { return HardRefType( maWeakRef, maUnsafeRef ); } + + // default copy constructor and assignment will do + // WeakCppRef( const WeakCppRef& ); + // WeakCppRef& operator= ( const WeakCppRef& ); + + private: + + // the interface, hold weakly + ::com::sun::star::uno::WeakReference< UnoInterfaceType > maWeakRef; + + // hard ref to c++ class, _only_ valid if maWeakRef.is() is true + InterfaceType* maUnsafeRef; + }; + + + /** This class manages the paragraphs of an AccessibleTextHelper + + To facilitate automatic deletion of paragraphs no longer used, + this class uses the WeakCppRef helper to hold the objects weakly. + */ + class AccessibleParaManager + { + public: + typedef WeakCppRef < ::drafts::com::sun::star::accessibility::XAccessible, AccessibleEditableTextPara > WeakPara; + typedef ::std::pair< WeakPara, ::com::sun::star::awt::Rectangle > WeakChild; + typedef ::std::pair< ::com::sun::star::uno::Reference< + ::drafts::com::sun::star::accessibility::XAccessible > , ::com::sun::star::awt::Rectangle > Child; + typedef ::std::vector< WeakChild > VectorOfChildren; + + AccessibleParaManager(); + ~AccessibleParaManager(); + + // changing the state of the AccessibleParaManager itself + void SetNum( sal_Int32 nNumParas ); + + // iterators + VectorOfChildren::iterator begin(); + VectorOfChildren::iterator end(); + VectorOfChildren::const_iterator begin() const; + VectorOfChildren::const_iterator end() const; + + // dealing with single paragraphs (release reference, return reference etc) + void Release( sal_Int32 nPara ); + void FireEvent( sal_Int32 nPara, + const sal_Int16 nEventId, + const ::com::sun::star::uno::Any& rNewValue = ::com::sun::star::uno::Any(), + const ::com::sun::star::uno::Any& rOldValue = ::com::sun::star::uno::Any() ) const; + + static sal_Bool IsReferencable( WeakPara::HardRefType aChild ); + sal_Bool IsReferencable( sal_Int32 nChild ) const; + static void ShutdownPara( const WeakChild& rChild ); + + Child GetChild( sal_Int32 nChild, + const ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessible >& xFrontEnd, + SvxEditSourceAdapter& rEditSource, + sal_Int32 nParagraphIndex ); + + // forwarder to all paragraphs + void SetEEOffset ( const Point& rOffset ); + void SetEditSource ( SvxEditSourceAdapter* pEditSource ); + + // forwarder to given paragraphs + void Release( sal_Int32 nStartPara, sal_Int32 nEndPara ); + void FireEvent( sal_Int32 nStartPara, + sal_Int32 nEndPara, + const sal_Int16 nEventId, + const ::com::sun::star::uno::Any& rNewValue = ::com::sun::star::uno::Any(), + const ::com::sun::star::uno::Any& rOldValue = ::com::sun::star::uno::Any() ) const; + + // functor adapter for ForEach template, accessing only the + // paragraph object and hiding the fact that our children are + // held weakly + template < typename Functor > class WeakChildAdapter : public ::std::unary_function< const WeakChild&, void > + { + public: + WeakChildAdapter( Functor& rFunctor ) : mrFunctor(rFunctor) {} + void operator()( const WeakChild& rPara ) + { + // retrieve hard reference from weak one + WeakPara::HardRefType aHardRef( rPara.first.get() ); + + if( aHardRef.is() ) + mrFunctor( *aHardRef ); + } + + private: + Functor& mrFunctor; + }; + + // generic algorithm on given paragraphs (non-mutating, i.e. the + // original vector is unchanged). convenience. + template < typename Functor > void ForEach( Functor& rFunctor ) + { + ::std::for_each( begin(), end(), WeakChildAdapter< Functor >(rFunctor) ); + } + + private: + // vector the size of the paragraph number of the underlying EditEngine + VectorOfChildren maChildren; + }; + +} // end of namespace accessibility + +#endif + diff --git a/svx/source/accessibility/AccessibleTextHelper.cxx b/svx/source/accessibility/AccessibleTextHelper.cxx new file mode 100644 index 000000000000..012b42c8c4cb --- /dev/null +++ b/svx/source/accessibility/AccessibleTextHelper.cxx @@ -0,0 +1,1204 @@ +/************************************************************************* + * + * $RCSfile: AccessibleTextHelper.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: thb $ $Date: 2002-05-16 16:10:57 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#pragma hdrstop + +//------------------------------------------------------------------------ +// +// Global header +// +//------------------------------------------------------------------------ + +#include <limits.h> +#include <memory> +#include <algorithm> + +#ifndef _VOS_MUTEX_HXX_ +#include <vos/mutex.hxx> +#endif + +#ifndef _COM_SUN_STAR_UNO_ANY_HXX_ +#include <com/sun/star/uno/Any.hxx> +#endif + +#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_ +#include <com/sun/star/uno/Reference.hxx> +#endif + +#ifndef _CPPUHELPER_WEAKREF_HXX_ +#include <cppuhelper/weakref.hxx> +#endif + +#ifndef _COM_SUN_STAR_AWT_POINT_HPP_ +#include <com/sun/star/awt/Point.hpp> +#endif + +#ifndef _COM_SUN_STAR_AWT_RECTANGLE_HPP_ +#include <com/sun/star/awt/Rectangle.hpp> +#endif + +#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLEEVENTID_HPP_ +#include <drafts/com/sun/star/accessibility/AccessibleEventId.hpp> +#endif + +#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLE_HPP_ +#include <drafts/com/sun/star/accessibility/XAccessible.hpp> +#endif + +#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLECONTEXT_HPP_ +#include <drafts/com/sun/star/accessibility/XAccessibleContext.hpp> +#endif + +#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLECOMPONENT_HPP_ +#include <drafts/com/sun/star/accessibility/XAccessibleComponent.hpp> +#endif + +#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLEROLE_HPP_ +#include <drafts/com/sun/star/accessibility/AccessibleRole.hpp> +#endif + +#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLETEXTTYPE_HPP_ +#include <drafts/com/sun/star/accessibility/AccessibleTextType.hpp> +#endif + +#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLETEXT_HPP_ +#include <drafts/com/sun/star/accessibility/XAccessibleText.hpp> +#endif + +#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEEDITABLETEXT_HPP_ +#include <drafts/com/sun/star/accessibility/XAccessibleEditableText.hpp> +#endif + +#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLESTATETYPE_HPP_ +#include <drafts/com/sun/star/accessibility/AccessibleStateType.hpp> +#endif + +#ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX_ +#include <unotools/accessiblestatesethelper.hxx> +#endif + + +//------------------------------------------------------------------------ +// +// Project-local header +// +//------------------------------------------------------------------------ + +#ifndef _SVX_UNOEDACC_HXX_ +#include "unoedacc.hxx" +#endif + +#ifndef _SVX_UNOSHAPE_HXX +#include "unoshape.hxx" +#endif + +#ifndef _UNO_LINGU_HXX +#include "unolingu.hxx" +#endif + +#ifndef _SVX_UNOTEXT_HXX +#include "unotext.hxx" +#endif + +#include "unoedhlp.hxx" +#include "unopracc.hxx" +#include "AccessibleParaManager.hxx" +#include "AccessibleEditableTextPara.hxx" +#include "svdmodel.hxx" +#include "svdpntv.hxx" +#include "editdata.hxx" +#include "editeng.hxx" +#include "editview.hxx" + +using namespace ::com::sun::star; +using namespace ::drafts::com::sun::star::accessibility; + + +//------------------------------------------------------------------------ +// +// SvxAccessibleTextHelper_Impl declaration +// +//------------------------------------------------------------------------ + +class SvxAccessibleTextHelper_Impl : public SfxListener +{ + +public: + + // receive pointer to our frontend class and view window + SvxAccessibleTextHelper_Impl( const uno::Reference< XAccessible >& rInterface ); + ~SvxAccessibleTextHelper_Impl(); + + // XAccessibleContext child handling methods + sal_Int32 SAL_CALL getAccessibleChildCount() throw (uno::RuntimeException); + uno::Reference< XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException); + + // XAccessibleEventBroadcaster child related methods + void SAL_CALL addEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException); + void SAL_CALL removeEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException); + + // XAccessibleComponent child related methods + uno::Reference< XAccessible > SAL_CALL getAccessibleAt( const awt::Point& aPoint ) throw (uno::RuntimeException); + + SvxEditSourceAdapter& GetEditSource() const throw (uno::RuntimeException); + void SetEditSource( ::std::auto_ptr< SvxEditSource > pEditSource ) throw (uno::RuntimeException); + + void SetOffset( const Point& ); + const Point& GetOffset() const { return maOffset; } // Strictly correct only with locked solar mutex! + + sal_Bool IsSelected() const; + + // do NOT hold object mutex when calling this! Danger of deadlock + void FireEvent( const sal_Int16 nEventId, const uno::Any& rNewValue = uno::Any(), const uno::Any& rOldValue = uno::Any() ) const; + +#ifdef DBG_UTIL + void CheckInvariants() const; +#endif + + // checks all children for visibility, throws away invisible ones + void UpdateVisibleChildren(); + +private: + + // syntactic sugar for FireEvent + void GotPropertyEvent( const uno::Any& rNewValue, const sal_Int16 nEventId ) const { FireEvent( nEventId, rNewValue ); } + void LostPropertyEvent( const uno::Any& rOldValue, const sal_Int16 nEventId ) const { FireEvent( nEventId, uno::Any(), rOldValue ); } + + // shutdown usage of current edit source on myself and the children. + void ShutdownEditSource() throw (uno::RuntimeException); + + virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ); + + // lock solar mutex before + SvxTextForwarder& GetTextForwarder() const throw (uno::RuntimeException); + // lock solar mutex before + SvxViewForwarder& GetViewForwarder() const throw (uno::RuntimeException); + // lock solar mutex before + SvxEditViewForwarder& GetEditViewForwarder( sal_Bool bCreate = sal_False ) const throw (uno::RuntimeException); + + // are we in edit mode? + sal_Bool IsActive() const throw (uno::RuntimeException); + + void UpdateVisibleData(); + + // calls SetSelection on the forwarder and updates maLastSelection + // cache. Caution: calls StateChangeEvent and sets object into + // edit mode! + void UpdateSelection( const ESelection& ); + + /// our current offset to the containing shape/cell (guarded by solar mutex) + Point maOffset; + + // our frontend class (the one implementing the actual + // interface). That's not necessarily the one containing the impl + // pointer! + const uno::Reference< XAccessible > mxFrontEnd; + + // a wrapper for the text forwarders (guarded by solar mutex) + mutable SvxEditSourceAdapter maEditSource; + + // store last selection (to correctly report selection changes, guarded by solar mutex) + ESelection maLastSelection; + + // cache range of visible children (guarded by solar mutex) + sal_Int32 mnFirstVisibleChild; + sal_Int32 mnLastVisibleChild; + + // the object handling our children (guarded by solar mutex) + accessibility::AccessibleParaManager maParaManager; + + // must be before maStateListeners, has to live longer + mutable ::osl::Mutex maMutex; + + // handles our event listeners (guarded by maMutex) + ::cppu::OInterfaceContainerHelper maStateListeners; + +}; + +//------------------------------------------------------------------------ +// +// SvxAccessibleTextHelper_Impl implementation +// +//------------------------------------------------------------------------ + +SvxAccessibleTextHelper_Impl::SvxAccessibleTextHelper_Impl( const uno::Reference< XAccessible >& rInterface ) : + maOffset(0,0), + mxFrontEnd( rInterface ), + maLastSelection( 0,0,0,0 ), + mnFirstVisibleChild( -1 ), + mnLastVisibleChild( -2 ), + maStateListeners( maMutex ) +{ +} + +SvxAccessibleTextHelper_Impl::~SvxAccessibleTextHelper_Impl() +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + try + { + // shutdown and release edit source + SetEditSource( ::std::auto_ptr< SvxEditSource >() ); + } + catch( const uno::RuntimeException& ) {} + + // owner is responsible for dispose and clear on listeners +} + +SvxTextForwarder& SvxAccessibleTextHelper_Impl::GetTextForwarder() const throw (uno::RuntimeException) +{ + if( !maEditSource.IsValid() ) + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unknown edit source")), mxFrontEnd); + + SvxTextForwarder* pTextForwarder = maEditSource.GetTextForwarder(); + + if( !pTextForwarder ) + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch text forwarder, model might be dead")), mxFrontEnd); + + if( pTextForwarder->IsValid() ) + return *pTextForwarder; + else + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Text forwarder is invalid, model might be dead")), mxFrontEnd); +} + +SvxViewForwarder& SvxAccessibleTextHelper_Impl::GetViewForwarder() const throw (uno::RuntimeException) +{ + if( !maEditSource.IsValid() ) + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unknown edit source")), mxFrontEnd); + + SvxViewForwarder* pViewForwarder = maEditSource.GetViewForwarder(); + + if( !pViewForwarder ) + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch view forwarder, model might be dead")), mxFrontEnd); + + if( pViewForwarder->IsValid() ) + return *pViewForwarder; + else + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("View forwarder is invalid, model might be dead")), mxFrontEnd); +} + +SvxEditViewForwarder& SvxAccessibleTextHelper_Impl::GetEditViewForwarder( sal_Bool bCreate ) const throw (uno::RuntimeException) +{ + if( !maEditSource.IsValid() ) + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unknown edit source")), mxFrontEnd); + + SvxEditViewForwarder* pViewForwarder = maEditSource.GetEditViewForwarder( bCreate ); + + if( !pViewForwarder ) + { + if( bCreate ) + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch edit view forwarder, model might be dead")), mxFrontEnd); + else + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("No edit view forwarder, object not in edit mode")), mxFrontEnd); + } + + if( pViewForwarder->IsValid() ) + return *pViewForwarder; + else + { + if( bCreate ) + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("View forwarder is invalid, model might be dead")), mxFrontEnd); + else + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("View forwarder is invalid, object not in edit mode")), mxFrontEnd); + } +} + +SvxEditSourceAdapter& SvxAccessibleTextHelper_Impl::GetEditSource() const throw (uno::RuntimeException) +{ + if( maEditSource.IsValid() ) + return maEditSource; + else + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SvxAccessibleTextHelper_Impl::GetEditSource: no edit source")), mxFrontEnd ); +} + +sal_Bool SvxAccessibleTextHelper_Impl::IsSelected() const +{ + sal_Bool bRet = sal_False; + + try + { + ESelection aSelection; + bRet = GetEditViewForwarder().GetSelection( aSelection ); + } + catch( const uno::RuntimeException& ) {} + + return bRet; +} + +sal_Bool SvxAccessibleTextHelper_Impl::IsActive() const throw (uno::RuntimeException) +{ + SvxEditSource& rEditSource = GetEditSource(); + SvxEditViewForwarder* pViewForwarder = rEditSource.GetEditViewForwarder(); + + if( !pViewForwarder ) + return sal_False; + + if( pViewForwarder->IsValid() ) + return sal_True; + else + return sal_False; +} + +void SvxAccessibleTextHelper_Impl::UpdateSelection( const ESelection& rSelection ) +{ + if( !maLastSelection.IsEqual( rSelection ) ) + { + // notify all affected paragraphs (TODO: may be suboptimal, + // since some paragraphs might stay selected) + + maParaManager.FireEvent( maLastSelection.nStartPara, + maLastSelection.nEndPara, + AccessibleEventId::ACCESSIBLE_SELECTION_EVENT ); + + maParaManager.FireEvent( maLastSelection.nStartPara, + maLastSelection.nStartPara, + AccessibleEventId::ACCESSIBLE_CARET_EVENT ); + + maParaManager.FireEvent( rSelection.nStartPara, + rSelection.nEndPara, + AccessibleEventId::ACCESSIBLE_SELECTION_EVENT ); + + maParaManager.FireEvent( rSelection.nStartPara, + rSelection.nStartPara, + AccessibleEventId::ACCESSIBLE_CARET_EVENT ); + + maLastSelection = rSelection; + } +} + +// functor for sending child events +class SvxAccessibleTextHelper_SendAccessibleChildEvent : public ::std::unary_function< accessibility::AccessibleEditableTextPara&, void > +{ +public: + SvxAccessibleTextHelper_SendAccessibleChildEvent( SvxAccessibleTextHelper_Impl& rImpl ) : mrImpl(rImpl) {} + void operator()( accessibility::AccessibleEditableTextPara& rPara ) + { + uno::Reference< XAccessible > xChild( static_cast< ::cppu::OWeakObject* > ( &rPara ), uno::UNO_QUERY ); + mrImpl.FireEvent(AccessibleEventId::ACCESSIBLE_CHILD_EVENT, uno::Any(), uno::makeAny( xChild ) ); + } + +private: + SvxAccessibleTextHelper_Impl& mrImpl; +}; + +void SvxAccessibleTextHelper_Impl::ShutdownEditSource() throw (uno::RuntimeException) +{ + // This should only be called with solar mutex locked, i.e. from the main office thread + + // invalidate children + maParaManager.SetEditSource( NULL ); + + // loosing all children + maParaManager.ForEach( SvxAccessibleTextHelper_SendAccessibleChildEvent( *this ) ); + maParaManager.SetNum(0); + + // quit listen on stale edit source + if( maEditSource.IsValid() ) + EndListening( maEditSource.GetBroadcaster() ); + + maEditSource.SetEditSource( ::std::auto_ptr< SvxEditSource >(NULL) ); +} + +void SvxAccessibleTextHelper_Impl::SetEditSource( ::std::auto_ptr< SvxEditSource > pEditSource ) throw (uno::RuntimeException) +{ + // This should only be called with solar mutex locked, i.e. from the main office thread + + // shutdown old edit source + ShutdownEditSource(); + + // set new edit source + maEditSource.SetEditSource( pEditSource ); + + // init child vector to the current child count + if( maEditSource.IsValid() ) + { + maParaManager.SetNum( GetTextForwarder().GetParagraphCount() ); + + // listen on new edit source + StartListening( maEditSource.GetBroadcaster() ); + + UpdateVisibleChildren(); + } +} + +void SvxAccessibleTextHelper_Impl::SetOffset( const Point& rPoint ) +{ + maOffset = rPoint; + maParaManager.SetEEOffset( rPoint ); + + // in all cases, check visibility afterwards. + UpdateVisibleChildren(); +} + +void SvxAccessibleTextHelper_Impl::UpdateVisibleChildren() +{ + try + { + SvxTextForwarder& rCacheTF = GetTextForwarder(); + SvxViewForwarder& rCacheVF = GetViewForwarder(); + + Rectangle aViewArea = rCacheVF.GetVisArea(); + + if( IsActive() ) + { + // maybe the edit view scrolls, adapt aViewArea + Rectangle aEditViewArea = GetEditViewForwarder().GetVisArea(); + aViewArea += aEditViewArea.TopLeft(); + + // now determine intersection + aViewArea.Intersection( aEditViewArea ); + } + + Rectangle aTmpBB, aParaBB; + sal_Bool bFirstChild = sal_True; + sal_Int32 nCurrPara; + sal_Int32 nParas=rCacheTF.GetParagraphCount(); + + mnFirstVisibleChild = -1; + mnLastVisibleChild = -2; + + for( nCurrPara=0; nCurrPara<nParas; ++nCurrPara ) + { + DBG_ASSERT(nCurrPara >= 0 && nCurrPara <= USHRT_MAX, + "SvxAccessibleTextHelper_Impl::UpdateVisibleChildren: index value overflow"); + + aTmpBB = rCacheTF.GetParaBounds( static_cast< USHORT >( nCurrPara ) ); + + // convert to screen coordinates + aParaBB = accessibility::AccessibleEditableTextPara::LogicToPixel( aTmpBB, rCacheTF.GetMapMode(), rCacheVF ); + + if( aParaBB.IsOver( aViewArea ) ) + { + // at least partially visible + if( bFirstChild ) + { + bFirstChild = sal_False; + mnFirstVisibleChild = nCurrPara; + } + + mnLastVisibleChild = nCurrPara; + + GotPropertyEvent( uno::makeAny( getAccessibleChild(nCurrPara) ), AccessibleEventId::ACCESSIBLE_CHILD_EVENT ); + } + else + { + // not or no longer visible + if( maParaManager.IsReferencable( nCurrPara ) ) + { + LostPropertyEvent( uno::makeAny( getAccessibleChild(nCurrPara) ), AccessibleEventId::ACCESSIBLE_CHILD_EVENT ); + + // clear reference + maParaManager.Release( nCurrPara ); + } + } + } + } + catch( const uno::RuntimeException& ) + { + DBG_ERROR("SvxAccessibleTextHelper_Impl::UpdateVisibleChildren error while determining visible children"); + + // something failed - currently no children + mnFirstVisibleChild = -1; + mnLastVisibleChild = -2; + + maParaManager.ForEach( SvxAccessibleTextHelper_SendAccessibleChildEvent( *this ) ); + maParaManager.SetNum(0); + } +} + +// functor for checking changes in paragraph bounding boxes +class SvxAccessibleTextHelper_UpdateChildBounds : public ::std::unary_function< const accessibility::AccessibleParaManager::WeakChild&, + accessibility::AccessibleParaManager::WeakChild > +{ +public: + SvxAccessibleTextHelper_UpdateChildBounds( SvxAccessibleTextHelper_Impl& rImpl ) : mrImpl(rImpl) {} + accessibility::AccessibleParaManager::WeakChild operator()( const accessibility::AccessibleParaManager::WeakChild& rChild ) + { + // retrieve hard reference from weak one + accessibility::AccessibleParaManager::WeakPara::HardRefType aHardRef( rChild.first.get() ); + + if( aHardRef.is() ) + { + awt::Rectangle aNewRect = aHardRef->getBounds(); + const awt::Rectangle& aOldRect = rChild.second; + + if( aNewRect.X != aOldRect.X || + aNewRect.Y != aOldRect.Y || + aNewRect.Width != aOldRect.Width || + aNewRect.Height != aOldRect.Height ) + { + // visible data changed + aHardRef->FireEvent( AccessibleEventId::ACCESSIBLE_VISIBLE_DATA_EVENT ); + + // update bounds + return accessibility::AccessibleParaManager::WeakChild( rChild.first, aNewRect ); + } + } + + // identity transform + return rChild; + } + +private: + SvxAccessibleTextHelper_Impl& mrImpl; +}; + +void SvxAccessibleTextHelper_Impl::UpdateVisibleData() +{ + // send CHILD_EVENT to affected children + ::accessibility::AccessibleParaManager::VectorOfChildren::const_iterator begin = maParaManager.begin(); + ::accessibility::AccessibleParaManager::VectorOfChildren::const_iterator end = begin; + + ::std::advance< ::accessibility::AccessibleParaManager::VectorOfChildren::const_iterator, sal_Int32 >( begin, mnFirstVisibleChild ); + ::std::advance< ::accessibility::AccessibleParaManager::VectorOfChildren::const_iterator, sal_Int32 >( end, mnLastVisibleChild ); + + ::std::for_each( begin, end, SvxAccessibleTextHelper_UpdateChildBounds( *this ) ); +} + +#ifdef DBG_UTIL +void SvxAccessibleTextHelper_Impl::CheckInvariants() const +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + if( !mxFrontEnd.is() ) + DBG_ERROR( "SvxAccessibleTextHelper: no frontend" ); + + if( mnFirstVisibleChild >= 0 && + mnFirstVisibleChild > mnLastVisibleChild ) + { + DBG_ERROR( "SvxAccessibleTextHelper: range invalid" ); + } +} +#endif + +void SvxAccessibleTextHelper_Impl::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) +{ + const SfxSimpleHint* pSimpleHint = PTR_CAST( SfxSimpleHint, &rHint ); + const TextHint* pTextHint = PTR_CAST( TextHint, &rHint ); + const SvxViewHint* pViewHint = PTR_CAST( SvxViewHint, &rHint ); + const SvxEditSourceHint* pEditSourceHint = PTR_CAST( SvxEditSourceHint, &rHint ); + + try + { + // precondition: solar mutex locked + if( pEditSourceHint ) + { + if( pEditSourceHint->GetValue() < GetTextForwarder().GetParagraphCount() ) + { + switch( pEditSourceHint->GetId() ) + { + case EDITSOURCE_HINT_PARASMOVED: + { + DBG_ASSERT( pEditSourceHint->GetStartValue() < GetTextForwarder().GetParagraphCount() && + pEditSourceHint->GetEndValue() < GetTextForwarder().GetParagraphCount(), + "SvxAccessibleTextHelper_Impl::NotifyHdl: Invalid notification"); + + const sal_Int32 nParas = GetTextForwarder().GetParagraphCount(); + sal_Int32 nFirst, nMiddle, nLast; + + /* rotate paragraphs + * ================= + * + * Three cases: + * + * 1. + * ... nParagraph ... nParam1 ... nParam2 ... + * |______________[xxxxxxxxxxx] + * becomes + * [xxxxxxxxxxx]|______________ + * + * tail is 0 + * + * 2. + * ... nParam1 ... nParagraph ... nParam2 ... + * [xxxxxxxxxxx|xxxxxxxxxxxxxx]____________ + * becomes + * ____________[xxxxxxxxxxx|xxxxxxxxxxxxxx] + * + * tail is nParagraph - nParam1 + * + * 3. + * ... nParam1 ... nParam2 ... nParagraph ... + * [xxxxxxxxxxx]___________|____________ + * becomes + * ___________|____________[xxxxxxxxxxx] + * + * tail is nParam2 - nParam1 + */ + + // sort nParagraph, nParam1 and nParam2 in ascending order, calc range + if( pEditSourceHint->GetValue() < pEditSourceHint->GetStartValue() ) + { + nFirst = pEditSourceHint->GetValue(); + nMiddle = pEditSourceHint->GetStartValue(); + nLast = pEditSourceHint->GetEndValue(); + } + else if( pEditSourceHint->GetValue() < pEditSourceHint->GetEndValue() ) + { + nFirst = pEditSourceHint->GetStartValue(); + nMiddle = pEditSourceHint->GetValue(); + nLast = pEditSourceHint->GetEndValue() + nMiddle - nFirst; + } + else + { + nFirst = pEditSourceHint->GetStartValue(); + nMiddle = pEditSourceHint->GetEndValue(); + nLast = pEditSourceHint->GetValue() + nMiddle - nFirst; + } + + if( nFirst < nParas && nMiddle < nParas && nLast < nParas ) + { + // since we have no "paragraph index + // changed" event on UAA, remove + // [first,last] and insert again later (in + // UpdateVisibleChildren) + + // maParaManager.Rotate( nFirst, nMiddle, nLast ); + + maParaManager.Release(nFirst, nLast); + + // send CHILD_EVENT to affected children + ::accessibility::AccessibleParaManager::VectorOfChildren::const_iterator begin = maParaManager.begin(); + ::accessibility::AccessibleParaManager::VectorOfChildren::const_iterator end = begin; + + ::std::advance< ::accessibility::AccessibleParaManager::VectorOfChildren::const_iterator, sal_Int32 >( begin, nFirst ); + ::std::advance< ::accessibility::AccessibleParaManager::VectorOfChildren::const_iterator, sal_Int32 >( end, nLast ); + + ::std::for_each( begin, end, + ::accessibility::AccessibleParaManager::WeakChildAdapter< SvxAccessibleTextHelper_SendAccessibleChildEvent > + (SvxAccessibleTextHelper_SendAccessibleChildEvent( *this )) ); + } +#ifdef DBG_UTIL + else + { + DBG_ERROR("SvxAccessibleTextHelper_Impl::NotifyHdl: Invalid move ranges"); + } +#endif + break; + } + + case EDITSOURCE_HINT_SELECTIONCHANGED: + // notify listeners + ESelection aSelection; + try + { + if( GetEditViewForwarder().GetSelection( aSelection ) ) + UpdateSelection( aSelection ); + else + UpdateSelection( ESelection() ); + } + // maybe we're not in edit mode (this is not an error) + catch( const uno::RuntimeException& ) {} + break; + } + + // in all cases, check visibility afterwards. + UpdateVisibleChildren(); + } +#ifdef DBG_UTIL + else + { + DBG_ERROR("SvxAccessibleTextHelper_Impl::NotifyHdl: Invalid notification"); + } +#endif + } + else if( pTextHint ) + { + if( pTextHint->GetValue() < GetTextForwarder().GetParagraphCount() ) + { + sal_Bool bUpdateVisibleData = sal_False; + + switch( pTextHint->GetId() ) + { + case TEXT_HINT_MODIFIED: + // notify listeners + maParaManager.FireEvent( pTextHint->GetValue(), AccessibleEventId::ACCESSIBLE_TEXT_EVENT ); + break; + + case TEXT_HINT_PARAINSERTED: + { + // resize child vector to the current child count + const sal_Int32 nParas = GetTextForwarder().GetParagraphCount(); + + maParaManager.SetNum( nParas ); + + // since we have no "paragraph index + // changed" event on UAA, remove + // [first,last] and insert again later (in + // UpdateVisibleChildren) + + // move successors of inserted paragraph one position further + //maParaManager.MoveRightFrom( pTextHint->GetValue() ); + + // release everything from the insertion position until the end + maParaManager.Release(pTextHint->GetValue(), nParas); + + // send CHILD_EVENT to affected children + ::accessibility::AccessibleParaManager::VectorOfChildren::const_iterator begin = maParaManager.begin(); + ::accessibility::AccessibleParaManager::VectorOfChildren::const_iterator end = begin; + + ::std::advance< ::accessibility::AccessibleParaManager::VectorOfChildren::const_iterator, sal_Int32 >( begin, pTextHint->GetValue() ); + ::std::advance< ::accessibility::AccessibleParaManager::VectorOfChildren::const_iterator, sal_Int32 >( end, nParas ); + + ::std::for_each( begin, end, + ::accessibility::AccessibleParaManager::WeakChildAdapter< SvxAccessibleTextHelper_SendAccessibleChildEvent > + (SvxAccessibleTextHelper_SendAccessibleChildEvent( *this )) ); + break; + } + + case TEXT_HINT_PARAREMOVED: + { + const sal_Int32 nParas = GetTextForwarder().GetParagraphCount(); + + // since we have no "paragraph index + // changed" event on UAA, remove + // [first,last] and insert again later (in + // UpdateVisibleChildren) + + // move successors of removed paragraph one position closer + // maParaManager.MoveLeftFrom( pTextHint->GetValue() ); + + // release everything from the remove position until the end + maParaManager.Release(pTextHint->GetValue(), nParas); + + // send CHILD_EVENT to affected children + ::accessibility::AccessibleParaManager::VectorOfChildren::const_iterator begin = maParaManager.begin(); + ::accessibility::AccessibleParaManager::VectorOfChildren::const_iterator end = begin; + + ::std::advance< ::accessibility::AccessibleParaManager::VectorOfChildren::const_iterator, sal_Int32 >( begin, pTextHint->GetValue() ); + ::std::advance< ::accessibility::AccessibleParaManager::VectorOfChildren::const_iterator, sal_Int32 >( end, nParas ); + + ::std::for_each( begin, end, + ::accessibility::AccessibleParaManager::WeakChildAdapter< SvxAccessibleTextHelper_SendAccessibleChildEvent > + (SvxAccessibleTextHelper_SendAccessibleChildEvent( *this )) ); + + // resize child vector to the current child count + maParaManager.SetNum( nParas ); + break; + } + + case TEXT_HINT_TEXTHEIGHTCHANGED: + bUpdateVisibleData = sal_True; + break; + + case TEXT_HINT_VIEWSCROLLED: + bUpdateVisibleData = sal_True; + break; + } + + // in all cases, check visibility afterwards. + UpdateVisibleChildren(); + + if( bUpdateVisibleData ) + UpdateVisibleData(); + } +#ifdef DBG_UTIL + else + { + DBG_ERROR("SvxAccessibleTextHelper_Impl::NotifyHdl: Invalid notification"); + + } +#endif + } + else if( pViewHint ) + { + switch( pViewHint->GetId() ) + { + case SVX_HINT_VIEWCHANGED: + // just check visibility + break; + } + + // in all cases, check visibility afterwards. + UpdateVisibleChildren(); + } + // it's VITAL to keep the SfxSimpleHint last! It's the base of some classes above! + else if( pSimpleHint ) + { + switch( pSimpleHint->GetId() ) + { + case SFX_HINT_DYING: + // edit source is dying under us, become defunc then + try + { + // make edit source inaccessible + // Note: cannot destroy it here, since we're called from there! + ShutdownEditSource(); + } + catch( const uno::RuntimeException& ) {} + + break; + } + } + } + catch( const uno::RuntimeException& ) + { +#ifdef DBG_UTIL + DBG_ERROR("SvxAccessibleTextHelper_Impl::Notify: Unhandled exception."); +#endif + } +} + +void SvxAccessibleTextHelper_Impl::FireEvent( const sal_Int16 nEventId, const uno::Any& rNewValue, const uno::Any& rOldValue ) const +{ +// -- object locked -- + ::osl::ClearableMutexGuard aGuard( maMutex ); + + AccessibleEventObject aEvent(mxFrontEnd, nEventId, rNewValue, rOldValue); + + ::cppu::OInterfaceIteratorHelper aIter( const_cast< SvxAccessibleTextHelper_Impl* >(this)->maStateListeners ); + + // no locking necessary, OInterfaceIteratorHelper copies listeners if someone removes/adds in between + // Further locking, actually, might lead to deadlocks, since we're calling out of this object + aGuard.clear(); +// -- until here -- + + while( aIter.hasMoreElements() ) + { + uno::Reference < XAccessibleEventListener > xListener( aIter.next(), uno::UNO_QUERY ); + + if( xListener.is() ) + { + try + { + xListener->notifyEvent( aEvent ); + } + catch( const uno::RuntimeException& ) + { +#ifdef DBG_UTIL + DBG_ERROR("SvxAccessibleTextHelper_Impl::StateChangeEvent: Caught runtime exception from listener (bridge/listener dead?)."); +#endif + } + } + } +} + +// XAccessibleContext +sal_Int32 SAL_CALL SvxAccessibleTextHelper_Impl::getAccessibleChildCount() throw (uno::RuntimeException) +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + return mnLastVisibleChild - mnFirstVisibleChild + 1; +} + +uno::Reference< XAccessible > SAL_CALL SvxAccessibleTextHelper_Impl::getAccessibleChild( sal_Int32 i ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + if( 0 > i || i > getAccessibleChildCount() || + GetTextForwarder().GetParagraphCount() <= i ) + { + throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Invalid child index")), mxFrontEnd); + } + + return maParaManager.GetChild( i, mxFrontEnd, GetEditSource(), mnFirstVisibleChild + i ).first; +} + +void SAL_CALL SvxAccessibleTextHelper_Impl::addEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException) +{ + maStateListeners.addInterface( xListener ); +} + +void SAL_CALL SvxAccessibleTextHelper_Impl::removeEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException) +{ + maStateListeners.removeInterface( xListener ); +} + +uno::Reference< XAccessible > SAL_CALL SvxAccessibleTextHelper_Impl::getAccessibleAt( const awt::Point& _aPoint ) throw (uno::RuntimeException) +{ + // make given position relative + if( !mxFrontEnd.is() ) + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SvxAccessibleTextHelper_Impl::getAccessibleAt: frontend invalid")), mxFrontEnd ); + + uno::Reference< XAccessibleContext > xFrontEndContext = mxFrontEnd->getAccessibleContext(); + + if( !xFrontEndContext.is() ) + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SvxAccessibleTextHelper_Impl::getAccessibleAt: frontend invalid")), mxFrontEnd ); + + uno::Reference< XAccessibleComponent > xFrontEndComponent( xFrontEndContext, uno::UNO_QUERY ); + + if( !xFrontEndComponent.is() ) + throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SvxAccessibleTextHelper_Impl::getAccessibleAt: frontend is no XAccessibleComponent")), + mxFrontEnd ); + + Point aPoint( _aPoint.X, _aPoint.Y ); + awt::Point aRefPoint = xFrontEndComponent->getLocationOnScreen(); + aPoint -= Point( aRefPoint.X, aRefPoint.Y ); + + // respect EditEngine offset to surrounding shape/cell + aPoint -= GetOffset(); + + // convert to EditEngine coordinate system + SvxTextForwarder& rCacheTF = GetTextForwarder(); + Point aLogPoint( GetViewForwarder().PixelToLogic( aPoint, rCacheTF.GetMapMode() ) ); + + // iterate over all visible children (including those not yet created) + sal_Int32 nChild; + for( nChild=mnFirstVisibleChild; nChild <= mnLastVisibleChild; ++nChild ) + { + DBG_ASSERT(nChild >= 0 && nChild <= USHRT_MAX, + "SvxAccessibleTextHelper_Impl::getAccessibleAt: index value overflow"); + + Rectangle aParaBounds( rCacheTF.GetParaBounds( static_cast< USHORT > (nChild) ) ); + + if( aParaBounds.IsInside( aLogPoint ) ) + { + DBG_ASSERT(nChild - mnFirstVisibleChild >= 0 && nChild - mnFirstVisibleChild <= USHRT_MAX, + "SvxAccessibleTextHelper_Impl::getAccessibleAt: index value overflow"); + + return getAccessibleChild( static_cast< USHORT > (nChild - mnFirstVisibleChild) ); + } + } + + // found none + return uno::Reference< XAccessible >(); +} + +//------------------------------------------------------------------------ +// +// SvxAccessibleTextHelper implementation (simply forwards to impl) +// +//------------------------------------------------------------------------ + +SvxAccessibleTextHelper::SvxAccessibleTextHelper( const uno::Reference< XAccessible >& rInterface, + ::std::auto_ptr< SvxEditSource > pEditSource ) : + mpImpl( new SvxAccessibleTextHelper_Impl( rInterface ) ) +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + SetEditSource( pEditSource ); +} + +SvxAccessibleTextHelper::~SvxAccessibleTextHelper() +{ +} + +SvxEditSource& SvxAccessibleTextHelper::GetEditSource() const throw (uno::RuntimeException) +{ +#ifdef DBG_UTIL + mpImpl->CheckInvariants(); + + SvxEditSource& aEditSource = mpImpl->GetEditSource(); + + mpImpl->CheckInvariants(); + + return aEditSource; +#else + return mpImpl->GetEditSource(); +#endif +} + +void SvxAccessibleTextHelper::SetEditSource( ::std::auto_ptr< SvxEditSource > pEditSource ) throw (uno::RuntimeException) +{ +#ifdef DBG_UTIL + mpImpl->CheckInvariants(); + + mpImpl->SetEditSource( pEditSource ); + + mpImpl->CheckInvariants(); +#else + mpImpl->SetEditSource( pEditSource ); +#endif +} + +void SvxAccessibleTextHelper::StateChangeEvent( const sal_Int16 nEventId, const uno::Any& rNewValue, const uno::Any& rOldValue ) const +{ +#ifdef DBG_UTIL + mpImpl->CheckInvariants(); + + mpImpl->FireEvent( nEventId, rNewValue, rOldValue ); + + mpImpl->CheckInvariants(); +#else + mpImpl->StateChangeEvent( nEventId, rNewValue, rOldValue ); +#endif +} + +void SvxAccessibleTextHelper::SetOffset( const Point& rPoint ) +{ +#ifdef DBG_UTIL + mpImpl->CheckInvariants(); + + mpImpl->SetOffset( rPoint ); + + mpImpl->CheckInvariants(); +#else + mpImpl->SetOffset( rPoint ); +#endif +} + +const Point& SvxAccessibleTextHelper::GetOffset() const +{ +#ifdef DBG_UTIL + mpImpl->CheckInvariants(); + + const Point& rRef = mpImpl->GetOffset(); + + mpImpl->CheckInvariants(); + + return rRef; +#else + return mpImpl->GetOffset(); +#endif +} + +void SvxAccessibleTextHelper::UpdateChildren() throw (::com::sun::star::uno::RuntimeException) +{ +#ifdef DBG_UTIL + mpImpl->CheckInvariants(); + + mpImpl->UpdateVisibleChildren(); + + mpImpl->CheckInvariants(); +#else + mpImpl->UpdateVisibleChildren(); +#endif +} + +sal_Bool SvxAccessibleTextHelper::IsSelected() const +{ +#ifdef DBG_UTIL + mpImpl->CheckInvariants(); + + sal_Bool aRet = mpImpl->IsSelected(); + + mpImpl->CheckInvariants(); + + return aRet; +#else + return mpImpl->IsSelected(); +#endif +} + +// XAccessibleContext +sal_Int32 SvxAccessibleTextHelper::GetChildCount() throw (uno::RuntimeException) +{ +#ifdef DBG_UTIL + mpImpl->CheckInvariants(); + + sal_Int32 nRet = mpImpl->getAccessibleChildCount(); + + mpImpl->CheckInvariants(); + + return nRet; +#else + return mpImpl->getAccessibleChildCount(); +#endif +} + +uno::Reference< XAccessible > SvxAccessibleTextHelper::GetChild( sal_Int32 i ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) +{ +#ifdef DBG_UTIL + mpImpl->CheckInvariants(); + + uno::Reference< XAccessible > xRet = mpImpl->getAccessibleChild( i ); + + mpImpl->CheckInvariants(); + + return xRet; +#else + return mpImpl->getAccessibleChild( i ); +#endif +} + +void SvxAccessibleTextHelper::AddEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException) +{ +#ifdef DBG_UTIL + mpImpl->CheckInvariants(); + + mpImpl->addEventListener( xListener ); + + mpImpl->CheckInvariants(); +#else + mpImpl->addEventListener( xListener ); +#endif +} + +void SvxAccessibleTextHelper::RemoveEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException) +{ +#ifdef DBG_UTIL + mpImpl->CheckInvariants(); + + mpImpl->removeEventListener( xListener ); + + mpImpl->CheckInvariants(); +#else + mpImpl->removeEventListener( xListener ); +#endif +} + +// XAccessibleComponent +uno::Reference< XAccessible > SvxAccessibleTextHelper::GetAt( const awt::Point& aPoint ) throw (uno::RuntimeException) +{ +#ifdef DBG_UTIL + mpImpl->CheckInvariants(); + + uno::Reference< XAccessible > xChild = mpImpl->getAccessibleAt( aPoint ); + + mpImpl->CheckInvariants(); + + return xChild; +#else + return mpImpl->getAccessibleAt( aPoint ); +#endif +} + +//------------------------------------------------------------------------ diff --git a/svx/source/inc/unoedprx.hxx b/svx/source/inc/unoedprx.hxx new file mode 100644 index 000000000000..8c31ae22ff0e --- /dev/null +++ b/svx/source/inc/unoedprx.hxx @@ -0,0 +1,196 @@ +/************************************************************************* + * + * $RCSfile: unoedprx.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: thb $ $Date: 2002-05-16 16:11:24 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _SVX_UNOEDPRX_HXX +#define _SVX_UNOEDPRX_HXX + +#include <memory> + +#ifndef _SFXBRDCST_HXX +#include <svtools/brdcst.hxx> +#endif + +#ifndef _SVX_UNOEDSRC_HXX +#include "unoedsrc.hxx" +#endif + +#include "editdata.hxx" + + +class SvxAccessibleTextAdapter : public SvxTextForwarder +{ +public: + SvxAccessibleTextAdapter(); + virtual ~SvxAccessibleTextAdapter(); + + virtual USHORT GetParagraphCount() const; + virtual USHORT GetTextLen( USHORT nParagraph ) const; + virtual String GetText( const ESelection& rSel ) const; + virtual SfxItemSet GetAttribs( const ESelection& rSel, BOOL bOnlyHardAttrib = 0 ) const; + virtual SfxItemSet GetParaAttribs( USHORT nPara ) const; + virtual void SetParaAttribs( USHORT nPara, const SfxItemSet& rSet ); + virtual void GetPortions( USHORT nPara, SvUShorts& rList ) const; + + virtual USHORT GetItemState( const ESelection& rSel, USHORT nWhich ) const; + virtual USHORT GetItemState( USHORT nPara, USHORT nWhich ) const; + + virtual void QuickInsertText( const String& rText, const ESelection& rSel ); + virtual void QuickInsertField( const SvxFieldItem& rFld, const ESelection& rSel ); + virtual void QuickSetAttribs( const SfxItemSet& rSet, const ESelection& rSel ); + virtual void QuickInsertLineBreak( const ESelection& rSel ); + + virtual SfxItemPool* GetPool() const; + + virtual XubString CalcFieldValue( const SvxFieldItem& rField, USHORT nPara, USHORT nPos, Color*& rpTxtColor, Color*& rpFldColor ); + virtual BOOL IsValid() const; + + virtual LanguageType GetLanguage( USHORT, USHORT ) const; + virtual USHORT GetFieldCount( USHORT nPara ) const; + virtual EFieldInfo GetFieldInfo( USHORT nPara, USHORT nField ) const; + virtual EBulletInfo GetBulletInfo( USHORT nPara ) const; + virtual Rectangle GetCharBounds( USHORT nPara, USHORT nIndex ) const; + virtual Rectangle GetParaBounds( USHORT nPara ) const; + virtual MapMode GetMapMode() const; + virtual OutputDevice* GetRefDevice() const; + virtual sal_Bool GetIndexAtPoint( const Point&, USHORT& nPara, USHORT& nIndex ) const; + virtual sal_Bool GetWordIndices( USHORT nPara, USHORT nIndex, USHORT& nStart, USHORT& nEnd ) const; + virtual USHORT GetLineCount( USHORT nPara ) const; + virtual USHORT GetLineLen( USHORT nPara, USHORT nLine ) const; + virtual sal_Bool Delete( const ESelection& ); + virtual sal_Bool InsertText( const String&, const ESelection& ); + virtual sal_Bool QuickFormatDoc( BOOL bFull=FALSE ); + + void SetForwarder( SvxTextForwarder& ); + sal_Bool HaveImageBullet( USHORT nPara ) const; + sal_Bool HaveTextBullet( USHORT nPara ) const; + + /** Query whether all text in given selection is editable + + @return sal_True if every character in the given selection can + be changed, and sal_False if e.g. a field or a bullet is + contained therein. + */ + sal_Bool IsEditable( const ESelection& rSelection ); + +private: + SvxTextForwarder* mrTextForwarder; +}; + +class SvxAccessibleTextEditViewAdapter : public SvxEditViewForwarder +{ +public: + + SvxAccessibleTextEditViewAdapter(); + virtual ~SvxAccessibleTextEditViewAdapter(); + + virtual BOOL IsValid() const; + + virtual Rectangle GetVisArea() const; + virtual Point LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const; + virtual Point PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const; + + virtual sal_Bool GetSelection( ESelection& rSelection ) const; + virtual sal_Bool SetSelection( const ESelection& rSelection ); + virtual sal_Bool Copy(); + virtual sal_Bool Cut(); + virtual sal_Bool Paste(); + + void SetForwarder( SvxEditViewForwarder&, SvxAccessibleTextAdapter& ); + +private: + SvxEditViewForwarder* mrViewForwarder; + SvxAccessibleTextAdapter* mrTextForwarder; +}; + +class SvxEditSourceAdapter : public SvxEditSource +{ +public: + SvxEditSourceAdapter(); + ~SvxEditSourceAdapter(); + + virtual SvxEditSource* Clone() const; + virtual SvxTextForwarder* GetTextForwarder(); + SvxAccessibleTextAdapter* GetTextForwarderAdapter(); // covariant return types don't work on MSVC + virtual SvxViewForwarder* GetViewForwarder(); + virtual SvxEditViewForwarder* GetEditViewForwarder( sal_Bool bCreate = sal_False ); + SvxAccessibleTextEditViewAdapter* GetEditViewForwarderAdapter( sal_Bool bCreate = sal_False ); // covariant return types don't work on MSVC + virtual void UpdateData(); + virtual SfxBroadcaster& GetBroadcaster() const; + + void SetEditSource( ::std::auto_ptr< SvxEditSource > pAdaptee ); + sal_Bool IsValid() const; + +private: + // declared, but not defined + SvxEditSourceAdapter( const SvxEditSourceAdapter& ); + SvxEditSourceAdapter& operator= ( const SvxEditSourceAdapter& ); + + ::std::auto_ptr< SvxEditSource > mpAdaptee; + + SvxAccessibleTextAdapter maTextAdapter; + SvxAccessibleTextEditViewAdapter maEditViewAdapter; + + mutable SfxBroadcaster maDummyBroadcaster; + + sal_Bool mbEditSourceValid; +}; + +#endif diff --git a/svx/source/inc/unopracc.hxx b/svx/source/inc/unopracc.hxx new file mode 100644 index 000000000000..c07e619d0212 --- /dev/null +++ b/svx/source/inc/unopracc.hxx @@ -0,0 +1,113 @@ +/************************************************************************* + * + * $RCSfile: unopracc.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: thb $ $Date: 2002-05-16 16:11:41 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _SVX_UNOPRACC_HXX +#define _SVX_UNOPRACC_HXX + +#ifndef _SVX_UNOSHAPE_HXX +#include "unoshape.hxx" +#endif + +#ifndef _SVX_UNOTEXT_HXX +#include "unotext.hxx" +#endif + + +class SvxEditSource; + +/** Wraps SvxUnoTextRangeBase and provides us with the text properties + + Inherits from SvxUnoTextRangeBase and provides XPropertySet and + XMultiPropertySet interfaces. Just set the selection to the + required text range and return a reference to a XPropertySet. + */ +class SvxAccessibleTextPropertySet : public SvxUnoTextRangeBase, + public ::com::sun::star::lang::XTypeProvider, + public ::cppu::OWeakObject +{ +public: + SvxAccessibleTextPropertySet( const SvxEditSource*, const SfxItemPropertyMap* ); + virtual ~SvxAccessibleTextPropertySet() throw(); + + // XTextRange + virtual ::com::sun::star::uno::Reference< ::com::sun::star::text::XText > SAL_CALL getText() throw (::com::sun::star::uno::RuntimeException); + + // uno::XInterface + virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL acquire() throw(); + virtual void SAL_CALL release() throw(); + + // lang::XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw (::com::sun::star::uno::RuntimeException); + + // lang::XTypeProvider + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException); + + // XServiceName + ::rtl::OUString SAL_CALL SvxAccessibleTextPropertySet::getServiceName() throw (::com::sun::star::uno::RuntimeException); +}; + +#endif + diff --git a/svx/source/unoedit/unoedprx.cxx b/svx/source/unoedit/unoedprx.cxx new file mode 100644 index 000000000000..0cbbf6a64cc8 --- /dev/null +++ b/svx/source/unoedit/unoedprx.cxx @@ -0,0 +1,1175 @@ +/************************************************************************* + * + * $RCSfile: unoedprx.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: thb $ $Date: 2002-05-16 16:12:20 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#pragma hdrstop + +//------------------------------------------------------------------------ +// +// Global header +// +//------------------------------------------------------------------------ + +#include <limits.h> +#include <vector> +#include <algorithm> + +#ifndef _VOS_MUTEX_HXX_ +#include <vos/mutex.hxx> +#endif + +#ifndef _SV_WINDOW_HXX +#include <vcl/window.hxx> +#endif + +#ifndef _SV_SVAPP_HXX +#include <vcl/svapp.hxx> +#endif + +#ifndef _COM_SUN_STAR_UNO_ANY_HXX_ +#include <com/sun/star/uno/Any.hxx> +#endif + +#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_ +#include <com/sun/star/uno/Reference.hxx> +#endif + +//------------------------------------------------------------------------ +// +// Project-local header +// +//------------------------------------------------------------------------ + +#ifndef _SVX_UNOEDPRX_HXX +#include "unoedprx.hxx" +#endif + +#ifndef _SVX_UNOTEXT_HXX +#include "unotext.hxx" +#endif + +#include "unoedhlp.hxx" +#include "svdmodel.hxx" +#include "svdpntv.hxx" +#include "editdata.hxx" +#include "editeng.hxx" +#include "editview.hxx" + +using namespace ::com::sun::star; + + +class SvxAccessibleTextIndex +{ +public: + SvxAccessibleTextIndex() : + mnPara(0), + mnIndex(0), + mnEEIndex(0), + mnFieldOffset(0), + mbInField(sal_False), + mnFieldLen(0), + mnBulletOffset(0), + mbInBullet(sal_False), + mnBulletLen(0) {}; + ~SvxAccessibleTextIndex() {}; + + // Get/Set current paragraph + void SetParagraph( USHORT nPara ) + { + mnPara = nPara; + } + USHORT GetParagraph() const { return mnPara; } + + /** Set the index in the UAA semantic + + @param nIndex + The index from the UA API (fields and bullets are expanded) + + @param rTF + The text forwarder to use in the calculations + */ + void SetIndex( sal_Int32 nIndex, const SvxTextForwarder& rTF ); + void SetIndex( USHORT nPara, sal_Int32 nIndex, const SvxTextForwarder& rTF ) { SetParagraph(nPara); SetIndex(nIndex, rTF); } + sal_Int32 GetIndex() const { return mnIndex; } + + /** Set the index in the edit engine semantic + + Update the object state to reflect the given index position in + EditEngine/Outliner index values + + @param nEEIndex + The index from the edit engine (fields span exactly one index increment) + + @param rTF + The text forwarder to use in the calculations + */ + void SetEEIndex( USHORT nEEIndex, const SvxTextForwarder& rTF ); + void SetEEIndex( USHORT nPara, USHORT nEEIndex, const SvxTextForwarder& rTF ) { SetParagraph(nPara); SetEEIndex(nEEIndex, rTF); } + USHORT GetEEIndex() const { return mnEEIndex; } + + void SetFieldOffset( sal_Int32 nOffset, sal_Int32 nLen ) { mnFieldOffset = nOffset; mnFieldLen = nLen; } + sal_Int32 GetFieldOffset() const { return mnFieldOffset; } + sal_Int32 GetFieldLen() const { return mnFieldLen; } + void AreInField( sal_Bool bInField = sal_True ) { mbInField = bInField; } + sal_Bool InField() const { return mbInField; } + + void SetBulletOffset( sal_Int32 nOffset, sal_Int32 nLen ) { mnBulletOffset = nOffset; mnBulletLen = nLen; } + sal_Int32 GetBulletOffset() const { return mnBulletOffset; } + sal_Int32 GetBulletLen() const { return mnBulletLen; } + void AreInBullet( sal_Bool bInBullet = sal_True ) { mbInBullet = bInBullet; } + sal_Bool InBullet() const { return mbInBullet; } + + /// returns false if the current index contains non-editable text (e.g. bullets) + sal_Bool IsEditable() const; + + /// returns false if the given range is non-editable (e.g. contains bullets or _parts_ of fields) + sal_Bool IsEditableRange( const SvxAccessibleTextIndex& rEnd ) const; + +private: + USHORT mnPara; + sal_Int32 mnIndex; + USHORT mnEEIndex; + sal_Int32 mnFieldOffset; + sal_Int32 mnFieldLen; + sal_Bool mbInField; + sal_Int32 mnBulletOffset; + sal_Int32 mnBulletLen; + sal_Bool mbInBullet; +}; + +ESelection MakeEESelection( const SvxAccessibleTextIndex& rStart, const SvxAccessibleTextIndex& rEnd ) +{ + // check overflow + DBG_ASSERT(rStart.GetParagraph() >= 0 && rStart.GetParagraph() <= USHRT_MAX && + rStart.GetEEIndex() >= 0 && rStart.GetEEIndex() <= USHRT_MAX && + rEnd.GetParagraph() >= 0 && rEnd.GetParagraph() <= USHRT_MAX && + rEnd.GetEEIndex() >= 0 && rEnd.GetEEIndex() <= USHRT_MAX, + "MakeEESelection: index value overflow"); + + return ESelection( rStart.GetParagraph(), rStart.GetEEIndex(), + rEnd.GetParagraph(), rEnd.GetEEIndex() ); +} + +ESelection MakeEESelection( const SvxAccessibleTextIndex& rIndex ) +{ + return MakeEESelection( rIndex, rIndex ); +} + + +void SvxAccessibleTextIndex::SetEEIndex( USHORT nEEIndex, const SvxTextForwarder& rTF ) +{ + // set known values + mnEEIndex = nEEIndex; + + // calculate unknowns + USHORT nCurrField, nFieldCount = rTF.GetFieldCount( GetParagraph() ); + sal_Int32 nTmp; + + mnIndex = nEEIndex; + + EBulletInfo aBulletInfo = rTF.GetBulletInfo( GetParagraph() ); + + // any text bullets? + if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && + aBulletInfo.bVisible && + aBulletInfo.nType != SVX_NUM_BITMAP ) + { + mnIndex += aBulletInfo.aText.Len(); + } + + for( nCurrField=0; nCurrField < nFieldCount; ++nCurrField ) + { + EFieldInfo aFieldInfo( rTF.GetFieldInfo( GetParagraph(), nCurrField ) ); + + if( aFieldInfo.aPosition.nIndex > nEEIndex ) + break; + + if( aFieldInfo.aPosition.nIndex == nEEIndex ) + { + AreInField(); + break; + } + + // nCharIndex = Max(aFieldInfo.aCurrentText.Len(), 1); + nTmp = aFieldInfo.aCurrentText.Len(); + mnIndex += nTmp > 1 ? nTmp-1 : 0 ; + } +} + +void SvxAccessibleTextIndex::SetIndex( sal_Int32 nIndex, const SvxTextForwarder& rTF ) +{ + // set known values + mnIndex = nIndex; + + // calculate unknowns + USHORT nCurrField, nFieldCount = rTF.GetFieldCount( GetParagraph() ); + sal_Int32 nTmp; + + DBG_ASSERT(nIndex >= 0 && nIndex <= USHRT_MAX, + "SvxAccessibleTextIndex::SetIndex: index value overflow"); + + mnEEIndex = static_cast< USHORT > (nIndex); + + EBulletInfo aBulletInfo = rTF.GetBulletInfo( GetParagraph() ); + + // any text bullets? + if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && + aBulletInfo.bVisible && + aBulletInfo.nType != SVX_NUM_BITMAP ) + { + sal_Int32 nBulletLen = aBulletInfo.aText.Len(); + + if( nIndex < nBulletLen ) + { + AreInBullet(); + SetBulletOffset( nIndex, nBulletLen ); + return; + } + + DBG_ASSERT(mnEEIndex >= nBulletLen && mnEEIndex - nBulletLen <= USHRT_MAX, + "SvxAccessibleTextIndex::SetIndex: index value overflow"); + + mnEEIndex = static_cast< USHORT > (mnEEIndex - nBulletLen); + } + + for( nCurrField=0; nCurrField < nFieldCount; ++nCurrField ) + { + EFieldInfo aFieldInfo( rTF.GetFieldInfo( GetParagraph(), nCurrField ) ); + + // we're before a field + if( aFieldInfo.aPosition.nIndex > mnEEIndex ) + break; + + // this is: nEEIndex = Max(aFieldInfo.aCurrentText.Len(), 1); + nTmp = aFieldInfo.aCurrentText.Len(); + mnEEIndex -= nTmp > 1 ? nTmp : 1 ; + + // we're within a field + if( aFieldInfo.aPosition.nIndex > mnEEIndex ) + { + AreInField(); + SetFieldOffset( aFieldInfo.aCurrentText.Len() - aFieldInfo.aPosition.nIndex + mnEEIndex, aFieldInfo.aCurrentText.Len() ); + mnEEIndex = aFieldInfo.aPosition.nIndex ; + break; + } + + // now we're after the field + mnEEIndex += 1; + } +} + +sal_Bool SvxAccessibleTextIndex::IsEditable() const +{ + if( InBullet() || InField() ) + return sal_False; + + return sal_True; +} + +sal_Bool SvxAccessibleTextIndex::IsEditableRange( const SvxAccessibleTextIndex& rEnd ) const +{ + if( GetIndex() > rEnd.GetIndex() ) + return rEnd.IsEditableRange( *this ); + + if( InBullet() || rEnd.InBullet() ) + return sal_False; + + if( InField() && GetFieldOffset() ) + return sal_False; // within field + + if( rEnd.InField() && rEnd.GetFieldOffset() >= rEnd.GetFieldLen() - 1 ) + return sal_False; // within field + + return sal_True; +} + +//------------------------------------------------------------------------ +// +// SvxAccessibleStringWrap declaration +// +//------------------------------------------------------------------------ + +class SvxAccessibleStringWrap +{ +public: + + SvxAccessibleStringWrap( OutputDevice& rDev, SvxFont& rFont, const String& rText ); + + sal_Bool GetCharacterBounds( sal_Int32 nIndex, Rectangle& rRect ); + sal_Int32 GetIndexAtPoint( const Point& rPoint ); + +private: + + OutputDevice& mrDev; + SvxFont& mrFont; + String maText; +}; + +//------------------------------------------------------------------------ +// +// SvxAccessibleStringWrap implementation +// +//------------------------------------------------------------------------ + +SvxAccessibleStringWrap::SvxAccessibleStringWrap( OutputDevice& rDev, SvxFont& rFont, const String& rText ) : + mrDev( rDev ), + mrFont( rFont ), + maText( rText ) +{ +} + +sal_Bool SvxAccessibleStringWrap::GetCharacterBounds( sal_Int32 nIndex, Rectangle& rRect ) +{ + DBG_ASSERT(nIndex >= 0 && nIndex <= USHRT_MAX, + "SvxAccessibleStringWrap::GetCharacterBounds: index value overflow"); + + rRect.Left() = 0; + rRect.Top() = 0; + rRect.SetSize( mrFont.GetPhysTxtSize( &mrDev, maText.Copy(static_cast< USHORT >(nIndex), 1) ) ); + + if( nIndex > 0 ) + { + // TODO: CTL, BiDi + Size aOffset = mrFont.GetPhysTxtSize( &mrDev, maText.Copy(0, static_cast< USHORT >(nIndex) ) ); + rRect.Move( aOffset.Width(), 0 ); + } + + return sal_True; +} + +sal_Int32 SvxAccessibleStringWrap::GetIndexAtPoint( const Point& rPoint ) +{ + // search for character bounding box containing given point + Rectangle aRect; + sal_Int32 i, nLen = maText.Len(); + for( i=0; i<nLen; ++i ) + { + GetCharacterBounds(i, aRect); + if( aRect.IsInside(rPoint) ) + return i; + } + + return -1; +} + + +//--------------------------------------------------------------------------------- + +SvxEditSourceAdapter::SvxEditSourceAdapter() : mbEditSourceValid( sal_False ) +{ +} + +SvxEditSourceAdapter::~SvxEditSourceAdapter() +{ +} + +SvxEditSource* SvxEditSourceAdapter::Clone() const +{ + if( mbEditSourceValid && mpAdaptee.get() ) + return mpAdaptee->Clone(); + + return NULL; +} + +SvxAccessibleTextAdapter* SvxEditSourceAdapter::GetTextForwarderAdapter() +{ + if( mbEditSourceValid && mpAdaptee.get() ) + { + SvxTextForwarder* pTextForwarder = mpAdaptee->GetTextForwarder(); + + if( pTextForwarder ) + { + maTextAdapter.SetForwarder(*pTextForwarder); + + return &maTextAdapter; + } + } + + return NULL; +} + +SvxTextForwarder* SvxEditSourceAdapter::GetTextForwarder() +{ + return GetTextForwarderAdapter(); +} + +SvxViewForwarder* SvxEditSourceAdapter::GetViewForwarder() +{ + if( mbEditSourceValid && mpAdaptee.get() ) + return mpAdaptee->GetViewForwarder(); + + return NULL; +} + +SvxAccessibleTextEditViewAdapter* SvxEditSourceAdapter::GetEditViewForwarderAdapter( sal_Bool bCreate ) +{ + if( mbEditSourceValid && mpAdaptee.get() ) + { + SvxEditViewForwarder* pEditViewForwarder = mpAdaptee->GetEditViewForwarder(); + + if( pEditViewForwarder ) + { + SvxAccessibleTextAdapter* pTextAdapter = GetTextForwarderAdapter(); + + if( pTextAdapter ) + { + maEditViewAdapter.SetForwarder(*pEditViewForwarder, *pTextAdapter); + + return &maEditViewAdapter; + } + } + } + + return NULL; +} + +SvxEditViewForwarder* SvxEditSourceAdapter::GetEditViewForwarder( sal_Bool bCreate ) +{ + return GetEditViewForwarderAdapter( bCreate ); +} + +void SvxEditSourceAdapter::UpdateData() +{ + if( mbEditSourceValid && mpAdaptee.get() ) + mpAdaptee->UpdateData(); +} + +SfxBroadcaster& SvxEditSourceAdapter::GetBroadcaster() const +{ + if( mbEditSourceValid && mpAdaptee.get() ) + return mpAdaptee->GetBroadcaster(); + + return maDummyBroadcaster; +} + +void SvxEditSourceAdapter::SetEditSource( ::std::auto_ptr< SvxEditSource > pAdaptee ) +{ + if( pAdaptee.get() ) + { + mpAdaptee = pAdaptee; + mbEditSourceValid = sal_True; + } + else + { + // do a lazy delete (prevents us from deleting the broadcaster + // from within a broadcast in + // AccessibleTextHelper_Impl::Notify) + mbEditSourceValid = sal_False; + } +} + +sal_Bool SvxEditSourceAdapter::IsValid() const +{ + return mbEditSourceValid; +} + + +//-------------------------------------------------------------------------------------- + +SvxAccessibleTextAdapter::SvxAccessibleTextAdapter() : mrTextForwarder( NULL ) +{ +} + +SvxAccessibleTextAdapter::~SvxAccessibleTextAdapter() +{ +} + +USHORT SvxAccessibleTextAdapter::GetParagraphCount() const +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + return mrTextForwarder->GetParagraphCount(); +} + +USHORT SvxAccessibleTextAdapter::GetTextLen( USHORT nParagraph ) const +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + SvxAccessibleTextIndex aIndex; + aIndex.SetEEIndex( nParagraph, mrTextForwarder->GetTextLen( nParagraph ), *this ); + + return static_cast< USHORT >(aIndex.GetIndex()); +} + +String SvxAccessibleTextAdapter::GetText( const ESelection& rSel ) const +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + SvxAccessibleTextIndex aStartIndex; + SvxAccessibleTextIndex aEndIndex; + + aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this ); + aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this ); + + // normalize selection + if( rSel.nStartPara > rSel.nEndPara || + (rSel.nStartPara == rSel.nEndPara && rSel.nStartPos > rSel.nEndPos) ) + { + ::std::swap( aStartIndex, aEndIndex ); + } + + String sStr = mrTextForwarder->GetText( MakeEESelection(aStartIndex, aEndIndex) ); + + EBulletInfo aBulletInfo1 = GetBulletInfo( static_cast< USHORT >(aStartIndex.GetParagraph()) ); + EBulletInfo aBulletInfo2 = GetBulletInfo( static_cast< USHORT >(aEndIndex.GetParagraph()) ); + + if( aStartIndex.InBullet() ) + { + // prepend leading bullet + String sBullet = aBulletInfo1.aText; + + sBullet += sStr; + sStr = sBullet; + } + + if( aEndIndex.InBullet() ) + { + // append trailing bullet + sStr += aBulletInfo2.aText;; + } + else if( HaveTextBullet( rSel.nEndPara ) ) + { + // insert bullet + sStr.Insert( aBulletInfo2.aText, + static_cast< USHORT > (GetTextLen(aStartIndex.GetParagraph()) - aStartIndex.GetIndex()) ); + } + + return sStr; +} + +SfxItemSet SvxAccessibleTextAdapter::GetAttribs( const ESelection& rSel, BOOL bOnlyHardAttrib ) const +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + SvxAccessibleTextIndex aStartIndex; + SvxAccessibleTextIndex aEndIndex; + + aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this ); + aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this ); + + return mrTextForwarder->GetAttribs( MakeEESelection(aStartIndex, aEndIndex), + bOnlyHardAttrib ); +} + +SfxItemSet SvxAccessibleTextAdapter::GetParaAttribs( USHORT nPara ) const +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + return mrTextForwarder->GetParaAttribs( nPara ); +} + +void SvxAccessibleTextAdapter::SetParaAttribs( USHORT nPara, const SfxItemSet& rSet ) +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + mrTextForwarder->SetParaAttribs( nPara, rSet ); +} + +void SvxAccessibleTextAdapter::GetPortions( USHORT nPara, SvUShorts& rList ) const +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + mrTextForwarder->GetPortions( nPara, rList ); +} + +USHORT SvxAccessibleTextAdapter::GetItemState( const ESelection& rSel, USHORT nWhich ) const +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + SvxAccessibleTextIndex aStartIndex; + SvxAccessibleTextIndex aEndIndex; + + aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this ); + aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this ); + + return mrTextForwarder->GetItemState( MakeEESelection(aStartIndex, aEndIndex), + nWhich ); +} + +USHORT SvxAccessibleTextAdapter::GetItemState( USHORT nPara, USHORT nWhich ) const +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + return mrTextForwarder->GetItemState( nPara, nWhich ); +} + +void SvxAccessibleTextAdapter::QuickInsertText( const String& rText, const ESelection& rSel ) +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + SvxAccessibleTextIndex aStartIndex; + SvxAccessibleTextIndex aEndIndex; + + aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this ); + aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this ); + + mrTextForwarder->QuickInsertText( rText, + MakeEESelection(aStartIndex, aEndIndex) ); +} + +void SvxAccessibleTextAdapter::QuickInsertField( const SvxFieldItem& rFld, const ESelection& rSel ) +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + SvxAccessibleTextIndex aStartIndex; + SvxAccessibleTextIndex aEndIndex; + + aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this ); + aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this ); + + mrTextForwarder->QuickInsertField( rFld, + MakeEESelection(aStartIndex, aEndIndex) ); +} + +void SvxAccessibleTextAdapter::QuickSetAttribs( const SfxItemSet& rSet, const ESelection& rSel ) +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + SvxAccessibleTextIndex aStartIndex; + SvxAccessibleTextIndex aEndIndex; + + aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this ); + aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this ); + + mrTextForwarder->QuickSetAttribs( rSet, + MakeEESelection(aStartIndex, aEndIndex) ); +} + +void SvxAccessibleTextAdapter::QuickInsertLineBreak( const ESelection& rSel ) +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + SvxAccessibleTextIndex aStartIndex; + SvxAccessibleTextIndex aEndIndex; + + aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this ); + aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this ); + + mrTextForwarder->QuickInsertLineBreak( MakeEESelection(aStartIndex, aEndIndex) ); +} + +SfxItemPool* SvxAccessibleTextAdapter::GetPool() const +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + return mrTextForwarder->GetPool(); +} + +XubString SvxAccessibleTextAdapter::CalcFieldValue( const SvxFieldItem& rField, USHORT nPara, USHORT nPos, Color*& rpTxtColor, Color*& rpFldColor ) +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + return mrTextForwarder->CalcFieldValue( rField, nPara, nPos, rpTxtColor, rpFldColor ); +} + +BOOL SvxAccessibleTextAdapter::IsValid() const +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + if( mrTextForwarder ) + return mrTextForwarder->IsValid(); + else + return sal_False; +} + +LanguageType SvxAccessibleTextAdapter::GetLanguage( USHORT nPara, USHORT nPos ) const +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + SvxAccessibleTextIndex aIndex; + + aIndex.SetIndex( nPara, nPos, *this ); + + return mrTextForwarder->GetLanguage( nPara, aIndex.GetEEIndex() ); +} + +USHORT SvxAccessibleTextAdapter::GetFieldCount( USHORT nPara ) const +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + return mrTextForwarder->GetFieldCount( nPara ); +} + +EFieldInfo SvxAccessibleTextAdapter::GetFieldInfo( USHORT nPara, USHORT nField ) const +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + return mrTextForwarder->GetFieldInfo( nPara, nField ); +} + +EBulletInfo SvxAccessibleTextAdapter::GetBulletInfo( USHORT nPara ) const +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + return mrTextForwarder->GetBulletInfo( nPara ); +} + +Rectangle SvxAccessibleTextAdapter::GetCharBounds( USHORT nPara, USHORT nIndex ) const +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + SvxAccessibleTextIndex aIndex; + aIndex.SetIndex( nPara, nIndex, *this ); + + // preset if anything goes wrong below + // n-th char in GetParagraphIndex's paragraph + Rectangle aRect = mrTextForwarder->GetCharBounds( nPara, static_cast< USHORT >( aIndex.GetEEIndex() ) ); + + if( aIndex.InBullet() ) + { + EBulletInfo aBulletInfo = GetBulletInfo( nPara ); + + OutputDevice* pOutDev = GetRefDevice(); + + DBG_ASSERT(pOutDev!=NULL, "SvxAccessibleTextAdapter::GetCharBounds: No ref device"); + + // preset if anything goes wrong below + aRect = aBulletInfo.aBounds; // better than nothing + if( pOutDev ) + { + SvxAccessibleStringWrap aStringWrap( *pOutDev, aBulletInfo.aFont, aBulletInfo.aText ); + + if( aStringWrap.GetCharacterBounds( aIndex.GetBulletOffset(), aRect ) ) + aRect.Move( aBulletInfo.aBounds.Left(), aBulletInfo.aBounds.Top() ); + } + } + else + { + // handle field content manually + if( aIndex.InField() ) + { + OutputDevice* pOutDev = GetRefDevice(); + + DBG_ASSERT(pOutDev!=NULL, "SvxAccessibleTextAdapter::GetCharBounds: No ref device"); + + if( pOutDev ) + { + ESelection aSel = MakeEESelection( aIndex ); + + SvxFont aFont = EditEngine::CreateSvxFontFromItemSet( mrTextForwarder->GetAttribs( aSel ) ); + SvxAccessibleStringWrap aStringWrap( *pOutDev, + aFont, + mrTextForwarder->GetText( aSel ) ); + + if( !aStringWrap.GetCharacterBounds( aIndex.GetFieldOffset(), aRect ) ) + aRect = mrTextForwarder->GetCharBounds( nPara, static_cast< USHORT >( aIndex.GetEEIndex() ) ); + } + } + } + + return aRect; +} + +Rectangle SvxAccessibleTextAdapter::GetParaBounds( USHORT nPara ) const +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + return mrTextForwarder->GetParaBounds( nPara ); +} + +MapMode SvxAccessibleTextAdapter::GetMapMode() const +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + return mrTextForwarder->GetMapMode(); +} + +OutputDevice* SvxAccessibleTextAdapter::GetRefDevice() const +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + return mrTextForwarder->GetRefDevice(); +} + +sal_Bool SvxAccessibleTextAdapter::GetIndexAtPoint( const Point& rPoint, USHORT& nPara, USHORT& nIndex ) const +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + if( !mrTextForwarder->GetIndexAtPoint( rPoint, nPara, nIndex ) ) + return sal_False; + + SvxAccessibleTextIndex aIndex; + aIndex.SetEEIndex(nPara, nIndex, *this); + + DBG_ASSERT(aIndex.GetIndex() >= 0 && aIndex.GetIndex() <= USHRT_MAX, + "SvxAccessibleTextIndex::SetIndex: index value overflow"); + + nIndex = static_cast< USHORT > (aIndex.GetIndex()); + + EBulletInfo aBulletInfo = GetBulletInfo( nPara ); + + // any text bullets? + if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && + aBulletInfo.bVisible && + aBulletInfo.nType != SVX_NUM_BITMAP ) + { + if( aBulletInfo.aBounds.IsInside( rPoint) ) + { + OutputDevice* pOutDev = GetRefDevice(); + + DBG_ASSERT(pOutDev!=NULL, "SvxAccessibleTextAdapter::GetIndexAtPoint: No ref device"); + + if( !pOutDev ) + return sal_False; + + SvxAccessibleStringWrap aStringWrap( *pOutDev, aBulletInfo.aFont, aBulletInfo.aText ); + + Point aPoint = rPoint; + aPoint.Move( -aBulletInfo.aBounds.Left(), -aBulletInfo.aBounds.Top() ); + + DBG_ASSERT(aStringWrap.GetIndexAtPoint( aPoint ) >= 0 && + aStringWrap.GetIndexAtPoint( aPoint ) <= USHRT_MAX, + "SvxAccessibleTextIndex::SetIndex: index value overflow"); + + nIndex = static_cast< USHORT > (aStringWrap.GetIndexAtPoint( aPoint )); + return sal_True; + } + } + + if( aIndex.InField() ) + { + OutputDevice* pOutDev = GetRefDevice(); + + DBG_ASSERT(pOutDev!=NULL, "SvxAccessibleTextAdapter::GetIndexAtPoint: No ref device"); + + if( !pOutDev ) + return sal_False; + + ESelection aSelection = MakeEESelection( aIndex ); + SvxFont aFont = EditEngine::CreateSvxFontFromItemSet( mrTextForwarder->GetAttribs( aSelection ) ); + SvxAccessibleStringWrap aStringWrap( *pOutDev, + aFont, + mrTextForwarder->GetText( aSelection ) ); + + DBG_ASSERT(aIndex.GetIndex() + aStringWrap.GetIndexAtPoint( rPoint ) >= 0 && + aIndex.GetIndex() + aStringWrap.GetIndexAtPoint( rPoint ) <= USHRT_MAX, + "SvxAccessibleTextIndex::SetIndex: index value overflow"); + + nIndex = static_cast< USHORT >(aIndex.GetIndex() + aStringWrap.GetIndexAtPoint( rPoint )); + return sal_True; + } + + return sal_True; +} + +sal_Bool SvxAccessibleTextAdapter::GetWordIndices( USHORT nPara, USHORT nIndex, USHORT& nStart, USHORT& nEnd ) const +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + SvxAccessibleTextIndex aIndex; + aIndex.SetIndex(nPara, nIndex, *this); + + if( aIndex.InBullet() ) + { + DBG_ASSERT(aIndex.GetBulletLen() >= 0 && + aIndex.GetBulletLen() <= USHRT_MAX, + "SvxAccessibleTextIndex::SetIndex: index value overflow"); + + // always treat bullet as separate word + nStart = 0; + nEnd = static_cast< USHORT > (aIndex.GetBulletLen()); + + return sal_True; + } + + if( aIndex.InField() ) + { + DBG_ASSERT(aIndex.GetIndex() - aIndex.GetFieldOffset() >= 0 && + aIndex.GetIndex() - aIndex.GetFieldOffset() <= USHRT_MAX && + nStart + aIndex.GetFieldLen() >= 0 && + nStart + aIndex.GetFieldLen() <= USHRT_MAX, + "SvxAccessibleTextIndex::SetIndex: index value overflow"); + + // always treat field as separate word + // TODO: to circumvent this, _we_ would have to do the break iterator stuff! + nStart = static_cast< USHORT > (aIndex.GetIndex() - aIndex.GetFieldOffset()); + nEnd = static_cast< USHORT > (nStart + aIndex.GetFieldLen()); + + return sal_True; + } + + if( !mrTextForwarder->GetWordIndices( nPara, nIndex, nStart, nEnd ) ) + return sal_False; + + aIndex.SetEEIndex( nPara, nStart, *this ); + DBG_ASSERT(aIndex.GetIndex() >= 0 && + aIndex.GetIndex() <= USHRT_MAX, + "SvxAccessibleTextIndex::SetIndex: index value overflow"); + nStart = static_cast< USHORT > (aIndex.GetIndex()); + + aIndex.SetEEIndex( nPara, nEnd, *this ); + DBG_ASSERT(aIndex.GetIndex() >= 0 && + aIndex.GetIndex() <= USHRT_MAX, + "SvxAccessibleTextIndex::SetIndex: index value overflow"); + nEnd = static_cast< USHORT > (aIndex.GetIndex()); + + return sal_True; +} + +USHORT SvxAccessibleTextAdapter::GetLineCount( USHORT nPara ) const +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + return mrTextForwarder->GetLineCount( nPara ); +} + +USHORT SvxAccessibleTextAdapter::GetLineLen( USHORT nPara, USHORT nLine ) const +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + return mrTextForwarder->GetLineLen( nPara, nLine ); +} + +sal_Bool SvxAccessibleTextAdapter::Delete( const ESelection& rSel ) +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + SvxAccessibleTextIndex aStartIndex; + SvxAccessibleTextIndex aEndIndex; + + aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this ); + aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this ); + + return mrTextForwarder->Delete( MakeEESelection(aStartIndex, aEndIndex ) ); +} + +sal_Bool SvxAccessibleTextAdapter::InsertText( const String& rStr, const ESelection& rSel ) +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + SvxAccessibleTextIndex aStartIndex; + SvxAccessibleTextIndex aEndIndex; + + aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this ); + aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this ); + + return mrTextForwarder->InsertText( rStr, MakeEESelection(aStartIndex, aEndIndex) ); +} + +sal_Bool SvxAccessibleTextAdapter::QuickFormatDoc( BOOL bFull ) +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + return mrTextForwarder->QuickFormatDoc( bFull ); +} + +void SvxAccessibleTextAdapter::SetForwarder( SvxTextForwarder& rForwarder ) +{ + mrTextForwarder = &rForwarder; +} + +sal_Bool SvxAccessibleTextAdapter::HaveImageBullet( USHORT nPara ) const +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + EBulletInfo aBulletInfo = GetBulletInfo( nPara ); + + if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && + aBulletInfo.bVisible && + aBulletInfo.nType == SVX_NUM_BITMAP ) + { + return sal_True; + } + else + { + return sal_False; + } +} + +sal_Bool SvxAccessibleTextAdapter::HaveTextBullet( USHORT nPara ) const +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + EBulletInfo aBulletInfo = GetBulletInfo( nPara ); + + if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && + aBulletInfo.bVisible && + aBulletInfo.nType != SVX_NUM_BITMAP ) + { + return sal_True; + } + else + { + return sal_False; + } +} + +sal_Bool SvxAccessibleTextAdapter::IsEditable( const ESelection& rSel ) +{ + DBG_ASSERT(mrTextForwarder, "SvxAccessibleTextAdapter: no forwarder"); + + SvxAccessibleTextIndex aStartIndex; + SvxAccessibleTextIndex aEndIndex; + + aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this ); + aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this ); + + // normalize selection + if( rSel.nStartPara > rSel.nEndPara || + (rSel.nStartPara == rSel.nEndPara && rSel.nStartPos > rSel.nEndPos) ) + { + ::std::swap( aStartIndex, aEndIndex ); + } + + return aStartIndex.IsEditableRange( aEndIndex ); +} + + +//--------------------------------------------------------------------------------------- + +SvxAccessibleTextEditViewAdapter::SvxAccessibleTextEditViewAdapter() +{ +} + +SvxAccessibleTextEditViewAdapter::~SvxAccessibleTextEditViewAdapter() +{ +} + +BOOL SvxAccessibleTextEditViewAdapter::IsValid() const +{ + DBG_ASSERT(mrViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder"); + + if( mrViewForwarder ) + return mrViewForwarder->IsValid(); + else + return sal_False; +} + +Rectangle SvxAccessibleTextEditViewAdapter::GetVisArea() const +{ + DBG_ASSERT(mrViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder"); + + return mrViewForwarder->GetVisArea(); +} + +Point SvxAccessibleTextEditViewAdapter::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const +{ + DBG_ASSERT(mrViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder"); + + return mrViewForwarder->LogicToPixel(rPoint, rMapMode); +} + +Point SvxAccessibleTextEditViewAdapter::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const +{ + DBG_ASSERT(mrViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder"); + + return mrViewForwarder->PixelToLogic(rPoint, rMapMode); +} + +sal_Bool SvxAccessibleTextEditViewAdapter::GetSelection( ESelection& rSel ) const +{ + DBG_ASSERT(mrViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder"); + + ESelection aSelection; + + if( !mrViewForwarder->GetSelection( aSelection ) ) + return sal_False; + + SvxAccessibleTextIndex aStartIndex; + SvxAccessibleTextIndex aEndIndex; + + aStartIndex.SetEEIndex( aSelection.nStartPara, aSelection.nStartPos, *mrTextForwarder ); + aEndIndex.SetEEIndex( aSelection.nEndPara, aSelection.nEndPos, *mrTextForwarder ); + + rSel = MakeEESelection( aStartIndex, aEndIndex ); + + return sal_True; +} + +sal_Bool SvxAccessibleTextEditViewAdapter::SetSelection( const ESelection& rSel ) +{ + DBG_ASSERT(mrViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder"); + + SvxAccessibleTextIndex aStartIndex; + SvxAccessibleTextIndex aEndIndex; + + aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *mrTextForwarder ); + aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *mrTextForwarder ); + + return mrViewForwarder->SetSelection( MakeEESelection(aStartIndex, aEndIndex) ); +} + +sal_Bool SvxAccessibleTextEditViewAdapter::Copy() +{ + DBG_ASSERT(mrViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder"); + + return mrViewForwarder->Copy(); +} + +sal_Bool SvxAccessibleTextEditViewAdapter::Cut() +{ + DBG_ASSERT(mrViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder"); + + return mrViewForwarder->Cut(); +} + +sal_Bool SvxAccessibleTextEditViewAdapter::Paste() +{ + DBG_ASSERT(mrViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder"); + + return mrViewForwarder->Paste(); +} + +void SvxAccessibleTextEditViewAdapter::SetForwarder( SvxEditViewForwarder& rForwarder, + SvxAccessibleTextAdapter& rTextForwarder ) +{ + mrViewForwarder = &rForwarder; + mrTextForwarder = &rTextForwarder; +} diff --git a/svx/source/unoedit/unopracc.cxx b/svx/source/unoedit/unopracc.cxx new file mode 100644 index 000000000000..6ae3522408bc --- /dev/null +++ b/svx/source/unoedit/unopracc.cxx @@ -0,0 +1,227 @@ +/************************************************************************* + * + * $RCSfile: unopracc.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: thb $ $Date: 2002-05-16 16:12:04 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#pragma hdrstop + +//------------------------------------------------------------------------ +// +// Global header +// +//------------------------------------------------------------------------ + +#ifndef _VOS_MUTEX_HXX_ +#include <vos/mutex.hxx> +#endif + +#ifndef _COM_SUN_STAR_UNO_ANY_HXX_ +#include <com/sun/star/uno/Any.hxx> +#endif + +#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_ +#include <com/sun/star/uno/Reference.hxx> +#endif + +#ifndef _CPPUHELPER_WEAKREF_HXX_ +#include <cppuhelper/weakref.hxx> +#endif + +#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_ +#include <com/sun/star/lang/XComponent.hpp> +#endif + +#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_ +#include <cppuhelper/typeprovider.hxx> +#endif + + +//------------------------------------------------------------------------ +// +// Project-local header +// +//------------------------------------------------------------------------ + +#ifndef _SVX_UNOPRACC_HXX_ +#include "unopracc.hxx" +#endif + +#ifndef _SVX_UNOEDSRC_HXX +#include "unoedsrc.hxx" +#endif + +using namespace ::com::sun::star; + +//------------------------------------------------------------------------ +// +// SvxAccessibleTextPropertySet implementation +// +//------------------------------------------------------------------------ + +SvxAccessibleTextPropertySet::SvxAccessibleTextPropertySet( const SvxEditSource* pEditSrc, const SfxItemPropertyMap* pPropMap ) + : SvxUnoTextRangeBase( pEditSrc, pPropMap ) +{ +} + +SvxAccessibleTextPropertySet::~SvxAccessibleTextPropertySet() throw() +{ +} + +uno::Reference< text::XText > SAL_CALL SvxAccessibleTextPropertySet::getText() throw (uno::RuntimeException) +{ + // TODO (empty?) + return uno::Reference< text::XText > (); +} + +uno::Any SAL_CALL SvxAccessibleTextPropertySet::queryAggregation( const uno::Type & rType ) throw(uno::RuntimeException) +{ + // TODO (empty?) + return uno::Any(); +} + +uno::Any SAL_CALL SvxAccessibleTextPropertySet::queryInterface( const uno::Type & rType ) + throw(uno::RuntimeException) +{ + return OWeakObject::queryInterface(rType); +} + +void SAL_CALL SvxAccessibleTextPropertySet::acquire() + throw() +{ + OWeakObject::acquire(); +} + +void SAL_CALL SvxAccessibleTextPropertySet::release() + throw() +{ + OWeakObject::release(); +} + +// XTypeProvider +uno::Sequence< uno::Type > SAL_CALL SvxAccessibleTextPropertySet::getTypes() throw ( uno::RuntimeException ) +{ + static ::cppu::OTypeCollection* pTypeCollection = NULL ; + + // double-checked locking pattern. + if ( pTypeCollection == NULL ) + { + osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; + + // Control these pointer again ... it can be, that another instance will be faster then these! + if ( pTypeCollection == NULL ) + { + // Create a static typecollection ... + static ::cppu::OTypeCollection aTypeCollection( + ::getCppuType( static_cast< const uno::Reference< beans::XPropertySet >* > (0) ), + ::getCppuType( static_cast< const uno::Reference< beans::XMultiPropertySet >* > (0) ), + ::getCppuType( static_cast< const uno::Reference< beans::XPropertyState >* > (0) ), + ::getCppuType( static_cast< const uno::Reference< lang::XServiceInfo >* > (0) ), + ::getCppuType( static_cast< const uno::Reference< lang::XTypeProvider >* > (0) ) ); + + // ... and set his address to static pointer! + pTypeCollection = &aTypeCollection ; + } + } + + return pTypeCollection->getTypes() ; +} + +uno::Sequence< sal_Int8 > SAL_CALL SvxAccessibleTextPropertySet::getImplementationId() + throw (uno::RuntimeException) +{ + static uno::Sequence< sal_Int8 > aId; + if( aId.getLength() == 0 ) + { + aId.realloc( 16 ); + rtl_createUuid( reinterpret_cast< sal_uInt8* > (aId.getArray()), 0, sal_True ); + } + return aId; +} + +// XServiceInfo +::rtl::OUString SAL_CALL SAL_CALL SvxAccessibleTextPropertySet::getImplementationName (void) throw (uno::RuntimeException) +{ + return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("SvxAccessibleTextPropertySet")); +} + +sal_Bool SAL_CALL SvxAccessibleTextPropertySet::supportsService (const ::rtl::OUString& sServiceName) throw (uno::RuntimeException) +{ + // Iterate over all supported service names and return true if on of them + // matches the given name. + uno::Sequence< ::rtl::OUString> aSupportedServices ( + getSupportedServiceNames ()); + for (int i=0; i<aSupportedServices.getLength(); i++) + if (sServiceName == aSupportedServices[i]) + return sal_True; + return sal_False; +} + +uno::Sequence< ::rtl::OUString> SAL_CALL SvxAccessibleTextPropertySet::getSupportedServiceNames (void) throw (uno::RuntimeException) +{ + // TODO + return SvxUnoTextRangeBase::getSupportedServiceNames(); +} + +// XServiceName +::rtl::OUString SAL_CALL SvxAccessibleTextPropertySet::getServiceName() throw (uno::RuntimeException) +{ + return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.beans.PropertyValue")); +} + + |