1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26 #include <svl/style.hxx>
27 #include <tools/bigint.hxx>
28 #include <svx/xlnwtit.hxx>
29 #include <svx/xlnedwit.hxx>
30 #include <svx/xlnstwit.hxx>
31 #include <svx/xlnstit.hxx>
32 #include <svx/xlnedit.hxx>
33 #include <svx/svdocirc.hxx>
34 #include <math.h>
35 #include <svx/xpool.hxx>
36 #include <svx/svdattr.hxx>
37 #include <svx/svdpool.hxx>
38 #include <svx/svdattrx.hxx>
39 #include <svx/svdtrans.hxx>
40 #include <svx/svdetc.hxx>
41 #include <svx/svddrag.hxx>
42 #include <svx/svdmodel.hxx>
43 #include <svx/svdpage.hxx>
44 #include <svx/svdopath.hxx> // fuer die Objektkonvertierung
45 #include <svx/svdview.hxx> // Zum Draggen (Ortho)
46 #include "svx/svdglob.hxx" // StringCache
47 #include "svx/svdstr.hrc" // Objektname
48 #include <editeng/eeitem.hxx>
49 #include "svdoimp.hxx"
50 #include <svx/sdr/properties/circleproperties.hxx>
51 #include <svx/sdr/contact/viewcontactofsdrcircobj.hxx>
52 #include <basegfx/point/b2dpoint.hxx>
53 #include <basegfx/polygon/b2dpolygon.hxx>
54 #include <basegfx/polygon/b2dpolygontools.hxx>
55 #include <basegfx/matrix/b2dhommatrix.hxx>
56 #include <basegfx/polygon/b2dpolygontools.hxx>
57 #include <basegfx/matrix/b2dhommatrixtools.hxx>
58
59 //////////////////////////////////////////////////////////////////////////////
60
GetWinkPnt(const Rectangle & rR,long nWink)61 Point GetWinkPnt(const Rectangle& rR, long nWink)
62 {
63 Point aCenter(rR.Center());
64 long nWdt=rR.Right()-rR.Left();
65 long nHgt=rR.Bottom()-rR.Top();
66 long nMaxRad=((nWdt>nHgt ? nWdt : nHgt)+1) /2;
67 double a;
68 a=nWink*nPi180;
69 Point aRetval(Round(cos(a)*nMaxRad),-Round(sin(a)*nMaxRad));
70 if (nWdt==0) aRetval.X()=0;
71 if (nHgt==0) aRetval.Y()=0;
72 if (nWdt!=nHgt) {
73 if (nWdt>nHgt) {
74 if (nWdt!=0) {
75 // eventuelle Ueberlaeufe bei sehr grossen Objekten abfangen (Bug 23384)
76 if (Abs(nHgt)>32767 || Abs(aRetval.Y())>32767) {
77 aRetval.Y()=BigMulDiv(aRetval.Y(),nHgt,nWdt);
78 } else {
79 aRetval.Y()=aRetval.Y()*nHgt/nWdt;
80 }
81 }
82 } else {
83 if (nHgt!=0) {
84 // eventuelle Ueberlaeufe bei sehr grossen Objekten abfangen (Bug 23384)
85 if (Abs(nWdt)>32767 || Abs(aRetval.X())>32767) {
86 aRetval.X()=BigMulDiv(aRetval.X(),nWdt,nHgt);
87 } else {
88 aRetval.X()=aRetval.X()*nWdt/nHgt;
89 }
90 }
91 }
92 }
93 aRetval+=aCenter;
94 return aRetval;
95 }
96
97 //////////////////////////////////////////////////////////////////////////////
98 // BaseProperties section
99
CreateObjectSpecificProperties()100 sdr::properties::BaseProperties* SdrCircObj::CreateObjectSpecificProperties()
101 {
102 return new sdr::properties::CircleProperties(*this);
103 }
104
105 //////////////////////////////////////////////////////////////////////////////
106 // DrawContact section
107
CreateObjectSpecificViewContact()108 sdr::contact::ViewContact* SdrCircObj::CreateObjectSpecificViewContact()
109 {
110 return new sdr::contact::ViewContactOfSdrCircObj(*this);
111 }
112
113 //////////////////////////////////////////////////////////////////////////////
114
115 TYPEINIT1(SdrCircObj,SdrRectObj);
116
SdrCircObj(SdrObjKind eNewKind)117 SdrCircObj::SdrCircObj(SdrObjKind eNewKind)
118 {
119 nStartWink=0;
120 nEndWink=36000;
121 meCircleKind=eNewKind;
122 bClosedObj=eNewKind!=OBJ_CARC;
123 }
124
SdrCircObj(SdrObjKind eNewKind,const Rectangle & rRect)125 SdrCircObj::SdrCircObj(SdrObjKind eNewKind, const Rectangle& rRect):
126 SdrRectObj(rRect)
127 {
128 nStartWink=0;
129 nEndWink=36000;
130 meCircleKind=eNewKind;
131 bClosedObj=eNewKind!=OBJ_CARC;
132 }
133
SdrCircObj(SdrObjKind eNewKind,const Rectangle & rRect,long nNewStartWink,long nNewEndWink)134 SdrCircObj::SdrCircObj(SdrObjKind eNewKind, const Rectangle& rRect, long nNewStartWink, long nNewEndWink):
135 SdrRectObj(rRect)
136 {
137 long nWinkDif=nNewEndWink-nNewStartWink;
138 nStartWink=NormAngle360(nNewStartWink);
139 nEndWink=NormAngle360(nNewEndWink);
140 if (nWinkDif==36000) nEndWink+=nWinkDif; // Vollkreis
141 meCircleKind=eNewKind;
142 bClosedObj=eNewKind!=OBJ_CARC;
143 }
144
~SdrCircObj()145 SdrCircObj::~SdrCircObj()
146 {
147 }
148
TakeObjInfo(SdrObjTransformInfoRec & rInfo) const149 void SdrCircObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
150 {
151 FASTBOOL bCanConv=!HasText() || ImpCanConvTextToCurve();
152 rInfo.bEdgeRadiusAllowed = sal_False;
153 rInfo.bCanConvToPath=bCanConv;
154 rInfo.bCanConvToPoly=bCanConv;
155 rInfo.bCanConvToContour = !IsFontwork() && (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
156 }
157
GetObjIdentifier() const158 sal_uInt16 SdrCircObj::GetObjIdentifier() const
159 {
160 return sal_uInt16(meCircleKind);
161 }
162
PaintNeedsXPolyCirc() const163 FASTBOOL SdrCircObj::PaintNeedsXPolyCirc() const
164 {
165 // XPoly ist notwendig fuer alle gedrehten Ellipsenobjekte,
166 // fuer alle Kreis- und Ellipsenabschnitte
167 // und wenn nicht WIN dann (erstmal) auch fuer Kreis-/Ellipsenausschnitte
168 // und Kreis-/Ellipsenboegen (wg. Genauigkeit)
169 FASTBOOL bNeed=aGeo.nDrehWink!=0 || aGeo.nShearWink!=0 || meCircleKind==OBJ_CCUT;
170 // Wenn nicht Win, dann fuer alle ausser Vollkreis (erstmal!!!)
171 if (meCircleKind!=OBJ_CIRC) bNeed=sal_True;
172
173 const SfxItemSet& rSet = GetObjectItemSet();
174 if(!bNeed)
175 {
176 // XPoly ist notwendig fuer alles was nicht LineSolid oder LineNone ist
177 XLineStyle eLine = ((XLineStyleItem&)(rSet.Get(XATTR_LINESTYLE))).GetValue();
178 bNeed = eLine != XLINE_NONE && eLine != XLINE_SOLID;
179
180 // XPoly ist notwendig fuer dicke Linien
181 if(!bNeed && eLine != XLINE_NONE)
182 bNeed = ((XLineWidthItem&)(rSet.Get(XATTR_LINEWIDTH))).GetValue() != 0;
183
184 // XPoly ist notwendig fuer Kreisboegen mit Linienenden
185 if(!bNeed && meCircleKind == OBJ_CARC)
186 {
187 // Linienanfang ist da, wenn StartPolygon und StartWidth!=0
188 bNeed=((XLineStartItem&)(rSet.Get(XATTR_LINESTART))).GetLineStartValue().count() != 0L &&
189 ((XLineStartWidthItem&)(rSet.Get(XATTR_LINESTARTWIDTH))).GetValue() != 0;
190
191 if(!bNeed)
192 {
193 // Linienende ist da, wenn EndPolygon und EndWidth!=0
194 bNeed = ((XLineEndItem&)(rSet.Get(XATTR_LINEEND))).GetLineEndValue().count() != 0L &&
195 ((XLineEndWidthItem&)(rSet.Get(XATTR_LINEENDWIDTH))).GetValue() != 0;
196 }
197 }
198 }
199
200 // XPoly ist notwendig, wenn Fill !=None und !=Solid
201 if(!bNeed && meCircleKind != OBJ_CARC)
202 {
203 XFillStyle eFill=((XFillStyleItem&)(rSet.Get(XATTR_FILLSTYLE))).GetValue();
204 bNeed = eFill != XFILL_NONE && eFill != XFILL_SOLID;
205 }
206
207 if(!bNeed && meCircleKind != OBJ_CIRC && nStartWink == nEndWink)
208 bNeed=sal_True; // Weil sonst Vollkreis gemalt wird
209
210 return bNeed;
211 }
212
ImpCalcXPolyCirc(const SdrObjKind eCicrleKind,const Rectangle & rRect1,long nStart,long nEnd) const213 basegfx::B2DPolygon SdrCircObj::ImpCalcXPolyCirc(const SdrObjKind eCicrleKind, const Rectangle& rRect1, long nStart, long nEnd) const
214 {
215 const basegfx::B2DRange aRange(rRect1.Left(), rRect1.Top(), rRect1.Right(), rRect1.Bottom());
216 basegfx::B2DPolygon aCircPolygon;
217
218 if(OBJ_CIRC == eCicrleKind)
219 {
220 // create full circle. Do not use createPolygonFromEllipse; it's necessary
221 // to get the start point to the bottom of the circle to keep compatible to
222 // old geometry creation
223 aCircPolygon = basegfx::tools::createPolygonFromUnitCircle(1);
224
225 // needs own scaling and translation from unit circle to target size (same as
226 // would be in createPolygonFromEllipse)
227 const basegfx::B2DPoint aCenter(aRange.getCenter());
228 const basegfx::B2DHomMatrix aMatrix(basegfx::tools::createScaleTranslateB2DHomMatrix(
229 aRange.getWidth() / 2.0, aRange.getHeight() / 2.0,
230 aCenter.getX(), aCenter.getY()));
231 aCircPolygon.transform(aMatrix);
232 }
233 else
234 {
235 // mirror start, end for geometry creation since model coordinate system is mirrored in Y
236 // #i111715# increase numerical correctness by first dividing and not using F_PI1800
237 const double fStart((((36000 - nEnd) % 36000) / 18000.0) * F_PI);
238 const double fEnd((((36000 - nStart) % 36000) / 18000.0) * F_PI);
239
240 // create circle segment. This is not closed by default
241 aCircPolygon = basegfx::tools::createPolygonFromEllipseSegment(
242 aRange.getCenter(), aRange.getWidth() / 2.0, aRange.getHeight() / 2.0,
243 fStart, fEnd);
244
245 // check closing states
246 const bool bCloseSegment(OBJ_CARC != eCicrleKind);
247 const bool bCloseUsingCenter(OBJ_SECT == eCicrleKind);
248
249 if(bCloseSegment)
250 {
251 if(bCloseUsingCenter)
252 {
253 // add center point at start (for historical reasons)
254 basegfx::B2DPolygon aSector;
255 aSector.append(aRange.getCenter());
256 aSector.append(aCircPolygon);
257 aCircPolygon = aSector;
258 }
259
260 // close
261 aCircPolygon.setClosed(true);
262 }
263 }
264
265 // #i76950#
266 if(aGeo.nShearWink || aGeo.nDrehWink)
267 {
268 // translate top left to (0,0)
269 const basegfx::B2DPoint aTopLeft(aRange.getMinimum());
270 basegfx::B2DHomMatrix aMatrix(basegfx::tools::createTranslateB2DHomMatrix(
271 -aTopLeft.getX(), -aTopLeft.getY()));
272
273 // shear, rotate and back to top left (if needed)
274 aMatrix = basegfx::tools::createShearXRotateTranslateB2DHomMatrix(
275 aGeo.nShearWink ? tan((36000 - aGeo.nShearWink) * F_PI18000) : 0.0,
276 aGeo.nDrehWink ? (36000 - aGeo.nDrehWink) * F_PI18000 : 0.0,
277 aTopLeft) * aMatrix;
278
279 // apply transformation
280 aCircPolygon.transform(aMatrix);
281 }
282
283 return aCircPolygon;
284 }
285
RecalcXPoly()286 void SdrCircObj::RecalcXPoly()
287 {
288 const basegfx::B2DPolygon aPolyCirc(ImpCalcXPolyCirc(meCircleKind, aRect, nStartWink, nEndWink));
289 mpXPoly = new XPolygon(aPolyCirc);
290 }
291
TakeObjNameSingul(XubString & rName) const292 void SdrCircObj::TakeObjNameSingul(XubString& rName) const
293 {
294 sal_uInt16 nID=STR_ObjNameSingulCIRC;
295 if (aRect.GetWidth()==aRect.GetHeight() && aGeo.nShearWink==0) {
296 switch (meCircleKind) {
297 case OBJ_CIRC: nID=STR_ObjNameSingulCIRC; break;
298 case OBJ_SECT: nID=STR_ObjNameSingulSECT; break;
299 case OBJ_CARC: nID=STR_ObjNameSingulCARC; break;
300 case OBJ_CCUT: nID=STR_ObjNameSingulCCUT; break;
301 default: break;
302 }
303 } else {
304 switch (meCircleKind) {
305 case OBJ_CIRC: nID=STR_ObjNameSingulCIRCE; break;
306 case OBJ_SECT: nID=STR_ObjNameSingulSECTE; break;
307 case OBJ_CARC: nID=STR_ObjNameSingulCARCE; break;
308 case OBJ_CCUT: nID=STR_ObjNameSingulCCUTE; break;
309 default: break;
310 }
311 }
312 rName=ImpGetResStr(nID);
313
314 String aName( GetName() );
315 if(aName.Len())
316 {
317 rName += sal_Unicode(' ');
318 rName += sal_Unicode('\'');
319 rName += aName;
320 rName += sal_Unicode('\'');
321 }
322 }
323
TakeObjNamePlural(XubString & rName) const324 void SdrCircObj::TakeObjNamePlural(XubString& rName) const
325 {
326 sal_uInt16 nID=STR_ObjNamePluralCIRC;
327 if (aRect.GetWidth()==aRect.GetHeight() && aGeo.nShearWink==0) {
328 switch (meCircleKind) {
329 case OBJ_CIRC: nID=STR_ObjNamePluralCIRC; break;
330 case OBJ_SECT: nID=STR_ObjNamePluralSECT; break;
331 case OBJ_CARC: nID=STR_ObjNamePluralCARC; break;
332 case OBJ_CCUT: nID=STR_ObjNamePluralCCUT; break;
333 default: break;
334 }
335 } else {
336 switch (meCircleKind) {
337 case OBJ_CIRC: nID=STR_ObjNamePluralCIRCE; break;
338 case OBJ_SECT: nID=STR_ObjNamePluralSECTE; break;
339 case OBJ_CARC: nID=STR_ObjNamePluralCARCE; break;
340 case OBJ_CCUT: nID=STR_ObjNamePluralCCUTE; break;
341 default: break;
342 }
343 }
344 rName=ImpGetResStr(nID);
345 }
346
operator =(const SdrObject & rObj)347 void SdrCircObj::operator=(const SdrObject& rObj)
348 {
349 SdrRectObj::operator=(rObj);
350
351 nStartWink = ((SdrCircObj&)rObj).nStartWink;
352 nEndWink = ((SdrCircObj&)rObj).nEndWink;
353 }
354
TakeXorPoly() const355 basegfx::B2DPolyPolygon SdrCircObj::TakeXorPoly() const
356 {
357 const basegfx::B2DPolygon aCircPolygon(ImpCalcXPolyCirc(meCircleKind, aRect, nStartWink, nEndWink));
358 return basegfx::B2DPolyPolygon(aCircPolygon);
359 }
360
361 struct ImpCircUser : public SdrDragStatUserData
362 {
363 Rectangle aR;
364 Point aCenter;
365 Point aRadius;
366 Point aP1;
367 Point aP2;
368 long nMaxRad;
369 long nHgt;
370 long nWdt;
371 long nStart;
372 long nEnd;
373 long nWink;
374 FASTBOOL bRight; // noch nicht implementiert
375
376 public:
ImpCircUserImpCircUser377 ImpCircUser()
378 : nMaxRad(0),
379 nHgt(0),
380 nWdt(0),
381 nStart(0),
382 nEnd(0),
383 bRight(sal_False)
384 {}
385 void SetCreateParams(SdrDragStat& rStat);
386 };
387
GetHdlCount() const388 sal_uInt32 SdrCircObj::GetHdlCount() const
389 {
390 if(OBJ_CIRC != meCircleKind)
391 {
392 return 10L;
393 }
394 else
395 {
396 return 8L;
397 }
398 }
399
GetHdl(sal_uInt32 nHdlNum) const400 SdrHdl* SdrCircObj::GetHdl(sal_uInt32 nHdlNum) const
401 {
402 if (meCircleKind==OBJ_CIRC)
403 {
404 nHdlNum += 2L;
405 }
406
407 SdrHdl* pH = NULL;
408 Point aPnt;
409 SdrHdlKind eLocalKind(HDL_MOVE);
410 sal_uInt32 nPNum(0);
411
412 switch (nHdlNum)
413 {
414 case 0:
415 aPnt = GetWinkPnt(aRect,nStartWink);
416 eLocalKind = HDL_CIRC;
417 nPNum = 1;
418 break;
419 case 1:
420 aPnt = GetWinkPnt(aRect,nEndWink);
421 eLocalKind = HDL_CIRC;
422 nPNum = 2L;
423 break;
424 case 2:
425 aPnt = aRect.TopLeft();
426 eLocalKind = HDL_UPLFT;
427 break;
428 case 3:
429 aPnt = aRect.TopCenter();
430 eLocalKind = HDL_UPPER;
431 break;
432 case 4:
433 aPnt = aRect.TopRight();
434 eLocalKind = HDL_UPRGT;
435 break;
436 case 5:
437 aPnt = aRect.LeftCenter();
438 eLocalKind = HDL_LEFT;
439 break;
440 case 6:
441 aPnt = aRect.RightCenter();
442 eLocalKind = HDL_RIGHT;
443 break;
444 case 7:
445 aPnt = aRect.BottomLeft();
446 eLocalKind = HDL_LWLFT;
447 break;
448 case 8:
449 aPnt = aRect.BottomCenter();
450 eLocalKind = HDL_LOWER;
451 break;
452 case 9:
453 aPnt = aRect.BottomRight();
454 eLocalKind = HDL_LWRGT;
455 break;
456 }
457
458 if (aGeo.nShearWink)
459 {
460 ShearPoint(aPnt,aRect.TopLeft(),aGeo.nTan);
461 }
462
463 if (aGeo.nDrehWink)
464 {
465 RotatePoint(aPnt,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
466 }
467
468 if (eLocalKind != HDL_MOVE)
469 {
470 pH = new SdrHdl(aPnt,eLocalKind);
471 pH->SetPointNum(nPNum);
472 pH->SetObj((SdrObject*)this);
473 pH->SetDrehWink(aGeo.nDrehWink);
474 }
475
476 return pH;
477 }
478
479 ////////////////////////////////////////////////////////////////////////////////////////////////////
480
hasSpecialDrag() const481 bool SdrCircObj::hasSpecialDrag() const
482 {
483 return true;
484 }
485
beginSpecialDrag(SdrDragStat & rDrag) const486 bool SdrCircObj::beginSpecialDrag(SdrDragStat& rDrag) const
487 {
488 const bool bWink(rDrag.GetHdl() && HDL_CIRC == rDrag.GetHdl()->GetKind());
489
490 if(bWink)
491 {
492 if(1 == rDrag.GetHdl()->GetPointNum() || 2 == rDrag.GetHdl()->GetPointNum())
493 {
494 rDrag.SetNoSnap(true);
495 }
496
497 return true;
498 }
499
500 return SdrTextObj::beginSpecialDrag(rDrag);
501 }
502
applySpecialDrag(SdrDragStat & rDrag)503 bool SdrCircObj::applySpecialDrag(SdrDragStat& rDrag)
504 {
505 const bool bWink(rDrag.GetHdl() && HDL_CIRC == rDrag.GetHdl()->GetKind());
506
507 if(bWink)
508 {
509 Point aPt(rDrag.GetNow());
510
511 if (aGeo.nDrehWink!=0)
512 RotatePoint(aPt,aRect.TopLeft(),-aGeo.nSin,aGeo.nCos);
513
514 if (aGeo.nShearWink!=0)
515 ShearPoint(aPt,aRect.TopLeft(),-aGeo.nTan);
516
517 aPt-=aRect.Center();
518
519 long nWdt=aRect.Right()-aRect.Left();
520 long nHgt=aRect.Bottom()-aRect.Top();
521
522 if(nWdt>=nHgt)
523 {
524 aPt.Y()=BigMulDiv(aPt.Y(),nWdt,nHgt);
525 }
526 else
527 {
528 aPt.X()=BigMulDiv(aPt.X(),nHgt,nWdt);
529 }
530
531 long nWink=NormAngle360(GetAngle(aPt));
532
533 if (rDrag.GetView() && rDrag.GetView()->IsAngleSnapEnabled())
534 {
535 long nSA=rDrag.GetView()->GetSnapAngle();
536
537 if (nSA!=0)
538 {
539 nWink+=nSA/2;
540 nWink/=nSA;
541 nWink*=nSA;
542 nWink=NormAngle360(nWink);
543 }
544 }
545
546 if(1 == rDrag.GetHdl()->GetPointNum())
547 {
548 nStartWink = nWink;
549 }
550 else if(2 == rDrag.GetHdl()->GetPointNum())
551 {
552 nEndWink = nWink;
553 }
554
555 SetRectsDirty();
556 SetXPolyDirty();
557 ImpSetCircInfoToAttr();
558 SetChanged();
559
560 return true;
561 }
562 else
563 {
564 return SdrTextObj::applySpecialDrag(rDrag);
565 }
566 }
567
getSpecialDragComment(const SdrDragStat & rDrag) const568 String SdrCircObj::getSpecialDragComment(const SdrDragStat& rDrag) const
569 {
570 const bool bCreateComment(rDrag.GetView() && this == rDrag.GetView()->GetCreateObj());
571
572 if(bCreateComment)
573 {
574 XubString aStr;
575 ImpTakeDescriptionStr(STR_ViewCreateObj, aStr);
576 const sal_uInt32 nPntAnz(rDrag.GetPointAnz());
577
578 if(OBJ_CIRC != meCircleKind && nPntAnz > 2)
579 {
580 ImpCircUser* pU = (ImpCircUser*)rDrag.GetUser();
581 sal_Int32 nWink;
582
583 aStr.AppendAscii(" (");
584
585 if(3 == nPntAnz)
586 {
587 nWink = pU->nStart;
588 }
589 else
590 {
591 nWink = pU->nEnd;
592 }
593
594 aStr += GetWinkStr(nWink,sal_False);
595 aStr += sal_Unicode(')');
596 }
597
598 return aStr;
599 }
600 else
601 {
602 const bool bWink(rDrag.GetHdl() && HDL_CIRC == rDrag.GetHdl()->GetKind());
603
604 if(bWink)
605 {
606 XubString aStr;
607 const sal_Int32 nWink(1 == rDrag.GetHdl()->GetPointNum() ? nStartWink : nEndWink);
608
609 ImpTakeDescriptionStr(STR_DragCircAngle, aStr);
610 aStr.AppendAscii(" (");
611 aStr += GetWinkStr(nWink,sal_False);
612 aStr += sal_Unicode(')');
613
614 return aStr;
615 }
616 else
617 {
618 return SdrTextObj::getSpecialDragComment(rDrag);
619 }
620 }
621 }
622
623 ////////////////////////////////////////////////////////////////////////////////////////////////////
624
SetCreateParams(SdrDragStat & rStat)625 void ImpCircUser::SetCreateParams(SdrDragStat& rStat)
626 {
627 rStat.TakeCreateRect(aR);
628 aR.Justify();
629 aCenter=aR.Center();
630 nWdt=aR.Right()-aR.Left();
631 nHgt=aR.Bottom()-aR.Top();
632 nMaxRad=((nWdt>nHgt ? nWdt : nHgt)+1) /2;
633 nStart=0;
634 nEnd=36000;
635 if (rStat.GetPointAnz()>2) {
636 Point aP(rStat.GetPoint(2)-aCenter);
637 if (nWdt==0) aP.X()=0;
638 if (nHgt==0) aP.Y()=0;
639 if (nWdt>=nHgt) {
640 if (nHgt!=0) aP.Y()=aP.Y()*nWdt/nHgt;
641 } else {
642 if (nWdt!=0) aP.X()=aP.X()*nHgt/nWdt;
643 }
644 nStart=NormAngle360(GetAngle(aP));
645 if (rStat.GetView()!=NULL && rStat.GetView()->IsAngleSnapEnabled()) {
646 long nSA=rStat.GetView()->GetSnapAngle();
647 if (nSA!=0) { // Winkelfang
648 nStart+=nSA/2;
649 nStart/=nSA;
650 nStart*=nSA;
651 nStart=NormAngle360(nStart);
652 }
653 }
654 aP1 = GetWinkPnt(aR,nStart);
655 nEnd=nStart;
656 aP2=aP1;
657 } else aP1=aCenter;
658 if (rStat.GetPointAnz()>3) {
659 Point aP(rStat.GetPoint(3)-aCenter);
660 if (nWdt>=nHgt) {
661 aP.Y()=BigMulDiv(aP.Y(),nWdt,nHgt);
662 } else {
663 aP.X()=BigMulDiv(aP.X(),nHgt,nWdt);
664 }
665 nEnd=NormAngle360(GetAngle(aP));
666 if (rStat.GetView()!=NULL && rStat.GetView()->IsAngleSnapEnabled()) {
667 long nSA=rStat.GetView()->GetSnapAngle();
668 if (nSA!=0) { // Winkelfang
669 nEnd+=nSA/2;
670 nEnd/=nSA;
671 nEnd*=nSA;
672 nEnd=NormAngle360(nEnd);
673 }
674 }
675 aP2 = GetWinkPnt(aR,nEnd);
676 } else aP2=aCenter;
677 }
678
ImpSetCreateParams(SdrDragStat & rStat) const679 void SdrCircObj::ImpSetCreateParams(SdrDragStat& rStat) const
680 {
681 ImpCircUser* pU=(ImpCircUser*)rStat.GetUser();
682 if (pU==NULL) {
683 pU=new ImpCircUser;
684 rStat.SetUser(pU);
685 }
686 pU->SetCreateParams(rStat);
687 }
688
BegCreate(SdrDragStat & rStat)689 FASTBOOL SdrCircObj::BegCreate(SdrDragStat& rStat)
690 {
691 rStat.SetOrtho4Possible();
692 Rectangle aRect1(rStat.GetStart(), rStat.GetNow());
693 aRect1.Justify();
694 rStat.SetActionRect(aRect1);
695 aRect = aRect1;
696 ImpSetCreateParams(rStat);
697 return sal_True;
698 }
699
MovCreate(SdrDragStat & rStat)700 FASTBOOL SdrCircObj::MovCreate(SdrDragStat& rStat)
701 {
702 ImpSetCreateParams(rStat);
703 ImpCircUser* pU=(ImpCircUser*)rStat.GetUser();
704 rStat.SetActionRect(pU->aR);
705 aRect=pU->aR; // fuer ObjName
706 ImpJustifyRect(aRect);
707 nStartWink=pU->nStart;
708 nEndWink=pU->nEnd;
709 SetBoundRectDirty();
710 bSnapRectDirty=sal_True;
711 SetXPolyDirty();
712
713 // #i103058# push current angle settings to ItemSet to
714 // allow FullDrag visualisation
715 if(rStat.GetPointAnz() >= 4)
716 {
717 ImpSetCircInfoToAttr();
718 }
719
720 return sal_True;
721 }
722
EndCreate(SdrDragStat & rStat,SdrCreateCmd eCmd)723 FASTBOOL SdrCircObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
724 {
725 ImpSetCreateParams(rStat);
726 ImpCircUser* pU=(ImpCircUser*)rStat.GetUser();
727 FASTBOOL bRet=sal_False;
728 if (eCmd==SDRCREATE_FORCEEND && rStat.GetPointAnz()<4) meCircleKind=OBJ_CIRC;
729 if (meCircleKind==OBJ_CIRC) {
730 bRet=rStat.GetPointAnz()>=2;
731 if (bRet) {
732 aRect=pU->aR;
733 ImpJustifyRect(aRect);
734 }
735 } else {
736 rStat.SetNoSnap(rStat.GetPointAnz()>=2);
737 rStat.SetOrtho4Possible(rStat.GetPointAnz()<2);
738 bRet=rStat.GetPointAnz()>=4;
739 if (bRet) {
740 aRect=pU->aR;
741 ImpJustifyRect(aRect);
742 nStartWink=pU->nStart;
743 nEndWink=pU->nEnd;
744 }
745 }
746 bClosedObj=meCircleKind!=OBJ_CARC;
747 SetRectsDirty();
748 SetXPolyDirty();
749 ImpSetCircInfoToAttr();
750 if (bRet) {
751 delete pU;
752 rStat.SetUser(NULL);
753 }
754 return bRet;
755 }
756
BrkCreate(SdrDragStat & rStat)757 void SdrCircObj::BrkCreate(SdrDragStat& rStat)
758 {
759 ImpCircUser* pU=(ImpCircUser*)rStat.GetUser();
760 delete pU;
761 rStat.SetUser(NULL);
762 }
763
BckCreate(SdrDragStat & rStat)764 FASTBOOL SdrCircObj::BckCreate(SdrDragStat& rStat)
765 {
766 rStat.SetNoSnap(rStat.GetPointAnz()>=3);
767 rStat.SetOrtho4Possible(rStat.GetPointAnz()<3);
768 return meCircleKind!=OBJ_CIRC;
769 }
770
TakeCreatePoly(const SdrDragStat & rDrag) const771 basegfx::B2DPolyPolygon SdrCircObj::TakeCreatePoly(const SdrDragStat& rDrag) const
772 {
773 ImpCircUser* pU = (ImpCircUser*)rDrag.GetUser();
774
775 if(rDrag.GetPointAnz() < 4L)
776 {
777 // force to OBJ_CIRC to get full visualisation
778 basegfx::B2DPolyPolygon aRetval(ImpCalcXPolyCirc(OBJ_CIRC, pU->aR, pU->nStart, pU->nEnd));
779
780 if(3L == rDrag.GetPointAnz())
781 {
782 // add edge to first point on ellipse
783 basegfx::B2DPolygon aNew;
784
785 aNew.append(basegfx::B2DPoint(pU->aCenter.X(), pU->aCenter.Y()));
786 aNew.append(basegfx::B2DPoint(pU->aP1.X(), pU->aP1.Y()));
787 aRetval.append(aNew);
788 }
789
790 return aRetval;
791 }
792 else
793 {
794 return basegfx::B2DPolyPolygon(ImpCalcXPolyCirc(meCircleKind, pU->aR, pU->nStart, pU->nEnd));
795 }
796 }
797
GetCreatePointer() const798 Pointer SdrCircObj::GetCreatePointer() const
799 {
800 switch (meCircleKind) {
801 case OBJ_CIRC: return Pointer(POINTER_DRAW_ELLIPSE);
802 case OBJ_SECT: return Pointer(POINTER_DRAW_PIE);
803 case OBJ_CARC: return Pointer(POINTER_DRAW_ARC);
804 case OBJ_CCUT: return Pointer(POINTER_DRAW_CIRCLECUT);
805 default: break;
806 } // switch
807 return Pointer(POINTER_CROSS);
808 }
809
NbcMove(const Size & aSiz)810 void SdrCircObj::NbcMove(const Size& aSiz)
811 {
812 MoveRect(aRect,aSiz);
813 MoveRect(aOutRect,aSiz);
814 MoveRect(maSnapRect,aSiz);
815 SetXPolyDirty();
816 SetRectsDirty(sal_True);
817 }
818
NbcResize(const Point & rRef,const Fraction & xFact,const Fraction & yFact)819 void SdrCircObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
820 {
821 long nWink0=aGeo.nDrehWink;
822 FASTBOOL bNoShearRota=(aGeo.nDrehWink==0 && aGeo.nShearWink==0);
823 SdrTextObj::NbcResize(rRef,xFact,yFact);
824 bNoShearRota|=(aGeo.nDrehWink==0 && aGeo.nShearWink==0);
825 if (meCircleKind!=OBJ_CIRC) {
826 FASTBOOL bXMirr=(xFact.GetNumerator()<0) != (xFact.GetDenominator()<0);
827 FASTBOOL bYMirr=(yFact.GetNumerator()<0) != (yFact.GetDenominator()<0);
828 if (bXMirr || bYMirr) {
829 // bei bXMirr!=bYMirr muessten eigentlich noch die beiden
830 // Linienende vertauscht werden. Das ist jedoch mal wieder
831 // schlecht (wg. zwangslaeufiger harter Formatierung).
832 // Alternativ koennte ein bMirrored-Flag eingefuehrt werden
833 // (Vielleicht ja mal grundsaetzlich, auch fuer gepiegelten Text, ...).
834 long nS0=nStartWink;
835 long nE0=nEndWink;
836 if (bNoShearRota) {
837 // Das RectObj spiegelt bei VMirror bereits durch durch 180deg Drehung.
838 if (! (bXMirr && bYMirr)) {
839 long nTmp=nS0;
840 nS0=18000-nE0;
841 nE0=18000-nTmp;
842 }
843 } else { // Spiegeln fuer verzerrte Ellipsen
844 if (bXMirr!=bYMirr) {
845 nS0+=nWink0;
846 nE0+=nWink0;
847 if (bXMirr) {
848 long nTmp=nS0;
849 nS0=18000-nE0;
850 nE0=18000-nTmp;
851 }
852 if (bYMirr) {
853 long nTmp=nS0;
854 nS0=-nE0;
855 nE0=-nTmp;
856 }
857 nS0-=aGeo.nDrehWink;
858 nE0-=aGeo.nDrehWink;
859 }
860 }
861 long nWinkDif=nE0-nS0;
862 nStartWink=NormAngle360(nS0);
863 nEndWink =NormAngle360(nE0);
864 if (nWinkDif==36000) nEndWink+=nWinkDif; // Vollkreis
865 }
866 }
867 SetXPolyDirty();
868 ImpSetCircInfoToAttr();
869 }
870
NbcShear(const Point & rRef,long nWink,double tn,FASTBOOL bVShear)871 void SdrCircObj::NbcShear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
872 {
873 SdrTextObj::NbcShear(rRef,nWink,tn,bVShear);
874 SetXPolyDirty();
875 ImpSetCircInfoToAttr();
876 }
877
NbcMirror(const Point & rRef1,const Point & rRef2)878 void SdrCircObj::NbcMirror(const Point& rRef1, const Point& rRef2)
879 {
880 //long nWink0=aGeo.nDrehWink;
881 FASTBOOL bFreeMirr=meCircleKind!=OBJ_CIRC;
882 Point aTmpPt1;
883 Point aTmpPt2;
884 if (bFreeMirr) { // bei freier Spiegelachse einige Vorbereitungen Treffen
885 Point aCenter(aRect.Center());
886 long nWdt=aRect.GetWidth()-1;
887 long nHgt=aRect.GetHeight()-1;
888 long nMaxRad=((nWdt>nHgt ? nWdt : nHgt)+1) /2;
889 double a;
890 // Startpunkt
891 a=nStartWink*nPi180;
892 aTmpPt1=Point(Round(cos(a)*nMaxRad),-Round(sin(a)*nMaxRad));
893 if (nWdt==0) aTmpPt1.X()=0;
894 if (nHgt==0) aTmpPt1.Y()=0;
895 aTmpPt1+=aCenter;
896 // Endpunkt
897 a=nEndWink*nPi180;
898 aTmpPt2=Point(Round(cos(a)*nMaxRad),-Round(sin(a)*nMaxRad));
899 if (nWdt==0) aTmpPt2.X()=0;
900 if (nHgt==0) aTmpPt2.Y()=0;
901 aTmpPt2+=aCenter;
902 if (aGeo.nDrehWink!=0) {
903 RotatePoint(aTmpPt1,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
904 RotatePoint(aTmpPt2,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
905 }
906 if (aGeo.nShearWink!=0) {
907 ShearPoint(aTmpPt1,aRect.TopLeft(),aGeo.nTan);
908 ShearPoint(aTmpPt2,aRect.TopLeft(),aGeo.nTan);
909 }
910 }
911 SdrTextObj::NbcMirror(rRef1,rRef2);
912 if (meCircleKind!=OBJ_CIRC) { // Anpassung von Start- und Endwinkel
913 MirrorPoint(aTmpPt1,rRef1,rRef2);
914 MirrorPoint(aTmpPt2,rRef1,rRef2);
915 // Unrotate:
916 if (aGeo.nDrehWink!=0) {
917 RotatePoint(aTmpPt1,aRect.TopLeft(),-aGeo.nSin,aGeo.nCos); // -sin fuer Umkehrung
918 RotatePoint(aTmpPt2,aRect.TopLeft(),-aGeo.nSin,aGeo.nCos); // -sin fuer Umkehrung
919 }
920 // Unshear:
921 if (aGeo.nShearWink!=0) {
922 ShearPoint(aTmpPt1,aRect.TopLeft(),-aGeo.nTan); // -tan fuer Umkehrung
923 ShearPoint(aTmpPt2,aRect.TopLeft(),-aGeo.nTan); // -tan fuer Umkehrung
924 }
925 Point aCenter(aRect.Center());
926 aTmpPt1-=aCenter;
927 aTmpPt2-=aCenter;
928 // Weil gespiegelt sind die Winkel nun auch noch vertauscht
929 nStartWink=GetAngle(aTmpPt2);
930 nEndWink =GetAngle(aTmpPt1);
931 long nWinkDif=nEndWink-nStartWink;
932 nStartWink=NormAngle360(nStartWink);
933 nEndWink =NormAngle360(nEndWink);
934 if (nWinkDif==36000) nEndWink+=nWinkDif; // Vollkreis
935 }
936 SetXPolyDirty();
937 ImpSetCircInfoToAttr();
938 }
939
NewGeoData() const940 SdrObjGeoData* SdrCircObj::NewGeoData() const
941 {
942 return new SdrCircObjGeoData;
943 }
944
SaveGeoData(SdrObjGeoData & rGeo) const945 void SdrCircObj::SaveGeoData(SdrObjGeoData& rGeo) const
946 {
947 SdrRectObj::SaveGeoData(rGeo);
948 SdrCircObjGeoData& rCGeo=(SdrCircObjGeoData&)rGeo;
949 rCGeo.nStartWink=nStartWink;
950 rCGeo.nEndWink =nEndWink;
951 }
952
RestGeoData(const SdrObjGeoData & rGeo)953 void SdrCircObj::RestGeoData(const SdrObjGeoData& rGeo)
954 {
955 SdrRectObj::RestGeoData(rGeo);
956 SdrCircObjGeoData& rCGeo=(SdrCircObjGeoData&)rGeo;
957 nStartWink=rCGeo.nStartWink;
958 nEndWink =rCGeo.nEndWink;
959 SetXPolyDirty();
960 ImpSetCircInfoToAttr();
961 }
962
Union(Rectangle & rR,const Point & rP)963 void Union(Rectangle& rR, const Point& rP)
964 {
965 if (rP.X()<rR.Left ()) rR.Left ()=rP.X();
966 if (rP.X()>rR.Right ()) rR.Right ()=rP.X();
967 if (rP.Y()<rR.Top ()) rR.Top ()=rP.Y();
968 if (rP.Y()>rR.Bottom()) rR.Bottom()=rP.Y();
969 }
970
TakeUnrotatedSnapRect(Rectangle & rRect) const971 void SdrCircObj::TakeUnrotatedSnapRect(Rectangle& rRect) const
972 {
973 rRect=aRect;
974 if (meCircleKind!=OBJ_CIRC) {
975 const Point aPntStart(GetWinkPnt(aRect,nStartWink));
976 const Point aPntEnd(GetWinkPnt(aRect,nEndWink));
977 long a=nStartWink;
978 long e=nEndWink;
979 rRect.Left ()=aRect.Right();
980 rRect.Right ()=aRect.Left();
981 rRect.Top ()=aRect.Bottom();
982 rRect.Bottom()=aRect.Top();
983 Union(rRect,aPntStart);
984 Union(rRect,aPntEnd);
985 if ((a<=18000 && e>=18000) || (a>e && (a<=18000 || e>=18000))) {
986 Union(rRect,aRect.LeftCenter());
987 }
988 if ((a<=27000 && e>=27000) || (a>e && (a<=27000 || e>=27000))) {
989 Union(rRect,aRect.BottomCenter());
990 }
991 if (a>e) {
992 Union(rRect,aRect.RightCenter());
993 }
994 if ((a<=9000 && e>=9000) || (a>e && (a<=9000 || e>=9000))) {
995 Union(rRect,aRect.TopCenter());
996 }
997 if (meCircleKind==OBJ_SECT) {
998 Union(rRect,aRect.Center());
999 }
1000 if (aGeo.nDrehWink!=0) {
1001 Point aDst(rRect.TopLeft());
1002 aDst-=aRect.TopLeft();
1003 Point aDst0(aDst);
1004 RotatePoint(aDst,Point(),aGeo.nSin,aGeo.nCos);
1005 aDst-=aDst0;
1006 rRect.Move(aDst.X(),aDst.Y());
1007 }
1008 }
1009 if (aGeo.nShearWink!=0) {
1010 long nDst=Round((rRect.Bottom()-rRect.Top())*aGeo.nTan);
1011 if (aGeo.nShearWink>0) {
1012 Point aRef(rRect.TopLeft());
1013 rRect.Left()-=nDst;
1014 Point aTmpPt(rRect.TopLeft());
1015 RotatePoint(aTmpPt,aRef,aGeo.nSin,aGeo.nCos);
1016 aTmpPt-=rRect.TopLeft();
1017 rRect.Move(aTmpPt.X(),aTmpPt.Y());
1018 } else {
1019 rRect.Right()-=nDst;
1020 }
1021 }
1022 }
1023
RecalcSnapRect()1024 void SdrCircObj::RecalcSnapRect()
1025 {
1026 if (PaintNeedsXPolyCirc()) {
1027 maSnapRect=GetXPoly().GetBoundRect();
1028 } else {
1029 TakeUnrotatedSnapRect(maSnapRect);
1030 }
1031 }
1032
NbcSetSnapRect(const Rectangle & rRect)1033 void SdrCircObj::NbcSetSnapRect(const Rectangle& rRect)
1034 {
1035 if (aGeo.nDrehWink!=0 || aGeo.nShearWink!=0 || meCircleKind!=OBJ_CIRC) {
1036 Rectangle aSR0(GetSnapRect());
1037 long nWdt0=aSR0.Right()-aSR0.Left();
1038 long nHgt0=aSR0.Bottom()-aSR0.Top();
1039 long nWdt1=rRect.Right()-rRect.Left();
1040 long nHgt1=rRect.Bottom()-rRect.Top();
1041 NbcResize(maSnapRect.TopLeft(),Fraction(nWdt1,nWdt0),Fraction(nHgt1,nHgt0));
1042 NbcMove(Size(rRect.Left()-aSR0.Left(),rRect.Top()-aSR0.Top()));
1043 } else {
1044 aRect=rRect;
1045 ImpJustifyRect(aRect);
1046 }
1047 SetRectsDirty();
1048 SetXPolyDirty();
1049 ImpSetCircInfoToAttr();
1050 }
1051
GetSnapPointCount() const1052 sal_uInt32 SdrCircObj::GetSnapPointCount() const
1053 {
1054 if (meCircleKind==OBJ_CIRC) {
1055 return 1L;
1056 } else {
1057 return 3L;
1058 }
1059 }
1060
GetSnapPoint(sal_uInt32 i) const1061 Point SdrCircObj::GetSnapPoint(sal_uInt32 i) const
1062 {
1063 switch (i) {
1064 case 1 : return GetWinkPnt(aRect,nStartWink);
1065 case 2 : return GetWinkPnt(aRect,nEndWink);
1066 default: return aRect.Center();
1067 }
1068 }
1069
Notify(SfxBroadcaster & rBC,const SfxHint & rHint)1070 void __EXPORT SdrCircObj::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
1071 {
1072 SetXPolyDirty();
1073 SdrRectObj::Notify(rBC,rHint);
1074 ImpSetAttrToCircInfo();
1075 }
1076
1077 ////////////////////////////////////////////////////////////////////////////////////////////////////
1078
ImpSetAttrToCircInfo()1079 void SdrCircObj::ImpSetAttrToCircInfo()
1080 {
1081 const SfxItemSet& rSet = GetObjectItemSet();
1082 SdrCircKind eNewKindA = ((SdrCircKindItem&)rSet.Get(SDRATTR_CIRCKIND)).GetValue();
1083 SdrObjKind eNewKind = meCircleKind;
1084
1085 if(eNewKindA == SDRCIRC_FULL)
1086 eNewKind = OBJ_CIRC;
1087 else if(eNewKindA == SDRCIRC_SECT)
1088 eNewKind = OBJ_SECT;
1089 else if(eNewKindA == SDRCIRC_ARC)
1090 eNewKind = OBJ_CARC;
1091 else if(eNewKindA == SDRCIRC_CUT)
1092 eNewKind = OBJ_CCUT;
1093
1094 sal_Int32 nNewStart = ((SdrCircStartAngleItem&)rSet.Get(SDRATTR_CIRCSTARTANGLE)).GetValue();
1095 sal_Int32 nNewEnd = ((SdrCircEndAngleItem&)rSet.Get(SDRATTR_CIRCENDANGLE)).GetValue();
1096
1097 sal_Bool bKindChg = meCircleKind != eNewKind;
1098 sal_Bool bWinkChg = nNewStart != nStartWink || nNewEnd != nEndWink;
1099
1100 if(bKindChg || bWinkChg)
1101 {
1102 meCircleKind = eNewKind;
1103 nStartWink = nNewStart;
1104 nEndWink = nNewEnd;
1105
1106 if(bKindChg || (meCircleKind != OBJ_CIRC && bWinkChg))
1107 {
1108 SetXPolyDirty();
1109 SetRectsDirty();
1110 }
1111 }
1112 }
1113
ImpSetCircInfoToAttr()1114 void SdrCircObj::ImpSetCircInfoToAttr()
1115 {
1116 SdrCircKind eNewKindA = SDRCIRC_FULL;
1117 const SfxItemSet& rSet = GetObjectItemSet();
1118
1119 if(meCircleKind == OBJ_SECT)
1120 eNewKindA = SDRCIRC_SECT;
1121 else if(meCircleKind == OBJ_CARC)
1122 eNewKindA = SDRCIRC_ARC;
1123 else if(meCircleKind == OBJ_CCUT)
1124 eNewKindA = SDRCIRC_CUT;
1125
1126 SdrCircKind eOldKindA = ((SdrCircKindItem&)rSet.Get(SDRATTR_CIRCKIND)).GetValue();
1127 sal_Int32 nOldStartWink = ((SdrCircStartAngleItem&)rSet.Get(SDRATTR_CIRCSTARTANGLE)).GetValue();
1128 sal_Int32 nOldEndWink = ((SdrCircEndAngleItem&)rSet.Get(SDRATTR_CIRCENDANGLE)).GetValue();
1129
1130 if(eNewKindA != eOldKindA || nStartWink != nOldStartWink || nEndWink != nOldEndWink)
1131 {
1132 // #81921# since SetItem() implicitly calls ImpSetAttrToCircInfo()
1133 // setting the item directly is necessary here.
1134 if(eNewKindA != eOldKindA)
1135 {
1136 GetProperties().SetObjectItemDirect(SdrCircKindItem(eNewKindA));
1137 }
1138
1139 if(nStartWink != nOldStartWink)
1140 {
1141 GetProperties().SetObjectItemDirect(SdrCircStartAngleItem(nStartWink));
1142 }
1143
1144 if(nEndWink != nOldEndWink)
1145 {
1146 GetProperties().SetObjectItemDirect(SdrCircEndAngleItem(nEndWink));
1147 }
1148
1149 SetXPolyDirty();
1150 ImpSetAttrToCircInfo();
1151 }
1152 }
1153
DoConvertToPolyObj(sal_Bool bBezier,bool bAddText) const1154 SdrObject* SdrCircObj::DoConvertToPolyObj(sal_Bool bBezier, bool bAddText) const
1155 {
1156 const sal_Bool bFill(OBJ_CARC == meCircleKind ? sal_False : sal_True);
1157 const basegfx::B2DPolygon aCircPolygon(ImpCalcXPolyCirc(meCircleKind, aRect, nStartWink, nEndWink));
1158 SdrObject* pRet = ImpConvertMakeObj(basegfx::B2DPolyPolygon(aCircPolygon), bFill, bBezier);
1159
1160 if(bAddText)
1161 {
1162 pRet = ImpConvertAddText(pRet, bBezier);
1163 }
1164
1165 return pRet;
1166 }
1167
1168 //////////////////////////////////////////////////////////////////////////////
1169 // eof
1170