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

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

#include <editeng/eeitem.hxx>
#include "svx/svdstr.hrc"
#include "svx/svdglob.hxx"
#include <svx/svdpagv.hxx>
#include <svx/svdmrkv.hxx>
#include <svx/svdedxv.hxx>
#include <svx/svdobj.hxx>
#include <svx/svdopath.hxx>
#include <svx/svdograf.hxx>
#include <svx/svdomedia.hxx>
#include <svx/svdetc.hxx>

#ifdef DBG_UTIL
#include <svdibrow.hxx>
#endif

#include "svx/svdoutl.hxx"
#include "svx/svdview.hxx"
#include "editeng/editview.hxx"
#include "editeng/flditem.hxx"
#include "svx/obj3d.hxx"
#include "svx/svddrgmt.hxx"
#include "svx/svdoutl.hxx"
#include "svx/svdotable.hxx"
#include <tools/tenccvt.hxx>
#include <svx/sdr/overlay/overlaypolypolygon.hxx>
#include <svx/sdr/overlay/overlaymanager.hxx>
#include <svx/sdrpaintwindow.hxx>
#include <svx/sdrpagewindow.hxx>
#include <svx/sdrhittesthelper.hxx>
#include <svx/sdr/contact/viewcontact.hxx>
#include <drawinglayer/processor2d/contourextractor2d.hxx>

////////////////////////////////////////////////////////////////////////////////////////////////////

SdrViewEvent::SdrViewEvent()
:	  pHdl(NULL),
	  pObj(NULL),
	  pRootObj(NULL),
	  pPV(NULL),
	  pURLField(NULL),
	  eHit(SDRHIT_NONE),
	  eEvent(SDREVENT_NONE),
	  eHdlKind(HDL_MOVE),
	  eEndCreateCmd(SDRCREATE_NEXTPOINT),
	  nMouseClicks(0),
	  nMouseMode(0),
	  nMouseCode(0),
	  nHlplIdx(0),
	  nGlueId(0),
	  bMouseDown(sal_False),
	  bMouseUp(sal_False),
	  bDoubleHdlSize(sal_False),
	  bIsAction(sal_False),
	  bIsTextEdit(sal_False),
	  bTextEditHit(sal_False),
	  bAddMark(sal_False),
	  bUnmark(sal_False),
	  bPrevNextMark(sal_False),
	  bMarkPrev(sal_False),
	  bInsPointNewObj(sal_False),
	  bDragWithCopy(sal_False),
	  bCaptureMouse(sal_False),
	  bReleaseMouse(sal_False)
{
}

SdrViewEvent::~SdrViewEvent()
{
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// helper class for all D&D overlays

void SdrDropMarkerOverlay::ImplCreateOverlays(
    const SdrView& rView,
    const basegfx::B2DPolyPolygon& rLinePolyPolygon)
{
	for(sal_uInt32 a(0L); a < rView.PaintWindowCount(); a++)
	{
		SdrPaintWindow* pCandidate = rView.GetPaintWindow(a);
		::sdr::overlay::OverlayManager* pTargetOverlay = pCandidate->GetOverlayManager();

		if(pTargetOverlay)
		{
			::sdr::overlay::OverlayPolyPolygonStripedAndFilled* pNew = new ::sdr::overlay::OverlayPolyPolygonStripedAndFilled(
				rLinePolyPolygon);

            pTargetOverlay->add(*pNew);
			maObjects.append(*pNew);
		}
	}
}

SdrDropMarkerOverlay::SdrDropMarkerOverlay(const SdrView& rView, const SdrObject& rObject)
{
    ImplCreateOverlays(
        rView,
        rObject.TakeXorPoly());
}

SdrDropMarkerOverlay::SdrDropMarkerOverlay(const SdrView& rView, const Rectangle& rRectangle)
{
	basegfx::B2DPolygon aB2DPolygon;

    aB2DPolygon.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Top()));
	aB2DPolygon.append(basegfx::B2DPoint(rRectangle.Right(), rRectangle.Top()));
	aB2DPolygon.append(basegfx::B2DPoint(rRectangle.Right(), rRectangle.Bottom()));
	aB2DPolygon.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Bottom()));
	aB2DPolygon.setClosed(true);

	ImplCreateOverlays(
        rView,
        basegfx::B2DPolyPolygon(aB2DPolygon));
}

SdrDropMarkerOverlay::SdrDropMarkerOverlay(const SdrView& rView, const Point& rStart, const Point& rEnd)
{
	basegfx::B2DPolygon aB2DPolygon;

    aB2DPolygon.append(basegfx::B2DPoint(rStart.X(), rStart.Y()));
	aB2DPolygon.append(basegfx::B2DPoint(rEnd.X(), rEnd.Y()));
	aB2DPolygon.setClosed(true);

	ImplCreateOverlays(
        rView,
        basegfx::B2DPolyPolygon(aB2DPolygon));
}

SdrDropMarkerOverlay::~SdrDropMarkerOverlay()
{
	// The OverlayObjects are cleared using the destructor of OverlayObjectList.
	// That destructor calls clear() at the list which removes all objects from the
	// OverlayManager and deletes them.
}

////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
//
//  @@ @@ @@ @@@@@ @@   @@
//  @@ @@ @@ @@    @@   @@
//  @@ @@ @@ @@    @@ @ @@
//  @@@@@ @@ @@@@  @@@@@@@
//   @@@  @@ @@    @@@@@@@
//   @@@  @@ @@    @@@ @@@
//    @   @@ @@@@@ @@   @@
//
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////

TYPEINIT1(SdrView,SdrCreateView);

SdrView::SdrView(SdrModel* pModel1, OutputDevice* pOut)
:	SdrCreateView(pModel1,pOut),
	bNoExtendedMouseDispatcher(sal_False),
	bNoExtendedKeyDispatcher(sal_False),
	bNoExtendedCommandDispatcher(sal_False),
	mbMasterPagePaintCaching(sal_False)
{
	bTextEditOnObjectsWithoutTextIfTextTool=sal_False;

	maAccessibilityOptions.AddListener(this);

	onAccessibilityOptionsChanged();
}

SdrView::~SdrView()
{
	maAccessibilityOptions.RemoveListener(this);
}

sal_Bool SdrView::KeyInput(const KeyEvent& rKEvt, Window* pWin)
{
	SetActualWin(pWin);
	sal_Bool bRet=SdrCreateView::KeyInput(rKEvt,pWin);
	if (!bRet && !IsExtendedKeyInputDispatcherEnabled()) {
		bRet=sal_True;
		switch (rKEvt.GetKeyCode().GetFullFunction()) {
			case KEYFUNC_CUT   : Cut(); break;
			case KEYFUNC_COPY  : Yank(); break;
			case KEYFUNC_PASTE : Paste(pWin); break;
			case KEYFUNC_DELETE: DeleteMarked(); break;
			case KEYFUNC_UNDO: pMod->Undo(); break;
			case KEYFUNC_REDO: pMod->Redo(); break;
			case KEYFUNC_REPEAT: pMod->Repeat(*this); break;
			default: {
				switch (rKEvt.GetKeyCode().GetFullCode()) {
					case KEY_ESCAPE: {
						if (IsTextEdit()) SdrEndTextEdit();
						if (IsAction()) BrkAction();
						if (pWin!=NULL) pWin->ReleaseMouse();
					} break;
					case KEY_DELETE: DeleteMarked(); break;
					case KEY_CUT: case KEY_DELETE+KEY_SHIFT: Cut(); break;
					case KEY_COPY: case KEY_INSERT+KEY_MOD1: Yank(); break;
					case KEY_PASTE: case KEY_INSERT+KEY_SHIFT: Paste(pWin); break;
					case KEY_UNDO: case KEY_BACKSPACE+KEY_MOD2: pMod->Undo(); break;
					case KEY_BACKSPACE+KEY_MOD2+KEY_SHIFT: pMod->Redo(); break;
					case KEY_REPEAT: case KEY_BACKSPACE+KEY_MOD2+KEY_MOD1: pMod->Repeat(*this); break;
					case KEY_MOD1+KEY_A: MarkAll(); break;
					default: bRet=sal_False;
				} // switch
			}
		} // switch
		if (bRet && pWin!=NULL) {
			pWin->SetPointer(GetPreferedPointer(
				pWin->PixelToLogic(pWin->ScreenToOutputPixel( pWin->GetPointerPosPixel() ) ),
				pWin,
				rKEvt.GetKeyCode().GetModifier()));
		}
	}
	return bRet;
}

sal_Bool SdrView::MouseButtonDown(const MouseEvent& rMEvt, Window* pWin)
{
	SetActualWin(pWin);
	if (rMEvt.IsLeft()) aDragStat.SetMouseDown(sal_True);
	sal_Bool bRet=SdrCreateView::MouseButtonDown(rMEvt,pWin);
	if (!bRet && !IsExtendedMouseEventDispatcherEnabled()) {
		SdrViewEvent aVEvt;
		PickAnything(rMEvt,SDRMOUSEBUTTONDOWN,aVEvt);
		bRet=DoMouseEvent(aVEvt);
	}
	return bRet;
}

sal_Bool SdrView::MouseButtonUp(const MouseEvent& rMEvt, Window* pWin)
{
	SetActualWin(pWin);
	if (rMEvt.IsLeft()) aDragStat.SetMouseDown(sal_False);
	sal_Bool bAction=IsAction();
	sal_Bool bRet=!bAction && SdrCreateView::MouseButtonUp(rMEvt,pWin);
	if (!bRet && !IsExtendedMouseEventDispatcherEnabled()) {
		SdrViewEvent aVEvt;
		PickAnything(rMEvt,SDRMOUSEBUTTONUP,aVEvt);
		bRet=DoMouseEvent(aVEvt);
	}
	return bRet;
}

sal_Bool SdrView::MouseMove(const MouseEvent& rMEvt, Window* pWin)
{
	SetActualWin(pWin);
	aDragStat.SetMouseDown(rMEvt.IsLeft());
	sal_Bool bRet=SdrCreateView::MouseMove(rMEvt,pWin);
	if (!IsExtendedMouseEventDispatcherEnabled() && !IsTextEditInSelectionMode()) {
		SdrViewEvent aVEvt;
		PickAnything(rMEvt,SDRMOUSEMOVE,aVEvt);
		if (DoMouseEvent(aVEvt)) bRet=sal_True;
	}

	// #87792# Removed code which did let the mouse snap on object
	// points

	return bRet;
}

sal_Bool SdrView::Command(const CommandEvent& rCEvt, Window* pWin)
{
	SetActualWin(pWin);
	sal_Bool bRet=SdrCreateView::Command(rCEvt,pWin);
	return bRet;
}

/* new interface src537 */
sal_Bool SdrView::GetAttributes(SfxItemSet& rTargetSet, sal_Bool bOnlyHardAttr) const
{
	return SdrCreateView::GetAttributes(rTargetSet, bOnlyHardAttr);
}

SfxStyleSheet* SdrView::GetStyleSheet() const
{
	//sal_Bool bOk=sal_False;
	return SdrCreateView::GetStyleSheet(); //bOk);
}

SdrHitKind SdrView::PickAnything(const MouseEvent& rMEvt, sal_uInt16 nEventKind, SdrViewEvent& rVEvt) const
{
	rVEvt.bMouseDown=nEventKind==SDRMOUSEBUTTONDOWN;
	rVEvt.bMouseUp=nEventKind==SDRMOUSEBUTTONUP;
	rVEvt.nMouseClicks=rMEvt.GetClicks();
	rVEvt.nMouseMode=rMEvt.GetMode();
	rVEvt.nMouseCode=rMEvt.GetButtons() | rMEvt.GetModifier();
	const OutputDevice* pOut=pActualOutDev;
	if (pOut==NULL)
	{
		pOut = GetFirstOutputDevice();
		//pOut=GetWin(0);
	}
	Point aPnt(rMEvt.GetPosPixel());
	if (pOut!=NULL) aPnt=pOut->PixelToLogic(aPnt);
	rVEvt.aLogicPos=aPnt;
	return PickAnything(aPnt,rVEvt);
}

// Mit der Maus draggen (Move)
// Beispiel beim erzeugen eines Rechtecks. MouseDown muss ohne
// ModKey erfolgen, weil sonst i.d.R. Markieren forciert wird (s.u.)
// Drueckt man dann beim MouseMove gleichzeitig Shift, Ctrl, und Alt,
// so erzeugt man ein zentrisches Quadrat ohne Fang.
// Die Doppelbelegung von Ortho und Shift stellt i.d.R. kein Problem dar,
// da sich beides meisst gegenseitig ausschliesst. Einzig Shear (das beim
// Verzerren, nicht dass beim Drehen) beruecksichtigt beides gleichzeitig.
// Dass muss der Anwender erstmal noch umschiffen (z.B. mit einer Hilfslinie).
#define MODKEY_NoSnap    bCtrl  /* Fang temporaer aus */
#define MODKEY_Ortho     bShift /* na eben ortho */
#define MODKEY_Center    bAlt   /* Zentrisch erzeugen/resizen */
#define MODKEY_AngleSnap bShift
#define MODKEY_CopyDrag  bCtrl  /* Draggen mit kopieren */

// irgendwo hinklicken (MouseDown)
#define MODKEY_PolyPoly  bAlt   /* Neues Poly bei InsPt und bei Create */
#define MODKEY_MultiMark bShift /* MarkObj ohne vorher UnmarkAll */
#define MODKEY_Unmark    bAlt   /* Unmark durch Rahmenaufziehen */
#define MODKEY_ForceMark bCtrl  /* Rahmenaufziehen erzwingen, auch wenn Obj an MausPos */
#define MODKEY_DeepMark  bAlt   /* MarkNextObj */
#define MODKEY_DeepBackw bShift /* MarkNextObj rueckwaerts */

SdrHitKind SdrView::PickAnything(const Point& rLogicPos, SdrViewEvent& rVEvt) const
{
	const OutputDevice* pOut=pActualOutDev;
	if (pOut==NULL)
	{
		pOut = GetFirstOutputDevice();
		//pOut=GetWin(0);
	}

	// #i73628# Use a non-changeable copy of he logic pos
	const Point aLocalLogicPosition(rLogicPos);

	sal_Bool bEditMode=IsEditMode();
	sal_Bool bPointMode=bEditMode && HasMarkablePoints();
	sal_Bool bGluePointMode=IsGluePointEditMode();
	sal_Bool bInsPolyPt=bPointMode && IsInsObjPointMode() && IsInsObjPointPossible();
	sal_Bool bInsGluePt=bGluePointMode && IsInsGluePointMode() && IsInsGluePointPossible();
	sal_Bool bIsTextEdit=IsTextEdit();
	sal_Bool bTextEditHit=IsTextEditHit(aLocalLogicPosition,0/*nHitTolLog*/);
	sal_Bool bTextEditSel=IsTextEditInSelectionMode();
	sal_Bool bShift=(rVEvt.nMouseCode & KEY_SHIFT) !=0;
	sal_Bool bCtrl=(rVEvt.nMouseCode & KEY_MOD1) !=0;
	sal_Bool bAlt=(rVEvt.nMouseCode & KEY_MOD2) !=0;
	SdrHitKind eHit=SDRHIT_NONE;
	SdrHdl* pHdl=pOut!=NULL && !bTextEditSel ? PickHandle(aLocalLogicPosition) : NULL;
	SdrPageView* pPV=NULL;
	SdrObject* pObj=NULL;
	SdrObject* pHitObj=NULL;
	sal_uInt16 nHitPassNum=0;
	sal_uInt16 nHlplIdx=0;
	sal_uInt16 nGlueId=0;
	sal_Bool bUnmarkedObjHit=sal_False;
	if (bTextEditHit || bTextEditSel)
	{
		eHit=SDRHIT_TEXTEDIT;
		bTextEditHit=sal_True;
	}
	else if (pHdl!=NULL)
	{
		eHit=SDRHIT_HANDLE; // Handle getroffen hat hoechste Prioritaet
	}
	else if (bEditMode && IsHlplVisible() && IsHlplFront() && pOut!=NULL && PickHelpLine(aLocalLogicPosition,nHitTolLog,*pOut,nHlplIdx,pPV))
	{
		eHit=SDRHIT_HELPLINE; // Hilfslinie im Vordergrund getroffen zum verschieben
	}
	else if (bGluePointMode && PickGluePoint(aLocalLogicPosition,pObj,nGlueId,pPV))
	{
		eHit=SDRHIT_GLUEPOINT; // nichtmarkierter Klebepunkt getroffen
	}
	else if (PickObj(aLocalLogicPosition,nHitTolLog,pHitObj,pPV,SDRSEARCH_DEEP|SDRSEARCH_MARKED,&pObj,NULL,&nHitPassNum))
	{
		eHit=SDRHIT_MARKEDOBJECT;
		::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( pObj );
		if( pTableObj )
		{
			sal_Int32 nX = 0, nY = 0;
			switch( pTableObj->CheckTableHit( aLocalLogicPosition, nX, nY, 0 ) )
			{
				case sdr::table::SDRTABLEHIT_CELL:
					eHit = SDRHIT_CELL;
					break;
				case sdr::table::SDRTABLEHIT_CELLTEXTAREA:
					eHit = SDRHIT_TEXTEDITOBJ;
					break;
				default:
					break;
			}
		}
	}
	else if (PickObj(aLocalLogicPosition,nHitTolLog,pHitObj,pPV,SDRSEARCH_DEEP|/*SDRSEARCH_TESTMARKABLE|*/SDRSEARCH_ALSOONMASTER|SDRSEARCH_WHOLEPAGE,&pObj,NULL,&nHitPassNum))
	{
		// MasterPages und WholePage fuer Macro und URL
		eHit=SDRHIT_UNMARKEDOBJECT;
		::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( pObj );
		if( pTableObj )
		{
			sal_Int32 nX = 0, nY = 0;
			switch( pTableObj->CheckTableHit( aLocalLogicPosition, nX, nY, 0 ) )
			{
				case sdr::table::SDRTABLEHIT_CELL:
					eHit = SDRHIT_CELL;
					break;
				case sdr::table::SDRTABLEHIT_CELLTEXTAREA:
					eHit = SDRHIT_TEXTEDITOBJ;
					break;
				default:
					break;
			}
		}
		bUnmarkedObjHit=sal_True;
	}
	else if (bEditMode && IsHlplVisible() && !IsHlplFront() && pOut!=NULL && PickHelpLine(aLocalLogicPosition,nHitTolLog,*pOut,nHlplIdx,pPV))
	{
		eHit=SDRHIT_HELPLINE; // Hilfslinie im Vordergrund getroffen zum verschieben
	}
	if (IsMacroMode() && eHit==SDRHIT_UNMARKEDOBJECT)
	{
		bool bRoot=pObj->HasMacro();
		sal_Bool bDeep=pObj!=pHitObj && pHitObj->HasMacro();
		sal_Bool bMid=sal_False; // Gruppierte Gruppe mit Macro getroffen?
		SdrObject* pMidObj=NULL;
		if (pObj!=pHitObj)
		{
			SdrObject* pObjTmp=NULL;
			pObjTmp=pHitObj->GetUpGroup();
			if (pObjTmp==pObj) pObjTmp=NULL;
			while (pObjTmp!=NULL)
			{
				if (pObjTmp->HasMacro())
				{
					bMid=sal_True;
					pMidObj=pObjTmp;
				}
				pObjTmp=pObjTmp->GetUpGroup();
				if (pObjTmp==pObj) pObjTmp=NULL;
			}
		}

		if (bDeep || bMid || bRoot)
		{
			SdrObjMacroHitRec aHitRec;
			aHitRec.aPos=aLocalLogicPosition;
			aHitRec.aDownPos=aLocalLogicPosition;
			aHitRec.nTol=nHitTolLog;
			aHitRec.pVisiLayer=&pPV->GetVisibleLayers();
			aHitRec.pPageView=pPV;
			if (bDeep) bDeep=pHitObj->IsMacroHit(aHitRec);
			if (bMid ) bMid =pMidObj->IsMacroHit(aHitRec);
			if (bRoot) bRoot=pObj->IsMacroHit(aHitRec);
			if (bRoot || bMid || bDeep)
			{
				// Prio: 1.Root, 2.Mid, 3.Deep
				rVEvt.pRootObj=pObj;
				if (!bRoot) pObj=pMidObj;
				if (!bRoot && !bMid) pObj=pHitObj;
				eHit=SDRHIT_MACRO;
			}
		}
	}
	// auf URL-Field checken
	if (IsMacroMode() && eHit==SDRHIT_UNMARKEDOBJECT)
	{
		SdrTextObj* pTextObj=PTR_CAST(SdrTextObj,pHitObj);
		if (pTextObj!=NULL && pTextObj->HasText())
		{
			bool bTEHit(pPV &&
                SdrObjectPrimitiveHit(*pTextObj, aLocalLogicPosition, 0, *pPV, &pPV->GetVisibleLayers(), true));

			if (bTEHit)
			{
				Rectangle aTextRect;
				Rectangle aAnchor;
				SdrOutliner* pOutliner = &pTextObj->ImpGetDrawOutliner();
				if( pTextObj->GetModel() )
					pOutliner = &pTextObj->GetModel()->GetHitTestOutliner();

				pTextObj->TakeTextRect( *pOutliner, aTextRect, sal_False, &aAnchor, sal_False );

				// #i73628# Use a text-relative position for hit test in hit test outliner
				Point aTemporaryTextRelativePosition(aLocalLogicPosition - aTextRect.TopLeft());

				// FitToSize berueksichtigen
				SdrFitToSizeType eFit=pTextObj->GetFitToSize();
				sal_Bool bFitToSize=(eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES);
				if (bFitToSize) {
					Fraction aX(aTextRect.GetWidth()-1,aAnchor.GetWidth()-1);
					Fraction aY(aTextRect.GetHeight()-1,aAnchor.GetHeight()-1);
					ResizePoint(aTemporaryTextRelativePosition,Point(),aX,aY);
				}
				// Drehung berueksichtigen
				const GeoStat& rGeo=pTextObj->GetGeoStat();
				if (rGeo.nDrehWink!=0) RotatePoint(aTemporaryTextRelativePosition,Point(),-rGeo.nSin,rGeo.nCos); // -sin fuer Unrotate
				// Laufschrift berueksichtigen fehlt noch ...
				if(pActualOutDev && pActualOutDev->GetOutDevType() == OUTDEV_WINDOW)
				{
					OutlinerView aOLV(pOutliner, (Window*)pActualOutDev);
					const EditView& aEV=aOLV.GetEditView();
					const SvxFieldItem* pItem=aEV.GetField(aTemporaryTextRelativePosition);
					if (pItem!=NULL) {
						const SvxFieldData* pFld=pItem->GetField();
						const SvxURLField* pURL=PTR_CAST(SvxURLField,pFld);
						if (pURL!=NULL) {
							eHit=SDRHIT_URLFIELD;
							rVEvt.pURLField=pURL;
						}
					}
				}
			}
		}
	}

	if (nHitPassNum==SDRSEARCHPASS_DIRECT &&
		(eHit==SDRHIT_MARKEDOBJECT || eHit==SDRHIT_UNMARKEDOBJECT) &&
		(IsTextTool() || (IsEditMode() && IsQuickTextEditMode())) && pHitObj->HasTextEdit())
	{
		// Ringsum die TextEditArea ein Rand zum Selektieren ohne Textedit
		Rectangle aBoundRect(pHitObj->GetCurrentBoundRect());

		// #105130# Force to SnapRect when Fontwork
		if(pHitObj->ISA(SdrTextObj) && ((SdrTextObj*)pHitObj)->IsFontwork())
		{
			aBoundRect = pHitObj->GetSnapRect();
		}

		// #105130# Old test for hit on BoundRect is completely wrong
		// and never worked, doing it new here.
		sal_Int32 nTolerance(nHitTolLog);
		sal_Bool bBoundRectHit(sal_False);

		if(pOut)
		{
			nTolerance = pOut->PixelToLogic(Size(2, 0)).Width();
		}

		if(	(aLocalLogicPosition.X() >= aBoundRect.Left() - nTolerance && aLocalLogicPosition.X() <= aBoundRect.Left() + nTolerance)
		 || (aLocalLogicPosition.X() >= aBoundRect.Right() - nTolerance && aLocalLogicPosition.X() <= aBoundRect.Right() + nTolerance)
		 || (aLocalLogicPosition.Y() >= aBoundRect.Top() - nTolerance && aLocalLogicPosition.Y() <= aBoundRect.Top() + nTolerance)
		 || (aLocalLogicPosition.Y() >= aBoundRect.Bottom() - nTolerance && aLocalLogicPosition.Y() <= aBoundRect.Bottom() + nTolerance))
		{
			bBoundRectHit = sal_True;
		}

		if(!bBoundRectHit)
		{
			bool bTEHit(pPV &&
                SdrObjectPrimitiveHit(*pHitObj, aLocalLogicPosition, 0, *pPV, &pPV->GetVisibleLayers(), true));

			// TextEdit an Objekten im gesperrten Layer
			if (pPV->GetLockedLayers().IsSet(pHitObj->GetLayer()))
            {
				bTEHit=sal_False;
            }

			if (bTEHit)
			{
				rVEvt.pRootObj=pObj;
				pObj=pHitObj;
				eHit=SDRHIT_TEXTEDITOBJ;
			}
		}
	}
	if (nHitPassNum!=SDRSEARCHPASS_DIRECT && eHit==SDRHIT_UNMARKEDOBJECT) {
		eHit=SDRHIT_NONE;
		pObj=NULL;
		pPV=NULL;
	}
	sal_Bool bMouseLeft=(rVEvt.nMouseCode&MOUSE_LEFT)!=0;
	sal_Bool bMouseRight=(rVEvt.nMouseCode&MOUSE_RIGHT)!=0;
	sal_Bool bMouseDown=rVEvt.bMouseDown;
	sal_Bool bMouseUp=rVEvt.bMouseUp;
	SdrEventKind eEvent=SDREVENT_NONE;
	sal_Bool bIsAction=IsAction();

	if (bIsAction)
	{
		if (bMouseDown)
		{
			if (bMouseRight) eEvent=SDREVENT_BCKACTION;
		}
		else if (bMouseUp)
		{
			if (bMouseLeft)
			{
				eEvent=SDREVENT_ENDACTION;
				if (IsDragObj())
				{
					eEvent=SDREVENT_ENDDRAG;
					rVEvt.bDragWithCopy=MODKEY_CopyDrag;
				}
				else if (IsCreateObj() || IsInsObjPoint())
				{
					eEvent=IsCreateObj() ? SDREVENT_ENDCREATE : SDREVENT_ENDINSOBJPOINT;
					rVEvt.eEndCreateCmd=SDRCREATE_NEXTPOINT;
					if (MODKEY_PolyPoly) rVEvt.eEndCreateCmd=SDRCREATE_NEXTOBJECT;
					if (rVEvt.nMouseClicks>1) rVEvt.eEndCreateCmd=SDRCREATE_FORCEEND;
				}
				else if (IsMarking())
				{
					eEvent=SDREVENT_ENDMARK;
					if (!aDragStat.IsMinMoved())
					{
						eEvent=SDREVENT_BRKMARK;
						rVEvt.bAddMark=MODKEY_MultiMark;
					}
				}
			}
		}
		else
		{
			eEvent=SDREVENT_MOVACTION;
		}
	}
	else if (eHit==SDRHIT_TEXTEDIT)
	{
		eEvent=SDREVENT_TEXTEDIT;
	}
	else if (bMouseDown && bMouseLeft)
	{
		if (rVEvt.nMouseClicks==2 && rVEvt.nMouseCode==MOUSE_LEFT && pObj!=NULL && pHitObj!=NULL && pHitObj->HasTextEdit() && eHit==SDRHIT_MARKEDOBJECT)
		{
			rVEvt.pRootObj=pObj;
			pObj=pHitObj;
			eEvent=SDREVENT_BEGTEXTEDIT;
		}
		else if (MODKEY_ForceMark && eHit!=SDRHIT_URLFIELD)
		{
			eEvent=SDREVENT_BEGMARK; // AddMark,Unmark */
		}
		else if (eHit==SDRHIT_HELPLINE)
		{
			eEvent=SDREVENT_BEGDRAGHELPLINE; // nix weiter
		}
		else if (eHit==SDRHIT_GLUEPOINT)
		{
			eEvent=SDREVENT_MARKGLUEPOINT; // AddMark+Drag
			rVEvt.bAddMark=MODKEY_MultiMark || MODKEY_DeepMark; // falls bei Deep nicht getroffen
		}
		else if (eHit==SDRHIT_HANDLE)
		{
			eEvent=SDREVENT_BEGDRAGOBJ;    // Mark+Drag,AddMark+Drag,DeepMark+Drag,Unmark
			sal_Bool bGlue=pHdl->GetKind()==HDL_GLUE;
			sal_Bool bPoly=!bGlue && IsPointMarkable(*pHdl);
			sal_Bool bMarked=bGlue || bPoly && pHdl->IsSelected();
			if (bGlue || bPoly)
			{
				eEvent=bGlue ? SDREVENT_MARKGLUEPOINT : SDREVENT_MARKPOINT;
				if (MODKEY_DeepMark)
				{
					rVEvt.bAddMark=sal_True;
					rVEvt.bPrevNextMark=sal_True;
					rVEvt.bMarkPrev=MODKEY_DeepBackw;
				}
				else if (MODKEY_MultiMark)
				{
					rVEvt.bAddMark=sal_True;
					rVEvt.bUnmark=bMarked; // Toggle
					if (bGlue)
					{
						pObj=pHdl->GetObj();
						nGlueId=(sal_uInt16)pHdl->GetObjHdlNum();
					}
				}
				else if (bMarked)
				{
					eEvent=SDREVENT_BEGDRAGOBJ; // MarkState nicht aendern, nur Drag
				}
			}
		}
		else if (bInsPolyPt && (MODKEY_PolyPoly || (!MODKEY_MultiMark && !MODKEY_DeepMark)))
		{
			eEvent=SDREVENT_BEGINSOBJPOINT;
			rVEvt.bInsPointNewObj=MODKEY_PolyPoly;
		}
		else if (bInsGluePt && !MODKEY_MultiMark && !MODKEY_DeepMark)
		{
			eEvent=SDREVENT_BEGINSGLUEPOINT;
		}
		else if (eHit==SDRHIT_TEXTEDITOBJ)
		{
			eEvent=SDREVENT_BEGTEXTEDIT; // AddMark+Drag,DeepMark+Drag,Unmark
			if (MODKEY_MultiMark || MODKEY_DeepMark)
			{ // falls bei Deep nicht getroffen
				eEvent=SDREVENT_MARKOBJ;
			}
		}
		else if (eHit==SDRHIT_MACRO)
		{
			eEvent=SDREVENT_BEGMACROOBJ;       // AddMark+Drag
			if (MODKEY_MultiMark || MODKEY_DeepMark)
			{ // falls bei Deep nicht getroffen
				eEvent=SDREVENT_MARKOBJ;
			}
		}
		else if (eHit==SDRHIT_URLFIELD)
		{
			eEvent=SDREVENT_EXECUTEURL;       // AddMark+Drag
			if (MODKEY_MultiMark || MODKEY_DeepMark)
			{ // falls bei Deep nicht getroffen
				eEvent=SDREVENT_MARKOBJ;
			}
		}
		else if (eHit==SDRHIT_MARKEDOBJECT)
		{
			eEvent=SDREVENT_BEGDRAGOBJ; // DeepMark+Drag,Unmark

			if (MODKEY_MultiMark || MODKEY_DeepMark)
			{ // falls bei Deep nicht getroffen
				eEvent=SDREVENT_MARKOBJ;
			}
		}
		else if (IsCreateMode())
		{
			eEvent=SDREVENT_BEGCREATEOBJ;          // Nix weiter
		}
		else if (eHit==SDRHIT_UNMARKEDOBJECT)
		{
			eEvent=SDREVENT_MARKOBJ;  // AddMark+Drag
		}
		else
		{
			eEvent=SDREVENT_BEGMARK;
		}

		if (eEvent==SDREVENT_MARKOBJ)
		{
			rVEvt.bAddMark=MODKEY_MultiMark || MODKEY_DeepMark; // falls bei Deep nicht getroffen
			rVEvt.bPrevNextMark=MODKEY_DeepMark;
			rVEvt.bMarkPrev=MODKEY_DeepMark && MODKEY_DeepBackw;
		}
		if (eEvent==SDREVENT_BEGMARK)
		{
			rVEvt.bAddMark=MODKEY_MultiMark;
			rVEvt.bUnmark=MODKEY_Unmark;
		}
	}
	rVEvt.bIsAction=bIsAction;
	rVEvt.bIsTextEdit=bIsTextEdit;
	rVEvt.bTextEditHit=bTextEditHit;
	rVEvt.aLogicPos=aLocalLogicPosition;
	rVEvt.pHdl=pHdl;
	rVEvt.pObj=pObj;
	if(rVEvt.pRootObj==NULL)
		rVEvt.pRootObj=pObj;
	rVEvt.pPV=pPV;
	rVEvt.nHlplIdx=nHlplIdx;
	rVEvt.nGlueId=nGlueId;
	rVEvt.eHit=eHit;
	rVEvt.eEvent=eEvent;
	rVEvt.bCaptureMouse=bMouseLeft && bMouseDown && eEvent!=SDREVENT_NONE;
	rVEvt.bReleaseMouse=bMouseLeft && bMouseUp;
#ifdef DGB_UTIL
	if (rVEvt.pRootObj!=NULL) {
		if (rVEvt.pRootObj->GetObjList()!=rVEvt.pPV->GetObjList()) {
			DBG_ERROR("SdrView::PickAnything(): pRootObj->GetObjList()!=pPV->GetObjList() !");
		}
	}
#endif
	return eHit;
}

sal_Bool SdrView::DoMouseEvent(const SdrViewEvent& rVEvt)
{
	sal_Bool bRet=sal_False;
	SdrHitKind eHit=rVEvt.eHit;
	Point aLogicPos(rVEvt.aLogicPos);

	sal_Bool bShift=(rVEvt.nMouseCode & KEY_SHIFT) !=0;
	sal_Bool bCtrl=(rVEvt.nMouseCode & KEY_MOD1) !=0;
	sal_Bool bAlt=(rVEvt.nMouseCode & KEY_MOD2) !=0;
	sal_Bool bMouseLeft=(rVEvt.nMouseCode&MOUSE_LEFT)!=0;
	//sal_Bool bMouseRight=(rVEvt.nMouseCode&MOUSE_RIGHT)!=0;
	sal_Bool bMouseDown=rVEvt.bMouseDown;
	sal_Bool bMouseUp=rVEvt.bMouseUp;
	if (bMouseDown) {
		if (bMouseLeft) aDragStat.SetMouseDown(sal_True);
	} else if (bMouseUp) {
		if (bMouseLeft) aDragStat.SetMouseDown(sal_False);
	} else { // else MouseMove
		aDragStat.SetMouseDown(bMouseLeft);
	}

#ifdef MODKEY_NoSnap
	SetSnapEnabled(!MODKEY_NoSnap);
#endif
#ifdef MODKEY_Ortho
	SetOrtho(MODKEY_Ortho!=IsOrthoDesired());
#endif
#ifdef MODKEY_BigOrtho
	SetBigOrtho(MODKEY_BigOrtho);
#endif
#ifdef MODKEY_AngleSnap
	SetAngleSnapEnabled(MODKEY_AngleSnap);
#endif
#ifdef MODKEY_CopyDrag
	SetDragWithCopy(MODKEY_CopyDrag);
#endif
#ifdef MODKEY_Center
	SetCreate1stPointAsCenter(MODKEY_Center);
	SetResizeAtCenter(MODKEY_Center);
	SetCrookAtCenter(MODKEY_Center);
#endif
	if (bMouseLeft && bMouseDown && rVEvt.bIsTextEdit && (eHit==SDRHIT_UNMARKEDOBJECT || eHit==SDRHIT_NONE)) {
		SdrEndTextEdit(); // Danebengeklickt, Ende mit Edit
		// pHdl ist dann ungueltig. Sollte aber egal sein, wein pHdl==NULL
		// sein muesste (wg. eHit).
	}
	switch (rVEvt.eEvent) {
		case SDREVENT_NONE: bRet=sal_False; break;
		case SDREVENT_TEXTEDIT: bRet=sal_False; break; // Events an die OutlinerView werden hier nicht beruecksichtigt
		case SDREVENT_MOVACTION: MovAction(aLogicPos); bRet=sal_True; break;
		case SDREVENT_ENDACTION: EndAction(); bRet=sal_True; break;
		case SDREVENT_BCKACTION: BckAction(); bRet=sal_True; break;
		case SDREVENT_BRKACTION: BrkAction(); bRet=sal_True; break;
		case SDREVENT_ENDMARK  : EndAction(); bRet=sal_True; break;
		case SDREVENT_BRKMARK  : {
			BrkAction();
			if (!MarkObj(aLogicPos,nHitTolLog,rVEvt.bAddMark)) {
				// Kein Obj getroffen. Dann werden zuerst
				// - Markierte Klebepunkte deselektiert
				// - dann ggf. selektierte Polygonpunkte
				// - und ansonsten Objekte
				if (!rVEvt.bAddMark) UnmarkAll();
			}
			bRet=sal_True;
		} break;
		case SDREVENT_ENDCREATE: { // ggf. MarkObj
			SdrCreateCmd eCmd=SDRCREATE_NEXTPOINT;
			if (MODKEY_PolyPoly) eCmd=SDRCREATE_NEXTOBJECT;
			if (rVEvt.nMouseClicks>1) eCmd=SDRCREATE_FORCEEND;
			if (!EndCreateObj(eCmd)) { // Event fuer Create nicht ausgewerten? -> Markieren
				if (eHit==SDRHIT_UNMARKEDOBJECT || eHit==SDRHIT_TEXTEDIT) {
					MarkObj(rVEvt.pRootObj,rVEvt.pPV);
					if (eHit==SDRHIT_TEXTEDIT)
					{
						sal_Bool bRet2(pActualOutDev && OUTDEV_WINDOW == pActualOutDev->GetOutDevType() &&
							SdrBeginTextEdit(rVEvt.pObj, rVEvt.pPV, (Window*)pActualOutDev, sal_False, (SdrOutliner*)0L));

						if(bRet2)
						{
							MouseEvent aMEvt(pActualOutDev->LogicToPixel(aLogicPos),
											 1,rVEvt.nMouseMode,rVEvt.nMouseCode,rVEvt.nMouseCode);

							OutlinerView* pOLV=GetTextEditOutlinerView();
							if (pOLV!=NULL) {
								pOLV->MouseButtonDown(aMEvt); // Event an den Outliner, aber ohne Doppelklick
								pOLV->MouseButtonUp(aMEvt); // Event an den Outliner, aber ohne Doppelklick
							}
						}
					}
					bRet=sal_True; // Obj markiert und ggf. TextEdit gestartet
				} else bRet=sal_False; // Create abgebrochen, sonst nix weiter.
			} else bRet=sal_True; // EndCreate mit sal_True returniert
		} break;
		case SDREVENT_ENDDRAG: {
			bRet=EndDragObj(IsDragWithCopy());
			ForceMarkedObjToAnotherPage(); // Undo+Klammerung fehlt noch !!!
		} break;
		case SDREVENT_MARKOBJ: { // + ggf. BegDrag
			if (!rVEvt.bAddMark) UnmarkAllObj();
			sal_Bool bUnmark=rVEvt.bUnmark;
			if (rVEvt.bPrevNextMark) {
				bRet=MarkNextObj(aLogicPos,nHitTolLog,rVEvt.bMarkPrev);
			} else {
				SortMarkedObjects();
				sal_uIntPtr nAnz0=GetMarkedObjectCount();
				bRet=MarkObj(aLogicPos,nHitTolLog,rVEvt.bAddMark);
				SortMarkedObjects();
				sal_uIntPtr nAnz1=GetMarkedObjectCount();
				bUnmark=nAnz1<nAnz0;
			}
			if (!bUnmark) {
				BegDragObj(aLogicPos,NULL,(SdrHdl*)NULL,nMinMovLog);
				bRet=sal_True;
			}
		} break;
		case SDREVENT_MARKPOINT: { // + ggf. BegDrag
			if (!rVEvt.bAddMark) UnmarkAllPoints();
			if (rVEvt.bPrevNextMark) {
				bRet=MarkNextPoint(aLogicPos,rVEvt.bMarkPrev);
			} else {
				bRet=MarkPoint(*rVEvt.pHdl,rVEvt.bUnmark);
			}
			if (!rVEvt.bUnmark && !rVEvt.bPrevNextMark) {
				BegDragObj(aLogicPos,NULL,rVEvt.pHdl,nMinMovLog);
				bRet=sal_True;
			}
		} break;
		case SDREVENT_MARKGLUEPOINT: { // + ggf. BegDrag
			if (!rVEvt.bAddMark) UnmarkAllGluePoints();
			if (rVEvt.bPrevNextMark) {
				bRet=MarkNextGluePoint(aLogicPos,rVEvt.bMarkPrev);
			} else {
				bRet=MarkGluePoint(rVEvt.pObj,rVEvt.nGlueId,rVEvt.pPV,rVEvt.bUnmark);
			}
			if (!rVEvt.bUnmark && !rVEvt.bPrevNextMark) {
				SdrHdl* pHdl=GetGluePointHdl(rVEvt.pObj,rVEvt.nGlueId);
				BegDragObj(aLogicPos,NULL,pHdl,nMinMovLog);
				bRet=sal_True;
			}
		} break;
		case SDREVENT_BEGMARK: bRet=BegMark(aLogicPos,rVEvt.bAddMark,rVEvt.bUnmark); break;
		case SDREVENT_BEGINSOBJPOINT: bRet = BegInsObjPoint(aLogicPos, MODKEY_PolyPoly); break;
		case SDREVENT_ENDINSOBJPOINT: {
			SdrCreateCmd eCmd=SDRCREATE_NEXTPOINT;
			if (MODKEY_PolyPoly) eCmd=SDRCREATE_NEXTOBJECT;
			if (rVEvt.nMouseClicks>1) eCmd=SDRCREATE_FORCEEND;
			EndInsObjPoint(eCmd);
			bRet=sal_True;
		} break;
		case SDREVENT_BEGINSGLUEPOINT: bRet=BegInsGluePoint(aLogicPos); break;
		case SDREVENT_BEGDRAGHELPLINE: bRet=BegDragHelpLine(rVEvt.nHlplIdx,rVEvt.pPV); break;
		case SDREVENT_BEGDRAGOBJ: bRet=BegDragObj(aLogicPos,NULL,rVEvt.pHdl,nMinMovLog); break;
		case SDREVENT_BEGCREATEOBJ: {
			if (nAktInvent==SdrInventor && nAktIdent==OBJ_CAPTION) {
				long nHgt=SdrEngineDefaults::GetFontHeight();
				bRet=BegCreateCaptionObj(aLogicPos,Size(5*nHgt,2*nHgt));
			} else bRet=BegCreateObj(aLogicPos);
		} break;
		case SDREVENT_BEGMACROOBJ: bRet=BegMacroObj(aLogicPos,nHitTolLog,rVEvt.pObj,rVEvt.pPV,(Window*)pActualOutDev); break;
		case SDREVENT_BEGTEXTEDIT: {
			if (!IsObjMarked(rVEvt.pObj)) {
				UnmarkAllObj();
				MarkObj(rVEvt.pRootObj,rVEvt.pPV);
			}

			bRet = pActualOutDev && OUTDEV_WINDOW == pActualOutDev->GetOutDevType()&&
				 SdrBeginTextEdit(rVEvt.pObj, rVEvt.pPV, (Window*)pActualOutDev, sal_False, (SdrOutliner*)0L);

			if(bRet)
			{
				MouseEvent aMEvt(pActualOutDev->LogicToPixel(aLogicPos),
								 1,rVEvt.nMouseMode,rVEvt.nMouseCode,rVEvt.nMouseCode);
				OutlinerView* pOLV=GetTextEditOutlinerView();
				if (pOLV!=NULL) pOLV->MouseButtonDown(aMEvt); // Event an den Outliner, aber ohne Doppelklick
			}
		} break;
		default: break;
	} // switch
	if (bRet && pActualOutDev!=NULL && pActualOutDev->GetOutDevType()==OUTDEV_WINDOW) {
		Window* pWin=(Window*)pActualOutDev;
		// Maus links gedrueckt?
		sal_Bool bLeftDown=(rVEvt.nMouseCode&MOUSE_LEFT)!=0 && rVEvt.bMouseDown;
		// Maus links losgelassen?
		sal_Bool bLeftUp=(rVEvt.nMouseCode&MOUSE_LEFT)!=0 && rVEvt.bMouseUp;
		// Maus links gedrueckt oder gehalten?
		sal_Bool bLeftDown1=(rVEvt.nMouseCode&MOUSE_LEFT)!=0 && !rVEvt.bMouseUp;
		pWin->SetPointer(GetPreferedPointer(rVEvt.aLogicPos,pWin,
				rVEvt.nMouseCode & (KEY_SHIFT|KEY_MOD1|KEY_MOD2),bLeftDown1));
		sal_Bool bAction=IsAction();
		if (bLeftDown && bAction) pWin->CaptureMouse();
		else if (bLeftUp || (rVEvt.bIsAction && !bAction)) pWin->ReleaseMouse();
	}
	return bRet;
}
#include <editeng/outlobj.hxx>

Pointer SdrView::GetPreferedPointer(const Point& rMousePos, const OutputDevice* pOut, sal_uInt16 nModifier, sal_Bool bLeftDown) const
{
	// Actions
	if (IsCreateObj())
	{
		return pAktCreate->GetCreatePointer();
	}
	if (mpCurrentSdrDragMethod)
	{
		if ((IsDraggingPoints() || IsDraggingGluePoints()) && IsMouseHideWhileDraggingPoints())
			return Pointer(POINTER_NULL);

		return mpCurrentSdrDragMethod->GetSdrDragPointer();
	}
	if (IsMarkObj() || IsMarkPoints() || IsMarkGluePoints() || IsEncirclement() || IsSetPageOrg()) return Pointer(POINTER_ARROW);
	if (IsDragHelpLine()) return GetDraggedHelpLinePointer();
	if (IsMacroObj()) {
		SdrObjMacroHitRec aHitRec;
		aHitRec.aPos=pOut->LogicToPixel(rMousePos);
		aHitRec.aDownPos=aMacroDownPos;
		aHitRec.nTol=nMacroTol;
		aHitRec.pVisiLayer=&pMacroPV->GetVisibleLayers();
		aHitRec.pPageView=pMacroPV;
		aHitRec.pOut=pMacroWin;
		aHitRec.bDown=bMacroDown;
		return pMacroObj->GetMacroPointer(aHitRec);
	}
	//sal_uInt16 nTol=nHitTolLog;
	// TextEdit, ObjEdit, Macro
	if (IsTextEdit() && (IsTextEditInSelectionMode() || IsTextEditHit(rMousePos,0/*nTol*/)))
	{
		if(!pOut || IsTextEditInSelectionMode())
		{
			if(pTextEditOutliner->IsVertical())
				return Pointer(POINTER_TEXT_VERTICAL);
			else
				return Pointer(POINTER_TEXT);
		}
		// hier muss besser der Outliner was liefern:
		Point aPos(pOut->LogicToPixel(rMousePos));
		Pointer aPointer(pTextEditOutlinerView->GetPointer(aPos));
		if (aPointer==POINTER_ARROW)
		{
			if(pTextEditOutliner->IsVertical())
				aPointer = POINTER_TEXT_VERTICAL;
			else
				aPointer = POINTER_TEXT;
		}
		return aPointer;
	}

	SdrViewEvent aVEvt;
	aVEvt.nMouseCode=(nModifier&(KEY_SHIFT|KEY_MOD1|KEY_MOD2))|MOUSE_LEFT; // um zu sehen, was bei MouseLeftDown passieren wuerde
	aVEvt.bMouseDown=!bLeftDown; // Was waere wenn ...
	aVEvt.bMouseUp=bLeftDown;    // Was waere wenn ...
	if (pOut!=NULL)
		((SdrView*)this)->SetActualWin(pOut);
	SdrHitKind eHit=PickAnything(rMousePos,aVEvt);
	SdrEventKind eEvent=aVEvt.eEvent;
	switch (eEvent)
	{
		case SDREVENT_BEGCREATEOBJ:
			return aAktCreatePointer;
		case SDREVENT_MARKOBJ:
		case SDREVENT_BEGMARK:
			return Pointer(POINTER_ARROW);
		case SDREVENT_MARKPOINT:
		case SDREVENT_MARKGLUEPOINT:
			return Pointer(POINTER_MOVEPOINT);
		case SDREVENT_BEGINSOBJPOINT:
		case SDREVENT_BEGINSGLUEPOINT:
			return Pointer(POINTER_CROSS);
		case SDREVENT_EXECUTEURL:
			return Pointer(POINTER_REFHAND);
		case SDREVENT_BEGMACROOBJ:
		{
			SdrObjMacroHitRec aHitRec;
			aHitRec.aPos=aVEvt.aLogicPos;
			aHitRec.aDownPos=aHitRec.aPos;
			aHitRec.nTol=nHitTolLog;
			aHitRec.pVisiLayer=&aVEvt.pPV->GetVisibleLayers();
			aHitRec.pPageView=aVEvt.pPV;
			aHitRec.pOut=(OutputDevice*)pOut;
			return aVEvt.pObj->GetMacroPointer(aHitRec);
		}
		default: break;
	} // switch

	switch(eHit)
	{
		case SDRHIT_CELL:
			return Pointer(POINTER_ARROW);
		case SDRHIT_HELPLINE :
			return aVEvt.pPV->GetHelpLines()[aVEvt.nHlplIdx].GetPointer();
		case SDRHIT_GLUEPOINT:
			return Pointer(POINTER_MOVEPOINT);
		case SDRHIT_TEXTEDIT :
		case SDRHIT_TEXTEDITOBJ:
		{
			SdrTextObj* pText = dynamic_cast< SdrTextObj* >( aVEvt.pObj );
			if(pText && pText->HasText())
			{
				OutlinerParaObject* pParaObj = pText->GetOutlinerParaObject();
				if(pParaObj && pParaObj->IsVertical())
					return Pointer(POINTER_TEXT_VERTICAL);
			}
			return Pointer(POINTER_TEXT);
		}
		default: break;
	}

	sal_Bool bMarkHit=eHit==SDRHIT_MARKEDOBJECT;
	SdrHdl* pHdl=aVEvt.pHdl;
	// Nun die Pointer fuer Dragging checken
	if (pHdl!=NULL || bMarkHit) {
		SdrHdlKind eHdl= pHdl!=NULL ? pHdl->GetKind() : HDL_MOVE;
		sal_Bool bCorner=pHdl!=NULL && pHdl->IsCornerHdl();
		sal_Bool bVertex=pHdl!=NULL && pHdl->IsVertexHdl();
		sal_Bool bMov=eHdl==HDL_MOVE;
		if (bMov && (eDragMode==SDRDRAG_MOVE || eDragMode==SDRDRAG_RESIZE || bMarkedHitMovesAlways)) {
			if (!IsMoveAllowed()) return Pointer(POINTER_ARROW); // weil Doppelklick oder Drag&Drop moeglich
			return Pointer(POINTER_MOVE);
		}
		switch (eDragMode) {
			case SDRDRAG_ROTATE: {
				if ((bCorner || bMov) && !IsRotateAllowed(sal_True))
					return Pointer(POINTER_NOTALLOWED);

				// Sind 3D-Objekte selektiert?
				sal_Bool b3DObjSelected = sal_False;
#ifndef SVX_LIGHT
				for (sal_uInt32 a=0; !b3DObjSelected && a<GetMarkedObjectCount(); a++) {
					SdrObject* pObj = GetMarkedObjectByIndex(a);
					if(pObj && pObj->ISA(E3dObject))
						b3DObjSelected = sal_True;
				}
#endif
				// Falls es um ein 3D-Objekt geht, muss trotz !IsShearAllowed
				// weitergemacht werden, da es sich um eine Rotation statt um
				// einen Shear handelt
				if (bVertex && !IsShearAllowed() && !b3DObjSelected)
					return Pointer(POINTER_NOTALLOWED);
				if (bMov)
					return Pointer(POINTER_ROTATE);
			} break;
			case SDRDRAG_SHEAR: case SDRDRAG_DISTORT: {
				if (bCorner) {
					if (!IsDistortAllowed(sal_True) && !IsDistortAllowed(sal_False)) return Pointer(POINTER_NOTALLOWED);
					else return Pointer(POINTER_REFHAND);
				}
				if (bVertex && !IsShearAllowed()) return Pointer(POINTER_NOTALLOWED);
				if (bMov) {
					if (!IsMoveAllowed()) return Pointer(POINTER_ARROW); // weil Doppelklick oder Drag&Drop moeglich
					return Pointer(POINTER_MOVE);
				}
			} break;
			case SDRDRAG_MIRROR: {
				if (bCorner || bVertex || bMov) {
					SdrHdl* pH1=aHdl.GetHdl(HDL_REF1);
					SdrHdl* pH2=aHdl.GetHdl(HDL_REF2);
					sal_Bool b90=sal_False;
					sal_Bool b45=sal_False;
					Point aDif;
					if (pH1!=NULL && pH2!=NULL) {
						aDif=pH2->GetPos()-pH1->GetPos();
						b90=(aDif.X()==0) || aDif.Y()==0;
						b45=b90 || (Abs(aDif.X())==Abs(aDif.Y()));
					}
					sal_Bool bNo=sal_False;
					if (!IsMirrorAllowed(sal_True,sal_True)) bNo=sal_True; // Spiegeln ueberhaupt nicht erlaubt
					if (!IsMirrorAllowed(sal_False,sal_False) && !b45) bNo=sal_True; // freies Spiegeln nicht erlaubt
					if (!IsMirrorAllowed(sal_True,sal_False) && !b90) bNo=sal_True;  // Spiegeln hor/ver erlaubt
					if (bNo) return Pointer(POINTER_NOTALLOWED);
					if (b90) {
						return Pointer(POINTER_MIRROR);
					}
					return Pointer(POINTER_MIRROR);
				}
			} break;

			case SDRDRAG_TRANSPARENCE:
			{
				if(!IsTransparenceAllowed())
					return Pointer(POINTER_NOTALLOWED);

				return Pointer(POINTER_REFHAND);
			}

			case SDRDRAG_GRADIENT:
			{
				if(!IsGradientAllowed())
					return Pointer(POINTER_NOTALLOWED);

				return Pointer(POINTER_REFHAND);
			}

			case SDRDRAG_CROOK: {
				if (bCorner || bVertex || bMov) {
					if (!IsCrookAllowed(sal_True) && !IsCrookAllowed(sal_False)) return Pointer(POINTER_NOTALLOWED);
					return Pointer(POINTER_CROOK);
				}
			}

			case SDRDRAG_CROP:
			{
				return Pointer(POINTER_CROP);
			}

			default: {
				if ((bCorner || bVertex) && !IsResizeAllowed(sal_True)) return Pointer(POINTER_NOTALLOWED);
			}
		}
		if (pHdl!=NULL) return pHdl->GetPointer();
		if (bMov) {
			if (!IsMoveAllowed()) return Pointer(POINTER_ARROW); // weil Doppelklick oder Drag&Drop moeglich
			return Pointer(POINTER_MOVE);
		}
	}
	if (eEditMode==SDREDITMODE_CREATE) return aAktCreatePointer;
	return Pointer(POINTER_ARROW);
}

XubString SdrView::GetStatusText()
{
	XubString aStr;
	XubString aName;

	aStr.AppendAscii("nix");

	if (pAktCreate!=NULL)
	{
		aStr=pAktCreate->getSpecialDragComment(aDragStat);

		if(!aStr.Len())
		{
			pAktCreate->TakeObjNameSingul(aName);
			aStr = ImpGetResStr(STR_ViewCreateObj);
		}
	}
	else if (mpCurrentSdrDragMethod)
	{
		if (bInsPolyPoint || IsInsertGluePoint())
		{
			aStr=aInsPointUndoStr;
		}
		else
		{
			if (aDragStat.IsMinMoved())
			{
				OSL_TRACE("SdrView::GetStatusText(%lx) %lx\n", this, mpCurrentSdrDragMethod);
				mpCurrentSdrDragMethod->TakeSdrDragComment(aStr);
			}
		}
	}
	else if(IsMarkObj())
	{
		if(AreObjectsMarked())
		{
			aStr = ImpGetResStr(STR_ViewMarkMoreObjs);
		}
		else
		{
			aStr = ImpGetResStr(STR_ViewMarkObjs);
		}
	}
	else if(IsMarkPoints())
	{
		if(HasMarkedPoints())
		{
			aStr = ImpGetResStr(STR_ViewMarkMorePoints);
		}
		else
		{
			aStr = ImpGetResStr(STR_ViewMarkPoints);
		}
	} else if (IsMarkGluePoints())
	{
		if(HasMarkedGluePoints())
		{
			aStr = ImpGetResStr(STR_ViewMarkMoreGluePoints);
		}
		else
		{
			aStr = ImpGetResStr(STR_ViewMarkGluePoints);
		}
	}
	else if (IsTextEdit() && pTextEditOutlinerView!=NULL) {
		aStr=ImpGetResStr(STR_ViewTextEdit); // "TextEdit - Zeile y  Spalte x";
		ESelection aSel(pTextEditOutlinerView->GetSelection());
		long nPar=aSel.nEndPara,nLin=0,nCol=aSel.nEndPos;
		if (aSel.nEndPara>0) {
			for (sal_uInt32 nParaNum=0; nParaNum<aSel.nEndPara; nParaNum++) {
				nLin+=pTextEditOutliner->GetLineCount(nParaNum);
			}
		}
		// Noch 'ne kleine Unschoenheit:
		// Am Ende einer Zeile eines mehrzeiligen Absatzes wird die Position
		// der naechsten Zeile des selben Absatzes angezeigt, so es eine solche
		// gibt.
		sal_uInt16 nParaLine=0;
		sal_uIntPtr nParaLineAnz=pTextEditOutliner->GetLineCount(aSel.nEndPara);
		sal_Bool bBrk=sal_False;
		while (!bBrk) {
			sal_uInt16 nLen=pTextEditOutliner->GetLineLen(aSel.nEndPara,nParaLine);
			sal_Bool bLastLine=(nParaLine==nParaLineAnz-1);
			if (nCol>nLen || (!bLastLine && nCol==nLen)) {
				nCol-=nLen;
				nLin++;
				nParaLine++;
			} else bBrk=sal_True;
			if (nLen==0) bBrk=sal_True; // Sicherheitshalber
		}

		aStr.SearchAndReplaceAscii("%1", UniString::CreateFromInt32(nPar + 1));
		aStr.SearchAndReplaceAscii("%2", UniString::CreateFromInt32(nLin + 1));
		aStr.SearchAndReplaceAscii("%3", UniString::CreateFromInt32(nCol + 1));

#ifdef DBG_UTIL
		aStr += UniString( RTL_CONSTASCII_USTRINGPARAM( ", Level " ) );
		aStr += UniString::CreateFromInt32( pTextEditOutliner->GetDepth( aSel.nEndPara ) );
#endif
	}

	if(aStr.EqualsAscii("nix"))
	{
		if (AreObjectsMarked()) {
			ImpTakeDescriptionStr(STR_ViewMarked,aStr);
			if (IsGluePointEditMode()) {
				if (HasMarkedGluePoints()) {
					ImpTakeDescriptionStr(STR_ViewMarked,aStr,0,IMPSDR_GLUEPOINTSDESCRIPTION);
				}
			} else {
				if (HasMarkedPoints()) {
					ImpTakeDescriptionStr(STR_ViewMarked,aStr,0,IMPSDR_POINTSDESCRIPTION);
				}
			}
		} else {
			aStr.Erase();
		}
	}
	else if(aName.Len())
	{
		aStr.SearchAndReplaceAscii("%1", aName);
	}

	if(aStr.Len())
	{
		// ersten Buchstaben gross schreiben
		String aTmpStr(aStr.Copy(0, 1));
		aTmpStr.ToUpperAscii();
		aStr.Replace(0, 1, aTmpStr);
	}
	return aStr;
}

SdrViewContext SdrView::GetContext() const
{
	if( IsGluePointEditMode() )
		return SDRCONTEXT_GLUEPOINTEDIT;

	const sal_uIntPtr nMarkAnz = GetMarkedObjectCount();

	if( HasMarkablePoints() && !IsFrameHandles() )
	{
		sal_Bool bPath=sal_True;
		for( sal_uIntPtr nMarkNum = 0; nMarkNum < nMarkAnz && bPath; nMarkNum++ )
			if (!GetMarkedObjectByIndex(nMarkNum)->ISA(SdrPathObj))
				bPath=sal_False;

		if( bPath )
			return SDRCONTEXT_POINTEDIT;
	}

	if( GetMarkedObjectCount() )
	{
		sal_Bool bGraf = sal_True, bMedia = sal_True, bTable = sal_True;

		for( sal_uIntPtr nMarkNum = 0; nMarkNum < nMarkAnz && ( bGraf || bMedia ); nMarkNum++ )
		{
			const SdrObject* pMarkObj = GetMarkedObjectByIndex( nMarkNum );
			DBG_ASSERT( pMarkObj, "SdrView::GetContext(), null pointer in mark list!" );

			if( !pMarkObj )
				continue;

			if( !pMarkObj->ISA( SdrGrafObj ) )
				bGraf = sal_False;

			if( !pMarkObj->ISA( SdrMediaObj ) )
				bMedia = sal_False;

			if( !pMarkObj->ISA( ::sdr::table::SdrTableObj ) )
				bTable = sal_False;
		}

		if( bGraf )
			return SDRCONTEXT_GRAPHIC;
		else if( bMedia )
			return SDRCONTEXT_MEDIA;
		else if( bTable )
			return SDRCONTEXT_TABLE;
	}

	return SDRCONTEXT_STANDARD;
}

void SdrView::MarkAll()
{
	if (IsTextEdit()) {
		GetTextEditOutlinerView()->SetSelection(ESelection(0,0,EE_PARA_MAX,EE_INDEX_MAX));
#ifdef DBG_UTIL
		if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
#endif
	} else if (IsGluePointEditMode()) MarkAllGluePoints();
	else if (HasMarkablePoints()) MarkAllPoints();
	else MarkAllObj();
}

void SdrView::UnmarkAll()
{
	if (IsTextEdit()) {
		ESelection eSel=GetTextEditOutlinerView()->GetSelection();
		eSel.nStartPara=eSel.nEndPara;
		eSel.nStartPos=eSel.nEndPos;
		GetTextEditOutlinerView()->SetSelection(eSel);
#ifdef DBG_UTIL
		if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
#endif
	} else if (HasMarkedGluePoints()) UnmarkAllGluePoints();
	else if (HasMarkedPoints()) UnmarkAllPoints(); // ! Marked statt Markable !
	else UnmarkAllObj();
}

sal_Bool SdrView::IsAllMarked() const
{
	if (IsTextEdit()) {
		return ImpIsTextEditAllSelected();
	}
	if (IsGluePointEditMode()) {
		sal_uIntPtr nAnz=GetMarkableGluePointCount();
		return nAnz!=0 && nAnz==GetMarkedGluePointCount();
	}
	if (HasMarkedPoints()) {
		sal_uIntPtr nAnz=GetMarkablePointCount();
		return nAnz!=0 && nAnz==GetMarkedPointCount();
	}
	sal_uIntPtr nAnz=GetMarkableObjCount();
	return nAnz!=0 && nAnz == GetMarkedObjectCount();
}

sal_Bool SdrView::IsMarkPossible() const
{
	if(IsTextEdit())
	{
		return SdrTextObj::HasTextImpl( pTextEditOutliner );
	}

	if(IsGluePointEditMode())
	{
		return HasMarkableGluePoints();
	}

	if(HasMarkedPoints())
	{
		return HasMarkablePoints();
	}

	return HasMarkableObj();
}

sal_Bool SdrView::IsAllMarkPrevNextPossible() const
{
	if (IsTextEdit()) {
		return sal_False;
	}
	if (IsGluePointEditMode()) {
		return HasMarkableGluePoints();
	}
	if (HasMarkedPoints()) {
		return HasMarkablePoints();
	}
	return HasMarkableObj();
}

sal_Bool SdrView::MarkNext(sal_Bool bPrev)
{
	if (IsTextEdit()) {
		return sal_False;
	}
	if (IsGluePointEditMode() && HasMarkedGluePoints()) {
		return MarkNextGluePoint(bPrev);
	}
	if (HasMarkedPoints()) {
		return MarkNextPoint(bPrev);
	}
	return MarkNextObj(bPrev);
}

sal_Bool SdrView::MarkNext(const Point& rPnt, sal_Bool bPrev)
{
	if (IsTextEdit()) {
		return sal_False;
	}
	if (IsGluePointEditMode() && HasMarkedGluePoints()) {
		//return MarkNextGluePoint(rPnt,bPrev); fehlende Implementation !!!
	}
	if (HasMarkedPoints()) {
		//return MarkNextPoint(rPnt,bPrev);     fehlende Implementation !!!
	}
	return MarkNextObj(rPnt,-2,bPrev);
}

const Rectangle& SdrView::GetMarkedRect() const
{
	if (IsGluePointEditMode() && HasMarkedGluePoints()) {
		return GetMarkedGluePointsRect();
	}
	if (HasMarkedPoints()) {
		return GetMarkedPointsRect();
	}
	return GetMarkedObjRect();
}

void SdrView::SetMarkedRect(const Rectangle& rRect)
{
	if (IsGluePointEditMode() && HasMarkedGluePoints()) {
		//SetMarkedGluePointsRect(rRect); fehlende Implementation !!!
	} else if (HasMarkedPoints()) {
		//SetMarkedPointsRect(rRect);     fehlende Implementation !!!
	} else SetMarkedObjRect(rRect);
}

void SdrView::DeleteMarked()
{
	if (IsTextEdit())
	{
		SdrObjEditView::KeyInput(KeyEvent(0,KeyCode(KEYFUNC_DELETE)),pTextEditWin);
	}
	else
	{
		if( mxSelectionController.is() && mxSelectionController->DeleteMarked() )
		{
			// action already performed by current selection controller, do nothing
		}
		else if (IsGluePointEditMode() && HasMarkedGluePoints())
		{
			DeleteMarkedGluePoints();
		}
		else if (GetContext()==SDRCONTEXT_POINTEDIT && HasMarkedPoints())
		{
			DeleteMarkedPoints();
		}
		else
		{
			DeleteMarkedObj();
		}
	}
}

sal_Bool SdrView::BegMark(const Point& rPnt, sal_Bool bAddMark, sal_Bool bUnmark)
{
	if (bUnmark) bAddMark=sal_True;
	if (IsGluePointEditMode()) {
		if (!bAddMark) UnmarkAllGluePoints();
		return BegMarkGluePoints(rPnt,bUnmark);
	} else if (HasMarkablePoints()) {
		if (!bAddMark) UnmarkAllPoints();
		return BegMarkPoints(rPnt,bUnmark);
	} else {
		if (!bAddMark) UnmarkAllObj();
		return BegMarkObj(rPnt,bUnmark);
	}
}

sal_Bool SdrView::IsDeleteMarkedPossible() const
{
	if (IsReadOnly()) return sal_False;
	if (IsTextEdit()) return sal_True;
	if (IsGluePointEditMode() && HasMarkedGluePoints()) return sal_True;
	if (HasMarkedPoints()) return sal_True;
	return IsDeleteMarkedObjPossible();
}

void SdrView::ConfigurationChanged( ::utl::ConfigurationBroadcaster*p, sal_uInt32 nHint)
{
	onAccessibilityOptionsChanged();
 	SdrCreateView::ConfigurationChanged(p, nHint);
}

SvtAccessibilityOptions& SdrView::getAccessibilityOptions()
{
	return maAccessibilityOptions;
}

/** method is called whenever the global SvtAccessibilityOptions is changed */
void SdrView::onAccessibilityOptionsChanged()
{
}

void SdrView::SetMasterPagePaintCaching(sal_Bool bOn)
{
	if(mbMasterPagePaintCaching != bOn)
	{
		mbMasterPagePaintCaching = bOn;

		// reset at all SdrPageWindow's
		SdrPageView* pPageView = GetSdrPageView();

		if(pPageView)
		{
			for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
			{
				SdrPageWindow* pPageWindow = pPageView->GetPageWindow(b);
				DBG_ASSERT(pPageWindow, "SdrView::SetMasterPagePaintCaching: Corrupt SdrPageWindow list (!)");

				// force deletion of ObjectContact, so at re-display all VOCs
				// will be re-created with updated flag setting
				pPageWindow->ResetObjectContact();
			}

			// force redraw of this view
			pPageView->InvalidateAllWin();
		}
	}
}
// eof
