text: /**************************************************************
   * 
   * 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_cui.hxx"
  
  // include ---------------------------------------------------------------
  
  #include <tools/shl.hxx>
  #include <sfx2/app.hxx>
  #include <svx/svdview.hxx>
  #include <svx/svdobj.hxx>
  #include <svx/svdpagv.hxx>
  #include <svx/svdotext.hxx>
  #include <svx/sderitm.hxx>
  #include <svx/dialogs.hrc>
  #include <cuires.hrc>
  #include "transfrm.hrc"
  #include <editeng/sizeitem.hxx>
  
  #include "transfrm.hxx"
  #include <dialmgr.hxx>
  #include "svx/dlgutil.hxx"
  #include <editeng/svxenum.hxx>
  #include "svx/anchorid.hxx"
  #include <sfx2/module.hxx>
  #include <svl/rectitem.hxx>
  #include <svl/aeitem.hxx>
  #include <swpossizetabpage.hxx>
  
  // Toleranz fuer WorkingArea
  #define DIFF 1000
  
  // static ----------------------------------------------------------------
  
  static sal_uInt16 pPosSizeRanges[] =
  {
  	SID_ATTR_TRANSFORM_POS_X,
  	SID_ATTR_TRANSFORM_POS_Y,
  	SID_ATTR_TRANSFORM_PROTECT_POS,
  	SID_ATTR_TRANSFORM_PROTECT_POS,
  	SID_ATTR_TRANSFORM_INTERN,
  	SID_ATTR_TRANSFORM_INTERN,
  	SID_ATTR_TRANSFORM_ANCHOR,
  	SID_ATTR_TRANSFORM_VERT_ORIENT,
  	SID_ATTR_TRANSFORM_WIDTH,
  	SID_ATTR_TRANSFORM_SIZE_POINT,
  	SID_ATTR_TRANSFORM_PROTECT_POS,
  	SID_ATTR_TRANSFORM_INTERN,
  	SID_ATTR_TRANSFORM_AUTOWIDTH,
  	SID_ATTR_TRANSFORM_AUTOHEIGHT,
  	0
  };
  
  static sal_uInt16 pAngleRanges[] =
  {
  	SID_ATTR_TRANSFORM_ROT_X,
  	SID_ATTR_TRANSFORM_ANGLE,
  	SID_ATTR_TRANSFORM_INTERN,
  	SID_ATTR_TRANSFORM_INTERN,
  	0
  };
  
  static sal_uInt16 pSlantRanges[] =
  {
  	SDRATTR_ECKENRADIUS,
  	SDRATTR_ECKENRADIUS,
  	SID_ATTR_TRANSFORM_SHEAR,
  	SID_ATTR_TRANSFORM_SHEAR_VERTICAL,
  	SID_ATTR_TRANSFORM_INTERN,
  	SID_ATTR_TRANSFORM_INTERN,
  	0
  };
  
  void lcl_ConvertRect(basegfx::B2DRange& rRange, const sal_uInt16 nDigits, const MapUnit ePoolUnit, const FieldUnit eDlgUnit)
  {
  	const basegfx::B2DPoint aTopLeft(
  		(double)MetricField::ConvertValue(basegfx::fround(rRange.getMinX()), nDigits, ePoolUnit, eDlgUnit),
  		(double)MetricField::ConvertValue(basegfx::fround(rRange.getMinY()), nDigits, ePoolUnit, eDlgUnit));
  	const basegfx::B2DPoint aBottomRight(
  		(double)MetricField::ConvertValue(basegfx::fround(rRange.getMaxX()), nDigits, ePoolUnit, eDlgUnit),
  		(double)MetricField::ConvertValue(basegfx::fround(rRange.getMaxY()), nDigits, ePoolUnit, eDlgUnit));
  
  	rRange = basegfx::B2DRange(aTopLeft, aBottomRight);
  }
  
  void lcl_ScaleRect(basegfx::B2DRange& rRange, const Fraction aUIScale)
  {
  	const double fFactor(1.0 / double(aUIScale));
  	rRange = basegfx::B2DRange(rRange.getMinimum() * fFactor, rRange.getMaximum() * fFactor);
  }
  
  /*************************************************************************
  |*
  |* Konstruktor des Tab-Dialogs: Fuegt die Seiten zum Dialog hinzu
  |*
  \************************************************************************/
  
  SvxTransformTabDialog::SvxTransformTabDialog( Window* pParent, const SfxItemSet* pAttr,
  								const SdrView* pSdrView, sal_uInt16 nAnchorTypes ) :
  	SfxTabDialog( pParent, CUI_RES( RID_SVXDLG_TRANSFORM ), pAttr ),
  	pView       ( pSdrView ),
  	nAnchorCtrls(nAnchorTypes)
  {
  	DBG_ASSERT(pView, "no valid view (!)");
  	FreeResource();
  
      //different positioning page in Writer
      if(nAnchorCtrls & 0x00ff)
      {        
          AddTabPage(RID_SVXPAGE_SWPOSSIZE, SvxSwPosSizeTabPage::Create, SvxSwPosSizeTabPage::GetRanges);
          RemoveTabPage(RID_SVXPAGE_POSITION_SIZE);
      }
      else
      {        
          AddTabPage(RID_SVXPAGE_POSITION_SIZE, SvxPositionSizeTabPage::Create, SvxPositionSizeTabPage::GetRanges);
          RemoveTabPage(RID_SVXPAGE_SWPOSSIZE);
      }
  
  	AddTabPage(RID_SVXPAGE_ANGLE, SvxAngleTabPage::Create, SvxAngleTabPage::GetRanges);
  	AddTabPage(RID_SVXPAGE_SLANT, SvxSlantTabPage::Create, SvxSlantTabPage::GetRanges);
  }
  
  // -----------------------------------------------------------------------
  
  SvxTransformTabDialog::~SvxTransformTabDialog()
  {
  }
  
  // -----------------------------------------------------------------------
  
  void SvxTransformTabDialog::PageCreated(sal_uInt16 nId, SfxTabPage &rPage)
  {
  	switch(nId)
  	{
  		case RID_SVXPAGE_POSITION_SIZE:
  		{
              SvxPositionSizeTabPage& rSvxPos =  static_cast<SvxPositionSizeTabPage&>(rPage);
  			rSvxPos.SetView(pView);
  			rSvxPos.Construct();
  			
  			if(nAnchorCtrls & SVX_OBJ_NORESIZE)
  			{
  				rSvxPos.DisableResize();
  			}
  
  			if(nAnchorCtrls & SVX_OBJ_NOPROTECT)
  			{
  				rSvxPos.DisableProtect();
  				rSvxPos.UpdateControlStates();
  			}
  		
  			break;
  		}
          case RID_SVXPAGE_SWPOSSIZE :
          {
              SvxSwPosSizeTabPage& rSwPos =  static_cast<SvxSwPosSizeTabPage&>(rPage);
  
  			rSwPos.EnableAnchorTypes(nAnchorCtrls);
              rSwPos.SetValidateFramePosLink(aValidateLink);
              rSwPos.SetView(pView);
  
  			break;
          }
  
  		case RID_SVXPAGE_ANGLE:
  		{
              SvxAngleTabPage& rSvxAng =  static_cast<SvxAngleTabPage&>(rPage);
  
  			rSvxAng.SetView( pView );
  			rSvxAng.Construct();
  		
  			break;
  		}
  
  		case RID_SVXPAGE_SLANT:
  		{
              SvxSlantTabPage& rSvxSlnt =  static_cast<SvxSlantTabPage&>(rPage);
  
  			rSvxSlnt.SetView( pView );
  			rSvxSlnt.Construct();
  
  			break;
  		}
  	}
  }
  
  // -----------------------------------------------------------------------
  
  void SvxTransformTabDialog::SetValidateFramePosLink(const Link& rLink)
  {
      aValidateLink = rLink;
  }
  
  /*************************************************************************
  |*
  |*      Dialog zum Aendern der Position des Drehwinkels und des Drehwinkels
  |*      der Grafikobjekte
  |*
  \************************************************************************/
  
  SvxAngleTabPage::SvxAngleTabPage( Window* pParent, const SfxItemSet& rInAttrs  ) :
  	SvxTabPage              ( pParent, CUI_RES( RID_SVXPAGE_ANGLE ), rInAttrs ),
  	aFlPosition				( this, CUI_RES( FL_POSITION ) ),
  	aFtPosX                 ( this, CUI_RES( FT_POS_X ) ),
  	aMtrPosX                ( this, CUI_RES( MTR_FLD_POS_X ) ),
  	aFtPosY                 ( this, CUI_RES( FT_POS_Y ) ),
  	aMtrPosY                ( this, CUI_RES( MTR_FLD_POS_Y ) ),
  	aFtPosPresets			( this, CUI_RES(FT_POSPRESETS) ),	
  	aCtlRect                ( this, CUI_RES( CTL_RECT ) ),
  	
  	aFlAngle                ( this, CUI_RES( FL_ANGLE ) ),
  	aFtAngle                ( this, CUI_RES( FT_ANGLE ) ),
  	aMtrAngle               ( this, CUI_RES( MTR_FLD_ANGLE ) ),
  	aFtAnglePresets			( this, CUI_RES(FT_ANGLEPRESETS) ),	
  	aCtlAngle               ( this, CUI_RES( CTL_ANGLE ),
  								RP_RB, 200, 80, CS_ANGLE ),
  	rOutAttrs               ( rInAttrs )
  {
  	FreeResource();
  
  	// calculate PoolUnit
  	SfxItemPool* pPool = rOutAttrs.GetPool();
  	DBG_ASSERT( pPool, "no pool (!)" );
  	ePoolUnit = pPool->GetMetric(SID_ATTR_TRANSFORM_POS_X);
  
  	aMtrAngle.SetModifyHdl(LINK( this, SvxAngleTabPage, ModifiedHdl));
  
  	aCtlRect.SetAccessibleRelationLabeledBy(&aFtPosPresets);
  	aCtlRect.SetAccessibleRelationMemberOf(&aFlPosition);
  	aCtlAngle.SetAccessibleRelationLabeledBy(&aFtAnglePresets);
  	aCtlAngle.SetAccessibleRelationMemberOf(&aFlAngle);	
  }
  
  // -----------------------------------------------------------------------
  
  void SvxAngleTabPage::Construct()
  {
  	DBG_ASSERT(pView, "No valid view (!)");
  	eDlgUnit = GetModuleFieldUnit(GetItemSet());
  	SetFieldUnit(aMtrPosX, eDlgUnit, sal_True);
  	SetFieldUnit(aMtrPosY, eDlgUnit, sal_True);
  
  	if(FUNIT_MILE == eDlgUnit || FUNIT_KM == eDlgUnit)
  	{
  		aMtrPosX.SetDecimalDigits( 3 );
  		aMtrPosY.SetDecimalDigits( 3 );
  	}
  
  	{ // #i75273#
  		Rectangle aTempRect(pView->GetAllMarkedRect());
  		pView->GetSdrPageView()->LogicToPagePos(aTempRect);
  		maRange = basegfx::B2DRange(aTempRect.Left(), aTempRect.Top(), aTempRect.Right(), aTempRect.Bottom());
  	}
  
  	// Take anchor into account (Writer)
  	const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
  
  	if(rMarkList.GetMarkCount())
  	{
  		const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
  		maAnchor = basegfx::B2DPoint(pObj->GetAnchorPos().X(), pObj->GetAnchorPos().Y());
  
  		if(!maAnchor.equalZero()) // -> Writer
  		{
  			maRange = basegfx::B2DRange(maRange.getMinimum() - maAnchor, maRange.getMaximum() - maAnchor);
  		}
  	}
  
  	// take scale into account
  	const Fraction aUIScale(pView->GetModel()->GetUIScale());
  	lcl_ScaleRect(maRange, aUIScale);
  
  	// take UI units into account
  	sal_uInt16 nDigits(aMtrPosX.GetDecimalDigits());
  	lcl_ConvertRect(maRange, nDigits, (MapUnit)ePoolUnit, eDlgUnit);
  
  	if(!pView->IsRotateAllowed())
  	{
  		aFlPosition.Disable();
  		aFtPosX.Disable();
  		aMtrPosX.Disable();
  		aFtPosY.Disable();
  		aMtrPosY.Disable();
  		aFtPosPresets.Disable();
  		aCtlRect.Disable();
  		aFlAngle.Disable();
  		aFtAngle.Disable();
  		aMtrAngle.Disable();
  		aFtAnglePresets.Disable();
  		aCtlAngle.Disable();
  	}
  }
  
  // -----------------------------------------------------------------------
  
  sal_Bool SvxAngleTabPage::FillItemSet(SfxItemSet& rSet)
  {
  	sal_Bool bModified = sal_False;
  
  	if(aMtrAngle.IsValueModified() || aMtrPosX.IsValueModified() || aMtrPosY.IsValueModified())
  	{
  		const double fUIScale(double(pView->GetModel()->GetUIScale()));
  		const double fTmpX((GetCoreValue(aMtrPosX, ePoolUnit) + maAnchor.getX()) * fUIScale);
  		const double fTmpY((GetCoreValue(aMtrPosY, ePoolUnit) + maAnchor.getY()) * fUIScale);
  
  		rSet.Put(SfxInt32Item(GetWhich(SID_ATTR_TRANSFORM_ANGLE), static_cast<sal_Int32>(aMtrAngle.GetValue())));
  		rSet.Put(SfxInt32Item(GetWhich(SID_ATTR_TRANSFORM_ROT_X), basegfx::fround(fTmpX)));
          rSet.Put(SfxInt32Item(GetWhich(SID_ATTR_TRANSFORM_ROT_Y), basegfx::fround(fTmpY)));
  
  		bModified |= sal_True;
  	}
  
  	return bModified;
  }
  
  // -----------------------------------------------------------------------
  
  void SvxAngleTabPage::Reset(const SfxItemSet& rAttrs)
  {
  	const double fUIScale(double(pView->GetModel()->GetUIScale()));
  
  	const SfxPoolItem* pItem = GetItem( rAttrs, SID_ATTR_TRANSFORM_ROT_X );
  	if(pItem)
  	{
  		const double fTmp(((double)((const SfxInt32Item*)pItem)->GetValue() - maAnchor.getX()) / fUIScale);
  		SetMetricValue(aMtrPosX, basegfx::fround(fTmp), ePoolUnit);
  	}
  	else
  	{
  		aMtrPosX.SetText( String() );
  	}
  
  	pItem = GetItem(rAttrs, SID_ATTR_TRANSFORM_ROT_Y);
  	if(pItem)
  	{
  		const double fTmp(((double)((const SfxInt32Item*)pItem)->GetValue() - maAnchor.getY()) / fUIScale);
  		SetMetricValue(aMtrPosY, basegfx::fround(fTmp), ePoolUnit);
  	}
  	else
  	{
  		aMtrPosX.SetText( String() );
  	}
  
  	pItem = GetItem( rAttrs, SID_ATTR_TRANSFORM_ANGLE );
  	if(pItem)
  	{
  		aMtrAngle.SetValue(((const SfxInt32Item*)pItem)->GetValue());
  	}
  	else
  	{
  		aMtrAngle.SetText( String() );
  	}
  
  	aMtrAngle.SaveValue();
  	ModifiedHdl(this);
  }
  
  // -----------------------------------------------------------------------
  
  SfxTabPage* SvxAngleTabPage::Create( Window* pWindow, const SfxItemSet& rSet)
  {
      return(new SvxAngleTabPage(pWindow, rSet));
  }
  
  //------------------------------------------------------------------------
  
  sal_uInt16* SvxAngleTabPage::GetRanges()
  {
  	return(pAngleRanges);
  }
  
  // -----------------------------------------------------------------------
  
  void SvxAngleTabPage::ActivatePage(const SfxItemSet& /*rSet*/)
  {
  }
  
  // -----------------------------------------------------------------------
  
  int SvxAngleTabPage::DeactivatePage( SfxItemSet* _pSet )
  {
      if(_pSet)
  	{
          FillItemSet(*_pSet);
  	}
  
  	return LEAVE_PAGE;
  }
  
  //------------------------------------------------------------------------
  
  void SvxAngleTabPage::PointChanged(Window* pWindow, RECT_POINT eRP)
  {
  	if(pWindow == &aCtlRect)
  	{
  		switch(eRP)
  		{
  			case RP_LT:
  			{
  				aMtrPosX.SetUserValue( basegfx::fround64(maRange.getMinX()), FUNIT_NONE );
  				aMtrPosY.SetUserValue( basegfx::fround64(maRange.getMinY()), FUNIT_NONE );
  				break;
  			}
  			case RP_MT:
  			{
  				aMtrPosX.SetUserValue( basegfx::fround64(maRange.getCenter().getX()), FUNIT_NONE );
  				aMtrPosY.SetUserValue( basegfx::fround64(maRange.getMinY()), FUNIT_NONE );
  				break;
  			}
  			case RP_RT:
  			{
  				aMtrPosX.SetUserValue( basegfx::fround64(maRange.getMaxX()), FUNIT_NONE );
  				aMtrPosY.SetUserValue( basegfx::fround64(maRange.getMinY()), FUNIT_NONE );
  				break;
  			}
  			case RP_LM:
  			{
  				aMtrPosX.SetUserValue( basegfx::fround64(maRange.getMinX()), FUNIT_NONE );
  				aMtrPosY.SetUserValue( basegfx::fround64(maRange.getCenter().getY()), FUNIT_NONE );
  				break;
  			}
  			case RP_MM:
  			{
  				aMtrPosX.SetUserValue( basegfx::fround64(maRange.getCenter().getX()), FUNIT_NONE );
  				aMtrPosY.SetUserValue( basegfx::fround64(maRange.getCenter().getY()), FUNIT_NONE );
  				break;
  			}
  			case RP_RM:
  			{
  				aMtrPosX.SetUserValue( basegfx::fround64(maRange.getMaxX()), FUNIT_NONE );
  				aMtrPosY.SetUserValue( basegfx::fround64(maRange.getCenter().getY()), FUNIT_NONE );
  				break;
  			}
  			case RP_LB:
  			{
  				aMtrPosX.SetUserValue( basegfx::fround64(maRange.getMinX()), FUNIT_NONE );
  				aMtrPosY.SetUserValue( basegfx::fround64(maRange.getMaxY()), FUNIT_NONE );
  				break;
  			}
  			case RP_MB:
  			{
  				aMtrPosX.SetUserValue( basegfx::fround64(maRange.getCenter().getX()), FUNIT_NONE );
  				aMtrPosY.SetUserValue( basegfx::fround64(maRange.getMaxY()), FUNIT_NONE );
  				break;
  			}
  			case RP_RB:
  			{
  				aMtrPosX.SetUserValue( basegfx::fround64(maRange.getMaxX()), FUNIT_NONE );
  				aMtrPosY.SetUserValue( basegfx::fround64(maRange.getMaxY()), FUNIT_NONE );
  				break;
  			}
  		}
  	}
  	else if(pWindow == &aCtlAngle)
  	{
  		switch( eRP )
  		{
  			case RP_LT: aMtrAngle.SetUserValue( 13500, FUNIT_NONE ); break;
  			case RP_MT: aMtrAngle.SetUserValue(  9000, FUNIT_NONE ); break;
  			case RP_RT: aMtrAngle.SetUserValue(  4500, FUNIT_NONE ); break;
  			case RP_LM: aMtrAngle.SetUserValue( 18000, FUNIT_NONE ); break;
  			case RP_RM: aMtrAngle.SetUserValue(     0, FUNIT_NONE ); break;
  			case RP_LB: aMtrAngle.SetUserValue( 22500, FUNIT_NONE ); break;
  			case RP_MB: aMtrAngle.SetUserValue( 27000, FUNIT_NONE ); break;
  			case RP_RB: aMtrAngle.SetUserValue( 31500, FUNIT_NONE ); break;
              case RP_MM: break;
          }
  	}
  }
  
  //------------------------------------------------------------------------
  
  IMPL_LINK( SvxAngleTabPage, ModifiedHdl, void *, EMPTYARG )
  {
  	switch(aMtrAngle.GetValue())
  	{
  		case 13500: aCtlAngle.SetActualRP( RP_LT ); break;
  		case  9000: aCtlAngle.SetActualRP( RP_MT ); break;
  		case  4500: aCtlAngle.SetActualRP( RP_RT ); break;
  		case 18000: aCtlAngle.SetActualRP( RP_LM ); break;
  		case     0: aCtlAngle.SetActualRP( RP_RM ); break;
  		case 22500: aCtlAngle.SetActualRP( RP_LB ); break;
  		case 27000: aCtlAngle.SetActualRP( RP_MB ); break;
  		case 31500: aCtlAngle.SetActualRP( RP_RB ); break;
  		default:    aCtlAngle.SetActualRP( RP_MM ); break;
  	}
  
  	return( 0L );
  }
  
  /*************************************************************************
  |*
  |*      Dialog zum Aendern des Eckenradius und zum Schraegstellen
  |*
  \************************************************************************/
  
  SvxSlantTabPage::SvxSlantTabPage( Window* pParent, const SfxItemSet& rInAttrs  ) :
  	SvxTabPage              ( pParent, CUI_RES( RID_SVXPAGE_SLANT ), rInAttrs ),
  
  	aFlRadius               ( this, CUI_RES( FL_RADIUS ) ),
  	aFtRadius               ( this, CUI_RES( FT_RADIUS ) ),
  	aMtrRadius              ( this, CUI_RES( MTR_FLD_RADIUS ) ),
  	aFlAngle                ( this, CUI_RES( FL_SLANT ) ),
  	aFtAngle                ( this, CUI_RES( FT_ANGLE ) ),
  	aMtrAngle               ( this, CUI_RES( MTR_FLD_ANGLE ) ),
  	rOutAttrs               ( rInAttrs )
  {
  	FreeResource();
  
  	// this page needs ExchangeSupport
  	SetExchangeSupport();
  
  	// evaluate PoolUnit
  	SfxItemPool* pPool = rOutAttrs.GetPool();
  	DBG_ASSERT( pPool, "no pool (!)" );
  	ePoolUnit = pPool->GetMetric( SID_ATTR_TRANSFORM_POS_X );
  }
  
  // -----------------------------------------------------------------------
  
  void SvxSlantTabPage::Construct()
  {
  	// get the range
  	DBG_ASSERT(pView, "no valid view (!)");
  	eDlgUnit = GetModuleFieldUnit(GetItemSet());
  	SetFieldUnit(aMtrRadius, eDlgUnit, sal_True);
  
  	{ // #i75273#
  		Rectangle aTempRect(pView->GetAllMarkedRect());
  		pView->GetSdrPageView()->LogicToPagePos(aTempRect);
  		maRange = basegfx::B2DRange(aTempRect.Left(), aTempRect.Top(), aTempRect.Right(), aTempRect.Bottom());
  	}
  }
  
  // -----------------------------------------------------------------------
  
  sal_Bool SvxSlantTabPage::FillItemSet(SfxItemSet& rAttrs)
  {
  	sal_Bool  bModified = sal_False;
  	sal_Int32 nValue = 0L;
  	String aStr = aMtrRadius.GetText();
  
  	if( aStr != aMtrRadius.GetSavedValue() )
  	{
  		Fraction aUIScale = pView->GetModel()->GetUIScale();
  		long nTmp = GetCoreValue( aMtrRadius, ePoolUnit );
  		nTmp = Fraction( nTmp ) * aUIScale;
  
  		rAttrs.Put( SdrEckenradiusItem( nTmp ) );
  		bModified = sal_True;
  	}
  
  	aStr = aMtrAngle.GetText();
  
  	if( aStr != aMtrAngle.GetSavedValue() )
  	{
  		nValue = static_cast<sal_Int32>(aMtrAngle.GetValue());
  		rAttrs.Put( SfxInt32Item( SID_ATTR_TRANSFORM_SHEAR, nValue ) );
  		bModified = sal_True;
  	}
  
  	if( bModified )
  	{
  		// Referenzpunkt setzen
  		// #75897#
  		Rectangle aObjectRect(pView->GetAllMarkedRect());
  		pView->GetSdrPageView()->LogicToPagePos(aObjectRect);
  		Point aPt = aObjectRect.Center();
  
  		rAttrs.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_X, aPt.X()));
  		rAttrs.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_Y, aPt.Y()));
  		rAttrs.Put( SfxBoolItem( SID_ATTR_TRANSFORM_SHEAR_VERTICAL, sal_False ) );
  	}
  
  	return( bModified );
  }
  
  // -----------------------------------------------------------------------
  
  void SvxSlantTabPage::Reset(const SfxItemSet& rAttrs)
  {
  	// if the view has selected objects, items with SFX_ITEM_DEFAULT need to be disabled
  	const SfxPoolItem* pItem;
  
  	// Eckenradius
  	if(!pView->IsEdgeRadiusAllowed())
  	{
  		aFlRadius.Disable();
  		aFtRadius.Disable();
  		aMtrRadius.Disable();
  		aMtrRadius.SetText( String() );
  	}
  	else
  	{
  		pItem = GetItem( rAttrs, SDRATTR_ECKENRADIUS );
  
  		if( pItem )
  		{
  			const double fUIScale(double(pView->GetModel()->GetUIScale()));
  			const double fTmp((double)((const SdrEckenradiusItem*)pItem)->GetValue() / fUIScale);
  			SetMetricValue(aMtrRadius, basegfx::fround(fTmp), ePoolUnit);
  		}
  		else
  		{
  			aMtrRadius.SetText( String() );
  		}
  	}
  
  	aMtrRadius.SaveValue();
  
  	// Schraegstellen: Winkel
  	if( !pView->IsShearAllowed() )
  	{
  		aFlAngle.Disable();
  		aFtAngle.Disable();
  		aMtrAngle.Disable();
  		aMtrAngle.SetText( String() );
  	}
  	else
  	{
  		pItem = GetItem( rAttrs, SID_ATTR_TRANSFORM_SHEAR );
  
  		if( pItem )
  		{
  			aMtrAngle.SetValue( ( (const SfxInt32Item*)pItem )->GetValue() );
  		}
  		else
  		{
  			aMtrAngle.SetText( String() );
  		}
  	}
  
  	aMtrAngle.SaveValue();
  }
  
  // -----------------------------------------------------------------------
  
  SfxTabPage* SvxSlantTabPage::Create( Window* pWindow, const SfxItemSet& rOutAttrs )
  {
  	return( new SvxSlantTabPage( pWindow, rOutAttrs ) );
  }
  
  //------------------------------------------------------------------------
  
  sal_uInt16* SvxSlantTabPage::GetRanges()
  {
  	return( pSlantRanges );
  }
  
  // -----------------------------------------------------------------------
  
  void SvxSlantTabPage::ActivatePage( const SfxItemSet& rSet )
  {
  	SfxRectangleItem* pRectItem = NULL;
  
  	if( SFX_ITEM_SET == rSet.GetItemState( GetWhich( SID_ATTR_TRANSFORM_INTERN ) , sal_False, (const SfxPoolItem**) &pRectItem ) )
  	{
  		const Rectangle aTempRect(pRectItem->GetValue());
  		maRange = basegfx::B2DRange(aTempRect.Left(), aTempRect.Top(), aTempRect.Right(), aTempRect.Bottom());
  	}
  }
  
  // -----------------------------------------------------------------------
  
  int SvxSlantTabPage::DeactivatePage( SfxItemSet* _pSet )
  {
      if(_pSet)
  	{
          FillItemSet(*_pSet);
  	}
  
  	return LEAVE_PAGE;
  }
  
  //------------------------------------------------------------------------
  
  void SvxSlantTabPage::PointChanged( Window* , RECT_POINT  )
  {
  }
  
  /*************************************************************************
  |*
  |*      Dialog for changing position and size of graphic objects
  |*
  \************************************************************************/
  
  SvxPositionSizeTabPage::SvxPositionSizeTabPage( Window* pParent, const SfxItemSet& rInAttrs  ) :
  	SvxTabPage      ( pParent, CUI_RES( RID_SVXPAGE_POSITION_SIZE ), rInAttrs ),
  	maFlPosition		( this, CUI_RES( FL_POSITION ) ),
  	maFtPosX			( this, CUI_RES( FT_POS_X ) ),
  	maMtrPosX			( this, CUI_RES( MTR_FLD_POS_X ) ),
  	maFtPosY			( this, CUI_RES( FT_POS_Y ) ),
  	maMtrPosY			( this, CUI_RES( MTR_FLD_POS_Y ) ),
      maFtPosReference    ( this, CUI_RES( FT_POSREFERENCE ) ),
      maCtlPos            ( this, CUI_RES( CTL_POSRECT ), RP_LT ),
      
      maFlSize                         ( this, CUI_RES( FL_SIZE ) ),
  	maFtWidth                        ( this, CUI_RES( FT_WIDTH ) ),
  	maMtrWidth                       ( this, CUI_RES( MTR_FLD_WIDTH ) ),
  	maFtHeight                       ( this, CUI_RES( FT_HEIGHT ) ),
  	maMtrHeight                      ( this, CUI_RES( MTR_FLD_HEIGHT ) ),
  	maCbxScale                       ( this, CUI_RES( CBX_SCALE ) ),
      maFtSizeReference                ( this, CUI_RES( FT_SIZEREFERENCE) ),       
      maCtlSize                        ( this, CUI_RES( CTL_SIZERECT ), RP_LT ),
      
      maFlProtect         ( this, CUI_RES( FL_PROTECT) ),
      maTsbPosProtect     ( this, CUI_RES( TSB_POSPROTECT ) ),
      maTsbSizeProtect                 ( this, CUI_RES( TSB_SIZEPROTECT ) ),
      
  
      maFlAdjust                       ( this, CUI_RES( FL_ADJUST ) ),
  	maTsbAutoGrowWidth				( this, CUI_RES( TSB_AUTOGROW_WIDTH ) ),
  	maTsbAutoGrowHeight				( this, CUI_RES( TSB_AUTOGROW_HEIGHT ) ),
  
  	maFlDivider						(this, CUI_RES( FL_DIVIDER ) ),
      
      mrOutAttrs       ( rInAttrs ),
      mnProtectSizeState( STATE_NOCHECK ),
      mbPageDisabled   ( sal_False ),
      mbProtectDisabled( false ),
      mbSizeDisabled( false ),
      mbAdjustDisabled( true )
  {
  	FreeResource();
  
  	// this pege needs ExchangeSupport
  	SetExchangeSupport();
  
  	// evaluate PoolUnit
  	SfxItemPool* pPool = mrOutAttrs.GetPool();
  	DBG_ASSERT( pPool, "no pool (!)" );
  	mePoolUnit = pPool->GetMetric( SID_ATTR_TRANSFORM_POS_X );
  
  	meRP = RP_LT; // s.o.
  
  	maMtrWidth.SetModifyHdl( LINK( this, SvxPositionSizeTabPage, ChangeWidthHdl ) );
  	maMtrHeight.SetModifyHdl( LINK( this, SvxPositionSizeTabPage, ChangeHeightHdl ) );
  	maCbxScale.SetClickHdl( LINK( this, SvxPositionSizeTabPage, ClickAutoHdl ) );
  
  	maTsbAutoGrowWidth.Disable();
  	maTsbAutoGrowHeight.Disable();
  	maFlAdjust.Disable();
  
  	// #i2379# disable controls when protected
  	maTsbPosProtect.SetClickHdl( LINK( this, SvxPositionSizeTabPage, ChangePosProtectHdl ) );
  	maTsbSizeProtect.SetClickHdl( LINK( this, SvxPositionSizeTabPage, ChangeSizeProtectHdl ) );
  
  	maCtlPos.SetAccessibleRelationMemberOf( &maFlPosition );
  	maCtlSize.SetAccessibleRelationMemberOf( &maFlSize );
      maCtlPos.SetAccessibleRelationLabeledBy( &maFtPosReference );
  	maCtlSize.SetAccessibleRelationLabeledBy( &maFtSizeReference );
  }
  
  // -----------------------------------------------------------------------
  
  void SvxPositionSizeTabPage::Construct()
  {
  	// get range and work area
  	DBG_ASSERT( mpView, "no valid view (!)" );
  	meDlgUnit = GetModuleFieldUnit( GetItemSet() );
  	SetFieldUnit( maMtrPosX, meDlgUnit, sal_True );
  	SetFieldUnit( maMtrPosY, meDlgUnit, sal_True );
  	SetFieldUnit( maMtrWidth, meDlgUnit, sal_True );
  	SetFieldUnit( maMtrHeight, meDlgUnit, sal_True );
  
  	if(FUNIT_MILE == meDlgUnit || FUNIT_KM == meDlgUnit)
  	{
  		maMtrPosX.SetDecimalDigits( 3 );
  		maMtrPosY.SetDecimalDigits( 3 );
  		maMtrWidth.SetDecimalDigits( 3 );
  		maMtrHeight.SetDecimalDigits( 3 );
  	}
  
  	{ // #i75273#
  		Rectangle aTempRect(mpView->GetAllMarkedRect());
  		mpView->GetSdrPageView()->LogicToPagePos(aTempRect);
  		maRange = basegfx::B2DRange(aTempRect.Left(), aTempRect.Top(), aTempRect.Right(), aTempRect.Bottom());
  	}
  
  	{ // #i75273#
  		Rectangle aTempRect(mpView->GetWorkArea());
  		mpView->GetSdrPageView()->LogicToPagePos(aTempRect);
  		maWorkRange = basegfx::B2DRange(aTempRect.Left(), aTempRect.Top(), aTempRect.Right(), aTempRect.Bottom());
  	}
  
  	// take anchor into account (Writer)
  	const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
  
  	if(rMarkList.GetMarkCount())
  	{
  		const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
  		maAnchor = basegfx::B2DPoint(pObj->GetAnchorPos().X(), pObj->GetAnchorPos().Y());
  
  		if(!maAnchor.equalZero()) // -> Writer
  		{
  			for(sal_uInt16 i(1); i < rMarkList.GetMarkCount(); i++)
  			{
  				pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
  
  				if(maAnchor != basegfx::B2DPoint(pObj->GetAnchorPos().X(), pObj->GetAnchorPos().Y()))
  				{
  					// different anchor positions
  					maMtrPosX.SetText( String() );
  					maMtrPosY.SetText( String() );
  					mbPageDisabled = sal_True;
  					return;
  				}
  			}
  
  			// translate ranges about anchor
  			maRange = basegfx::B2DRange(maRange.getMinimum() - maAnchor, maRange.getMaximum() - maAnchor);
  			maWorkRange = basegfx::B2DRange(maWorkRange.getMinimum() - maAnchor, maWorkRange.getMaximum() - maAnchor);
  		}
  	}
  
  	// this should happen via SID_ATTR_TRANSFORM_AUTOSIZE 
  	if(1 == rMarkList.GetMarkCount())
  	{
  		const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
  		const SdrObjKind eKind((SdrObjKind)pObj->GetObjIdentifier());
  
  		if((pObj->GetObjInventor() == SdrInventor) && 
              (OBJ_TEXT == eKind || OBJ_TITLETEXT == eKind || OBJ_OUTLINETEXT == eKind) && 
              pObj->HasText())
  		{
  			mbAdjustDisabled = false;
  			maFlAdjust.Enable();
  			maTsbAutoGrowWidth.Enable();
  			maTsbAutoGrowHeight.Enable();
  			maTsbAutoGrowWidth.SetClickHdl( LINK( this, SvxPositionSizeTabPage, ClickSizeProtectHdl ) );
  			maTsbAutoGrowHeight.SetClickHdl( LINK( this, SvxPositionSizeTabPage, ClickSizeProtectHdl ) );
  
  			// is used as flag to evaluate if its selectable
  			maTsbAutoGrowWidth.EnableTriState( sal_False );
  			maTsbAutoGrowHeight.EnableTriState( sal_False );
  		}
  	}
  
  	// take scale into account
  	const Fraction aUIScale(mpView->GetModel()->GetUIScale());
  	lcl_ScaleRect( maWorkRange, aUIScale );
  	lcl_ScaleRect( maRange, aUIScale );
  
  	// take UI units into account
  	const sal_uInt16 nDigits(maMtrPosX.GetDecimalDigits());
  	lcl_ConvertRect( maWorkRange, nDigits, (MapUnit) mePoolUnit, meDlgUnit );
  	lcl_ConvertRect( maRange, nDigits, (MapUnit) mePoolUnit, meDlgUnit );
  
  	SetMinMaxPosition();
  }
  
  // -----------------------------------------------------------------------
  
  sal_Bool SvxPositionSizeTabPage::FillItemSet( SfxItemSet& rOutAttrs )
  {
  	sal_Bool bModified(sal_False);
  
  	if ( maMtrWidth.HasFocus() )
  	{
  		ChangeWidthHdl( this );
  	}
  
  	if ( maMtrHeight.HasFocus() )
  	{
  		ChangeHeightHdl( this );
  	}
  
  	if( !mbPageDisabled )
  	{
  		if ( maMtrPosX.IsValueModified() || maMtrPosY.IsValueModified() )
  		{
  			const double fUIScale(double(mpView->GetModel()->GetUIScale()));
  			double fX((GetCoreValue( maMtrPosX, mePoolUnit ) + maAnchor.getX()) * fUIScale);
  			double fY((GetCoreValue( maMtrPosY, mePoolUnit ) + maAnchor.getY()) * fUIScale);
  
  			{ // #i75273#
  				Rectangle aTempRect(mpView->GetAllMarkedRect());
  				mpView->GetSdrPageView()->LogicToPagePos(aTempRect);
  				maRange = basegfx::B2DRange(aTempRect.Left(), aTempRect.Top(), aTempRect.Right(), aTempRect.Bottom());
  			}
  
  			// #101581# GetTopLeftPosition(...) needs coordinates after UI scaling, in real PagePositions
  			GetTopLeftPosition(fX, fY, maRange);
  
  			rOutAttrs.Put(SfxInt32Item(GetWhich(SID_ATTR_TRANSFORM_POS_X), basegfx::fround(fX)));
  			rOutAttrs.Put(SfxInt32Item(GetWhich(SID_ATTR_TRANSFORM_POS_Y), basegfx::fround(fY)));
  
  			bModified |= sal_True;
  		}
  
  		if ( maTsbPosProtect.GetState() != maTsbPosProtect.GetSavedValue() )
  		{
  			if( maTsbPosProtect.GetState() == STATE_DONTKNOW )
  			{
  				rOutAttrs.InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_POS );
  			}
  			else
  			{
  				rOutAttrs.Put(
  					SfxBoolItem( GetWhich( SID_ATTR_TRANSFORM_PROTECT_POS ),
  					maTsbPosProtect.GetState() == STATE_CHECK ? sal_True : sal_False ) );
  			}
  
  			bModified |= sal_True;
  		}
  	}
  
  	if ( maMtrWidth.IsValueModified() || maMtrHeight.IsValueModified() )
  	{
  		Fraction aUIScale = mpView->GetModel()->GetUIScale();
  
  		// get Width
  		double nWidth = static_cast<double>(maMtrWidth.GetValue( meDlgUnit ));
  		nWidth = MetricField::ConvertDoubleValue( nWidth, maMtrWidth.GetBaseValue(), maMtrWidth.GetDecimalDigits(), meDlgUnit, FUNIT_100TH_MM );
          long lWidth = long(nWidth * (double)aUIScale);
  		lWidth = OutputDevice::LogicToLogic( lWidth, MAP_100TH_MM, (MapUnit)mePoolUnit );
  		lWidth = static_cast<long>(maMtrWidth.Denormalize( lWidth ));
  
  		// get Height
  		double nHeight = static_cast<double>(maMtrHeight.GetValue( meDlgUnit ));
  		nHeight = MetricField::ConvertDoubleValue( nHeight, maMtrHeight.GetBaseValue(), maMtrHeight.GetDecimalDigits(), meDlgUnit, FUNIT_100TH_MM );
          long lHeight = long(nHeight * (double)aUIScale);
  		lHeight = OutputDevice::LogicToLogic( lHeight, MAP_100TH_MM, (MapUnit)mePoolUnit );
  		lHeight = static_cast<long>(maMtrWidth.Denormalize( lHeight ));
  
  		// put Width & Height to itemset
  		rOutAttrs.Put( SfxUInt32Item( GetWhich( SID_ATTR_TRANSFORM_WIDTH ),
  						(sal_uInt32) lWidth ) );
  		rOutAttrs.Put( SfxUInt32Item( GetWhich( SID_ATTR_TRANSFORM_HEIGHT ),
  						(sal_uInt32) lHeight ) );
  		rOutAttrs.Put( SfxAllEnumItem( GetWhich( SID_ATTR_TRANSFORM_SIZE_POINT ), sal::static_int_cast< sal_uInt16 >( meRP ) ) );
  		bModified |= sal_True;
  	}
  
  	if ( maTsbSizeProtect.GetState() != maTsbSizeProtect.GetSavedValue() )
  	{
  		if ( maTsbSizeProtect.GetState() == STATE_DONTKNOW )
  			rOutAttrs.InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_SIZE );
  		else
  			rOutAttrs.Put(
  				SfxBoolItem( GetWhich( SID_ATTR_TRANSFORM_PROTECT_SIZE ),
  				maTsbSizeProtect.GetState() == STATE_CHECK ? sal_True : sal_False ) );
  		bModified |= sal_True;
  	}
  
  	if ( maTsbAutoGrowWidth.GetState() != maTsbAutoGrowWidth.GetSavedValue() )
  	{
  		if ( !maTsbAutoGrowWidth.IsTriStateEnabled() )
  		{
  			if( maTsbAutoGrowWidth.GetState() == STATE_DONTKNOW )
  				rOutAttrs.InvalidateItem( SID_ATTR_TRANSFORM_AUTOWIDTH );
  			else
  				rOutAttrs.Put(
  					SfxBoolItem( GetWhich( SID_ATTR_TRANSFORM_AUTOWIDTH ),
  					maTsbAutoGrowWidth.GetState() == STATE_CHECK ? sal_True : sal_False ) );
  		}
  		bModified |= sal_True;
  	}
  
  	if ( maTsbAutoGrowHeight.GetState() != maTsbAutoGrowHeight.GetSavedValue() )
  	{
  		if ( !maTsbAutoGrowHeight.IsTriStateEnabled() )
  		{
  			if( maTsbAutoGrowHeight.GetState() == STATE_DONTKNOW )
  				rOutAttrs.InvalidateItem( SID_ATTR_TRANSFORM_AUTOHEIGHT );
  			else
  				rOutAttrs.Put(
  					SfxBoolItem( GetWhich( SID_ATTR_TRANSFORM_AUTOHEIGHT ),
  					maTsbAutoGrowHeight.GetState() == STATE_CHECK ? sal_True : sal_False ) );
  		}
  		bModified |= sal_True;
  	}
  
  
  	return bModified;
  }
  
  // -----------------------------------------------------------------------
  
  void SvxPositionSizeTabPage::Reset( const SfxItemSet&  )
  {
  	const SfxPoolItem* pItem;
  	const double fUIScale(double(mpView->GetModel()->GetUIScale()));
  
  	if ( !mbPageDisabled )
  	{
  		pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_POS_X );
  		if ( pItem )
  		{
  			const double fTmp((((const SfxInt32Item*)pItem)->GetValue() - maAnchor.getX()) / fUIScale);
  			SetMetricValue(maMtrPosX, basegfx::fround(fTmp), mePoolUnit);
  		}
  
  		pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_POS_Y );
  		if ( pItem )
  		{
  			const double fTmp((((const SfxInt32Item*)pItem)->GetValue() - maAnchor.getY()) / fUIScale);
  			SetMetricValue(maMtrPosY, basegfx::fround(fTmp), mePoolUnit);
  		}
  
  		pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_PROTECT_POS );
  		if ( pItem )
  		{
  			sal_Bool bProtected = ( ( const SfxBoolItem* )pItem )->GetValue();
  			maTsbPosProtect.SetState( bProtected ? STATE_CHECK : STATE_NOCHECK );
  			maTsbPosProtect.EnableTriState( sal_False );
  		}
  		else
  		{
  			maTsbPosProtect.SetState( STATE_DONTKNOW );
  		}
  
  		maTsbPosProtect.SaveValue();
  		maCtlPos.Reset();
  
          // #i2379# Disable controls for protected objects
          ChangePosProtectHdl( this );
  	}
  
  	{ // #i75273# set width
  		pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_WIDTH );
  		mfOldWidth = std::max( pItem ? (double)((const SfxUInt32Item*)pItem)->GetValue() : 0.0, 1.0 );
  		double fTmpWidth((OutputDevice::LogicToLogic(static_cast<sal_Int32>(mfOldWidth), (MapUnit)mePoolUnit, MAP_100TH_MM)) / fUIScale);
  
  		if(maMtrWidth.GetDecimalDigits())
  			fTmpWidth *= pow(10.0, maMtrWidth.GetDecimalDigits());
  
  		fTmpWidth = MetricField::ConvertDoubleValue(fTmpWidth, maMtrWidth.GetBaseValue(), maMtrWidth.GetDecimalDigits(), FUNIT_100TH_MM, meDlgUnit);
  		maMtrWidth.SetValue(static_cast<sal_Int64>(fTmpWidth), meDlgUnit);
  	}
  
  	{ // #i75273# set height
  		pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_HEIGHT );
  		mfOldHeight = std::max( pItem ? (double)((const SfxUInt32Item*)pItem)->GetValue() : 0.0, 1.0 );
  		double fTmpHeight((OutputDevice::LogicToLogic(static_cast<sal_Int32>(mfOldHeight), (MapUnit)mePoolUnit, MAP_100TH_MM)) / fUIScale);
  
  		if(maMtrHeight.GetDecimalDigits())
  			fTmpHeight *= pow(10.0, maMtrHeight.GetDecimalDigits());
  
  		fTmpHeight = MetricField::ConvertDoubleValue(fTmpHeight, maMtrHeight.GetBaseValue(), maMtrHeight.GetDecimalDigits(), FUNIT_100TH_MM, meDlgUnit);
  		maMtrHeight.SetValue(static_cast<sal_Int64>(fTmpHeight), meDlgUnit);
  	}
  
  	pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_PROTECT_SIZE );
  	if ( pItem )
  	{
  		maTsbSizeProtect.SetState( ( (const SfxBoolItem*)pItem )->GetValue()
  							  ? STATE_CHECK : STATE_NOCHECK );
  		maTsbSizeProtect.EnableTriState( sal_False );
  	}
  	else
  		maTsbSizeProtect.SetState( STATE_DONTKNOW );
  
  	pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_AUTOWIDTH );
  	if ( pItem )
  	{
  		maTsbAutoGrowWidth.SetState( ( ( const SfxBoolItem* )pItem )->GetValue()
  						   ? STATE_CHECK : STATE_NOCHECK );
  	}
  	else
  		maTsbAutoGrowWidth.SetState( STATE_DONTKNOW );
  
  	pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_AUTOHEIGHT );
  	if ( pItem )
  	{
  		maTsbAutoGrowHeight.SetState( ( ( const SfxBoolItem* )pItem )->GetValue()
  						   ? STATE_CHECK : STATE_NOCHECK );
  	}
  	else
  		maTsbAutoGrowHeight.SetState( STATE_DONTKNOW );
  
  	// Ist Abgleich gesetzt?
  	String aStr = GetUserData();
  	maCbxScale.Check( (sal_Bool)aStr.ToInt32() );
  
  	maTsbSizeProtect.SaveValue();
  	maTsbAutoGrowWidth.SaveValue();
  	maTsbAutoGrowHeight.SaveValue();
  	ClickSizeProtectHdl( NULL );
  
      // #i2379# Disable controls for protected objects
      ChangeSizeProtectHdl( this );
  }
  
  // -----------------------------------------------------------------------
  
  SfxTabPage* SvxPositionSizeTabPage::Create( Window* pWindow, const SfxItemSet& rOutAttrs )
  {
  	return( new SvxPositionSizeTabPage( pWindow, rOutAttrs ) );
  }
  
  //------------------------------------------------------------------------
  
  sal_uInt16* SvxPositionSizeTabPage::GetRanges()
  {
  	return( pPosSizeRanges );
  }
  
  // -----------------------------------------------------------------------
  
  void SvxPositionSizeTabPage::ActivatePage( const SfxItemSet& rSet )
  {
  	SfxRectangleItem* pRectItem = NULL;
  
  	if( SFX_ITEM_SET == rSet.GetItemState( GetWhich( SID_ATTR_TRANSFORM_INTERN ) , sal_False, (const SfxPoolItem**) &pRectItem ) )
  	{
  		{ // #i75273#
  			const Rectangle aTempRect(pRectItem->GetValue());
  			maRange = basegfx::B2DRange(aTempRect.Left(), aTempRect.Top(), aTempRect.Right(), aTempRect.Bottom());
  		}
  
  		SetMinMaxPosition();
  	}
  }
  
  // -----------------------------------------------------------------------
  
  int SvxPositionSizeTabPage::DeactivatePage( SfxItemSet* _pSet )
  {
      if( _pSet )
  	{
  		double fX((double)maMtrPosX.GetValue());
  		double fY((double)maMtrPosY.GetValue());
  
  		GetTopLeftPosition(fX, fY, maRange);
  		const Rectangle aOutRectangle(
  			basegfx::fround(fX), basegfx::fround(fY),
  			basegfx::fround(fX + maRange.getWidth()), basegfx::fround(fY + maRange.getHeight()));
          _pSet->Put(SfxRectangleItem(SID_ATTR_TRANSFORM_INTERN, aOutRectangle));
  
          FillItemSet(*_pSet);
  	}
  
  	return LEAVE_PAGE;
  }
  
  //------------------------------------------------------------------------
  
  IMPL_LINK( SvxPositionSizeTabPage, ChangePosProtectHdl, void *, EMPTYARG )
  {
      // #106572# Remember user's last choice
  	maTsbSizeProtect.SetState( maTsbPosProtect.GetState() == STATE_CHECK ?  STATE_CHECK : mnProtectSizeState );
      UpdateControlStates();
  	return( 0L );
  }
  
  //------------------------------------------------------------------------
  
  void SvxPositionSizeTabPage::UpdateControlStates()
  {
  	const bool bPosProtect =  maTsbPosProtect.GetState() == STATE_CHECK;
  	const bool bSizeProtect = maTsbSizeProtect.GetState() == STATE_CHECK;
  	const bool bHeightChecked = !maTsbAutoGrowHeight.IsTriStateEnabled() && (maTsbAutoGrowHeight.GetState() == STATE_CHECK);
  	const bool bWidthChecked = !maTsbAutoGrowWidth.IsTriStateEnabled() && (maTsbAutoGrowWidth.GetState() == STATE_CHECK);
  
  	maFlPosition.Enable( !bPosProtect && !mbPageDisabled );
  	maFtPosX.Enable( !bPosProtect && !mbPageDisabled );
  	maMtrPosX.Enable( !bPosProtect && !mbPageDisabled );
  	maFtPosY.Enable( !bPosProtect && !mbPageDisabled );
  	maMtrPosY.Enable( !bPosProtect && !mbPageDisabled );
  	maFtPosReference.Enable( !bPosProtect && !mbPageDisabled );
  	maCtlPos.Enable( !bPosProtect );
  	maTsbPosProtect.Enable( !mbProtectDisabled && !mbPageDisabled );
  
  	maFlSize.Enable( !mbSizeDisabled && !bSizeProtect );
  	maCtlSize.Enable( !mbSizeDisabled && !bSizeProtect && (!bHeightChecked || !bWidthChecked) );
  	maFtWidth.Enable( !mbSizeDisabled && !bSizeProtect && !bWidthChecked );
  	maMtrWidth.Enable( !mbSizeDisabled && !bSizeProtect && !bWidthChecked );
  	maFtHeight.Enable( !mbSizeDisabled && !bSizeProtect && !bHeightChecked );
  	maMtrHeight.Enable( !mbSizeDisabled && !bSizeProtect && !bHeightChecked );
  	maCbxScale.Enable( !mbSizeDisabled && !bSizeProtect && !bHeightChecked && !bWidthChecked );
  	maFtSizeReference.Enable( !mbSizeDisabled && !bSizeProtect );
  	maFlProtect.Enable( !mbProtectDisabled );
  	maTsbSizeProtect.Enable( !mbProtectDisabled && !bPosProtect );
  
  	maFlAdjust.Enable( !mbSizeDisabled && !bSizeProtect && !mbAdjustDisabled );
  	maTsbAutoGrowWidth.Enable( !mbSizeDisabled && !bSizeProtect && !mbAdjustDisabled );
  	maTsbAutoGrowHeight.Enable( !mbSizeDisabled && !bSizeProtect && !mbAdjustDisabled );
  
  	maCtlSize.Invalidate();
  	maCtlPos.Invalidate();
  
  }
  
  //------------------------------------------------------------------------
  
  IMPL_LINK( SvxPositionSizeTabPage, ChangeSizeProtectHdl, void *, EMPTYARG )
  {
  	if( maTsbSizeProtect.IsEnabled() )
  	{
          // #106572# Remember user's last choice
  
          // Note: this works only as long as the dialog is open.  When
          // the user closes the dialog, there is no way to remember
          // whether size was enabled or disabled befor pos protect was
          // clicked. Thus, if pos protect is selected, the dialog is
          // closed and reopened again, unchecking pos protect will
          // always uncheck size protect, too. That's life.
          mnProtectSizeState = maTsbSizeProtect.GetState();
      }
  
      UpdateControlStates();
  
  	return( 0L );
  }
  
  //------------------------------------------------------------------------
  
  IMPL_LINK_INLINE_START( SvxPositionSizeTabPage, ChangePosXHdl, void *, EMPTYARG )
  {
  	return( 0L );
  }
  IMPL_LINK_INLINE_END( SvxPositionSizeTabPage, ChangePosXHdl, void *, EMPTYARG )
  
  //------------------------------------------------------------------------
  
  IMPL_LINK_INLINE_START( SvxPositionSizeTabPage, ChangePosYHdl, void *, EMPTYARG )
  {
  	return( 0L );
  }
  IMPL_LINK_INLINE_END( SvxPositionSizeTabPage, ChangePosYHdl, void *, EMPTYARG )
  
  //------------------------------------------------------------------------
  
  void SvxPositionSizeTabPage::SetMinMaxPosition()
  {
  	// position
  	double fLeft(maWorkRange.getMinX());
  	double fTop(maWorkRange.getMinY());
  	double fRight(maWorkRange.getMaxX());
  	double fBottom(maWorkRange.getMaxY());
  
  	switch ( maCtlPos.GetActualRP() )
  	{
  		case RP_LT:
  		{
  			fRight  -= maRange.getWidth();
  			fBottom -= maRange.getHeight();
  			break;
  		}
  		case RP_MT:
  		{
  			fLeft   += maRange.getWidth() / 2.0;
  			fRight  -= maRange.getWidth() / 2.0;
  			fBottom -= maRange.getHeight();
  			break;
  		}
  		case RP_RT:
  		{
  			fLeft   += maRange.getWidth();
  			fBottom -= maRange.getHeight();
  			break;
  		}
  		case RP_LM:
  		{
  			fRight  -= maRange.getWidth();
  			fTop    += maRange.getHeight() / 2.0;
  			fBottom -= maRange.getHeight() / 2.0;
  			break;
  		}
  		case RP_MM:
  		{
  			fLeft   += maRange.getWidth() / 2.0;
  			fRight  -= maRange.getWidth() / 2.0;
  			fTop    += maRange.getHeight() / 2.0;
  			fBottom -= maRange.getHeight() / 2.0;
  			break;
  		}
  		case RP_RM:
  		{
  			fLeft   += maRange.getWidth();
  			fTop    += maRange.getHeight() / 2.0;
  			fBottom -= maRange.getHeight() / 2.0;
  			break;
  		}
  		case RP_LB:
  		{
  			fRight  -= maRange.getWidth();
  			fTop    += maRange.getHeight();
  			break;
  		}
  		case RP_MB:
  		{
  			fLeft   += maRange.getWidth() / 2.0;
  			fRight  -= maRange.getWidth() / 2.0;
  			fTop    += maRange.getHeight();
  			break;
  		}
  		case RP_RB:
  		{
  			fLeft   += maRange.getWidth();
  			fTop    += maRange.getHeight();
  			break;
  		}
  	}
  
  	const double fMaxLong((double)(MetricField::ConvertValue( LONG_MAX, 0, MAP_100TH_MM, meDlgUnit ) - 1L));
  	fLeft = (fLeft > fMaxLong) ? fMaxLong : (fLeft < -fMaxLong) ? -fMaxLong : fLeft;
  	fRight = (fRight > fMaxLong) ? fMaxLong : (fRight < -fMaxLong) ? -fMaxLong : fRight;
  	fTop = (fTop > fMaxLong) ? fMaxLong : (fTop < -fMaxLong) ? -fMaxLong : fTop;
  	fBottom = (fBottom > fMaxLong) ? fMaxLong : (fBottom < -fMaxLong) ? -fMaxLong : fBottom;
  
  	// #i75273# normalizing when setting the min/max values was wrong, removed
  	maMtrPosX.SetMin(basegfx::fround64(fLeft));
  	maMtrPosX.SetFirst(basegfx::fround64(fLeft));
      maMtrPosX.SetMax(basegfx::fround64(fRight));
  	maMtrPosX.SetLast(basegfx::fround64(fRight));
      maMtrPosY.SetMin(basegfx::fround64(fTop));
  	maMtrPosY.SetFirst(basegfx::fround64(fTop));
      maMtrPosY.SetMax(basegfx::fround64(fBottom));
  	maMtrPosY.SetLast(basegfx::fround64(fBottom));
  
  	// size
  	fLeft = maWorkRange.getMinX();
  	fTop = maWorkRange.getMinY();
  	fRight = maWorkRange.getMaxX();
  	fBottom = maWorkRange.getMaxY();
  	double fNewX(0);
  	double fNewY(0);
  
  	switch ( maCtlSize.GetActualRP() )
  	{
  		case RP_LT:
  		{
  			fNewX = maWorkRange.getWidth() - ( maRange.getMinX() - fLeft );
  			fNewY = maWorkRange.getHeight() - ( maRange.getMinY() - fTop );
  			break;
  		}
  		case RP_MT:
  		{
  			fNewX = std::min( maRange.getCenter().getX() - fLeft, fRight - maRange.getCenter().getX() ) * 2.0;
  			fNewY = maWorkRange.getHeight() - ( maRange.getMinY() - fTop );
  			break;
  		}
  		case RP_RT:
  		{
  			fNewX = maWorkRange.getWidth() - ( fRight - maRange.getMaxX() );
  			fNewY = maWorkRange.getHeight() - ( maRange.getMinY() - fTop );
  			break;
  		}
  		case RP_LM:
  		{
  			fNewX = maWorkRange.getWidth() - ( maRange.getMinX() - fLeft );
  			fNewY = std::min( maRange.getCenter().getY() - fTop, fBottom - maRange.getCenter().getY() ) * 2.0;
  			break;
  		}
  		case RP_MM:
  		{
  			const double f1(maRange.getCenter().getX() - fLeft);
  			const double f2(fRight - maRange.getCenter().getX());
  			const double f3(std::min(f1, f2));
  			const double f4(maRange.getCenter().getY() - fTop);
  			const double f5(fBottom - maRange.getCenter().getY());
  			const double f6(std::min(f4, f5));
  
  			fNewX = f3 * 2.0;
  			fNewY = f6 * 3.0;
  
  			break;
  		}
  		case RP_RM:
  		{
  			fNewX = maWorkRange.getWidth() - ( fRight - maRange.getMaxX() );
  			fNewY = std::min( maRange.getCenter().getY() - fTop, fBottom - maRange.getCenter().getY() ) * 2.0;
  			break;
  		}
  		case RP_LB:
  		{
  			fNewX = maWorkRange.getWidth() - ( maRange.getMinX() - fLeft );
  			fNewY = maWorkRange.getHeight() - ( fBottom - maRange.getMaxY() );
  			break;
  		}
  		case RP_MB:
  		{
  			fNewX = std::min( maRange.getCenter().getX() - fLeft, fRight - maRange.getCenter().getX() ) * 2.0;
  			fNewY = maWorkRange.getHeight() - ( maRange.getMaxY() - fBottom );
  			break;
  		}
  		case RP_RB:
  		{
  			fNewX = maWorkRange.getWidth() - ( fRight - maRange.getMaxX() );
  			fNewY = maWorkRange.getHeight() - ( fBottom - maRange.getMaxY() );
  			break;
  		}
  	}
  
  	// #i75273# normalizing when setting the min/max values was wrong, removed
      maMtrWidth.SetMax(basegfx::fround64(fNewX));
  	maMtrWidth.SetLast(basegfx::fround64(fNewX));
      maMtrHeight.SetMax(basegfx::fround64(fNewY));
  	maMtrHeight.SetLast(basegfx::fround64(fNewY));
  }
  
  //------------------------------------------------------------------------
  
  void SvxPositionSizeTabPage::GetTopLeftPosition(double& rfX, double& rfY, const basegfx::B2DRange& rRange)
  {
  	switch (maCtlPos.GetActualRP())
  	{
  		case RP_LT:
  		{
  			break;
  		}
  		case RP_MT:
  		{
  			rfX -= rRange.getCenter().getX() - rRange.getMinX();
  			break;
  		}
  		case RP_RT:
  		{
  			rfX -= rRange.getWidth();
  			break;
  		}
  		case RP_LM:
  		{
  			rfY -= rRange.getCenter().getY() - rRange.getMinY();
  			break;
  		}
  		case RP_MM:
  		{
  			rfX -= rRange.getCenter().getX() - rRange.getMinX();
  			rfY -= rRange.getCenter().getY() - rRange.getMinY();
  			break;
  		}
  		case RP_RM:
  		{
  			rfX -= rRange.getWidth();
  			rfY -= rRange.getCenter().getY() - rRange.getMinY();
  			break;
  		}
  		case RP_LB:
  		{
  			rfY -= rRange.getHeight();
  			break;
  		}
  		case RP_MB:
  		{
  			rfX -= rRange.getCenter().getX() - rRange.getMinX();
  			rfY -= rRange.getHeight();
  			break;
  		}
  		case RP_RB:
  		{
  			rfX -= rRange.getWidth();
  			rfY -= rRange.getHeight();
  			break;
  		}
  	}
  }
  
  //------------------------------------------------------------------------
  
  void SvxPositionSizeTabPage::PointChanged( Window* pWindow, RECT_POINT eRP )
  {
  	if( pWindow == &maCtlPos )
  	{
  		SetMinMaxPosition();
  		switch( eRP )
  		{
  			case RP_LT:
  			{
  				maMtrPosX.SetValue( basegfx::fround64(maRange.getMinX()) );
  				maMtrPosY.SetValue( basegfx::fround64(maRange.getMinY()) );
  				break;
  			}
  			case RP_MT:
  			{
  				maMtrPosX.SetValue( basegfx::fround64(maRange.getCenter().getX()) );
  				maMtrPosY.SetValue( basegfx::fround64(maRange.getMinY()) );
  				break;
  			}
  			case RP_RT:
  			{
  				maMtrPosX.SetValue( basegfx::fround64(maRange.getMaxX()) );
  				maMtrPosY.SetValue( basegfx::fround64(maRange.getMinY()) );
  				break;
  			}
  			case RP_LM:
  			{
  				maMtrPosX.SetValue( basegfx::fround64(maRange.getMinX()) );
  				maMtrPosY.SetValue( basegfx::fround64(maRange.getCenter().getY()) );
  				break;
  			}
  			case RP_MM:
  			{
  				maMtrPosX.SetValue( basegfx::fround64(maRange.getCenter().getX()) );
  				maMtrPosY.SetValue( basegfx::fround64(maRange.getCenter().getY()) );
  				break;
  			}
  			case RP_RM:
  			{
  				maMtrPosX.SetValue( basegfx::fround64(maRange.getMaxX()) );
  				maMtrPosY.SetValue( basegfx::fround64(maRange.getCenter().getY()) );
  				break;
  			}
  			case RP_LB:
  			{
  				maMtrPosX.SetValue( basegfx::fround64(maRange.getMinX()) );
  				maMtrPosY.SetValue( basegfx::fround64(maRange.getMaxY()) );
  				break;
  			}
  			case RP_MB:
  			{
  				maMtrPosX.SetValue( basegfx::fround64(maRange.getCenter().getX()) );
  				maMtrPosY.SetValue( basegfx::fround64(maRange.getMaxY()) );
  				break;
  			}
  			case RP_RB:
  			{
  				maMtrPosX.SetValue( basegfx::fround64(maRange.getMaxX()) );
  				maMtrPosY.SetValue( basegfx::fround64(maRange.getMaxY()) );
  				break;
  			}
  		}
  	}
  	else
  	{
  		meRP = eRP;
  
  		Rectangle aTmpRect( GetRect() );
  		SetMinMaxPosition();
  	}
  }
  
  //------------------------------------------------------------------------
  
  void SvxPositionSizeTabPage::DisableResize()
  {
  	mbSizeDisabled = true;
  }
  
  //------------------------------------------------------------------------
  
  void SvxPositionSizeTabPage::DisableProtect()
  {
  	mbProtectDisabled = true;
  }
  
  //------------------------------------------------------------------------
  
  Rectangle SvxPositionSizeTabPage::GetRect()
  {
  	double fLeft(maRange.getMinX());
  	double fTop(maRange.getMinY());
  	double fRight(fLeft + (double)maMtrWidth.GetValue());
  	double fBottom(fTop + (double)maMtrHeight.GetValue());
  
  	switch ( maCtlSize.GetActualRP() )
  	{
  		case RP_LT:
  		{
  			break;
  		}
  		case RP_MT:
  		{
  			fLeft = maRange.getMinX() - ( fRight - maRange.getMaxX() ) / 2.0;
  			break;
  		}
  		case RP_RT:
  		{
  			fLeft = maRange.getMinX() - ( fRight - maRange.getMaxX() );
  			break;
  		}
  		case RP_LM:
  		{
  			fTop = maRange.getMinY() - ( fBottom - maRange.getMaxY() ) / 2.0;
  			break;
  		}
  		case RP_MM:
  		{
  			fLeft = maRange.getMinX() - ( fRight - maRange.getMaxX() ) / 2.0;
  			fTop = maRange.getMinY() - ( fBottom - maRange.getMaxY() ) / 2.0;
  			break;
  		}
  		case RP_RM:
  		{
  			fLeft = maRange.getMinX() - ( fRight - maRange.getMaxX() );
  			fTop = maRange.getMinY() - ( fBottom - maRange.getMaxY() ) / 2.0;
  			break;
  		}
  		case RP_LB:
  		{
  			fTop = maRange.getMinY() - ( fBottom - maRange.getMaxY() );
  			break;
  		}
  		case RP_MB:
  		{
  			fLeft = maRange.getMinX() - ( fRight - maRange.getMaxX() ) / 2.0;
  			fTop = maRange.getMinY() - ( fBottom - maRange.getMaxY() );
  			break;
  		}
  		case RP_RB:
  		{
  			fLeft = maRange.getMinX() - ( fRight - maRange.getMaxX() );
  			fTop = maRange.getMinY() - ( fBottom - maRange.getMaxY() );
  			break;
  		}
  	}
  
  	return Rectangle(basegfx::fround(fLeft), basegfx::fround(fTop), basegfx::fround(fRight), basegfx::fround(fBottom));
  }
  
  //------------------------------------------------------------------------
  
  IMPL_LINK( SvxPositionSizeTabPage, ChangeWidthHdl, void *, EMPTYARG )
  {
  	if( maCbxScale.IsChecked() && maCbxScale.IsEnabled() )
  	{
  		sal_Int64 nHeight(basegfx::fround64((mfOldHeight * (double)maMtrWidth.GetValue()) / mfOldWidth));
  		
  		if(nHeight <= maMtrHeight.GetMax(FUNIT_NONE))
  		{
  			maMtrHeight.SetUserValue(nHeight, FUNIT_NONE);
  		}
  		else
  		{
  			nHeight = maMtrHeight.GetMax(FUNIT_NONE);
  			maMtrHeight.SetUserValue(nHeight);
  			
  			const sal_Int64 nWidth(basegfx::fround64((mfOldWidth * (double)nHeight) / mfOldHeight));
  			maMtrWidth.SetUserValue(nWidth, FUNIT_NONE);
  		}
  	}
  
  	return( 0L );
  }
  
  //------------------------------------------------------------------------
  
  IMPL_LINK( SvxPositionSizeTabPage, ChangeHeightHdl, void *, EMPTYARG )
  {
  	if( maCbxScale.IsChecked() && maCbxScale.IsEnabled() )
  	{
  		sal_Int64 nWidth(basegfx::fround64((mfOldWidth * (double)maMtrHeight.GetValue()) / mfOldHeight));
  
  		if(nWidth <= maMtrWidth.GetMax(FUNIT_NONE))
  		{
  			maMtrWidth.SetUserValue(nWidth, FUNIT_NONE);
  		}
  		else
  		{
  			nWidth = maMtrWidth.GetMax(FUNIT_NONE);
  			maMtrWidth.SetUserValue(nWidth);
  
  			const sal_Int64 nHeight(basegfx::fround64((mfOldHeight * (double)nWidth) / mfOldWidth));
  			maMtrHeight.SetUserValue(nHeight, FUNIT_NONE);
  		}
  	}
  
  	return( 0L );
  }
  
  //------------------------------------------------------------------------
  
  IMPL_LINK( SvxPositionSizeTabPage, ClickSizeProtectHdl, void *, EMPTYARG )
  {
  	UpdateControlStates();
  	return( 0L );
  }
  
  //------------------------------------------------------------------------
  
  IMPL_LINK( SvxPositionSizeTabPage, ClickAutoHdl, void *, EMPTYARG )
  {
  	if( maCbxScale.IsChecked() )
  	{
  		mfOldWidth  = std::max( (double)GetCoreValue( maMtrWidth,  mePoolUnit ), 1.0 );
  		mfOldHeight = std::max( (double)GetCoreValue( maMtrHeight, mePoolUnit ), 1.0 );
  	}
  
  	return( 0L );
  }
  
  //------------------------------------------------------------------------
  
  void SvxPositionSizeTabPage::FillUserData()
  {
  	// Abgleich wird in der Ini-Datei festgehalten
  	UniString aStr = UniString::CreateFromInt32( (sal_Int32) maCbxScale.IsChecked() );
  	SetUserData( aStr );
  }
  
  // eof
  