/**************************************************************
 *
 * 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_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 *definitely* 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 );

        {
            sal_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 useful 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(), sal_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 )
    {
        sal_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 definitely 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, sal_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(), sal_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
//........................................................................
