update dev300-m58
[ooovba.git] / svx / source / svdraw / svdocapt.cxx
blob29488fc407280352540c30ee6c450113a970aec2
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svdocapt.cxx,v $
10 * $Revision: 1.30.18.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
33 #include <tools/bigint.hxx>
34 #include <svx/xlnwtit.hxx>
35 #include <svtools/style.hxx>
36 #include <svx/svdocapt.hxx>
37 #include <svx/xpool.hxx>
38 #include <svx/xpoly.hxx>
39 #include <svx/svdattrx.hxx>
40 #include <svx/svdpool.hxx>
41 #include <svx/svdetc.hxx>
42 #include <svx/svdtrans.hxx>
43 #include <svx/svdhdl.hxx>
44 #include <svx/svddrag.hxx>
45 #include <svx/svdmodel.hxx>
46 #include <svx/svdview.hxx> // fuer RectSnap
47 #include "svdglob.hxx" // StringCache
48 #include "svdstr.hrc" // Objektname
49 #include <svx/svdogrp.hxx>
50 #include <svx/svdpage.hxx>
51 #include <svx/xflhtit.hxx>
52 #include <svx/xflclit.hxx>
53 #include <svx/xfltrit.hxx>
54 #include <svx/eeitem.hxx>
55 #include <svx/sdr/properties/captionproperties.hxx>
56 #include <vcl/salbtype.hxx> // FRound
57 #include <svx/sdr/contact/viewcontactofsdrcaptionobj.hxx>
58 #include <basegfx/tuple/b2dtuple.hxx>
59 #include <basegfx/matrix/b2dhommatrix.hxx>
60 #include <basegfx/polygon/b2dpolygon.hxx>
61 #include <basegfx/range/b2drange.hxx>
62 #include <basegfx/polygon/b2dpolygontools.hxx>
63 #include <svx/sdrhittesthelper.hxx>
65 // #i32599#
66 inline double ImplTwipsToMM(double fVal) { return (fVal * (127.0 / 72.0)); }
67 inline double ImplMMToTwips(double fVal) { return (fVal * (72.0 / 127.0)); }
69 ////////////////////////////////////////////////////////////////////////////////////////////////////
71 enum EscDir {LKS,RTS,OBN,UNT};
73 class ImpCaptParams
75 public:
76 SdrCaptionType eType;
77 long nAngle;
78 long nGap;
79 long nEscRel;
80 long nEscAbs;
81 long nLineLen;
82 SdrCaptionEscDir eEscDir;
83 FASTBOOL bFitLineLen;
84 FASTBOOL bEscRel;
85 FASTBOOL bFixedAngle;
87 public:
88 ImpCaptParams()
90 eType =SDRCAPT_TYPE3;
91 bFixedAngle=FALSE;
92 nAngle =4500;
93 nGap =0;
94 eEscDir =SDRCAPT_ESCHORIZONTAL;
95 bEscRel =TRUE;
96 nEscRel =5000;
97 nEscAbs =0;
98 nLineLen =0;
99 bFitLineLen=TRUE;
101 void CalcEscPos(const Point& rTail, const Rectangle& rRect, Point& rPt, EscDir& rDir) const;
104 void ImpCaptParams::CalcEscPos(const Point& rTailPt, const Rectangle& rRect, Point& rPt, EscDir& rDir) const
106 Point aTl(rTailPt); // lokal kopieren wg. Performance
107 long nX,nY;
108 if (bEscRel) {
109 nX=rRect.Right()-rRect.Left();
110 nX=BigMulDiv(nX,nEscRel,10000);
111 nY=rRect.Bottom()-rRect.Top();
112 nY=BigMulDiv(nY,nEscRel,10000);
113 } else {
114 nX=nEscAbs;
115 nY=nEscAbs;
117 nX+=rRect.Left();
118 nY+=rRect.Top();
119 Point aBestPt;
120 EscDir eBestDir=LKS;
121 FASTBOOL bTryH=eEscDir==SDRCAPT_ESCBESTFIT;
122 if (!bTryH) {
123 if (eType!=SDRCAPT_TYPE1) {
124 bTryH=eEscDir==SDRCAPT_ESCHORIZONTAL;
125 } else {
126 bTryH=eEscDir==SDRCAPT_ESCVERTICAL;
129 FASTBOOL bTryV=eEscDir==SDRCAPT_ESCBESTFIT;
130 if (!bTryV) {
131 if (eType!=SDRCAPT_TYPE1) {
132 bTryV=eEscDir==SDRCAPT_ESCVERTICAL;
133 } else {
134 bTryV=eEscDir==SDRCAPT_ESCHORIZONTAL;
138 if (bTryH) {
139 Point aLft(rRect.Left()-nGap,nY);
140 Point aRgt(rRect.Right()+nGap,nY);
141 FASTBOOL bLft=(aTl.X()-aLft.X()<aRgt.X()-aTl.X());
142 if (bLft) {
143 eBestDir=LKS;
144 aBestPt=aLft;
145 } else {
146 eBestDir=RTS;
147 aBestPt=aRgt;
150 if (bTryV) {
151 Point aTop(nX,rRect.Top()-nGap);
152 Point aBtm(nX,rRect.Bottom()+nGap);
153 FASTBOOL bTop=(aTl.Y()-aTop.Y()<aBtm.Y()-aTl.Y());
154 Point aBest2;
155 EscDir eBest2;
156 if (bTop) {
157 eBest2=OBN;
158 aBest2=aTop;
159 } else {
160 eBest2=UNT;
161 aBest2=aBtm;
163 FASTBOOL bTakeIt=eEscDir!=SDRCAPT_ESCBESTFIT;
164 if (!bTakeIt) {
165 BigInt aHorX(aBestPt.X()-aTl.X()); aHorX*=aHorX;
166 BigInt aHorY(aBestPt.Y()-aTl.Y()); aHorY*=aHorY;
167 BigInt aVerX(aBest2.X()-aTl.X()); aVerX*=aVerX;
168 BigInt aVerY(aBest2.Y()-aTl.Y()); aVerY*=aVerY;
169 if (eType!=SDRCAPT_TYPE1) {
170 bTakeIt=aVerX+aVerY<aHorX+aHorY;
171 } else {
172 bTakeIt=aVerX+aVerY>=aHorX+aHorY;
175 if (bTakeIt) {
176 aBestPt=aBest2;
177 eBestDir=eBest2;
180 rPt=aBestPt;
181 rDir=eBestDir;
184 //////////////////////////////////////////////////////////////////////////////
185 // BaseProperties section
187 sdr::properties::BaseProperties* SdrCaptionObj::CreateObjectSpecificProperties()
189 return new sdr::properties::CaptionProperties(*this);
192 //////////////////////////////////////////////////////////////////////////////
193 // DrawContact section
195 sdr::contact::ViewContact* SdrCaptionObj::CreateObjectSpecificViewContact()
197 return new sdr::contact::ViewContactOfSdrCaptionObj(*this);
200 //////////////////////////////////////////////////////////////////////////////
202 TYPEINIT1(SdrCaptionObj,SdrRectObj);
204 SdrCaptionObj::SdrCaptionObj():
205 SdrRectObj(OBJ_TEXT),
206 aTailPoly(3), // Default Groesse: 3 Punkte = 2 Linien
207 mbSpecialTextBoxShadow(FALSE),
208 mbFixedTail(FALSE)
212 SdrCaptionObj::SdrCaptionObj(const Rectangle& rRect):
213 SdrRectObj(OBJ_TEXT,rRect),
214 aTailPoly(3), // Default Groesse: 3 Punkte = 2 Linien
215 mbSpecialTextBoxShadow(FALSE),
216 mbFixedTail(FALSE)
220 SdrCaptionObj::SdrCaptionObj(const Rectangle& rRect, const Point& rTail):
221 SdrRectObj(OBJ_TEXT,rRect),
222 aTailPoly(3), // Default Groesse: 3 Punkte = 2 Linien
223 mbSpecialTextBoxShadow(FALSE),
224 mbFixedTail(FALSE)
226 aTailPoly[0]=maFixedTailPos=rTail;
229 SdrCaptionObj::~SdrCaptionObj()
233 void SdrCaptionObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
235 rInfo.bRotateFreeAllowed=FALSE;
236 rInfo.bRotate90Allowed =FALSE;
237 rInfo.bMirrorFreeAllowed=FALSE;
238 rInfo.bMirror45Allowed =FALSE;
239 rInfo.bMirror90Allowed =FALSE;
240 rInfo.bTransparenceAllowed = FALSE;
241 rInfo.bGradientAllowed = FALSE;
242 rInfo.bShearAllowed =FALSE;
243 rInfo.bEdgeRadiusAllowed=FALSE;
244 rInfo.bCanConvToPath =TRUE;
245 rInfo.bCanConvToPoly =TRUE;
246 rInfo.bCanConvToPathLineToArea=FALSE;
247 rInfo.bCanConvToPolyLineToArea=FALSE;
248 rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
251 UINT16 SdrCaptionObj::GetObjIdentifier() const
253 return UINT16(OBJ_CAPTION);
256 void SdrCaptionObj::operator=(const SdrObject& rObj)
258 SdrRectObj::operator=(rObj);
259 aTailPoly=((SdrCaptionObj&)rObj).aTailPoly;
262 void SdrCaptionObj::TakeObjNameSingul(XubString& rName) const
264 rName=ImpGetResStr(STR_ObjNameSingulCAPTION);
266 String aName( GetName() );
267 if(aName.Len())
269 rName += sal_Unicode(' ');
270 rName += sal_Unicode('\'');
271 rName += aName;
272 rName += sal_Unicode('\'');
276 void SdrCaptionObj::TakeObjNamePlural(XubString& rName) const
278 rName=ImpGetResStr(STR_ObjNamePluralCAPTION);
281 basegfx::B2DPolyPolygon SdrCaptionObj::TakeXorPoly() const
283 basegfx::B2DPolyPolygon aPolyPoly(SdrRectObj::TakeXorPoly());
284 aPolyPoly.append(aTailPoly.getB2DPolygon());
286 return aPolyPoly;
289 sal_uInt32 SdrCaptionObj::GetHdlCount() const
291 sal_uInt32 nAnz1(SdrRectObj::GetHdlCount());
292 // sal_uInt32 nAnz2(aTailPoly.GetSize());
293 // Derzeit ist nur das Draggen des Schwanzendes implementiert
294 return nAnz1 + 1L;
297 SdrHdl* SdrCaptionObj::GetHdl(sal_uInt32 nHdlNum) const
299 const sal_uInt32 nRectHdlAnz(SdrRectObj::GetHdlCount());
301 if(nHdlNum < nRectHdlAnz)
303 return SdrRectObj::GetHdl(nHdlNum);
305 else
307 sal_uInt32 nPntNum(nHdlNum);
308 nPntNum -= nRectHdlAnz;
310 if(nPntNum < aTailPoly.GetSize())
312 SdrHdl* pHdl = new SdrHdl(aTailPoly.GetPoint((sal_uInt16)nPntNum), HDL_POLY);
313 pHdl->SetPolyNum(1L);
314 pHdl->SetPointNum(nPntNum);
315 return pHdl;
317 else
319 return 0L;
324 ////////////////////////////////////////////////////////////////////////////////////////////////////
326 bool SdrCaptionObj::hasSpecialDrag() const
328 return true;
331 bool SdrCaptionObj::beginSpecialDrag(SdrDragStat& rDrag) const
333 const SdrHdl* pHdl = rDrag.GetHdl();
334 rDrag.SetEndDragChangesAttributes(true);
335 rDrag.SetEndDragChangesGeoAndAttributes(true);
337 if(pHdl && 0 == pHdl->GetPolyNum())
339 return SdrRectObj::beginSpecialDrag(rDrag);
341 else
343 rDrag.SetOrtho8Possible(true);
345 if(!pHdl)
347 if (bMovProt)
348 return 0;
350 rDrag.SetNoSnap(true);
351 rDrag.SetActionRect(aRect);
353 Point aHit(rDrag.GetStart());
355 if(rDrag.GetPageView() && SdrObjectPrimitiveHit(*this, aHit, 0, *rDrag.GetPageView(), 0, false))
357 return true;
360 else
362 if((1 == pHdl->GetPolyNum()) && (0 == pHdl->GetPointNum()))
363 return true;
367 return false;
370 bool SdrCaptionObj::applySpecialDrag(SdrDragStat& rDrag)
372 const SdrHdl* pHdl = rDrag.GetHdl();
374 if(pHdl && 0 == pHdl->GetPolyNum())
376 const bool bRet(SdrRectObj::applySpecialDrag(rDrag));
377 ImpRecalcTail();
378 ActionChanged();
380 return bRet;
382 else
384 Point aDelt(rDrag.GetNow()-rDrag.GetStart());
386 if(!pHdl)
388 aRect.Move(aDelt.X(),aDelt.Y());
390 else
392 aTailPoly[0] += aDelt;
395 ImpRecalcTail();
396 ActionChanged();
398 return true;
402 String SdrCaptionObj::getSpecialDragComment(const SdrDragStat& rDrag) const
404 const SdrHdl* pHdl = rDrag.GetHdl();
406 if(pHdl && 0 == pHdl->GetPolyNum())
408 return SdrRectObj::getSpecialDragComment(rDrag);
410 else
412 XubString aStr;
414 if(!pHdl)
416 ImpTakeDescriptionStr(STR_DragCaptFram, aStr);
418 else
420 ImpTakeDescriptionStr(STR_DragCaptTail, aStr);
423 return aStr;
427 ////////////////////////////////////////////////////////////////////////////////////////////////////
429 void SdrCaptionObj::ImpGetCaptParams(ImpCaptParams& rPara) const
431 const SfxItemSet& rSet = GetObjectItemSet();
432 rPara.eType =((SdrCaptionTypeItem&) (rSet.Get(SDRATTR_CAPTIONTYPE ))).GetValue();
433 rPara.bFixedAngle=((SdrCaptionFixedAngleItem&)(rSet.Get(SDRATTR_CAPTIONANGLE ))).GetValue();
434 rPara.nAngle =((SdrCaptionAngleItem&) (rSet.Get(SDRATTR_CAPTIONFIXEDANGLE))).GetValue();
435 rPara.nGap =((SdrCaptionGapItem&) (rSet.Get(SDRATTR_CAPTIONGAP ))).GetValue();
436 rPara.eEscDir =((SdrCaptionEscDirItem&) (rSet.Get(SDRATTR_CAPTIONESCDIR ))).GetValue();
437 rPara.bEscRel =((SdrCaptionEscIsRelItem&) (rSet.Get(SDRATTR_CAPTIONESCISREL ))).GetValue();
438 rPara.nEscRel =((SdrCaptionEscRelItem&) (rSet.Get(SDRATTR_CAPTIONESCREL ))).GetValue();
439 rPara.nEscAbs =((SdrCaptionEscAbsItem&) (rSet.Get(SDRATTR_CAPTIONESCABS ))).GetValue();
440 rPara.nLineLen =((SdrCaptionLineLenItem&) (rSet.Get(SDRATTR_CAPTIONLINELEN ))).GetValue();
441 rPara.bFitLineLen=((SdrCaptionFitLineLenItem&)(rSet.Get(SDRATTR_CAPTIONFITLINELEN))).GetValue();
444 void SdrCaptionObj::ImpRecalcTail()
446 ImpCaptParams aPara;
447 ImpGetCaptParams(aPara);
448 ImpCalcTail(aPara,aTailPoly,aRect);
449 SetRectsDirty();
450 SetXPolyDirty();
453 // #i35971#
454 // SdrCaptionObj::ImpCalcTail1 does move the object(!). What a hack.
455 // I really wonder why this had not triggered problems before. I am
456 // sure there are some places where SetTailPos() is called at least
457 // twice or SetSnapRect after it again just to work around this.
458 // Changed this method to not do that.
459 // Also found why this has been done: For interactive dragging of the
460 // tail end pos for SDRCAPT_TYPE1. This sure was the simplest method
461 // to achieve this, for the cost to make a whole group of const methods
462 // of this object implicitly chainging the object's position.
463 void SdrCaptionObj::ImpCalcTail1(const ImpCaptParams& rPara, Polygon& rPoly, Rectangle& rRect) const
465 Polygon aPol(2);
466 Point aTl(rPoly[0]);
468 aPol[0] = aTl;
469 aPol[1] = aTl;
471 EscDir eEscDir;
472 Point aEscPos;
474 rPara.CalcEscPos(aTl, rRect, aEscPos, eEscDir);
475 aPol[1] = aEscPos;
477 if(eEscDir==LKS || eEscDir==RTS)
479 aPol[0].X() = aEscPos.X();
481 else
483 aPol[0].Y() = aEscPos.Y();
486 rPoly = aPol;
489 void SdrCaptionObj::ImpCalcTail2(const ImpCaptParams& rPara, Polygon& rPoly, Rectangle& rRect) const
490 { // Gap/EscDir/EscPos/Angle
491 Polygon aPol(2);
492 Point aTl(rPoly[0]);
493 aPol[0]=aTl;
495 EscDir eEscDir;
496 Point aEscPos;
497 rPara.CalcEscPos(aTl,rRect,aEscPos,eEscDir);
498 aPol[1]=aEscPos;
500 if (!rPara.bFixedAngle) {
501 // fehlende Implementation
503 rPoly=aPol;
506 void SdrCaptionObj::ImpCalcTail3(const ImpCaptParams& rPara, Polygon& rPoly, Rectangle& rRect) const
507 { // Gap/EscDir/EscPos/Angle/LineLen
508 Polygon aPol(3);
509 Point aTl(rPoly[0]);
510 aPol[0]=aTl;
512 EscDir eEscDir;
513 Point aEscPos;
514 rPara.CalcEscPos(aTl,rRect,aEscPos,eEscDir);
515 aPol[1]=aEscPos;
516 aPol[2]=aEscPos;
518 if (eEscDir==LKS || eEscDir==RTS) {
519 if (rPara.bFitLineLen) {
520 aPol[1].X()=(aTl.X()+aEscPos.X())/2;
521 } else {
522 if (eEscDir==LKS) aPol[1].X()-=rPara.nLineLen;
523 else aPol[1].X()+=rPara.nLineLen;
525 } else {
526 if (rPara.bFitLineLen) {
527 aPol[1].Y()=(aTl.Y()+aEscPos.Y())/2;
528 } else {
529 if (eEscDir==OBN) aPol[1].Y()-=rPara.nLineLen;
530 else aPol[1].Y()+=rPara.nLineLen;
533 if (!rPara.bFixedAngle) {
534 // fehlende Implementation
536 rPoly=aPol;
539 void SdrCaptionObj::ImpCalcTail4(const ImpCaptParams& rPara, Polygon& rPoly, Rectangle& rRect) const
541 ImpCalcTail3(rPara,rPoly,rRect);
544 void SdrCaptionObj::ImpCalcTail(const ImpCaptParams& rPara, Polygon& rPoly, Rectangle& rRect) const
546 switch (rPara.eType) {
547 case SDRCAPT_TYPE1: ImpCalcTail1(rPara,rPoly,rRect); break;
548 case SDRCAPT_TYPE2: ImpCalcTail2(rPara,rPoly,rRect); break;
549 case SDRCAPT_TYPE3: ImpCalcTail3(rPara,rPoly,rRect); break;
550 case SDRCAPT_TYPE4: ImpCalcTail4(rPara,rPoly,rRect); break;
554 FASTBOOL SdrCaptionObj::BegCreate(SdrDragStat& rStat)
556 if (aRect.IsEmpty()) return FALSE; // Create z.Zt. nur mit vorgegebenen Rect
558 ImpCaptParams aPara;
559 ImpGetCaptParams(aPara);
560 aRect.SetPos(rStat.GetNow());
561 aTailPoly[0]=rStat.GetStart();
562 ImpCalcTail(aPara,aTailPoly,aRect);
563 rStat.SetActionRect(aRect);
564 return TRUE;
567 FASTBOOL SdrCaptionObj::MovCreate(SdrDragStat& rStat)
569 ImpCaptParams aPara;
570 ImpGetCaptParams(aPara);
571 aRect.SetPos(rStat.GetNow());
572 ImpCalcTail(aPara,aTailPoly,aRect);
573 rStat.SetActionRect(aRect);
574 SetBoundRectDirty();
575 bSnapRectDirty=TRUE;
576 return TRUE;
579 FASTBOOL SdrCaptionObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
581 ImpCaptParams aPara;
582 ImpGetCaptParams(aPara);
583 aRect.SetPos(rStat.GetNow());
584 ImpCalcTail(aPara,aTailPoly,aRect);
585 SetRectsDirty();
586 return (eCmd==SDRCREATE_FORCEEND || rStat.GetPointAnz()>=2);
589 FASTBOOL SdrCaptionObj::BckCreate(SdrDragStat& /*rStat*/)
591 return FALSE;
594 void SdrCaptionObj::BrkCreate(SdrDragStat& /*rStat*/)
598 basegfx::B2DPolyPolygon SdrCaptionObj::TakeCreatePoly(const SdrDragStat& /*rDrag*/) const
600 basegfx::B2DPolyPolygon aRetval;
601 const basegfx::B2DRange aRange(aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom());
602 aRetval.append(basegfx::tools::createPolygonFromRect(aRange));
603 aRetval.append(aTailPoly.getB2DPolygon());
604 return aRetval;
607 Pointer SdrCaptionObj::GetCreatePointer() const
609 return Pointer(POINTER_DRAW_CAPTION);
612 void SdrCaptionObj::NbcMove(const Size& rSiz)
614 SdrRectObj::NbcMove(rSiz);
615 MovePoly(aTailPoly,rSiz);
616 if(mbFixedTail)
617 SetTailPos(GetFixedTailPos());
620 void SdrCaptionObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
622 SdrRectObj::NbcResize(rRef,xFact,yFact);
623 ResizePoly(aTailPoly,rRef,xFact,yFact);
624 ImpRecalcTail();
625 if(mbFixedTail)
626 SetTailPos(GetFixedTailPos());
629 void SdrCaptionObj::NbcSetRelativePos(const Point& rPnt)
631 Point aRelPos0(aTailPoly.GetPoint(0)-aAnchor);
632 Size aSiz(rPnt.X()-aRelPos0.X(),rPnt.Y()-aRelPos0.Y());
633 NbcMove(aSiz); // Der ruft auch das SetRectsDirty()
636 Point SdrCaptionObj::GetRelativePos() const
638 return aTailPoly.GetPoint(0)-aAnchor;
641 void SdrCaptionObj::NbcSetAnchorPos(const Point& rPnt)
643 SdrRectObj::NbcSetAnchorPos(rPnt);
644 // !!!!! fehlende Impl.
647 const Point& SdrCaptionObj::GetAnchorPos() const
649 // !!!!! fehlende Impl.
650 return SdrRectObj::GetAnchorPos();
653 void SdrCaptionObj::RecalcSnapRect()
655 SdrRectObj::RecalcSnapRect();
656 // #i32599#
657 // maSnapRect.Union(aTailPoly.GetBoundRect());
658 // !!!!! fehlende Impl.
661 const Rectangle& SdrCaptionObj::GetSnapRect() const
663 return SdrRectObj::GetSnapRect();
666 void SdrCaptionObj::NbcSetSnapRect(const Rectangle& rRect)
668 // #i32599#
669 // Move back to see the rectangle of the underlying SdrRectObj
670 // as the SnapRect, without the TailPos. That simplifies SnapRect
671 // handling again, if not allows it at all...
672 SdrRectObj::NbcSetSnapRect(rRect);
675 const Rectangle& SdrCaptionObj::GetLogicRect() const
677 return aRect;
680 void SdrCaptionObj::NbcSetLogicRect(const Rectangle& rRect)
682 SdrRectObj::NbcSetLogicRect(rRect);
683 ImpRecalcTail();
686 const Point& SdrCaptionObj::GetTailPos() const
688 return aTailPoly[0];
691 void SdrCaptionObj::SetTailPos(const Point& rPos)
693 if (aTailPoly.GetSize()==0 || aTailPoly[0]!=rPos) {
694 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
695 // #110094#-14 SendRepaintBroadcast();
696 NbcSetTailPos(rPos);
697 SetChanged();
698 BroadcastObjectChange();
699 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
703 void SdrCaptionObj::NbcSetTailPos(const Point& rPos)
705 aTailPoly[0]=rPos;
706 ImpRecalcTail();
709 sal_uInt32 SdrCaptionObj::GetSnapPointCount() const
711 // !!!!! fehlende Impl.
712 return 0L;
715 Point SdrCaptionObj::GetSnapPoint(sal_uInt32 /*i*/) const
717 // !!!!! fehlende Impl.
718 return Point(0,0);
721 void SdrCaptionObj::SetModel(SdrModel* pNewModel)
723 SdrRectObj::SetModel(pNewModel);
724 ImpRecalcTail();
727 void SdrCaptionObj::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
729 SdrRectObj::Notify(rBC,rHint);
730 ImpRecalcTail();
733 SdrObjGeoData* SdrCaptionObj::NewGeoData() const
735 return new SdrCaptObjGeoData;
738 void SdrCaptionObj::SaveGeoData(SdrObjGeoData& rGeo) const
740 SdrRectObj::SaveGeoData(rGeo);
741 SdrCaptObjGeoData& rCGeo=(SdrCaptObjGeoData&)rGeo;
742 rCGeo.aTailPoly=aTailPoly;
745 void SdrCaptionObj::RestGeoData(const SdrObjGeoData& rGeo)
747 SdrRectObj::RestGeoData(rGeo);
748 SdrCaptObjGeoData& rCGeo=(SdrCaptObjGeoData&)rGeo;
749 aTailPoly=rCGeo.aTailPoly;
752 SdrObject* SdrCaptionObj::DoConvertToPolyObj(BOOL bBezier) const
753 { // #42334# - Convert implementiert
754 SdrObject* pRect=SdrRectObj::DoConvertToPolyObj(bBezier);
755 SdrObject* pTail = ImpConvertMakeObj(basegfx::B2DPolyPolygon(aTailPoly.getB2DPolygon()), sal_False, bBezier);
756 SdrObject* pRet=(pTail!=NULL) ? pTail : pRect;
757 if (pTail!=NULL && pRect!=NULL) {
758 FASTBOOL bInsRect=TRUE;
759 FASTBOOL bInsTail=TRUE;
760 SdrObjList* pOL=pTail->GetSubList();
761 if (pOL!=NULL) { pRet=pRect; bInsTail=FALSE; }
762 if (pOL==NULL) pOL=pRect->GetSubList();
763 if (pOL!=NULL) { pRet=pRect; bInsRect=FALSE; }
764 if (pOL==NULL) {
765 SdrObjGroup* pGrp=new SdrObjGroup;
766 pOL=pGrp->GetSubList();
767 pRet=pGrp;
769 if (bInsRect) pOL->NbcInsertObject(pRect);
770 if (bInsTail) pOL->NbcInsertObject(pTail,0);
772 return pRet;
775 // #i32599#
776 // Add own implementation for TRSetBaseGeometry to handle TailPos over changes.
777 void SdrCaptionObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& /*rPolyPolygon*/)
779 // break up matrix
780 basegfx::B2DTuple aScale;
781 basegfx::B2DTuple aTranslate;
782 double fRotate, fShearX;
783 rMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
785 // #i75086# Old DrawingLayer (GeoStat and geometry) does not support holding negative scalings
786 // in X and Y which equal a 180 degree rotation. Recognize it and react accordingly
787 if(basegfx::fTools::less(aScale.getX(), 0.0) && basegfx::fTools::less(aScale.getY(), 0.0))
789 aScale.setX(fabs(aScale.getX()));
790 aScale.setY(fabs(aScale.getY()));
791 fRotate = fmod(fRotate + F_PI, F_2PI);
794 // force metric to pool metric
795 SfxMapUnit eMapUnit = pModel->GetItemPool().GetMetric(0);
796 if(eMapUnit != SFX_MAPUNIT_100TH_MM)
798 switch(eMapUnit)
800 case SFX_MAPUNIT_TWIP :
802 // position
803 aTranslate.setX(ImplMMToTwips(aTranslate.getX()));
804 aTranslate.setY(ImplMMToTwips(aTranslate.getY()));
806 // size
807 aScale.setX(ImplMMToTwips(aScale.getX()));
808 aScale.setY(ImplMMToTwips(aScale.getY()));
810 break;
812 default:
814 DBG_ERROR("TRSetBaseGeometry: Missing unit translation to PoolMetric!");
819 // if anchor is used, make position relative to it
820 if( pModel->IsWriter() )
822 if(GetAnchorPos().X() || GetAnchorPos().Y())
824 aTranslate += basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
828 // build BaseRect
829 Point aPoint(FRound(aTranslate.getX()), FRound(aTranslate.getY()));
830 Rectangle aBaseRect(aPoint, Size(FRound(aScale.getX()), FRound(aScale.getY())));
832 // set BaseRect, but rescue TailPos over this call
833 const Point aTailPoint = GetTailPos();
834 SetSnapRect(aBaseRect);
835 SetTailPos(aTailPoint);
836 ImpRecalcTail();
839 // geometry access
840 ::basegfx::B2DPolygon SdrCaptionObj::getTailPolygon() const
842 return aTailPoly.getB2DPolygon();
845 // eof