/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"

#include "fmprop.hrc"
#include "svx/fmresids.hrc"
#include "fmtextcontroldialogs.hxx"
#include "fmtextcontrolfeature.hxx"
#include "fmtextcontrolshell.hxx"
#include "editeng/crsditem.hxx"
#include "svx/dialmgr.hxx"
#include "editeng/editeng.hxx"
#include "editeng/eeitem.hxx"
#include "svx/fmglob.hxx"
#include "editeng/scriptspaceitem.hxx"
#include "svx/svxids.hrc"
#include "editeng/udlnitem.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/awt/FontDescriptor.hpp>
#include <com/sun/star/frame/XDispatchProvider.hpp>
#include <com/sun/star/form/XForm.hpp>
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/awt/XFocusListener.hpp>
#include <com/sun/star/awt/XMouseListener.hpp>
/** === end UNO includes === **/

#include <comphelper/componentcontext.hxx>
#include <comphelper/processfactory.hxx>
#include <cppuhelper/implbase1.hxx>
#include <sfx2/app.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/msgpool.hxx>
#include <sfx2/objsh.hxx>
#include <sfx2/request.hxx>
#include <sfx2/sfxuno.hxx>
#include <sfx2/viewfrm.hxx>
#include <svl/eitem.hxx>
#include <svl/intitem.hxx>
#include <svl/itempool.hxx>
#include <svl/languageoptions.hxx>
#include <svtools/stringtransfer.hxx>
#include <svl/whiter.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <tools/diagnose_ex.h>
#include <vcl/msgbox.hxx>
#include <vcl/outdev.hxx>
#include <vos/mutex.hxx>

#include <memory>

//........................................................................
namespace svx
{
//........................................................................

    using namespace ::com::sun::star;
    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::awt;
    using namespace ::com::sun::star::form;
    using namespace ::com::sun::star::form::runtime;
    using namespace ::com::sun::star::lang;
    using namespace ::com::sun::star::frame;
    using namespace ::com::sun::star::util;
    using namespace ::com::sun::star::beans;
    using namespace ::com::sun::star::container;

	//====================================================================
    typedef sal_uInt16 WhichId;

	//====================================================================
    static SfxSlotId pTextControlSlots[] =
    {
        SID_CLIPBOARD_FORMAT_ITEMS,
        SID_CUT,
        SID_COPY,
        SID_PASTE,
        SID_SELECTALL,
//        SID_ATTR_TABSTOP,           /* 2 */
        SID_ATTR_CHAR_FONT,
        SID_ATTR_CHAR_POSTURE,
        SID_ATTR_CHAR_WEIGHT,
        SID_ATTR_CHAR_SHADOWED,
        SID_ATTR_CHAR_WORDLINEMODE,
        SID_ATTR_CHAR_CONTOUR,
        SID_ATTR_CHAR_STRIKEOUT,
        SID_ATTR_CHAR_UNDERLINE,
        SID_ATTR_CHAR_FONTHEIGHT,
        SID_ATTR_CHAR_COLOR,
        SID_ATTR_CHAR_KERNING,
        SID_ATTR_CHAR_LANGUAGE,     /* 20 */
        SID_ATTR_CHAR_ESCAPEMENT,
        SID_ATTR_PARA_ADJUST,       /* 28 */
        SID_ATTR_PARA_ADJUST_LEFT,
        SID_ATTR_PARA_ADJUST_RIGHT,
        SID_ATTR_PARA_ADJUST_CENTER,
        SID_ATTR_PARA_ADJUST_BLOCK,
        SID_ATTR_PARA_LINESPACE,    /* 33 */
        SID_ATTR_PARA_LINESPACE_10,
        SID_ATTR_PARA_LINESPACE_15,
        SID_ATTR_PARA_LINESPACE_20,
        SID_ATTR_LRSPACE,           /* 48 */
        SID_ATTR_ULSPACE,           /* 49 */
        SID_ATTR_CHAR_AUTOKERN,
        SID_SET_SUPER_SCRIPT,
        SID_SET_SUB_SCRIPT,
        SID_CHAR_DLG,
        SID_PARA_DLG,
//        SID_TEXTDIRECTION_LEFT_TO_RIGHT, /* 907 */
//        SID_TEXTDIRECTION_TOP_TO_BOTTOM,
        SID_ATTR_CHAR_SCALEWIDTH,       /* 911 */
        SID_ATTR_CHAR_RELIEF,
        SID_ATTR_PARA_LEFT_TO_RIGHT,    /* 950 */
        SID_ATTR_PARA_RIGHT_TO_LEFT,
        SID_ATTR_CHAR_OVERLINE,
        0
    };

    // slots which we are not responsible for on the SfxShell level, but
    // need to handle during the "paragraph attributes" and/or "character
    // attributes" dialogs
    static SfxSlotId pDialogSlots[] =
    {
        SID_ATTR_TABSTOP,
        SID_ATTR_PARA_HANGPUNCTUATION,
        SID_ATTR_PARA_FORBIDDEN_RULES,
        SID_ATTR_PARA_SCRIPTSPACE,
        SID_ATTR_CHAR_LATIN_LANGUAGE,
        SID_ATTR_CHAR_CJK_LANGUAGE,
        SID_ATTR_CHAR_CTL_LANGUAGE,
        SID_ATTR_CHAR_LATIN_FONT,
        SID_ATTR_CHAR_CJK_FONT,
        SID_ATTR_CHAR_CTL_FONT,
		SID_ATTR_CHAR_LATIN_FONTHEIGHT,
		SID_ATTR_CHAR_CJK_FONTHEIGHT,
		SID_ATTR_CHAR_CTL_FONTHEIGHT,
		SID_ATTR_CHAR_LATIN_WEIGHT,
		SID_ATTR_CHAR_CJK_WEIGHT,
		SID_ATTR_CHAR_CTL_WEIGHT,
		SID_ATTR_CHAR_LATIN_POSTURE,
		SID_ATTR_CHAR_CJK_POSTURE,
        SID_ATTR_CHAR_CTL_POSTURE,
        SID_ATTR_CHAR_EMPHASISMARK,
        0
    };

	//====================================================================
	//= FmFocusListenerAdapter
	//====================================================================
    typedef ::cppu::WeakImplHelper1 <   XFocusListener
                                    >   FmFocusListenerAdapter_Base;
    class FmFocusListenerAdapter : public FmFocusListenerAdapter_Base
    {
    private:
        IFocusObserver*         m_pObserver;
        Reference< XWindow >    m_xWindow;

    public:
        FmFocusListenerAdapter( const Reference< XControl >& _rxControl, IFocusObserver* _pObserver );

        // clean up the instance
        void    dispose();

    protected:
        ~FmFocusListenerAdapter();

    protected:
        virtual void SAL_CALL focusGained( const FocusEvent& e ) throw (RuntimeException);
        virtual void SAL_CALL focusLost( const FocusEvent& e ) throw (RuntimeException);
        virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException);
    };

    //--------------------------------------------------------------------
    DBG_NAME( FmFocusListenerAdapter )
    //--------------------------------------------------------------------
    FmFocusListenerAdapter::FmFocusListenerAdapter( const Reference< XControl >& _rxControl, IFocusObserver* _pObserver )
        :m_pObserver( _pObserver )
        ,m_xWindow( _rxControl, UNO_QUERY )
    {
        DBG_CTOR( FmFocusListenerAdapter, NULL );

        DBG_ASSERT( m_xWindow.is(), "FmFocusListenerAdapter::FmFocusListenerAdapter: invalid control!" );
        osl_incrementInterlockedCount( &m_refCount );
        {
            try
            {
                if ( m_xWindow.is() )
                    m_xWindow->addFocusListener( this );
            }
            catch( const Exception& )
            {
                DBG_UNHANDLED_EXCEPTION();
            }
        }
        osl_decrementInterlockedCount( &m_refCount );
    }

    //--------------------------------------------------------------------
    FmFocusListenerAdapter::~FmFocusListenerAdapter()
    {
        acquire();
        dispose();

        DBG_DTOR( FmFocusListenerAdapter, NULL );
    }

    //--------------------------------------------------------------------
    void FmFocusListenerAdapter::dispose()
    {
        if ( m_xWindow.is() )
        {
            m_xWindow->removeFocusListener( this );
            m_xWindow.clear();
        }
    }

    //--------------------------------------------------------------------
    void SAL_CALL FmFocusListenerAdapter::focusGained( const FocusEvent& e ) throw (RuntimeException)
    {
        if ( m_pObserver )
            m_pObserver->focusGained( e );
    }

    //--------------------------------------------------------------------
    void SAL_CALL FmFocusListenerAdapter::focusLost( const FocusEvent& e ) throw (RuntimeException)
    {
        if ( m_pObserver )
            m_pObserver->focusLost( e );
    }

    //--------------------------------------------------------------------
    void SAL_CALL FmFocusListenerAdapter::disposing( const EventObject& Source ) throw (RuntimeException)
    {
        (void)Source;
        DBG_ASSERT( Source.Source == m_xWindow, "FmFocusListenerAdapter::disposing: where did this come from?" );
        m_xWindow.clear();
    }

	//====================================================================
	//= FmMouseListenerAdapter
	//====================================================================
    typedef ::cppu::WeakImplHelper1 <   XMouseListener
                                    >   FmMouseListenerAdapter_Base;
    class FmMouseListenerAdapter : public FmMouseListenerAdapter_Base
    {
    private:
        IContextRequestObserver*  m_pObserver;
        Reference< XWindow >    m_xWindow;

    public:
        FmMouseListenerAdapter( const Reference< XControl >& _rxControl, IContextRequestObserver* _pObserver );

        // clean up the instance
        void    dispose();

    protected:
        ~FmMouseListenerAdapter();

    protected:
        virtual void SAL_CALL mousePressed( const awt::MouseEvent& e ) throw (RuntimeException);
        virtual void SAL_CALL mouseReleased( const awt::MouseEvent& e ) throw (RuntimeException);
        virtual void SAL_CALL mouseEntered( const awt::MouseEvent& e ) throw (RuntimeException);
        virtual void SAL_CALL mouseExited( const awt::MouseEvent& e ) throw (RuntimeException);
        virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException);
    };

	//====================================================================
	//= FmMouseListenerAdapter
	//====================================================================
    //--------------------------------------------------------------------
    DBG_NAME( FmMouseListenerAdapter )
    //--------------------------------------------------------------------
    FmMouseListenerAdapter::FmMouseListenerAdapter( const Reference< XControl >& _rxControl, IContextRequestObserver* _pObserver )
        :m_pObserver( _pObserver )
        ,m_xWindow( _rxControl, UNO_QUERY )
    {
        DBG_CTOR( FmMouseListenerAdapter, NULL );

        DBG_ASSERT( m_xWindow.is(), "FmMouseListenerAdapter::FmMouseListenerAdapter: invalid control!" );
        osl_incrementInterlockedCount( &m_refCount );
        {
            try
            {
                if ( m_xWindow.is() )
                    m_xWindow->addMouseListener( this );
            }
            catch( const Exception& )
            {
                DBG_UNHANDLED_EXCEPTION();
            }
        }
        osl_decrementInterlockedCount( &m_refCount );
    }

    //--------------------------------------------------------------------
    FmMouseListenerAdapter::~FmMouseListenerAdapter()
    {
        acquire();
        dispose();

        DBG_DTOR( FmMouseListenerAdapter, NULL );
    }

    //--------------------------------------------------------------------
    void FmMouseListenerAdapter::dispose()
    {
        if ( m_xWindow.is() )
        {
            m_xWindow->removeMouseListener( this );
            m_xWindow.clear();
        }
    }

    //--------------------------------------------------------------------
    void SAL_CALL FmMouseListenerAdapter::mousePressed( const awt::MouseEvent& _rEvent ) throw (::com::sun::star::uno::RuntimeException)
    {
        ::vos::OGuard aGuard( Application::GetSolarMutex() );
	    // is this a request for a context menu?
	    if ( _rEvent.PopupTrigger )
        {
            if ( m_pObserver )
                m_pObserver->contextMenuRequested( _rEvent );
        }
    }

    //--------------------------------------------------------------------
    void SAL_CALL FmMouseListenerAdapter::mouseReleased( const awt::MouseEvent& /*e*/ ) throw (::com::sun::star::uno::RuntimeException)
    {
        // not interested in
    }

    //--------------------------------------------------------------------
    void SAL_CALL FmMouseListenerAdapter::mouseEntered( const awt::MouseEvent& /*e*/ ) throw (::com::sun::star::uno::RuntimeException)
    {
        // not interested in
    }

    //--------------------------------------------------------------------
    void SAL_CALL FmMouseListenerAdapter::mouseExited( const awt::MouseEvent& /*e*/ ) throw (::com::sun::star::uno::RuntimeException)
    {
        // not interested in
    }

    //--------------------------------------------------------------------
    void SAL_CALL FmMouseListenerAdapter::disposing( const EventObject& Source ) throw (RuntimeException)
    {
        (void)Source;
        DBG_ASSERT( Source.Source == m_xWindow, "FmMouseListenerAdapter::disposing: where did this come from?" );
        m_xWindow.clear();
    }

    //====================================================================
    //= FmTextControlShell
	//====================================================================
    //------------------------------------------------------------------------
    namespace
    {
        //....................................................................
        void lcl_translateUnoStateToItem( SfxSlotId _nSlot, const Any& _rUnoState, SfxItemSet& _rSet )
        {
            WhichId nWhich = _rSet.GetPool()->GetWhich( _nSlot );
            if ( !_rUnoState.hasValue() )
            {
                if  ( ( _nSlot != SID_CUT )
                   && ( _nSlot != SID_COPY )
                   && ( _nSlot != SID_PASTE )
                    )
                {
                    _rSet.InvalidateItem( nWhich );
                }
            }
            else
            {
                switch ( _rUnoState.getValueType().getTypeClass() )
                {
                case TypeClass_BOOLEAN:
                {
                    sal_Bool bState = sal_False;
                    _rUnoState >>= bState;
                    if ( _nSlot == SID_ATTR_PARA_SCRIPTSPACE )
                        _rSet.Put( SvxScriptSpaceItem( bState, nWhich ) );
                    else
    				    _rSet.Put( SfxBoolItem( nWhich, bState ) );
                }
                break;

                default:
                {
                    Sequence< PropertyValue > aComplexState;
                    if ( _rUnoState >>= aComplexState )
                    {
                        if ( !aComplexState.getLength() )
                            _rSet.InvalidateItem( nWhich );
                        else
                        {
                            SfxAllItemSet aAllItems( _rSet );
                            TransformParameters( _nSlot, aComplexState, aAllItems );
                            const SfxPoolItem* pTransformed = aAllItems.GetItem( nWhich );
                            OSL_ENSURE( pTransformed, "lcl_translateUnoStateToItem: non-empty parameter sequence leading to empty item?" );
                            if ( pTransformed )
                                _rSet.Put( *pTransformed );
                            else
                                _rSet.InvalidateItem( nWhich );
                        }
                    }
                    else
                    {
                        DBG_ERROR( "lcl_translateUnoStateToItem: invalid state!" );
                    }
                }
                }
            }
        }

        //....................................................................
        ::rtl::OUString lcl_getUnoSlotName( SfxApplication&, SfxSlotId _nSlotId )
        {
            ::rtl::OUString sSlotUnoName;

            SfxSlotPool& rSlotPool = SfxSlotPool::GetSlotPool( NULL );
            const SfxSlot* pSlot = rSlotPool.GetSlot( _nSlotId );

            const sal_Char* pAsciiUnoName = NULL;
            if ( pSlot )
            {
                pAsciiUnoName = pSlot->GetUnoName();
            }
            else
            {
                // 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
                switch ( _nSlotId )
                {
                case SID_ATTR_PARA_HANGPUNCTUATION: pAsciiUnoName = "AllowHangingPunctuation"; break;
                case SID_ATTR_PARA_FORBIDDEN_RULES: pAsciiUnoName = "ApplyForbiddenCharacterRules"; break;
                case SID_ATTR_PARA_SCRIPTSPACE: pAsciiUnoName = "UseScriptSpacing"; break;
                }
            }

            if ( pAsciiUnoName )
            {
                sSlotUnoName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:" ) );
                sSlotUnoName += ::rtl::OUString::createFromAscii( pAsciiUnoName );
            }
#if OSL_DEBUG_LEVEL > 0
            else
            {
                ::rtl::OString sMessage( "lcl_getUnoSlotName: invalid slot id, or invalid slot, or no UNO name!\n" );
                sMessage += "(slot id: ";
                sMessage += ::rtl::OString::valueOf( (sal_Int32)_nSlotId );
                sMessage += ")";
                DBG_ERROR( sMessage );
            }
#endif
            return sSlotUnoName;
        }

        //....................................................................
        bool lcl_determineReadOnly( const Reference< XControl >& _rxControl )
        {
            bool bIsReadOnlyModel = true;
            try
            {
                Reference< XPropertySet > xModelProps;
                if ( _rxControl.is() )
                    xModelProps = xModelProps.query( _rxControl->getModel() );
                Reference< XPropertySetInfo > xModelPropInfo;
                if ( xModelProps.is() )
                    xModelPropInfo = xModelProps->getPropertySetInfo();

                if ( !xModelPropInfo.is() || !xModelPropInfo->hasPropertyByName( FM_PROP_READONLY ) )
                    bIsReadOnlyModel = true;
                else
                {
                    sal_Bool bReadOnly = sal_True;
                    xModelProps->getPropertyValue( FM_PROP_READONLY ) >>= bReadOnly;
                    bIsReadOnlyModel = bReadOnly;
                }
            }
            catch( const Exception& )
            {
                DBG_UNHANDLED_EXCEPTION();
            }
            return bIsReadOnlyModel;
        }

        //....................................................................
        static Window* lcl_getWindow( const Reference< XControl >& _rxControl )
        {
            Window* pWindow = NULL;
            try
            {
                Reference< XWindowPeer > xControlPeer;
                if ( _rxControl.is() )
                    xControlPeer = _rxControl->getPeer();
                if ( xControlPeer.is() )
                    pWindow = VCLUnoHelper::GetWindow( xControlPeer );
            }
            catch( const Exception& )
            {
                DBG_UNHANDLED_EXCEPTION();
            }

            return pWindow;
        }

        //....................................................................
        bool lcl_isRichText( const Reference< XControl >& _rxControl )
        {
            if ( !_rxControl.is() )
                return false;

            bool bIsRichText = false;
            try
            {
                Reference< XPropertySet > xModelProps( _rxControl->getModel(), UNO_QUERY );
                Reference< XPropertySetInfo > xPSI;
                if ( xModelProps.is() )
                    xPSI = xModelProps->getPropertySetInfo();
                ::rtl::OUString sRichTextPropertyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RichText" ) );
                if ( xPSI.is() && xPSI->hasPropertyByName( sRichTextPropertyName ) )
                {
                    OSL_VERIFY( xModelProps->getPropertyValue( sRichTextPropertyName ) >>= bIsRichText );
                }
            }
            catch( const Exception& )
            {
                DBG_UNHANDLED_EXCEPTION();
            }
            return bIsRichText;
        }
    }

    //------------------------------------------------------------------------
    FmTextControlShell::FmTextControlShell( SfxViewFrame* _pFrame )
        :m_bActiveControl( false )
        ,m_bActiveControlIsReadOnly( true )
        ,m_bActiveControlIsRichText( false )
        ,m_pViewFrame( _pFrame )
        ,m_rBindings( _pFrame->GetBindings() )
        ,m_bNeedClipboardInvalidation( true )
    {
        m_aClipboardInvalidation.SetTimeoutHdl( LINK( this, FmTextControlShell, OnInvalidateClipboard ) );
        m_aClipboardInvalidation.SetTimeout( 200 );
    }

    //------------------------------------------------------------------------
    FmTextControlShell::~FmTextControlShell()
    {
        dispose();
    }

    //------------------------------------------------------------------------
    IMPL_LINK( FmTextControlShell, OnInvalidateClipboard, void*, /*_pNotInterestedIn*/ )
    {
        if ( m_bNeedClipboardInvalidation )
        {
            DBG_TRACE( "FmTextControlShell::ClipBoard: invalidating clipboard slots" );
            m_rBindings.Invalidate( SID_CUT );
            m_rBindings.Invalidate( SID_COPY );
            m_rBindings.Invalidate( SID_PASTE );
            m_bNeedClipboardInvalidation = false;
        }
        return 0L;
    }

    //------------------------------------------------------------------------
    void FmTextControlShell::transferFeatureStatesToItemSet( ControlFeatures& _rDispatchers, SfxAllItemSet& _rSet, bool _bTranslateLatin )
    {
        SfxItemPool& rPool = *_rSet.GetPool();

        for (   ControlFeatures::const_iterator aFeature = _rDispatchers.begin();
                aFeature != _rDispatchers.end();
                ++aFeature
            )
        {
            SfxSlotId nSlotId( aFeature->first );
            #if OSL_DEBUG_LEVEL > 0
                ::rtl::OUString sUnoSlotName;
                if ( SFX_APP() )
                    sUnoSlotName = lcl_getUnoSlotName( *SFX_APP(), nSlotId );
                else
                    sUnoSlotName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "<unknown>" ) );
                ::rtl::OString sUnoSlotNameAscii( "\"" );
                sUnoSlotNameAscii += ::rtl::OString( sUnoSlotName.getStr(), sUnoSlotName.getLength(), RTL_TEXTENCODING_ASCII_US );
                sUnoSlotNameAscii += "\"";
            #endif

            if ( _bTranslateLatin )
            {
                // A rich text control offers a dispatcher for the "Font" slot/feature.
                // Sadly, the semantics of the dispatches is that the feature "Font" depends
                // on the current cursor position: If it's on latin text, it's the "latin font"
                // which is set up at the control. If it's on CJK text, it's the "CJK font", and
                // aequivalent for "CTL font".
                // The same holds for some other font related features/slots.
                // Thus, we have separate dispatches for "Latin Font", "Latin Font Size", etc,
                // which are only "virtual", in a sense that there exist no item with this id.
                // So when we encounter such a dispatcher for, say, "Latin Font", we need to
                // put an item into the set which has the "Font" id.

                switch ( nSlotId )
                {
                case SID_ATTR_CHAR_LATIN_FONT:      nSlotId = SID_ATTR_CHAR_FONT; break;
                case SID_ATTR_CHAR_LATIN_FONTHEIGHT:nSlotId = SID_ATTR_CHAR_FONTHEIGHT; break;
                case SID_ATTR_CHAR_LATIN_LANGUAGE:  nSlotId = SID_ATTR_CHAR_LANGUAGE; break;
                case SID_ATTR_CHAR_LATIN_POSTURE:   nSlotId = SID_ATTR_CHAR_POSTURE; break;
                case SID_ATTR_CHAR_LATIN_WEIGHT:    nSlotId = SID_ATTR_CHAR_WEIGHT; break;
                }
            }

            WhichId nWhich = rPool.GetWhich( nSlotId );
            bool bIsInPool = rPool.IsInRange( nWhich );
            if ( bIsInPool )
            {
                #if OSL_DEBUG_LEVEL > 0
                    bool bFeatureIsEnabled = aFeature->second->isFeatureEnabled();
                    ::rtl::OString sMessage( "FmTextControlShell::transferFeatureStatesToItemSet: found a feature state for " );
                    sMessage += sUnoSlotNameAscii;
                    if ( !bFeatureIsEnabled )
                        sMessage += " (disabled)";
                    DBG_TRACE( sMessage );
                #endif

                lcl_translateUnoStateToItem( nSlotId, aFeature->second->getFeatureState(), _rSet );
            }
            #if OSL_DEBUG_LEVEL > 0
            else
            {
                ::rtl::OString sMessage( "FmTextControlShell::transferFeatureStatesToItemSet: found a feature state for " );
                sMessage += sUnoSlotNameAscii;
                sMessage += ", but could not translate it into an item!";
                DBG_TRACE( sMessage );
            }
            #endif
        }
    }

    //------------------------------------------------------------------------
    void FmTextControlShell::executeAttributeDialog( AttributeSet _eSet, SfxRequest& _rReq )
    {
        const SvxFontListItem* pFontList = PTR_CAST( SvxFontListItem, m_pViewFrame->GetObjectShell()->GetItem( SID_ATTR_CHAR_FONTLIST ) );
        DBG_ASSERT( pFontList, "FmTextControlShell::executeAttributeDialog: no font list item!" );
        if ( !pFontList )
            return;

        SfxItemPool* pPool = EditEngine::CreatePool();
        pPool->FreezeIdRanges();
        ::std::auto_ptr< SfxItemSet > pPureItems( new SfxItemSet( *pPool ) );

        // put the current states of the items into the set
        ::std::auto_ptr< SfxAllItemSet > pCurrentItems( new SfxAllItemSet( *pPureItems ) );
        transferFeatureStatesToItemSet( m_aControlFeatures, *pCurrentItems );

        // additional items, which we are not responsible for at the SfxShell level,
        // but which need to be forwarded to the dialog, anyway
        ControlFeatures aAdditionalFestures;
        fillFeatureDispatchers( m_xActiveControl, pDialogSlots, aAdditionalFestures );
        transferFeatureStatesToItemSet( aAdditionalFestures, *pCurrentItems, true );

        ::std::auto_ptr< SfxTabDialog > pDialog ( _eSet == eCharAttribs
                                                ? static_cast< SfxTabDialog* >( new TextControlCharAttribDialog( NULL, *pCurrentItems, *pFontList ) )
                                                : static_cast< SfxTabDialog* >( new TextControlParaAttribDialog( NULL, *pCurrentItems ) ) );
        if ( RET_OK == pDialog->Execute() )
        {
            const SfxItemSet& rModifiedItems = *pDialog->GetOutputItemSet();
            for ( WhichId nWhich = pPool->GetFirstWhich(); nWhich <= pPool->GetLastWhich(); ++nWhich )
            {
                if ( rModifiedItems.GetItemState( nWhich ) == SFX_ITEM_SET )
                {
                    SfxSlotId nSlotForItemSet = pPool->GetSlotId( nWhich );
                    const SfxPoolItem* pModifiedItem = rModifiedItems.GetItem( nWhich );


                    SfxSlotId nSlotForDispatcher = nSlotForItemSet;
                    switch ( nSlotForDispatcher )
                    {
                        case SID_ATTR_CHAR_FONT:      nSlotForDispatcher = SID_ATTR_CHAR_LATIN_FONT; break;
                        case SID_ATTR_CHAR_FONTHEIGHT:nSlotForDispatcher = SID_ATTR_CHAR_LATIN_FONTHEIGHT; break;
                        case SID_ATTR_CHAR_LANGUAGE:  nSlotForDispatcher = SID_ATTR_CHAR_LATIN_LANGUAGE; break;
                        case SID_ATTR_CHAR_POSTURE:   nSlotForDispatcher = SID_ATTR_CHAR_LATIN_POSTURE; break;
                        case SID_ATTR_CHAR_WEIGHT:    nSlotForDispatcher = SID_ATTR_CHAR_LATIN_WEIGHT; break;
                    }

                    // do we already have a dispatcher for this slot/feature?
                    ControlFeatures::const_iterator aFeaturePos = m_aControlFeatures.find( nSlotForDispatcher );
                    bool bFound = aFeaturePos != m_aControlFeatures.end( );

                    if ( !bFound )
                    {
                        aFeaturePos = aAdditionalFestures.find( nSlotForDispatcher );
                        bFound = aFeaturePos != aAdditionalFestures.end( );
                    }

                    if ( bFound )
                    {
                        Sequence< PropertyValue > aArgs;
                        // temporarily put the modified item into a "clean" set,
                        // and let TransformItems calc the respective UNO parameters
                        pPureItems->Put( *pModifiedItem );
                        TransformItems( nSlotForItemSet, *pPureItems, aArgs );
                        pPureItems->ClearItem( nWhich );

                        if  (   ( nSlotForItemSet == SID_ATTR_PARA_HANGPUNCTUATION )
                            ||  ( nSlotForItemSet == SID_ATTR_PARA_FORBIDDEN_RULES )
                            ||  ( nSlotForItemSet == SID_ATTR_PARA_SCRIPTSPACE )
                            )
                        {
                            // these are no UNO slots, they need special handling since TransformItems cannot
                            // handle them
                            DBG_ASSERT( aArgs.getLength() == 0, "FmTextControlShell::executeAttributeDialog: these are no UNO slots - are they?" );

                            const SfxBoolItem* pBoolItem = PTR_CAST( SfxBoolItem, pModifiedItem );
                            DBG_ASSERT( pBoolItem, "FmTextControlShell::executeAttributeDialog: no bool item?!" );
                            if ( pBoolItem )
                            {
                                aArgs.realloc( 1 );
                                aArgs[ 0 ].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Enable" ) );
                                aArgs[ 0 ].Value <<= (sal_Bool)pBoolItem->GetValue();
                            }
                        }

                        // dispatch this
                        aFeaturePos->second->dispatch( aArgs );
                    }
                #if OSL_DEBUG_LEVEL > 0
                    else
                    {
                        ::rtl::OString sError( "FmTextControShell::executeAttributeDialog: Could not handle the following item:" );
                        sError += "\n  SlotID: "; sError += ::rtl::OString::valueOf( (sal_Int32)nSlotForItemSet );
                        sError += "\n  WhichID: "; sError += ::rtl::OString::valueOf( (sal_Int32)nWhich );
                        sError += "\n  UNO name: ";

                        ::rtl::OUString sUnoSlotName = lcl_getUnoSlotName( *SFX_APP(), nSlotForItemSet );
                        if ( sUnoSlotName.getLength() )
                            sError += ::rtl::OString( sUnoSlotName.getStr(), sUnoSlotName.getLength(), RTL_TEXTENCODING_ASCII_US );
                        else
                            sError += "unknown (no SfxSlot)";
                        DBG_ERROR( sError.getStr() );
                    }
                #endif
                }
            }
            _rReq.Done( rModifiedItems );
        }

        pDialog.reset();
        pCurrentItems.reset();
        pPureItems.reset();
        SfxItemPool::Free(pPool);
    }

    //------------------------------------------------------------------------
    bool FmTextControlShell::executeSelectAll( )
    {
        try
        {
            if ( m_xActiveTextComponent.is() )
            {
                sal_Int32 nTextLen = m_xActiveTextComponent->getText().getLength();
                m_xActiveTextComponent->setSelection( awt::Selection( 0, nTextLen ) );
                return true;
            }
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
        return false;   // not handled
    }

    //------------------------------------------------------------------------
    bool FmTextControlShell::executeClipboardSlot( SfxSlotId _nSlot )
    {
        try
        {
            if ( m_xActiveTextComponent.is() )
            {
                switch ( _nSlot )
                {
                case SID_COPY:
                case SID_CUT:
                {
                    ::rtl::OUString sSelectedText( m_xActiveTextComponent->getSelectedText() );
                    ::svt::OStringTransfer::CopyString( sSelectedText, lcl_getWindow( m_xActiveControl ) );
                    if ( SID_CUT == _nSlot )
                    {
                        awt::Selection aSelection( m_xActiveTextComponent->getSelection() );
                        m_xActiveTextComponent->insertText( aSelection, ::rtl::OUString() );
                    }
                }
                break;
                case SID_PASTE:
                {
                    ::rtl::OUString sClipboardContent;
                    OSL_VERIFY( ::svt::OStringTransfer::PasteString( sClipboardContent, lcl_getWindow( m_xActiveControl ) ) );
                    awt::Selection aSelection( m_xActiveTextComponent->getSelection() );
                    m_xActiveTextComponent->insertText( aSelection, sClipboardContent );
                }
                break;
                default:
                    OSL_ENSURE( sal_False, "FmTextControlShell::executeClipboardSlot: invalid slot!" );
                }
                return true;
            }
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
        return false;   // not handled
    }

    //------------------------------------------------------------------------
    void FmTextControlShell::ExecuteTextAttribute( SfxRequest& _rReq )
    {
	    SfxSlotId nSlot = _rReq.GetSlot();

        ControlFeatures::const_iterator aFeaturePos = m_aControlFeatures.find( nSlot );
        if ( aFeaturePos == m_aControlFeatures.end() )
        {
            // special slots
            switch ( nSlot )
            {
            case SID_CHAR_DLG:
                executeAttributeDialog( eCharAttribs, _rReq );
                break;

            case SID_PARA_DLG:
                executeAttributeDialog( eParaAttribs, _rReq );
                break;
            
            case SID_SELECTALL:
                executeSelectAll();
                break;

            case SID_CUT:
            case SID_COPY:
            case SID_PASTE:
                executeClipboardSlot( nSlot );
                break;

            default:
                DBG_ASSERT( aFeaturePos != m_aControlFeatures.end(), "FmTextControShell::ExecuteTextAttribute: I have no such dispatcher, and cannot handle it at all!" );
                return;
            }
        }
        else
        {
            // slots which are dispatched to the control

            switch ( nSlot )
            {
            case SID_ATTR_CHAR_STRIKEOUT:
            case SID_ATTR_CHAR_UNDERLINE:
            case SID_ATTR_CHAR_OVERLINE:
            {
                SfxItemSet aToggled( *_rReq.GetArgs() );

                lcl_translateUnoStateToItem( nSlot, aFeaturePos->second->getFeatureState(), aToggled );
                WhichId nWhich = aToggled.GetPool()->GetWhich( nSlot );
                const SfxPoolItem* pItem = aToggled.GetItem( nWhich );
                if ( ( SID_ATTR_CHAR_UNDERLINE == nSlot ) || ( SID_ATTR_CHAR_OVERLINE == nSlot ) )
                {
                    const SvxOverlineItem* pTextLine = PTR_CAST( SvxOverlineItem, pItem );
                    DBG_ASSERT( pTextLine, "FmTextControlShell::ExecuteTextAttribute: ooops - no underline/overline item!" );
                    if ( pTextLine )
                    {
            		    FontUnderline eTL = pTextLine->GetLineStyle();
						if ( SID_ATTR_CHAR_UNDERLINE == nSlot ) {
	            		    aToggled.Put( SvxUnderlineItem( eTL == UNDERLINE_SINGLE ? UNDERLINE_NONE : UNDERLINE_SINGLE, nWhich ) );
						} else {
	            		    aToggled.Put( SvxOverlineItem( eTL == UNDERLINE_SINGLE ? UNDERLINE_NONE : UNDERLINE_SINGLE, nWhich ) );
						}
                    }
                }
                else
                {
                    const SvxCrossedOutItem* pCrossedOut = PTR_CAST( SvxCrossedOutItem, pItem );
                    DBG_ASSERT( pCrossedOut, "FmTextControlShell::ExecuteTextAttribute: ooops - no CrossedOut item!" );
                    if ( pCrossedOut )
                    {
            		    FontStrikeout eFS = pCrossedOut->GetStrikeout();
            		    aToggled.Put( SvxCrossedOutItem( eFS == STRIKEOUT_SINGLE ? STRIKEOUT_NONE : STRIKEOUT_SINGLE, nWhich ) );
                    }
                }

                Sequence< PropertyValue > aArguments;
                TransformItems( nSlot, aToggled, aArguments );
                aFeaturePos->second->dispatch( aArguments );
            }
            break;

            case SID_ATTR_CHAR_FONTHEIGHT:
            case SID_ATTR_CHAR_FONT:
            case SID_ATTR_CHAR_POSTURE:
            case SID_ATTR_CHAR_WEIGHT:
            case SID_ATTR_CHAR_SHADOWED:
            case SID_ATTR_CHAR_CONTOUR:
            case SID_SET_SUPER_SCRIPT:
            case SID_SET_SUB_SCRIPT:
            {
                const SfxItemSet* pArgs = _rReq.GetArgs();
                Sequence< PropertyValue > aArgs;
                if ( pArgs )
                    TransformItems( nSlot, *pArgs, aArgs );
                aFeaturePos->second->dispatch( aArgs );
            }
            break;

            default:
                if ( aFeaturePos->second->isFeatureEnabled() )
                    aFeaturePos->second->dispatch();
                break;
            }
        }
        _rReq.Done();
    }

    //------------------------------------------------------------------------
    void FmTextControlShell::GetTextAttributeState( SfxItemSet& _rSet )
    {
	    SfxWhichIter aIter( _rSet );
	    sal_uInt16 nSlot = aIter.FirstWhich();
	    while ( nSlot )
	    {
            if  (   ( nSlot == SID_ATTR_PARA_LEFT_TO_RIGHT )
                ||  ( nSlot == SID_ATTR_PARA_RIGHT_TO_LEFT )
                )
            {
                if ( !SvtLanguageOptions().IsCTLFontEnabled() )
                {
                    _rSet.DisableItem( nSlot );
                    nSlot = aIter.NextWhich();
                    continue;
                }
            }

            ControlFeatures::const_iterator aFeaturePos = m_aControlFeatures.find( nSlot );
            if ( aFeaturePos != m_aControlFeatures.end() )
            {
                if ( aFeaturePos->second->isFeatureEnabled() )
                    lcl_translateUnoStateToItem( nSlot, aFeaturePos->second->getFeatureState(), _rSet );
                else
                    _rSet.DisableItem( nSlot );
            }
            else
            {
                bool bDisable = false;

                bool bNeedWriteableControl = false;
                bool bNeedTextComponent = false;
                bool bNeedSelection = false;

                switch ( nSlot )
                {
                case SID_CHAR_DLG:
                case SID_PARA_DLG:
                    bDisable |= m_aControlFeatures.empty();
                    bNeedWriteableControl = true;
                    break;

                case SID_CUT:
                    bNeedSelection = true;
                    bNeedTextComponent = true;
                    bNeedWriteableControl = true;
                    DBG_TRACE( "FmTextControlShell::ClipBoard: need to invalidate again" );
                    m_bNeedClipboardInvalidation = true;
                    break;

                case SID_PASTE:
                {
                    Window* pActiveControlVCLWindow = lcl_getWindow( m_xActiveControl );
                    if ( pActiveControlVCLWindow )
                    {
		                TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pActiveControlVCLWindow) );
                        bDisable |= !aDataHelper.HasFormat( SOT_FORMAT_STRING );
                    }
                    else
                        bDisable |= true;

                    bNeedTextComponent = true;
                    bNeedWriteableControl = true;
                }
                break;

                case SID_COPY:
                    bNeedTextComponent = true;
                    bNeedSelection = true;
                    break;

                case SID_SELECTALL:
                    bNeedTextComponent = true;
                    break;

                default:
                    // slot is unknown at all
                    bDisable |= true;
                    break;
                }
                OSL_POSTCOND( !bNeedSelection || bNeedTextComponent, "FmTextControlShell::GetTextAttributeState: bNeedSelection should imply bNeedTextComponent!" );

                if ( !bDisable && bNeedWriteableControl )
                    bDisable |= !IsActiveControl( ) || m_bActiveControlIsReadOnly;

                if ( !bDisable && bNeedTextComponent )
                    bDisable |= !m_xActiveTextComponent.is();

                if ( !bDisable && bNeedSelection )
                {
                    awt::Selection aSelection = m_xActiveTextComponent->getSelection();
                    bDisable |= aSelection.Min == aSelection.Max;
                }

                if ( bDisable )
                    _rSet.DisableItem( nSlot );
            }

            nSlot = aIter.NextWhich();
	    }
    }

    //------------------------------------------------------------------------
    bool FmTextControlShell::IsActiveControl( bool _bCountRichTextOnly ) const
    {
        if ( _bCountRichTextOnly && !m_bActiveControlIsRichText )
            return false;

        return m_bActiveControl;
    }

    //------------------------------------------------------------------------
    void FmTextControlShell::dispose()
    {
        if ( IsActiveControl() )
            controlDeactivated();
        if ( isControllerListening() )
            stopControllerListening();
    }

    //------------------------------------------------------------------------
    void FmTextControlShell::designModeChanged( bool /*_bNewDesignMode*/ )
    {
        m_rBindings.Invalidate( pTextControlSlots );
    }

    //------------------------------------------------------------------------
    void FmTextControlShell::formActivated( const Reference< XFormController >& _rxController )
    {
#if OSL_DEBUG_LEVEL > 0
        ::rtl::OString sTrace( "FmTextControlShell::formActivated: 0x" );
        sTrace += ::rtl::OString::valueOf( (sal_IntPtr)_rxController.get(), 16 );
        DBG_TRACE( sTrace );
#endif

        DBG_ASSERT( _rxController.is(), "FmTextControlShell::formActivated: invalid controller!" );
        if ( !_rxController.is() )
            return;

        // sometimes, a form controller notifies activations, even if it's already activated
        if ( m_xActiveController == _rxController )
            return;

        try
        {
            startControllerListening( _rxController );
            controlActivated( _rxController->getCurrentControl() );
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
    }

    //------------------------------------------------------------------------
    void FmTextControlShell::formDeactivated( const Reference< XFormController >& _rxController )
    {
#if OSL_DEBUG_LEVEL > 0
        ::rtl::OString sTrace( "FmTextControlShell::formDeactivated: 0x" );
        sTrace += ::rtl::OString::valueOf( (sal_IntPtr)_rxController.get(), 16 );
        DBG_TRACE( sTrace );
#endif
        (void)_rxController;

        if ( IsActiveControl() )
            controlDeactivated();
        if ( isControllerListening() )
            stopControllerListening();
    }

    //------------------------------------------------------------------------
    void FmTextControlShell::startControllerListening( const Reference< XFormController >& _rxController )
    {
        OSL_PRECOND( _rxController.is(), "FmTextControlShell::startControllerListening: invalid controller!" );
        if ( !_rxController.is() )
            return;

        OSL_PRECOND( !isControllerListening(), "FmTextControlShell::startControllerListening: already listening!" );
        if ( isControllerListening() )
            stopControllerListening( );
        DBG_ASSERT( !isControllerListening(), "FmTextControlShell::startControllerListening: inconsistence!" );

        try
        {
            Sequence< Reference< XControl > > aControls( _rxController->getControls() );
            m_aControlObservers.resize( 0 );
            m_aControlObservers.reserve( aControls.getLength() );

            const Reference< XControl >* pControls = aControls.getConstArray();
            const Reference< XControl >* pControlsEnd = pControls + aControls.getLength();
            for ( ; pControls != pControlsEnd; ++pControls )
            {
                m_aControlObservers.push_back( FocusListenerAdapter( new FmFocusListenerAdapter( *pControls, this ) ) );
            }
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }

        m_xActiveController = _rxController;
    }

    //------------------------------------------------------------------------
    void FmTextControlShell::stopControllerListening( )
    {
        OSL_PRECOND( isControllerListening(), "FmTextControlShell::stopControllerListening: inconsistence!" );

        // dispose all listeners associated with the controls of the active controller
        for (   FocusListenerAdapters::iterator aLoop = m_aControlObservers.begin();
                aLoop != m_aControlObservers.end();
                ++aLoop
            )
        {
            (*aLoop)->dispose();
        }

        FocusListenerAdapters aEmpty;
        m_aControlObservers.swap( aEmpty );

        m_xActiveController.clear();
    }

    //------------------------------------------------------------------------
    void FmTextControlShell::implClearActiveControlRef()
    {
        // no more features for this control
        for (   ControlFeatures::iterator aLoop = m_aControlFeatures.begin();
                aLoop != m_aControlFeatures.end();
                ++aLoop
            )
        {
            aLoop->second->dispose();
        }

        ControlFeatures aEmpty;
        m_aControlFeatures.swap( aEmpty );

        if ( m_aContextMenuObserver.get() )
        {
            m_aContextMenuObserver->dispose();
            m_aContextMenuObserver = MouseListenerAdapter();
        }

        if ( m_xActiveTextComponent.is() )
        {
            DBG_TRACE( "FmTextControlShell::ClipBoard: stopping timer for clipboard invalidation" );
            m_aClipboardInvalidation.Stop();
        }
        // no more active control
        m_xActiveControl.clear();
        m_xActiveTextComponent.clear();
        m_bActiveControlIsReadOnly = true;
        m_bActiveControlIsRichText = false;
        m_bActiveControl = false;
    }

    //------------------------------------------------------------------------
    void FmTextControlShell::controlDeactivated( )
    {
        DBG_ASSERT( IsActiveControl(), "FmTextControlShell::controlDeactivated: no active control!" );

        m_bActiveControl = false;

        m_rBindings.Invalidate( pTextControlSlots );
    }

    //------------------------------------------------------------------------
    void FmTextControlShell::controlActivated( const Reference< XControl >& _rxControl )
    {
        // ensure that all knittings with the previously active control are lost
        if ( m_xActiveControl.is() )
            implClearActiveControlRef();
        DBG_ASSERT( m_aControlFeatures.empty(), "FmTextControlShell::controlActivated: should have no dispatchers when I'm here!" );

#if OSL_DEBUG_LEVEL > 0
        {
            Sequence< Reference< XControl > > aActiveControls;
            if ( m_xActiveController.is() )
                aActiveControls = m_xActiveController->getControls();

            bool bFoundThisControl = false;

            const Reference< XControl >* pControls = aActiveControls.getConstArray();
            const Reference< XControl >* pControlsEnd = pControls + aActiveControls.getLength();
            for ( ; ( pControls != pControlsEnd ) && !bFoundThisControl; ++pControls )
            {
                if ( *pControls == _rxControl )
                    bFoundThisControl = true;
            }
            DBG_ASSERT( bFoundThisControl, "FmTextControlShell::controlActivated: only controls which belong to the active controller can be activated!" );
        }
#endif
        // ask the control for dispatchers for our text-related slots
        fillFeatureDispatchers( _rxControl, pTextControlSlots, m_aControlFeatures );

        // remember this control
        m_xActiveControl = _rxControl;
        m_xActiveTextComponent = m_xActiveTextComponent.query( _rxControl );
        m_bActiveControlIsReadOnly = lcl_determineReadOnly( m_xActiveControl );
        m_bActiveControlIsRichText = lcl_isRichText( m_xActiveControl );

        // if we found a rich text control, we need context menu support
        if ( m_bActiveControlIsRichText )
        {
            DBG_ASSERT( NULL == m_aContextMenuObserver.get(), "FmTextControlShell::controlActivated: already have an observer!" );
            m_aContextMenuObserver = MouseListenerAdapter( new FmMouseListenerAdapter( _rxControl, this ) );
        }

        if ( m_xActiveTextComponent.is() )
        {
            DBG_TRACE( "FmTextControlShell::ClipBoard: starting timer for clipboard invalidation" );
            m_aClipboardInvalidation.Start();
        }

        m_bActiveControl = true;

    	m_rBindings.Invalidate( pTextControlSlots );

        if ( m_pViewFrame )
            m_pViewFrame->UIFeatureChanged();

        // don't call the activation handler if we don't have any slots we can serve
        // The activation handler is used to put the shell on the top of the dispatcher stack,
        // so it's preferred when slots are distributed.
        // Note that this is a slight hack, to prevent that we grab slots from the SfxDispatcher
        // which should be served by other shells (e.g. Cut/Copy/Paste).
        // A real solution would be a forwarding-mechanism for slots: We should be on the top
        // if we're active, but if we cannot handle the slot, then we need to tell the dispatcher
        // to skip our shell, and pass the slot to the next one. However, this mechanism is not
        // not in place in SFX.
        // Another possibility would be to have dedicated shells for the slots which we might
        // or might not be able to serve. However, this could probably increase the number of
        // shells too much (In theory, nearly every slot could have an own shell then).
        //
        // #i51621# / 2005-08-19 / frank.schoenheit@sun.com
        bool bHaveAnyServeableSlots = m_xActiveTextComponent.is() || !m_aControlFeatures.empty();
        if ( m_aControlActivationHandler.IsSet() && bHaveAnyServeableSlots )
            m_aControlActivationHandler.Call( NULL );

        m_bNeedClipboardInvalidation = true;
    }

    //------------------------------------------------------------------------
    void FmTextControlShell::fillFeatureDispatchers(  const Reference< XControl > _rxControl, SfxSlotId* _pZeroTerminatedSlots,
            ControlFeatures& _rDispatchers )
    {
        Reference< XDispatchProvider > xProvider( _rxControl, UNO_QUERY );
        SfxApplication* pApplication = SFX_APP();
        DBG_ASSERT( pApplication, "FmTextControlShell::fillFeatureDispatchers: no SfxApplication!" );
        if ( xProvider.is() && pApplication )
        {
            SfxSlotId* pSlots = _pZeroTerminatedSlots;
            while ( *pSlots )
            {
                FmTextControlFeature* pDispatcher = implGetFeatureDispatcher( xProvider, pApplication, *pSlots );
                if ( pDispatcher )
                    _rDispatchers.insert( ControlFeatures::value_type( *pSlots, ControlFeature( pDispatcher ) ) );

                ++pSlots;
            }
        }
    }

    //------------------------------------------------------------------------
    void FmTextControlShell::impl_parseURL_nothrow( URL& _rURL )
    {
        try
        {
            if ( !m_xURLTransformer.is() )
            {
                ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
                aContext.createComponent( "com.sun.star.util.URLTransformer", m_xURLTransformer );
            }
            if ( m_xURLTransformer.is() )
                m_xURLTransformer->parseStrict( _rURL );
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
    }

    //------------------------------------------------------------------------
    FmTextControlFeature* FmTextControlShell::implGetFeatureDispatcher( const Reference< XDispatchProvider >& _rxProvider, SfxApplication* _pApplication, SfxSlotId _nSlot )
    {
        OSL_PRECOND( _rxProvider.is() && _pApplication, "FmTextControlShell::implGetFeatureDispatcher: invalid arg(s)!" );
        URL aFeatureURL;
        aFeatureURL.Complete = lcl_getUnoSlotName( *_pApplication, _nSlot );
        impl_parseURL_nothrow( aFeatureURL );
        Reference< XDispatch > xDispatcher = _rxProvider->queryDispatch( aFeatureURL, ::rtl::OUString(), 0xFF );
        if ( xDispatcher.is() )
            return new FmTextControlFeature( xDispatcher, aFeatureURL, _nSlot, this );
        return NULL;
    }

    //------------------------------------------------------------------------
    void FmTextControlShell::Invalidate( SfxSlotId _nSlot )
    {
    	m_rBindings.Invalidate( _nSlot );
        // despite this method being called "Invalidate", we also update here - this gives more immediate
        // feedback in the UI
    	m_rBindings.Update( _nSlot );
    }

    //------------------------------------------------------------------------
    void FmTextControlShell::focusGained( const ::com::sun::star::awt::FocusEvent& _rEvent )
    {
        Reference< XControl > xControl( _rEvent.Source, UNO_QUERY );

#if OSL_DEBUG_LEVEL > 0
        ::rtl::OString sTrace( "FmTextControlShell::focusGained: 0x" );
        sTrace += ::rtl::OString::valueOf( (sal_IntPtr)xControl.get(), 16 );
        DBG_TRACE( sTrace );
#endif

        DBG_ASSERT( xControl.is(), "FmTextControlShell::focusGained: suspicious focus event!" );
        if ( xControl.is() )
            controlActivated( xControl );
    }

    //------------------------------------------------------------------------
    void FmTextControlShell::focusLost( const ::com::sun::star::awt::FocusEvent& _rEvent )
    {
        Reference< XControl > xControl( _rEvent.Source, UNO_QUERY );

#if OSL_DEBUG_LEVEL > 0
        ::rtl::OString sTrace( "FmTextControlShell::focusLost: 0x" );
        sTrace += ::rtl::OString::valueOf( (sal_IntPtr)xControl.get(), 16 );
        DBG_TRACE( sTrace );
#endif

        m_bActiveControl = false;
    }

    //------------------------------------------------------------------------
    void FmTextControlShell::ForgetActiveControl()
    {
        implClearActiveControlRef();
    }

    //------------------------------------------------------------------------
    void FmTextControlShell::contextMenuRequested( const awt::MouseEvent& /*_rEvent*/ )
    {
        m_rBindings.GetDispatcher()->ExecutePopup( SVX_RES( RID_FM_TEXTATTRIBUTE_MENU ) );
    }

//........................................................................
} // namespace svx
//........................................................................
