xref: /aoo41x/main/svx/source/svdraw/svdocapt.cxx (revision a5258243)
1cdf0e10cSrcweir /*************************************************************************
2cdf0e10cSrcweir  *
3cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4cdf0e10cSrcweir  *
5cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6cdf0e10cSrcweir  *
7cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8cdf0e10cSrcweir  *
9cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10cdf0e10cSrcweir  *
11cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14cdf0e10cSrcweir  *
15cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20cdf0e10cSrcweir  *
21cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25cdf0e10cSrcweir  *
26cdf0e10cSrcweir  ************************************************************************/
27cdf0e10cSrcweir 
28cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29cdf0e10cSrcweir #include "precompiled_svx.hxx"
30cdf0e10cSrcweir #include <tools/bigint.hxx>
31cdf0e10cSrcweir #include <svx/xlnwtit.hxx>
32cdf0e10cSrcweir #include <svl/style.hxx>
33cdf0e10cSrcweir #include <svx/svdocapt.hxx>
34cdf0e10cSrcweir #include <svx/xpool.hxx>
35cdf0e10cSrcweir #include <svx/xpoly.hxx>
36cdf0e10cSrcweir #include <svx/svdattrx.hxx>
37cdf0e10cSrcweir #include <svx/svdpool.hxx>
38cdf0e10cSrcweir #include <svx/svdetc.hxx>
39cdf0e10cSrcweir #include <svx/svdtrans.hxx>
40cdf0e10cSrcweir #include <svx/svdhdl.hxx>
41cdf0e10cSrcweir #include <svx/svddrag.hxx>
42cdf0e10cSrcweir #include <svx/svdmodel.hxx>
43cdf0e10cSrcweir #include <svx/svdview.hxx>   // fuer RectSnap
44cdf0e10cSrcweir #include "svx/svdglob.hxx"   // StringCache
45cdf0e10cSrcweir #include "svx/svdstr.hrc"    // Objektname
46cdf0e10cSrcweir #include <svx/svdogrp.hxx>
47cdf0e10cSrcweir #include <svx/svdpage.hxx>
48cdf0e10cSrcweir #include <svx/xflhtit.hxx>
49cdf0e10cSrcweir #include <svx/xflclit.hxx>
50cdf0e10cSrcweir #include <svx/xfltrit.hxx>
51cdf0e10cSrcweir #include <editeng/eeitem.hxx>
52cdf0e10cSrcweir #include <svx/sdr/properties/captionproperties.hxx>
53cdf0e10cSrcweir #include <vcl/salbtype.hxx>		// FRound
54cdf0e10cSrcweir #include <svx/sdr/contact/viewcontactofsdrcaptionobj.hxx>
55cdf0e10cSrcweir #include <basegfx/tuple/b2dtuple.hxx>
56cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx>
57cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx>
58cdf0e10cSrcweir #include <basegfx/range/b2drange.hxx>
59cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygontools.hxx>
60cdf0e10cSrcweir #include <svx/sdrhittesthelper.hxx>
61cdf0e10cSrcweir 
62cdf0e10cSrcweir // #i32599#
63cdf0e10cSrcweir inline double ImplTwipsToMM(double fVal) { return (fVal * (127.0 / 72.0)); }
64cdf0e10cSrcweir inline double ImplMMToTwips(double fVal) { return (fVal * (72.0 / 127.0)); }
65cdf0e10cSrcweir 
66cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
67cdf0e10cSrcweir 
68cdf0e10cSrcweir enum EscDir {LKS,RTS,OBN,UNT};
69cdf0e10cSrcweir 
70cdf0e10cSrcweir class ImpCaptParams
71cdf0e10cSrcweir {
72cdf0e10cSrcweir public:
73cdf0e10cSrcweir 	SdrCaptionType				eType;
74cdf0e10cSrcweir 	long						nAngle;
75cdf0e10cSrcweir 	long						nGap;
76cdf0e10cSrcweir 	long						nEscRel;
77cdf0e10cSrcweir 	long						nEscAbs;
78cdf0e10cSrcweir 	long						nLineLen;
79cdf0e10cSrcweir 	SdrCaptionEscDir			eEscDir;
80cdf0e10cSrcweir 	FASTBOOL					bFitLineLen;
81cdf0e10cSrcweir 	FASTBOOL					bEscRel;
82cdf0e10cSrcweir 	FASTBOOL					bFixedAngle;
83cdf0e10cSrcweir 
84cdf0e10cSrcweir public:
85cdf0e10cSrcweir 	ImpCaptParams()
86cdf0e10cSrcweir 	{
87cdf0e10cSrcweir 		eType      =SDRCAPT_TYPE3;
88cdf0e10cSrcweir 		bFixedAngle=sal_False;
89cdf0e10cSrcweir 		nAngle     =4500;
90cdf0e10cSrcweir 		nGap       =0;
91cdf0e10cSrcweir 		eEscDir    =SDRCAPT_ESCHORIZONTAL;
92cdf0e10cSrcweir 		bEscRel    =sal_True;
93cdf0e10cSrcweir 		nEscRel    =5000;
94cdf0e10cSrcweir 		nEscAbs    =0;
95cdf0e10cSrcweir 		nLineLen   =0;
96cdf0e10cSrcweir 		bFitLineLen=sal_True;
97cdf0e10cSrcweir 	}
98cdf0e10cSrcweir 	void CalcEscPos(const Point& rTail, const Rectangle& rRect, Point& rPt, EscDir& rDir) const;
99cdf0e10cSrcweir };
100cdf0e10cSrcweir 
101cdf0e10cSrcweir void ImpCaptParams::CalcEscPos(const Point& rTailPt, const Rectangle& rRect, Point& rPt, EscDir& rDir) const
102cdf0e10cSrcweir {
103cdf0e10cSrcweir 	Point aTl(rTailPt); // lokal kopieren wg. Performance
104cdf0e10cSrcweir 	long nX,nY;
105cdf0e10cSrcweir 	if (bEscRel) {
106cdf0e10cSrcweir 		nX=rRect.Right()-rRect.Left();
107cdf0e10cSrcweir 		nX=BigMulDiv(nX,nEscRel,10000);
108cdf0e10cSrcweir 		nY=rRect.Bottom()-rRect.Top();
109cdf0e10cSrcweir 		nY=BigMulDiv(nY,nEscRel,10000);
110cdf0e10cSrcweir 	} else {
111cdf0e10cSrcweir 		nX=nEscAbs;
112cdf0e10cSrcweir 		nY=nEscAbs;
113cdf0e10cSrcweir 	}
114cdf0e10cSrcweir 	nX+=rRect.Left();
115cdf0e10cSrcweir 	nY+=rRect.Top();
116cdf0e10cSrcweir 	Point  aBestPt;
117cdf0e10cSrcweir 	EscDir eBestDir=LKS;
118cdf0e10cSrcweir 	FASTBOOL bTryH=eEscDir==SDRCAPT_ESCBESTFIT;
119cdf0e10cSrcweir 	if (!bTryH) {
120cdf0e10cSrcweir 		if (eType!=SDRCAPT_TYPE1) {
121cdf0e10cSrcweir 			bTryH=eEscDir==SDRCAPT_ESCHORIZONTAL;
122cdf0e10cSrcweir 		} else {
123cdf0e10cSrcweir 			bTryH=eEscDir==SDRCAPT_ESCVERTICAL;
124cdf0e10cSrcweir 		}
125cdf0e10cSrcweir 	}
126cdf0e10cSrcweir 	FASTBOOL bTryV=eEscDir==SDRCAPT_ESCBESTFIT;
127cdf0e10cSrcweir 	if (!bTryV) {
128cdf0e10cSrcweir 		if (eType!=SDRCAPT_TYPE1) {
129cdf0e10cSrcweir 			bTryV=eEscDir==SDRCAPT_ESCVERTICAL;
130cdf0e10cSrcweir 		} else {
131cdf0e10cSrcweir 			bTryV=eEscDir==SDRCAPT_ESCHORIZONTAL;
132cdf0e10cSrcweir 		}
133cdf0e10cSrcweir 	}
134cdf0e10cSrcweir 
135cdf0e10cSrcweir 	if (bTryH) {
136cdf0e10cSrcweir 		Point aLft(rRect.Left()-nGap,nY);
137cdf0e10cSrcweir 		Point aRgt(rRect.Right()+nGap,nY);
138cdf0e10cSrcweir 		FASTBOOL bLft=(aTl.X()-aLft.X()<aRgt.X()-aTl.X());
139cdf0e10cSrcweir 		if (bLft) {
140cdf0e10cSrcweir 			eBestDir=LKS;
141cdf0e10cSrcweir 			aBestPt=aLft;
142cdf0e10cSrcweir 		} else {
143cdf0e10cSrcweir 			eBestDir=RTS;
144cdf0e10cSrcweir 			aBestPt=aRgt;
145cdf0e10cSrcweir 		}
146cdf0e10cSrcweir 	}
147cdf0e10cSrcweir 	if (bTryV) {
148cdf0e10cSrcweir 		Point aTop(nX,rRect.Top()-nGap);
149cdf0e10cSrcweir 		Point aBtm(nX,rRect.Bottom()+nGap);
150cdf0e10cSrcweir 		FASTBOOL bTop=(aTl.Y()-aTop.Y()<aBtm.Y()-aTl.Y());
151cdf0e10cSrcweir 		Point aBest2;
152cdf0e10cSrcweir 		EscDir eBest2;
153cdf0e10cSrcweir 		if (bTop) {
154cdf0e10cSrcweir 			eBest2=OBN;
155cdf0e10cSrcweir 			aBest2=aTop;
156cdf0e10cSrcweir 		} else {
157cdf0e10cSrcweir 			eBest2=UNT;
158cdf0e10cSrcweir 			aBest2=aBtm;
159cdf0e10cSrcweir 		}
160cdf0e10cSrcweir 		FASTBOOL bTakeIt=eEscDir!=SDRCAPT_ESCBESTFIT;
161cdf0e10cSrcweir 		if (!bTakeIt) {
162cdf0e10cSrcweir 			BigInt aHorX(aBestPt.X()-aTl.X()); aHorX*=aHorX;
163cdf0e10cSrcweir 			BigInt aHorY(aBestPt.Y()-aTl.Y()); aHorY*=aHorY;
164cdf0e10cSrcweir 			BigInt aVerX(aBest2.X()-aTl.X());  aVerX*=aVerX;
165cdf0e10cSrcweir 			BigInt aVerY(aBest2.Y()-aTl.Y());  aVerY*=aVerY;
166cdf0e10cSrcweir 			if (eType!=SDRCAPT_TYPE1) {
167cdf0e10cSrcweir 				bTakeIt=aVerX+aVerY<aHorX+aHorY;
168cdf0e10cSrcweir 			} else {
169cdf0e10cSrcweir 				bTakeIt=aVerX+aVerY>=aHorX+aHorY;
170cdf0e10cSrcweir 			}
171cdf0e10cSrcweir 		}
172cdf0e10cSrcweir 		if (bTakeIt) {
173cdf0e10cSrcweir 			aBestPt=aBest2;
174cdf0e10cSrcweir 			eBestDir=eBest2;
175cdf0e10cSrcweir 		}
176cdf0e10cSrcweir 	}
177cdf0e10cSrcweir 	rPt=aBestPt;
178cdf0e10cSrcweir 	rDir=eBestDir;
179cdf0e10cSrcweir }
180cdf0e10cSrcweir 
181cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
182cdf0e10cSrcweir // BaseProperties section
183cdf0e10cSrcweir 
184cdf0e10cSrcweir sdr::properties::BaseProperties* SdrCaptionObj::CreateObjectSpecificProperties()
185cdf0e10cSrcweir {
186cdf0e10cSrcweir 	return new sdr::properties::CaptionProperties(*this);
187cdf0e10cSrcweir }
188cdf0e10cSrcweir 
189cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
190cdf0e10cSrcweir // DrawContact section
191cdf0e10cSrcweir 
192cdf0e10cSrcweir sdr::contact::ViewContact* SdrCaptionObj::CreateObjectSpecificViewContact()
193cdf0e10cSrcweir {
194cdf0e10cSrcweir 	return new sdr::contact::ViewContactOfSdrCaptionObj(*this);
195cdf0e10cSrcweir }
196cdf0e10cSrcweir 
197cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
198cdf0e10cSrcweir 
199cdf0e10cSrcweir TYPEINIT1(SdrCaptionObj,SdrRectObj);
200cdf0e10cSrcweir 
201cdf0e10cSrcweir SdrCaptionObj::SdrCaptionObj():
202cdf0e10cSrcweir 	SdrRectObj(OBJ_TEXT),
203cdf0e10cSrcweir 	aTailPoly(3),  // Default Groesse: 3 Punkte = 2 Linien
204cdf0e10cSrcweir 	mbSpecialTextBoxShadow(sal_False),
205cdf0e10cSrcweir 	mbFixedTail(sal_False)
206cdf0e10cSrcweir {
207cdf0e10cSrcweir }
208cdf0e10cSrcweir 
209cdf0e10cSrcweir SdrCaptionObj::SdrCaptionObj(const Rectangle& rRect):
210cdf0e10cSrcweir 	SdrRectObj(OBJ_TEXT,rRect),
211cdf0e10cSrcweir 	aTailPoly(3),  // Default Groesse: 3 Punkte = 2 Linien
212cdf0e10cSrcweir 	mbSpecialTextBoxShadow(sal_False),
213cdf0e10cSrcweir 	mbFixedTail(sal_False)
214cdf0e10cSrcweir {
215cdf0e10cSrcweir }
216cdf0e10cSrcweir 
217cdf0e10cSrcweir SdrCaptionObj::SdrCaptionObj(const Rectangle& rRect, const Point& rTail):
218cdf0e10cSrcweir 	SdrRectObj(OBJ_TEXT,rRect),
219cdf0e10cSrcweir 	aTailPoly(3),  // Default Groesse: 3 Punkte = 2 Linien
220cdf0e10cSrcweir 	mbSpecialTextBoxShadow(sal_False),
221cdf0e10cSrcweir 	mbFixedTail(sal_False)
222cdf0e10cSrcweir {
223cdf0e10cSrcweir 	aTailPoly[0]=maFixedTailPos=rTail;
224cdf0e10cSrcweir }
225cdf0e10cSrcweir 
226cdf0e10cSrcweir SdrCaptionObj::~SdrCaptionObj()
227cdf0e10cSrcweir {
228cdf0e10cSrcweir }
229cdf0e10cSrcweir 
230cdf0e10cSrcweir void SdrCaptionObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
231cdf0e10cSrcweir {
232cdf0e10cSrcweir 	rInfo.bRotateFreeAllowed=sal_False;
233cdf0e10cSrcweir 	rInfo.bRotate90Allowed  =sal_False;
234cdf0e10cSrcweir 	rInfo.bMirrorFreeAllowed=sal_False;
235cdf0e10cSrcweir 	rInfo.bMirror45Allowed  =sal_False;
236cdf0e10cSrcweir 	rInfo.bMirror90Allowed  =sal_False;
237cdf0e10cSrcweir 	rInfo.bTransparenceAllowed = sal_False;
238cdf0e10cSrcweir 	rInfo.bGradientAllowed = sal_False;
239cdf0e10cSrcweir 	rInfo.bShearAllowed     =sal_False;
240cdf0e10cSrcweir 	rInfo.bEdgeRadiusAllowed=sal_False;
241cdf0e10cSrcweir 	rInfo.bCanConvToPath    =sal_True;
242cdf0e10cSrcweir 	rInfo.bCanConvToPoly    =sal_True;
243cdf0e10cSrcweir 	rInfo.bCanConvToPathLineToArea=sal_False;
244cdf0e10cSrcweir 	rInfo.bCanConvToPolyLineToArea=sal_False;
245cdf0e10cSrcweir 	rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
246cdf0e10cSrcweir }
247cdf0e10cSrcweir 
248cdf0e10cSrcweir sal_uInt16 SdrCaptionObj::GetObjIdentifier() const
249cdf0e10cSrcweir {
250cdf0e10cSrcweir 	return sal_uInt16(OBJ_CAPTION);
251cdf0e10cSrcweir }
252cdf0e10cSrcweir 
253cdf0e10cSrcweir void SdrCaptionObj::operator=(const SdrObject& rObj)
254cdf0e10cSrcweir {
255cdf0e10cSrcweir 	SdrRectObj::operator=(rObj);
256cdf0e10cSrcweir 	aTailPoly=((SdrCaptionObj&)rObj).aTailPoly;
257cdf0e10cSrcweir }
258cdf0e10cSrcweir 
259cdf0e10cSrcweir void SdrCaptionObj::TakeObjNameSingul(XubString& rName) const
260cdf0e10cSrcweir {
261cdf0e10cSrcweir 	rName=ImpGetResStr(STR_ObjNameSingulCAPTION);
262cdf0e10cSrcweir 
263cdf0e10cSrcweir 	String aName( GetName() );
264cdf0e10cSrcweir 	if(aName.Len())
265cdf0e10cSrcweir 	{
266cdf0e10cSrcweir 		rName += sal_Unicode(' ');
267cdf0e10cSrcweir 		rName += sal_Unicode('\'');
268cdf0e10cSrcweir 		rName += aName;
269cdf0e10cSrcweir 		rName += sal_Unicode('\'');
270cdf0e10cSrcweir 	}
271cdf0e10cSrcweir }
272cdf0e10cSrcweir 
273cdf0e10cSrcweir void SdrCaptionObj::TakeObjNamePlural(XubString& rName) const
274cdf0e10cSrcweir {
275cdf0e10cSrcweir 	rName=ImpGetResStr(STR_ObjNamePluralCAPTION);
276cdf0e10cSrcweir }
277cdf0e10cSrcweir 
278cdf0e10cSrcweir basegfx::B2DPolyPolygon SdrCaptionObj::TakeXorPoly() const
279cdf0e10cSrcweir {
280cdf0e10cSrcweir 	basegfx::B2DPolyPolygon aPolyPoly(SdrRectObj::TakeXorPoly());
281cdf0e10cSrcweir 	aPolyPoly.append(aTailPoly.getB2DPolygon());
282cdf0e10cSrcweir 
283cdf0e10cSrcweir 	return aPolyPoly;
284cdf0e10cSrcweir }
285cdf0e10cSrcweir 
286cdf0e10cSrcweir sal_uInt32 SdrCaptionObj::GetHdlCount() const
287cdf0e10cSrcweir {
288cdf0e10cSrcweir 	sal_uInt32 nAnz1(SdrRectObj::GetHdlCount());
289cdf0e10cSrcweir 	// sal_uInt32 nAnz2(aTailPoly.GetSize());
290cdf0e10cSrcweir 	// Derzeit ist nur das Draggen des Schwanzendes implementiert
291cdf0e10cSrcweir 	return nAnz1 + 1L;
292cdf0e10cSrcweir }
293cdf0e10cSrcweir 
294cdf0e10cSrcweir SdrHdl* SdrCaptionObj::GetHdl(sal_uInt32 nHdlNum) const
295cdf0e10cSrcweir {
296cdf0e10cSrcweir 	const sal_uInt32 nRectHdlAnz(SdrRectObj::GetHdlCount());
297cdf0e10cSrcweir 
298cdf0e10cSrcweir 	if(nHdlNum < nRectHdlAnz)
299cdf0e10cSrcweir 	{
300cdf0e10cSrcweir 		return SdrRectObj::GetHdl(nHdlNum);
301cdf0e10cSrcweir 	}
302cdf0e10cSrcweir 	else
303cdf0e10cSrcweir 	{
304cdf0e10cSrcweir 		sal_uInt32 nPntNum(nHdlNum);
305cdf0e10cSrcweir 		nPntNum -= nRectHdlAnz;
306cdf0e10cSrcweir 
307cdf0e10cSrcweir 		if(nPntNum < aTailPoly.GetSize())
308cdf0e10cSrcweir 		{
309cdf0e10cSrcweir 			SdrHdl* pHdl = new SdrHdl(aTailPoly.GetPoint((sal_uInt16)nPntNum), HDL_POLY);
310cdf0e10cSrcweir 			pHdl->SetPolyNum(1L);
311cdf0e10cSrcweir 			pHdl->SetPointNum(nPntNum);
312cdf0e10cSrcweir 			return pHdl;
313cdf0e10cSrcweir 		}
314cdf0e10cSrcweir 		else
315cdf0e10cSrcweir 		{
316cdf0e10cSrcweir 			return 0L;
317cdf0e10cSrcweir 		}
318cdf0e10cSrcweir 	}
319cdf0e10cSrcweir }
320cdf0e10cSrcweir 
321cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
322cdf0e10cSrcweir 
323cdf0e10cSrcweir bool SdrCaptionObj::hasSpecialDrag() const
324cdf0e10cSrcweir {
325cdf0e10cSrcweir 	return true;
326cdf0e10cSrcweir }
327cdf0e10cSrcweir 
328cdf0e10cSrcweir bool SdrCaptionObj::beginSpecialDrag(SdrDragStat& rDrag) const
329cdf0e10cSrcweir {
330cdf0e10cSrcweir 	const SdrHdl* pHdl = rDrag.GetHdl();
331cdf0e10cSrcweir 	rDrag.SetEndDragChangesAttributes(true);
332cdf0e10cSrcweir 	rDrag.SetEndDragChangesGeoAndAttributes(true);
333cdf0e10cSrcweir 
334cdf0e10cSrcweir 	if(pHdl && 0 == pHdl->GetPolyNum())
335cdf0e10cSrcweir     {
336cdf0e10cSrcweir 		return SdrRectObj::beginSpecialDrag(rDrag);
337cdf0e10cSrcweir 	}
338cdf0e10cSrcweir     else
339cdf0e10cSrcweir     {
340cdf0e10cSrcweir 		rDrag.SetOrtho8Possible(true);
341cdf0e10cSrcweir 
342cdf0e10cSrcweir         if(!pHdl)
343cdf0e10cSrcweir         {
344cdf0e10cSrcweir 			if (bMovProt)
345cdf0e10cSrcweir                 return 0;
346cdf0e10cSrcweir 
347cdf0e10cSrcweir 			rDrag.SetNoSnap(true);
348cdf0e10cSrcweir 			rDrag.SetActionRect(aRect);
349cdf0e10cSrcweir 
350cdf0e10cSrcweir             Point aHit(rDrag.GetStart());
351cdf0e10cSrcweir 
352cdf0e10cSrcweir             if(rDrag.GetPageView() && SdrObjectPrimitiveHit(*this, aHit, 0, *rDrag.GetPageView(), 0, false))
353cdf0e10cSrcweir             {
354cdf0e10cSrcweir                 return true;
355cdf0e10cSrcweir             }
356cdf0e10cSrcweir 		}
357cdf0e10cSrcweir         else
358cdf0e10cSrcweir         {
359cdf0e10cSrcweir 			if((1 == pHdl->GetPolyNum()) && (0 == pHdl->GetPointNum()))
360cdf0e10cSrcweir                 return true;
361cdf0e10cSrcweir 		}
362cdf0e10cSrcweir 	}
363cdf0e10cSrcweir 
364cdf0e10cSrcweir     return false;
365cdf0e10cSrcweir }
366cdf0e10cSrcweir 
367cdf0e10cSrcweir bool SdrCaptionObj::applySpecialDrag(SdrDragStat& rDrag)
368cdf0e10cSrcweir {
369cdf0e10cSrcweir 	const SdrHdl* pHdl = rDrag.GetHdl();
370cdf0e10cSrcweir 
371cdf0e10cSrcweir     if(pHdl && 0 == pHdl->GetPolyNum())
372cdf0e10cSrcweir     {
373cdf0e10cSrcweir 		const bool bRet(SdrRectObj::applySpecialDrag(rDrag));
374cdf0e10cSrcweir         ImpRecalcTail();
375cdf0e10cSrcweir 	    ActionChanged();
376cdf0e10cSrcweir 
377cdf0e10cSrcweir         return bRet;
378cdf0e10cSrcweir 	}
379cdf0e10cSrcweir     else
380cdf0e10cSrcweir     {
381cdf0e10cSrcweir 		Point aDelt(rDrag.GetNow()-rDrag.GetStart());
382cdf0e10cSrcweir 
383cdf0e10cSrcweir         if(!pHdl)
384cdf0e10cSrcweir         {
385cdf0e10cSrcweir 			aRect.Move(aDelt.X(),aDelt.Y());
386cdf0e10cSrcweir 		}
387cdf0e10cSrcweir         else
388cdf0e10cSrcweir         {
389cdf0e10cSrcweir 			aTailPoly[0] += aDelt;
390cdf0e10cSrcweir 		}
391cdf0e10cSrcweir 
392cdf0e10cSrcweir         ImpRecalcTail();
393cdf0e10cSrcweir 	    ActionChanged();
394cdf0e10cSrcweir 
395cdf0e10cSrcweir         return true;
396cdf0e10cSrcweir 	}
397cdf0e10cSrcweir }
398cdf0e10cSrcweir 
399cdf0e10cSrcweir String SdrCaptionObj::getSpecialDragComment(const SdrDragStat& rDrag) const
400cdf0e10cSrcweir {
401cdf0e10cSrcweir     const bool bCreateComment(rDrag.GetView() && this == rDrag.GetView()->GetCreateObj());
402cdf0e10cSrcweir 
403cdf0e10cSrcweir     if(bCreateComment)
404cdf0e10cSrcweir     {
405cdf0e10cSrcweir         return String();
406cdf0e10cSrcweir     }
407cdf0e10cSrcweir     else
408cdf0e10cSrcweir     {
409cdf0e10cSrcweir         const SdrHdl* pHdl = rDrag.GetHdl();
410cdf0e10cSrcweir 
411cdf0e10cSrcweir         if(pHdl && 0 == pHdl->GetPolyNum())
412cdf0e10cSrcweir         {
413cdf0e10cSrcweir 		    return SdrRectObj::getSpecialDragComment(rDrag);
414cdf0e10cSrcweir 	    }
415cdf0e10cSrcweir         else
416cdf0e10cSrcweir         {
417cdf0e10cSrcweir 		    XubString aStr;
418cdf0e10cSrcweir 
419cdf0e10cSrcweir             if(!pHdl)
420cdf0e10cSrcweir             {
421cdf0e10cSrcweir 			    ImpTakeDescriptionStr(STR_DragCaptFram, aStr);
422cdf0e10cSrcweir 		    }
423cdf0e10cSrcweir             else
424cdf0e10cSrcweir             {
425cdf0e10cSrcweir 			    ImpTakeDescriptionStr(STR_DragCaptTail, aStr);
426cdf0e10cSrcweir 		    }
427cdf0e10cSrcweir 
428cdf0e10cSrcweir             return aStr;
429cdf0e10cSrcweir 	    }
430cdf0e10cSrcweir     }
431cdf0e10cSrcweir }
432cdf0e10cSrcweir 
433cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
434cdf0e10cSrcweir 
435cdf0e10cSrcweir void SdrCaptionObj::ImpGetCaptParams(ImpCaptParams& rPara) const
436cdf0e10cSrcweir {
437cdf0e10cSrcweir 	const SfxItemSet& rSet = GetObjectItemSet();
438cdf0e10cSrcweir 	rPara.eType      =((SdrCaptionTypeItem&)      (rSet.Get(SDRATTR_CAPTIONTYPE      ))).GetValue();
439cdf0e10cSrcweir 	rPara.bFixedAngle=((SdrCaptionFixedAngleItem&)(rSet.Get(SDRATTR_CAPTIONANGLE     ))).GetValue();
440cdf0e10cSrcweir 	rPara.nAngle     =((SdrCaptionAngleItem&)     (rSet.Get(SDRATTR_CAPTIONFIXEDANGLE))).GetValue();
441cdf0e10cSrcweir 	rPara.nGap       =((SdrCaptionGapItem&)       (rSet.Get(SDRATTR_CAPTIONGAP       ))).GetValue();
442cdf0e10cSrcweir 	rPara.eEscDir    =((SdrCaptionEscDirItem&)    (rSet.Get(SDRATTR_CAPTIONESCDIR    ))).GetValue();
443cdf0e10cSrcweir 	rPara.bEscRel    =((SdrCaptionEscIsRelItem&)  (rSet.Get(SDRATTR_CAPTIONESCISREL  ))).GetValue();
444cdf0e10cSrcweir 	rPara.nEscRel    =((SdrCaptionEscRelItem&)    (rSet.Get(SDRATTR_CAPTIONESCREL    ))).GetValue();
445cdf0e10cSrcweir 	rPara.nEscAbs    =((SdrCaptionEscAbsItem&)    (rSet.Get(SDRATTR_CAPTIONESCABS    ))).GetValue();
446cdf0e10cSrcweir 	rPara.nLineLen   =((SdrCaptionLineLenItem&)   (rSet.Get(SDRATTR_CAPTIONLINELEN   ))).GetValue();
447cdf0e10cSrcweir 	rPara.bFitLineLen=((SdrCaptionFitLineLenItem&)(rSet.Get(SDRATTR_CAPTIONFITLINELEN))).GetValue();
448cdf0e10cSrcweir }
449cdf0e10cSrcweir 
450cdf0e10cSrcweir void SdrCaptionObj::ImpRecalcTail()
451cdf0e10cSrcweir {
452cdf0e10cSrcweir 	ImpCaptParams aPara;
453cdf0e10cSrcweir 	ImpGetCaptParams(aPara);
454cdf0e10cSrcweir 	ImpCalcTail(aPara,aTailPoly,aRect);
455cdf0e10cSrcweir 	SetRectsDirty();
456cdf0e10cSrcweir 	SetXPolyDirty();
457cdf0e10cSrcweir }
458cdf0e10cSrcweir 
459cdf0e10cSrcweir // #i35971#
460cdf0e10cSrcweir // SdrCaptionObj::ImpCalcTail1 does move the object(!). What a hack.
461cdf0e10cSrcweir // I really wonder why this had not triggered problems before. I am
462cdf0e10cSrcweir // sure there are some places where SetTailPos() is called at least
463cdf0e10cSrcweir // twice or SetSnapRect after it again just to work around this.
464cdf0e10cSrcweir // Changed this method to not do that.
465cdf0e10cSrcweir // Also found why this has been done: For interactive dragging of the
466cdf0e10cSrcweir // tail end pos for SDRCAPT_TYPE1. This sure was the simplest method
467cdf0e10cSrcweir // to achieve this, for the cost to make a whole group of const methods
468cdf0e10cSrcweir // of this object implicitly chainging the object's position.
469cdf0e10cSrcweir void SdrCaptionObj::ImpCalcTail1(const ImpCaptParams& rPara, Polygon& rPoly, Rectangle& rRect) const
470cdf0e10cSrcweir {
471cdf0e10cSrcweir 	Polygon aPol(2);
472cdf0e10cSrcweir 	Point aTl(rPoly[0]);
473cdf0e10cSrcweir 
474cdf0e10cSrcweir 	aPol[0] = aTl;
475cdf0e10cSrcweir 	aPol[1] = aTl;
476cdf0e10cSrcweir 
477cdf0e10cSrcweir 	EscDir eEscDir;
478cdf0e10cSrcweir 	Point aEscPos;
479cdf0e10cSrcweir 
480cdf0e10cSrcweir 	rPara.CalcEscPos(aTl, rRect, aEscPos, eEscDir);
481cdf0e10cSrcweir 	aPol[1] = aEscPos;
482cdf0e10cSrcweir 
483cdf0e10cSrcweir 	if(eEscDir==LKS || eEscDir==RTS)
484cdf0e10cSrcweir 	{
485cdf0e10cSrcweir 		aPol[0].X() = aEscPos.X();
486cdf0e10cSrcweir 	}
487cdf0e10cSrcweir 	else
488cdf0e10cSrcweir 	{
489cdf0e10cSrcweir 		aPol[0].Y() = aEscPos.Y();
490cdf0e10cSrcweir 	}
491cdf0e10cSrcweir 
492cdf0e10cSrcweir 	rPoly = aPol;
493cdf0e10cSrcweir }
494cdf0e10cSrcweir 
495cdf0e10cSrcweir void SdrCaptionObj::ImpCalcTail2(const ImpCaptParams& rPara, Polygon& rPoly, Rectangle& rRect) const
496cdf0e10cSrcweir { // Gap/EscDir/EscPos/Angle
497cdf0e10cSrcweir 	Polygon aPol(2);
498cdf0e10cSrcweir 	Point aTl(rPoly[0]);
499cdf0e10cSrcweir 	aPol[0]=aTl;
500cdf0e10cSrcweir 
501cdf0e10cSrcweir 	EscDir eEscDir;
502cdf0e10cSrcweir 	Point aEscPos;
503cdf0e10cSrcweir 	rPara.CalcEscPos(aTl,rRect,aEscPos,eEscDir);
504cdf0e10cSrcweir 	aPol[1]=aEscPos;
505cdf0e10cSrcweir 
506cdf0e10cSrcweir 	if (!rPara.bFixedAngle) {
507cdf0e10cSrcweir 		// fehlende Implementation
508cdf0e10cSrcweir 	}
509cdf0e10cSrcweir 	rPoly=aPol;
510cdf0e10cSrcweir }
511cdf0e10cSrcweir 
512cdf0e10cSrcweir void SdrCaptionObj::ImpCalcTail3(const ImpCaptParams& rPara, Polygon& rPoly, Rectangle& rRect) const
513cdf0e10cSrcweir { // Gap/EscDir/EscPos/Angle/LineLen
514cdf0e10cSrcweir 	Polygon aPol(3);
515cdf0e10cSrcweir 	Point aTl(rPoly[0]);
516cdf0e10cSrcweir 	aPol[0]=aTl;
517cdf0e10cSrcweir 
518cdf0e10cSrcweir 	EscDir eEscDir;
519cdf0e10cSrcweir 	Point aEscPos;
520cdf0e10cSrcweir 	rPara.CalcEscPos(aTl,rRect,aEscPos,eEscDir);
521cdf0e10cSrcweir 	aPol[1]=aEscPos;
522cdf0e10cSrcweir 	aPol[2]=aEscPos;
523cdf0e10cSrcweir 
524cdf0e10cSrcweir 	if (eEscDir==LKS || eEscDir==RTS) {
525cdf0e10cSrcweir 		if (rPara.bFitLineLen) {
526cdf0e10cSrcweir 			aPol[1].X()=(aTl.X()+aEscPos.X())/2;
527cdf0e10cSrcweir 		} else {
528cdf0e10cSrcweir 			if (eEscDir==LKS) aPol[1].X()-=rPara.nLineLen;
529cdf0e10cSrcweir 			else aPol[1].X()+=rPara.nLineLen;
530cdf0e10cSrcweir 		}
531cdf0e10cSrcweir 	} else {
532cdf0e10cSrcweir 		if (rPara.bFitLineLen) {
533cdf0e10cSrcweir 			aPol[1].Y()=(aTl.Y()+aEscPos.Y())/2;
534cdf0e10cSrcweir 		} else {
535cdf0e10cSrcweir 			if (eEscDir==OBN) aPol[1].Y()-=rPara.nLineLen;
536cdf0e10cSrcweir 			else aPol[1].Y()+=rPara.nLineLen;
537cdf0e10cSrcweir 		}
538cdf0e10cSrcweir 	}
539cdf0e10cSrcweir 	if (!rPara.bFixedAngle) {
540cdf0e10cSrcweir 		// fehlende Implementation
541cdf0e10cSrcweir 	}
542cdf0e10cSrcweir 	rPoly=aPol;
543cdf0e10cSrcweir }
544cdf0e10cSrcweir 
545cdf0e10cSrcweir void SdrCaptionObj::ImpCalcTail4(const ImpCaptParams& rPara, Polygon& rPoly, Rectangle& rRect) const
546cdf0e10cSrcweir {
547cdf0e10cSrcweir 	ImpCalcTail3(rPara,rPoly,rRect);
548cdf0e10cSrcweir }
549cdf0e10cSrcweir 
550cdf0e10cSrcweir void SdrCaptionObj::ImpCalcTail(const ImpCaptParams& rPara, Polygon& rPoly, Rectangle& rRect) const
551cdf0e10cSrcweir {
552cdf0e10cSrcweir 	switch (rPara.eType) {
553cdf0e10cSrcweir 		case SDRCAPT_TYPE1: ImpCalcTail1(rPara,rPoly,rRect); break;
554cdf0e10cSrcweir 		case SDRCAPT_TYPE2: ImpCalcTail2(rPara,rPoly,rRect); break;
555cdf0e10cSrcweir 		case SDRCAPT_TYPE3: ImpCalcTail3(rPara,rPoly,rRect); break;
556cdf0e10cSrcweir 		case SDRCAPT_TYPE4: ImpCalcTail4(rPara,rPoly,rRect); break;
557cdf0e10cSrcweir 	}
558cdf0e10cSrcweir }
559cdf0e10cSrcweir 
560cdf0e10cSrcweir FASTBOOL SdrCaptionObj::BegCreate(SdrDragStat& rStat)
561cdf0e10cSrcweir {
562cdf0e10cSrcweir 	if (aRect.IsEmpty()) return sal_False; // Create z.Zt. nur mit vorgegebenen Rect
563cdf0e10cSrcweir 
564cdf0e10cSrcweir 	ImpCaptParams aPara;
565cdf0e10cSrcweir 	ImpGetCaptParams(aPara);
566cdf0e10cSrcweir 	aRect.SetPos(rStat.GetNow());
567cdf0e10cSrcweir 	aTailPoly[0]=rStat.GetStart();
568cdf0e10cSrcweir 	ImpCalcTail(aPara,aTailPoly,aRect);
569cdf0e10cSrcweir 	rStat.SetActionRect(aRect);
570cdf0e10cSrcweir 	return sal_True;
571cdf0e10cSrcweir }
572cdf0e10cSrcweir 
573cdf0e10cSrcweir FASTBOOL SdrCaptionObj::MovCreate(SdrDragStat& rStat)
574cdf0e10cSrcweir {
575cdf0e10cSrcweir 	ImpCaptParams aPara;
576cdf0e10cSrcweir 	ImpGetCaptParams(aPara);
577cdf0e10cSrcweir 	aRect.SetPos(rStat.GetNow());
578cdf0e10cSrcweir 	ImpCalcTail(aPara,aTailPoly,aRect);
579cdf0e10cSrcweir 	rStat.SetActionRect(aRect);
580cdf0e10cSrcweir 	SetBoundRectDirty();
581cdf0e10cSrcweir 	bSnapRectDirty=sal_True;
582cdf0e10cSrcweir 	return sal_True;
583cdf0e10cSrcweir }
584cdf0e10cSrcweir 
585cdf0e10cSrcweir FASTBOOL SdrCaptionObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
586cdf0e10cSrcweir {
587cdf0e10cSrcweir 	ImpCaptParams aPara;
588cdf0e10cSrcweir 	ImpGetCaptParams(aPara);
589cdf0e10cSrcweir 	aRect.SetPos(rStat.GetNow());
590cdf0e10cSrcweir 	ImpCalcTail(aPara,aTailPoly,aRect);
591cdf0e10cSrcweir 	SetRectsDirty();
592cdf0e10cSrcweir 	return (eCmd==SDRCREATE_FORCEEND || rStat.GetPointAnz()>=2);
593cdf0e10cSrcweir }
594cdf0e10cSrcweir 
595cdf0e10cSrcweir FASTBOOL SdrCaptionObj::BckCreate(SdrDragStat& /*rStat*/)
596cdf0e10cSrcweir {
597cdf0e10cSrcweir 	return sal_False;
598cdf0e10cSrcweir }
599cdf0e10cSrcweir 
600cdf0e10cSrcweir void SdrCaptionObj::BrkCreate(SdrDragStat& /*rStat*/)
601cdf0e10cSrcweir {
602cdf0e10cSrcweir }
603cdf0e10cSrcweir 
604cdf0e10cSrcweir basegfx::B2DPolyPolygon SdrCaptionObj::TakeCreatePoly(const SdrDragStat& /*rDrag*/) const
605cdf0e10cSrcweir {
606cdf0e10cSrcweir 	basegfx::B2DPolyPolygon aRetval;
607cdf0e10cSrcweir 	const basegfx::B2DRange aRange(aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom());
608cdf0e10cSrcweir 	aRetval.append(basegfx::tools::createPolygonFromRect(aRange));
609cdf0e10cSrcweir 	aRetval.append(aTailPoly.getB2DPolygon());
610cdf0e10cSrcweir 	return aRetval;
611cdf0e10cSrcweir }
612cdf0e10cSrcweir 
613cdf0e10cSrcweir Pointer SdrCaptionObj::GetCreatePointer() const
614cdf0e10cSrcweir {
615cdf0e10cSrcweir 	return Pointer(POINTER_DRAW_CAPTION);
616cdf0e10cSrcweir }
617cdf0e10cSrcweir 
618cdf0e10cSrcweir void SdrCaptionObj::NbcMove(const Size& rSiz)
619cdf0e10cSrcweir {
620cdf0e10cSrcweir 	SdrRectObj::NbcMove(rSiz);
621cdf0e10cSrcweir 	MovePoly(aTailPoly,rSiz);
622cdf0e10cSrcweir     if(mbFixedTail)
623cdf0e10cSrcweir         SetTailPos(GetFixedTailPos());
624cdf0e10cSrcweir }
625cdf0e10cSrcweir 
626cdf0e10cSrcweir void SdrCaptionObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
627cdf0e10cSrcweir {
628cdf0e10cSrcweir 	SdrRectObj::NbcResize(rRef,xFact,yFact);
629cdf0e10cSrcweir 	ResizePoly(aTailPoly,rRef,xFact,yFact);
630cdf0e10cSrcweir 	ImpRecalcTail();
631cdf0e10cSrcweir     if(mbFixedTail)
632cdf0e10cSrcweir         SetTailPos(GetFixedTailPos());
633cdf0e10cSrcweir }
634cdf0e10cSrcweir 
635cdf0e10cSrcweir void SdrCaptionObj::NbcSetRelativePos(const Point& rPnt)
636cdf0e10cSrcweir {
637cdf0e10cSrcweir 	Point aRelPos0(aTailPoly.GetPoint(0)-aAnchor);
638cdf0e10cSrcweir 	Size aSiz(rPnt.X()-aRelPos0.X(),rPnt.Y()-aRelPos0.Y());
639cdf0e10cSrcweir 	NbcMove(aSiz); // Der ruft auch das SetRectsDirty()
640cdf0e10cSrcweir }
641cdf0e10cSrcweir 
642cdf0e10cSrcweir Point SdrCaptionObj::GetRelativePos() const
643cdf0e10cSrcweir {
644cdf0e10cSrcweir 	return aTailPoly.GetPoint(0)-aAnchor;
645cdf0e10cSrcweir }
646cdf0e10cSrcweir 
647cdf0e10cSrcweir void SdrCaptionObj::NbcSetAnchorPos(const Point& rPnt)
648cdf0e10cSrcweir {
649cdf0e10cSrcweir 	SdrRectObj::NbcSetAnchorPos(rPnt);
650cdf0e10cSrcweir 	// !!!!! fehlende Impl.
651cdf0e10cSrcweir }
652cdf0e10cSrcweir 
653cdf0e10cSrcweir const Point& SdrCaptionObj::GetAnchorPos() const
654cdf0e10cSrcweir {
655cdf0e10cSrcweir 	// !!!!! fehlende Impl.
656cdf0e10cSrcweir 	return SdrRectObj::GetAnchorPos();
657cdf0e10cSrcweir }
658cdf0e10cSrcweir 
659cdf0e10cSrcweir void SdrCaptionObj::RecalcSnapRect()
660cdf0e10cSrcweir {
661cdf0e10cSrcweir 	SdrRectObj::RecalcSnapRect();
662cdf0e10cSrcweir 	// #i32599#
663cdf0e10cSrcweir 	// maSnapRect.Union(aTailPoly.GetBoundRect());
664cdf0e10cSrcweir 	// !!!!! fehlende Impl.
665cdf0e10cSrcweir }
666cdf0e10cSrcweir 
667cdf0e10cSrcweir const Rectangle& SdrCaptionObj::GetSnapRect() const
668cdf0e10cSrcweir {
669cdf0e10cSrcweir 	return SdrRectObj::GetSnapRect();
670cdf0e10cSrcweir }
671cdf0e10cSrcweir 
672cdf0e10cSrcweir void SdrCaptionObj::NbcSetSnapRect(const Rectangle& rRect)
673cdf0e10cSrcweir {
674cdf0e10cSrcweir 	// #i32599#
675cdf0e10cSrcweir 	// Move back to see the rectangle of the underlying SdrRectObj
676cdf0e10cSrcweir 	// as the SnapRect, without the TailPos. That simplifies SnapRect
677cdf0e10cSrcweir 	// handling again, if not allows it at all...
678cdf0e10cSrcweir 	SdrRectObj::NbcSetSnapRect(rRect);
679cdf0e10cSrcweir }
680cdf0e10cSrcweir 
681cdf0e10cSrcweir const Rectangle& SdrCaptionObj::GetLogicRect() const
682cdf0e10cSrcweir {
683cdf0e10cSrcweir 	return aRect;
684cdf0e10cSrcweir }
685cdf0e10cSrcweir 
686cdf0e10cSrcweir void SdrCaptionObj::NbcSetLogicRect(const Rectangle& rRect)
687cdf0e10cSrcweir {
688cdf0e10cSrcweir 	SdrRectObj::NbcSetLogicRect(rRect);
689cdf0e10cSrcweir 	ImpRecalcTail();
690cdf0e10cSrcweir }
691cdf0e10cSrcweir 
692cdf0e10cSrcweir const Point& SdrCaptionObj::GetTailPos() const
693cdf0e10cSrcweir {
694cdf0e10cSrcweir 	return aTailPoly[0];
695cdf0e10cSrcweir }
696cdf0e10cSrcweir 
697cdf0e10cSrcweir void SdrCaptionObj::SetTailPos(const Point& rPos)
698cdf0e10cSrcweir {
699cdf0e10cSrcweir 	if (aTailPoly.GetSize()==0 || aTailPoly[0]!=rPos) {
700cdf0e10cSrcweir 		Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
701cdf0e10cSrcweir 		// #110094#-14 SendRepaintBroadcast();
702cdf0e10cSrcweir 		NbcSetTailPos(rPos);
703cdf0e10cSrcweir 		SetChanged();
704cdf0e10cSrcweir 		BroadcastObjectChange();
705cdf0e10cSrcweir 		SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
706cdf0e10cSrcweir 	}
707cdf0e10cSrcweir }
708cdf0e10cSrcweir 
709cdf0e10cSrcweir void SdrCaptionObj::NbcSetTailPos(const Point& rPos)
710cdf0e10cSrcweir {
711cdf0e10cSrcweir 	aTailPoly[0]=rPos;
712cdf0e10cSrcweir 	ImpRecalcTail();
713cdf0e10cSrcweir }
714cdf0e10cSrcweir 
715cdf0e10cSrcweir sal_uInt32 SdrCaptionObj::GetSnapPointCount() const
716cdf0e10cSrcweir {
717cdf0e10cSrcweir 	// !!!!! fehlende Impl.
718cdf0e10cSrcweir 	return 0L;
719cdf0e10cSrcweir }
720cdf0e10cSrcweir 
721cdf0e10cSrcweir Point SdrCaptionObj::GetSnapPoint(sal_uInt32 /*i*/) const
722cdf0e10cSrcweir {
723cdf0e10cSrcweir 	// !!!!! fehlende Impl.
724cdf0e10cSrcweir 	return Point(0,0);
725cdf0e10cSrcweir }
726cdf0e10cSrcweir 
727cdf0e10cSrcweir void SdrCaptionObj::SetModel(SdrModel* pNewModel)
728cdf0e10cSrcweir {
729cdf0e10cSrcweir 	SdrRectObj::SetModel(pNewModel);
730cdf0e10cSrcweir 	ImpRecalcTail();
731cdf0e10cSrcweir }
732cdf0e10cSrcweir 
733cdf0e10cSrcweir void SdrCaptionObj::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
734cdf0e10cSrcweir {
735cdf0e10cSrcweir 	SdrRectObj::Notify(rBC,rHint);
736cdf0e10cSrcweir 	ImpRecalcTail();
737cdf0e10cSrcweir }
738cdf0e10cSrcweir 
739cdf0e10cSrcweir SdrObjGeoData* SdrCaptionObj::NewGeoData() const
740cdf0e10cSrcweir {
741cdf0e10cSrcweir 	return new SdrCaptObjGeoData;
742cdf0e10cSrcweir }
743cdf0e10cSrcweir 
744cdf0e10cSrcweir void SdrCaptionObj::SaveGeoData(SdrObjGeoData& rGeo) const
745cdf0e10cSrcweir {
746cdf0e10cSrcweir 	SdrRectObj::SaveGeoData(rGeo);
747cdf0e10cSrcweir 	SdrCaptObjGeoData& rCGeo=(SdrCaptObjGeoData&)rGeo;
748cdf0e10cSrcweir 	rCGeo.aTailPoly=aTailPoly;
749cdf0e10cSrcweir }
750cdf0e10cSrcweir 
751cdf0e10cSrcweir void SdrCaptionObj::RestGeoData(const SdrObjGeoData& rGeo)
752cdf0e10cSrcweir {
753cdf0e10cSrcweir 	SdrRectObj::RestGeoData(rGeo);
754cdf0e10cSrcweir 	SdrCaptObjGeoData& rCGeo=(SdrCaptObjGeoData&)rGeo;
755cdf0e10cSrcweir 	aTailPoly=rCGeo.aTailPoly;
756cdf0e10cSrcweir }
757cdf0e10cSrcweir 
758*a5258243SPedro Giffuni SdrObject* SdrCaptionObj::DoConvertToPolyObj(sal_Bool bBezier, bool bAddText) const
759cdf0e10cSrcweir { // #42334# - Convert implementiert
760*a5258243SPedro Giffuni 	SdrObject* pRect=SdrRectObj::DoConvertToPolyObj(bBezier, bAddText);
761cdf0e10cSrcweir 	SdrObject* pTail = ImpConvertMakeObj(basegfx::B2DPolyPolygon(aTailPoly.getB2DPolygon()), sal_False, bBezier);
762cdf0e10cSrcweir 	SdrObject* pRet=(pTail!=NULL) ? pTail : pRect;
763cdf0e10cSrcweir 	if (pTail!=NULL && pRect!=NULL) {
764cdf0e10cSrcweir 		FASTBOOL bInsRect=sal_True;
765cdf0e10cSrcweir 		FASTBOOL bInsTail=sal_True;
766cdf0e10cSrcweir 		SdrObjList* pOL=pTail->GetSubList();
767cdf0e10cSrcweir 		if (pOL!=NULL) { pRet=pRect; bInsTail=sal_False; }
768cdf0e10cSrcweir 		if (pOL==NULL) pOL=pRect->GetSubList();
769cdf0e10cSrcweir 		if (pOL!=NULL) { pRet=pRect; bInsRect=sal_False; }
770cdf0e10cSrcweir 		if (pOL==NULL) {
771cdf0e10cSrcweir 			SdrObjGroup* pGrp=new SdrObjGroup;
772cdf0e10cSrcweir 			pOL=pGrp->GetSubList();
773cdf0e10cSrcweir 			pRet=pGrp;
774cdf0e10cSrcweir 		}
775cdf0e10cSrcweir 		if (bInsRect) pOL->NbcInsertObject(pRect);
776cdf0e10cSrcweir 		if (bInsTail) pOL->NbcInsertObject(pTail,0);
777cdf0e10cSrcweir 	}
778cdf0e10cSrcweir 	return pRet;
779cdf0e10cSrcweir }
780cdf0e10cSrcweir 
781cdf0e10cSrcweir // #i32599#
782cdf0e10cSrcweir // Add own implementation for TRSetBaseGeometry to handle TailPos over changes.
783cdf0e10cSrcweir void SdrCaptionObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& /*rPolyPolygon*/)
784cdf0e10cSrcweir {
785cdf0e10cSrcweir 	// break up matrix
786cdf0e10cSrcweir 	basegfx::B2DTuple aScale;
787cdf0e10cSrcweir 	basegfx::B2DTuple aTranslate;
788cdf0e10cSrcweir 	double fRotate, fShearX;
789cdf0e10cSrcweir 	rMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
790cdf0e10cSrcweir 
791cdf0e10cSrcweir 	// #i75086# Old DrawingLayer (GeoStat and geometry) does not support holding negative scalings
792cdf0e10cSrcweir 	// in X and Y which equal a 180 degree rotation. Recognize it and react accordingly
793cdf0e10cSrcweir 	if(basegfx::fTools::less(aScale.getX(), 0.0) && basegfx::fTools::less(aScale.getY(), 0.0))
794cdf0e10cSrcweir 	{
795cdf0e10cSrcweir 		aScale.setX(fabs(aScale.getX()));
796cdf0e10cSrcweir 		aScale.setY(fabs(aScale.getY()));
797cdf0e10cSrcweir 		fRotate = fmod(fRotate + F_PI, F_2PI);
798cdf0e10cSrcweir 	}
799cdf0e10cSrcweir 
800cdf0e10cSrcweir 	// force metric to pool metric
801cdf0e10cSrcweir 	SfxMapUnit eMapUnit = pModel->GetItemPool().GetMetric(0);
802cdf0e10cSrcweir 	if(eMapUnit != SFX_MAPUNIT_100TH_MM)
803cdf0e10cSrcweir 	{
804cdf0e10cSrcweir 		switch(eMapUnit)
805cdf0e10cSrcweir 		{
806cdf0e10cSrcweir 			case SFX_MAPUNIT_TWIP :
807cdf0e10cSrcweir 			{
808cdf0e10cSrcweir 				// position
809cdf0e10cSrcweir 				aTranslate.setX(ImplMMToTwips(aTranslate.getX()));
810cdf0e10cSrcweir 				aTranslate.setY(ImplMMToTwips(aTranslate.getY()));
811cdf0e10cSrcweir 
812cdf0e10cSrcweir 				// size
813cdf0e10cSrcweir 				aScale.setX(ImplMMToTwips(aScale.getX()));
814cdf0e10cSrcweir 				aScale.setY(ImplMMToTwips(aScale.getY()));
815cdf0e10cSrcweir 
816cdf0e10cSrcweir 				break;
817cdf0e10cSrcweir 			}
818cdf0e10cSrcweir 			default:
819cdf0e10cSrcweir 			{
820cdf0e10cSrcweir 				DBG_ERROR("TRSetBaseGeometry: Missing unit translation to PoolMetric!");
821cdf0e10cSrcweir 			}
822cdf0e10cSrcweir 		}
823cdf0e10cSrcweir 	}
824cdf0e10cSrcweir 
825cdf0e10cSrcweir 	// if anchor is used, make position relative to it
826cdf0e10cSrcweir 	if( pModel->IsWriter() )
827cdf0e10cSrcweir 	{
828cdf0e10cSrcweir 		if(GetAnchorPos().X() || GetAnchorPos().Y())
829cdf0e10cSrcweir 		{
830cdf0e10cSrcweir 			aTranslate += basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
831cdf0e10cSrcweir 		}
832cdf0e10cSrcweir 	}
833cdf0e10cSrcweir 
834cdf0e10cSrcweir 	// build BaseRect
835cdf0e10cSrcweir 	Point aPoint(FRound(aTranslate.getX()), FRound(aTranslate.getY()));
836cdf0e10cSrcweir 	Rectangle aBaseRect(aPoint, Size(FRound(aScale.getX()), FRound(aScale.getY())));
837cdf0e10cSrcweir 
838cdf0e10cSrcweir 	// set BaseRect, but rescue TailPos over this call
839cdf0e10cSrcweir 	const Point aTailPoint = GetTailPos();
840cdf0e10cSrcweir 	SetSnapRect(aBaseRect);
841cdf0e10cSrcweir 	SetTailPos(aTailPoint);
842cdf0e10cSrcweir 	ImpRecalcTail();
843cdf0e10cSrcweir }
844cdf0e10cSrcweir 
845cdf0e10cSrcweir // geometry access
846cdf0e10cSrcweir basegfx::B2DPolygon SdrCaptionObj::getTailPolygon() const
847cdf0e10cSrcweir {
848cdf0e10cSrcweir 	return aTailPoly.getB2DPolygon();
849cdf0e10cSrcweir }
850cdf0e10cSrcweir 
851cdf0e10cSrcweir // eof
852