/**************************************************************
 * 
 * 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' postion
            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( pAttr->GetItem()->ISA( SvxFieldItem ), "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;
    }
}
