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