/**************************************************************
 * 
 * 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_sd.hxx"


#include "futext.hxx"
#include <editeng/eeitem.hxx>
#include <editeng/editerr.hxx>
#include <svx/dlgutil.hxx>
#include <svx/svxerr.hxx>
#include <tools/urlobj.hxx>
#include <vcl/help.hxx>
#include <editeng/editstat.hxx>
#include <svl/aeitem.hxx>
#include <svl/intitem.hxx>
#include <svx/svdotext.hxx>
#include <svx/svdogrp.hxx>
#include <editeng/flditem.hxx>
#include <svl/style.hxx>
#include <svx/svdpagv.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/request.hxx>
#include <editeng/editeng.hxx>
#include <svx/svdoutl.hxx>
#include <svx/svxids.hrc>
#include <sfx2/docfile.hxx>
#include <comphelper/processfactory.hxx>
#include <editeng/outlobj.hxx>
#include <svtools/langtab.hxx>

// #104122#
#include <editeng/frmdiritem.hxx>

#include <svx/svdetc.hxx>
#include <editeng/editview.hxx>

#include "sdresid.hxx"
#include "app.hrc"
#include "res_bmp.hrc"
#include "ViewShell.hxx"
#include "ViewShellBase.hxx"
#include "View.hxx"
#include "Outliner.hxx"
#include "Window.hxx"
#include "drawdoc.hxx"
#include "sdpage.hxx"
#include "sdmod.hxx"
#include "FrameView.hxx"
#include "ToolBarManager.hxx"
#include "DrawDocShell.hxx"
#include "glob.hrc"
#include "pres.hxx"
#include "optsitem.hxx"

using ::rtl::OUString;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::linguistic2;

namespace sd {

static sal_uInt16 SidArray[] = {
	SID_STYLE_FAMILY2,                //    5542
	SID_STYLE_FAMILY5,                //    5545
	SID_CUT,                          //    5710
	SID_COPY,                         //    5711
	SID_ATTR_TABSTOP,                 //   10002
	SID_ATTR_CHAR_FONT,               //   10007
	SID_ATTR_CHAR_POSTURE,            //   10008
	SID_ATTR_CHAR_WEIGHT,             //   10009
	SID_ATTR_CHAR_SHADOWED,		//10010
	SID_ATTR_CHAR_STRIKEOUT,		//10013
	SID_ATTR_CHAR_UNDERLINE,          //   10014
	SID_ATTR_CHAR_FONTHEIGHT,         //   10015
	SID_ATTR_CHAR_COLOR,              //   10017
	SID_ATTR_CHAR_KERNING,			//10018
	SID_ATTR_PARA_ADJUST_LEFT,        //   10028
	SID_ATTR_PARA_ADJUST_RIGHT,       //   10029
	SID_ATTR_PARA_ADJUST_CENTER,      //   10030
	SID_ATTR_PARA_ADJUST_BLOCK,       //   10031
	SID_ATTR_PARA_LINESPACE_10,       //   10034
	SID_ATTR_PARA_LINESPACE_15,       //   10035
	SID_ATTR_PARA_LINESPACE_20,       //   10036
	SID_ATTR_PARA_ULSPACE,  	   //   10042
	SID_ATTR_PARA_LRSPACE,            //   10043
    SID_ATTR_TRANSFORM_POS_X, //  10088
    SID_ATTR_TRANSFORM_POS_Y, //  10089
    SID_ATTR_TRANSFORM_WIDTH, //  10090
    SID_ATTR_TRANSFORM_HEIGHT,//  10091
    SID_ATTR_TRANSFORM_ROT_X, //  10093
    SID_ATTR_TRANSFORM_ROT_Y, //  10094
    SID_ATTR_TRANSFORM_ANGLE, //  10095 //Added
	SID_OUTLINE_UP,                   //   10150
	SID_OUTLINE_DOWN,                 //   10151
	SID_OUTLINE_LEFT,                 //   10152
	SID_OUTLINE_RIGHT,                //   10153
    SID_ATTR_TRANSFORM_PROTECT_POS,//  10236
    SID_ATTR_TRANSFORM_PROTECT_SIZE,// 10237 //Added
	SID_FORMTEXT_STYLE,               //   10257
	SID_SET_SUPER_SCRIPT,             //   10294
	SID_SET_SUB_SCRIPT,               //   10295
    SID_ATTR_TRANSFORM_AUTOWIDTH,//    10310
    SID_ATTR_TRANSFORM_AUTOHEIGHT,//   10311 //Added
	SID_HYPERLINK_GETLINK,            //   10361
	SID_CHARMAP,					  //   10503
	SID_TEXTDIRECTION_LEFT_TO_RIGHT,  //   10907
	SID_TEXTDIRECTION_TOP_TO_BOTTOM,  //   10908
    SID_ATTR_PARA_LEFT_TO_RIGHT,      //   10950
    SID_ATTR_PARA_RIGHT_TO_LEFT,      //   10951
	FN_NUM_BULLET_ON,                 //   20138
	SID_PARASPACE_INCREASE,           //   27346
	SID_PARASPACE_DECREASE,           //   27347
							0 };

TYPEINIT1( FuText, FuConstruct );


static sal_Bool bTestText = 0;

/*************************************************************************
|*
|* Basisklasse fuer Textfunktionen
|*
\************************************************************************/

FuText::FuText( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq ) 
: FuConstruct(pViewSh, pWin, pView, pDoc, rReq)
, bFirstObjCreated(sal_False)
, rRequest (rReq)
{
}

FunctionReference FuText::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq )
{
	FunctionReference xFunc( new FuText( pViewSh, pWin, pView, pDoc, rReq ) );
	return xFunc;
}

/*************************************************************************
|*
|* Destruktor
|*
\************************************************************************/

void FuText::disposing()
{
	if(mpView)
	{
		if(mpView->SdrEndTextEdit(sal_False) == SDRENDTEXTEDIT_DELETED)
			mxTextObj.reset( 0 );

		// die RequestHandler der benutzten Outliner zuruecksetzen auf den
		// Handler am Dokument
		::Outliner* pOutliner = mpView->GetTextEditOutliner();

		if (pOutliner)
			pOutliner->SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(mpDoc->GetStyleSheetPool()));
	}
}

/*************************************************************************
|*
|* Execute functionality of this class:
|*
|* #71422: Start the functionality of this class in this method
|* and not in the ctor.
|* If you construct an object of this class and you put the
|* address of this object to pFuActual you've got a problem,
|* because some methods inside DoExecute use the pFuActual-Pointer.
|* If the code inside DoExecute is executed inside the ctor,
|* the value of pFuActual is not right. And the value will not
|* be right until the ctor finished !!!
|*
\************************************************************************/
void FuText::DoExecute( SfxRequest& )
{
	mpViewShell->GetViewShellBase().GetToolBarManager()->SetToolBarShell(
        ToolBarManager::TBG_FUNCTION,
        RID_DRAW_TEXT_TOOLBOX);

	mpView->SetCurrentObj(OBJ_TEXT);
	mpView->SetEditMode(SDREDITMODE_EDIT);

	MouseEvent aMEvt(mpWindow->GetPointerPosPixel());

	if (nSlotId == SID_TEXTEDIT)
	{
		// Try to select an object
		SdrPageView* pPV = mpView->GetSdrPageView();
		SdrViewEvent aVEvt;
		mpView->PickAnything(aMEvt, SDRMOUSEBUTTONDOWN, aVEvt);
		mpView->MarkObj(aVEvt.pRootObj, pPV);

		mxTextObj.reset( dynamic_cast< SdrTextObj* >( aVEvt.pObj ) );
	}
	else if (mpView->AreObjectsMarked())
	{
		const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();

		if (rMarkList.GetMarkCount() == 1)
		{
			SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
			mxTextObj.reset( dynamic_cast< SdrTextObj* >( pObj ) );
		}
	}

	// check for table
	if (mpView->AreObjectsMarked())
	{
		const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();

		if (rMarkList.GetMarkCount() == 1)
		{
			SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
			if( pObj && (pObj->GetObjInventor() == SdrInventor ) && (pObj->GetObjIdentifier() == OBJ_TABLE) )
			{
				mpViewShell->GetViewShellBase().GetToolBarManager()->AddToolBarShell( ToolBarManager::TBG_FUNCTION, RID_DRAW_TABLE_TOOLBOX );
			}
		}
	}

	sal_Bool bQuickDrag = sal_True;

	const SfxItemSet* pArgs = rRequest.GetArgs();

	if (pArgs

		// #98198# test for type before using
		&& SID_TEXTEDIT == nSlotId
		&& SFX_ITEM_SET == pArgs->GetItemState(SID_TEXTEDIT)

		&& (sal_uInt16)((SfxUInt16Item&)pArgs->Get(SID_TEXTEDIT)).GetValue() == 2)
	{
		// Selection by doubleclick -> don't allow QuickDrag
		bQuickDrag = sal_False;
	}

	SetInEditMode(aMEvt, bQuickDrag);
}

/*************************************************************************
|*
|* MouseButtonDown-event
|*
\************************************************************************/

sal_Bool FuText::MouseButtonDown(const MouseEvent& rMEvt)
{
	bMBDown = sal_True;

	sal_Bool bReturn = FuDraw::MouseButtonDown(rMEvt);

    /* af: (de)Select object before showing the context menu.
	// Fuer PopupMenu (vorher DrawViewShell)
	if ((rMEvt.GetButtons() == MOUSE_RIGHT) && rMEvt.GetClicks() == 1 &&
		mpView->IsTextEdit())
	{
		return (sal_True);
	}
        */

	mpView->SetMarkHdlWhenTextEdit(sal_True);
	SdrViewEvent aVEvt;
	SdrHitKind eHit = mpView->PickAnything(rMEvt, SDRMOUSEBUTTONDOWN, aVEvt);

	if (eHit == SDRHIT_TEXTEDIT)
	{
		// Text getroffen -> Event von SdrView auswerten lassen
		if (mpView->MouseButtonDown(rMEvt, mpWindow))
			return (sal_True);
	}

	if (rMEvt.GetClicks() == 1)
	{
		if (mpView->IsTextEdit() && eHit != SDRHIT_MARKEDOBJECT && eHit != SDRHIT_HANDLE)
		{
			// Texteingabe beenden
			if(mpView->SdrEndTextEdit() == SDRENDTEXTEDIT_DELETED)
			{
				// Bugfix von MBA: bei Doppelclick auf der Wiese im Modus Text wird
				// beim zweiten Click eHit = SDRHIT_TEXTEDITOBJ erhalten, weil ja der
				// zweite Click auf das im ersten Click angelegte TextObject geht.
				// Dieses wird aber in SdrEndTextEdit entfernt, weil es leer ist. Es
				// befindet sich aber noch in der Mark-Liste und der Aufruf MarkObj
				// weiter unten greift dann auf das tote Object zu.
				// Als einfacher Fix wird nach SdrEndTextEdit noch einmal eHit ermittelt,
				// was dann SDRHIT_NONE liefert.
				mxTextObj.reset( NULL );
				eHit = mpView->PickAnything(rMEvt, SDRMOUSEBUTTONDOWN, aVEvt);
			}

			mpView->SetCurrentObj(OBJ_TEXT);
			mpView->SetEditMode(SDREDITMODE_EDIT);
		}

		if (rMEvt.IsLeft() || rMEvt.IsRight())
		{
			mpWindow->CaptureMouse();
			SdrObject* pObj;
			SdrPageView* pPV = mpView->GetSdrPageView();

			if (eHit == SDRHIT_TEXTEDIT)
			{
				SetInEditMode(rMEvt, sal_False);
			}
			else
			{
				sal_Bool bMacro = sal_False;

				if (bMacro && mpView->PickObj(aMDPos,mpView->getHitTolLog(),pObj,pPV,SDRSEARCH_PICKMACRO))
				{
					// Makro
					sal_uInt16 nHitLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(HITPIX,0)).Width() );
					mpView->BegMacroObj(aMDPos,nHitLog,pObj,pPV,mpWindow);
				}
				else
				{
					if (eHit != SDRHIT_HANDLE)
					{
						// Selektion aufheben
						if (!rMEvt.IsShift() && eHit == SDRHIT_TEXTEDITOBJ)
						{
							mpView->UnmarkAll();
							mpView->SetDragMode(SDRDRAG_MOVE);
						}
					}

					if ( aVEvt.eEvent == SDREVENT_EXECUTEURL                   ||
						 eHit == SDRHIT_HANDLE                                 ||
						 eHit == SDRHIT_MARKEDOBJECT                           ||
						 eHit == SDRHIT_TEXTEDITOBJ                            ||
						 ( eHit == SDRHIT_UNMARKEDOBJECT && bFirstObjCreated &&
						   !bPermanent ) )
					{
						/**********************************************************
						* Handle, markiertes oder unmarkiertes Objekt getroffen
						**********************************************************/
						if (eHit == SDRHIT_TEXTEDITOBJ)
						{
							/******************************************************
							* Text eines unmarkierten Objekts getroffen:
							* Objekt wird selektiert und in EditMode versetzt
							******************************************************/
							mpView->MarkObj(aVEvt.pRootObj, pPV);

							if (aVEvt.pObj && aVEvt.pObj->ISA(SdrTextObj))
							{
								mxTextObj.reset( static_cast<SdrTextObj*>(aVEvt.pObj) );
							}

							SetInEditMode(rMEvt, sal_True);
						}
						else if (aVEvt.eEvent == SDREVENT_EXECUTEURL && !rMEvt.IsMod2())
						{
							/******************************************************
							* URL ausfuehren
							******************************************************/
							mpWindow->ReleaseMouse();
							SfxStringItem aStrItem(SID_FILE_NAME, aVEvt.pURLField->GetURL());
							SfxStringItem aReferer(SID_REFERER, mpDocSh->GetMedium()->GetName());
							SfxBoolItem aBrowseItem( SID_BROWSE, sal_True );
							SfxViewFrame* pFrame = mpViewShell->GetViewFrame();
							mpWindow->ReleaseMouse();

							if (rMEvt.IsMod1())
							{
								// Im neuen Frame oeffnen
								pFrame->GetDispatcher()->Execute(SID_OPENDOC, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
											&aStrItem, &aBrowseItem, &aReferer, 0L);
							}
							else
							{
								// Im aktuellen Frame oeffnen
								SfxFrameItem aFrameItem(SID_DOCFRAME, pFrame);
								pFrame->GetDispatcher()->Execute(SID_OPENDOC, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
											&aStrItem, &aFrameItem, &aBrowseItem, &aReferer, 0L);
							}
						}
						else
						{
							/******************************************************
							* Objekt oder Handle draggen
							******************************************************/

							// #i78748#
							// do the EndTextEdit first, it will delete the handles and force a
							// recreation. This will make aVEvt.pHdl to point to a deleted handle,
							// thus it is necessary to reset it and to get it again.

							// #i112855#
							// cl: I'm not sure why we checked here also for mxTextObj->GetOutlinerParaObjet
							// this caused SdrEndTextEdit() to be called also when not in text editing and
							// this does not make sense and caused troubles. (see issue 112855)

//							::Outliner* pOutl = mpView->GetTextEditOutliner();
//							
//							if (mxTextObj.is() && (mxTextObj->GetOutlinerParaObject() ||
//								(pOutl && pOutl->GetText(pOutl->GetParagraph( 0 )).Len() != 0)))
							if( mpView->IsTextEdit() )
							{
								mpView->SdrEndTextEdit();

								if(aVEvt.pHdl)
								{
									// force new handle identification, the pointer will be dead here
									// since SdrEndTextEdit has resetted (deleted) the handles.
									aVEvt.pHdl = 0;
									mpView->PickAnything(rMEvt, SDRMOUSEBUTTONDOWN, aVEvt);
								}
							}

							if (!aVEvt.pHdl)
							{
								if( eHit == SDRHIT_UNMARKEDOBJECT )
								{
									if ( !rMEvt.IsShift() )
										mpView->UnmarkAll();

									mpView->MarkObj(aVEvt.pRootObj, pPV);
								}

								// Objekt draggen
								bFirstMouseMove = sal_True;
								aDragTimer.Start();
							}


                            if ( ! rMEvt.IsRight())
                            {
							    // we need to pick again since SdrEndTextEdit can rebuild the handles list
                                eHit = mpView->PickAnything(rMEvt, SDRMOUSEBUTTONDOWN, aVEvt);
							    if( (eHit == SDRHIT_HANDLE) || (eHit == SDRHIT_MARKEDOBJECT) )
							    {
								    sal_uInt16 nDrgLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(DRGPIX,0)).Width() );
								    mpView->BegDragObj(aMDPos, (OutputDevice*) NULL, aVEvt.pHdl, nDrgLog);
							    }
                            }
                            bReturn = true;
						}
					}
					else if ( nSlotId != SID_TEXTEDIT &&
							  (bPermanent || !bFirstObjCreated) )
					{
						/**********************************************************
						* Objekt erzeugen
						**********************************************************/
						mpView->SetCurrentObj(OBJ_TEXT);
						mpView->SetEditMode(SDREDITMODE_CREATE);
						sal_uInt16 nDrgLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(DRGPIX,0)).Width() );
						mpView->BegCreateObj(aMDPos, (OutputDevice*) NULL, nDrgLog);
					}
					else
					{
						/**********************************************************
						* Selektieren
						**********************************************************/
						if( !rMEvt.IsShift() )
							mpView->UnmarkAll();

						mpView->BegMarkObj( aMDPos );
					}
				}
			}
		}
	}
	else if ( rMEvt.GetClicks() == 2 && !mpView->IsTextEdit() )
	{
		MouseEvent aMEvt( mpWindow->GetPointerPosPixel() );
		SetInEditMode( aMEvt, sal_False );
	}

	if (!bIsInDragMode)
	{
		ForcePointer(&rMEvt);
		mpViewShell->GetViewFrame()->GetBindings().Invalidate(SidArray);
	}

	return (bReturn);
}

/*************************************************************************
|*
|* MouseMove-event
|*
\************************************************************************/

sal_Bool FuText::MouseMove(const MouseEvent& rMEvt)
{
	sal_Bool bReturn = FuDraw::MouseMove(rMEvt);

	if (aDragTimer.IsActive() )
	{
		if( bFirstMouseMove )
			bFirstMouseMove = sal_False;
		else
			aDragTimer.Stop();
	}

	if (!bReturn && mpView->IsAction() && !mpDocSh->IsReadOnly())
	{
		Point aPix(rMEvt.GetPosPixel());
		Point aPnt(mpWindow->PixelToLogic(aPix));

		ForceScroll(aPix);
		mpView->MovAction(aPnt);
	}

	ForcePointer(&rMEvt);

	return (bReturn);
}

/*************************************************************************
|*
|* MouseButtonUp-event
|*
\************************************************************************/

// #97016#
void FuText::ImpSetAttributesForNewTextObject(SdrTextObj* pTxtObj)
{
	if(mpDoc->GetDocumentType() == DOCUMENT_TYPE_IMPRESS)
	{
		if( nSlotId == SID_ATTR_CHAR )
		{
			// Impress-Textobjekt wird erzeugt (faellt auf Zeilenhoehe zusammen)
			// Damit das Objekt beim anschliessenden Erzeugen gleich die richtige
			// Hoehe bekommt (sonst wird zuviel gepainted)
			SfxItemSet aSet(mpViewShell->GetPool());
			aSet.Put(SdrTextMinFrameHeightItem(0));
			aSet.Put(SdrTextAutoGrowWidthItem(sal_False));
			aSet.Put(SdrTextAutoGrowHeightItem(sal_True));
			pTxtObj->SetMergedItemSet(aSet);
			pTxtObj->AdjustTextFrameWidthAndHeight();
			aSet.Put(SdrTextMaxFrameHeightItem(pTxtObj->GetLogicRect().GetSize().Height()));
			pTxtObj->SetMergedItemSet(aSet);
		}
		else if( nSlotId == SID_ATTR_CHAR_VERTICAL )
		{
			SfxItemSet aSet(mpViewShell->GetPool());
			aSet.Put(SdrTextMinFrameWidthItem(0));
			aSet.Put(SdrTextAutoGrowWidthItem(sal_True));
			aSet.Put(SdrTextAutoGrowHeightItem(sal_False));

			// #91853# Needs to be set since default is SDRTEXTHORZADJUST_BLOCK
			aSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT));
			pTxtObj->SetMergedItemSet(aSet);
			pTxtObj->AdjustTextFrameWidthAndHeight();
			aSet.Put(SdrTextMaxFrameWidthItem(pTxtObj->GetLogicRect().GetSize().Width()));
			pTxtObj->SetMergedItemSet(aSet);
		}
	}
	else
	{
		if( nSlotId == SID_ATTR_CHAR_VERTICAL )
		{
			// draw text object, needs to be initialized when vertical text is used
			SfxItemSet aSet(mpViewShell->GetPool());

			// #91510#
			aSet.Put(SdrTextAutoGrowWidthItem(sal_True));
			aSet.Put(SdrTextAutoGrowHeightItem(sal_False));

			// #91508#
			//aSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP));
			//aSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT));

			// #107235#
			// Set defaults for vertical klick-n'drag text object, pool defaults are:
			// SdrTextVertAdjustItem: SDRTEXTVERTADJUST_TOP
			// SdrTextHorzAdjustItem: SDRTEXTHORZADJUST_BLOCK
			// Analog to that (thus, #91508# was not completely correct):
			aSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BLOCK));
			aSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT));

			pTxtObj->SetMergedItemSet(aSet);
		}
	}
}

// #97016#
void FuText::ImpSetAttributesFitToSize(SdrTextObj* pTxtObj)
{
	// FitToSize (An Rahmen anpassen)
	SfxItemSet aSet(mpViewShell->GetPool(), SDRATTR_TEXT_AUTOGROWHEIGHT, SDRATTR_TEXT_AUTOGROWWIDTH);
	SdrFitToSizeType eFTS = SDRTEXTFIT_PROPORTIONAL;
	aSet.Put(SdrTextFitToSizeTypeItem(eFTS));
	aSet.Put(SdrTextAutoGrowHeightItem(sal_False));
	aSet.Put(SdrTextAutoGrowWidthItem(sal_False));
	pTxtObj->SetMergedItemSet(aSet);
	pTxtObj->AdjustTextFrameWidthAndHeight();
}

// #97016#
void FuText::ImpSetAttributesFitToSizeVertical(SdrTextObj* pTxtObj)
{
	SfxItemSet aSet(mpViewShell->GetPool(),
		SDRATTR_TEXT_AUTOGROWHEIGHT, SDRATTR_TEXT_AUTOGROWWIDTH);
	SdrFitToSizeType eFTS = SDRTEXTFIT_PROPORTIONAL;
	aSet.Put(SdrTextFitToSizeTypeItem(eFTS));
	aSet.Put(SdrTextAutoGrowHeightItem(sal_False));
	aSet.Put(SdrTextAutoGrowWidthItem(sal_False));
	pTxtObj->SetMergedItemSet(aSet);
	pTxtObj->AdjustTextFrameWidthAndHeight();
}

// #97016#
void FuText::ImpSetAttributesFitCommon(SdrTextObj* pTxtObj)
{
	// Normales Textobjekt
	if (mpDoc->GetDocumentType() == DOCUMENT_TYPE_IMPRESS)
	{
		if( nSlotId == SID_ATTR_CHAR )
		{
			// Impress-Textobjekt (faellt auf Zeilenhoehe zusammen)
			SfxItemSet aSet(mpViewShell->GetPool());
			aSet.Put(SdrTextMinFrameHeightItem(0));
			aSet.Put(SdrTextMaxFrameHeightItem(0));
			aSet.Put(SdrTextAutoGrowHeightItem(sal_True));
			aSet.Put(SdrTextAutoGrowWidthItem(sal_False));
			pTxtObj->SetMergedItemSet(aSet);
		}
		else if( nSlotId == SID_ATTR_CHAR_VERTICAL )
		{
			SfxItemSet aSet(mpViewShell->GetPool());
			aSet.Put(SdrTextMinFrameWidthItem(0));
			aSet.Put(SdrTextMaxFrameWidthItem(0));
			aSet.Put(SdrTextAutoGrowWidthItem(sal_True));
			aSet.Put(SdrTextAutoGrowHeightItem(sal_False));
			pTxtObj->SetMergedItemSet(aSet);
		}

		pTxtObj->AdjustTextFrameWidthAndHeight();
	}
}

sal_Bool FuText::MouseButtonUp(const MouseEvent& rMEvt)
{
	sal_Bool bReturn = sal_False;

	if (aDragTimer.IsActive())
	{
		aDragTimer.Stop();
		bIsInDragMode = sal_False;
	}

	mpViewShell->GetViewFrame()->GetBindings().Invalidate( SidArray );

	Point aPnt( mpWindow->PixelToLogic( rMEvt.GetPosPixel() ) );

	if( (mpView && mpView->MouseButtonUp(rMEvt, mpWindow)) || rMEvt.GetClicks() == 2 )
		return (sal_True); // Event von der SdrView ausgewertet

	sal_Bool bEmptyTextObj = sal_False;

	if (mxTextObj.is())
	{
		const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();

		if (rMarkList.GetMarkCount() == 1
            && ( rMarkList.GetMark(0)->GetMarkedSdrObj() == mxTextObj.get()) )
		{
			if( mxTextObj.is() && !GetTextObj()->GetOutlinerParaObject() )
				bEmptyTextObj = sal_True;
			else
				bFirstObjCreated = sal_True;
		}
		else
		{
			mxTextObj.reset( 0 );
		}
	}

	if( mpView && mpView->IsDragObj())
	{
		/**********************************************************************
		* Objekt wurde verschoben
		**********************************************************************/
		FrameView* pFrameView = mpViewShell->GetFrameView();
		sal_Bool bDragWithCopy = (rMEvt.IsMod1() && pFrameView->IsDragWithCopy());

		if (bDragWithCopy)
		{
			bDragWithCopy = !mpView->IsPresObjSelected(sal_False, sal_True);
		}

		mpView->SetDragWithCopy(bDragWithCopy);
		mpView->EndDragObj( mpView->IsDragWithCopy() );
		mpView->ForceMarkedToAnotherPage();
		mpView->SetCurrentObj(OBJ_TEXT);

	    sal_uInt16 nDrgLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(DRGPIX,0)).Width() );

        if ( mpView->IsRotateAllowed() && mpViewShell->GetFrameView()->IsClickChangeRotation() && (rMEvt.GetClicks() != 2) &&
			!rMEvt.IsShift() && !rMEvt.IsMod1() && !rMEvt.IsMod2() && !rMEvt.IsRight() &&
            Abs(aPnt.X() - aMDPos.X()) < nDrgLog &&
            Abs(aPnt.Y() - aMDPos.Y()) < nDrgLog)
        {
			// toggle to rotation mode
			mpViewShell->GetViewFrame()->GetDispatcher()->Execute( SID_OBJECT_ROTATE, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD );
		}
	}
	else if( mpView && mpView->IsCreateObj() && rMEvt.IsLeft())
	{
		/**********************************************************************
		* Objekt wurde erzeugt
		**********************************************************************/
		mxTextObj.reset( dynamic_cast< SdrTextObj* >( mpView->GetCreateObj() ) );

		if( mxTextObj.is() )
		{
			//AW outliner needs to be set to vertical when there is no
			// outliner object up to now; also it needs to be set back to not
			// vertical when there was a vertical one used last time.
			OutlinerParaObject* pOPO = GetTextObj()->GetOutlinerParaObject();
			SdrOutliner& rOutl = mxTextObj->GetModel()->GetDrawOutliner(GetTextObj());
			sal_Bool bVertical((pOPO && pOPO->IsVertical())
				|| nSlotId == SID_ATTR_CHAR_VERTICAL
				|| nSlotId == SID_TEXT_FITTOSIZE_VERTICAL);
			rOutl.SetVertical(bVertical);

			// #107235#
			// Before ImpSetAttributesForNewTextObject the vertical writing mode
			// needs to be set at the object. This is done here at the OutlinerParaObject
			// directly to not mirror the layout text items involved. These items will be set
			// from ImpSetAttributesForNewTextObject and below.
			OutlinerParaObject* pPara = GetTextObj()->GetOutlinerParaObject();

			if(!pPara)
			{
				GetTextObj()->ForceOutlinerParaObject();
				pPara = GetTextObj()->GetOutlinerParaObject();
			}

			if(pPara && (bool)bVertical != pPara->IsVertical())
			{
				// set ParaObject orientation accordingly
				pPara->SetVertical(bVertical);
			}

			// #97016#
			ImpSetAttributesForNewTextObject(GetTextObj());
		}

		if (!mpView->EndCreateObj(SDRCREATE_FORCEEND))
		{
			// Textobjekt konnte nicht erzeugt werden
			mxTextObj.reset(0);
		}
		else if (nSlotId == SID_TEXT_FITTOSIZE)
		{
			// #97016#
			ImpSetAttributesFitToSize(GetTextObj());

			SetInEditMode(rMEvt, sal_False);
		}
		else if ( nSlotId == SID_TEXT_FITTOSIZE_VERTICAL )
		{
			// #97016#
			ImpSetAttributesFitToSizeVertical(GetTextObj());

			SetInEditMode(rMEvt, sal_False);
		}
		else
		{
			// #97016#
			ImpSetAttributesFitCommon(GetTextObj());

			// Damit die Handles und der graue Rahmen stimmen
			mpView->AdjustMarkHdl();
			mpView->PickHandle(aPnt);
			SetInEditMode(rMEvt, sal_False);
		}
	}
	else if ( mpView && mpView->IsAction())
	{
		mpView->EndAction();
	}

	ForcePointer(&rMEvt);
	mpWindow->ReleaseMouse();
	sal_uInt16 nDrgLog1 = sal_uInt16 ( mpWindow->PixelToLogic(Size(DRGPIX,0)).Width() );

	if ( mpView && !mpView->AreObjectsMarked() &&
		 Abs(aMDPos.X() - aPnt.X()) < nDrgLog1 &&
		 Abs(aMDPos.Y() - aPnt.Y()) < nDrgLog1 &&
		 !rMEvt.IsShift() && !rMEvt.IsMod2() )
	{
		SdrPageView* pPV = mpView->GetSdrPageView();
		SdrViewEvent aVEvt;
		mpView->PickAnything(rMEvt, SDRMOUSEBUTTONDOWN, aVEvt);
		mpView->MarkObj(aVEvt.pRootObj, pPV);
	}

	if ( !mxTextObj.is() && mpView )
	{
		if ( ( (!bEmptyTextObj   &&  bPermanent) ||
			 (!bFirstObjCreated && !bPermanent) ) &&
			  !mpDocSh->IsReadOnly()               &&
			  nSlotId != SID_TEXTEDIT )
		{
			/**********************************************************************
			* Mengentext (linksbuendiges AutoGrow)
			**********************************************************************/
			mpView->SetCurrentObj(OBJ_TEXT);
			mpView->SetEditMode(SDREDITMODE_CREATE);
			sal_uInt16 nDrgLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(DRGPIX,0)).Width() );
			mpView->BegCreateObj(aMDPos, (OutputDevice*) NULL, nDrgLog);

			sal_Bool bSnapEnabled = mpView->IsSnapEnabled();

			if (bSnapEnabled)
				mpView->SetSnapEnabled(sal_False);

			aPnt.X() += nDrgLog + nDrgLog;
			aPnt.Y() += nDrgLog + nDrgLog;
			mpView->MovAction(aPnt);

			mxTextObj.reset( dynamic_cast< SdrTextObj* >( mpView->GetCreateObj() ) );

			if(mxTextObj.is())
			{
				GetTextObj()->SetDisableAutoWidthOnDragging(sal_True);
			}

			if(!mpView->EndCreateObj(SDRCREATE_FORCEEND))
			{
				mxTextObj.reset(0);
			}

			if(bSnapEnabled)
				mpView->SetSnapEnabled(bSnapEnabled);

			if(mxTextObj.is())
			{
				SfxItemSet aSet(mpViewShell->GetPool());
				aSet.Put(SdrTextMinFrameHeightItem(0));
				aSet.Put(SdrTextMinFrameWidthItem(0));
				aSet.Put(SdrTextAutoGrowHeightItem(sal_True));
				aSet.Put(SdrTextAutoGrowWidthItem(sal_True));

				// #91508#
				if(nSlotId == SID_ATTR_CHAR_VERTICAL)
				{
					// #107235#
					//
					// Here, all items which need to be different from pool default need to be set
					// again on the newly created text object.
					// Since this is a simple klick text object, it is first created, then SetVertical()
					// is used, then ImpSetAttributesForNewTextObject is called and then the object is
					// deleted again since not the minimum drag distance was travelled. Then, a new
					// klick text object is created and thus all that stuff needs to be set again here.
					//
					// Before using the new object the vertical writing mode
					// needs to be set. This is done here at the OutlinerParaObject
					// directly to not mirror the layout text items involved. These items will be set
					// below.
					OutlinerParaObject* pPara = GetTextObj()->GetOutlinerParaObject();

					if(!pPara)
					{
						GetTextObj()->ForceOutlinerParaObject();
						pPara = GetTextObj()->GetOutlinerParaObject();
					}

					if(pPara && sal_True != pPara->IsVertical())
					{
						// set ParaObject orientation accordingly
						pPara->SetVertical(sal_True);
					}

					// #91508#
					// aSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP));
					aSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT));

					// #107235#
					// Analog to the else case below, for vertical simple click texts
					// one of the defaulted setted items from ImpSetAttributesForNewTextObject
					// needs to be adapted to non-block mode. This could have been done with the
					// #104122#, but was obviously overseen.
					const SfxItemSet& rSet = mpView->GetDefaultAttr();
					SvxFrameDirection eDirection = (SvxFrameDirection)((SvxFrameDirectionItem&)rSet.Get(EE_PARA_WRITINGDIR)).GetValue();

					if(FRMDIR_HORI_RIGHT_TOP == eDirection || FRMDIR_VERT_TOP_RIGHT == eDirection)
					{
	                    aSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BOTTOM));
					}
					else
					{
	                    aSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP));
					}
				}
				else
				{
					// #104122# This is for Format/Page settings. Since this also leads
					// to the object defaults to be changed, i think this code can be
					// removed. CL. wanted to take a look before adding this.
                    //const SdrTextHorzAdjust eHA = ( ( pDoc && pDoc->GetDefaultWritingMode() == ::com::sun::star::text::WritingMode_RL_TB ) ?
                    //                                SDRTEXTHORZADJUST_RIGHT : SDRTEXTHORZADJUST_LEFT );
                    //aSet.Put( SdrTextHorzAdjustItem( eHA ) );

					// #104122# Look in the object defaults if left-to-right is wanted. If
					// yes, set text anchoring to right to let the box grow to left.
					const SfxItemSet& rSet = mpView->GetDefaultAttr();
					SvxFrameDirection eDirection = (SvxFrameDirection)((SvxFrameDirectionItem&)rSet.Get(EE_PARA_WRITINGDIR)).GetValue();

					if(FRMDIR_HORI_RIGHT_TOP == eDirection)
					{
	                    aSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT));
					}
					else
					{
	                    aSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_LEFT));
					}
				}

				GetTextObj()->SetMergedItemSet(aSet);
				GetTextObj()->SetDisableAutoWidthOnDragging(sal_True);
				SetInEditMode(rMEvt, sal_False);
			}

			bFirstObjCreated = sal_True;
		}
		else
		{
			// In die Fkt. Selektion wechseln
			if (mpView->SdrEndTextEdit() == SDRENDTEXTEDIT_DELETED)
			{
				mxTextObj.reset(0);
			}

			mpViewShell->GetViewFrame()->GetDispatcher()->Execute( SID_OBJECT_SELECT,
									  SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD );
		}
	}

	bMBDown = sal_False;
	FuConstruct::MouseButtonUp(rMEvt);
	return (bReturn);
}

/*************************************************************************
|*
|* Tastaturereignisse bearbeiten
|*
|* Wird ein KeyEvent bearbeitet, so ist der Return-Wert sal_True, andernfalls
|* sal_False.
|*
\************************************************************************/

sal_Bool FuText::KeyInput(const KeyEvent& rKEvt)
{
	sal_Bool bReturn = sal_False;
	mpView->SetMarkHdlWhenTextEdit(sal_True);

	KeyCode nCode = rKEvt.GetKeyCode();
	sal_Bool bShift = nCode.IsShift();

	// #97016# IV
	if(mxTextObj.is())
	{
		// maybe object is deleted, test if it's equal to the selected object
		const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
		SdrObject* pSelectedObj = 0L;

		if(1 == rMarkList.GetMarkCount())
		{
			SdrMark* pMark = rMarkList.GetMark(0);
			pSelectedObj = pMark->GetMarkedSdrObj();
		}

		if(mxTextObj.get() != pSelectedObj)
		{
			mxTextObj.reset(0);
		}
	}

	if ( mxTextObj.is() && mxTextObj->GetObjInventor() == SdrInventor && mxTextObj->GetObjIdentifier() == OBJ_TITLETEXT && rKEvt.GetKeyCode().GetCode() == KEY_RETURN )
	{
		// Titeltext-Objekt: immer "weiche" Umbrueche
		bShift = sal_True;
	}

	sal_uInt16 nKey = nCode.GetCode();
	KeyCode aKeyCode (nKey, bShift, nCode.IsMod1(), nCode.IsMod2(), nCode.IsMod3() );
	KeyEvent aKEvt(rKEvt.GetCharCode(), aKeyCode);

	sal_Bool bOK = sal_True;

	if (mpDocSh->IsReadOnly())
	{
		bOK = !EditEngine::DoesKeyChangeText(aKEvt);
	}
	if( aKeyCode.GetCode() == KEY_PAGEUP || aKeyCode.GetCode() == KEY_PAGEDOWN )
	{
		bOK = sal_False;   // default handling in base class
	}

	if (bOK && mpView->KeyInput(aKEvt, mpWindow) )
	{
		bReturn = sal_True;

		mpViewShell->GetViewFrame()->GetBindings().Invalidate( SidArray );

//		if ( pTextObj )
//			pTextObj->SetEmptyPresObj(sal_False);
	}
	else if (aKeyCode == KEY_ESCAPE)
	{
		bReturn = cancel();
	}

	if( bPermanent )
	{
		mpView->SetCurrentObj(OBJ_TEXT);
		mpView->SetEditMode(SDREDITMODE_CREATE);
	}

	if (!bReturn)
	{
		bReturn = FuDraw::KeyInput(aKEvt);
	}

	return (bReturn);
}



/*************************************************************************
|*
|* Function aktivieren
|*
\************************************************************************/

void FuText::Activate()
{
	mpView->SetQuickTextEditMode(mpViewShell->GetFrameView()->IsQuickEdit());

    // #i89661# it's no longer necessary to make it so big here, it's fine tuned
    // for text objects in SdrMarkView::CheckSingleSdrObjectHit
	mpView->SetHitTolerancePixel( 2 * HITPIX );

	OutlinerView* pOLV = mpView->GetTextEditOutlinerView();

	if (pOLV)
		pOLV->ShowCursor();

	FuConstruct::Activate();

	if( pOLV )
		mpView->SetEditMode(SDREDITMODE_EDIT);
}


/*************************************************************************
|*
|* Function deaktivieren
|*
\************************************************************************/

void FuText::Deactivate()
{
	OutlinerView* pOLV = mpView->GetTextEditOutlinerView();

	if (pOLV)
		pOLV->HideCursor();

	mpView->SetHitTolerancePixel( HITPIX );

	FuConstruct::Deactivate();
}


/*************************************************************************
|*
|* Objekt in Edit-Mode setzen
|*
\************************************************************************/

void FuText::SetInEditMode(const MouseEvent& rMEvt, sal_Bool bQuickDrag)
{
	SdrPageView* pPV = mpView->GetSdrPageView();
	if( mxTextObj.is() && (mxTextObj->GetPage() == pPV->GetPage()) )
	{
		mpView->SetCurrentObj(OBJ_TEXT);

		if( bPermanent )
			mpView->SetEditMode(SDREDITMODE_CREATE);
		else
			mpView->SetEditMode(SDREDITMODE_EDIT);

		sal_Bool bEmptyOutliner = sal_False;

		if (!GetTextObj()->GetOutlinerParaObject() && mpView->GetTextEditOutliner())
		{
			::Outliner* pOutl = mpView->GetTextEditOutliner();
			sal_uLong nParaAnz = pOutl->GetParagraphCount();
			Paragraph* p1stPara = pOutl->GetParagraph( 0 );

			if (nParaAnz==1 && p1stPara)
			{
				// Bei nur einem Pararaph
				if (pOutl->GetText(p1stPara).Len() == 0)
				{
					bEmptyOutliner = sal_True;
				}
			}
		}

		if (GetTextObj() != mpView->GetTextEditObject() || bEmptyOutliner)
		{
			sal_uInt32 nInv = mxTextObj->GetObjInventor();
			sal_uInt16 nSdrObjKind = mxTextObj->GetObjIdentifier();

			if (nInv == SdrInventor && GetTextObj()->HasTextEdit() &&
				(nSdrObjKind == OBJ_TEXT ||
			 	nSdrObjKind == OBJ_TITLETEXT ||
			 	nSdrObjKind == OBJ_OUTLINETEXT || !mxTextObj->IsEmptyPresObj() ) )
			{
				// Neuen Outliner machen (gehoert der SdrObjEditView)
				SdrOutliner* pOutl = SdrMakeOutliner( OUTLINERMODE_OUTLINEOBJECT, mpDoc );

				if (bEmptyOutliner)
					mpView->SdrEndTextEdit(sal_True);

				SdrTextObj* pTextObj = GetTextObj();
				if( pTextObj )
				{
					OutlinerParaObject* pOPO = pTextObj->GetOutlinerParaObject();
					if( ( pOPO && pOPO->IsVertical() ) || (nSlotId == SID_ATTR_CHAR_VERTICAL) || (nSlotId == SID_TEXT_FITTOSIZE_VERTICAL) )
						pOutl->SetVertical( sal_True );

					if( pTextObj->getTextCount() > 1 )
					{
						Point aPix(rMEvt.GetPosPixel());
						Point aPnt(mpWindow->PixelToLogic(aPix));
						pTextObj->setActiveText( pTextObj->CheckTextHit(aPnt ) );
					}

					if (mpView->SdrBeginTextEdit(pTextObj, pPV, mpWindow, sal_True, pOutl) && mxTextObj->GetObjInventor() == SdrInventor)
					{
						bFirstObjCreated = sal_True;
						DeleteDefaultText();

						OutlinerView* pOLV = mpView->GetTextEditOutlinerView();

						nSdrObjKind = mxTextObj->GetObjIdentifier();

						SdrViewEvent aVEvt;
						SdrHitKind eHit = mpView->PickAnything(rMEvt, SDRMOUSEBUTTONDOWN, aVEvt);

						if (eHit == SDRHIT_TEXTEDIT)
						{
							// Text getroffen
							if (nSdrObjKind == OBJ_TEXT ||
								nSdrObjKind == OBJ_TITLETEXT ||
								nSdrObjKind == OBJ_OUTLINETEXT ||
								nSdrObjKind == OBJ_TABLE ||
								nSlotId == SID_TEXTEDIT ||
								!bQuickDrag)
							{
								pOLV->MouseButtonDown(rMEvt);
								pOLV->MouseMove(rMEvt);
								pOLV->MouseButtonUp(rMEvt);
							}

							if (mpViewShell->GetFrameView()->IsQuickEdit() && bQuickDrag && GetTextObj()->GetOutlinerParaObject())
							{
								pOLV->MouseButtonDown(rMEvt);
							}
						}
						else
						{
							// #98198# Move cursor to end of text
							ESelection aNewSelection(EE_PARA_NOT_FOUND, EE_INDEX_NOT_FOUND, EE_PARA_NOT_FOUND, EE_INDEX_NOT_FOUND);
							if (pOLV != NULL)
								pOLV->SetSelection(aNewSelection);
						}
					}
					else
					{
						mpView->RestoreDefaultText(dynamic_cast< SdrTextObj* >( mxTextObj.get() ));
					}
				}
			}
		}
	}
	else
	{
		mxTextObj.reset(0);
	}
}

/*************************************************************************
|*
|* Texteingabe wird gestartet, ggf. Default-Text loeschen
|*
\************************************************************************/

sal_Bool FuText::DeleteDefaultText()
{
	sal_Bool bDeleted = sal_False;

	if ( mxTextObj.is() && mxTextObj->IsEmptyPresObj() )
	{
		String aString;
		SdPage* pPage = (SdPage*) mxTextObj->GetPage();

		if (pPage)
		{
			PresObjKind ePresObjKind = pPage->GetPresObjKind(mxTextObj.get());

			if ( (ePresObjKind == PRESOBJ_TITLE   ||
				  ePresObjKind == PRESOBJ_OUTLINE ||
				  ePresObjKind == PRESOBJ_NOTES   ||
				  ePresObjKind == PRESOBJ_TEXT) &&
				  !pPage->IsMasterPage() )
			{
				::Outliner* pOutliner = mpView->GetTextEditOutliner();
				SfxStyleSheet* pSheet = pOutliner->GetStyleSheet( 0 );
				sal_Bool bIsUndoEnabled = pOutliner->IsUndoEnabled();
				if( bIsUndoEnabled )
					pOutliner->EnableUndo(sal_False);

				pOutliner->SetText( String(), pOutliner->GetParagraph( 0 ) );

				if( bIsUndoEnabled )
					pOutliner->EnableUndo(sal_True);

				if (pSheet &&
					(ePresObjKind == PRESOBJ_NOTES || ePresObjKind == PRESOBJ_TEXT))
					pOutliner->SetStyleSheet(0, pSheet);

				mxTextObj->SetEmptyPresObj(sal_True);
				bDeleted = sal_True;
			}
		}
	}

	return(bDeleted);
}

/*************************************************************************
|*
|* Command-event
|*
\************************************************************************/

sal_Bool FuText::Command(const CommandEvent& rCEvt)
{
	return( FuPoor::Command(rCEvt) );
}

/*************************************************************************
|*
|* Help-event
|*
\************************************************************************/

sal_Bool FuText::RequestHelp(const HelpEvent& rHEvt)
{
	sal_Bool bReturn = sal_False;

	OutlinerView* pOLV = mpView->GetTextEditOutlinerView();

	if ((Help::IsBalloonHelpEnabled() || Help::IsQuickHelpEnabled()) &&
		mxTextObj.is() && pOLV && pOLV->GetFieldUnderMousePointer())
	{
		String aHelpText;
		const SvxFieldItem* pFieldItem = pOLV->GetFieldUnderMousePointer();
		const SvxFieldData* pField = pFieldItem->GetField();

		if (pField && pField->ISA(SvxURLField))
		{
			/******************************************************************
			* URL-Field
			******************************************************************/
			aHelpText = INetURLObject::decode( ((const SvxURLField*)pField)->GetURL(), '%', INetURLObject::DECODE_WITH_CHARSET );
		}
		if (aHelpText.Len())
		{
			Rectangle aLogicPix = mpWindow->LogicToPixel(mxTextObj->GetLogicRect());
			Rectangle aScreenRect(mpWindow->OutputToScreenPixel(aLogicPix.TopLeft()),
								  mpWindow->OutputToScreenPixel(aLogicPix.BottomRight()));

			if (Help::IsBalloonHelpEnabled())
			{
				bReturn = Help::ShowBalloon( (Window*)mpWindow, rHEvt.GetMousePosPixel(), aScreenRect, aHelpText);
			}
			else if (Help::IsQuickHelpEnabled())
			{
				bReturn = Help::ShowQuickHelp( (Window*)mpWindow, aScreenRect, aHelpText);
			}
		}
	}

	if (!bReturn)
	{
		bReturn = FuConstruct::RequestHelp(rHEvt);
	}

	return(bReturn);
}

/*************************************************************************
|*
|* Request verarbeiten
|*
\************************************************************************/

void FuText::ReceiveRequest(SfxRequest& rReq)
{
	nSlotId = rReq.GetSlot();

	// Dann Basisklasse rufen (dort wird u.a. nSlotId NICHT gesetzt)
	FuPoor::ReceiveRequest(rReq);

	if (nSlotId == SID_TEXTEDIT || mpViewShell->GetFrameView()->IsQuickEdit() || /*#95971#*/ SID_ATTR_CHAR == nSlotId)
	{
		MouseEvent aMEvt(mpWindow->GetPointerPosPixel());

		mxTextObj.reset(0);

		if (nSlotId == SID_TEXTEDIT)
		{
			// Wird gerade editiert?
			if(!bTestText)
				mxTextObj.reset( dynamic_cast< SdrTextObj* >( mpView->GetTextEditObject() ) );

			if (!mxTextObj.is())
			{
				// Versuchen, ein Obj zu selektieren
				SdrPageView* pPV = mpView->GetSdrPageView();
				SdrViewEvent aVEvt;
				mpView->PickAnything(aMEvt, SDRMOUSEBUTTONDOWN, aVEvt);
				mpView->MarkObj(aVEvt.pRootObj, pPV);

				if (aVEvt.pObj && aVEvt.pObj->ISA(SdrTextObj))
				{
					mxTextObj.reset( static_cast< SdrTextObj* >( aVEvt.pObj ) );
				}
			}
		}
		else if (mpView->AreObjectsMarked())
		{
			const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();

			if (rMarkList.GetMarkCount() == 1)
			{
				SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();

				if (pObj->ISA(SdrTextObj))
				{
					mxTextObj.reset( static_cast< SdrTextObj* >( pObj ) );
				}
			}
		}

		sal_Bool bQuickDrag = sal_True;

		const SfxItemSet* pArgs = rReq.GetArgs();

		if (pArgs

			// #98198# test for type before using
			&& SID_TEXTEDIT == nSlotId
			&& SFX_ITEM_SET == pArgs->GetItemState(SID_TEXTEDIT)

			&& (sal_uInt16) ((SfxUInt16Item&) pArgs->Get(SID_TEXTEDIT)).GetValue() == 2)
		{
			// Anwahl per Doppelklick -> kein QuickDrag zulassen
			bQuickDrag = sal_False;
		}

		SetInEditMode(aMEvt, bQuickDrag);
	}
}



/*************************************************************************
|*
|* SpellChecker: Error-LinkHdl
|*
\************************************************************************/

IMPL_LINK( FuText, SpellError, void *, nLang )
{
	String aError( SvtLanguageTable::GetLanguageString( (LanguageType)(sal_uLong)nLang ) );
	ErrorHandler::HandleError(* new StringErrorInfo(
								ERRCODE_SVX_LINGU_LANGUAGENOTEXISTS, aError) );
	return 0;
}


/*************************************************************************
|*
|* Reaktion auf Doppelklick
|*
\************************************************************************/
void FuText::DoubleClick(const MouseEvent& )
{
	// Nichts zu tun
}

/** #97016#
    #105815# Removed the insertion of default text and putting a new text
    object directly into edit mode.
*/
SdrObject* FuText::CreateDefaultObject(const sal_uInt16 nID, const Rectangle& rRectangle)
{
	// case SID_TEXTEDIT:	// BASIC ???
	// case SID_ATTR_CHAR:
	// case SID_ATTR_CHAR_VERTICAL:
	// case SID_TEXT_FITTOSIZE:
	// case SID_TEXT_FITTOSIZE_VERTICAL:

	SdrObject* pObj = SdrObjFactory::MakeNewObject(
		mpView->GetCurrentObjInventor(), mpView->GetCurrentObjIdentifier(),
		0L, mpDoc);

	if(pObj)
	{
		if(pObj->ISA(SdrTextObj))
		{
			SdrTextObj* pText = (SdrTextObj*)pObj;
			pText->SetLogicRect(rRectangle);

			sal_Bool bVertical = (SID_ATTR_CHAR_VERTICAL == nID || SID_TEXT_FITTOSIZE_VERTICAL == nID);
			pText->SetVerticalWriting(bVertical);

			// #97016#
			ImpSetAttributesForNewTextObject(pText);

			if (nSlotId == SID_TEXT_FITTOSIZE)
			{
				// #97016#
				ImpSetAttributesFitToSize(pText);
			}
			else if ( nSlotId == SID_TEXT_FITTOSIZE_VERTICAL )
			{
				// #97016#
				ImpSetAttributesFitToSizeVertical(pText);
			}
			else
			{
				// #97016#
				ImpSetAttributesFitCommon(pText);
			}

            // Put text object into edit mode.
            SdrPageView* pPV = mpView->GetSdrPageView();
            mpView->SdrBeginTextEdit(pText, pPV);
		}
		else
		{
			DBG_ERROR("Object is NO text object");
		}
	}

	return pObj;
}




/** is called when the currenct function should be aborted. <p>
	This is used when a function gets a KEY_ESCAPE but can also
	be called directly.

	@returns true if a active function was aborted
*/
bool FuText::cancel()
{
	if ( mpView->IsTextEdit() )
	{
		if(mpView->SdrEndTextEdit() == SDRENDTEXTEDIT_DELETED)
			mxTextObj.reset(0);

		mpView->SetCurrentObj(OBJ_TEXT);
		mpView->SetEditMode(SDREDITMODE_EDIT);
		return true;
	}
	else
	{
		return false;
	}
}

void FuText::ChangeFontSize( bool bGrow, OutlinerView* pOLV, const FontList* pFontList, ::sd::View* pView )
{
    if( !pFontList || !pView )
        return;

    if( pOLV )
    {
        pOLV->GetEditView().ChangeFontSize( bGrow, pFontList );
    }
    else
    {
//		SdDrawDocument* pDoc = pView->GetDoc();

        const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
        for( sal_uInt32 nMark = 0; nMark < rMarkList.GetMarkCount(); nMark++ )
        {
            SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( rMarkList.GetMark(nMark)->GetMarkedSdrObj() );
            if( pTextObj )
            {
                for( sal_Int32 nText = 0; nText < pTextObj->getTextCount(); nText++ )
                {
                    pTextObj->setActiveText( nText );

                    // Put text object into edit mode.
                    SdrPageView* pPV = pView->GetSdrPageView();
                    pView->SdrBeginTextEdit(pTextObj, pPV);

                    pOLV = pView->GetTextEditOutlinerView();
                    if( pOLV )
                    {
                        EditEngine* pEditEngine = pOLV->GetEditView().GetEditEngine();
                        if( pEditEngine )
                        {
                            ESelection aSel;
                            aSel.nEndPara = pEditEngine->GetParagraphCount()-1;
                            aSel.nEndPos = pEditEngine->GetTextLen(aSel.nEndPara);
                            pOLV->SetSelection(aSel);
                        }

                        ChangeFontSize( bGrow, pOLV, pFontList, pView );
                    }

                    pView->SdrEndTextEdit();
                }

                SfxItemSet aShapeSet( pTextObj->GetMergedItemSet() );
                if( EditView::ChangeFontSize( bGrow, aShapeSet, pFontList ) )
                {
                    pTextObj->SetObjectItemNoBroadcast( aShapeSet.Get( EE_CHAR_FONTHEIGHT ) );
                    pTextObj->SetObjectItemNoBroadcast( aShapeSet.Get( EE_CHAR_FONTHEIGHT_CJK ) );
                    pTextObj->SetObjectItemNoBroadcast( aShapeSet.Get( EE_CHAR_FONTHEIGHT_CTL ) );
                }
            }
        }                
    }
}

} // end of namespace sd

