| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_svx.hxx" |
| #include <tools/bigint.hxx> |
| #include <svx/xlnwtit.hxx> |
| #include <svl/style.hxx> |
| #include <svx/svdocapt.hxx> |
| #include <svx/xpool.hxx> |
| #include <svx/xpoly.hxx> |
| #include <svx/svdattrx.hxx> |
| #include <svx/svdpool.hxx> |
| #include <svx/svdetc.hxx> |
| #include <svx/svdtrans.hxx> |
| #include <svx/svdhdl.hxx> |
| #include <svx/svddrag.hxx> |
| #include <svx/svdmodel.hxx> |
| #include <svx/svdview.hxx> // fuer RectSnap |
| #include "svx/svdglob.hxx" // StringCache |
| #include "svx/svdstr.hrc" // Objektname |
| #include <svx/svdogrp.hxx> |
| #include <svx/svdpage.hxx> |
| #include <svx/xflhtit.hxx> |
| #include <svx/xflclit.hxx> |
| #include <svx/xfltrit.hxx> |
| #include <editeng/eeitem.hxx> |
| #include <svx/sdr/properties/captionproperties.hxx> |
| #include <vcl/salbtype.hxx> // FRound |
| #include <svx/sdr/contact/viewcontactofsdrcaptionobj.hxx> |
| #include <basegfx/tuple/b2dtuple.hxx> |
| #include <basegfx/matrix/b2dhommatrix.hxx> |
| #include <basegfx/polygon/b2dpolygon.hxx> |
| #include <basegfx/range/b2drange.hxx> |
| #include <basegfx/polygon/b2dpolygontools.hxx> |
| #include <svx/sdrhittesthelper.hxx> |
| |
| // #i32599# |
| inline double ImplTwipsToMM(double fVal) { return (fVal * (127.0 / 72.0)); } |
| inline double ImplMMToTwips(double fVal) { return (fVal * (72.0 / 127.0)); } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| |
| enum EscDir {LKS,RTS,OBN,UNT}; |
| |
| class ImpCaptParams |
| { |
| public: |
| SdrCaptionType eType; |
| long nAngle; |
| long nGap; |
| long nEscRel; |
| long nEscAbs; |
| long nLineLen; |
| SdrCaptionEscDir eEscDir; |
| FASTBOOL bFitLineLen; |
| FASTBOOL bEscRel; |
| FASTBOOL bFixedAngle; |
| |
| public: |
| ImpCaptParams() |
| { |
| eType =SDRCAPT_TYPE3; |
| bFixedAngle=sal_False; |
| nAngle =4500; |
| nGap =0; |
| eEscDir =SDRCAPT_ESCHORIZONTAL; |
| bEscRel =sal_True; |
| nEscRel =5000; |
| nEscAbs =0; |
| nLineLen =0; |
| bFitLineLen=sal_True; |
| } |
| void CalcEscPos(const Point& rTail, const Rectangle& rRect, Point& rPt, EscDir& rDir) const; |
| }; |
| |
| void ImpCaptParams::CalcEscPos(const Point& rTailPt, const Rectangle& rRect, Point& rPt, EscDir& rDir) const |
| { |
| Point aTl(rTailPt); // lokal kopieren wg. Performance |
| long nX,nY; |
| if (bEscRel) { |
| nX=rRect.Right()-rRect.Left(); |
| nX=BigMulDiv(nX,nEscRel,10000); |
| nY=rRect.Bottom()-rRect.Top(); |
| nY=BigMulDiv(nY,nEscRel,10000); |
| } else { |
| nX=nEscAbs; |
| nY=nEscAbs; |
| } |
| nX+=rRect.Left(); |
| nY+=rRect.Top(); |
| Point aBestPt; |
| EscDir eBestDir=LKS; |
| FASTBOOL bTryH=eEscDir==SDRCAPT_ESCBESTFIT; |
| if (!bTryH) { |
| if (eType!=SDRCAPT_TYPE1) { |
| bTryH=eEscDir==SDRCAPT_ESCHORIZONTAL; |
| } else { |
| bTryH=eEscDir==SDRCAPT_ESCVERTICAL; |
| } |
| } |
| FASTBOOL bTryV=eEscDir==SDRCAPT_ESCBESTFIT; |
| if (!bTryV) { |
| if (eType!=SDRCAPT_TYPE1) { |
| bTryV=eEscDir==SDRCAPT_ESCVERTICAL; |
| } else { |
| bTryV=eEscDir==SDRCAPT_ESCHORIZONTAL; |
| } |
| } |
| |
| if (bTryH) { |
| Point aLft(rRect.Left()-nGap,nY); |
| Point aRgt(rRect.Right()+nGap,nY); |
| FASTBOOL bLft=(aTl.X()-aLft.X()<aRgt.X()-aTl.X()); |
| if (bLft) { |
| eBestDir=LKS; |
| aBestPt=aLft; |
| } else { |
| eBestDir=RTS; |
| aBestPt=aRgt; |
| } |
| } |
| if (bTryV) { |
| Point aTop(nX,rRect.Top()-nGap); |
| Point aBtm(nX,rRect.Bottom()+nGap); |
| FASTBOOL bTop=(aTl.Y()-aTop.Y()<aBtm.Y()-aTl.Y()); |
| Point aBest2; |
| EscDir eBest2; |
| if (bTop) { |
| eBest2=OBN; |
| aBest2=aTop; |
| } else { |
| eBest2=UNT; |
| aBest2=aBtm; |
| } |
| FASTBOOL bTakeIt=eEscDir!=SDRCAPT_ESCBESTFIT; |
| if (!bTakeIt) { |
| BigInt aHorX(aBestPt.X()-aTl.X()); aHorX*=aHorX; |
| BigInt aHorY(aBestPt.Y()-aTl.Y()); aHorY*=aHorY; |
| BigInt aVerX(aBest2.X()-aTl.X()); aVerX*=aVerX; |
| BigInt aVerY(aBest2.Y()-aTl.Y()); aVerY*=aVerY; |
| if (eType!=SDRCAPT_TYPE1) { |
| bTakeIt=aVerX+aVerY<aHorX+aHorY; |
| } else { |
| bTakeIt=aVerX+aVerY>=aHorX+aHorY; |
| } |
| } |
| if (bTakeIt) { |
| aBestPt=aBest2; |
| eBestDir=eBest2; |
| } |
| } |
| rPt=aBestPt; |
| rDir=eBestDir; |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| // BaseProperties section |
| |
| sdr::properties::BaseProperties* SdrCaptionObj::CreateObjectSpecificProperties() |
| { |
| return new sdr::properties::CaptionProperties(*this); |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| // DrawContact section |
| |
| sdr::contact::ViewContact* SdrCaptionObj::CreateObjectSpecificViewContact() |
| { |
| return new sdr::contact::ViewContactOfSdrCaptionObj(*this); |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| TYPEINIT1(SdrCaptionObj,SdrRectObj); |
| |
| SdrCaptionObj::SdrCaptionObj(): |
| SdrRectObj(OBJ_TEXT), |
| aTailPoly(3), // Default Groesse: 3 Punkte = 2 Linien |
| mbSpecialTextBoxShadow(sal_False), |
| mbFixedTail(sal_False) |
| { |
| } |
| |
| SdrCaptionObj::SdrCaptionObj(const Rectangle& rRect): |
| SdrRectObj(OBJ_TEXT,rRect), |
| aTailPoly(3), // Default Groesse: 3 Punkte = 2 Linien |
| mbSpecialTextBoxShadow(sal_False), |
| mbFixedTail(sal_False) |
| { |
| } |
| |
| SdrCaptionObj::SdrCaptionObj(const Rectangle& rRect, const Point& rTail): |
| SdrRectObj(OBJ_TEXT,rRect), |
| aTailPoly(3), // Default Groesse: 3 Punkte = 2 Linien |
| mbSpecialTextBoxShadow(sal_False), |
| mbFixedTail(sal_False) |
| { |
| aTailPoly[0]=maFixedTailPos=rTail; |
| } |
| |
| SdrCaptionObj::~SdrCaptionObj() |
| { |
| } |
| |
| void SdrCaptionObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const |
| { |
| rInfo.bRotateFreeAllowed=sal_False; |
| rInfo.bRotate90Allowed =sal_False; |
| rInfo.bMirrorFreeAllowed=sal_False; |
| rInfo.bMirror45Allowed =sal_False; |
| rInfo.bMirror90Allowed =sal_False; |
| rInfo.bTransparenceAllowed = sal_False; |
| rInfo.bGradientAllowed = sal_False; |
| rInfo.bShearAllowed =sal_False; |
| rInfo.bEdgeRadiusAllowed=sal_False; |
| rInfo.bCanConvToPath =sal_True; |
| rInfo.bCanConvToPoly =sal_True; |
| rInfo.bCanConvToPathLineToArea=sal_False; |
| rInfo.bCanConvToPolyLineToArea=sal_False; |
| rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary()); |
| } |
| |
| sal_uInt16 SdrCaptionObj::GetObjIdentifier() const |
| { |
| return sal_uInt16(OBJ_CAPTION); |
| } |
| |
| void SdrCaptionObj::operator=(const SdrObject& rObj) |
| { |
| SdrRectObj::operator=(rObj); |
| aTailPoly=((SdrCaptionObj&)rObj).aTailPoly; |
| } |
| |
| void SdrCaptionObj::TakeObjNameSingul(XubString& rName) const |
| { |
| rName=ImpGetResStr(STR_ObjNameSingulCAPTION); |
| |
| String aName( GetName() ); |
| if(aName.Len()) |
| { |
| rName += sal_Unicode(' '); |
| rName += sal_Unicode('\''); |
| rName += aName; |
| rName += sal_Unicode('\''); |
| } |
| } |
| |
| void SdrCaptionObj::TakeObjNamePlural(XubString& rName) const |
| { |
| rName=ImpGetResStr(STR_ObjNamePluralCAPTION); |
| } |
| |
| basegfx::B2DPolyPolygon SdrCaptionObj::TakeXorPoly() const |
| { |
| basegfx::B2DPolyPolygon aPolyPoly(SdrRectObj::TakeXorPoly()); |
| aPolyPoly.append(aTailPoly.getB2DPolygon()); |
| |
| return aPolyPoly; |
| } |
| |
| sal_uInt32 SdrCaptionObj::GetHdlCount() const |
| { |
| sal_uInt32 nAnz1(SdrRectObj::GetHdlCount()); |
| // sal_uInt32 nAnz2(aTailPoly.GetSize()); |
| // Derzeit ist nur das Draggen des Schwanzendes implementiert |
| return nAnz1 + 1L; |
| } |
| |
| SdrHdl* SdrCaptionObj::GetHdl(sal_uInt32 nHdlNum) const |
| { |
| const sal_uInt32 nRectHdlAnz(SdrRectObj::GetHdlCount()); |
| |
| if(nHdlNum < nRectHdlAnz) |
| { |
| return SdrRectObj::GetHdl(nHdlNum); |
| } |
| else |
| { |
| sal_uInt32 nPntNum(nHdlNum); |
| nPntNum -= nRectHdlAnz; |
| |
| if(nPntNum < aTailPoly.GetSize()) |
| { |
| SdrHdl* pHdl = new SdrHdl(aTailPoly.GetPoint((sal_uInt16)nPntNum), HDL_POLY); |
| pHdl->SetPolyNum(1L); |
| pHdl->SetPointNum(nPntNum); |
| return pHdl; |
| } |
| else |
| { |
| return 0L; |
| } |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| |
| bool SdrCaptionObj::hasSpecialDrag() const |
| { |
| return true; |
| } |
| |
| bool SdrCaptionObj::beginSpecialDrag(SdrDragStat& rDrag) const |
| { |
| const SdrHdl* pHdl = rDrag.GetHdl(); |
| rDrag.SetEndDragChangesAttributes(true); |
| rDrag.SetEndDragChangesGeoAndAttributes(true); |
| |
| if(pHdl && 0 == pHdl->GetPolyNum()) |
| { |
| return SdrRectObj::beginSpecialDrag(rDrag); |
| } |
| else |
| { |
| rDrag.SetOrtho8Possible(true); |
| |
| if(!pHdl) |
| { |
| if (bMovProt) |
| return 0; |
| |
| rDrag.SetNoSnap(true); |
| rDrag.SetActionRect(aRect); |
| |
| Point aHit(rDrag.GetStart()); |
| |
| if(rDrag.GetPageView() && SdrObjectPrimitiveHit(*this, aHit, 0, *rDrag.GetPageView(), 0, false)) |
| { |
| return true; |
| } |
| } |
| else |
| { |
| if((1 == pHdl->GetPolyNum()) && (0 == pHdl->GetPointNum())) |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| bool SdrCaptionObj::applySpecialDrag(SdrDragStat& rDrag) |
| { |
| const SdrHdl* pHdl = rDrag.GetHdl(); |
| |
| if(pHdl && 0 == pHdl->GetPolyNum()) |
| { |
| const bool bRet(SdrRectObj::applySpecialDrag(rDrag)); |
| ImpRecalcTail(); |
| ActionChanged(); |
| |
| return bRet; |
| } |
| else |
| { |
| Point aDelt(rDrag.GetNow()-rDrag.GetStart()); |
| |
| if(!pHdl) |
| { |
| aRect.Move(aDelt.X(),aDelt.Y()); |
| } |
| else |
| { |
| aTailPoly[0] += aDelt; |
| } |
| |
| ImpRecalcTail(); |
| ActionChanged(); |
| |
| return true; |
| } |
| } |
| |
| String SdrCaptionObj::getSpecialDragComment(const SdrDragStat& rDrag) const |
| { |
| const bool bCreateComment(rDrag.GetView() && this == rDrag.GetView()->GetCreateObj()); |
| |
| if(bCreateComment) |
| { |
| return String(); |
| } |
| else |
| { |
| const SdrHdl* pHdl = rDrag.GetHdl(); |
| |
| if(pHdl && 0 == pHdl->GetPolyNum()) |
| { |
| return SdrRectObj::getSpecialDragComment(rDrag); |
| } |
| else |
| { |
| XubString aStr; |
| |
| if(!pHdl) |
| { |
| ImpTakeDescriptionStr(STR_DragCaptFram, aStr); |
| } |
| else |
| { |
| ImpTakeDescriptionStr(STR_DragCaptTail, aStr); |
| } |
| |
| return aStr; |
| } |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| |
| void SdrCaptionObj::ImpGetCaptParams(ImpCaptParams& rPara) const |
| { |
| const SfxItemSet& rSet = GetObjectItemSet(); |
| rPara.eType =((SdrCaptionTypeItem&) (rSet.Get(SDRATTR_CAPTIONTYPE ))).GetValue(); |
| rPara.bFixedAngle=((SdrCaptionFixedAngleItem&)(rSet.Get(SDRATTR_CAPTIONANGLE ))).GetValue(); |
| rPara.nAngle =((SdrCaptionAngleItem&) (rSet.Get(SDRATTR_CAPTIONFIXEDANGLE))).GetValue(); |
| rPara.nGap =((SdrCaptionGapItem&) (rSet.Get(SDRATTR_CAPTIONGAP ))).GetValue(); |
| rPara.eEscDir =((SdrCaptionEscDirItem&) (rSet.Get(SDRATTR_CAPTIONESCDIR ))).GetValue(); |
| rPara.bEscRel =((SdrCaptionEscIsRelItem&) (rSet.Get(SDRATTR_CAPTIONESCISREL ))).GetValue(); |
| rPara.nEscRel =((SdrCaptionEscRelItem&) (rSet.Get(SDRATTR_CAPTIONESCREL ))).GetValue(); |
| rPara.nEscAbs =((SdrCaptionEscAbsItem&) (rSet.Get(SDRATTR_CAPTIONESCABS ))).GetValue(); |
| rPara.nLineLen =((SdrCaptionLineLenItem&) (rSet.Get(SDRATTR_CAPTIONLINELEN ))).GetValue(); |
| rPara.bFitLineLen=((SdrCaptionFitLineLenItem&)(rSet.Get(SDRATTR_CAPTIONFITLINELEN))).GetValue(); |
| } |
| |
| void SdrCaptionObj::ImpRecalcTail() |
| { |
| ImpCaptParams aPara; |
| ImpGetCaptParams(aPara); |
| ImpCalcTail(aPara,aTailPoly,aRect); |
| SetRectsDirty(); |
| SetXPolyDirty(); |
| } |
| |
| // #i35971# |
| // SdrCaptionObj::ImpCalcTail1 does move the object(!). What a hack. |
| // I really wonder why this had not triggered problems before. I am |
| // sure there are some places where SetTailPos() is called at least |
| // twice or SetSnapRect after it again just to work around this. |
| // Changed this method to not do that. |
| // Also found why this has been done: For interactive dragging of the |
| // tail end pos for SDRCAPT_TYPE1. This sure was the simplest method |
| // to achieve this, for the cost to make a whole group of const methods |
| // of this object implicitly chainging the object's position. |
| void SdrCaptionObj::ImpCalcTail1(const ImpCaptParams& rPara, Polygon& rPoly, Rectangle& rRect) const |
| { |
| Polygon aPol(2); |
| Point aTl(rPoly[0]); |
| |
| aPol[0] = aTl; |
| aPol[1] = aTl; |
| |
| EscDir eEscDir; |
| Point aEscPos; |
| |
| rPara.CalcEscPos(aTl, rRect, aEscPos, eEscDir); |
| aPol[1] = aEscPos; |
| |
| if(eEscDir==LKS || eEscDir==RTS) |
| { |
| aPol[0].X() = aEscPos.X(); |
| } |
| else |
| { |
| aPol[0].Y() = aEscPos.Y(); |
| } |
| |
| rPoly = aPol; |
| } |
| |
| void SdrCaptionObj::ImpCalcTail2(const ImpCaptParams& rPara, Polygon& rPoly, Rectangle& rRect) const |
| { // Gap/EscDir/EscPos/Angle |
| Polygon aPol(2); |
| Point aTl(rPoly[0]); |
| aPol[0]=aTl; |
| |
| EscDir eEscDir; |
| Point aEscPos; |
| rPara.CalcEscPos(aTl,rRect,aEscPos,eEscDir); |
| aPol[1]=aEscPos; |
| |
| if (!rPara.bFixedAngle) { |
| // fehlende Implementation |
| } |
| rPoly=aPol; |
| } |
| |
| void SdrCaptionObj::ImpCalcTail3(const ImpCaptParams& rPara, Polygon& rPoly, Rectangle& rRect) const |
| { // Gap/EscDir/EscPos/Angle/LineLen |
| Polygon aPol(3); |
| Point aTl(rPoly[0]); |
| aPol[0]=aTl; |
| |
| EscDir eEscDir; |
| Point aEscPos; |
| rPara.CalcEscPos(aTl,rRect,aEscPos,eEscDir); |
| aPol[1]=aEscPos; |
| aPol[2]=aEscPos; |
| |
| if (eEscDir==LKS || eEscDir==RTS) { |
| if (rPara.bFitLineLen) { |
| aPol[1].X()=(aTl.X()+aEscPos.X())/2; |
| } else { |
| if (eEscDir==LKS) aPol[1].X()-=rPara.nLineLen; |
| else aPol[1].X()+=rPara.nLineLen; |
| } |
| } else { |
| if (rPara.bFitLineLen) { |
| aPol[1].Y()=(aTl.Y()+aEscPos.Y())/2; |
| } else { |
| if (eEscDir==OBN) aPol[1].Y()-=rPara.nLineLen; |
| else aPol[1].Y()+=rPara.nLineLen; |
| } |
| } |
| if (!rPara.bFixedAngle) { |
| // fehlende Implementation |
| } |
| rPoly=aPol; |
| } |
| |
| void SdrCaptionObj::ImpCalcTail4(const ImpCaptParams& rPara, Polygon& rPoly, Rectangle& rRect) const |
| { |
| ImpCalcTail3(rPara,rPoly,rRect); |
| } |
| |
| void SdrCaptionObj::ImpCalcTail(const ImpCaptParams& rPara, Polygon& rPoly, Rectangle& rRect) const |
| { |
| switch (rPara.eType) { |
| case SDRCAPT_TYPE1: ImpCalcTail1(rPara,rPoly,rRect); break; |
| case SDRCAPT_TYPE2: ImpCalcTail2(rPara,rPoly,rRect); break; |
| case SDRCAPT_TYPE3: ImpCalcTail3(rPara,rPoly,rRect); break; |
| case SDRCAPT_TYPE4: ImpCalcTail4(rPara,rPoly,rRect); break; |
| } |
| } |
| |
| FASTBOOL SdrCaptionObj::BegCreate(SdrDragStat& rStat) |
| { |
| if (aRect.IsEmpty()) return sal_False; // Create z.Zt. nur mit vorgegebenen Rect |
| |
| ImpCaptParams aPara; |
| ImpGetCaptParams(aPara); |
| aRect.SetPos(rStat.GetNow()); |
| aTailPoly[0]=rStat.GetStart(); |
| ImpCalcTail(aPara,aTailPoly,aRect); |
| rStat.SetActionRect(aRect); |
| return sal_True; |
| } |
| |
| FASTBOOL SdrCaptionObj::MovCreate(SdrDragStat& rStat) |
| { |
| ImpCaptParams aPara; |
| ImpGetCaptParams(aPara); |
| aRect.SetPos(rStat.GetNow()); |
| ImpCalcTail(aPara,aTailPoly,aRect); |
| rStat.SetActionRect(aRect); |
| SetBoundRectDirty(); |
| bSnapRectDirty=sal_True; |
| return sal_True; |
| } |
| |
| FASTBOOL SdrCaptionObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd) |
| { |
| ImpCaptParams aPara; |
| ImpGetCaptParams(aPara); |
| aRect.SetPos(rStat.GetNow()); |
| ImpCalcTail(aPara,aTailPoly,aRect); |
| SetRectsDirty(); |
| return (eCmd==SDRCREATE_FORCEEND || rStat.GetPointAnz()>=2); |
| } |
| |
| FASTBOOL SdrCaptionObj::BckCreate(SdrDragStat& /*rStat*/) |
| { |
| return sal_False; |
| } |
| |
| void SdrCaptionObj::BrkCreate(SdrDragStat& /*rStat*/) |
| { |
| } |
| |
| basegfx::B2DPolyPolygon SdrCaptionObj::TakeCreatePoly(const SdrDragStat& /*rDrag*/) const |
| { |
| basegfx::B2DPolyPolygon aRetval; |
| const basegfx::B2DRange aRange(aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom()); |
| aRetval.append(basegfx::tools::createPolygonFromRect(aRange)); |
| aRetval.append(aTailPoly.getB2DPolygon()); |
| return aRetval; |
| } |
| |
| Pointer SdrCaptionObj::GetCreatePointer() const |
| { |
| return Pointer(POINTER_DRAW_CAPTION); |
| } |
| |
| void SdrCaptionObj::NbcMove(const Size& rSiz) |
| { |
| SdrRectObj::NbcMove(rSiz); |
| MovePoly(aTailPoly,rSiz); |
| if(mbFixedTail) |
| SetTailPos(GetFixedTailPos()); |
| } |
| |
| void SdrCaptionObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact) |
| { |
| SdrRectObj::NbcResize(rRef,xFact,yFact); |
| ResizePoly(aTailPoly,rRef,xFact,yFact); |
| ImpRecalcTail(); |
| if(mbFixedTail) |
| SetTailPos(GetFixedTailPos()); |
| } |
| |
| void SdrCaptionObj::NbcSetRelativePos(const Point& rPnt) |
| { |
| Point aRelPos0(aTailPoly.GetPoint(0)-aAnchor); |
| Size aSiz(rPnt.X()-aRelPos0.X(),rPnt.Y()-aRelPos0.Y()); |
| NbcMove(aSiz); // Der ruft auch das SetRectsDirty() |
| } |
| |
| Point SdrCaptionObj::GetRelativePos() const |
| { |
| return aTailPoly.GetPoint(0)-aAnchor; |
| } |
| |
| void SdrCaptionObj::NbcSetAnchorPos(const Point& rPnt) |
| { |
| SdrRectObj::NbcSetAnchorPos(rPnt); |
| // !!!!! fehlende Impl. |
| } |
| |
| const Point& SdrCaptionObj::GetAnchorPos() const |
| { |
| // !!!!! fehlende Impl. |
| return SdrRectObj::GetAnchorPos(); |
| } |
| |
| void SdrCaptionObj::RecalcSnapRect() |
| { |
| SdrRectObj::RecalcSnapRect(); |
| // #i32599# |
| // maSnapRect.Union(aTailPoly.GetBoundRect()); |
| // !!!!! fehlende Impl. |
| } |
| |
| const Rectangle& SdrCaptionObj::GetSnapRect() const |
| { |
| return SdrRectObj::GetSnapRect(); |
| } |
| |
| void SdrCaptionObj::NbcSetSnapRect(const Rectangle& rRect) |
| { |
| // #i32599# |
| // Move back to see the rectangle of the underlying SdrRectObj |
| // as the SnapRect, without the TailPos. That simplifies SnapRect |
| // handling again, if not allows it at all... |
| SdrRectObj::NbcSetSnapRect(rRect); |
| } |
| |
| const Rectangle& SdrCaptionObj::GetLogicRect() const |
| { |
| return aRect; |
| } |
| |
| void SdrCaptionObj::NbcSetLogicRect(const Rectangle& rRect) |
| { |
| SdrRectObj::NbcSetLogicRect(rRect); |
| ImpRecalcTail(); |
| } |
| |
| const Point& SdrCaptionObj::GetTailPos() const |
| { |
| return aTailPoly[0]; |
| } |
| |
| void SdrCaptionObj::SetTailPos(const Point& rPos) |
| { |
| if (aTailPoly.GetSize()==0 || aTailPoly[0]!=rPos) { |
| Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect(); |
| // #110094#-14 SendRepaintBroadcast(); |
| NbcSetTailPos(rPos); |
| SetChanged(); |
| BroadcastObjectChange(); |
| SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0); |
| } |
| } |
| |
| void SdrCaptionObj::NbcSetTailPos(const Point& rPos) |
| { |
| aTailPoly[0]=rPos; |
| ImpRecalcTail(); |
| } |
| |
| sal_uInt32 SdrCaptionObj::GetSnapPointCount() const |
| { |
| // !!!!! fehlende Impl. |
| return 0L; |
| } |
| |
| Point SdrCaptionObj::GetSnapPoint(sal_uInt32 /*i*/) const |
| { |
| // !!!!! fehlende Impl. |
| return Point(0,0); |
| } |
| |
| void SdrCaptionObj::SetModel(SdrModel* pNewModel) |
| { |
| SdrRectObj::SetModel(pNewModel); |
| ImpRecalcTail(); |
| } |
| |
| void SdrCaptionObj::Notify(SfxBroadcaster& rBC, const SfxHint& rHint) |
| { |
| SdrRectObj::Notify(rBC,rHint); |
| ImpRecalcTail(); |
| } |
| |
| SdrObjGeoData* SdrCaptionObj::NewGeoData() const |
| { |
| return new SdrCaptObjGeoData; |
| } |
| |
| void SdrCaptionObj::SaveGeoData(SdrObjGeoData& rGeo) const |
| { |
| SdrRectObj::SaveGeoData(rGeo); |
| SdrCaptObjGeoData& rCGeo=(SdrCaptObjGeoData&)rGeo; |
| rCGeo.aTailPoly=aTailPoly; |
| } |
| |
| void SdrCaptionObj::RestGeoData(const SdrObjGeoData& rGeo) |
| { |
| SdrRectObj::RestGeoData(rGeo); |
| SdrCaptObjGeoData& rCGeo=(SdrCaptObjGeoData&)rGeo; |
| aTailPoly=rCGeo.aTailPoly; |
| } |
| |
| SdrObject* SdrCaptionObj::DoConvertToPolyObj(sal_Bool bBezier, bool bAddText) const |
| { // #42334# - Convert implementiert |
| SdrObject* pRect=SdrRectObj::DoConvertToPolyObj(bBezier, bAddText); |
| SdrObject* pTail = ImpConvertMakeObj(basegfx::B2DPolyPolygon(aTailPoly.getB2DPolygon()), sal_False, bBezier); |
| SdrObject* pRet=(pTail!=NULL) ? pTail : pRect; |
| if (pTail!=NULL && pRect!=NULL) { |
| FASTBOOL bInsRect=sal_True; |
| FASTBOOL bInsTail=sal_True; |
| SdrObjList* pOL=pTail->GetSubList(); |
| if (pOL!=NULL) { pRet=pRect; bInsTail=sal_False; } |
| if (pOL==NULL) pOL=pRect->GetSubList(); |
| if (pOL!=NULL) { pRet=pRect; bInsRect=sal_False; } |
| if (pOL==NULL) { |
| SdrObjGroup* pGrp=new SdrObjGroup; |
| pOL=pGrp->GetSubList(); |
| pRet=pGrp; |
| } |
| if (bInsRect) pOL->NbcInsertObject(pRect); |
| if (bInsTail) pOL->NbcInsertObject(pTail,0); |
| } |
| return pRet; |
| } |
| |
| // #i32599# |
| // Add own implementation for TRSetBaseGeometry to handle TailPos over changes. |
| void SdrCaptionObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& /*rPolyPolygon*/) |
| { |
| // break up matrix |
| basegfx::B2DTuple aScale; |
| basegfx::B2DTuple aTranslate; |
| double fRotate, fShearX; |
| rMatrix.decompose(aScale, aTranslate, fRotate, fShearX); |
| |
| // #i75086# Old DrawingLayer (GeoStat and geometry) does not support holding negative scalings |
| // in X and Y which equal a 180 degree rotation. Recognize it and react accordingly |
| if(basegfx::fTools::less(aScale.getX(), 0.0) && basegfx::fTools::less(aScale.getY(), 0.0)) |
| { |
| aScale.setX(fabs(aScale.getX())); |
| aScale.setY(fabs(aScale.getY())); |
| fRotate = fmod(fRotate + F_PI, F_2PI); |
| } |
| |
| // force metric to pool metric |
| SfxMapUnit eMapUnit = pModel->GetItemPool().GetMetric(0); |
| if(eMapUnit != SFX_MAPUNIT_100TH_MM) |
| { |
| switch(eMapUnit) |
| { |
| case SFX_MAPUNIT_TWIP : |
| { |
| // position |
| aTranslate.setX(ImplMMToTwips(aTranslate.getX())); |
| aTranslate.setY(ImplMMToTwips(aTranslate.getY())); |
| |
| // size |
| aScale.setX(ImplMMToTwips(aScale.getX())); |
| aScale.setY(ImplMMToTwips(aScale.getY())); |
| |
| break; |
| } |
| default: |
| { |
| DBG_ERROR("TRSetBaseGeometry: Missing unit translation to PoolMetric!"); |
| } |
| } |
| } |
| |
| // if anchor is used, make position relative to it |
| if( pModel->IsWriter() ) |
| { |
| if(GetAnchorPos().X() || GetAnchorPos().Y()) |
| { |
| aTranslate += basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y()); |
| } |
| } |
| |
| // build BaseRect |
| Point aPoint(FRound(aTranslate.getX()), FRound(aTranslate.getY())); |
| Rectangle aBaseRect(aPoint, Size(FRound(aScale.getX()), FRound(aScale.getY()))); |
| |
| // set BaseRect, but rescue TailPos over this call |
| const Point aTailPoint = GetTailPos(); |
| SetSnapRect(aBaseRect); |
| SetTailPos(aTailPoint); |
| ImpRecalcTail(); |
| } |
| |
| // geometry access |
| basegfx::B2DPolygon SdrCaptionObj::getTailPolygon() const |
| { |
| return aTailPoly.getB2DPolygon(); |
| } |
| |
| // eof |