diff options
Diffstat (limited to 'forms/source/richtext')
29 files changed, 6283 insertions, 0 deletions
diff --git a/forms/source/richtext/attributedispatcher.cxx b/forms/source/richtext/attributedispatcher.cxx new file mode 100644 index 000000000000..82df2c3fbbf1 --- /dev/null +++ b/forms/source/richtext/attributedispatcher.cxx @@ -0,0 +1,138 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_forms.hxx" +#include "attributedispatcher.hxx" + +/** === begin UNO includes === **/ +/** === end UNO includes === **/ +#include <editeng/editview.hxx> + +//........................................................................ +namespace frm +{ +//........................................................................ + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::frame; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::util; + using namespace ::com::sun::star::beans; + + //==================================================================== + //= OAttributeDispatcher + //==================================================================== + //-------------------------------------------------------------------- + OAttributeDispatcher::OAttributeDispatcher( EditView& _rView, AttributeId _nAttributeId, const URL& _rURL, + IMultiAttributeDispatcher* _pMasterDispatcher ) + :ORichTextFeatureDispatcher( _rView, _rURL ) + ,m_pMasterDispatcher( _pMasterDispatcher ) + ,m_nAttributeId( _nAttributeId ) + { + OSL_ENSURE( m_pMasterDispatcher, "OAttributeDispatcher::OAttributeDispatcher: invalid master dispatcher!" ); + } + + //-------------------------------------------------------------------- + OAttributeDispatcher::~OAttributeDispatcher( ) + { + acquire(); + dispose(); + } + + //-------------------------------------------------------------------- + void OAttributeDispatcher::disposing( ::osl::ClearableMutexGuard& _rClearBeforeNotify ) + { + m_pMasterDispatcher = NULL; + ORichTextFeatureDispatcher::disposing( _rClearBeforeNotify ); + } + + //-------------------------------------------------------------------- + void OAttributeDispatcher::fillFeatureEventFromAttributeState( FeatureStateEvent& _rEvent, const AttributeState& _rState ) const + { + if ( _rState.eSimpleState == eChecked ) + _rEvent.State <<= (sal_Bool)sal_True; + else if ( _rState.eSimpleState == eUnchecked ) + _rEvent.State <<= (sal_Bool)sal_False; + } + + //-------------------------------------------------------------------- + FeatureStateEvent OAttributeDispatcher::buildStatusEvent() const + { + FeatureStateEvent aEvent( ORichTextFeatureDispatcher::buildStatusEvent() ); + aEvent.IsEnabled = getEditView() ? !getEditView()->IsReadOnly() : sal_False; + + AttributeState aState; + if ( m_pMasterDispatcher ) + aState = m_pMasterDispatcher->getState( m_nAttributeId ); + + fillFeatureEventFromAttributeState( aEvent, aState ); + + return aEvent; + } + + //-------------------------------------------------------------------- + void SAL_CALL OAttributeDispatcher::dispatch( const URL& _rURL, const Sequence< PropertyValue >& _rArguments ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + checkDisposed(); + + (void)_rURL; + (void)_rArguments; + + OSL_ENSURE( _rURL.Complete == getFeatureURL().Complete, "OAttributeDispatcher::dispatch: invalid URL!" ); +#if OSL_DEBUG_LEVEL > 0 + if ( _rArguments.getLength() ) + { + ::rtl::OString sMessage( "OAttributeDispatcher::dispatch: found arguments, but can't handle arguments at all" ); + sMessage += "\n (URL: "; + sMessage += ::rtl::OString( _rURL.Complete.getStr(), _rURL.Complete.getLength(), RTL_TEXTENCODING_ASCII_US ); + sMessage += ")"; + DBG_ERROR( sMessage.getStr() ); + } +#endif + + if ( m_pMasterDispatcher ) + m_pMasterDispatcher->executeAttribute( m_nAttributeId, NULL ); + } + + //-------------------------------------------------------------------- + void OAttributeDispatcher::onAttributeStateChanged( AttributeId _nAttributeId, const AttributeState& /*_rState*/ ) + { + OSL_ENSURE( _nAttributeId == m_nAttributeId, "OAttributeDispatcher::onAttributeStateChanged: wrong attribute!" ); + (void)_nAttributeId; + + FeatureStateEvent aEvent( buildStatusEvent() ); + ::cppu::OInterfaceIteratorHelper aIter( getStatusListeners() ); + while ( aIter.hasMoreElements() ) + doNotify( static_cast< XStatusListener* >( aIter.next() ), aEvent ); + } + +//........................................................................ +} // namespace frm +//........................................................................ diff --git a/forms/source/richtext/attributedispatcher.hxx b/forms/source/richtext/attributedispatcher.hxx new file mode 100644 index 000000000000..6c9b7b461267 --- /dev/null +++ b/forms/source/richtext/attributedispatcher.hxx @@ -0,0 +1,104 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef FORMS_SOURCE_RICHTEXT_ATTRIBUTEDISPATCHER_HXX +#define FORMS_SOURCE_RICHTEXT_ATTRIBUTEDISPATCHER_HXX + +#include "featuredispatcher.hxx" +#include "rtattributes.hxx" +#include "textattributelistener.hxx" + +//........................................................................ +namespace frm +{ +//........................................................................ + + //==================================================================== + //= OAttributeDispatcher + //==================================================================== + class OAttributeDispatcher :public ORichTextFeatureDispatcher + ,public ITextAttributeListener + { + protected: + IMultiAttributeDispatcher* m_pMasterDispatcher; + AttributeId m_nAttributeId; + + public: + /** ctor + @param _nAttributeId + the id of the attribute which this instance is responsible for + @param _rURL + the URL of the feature which this instance is responsible for + @param _pMasterDispatcher + the dispatcher which can execute the given attribute + @param _pConverter + an instance which is able to convert between SfxPoolItems and XDispatch-Parameters + If not <NULL/>, the parametrized version of IMultiAttributeDispatcher::executeAttribute + will be used. + */ + OAttributeDispatcher( + EditView& _rView, + AttributeId _nAttributeId, + const ::com::sun::star::util::URL& _rURL, + IMultiAttributeDispatcher* _pMasterDispatcher + ); + + /// notifies a new attribute state + void notifyAttributeState( const AttributeState& _rState ) SAL_THROW (()); + + protected: + ~OAttributeDispatcher( ); + + protected: + // XDispatch + virtual void SAL_CALL dispatch( const ::com::sun::star::util::URL& URL, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& Arguments ) throw (::com::sun::star::uno::RuntimeException); + + // ITextAttributeListener + virtual void onAttributeStateChanged( AttributeId _nAttributeId, const AttributeState& _rState ); + + // ORichTextFeatureDispatcher + virtual void disposing( ::osl::ClearableMutexGuard& _rClearBeforeNotify ); + + // ORichTextFeatureDispatcher + virtual ::com::sun::star::frame::FeatureStateEvent buildStatusEvent() const; + + // own overridables + virtual void fillFeatureEventFromAttributeState( ::com::sun::star::frame::FeatureStateEvent& _rEvent, const AttributeState& _rState ) const; + + protected: + /// notifies our feature state to one particular listener + void notifyState( + const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener >& _rxControl, + const AttributeState& _rState + ) SAL_THROW (()); + }; + +//........................................................................ +} // namespace frm +//........................................................................ + +#endif // FORMS_SOURCE_RICHTEXT_ATTRIBUTEDISPATCHER_HXX + diff --git a/forms/source/richtext/clipboarddispatcher.cxx b/forms/source/richtext/clipboarddispatcher.cxx new file mode 100644 index 000000000000..97b2ec1cba84 --- /dev/null +++ b/forms/source/richtext/clipboarddispatcher.cxx @@ -0,0 +1,208 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_forms.hxx" +#include "clipboarddispatcher.hxx" +#include <editeng/editview.hxx> + +/** === begin UNO includes === **/ +#include <com/sun/star/lang/DisposedException.hpp> +/** === end UNO includes === **/ +#include <svtools/cliplistener.hxx> +#include <svtools/transfer.hxx> + +//........................................................................ +namespace frm +{ +//........................................................................ + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::frame; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::util; + using namespace ::com::sun::star::beans; + + //==================================================================== + namespace + { + static URL createClipboardURL( OClipboardDispatcher::ClipboardFunc _eFunc ) + { + URL aURL; + switch ( _eFunc ) + { + case OClipboardDispatcher::eCut: + aURL.Complete = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:Cut" ) ); + break; + case OClipboardDispatcher::eCopy: + aURL.Complete = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:Copy" ) ); + break; + case OClipboardDispatcher::ePaste: + aURL.Complete = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:Paste" ) ); + break; + } + return aURL; + } + } + + //==================================================================== + //= OClipboardDispatcher + //==================================================================== + //-------------------------------------------------------------------- + OClipboardDispatcher::OClipboardDispatcher( EditView& _rView, ClipboardFunc _eFunc ) + :ORichTextFeatureDispatcher( _rView, createClipboardURL( _eFunc ) ) + ,m_eFunc( _eFunc ) + ,m_bLastKnownEnabled( sal_True ) + { + } + + //-------------------------------------------------------------------- + sal_Bool OClipboardDispatcher::implIsEnabled( ) const + { + sal_Bool bEnabled = sal_False; + switch ( m_eFunc ) + { + case eCut: + bEnabled = !getEditView()->IsReadOnly() && getEditView()->HasSelection(); + break; + + case eCopy: + bEnabled = getEditView()->HasSelection(); + break; + + case ePaste: + bEnabled = !getEditView()->IsReadOnly(); + break; + } + return bEnabled; + } + + //-------------------------------------------------------------------- + FeatureStateEvent OClipboardDispatcher::buildStatusEvent() const + { + FeatureStateEvent aEvent( ORichTextFeatureDispatcher::buildStatusEvent() ); + aEvent.IsEnabled = implIsEnabled(); + return aEvent; + } + + //-------------------------------------------------------------------- + void OClipboardDispatcher::invalidateFeatureState_Broadcast() + { + sal_Bool bEnabled = implIsEnabled(); + if ( m_bLastKnownEnabled == bEnabled ) + // nothing changed -> no notification + return; + m_bLastKnownEnabled = bEnabled; + + ORichTextFeatureDispatcher::invalidateFeatureState_Broadcast(); + } + + //-------------------------------------------------------------------- + void SAL_CALL OClipboardDispatcher::dispatch( const URL& /*_rURL*/, const Sequence< PropertyValue >& /*Arguments*/ ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + if ( !getEditView() ) + throw DisposedException(); + + switch ( m_eFunc ) + { + case eCut: + getEditView()->Cut(); + break; + + case eCopy: + getEditView()->Copy(); + break; + + case ePaste: + getEditView()->Paste(); + break; + } + } + + //==================================================================== + //= OPasteClipboardDispatcher + //==================================================================== + //-------------------------------------------------------------------- + OPasteClipboardDispatcher::OPasteClipboardDispatcher( EditView& _rView ) + :OClipboardDispatcher( _rView, ePaste ) + ,m_pClipListener( NULL ) + ,m_bPastePossible( sal_False ) + { + m_pClipListener = new TransferableClipboardListener( LINK( this, OPasteClipboardDispatcher, OnClipboardChanged ) ); + m_pClipListener->acquire(); + m_pClipListener->AddRemoveListener( _rView.GetWindow(), TRUE ); + + // initial state + TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( _rView.GetWindow() ) ); + m_bPastePossible = ( aDataHelper.HasFormat( SOT_FORMAT_STRING ) || aDataHelper.HasFormat( SOT_FORMAT_RTF ) ); + } + + //-------------------------------------------------------------------- + OPasteClipboardDispatcher::~OPasteClipboardDispatcher() + { + if ( !isDisposed() ) + { + acquire(); + dispose(); + } + } + + //-------------------------------------------------------------------- + IMPL_LINK( OPasteClipboardDispatcher, OnClipboardChanged, TransferableDataHelper*, _pDataHelper ) + { + OSL_ENSURE( _pDataHelper, "OPasteClipboardDispatcher::OnClipboardChanged: ooops!" ); + m_bPastePossible = _pDataHelper->HasFormat( SOT_FORMAT_STRING ) + || _pDataHelper->HasFormat( SOT_FORMAT_RTF ); + + invalidate(); + + return 0L; + } + + //-------------------------------------------------------------------- + void OPasteClipboardDispatcher::disposing( ::osl::ClearableMutexGuard& _rClearBeforeNotify ) + { + OSL_ENSURE( getEditView() && getEditView()->GetWindow(), "OPasteClipboardDispatcher::disposing: EditView should not (yet) be disfunctional here!" ); + if ( getEditView() && getEditView()->GetWindow() && m_pClipListener ) + m_pClipListener->AddRemoveListener( getEditView()->GetWindow(), FALSE ); + m_pClipListener->release(); + m_pClipListener = NULL; + + OClipboardDispatcher::disposing( _rClearBeforeNotify ); + } + + //-------------------------------------------------------------------- + sal_Bool OPasteClipboardDispatcher::implIsEnabled( ) const + { + return m_bPastePossible && OClipboardDispatcher::implIsEnabled(); + } + +//........................................................................ +} // namespace frm +//........................................................................ + diff --git a/forms/source/richtext/clipboarddispatcher.hxx b/forms/source/richtext/clipboarddispatcher.hxx new file mode 100644 index 000000000000..a9e6bd7417c1 --- /dev/null +++ b/forms/source/richtext/clipboarddispatcher.hxx @@ -0,0 +1,107 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef FORMS_SOURCE_RICHTEXT_CLIPBOARDDISPATCHER_HXX +#define FORMS_SOURCE_RICHTEXT_CLIPBOARDDISPATCHER_HXX + +#include "featuredispatcher.hxx" +#include <tools/link.hxx> + +class TransferableClipboardListener; +class TransferableDataHelper; +//........................................................................ +namespace frm +{ +//........................................................................ + + //==================================================================== + //= OClipboardDispatcher + //==================================================================== + class OClipboardDispatcher : public ORichTextFeatureDispatcher + { + public: + enum ClipboardFunc + { + eCut, + eCopy, + ePaste + }; + + private: + ClipboardFunc m_eFunc; + sal_Bool m_bLastKnownEnabled; + + public: + OClipboardDispatcher( EditView& _rView, ClipboardFunc _eFunc ); + + protected: + // XDispatch + virtual void SAL_CALL dispatch( const ::com::sun::star::util::URL& URL, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& Arguments ) throw (::com::sun::star::uno::RuntimeException); + + // ORichTextFeatureDispatcher + virtual void invalidateFeatureState_Broadcast(); + virtual ::com::sun::star::frame::FeatureStateEvent + buildStatusEvent() const; + + protected: + /** determines whether our functionality is currently available + to be overridden for ePaste + */ + virtual sal_Bool implIsEnabled( ) const; + }; + + //==================================================================== + //= OPasteClipboardDispatcher + //==================================================================== + class OPasteClipboardDispatcher : public OClipboardDispatcher + { + private: + TransferableClipboardListener* m_pClipListener; + sal_Bool m_bPastePossible; + + public: + OPasteClipboardDispatcher( EditView& _rView ); + + protected: + ~OPasteClipboardDispatcher(); + + // OClipboardDispatcher + virtual sal_Bool implIsEnabled( ) const; + + // ORichTextFeatureDispatcher + virtual void disposing( ::osl::ClearableMutexGuard& _rClearBeforeNotify ); + + private: + DECL_LINK( OnClipboardChanged, TransferableDataHelper* ); + }; + +//........................................................................ +} // namespace frm +//........................................................................ + +#endif // FORMS_SOURCE_RICHTEXT_CLIPBOARDDISPATCHER_HXX + diff --git a/forms/source/richtext/featuredispatcher.cxx b/forms/source/richtext/featuredispatcher.cxx new file mode 100644 index 000000000000..d24e625e0f33 --- /dev/null +++ b/forms/source/richtext/featuredispatcher.cxx @@ -0,0 +1,157 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_forms.hxx" +#include "featuredispatcher.hxx" + +/** === begin UNO includes === **/ +/** === end UNO includes === **/ + +//........................................................................ +namespace frm +{ +//........................................................................ + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::frame; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::util; + + //==================================================================== + //= ORichTextFeatureDispatcher + //==================================================================== + //-------------------------------------------------------------------- + ORichTextFeatureDispatcher::ORichTextFeatureDispatcher( EditView& _rView, const URL& _rURL ) + :m_aFeatureURL( _rURL ) + ,m_aStatusListeners( m_aMutex ) + ,m_pEditView( &_rView ) + ,m_bDisposed( false ) + { + } + + //-------------------------------------------------------------------- + ORichTextFeatureDispatcher::~ORichTextFeatureDispatcher( ) + { + if ( !m_bDisposed ) + { + acquire(); + dispose(); + } + } + + //-------------------------------------------------------------------- + void ORichTextFeatureDispatcher::dispose() + { + EventObject aEvent( *this ); + m_aStatusListeners.disposeAndClear( aEvent ); + + ::osl::ClearableMutexGuard aGuard( m_aMutex ); + m_bDisposed = true; + disposing( aGuard ); + } + + //-------------------------------------------------------------------- + void ORichTextFeatureDispatcher::disposing( ::osl::ClearableMutexGuard& /*_rClearBeforeNotify*/ ) + { + m_pEditView = NULL; + } + + //-------------------------------------------------------------------- + void SAL_CALL ORichTextFeatureDispatcher::addStatusListener( const Reference< XStatusListener >& _rxControl, const URL& _rURL ) throw (RuntimeException) + { + OSL_ENSURE( !m_bDisposed, "ORichTextFeatureDispatcher::addStatusListener: already disposed!" ); + if ( m_bDisposed ) + throw DisposedException(); + + OSL_ENSURE( _rURL.Complete == getFeatureURL().Complete, "ORichTextFeatureDispatcher::addStatusListener: invalid URL!" ); + if ( _rURL.Complete == getFeatureURL().Complete ) + if ( _rxControl.is() ) + { + m_aStatusListeners.addInterface( _rxControl ); + newStatusListener( _rxControl ); + } + } + + //-------------------------------------------------------------------- + void SAL_CALL ORichTextFeatureDispatcher::removeStatusListener( const Reference< XStatusListener >& _rxControl, const URL& /*_rURL*/ ) throw (RuntimeException) + { + m_aStatusListeners.removeInterface( _rxControl ); + } + + //-------------------------------------------------------------------- + void ORichTextFeatureDispatcher::invalidate() + { + invalidateFeatureState_Broadcast(); + } + + //-------------------------------------------------------------------- + FeatureStateEvent ORichTextFeatureDispatcher::buildStatusEvent() const + { + FeatureStateEvent aEvent; + aEvent.IsEnabled = sal_False; + aEvent.Source = *const_cast< ORichTextFeatureDispatcher* >( this ); + aEvent.FeatureURL = getFeatureURL(); + aEvent.Requery = sal_False; + return aEvent; + } + + //-------------------------------------------------------------------- + void ORichTextFeatureDispatcher::invalidateFeatureState_Broadcast() + { + FeatureStateEvent aEvent( buildStatusEvent() ); + ::cppu::OInterfaceIteratorHelper aIter( getStatusListeners() ); + while ( aIter.hasMoreElements() ) + doNotify( static_cast< XStatusListener* >( aIter.next() ), aEvent ); + } + + //-------------------------------------------------------------------- + void ORichTextFeatureDispatcher::newStatusListener( const Reference< XStatusListener >& _rxListener ) + { + doNotify( _rxListener, buildStatusEvent() ); + } + + //-------------------------------------------------------------------- + void ORichTextFeatureDispatcher::doNotify( const Reference< XStatusListener >& _rxListener, const FeatureStateEvent& _rEvent ) const SAL_THROW(()) + { + OSL_PRECOND( _rxListener.is(), "ORichTextFeatureDispatcher::doNotify: invalid listener!" ); + if ( _rxListener.is() ) + { + try + { + _rxListener->statusChanged( _rEvent ); + } + catch( const Exception& ) + { + OSL_ENSURE( sal_False, "ORichTextFeatureDispatcher::doNotify: caught an exception!" ); + } + } + } + +//........................................................................ +} // namespace frm +//........................................................................ diff --git a/forms/source/richtext/featuredispatcher.hxx b/forms/source/richtext/featuredispatcher.hxx new file mode 100644 index 000000000000..9a8252a21783 --- /dev/null +++ b/forms/source/richtext/featuredispatcher.hxx @@ -0,0 +1,107 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef FORMS_SOURCE_RICHTEXT_FEATUREDISPATCHER_HXX +#define FORMS_SOURCE_RICHTEXT_FEATUREDISPATCHER_HXX + +/** === begin UNO includes === **/ +#include <com/sun/star/frame/XDispatch.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +/** === end UNO includes === **/ +#include <cppuhelper/interfacecontainer.hxx> +#include <cppuhelper/implbase1.hxx> +#include <comphelper/broadcasthelper.hxx> + +class EditView; +//........................................................................ +namespace frm +{ +//........................................................................ + + //==================================================================== + //= ORichTextFeatureDispatcher + //==================================================================== + typedef ::cppu::WeakImplHelper1 < ::com::sun::star::frame::XDispatch + > ORichTextFeatureDispatcher_Base; + + class ORichTextFeatureDispatcher :public ::comphelper::OBaseMutex + ,public ORichTextFeatureDispatcher_Base + { + private: + ::com::sun::star::util::URL m_aFeatureURL; + ::cppu::OInterfaceContainerHelper m_aStatusListeners; + EditView* m_pEditView; + bool m_bDisposed; + + protected: + EditView* getEditView() { return m_pEditView; } + const EditView* getEditView() const { return m_pEditView; } + + protected: + inline const ::com::sun::star::util::URL& getFeatureURL() const { return m_aFeatureURL; } + inline ::cppu::OInterfaceContainerHelper& getStatusListeners() { return m_aStatusListeners; } + inline bool isDisposed() const { return m_bDisposed; } + inline void checkDisposed() const { if ( isDisposed() ) throw ::com::sun::star::lang::DisposedException(); } + + protected: + ORichTextFeatureDispatcher( EditView& _rView, const ::com::sun::star::util::URL& _rURL ); + ~ORichTextFeatureDispatcher( ); + + public: + /// clean up resources associated with this instance + void dispose(); + + // invalidate the feature, re-retrieve it's state, and broadcast changes, if necessary + void invalidate(); + + protected: + // overridables + virtual void newStatusListener( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener >& _rxListener ); + virtual void disposing( ::osl::ClearableMutexGuard& _rClearBeforeNotify ); + virtual void invalidateFeatureState_Broadcast(); + + // to be overridden, and filled with the info special do your derived class + virtual ::com::sun::star::frame::FeatureStateEvent + buildStatusEvent() const; + + void doNotify( + const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener >& _rxListener, + const ::com::sun::star::frame::FeatureStateEvent& _rEvent + ) const SAL_THROW(()); + + protected: + // XDispatch + virtual void SAL_CALL addStatusListener( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener >& _rxControl, const ::com::sun::star::util::URL& _rURL ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeStatusListener( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener >& _rxControl, const ::com::sun::star::util::URL& _rURL ) throw (::com::sun::star::uno::RuntimeException); + }; + +//........................................................................ +} // namespace frm +//........................................................................ + +#endif // FORMS_SOURCE_RICHTEXT_FEATUREDISPATCHER_HXX + diff --git a/forms/source/richtext/makefile.mk b/forms/source/richtext/makefile.mk new file mode 100644 index 000000000000..5c62a1a9e675 --- /dev/null +++ b/forms/source/richtext/makefile.mk @@ -0,0 +1,60 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org 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 version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. +PRJINC=.. +PRJNAME=forms +TARGET=richtext + +# --- Settings ---------------------------------- + +.INCLUDE : settings.mk +.INCLUDE: $(PRJ)$/makefile.pmk + +# --- Files ------------------------------------- + +EXCEPTIONSFILES=\ + $(SLO)$/richtextunowrapper.obj \ + $(SLO)$/richtextmodel.obj \ + $(SLO)$/richtextcontrol.obj \ + $(SLO)$/featuredispatcher.obj \ + $(SLO)$/clipboarddispatcher.obj \ + $(SLO)$/attributedispatcher.obj \ + $(SLO)$/parametrizedattributedispatcher.obj \ + $(SLO)$/specialdispatchers.obj \ + $(SLO)$/richtextengine.obj \ + $(SLO)$/richtextimplcontrol.obj + +SLOFILES= $(EXCEPTIONSFILES) \ + $(SLO)$/richtextvclcontrol.obj \ + $(SLO)$/richtextviewport.obj \ + $(SLO)$/rtattributehandler.obj \ + +# --- Targets ---------------------------------- + +.INCLUDE : target.mk + diff --git a/forms/source/richtext/parametrizedattributedispatcher.cxx b/forms/source/richtext/parametrizedattributedispatcher.cxx new file mode 100644 index 000000000000..60791969c119 --- /dev/null +++ b/forms/source/richtext/parametrizedattributedispatcher.cxx @@ -0,0 +1,143 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_forms.hxx" +#include "parametrizedattributedispatcher.hxx" +#include <editeng/editview.hxx> +#include <svl/itemset.hxx> +#include <svl/itempool.hxx> + +#ifndef _SVX_SVXIDS_HRC +#include <svx/svxids.hrc> +#endif +#include <sfx2/sfxuno.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> + +//........................................................................ +namespace frm +{ +//........................................................................ + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::frame; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::util; + using namespace ::com::sun::star::beans; + + //==================================================================== + //= OParametrizedAttributeDispatcher + //==================================================================== + //-------------------------------------------------------------------- + OParametrizedAttributeDispatcher::OParametrizedAttributeDispatcher( EditView& _rView, AttributeId _nAttributeId, const URL& _rURL, IMultiAttributeDispatcher* _pMasterDispatcher ) + :OAttributeDispatcher( _rView, _nAttributeId, _rURL, _pMasterDispatcher ) + { + } + + //-------------------------------------------------------------------- + OParametrizedAttributeDispatcher::~OParametrizedAttributeDispatcher() + { + acquire(); + dispose(); + } + + //-------------------------------------------------------------------- + namespace + { + static SfxSlotId lcl_normalizeLatinScriptSlotId( SfxSlotId _nSlotId ) + { + switch ( _nSlotId ) + { + case SID_ATTR_CHAR_LATIN_FONT: return SID_ATTR_CHAR_FONT; + case SID_ATTR_CHAR_LATIN_LANGUAGE: return SID_ATTR_CHAR_LANGUAGE; + case SID_ATTR_CHAR_LATIN_POSTURE: return SID_ATTR_CHAR_POSTURE; + case SID_ATTR_CHAR_LATIN_WEIGHT: return SID_ATTR_CHAR_WEIGHT; + case SID_ATTR_CHAR_LATIN_FONTHEIGHT:return SID_ATTR_CHAR_FONTHEIGHT; + } + return _nSlotId; + } + } + + //-------------------------------------------------------------------- + void OParametrizedAttributeDispatcher::fillFeatureEventFromAttributeState( FeatureStateEvent& _rEvent, const AttributeState& _rState ) const + { + OSL_ENSURE( getEditView(), "OParametrizedAttributeDispatcher::notifyState: already disposed!" ); + if ( !getEditView() ) + return; + + SfxItemSet aEmptySet( const_cast< EditView* >( getEditView() )->GetEmptyItemSet() ); + Sequence< PropertyValue > aUnoStateDescription; + if ( _rState.getItem() ) + { + aEmptySet.Put( *_rState.getItem() ); + SfxSlotId nSlotId = aEmptySet.GetPool()->GetSlotId( _rState.getItem()->Which() ); + TransformItems( nSlotId, aEmptySet, aUnoStateDescription ); + _rEvent.State <<= aUnoStateDescription; + } + else + OAttributeDispatcher::fillFeatureEventFromAttributeState( _rEvent, _rState ); + } + + //-------------------------------------------------------------------- + const SfxPoolItem* OParametrizedAttributeDispatcher::convertDispatchArgsToItem( const Sequence< PropertyValue >& _rArguments ) + { + // get the real slot id. This may differ from our attribute id: for instance, both + // SID_ATTR_CHAR_HEIGHT and SID_ATTR_CHAR_LATIN_HEIGHT are mapped to the same which id + SfxSlotId nSlotId = lcl_normalizeLatinScriptSlotId( (SfxSlotId)m_nAttributeId ); + + SfxAllItemSet aParameterSet( getEditView()->GetEmptyItemSet() ); + TransformParameters( nSlotId, _rArguments, aParameterSet ); + + const SfxPoolItem* pArgument = NULL; + if ( aParameterSet.Count() ) + { + OSL_ENSURE( aParameterSet.Count() == 1, "OParametrizedAttributeDispatcher::convertDispatchArgsToItem: Arguments which form more than 1 item? How this?" ); + WhichId nAttributeWhich = aParameterSet.GetPool()->GetWhich( nSlotId ); + pArgument = aParameterSet.GetItem( nAttributeWhich ); + OSL_ENSURE( pArgument, "OParametrizedAttributeDispatcher::convertDispatchArgsToItem: suspicious: there were arguments, but they're not for my slot!" ); + } + + return pArgument; + } + + //-------------------------------------------------------------------- + void SAL_CALL OParametrizedAttributeDispatcher::dispatch( const URL& _rURL, const Sequence< PropertyValue >& _rArguments ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + OSL_ENSURE( _rURL.Complete == getFeatureURL().Complete, "OParametrizedAttributeDispatcher::dispatch: invalid URL!" ); + (void)_rURL; + if ( m_pMasterDispatcher ) + { + const SfxPoolItem* pConvertedArgument = convertDispatchArgsToItem( _rArguments ); + m_pMasterDispatcher->executeAttribute( m_nAttributeId, pConvertedArgument ); + } + } + +//........................................................................ +} // namespace frm +//........................................................................ diff --git a/forms/source/richtext/parametrizedattributedispatcher.hxx b/forms/source/richtext/parametrizedattributedispatcher.hxx new file mode 100644 index 000000000000..bbc73a6bd513 --- /dev/null +++ b/forms/source/richtext/parametrizedattributedispatcher.hxx @@ -0,0 +1,75 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef FORMS_SOURCE_RICHTEXT_PARAMETRIZEDATTRIBUTEDISPATCHER_HXX +#define FORMS_SOURCE_RICHTEXT_PARAMETRIZEDATTRIBUTEDISPATCHER_HXX + +#include "attributedispatcher.hxx" + +class SfxPoolItem; +//........................................................................ +namespace frm +{ +//........................................................................ + + //==================================================================== + //= OParametrizedAttributeDispatcher + //==================================================================== + class OParametrizedAttributeDispatcher :public OAttributeDispatcher + { + public: + OParametrizedAttributeDispatcher( + EditView& _rView, + AttributeId _nAttributeId, + const ::com::sun::star::util::URL& _rURL, + IMultiAttributeDispatcher* _pMasterDispatcher + ); + + protected: + ~OParametrizedAttributeDispatcher(); + + // XDispatch + virtual void SAL_CALL dispatch( const ::com::sun::star::util::URL& URL, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& Arguments ) throw (::com::sun::star::uno::RuntimeException); + + // OAttributeDispatcher + virtual void fillFeatureEventFromAttributeState( ::com::sun::star::frame::FeatureStateEvent& _rEvent, const AttributeState& _rState ) const; + + protected: + // own overridables + /** convert the arguments as got in a XDispatch::dispatch call into an SfxPoolItem, which can + be used with a IMultiAttributeDispatcher::executeAttribute + */ + virtual const SfxPoolItem* convertDispatchArgsToItem( + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _rArguments ); + }; + +//........................................................................ +} // namespace frm +//........................................................................ + +#endif // FORMS_SOURCE_RICHTEXT_PARAMETRIZEDATTRIBUTEDISPATCHER_HXX + diff --git a/forms/source/richtext/richtextcontrol.cxx b/forms/source/richtext/richtextcontrol.cxx new file mode 100644 index 000000000000..0755510cdd48 --- /dev/null +++ b/forms/source/richtext/richtextcontrol.cxx @@ -0,0 +1,766 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_forms.hxx" +#include "richtextcontrol.hxx" +#include "frm_module.hxx" +#ifndef _FRM_PROPERTY_HRC_ +#include "property.hrc" +#endif +#include "services.hxx" + +#include "richtextmodel.hxx" +#include "richtextvclcontrol.hxx" +#include "clipboarddispatcher.hxx" +#include "parametrizedattributedispatcher.hxx" +#include "specialdispatchers.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/awt/PosSize.hpp> +/** === end UNO includes === **/ + +#include <toolkit/helper/vclunohelper.hxx> +#include <tools/diagnose_ex.h> +#include <vcl/svapp.hxx> + +#include <svx/svxids.hrc> +#include <editeng/editview.hxx> +#include <svl/itemset.hxx> +#include <svl/itempool.hxx> +#include <sfx2/msgpool.hxx> + +//-------------------------------------------------------------------------- +extern "C" void SAL_CALL createRegistryInfo_ORichTextControl() +{ + static ::frm::OMultiInstanceAutoRegistration< ::frm::ORichTextControl > aAutoRegistration; +} + +//......................................................................... +namespace frm +{ +//......................................................................... + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::beans; + using namespace ::com::sun::star::awt; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::frame; + +#define FORWARD_TO_PEER_1( unoInterface, method, param1 ) \ + Reference< unoInterface > xTypedPeer( getPeer(), UNO_QUERY ); \ + if ( xTypedPeer.is() ) \ + { \ + xTypedPeer->method( param1 ); \ + } + +#define FORWARD_TO_PEER_1_RET( returnType, unoInterface, method, param1 ) \ + returnType aReturn; \ + Reference< unoInterface > xTypedPeer( getPeer(), UNO_QUERY ); \ + if ( xTypedPeer.is() ) \ + { \ + aReturn = xTypedPeer->method( param1 ); \ + } \ + return aReturn; + +#define FORWARD_TO_PEER_3( unoInterface, method, param1, param2, param3 ) \ + Reference< unoInterface > xTypedPeer( getPeer(), UNO_QUERY ); \ + if ( xTypedPeer.is() ) \ + { \ + xTypedPeer->method( param1, param2, param3 ); \ + } + +#define FORWARD_TO_PEER_3_RET( returnType, unoInterface, method, param1, param2, param3 ) \ + returnType aReturn; \ + Reference< unoInterface > xTypedPeer( getPeer(), UNO_QUERY ); \ + if ( xTypedPeer.is() ) \ + { \ + aReturn = xTypedPeer->method( param1, param2, param3 ); \ + } \ + return aReturn; + + //================================================================== + // ORichTextControl + //================================================================== + DBG_NAME( ORichTextControl ) + //------------------------------------------------------------------ + ORichTextControl::ORichTextControl( const Reference< XMultiServiceFactory >& _rxORB ) + :m_xORB( _rxORB ) + { + DBG_CTOR( ORichTextControl, NULL ); + } + + //------------------------------------------------------------------ + ORichTextControl::~ORichTextControl() + { + DBG_DTOR( ORichTextControl, NULL ); + } + + //------------------------------------------------------------------ + IMPLEMENT_FORWARD_XTYPEPROVIDER2( ORichTextControl, UnoEditControl, ORichTextControl_Base ) + + //------------------------------------------------------------------ + Any SAL_CALL ORichTextControl::queryAggregation( const Type& _rType ) throw ( RuntimeException ) + { + Any aReturn = UnoEditControl::queryAggregation( _rType ); + + if ( !aReturn.hasValue() ) + aReturn = ORichTextControl_Base::queryInterface( _rType ); + + return aReturn; + } + + //------------------------------------------------------------------ + namespace + { + //.............................................................. + static void implAdjustTriStateFlag( const Reference< XPropertySet >& _rxProps, const ::rtl::OUString& _rPropertyName, + WinBits& _rAllBits, WinBits _nPositiveFlag, WinBits nNegativeFlag ) + { + sal_Bool bFlagValue = sal_False; + if ( _rxProps->getPropertyValue( _rPropertyName ) >>= bFlagValue ) + _rAllBits |= ( bFlagValue ? _nPositiveFlag : nNegativeFlag ); + } + + //.............................................................. + static void implAdjustTwoStateFlag( const Any& _rValue, WinBits& _rAllBits, WinBits _nFlag, bool _bInvert = false ) + { + sal_Bool bFlagValue = sal_False; + if ( _rValue >>= bFlagValue ) + { + if ( _bInvert ) + bFlagValue = !bFlagValue; + if ( bFlagValue ) + _rAllBits |= _nFlag; + else + _rAllBits &= ~_nFlag; + } + } + + //.............................................................. + static void implAdjustTwoStateFlag( const Reference< XPropertySet >& _rxProps, const ::rtl::OUString& _rPropertyName, + WinBits& _rAllBits, WinBits _nFlag, bool _bInvert = false ) + { + implAdjustTwoStateFlag( _rxProps->getPropertyValue( _rPropertyName ), _rAllBits, _nFlag, _bInvert ); + } + + //.............................................................. + static void adjustTwoStateWinBit( Window* _pWindow, const Any& _rValue, WinBits _nFlag, bool _bInvert = false ) + { + WinBits nBits = _pWindow->GetStyle(); + implAdjustTwoStateFlag( _rValue, nBits, _nFlag, _bInvert ); + _pWindow->SetStyle( nBits ); + } + + //.............................................................. + static WinBits getWinBits( const Reference< XControlModel >& _rxModel, WinBits nBaseBits = 0 ) + { + WinBits nBits = nBaseBits; + try + { + Reference< XPropertySet > xProps( _rxModel, UNO_QUERY ); + if ( xProps.is() ) + { + sal_Int16 nBorder = 0; + xProps->getPropertyValue( PROPERTY_BORDER ) >>= nBorder; + if ( nBorder ) + nBits |= WB_BORDER; + + implAdjustTriStateFlag( xProps, PROPERTY_TABSTOP, nBits, WB_TABSTOP, WB_NOTABSTOP ); + implAdjustTwoStateFlag( xProps, PROPERTY_HSCROLL, nBits, WB_HSCROLL ); + implAdjustTwoStateFlag( xProps, PROPERTY_VSCROLL, nBits, WB_VSCROLL ); + implAdjustTwoStateFlag( xProps, PROPERTY_HARDLINEBREAKS, nBits, WB_WORDBREAK, true ); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return nBits; + } + } + + //------------------------------------------------------------------ + void SAL_CALL ORichTextControl::createPeer( const Reference< XToolkit >& _rToolkit, const Reference< XWindowPeer >& _rParentPeer ) throw( RuntimeException ) + { + sal_Bool bReallyActAsRichText = sal_False; + try + { + Reference< XPropertySet > xModelProps( getModel(), UNO_QUERY_THROW ); + xModelProps->getPropertyValue( PROPERTY_RICH_TEXT ) >>= bReallyActAsRichText; + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + if ( !bReallyActAsRichText ) + { + UnoEditControl::createPeer( _rToolkit, _rParentPeer ); + OControl::initFormControlPeer( getPeer() ); + return; + } + + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + if (!getPeer().is()) + { + mbCreatingPeer = sal_True; + + // determine the VLC window for the parent + Window* pParentWin = NULL; + if ( _rParentPeer.is() ) + { + VCLXWindow* pParentXWin = VCLXWindow::GetImplementation( _rParentPeer ); + if ( pParentXWin ) + pParentWin = pParentXWin->GetWindow(); + DBG_ASSERT( pParentWin, "ORichTextControl::createPeer: could not obtain the VCL-level parent window!" ); + } + + // create the peer + Reference< XControlModel > xModel( getModel() ); + ORichTextPeer* pPeer = ORichTextPeer::Create( xModel, pParentWin, getWinBits( xModel ) ); + DBG_ASSERT( pPeer, "ORichTextControl::createPeer: invalid peer returned!" ); + if ( pPeer ) + { + // by definition, the returned component is aquired once + pPeer->release(); + + // announce the peer to the base class + setPeer( pPeer ); + + // initialize ourself (and thus the peer) with the model properties + updateFromModel(); + + Reference< XView > xPeerView( getPeer(), UNO_QUERY ); + if ( xPeerView.is() ) + { + xPeerView->setZoom( maComponentInfos.nZoomX, maComponentInfos.nZoomY ); + xPeerView->setGraphics( mxGraphics ); + } + + // a lot of initial settings from our component infos + setPosSize( maComponentInfos.nX, maComponentInfos.nY, maComponentInfos.nWidth, maComponentInfos.nHeight, PosSize::POSSIZE ); + + pPeer->setVisible ( maComponentInfos.bVisible && !mbDesignMode ); + pPeer->setEnable ( maComponentInfos.bEnable ); + pPeer->setDesignMode( mbDesignMode ); + + peerCreated(); + } + + mbCreatingPeer = sal_False; + + OControl::initFormControlPeer( getPeer() ); + } + } + + //------------------------------------------------------------------ + ::rtl::OUString SAL_CALL ORichTextControl::getImplementationName() throw( RuntimeException ) + { + return getImplementationName_Static(); + } + + //------------------------------------------------------------------ + Sequence< ::rtl::OUString > SAL_CALL ORichTextControl::getSupportedServiceNames() throw( RuntimeException ) + { + return getSupportedServiceNames_Static(); + } + + //------------------------------------------------------------------ + ::rtl::OUString SAL_CALL ORichTextControl::getImplementationName_Static() + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.form.ORichTextControl" ) ); + } + + //------------------------------------------------------------------ + Sequence< ::rtl::OUString > SAL_CALL ORichTextControl::getSupportedServiceNames_Static() + { + Sequence< ::rtl::OUString > aServices( 3 ); + aServices[ 0 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControl" ) ); + aServices[ 1 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControlEdit" ) ); + aServices[ 2 ] = FRM_SUN_CONTROL_RICHTEXTCONTROL; + return aServices; + } + + //------------------------------------------------------------------ + Reference< XInterface > SAL_CALL ORichTextControl::Create( const Reference< XMultiServiceFactory >& _rxFactory ) + { + return *( new ORichTextControl( _rxFactory ) ); + } + + //-------------------------------------------------------------------- + Reference< XDispatch > SAL_CALL ORichTextControl::queryDispatch( const ::com::sun::star::util::URL& _rURL, const ::rtl::OUString& _rTargetFrameName, sal_Int32 _nSearchFlags ) throw (RuntimeException) + { + FORWARD_TO_PEER_3_RET( Reference< XDispatch >, XDispatchProvider, queryDispatch, _rURL, _rTargetFrameName, _nSearchFlags ); + } + + //-------------------------------------------------------------------- + Sequence< Reference< XDispatch > > SAL_CALL ORichTextControl::queryDispatches( const Sequence< DispatchDescriptor >& _rRequests ) throw (RuntimeException) + { + FORWARD_TO_PEER_1_RET( Sequence< Reference< XDispatch > >, XDispatchProvider, queryDispatches, _rRequests ); + } + + //-------------------------------------------------------------------- + sal_Bool ORichTextControl::requiresNewPeer( const ::rtl::OUString& _rPropertyName ) const + { + return UnoControl::requiresNewPeer( _rPropertyName ) || _rPropertyName.equals( PROPERTY_RICH_TEXT ); + } + + //================================================================== + // ORichTextPeer + //================================================================== + DBG_NAME( ORichTextPeer ) + //------------------------------------------------------------------ + ORichTextPeer* ORichTextPeer::Create( const Reference< XControlModel >& _rxModel, Window* _pParentWindow, WinBits _nStyle ) + { + DBG_TESTSOLARMUTEX(); + + // the EditEngine of the model + RichTextEngine* pEngine = ORichTextModel::getEditEngine( _rxModel ); + OSL_ENSURE( pEngine, "ORichTextPeer::Create: could not obtaine the edit engine from the model!" ); + if ( !pEngine ) + return NULL; + + // the peer itself + ORichTextPeer* pPeer = new ORichTextPeer; + pPeer->acquire(); // by definition, the returned object is aquired once + + // the VCL control for the peer + RichTextControl* pRichTextControl = new RichTextControl( pEngine, _pParentWindow, _nStyle, NULL, pPeer ); + + // some knittings + pRichTextControl->SetComponentInterface( pPeer ); + + // outta here + return pPeer; + } + + //------------------------------------------------------------------ + ORichTextPeer::ORichTextPeer() + { + DBG_CTOR( ORichTextPeer, NULL ); + } + + //------------------------------------------------------------------ + ORichTextPeer::~ORichTextPeer() + { + DBG_DTOR( ORichTextPeer, NULL ); + } + + //------------------------------------------------------------------ + void ORichTextPeer::dispose( ) throw(RuntimeException) + { + { + ::vos::OGuard aGuard( GetMutex() ); + RichTextControl* pRichTextControl = static_cast< RichTextControl* >( GetWindow() ); + + if ( pRichTextControl ) + { + for ( AttributeDispatchers::iterator aDisposeLoop = m_aDispatchers.begin(); + aDisposeLoop != m_aDispatchers.end(); + ++aDisposeLoop + ) + { + pRichTextControl->disableAttributeNotification( aDisposeLoop->first ); + aDisposeLoop->second->dispose(); + } + } + + AttributeDispatchers aEmpty; + m_aDispatchers.swap( aEmpty ); + } + + VCLXWindow::dispose(); + } + + //-------------------------------------------------------------------- + void SAL_CALL ORichTextPeer::draw( sal_Int32 _nX, sal_Int32 _nY ) throw(::com::sun::star::uno::RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + RichTextControl* pControl = static_cast< RichTextControl* >( GetWindow() ); + if ( !pControl ) + return; + + OutputDevice* pTargetDevice = VCLUnoHelper::GetOutputDevice( getGraphics() ); + OSL_ENSURE( pTargetDevice != NULL, "ORichTextPeer::draw: no graphics -> no drawing!" ); + if ( !pTargetDevice ) + return; + + ::Size aSize = pControl->GetSizePixel(); + const MapUnit eTargetUnit = pTargetDevice->GetMapMode().GetMapUnit(); + if ( eTargetUnit != MAP_PIXEL ) + aSize = pControl->PixelToLogic( aSize, eTargetUnit ); + + ::Point aPos( _nX, _nY ); + // the XView::draw API talks about pixels, always ... + if ( eTargetUnit != MAP_PIXEL ) + aPos = pTargetDevice->PixelToLogic( aPos ); + + pControl->Draw( pTargetDevice, aPos, aSize, WINDOW_DRAW_NOCONTROLS ); + } + + //-------------------------------------------------------------------- + void SAL_CALL ORichTextPeer::setProperty( const ::rtl::OUString& _rPropertyName, const Any& _rValue ) throw (RuntimeException) + { + if ( !GetWindow() ) + { + VCLXWindow::setProperty( _rPropertyName, _rValue ); + return; + } + + if ( _rPropertyName.equals( PROPERTY_BACKGROUNDCOLOR ) ) + { + RichTextControl* pControl = static_cast< RichTextControl* >( GetWindow() ); + if ( !_rValue.hasValue() ) + { + pControl->SetBackgroundColor( ); + } + else + { + sal_Int32 nColor = COL_TRANSPARENT; + _rValue >>= nColor; + pControl->SetBackgroundColor( Color( nColor ) ); + } + } + else if ( _rPropertyName.equals( PROPERTY_HSCROLL ) ) + { + adjustTwoStateWinBit( GetWindow(), _rValue, WB_HSCROLL ); + } + else if ( _rPropertyName.equals( PROPERTY_VSCROLL ) ) + { + adjustTwoStateWinBit( GetWindow(), _rValue, WB_VSCROLL ); + } + else if ( _rPropertyName.equals( PROPERTY_HARDLINEBREAKS ) ) + { + adjustTwoStateWinBit( GetWindow(), _rValue, WB_WORDBREAK, true ); + } + else if ( _rPropertyName.equals( PROPERTY_READONLY ) ) + { + RichTextControl* pControl = static_cast< RichTextControl* >( GetWindow() ); + sal_Bool bReadOnly( pControl->IsReadOnly() ); + OSL_VERIFY( _rValue >>= bReadOnly ); + pControl->SetReadOnly( bReadOnly ); + + // update the dispatchers + for ( AttributeDispatchers::iterator aDispatcherLoop = m_aDispatchers.begin(); + aDispatcherLoop != m_aDispatchers.end(); + ++aDispatcherLoop + ) + { + aDispatcherLoop->second->invalidate(); + } + } + else if ( _rPropertyName.equals( PROPERTY_HIDEINACTIVESELECTION ) ) + { + RichTextControl* pRichTextControl = static_cast< RichTextControl* >( GetWindow() ); + sal_Bool bHide = pRichTextControl->GetHideInactiveSelection(); + OSL_VERIFY( _rValue >>= bHide ); + pRichTextControl->SetHideInactiveSelection( bHide ); + } + else + VCLXWindow::setProperty( _rPropertyName, _rValue ); + } + + //------------------------------------------------------------------ + IMPLEMENT_FORWARD_XINTERFACE2( ORichTextPeer, VCLXWindow, ORichTextPeer_Base ) + + //------------------------------------------------------------------ + IMPLEMENT_FORWARD_XTYPEPROVIDER2( ORichTextPeer, VCLXWindow, ORichTextPeer_Base ) + + //-------------------------------------------------------------------- + namespace + { + static SfxSlotId lcl_translateConflictingSlot( SfxSlotId _nIDFromPool ) + { + // HACK HACK HACK + // unfortunately, some of our applications have some conflicting slots, + // i.e. slots which have the same UNO name as an existing other (common) + // slot. + // For instance, both the slots SID_SET_SUPER_SCRIPT (from SVX) and FN_SET_SUPER_SCRIPT + // (from SW) have the UNO name "SuperScript". + // Now, if the controls lives in a text document, and asks the SfxSlotPool for + // the id belonging to "SuperScript", it gets the FN_SET_SUPER_SCRIPT - which + // is completely unknown to the EditEngine. + // So, we need to translate such conflicting ids. + // + // Note that the real solution would be to fix the applications to + // *not* define conflicting slots. Alternatively, if SFX would provide a slot pool + // which is *static* (i.e. independent on the active application), then we + // would also never encounter such a conflict. + SfxSlotId nReturn( _nIDFromPool ); + switch ( _nIDFromPool ) + { + case 20411: /* FM_SET_SUPER_SCRIPT, originating in SW */ + nReturn = SID_SET_SUPER_SCRIPT; + break; + case 20412: /* FN_SET_SUB_SCRIPT, originating in SW */ + nReturn = SID_SET_SUB_SCRIPT; + break; + } + return nReturn; + } + } + + //-------------------------------------------------------------------- + ORichTextPeer::SingleAttributeDispatcher ORichTextPeer::implCreateDispatcher( SfxSlotId _nSlotId, const ::com::sun::star::util::URL& _rURL ) + { + RichTextControl* pRichTextControl = static_cast< RichTextControl* >( GetWindow() ); + OSL_PRECOND( pRichTextControl, "ORichTextPeer::implCreateDispatcher: invalid window!" ); + if ( !pRichTextControl ) + return SingleAttributeDispatcher( NULL ); + + ORichTextFeatureDispatcher* pDispatcher = NULL; + OAttributeDispatcher* pAttributeDispatcher = NULL; + switch ( _nSlotId ) + { + case SID_CUT: + pDispatcher = new OClipboardDispatcher( pRichTextControl->getView(), OClipboardDispatcher::eCut ); + break; + + case SID_COPY: + pDispatcher = new OClipboardDispatcher( pRichTextControl->getView(), OClipboardDispatcher::eCopy ); + break; + + case SID_PASTE: + pDispatcher = new OPasteClipboardDispatcher( pRichTextControl->getView() ); + break; + + case SID_SELECTALL: + pDispatcher = new OSelectAllDispatcher( pRichTextControl->getView(), _rURL ); + break; + + case SID_ATTR_PARA_LEFT_TO_RIGHT: + case SID_ATTR_PARA_RIGHT_TO_LEFT: + pAttributeDispatcher = new OParagraphDirectionDispatcher( pRichTextControl->getView(), _nSlotId, _rURL, pRichTextControl ); + break; + + case SID_TEXTDIRECTION_TOP_TO_BOTTOM: + case SID_TEXTDIRECTION_LEFT_TO_RIGHT: + pDispatcher = new OTextDirectionDispatcher( pRichTextControl->getView(), _rURL ); + break; + + case SID_ATTR_PARA_HANGPUNCTUATION: + case SID_ATTR_PARA_FORBIDDEN_RULES: + case SID_ATTR_PARA_SCRIPTSPACE: + pAttributeDispatcher = new OAsianFontLayoutDispatcher( pRichTextControl->getView(), _nSlotId, _rURL, pRichTextControl ); + break; + + default: + { + // is it a supported slot? + bool bSupportedSlot = false; + if ( !bSupportedSlot ) + { + const SfxItemPool& rPool = *pRichTextControl->getView().GetEmptyItemSet().GetPool(); + bSupportedSlot = rPool.IsInRange( rPool.GetWhich( _nSlotId ) ); + } + if ( !bSupportedSlot ) + bSupportedSlot = RichTextControl::isMappableSlot( _nSlotId ); + + if ( bSupportedSlot ) + { // it's really a slot which is supported by the EditEngine + + bool bNeedParametrizedDispatcher = true; + if ( ( _nSlotId == SID_ATTR_CHAR_POSTURE ) + || ( _nSlotId == SID_ATTR_CHAR_CJK_POSTURE ) + || ( _nSlotId == SID_ATTR_CHAR_CTL_POSTURE ) + || ( _nSlotId == SID_ATTR_CHAR_LATIN_POSTURE ) + || ( _nSlotId == SID_ATTR_CHAR_WEIGHT ) + || ( _nSlotId == SID_ATTR_CHAR_CJK_WEIGHT ) + || ( _nSlotId == SID_ATTR_CHAR_CTL_WEIGHT ) + || ( _nSlotId == SID_ATTR_CHAR_LATIN_WEIGHT ) + || ( _nSlotId == SID_ATTR_CHAR_LANGUAGE ) + || ( _nSlotId == SID_ATTR_CHAR_CJK_LANGUAGE ) + || ( _nSlotId == SID_ATTR_CHAR_CTL_LANGUAGE ) + || ( _nSlotId == SID_ATTR_CHAR_LATIN_LANGUAGE ) + || ( _nSlotId == SID_ATTR_CHAR_CONTOUR ) + || ( _nSlotId == SID_ATTR_CHAR_SHADOWED ) + || ( _nSlotId == SID_ATTR_CHAR_WORDLINEMODE ) + || ( _nSlotId == SID_ATTR_CHAR_COLOR ) + || ( _nSlotId == SID_ATTR_CHAR_RELIEF ) + || ( _nSlotId == SID_ATTR_CHAR_KERNING ) + || ( _nSlotId == SID_ATTR_CHAR_AUTOKERN ) + || ( _nSlotId == SID_ATTR_CHAR_SCALEWIDTH ) + ) + { + bNeedParametrizedDispatcher = true; + } + else if ( ( _nSlotId == SID_ATTR_PARA_HANGPUNCTUATION ) + || ( _nSlotId == SID_ATTR_PARA_FORBIDDEN_RULES ) + || ( _nSlotId == SID_ATTR_PARA_SCRIPTSPACE ) + ) + { + bNeedParametrizedDispatcher = false; + } + else + { + SfxSlotPool& rSlotPool = SfxSlotPool::GetSlotPool( NULL ); + const SfxSlot* pSlot = rSlotPool.GetSlot( _nSlotId ); + const SfxType* pType = pSlot ? pSlot->GetType() : NULL; + if ( pType ) + { + bNeedParametrizedDispatcher = ( pType->nAttribs > 0 ); + } + } + + if ( bNeedParametrizedDispatcher ) + { + #if OSL_DEBUG_LEVEL > 0 + ::rtl::OString sTrace( "ORichTextPeer::implCreateDispatcher: creating *parametrized* dispatcher for " ); + sTrace += ::rtl::OString( _rURL.Complete.getStr(), _rURL.Complete.getLength(), RTL_TEXTENCODING_ASCII_US ); + DBG_TRACE( sTrace.getStr() ); + #endif + pAttributeDispatcher = new OParametrizedAttributeDispatcher( pRichTextControl->getView(), _nSlotId, _rURL, pRichTextControl ); + } + else + { + #if OSL_DEBUG_LEVEL > 0 + ::rtl::OString sTrace( "ORichTextPeer::implCreateDispatcher: creating *normal* dispatcher for " ); + sTrace += ::rtl::OString( _rURL.Complete.getStr(), _rURL.Complete.getLength(), RTL_TEXTENCODING_ASCII_US ); + DBG_TRACE( sTrace.getStr() ); + #endif + pAttributeDispatcher = new OAttributeDispatcher( pRichTextControl->getView(), _nSlotId, _rURL, pRichTextControl ); + } + } + #if OSL_DEBUG_LEVEL > 0 + else + { + ::rtl::OString sTrace( "ORichTextPeer::implCreateDispatcher: not creating dispatcher (unsupported slot) for " ); + sTrace += ::rtl::OString( _rURL.Complete.getStr(), _rURL.Complete.getLength(), RTL_TEXTENCODING_ASCII_US ); + DBG_TRACE( sTrace.getStr() ); + } + #endif + } + break; + } + + SingleAttributeDispatcher xDispatcher( pDispatcher ); + if ( pAttributeDispatcher ) + { + xDispatcher = SingleAttributeDispatcher( pAttributeDispatcher ); + pRichTextControl->enableAttributeNotification( _nSlotId, pAttributeDispatcher ); + } + + return xDispatcher; + } + + //-------------------------------------------------------------------- + namespace + { + SfxSlotId lcl_getSlotFromUnoName( SfxSlotPool& _rSlotPool, const ::rtl::OUString& _rUnoSlotName ) + { + const SfxSlot* pSlot = _rSlotPool.GetUnoSlot( _rUnoSlotName ); + if ( pSlot ) + { + // okay, there's a slot with the given UNO name + return lcl_translateConflictingSlot( pSlot->GetSlotId() ); + } + + // some hard-coded slots, which do not have a UNO name at SFX level, but which + // we nevertheless need to transport via UNO mechanisms, so we need a name + if ( _rUnoSlotName.equalsAscii( "AllowHangingPunctuation" ) ) + return SID_ATTR_PARA_HANGPUNCTUATION; + if ( _rUnoSlotName.equalsAscii( "ApplyForbiddenCharacterRules" ) ) + return SID_ATTR_PARA_FORBIDDEN_RULES; + if ( _rUnoSlotName.equalsAscii( "UseScriptSpacing" ) ) + return SID_ATTR_PARA_SCRIPTSPACE; + + OSL_ENSURE( pSlot, "lcl_getSlotFromUnoName: unknown UNO slot name!" ); + return 0; + } + } + + //-------------------------------------------------------------------- + Reference< XDispatch > SAL_CALL ORichTextPeer::queryDispatch( const ::com::sun::star::util::URL& _rURL, const ::rtl::OUString& /*_rTargetFrameName*/, sal_Int32 /*_nSearchFlags*/ ) throw (RuntimeException) + { + Reference< XDispatch > xReturn; + if ( !GetWindow() ) + { + OSL_ENSURE( sal_False, "ORichTextPeer::queryDispatch: already disposed?" ); + return xReturn; + } + + // is it an UNO slot? + ::rtl::OUString sUnoProtocolPrefix( RTL_CONSTASCII_USTRINGPARAM( ".uno:" ) ); + if ( 0 == _rURL.Complete.compareTo( sUnoProtocolPrefix, sUnoProtocolPrefix.getLength() ) ) + { + ::rtl::OUString sUnoSlotName = _rURL.Complete.copy( sUnoProtocolPrefix.getLength() ); + SfxSlotId nSlotId = lcl_getSlotFromUnoName( SfxSlotPool::GetSlotPool( NULL ), sUnoSlotName ); + if ( nSlotId > 0 ) + { + // do we already have a dispatcher for this? + AttributeDispatchers::const_iterator aDispatcherPos = m_aDispatchers.find( nSlotId ); + if ( aDispatcherPos == m_aDispatchers.end() ) + { + SingleAttributeDispatcher pDispatcher = implCreateDispatcher( nSlotId, _rURL ); + if ( pDispatcher.is() ) + { + aDispatcherPos = m_aDispatchers.insert( AttributeDispatchers::value_type( nSlotId, pDispatcher ) ).first; + } + } + + if ( aDispatcherPos != m_aDispatchers.end() ) + xReturn = aDispatcherPos->second.getRef(); + } + } + + return xReturn; + } + + //-------------------------------------------------------------------- + Sequence< Reference< XDispatch > > SAL_CALL ORichTextPeer::queryDispatches( const Sequence< DispatchDescriptor >& _rRequests ) throw (RuntimeException) + { + Sequence< Reference< XDispatch > > aReturn( _rRequests.getLength() ); + Reference< XDispatch >* pReturn = aReturn.getArray(); + + const DispatchDescriptor* pRequest = _rRequests.getConstArray(); + const DispatchDescriptor* pRequestEnd = pRequest + _rRequests.getLength(); + for ( ; pRequest != pRequestEnd; ++pRequest, ++pReturn ) + { + *pReturn = queryDispatch( pRequest->FeatureURL, pRequest->FrameName, pRequest->SearchFlags ); + } + return aReturn; + } + + //-------------------------------------------------------------------- + void ORichTextPeer::onSelectionChanged( const ESelection& /*_rSelection*/ ) + { + AttributeDispatchers::iterator aDispatcherPos = m_aDispatchers.find( SID_COPY ); + if ( aDispatcherPos != m_aDispatchers.end() ) + aDispatcherPos->second.get()->invalidate(); + + aDispatcherPos = m_aDispatchers.find( SID_CUT ); + if ( aDispatcherPos != m_aDispatchers.end() ) + aDispatcherPos->second.get()->invalidate(); + } + +//........................................................................ +} // namespace frm +//........................................................................ + diff --git a/forms/source/richtext/richtextcontrol.hxx b/forms/source/richtext/richtextcontrol.hxx new file mode 100644 index 000000000000..e4dea25ec225 --- /dev/null +++ b/forms/source/richtext/richtextcontrol.hxx @@ -0,0 +1,163 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef FORMS_SOURCE_RICHTEXT_RICHTEXTCONTROL_HXX +#define FORMS_SOURCE_RICHTEXT_RICHTEXTCONTROL_HXX + +#include <toolkit/controls/unocontrols.hxx> +#include <toolkit/awt/vclxwindow.hxx> + +/** === begin UNO includes === **/ +#include <com/sun/star/frame/XDispatchProvider.hpp> +/** === end UNO includes === **/ +#include <comphelper/uno3.hxx> +#include <comphelper/implementationreference.hxx> +#include <cppuhelper/implbase1.hxx> +#include <tools/wintypes.hxx> +#include "rtattributes.hxx" +#include "attributedispatcher.hxx" + +#include <map> + +//......................................................................... +namespace frm +{ +//......................................................................... + + class ORichTextFeatureDispatcher; + class RichTextControl; + + //================================================================== + // ORichTextControl + //================================================================== + typedef ::cppu::ImplHelper1 < ::com::sun::star::frame::XDispatchProvider + > ORichTextControl_Base; + class ORichTextControl :public UnoEditControl + ,public ORichTextControl_Base + { + private: + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > + m_xORB; + + public: + ORichTextControl( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB + ); + + protected: + ~ORichTextControl(); + + public: + // XServiceInfo - static version + static ::rtl::OUString SAL_CALL getImplementationName_Static(); + static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_Static(); + static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL Create( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory ); + + protected: + // UNO + DECLARE_UNO3_AGG_DEFAULTS( ORichTextControl, UnoEditControl ); + virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw ( ::com::sun::star::uno::RuntimeException ); + + // XControl + virtual void SAL_CALL createPeer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit >& _rToolkit, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >& _rParent ) throw( ::com::sun::star::uno::RuntimeException ); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException); + + // XTypeProvider + DECLARE_XTYPEPROVIDER() + + // XDispatchProvider + virtual ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > SAL_CALL queryDispatch( const ::com::sun::star::util::URL& _rURL, const ::rtl::OUString& _rTargetFrameName, sal_Int32 _rSearchFlags ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > > SAL_CALL queryDispatches( const ::com::sun::star::uno::Sequence< ::com::sun::star::frame::DispatchDescriptor >& Requests ) throw (::com::sun::star::uno::RuntimeException); + + // UnoControl + virtual sal_Bool requiresNewPeer( const ::rtl::OUString& _rPropertyName ) const; + }; + + //================================================================== + // ORichTextPeer + //================================================================== + typedef ::cppu::ImplHelper1 < ::com::sun::star::frame::XDispatchProvider + > ORichTextPeer_Base; + class ORichTextPeer :public VCLXWindow + ,public ORichTextPeer_Base + ,public ITextSelectionListener + { + private: + typedef ::comphelper::ImplementationReference< ORichTextFeatureDispatcher, ::com::sun::star::frame::XDispatch > SingleAttributeDispatcher; + typedef ::std::map< SfxSlotId, SingleAttributeDispatcher > AttributeDispatchers; + AttributeDispatchers m_aDispatchers; + + public: + /** factory method + @return + a new ORichTextPeer instance, which has been aquired once! + */ + static ORichTextPeer* Create( + const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >& _rxModel, + Window* _pParentWindow, + WinBits _nStyle + ); + + // XInterface + DECLARE_XINTERFACE( ) + + protected: + ORichTextPeer(); + ~ORichTextPeer(); + + // XView + void SAL_CALL draw( sal_Int32 nX, sal_Int32 nY ) throw(::com::sun::star::uno::RuntimeException); + + // XVclWindowPeer + virtual void SAL_CALL setProperty( const ::rtl::OUString& _rPropertyName, const ::com::sun::star::uno::Any& _rValue ) throw (::com::sun::star::uno::RuntimeException); + + // XTypeProvider + DECLARE_XTYPEPROVIDER( ) + + // XComponent + virtual void SAL_CALL dispose( ) throw(::com::sun::star::uno::RuntimeException); + + // XDispatchProvider + virtual ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > SAL_CALL queryDispatch( const ::com::sun::star::util::URL& _rURL, const ::rtl::OUString& _rTargetFrameName, sal_Int32 _rSearchFlags ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > > SAL_CALL queryDispatches( const ::com::sun::star::uno::Sequence< ::com::sun::star::frame::DispatchDescriptor >& Requests ) throw (::com::sun::star::uno::RuntimeException); + + // ITextSelectionListener + virtual void onSelectionChanged( const ESelection& _rSelection ); + + private: + SingleAttributeDispatcher implCreateDispatcher( SfxSlotId _nSlotId, const ::com::sun::star::util::URL& _rURL ); + }; + +//......................................................................... +} // namespace frm +//......................................................................... + +#endif // FORMS_SOURCE_RICHTEXT_RICHTEXTCONTROL_HXX + diff --git a/forms/source/richtext/richtextengine.cxx b/forms/source/richtext/richtextengine.cxx new file mode 100644 index 000000000000..3b220a2e222a --- /dev/null +++ b/forms/source/richtext/richtextengine.cxx @@ -0,0 +1,162 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_forms.hxx" +#include "richtextengine.hxx" +#include <svl/itempool.hxx> +#include <editeng/eeitem.hxx> +#include <editeng/editobj.hxx> +#define ITEMID_FONTHEIGHT EE_CHAR_FONTHEIGHT +#include <editeng/fhgtitem.hxx> +#define ITEMID_FONT EE_CHAR_FONTHEIGHT +#include <editeng/fontitem.hxx> +#define ITEMID_LANGUAGE EE_CHAR_LANGUAGE +#include <editeng/langitem.hxx> +#include <vcl/svapp.hxx> +#include <tools/mapunit.hxx> +#include <vcl/mapmod.hxx> +#include <vcl/outdev.hxx> +#include <unotools/lingucfg.hxx> +#include <svl/undo.hxx> +#include <vos/mutex.hxx> + +#include <algorithm> +#include <functional> + +//........................................................................ +namespace frm +{ +//........................................................................ + + //==================================================================== + //= RichTextEngine + //==================================================================== + //-------------------------------------------------------------------- + RichTextEngine* RichTextEngine::Create() + { + SfxItemPool* pPool = EditEngine::CreatePool(); + pPool->FreezeIdRanges(); + + RichTextEngine* pReturn = new RichTextEngine( pPool ); + OutputDevice* pOutputDevice = pReturn->GetRefDevice(); + MapMode aDeviceMapMode( pOutputDevice->GetMapMode() ); + + pReturn->SetStatusEventHdl( LINK( pReturn, RichTextEngine, EditEngineStatusChanged ) ); + + pPool->SetDefaultMetric( (SfxMapUnit)( aDeviceMapMode.GetMapUnit() ) ); + + // defaults + Font aFont = Application::GetSettings().GetStyleSettings().GetAppFont(); + aFont.SetName( String( RTL_CONSTASCII_USTRINGPARAM( "Times New Roman" ) ) ); + pPool->SetPoolDefaultItem( SvxFontItem( aFont.GetFamily(), aFont.GetName(), String(), aFont.GetPitch(), aFont.GetCharSet(), EE_CHAR_FONTINFO ) ); + + // 12 pt font size + MapMode aPointMapMode( MAP_POINT ); + Size a12PointSize( OutputDevice::LogicToLogic( Size( 12, 0 ), aPointMapMode, aDeviceMapMode ) ); + pPool->SetPoolDefaultItem( SvxFontHeightItem( a12PointSize.Width(), 100, EE_CHAR_FONTHEIGHT ) ); + + // font languages + SvtLinguOptions aLinguOpt; + pPool->SetPoolDefaultItem( SvxLanguageItem( aLinguOpt.nDefaultLanguage, EE_CHAR_LANGUAGE ) ); + pPool->SetPoolDefaultItem( SvxLanguageItem( aLinguOpt.nDefaultLanguage_CJK, EE_CHAR_LANGUAGE_CJK ) ); + pPool->SetPoolDefaultItem( SvxLanguageItem( aLinguOpt.nDefaultLanguage_CTL, EE_CHAR_LANGUAGE_CTL ) ); + + return pReturn; + } + + //-------------------------------------------------------------------- + RichTextEngine* RichTextEngine::Clone() + { + RichTextEngine* pClone( NULL ); + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + EditTextObject* pMyText = CreateTextObject(); + OSL_ENSURE( pMyText, "RichTextEngine::Clone: CreateTextObject returned nonsense!" ); + + pClone = Create(); + + if ( pMyText ) + pClone->SetText( *pMyText ); + delete pMyText; + } + + return pClone; + } + + DBG_NAME(RichTextEngine) + //-------------------------------------------------------------------- + RichTextEngine::RichTextEngine( SfxItemPool* _pPool ) + :EditEngine( _pPool ) + ,m_pEnginePool( _pPool ) + { + DBG_CTOR(RichTextEngine,NULL); + } + + //-------------------------------------------------------------------- + RichTextEngine::~RichTextEngine( ) + { + //delete m_pEnginePool; // must be done after the RichTextEngine was deleted + DBG_DTOR(RichTextEngine,NULL); + } + + //-------------------------------------------------------------------- + void RichTextEngine::registerEngineStatusListener( IEngineStatusListener* _pListener ) + { + OSL_ENSURE( _pListener, "RichTextEngine::registerEngineStatusListener: invalid listener!" ); + if ( _pListener ) + m_aStatusListeners.push_back( _pListener ); + } + + //-------------------------------------------------------------------- + void RichTextEngine::revokeEngineStatusListener( IEngineStatusListener* _pListener ) + { + ::std::vector< IEngineStatusListener* >::iterator aPos = ::std::find_if( + m_aStatusListeners.begin(), + m_aStatusListeners.end(), + ::std::bind2nd( ::std::equal_to< IEngineStatusListener* >( ), _pListener ) + ); + OSL_ENSURE( aPos != m_aStatusListeners.end(), "RichTextEngine::revokeEngineStatusListener: listener not registered!" ); + if ( aPos != m_aStatusListeners.end() ) + m_aStatusListeners.erase( aPos ); + } + + //-------------------------------------------------------------------- + IMPL_LINK( RichTextEngine, EditEngineStatusChanged, EditStatus*, _pStatus ) + { + for ( ::std::vector< IEngineStatusListener* >::const_iterator aLoop = m_aStatusListeners.begin(); + aLoop != m_aStatusListeners.end(); + ++aLoop + ) + (*aLoop)->EditEngineStatusChanged( *_pStatus ); + return 0L; + } + +//........................................................................ +} // namespace frm +//........................................................................ + diff --git a/forms/source/richtext/richtextengine.hxx b/forms/source/richtext/richtextengine.hxx new file mode 100644 index 000000000000..c3a1eb36550c --- /dev/null +++ b/forms/source/richtext/richtextengine.hxx @@ -0,0 +1,91 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef FORMS_SOURCE_RICHTEXT_RICHTEXTENGINE_HXX +#define FORMS_SOURCE_RICHTEXT_RICHTEXTENGINE_HXX + +#include <editeng/editeng.hxx> +#include <tools/link.hxx> + +#include <vector> + +class SfxItemPool; +class EditStatus; +//........................................................................ +namespace frm +{ +//........................................................................ + + //==================================================================== + //= IEngineStatusListener + //==================================================================== + class IEngineStatusListener + { + public: + virtual void EditEngineStatusChanged( const EditStatus& _rStatus ) = 0; + }; + + //==================================================================== + //= RichTextEngine + //==================================================================== + class RichTextEngine : public EditEngine + { + private: + SfxItemPool* m_pEnginePool; + ::std::vector< IEngineStatusListener* > m_aStatusListeners; + + public: + static RichTextEngine* Create(); + RichTextEngine* Clone(); + + ~RichTextEngine( ); + + // for multiplexing the StatusChanged events of the edit engine + void registerEngineStatusListener( IEngineStatusListener* _pListener ); + void revokeEngineStatusListener( IEngineStatusListener* _pListener ); + + inline SfxItemPool* getPool() { return m_pEnginePool; } + + protected: + /** constructs a new RichTextEngine. The instances takes the ownership of the given SfxItemPool + */ + RichTextEngine( SfxItemPool* _pPool ); + + private: + RichTextEngine( ); // never implemented + RichTextEngine( const RichTextEngine& ); // never implemented + RichTextEngine& operator=( const RichTextEngine& ); // never implemented + + private: + DECL_LINK( EditEngineStatusChanged, EditStatus* ); + }; + +//........................................................................ +} // namespace frm +//........................................................................ + +#endif // FORMS_SOURCE_RICHTEXT_RICHTEXTENGINE_HXX + diff --git a/forms/source/richtext/richtextimplcontrol.cxx b/forms/source/richtext/richtextimplcontrol.cxx new file mode 100644 index 000000000000..7aac8918c877 --- /dev/null +++ b/forms/source/richtext/richtextimplcontrol.cxx @@ -0,0 +1,680 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_forms.hxx" +#include "richtextimplcontrol.hxx" +#include "textattributelistener.hxx" +#include "richtextengine.hxx" +#include <editeng/editeng.hxx> +#include <editeng/editview.hxx> +#include <editeng/eeitem.hxx> +#include <editeng/editstat.hxx> +#ifndef _SVX_SVXIDS_HRC +#include <svx/svxids.hrc> +#endif +#include <editeng/scripttypeitem.hxx> + +#include <editeng/editobj.hxx> +#include <svl/itempool.hxx> +#include <svl/itemset.hxx> +#include <tools/mapunit.hxx> +#include <vcl/window.hxx> +#include <vcl/svapp.hxx> + +#include <memory> + +#define EMPTY_PAPER_SIZE 0x7FFFFFFF + +//........................................................................ +namespace frm +{ +//........................................................................ + //==================================================================== + //= RichTextControlImpl + //==================================================================== + //-------------------------------------------------------------------- + RichTextControlImpl::RichTextControlImpl( Control* _pAntiImpl, RichTextEngine* _pEngine, ITextAttributeListener* _pTextAttrListener, ITextSelectionListener* _pSelectionListener ) + :m_pAntiImpl ( _pAntiImpl ) + ,m_pViewport ( NULL ) + ,m_pHScroll ( NULL ) + ,m_pVScroll ( NULL ) + ,m_pScrollCorner ( NULL ) + ,m_pEngine ( _pEngine ) + ,m_pView ( NULL ) + ,m_pTextAttrListener ( _pTextAttrListener ) + ,m_pSelectionListener ( _pSelectionListener ) + ,m_bHasEverBeenShown ( false ) + { + OSL_ENSURE( m_pAntiImpl, "RichTextControlImpl::RichTextControlImpl: invalid window!" ); + OSL_ENSURE( m_pEngine, "RichTextControlImpl::RichTextControlImpl: invalid edit engine! This will *definately* crash!" ); + + m_pViewport = new RichTextViewPort( m_pAntiImpl ); + m_pViewport->setAttributeInvalidationHandler( LINK( this, RichTextControlImpl, OnInvalidateAllAttributes ) ); + m_pViewport->Show(); + + // ensure that both the window and the reference device have the same map unit + MapMode aRefDeviceMapMode( m_pEngine->GetRefDevice()->GetMapMode() ); + m_pAntiImpl->SetMapMode( aRefDeviceMapMode ); + m_pViewport->SetMapMode( aRefDeviceMapMode ); + + m_pView = new EditView( m_pEngine, m_pViewport ); + m_pEngine->InsertView( m_pView ); + m_pViewport->setView( *m_pView ); + + m_pEngine->registerEngineStatusListener( this ); + + { + ULONG nViewControlWord = m_pView->GetControlWord(); + nViewControlWord |= EV_CNTRL_AUTOSCROLL; + m_pView->SetControlWord( nViewControlWord ); + } + + // ensure that it's initially scrolled to the upper left + m_pView->SetVisArea( Rectangle( Point( ), m_pViewport->GetOutputSize() ) ); + + ensureScrollbars(); + + m_pAntiImpl->SetBackground( Wallpaper( m_pAntiImpl->GetSettings().GetStyleSettings().GetFieldColor() ) ); + } + + //-------------------------------------------------------------------- + RichTextControlImpl::~RichTextControlImpl( ) + { + m_pEngine->RemoveView( m_pView ); + m_pEngine->revokeEngineStatusListener( this ); + delete m_pView; + delete m_pViewport; + delete m_pHScroll; + delete m_pVScroll; + delete m_pScrollCorner; + } + + //-------------------------------------------------------------------- + void RichTextControlImpl::implUpdateAttribute( AttributeHandlerPool::const_iterator _pHandler ) + { + if ( ( _pHandler->first == SID_ATTR_CHAR_WEIGHT ) + || ( _pHandler->first == SID_ATTR_CHAR_POSTURE ) + || ( _pHandler->first == SID_ATTR_CHAR_FONT ) + || ( _pHandler->first == SID_ATTR_CHAR_FONTHEIGHT ) + ) + { + // these are attributes whose value depends on the current script type. + // I.e., in real, there are *three* items in the ItemSet: One for each script + // type (Latin, Asian, Complex). However, if we have an observer who is interested + // in the state of this attribute, we have to kind of *merge* the three attributes + // to only one. + // This is usefull in case the observer is for instance a toolbox which contains only + // an, e.g., "bold" slot, and thus not interested in the particular script type of the + // current selection. + SvxScriptSetItem aNormalizedSet( (WhichId)_pHandler->first, *m_pView->GetAttribs().GetPool() ); + normalizeScriptDependentAttribute( aNormalizedSet ); + + implCheckUpdateCache( _pHandler->first, _pHandler->second->getState( aNormalizedSet.GetItemSet() ) ); + } + else + implCheckUpdateCache( _pHandler->first, _pHandler->second->getState( m_pView->GetAttribs() ) ); + } + + //-------------------------------------------------------------------- + void RichTextControlImpl::updateAttribute( AttributeId _nAttribute ) + { + AttributeHandlerPool::const_iterator pHandler = m_aAttributeHandlers.find( _nAttribute ); + if ( pHandler != m_aAttributeHandlers.end() ) + implUpdateAttribute( pHandler ); + } + + //-------------------------------------------------------------------- + void RichTextControlImpl::updateAllAttributes( ) + { + for ( AttributeHandlerPool::const_iterator pHandler = m_aAttributeHandlers.begin(); + pHandler != m_aAttributeHandlers.end(); + ++pHandler + ) + { + implUpdateAttribute( pHandler ); + } + + // notify changes of the selection, if necessary + if ( m_pSelectionListener && m_pView ) + { + ESelection aCurrentSelection = m_pView->GetSelection(); + if ( !aCurrentSelection.IsEqual( m_aLastKnownSelection ) ) + { + m_aLastKnownSelection = aCurrentSelection; + m_pSelectionListener->onSelectionChanged( m_aLastKnownSelection ); + } + } + } + + //-------------------------------------------------------------------- + AttributeState RichTextControlImpl::getAttributeState( AttributeId _nAttributeId ) const + { + StateCache::const_iterator aCachedStatePos = m_aLastKnownStates.find( _nAttributeId ); + if ( aCachedStatePos == m_aLastKnownStates.end() ) + { + OSL_ENSURE( sal_False, "RichTextControlImpl::getAttributeState: Don't ask for the state of an attribute which I never encountered!" ); + return AttributeState( eIndetermined ); + } + return aCachedStatePos->second; + } + + //-------------------------------------------------------------------- + bool RichTextControlImpl::executeAttribute( const SfxItemSet& _rCurrentAttribs, SfxItemSet& _rAttribs, AttributeId _nAttribute, const SfxPoolItem* _pArgument, ScriptType _nForScriptType ) + { + // let's see whether we have a handler for this attribute + AttributeHandlerPool::const_iterator aHandlerPos = m_aAttributeHandlers.find( _nAttribute ); + if ( aHandlerPos != m_aAttributeHandlers.end() ) + { + aHandlerPos->second->executeAttribute( _rCurrentAttribs, _rAttribs, _pArgument, _nForScriptType ); + return true; + } + return false; + } + + //-------------------------------------------------------------------- + void RichTextControlImpl::enableAttributeNotification( AttributeId _nAttributeId, ITextAttributeListener* _pListener ) + { + AttributeHandlerPool::const_iterator aHandlerPos = m_aAttributeHandlers.find( _nAttributeId ); + if ( aHandlerPos == m_aAttributeHandlers.end() ) + { + ::rtl::Reference< IAttributeHandler > aHandler = AttributeHandlerFactory::getHandlerFor( _nAttributeId, *m_pEngine->GetEmptyItemSet().GetPool() ); + OSL_ENSURE( aHandler.is(), "RichTextControlImpl::enableAttributeNotification: no handler available for this attribute!" ); + if ( !aHandler.is() ) + return; + OSL_POSTCOND( _nAttributeId == aHandler->getAttributeId(), "RichTextControlImpl::enableAttributeNotification: suspicious handler!" ); + + aHandlerPos = m_aAttributeHandlers.insert( AttributeHandlerPool::value_type( _nAttributeId , aHandler ) ).first; + } + + // remember the listener + if ( _pListener ) + m_aAttributeListeners.insert( AttributeListenerPool::value_type( _nAttributeId, _pListener ) ); + + // update (and broadcast) the state of this attribute + updateAttribute( _nAttributeId ); + } + + //-------------------------------------------------------------------- + void RichTextControlImpl::disableAttributeNotification( AttributeId _nAttributeId ) + { + // forget the handler for this attribute + AttributeHandlerPool::iterator aHandlerPos = m_aAttributeHandlers.find( _nAttributeId ); + if ( aHandlerPos != m_aAttributeHandlers.end() ) + m_aAttributeHandlers.erase( aHandlerPos ); + + // as well as the listener + AttributeListenerPool::iterator aListenerPos = m_aAttributeListeners.find( _nAttributeId ); + if ( aListenerPos != m_aAttributeListeners.end() ) + m_aAttributeListeners.erase( aListenerPos ); + } + + //-------------------------------------------------------------------- + void RichTextControlImpl::normalizeScriptDependentAttribute( SvxScriptSetItem& _rScriptSetItem ) + { + _rScriptSetItem.GetItemSet().Put( m_pView->GetAttribs(), FALSE ); + const SfxPoolItem* pNormalizedItem = _rScriptSetItem.GetItemOfScript( getSelectedScriptType() ); + + WhichId nNormalizedWhichId = _rScriptSetItem.GetItemSet().GetPool()->GetWhich( _rScriptSetItem.Which() ); + if ( pNormalizedItem ) + { + SfxPoolItem* pProperWhich = pNormalizedItem->Clone(); + pProperWhich->SetWhich( nNormalizedWhichId ); + _rScriptSetItem.GetItemSet().Put( *pProperWhich ); + DELETEZ( pProperWhich ); + } + else + _rScriptSetItem.GetItemSet().InvalidateItem( nNormalizedWhichId ); + } + + //-------------------------------------------------------------------- + void RichTextControlImpl::implCheckUpdateCache( AttributeId _nAttribute, const AttributeState& _rState ) + { + StateCache::iterator aCachePos = m_aLastKnownStates.find( _nAttribute ); + if ( aCachePos == m_aLastKnownStates.end() ) + { // nothing known about this attribute, yet + m_aLastKnownStates.insert( StateCache::value_type( _nAttribute, _rState ) ); + } + else + { + if ( aCachePos->second == _rState ) + { + // nothing to do + return; + } + aCachePos->second = _rState; + } + + // is there a dedicated listener for this particular attribute? + AttributeListenerPool::const_iterator aListenerPos = m_aAttributeListeners.find( _nAttribute ); + if ( aListenerPos != m_aAttributeListeners.end( ) ) + aListenerPos->second->onAttributeStateChanged( _nAttribute, _rState ); + + // call our global listener, if there is one + if ( m_pTextAttrListener ) + m_pTextAttrListener->onAttributeStateChanged( _nAttribute, _rState ); + } + + //-------------------------------------------------------------------- + ScriptType RichTextControlImpl::getSelectedScriptType() const + { + ScriptType nScript = m_pView->GetSelectedScriptType(); + if ( !nScript ) + nScript = SvtLanguageOptions::GetScriptTypeOfLanguage( Application::GetSettings().GetLanguage() ); + return nScript; + } + + //-------------------------------------------------------------------- + void RichTextControlImpl::EditEngineStatusChanged( const EditStatus& _rStatus ) + { + ULONG nStatusWord( _rStatus.GetStatusWord() ); + if ( ( nStatusWord & EE_STAT_TEXTWIDTHCHANGED ) + || ( nStatusWord & EE_STAT_TEXTHEIGHTCHANGED ) + ) + { + if ( ( nStatusWord & EE_STAT_TEXTHEIGHTCHANGED ) && windowHasAutomaticLineBreak() ) + m_pEngine->SetPaperSize( Size( m_pEngine->GetPaperSize().Width(), m_pEngine->GetTextHeight() ) ); + + updateScrollbars(); + } + + bool bHScroll = 0 != ( nStatusWord & EE_STAT_HSCROLL ); + bool bVScroll = 0 != ( nStatusWord & EE_STAT_VSCROLL ); + + // In case of *no* automatic line breaks, we also need to check for the *range* here. + // Normally, we would do this only after a EE_STAT_TEXTWIDTHCHANGED. However, due to a bug + // in the EditEngine (I believe so) this is not fired when the engine does not have + // the AutoPaperSize bits set. + // So in order to be properly notified, we would need the AutoPaperSize. But, with + // AutoPaperSize, other things do not work anymore: Either, when we set a MaxAutoPaperSize, + // then the view does automatic soft line breaks at the paper end - which we definately do + // want. Or, if we did not set a MaxAutoPaperSize, then the view does not automatically scroll + // anymore in horizontal direction. + // So this is some kind of lose-lose situation ... :( + if ( !windowHasAutomaticLineBreak() && bHScroll ) + { + updateScrollbars(); + return; + } + + if ( bHScroll && m_pHScroll ) + m_pHScroll->SetThumbPos( m_pView->GetVisArea().Left() ); + if ( bVScroll && m_pVScroll ) + m_pVScroll->SetThumbPos( m_pView->GetVisArea().Top() ); + } + + //-------------------------------------------------------------------- + IMPL_LINK( RichTextControlImpl, OnInvalidateAllAttributes, void*, /*_pNotInterestedIn*/ ) + { + updateAllAttributes(); + return 0L; + } + + //-------------------------------------------------------------------- + IMPL_LINK( RichTextControlImpl, OnHScroll, ScrollBar*, _pScrollbar ) + { + m_pView->Scroll( -_pScrollbar->GetDelta(), 0, RGCHK_PAPERSZ1 ); + return 0L; + } + + //-------------------------------------------------------------------- + IMPL_LINK( RichTextControlImpl, OnVScroll, ScrollBar*, _pScrollbar ) + { + m_pView->Scroll( 0, -_pScrollbar->GetDelta(), RGCHK_PAPERSZ1 ); + return 0L; + } + + //-------------------------------------------------------------------- + void RichTextControlImpl::ensureScrollbars() + { + bool bNeedVScroll = 0 != ( m_pAntiImpl->GetStyle() & WB_VSCROLL ); + bool bNeedHScroll = 0 != ( m_pAntiImpl->GetStyle() & WB_HSCROLL ); + + if ( ( bNeedVScroll == hasVScrollBar() ) && ( bNeedHScroll == hasHScrollBar( ) ) ) + // nothing to do + return; + + // create or delete the scrollbars, as necessary + if ( !bNeedVScroll ) + { + delete m_pVScroll; + m_pVScroll = NULL; + } + else + { + m_pVScroll = new ScrollBar( m_pAntiImpl, WB_VSCROLL | WB_DRAG | WB_REPEAT ); + m_pVScroll->SetScrollHdl ( LINK( this, RichTextControlImpl, OnVScroll ) ); + m_pVScroll->Show(); + } + + if ( !bNeedHScroll ) + { + delete m_pHScroll; + m_pHScroll = NULL; + } + else + { + m_pHScroll = new ScrollBar( m_pAntiImpl, WB_HSCROLL | WB_DRAG | WB_REPEAT ); + m_pHScroll->SetScrollHdl ( LINK( this, RichTextControlImpl, OnHScroll ) ); + m_pHScroll->Show(); + } + + if ( m_pHScroll && m_pVScroll ) + { + delete m_pScrollCorner; + m_pScrollCorner = new ScrollBarBox( m_pAntiImpl ); + m_pScrollCorner->Show(); + } + else + { + delete m_pScrollCorner; + m_pScrollCorner = NULL; + } + + layoutWindow(); + } + + //-------------------------------------------------------------------- + void RichTextControlImpl::ensureLineBreakSetting() + { + if ( !windowHasAutomaticLineBreak() ) + m_pEngine->SetPaperSize( Size( EMPTY_PAPER_SIZE, EMPTY_PAPER_SIZE ) ); + + layoutWindow(); + } + + //-------------------------------------------------------------------- + void RichTextControlImpl::layoutWindow() + { + if ( !m_bHasEverBeenShown ) + // no need to do anything. Especially, no need to set the paper size on the + // EditEngine to anything .... + return; + + const StyleSettings& rStyleSettings = m_pAntiImpl->GetSettings().GetStyleSettings(); + + long nScrollBarWidth = m_pVScroll ? rStyleSettings.GetScrollBarSize() : 0; + long nScrollBarHeight = m_pHScroll ? rStyleSettings.GetScrollBarSize() : 0; + + if ( m_pAntiImpl->IsZoom() ) + { + nScrollBarWidth = m_pAntiImpl->CalcZoom( nScrollBarWidth ); + nScrollBarHeight = m_pAntiImpl->CalcZoom( nScrollBarHeight ); + } + + // the overall size we can use + Size aPlaygroundSizePixel( m_pAntiImpl->GetOutputSizePixel() ); + + // the size of the viewport - note that the viewport does *not* occupy all the place + // which is left when subtracting the scrollbar width/height + Size aViewportPlaygroundPixel( aPlaygroundSizePixel ); + aViewportPlaygroundPixel.Width() = ::std::max( long( 10 ), long( aViewportPlaygroundPixel.Width() - nScrollBarWidth ) ); + aViewportPlaygroundPixel.Height() = ::std::max( long( 10 ), long( aViewportPlaygroundPixel.Height() - nScrollBarHeight ) ); + Size aViewportPlaygroundLogic( m_pViewport->PixelToLogic( aViewportPlaygroundPixel ) ); + + const long nOffset = 2; + Size aViewportSizePixel( aViewportPlaygroundPixel.Width() - 2 * nOffset, aViewportPlaygroundPixel.Height() - 2 * nOffset ); + Size aViewportSizeLogic( m_pViewport->PixelToLogic( aViewportSizePixel ) ); + + // position the viewport + m_pViewport->SetPosSizePixel( Point( nOffset, nOffset ), aViewportSizePixel ); + // position the scrollbars + if ( m_pVScroll ) + m_pVScroll->SetPosSizePixel( Point( aViewportPlaygroundPixel.Width(), 0 ), Size( nScrollBarWidth, aViewportPlaygroundPixel.Height() ) ); + if ( m_pHScroll ) + m_pHScroll->SetPosSizePixel( Point( 0, aViewportPlaygroundPixel.Height() ), Size( aViewportPlaygroundPixel.Width(), nScrollBarHeight ) ); + if ( m_pScrollCorner ) + m_pScrollCorner->SetPosSizePixel( Point( aViewportPlaygroundPixel.Width(), aViewportPlaygroundPixel.Height() ), Size( nScrollBarWidth, nScrollBarHeight ) ); + + // paper size + if ( windowHasAutomaticLineBreak() ) + m_pEngine->SetPaperSize( Size( aViewportSizeLogic.Width(), m_pEngine->GetTextHeight() ) ); + + // output area of the view + m_pView->SetOutputArea( Rectangle( Point( ), aViewportSizeLogic ) ); + m_pView->SetVisArea( Rectangle( Point( ), aViewportSizeLogic ) ); + + if ( m_pVScroll ) + { + m_pVScroll->SetVisibleSize( aViewportPlaygroundLogic.Height() ); + + // the default height of a text line .... + long nFontHeight = m_pEngine->GetStandardFont(0).GetSize().Height(); + // ... is the scroll size for the vertical scrollbar + m_pVScroll->SetLineSize( nFontHeight ); + // the viewport width, minus one line, is the page scroll size + m_pVScroll->SetPageSize( ::std::max( nFontHeight, aViewportPlaygroundLogic.Height() - nFontHeight ) ); + } + + // the font width + if ( m_pHScroll ) + { + m_pHScroll->SetVisibleSize( aViewportPlaygroundLogic.Width() ); + + long nFontWidth = m_pEngine->GetStandardFont(0).GetSize().Width(); + if ( !nFontWidth ) + { + m_pViewport->Push( PUSH_FONT ); + m_pViewport->SetFont( m_pEngine->GetStandardFont(0) ); + nFontWidth = m_pViewport->GetTextWidth( String( RTL_CONSTASCII_USTRINGPARAM( "x" ) ) ); + m_pViewport->Pop(); + } + // ... is the scroll size for the horizontal scrollbar + m_pHScroll->SetLineSize( 5 * nFontWidth ); + // the viewport height, minus one character, is the page scroll size + m_pHScroll->SetPageSize( ::std::max( nFontWidth, aViewportPlaygroundLogic.Width() - nFontWidth ) ); + } + + // update range and position of the scrollbars + updateScrollbars(); + } + + //-------------------------------------------------------------------- + void RichTextControlImpl::updateScrollbars() + { + if ( m_pVScroll ) + { + long nOverallTextHeight = m_pEngine->GetTextHeight(); + m_pVScroll->SetRange( Range( 0, nOverallTextHeight ) ); + m_pVScroll->SetThumbPos( m_pView->GetVisArea().Top() ); + } + + if ( m_pHScroll ) + { + Size aPaperSize( m_pEngine->GetPaperSize() ); + long nOverallTextWidth = ( aPaperSize.Width() == EMPTY_PAPER_SIZE ) ? m_pEngine->CalcTextWidth() : aPaperSize.Width(); + m_pHScroll->SetRange( Range( 0, nOverallTextWidth ) ); + m_pHScroll->SetThumbPos( m_pView->GetVisArea().Left() ); + } + } + + //-------------------------------------------------------------------- + void RichTextControlImpl::notifyInitShow() + { + if ( !m_bHasEverBeenShown ) + { + m_bHasEverBeenShown = true; + layoutWindow(); + } + } + + //-------------------------------------------------------------------- + void RichTextControlImpl::notifyStyleChanged() + { + ensureScrollbars(); + ensureLineBreakSetting(); + } + + //-------------------------------------------------------------------- + void RichTextControlImpl::notifyZoomChanged() + { + const Fraction& rZoom = m_pAntiImpl->GetZoom(); + + MapMode aMapMode( m_pAntiImpl->GetMapMode() ); + aMapMode.SetScaleX( rZoom ); + aMapMode.SetScaleY( rZoom ); + m_pAntiImpl->SetMapMode( aMapMode ); + + m_pViewport->SetZoom( rZoom ); + m_pViewport->SetMapMode( aMapMode ); + + layoutWindow(); + } + + //-------------------------------------------------------------------- + bool RichTextControlImpl::windowHasAutomaticLineBreak() + { + return ( m_pAntiImpl->GetStyle() & WB_WORDBREAK ) != 0; + } + + //-------------------------------------------------------------------- + void RichTextControlImpl::SetReadOnly( bool _bReadOnly ) + { + m_pView->SetReadOnly( _bReadOnly ); + } + + //-------------------------------------------------------------------- + bool RichTextControlImpl::IsReadOnly() const + { + return m_pView->IsReadOnly( ); + } + + //-------------------------------------------------------------------- + namespace + { + static void lcl_inflate( Rectangle& _rRect, long _nInflateX, long _nInflateY ) + { + _rRect.Left() -= _nInflateX; + _rRect.Right() += _nInflateX; + _rRect.Top() -= _nInflateY; + _rRect.Bottom() += _nInflateY; + } + } + //-------------------------------------------------------------------- + long RichTextControlImpl::HandleCommand( const CommandEvent& _rEvent ) + { + if ( ( _rEvent.GetCommand() == COMMAND_WHEEL ) + || ( _rEvent.GetCommand() == COMMAND_STARTAUTOSCROLL ) + || ( _rEvent.GetCommand() == COMMAND_AUTOSCROLL ) + ) + { + m_pAntiImpl->HandleScrollCommand( _rEvent, m_pHScroll, m_pVScroll ); + return 1; + } + return 0; + } + + //-------------------------------------------------------------------- + void RichTextControlImpl::Draw( OutputDevice* _pDev, const Point& _rPos, const Size& _rSize, ULONG /*_nFlags*/ ) + { + // need to normalize the map mode of the device - every paint operation on any device needs + // to use the same map mode + _pDev->Push( PUSH_MAPMODE | PUSH_LINECOLOR | PUSH_FILLCOLOR ); + + // enforce our "normalize map mode" on the device + MapMode aRefMapMode( m_pEngine->GetRefDevice()->GetMapMode() ); + MapMode aOriginalMapMode( _pDev->GetMapMode() ); + MapMode aNormalizedMapMode( aRefMapMode.GetMapUnit(), aRefMapMode.GetOrigin(), aOriginalMapMode.GetScaleX(), aOriginalMapMode.GetScaleY() ); + _pDev->SetMapMode( aNormalizedMapMode ); + + // translate coordinates + Point aPos( _rPos ); + Size aSize( _rSize ); + if ( aOriginalMapMode.GetMapUnit() == MAP_PIXEL ) + { + aPos = _pDev->PixelToLogic( _rPos, aNormalizedMapMode ); + aSize = _pDev->PixelToLogic( _rSize, aNormalizedMapMode ); + } + else + { + aPos = OutputDevice::LogicToLogic( _rPos, aOriginalMapMode, aNormalizedMapMode ); + aSize = OutputDevice::LogicToLogic( _rSize, aOriginalMapMode, aNormalizedMapMode ); + } + + Rectangle aPlayground( aPos, aSize ); + Size aOnePixel( _pDev->PixelToLogic( Size( 1, 1 ) ) ); + aPlayground.Right() -= aOnePixel.Width(); + aPlayground.Bottom() -= aOnePixel.Height(); + + // background + _pDev->SetLineColor(); + _pDev->DrawRect( aPlayground ); + + // do we need to draw a border? + bool bBorder = ( m_pAntiImpl->GetStyle() & WB_BORDER ); + if ( bBorder ) + _pDev->SetLineColor( m_pAntiImpl->GetSettings().GetStyleSettings().GetMonoColor() ); + else + _pDev->SetLineColor(); + _pDev->SetFillColor( m_pAntiImpl->GetBackground().GetColor() ); + _pDev->DrawRect( aPlayground ); + + if ( bBorder ) + // don't draw the text over the border + lcl_inflate( aPlayground, -aOnePixel.Width(), -aOnePixel.Height() ); + + // leave a space of one pixel between the "surroundings" of the control + // and the content + lcl_inflate( aPlayground, -aOnePixel.Width(), -aOnePixel.Height() ); + lcl_inflate( aPlayground, -aOnePixel.Width(), -aOnePixel.Height() ); + + // actually draw the content + m_pEngine->Draw( _pDev, aPlayground, Point(), TRUE ); + + _pDev->Pop(); + } + + //-------------------------------------------------------------------- + void RichTextControlImpl::SetBackgroundColor( ) + { + SetBackgroundColor( Application::GetSettings().GetStyleSettings().GetFieldColor() ); + } + + //-------------------------------------------------------------------- + void RichTextControlImpl::SetBackgroundColor( const Color& _rColor ) + { + Wallpaper aWallpaper( _rColor ); + m_pAntiImpl->SetBackground( aWallpaper ); + m_pViewport->SetBackground( aWallpaper ); + } + + //-------------------------------------------------------------------- + void RichTextControlImpl::SetHideInactiveSelection( bool _bHide ) + { + m_pViewport->SetHideInactiveSelection( _bHide ); + } + + //-------------------------------------------------------------------- + bool RichTextControlImpl::GetHideInactiveSelection() const + { + return m_pViewport->GetHideInactiveSelection( ); + } + +//........................................................................ +} // namespace frm +//........................................................................ + diff --git a/forms/source/richtext/richtextimplcontrol.hxx b/forms/source/richtext/richtextimplcontrol.hxx new file mode 100644 index 000000000000..619766bbfc4e --- /dev/null +++ b/forms/source/richtext/richtextimplcontrol.hxx @@ -0,0 +1,196 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef FORMS_SOURCE_RICHTEXT_RICHTEXTIMPLCONTOL_HXX +#define FORMS_SOURCE_RICHTEXT_RICHTEXTIMPLCONTOL_HXX + +#include "rtattributehandler.hxx" +#include "richtextviewport.hxx" +#include "richtextengine.hxx" +#include <vcl/scrbar.hxx> +#include <editeng/editdata.hxx> + +#include <map> + +class EditView; +class EditStatus; +class Window; +class SvxScriptSetItem; +//........................................................................ +namespace frm +{ +//........................................................................ + + class ITextAttributeListener; + class ITextSelectionListener; + class RichTextViewPort; + //==================================================================== + //= RichTextControlImpl + //==================================================================== + class RichTextControlImpl : public IEngineStatusListener + { + typedef ::std::map< AttributeId, AttributeState > StateCache; + typedef ::std::map< AttributeId, ::rtl::Reference< IAttributeHandler > > AttributeHandlerPool; + typedef ::std::map< AttributeId, ITextAttributeListener* > AttributeListenerPool; + + StateCache m_aLastKnownStates; + AttributeHandlerPool m_aAttributeHandlers; + AttributeListenerPool m_aAttributeListeners; + + ESelection m_aLastKnownSelection; + + Control* m_pAntiImpl; + RichTextViewPort* m_pViewport; + ScrollBar* m_pHScroll; + ScrollBar* m_pVScroll; + ScrollBarBox* m_pScrollCorner; + RichTextEngine* m_pEngine; + EditView* m_pView; + ITextAttributeListener* m_pTextAttrListener; + ITextSelectionListener* m_pSelectionListener; + bool m_bHasEverBeenShown; + + public: + struct GrantAccess { friend class RichTextControl; private: GrantAccess() { } }; + inline EditView* getView( const GrantAccess& ) const { return m_pView; } + inline RichTextEngine* getEngine( const GrantAccess& ) const { return m_pEngine; } + inline Window* getViewport( const GrantAccess& ) const { return m_pViewport; } + + public: + RichTextControlImpl( Control* _pAntiImpl, RichTextEngine* _pEngine, + ITextAttributeListener* _pTextAttrListener, ITextSelectionListener* _pSelectionListener ); + virtual ~RichTextControlImpl(); + + /** updates the cache with the state of all attribute values from the given set, notifies + the listener if the state changed + */ + void updateAllAttributes( ); + + /** updates the cache with the state of the attribute given by which id, notifies + the listener if the state changed + */ + void updateAttribute( AttributeId _nAttribute ); + + /// enables the callback for a particular attribute + void enableAttributeNotification( AttributeId _nAttributeId, ITextAttributeListener* _pListener = NULL ); + + /// disables the change notifications for a particular attribute + void disableAttributeNotification( AttributeId _nAttributeId ); + + /// executes a toggle of the given attribute + bool executeAttribute( const SfxItemSet& _rCurrentAttribs, SfxItemSet& _rNewAttribs, AttributeId _nAttribute, const SfxPoolItem* _pArgument, ScriptType _nForScriptType ); + + /// retrieves the state of the given attribute from the cache + AttributeState getAttributeState( AttributeId _nAttributeId ) const; + + /** normalizes the given item so that the state of script dependent attributes + is correct considering the current script type + + There are some attributes which are script dependent, e.g. the CharPosture. This means + that in real, there are 3 attributes for this, one for every possible script type (latin, + asian, complex). However, to the out world, we behave as if there is only one attribute: + E.g., if the outter world asks for the state of the "CharPosture" attribute, we return + the state of either CharPostureLatin, CharPostureAsian, or CharPostureComplex, depending + on the script type of the current selection. (In real, it may be more complex since + the current selection may contain more than one script type.) + + This method normalizes a script dependent attribute, so that it's state takes into account + the currently selected script type. + */ + void normalizeScriptDependentAttribute( SvxScriptSetItem& _rScriptSetItem ); + + // gets the script type of the selection in our edit view (with fallback) + ScriptType getSelectedScriptType() const; + + /** re-arranges the view and the scrollbars + */ + void layoutWindow(); + + /** to be called when the style of our window changed + */ + void notifyStyleChanged(); + + /** to be called when the zoom of our window changed + */ + void notifyZoomChanged(); + + /** to be called when the STATE_CHANGE_INITSHOW event arrives + */ + void notifyInitShow(); + + // VCL "overrides" + void SetBackgroundColor( ); + void SetBackgroundColor( const Color& _rColor ); + + void SetReadOnly( bool _bReadOnly ); + bool IsReadOnly() const; + + void SetHideInactiveSelection( bool _bHide ); + bool GetHideInactiveSelection() const; + + /// draws the control onto a given output device + void Draw( OutputDevice* _pDev, const Point& _rPos, const Size& _rSize, ULONG _nFlags ); + + /// handles command events arrived at the anti-impl control + long HandleCommand( const CommandEvent& _rEvent ); + + private: + // updates the cache with the state provided by the given attribut handler + void implUpdateAttribute( AttributeHandlerPool::const_iterator _pHandler ); + + // updates the cache with the given state, and calls listeners (if necessary) + void implCheckUpdateCache( AttributeId _nAttribute, const AttributeState& _rState ); + + // updates range and position of our scrollbars + void updateScrollbars(); + + // determines whether automatic (soft) line breaks are ON + bool windowHasAutomaticLineBreak(); + + /// hides or shows our scrollbars, according to the current WinBits of the window + void ensureScrollbars(); + + /// ensures that our "automatic line break" setting matches the current WinBits of the window + void ensureLineBreakSetting(); + + inline bool hasVScrollBar( ) const { return m_pVScroll != NULL; } + inline bool hasHScrollBar( ) const { return m_pHScroll != NULL; } + + // IEngineStatusListener overridables + virtual void EditEngineStatusChanged( const EditStatus& _rStatus ); + + private: + DECL_LINK( OnInvalidateAllAttributes, void* ); + DECL_LINK( OnHScroll, ScrollBar* ); + DECL_LINK( OnVScroll, ScrollBar* ); + }; + +//........................................................................ +} // namespace frm +//........................................................................ + +#endif // FORMS_SOURCE_RICHTEXT_RICHTEXTIMPLCONTOL_HXX + diff --git a/forms/source/richtext/richtextmodel.cxx b/forms/source/richtext/richtextmodel.cxx new file mode 100644 index 000000000000..46a77c6dd791 --- /dev/null +++ b/forms/source/richtext/richtextmodel.cxx @@ -0,0 +1,638 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_forms.hxx" + +#ifndef FORMS_SOURCE_RICHTEXT_RICHTEXTMODEL_CXX +#include "richtextmodel.hxx" +#endif +#include "richtextengine.hxx" +#include "richtextunowrapper.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/awt/LineEndFormat.hpp> +#include <com/sun/star/text/WritingMode2.hpp> +#include <com/sun/star/style/VerticalAlignment.hpp> +/** === end UNO includes === **/ + +#include <cppuhelper/typeprovider.hxx> +#include <comphelper/guarding.hxx> +#include <toolkit/awt/vclxdevice.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <editeng/editstat.hxx> +#include <vcl/outdev.hxx> +#include <vcl/svapp.hxx> + +//-------------------------------------------------------------------------- +extern "C" void SAL_CALL createRegistryInfo_ORichTextModel() +{ + static ::frm::OMultiInstanceAutoRegistration< ::frm::ORichTextModel > aRegisterModel; +} + +//........................................................................ +namespace frm +{ +//........................................................................ + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::awt; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::io; + using namespace ::com::sun::star::beans; + using namespace ::com::sun::star::form; + using namespace ::com::sun::star::util; + using namespace ::com::sun::star::style; + + namespace WritingMode2 = ::com::sun::star::text::WritingMode2; + + //==================================================================== + //= ORichTextModel + //==================================================================== + DBG_NAME( ORichTextModel ) + //-------------------------------------------------------------------- + ORichTextModel::ORichTextModel( const Reference< XMultiServiceFactory >& _rxFactory ) + :OControlModel ( _rxFactory, ::rtl::OUString() ) + ,FontControlModel ( true ) + ,m_pEngine ( RichTextEngine::Create() ) + ,m_bSettingEngineText( false ) + ,m_aModifyListeners ( m_aMutex ) + { + DBG_CTOR( ORichTextModel, NULL ); + m_nClassId = FormComponentType::TEXTFIELD; + + getPropertyDefaultByHandle( PROPERTY_ID_DEFAULTCONTROL ) >>= m_sDefaultControl; + getPropertyDefaultByHandle( PROPERTY_ID_BORDER ) >>= m_nBorder; + getPropertyDefaultByHandle( PROPERTY_ID_ENABLED ) >>= m_bEnabled; + getPropertyDefaultByHandle( PROPERTY_ID_ENABLEVISIBLE ) >>= m_bEnableVisible; + getPropertyDefaultByHandle( PROPERTY_ID_HARDLINEBREAKS ) >>= m_bHardLineBreaks; + getPropertyDefaultByHandle( PROPERTY_ID_HSCROLL ) >>= m_bHScroll; + getPropertyDefaultByHandle( PROPERTY_ID_VSCROLL ) >>= m_bVScroll; + getPropertyDefaultByHandle( PROPERTY_ID_READONLY ) >>= m_bReadonly; + getPropertyDefaultByHandle( PROPERTY_ID_PRINTABLE ) >>= m_bPrintable; + getPropertyDefaultByHandle( PROPERTY_ID_ALIGN ) >>= m_aAlign; + getPropertyDefaultByHandle( PROPERTY_ID_ECHO_CHAR ) >>= m_nEchoChar; + getPropertyDefaultByHandle( PROPERTY_ID_MAXTEXTLEN ) >>= m_nMaxTextLength; + getPropertyDefaultByHandle( PROPERTY_ID_MULTILINE ) >>= m_bMultiLine; + getPropertyDefaultByHandle( PROPERTY_ID_RICH_TEXT ) >>= m_bReallyActAsRichText; + getPropertyDefaultByHandle( PROPERTY_ID_HIDEINACTIVESELECTION ) >>= m_bHideInactiveSelection; + getPropertyDefaultByHandle( PROPERTY_ID_LINEEND_FORMAT ) >>= m_nLineEndFormat; + getPropertyDefaultByHandle( PROPERTY_ID_WRITING_MODE ) >>= m_nTextWritingMode; + getPropertyDefaultByHandle( PROPERTY_ID_CONTEXT_WRITING_MODE ) >>= m_nContextWritingMode; + + implInit(); + } + + //------------------------------------------------------------------ + ORichTextModel::ORichTextModel( const ORichTextModel* _pOriginal, const Reference< XMultiServiceFactory >& _rxFactory ) + :OControlModel ( _pOriginal, _rxFactory, sal_False ) + ,FontControlModel ( _pOriginal ) + ,m_pEngine ( NULL ) + ,m_bSettingEngineText( false ) + ,m_aModifyListeners ( m_aMutex ) + { + DBG_CTOR( ORichTextModel, NULL ); + + m_aTabStop = _pOriginal->m_aTabStop; + m_aBackgroundColor = _pOriginal->m_aBackgroundColor; + m_aBorderColor = _pOriginal->m_aBorderColor; + m_aVerticalAlignment = _pOriginal->m_aVerticalAlignment; + m_sDefaultControl = _pOriginal->m_sDefaultControl; + m_sHelpText = _pOriginal->m_sHelpText; + m_sHelpURL = _pOriginal->m_sHelpURL; + m_nBorder = _pOriginal->m_nBorder; + m_bEnabled = _pOriginal->m_bEnabled; + m_bEnableVisible = _pOriginal->m_bEnableVisible; + m_bHardLineBreaks = _pOriginal->m_bHardLineBreaks; + m_bHScroll = _pOriginal->m_bHScroll; + m_bVScroll = _pOriginal->m_bVScroll; + m_bReadonly = _pOriginal->m_bReadonly; + m_bPrintable = _pOriginal->m_bPrintable; + m_bReallyActAsRichText = _pOriginal->m_bReallyActAsRichText; + m_bHideInactiveSelection = _pOriginal->m_bHideInactiveSelection; + m_nLineEndFormat = _pOriginal->m_nLineEndFormat; + m_nTextWritingMode = _pOriginal->m_nTextWritingMode; + m_nContextWritingMode = _pOriginal->m_nContextWritingMode; + + m_aAlign = _pOriginal->m_aAlign; + m_nEchoChar = _pOriginal->m_nEchoChar; + m_nMaxTextLength = _pOriginal->m_nMaxTextLength; + m_bMultiLine = _pOriginal->m_bMultiLine; + + m_pEngine.reset(_pOriginal->m_pEngine->Clone()); + m_sLastKnownEngineText = m_pEngine->GetText(); + + implInit(); + } + + //------------------------------------------------------------------ + void ORichTextModel::implInit() + { + OSL_ENSURE( m_pEngine.get(), "ORichTextModel::implInit: where's the engine?" ); + if ( m_pEngine.get() ) + { + m_pEngine->SetModifyHdl( LINK( this, ORichTextModel, OnEngineContentModified ) ); + + ULONG nEngineControlWord = m_pEngine->GetControlWord(); + nEngineControlWord = nEngineControlWord & ~EE_CNTRL_AUTOPAGESIZE; + m_pEngine->SetControlWord( nEngineControlWord ); + + VCLXDevice* pUnoRefDevice = new VCLXDevice; + pUnoRefDevice->SetOutputDevice( m_pEngine->GetRefDevice() ); + m_xReferenceDevice = pUnoRefDevice; + } + + implDoAggregation(); + implRegisterProperties(); + } + + //------------------------------------------------------------------ + void ORichTextModel::implDoAggregation() + { + increment( m_refCount ); + + { + m_xAggregate = new ORichTextUnoWrapper( *m_pEngine, this ); + setAggregation( m_xAggregate ); + doSetDelegator(); + } + + decrement( m_refCount ); + } + + //------------------------------------------------------------------ + void ORichTextModel::implRegisterProperties() + { + REGISTER_PROP_2( DEFAULTCONTROL, m_sDefaultControl, BOUND, MAYBEDEFAULT ); + REGISTER_PROP_2( HELPTEXT, m_sHelpText, BOUND, MAYBEDEFAULT ); + REGISTER_PROP_2( HELPURL, m_sHelpURL, BOUND, MAYBEDEFAULT ); + REGISTER_PROP_2( ENABLED, m_bEnabled, BOUND, MAYBEDEFAULT ); + REGISTER_PROP_2( ENABLEVISIBLE, m_bEnableVisible, BOUND, MAYBEDEFAULT ); + REGISTER_PROP_2( BORDER, m_nBorder, BOUND, MAYBEDEFAULT ); + REGISTER_PROP_2( HARDLINEBREAKS, m_bHardLineBreaks, BOUND, MAYBEDEFAULT ); + REGISTER_PROP_2( HSCROLL, m_bHScroll, BOUND, MAYBEDEFAULT ); + REGISTER_PROP_2( VSCROLL, m_bVScroll, BOUND, MAYBEDEFAULT ); + REGISTER_PROP_2( READONLY, m_bReadonly, BOUND, MAYBEDEFAULT ); + REGISTER_PROP_2( PRINTABLE, m_bPrintable, BOUND, MAYBEDEFAULT ); + REGISTER_PROP_2( REFERENCE_DEVICE, m_xReferenceDevice, BOUND, TRANSIENT ); + REGISTER_PROP_2( RICH_TEXT, m_bReallyActAsRichText, BOUND, MAYBEDEFAULT ); + REGISTER_PROP_2( HIDEINACTIVESELECTION, m_bHideInactiveSelection, BOUND, MAYBEDEFAULT ); + + REGISTER_VOID_PROP_2( TABSTOP, m_aTabStop, sal_Bool, BOUND, MAYBEDEFAULT ); + REGISTER_VOID_PROP_2( BACKGROUNDCOLOR, m_aBackgroundColor, sal_Int32, BOUND, MAYBEDEFAULT ); + REGISTER_VOID_PROP_2( BORDERCOLOR, m_aBorderColor, sal_Int32, BOUND, MAYBEDEFAULT ); + REGISTER_VOID_PROP_2( VERTICAL_ALIGN, m_aVerticalAlignment, VerticalAlignment, BOUND, MAYBEDEFAULT ); + + // properties which exist only for compatibility with the css.swt.UnoControlEditModel, + // since we replace the default implementation for this service + REGISTER_PROP_2( ECHO_CHAR, m_nEchoChar, BOUND, MAYBEDEFAULT ); + REGISTER_PROP_2( MAXTEXTLEN, m_nMaxTextLength, BOUND, MAYBEDEFAULT ); + REGISTER_PROP_2( MULTILINE, m_bMultiLine, BOUND, MAYBEDEFAULT ); + REGISTER_PROP_2( TEXT, m_sLastKnownEngineText, BOUND, MAYBEDEFAULT ); + REGISTER_PROP_2( LINEEND_FORMAT, m_nLineEndFormat, BOUND, MAYBEDEFAULT ); + REGISTER_PROP_2( WRITING_MODE, m_nTextWritingMode, BOUND, MAYBEDEFAULT ); + REGISTER_PROP_3( CONTEXT_WRITING_MODE, m_nContextWritingMode, BOUND, MAYBEDEFAULT, TRANSIENT ); + + REGISTER_VOID_PROP_2( ALIGN, m_aAlign, sal_Int16, BOUND, MAYBEDEFAULT ); + } + + //-------------------------------------------------------------------- + ORichTextModel::~ORichTextModel( ) + { + if ( !OComponentHelper::rBHelper.bDisposed ) + { + acquire(); + dispose(); + } + if ( m_pEngine.get() ) + { + SfxItemPool* pPool = m_pEngine->getPool(); + m_pEngine.reset(); + SfxItemPool::Free(pPool); + } + + + DBG_DTOR( ORichTextModel, NULL ); + } + + //------------------------------------------------------------------ + Any SAL_CALL ORichTextModel::queryAggregation( const Type& _rType ) throw ( RuntimeException ) + { + Any aReturn = ORichTextModel_BASE::queryInterface( _rType ); + + if ( !aReturn.hasValue() ) + aReturn = OControlModel::queryAggregation( _rType ); + + return aReturn; + } + + //------------------------------------------------------------------ + IMPLEMENT_FORWARD_XTYPEPROVIDER2( ORichTextModel, OControlModel, ORichTextModel_BASE ) + + //-------------------------------------------------------------------- + IMPLEMENT_SERVICE_REGISTRATION_8( ORichTextModel, OControlModel, + FRM_SUN_COMPONENT_RICHTEXTCONTROL, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.TextRange" ) ), + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.style.CharacterProperties" ) ), + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.style.ParagraphProperties" ) ), + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.style.CharacterPropertiesAsian" ) ), + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.style.CharacterPropertiesComplex" ) ), + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.style.ParagraphPropertiesAsian" ) ), + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.style.ParagraphPropertiesComplex" ) ) + ) + + //------------------------------------------------------------------------------ + IMPLEMENT_DEFAULT_CLONING( ORichTextModel ) + + //------------------------------------------------------------------------------ + void SAL_CALL ORichTextModel::disposing() + { + m_aModifyListeners.disposeAndClear( EventObject( *this ) ); + OControlModel::disposing(); + } + + //------------------------------------------------------------------------------ + namespace + { + void lcl_removeProperty( Sequence< Property >& _rSeq, const ::rtl::OUString& _rPropertyName ) + { + Property* pLoop = _rSeq.getArray(); + Property* pEnd = _rSeq.getArray() + _rSeq.getLength(); + while ( pLoop != pEnd ) + { + if ( pLoop->Name == _rPropertyName ) + { + ::std::copy( pLoop + 1, pEnd, pLoop ); + _rSeq.realloc( _rSeq.getLength() - 1 ); + break; + } + ++pLoop; + } + } + } + //------------------------------------------------------------------------------ + void ORichTextModel::describeFixedProperties( Sequence< Property >& _rProps ) const + { + BEGIN_DESCRIBE_PROPERTIES( 1, OControlModel ) + DECL_PROP2( TABINDEX, sal_Int16, BOUND, MAYBEDEFAULT ); + END_DESCRIBE_PROPERTIES(); + + // properties which the OPropertyContainerHelper is responsible for + Sequence< Property > aContainedProperties; + describeProperties( aContainedProperties ); + + // properties which the FontControlModel is responsible for + Sequence< Property > aFontProperties; + describeFontRelatedProperties( aFontProperties ); + + _rProps = concatSequences( aContainedProperties, aFontProperties, _rProps ); + } + + //------------------------------------------------------------------------------ + void ORichTextModel::describeAggregateProperties( Sequence< Property >& _rAggregateProps ) const + { + OControlModel::describeAggregateProperties( _rAggregateProps ); + + // our aggregate (the SvxUnoText) declares a FontDescriptor property, as does + // our FormControlFont base class. We remove it from the base class' sequence + // here, and later on care for both instances being in sync + lcl_removeProperty( _rAggregateProps, PROPERTY_FONT ); + + // similar, the WritingMode property is declared in our aggregate, too, but we override + // it, since the aggregate does no proper PropertyState handling. + lcl_removeProperty( _rAggregateProps, PROPERTY_WRITING_MODE ); + } + + //-------------------------------------------------------------------- + void SAL_CALL ORichTextModel::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const + { + if ( isRegisteredProperty( _nHandle ) ) + { + OPropertyContainerHelper::getFastPropertyValue( _rValue, _nHandle ); + } + else if ( isFontRelatedProperty( _nHandle ) ) + { + FontControlModel::getFastPropertyValue( _rValue, _nHandle ); + } + else + { + OControlModel::getFastPropertyValue( _rValue, _nHandle ); + } + } + + //-------------------------------------------------------------------- + sal_Bool SAL_CALL ORichTextModel::convertFastPropertyValue( Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue ) throw( IllegalArgumentException ) + { + sal_Bool bModified = sal_False; + + if ( isRegisteredProperty( _nHandle ) ) + { + bModified = OPropertyContainerHelper::convertFastPropertyValue( _rConvertedValue, _rOldValue, _nHandle, _rValue ); + } + else if ( isFontRelatedProperty( _nHandle ) ) + { + bModified = FontControlModel::convertFastPropertyValue( _rConvertedValue, _rOldValue, _nHandle, _rValue ); + } + else + { + bModified = OControlModel::convertFastPropertyValue( _rConvertedValue, _rOldValue, _nHandle, _rValue ); + } + + return bModified; + } + + //-------------------------------------------------------------------- + void SAL_CALL ORichTextModel::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const Any& _rValue ) throw ( Exception) + { + if ( isRegisteredProperty( _nHandle ) ) + { + OPropertyContainerHelper::setFastPropertyValue( _nHandle, _rValue ); + + switch ( _nHandle ) + { + case PROPERTY_ID_REFERENCE_DEVICE: + { + #if OSL_DEBUG_LEVEL > 0 + MapMode aOldMapMode = m_pEngine->GetRefDevice()->GetMapMode(); + #endif + + OutputDevice* pRefDevice = VCLUnoHelper::GetOutputDevice( m_xReferenceDevice ); + OSL_ENSURE( pRefDevice, "ORichTextModel::setFastPropertyValue_NoBroadcast: empty reference device?" ); + m_pEngine->SetRefDevice( pRefDevice ); + + #if OSL_DEBUG_LEVEL > 0 + MapMode aNewMapMode = m_pEngine->GetRefDevice()->GetMapMode(); + OSL_ENSURE( aNewMapMode.GetMapUnit() == aOldMapMode.GetMapUnit(), + "ORichTextModel::setFastPropertyValue_NoBroadcast: You should not tamper with the MapUnit of the ref device!" ); + // if this assertion here is triggered, then we would need to adjust all + // items in all text portions in all paragraphs in the attributes of the EditEngine, + // as long as they are MapUnit-dependent. This holds at least for the FontSize. + #endif + } + break; + + case PROPERTY_ID_TEXT: + { + MutexRelease aReleaseMutex( m_aMutex ); + impl_smlock_setEngineText( m_sLastKnownEngineText ); + } + break; + } // switch ( _nHandle ) + } + else if ( isFontRelatedProperty( _nHandle ) ) + { + FontDescriptor aOldFont( getFont() ); + + FontControlModel::setFastPropertyValue_NoBroadcast( _nHandle, _rValue ); + + if ( isFontAggregateProperty( _nHandle ) ) + firePropertyChange( PROPERTY_ID_FONT, makeAny( getFont() ), makeAny( aOldFont ) ); + } + else + { + switch ( _nHandle ) + { + case PROPERTY_ID_WRITING_MODE: + { + // forward to our aggregate, so the EditEngine knows about it + if ( m_xAggregateSet.is() ) + m_xAggregateSet->setPropertyValue( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "WritingMode" ) ), _rValue ); + } + break; + + default: + OControlModel::setFastPropertyValue_NoBroadcast( _nHandle, _rValue ); + break; + } + } + } + + //-------------------------------------------------------------------- + Any ORichTextModel::getPropertyDefaultByHandle( sal_Int32 _nHandle ) const + { + Any aDefault; + + switch ( _nHandle ) + { + case PROPERTY_ID_WRITING_MODE: + case PROPERTY_ID_CONTEXT_WRITING_MODE: + aDefault <<= WritingMode2::CONTEXT; + break; + + case PROPERTY_ID_LINEEND_FORMAT: + aDefault <<= (sal_Int16)LineEndFormat::LINE_FEED; + break; + + case PROPERTY_ID_ECHO_CHAR: + case PROPERTY_ID_ALIGN: + case PROPERTY_ID_MAXTEXTLEN: + aDefault <<= (sal_Int16)0; + break; + + case PROPERTY_ID_TABSTOP: + case PROPERTY_ID_BACKGROUNDCOLOR: + case PROPERTY_ID_BORDERCOLOR: + case PROPERTY_ID_VERTICAL_ALIGN: + /* void */ + break; + + case PROPERTY_ID_ENABLED: + case PROPERTY_ID_ENABLEVISIBLE: + case PROPERTY_ID_PRINTABLE: + case PROPERTY_ID_HIDEINACTIVESELECTION: + aDefault <<= (sal_Bool)sal_True; + break; + + case PROPERTY_ID_HARDLINEBREAKS: + case PROPERTY_ID_HSCROLL: + case PROPERTY_ID_VSCROLL: + case PROPERTY_ID_READONLY: + case PROPERTY_ID_MULTILINE: + case PROPERTY_ID_RICH_TEXT: + aDefault <<= (sal_Bool)sal_False; + break; + + case PROPERTY_ID_DEFAULTCONTROL: + aDefault <<= (::rtl::OUString)FRM_SUN_CONTROL_RICHTEXTCONTROL; + break; + + case PROPERTY_ID_HELPTEXT: + case PROPERTY_ID_HELPURL: + case PROPERTY_ID_TEXT: + aDefault <<= ::rtl::OUString(); + break; + + case PROPERTY_ID_BORDER: + aDefault <<= (sal_Int16)1; + break; + + default: + if ( isFontRelatedProperty( _nHandle ) ) + aDefault = FontControlModel::getPropertyDefaultByHandle( _nHandle ); + else + aDefault = OControlModel::getPropertyDefaultByHandle( _nHandle ); + } + + return aDefault; + } + + //-------------------------------------------------------------------- + void ORichTextModel::impl_smlock_setEngineText( const ::rtl::OUString& _rText ) + { + if ( m_pEngine.get() ) + { + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + m_bSettingEngineText = true; + m_pEngine->SetText( _rText ); + m_bSettingEngineText = false; + } + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL ORichTextModel::getServiceName() throw ( RuntimeException) + { + return FRM_SUN_COMPONENT_RICHTEXTCONTROL; + } + + //-------------------------------------------------------------------- + void SAL_CALL ORichTextModel::write(const Reference< XObjectOutputStream >& _rxOutStream) throw ( IOException, RuntimeException) + { + OControlModel::write( _rxOutStream ); + // TODO: place your code here + } + + //-------------------------------------------------------------------- + void SAL_CALL ORichTextModel::read(const Reference< XObjectInputStream >& _rxInStream) throw ( IOException, RuntimeException) + { + OControlModel::read( _rxInStream ); + // TODO: place your code here + } + + //-------------------------------------------------------------------- + RichTextEngine* ORichTextModel::getEditEngine( const Reference< XControlModel >& _rxModel ) + { + RichTextEngine* pEngine = NULL; + + Reference< XUnoTunnel > xTunnel( _rxModel, UNO_QUERY ); + OSL_ENSURE( xTunnel.is(), "ORichTextModel::getEditEngine: invalid model!" ); + if ( xTunnel.is() ) + { + try + { + pEngine = reinterpret_cast< RichTextEngine* >( xTunnel->getSomething( getEditEngineTunnelId() ) ); + } + catch( const Exception& ) + { + OSL_ENSURE( sal_False, "ORichTextModel::getEditEngine: caught an exception!" ); + } + } + return pEngine; + } + + //-------------------------------------------------------------------- + Sequence< sal_Int8 > ORichTextModel::getEditEngineTunnelId() + { + static ::cppu::OImplementationId * pId = 0; + if (! pId) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if (! pId) + { + static ::cppu::OImplementationId aId; + pId = &aId; + } + } + return pId->getImplementationId(); + } + + //-------------------------------------------------------------------- + IMPL_LINK( ORichTextModel, OnEngineContentModified, void*, /*_pNotInterestedIn*/ ) + { + if ( !m_bSettingEngineText ) + { + m_aModifyListeners.notifyEach( &XModifyListener::modified, EventObject( *this ) ); + + potentialTextChange(); + // is this a good idea? It may become expensive in case of larger texts, + // and this method here is called for every single changed character ... + // On the other hand, the API *requires* us to notify changes in the "Text" + // property immediately ... + } + + return 0L; + } + + //-------------------------------------------------------------------- + sal_Int64 SAL_CALL ORichTextModel::getSomething( const Sequence< sal_Int8 >& _rId ) throw (RuntimeException) + { + Sequence< sal_Int8 > aEditEngineAccessId( getEditEngineTunnelId() ); + if ( ( _rId.getLength() == aEditEngineAccessId.getLength() ) + && ( 0 == rtl_compareMemory( aEditEngineAccessId.getConstArray(), _rId.getConstArray(), _rId.getLength() ) ) + ) + return reinterpret_cast< sal_Int64 >( m_pEngine.get() ); + + Reference< XUnoTunnel > xAggTunnel; + if ( query_aggregation( m_xAggregate, xAggTunnel ) ) + return xAggTunnel->getSomething( _rId ); + + return 0; + } + + //-------------------------------------------------------------------- + void SAL_CALL ORichTextModel::addModifyListener( const Reference< XModifyListener >& _rxListener ) throw (RuntimeException) + { + m_aModifyListeners.addInterface( _rxListener ); + } + + //-------------------------------------------------------------------- + void SAL_CALL ORichTextModel::removeModifyListener( const Reference< XModifyListener >& _rxListener ) throw (RuntimeException) + { + m_aModifyListeners.removeInterface( _rxListener ); + } + + //-------------------------------------------------------------------- + void ORichTextModel::potentialTextChange( ) + { + ::rtl::OUString sCurrentEngineText; + if ( m_pEngine.get() ) + sCurrentEngineText = m_pEngine->GetText(); + + if ( sCurrentEngineText != m_sLastKnownEngineText ) + { + sal_Int32 nHandle = PROPERTY_ID_TEXT; + Any aOldValue; aOldValue <<= m_sLastKnownEngineText; + Any aNewValue; aNewValue <<= sCurrentEngineText; + fire( &nHandle, &aNewValue, &aOldValue, 1, sal_False ); + + m_sLastKnownEngineText = sCurrentEngineText; + } + } + +//........................................................................ +} // namespace frm +//........................................................................ diff --git a/forms/source/richtext/richtextmodel.hxx b/forms/source/richtext/richtextmodel.hxx new file mode 100644 index 000000000000..94e5523fb001 --- /dev/null +++ b/forms/source/richtext/richtextmodel.hxx @@ -0,0 +1,194 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef FORMS_SOURCE_RICHTEXT_RICHTEXTMODEL_HXX +#define FORMS_SOURCE_RICHTEXT_RICHTEXTMODEL_HXX + +#include "FormComponent.hxx" +#include "frm_module.hxx" +#include "formcontrolfont.hxx" +#include "richtextunowrapper.hxx" +#include <comphelper/propertycontainerhelper.hxx> +#include <comphelper/listenernotification.hxx> + +/** === begin UNO includes === **/ +#include <com/sun/star/awt/XDevice.hpp> +#include <com/sun/star/util/XModifyBroadcaster.hpp> +/** === end UNO includes === **/ +#include <cppuhelper/implbase3.hxx> +#include <tools/link.hxx> +#include <memory> + +class EditEngine; +//........................................................................ +namespace frm +{ +//........................................................................ + + class RichTextEngine; + //==================================================================== + //= ORichTextModel + //==================================================================== + typedef ::cppu::ImplHelper3 < ::com::sun::star::awt::XControlModel + , ::com::sun::star::lang::XUnoTunnel + , ::com::sun::star::util::XModifyBroadcaster + > ORichTextModel_BASE; + + class ORichTextModel + :public OControlModel + ,public FontControlModel + ,public IEngineTextChangeListener + ,public ::comphelper::OPropertyContainerHelper + ,public ORichTextModel_BASE + { + private: + // <properties> + ::com::sun::star::uno::Reference< ::com::sun::star::awt::XDevice > + m_xReferenceDevice; + ::com::sun::star::uno::Any m_aTabStop; + ::com::sun::star::uno::Any m_aBackgroundColor; + ::com::sun::star::uno::Any m_aBorderColor; + ::com::sun::star::uno::Any m_aVerticalAlignment; + ::rtl::OUString m_sDefaultControl; + ::rtl::OUString m_sHelpText; + ::rtl::OUString m_sHelpURL; + ::rtl::OUString m_sLastKnownEngineText; + sal_Int16 m_nLineEndFormat; + sal_Int16 m_nTextWritingMode; + sal_Int16 m_nContextWritingMode; + sal_Int16 m_nBorder; + sal_Bool m_bEnabled; + sal_Bool m_bEnableVisible; + sal_Bool m_bHardLineBreaks; + sal_Bool m_bHScroll; + sal_Bool m_bVScroll; + sal_Bool m_bReadonly; + sal_Bool m_bPrintable; + sal_Bool m_bReallyActAsRichText; // despite the class name, the RichTextControl later on + // will create "ordinary" text peers depending on this property + sal_Bool m_bHideInactiveSelection; + // </properties> + + // <properties_for_awt_edit_compatibility> + ::com::sun::star::uno::Any m_aAlign; + sal_Int16 m_nEchoChar; + sal_Int16 m_nMaxTextLength; + sal_Bool m_bMultiLine; + // </properties_for_awt_edit_compatibility> + + ::std::auto_ptr<RichTextEngine> + m_pEngine; + bool m_bSettingEngineText; + + ::cppu::OInterfaceContainerHelper + m_aModifyListeners; + + public: + static RichTextEngine* getEditEngine( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >& _rxModel ); + + protected: + DECLARE_DEFAULT_LEAF_XTOR( ORichTextModel ); + + // UNO + DECLARE_UNO3_AGG_DEFAULTS( ORichTextModel, OControlModel ); + virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException); + + // XServiceInfo + DECLARE_SERVICE_REGISTRATION( ORichTextModel ) + + // XPersistObject + DECLARE_XPERSISTOBJECT() + + // XTypeProvider + DECLARE_XTYPEPROVIDER() + + // XCloneable + DECLARE_XCLONEABLE(); + + // XUnoTunnel + virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw (::com::sun::star::uno::RuntimeException); + + // XModifyBroadcaster + virtual void SAL_CALL addModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) throw (::com::sun::star::uno::RuntimeException); + + // XPropertySet and friends + virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle ) const; + virtual sal_Bool SAL_CALL convertFastPropertyValue(::com::sun::star::uno::Any& rConvertedValue, ::com::sun::star::uno::Any& rOldValue, + sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue ) + throw(::com::sun::star::lang::IllegalArgumentException); + virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue) throw ( ::com::sun::star::uno::Exception); + virtual ::com::sun::star::uno::Any getPropertyDefaultByHandle( sal_Int32 nHandle ) const; + + // OControlModel's property handling + virtual void describeFixedProperties( + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps + ) const; + virtual void describeAggregateProperties( + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rAggregateProps + ) const; + + // prevent method hiding + using OControlModel::disposing; + using OControlModel::getFastPropertyValue; + + // OComponentHelper + virtual void SAL_CALL disposing(); + + // IEngineTextChangeListener + virtual void potentialTextChange( ); + + private: + void implInit(); + void implDoAggregation(); + void implRegisterProperties(); + + /** propagates a new text to the EditEngine + + This method needs to lock the global solar mutex, so our own mutex must not + be locked when calling. + + @precond + our mutex is not locked + */ + void impl_smlock_setEngineText( const ::rtl::OUString& _rText ); + + DECL_LINK( OnEngineContentModified, void* ); + + static ::com::sun::star::uno::Sequence< sal_Int8 > getEditEngineTunnelId(); + + private: + ORichTextModel(); // never implemented + ORichTextModel( const ORichTextModel& ); // never implemented + ORichTextModel& operator=( const ORichTextModel& ); // never implemented + }; + +//........................................................................ +} // namespace frm +//........................................................................ + +#endif // FORMS_SOURCE_RICHTEXT_RICHTEXTMODEL_HXX + diff --git a/forms/source/richtext/richtextunowrapper.cxx b/forms/source/richtext/richtextunowrapper.cxx new file mode 100644 index 000000000000..1d3f98467aa7 --- /dev/null +++ b/forms/source/richtext/richtextunowrapper.cxx @@ -0,0 +1,136 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_forms.hxx" +#include "richtextunowrapper.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/container/XNameContainer.hpp> +/** === end UNO includes === **/ +#include <editeng/unofored.hxx> +#include <editeng/editview.hxx> +#include <editeng/unoipset.hxx> +#include <svx/svdpool.hxx> +#include <svx/svdobj.hxx> +#include <editeng/unoprnms.hxx> + +//........................................................................ +namespace frm +{ +//........................................................................ + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::beans; + using namespace ::com::sun::star::container; + + //==================================================================== + namespace + { + const SvxItemPropertySet* getTextEnginePropertySet() + { + // Propertymap fuer einen Outliner Text + static const SfxItemPropertyMapEntry aTextEnginePropertyMap[] = + { + SVX_UNOEDIT_CHAR_PROPERTIES, + SVX_UNOEDIT_FONT_PROPERTIES, + SVX_UNOEDIT_PARA_PROPERTIES, + { MAP_CHAR_LEN("TextUserDefinedAttributes"), EE_CHAR_XMLATTRIBS, &::getCppuType( static_cast< const Reference< XNameContainer >* >( NULL ) ), 0, 0 }, + { MAP_CHAR_LEN("ParaUserDefinedAttributes"), EE_PARA_XMLATTRIBS, &::getCppuType( static_cast< const Reference< XNameContainer >* >( NULL ) ), 0, 0 }, + { NULL, 0, 0, NULL, 0, 0 } + }; + static SvxItemPropertySet aTextEnginePropertySet( aTextEnginePropertyMap, SdrObject::GetGlobalDrawObjectItemPool() ); + return &aTextEnginePropertySet; + } + } + + //==================================================================== + //= ORichTextUnoWrapper + //==================================================================== + //-------------------------------------------------------------------- + ORichTextUnoWrapper::ORichTextUnoWrapper( EditEngine& _rEngine, IEngineTextChangeListener* _pTextChangeListener ) + :SvxUnoText( getTextEnginePropertySet() ) + { + SetEditSource( new RichTextEditSource( _rEngine, _pTextChangeListener ) ); + } + + //-------------------------------------------------------------------- + ORichTextUnoWrapper::~ORichTextUnoWrapper() throw() + { + } + + //==================================================================== + //= RichTextEditSource + //==================================================================== + //-------------------------------------------------------------------- + RichTextEditSource::RichTextEditSource( EditEngine& _rEngine, IEngineTextChangeListener* _pTextChangeListener ) + :m_rEngine ( _rEngine ) + ,m_pTextForwarder ( new SvxEditEngineForwarder( _rEngine ) ) + ,m_pTextChangeListener ( _pTextChangeListener ) + { + } + + //-------------------------------------------------------------------- + RichTextEditSource::~RichTextEditSource() + { + delete m_pTextForwarder; + } + + //-------------------------------------------------------------------- + SvxEditSource* RichTextEditSource::Clone() const + { + return new RichTextEditSource( m_rEngine, m_pTextChangeListener ); + } + + //-------------------------------------------------------------------- + SvxTextForwarder* RichTextEditSource::GetTextForwarder() + { + return m_pTextForwarder; + } + + //-------------------------------------------------------------------- + void RichTextEditSource::UpdateData() + { + // this means that the content of the EditEngine changed via the UNO API + // to reflect this in the views, we need to update them + USHORT viewCount = m_rEngine.GetViewCount(); + for ( USHORT view = 0; view < viewCount; ++view ) + { + EditView* pView = m_rEngine.GetView( view ); + if ( pView ) + pView->ForceUpdate(); + } + + if ( m_pTextChangeListener ) + m_pTextChangeListener->potentialTextChange(); + } + +//........................................................................ +} // namespace frm +//........................................................................ + diff --git a/forms/source/richtext/richtextunowrapper.hxx b/forms/source/richtext/richtextunowrapper.hxx new file mode 100644 index 000000000000..a461eb4d507e --- /dev/null +++ b/forms/source/richtext/richtextunowrapper.hxx @@ -0,0 +1,98 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef FORMS_SOURCE_RICHTEXT_RICHTEXTUNOWRAPPER_HXX +#define FORMS_SOURCE_RICHTEXT_RICHTEXTUNOWRAPPER_HXX + +#include <editeng/unotext.hxx> +#include <editeng/unoedsrc.hxx> + +//........................................................................ +namespace frm +{ +//........................................................................ + + //==================================================================== + //= IEngineTextChangeListener + //==================================================================== + class IEngineTextChangeListener + { + public: + virtual void potentialTextChange( ) = 0; + }; + + //==================================================================== + //= ORichTextUnoWrapper + //==================================================================== + class ORichTextUnoWrapper : public SvxUnoText + { + public: + ORichTextUnoWrapper( EditEngine& _rEngine, IEngineTextChangeListener* _pTextChangeListener ); + + protected: + ~ORichTextUnoWrapper() throw(); + + + private: + ORichTextUnoWrapper(); // never implemented + ORichTextUnoWrapper( const ORichTextUnoWrapper& ); // never implemented + ORichTextUnoWrapper& operator=( const ORichTextUnoWrapper& ); // never implemented + }; + + //==================================================================== + //= RichTextEditSource + //==================================================================== + class RichTextEditSource : public SvxEditSource + { + private: + EditEngine& m_rEngine; + SvxTextForwarder* m_pTextForwarder; + IEngineTextChangeListener* m_pTextChangeListener; + + public: + RichTextEditSource( EditEngine& _rEngine, IEngineTextChangeListener* _pTextChangeListener ); + + // SvxEditSource + virtual SvxEditSource* Clone() const; + virtual SvxTextForwarder* GetTextForwarder(); + virtual void UpdateData(); + + protected: + ~RichTextEditSource(); + + private: + RichTextEditSource( ); // never implemented + RichTextEditSource( const RichTextEditSource& _rSource ); // never implemented + RichTextEditSource& operator=( const RichTextEditSource& ); // never implemented + }; + +//........................................................................ +} // namespace frm +//........................................................................ + +#endif // FORMS_SOURCE_RICHTEXT_RICHTEXTUNOWRAPPER_HXX + diff --git a/forms/source/richtext/richtextvclcontrol.cxx b/forms/source/richtext/richtextvclcontrol.cxx new file mode 100644 index 000000000000..48d458288d40 --- /dev/null +++ b/forms/source/richtext/richtextvclcontrol.cxx @@ -0,0 +1,392 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_forms.hxx" +#include "richtextvclcontrol.hxx" +#include "richtextimplcontrol.hxx" +#include <svl/itempool.hxx> +#include <svl/itemset.hxx> +#include <svl/languageoptions.hxx> +#if OSL_DEBUG_LEVEL > 0 + #ifndef _TOOLS_TEMPFILE_HXX + #include <tools/tempfile.hxx> + #endif + #ifndef _UNTOOLS_UCBSTREAMHELPER_HXX + #include <unotools/ucbstreamhelper.hxx> + #endif + #ifndef _SV_MSGBOX_HXX + #include <vcl/msgbox.hxx> + #endif + #ifndef _FILEDLGHELPER_HXX + #include <sfx2/filedlghelper.hxx> + #endif + #ifndef _URLOBJ_HXX + #include <tools/urlobj.hxx> + #endif + #include "com/sun/star/ui/dialogs/TemplateDescription.hpp" +#endif +#include <editeng/scripttypeitem.hxx> +#include <editeng/editeng.hxx> +#include <editeng/editview.hxx> +#include <editeng/eeitem.hxx> +#include <editeng/fontitem.hxx> +#include <editeng/fhgtitem.hxx> +#include <editeng/editids.hrc> +#include <svx/svxids.hrc> +#include <memory> + +//........................................................................ +namespace frm +{ +//........................................................................ + + using namespace ::com::sun::star::awt; + + //==================================================================== + //= RichTextControl + //==================================================================== + //-------------------------------------------------------------------- + RichTextControl::RichTextControl( RichTextEngine* _pEngine, Window* _pParent, WinBits _nStyle, + ITextAttributeListener* _pTextAttribListener, ITextSelectionListener* _pSelectionListener ) + :Control( _pParent, implInitStyle( _nStyle ) ) + ,m_pImpl( NULL ) + { + implInit( _pEngine, _pTextAttribListener, _pSelectionListener ); + } + + //-------------------------------------------------------------------- + void RichTextControl::implInit( RichTextEngine* _pEngine, ITextAttributeListener* _pTextAttribListener, ITextSelectionListener* _pSelectionListener ) + { + m_pImpl = new RichTextControlImpl( this, _pEngine, _pTextAttribListener, _pSelectionListener ); + SetCompoundControl( TRUE ); + } + + //-------------------------------------------------------------------- + RichTextControl::~RichTextControl( ) + { + delete m_pImpl; + } + + //-------------------------------------------------------------------- + AttributeState RichTextControl::getState( AttributeId _nAttributeId ) const + { + return m_pImpl->getAttributeState( _nAttributeId ); + } + + //-------------------------------------------------------------------- + void RichTextControl::executeAttribute( AttributeId _nAttributeId, const SfxPoolItem* _pArgument ) + { + SfxItemSet aToApplyAttributes( getView().GetEmptyItemSet() ); + if ( !m_pImpl->executeAttribute( getView().GetAttribs(), aToApplyAttributes, _nAttributeId, _pArgument, m_pImpl->getSelectedScriptType() ) ) + { + OSL_ENSURE( sal_False, "RichTextControl::executeAttribute: cannot handle the given attribute!" ); + return; + } + + applyAttributes( aToApplyAttributes ); + } + + //-------------------------------------------------------------------- + void RichTextControl::applyAttributes( const SfxItemSet& _rAttributesToApply ) + { + // apply + if ( HasChildPathFocus() ) + getView().HideCursor(); + + BOOL bOldUpdateMode = getEngine().GetUpdateMode(); // TODO: guard? + getEngine().SetUpdateMode( FALSE ); + + getView().SetAttribs( _rAttributesToApply ); + + getEngine().SetUpdateMode( bOldUpdateMode ); + getView().Invalidate(); + + if ( HasChildPathFocus() ) + getView().ShowCursor(); + + m_pImpl->updateAllAttributes(); + // TODO: maybe we should have a list of attributes which need to be updated + // (the handler for the just executed attribute should know) + } + + //-------------------------------------------------------------------- + void RichTextControl::enableAttributeNotification( AttributeId _nAttributeId, ITextAttributeListener* _pListener ) + { + m_pImpl->enableAttributeNotification( _nAttributeId, _pListener ); + } + + //-------------------------------------------------------------------- + void RichTextControl::disableAttributeNotification( AttributeId _nAttributeId ) + { + m_pImpl->disableAttributeNotification( _nAttributeId ); + } + + //-------------------------------------------------------------------- + bool RichTextControl::isMappableSlot( SfxSlotId _nSlotId ) + { + switch ( _nSlotId ) + { + case SID_ATTR_PARA_ADJUST_LEFT: + case SID_ATTR_PARA_ADJUST_CENTER: + case SID_ATTR_PARA_ADJUST_RIGHT: + case SID_ATTR_PARA_ADJUST_BLOCK: + case SID_SET_SUPER_SCRIPT: + case SID_SET_SUB_SCRIPT: + case SID_ATTR_PARA_LINESPACE_10: + case SID_ATTR_PARA_LINESPACE_15: + case SID_ATTR_PARA_LINESPACE_20: + case SID_ATTR_PARA_LEFT_TO_RIGHT: + case SID_ATTR_PARA_RIGHT_TO_LEFT: + case SID_TEXTDIRECTION_TOP_TO_BOTTOM: + case SID_TEXTDIRECTION_LEFT_TO_RIGHT: + case SID_ATTR_CHAR_LATIN_FONT: + case SID_ATTR_CHAR_LATIN_FONTHEIGHT: + case SID_ATTR_CHAR_LATIN_LANGUAGE: + case SID_ATTR_CHAR_LATIN_POSTURE: + case SID_ATTR_CHAR_LATIN_WEIGHT: + return true; + } + return false; + } + + //-------------------------------------------------------------------- + void RichTextControl::Resize() + { + m_pImpl->layoutWindow(); + Invalidate(); + } + + //-------------------------------------------------------------------- + void RichTextControl::GetFocus() + { + getViewport().GrabFocus(); + } + + //-------------------------------------------------------------------- + WinBits RichTextControl::implInitStyle( WinBits nStyle ) + { + if ( !( nStyle & WB_NOTABSTOP ) ) + nStyle |= WB_TABSTOP; + return nStyle; + } + + //-------------------------------------------------------------------- + void RichTextControl::StateChanged( StateChangedType _nStateChange ) + { + if ( _nStateChange == STATE_CHANGE_STYLE ) + { + SetStyle( implInitStyle( GetStyle() ) ); + m_pImpl->notifyStyleChanged(); + } + else if ( _nStateChange == STATE_CHANGE_ZOOM ) + { + m_pImpl->notifyZoomChanged(); + } + else if ( _nStateChange == STATE_CHANGE_INITSHOW ) + { + m_pImpl->notifyInitShow(); + } + Control::StateChanged( _nStateChange ); + } + + //-------------------------------------------------------------------- + long RichTextControl::PreNotify( NotifyEvent& _rNEvt ) + { + if ( IsWindowOrChild( _rNEvt.GetWindow() ) ) + { + if ( EVENT_KEYINPUT == _rNEvt.GetType() ) + { + const ::KeyEvent* pKeyEvent = _rNEvt.GetKeyEvent(); + + sal_uInt16 nCode = pKeyEvent->GetKeyCode().GetCode(); + sal_Bool bShift = pKeyEvent->GetKeyCode().IsShift(); + sal_Bool bCtrl = pKeyEvent->GetKeyCode().IsMod1(); + sal_Bool bAlt = pKeyEvent->GetKeyCode().IsMod2(); + if ( ( KEY_TAB == nCode ) && bCtrl && !bAlt ) + { + // Ctrl-Tab is used to step out of the control + // -> build a new key event without the Ctrl-key, and let the very base class handle it + KeyCode aNewCode( KEY_TAB, bShift, sal_False, sal_False, sal_False ); + ::KeyEvent aNewEvent( pKeyEvent->GetCharCode(), aNewCode ); + Control::KeyInput( aNewEvent ); + return 1; // handled + } + +#if OSL_DEBUG_LEVEL > 0 + if ( ( ( KEY_F12 == nCode ) + || ( KEY_F11 == nCode ) + ) + && bCtrl + && bAlt + ) + { + bool bLoad = KEY_F11 == nCode; + struct + { + const sal_Char* pDescription; + const sal_Char* pExtension; + EETextFormat eFormat; + } aExportFormats[] = + { + { "OASIS OpenDocument (*.xml)", "*.xml", EE_FORMAT_XML }, + { "HyperText Markup Language (*.html)", "*.html", EE_FORMAT_HTML }, + { "Rich Text format (*.rtf)", "*.rtf", EE_FORMAT_RTF }, + { "Text (*.txt)", "*.txt", EE_FORMAT_TEXT } + }; + + ::sfx2::FileDialogHelper aFP( bLoad ? com::sun::star::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE : com::sun::star::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION, 0, this ); + + for ( size_t i = 0; i < sizeof( aExportFormats ) / sizeof( aExportFormats[ 0 ] ); ++i ) + { + aFP.AddFilter( + String::CreateFromAscii( aExportFormats[i].pDescription ), + String::CreateFromAscii( aExportFormats[i].pExtension ) ); + } + ErrCode nResult = aFP.Execute(); + if ( nResult == 0 ) + { + String sFileName = aFP.GetPath(); + SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( + sFileName, ( bLoad ? STREAM_READ : STREAM_WRITE | STREAM_TRUNC ) | STREAM_SHARE_DENYALL + ); + if ( pStream ) + { + EETextFormat eFormat = EE_FORMAT_XML; + String sFilter = aFP.GetCurrentFilter(); + for ( size_t i = 0; i < sizeof( aExportFormats ) / sizeof( aExportFormats[ 0 ] ); ++i ) + { + if ( sFilter.EqualsAscii( aExportFormats[i].pDescription ) ) + { + eFormat = aExportFormats[i].eFormat; + break; + } + } + if ( bLoad ) + { + INetURLObject aURL( sFileName ); + aURL.removeSegment(); + getEngine().Read( *pStream, aURL.GetMainURL( INetURLObject::NO_DECODE ), eFormat ); + } + else + { + getEngine().Write( *pStream, eFormat ); + } + } + DELETEZ( pStream ); + } + return 1; // handled + } +#endif + } + } + return Control::PreNotify( _rNEvt ); + } + + //-------------------------------------------------------------------- + long RichTextControl::Notify( NotifyEvent& _rNEvt ) + { + long nDone = 0; + if ( _rNEvt.GetType() == EVENT_COMMAND ) + { + const CommandEvent& rEvent = *_rNEvt.GetCommandEvent(); + nDone = m_pImpl->HandleCommand( rEvent ); + } + return nDone ? nDone : Control::Notify( _rNEvt ); + } + + //-------------------------------------------------------------------- + void RichTextControl::Draw( OutputDevice* _pDev, const Point& _rPos, const Size& _rSize, ULONG _nFlags ) + { + m_pImpl->Draw( _pDev, _rPos, _rSize, _nFlags ); + } + + //-------------------------------------------------------------------- + EditView& RichTextControl::getView() + { + return *m_pImpl->getView( RichTextControlImpl::GrantAccess() ); + } + + //-------------------------------------------------------------------- + const EditView& RichTextControl::getView() const + { + return *m_pImpl->getView( RichTextControlImpl::GrantAccess() ); + } + + //-------------------------------------------------------------------- + EditEngine& RichTextControl::getEngine() const + { + return *m_pImpl->getEngine( RichTextControlImpl::GrantAccess() ); + } + + //-------------------------------------------------------------------- + Window& RichTextControl::getViewport() const + { + return *m_pImpl->getViewport( RichTextControlImpl::GrantAccess() ); + } + + //-------------------------------------------------------------------- + void RichTextControl::SetReadOnly( bool _bReadOnly ) + { + m_pImpl->SetReadOnly( _bReadOnly ); + } + + //-------------------------------------------------------------------- + bool RichTextControl::IsReadOnly() const + { + return m_pImpl->IsReadOnly(); + } + + //-------------------------------------------------------------------- + void RichTextControl::SetBackgroundColor( ) + { + m_pImpl->SetBackgroundColor( ); + } + + //-------------------------------------------------------------------- + void RichTextControl::SetBackgroundColor( const Color& _rColor ) + { + m_pImpl->SetBackgroundColor( _rColor ); + } + + //-------------------------------------------------------------------- + void RichTextControl::SetHideInactiveSelection( bool _bHide ) + { + m_pImpl->SetHideInactiveSelection( _bHide ); + } + + //-------------------------------------------------------------------- + bool RichTextControl::GetHideInactiveSelection() const + { + return m_pImpl->GetHideInactiveSelection( ); + } + +//........................................................................ +} // namespace frm +//........................................................................ + + diff --git a/forms/source/richtext/richtextvclcontrol.hxx b/forms/source/richtext/richtextvclcontrol.hxx new file mode 100644 index 000000000000..54f59569984f --- /dev/null +++ b/forms/source/richtext/richtextvclcontrol.hxx @@ -0,0 +1,143 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef FORMS_SOURCE_RICHTEXT_RICHTEXTVCLCONTROL_HXX +#define FORMS_SOURCE_RICHTEXT_RICHTEXTVCLCONTROL_HXX + +#include <vcl/dialog.hxx> +#include <vcl/fixed.hxx> +#ifndef _SV_BUTTON_HXX +#include <vcl/button.hxx> +#endif +#include <vcl/toolbox.hxx> +#include <com/sun/star/awt/FontDescriptor.hpp> +#include "rtattributes.hxx" +#include "textattributelistener.hxx" + +/** === begin UNO includes === **/ +/** === end UNO includes === **/ + +class EditView; +class EditEngine; +class SfxItemSet; +//........................................................................ +namespace frm +{ +//........................................................................ + + class RichTextControlImpl; + class RichTextEngine; + //==================================================================== + //= RichTextControl + //==================================================================== + class RichTextControl : public Control, public IMultiAttributeDispatcher + { + private: + RichTextControlImpl* m_pImpl; + + public: + RichTextControl( + RichTextEngine* _pEngine, + Window* _pParent, + WinBits _nStyle, + ITextAttributeListener* _pTextAttribListener, + ITextSelectionListener* _pSelectionListener + ); + + ~RichTextControl( ); + + /* enables the change notifications for a particular attribute + + If you want to be notified of any changes in the state of an attribute, you need to call enableAttributeNotification. + + If you provide a dedicated listener for this attribute, this listener is called for every change in the state of + the attribute. + + No matter whether you provide such a dedicated listener, the "global" listener which you specified + in the constructor of the control is also called for all changes in the attribute state. + + If you previously already enabled the notification for this attribute, and specified a different listener, + then the previous listener will be replaced with the new listener, provided the latter is not <NULL/>. + */ + void enableAttributeNotification( AttributeId _nAttributeId, ITextAttributeListener* _pListener = NULL ); + + /** disables the change notifications for a particular attribute + + If there was a listener dedicated to this attribute, it will not be referenced and used anymore + after this method had been called + */ + void disableAttributeNotification( AttributeId _nAttributeId ); + + /** determines whether a given slot can be mapped to an aspect of an attribute of the EditEngine + + E.g. SID_ATTR_PARA_ADJUST_LEFT can, though it's not part of the EditEngine pool, be mapped + to the SID_ATTR_PARA_ADJUST slot, which in fact *is* usable with the EditEngine. + */ + static bool isMappableSlot( SfxSlotId _nSlotId ); + + // IMultiAttributeDispatcher + virtual AttributeState getState( AttributeId _nAttributeId ) const; + virtual void executeAttribute( AttributeId _nAttributeId, const SfxPoolItem* _pArgument ); + + void SetBackgroundColor( ); + void SetBackgroundColor( const Color& _rColor ); + + void SetReadOnly( bool _bReadOnly ); + bool IsReadOnly() const; + + void SetHideInactiveSelection( bool _bHide ); + bool GetHideInactiveSelection() const; + + const EditView& getView() const; + EditView& getView(); + + // Window overridables + virtual void Draw( OutputDevice* _pDev, const Point& _rPos, const Size& _rSize, ULONG _nFlags ); + + protected: + // Window overridables + virtual void Resize(); + virtual void GetFocus(); + virtual void StateChanged( StateChangedType nStateChange ); + virtual long PreNotify( NotifyEvent& _rNEvt ); + virtual long Notify( NotifyEvent& _rNEvt ); + + private: + void applyAttributes( const SfxItemSet& _rAttributesToApply ); + void implInit( RichTextEngine* _pEngine, ITextAttributeListener* _pTextAttribListener, ITextSelectionListener* _pSelectionListener ); + static WinBits implInitStyle( WinBits nStyle ); + + private: + EditEngine& getEngine() const; + Window& getViewport() const; + }; + +//........................................................................ +} // namespace frm +//........................................................................ + +#endif // FORMS_SOURCE_RICHTEXT_RICHTEXTVCLCONTROL_HXX + diff --git a/forms/source/richtext/richtextviewport.cxx b/forms/source/richtext/richtextviewport.cxx new file mode 100644 index 000000000000..ffeda61e6b0c --- /dev/null +++ b/forms/source/richtext/richtextviewport.cxx @@ -0,0 +1,127 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_forms.hxx" +#include "richtextviewport.hxx" +#include <editeng/editview.hxx> + +//........................................................................ +namespace frm +{ +//........................................................................ + + //==================================================================== + //= RichTextViewPort + //==================================================================== + //-------------------------------------------------------------------- + RichTextViewPort::RichTextViewPort( Window* _pParent ) + :Control ( _pParent ) + ,m_bHideInactiveSelection( true ) + { + } + + //-------------------------------------------------------------------- + void RichTextViewPort::setView( EditView& _rView ) + { + m_pView = &_rView; + SetPointer( _rView.GetPointer() ); + } + + //-------------------------------------------------------------------- + void RichTextViewPort::Paint( const Rectangle& _rRect ) + { + m_pView->Paint( _rRect ); + } + + //-------------------------------------------------------------------- + void RichTextViewPort::GetFocus() + { + Control::GetFocus(); + m_pView->SetSelectionMode( EE_SELMODE_STD ); + m_pView->ShowCursor( TRUE ); + } + + //-------------------------------------------------------------------- + void RichTextViewPort::LoseFocus() + { + m_pView->HideCursor(); + m_pView->SetSelectionMode( m_bHideInactiveSelection ? EE_SELMODE_HIDDEN : EE_SELMODE_STD ); + Control::LoseFocus(); + } + + //-------------------------------------------------------------------- + void RichTextViewPort::KeyInput( const KeyEvent& _rKEvt ) + { + if ( !m_pView->PostKeyEvent( _rKEvt ) ) + Control::KeyInput( _rKEvt ); + else + implInvalidateAttributes(); + } + + //-------------------------------------------------------------------- + void RichTextViewPort::MouseMove( const MouseEvent& _rMEvt ) + { + Control::MouseMove( _rMEvt ); + m_pView->MouseMove( _rMEvt ); + } + + //-------------------------------------------------------------------- + void RichTextViewPort::MouseButtonDown( const MouseEvent& _rMEvt ) + { + Control::MouseButtonDown( _rMEvt ); + m_pView->MouseButtonDown( _rMEvt ); + GrabFocus(); + } + + //-------------------------------------------------------------------- + void RichTextViewPort::MouseButtonUp( const MouseEvent& _rMEvt ) + { + Control::MouseButtonUp( _rMEvt ); + m_pView->MouseButtonUp( _rMEvt ); + implInvalidateAttributes(); + } + + //-------------------------------------------------------------------- + void RichTextViewPort::SetHideInactiveSelection( bool _bHide ) + { + if ( m_bHideInactiveSelection == _bHide ) + return; + m_bHideInactiveSelection = _bHide; + if ( !HasFocus() ) + m_pView->SetSelectionMode( m_bHideInactiveSelection ? EE_SELMODE_HIDDEN : EE_SELMODE_STD ); + } + + //-------------------------------------------------------------------- + bool RichTextViewPort::GetHideInactiveSelection() const + { + return m_bHideInactiveSelection; + } + +//........................................................................ +} // namespace frm +//........................................................................ diff --git a/forms/source/richtext/richtextviewport.hxx b/forms/source/richtext/richtextviewport.hxx new file mode 100644 index 000000000000..70ae75a346f6 --- /dev/null +++ b/forms/source/richtext/richtextviewport.hxx @@ -0,0 +1,80 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef FORMS_SOURCE_RICHTEXT_RICHTEXTVIEWPORT_HXX +#define FORMS_SOURCE_RICHTEXT_RICHTEXTVIEWPORT_HXX + +#include <vcl/ctrl.hxx> + +class EditView; +//........................................................................ +namespace frm +{ +//........................................................................ + + //==================================================================== + //= RichTextViewPort + //==================================================================== + class RichTextViewPort : public Control + { + private: + EditView* m_pView; + Link m_aInvalidationHandler; + bool m_bHideInactiveSelection; + + public: + RichTextViewPort( Window* _pParent ); + + void setView( EditView& _rView ); + + inline void setAttributeInvalidationHandler( const Link& _rHandler ) { m_aInvalidationHandler = _rHandler; } + + void SetHideInactiveSelection( bool _bHide ); + bool GetHideInactiveSelection() const; + + protected: + virtual void Paint( const Rectangle& rRect ); + virtual void GetFocus(); + virtual void LoseFocus(); + virtual void KeyInput( const KeyEvent& _rKEvt ); + virtual void MouseMove( const MouseEvent& _rMEvt ); + virtual void MouseButtonDown( const MouseEvent& _rMEvt ); + virtual void MouseButtonUp( const MouseEvent& _rMEvt ); + + private: + inline void implInvalidateAttributes() const + { + if ( m_aInvalidationHandler.IsSet() ) + m_aInvalidationHandler.Call( NULL ); + } + }; + +//........................................................................ +} // namespace frm +//........................................................................ + +#endif // FORMS_SOURCE_RICHTEXT_RICHTEXTVIEWPORT_HXX + diff --git a/forms/source/richtext/rtattributehandler.cxx b/forms/source/richtext/rtattributehandler.cxx new file mode 100644 index 000000000000..b56319f33dee --- /dev/null +++ b/forms/source/richtext/rtattributehandler.cxx @@ -0,0 +1,532 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_forms.hxx" +#include "rtattributehandler.hxx" + +#ifndef _SVX_SVXIDS_HRC +#include <svx/svxids.hrc> +#endif +#include <editeng/eeitem.hxx> +#include <svl/itemset.hxx> +#include <svl/itempool.hxx> +#include <tools/mapunit.hxx> +#include <vcl/mapmod.hxx> +#include <vcl/outdev.hxx> + +#define ITEMID_ADJUST EE_PARA_JUST +#include <editeng/adjitem.hxx> +#define ITEMID_WEIGHT EE_CHAR_WEIGHT +#include <editeng/wghtitem.hxx> +#define ITEMID_ESCAPEMENT EE_CHAR_ESCAPEMENT +#include <editeng/escpitem.hxx> +#define ITEMID_LINESPACING EE_PARA_SBL +#include <editeng/lspcitem.hxx> +#define ITEMID_FONTHEIGHT EE_CHAR_FONTHEIGHT +#include <editeng/fhgtitem.hxx> +#define ITEMID_FRAMEDIR EE_PARA_WRITINGDIR +#include <editeng/frmdiritem.hxx> +#include <editeng/scripttypeitem.hxx> + +//........................................................................ +namespace frm +{ +//........................................................................ + //==================================================================== + //= ReferenceBase + //==================================================================== + //-------------------------------------------------------------------- + oslInterlockedCount SAL_CALL ReferenceBase::acquire() + { + return osl_incrementInterlockedCount( &m_refCount ); + } + + //-------------------------------------------------------------------- + oslInterlockedCount SAL_CALL ReferenceBase::release() + { + return osl_decrementInterlockedCount( &m_refCount ); + } + + //-------------------------------------------------------------------- + ReferenceBase::~ReferenceBase() + { + } + + //==================================================================== + //= AttributeHandler + //==================================================================== + //-------------------------------------------------------------------- + AttributeHandler::AttributeHandler( AttributeId _nAttributeId, WhichId _nWhichId ) + :m_nAttribute( _nAttributeId ) + ,m_nWhich ( _nWhichId ) + { + } + + //-------------------------------------------------------------------- + AttributeHandler::~AttributeHandler() + { + } + + //-------------------------------------------------------------------- + oslInterlockedCount SAL_CALL AttributeHandler::acquire() + { + return ReferenceBase::acquire(); + } + + //-------------------------------------------------------------------- + oslInterlockedCount SAL_CALL AttributeHandler::release() + { + return ReferenceBase::release(); + } + + //-------------------------------------------------------------------- + AttributeId AttributeHandler::getAttributeId( ) const + { + return getAttribute(); + } + + //-------------------------------------------------------------------- + AttributeCheckState AttributeHandler::implGetCheckState( const SfxPoolItem& /*_rItem*/ ) const + { + OSL_ENSURE( sal_False, "AttributeHandler::implGetCheckState: not to be called!" ); + return eIndetermined; + } + + //-------------------------------------------------------------------- + void AttributeHandler::putItemForScript( SfxItemSet& _rAttribs, const SfxPoolItem& _rItem, ScriptType _nForScriptType ) const + { + SvxScriptSetItem aSetItem( (WhichId)getAttributeId(), *_rAttribs.GetPool() ); + aSetItem.PutItemForScriptType( _nForScriptType, _rItem ); + _rAttribs.Put( aSetItem.GetItemSet(), FALSE ); + } + + //-------------------------------------------------------------------- + AttributeCheckState AttributeHandler::getCheckState( const SfxItemSet& _rAttribs ) const + { + AttributeCheckState eSimpleState( eIndetermined ); + const SfxPoolItem* pItem = _rAttribs.GetItem( getWhich() ); + if ( pItem ) + eSimpleState = implGetCheckState( *pItem ); + return eSimpleState; + } + + //-------------------------------------------------------------------- + AttributeState AttributeHandler::getState( const SfxItemSet& _rAttribs ) const + { + AttributeState aState( eIndetermined ); + aState.eSimpleState = getCheckState( _rAttribs ); + return aState; + } + + //==================================================================== + //= AttributeHandlerFactory + //==================================================================== + //-------------------------------------------------------------------- + namespace + { + static WhichId lcl_implGetWhich( const SfxItemPool& _rPool, AttributeId _nAttributeId ) + { + WhichId nWhich = 0; + switch ( _nAttributeId ) + { + case SID_ATTR_CHAR_LATIN_FONTHEIGHT:nWhich = EE_CHAR_FONTHEIGHT;break; + case SID_ATTR_CHAR_LATIN_FONT: nWhich = EE_CHAR_FONTINFO; break; + case SID_ATTR_CHAR_LATIN_LANGUAGE: nWhich = EE_CHAR_LANGUAGE; break; + case SID_ATTR_CHAR_LATIN_POSTURE: nWhich = EE_CHAR_ITALIC; break; + case SID_ATTR_CHAR_LATIN_WEIGHT: nWhich = EE_CHAR_WEIGHT; break; + + default: + nWhich = _rPool.GetWhich( (SfxSlotId)_nAttributeId ); + } + return nWhich; + } + } + //-------------------------------------------------------------------- + ::rtl::Reference< IAttributeHandler > AttributeHandlerFactory::getHandlerFor( AttributeId _nAttributeId, const SfxItemPool& _rEditEnginePool ) + { + ::rtl::Reference< IAttributeHandler > pReturn; + switch ( _nAttributeId ) + { + case SID_ATTR_PARA_ADJUST_LEFT : + case SID_ATTR_PARA_ADJUST_CENTER: + case SID_ATTR_PARA_ADJUST_RIGHT : + case SID_ATTR_PARA_ADJUST_BLOCK : + pReturn = new ParaAlignmentHandler( _nAttributeId ); + break; + + case SID_ATTR_PARA_LINESPACE_10: + case SID_ATTR_PARA_LINESPACE_15: + case SID_ATTR_PARA_LINESPACE_20: + pReturn = new LineSpacingHandler( _nAttributeId ); + break; + + case SID_SET_SUPER_SCRIPT: + case SID_SET_SUB_SCRIPT: + pReturn = new EscapementHandler( _nAttributeId ); + break; + + case SID_ATTR_CHAR_FONTHEIGHT: + case SID_ATTR_CHAR_CTL_FONTHEIGHT: + case SID_ATTR_CHAR_CJK_FONTHEIGHT: + case SID_ATTR_CHAR_LATIN_FONTHEIGHT: + pReturn = new FontSizeHandler( _nAttributeId, lcl_implGetWhich( _rEditEnginePool, _nAttributeId ) ); + break; + + case SID_ATTR_PARA_LEFT_TO_RIGHT: + case SID_ATTR_PARA_RIGHT_TO_LEFT: + pReturn = new ParagraphDirectionHandler( _nAttributeId ); + break; + + case SID_ATTR_PARA_HANGPUNCTUATION: + case SID_ATTR_PARA_FORBIDDEN_RULES: + case SID_ATTR_PARA_SCRIPTSPACE: + pReturn = new BooleanHandler( _nAttributeId, lcl_implGetWhich( _rEditEnginePool, _nAttributeId ) ); + break; + + default: + pReturn = new SlotHandler( (SfxSlotId)_nAttributeId, lcl_implGetWhich( _rEditEnginePool, _nAttributeId ) ); + break; + + } + + return pReturn; + } + + //==================================================================== + //= ParaAlignmentHandler + //==================================================================== + //-------------------------------------------------------------------- + ParaAlignmentHandler::ParaAlignmentHandler( AttributeId _nAttributeId ) + :AttributeHandler( _nAttributeId, EE_PARA_JUST ) + ,m_eAdjust( SVX_ADJUST_CENTER ) + { + switch ( getAttribute() ) + { + case SID_ATTR_PARA_ADJUST_LEFT : m_eAdjust = SVX_ADJUST_LEFT; break; + case SID_ATTR_PARA_ADJUST_CENTER: m_eAdjust = SVX_ADJUST_CENTER; break; + case SID_ATTR_PARA_ADJUST_RIGHT : m_eAdjust = SVX_ADJUST_RIGHT; break; + case SID_ATTR_PARA_ADJUST_BLOCK : m_eAdjust = SVX_ADJUST_BLOCK; break; + default: + OSL_ENSURE( sal_False, "ParaAlignmentHandler::ParaAlignmentHandler: invalid slot!" ); + break; + } + } + + //-------------------------------------------------------------------- + AttributeCheckState ParaAlignmentHandler::implGetCheckState( const SfxPoolItem& _rItem ) const + { + OSL_ENSURE( _rItem.ISA( SvxAdjustItem ), "ParaAlignmentHandler::implGetCheckState: invalid pool item!" ); + SvxAdjust eAdjust = static_cast< const SvxAdjustItem& >( _rItem ).GetAdjust(); + return ( eAdjust == m_eAdjust ) ? eChecked : eUnchecked; + } + + //-------------------------------------------------------------------- + void ParaAlignmentHandler::executeAttribute( const SfxItemSet& /*_rCurrentAttribs*/, SfxItemSet& _rNewAttribs, const SfxPoolItem* _pAdditionalArg, ScriptType /*_nForScriptType*/ ) const + { + OSL_ENSURE( !_pAdditionalArg, "ParaAlignmentHandler::executeAttribute: this is a simple toggle attribute - no args possible!" ); + (void)_pAdditionalArg; + _rNewAttribs.Put( SvxAdjustItem( m_eAdjust, getWhich() ) ); + } + + //==================================================================== + //= LineSpacingHandler + //==================================================================== + //-------------------------------------------------------------------- + LineSpacingHandler::LineSpacingHandler( AttributeId _nAttributeId ) + :AttributeHandler( _nAttributeId, EE_PARA_SBL ) + ,m_nLineSpace( 100 ) + { + switch ( getAttribute() ) + { + case SID_ATTR_PARA_LINESPACE_10: m_nLineSpace = 100; break; + case SID_ATTR_PARA_LINESPACE_15: m_nLineSpace = 150; break; + case SID_ATTR_PARA_LINESPACE_20: m_nLineSpace = 200; break; + default: + OSL_ENSURE( sal_False, "LineSpacingHandler::LineSpacingHandler: invalid slot!" ); + break; + } + } + + //-------------------------------------------------------------------- + AttributeCheckState LineSpacingHandler::implGetCheckState( const SfxPoolItem& _rItem ) const + { + OSL_ENSURE( _rItem.ISA( SvxLineSpacingItem ), "LineSpacingHandler::implGetCheckState: invalid pool item!" ); + USHORT nLineSpace = static_cast< const SvxLineSpacingItem& >( _rItem ).GetPropLineSpace(); + return ( nLineSpace == m_nLineSpace ) ? eChecked : eUnchecked; + } + + //-------------------------------------------------------------------- + void LineSpacingHandler::executeAttribute( const SfxItemSet& /*_rCurrentAttribs*/, SfxItemSet& _rNewAttribs, const SfxPoolItem* _pAdditionalArg, ScriptType /*_nForScriptType*/ ) const + { + OSL_ENSURE( !_pAdditionalArg, "LineSpacingHandler::executeAttribute: this is a simple toggle attribute - no args possible!" ); + (void)_pAdditionalArg; + + SvxLineSpacingItem aLineSpacing( m_nLineSpace, getWhich() ); + aLineSpacing.GetLineSpaceRule() = SVX_LINE_SPACE_AUTO; + if ( 100 == m_nLineSpace ) + aLineSpacing.GetInterLineSpaceRule() = SVX_INTER_LINE_SPACE_OFF; + else + aLineSpacing.SetPropLineSpace( (BYTE)m_nLineSpace ); + + _rNewAttribs.Put( aLineSpacing ); + } + + //==================================================================== + //= EscapementHandler + //==================================================================== + //-------------------------------------------------------------------- + EscapementHandler::EscapementHandler( AttributeId _nAttributeId ) + :AttributeHandler( _nAttributeId, EE_CHAR_ESCAPEMENT ) + ,m_eEscapement( SVX_ESCAPEMENT_OFF ) + { + switch ( getAttribute() ) + { + case SID_SET_SUPER_SCRIPT : m_eEscapement = SVX_ESCAPEMENT_SUPERSCRIPT; break; + case SID_SET_SUB_SCRIPT : m_eEscapement = SVX_ESCAPEMENT_SUBSCRIPT; break; + default: + OSL_ENSURE( sal_False, "EscapementHandler::EscapementHandler: invalid slot!" ); + break; + } + } + + //-------------------------------------------------------------------- + AttributeCheckState EscapementHandler::implGetCheckState( const SfxPoolItem& _rItem ) const + { + OSL_ENSURE( _rItem.ISA( SvxEscapementItem ), "EscapementHandler::getState: invalid pool item!" ); + SvxEscapement eEscapement = static_cast< const SvxEscapementItem& >( _rItem ).GetEscapement(); + return ( eEscapement == m_eEscapement ) ? eChecked : eUnchecked; + } + + //-------------------------------------------------------------------- + void EscapementHandler::executeAttribute( const SfxItemSet& _rCurrentAttribs, SfxItemSet& _rNewAttribs, const SfxPoolItem* _pAdditionalArg, ScriptType /*_nForScriptType*/ ) const + { + OSL_ENSURE( !_pAdditionalArg, "EscapementHandler::executeAttribute: this is a simple toggle attribute - no args possible!" ); + // well, in theory we could allow an SvxEscapementItem here, but this is not needed + (void)_pAdditionalArg; + + bool bIsChecked = getCheckState( _rCurrentAttribs ) == eChecked; + _rNewAttribs.Put( SvxEscapementItem( bIsChecked ? SVX_ESCAPEMENT_OFF : m_eEscapement, getWhich() ) ); + } + + //==================================================================== + //= SlotHandler + //==================================================================== + //-------------------------------------------------------------------- + SlotHandler::SlotHandler( AttributeId _nAttributeId, WhichId _nWhichId ) + :AttributeHandler( _nAttributeId, _nWhichId ) + ,m_bScriptDependent( false ) + { + m_bScriptDependent = ( SID_ATTR_CHAR_WEIGHT == _nAttributeId ) + || ( SID_ATTR_CHAR_POSTURE == _nAttributeId ) + || ( SID_ATTR_CHAR_FONT == _nAttributeId ); + } + + //-------------------------------------------------------------------- + AttributeState SlotHandler::getState( const SfxItemSet& _rAttribs ) const + { + AttributeState aState( eIndetermined ); + + const SfxPoolItem* pItem = _rAttribs.GetItem( getWhich() ); + if ( pItem ) + aState.setItem( pItem->Clone() ); + + return aState; + } + + //-------------------------------------------------------------------- + void SlotHandler::executeAttribute( const SfxItemSet& /*_rCurrentAttribs*/, SfxItemSet& _rNewAttribs, const SfxPoolItem* _pAdditionalArg, ScriptType _nForScriptType ) const + { + if ( _pAdditionalArg ) + { + SfxPoolItem* pCorrectWich = _pAdditionalArg->Clone(); + pCorrectWich->SetWhich( getWhich() ); + + if ( m_bScriptDependent ) + putItemForScript( _rNewAttribs, *pCorrectWich, _nForScriptType ); + else + _rNewAttribs.Put( *pCorrectWich ); + DELETEZ( pCorrectWich ); + } + else + OSL_ENSURE( sal_False, "SlotHandler::executeAttribute: need attributes to do something!" ); + } + + //==================================================================== + //= FontSizeHandler + //==================================================================== + //-------------------------------------------------------------------- + FontSizeHandler::FontSizeHandler( AttributeId _nAttributeId, WhichId _nWhichId ) + :AttributeHandler( _nAttributeId, _nWhichId ) + { + OSL_ENSURE( ( _nAttributeId == SID_ATTR_CHAR_FONTHEIGHT ) || ( _nAttributeId == SID_ATTR_CHAR_CTL_FONTHEIGHT ) + || ( _nAttributeId == SID_ATTR_CHAR_CJK_FONTHEIGHT ) || ( _nAttributeId == SID_ATTR_CHAR_LATIN_FONTHEIGHT ), + "FontSizeHandler::FontSizeHandler: invalid attribute id!" ); + } + + //-------------------------------------------------------------------- + AttributeState FontSizeHandler::getState( const SfxItemSet& _rAttribs ) const + { + AttributeState aState( eIndetermined ); + + const SfxPoolItem* pItem = _rAttribs.GetItem( getWhich() ); + const SvxFontHeightItem* pFontHeightItem = PTR_CAST( SvxFontHeightItem, pItem ); + OSL_ENSURE( pFontHeightItem || !pItem, "FontSizeHandler::getState: invalid item!" ); + if ( pFontHeightItem ) + { + // by definition, the item should have the unit twip + ULONG nHeight = pFontHeightItem->GetHeight(); + if ( _rAttribs.GetPool()->GetMetric( getWhich() ) != SFX_MAPUNIT_TWIP ) + { + nHeight = OutputDevice::LogicToLogic( + Size( 0, nHeight ), + MapMode( (MapUnit)( _rAttribs.GetPool()->GetMetric( getWhich() ) ) ), + MapMode( MAP_TWIP ) + ).Height(); + } + + SvxFontHeightItem* pNewItem = new SvxFontHeightItem( nHeight, 100, getWhich() ); + pNewItem->SetProp( pFontHeightItem->GetProp(), pFontHeightItem->GetPropUnit() ); + aState.setItem( pNewItem ); + } + + return aState; + } + + //-------------------------------------------------------------------- + void FontSizeHandler::executeAttribute( const SfxItemSet& /*_rCurrentAttribs*/, SfxItemSet& _rNewAttribs, const SfxPoolItem* _pAdditionalArg, ScriptType _nForScriptType ) const + { + const SvxFontHeightItem* pFontHeightItem = PTR_CAST( SvxFontHeightItem, _pAdditionalArg ); + OSL_ENSURE( pFontHeightItem, "FontSizeHandler::executeAttribute: need a FontHeightItem!" ); + + if ( pFontHeightItem ) + { + // corect measurement units + SfxMapUnit eItemMapUnit = pFontHeightItem->GetPropUnit(); (void)eItemMapUnit; + ULONG nHeight = pFontHeightItem->GetHeight(); + if ( _rNewAttribs.GetPool()->GetMetric( getWhich() ) != SFX_MAPUNIT_TWIP ) + { + nHeight = OutputDevice::LogicToLogic( + Size( 0, nHeight ), + MapMode( (MapUnit)( SFX_MAPUNIT_TWIP ) ), + MapMode( (MapUnit)( _rNewAttribs.GetPool()->GetMetric( getWhich() ) ) ) + ).Height(); + } + + SvxFontHeightItem aNewItem( nHeight, 100, getWhich() ); + aNewItem.SetProp( pFontHeightItem->GetProp(), pFontHeightItem->GetPropUnit() ); + + if ( ( getAttributeId() == SID_ATTR_CHAR_FONTHEIGHT ) && _nForScriptType ) + putItemForScript( _rNewAttribs, aNewItem, _nForScriptType ); + else + _rNewAttribs.Put( aNewItem ); + } + } + + //==================================================================== + //= ParagraphDirectionHandler + //==================================================================== + //-------------------------------------------------------------------- + ParagraphDirectionHandler::ParagraphDirectionHandler( AttributeId _nAttributeId ) + :AttributeHandler( _nAttributeId, EE_PARA_WRITINGDIR ) + ,m_eParagraphDirection( FRMDIR_HORI_LEFT_TOP ) + ,m_eDefaultAdjustment( SVX_ADJUST_RIGHT ) + ,m_eOppositeDefaultAdjustment( SVX_ADJUST_LEFT ) + { + switch ( getAttributeId() ) + { + case SID_ATTR_PARA_LEFT_TO_RIGHT: m_eParagraphDirection = FRMDIR_HORI_LEFT_TOP; m_eDefaultAdjustment = SVX_ADJUST_LEFT; break; + case SID_ATTR_PARA_RIGHT_TO_LEFT: m_eParagraphDirection = FRMDIR_HORI_RIGHT_TOP; m_eDefaultAdjustment = SVX_ADJUST_RIGHT; break; + default: + OSL_ENSURE( sal_False, "ParagraphDirectionHandler::ParagraphDirectionHandler: invalid attribute id!" ); + } + + if ( SVX_ADJUST_RIGHT == m_eDefaultAdjustment ) + m_eOppositeDefaultAdjustment = SVX_ADJUST_LEFT; + else + m_eOppositeDefaultAdjustment = SVX_ADJUST_RIGHT; + } + + //-------------------------------------------------------------------- + AttributeCheckState ParagraphDirectionHandler::implGetCheckState( const SfxPoolItem& _rItem ) const + { + OSL_ENSURE( _rItem.ISA( SvxFrameDirectionItem ), "ParagraphDirectionHandler::implGetCheckState: invalid pool item!" ); + SvxFrameDirection eDirection = static_cast< SvxFrameDirection >( static_cast< const SvxFrameDirectionItem& >( _rItem ).GetValue() ); + return ( eDirection == m_eParagraphDirection ) ? eChecked : eUnchecked; + } + + //-------------------------------------------------------------------- + void ParagraphDirectionHandler::executeAttribute( const SfxItemSet& _rCurrentAttribs, SfxItemSet& _rNewAttribs, const SfxPoolItem* /*_pAdditionalArg*/, ScriptType /*_nForScriptType*/ ) const + { + _rNewAttribs.Put( SvxFrameDirectionItem( m_eParagraphDirection, getWhich() ) ); + + // if the current adjustment of the was the default adjustment for the *previous* text direction, + // then we toggle the adjustment, too + SvxAdjust eCurrentAdjustment = SVX_ADJUST_LEFT; + const SfxPoolItem* pCurrentAdjustment = NULL; + if ( SFX_ITEM_ON == _rCurrentAttribs.GetItemState( EE_PARA_JUST, TRUE, &pCurrentAdjustment ) ) + eCurrentAdjustment = static_cast< const SvxAdjustItem* >( pCurrentAdjustment )->GetAdjust(); + + if ( eCurrentAdjustment == m_eOppositeDefaultAdjustment ) + _rNewAttribs.Put( SvxAdjustItem( m_eDefaultAdjustment, EE_PARA_JUST ) ); + } + + //==================================================================== + //= BooleanHandler + //==================================================================== + //-------------------------------------------------------------------- + BooleanHandler::BooleanHandler( AttributeId _nAttributeId, WhichId _nWhichId ) + :AttributeHandler( _nAttributeId, _nWhichId ) + { + } + + //-------------------------------------------------------------------- + AttributeCheckState BooleanHandler::implGetCheckState( const SfxPoolItem& _rItem ) const + { + OSL_ENSURE( _rItem.ISA( SfxBoolItem ), "BooleanHandler::implGetCheckState: invalid item!" ); + if ( _rItem.ISA( SfxBoolItem ) ) + return static_cast< const SfxBoolItem& >( _rItem ).GetValue() ? eChecked : eUnchecked; + + return eIndetermined; + } + + //-------------------------------------------------------------------- + void BooleanHandler::executeAttribute( const SfxItemSet& /*_rCurrentAttribs*/, SfxItemSet& _rNewAttribs, const SfxPoolItem* _pAdditionalArg, ScriptType /*_nForScriptType*/ ) const + { + OSL_ENSURE( _pAdditionalArg && _pAdditionalArg->ISA( SfxBoolItem ), "BooleanHandler::executeAttribute: invalid argument!" ); + if ( _pAdditionalArg ) + { + SfxPoolItem* pCorrectWich = _pAdditionalArg->Clone(); + pCorrectWich->SetWhich( getWhich() ); + _rNewAttribs.Put( *pCorrectWich ); + DELETEZ( pCorrectWich ); + } + } + +//........................................................................ +} // namespace frm +//........................................................................ diff --git a/forms/source/richtext/rtattributehandler.hxx b/forms/source/richtext/rtattributehandler.hxx new file mode 100644 index 000000000000..4e15cbc44050 --- /dev/null +++ b/forms/source/richtext/rtattributehandler.hxx @@ -0,0 +1,240 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef FORMS_SOURCE_COMPONENT_RTATTRIBUTEHANDLER_HXX +#define FORMS_SOURCE_COMPONENT_RTATTRIBUTEHANDLER_HXX + +#include "rtattributes.hxx" +#include <rtl/ref.hxx> +#include <editeng/svxenum.hxx> +#include <editeng/frmdir.hxx> + +class SfxItemSet; +class SfxPoolItem; +class SfxItemPool; +//........................................................................ +namespace frm +{ +//........................................................................ + + //==================================================================== + //= ReferenceBase + //==================================================================== + class ReferenceBase : public ::rtl::IReference + { + protected: + oslInterlockedCount m_refCount; + + public: + // IReference + virtual oslInterlockedCount SAL_CALL acquire(); + virtual oslInterlockedCount SAL_CALL release(); + + protected: + virtual ~ReferenceBase(); + }; + + //==================================================================== + //= IAttributeHandler + //==================================================================== + class IAttributeHandler : public ::rtl::IReference + { + public: + virtual AttributeId getAttributeId( ) const = 0; + virtual AttributeState getState( const SfxItemSet& _rAttribs ) const = 0; + virtual void executeAttribute( const SfxItemSet& _rCurrentAttribs, SfxItemSet& _rNewAttribs, const SfxPoolItem* _pAdditionalArg, ScriptType _nForScriptType ) const = 0; + }; + + //==================================================================== + //= AttributeHandler + //==================================================================== + class AttributeHandler :public ReferenceBase + ,public IAttributeHandler + { + private: + AttributeId m_nAttribute; + WhichId m_nWhich; + + protected: + AttributeId getAttribute() const { return m_nAttribute; } + WhichId getWhich() const { return m_nWhich; } + + public: + AttributeHandler( AttributeId _nAttributeId, WhichId _nWhichId ); + + // IAttributeHandler + virtual AttributeId getAttributeId( ) const; + virtual AttributeState getState( const SfxItemSet& _rAttribs ) const; + virtual void executeAttribute( const SfxItemSet& _rCurrentAttribs, SfxItemSet& _rNewAttribs, const SfxPoolItem* _pAdditionalArg, ScriptType _nForScriptType ) const = 0; + + protected: + /// helper method calling implGetCheckState + AttributeCheckState getCheckState( const SfxItemSet& _rAttribs ) const; + + /// helper method putting an item into a set, respecting a script type + void putItemForScript( SfxItemSet& _rAttribs, const SfxPoolItem& _rItem, ScriptType _nForScriptType ) const; + + // pseudo-abstract + virtual AttributeCheckState implGetCheckState( const SfxPoolItem& _rItem ) const; + + // disambiguate IReference + virtual oslInterlockedCount SAL_CALL acquire(); + virtual oslInterlockedCount SAL_CALL release(); + + protected: + virtual ~AttributeHandler(); + }; + + //==================================================================== + //= AttributeHandlerFactory + //==================================================================== + class AttributeHandlerFactory + { + public: + static ::rtl::Reference< IAttributeHandler > getHandlerFor( AttributeId _nAttributeId, const SfxItemPool& _rEditEnginePool ); + + private: + AttributeHandlerFactory(); // never implemented + AttributeHandlerFactory( const AttributeHandlerFactory& ); // never implemented + AttributeHandlerFactory& operator=( const AttributeHandlerFactory& ); // never implemented + ~AttributeHandlerFactory(); // never implemented + }; + + //==================================================================== + //= ParaAlignmentHandler + //==================================================================== + class ParaAlignmentHandler : public AttributeHandler + { + private: + SvxAdjust m_eAdjust; + + public: + ParaAlignmentHandler( AttributeId _nAttributeId ); + + public: + virtual AttributeCheckState implGetCheckState( const SfxPoolItem& _rItem ) const; + virtual void executeAttribute( const SfxItemSet& _rCurrentAttribs, SfxItemSet& _rNewAttribs, const SfxPoolItem* _pAdditionalArg, ScriptType _nForScriptType ) const; + }; + + //==================================================================== + //= LineSpacingHandler + //==================================================================== + class LineSpacingHandler : public AttributeHandler + { + private: + USHORT m_nLineSpace; + + public: + LineSpacingHandler( AttributeId _nAttributeId ); + + public: + virtual AttributeCheckState implGetCheckState( const SfxPoolItem& _rItem ) const; + virtual void executeAttribute( const SfxItemSet& _rCurrentAttribs, SfxItemSet& _rNewAttribs, const SfxPoolItem* _pAdditionalArg, ScriptType _nForScriptType ) const; + }; + + //==================================================================== + //= EscapementHandler + //==================================================================== + class EscapementHandler : public AttributeHandler + { + private: + SvxEscapement m_eEscapement; + + public: + EscapementHandler( AttributeId _nAttributeId ); + + public: + virtual AttributeCheckState implGetCheckState( const SfxPoolItem& _rItem ) const; + virtual void executeAttribute( const SfxItemSet& _rCurrentAttribs, SfxItemSet& _rNewAttribs, const SfxPoolItem* _pAdditionalArg, ScriptType _nForScriptType ) const; + }; + + //==================================================================== + //= SlotHandler + //==================================================================== + class SlotHandler : public AttributeHandler + { + private: + bool m_bScriptDependent; + + public: + SlotHandler( AttributeId _nAttributeId, WhichId _nWhichId ); + + public: + virtual AttributeState getState( const SfxItemSet& _rAttribs ) const; + virtual void executeAttribute( const SfxItemSet& _rCurrentAttribs, SfxItemSet& _rNewAttribs, const SfxPoolItem* _pAdditionalArg, ScriptType _nForScriptType ) const; + }; + + //==================================================================== + //= BooleanHandler + //==================================================================== + class BooleanHandler : public AttributeHandler + { + public: + BooleanHandler( AttributeId _nAttributeId, WhichId _nWhichId ); + + public: + virtual AttributeCheckState implGetCheckState( const SfxPoolItem& _rItem ) const; + virtual void executeAttribute( const SfxItemSet& _rCurrentAttribs, SfxItemSet& _rNewAttribs, const SfxPoolItem* _pAdditionalArg, ScriptType _nForScriptType ) const; + }; + + //==================================================================== + //= FontSizeHandler + //==================================================================== + class FontSizeHandler : public AttributeHandler + { + public: + FontSizeHandler( AttributeId _nAttributeId, WhichId _nWhichId ); + + public: + virtual AttributeState getState( const SfxItemSet& _rAttribs ) const; + virtual void executeAttribute( const SfxItemSet& _rCurrentAttribs, SfxItemSet& _rNewAttribs, const SfxPoolItem* _pAdditionalArg, ScriptType _nForScriptType ) const; + }; + + //==================================================================== + //= ParagraphDirectionHandler + //==================================================================== + class ParagraphDirectionHandler : public AttributeHandler + { + private: + SvxFrameDirection m_eParagraphDirection; + SvxAdjust m_eDefaultAdjustment; + SvxAdjust m_eOppositeDefaultAdjustment; + + public: + ParagraphDirectionHandler( AttributeId _nAttributeId ); + + public: + virtual AttributeCheckState implGetCheckState( const SfxPoolItem& _rItem ) const; + virtual void executeAttribute( const SfxItemSet& _rCurrentAttribs, SfxItemSet& _rNewAttribs, const SfxPoolItem* _pAdditionalArg, ScriptType _nForScriptType ) const; + }; + +//........................................................................ +} // namespace frm +//........................................................................ + +#endif // FORMS_SOURCE_COMPONENT_RTATTRIBUTEHANDLER_HXX + diff --git a/forms/source/richtext/rtattributes.hxx b/forms/source/richtext/rtattributes.hxx new file mode 100644 index 000000000000..2506dbcb5186 --- /dev/null +++ b/forms/source/richtext/rtattributes.hxx @@ -0,0 +1,172 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef FORMS_SOURCE_RICHTEXT_RTATTRIBUTES_HXX +#define FORMS_SOURCE_RICHTEXT_RTATTRIBUTES_HXX + +#include <tools/solar.h> +#include <sal/types.h> +#include <svl/poolitem.hxx> + +//........................................................................ +namespace frm +{ +//........................................................................ + + //==================================================================== + //= misc + //==================================================================== + /// the id of an attribute + typedef sal_Int32 AttributeId; + /// the "which id" of an item in an SfxItemSet + typedef USHORT WhichId; + /// a SFX slot id + typedef USHORT SfxSlotId; + /// a script type + typedef USHORT ScriptType; + + //==================================================================== + //= AttributeCheckState + //==================================================================== + enum AttributeCheckState + { + eChecked, + eUnchecked, + eIndetermined + }; + + //==================================================================== + //= AttributeState + //==================================================================== + struct AttributeState + { + private: + SfxItemHandle* pItemHandle; + + public: + AttributeCheckState eSimpleState; + + //................................................................ + inline AttributeState( ); + inline explicit AttributeState( AttributeCheckState _eCheckState ); + inline AttributeState( const AttributeState& _rSource ); + + inline AttributeState& operator=( const AttributeState& _rSource ); + + inline bool operator==( const AttributeState& _rRHS ); + + inline const SfxPoolItem* getItem() const; + inline void setItem( const SfxPoolItem* _pItem ); + }; + + //==================================================================== + //= AttributeState (inline implementation) + //==================================================================== + //................................................................ + inline AttributeState::AttributeState( ) + :pItemHandle( NULL ) + ,eSimpleState( eIndetermined ) + { + } + + //................................................................ + inline AttributeState::AttributeState( AttributeCheckState _eCheckState ) + :pItemHandle( NULL ) + ,eSimpleState( _eCheckState ) + { + } + + //................................................................ + inline AttributeState::AttributeState( const AttributeState& _rSource ) + :pItemHandle( NULL ) + ,eSimpleState( eIndetermined ) + { + operator=( _rSource ); + } + + //................................................................ + inline AttributeState& AttributeState::operator=( const AttributeState& _rSource ) + { + if ( &_rSource == this ) + return *this; + + eSimpleState = _rSource.eSimpleState; + setItem( _rSource.getItem() ); + return *this; + } + + //................................................................ + inline const SfxPoolItem* AttributeState::getItem() const + { + return pItemHandle ? &pItemHandle->GetItem() : NULL; + } + + //................................................................ + inline void AttributeState::setItem( const SfxPoolItem* _pItem ) + { + if ( pItemHandle ) + delete pItemHandle; + if ( _pItem ) + pItemHandle = new SfxItemHandle( *const_cast< SfxPoolItem* >( _pItem ) ); + else + pItemHandle = NULL; + } + + //................................................................ + inline bool AttributeState::operator==( const AttributeState& _rRHS ) + { + if ( eSimpleState != _rRHS.eSimpleState ) + return false; + + if ( pItemHandle && !_rRHS.pItemHandle ) + return false; + + if ( !pItemHandle && _rRHS.pItemHandle ) + return false; + + if ( !pItemHandle && !_rRHS.pItemHandle ) + return true; + + return ( pItemHandle->GetItem() == _rRHS.pItemHandle->GetItem() ); + } + + //==================================================================== + //= IMultiAttributeDispatcher + //==================================================================== + class IMultiAttributeDispatcher + { + public: + virtual AttributeState getState( AttributeId _nAttributeId ) const = 0; + virtual void executeAttribute( AttributeId _nAttributeId, const SfxPoolItem* _pArgument ) = 0; + }; + +//........................................................................ +} // namespace frm +//........................................................................ + +#endif // FORMS_SOURCE_RICHTEXT_RTATTRIBUTES_HXX + diff --git a/forms/source/richtext/specialdispatchers.cxx b/forms/source/richtext/specialdispatchers.cxx new file mode 100644 index 000000000000..2540c9d797f2 --- /dev/null +++ b/forms/source/richtext/specialdispatchers.cxx @@ -0,0 +1,200 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_forms.hxx" +#include "specialdispatchers.hxx" +#include <editeng/editeng.hxx> +#include <editeng/editview.hxx> +#ifndef _SVX_SVXIDS_HRC +#include <svx/svxids.hrc> +#endif +#define ITEMID_SCRIPTSPACE SID_ATTR_PARA_SCRIPTSPACE +#include <editeng/scriptspaceitem.hxx> + +//........................................................................ +namespace frm +{ +//........................................................................ + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::util; + using namespace ::com::sun::star::frame; + using namespace ::com::sun::star::beans; + + //==================================================================== + //= OSelectAllDispatcher + //==================================================================== + //-------------------------------------------------------------------- + OSelectAllDispatcher::OSelectAllDispatcher( EditView& _rView, const URL& _rURL ) + :ORichTextFeatureDispatcher( _rView, _rURL ) + { + } + + //-------------------------------------------------------------------- + OSelectAllDispatcher::~OSelectAllDispatcher( ) + { + if ( !isDisposed() ) + { + acquire(); + dispose(); + } + } + + //-------------------------------------------------------------------- + void SAL_CALL OSelectAllDispatcher::dispatch( const URL& _rURL, const Sequence< PropertyValue >& /*_rArguments*/ ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + OSL_ENSURE( _rURL.Complete == getFeatureURL().Complete, "OSelectAllDispatcher::dispatch: invalid URL!" ); + (void)_rURL; + + checkDisposed(); + + EditEngine* pEngine = getEditView() ? getEditView()->GetEditEngine() : NULL; + OSL_ENSURE( pEngine, "OSelectAllDispatcher::dispatch: no edit engine - but not yet disposed?" ); + if ( !pEngine ) + return; + + USHORT nParagraphs = pEngine->GetParagraphCount(); + if ( nParagraphs ) + { + USHORT nLastParaNumber = nParagraphs - 1; + xub_StrLen nParaLen = pEngine->GetTextLen( nLastParaNumber ); + getEditView()->SetSelection( ESelection( 0, 0, nLastParaNumber, nParaLen ) ); + } + } + + //-------------------------------------------------------------------- + FeatureStateEvent OSelectAllDispatcher::buildStatusEvent() const + { + FeatureStateEvent aEvent( ORichTextFeatureDispatcher::buildStatusEvent() ); + aEvent.IsEnabled = sal_True; + return aEvent; + } + + //==================================================================== + //= OParagraphDirectionDispatcher + //==================================================================== + //-------------------------------------------------------------------- + OParagraphDirectionDispatcher::OParagraphDirectionDispatcher( EditView& _rView, AttributeId _nAttributeId, const URL& _rURL, + IMultiAttributeDispatcher* _pMasterDispatcher ) + :OAttributeDispatcher( _rView, _nAttributeId, _rURL, _pMasterDispatcher ) + { + } + + //-------------------------------------------------------------------- + FeatureStateEvent OParagraphDirectionDispatcher::buildStatusEvent() const + { + FeatureStateEvent aEvent( OAttributeDispatcher::buildStatusEvent() ); + + EditEngine* pEngine = getEditView() ? getEditView()->GetEditEngine() : NULL; + OSL_ENSURE( pEngine, "OParagraphDirectionDispatcher::dispatch: no edit engine - but not yet disposed?" ); + if ( pEngine && pEngine->IsVertical() ) + aEvent.IsEnabled = sal_False; + + return aEvent; + } + + //==================================================================== + //= OTextDirectionDispatcher + //==================================================================== + //-------------------------------------------------------------------- + OTextDirectionDispatcher::OTextDirectionDispatcher( EditView& _rView, const URL& _rURL ) + :ORichTextFeatureDispatcher( _rView, _rURL ) + { + } + + //-------------------------------------------------------------------- + void SAL_CALL OTextDirectionDispatcher::dispatch( const URL& _rURL, const Sequence< PropertyValue >& /*_rArguments*/ ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + OSL_ENSURE( _rURL.Complete == getFeatureURL().Complete, "OTextDirectionDispatcher::dispatch: invalid URL!" ); + (void)_rURL; + + checkDisposed(); + + EditEngine* pEngine = getEditView() ? getEditView()->GetEditEngine() : NULL; + OSL_ENSURE( pEngine, "OTextDirectionDispatcher::dispatch: no edit engine - but not yet disposed?" ); + if ( !pEngine ) + return; + + pEngine->SetVertical( !pEngine->IsVertical() ); + } + + //-------------------------------------------------------------------- + FeatureStateEvent OTextDirectionDispatcher::buildStatusEvent() const + { + FeatureStateEvent aEvent( ORichTextFeatureDispatcher::buildStatusEvent() ); + + EditEngine* pEngine = getEditView() ? getEditView()->GetEditEngine() : NULL; + OSL_ENSURE( pEngine, "OTextDirectionDispatcher::dispatch: no edit engine - but not yet disposed?" ); + + aEvent.IsEnabled = sal_True; + aEvent.State <<= (sal_Bool)( pEngine && pEngine->IsVertical() ); + + return aEvent; + } + + //==================================================================== + //= OAsianFontLayoutDispatcher + //==================================================================== + //-------------------------------------------------------------------- + OAsianFontLayoutDispatcher::OAsianFontLayoutDispatcher( EditView& _rView, AttributeId _nAttributeId, const URL& _rURL, IMultiAttributeDispatcher* _pMasterDispatcher ) + :OParametrizedAttributeDispatcher( _rView, _nAttributeId, _rURL, _pMasterDispatcher ) + { + } + + //-------------------------------------------------------------------- + const SfxPoolItem* OAsianFontLayoutDispatcher::convertDispatchArgsToItem( const Sequence< PropertyValue >& _rArguments ) + { + // look for the "Enable" parameter + const PropertyValue* pLookup = _rArguments.getConstArray(); + const PropertyValue* pLookupEnd = _rArguments.getConstArray() + _rArguments.getLength(); + while ( pLookup != pLookupEnd ) + { + if ( pLookup->Name.equalsAscii( "Enable" ) ) + break; + ++pLookup; + } + if ( pLookup != pLookupEnd ) + { + sal_Bool bEnable = sal_True; + OSL_VERIFY( pLookup->Value >>= bEnable ); + if ( m_nAttributeId == SID_ATTR_PARA_SCRIPTSPACE ) + return new SvxScriptSpaceItem( bEnable, (WhichId)m_nAttributeId ); + return new SfxBoolItem( (WhichId)m_nAttributeId, bEnable ); + } + + OSL_ENSURE( sal_False, "OAsianFontLayoutDispatcher::convertDispatchArgsToItem: did not find the one and only argument!" ); + return NULL; + } + +//........................................................................ +} // namespace frm +//........................................................................ + diff --git a/forms/source/richtext/specialdispatchers.hxx b/forms/source/richtext/specialdispatchers.hxx new file mode 100644 index 000000000000..7b6c7b98ea24 --- /dev/null +++ b/forms/source/richtext/specialdispatchers.hxx @@ -0,0 +1,113 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef FORMS_SOURCE_RICHTEXT_SPECIALDISPATCHERS_HXX +#define FORMS_SOURCE_RICHTEXT_SPECIALDISPATCHERS_HXX + +#include "parametrizedattributedispatcher.hxx" + +//........................................................................ +namespace frm +{ +//........................................................................ + + //==================================================================== + //= OSelectAllDispatcher + //==================================================================== + class OSelectAllDispatcher : public ORichTextFeatureDispatcher + { + public: + OSelectAllDispatcher( EditView& _rView, const ::com::sun::star::util::URL& _rURL ); + + protected: + ~OSelectAllDispatcher(); + + // XDispatch + virtual void SAL_CALL dispatch( const ::com::sun::star::util::URL& URL, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& Arguments ) throw (::com::sun::star::uno::RuntimeException); + + // ORichTextFeatureDispatcher + virtual ::com::sun::star::frame::FeatureStateEvent buildStatusEvent() const; + }; + + //==================================================================== + //= OParagraphDirectionDispatcher + //==================================================================== + class OParagraphDirectionDispatcher : public OAttributeDispatcher + { + public: + OParagraphDirectionDispatcher( + EditView& _rView, + AttributeId _nAttributeId, + const ::com::sun::star::util::URL& _rURL, + IMultiAttributeDispatcher* _pMasterDispatcher + ); + + protected: + // ORichTextFeatureDispatcher + virtual ::com::sun::star::frame::FeatureStateEvent buildStatusEvent() const; + }; + + //==================================================================== + //= OTextDirectionDispatcher + //==================================================================== + class OTextDirectionDispatcher : public ORichTextFeatureDispatcher + { + public: + OTextDirectionDispatcher( EditView& _rView, const ::com::sun::star::util::URL& _rURL ); + + protected: + // XDispatch + virtual void SAL_CALL dispatch( const ::com::sun::star::util::URL& URL, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& Arguments ) throw (::com::sun::star::uno::RuntimeException); + + // ORichTextFeatureDispatcher + virtual ::com::sun::star::frame::FeatureStateEvent buildStatusEvent() const; + }; + + //==================================================================== + //= OAsianFontLayoutDispatcher + //==================================================================== + class OAsianFontLayoutDispatcher : public OParametrizedAttributeDispatcher + { + public: + OAsianFontLayoutDispatcher( + EditView& _rView, + AttributeId _nAttributeId, + const ::com::sun::star::util::URL& _rURL, + IMultiAttributeDispatcher* _pMasterDispatcher + ); + + protected: + // OParametrizedAttributeDispatcher + virtual const SfxPoolItem* convertDispatchArgsToItem( + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _rArguments ); + }; + +//........................................................................ +} // namespace frm +//........................................................................ + +#endif // FORMS_SOURCE_RICHTEXT_SPECIALDISPATCHERS_HXX diff --git a/forms/source/richtext/textattributelistener.hxx b/forms/source/richtext/textattributelistener.hxx new file mode 100644 index 000000000000..3b7b29ee19f9 --- /dev/null +++ b/forms/source/richtext/textattributelistener.hxx @@ -0,0 +1,61 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef FORMS_SOURCE_RICHTEXT_TEXTATTRIBUTELISTENER_HXX +#define FORMS_SOURCE_RICHTEXT_TEXTATTRIBUTELISTENER_HXX + +#include "rtattributes.hxx" + +struct ESelection; +//........................................................................ +namespace frm +{ +//........................................................................ + + //==================================================================== + //= ITextAttributeListener + //==================================================================== + class ITextAttributeListener + { + public: + virtual void onAttributeStateChanged( AttributeId _nAttributeId, const AttributeState& _rState ) = 0; + }; + + //==================================================================== + //= ITextAttributeListener + //==================================================================== + class ITextSelectionListener + { + public: + virtual void onSelectionChanged( const ESelection& _rSelection ) = 0; + }; + +//........................................................................ +} // namespace frm +//........................................................................ + +#endif // FORMS_SOURCE_RICHTEXT_TEXTATTRIBUTELISTENER_HXX + |