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



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

#include <eeng_pch.hxx>

#include <impedit.hxx>
#include <editeng/editeng.hxx>
#include <editeng/editview.hxx>
#include <tools/poly.hxx>
#include <editeng/unolingu.hxx>
#include <com/sun/star/linguistic2/XDictionaryEntry.hpp>
#include <com/sun/star/linguistic2/DictionaryType.hpp>
#include <com/sun/star/linguistic2/DictionaryEvent.hpp>
#include <com/sun/star/linguistic2/XDictionaryEventListener.hpp>
#include <com/sun/star/linguistic2/DictionaryEventFlags.hpp>
#include <com/sun/star/linguistic2/XDictionary.hpp>
#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
#include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp>
#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
#include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
#include <vos/mutex.hxx>
#include <editeng/flditem.hxx>
#include <svl/intitem.hxx>
#include <svtools/transfer.hxx>
#include <sot/exchange.hxx>
#include <sot/formats.hxx>

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::linguistic2;

#define SCRLRANGE	20		// 1/20 der Breite/Hoehe scrollen, wenn im QueryDrop

inline void lcl_AllignToPixel( Point& rPoint, OutputDevice* pOutDev, short nDiffX, short nDiffY )
{
	rPoint = pOutDev->LogicToPixel( rPoint );

	if ( nDiffX )
		rPoint.X() += nDiffX;
	if ( nDiffY )
		rPoint.Y() += nDiffY;

	rPoint = pOutDev->PixelToLogic( rPoint );
}

//	----------------------------------------------------------------------
//	class ImpEditView
//	----------------------------------------------------------------------
ImpEditView::ImpEditView( EditView* pView, EditEngine* pEng, Window* pWindow ) :
	aOutArea( Point(), pEng->GetPaperSize() )
{
    pEditView           = pView;
	pEditEngine			= pEng;
	pOutWin 			= pWindow;
	pPointer			= NULL;
	pBackgroundColor	= NULL;
	nScrollDiffX		= 0;
    nExtraCursorFlags   = 0;
    nCursorBidiLevel    = CURSOR_BIDILEVEL_DONTKNOW;
	pCursor				= NULL;
   	pDragAndDropInfo	= NULL;
	bReadOnly			= sal_False;
    bClickedInSelection = sal_False;
	eSelectionMode		= EE_SELMODE_TXTONLY;
	eAnchorMode			= ANCHOR_TOP_LEFT;
	nInvMore			= 1;
	nTravelXPos			= TRAVEL_X_DONTKNOW;
	nControl 			= EV_CNTRL_AUTOSCROLL | EV_CNTRL_ENABLEPASTE;
    bActiveDragAndDropListener = sal_False;

	aEditSelection.Min() = pEng->pImpEditEngine->GetEditDoc().GetStartPaM();
	aEditSelection.Max() = pEng->pImpEditEngine->GetEditDoc().GetEndPaM();
}

ImpEditView::~ImpEditView()
{
    RemoveDragAndDropListeners();

    if ( pOutWin && ( pOutWin->GetCursor() == pCursor ) )
		pOutWin->SetCursor( NULL );

	delete pCursor;
	delete pBackgroundColor;
	delete pPointer;
	delete pDragAndDropInfo;
}

void ImpEditView::SetBackgroundColor( const Color& rColor )
{
	delete pBackgroundColor;
	pBackgroundColor = new Color( rColor );
}

void ImpEditView::SetEditSelection( const EditSelection& rEditSelection )
{
	// #100856# set state before notification
    aEditSelection = rEditSelection;

    if ( pEditEngine->pImpEditEngine->GetNotifyHdl().IsSet() )
    {
		const EditDoc& rDoc = pEditEngine->pImpEditEngine->GetEditDoc();
		const EditPaM pmEnd = rDoc.GetEndPaM();
		EENotifyType eNotifyType;
		if (rDoc.Count() > 1 && 
			pmEnd == rEditSelection.Min() && 
			pmEnd == rEditSelection.Max())//if move cursor to the last para.
		{
			eNotifyType = EE_NOTIFY_TEXTVIEWSELECTIONCHANGED_ENDD_PARA;
		}
		else 
		{
			eNotifyType = EE_NOTIFY_TEXTVIEWSELECTIONCHANGED;
		}
        //EENotify aNotify( EE_NOTIFY_TEXTVIEWSELECTIONCHANGED );
        EENotify aNotify( eNotifyType );
        aNotify.pEditEngine = pEditEngine;
        aNotify.pEditView = GetEditViewPtr();
        pEditEngine->pImpEditEngine->CallNotify( aNotify );
    }
}


void ImpEditView::DrawSelection( EditSelection aTmpSel, Region* pRegion, OutputDevice* pTargetDevice )
{
    if ( GetSelectionMode() == EE_SELMODE_HIDDEN )
        return;

	// Vor dem Zeichnen der Selektion muss sichergestellt werden,
	// das der Fensterinhalt komplett gueltig ist!
	// Muss hier stehen, damit auf jeden Fall weg wenn lerr, nicht spaeter
	// zwei Paint-Events!
	// 19.10: Muss sogar vor Abfrage von bUpdate, falls nach Invalidate
	// noch Paints in der Queue, aber jemand schaltet den UpdateMode um!
	// pRegion: Wenn nicht NULL, dann nur Region berechnen.
	PolyPolygon* pPolyPoly = NULL;
	if ( pRegion )
		pPolyPoly = new PolyPolygon;

	OutputDevice* pTarget = pTargetDevice ? pTargetDevice : pOutWin;
	sal_Bool bClipRegion = pTarget->IsClipRegion();
	Region aOldRegion = pTarget->GetClipRegion();

	if ( !pRegion )
	{
		if ( pEditEngine->pImpEditEngine->GetUpdateMode() == sal_False )
			return;
		if ( pEditEngine->pImpEditEngine->IsInUndo() )
			return;

		if ( !aTmpSel.HasRange() )
			return;

	    // aTmpOutArea: Falls OutputArea > Papierbreite und
	    // Text > Papierbreite ( uebergrosse Felder )
	    Rectangle aTmpOutArea( aOutArea );
	    if ( aTmpOutArea.GetWidth() > pEditEngine->pImpEditEngine->GetPaperSize().Width() )
		    aTmpOutArea.Right() = aTmpOutArea.Left() + pEditEngine->pImpEditEngine->GetPaperSize().Width();
		pTarget->IntersectClipRegion( aTmpOutArea );

		if ( pOutWin->GetCursor() )
			pOutWin->GetCursor()->Hide();
	}

	DBG_ASSERT( !pEditEngine->pImpEditEngine->aIdleFormatter.IsActive(), "DrawSelection: Not formatted!" );
	aTmpSel.Adjust( pEditEngine->pImpEditEngine->GetEditDoc() );

	ContentNode* pStartNode = aTmpSel.Min().GetNode();
	ContentNode* pEndNode = aTmpSel.Max().GetNode();
	sal_uInt16 nStartPara = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( pStartNode );
	sal_uInt16 nEndPara = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( pEndNode );
	// ueber die Absaetze iterieren....
	for ( sal_uInt16 nPara = nStartPara; nPara <= nEndPara; nPara++ )
	{
		ParaPortion* pTmpPortion = pEditEngine->pImpEditEngine->GetParaPortions().SaveGetObject( nPara );
		DBG_ASSERT( pTmpPortion, "Portion in Selektion nicht gefunden!" );
		DBG_ASSERT( !pTmpPortion->IsInvalid(), "Portion in Selektion nicht formatiert!" );

		if ( !pTmpPortion->IsVisible() || pTmpPortion->IsInvalid() )
			continue;

		long nParaStart = pEditEngine->pImpEditEngine->GetParaPortions().GetYOffset( pTmpPortion );
		if ( ( nParaStart + pTmpPortion->GetHeight() ) < GetVisDocTop() )
			continue;
		if ( nParaStart > GetVisDocBottom() )
			break;

		sal_uInt16 nStartLine = 0;
		sal_uInt16 nEndLine = pTmpPortion->GetLines().Count() -1;
		if ( nPara == nStartPara )
			nStartLine = pTmpPortion->GetLines().FindLine( aTmpSel.Min().GetIndex(), sal_False );
		if ( nPara == nEndPara )
			nEndLine = pTmpPortion->GetLines().FindLine( aTmpSel.Max().GetIndex(), sal_True );

		// ueber die Zeilen iterieren....
		for ( sal_uInt16 nLine = nStartLine; nLine <= nEndLine; nLine++ )
		{
			EditLine* pLine = pTmpPortion->GetLines().GetObject( nLine );
			DBG_ASSERT( pLine, "Zeile nicht gefunden: DrawSelection()" );

            sal_Bool bPartOfLine = sal_False;
			sal_uInt16 nStartIndex = pLine->GetStart();
			sal_uInt16 nEndIndex = pLine->GetEnd();
			if ( ( nPara == nStartPara ) && ( nLine == nStartLine ) && ( nStartIndex != aTmpSel.Min().GetIndex() ) )
            {
				nStartIndex = aTmpSel.Min().GetIndex();
                bPartOfLine = sal_True;
            }
			if ( ( nPara == nEndPara ) && ( nLine == nEndLine ) && ( nEndIndex != aTmpSel.Max().GetIndex() ) )
            {
				nEndIndex = aTmpSel.Max().GetIndex();
                bPartOfLine = sal_True;
            }

			// Kann passieren, wenn am Anfang einer umgebrochenen Zeile.
			if ( nEndIndex < nStartIndex )
				nEndIndex = nStartIndex;

			Rectangle aTmpRec( pEditEngine->pImpEditEngine->GetEditCursor( pTmpPortion, nStartIndex ) );
			Point aTopLeft( aTmpRec.TopLeft() );
			Point aBottomRight( aTmpRec.BottomRight() );

            aTopLeft.Y() += nParaStart;
			aBottomRight.Y() += nParaStart;

            // Nur Painten, wenn im sichtbaren Bereich...
			if ( aTopLeft.Y() > GetVisDocBottom() )
				break;

            if ( aBottomRight.Y() < GetVisDocTop() )
                continue;

            // Now that we have Bidi, the first/last index doesn't have to be the 'most outside' position
            if ( !bPartOfLine )
            {
                Range aLineXPosStartEnd = pEditEngine->pImpEditEngine->GetLineXPosStartEnd( pTmpPortion, pLine );
                aTopLeft.X() = aLineXPosStartEnd.Min();
                aBottomRight.X() = aLineXPosStartEnd.Max();
                ImplDrawHighlightRect( pTarget, aTopLeft, aBottomRight, pPolyPoly );
            }
            else
            {
                sal_uInt16 nTmpStartIndex = nStartIndex;
                sal_uInt16 nWritingDirStart, nTmpEndIndex;

                while ( nTmpStartIndex < nEndIndex )
                {
                    pEditEngine->pImpEditEngine->GetRightToLeft( nPara, nTmpStartIndex+1, &nWritingDirStart, &nTmpEndIndex );
                    if ( nTmpEndIndex > nEndIndex )
                        nTmpEndIndex = nEndIndex;

                    DBG_ASSERT( nTmpEndIndex > nTmpStartIndex, "DrawSelection, Start >= End?" );

                    long nX1 = pEditEngine->pImpEditEngine->GetXPos( pTmpPortion, pLine, nTmpStartIndex, sal_True );
                    long nX2 = pEditEngine->pImpEditEngine->GetXPos( pTmpPortion, pLine, nTmpEndIndex );

                    Point aPt1( Min( nX1, nX2 ), aTopLeft.Y() );
                    Point aPt2( Max( nX1, nX2 ), aBottomRight.Y() );

                    ImplDrawHighlightRect( pTarget, aPt1, aPt2, pPolyPoly );

                    nTmpStartIndex = nTmpEndIndex;
                }
            }

		}
	}

	if ( pRegion )
	{
		*pRegion = Region( *pPolyPoly );
		delete pPolyPoly;
	}
	else
	{
		if ( pOutWin->GetCursor() )
			pOutWin->GetCursor()->Show();

		if ( bClipRegion )
			pTarget->SetClipRegion( aOldRegion );
		else
			pTarget->SetClipRegion();
	}
}

void ImpEditView::ImplDrawHighlightRect( OutputDevice* _pTarget, const Point& rDocPosTopLeft, const Point& rDocPosBottomRight, PolyPolygon* pPolyPoly )
{
	if ( rDocPosTopLeft.X() != rDocPosBottomRight.X() )
	{
	    sal_Bool bPixelMode = _pTarget->GetMapMode() == MAP_PIXEL;

        Point aPnt1( GetWindowPos( rDocPosTopLeft ) );
		Point aPnt2( GetWindowPos( rDocPosBottomRight ) );

		if ( !IsVertical() )
		{
			lcl_AllignToPixel( aPnt1, _pTarget, +1, 0 );
			lcl_AllignToPixel( aPnt2, _pTarget, 0, ( bPixelMode ? 0 : -1 ) );
		}
		else
		{
			lcl_AllignToPixel( aPnt1, _pTarget, 0, +1 );
			lcl_AllignToPixel( aPnt2, _pTarget, ( bPixelMode ? 0 : +1 ), 0 );
		}

		Rectangle aRect( aPnt1, aPnt2 );
		if ( pPolyPoly )
		{
			Polygon aTmpPoly( 4 );
			aTmpPoly[0] = aRect.TopLeft();
			aTmpPoly[1] = aRect.TopRight();
			aTmpPoly[2] = aRect.BottomRight();
			aTmpPoly[3] = aRect.BottomLeft();
			pPolyPoly->Insert( aTmpPoly );
		}
		else
		{
			Window* pWindow = dynamic_cast< Window* >(_pTarget);

			if(pWindow)
			{
				pWindow->Invert( aRect );
			}
			else
			{
				_pTarget->Push(PUSH_LINECOLOR|PUSH_FILLCOLOR|PUSH_RASTEROP);
				_pTarget->SetLineColor();
				_pTarget->SetFillColor(COL_BLACK);
				_pTarget->SetRasterOp(ROP_INVERT);
				_pTarget->DrawRect(aRect);
				_pTarget->Pop();
			}
		}
	}
}


sal_Bool ImpEditView::IsVertical() const
{
	return pEditEngine->pImpEditEngine->IsVertical();
}

Rectangle ImpEditView::GetVisDocArea() const
{
	return Rectangle( GetVisDocLeft(), GetVisDocTop(), GetVisDocRight(), GetVisDocBottom() );
}

Point ImpEditView::GetDocPos( const Point& rWindowPos ) const
{
	// Fensterposition => Dokumentposition
	Point aPoint;

	if ( !pEditEngine->pImpEditEngine->IsVertical() )
	{
		aPoint.X() = rWindowPos.X() - aOutArea.Left() + GetVisDocLeft();
		aPoint.Y() = rWindowPos.Y() - aOutArea.Top() + GetVisDocTop();
	}
	else
	{
		aPoint.X() = rWindowPos.Y() - aOutArea.Top() + GetVisDocLeft();
		aPoint.Y() = aOutArea.Right() - rWindowPos.X() + GetVisDocTop();
	}

	return aPoint;
}

Point ImpEditView::GetWindowPos( const Point& rDocPos ) const
{
	// Dokumentposition => Fensterposition
	Point aPoint;

	if ( !pEditEngine->pImpEditEngine->IsVertical() )
	{
		aPoint.X() = rDocPos.X() + aOutArea.Left() - GetVisDocLeft();
		aPoint.Y() = rDocPos.Y() + aOutArea.Top() - GetVisDocTop();
	}
	else
	{
		aPoint.X() = aOutArea.Right() - rDocPos.Y() + GetVisDocTop();
		aPoint.Y() = rDocPos.X() + aOutArea.Top() - GetVisDocLeft();
	}

	return aPoint;
}

Rectangle ImpEditView::GetWindowPos( const Rectangle& rDocRect ) const
{
	// Dokumentposition => Fensterposition
	Point aPos( GetWindowPos( rDocRect.TopLeft() ) );
	Size aSz = rDocRect.GetSize();
	Rectangle aRect;
	if ( !pEditEngine->pImpEditEngine->IsVertical() )
	{
		aRect = Rectangle( aPos, aSz );
	}
	else
	{
		Point aNewPos( aPos.X()-aSz.Height(), aPos.Y() );
		aRect = Rectangle( aNewPos, Size( aSz.Height(), aSz.Width() ) );
	}
	return aRect;
}


Region* ImpEditView::CalcSelectedRegion()
{
	Region* pRegion = new Region;
	DrawSelection( GetEditSelection(), pRegion );
	return pRegion;
}

void ImpEditView::SetSelectionMode( EESelectionMode	eNewMode )
{
	if ( eSelectionMode != eNewMode )
	{
		DrawSelection();	// 'Wegmalen' ...
		eSelectionMode = eNewMode;
		DrawSelection();	// und neu zeichnen.
	}
}

void ImpEditView::SetOutputArea( const Rectangle& rRec )
{
	// sollte besser auf Pixel allignt sein!
	Rectangle aNewRec( pOutWin->LogicToPixel( rRec ) );
	aNewRec = pOutWin->PixelToLogic( aNewRec );
	aOutArea = aNewRec;
	if ( aOutArea.Right() < aOutArea.Left() )
		aOutArea.Right() = aOutArea.Left();
	if ( aOutArea.Bottom() < aOutArea.Top() )
		aOutArea.Bottom() = aOutArea.Top();

	if ( DoBigScroll() )
		SetScrollDiffX( (sal_uInt16)aOutArea.GetWidth() * 3 / 10 );
	else
		SetScrollDiffX( (sal_uInt16)aOutArea.GetWidth() * 2 / 10 );
}

void ImpEditView::ResetOutputArea( const Rectangle& rRec )
{
    // remember old out area
    const Rectangle aOldArea(aOutArea);

    // apply new one
    SetOutputArea(rRec);

    // invalidate surrounding areas if update is true
    if(!aOldArea.IsEmpty() && pEditEngine->pImpEditEngine->GetUpdateMode())
    {
        // #119885# use grown area if needed; do when getting bigger OR smaller
        const sal_Int32 nMore(DoInvalidateMore() ? GetWindow()->PixelToLogic(Size(nInvMore, 0)).Width() : 0);

        if(aOldArea.Left() > aOutArea.Left())
        {
            GetWindow()->Invalidate(Rectangle(aOutArea.Left() - nMore, aOldArea.Top() - nMore, aOldArea.Left(), aOldArea.Bottom() + nMore));
        }
        else if(aOldArea.Left() < aOutArea.Left())
        {
            GetWindow()->Invalidate(Rectangle(aOldArea.Left() - nMore, aOldArea.Top() - nMore, aOutArea.Left(), aOldArea.Bottom() + nMore));
        }

        if(aOldArea.Right() > aOutArea.Right())
        {
            GetWindow()->Invalidate(Rectangle(aOutArea.Right(), aOldArea.Top() - nMore, aOldArea.Right() + nMore, aOldArea.Bottom() + nMore));
        }
        else if(aOldArea.Right() < aOutArea.Right())
        {
            GetWindow()->Invalidate(Rectangle(aOldArea.Right(), aOldArea.Top() - nMore, aOutArea.Right() + nMore, aOldArea.Bottom() + nMore));
        }

        if(aOldArea.Top() > aOutArea.Top())
        {
            GetWindow()->Invalidate(Rectangle(aOldArea.Left() - nMore, aOutArea.Top() - nMore, aOldArea.Right() + nMore, aOldArea.Top()));
        }
        else if(aOldArea.Top() < aOutArea.Top())
        {
            GetWindow()->Invalidate(Rectangle(aOldArea.Left() - nMore, aOldArea.Top() - nMore, aOldArea.Right() + nMore, aOutArea.Top()));
        }

        if(aOldArea.Bottom() > aOutArea.Bottom())
        {
            GetWindow()->Invalidate(Rectangle(aOldArea.Left() - nMore, aOutArea.Bottom(), aOldArea.Right() + nMore, aOldArea.Bottom() + nMore));
        }
        else if(aOldArea.Bottom() < aOutArea.Bottom())
        {
            GetWindow()->Invalidate(Rectangle(aOldArea.Left() - nMore, aOldArea.Bottom(), aOldArea.Right() + nMore, aOutArea.Bottom() + nMore));
        }
    }
}

void ImpEditView::RecalcOutputArea()
{
	Rectangle aOldArea( aOutArea );
	Point aNewTopLeft( aOutArea.TopLeft() );
	Size aNewSz( aOutArea.GetSize() );

	// X:
	if ( DoAutoWidth() )
	{
		if ( pEditEngine->pImpEditEngine->GetStatus().AutoPageWidth() )
			aNewSz.Width() = pEditEngine->pImpEditEngine->GetPaperSize().Width();
		switch ( eAnchorMode )
		{
			case ANCHOR_TOP_LEFT:
			case ANCHOR_VCENTER_LEFT:
			case ANCHOR_BOTTOM_LEFT:
			{
				aNewTopLeft.X() = aAnchorPoint.X();
			}
			break;
			case ANCHOR_TOP_HCENTER:
			case ANCHOR_VCENTER_HCENTER:
			case ANCHOR_BOTTOM_HCENTER:
			{
				aNewTopLeft.X() = aAnchorPoint.X() - aNewSz.Width() / 2;
			}
			break;
			case ANCHOR_TOP_RIGHT:
			case ANCHOR_VCENTER_RIGHT:
			case ANCHOR_BOTTOM_RIGHT:
			{
				aNewTopLeft.X() = aAnchorPoint.X() - aNewSz.Width() - 1;
			}
			break;
		}
	}

	// Y:
	if ( DoAutoHeight() )
	{
		if ( pEditEngine->pImpEditEngine->GetStatus().AutoPageHeight() )
			aNewSz.Height() = pEditEngine->pImpEditEngine->GetPaperSize().Height();
		switch ( eAnchorMode )
		{
			case ANCHOR_TOP_LEFT:
			case ANCHOR_TOP_HCENTER:
			case ANCHOR_TOP_RIGHT:
			{
				aNewTopLeft.Y() = aAnchorPoint.Y();
			}
			break;
			case ANCHOR_VCENTER_LEFT:
			case ANCHOR_VCENTER_HCENTER:
			case ANCHOR_VCENTER_RIGHT:
			{
				aNewTopLeft.Y() = aAnchorPoint.Y() - aNewSz.Height() / 2;
			}
			break;
			case ANCHOR_BOTTOM_LEFT:
			case ANCHOR_BOTTOM_HCENTER:
			case ANCHOR_BOTTOM_RIGHT:
			{
				aNewTopLeft.Y() = aAnchorPoint.Y() - aNewSz.Height() - 1;
			}
			break;
		}
	}
	ResetOutputArea( Rectangle( aNewTopLeft, aNewSz ) );
}

void ImpEditView::SetAnchorMode( EVAnchorMode eMode )
{
	eAnchorMode = eMode;
	CalcAnchorPoint();
}

void ImpEditView::CalcAnchorPoint()
{
	// GetHeight() und GetWidth() -1, da Rectangle-Berechnung nicht erwuenscht.

	// X:
	switch ( eAnchorMode )
	{
		case ANCHOR_TOP_LEFT:
		case ANCHOR_VCENTER_LEFT:
		case ANCHOR_BOTTOM_LEFT:
		{
			aAnchorPoint.X() = aOutArea.Left();
		}
		break;
		case ANCHOR_TOP_HCENTER:
		case ANCHOR_VCENTER_HCENTER:
		case ANCHOR_BOTTOM_HCENTER:
		{
			aAnchorPoint.X() = aOutArea.Left() + (aOutArea.GetWidth()-1) / 2;
		}
		break;
		case ANCHOR_TOP_RIGHT:
		case ANCHOR_VCENTER_RIGHT:
		case ANCHOR_BOTTOM_RIGHT:
		{
			aAnchorPoint.X() = aOutArea.Right();
		}
		break;
	}

	// Y:
	switch ( eAnchorMode )
	{
		case ANCHOR_TOP_LEFT:
		case ANCHOR_TOP_HCENTER:
		case ANCHOR_TOP_RIGHT:
		{
			aAnchorPoint.Y() = aOutArea.Top();
		}
		break;
		case ANCHOR_VCENTER_LEFT:
		case ANCHOR_VCENTER_HCENTER:
		case ANCHOR_VCENTER_RIGHT:
		{
			aAnchorPoint.Y() = aOutArea.Top() + (aOutArea.GetHeight()-1) / 2;
		}
		break;
		case ANCHOR_BOTTOM_LEFT:
		case ANCHOR_BOTTOM_HCENTER:
		case ANCHOR_BOTTOM_RIGHT:
		{
			aAnchorPoint.Y() = aOutArea.Bottom() - 1;
		}
		break;
	}
}

void ImpEditView::ShowCursor( sal_Bool bGotoCursor, sal_Bool bForceVisCursor, sal_uInt16 nShowCursorFlags )
{
	// Kein ShowCursor bei einer leeren View...
	if ( ( aOutArea.Left() >= aOutArea.Right() ) && ( aOutArea.Top() >= aOutArea.Bottom() ) )
		return;

	pEditEngine->pImpEditEngine->CheckIdleFormatter();
	if ( !pEditEngine->pImpEditEngine->IsFormatted() )
		pEditEngine->pImpEditEngine->FormatDoc();

	// Aus irgendwelchen Gruenden lande ich waehrend der Formatierung hier,
	// wenn sich der Outiner im Paint initialisiert, weil kein SetPool();
	if ( pEditEngine->pImpEditEngine->IsFormatting() )
		return;
	if ( pEditEngine->pImpEditEngine->GetUpdateMode() == sal_False )
		return;
	if ( pEditEngine->pImpEditEngine->IsInUndo() )
		return;

	if ( pOutWin->GetCursor() != GetCursor() )
		pOutWin->SetCursor( GetCursor() );

	EditPaM aPaM( aEditSelection.Max() );

    sal_uInt16 nTextPortionStart = 0;
    sal_uInt16 nPara = pEditEngine->pImpEditEngine->aEditDoc.GetPos( aPaM.GetNode() );
    if (nPara == USHRT_MAX) // #i94322
        return;
    ParaPortion* pParaPortion = pEditEngine->pImpEditEngine->GetParaPortions().GetObject( nPara );

    nShowCursorFlags |= nExtraCursorFlags;

    nShowCursorFlags |= GETCRSR_TXTONLY;

    // Use CursorBidiLevel 0/1 in meaning of
    // 0: prefer portion end, normal mode
    // 1: prefer portion start

    if ( ( GetCursorBidiLevel() != CURSOR_BIDILEVEL_DONTKNOW ) && GetCursorBidiLevel() )
    {
        nShowCursorFlags |= GETCRSR_PREFERPORTIONSTART;
    }

    Rectangle aEditCursor = pEditEngine->pImpEditEngine->PaMtoEditCursor( aPaM, nShowCursorFlags );
	if ( !IsInsertMode() && !aEditSelection.HasRange() )
	{
		if ( aPaM.GetNode()->Len() && ( aPaM.GetIndex() < aPaM.GetNode()->Len() ) )
		{
            // If we are behind a portion, and the next portion has other direction, we must change position...
			aEditCursor.Left() = aEditCursor.Right() = pEditEngine->pImpEditEngine->PaMtoEditCursor( aPaM, GETCRSR_TXTONLY|GETCRSR_PREFERPORTIONSTART ).Left();

            sal_uInt16 nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), nTextPortionStart, sal_True );
            TextPortion* pTextPortion = pParaPortion->GetTextPortions().GetObject( nTextPortion );
            if ( pTextPortion->GetKind() == PORTIONKIND_TAB )
            {
		        aEditCursor.Right() += pTextPortion->GetSize().Width();
            }
            else
            {
                EditPaM aNext = pEditEngine->pImpEditEngine->CursorRight( aPaM, (sal_uInt16)i18n::CharacterIteratorMode::SKIPCELL );
			    Rectangle aTmpRect = pEditEngine->pImpEditEngine->PaMtoEditCursor( aNext, GETCRSR_TXTONLY );
                if ( aTmpRect.Top() != aEditCursor.Top() )
                    aTmpRect = pEditEngine->pImpEditEngine->PaMtoEditCursor( aNext, GETCRSR_TXTONLY|GETCRSR_ENDOFLINE );
			    aEditCursor.Right() = aTmpRect.Left();
            }
		}
	}
	long nMaxHeight = !IsVertical() ? aOutArea.GetHeight() : aOutArea.GetWidth();
	if ( aEditCursor.GetHeight() > nMaxHeight )
	{
		aEditCursor.Bottom() = aEditCursor.Top() + nMaxHeight - 1;
	}
	if ( bGotoCursor  ) // && (!pEditEngine->pImpEditEngine->GetStatus().AutoPageSize() ) )
	{
		// pruefen, ob scrollen notwendig...
		// wenn scrollen, dann Update() und Scroll() !
		long nDocDiffX = 0;
		long nDocDiffY = 0;

		Rectangle aTmpVisArea( GetVisDocArea() );
		// aTmpOutArea: Falls OutputArea > Papierbreite und
		// Text > Papierbreite ( uebergrosse Felder )
		long nMaxTextWidth = !IsVertical() ? pEditEngine->pImpEditEngine->GetPaperSize().Width() : pEditEngine->pImpEditEngine->GetPaperSize().Height();
		if ( aTmpVisArea.GetWidth() > nMaxTextWidth )
			aTmpVisArea.Right() = aTmpVisArea.Left() + nMaxTextWidth;

		if ( aEditCursor.Bottom() > aTmpVisArea.Bottom() )
		{   // hochscrollen, hier positiv
			nDocDiffY = aEditCursor.Bottom() - aTmpVisArea.Bottom();
		}
		else if ( aEditCursor.Top() < aTmpVisArea.Top() )
		{	// runterscrollen, negativ
			nDocDiffY = aEditCursor.Top() - aTmpVisArea.Top();
		}

		if ( aEditCursor.Right() > aTmpVisArea.Right() )
		{
			// linksscrollen, positiv
			nDocDiffX = aEditCursor.Right() - aTmpVisArea.Right();
			// Darfs ein bischen mehr sein?
			if ( aEditCursor.Right() < ( nMaxTextWidth - GetScrollDiffX() ) )
				nDocDiffX += GetScrollDiffX();
			else
			{
				long n = nMaxTextWidth - aEditCursor.Right();
				// Bei einem MapMode != RefMapMode kann der EditCursor auch mal ueber
				// die Papierbreite Wandern!
				nDocDiffX += ( n > 0 ? n : -n );
			}
		}
		else if ( aEditCursor.Left() < aTmpVisArea.Left() )
		{	// rechtsscrollen
			// negativ:
			nDocDiffX = aEditCursor.Left() - aTmpVisArea.Left();
			// Darfs ein bischen mehr sein?
			if ( aEditCursor.Left() > ( - (long)GetScrollDiffX() ) )
				nDocDiffX -= GetScrollDiffX();
			else
				nDocDiffX -= aEditCursor.Left();
		}
		if ( aPaM.GetIndex() == 0 ) 	// braucht Olli fuer den Outliner
		{
			// Aber sicherstellen, dass dadurch der Cursor nicht den
			// sichtbaren bereich verlaesst!
			if ( aEditCursor.Left() < aTmpVisArea.GetWidth() )
			{
				nDocDiffX = -aTmpVisArea.Left();
			}
		}

		if ( nDocDiffX | nDocDiffY )
		{
			long nDiffX = !IsVertical() ? nDocDiffX : -nDocDiffY;
			long nDiffY = !IsVertical() ? nDocDiffY : nDocDiffX;

			// Negativ: Zum Anfang bzw. linken Rand
			if ( ( Abs( nDiffY ) > pEditEngine->pImpEditEngine->nOnePixelInRef ) && DoBigScroll() )
			{
				long nH = aOutArea.GetHeight() / 4;
				if ( ( nH > aEditCursor.GetHeight() ) && ( Abs( nDiffY ) < nH ) )
				{
					if ( nDiffY < 0 )
						nDiffY -= nH;
					else
						nDiffY += nH;
				}
			}

			if ( ( Abs( nDiffX ) > pEditEngine->pImpEditEngine->nOnePixelInRef ) && DoBigScroll() )
			{
				long nW = aOutArea.GetWidth() / 4;
				if ( Abs( nDiffX ) < nW )
				{
					if ( nDiffY < 0 )
						nDiffY -= nW;
					else
						nDiffY += nW;
				}
			}

			if ( nDiffX )
				pEditEngine->pImpEditEngine->aStatus.GetStatusWord() = pEditEngine->pImpEditEngine->aStatus.GetStatusWord() | EE_STAT_HSCROLL;
			if ( nDiffY )
				pEditEngine->pImpEditEngine->aStatus.GetStatusWord() = pEditEngine->pImpEditEngine->aStatus.GetStatusWord() | EE_STAT_VSCROLL;
			Scroll( -nDiffX, -nDiffY );
			pEditEngine->pImpEditEngine->DelayedCallStatusHdl();
		}
	}

	// Cursor evtl. etwas stutzen...
	if ( ( aEditCursor.Bottom() > GetVisDocTop() ) &&
		 ( aEditCursor.Top() < GetVisDocBottom() ) )
	{
		if ( aEditCursor.Bottom() > GetVisDocBottom() )
			aEditCursor.Bottom() = GetVisDocBottom();
		if ( aEditCursor.Top() < GetVisDocTop() )
			aEditCursor.Top() = GetVisDocTop();
	}

	long nOnePixel = pOutWin->PixelToLogic( Size( 1, 0 ) ).Width();

	if ( /* pEditEngine->pImpEditEngine->GetStatus().AutoPageSize() || */
		 ( ( aEditCursor.Top() + nOnePixel >= GetVisDocTop() ) &&
		 ( aEditCursor.Bottom() - nOnePixel <= GetVisDocBottom() ) &&
		 ( aEditCursor.Left() + nOnePixel >= GetVisDocLeft() ) &&
		 ( aEditCursor.Right() - nOnePixel <= GetVisDocRight() ) ) )
	{
		Rectangle aCursorRect = GetWindowPos( aEditCursor );
		GetCursor()->SetPos( aCursorRect.TopLeft() );
		Size aCursorSz( aCursorRect.GetSize() );
		// Rectangle is inclusive
		aCursorSz.Width()--;
		aCursorSz.Height()--;
		if ( !aCursorSz.Width() || !aCursorSz.Height() )
		{
			long nCursorSz = pOutWin->GetSettings().GetStyleSettings().GetCursorSize();
			nCursorSz = pOutWin->PixelToLogic( Size( nCursorSz, 0 ) ).Width();
			if ( !aCursorSz.Width() )
				aCursorSz.Width() = nCursorSz;
			if ( !aCursorSz.Height() )
				aCursorSz.Height() = nCursorSz;
		}
		// #111036# Let VCL do orientation for cursor, otherwise problem when cursor has direction flag
		if ( IsVertical() )
		{
			Size aOldSz( aCursorSz );
			aCursorSz.Width() = aOldSz.Height();
			aCursorSz.Height() = aOldSz.Width();
			GetCursor()->SetPos( aCursorRect.TopRight() );
			GetCursor()->SetOrientation( 2700 );
		}
        else
            // --> FME 2004-10-18 #i32593#
            // Reset correct orientation in horizontal layout
            GetCursor()->SetOrientation( 0 );
            // <--

		GetCursor()->SetSize( aCursorSz );

        unsigned char nCursorDir = CURSOR_DIRECTION_NONE;
        if ( IsInsertMode() && !aEditSelection.HasRange() && ( pEditEngine->pImpEditEngine->HasDifferentRTLLevels( aPaM.GetNode() ) ) )
        {
            sal_uInt16 nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), nTextPortionStart, nShowCursorFlags & GETCRSR_PREFERPORTIONSTART ? sal_True : sal_False );
            TextPortion* pTextPortion = pParaPortion->GetTextPortions().GetObject( nTextPortion );
            sal_uInt16 nRTLLevel = pTextPortion->GetRightToLeft();
            if ( nRTLLevel%2 )
                nCursorDir = CURSOR_DIRECTION_RTL;
            else
                nCursorDir = CURSOR_DIRECTION_LTR;

        }
        GetCursor()->SetDirection( nCursorDir );

        if ( bForceVisCursor )
			GetCursor()->Show();

        // #102936# Call SetInputContext every time, otherwise we may have the wrong font
		// if ( !pEditEngine->pImpEditEngine->mpIMEInfos )
		{
			SvxFont aFont;
			pEditEngine->pImpEditEngine->SeekCursor( aPaM.GetNode(), aPaM.GetIndex()+1, aFont );
			sal_uLong nContextFlags = INPUTCONTEXT_TEXT|INPUTCONTEXT_EXTTEXTINPUT;
			GetWindow()->SetInputContext( InputContext( aFont, nContextFlags ) );
		}
	}
	else
	{
		pEditEngine->pImpEditEngine->GetStatus().GetStatusWord() = pEditEngine->pImpEditEngine->GetStatus().GetStatusWord() | EE_STAT_CURSOROUT;
		GetCursor()->Hide();
		GetCursor()->SetPos( Point( -1, -1 ) );
		GetCursor()->SetSize( Size( 0, 0 ) );
	}
}

Pair ImpEditView::Scroll( long ndX, long ndY, sal_uInt8 nRangeCheck )
{
	DBG_ASSERT( pEditEngine->pImpEditEngine->IsFormatted(), "Scroll: Nicht formatiert!" );
	if ( !ndX && !ndY )
		return Range( 0, 0 );

#ifdef DBG_UTIL
	Rectangle aR( aOutArea );
	aR = pOutWin->LogicToPixel( aR );
	aR = pOutWin->PixelToLogic( aR );
	DBG_ASSERTWARNING( aR == aOutArea, "OutArea vor Scroll nicht aligned" );
#endif

	Rectangle aNewVisArea( GetVisDocArea() );
	Size aPaperSz( pEditEngine->pImpEditEngine->GetPaperSize() );

	// Vertical:
	if ( !IsVertical() )
	{
		aNewVisArea.Top() -= ndY;
		aNewVisArea.Bottom() -= ndY;
	}
	else
	{
		aNewVisArea.Top() += ndX;
		aNewVisArea.Bottom() += ndX;
	}
	if ( ( nRangeCheck == RGCHK_PAPERSZ1 ) && ( aNewVisArea.Bottom() > (long)pEditEngine->pImpEditEngine->GetTextHeight() ) )
	{
		// GetTextHeight noch optimieren!
		long nDiff = pEditEngine->pImpEditEngine->GetTextHeight() - aNewVisArea.Bottom(); // negativ
		aNewVisArea.Move( 0, nDiff );	// koennte im neg. Bereich landen...
	}
	if ( ( aNewVisArea.Top() < 0 ) && ( nRangeCheck != RGCHK_NONE ) )
		aNewVisArea.Move( 0, -aNewVisArea.Top() );

	// Horizontal:
	if ( !IsVertical() )
	{
		aNewVisArea.Left() -= ndX;
		aNewVisArea.Right() -= ndX;
	}
	else
	{
		aNewVisArea.Left() -= ndY;
		aNewVisArea.Right() -= ndY;
	}
	if ( ( nRangeCheck == RGCHK_PAPERSZ1 ) && ( aNewVisArea.Right() > (long)pEditEngine->pImpEditEngine->CalcTextWidth( sal_False ) ) )
	{
		long nDiff = pEditEngine->pImpEditEngine->CalcTextWidth( sal_False ) - aNewVisArea.Right(); 	// negativ
		aNewVisArea.Move( nDiff, 0 );	// koennte im neg. Bereich landen...
	}
	if ( ( aNewVisArea.Left() < 0 ) && ( nRangeCheck != RGCHK_NONE ) )
		aNewVisArea.Move( -aNewVisArea.Left(), 0 );

	// Die Differenz muss auf Pixel alignt sein (wegen Scroll!)
	long nDiffX = !IsVertical() ? ( GetVisDocLeft() - aNewVisArea.Left() ) : -( GetVisDocTop() - aNewVisArea.Top() );
	long nDiffY = !IsVertical() ? ( GetVisDocTop() - aNewVisArea.Top() ) : ( GetVisDocLeft() - aNewVisArea.Left() );

	Size aDiffs( nDiffX, nDiffY );
	aDiffs = pOutWin->LogicToPixel( aDiffs );
	aDiffs = pOutWin->PixelToLogic( aDiffs );

	long nRealDiffX = aDiffs.Width();
	long nRealDiffY = aDiffs.Height();


	if ( nRealDiffX || nRealDiffY )
	{
		Cursor* pCrsr = GetCursor();
		sal_Bool bVisCursor = pCrsr->IsVisible();
		pCrsr->Hide();
		pOutWin->Update();
		if ( !IsVertical() )
			aVisDocStartPos.Move( -nRealDiffX, -nRealDiffY );
		else
			aVisDocStartPos.Move( -nRealDiffY, nRealDiffX );
		// Das Move um den allignten Wert ergibt nicht unbedingt ein
		// alligntes Rechteck...
		// MT 11/00: Align VisArea???
		aVisDocStartPos = pOutWin->LogicToPixel( aVisDocStartPos );
		aVisDocStartPos = pOutWin->PixelToLogic( aVisDocStartPos );
		Rectangle aRec( aOutArea );
		pOutWin->Scroll( nRealDiffX, nRealDiffY, aRec, sal_True );
		pOutWin->Update();
		pCrsr->SetPos( pCrsr->GetPos() + Point( nRealDiffX, nRealDiffY ) );
		if ( bVisCursor )
		{
			Rectangle aCursorRec( pCrsr->GetPos(), pCrsr->GetSize() );
			if ( aOutArea.IsInside( aCursorRec ) )
				pCrsr->Show();
		}

        if ( pEditEngine->pImpEditEngine->GetNotifyHdl().IsSet() )
        {
            EENotify aNotify( EE_NOTIFY_TEXTVIEWSCROLLED );
            aNotify.pEditEngine = pEditEngine;
            aNotify.pEditView = GetEditViewPtr();
            pEditEngine->pImpEditEngine->CallNotify( aNotify );
        }
	}

	return Pair( nRealDiffX, nRealDiffY );
}

sal_Bool ImpEditView::PostKeyEvent( const KeyEvent& rKeyEvent )
{
    sal_Bool bDone = sal_False;

	KeyFuncType eFunc = rKeyEvent.GetKeyCode().GetFunction();
	if ( eFunc != KEYFUNC_DONTKNOW )
	{
		switch ( eFunc )
		{
			case KEYFUNC_CUT:
			{
				if ( !bReadOnly )
				{
                    Reference<com::sun::star::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetClipboard());
					CutCopy( aClipBoard, sal_True );
					bDone = sal_True;
				}
			}
			break;
			case KEYFUNC_COPY:
			{
                Reference<com::sun::star::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetClipboard());
				CutCopy( aClipBoard, sal_False );
                bDone = sal_True;
			}
			break;
			case KEYFUNC_PASTE:
			{
				if ( !bReadOnly && IsPasteEnabled() )
				{
					pEditEngine->pImpEditEngine->UndoActionStart( EDITUNDO_PASTE );
                    Reference<com::sun::star::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetClipboard());
					Paste( aClipBoard, pEditEngine->pImpEditEngine->GetStatus().AllowPasteSpecial() );
					pEditEngine->pImpEditEngine->UndoActionEnd( EDITUNDO_PASTE );
					bDone = sal_True;
				}
			}
			break;
			default:
				break;
        }
    }

    if( !bDone )
	    bDone = pEditEngine->PostKeyEvent( rKeyEvent, GetEditViewPtr() );

    return bDone;
}

sal_Bool ImpEditView::MouseButtonUp( const MouseEvent& rMouseEvent )
{
	if ( pEditEngine->pImpEditEngine->aStatus.NotifyCursorMovements() )
	{
		if ( pEditEngine->pImpEditEngine->aStatus.GetPrevParagraph() != pEditEngine->pImpEditEngine->GetEditDoc().GetPos( GetEditSelection().Max().GetNode() ) )
		{
			pEditEngine->pImpEditEngine->aStatus.GetStatusWord() = pEditEngine->pImpEditEngine->aStatus.GetStatusWord() | EE_STAT_CRSRLEFTPARA;
			pEditEngine->pImpEditEngine->CallStatusHdl();
		}
	}
	nTravelXPos = TRAVEL_X_DONTKNOW;
    nCursorBidiLevel = CURSOR_BIDILEVEL_DONTKNOW;
    nExtraCursorFlags = 0;
    bClickedInSelection = sal_False;

    if ( rMouseEvent.IsMiddle() && !bReadOnly &&
         ( GetWindow()->GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION ) )
    {
        Reference<com::sun::star::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetPrimarySelection());
        Paste( aClipBoard );
    }
    else if ( rMouseEvent.IsLeft() && GetEditSelection().HasRange() )
    {
        Reference<com::sun::star::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetPrimarySelection());
        CutCopy( aClipBoard, sal_False );
    }

	return pEditEngine->pImpEditEngine->MouseButtonUp( rMouseEvent, GetEditViewPtr() );
}

sal_Bool ImpEditView::MouseButtonDown( const MouseEvent& rMouseEvent )
{
	pEditEngine->pImpEditEngine->CheckIdleFormatter();	// Falls schnelles Tippen und MouseButtonDown
	if ( pEditEngine->pImpEditEngine->aStatus.NotifyCursorMovements() )
		pEditEngine->pImpEditEngine->aStatus.GetPrevParagraph() = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( GetEditSelection().Max().GetNode() );
	nTravelXPos = TRAVEL_X_DONTKNOW;
    nExtraCursorFlags = 0;
    nCursorBidiLevel    = CURSOR_BIDILEVEL_DONTKNOW;
    bClickedInSelection = IsSelectionAtPoint( rMouseEvent.GetPosPixel() );
	return pEditEngine->pImpEditEngine->MouseButtonDown( rMouseEvent, GetEditViewPtr() );
}

sal_Bool ImpEditView::MouseMove( const MouseEvent& rMouseEvent )
{
	return pEditEngine->pImpEditEngine->MouseMove( rMouseEvent, GetEditViewPtr() );
}

void ImpEditView::Command( const CommandEvent& rCEvt )
{
	pEditEngine->pImpEditEngine->CheckIdleFormatter();	// Falls schnelles Tippen und MouseButtonDown
	pEditEngine->pImpEditEngine->Command( rCEvt, GetEditViewPtr() );
}


void ImpEditView::SetInsertMode( sal_Bool bInsert )
{
	if ( bInsert != IsInsertMode() )
	{
		SetFlags( nControl, EV_CNTRL_OVERWRITE, !bInsert );
		ShowCursor( DoAutoScroll(), sal_False );
	}
}

sal_Bool ImpEditView::IsWrongSpelledWord( const EditPaM& rPaM, sal_Bool bMarkIfWrong )
{
	sal_Bool bIsWrong = sal_False;
#ifndef SVX_LIGHT
	if ( rPaM.GetNode()->GetWrongList() )
	{
		EditSelection aSel = pEditEngine->pImpEditEngine->SelectWord( rPaM, ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
		bIsWrong = rPaM.GetNode()->GetWrongList()->HasWrong( aSel.Min().GetIndex(), aSel.Max().GetIndex() );
		if ( bIsWrong && bMarkIfWrong )
		{
			DrawSelection();	// alte Selektion 'weg-zeichnen'
			SetEditSelection( aSel );
			DrawSelection();
		}
	}
#endif // !SVX_LIGHT
	return bIsWrong;
}

String ImpEditView::SpellIgnoreOrAddWord( sal_Bool bAdd )
{
	String aWord;
#ifndef SVX_LIGHT
	if ( pEditEngine->pImpEditEngine->GetSpeller().is() )
	{
		EditPaM aPaM = GetEditSelection().Max();
		if ( !HasSelection() )
		{
			EditSelection aSel = pEditEngine->pImpEditEngine->SelectWord( aPaM );
			aWord = pEditEngine->pImpEditEngine->GetSelected( aSel );
		}
		else
		{
			aWord = pEditEngine->pImpEditEngine->GetSelected( GetEditSelection() );
			// Und deselektieren
			DrawSelection();	// alte Selektion 'weg-zeichnen'
			SetEditSelection( EditSelection( aPaM, aPaM ) );
			DrawSelection();
		}

		if ( aWord.Len() )
		{
			if ( bAdd )
			{
				DBG_ERROR( "Sorry, AddWord not implemented" );
			}
			else // Ignore
			{
                Reference< XDictionary >  xDic( SvxGetIgnoreAllList(), UNO_QUERY );
				if (xDic.is())
					xDic->add( aWord, sal_False, String() );
			}
			const EditDoc& rDoc = pEditEngine->pImpEditEngine->GetEditDoc();
			sal_uInt16 nNodes = rDoc.Count();
			for ( sal_uInt16 n = 0; n < nNodes; n++ )
			{
				ContentNode* pNode = rDoc.GetObject( n );
				pNode->GetWrongList()->MarkWrongsInvalid();
			}
			pEditEngine->pImpEditEngine->DoOnlineSpelling( aPaM.GetNode() );
			pEditEngine->pImpEditEngine->StartOnlineSpellTimer();
		}
	}
#endif // !SVX_LIGHT
	return aWord;
}

void ImpEditView::DeleteSelected()
{
	DrawSelection();

	pEditEngine->pImpEditEngine->UndoActionStart( EDITUNDO_DELETE );

	EditPaM aPaM = pEditEngine->pImpEditEngine->DeleteSelected( GetEditSelection() );

	pEditEngine->pImpEditEngine->UndoActionEnd( EDITUNDO_DELETE );

	SetEditSelection( EditSelection( aPaM, aPaM ) );
	pEditEngine->pImpEditEngine->FormatAndUpdate( GetEditViewPtr() );
	ShowCursor( DoAutoScroll(), sal_True );
}

const SvxFieldItem* ImpEditView::GetField( const Point& rPos, sal_uInt16* pPara, sal_uInt16* pPos ) const
{
	if( !GetOutputArea().IsInside( rPos ) )
		return 0;

	Point aDocPos( GetDocPos( rPos ) );
	EditPaM aPaM = pEditEngine->pImpEditEngine->GetPaM( aDocPos, sal_False );

	if ( aPaM.GetIndex() == aPaM.GetNode()->Len() )
	{
		// Sonst immer, wenn Feld ganz am Schluss und Mouse unter Text
		return 0;
	}

	const CharAttribArray& rAttrs = aPaM.GetNode()->GetCharAttribs().GetAttribs();
	sal_uInt16 nXPos = aPaM.GetIndex();
	for ( sal_uInt16 nAttr = rAttrs.Count(); nAttr; )
	{
		EditCharAttrib* pAttr = rAttrs[--nAttr];
		if ( pAttr->GetStart() == nXPos )
			if ( pAttr->Which() == EE_FEATURE_FIELD )
			{
				DBG_ASSERT( dynamic_cast< const SvxFieldItem* >(pAttr->GetItem()), "Kein FeldItem..." );
				if ( pPara )
					*pPara = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( aPaM.GetNode() );
				if ( pPos )
					*pPos = pAttr->GetStart();
				return (const SvxFieldItem*)pAttr->GetItem();
			}
	}
	return NULL;
}

sal_Bool ImpEditView::IsBulletArea( const Point& rPos, sal_uInt16* pPara )
{
    if ( pPara )
        *pPara = 0xFFFF;

    if( !GetOutputArea().IsInside( rPos ) )
		return sal_False;

	Point aDocPos( GetDocPos( rPos ) );
	EditPaM aPaM = pEditEngine->pImpEditEngine->GetPaM( aDocPos, sal_False );

	if ( aPaM.GetIndex() == 0 )
	{
        sal_uInt16 nPara = pEditEngine->pImpEditEngine->aEditDoc.GetPos( aPaM.GetNode() );
		Rectangle aBulletArea = pEditEngine->GetBulletArea( nPara );
        long nY = pEditEngine->GetDocPosTopLeft( nPara ).Y();
        ParaPortion* pParaPortion = pEditEngine->pImpEditEngine->GetParaPortions().GetObject( nPara );
        nY += pParaPortion->GetFirstLineOffset();
        if ( ( aDocPos.Y() > ( nY + aBulletArea.Top() ) ) &&
             ( aDocPos.Y() < ( nY + aBulletArea.Bottom() ) ) &&
             ( aDocPos.X() > ( aBulletArea.Left() ) ) &&
             ( aDocPos.X() < ( aBulletArea.Right() ) ) )
        {
            if ( pPara )
                *pPara = nPara;
		    return sal_True;
        }
	}

    return sal_False;
}

void ImpEditView::CutCopy( ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboard >& rxClipboard, sal_Bool bCut )
{
	if ( rxClipboard.is() && GetEditSelection().HasRange() )
    {
		uno::Reference< datatransfer::XTransferable > xData = pEditEngine->pImpEditEngine->CreateTransferable( GetEditSelection() );

        const sal_uInt32 nRef = Application::ReleaseSolarMutex();

        try
		{
            rxClipboard->setContents( xData, NULL );

            // #87756# FlushClipboard, but it would be better to become a TerminateListener to the Desktop and flush on demand...
            uno::Reference< datatransfer::clipboard::XFlushableClipboard > xFlushableClipboard( rxClipboard, uno::UNO_QUERY );
		    if( xFlushableClipboard.is() )
			    xFlushableClipboard->flushClipboard();
		}
		catch( const ::com::sun::star::uno::Exception& )
		{
		}

        Application::AcquireSolarMutex( nRef );

        if ( bCut )
	    {
            pEditEngine->pImpEditEngine->UndoActionStart( EDITUNDO_CUT );
		    DeleteSelected();
            pEditEngine->pImpEditEngine->UndoActionEnd( EDITUNDO_CUT );

	    }
    }
}

void ImpEditView::Paste( ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboard >& rxClipboard, sal_Bool bUseSpecial )
{
	if ( rxClipboard.is() )
	{
        uno::Reference< datatransfer::XTransferable > xDataObj;

        const sal_uInt32 nRef = Application::ReleaseSolarMutex();

        try
		{
		    xDataObj = rxClipboard->getContents();
		}
		catch( const ::com::sun::star::uno::Exception& )
		{
		}

        Application::AcquireSolarMutex( nRef );

        if ( xDataObj.is() && EditEngine::HasValidData( xDataObj ) )
	    {
	        pEditEngine->pImpEditEngine->UndoActionStart( EDITUNDO_PASTE );

            EditSelection aSel( GetEditSelection() );
            if ( aSel.HasRange() )
	        {
		        DrawSelection();
		        aSel = pEditEngine->pImpEditEngine->ImpDeleteSelection( aSel );
            }

            PasteOrDropInfos aPasteOrDropInfos;
            aPasteOrDropInfos.nAction = EE_ACTION_PASTE;
            aPasteOrDropInfos.nStartPara = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( aSel.Min().GetNode() );
            pEditEngine->pImpEditEngine->aBeginPasteOrDropHdl.Call( &aPasteOrDropInfos );

            if ( DoSingleLinePaste() )
	        {
			    datatransfer::DataFlavor aFlavor;
			    SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING, aFlavor );
			    if ( xDataObj->isDataFlavorSupported( aFlavor ) )
			    {
					try
        			{
						uno::Any aData = xDataObj->getTransferData( aFlavor );
						::rtl::OUString aTmpText;
						aData >>= aTmpText;
						String aText( aTmpText );
						aText.ConvertLineEnd( LINEEND_LF );
						aText.SearchAndReplaceAll( LINE_SEP, ' ' );
						aSel = pEditEngine->pImpEditEngine->ImpInsertText( aSel, aText );
					}
					catch( ... )
					{
						; // #i9286# can happen, even if isDataFlavorSupported returns true...
					}
			    }
	        }
	        else
	        {
                aSel = pEditEngine->pImpEditEngine->InsertText( xDataObj, String(), aSel.Min(), bUseSpecial && pEditEngine->pImpEditEngine->GetStatus().AllowPasteSpecial() );
	        }

            aPasteOrDropInfos.nEndPara = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( aSel.Max().GetNode() );
            pEditEngine->pImpEditEngine->aEndPasteOrDropHdl.Call( &aPasteOrDropInfos );

	        pEditEngine->pImpEditEngine->UndoActionEnd( EDITUNDO_PASTE );
	        SetEditSelection( aSel );
	        pEditEngine->pImpEditEngine->UpdateSelections();
	        pEditEngine->pImpEditEngine->FormatAndUpdate( GetEditViewPtr() );
            ShowCursor( DoAutoScroll(), sal_True );
        }
	}
}


sal_Bool ImpEditView::IsInSelection( const EditPaM& rPaM )
{
	EditSelection aSel = GetEditSelection();
	if ( !aSel.HasRange() )
		return sal_False;

	aSel.Adjust( pEditEngine->pImpEditEngine->GetEditDoc() );

	sal_uInt16 nStartNode = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( aSel.Min().GetNode() );
	sal_uInt16 nEndNode = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( aSel.Max().GetNode() );
	sal_uInt16 nCurNode = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( rPaM.GetNode() );

	if ( ( nCurNode > nStartNode ) && ( nCurNode < nEndNode ) )
		return sal_True;

	if ( nStartNode == nEndNode )
	{
		if ( nCurNode == nStartNode )
			if ( ( rPaM.GetIndex() >= aSel.Min().GetIndex() ) && ( rPaM.GetIndex() < aSel.Max().GetIndex() ) )
				return sal_True;
	}
	else if ( ( nCurNode == nStartNode ) && ( rPaM.GetIndex() >= aSel.Min().GetIndex() ) )
		return sal_True;
	else if ( ( nCurNode == nEndNode ) && ( rPaM.GetIndex() < aSel.Max().GetIndex() ) )
		return sal_True;

	return sal_False;
}

void ImpEditView::CreateAnchor()
{
	pEditEngine->pImpEditEngine->bInSelection = sal_True;
	GetEditSelection().Min() = GetEditSelection().Max();
}

void ImpEditView::DeselectAll()
{
	pEditEngine->pImpEditEngine->bInSelection = sal_False;
	DrawSelection();
	GetEditSelection().Min() = GetEditSelection().Max();
}

sal_Bool ImpEditView::IsSelectionAtPoint( const Point& rPosPixel )
{
	if ( pDragAndDropInfo && pDragAndDropInfo->pField )
		return sal_True;

	Point aMousePos( rPosPixel );

	// Logische Einheiten...
	aMousePos = GetWindow()->PixelToLogic( aMousePos );

	if ( ( !GetOutputArea().IsInside( aMousePos ) ) && !pEditEngine->pImpEditEngine->IsInSelectionMode() )
	{
		return sal_False;
	}

	Point aDocPos( GetDocPos( aMousePos ) );
	EditPaM aPaM = pEditEngine->pImpEditEngine->GetPaM( aDocPos, sal_False );
	return IsInSelection( aPaM );
}

sal_Bool ImpEditView::SetCursorAtPoint( const Point& rPointPixel )
{
	pEditEngine->pImpEditEngine->CheckIdleFormatter();

	Point aMousePos( rPointPixel );

	// Logische Einheiten...
	aMousePos = GetWindow()->PixelToLogic( aMousePos );

	if ( ( !GetOutputArea().IsInside( aMousePos ) ) && !pEditEngine->pImpEditEngine->IsInSelectionMode() )
	{
		return sal_False;
	}

	Point aDocPos( GetDocPos( aMousePos ) );

	// Kann optimiert werden: Erst innerhalb eines Absatzes die Zeilen
	// fuer den PaM durchwuehlen, dann nochmal mit dem PaM fuer das Rect,
	// obwohl die Zeile schon bekannt ist....
	// Das muss doch nicht sein !

	EditPaM aPaM = pEditEngine->pImpEditEngine->GetPaM( aDocPos );
	sal_Bool bGotoCursor = DoAutoScroll();

	// aTmpNewSel: Diff zwischen alt und neu, nicht die neue Selektion
	EditSelection aTmpNewSel( GetEditSelection().Max(), aPaM );

    // --> OD 2005-12-16 #i27299#
    // work on copy of current selection and set new selection, if it has changed.
    EditSelection aNewEditSelection( GetEditSelection() );

    aNewEditSelection.Max() = aPaM;
	if ( !pEditEngine->pImpEditEngine->aSelEngine.HasAnchor() )
	{
        if ( aNewEditSelection.Min() != aPaM )
            pEditEngine->pImpEditEngine->CursorMoved( aNewEditSelection.Min().GetNode() );
        aNewEditSelection.Min() = aPaM;
	}
	else
	{
		DrawSelection( aTmpNewSel );
	}

    // set changed text selection
    if ( GetEditSelection() != aNewEditSelection )
    {
        SetEditSelection( aNewEditSelection );
    }
    // <--

	sal_Bool bForceCursor = ( pDragAndDropInfo ? sal_False : sal_True ) && !pEditEngine->pImpEditEngine->IsInSelectionMode();
	ShowCursor( bGotoCursor, bForceCursor );
	return sal_True;
}


void ImpEditView::HideDDCursor()
{
	if ( pDragAndDropInfo && pDragAndDropInfo->bVisCursor )
	{
		GetWindow()->DrawOutDev( pDragAndDropInfo->aCurSavedCursor.TopLeft(), pDragAndDropInfo->aCurSavedCursor.GetSize(),
							Point(0,0), pDragAndDropInfo->aCurSavedCursor.GetSize(),*pDragAndDropInfo->pBackground );
		pDragAndDropInfo->bVisCursor = sal_False;
	}
}

void ImpEditView::ShowDDCursor( const Rectangle& rRect )
{
	if ( pDragAndDropInfo && !pDragAndDropInfo->bVisCursor )
	{
		if ( pOutWin->GetCursor() )
			pOutWin->GetCursor()->Hide();

		Color aOldFillColor = GetWindow()->GetFillColor();
		GetWindow()->SetFillColor( Color(4210752) );	// GRAY BRUSH_50, OLDSV, change to DDCursor!

		// Hintergrund sichern...
		Rectangle aSaveRec( GetWindow()->LogicToPixel( rRect ) );
		// lieber etwas mehr sichern...
		aSaveRec.Right() += 1;
		aSaveRec.Bottom() += 1;

		Size aNewSzPx( aSaveRec.GetSize() );
		if ( !pDragAndDropInfo->pBackground )
		{
			pDragAndDropInfo->pBackground = new VirtualDevice( *GetWindow() );
	    	MapMode aMapMode( GetWindow()->GetMapMode() );
	    	aMapMode.SetOrigin( Point( 0, 0 ) );
	    	pDragAndDropInfo->pBackground->SetMapMode( aMapMode );

		}

#ifdef DBG_UTIL
		Size aCurSzPx( pDragAndDropInfo->pBackground->GetOutputSizePixel() );
		if ( ( aCurSzPx.Width() < aNewSzPx.Width() ) ||( aCurSzPx.Height() < aNewSzPx.Height() ) )
		{
			sal_Bool bDone = pDragAndDropInfo->pBackground->SetOutputSizePixel( aNewSzPx );
			DBG_ASSERT( bDone, "Virtuelles Device kaputt?" );
		}
#endif

		aSaveRec = GetWindow()->PixelToLogic( aSaveRec );

		pDragAndDropInfo->pBackground->DrawOutDev( Point(0,0), aSaveRec.GetSize(),
									aSaveRec.TopLeft(), aSaveRec.GetSize(), *GetWindow() );
		pDragAndDropInfo->aCurSavedCursor = aSaveRec;

		// Cursor malen...
		GetWindow()->DrawRect( rRect );

		pDragAndDropInfo->bVisCursor = sal_True;
		pDragAndDropInfo->aCurCursor = rRect;

		GetWindow()->SetFillColor( aOldFillColor );
	}
}

void ImpEditView::dragGestureRecognized( const ::com::sun::star::datatransfer::dnd::DragGestureEvent& rDGE ) throw (::com::sun::star::uno::RuntimeException)
{
    DBG_ASSERT( !pDragAndDropInfo, "dragGestureRecognized - DragAndDropInfo exist!" );

    vos::OGuard aVclGuard( Application::GetSolarMutex() );

    pDragAndDropInfo = NULL;

    Point aMousePosPixel( rDGE.DragOriginX, rDGE.DragOriginY );

    EditSelection aCopySel( GetEditSelection() );
    aCopySel.Adjust( pEditEngine->pImpEditEngine->GetEditDoc() );

    if ( GetEditSelection().HasRange() && bClickedInSelection )
    {
        pDragAndDropInfo = new DragAndDropInfo();
    }
    else
    {
	    // Field?!
		sal_uInt16 nPara, nPos;
	    Point aMousePos = GetWindow()->PixelToLogic( aMousePosPixel );
		const SvxFieldItem* pField = GetField( aMousePos, &nPara, &nPos );
		if ( pField )
		{
			pDragAndDropInfo = new DragAndDropInfo();
			pDragAndDropInfo->pField = pField;
            ContentNode* pNode = pEditEngine->pImpEditEngine->GetEditDoc().GetObject( nPara );
            aCopySel = EditSelection( EditPaM( pNode, nPos ), EditPaM( pNode, nPos+1 ) );
			GetEditSelection() = aCopySel;
			DrawSelection();
			sal_Bool bGotoCursor = DoAutoScroll();
			sal_Bool bForceCursor = ( pDragAndDropInfo ? sal_False : sal_True ) && !pEditEngine->pImpEditEngine->IsInSelectionMode();
			ShowCursor( bGotoCursor, bForceCursor );
		}
        else if ( IsBulletArea( aMousePos, &nPara ) )
        {
            pDragAndDropInfo = new DragAndDropInfo();
            pDragAndDropInfo->bOutlinerMode = sal_True;
            EditPaM aStartPaM( pEditEngine->pImpEditEngine->GetEditDoc().GetObject( nPara ), 0 );
            EditPaM aEndPaM( aStartPaM );
            const SfxInt16Item& rLevel = (const SfxInt16Item&) pEditEngine->GetParaAttrib( nPara, EE_PARA_OUTLLEVEL );
            for ( sal_uInt16 n = nPara +1; n < pEditEngine->pImpEditEngine->GetEditDoc().Count(); n++ )
            {
                const SfxInt16Item& rL = (const SfxInt16Item&) pEditEngine->GetParaAttrib( n, EE_PARA_OUTLLEVEL );
                if ( rL.GetValue() > rLevel.GetValue() )
                {
                    aEndPaM.SetNode( pEditEngine->pImpEditEngine->GetEditDoc().GetObject( n ) );
                }
                else
                {
                    break;
                }
            }
            aEndPaM.GetIndex() = aEndPaM.GetNode()->Len();
            SetEditSelection( EditSelection( aStartPaM, aEndPaM ) );
        }
    }

    if ( pDragAndDropInfo )
    {

	    pDragAndDropInfo->bStarterOfDD = sal_True;

	    // Sensibler Bereich, wo gescrollt werden soll.
	    Size aSz( 5, 0 );
	    aSz = GetWindow()->PixelToLogic( aSz );
	    pDragAndDropInfo->nSensibleRange = (sal_uInt16) aSz.Width();
	    pDragAndDropInfo->nCursorWidth = (sal_uInt16) aSz.Width() / 2;
	    pDragAndDropInfo->aBeginDragSel = pEditEngine->pImpEditEngine->CreateESel( aCopySel );

        uno::Reference< datatransfer::XTransferable > xData = pEditEngine->pImpEditEngine->CreateTransferable( aCopySel );

        sal_Int8 nActions = bReadOnly ? datatransfer::dnd::DNDConstants::ACTION_COPY : datatransfer::dnd::DNDConstants::ACTION_COPY_OR_MOVE;

        rDGE.DragSource->startDrag( rDGE, nActions, 0 /*cursor*/, 0 /*image*/, xData, mxDnDListener );
		// Falls Drag&Move in einer Engine, muessen Copy&Del geklammert sein!
	    GetCursor()->Hide();

    }
}

void ImpEditView::dragDropEnd( const ::com::sun::star::datatransfer::dnd::DragSourceDropEvent& rDSDE ) throw (::com::sun::star::uno::RuntimeException)
{
	vos::OGuard aVclGuard( Application::GetSolarMutex() );

	DBG_ASSERT( pDragAndDropInfo, "ImpEditView::dragDropEnd: pDragAndDropInfo is NULL!" );

	// #123688# Shouldn't happen, but seems to happen...
	if ( pDragAndDropInfo )
	{
		if ( !bReadOnly && rDSDE.DropSuccess && !pDragAndDropInfo->bOutlinerMode && ( rDSDE.DropAction & datatransfer::dnd::DNDConstants::ACTION_MOVE ) )
		{
			if ( pDragAndDropInfo->bStarterOfDD && pDragAndDropInfo->bDroppedInMe )
			{
				// DropPos: Wohin wurde gedroppt, unabhaengig von laenge.
				ESelection aDropPos( pDragAndDropInfo->aDropSel.nStartPara, pDragAndDropInfo->aDropSel.nStartPos, pDragAndDropInfo->aDropSel.nStartPara, pDragAndDropInfo->aDropSel.nStartPos );
				ESelection aToBeDelSel = pDragAndDropInfo->aBeginDragSel;
				ESelection aNewSel( pDragAndDropInfo->aDropSel.nEndPara, pDragAndDropInfo->aDropSel.nEndPos,
									pDragAndDropInfo->aDropSel.nEndPara, pDragAndDropInfo->aDropSel.nEndPos );
				sal_Bool bBeforeSelection = aDropPos.IsLess( pDragAndDropInfo->aBeginDragSel );
				sal_uInt16 nParaDiff = pDragAndDropInfo->aBeginDragSel.nEndPara - pDragAndDropInfo->aBeginDragSel.nStartPara;
				if ( bBeforeSelection )
				{
					// aToBeDelSel anpassen.
					DBG_ASSERT( pDragAndDropInfo->aBeginDragSel.nStartPara >= pDragAndDropInfo->aDropSel.nStartPara, "Doch nicht davor?" );
					aToBeDelSel.nStartPara = aToBeDelSel.nStartPara + nParaDiff;
					aToBeDelSel.nEndPara = aToBeDelSel.nEndPara + nParaDiff;
					// Zeichen korrigieren?
					if ( aToBeDelSel.nStartPara == pDragAndDropInfo->aDropSel.nEndPara )
					{
						sal_uInt16 nMoreChars;
						if ( pDragAndDropInfo->aDropSel.nStartPara == pDragAndDropInfo->aDropSel.nEndPara )
							nMoreChars = pDragAndDropInfo->aDropSel.nEndPos - pDragAndDropInfo->aDropSel.nStartPos;
						else
							nMoreChars = pDragAndDropInfo->aDropSel.nEndPos;
						aToBeDelSel.nStartPos =
                            aToBeDelSel.nStartPos + nMoreChars;
						if ( aToBeDelSel.nStartPara == aToBeDelSel.nEndPara )
							aToBeDelSel.nEndPos =
                                aToBeDelSel.nEndPos + nMoreChars;
					}
				}
				else
				{
					// aToBeDelSel ist ok, aber Selektion der View
					// muss angepasst werden, wenn davor geloescht wird!
					DBG_ASSERT( pDragAndDropInfo->aBeginDragSel.nStartPara <= pDragAndDropInfo->aDropSel.nStartPara, "Doch nicht davor?" );
					aNewSel.nStartPara = aNewSel.nStartPara - nParaDiff;
					aNewSel.nEndPara = aNewSel.nEndPara - nParaDiff;
					// Zeichen korrigieren?
					if ( pDragAndDropInfo->aBeginDragSel.nEndPara == pDragAndDropInfo->aDropSel.nStartPara )
					{
						sal_uInt16 nLessChars;
						if ( pDragAndDropInfo->aBeginDragSel.nStartPara == pDragAndDropInfo->aBeginDragSel.nEndPara )
							nLessChars = pDragAndDropInfo->aBeginDragSel.nEndPos - pDragAndDropInfo->aBeginDragSel.nStartPos;
						else
							nLessChars = pDragAndDropInfo->aBeginDragSel.nEndPos;
						aNewSel.nStartPos = aNewSel.nStartPos - nLessChars;
						if ( aNewSel.nStartPara == aNewSel.nEndPara )
							aNewSel.nEndPos = aNewSel.nEndPos - nLessChars;
					}
				}

				DrawSelection();
				EditSelection aDelSel( pEditEngine->pImpEditEngine->CreateSel( aToBeDelSel ) );
				DBG_ASSERT( !aDelSel.DbgIsBuggy( pEditEngine->pImpEditEngine->aEditDoc ), "ToBeDel ist buggy!" );
				pEditEngine->pImpEditEngine->ImpDeleteSelection( aDelSel );
				if ( !bBeforeSelection )
				{
					DBG_ASSERT( !pEditEngine->pImpEditEngine->CreateSel( aNewSel ).DbgIsBuggy(pEditEngine->pImpEditEngine->aEditDoc), "Bad" );
					SetEditSelection( pEditEngine->pImpEditEngine->CreateSel( aNewSel ) );
				}
				pEditEngine->pImpEditEngine->FormatAndUpdate( pEditEngine->pImpEditEngine->GetActiveView() );
				DrawSelection();
			}
			else
			{
				// andere EditEngine...
				if ( pEditEngine->pImpEditEngine->ImplHasText() )   // #88630# SC ist removing the content when switching the task
					DeleteSelected();
			}
		}

		if ( pDragAndDropInfo->bUndoAction )
			pEditEngine->pImpEditEngine->UndoActionEnd( EDITUNDO_DRAGANDDROP );

		HideDDCursor();
		ShowCursor( DoAutoScroll(), sal_True );
		delete pDragAndDropInfo;
		pDragAndDropInfo = NULL;
		pEditEngine->GetEndDropHdl().Call(GetEditViewPtr());
	}
}

void ImpEditView::drop( const ::com::sun::star::datatransfer::dnd::DropTargetDropEvent& rDTDE ) throw (::com::sun::star::uno::RuntimeException)
{
	vos::OGuard aVclGuard( Application::GetSolarMutex() );

    DBG_ASSERT( pDragAndDropInfo, "Drop - No Drag&Drop info?!" );

    if ( pDragAndDropInfo && pDragAndDropInfo->bDragAccepted )
    {
		pEditEngine->GetBeginDropHdl().Call(GetEditViewPtr());
	    sal_Bool bChanges = sal_False;

        HideDDCursor();

        if ( pDragAndDropInfo->bStarterOfDD )
        {
            pEditEngine->pImpEditEngine->UndoActionStart( EDITUNDO_DRAGANDDROP );
            pDragAndDropInfo->bUndoAction = sal_True;
        }

        if ( pDragAndDropInfo->bOutlinerMode )
        {
            bChanges = sal_True;
            GetEditViewPtr()->MoveParagraphs( Range( pDragAndDropInfo->aBeginDragSel.nStartPara, pDragAndDropInfo->aBeginDragSel.nEndPara ), pDragAndDropInfo->nOutlinerDropDest );
        }
        else
        {
	        uno::Reference< datatransfer::XTransferable > xDataObj = rDTDE.Transferable;
	        if ( xDataObj.is() )
	        {
                bChanges = sal_True;
	            // Selektion wegmalen...
	            DrawSelection();
                EditPaM aPaM( pDragAndDropInfo->aDropDest );

                PasteOrDropInfos aPasteOrDropInfos;
                aPasteOrDropInfos.nAction = EE_ACTION_DROP;
                aPasteOrDropInfos.nStartPara = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( aPaM.GetNode() );
                pEditEngine->pImpEditEngine->aBeginPasteOrDropHdl.Call( &aPasteOrDropInfos );

                EditSelection aNewSel = pEditEngine->pImpEditEngine->InsertText( xDataObj, String(), aPaM, pEditEngine->pImpEditEngine->GetStatus().AllowPasteSpecial() );

                aPasteOrDropInfos.nEndPara = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( aNewSel.Max().GetNode() );
                pEditEngine->pImpEditEngine->aEndPasteOrDropHdl.Call( &aPasteOrDropInfos );

                SetEditSelection( aNewSel );
	            pEditEngine->pImpEditEngine->FormatAndUpdate( pEditEngine->pImpEditEngine->GetActiveView() );
	            if ( pDragAndDropInfo->bStarterOfDD )
	            {
		            // Nur dann setzen, wenn in gleicher Engine!
		            pDragAndDropInfo->aDropSel.nStartPara = pEditEngine->pImpEditEngine->aEditDoc.GetPos( aPaM.GetNode() );
		            pDragAndDropInfo->aDropSel.nStartPos = aPaM.GetIndex();
		            pDragAndDropInfo->aDropSel.nEndPara = pEditEngine->pImpEditEngine->aEditDoc.GetPos( aNewSel.Max().GetNode() );
		            pDragAndDropInfo->aDropSel.nEndPos = aNewSel.Max().GetIndex();
		            pDragAndDropInfo->bDroppedInMe = sal_True;
	            }
            }
        }

        if ( bChanges )
        {
            rDTDE.Context->acceptDrop( rDTDE.DropAction );
        }

	    if ( !pDragAndDropInfo->bStarterOfDD )
	    {
		    delete pDragAndDropInfo;
		    pDragAndDropInfo = NULL;
	    }

        rDTDE.Context->dropComplete( bChanges );
    }
}

void ImpEditView::dragEnter( const ::com::sun::star::datatransfer::dnd::DropTargetDragEnterEvent& rDTDEE ) throw (::com::sun::star::uno::RuntimeException)
{
	vos::OGuard aVclGuard( Application::GetSolarMutex() );

    if ( !pDragAndDropInfo )
        pDragAndDropInfo = new DragAndDropInfo( );

    pDragAndDropInfo->bHasValidData = sal_False;

    // Check for supported format...
    // Only check for text, will also be there if bin or rtf
    datatransfer::DataFlavor aTextFlavor;
	SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING, aTextFlavor );
    const ::com::sun::star::datatransfer::DataFlavor* pFlavors = rDTDEE.SupportedDataFlavors.getConstArray();
    int nFlavors = rDTDEE.SupportedDataFlavors.getLength();
    for ( int n = 0; n < nFlavors; n++ )
    {
        if( TransferableDataHelper::IsEqual( pFlavors[n], aTextFlavor ) )
        {
            pDragAndDropInfo->bHasValidData = sal_True;
            break;
        }
    }

    dragOver( rDTDEE );
}

void ImpEditView::dragExit( const ::com::sun::star::datatransfer::dnd::DropTargetEvent& ) throw (::com::sun::star::uno::RuntimeException)
{
	vos::OGuard aVclGuard( Application::GetSolarMutex() );

    HideDDCursor();

	if ( pDragAndDropInfo && !pDragAndDropInfo->bStarterOfDD )
	{
		delete pDragAndDropInfo;
		pDragAndDropInfo = NULL;
	}
}

void ImpEditView::dragOver( const ::com::sun::star::datatransfer::dnd::DropTargetDragEvent& rDTDE ) throw (::com::sun::star::uno::RuntimeException)
{
    vos::OGuard aVclGuard( Application::GetSolarMutex() );

    Point aMousePos( rDTDE.LocationX, rDTDE.LocationY );
	aMousePos = GetWindow()->PixelToLogic( aMousePos );

    sal_Bool bAccept = sal_False;

    if ( GetOutputArea().IsInside( aMousePos ) && !bReadOnly )
    {
//        sal_Int8 nSupportedActions = bReadOnly ? datatransfer::dnd::DNDConstants::ACTION_COPY : datatransfer::dnd::DNDConstants::ACTION_COPY_OR_MOVE;

        if ( pDragAndDropInfo && pDragAndDropInfo->bHasValidData /* && ( nSupportedActions & rDTDE.DropAction ) MT: Default = 0x80 ?! */ )
        {
            bAccept = sal_True;

            sal_Bool bAllowScroll = DoAutoScroll();
	        if ( bAllowScroll )
	        {
		        long nScrollX = 0;
		        long nScrollY = 0;
		        // pruefen, ob im sensitiven Bereich
		        if ( ( (aMousePos.X()-pDragAndDropInfo->nSensibleRange) < GetOutputArea().Left() ) && ( ( aMousePos.X() + pDragAndDropInfo->nSensibleRange ) > GetOutputArea().Left() ) )
				        nScrollX = GetOutputArea().GetWidth() / SCRLRANGE;
		        else if ( ( (aMousePos.X()+pDragAndDropInfo->nSensibleRange) > GetOutputArea().Right() ) && ( ( aMousePos.X() - pDragAndDropInfo->nSensibleRange ) < GetOutputArea().Right() ) )
				        nScrollX = -( GetOutputArea().GetWidth() / SCRLRANGE );

		        if ( ( (aMousePos.Y()-pDragAndDropInfo->nSensibleRange) < GetOutputArea().Top() ) && ( ( aMousePos.Y() + pDragAndDropInfo->nSensibleRange ) > GetOutputArea().Top() ) )
				        nScrollY = GetOutputArea().GetHeight() / SCRLRANGE;
		        else if ( ( (aMousePos.Y()+pDragAndDropInfo->nSensibleRange) > GetOutputArea().Bottom() ) && ( ( aMousePos.Y() - pDragAndDropInfo->nSensibleRange ) < GetOutputArea().Bottom() ) )
				        nScrollY = -( GetOutputArea().GetHeight() / SCRLRANGE );

		        if ( nScrollX || nScrollY )
		        {
			        HideDDCursor();
			        Scroll( nScrollX, nScrollY, RGCHK_PAPERSZ1 );
		        }
	        }

	        Point aDocPos( GetDocPos( aMousePos ) );
	        EditPaM aPaM = pEditEngine->pImpEditEngine->GetPaM( aDocPos );
	        pDragAndDropInfo->aDropDest = aPaM;
            if ( pDragAndDropInfo->bOutlinerMode )
            {
                sal_uInt16 nPara = pEditEngine->pImpEditEngine->aEditDoc.GetPos( aPaM.GetNode() );
		        ParaPortion* pPPortion = pEditEngine->pImpEditEngine->GetParaPortions().SaveGetObject( nPara );
                long nDestParaStartY = pEditEngine->pImpEditEngine->GetParaPortions().GetYOffset( pPPortion );
                long nRel = aDocPos.Y() - nDestParaStartY;
                if ( nRel < ( pPPortion->GetHeight() / 2 ) )
                {
                    pDragAndDropInfo->nOutlinerDropDest = nPara;
                }
                else
                {
                    pDragAndDropInfo->nOutlinerDropDest = nPara+1;
                }

                if( ( pDragAndDropInfo->nOutlinerDropDest >= pDragAndDropInfo->aBeginDragSel.nStartPara ) &&
                    ( pDragAndDropInfo->nOutlinerDropDest <= (pDragAndDropInfo->aBeginDragSel.nEndPara+1) ) )
                {
                    bAccept = sal_False;
                }
            }
	        else if ( HasSelection() )
	        {
		        // es darf nicht in eine Selektion gedroppt werden
		        EPaM aP = pEditEngine->pImpEditEngine->CreateEPaM( aPaM );
		        ESelection aDestSel( aP.nPara, aP.nIndex, aP.nPara, aP.nIndex);
		        ESelection aCurSel = pEditEngine->pImpEditEngine->CreateESel( GetEditSelection() );
		        aCurSel.Adjust();
		        if ( !aDestSel.IsLess( aCurSel ) && !aDestSel.IsGreater( aCurSel ) )
		        {
                    bAccept = sal_False;
		        }
	        }
            if ( bAccept )
            {
	            Rectangle aEditCursor;
                if ( pDragAndDropInfo->bOutlinerMode )
                {
                    long nDDYPos;
                    if ( pDragAndDropInfo->nOutlinerDropDest < pEditEngine->pImpEditEngine->GetEditDoc().Count() )
                    {
		                ParaPortion* pPPortion = pEditEngine->pImpEditEngine->GetParaPortions().SaveGetObject( pDragAndDropInfo->nOutlinerDropDest );
                        nDDYPos = pEditEngine->pImpEditEngine->GetParaPortions().GetYOffset( pPPortion );
                    }
                    else
                    {
                        nDDYPos = pEditEngine->pImpEditEngine->GetTextHeight();
                    }
                    Point aStartPos( 0, nDDYPos );
                    aStartPos = GetWindowPos( aStartPos );
                    Point aEndPos( GetOutputArea().GetWidth(), nDDYPos );
                    aEndPos = GetWindowPos( aEndPos );
	                aEditCursor = GetWindow()->LogicToPixel( Rectangle( aStartPos, aEndPos ) );
                    if ( !pEditEngine->IsVertical() )
                    {
                        aEditCursor.Top()--;
                        aEditCursor.Bottom()++;
                    }
                    else
                    {
                        aEditCursor.Left()--;
                        aEditCursor.Right()++;
                    }
	                aEditCursor = GetWindow()->PixelToLogic( aEditCursor );
                }
                else
                {
	                aEditCursor = pEditEngine->pImpEditEngine->PaMtoEditCursor( aPaM );
	                Point aTopLeft( GetWindowPos( aEditCursor.TopLeft() ) );
	                aEditCursor.SetPos( aTopLeft );
	                aEditCursor.Right() = aEditCursor.Left() + pDragAndDropInfo->nCursorWidth;
	                aEditCursor = GetWindow()->LogicToPixel( aEditCursor );
	                aEditCursor = GetWindow()->PixelToLogic( aEditCursor );
                }

                sal_Bool bCursorChanged = !pDragAndDropInfo->bVisCursor || ( pDragAndDropInfo->aCurCursor != aEditCursor );
	            if ( bCursorChanged )
	            {
		            HideDDCursor();
		            ShowDDCursor(aEditCursor );
	            }
                pDragAndDropInfo->bDragAccepted = sal_True;
                rDTDE.Context->acceptDrag( rDTDE.DropAction );
            }
        }
    }

    if ( !bAccept )
    {
        HideDDCursor();
        if (pDragAndDropInfo)
            pDragAndDropInfo->bDragAccepted = sal_False;
        rDTDE.Context->rejectDrag();
    }
}

void ImpEditView::AddDragAndDropListeners()
{
    Window* pWindow = GetWindow();
    if ( !bActiveDragAndDropListener && pWindow && pWindow->GetDragGestureRecognizer().is() )
    {
        vcl::unohelper::DragAndDropWrapper* pDnDWrapper = new vcl::unohelper::DragAndDropWrapper( this );
        mxDnDListener = pDnDWrapper;

        uno::Reference< datatransfer::dnd::XDragGestureListener> xDGL( mxDnDListener, uno::UNO_QUERY );
        pWindow->GetDragGestureRecognizer()->addDragGestureListener( xDGL );
        uno::Reference< datatransfer::dnd::XDropTargetListener> xDTL( xDGL, uno::UNO_QUERY );
        pWindow->GetDropTarget()->addDropTargetListener( xDTL );
        pWindow->GetDropTarget()->setActive( sal_True );
        pWindow->GetDropTarget()->setDefaultActions( datatransfer::dnd::DNDConstants::ACTION_COPY_OR_MOVE );

        bActiveDragAndDropListener = sal_True;
    }
}

void ImpEditView::RemoveDragAndDropListeners()
{
    if ( bActiveDragAndDropListener && GetWindow() && GetWindow()->GetDragGestureRecognizer().is() )
    {
        uno::Reference< datatransfer::dnd::XDragGestureListener> xDGL( mxDnDListener, uno::UNO_QUERY );
        GetWindow()->GetDragGestureRecognizer()->removeDragGestureListener( xDGL );
        uno::Reference< datatransfer::dnd::XDropTargetListener> xDTL( xDGL, uno::UNO_QUERY );
        GetWindow()->GetDropTarget()->removeDropTargetListener( xDTL );

        if ( mxDnDListener.is() )
        {
            uno::Reference< lang::XEventListener> xEL( mxDnDListener, uno::UNO_QUERY );
            xEL->disposing( lang::EventObject() );  // #95154# Empty Source means it's the Client
            mxDnDListener.clear();
        }

        bActiveDragAndDropListener = sal_False;
    }
}
