LibreOffice Module svx (master)  1
svdocirc.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
25 #include <math.h>
26 
27 #include <svx/dialmgr.hxx>
28 #include <svx/strings.hrc>
29 
32 #include <svx/svddrag.hxx>
33 #include <svx/svdmodel.hxx>
34 #include <svx/svdocirc.hxx>
35 #include <svx/svdopath.hxx>
36 #include <svx/svdtrans.hxx>
37 #include <svx/svdview.hxx>
38 #include <svx/sxciaitm.hxx>
39 #include <sxcikitm.hxx>
40 #include <svx/xfillit0.hxx>
41 #include <svx/xlineit0.hxx>
42 #include <svx/xlnedit.hxx>
43 #include <svx/xlnedwit.hxx>
44 #include <svx/xlnstit.hxx>
45 #include <svx/xlnstwit.hxx>
46 #include <svx/xlnwtit.hxx>
47 #include <vcl/canvastools.hxx>
48 #include <vcl/ptrstyle.hxx>
49 
50 using namespace com::sun::star;
51 
52 static Point GetAnglePnt(const tools::Rectangle& rR, long nAngle)
53 {
54  Point aCenter(rR.Center());
55  long nWdt=rR.Right()-rR.Left();
56  long nHgt=rR.Bottom()-rR.Top();
57  long nMaxRad=(std::max(nWdt,nHgt)+1) /2;
58  double a;
59  a = nAngle * F_PI18000;
60  Point aRetval(FRound(cos(a)*nMaxRad),-FRound(sin(a)*nMaxRad));
61  if (nWdt==0) aRetval.setX(0 );
62  if (nHgt==0) aRetval.setY(0 );
63  if (nWdt!=nHgt) {
64  if (nWdt>nHgt) {
65  if (nWdt!=0) {
66  // stop possible overruns for very large objects
67  if (std::abs(nHgt)>32767 || std::abs(aRetval.Y())>32767) {
68  aRetval.setY(BigMulDiv(aRetval.Y(),nHgt,nWdt) );
69  } else {
70  aRetval.setY(aRetval.Y()*nHgt/nWdt );
71  }
72  }
73  } else {
74  if (nHgt!=0) {
75  // stop possible overruns for very large objects
76  if (std::abs(nWdt)>32767 || std::abs(aRetval.X())>32767) {
77  aRetval.setX(BigMulDiv(aRetval.X(),nWdt,nHgt) );
78  } else {
79  aRetval.setX(aRetval.X()*nWdt/nHgt );
80  }
81  }
82  }
83  }
84  aRetval+=aCenter;
85  return aRetval;
86 }
87 
88 
89 // BaseProperties section
90 
91 std::unique_ptr<sdr::properties::BaseProperties> SdrCircObj::CreateObjectSpecificProperties()
92 {
93  return std::make_unique<sdr::properties::CircleProperties>(*this);
94 }
95 
96 
97 // DrawContact section
98 
99 std::unique_ptr<sdr::contact::ViewContact> SdrCircObj::CreateObjectSpecificViewContact()
100 {
101  return std::make_unique<sdr::contact::ViewContactOfSdrCircObj>(*this);
102 }
103 
105 {
106  switch (eKind)
107  {
108  case OBJ_CIRC: return SdrCircKind::Full;
109  case OBJ_SECT: return SdrCircKind::Section;
110  case OBJ_CARC: return SdrCircKind::Arc;
111  case OBJ_CCUT: return SdrCircKind::Cut;
112  default: assert(false);
113  }
114  return SdrCircKind::Full;
115 }
116 
118  SdrModel& rSdrModel,
119  SdrCircKind eNewKind)
120 : SdrRectObj(rSdrModel)
121 {
122  nStartAngle=0;
123  nEndAngle=36000;
124  meCircleKind=eNewKind;
125  bClosedObj=eNewKind!=SdrCircKind::Arc;
126 }
127 
129  SdrModel& rSdrModel,
130  SdrCircKind eNewKind,
131  const tools::Rectangle& rRect)
132 : SdrRectObj(rSdrModel, rRect)
133 {
134  nStartAngle=0;
135  nEndAngle=36000;
136  meCircleKind=eNewKind;
137  bClosedObj=eNewKind!=SdrCircKind::Arc;
138 }
139 
141  SdrModel& rSdrModel,
142  SdrCircKind eNewKind,
143  const tools::Rectangle& rRect,
144  long nNewStartWink,
145  long nNewEndWink)
146 : SdrRectObj(rSdrModel, rRect)
147 {
148  long nAngleDif=nNewEndWink-nNewStartWink;
149  nStartAngle=NormAngle36000(nNewStartWink);
150  nEndAngle=NormAngle36000(nNewEndWink);
151  if (nAngleDif==36000) nEndAngle+=nAngleDif; // full circle
152  meCircleKind=eNewKind;
153  bClosedObj=eNewKind!=SdrCircKind::Arc;
154 }
155 
157 {
158 }
159 
161 {
162  bool bCanConv=!HasText() || ImpCanConvTextToCurve();
163  rInfo.bEdgeRadiusAllowed = false;
164  rInfo.bCanConvToPath=bCanConv;
165  rInfo.bCanConvToPoly=bCanConv;
167 }
168 
170 {
171  switch (meCircleKind)
172  {
173  case SdrCircKind::Full: return OBJ_CIRC;
174  case SdrCircKind::Section: return OBJ_SECT;
175  case SdrCircKind::Cut: return OBJ_CCUT;
176  case SdrCircKind::Arc: return OBJ_CARC;
177  default: assert(false);
178  }
179  return OBJ_CIRC;
180 }
181 
183 {
184  // XPoly is necessary for all rotated ellipse objects, circle and
185  // ellipse segments.
186  // If not WIN, then (for now) also for circle/ellipse segments and circle/
187  // ellipse arcs (for precision)
189  // If not WIN, then for everything except full circle (for now!)
190  if (meCircleKind!=SdrCircKind::Full) bNeed = true;
191 
192  const SfxItemSet& rSet = GetObjectItemSet();
193  if(!bNeed)
194  {
195  // XPoly is necessary for everything that isn't LineSolid or LineNone
196  drawing::LineStyle eLine = rSet.Get(XATTR_LINESTYLE).GetValue();
197  bNeed = eLine != drawing::LineStyle_NONE && eLine != drawing::LineStyle_SOLID;
198 
199  // XPoly is necessary for thick lines
200  if(!bNeed && eLine != drawing::LineStyle_NONE)
201  bNeed = rSet.Get(XATTR_LINEWIDTH).GetValue() != 0;
202 
203  // XPoly is necessary for circle arcs with line ends
204  if(!bNeed && meCircleKind == SdrCircKind::Arc)
205  {
206  // start of the line is here if StartPolygon, StartWidth!=0
207  bNeed=rSet.Get(XATTR_LINESTART).GetLineStartValue().count() != 0 &&
208  rSet.Get(XATTR_LINESTARTWIDTH).GetValue() != 0;
209 
210  if(!bNeed)
211  {
212  // end of the line is here if EndPolygon, EndWidth!=0
213  bNeed = rSet.Get(XATTR_LINEEND).GetLineEndValue().count() != 0 &&
214  rSet.Get(XATTR_LINEENDWIDTH).GetValue() != 0;
215  }
216  }
217  }
218 
219  // XPoly is necessary if Fill !=None and !=Solid
220  if(!bNeed && meCircleKind != SdrCircKind::Arc)
221  {
222  drawing::FillStyle eFill=rSet.Get(XATTR_FILLSTYLE).GetValue();
223  bNeed = eFill != drawing::FillStyle_NONE && eFill != drawing::FillStyle_SOLID;
224  }
225 
226  if(!bNeed && meCircleKind != SdrCircKind::Full && nStartAngle == nEndAngle)
227  bNeed = true; // otherwise we're drawing a full circle
228 
229  return bNeed;
230 }
231 
232 basegfx::B2DPolygon SdrCircObj::ImpCalcXPolyCirc(const SdrCircKind eCicrleKind, const tools::Rectangle& rRect1, long nStart, long nEnd) const
233 {
235  basegfx::B2DPolygon aCircPolygon;
236 
237  if(SdrCircKind::Full == eCicrleKind)
238  {
239  // create full circle. Do not use createPolygonFromEllipse; it's necessary
240  // to get the start point to the bottom of the circle to keep compatible to
241  // old geometry creation
243 
244  // needs own scaling and translation from unit circle to target size (same as
245  // would be in createPolygonFromEllipse)
246  const basegfx::B2DPoint aCenter(aRange.getCenter());
248  aRange.getWidth() / 2.0, aRange.getHeight() / 2.0,
249  aCenter.getX(), aCenter.getY()));
250  aCircPolygon.transform(aMatrix);
251  }
252  else
253  {
254  // mirror start, end for geometry creation since model coordinate system is mirrored in Y
255  // #i111715# increase numerical correctness by first dividing and not using F_PI1800
256  const double fStart((((36000 - nEnd) % 36000) / 18000.0) * F_PI);
257  const double fEnd((((36000 - nStart) % 36000) / 18000.0) * F_PI);
258 
259  // create circle segment. This is not closed by default
261  aRange.getCenter(), aRange.getWidth() / 2.0, aRange.getHeight() / 2.0,
262  fStart, fEnd);
263 
264  // check closing states
265  const bool bCloseSegment(SdrCircKind::Arc != eCicrleKind);
266  const bool bCloseUsingCenter(SdrCircKind::Section == eCicrleKind);
267 
268  if(bCloseSegment)
269  {
270  if(bCloseUsingCenter)
271  {
272  // add center point at start (for historical reasons)
273  basegfx::B2DPolygon aSector;
274  aSector.append(aRange.getCenter());
275  aSector.append(aCircPolygon);
276  aCircPolygon = aSector;
277  }
278 
279  // close
280  aCircPolygon.setClosed(true);
281  }
282  }
283 
284  // #i76950#
286  {
287  // translate top left to (0,0)
288  const basegfx::B2DPoint aTopLeft(aRange.getMinimum());
290  -aTopLeft.getX(), -aTopLeft.getY()));
291 
292  // shear, rotate and back to top left (if needed)
294  aGeo.nShearAngle ? tan((36000 - aGeo.nShearAngle) * F_PI18000) : 0.0,
295  aGeo.nRotationAngle ? (36000 - aGeo.nRotationAngle) * F_PI18000 : 0.0,
296  aTopLeft) * aMatrix;
297 
298  // apply transformation
299  aCircPolygon.transform(aMatrix);
300  }
301 
302  return aCircPolygon;
303 }
304 
306 {
308  mpXPoly.reset( new XPolygon(aPolyCirc) );
309 }
310 
312 {
313  const char* pID=STR_ObjNameSingulCIRC;
314  if (maRect.GetWidth() == maRect.GetHeight() && aGeo.nShearAngle==0)
315  {
316  switch (meCircleKind) {
317  case SdrCircKind::Full: pID=STR_ObjNameSingulCIRC; break;
318  case SdrCircKind::Section: pID=STR_ObjNameSingulSECT; break;
319  case SdrCircKind::Arc: pID=STR_ObjNameSingulCARC; break;
320  case SdrCircKind::Cut: pID=STR_ObjNameSingulCCUT; break;
321  default: break;
322  }
323  } else {
324  switch (meCircleKind) {
325  case SdrCircKind::Full: pID=STR_ObjNameSingulCIRCE; break;
326  case SdrCircKind::Section: pID=STR_ObjNameSingulSECTE; break;
327  case SdrCircKind::Arc: pID=STR_ObjNameSingulCARCE; break;
328  case SdrCircKind::Cut: pID=STR_ObjNameSingulCCUTE; break;
329  default: break;
330  }
331  }
332  OUStringBuffer sName(SvxResId(pID));
333 
334  OUString aName(GetName());
335  if (!aName.isEmpty())
336  {
337  sName.append(' ');
338  sName.append('\'');
339  sName.append(aName);
340  sName.append('\'');
341  }
342  return sName.makeStringAndClear();
343 }
344 
346 {
347  const char* pID=STR_ObjNamePluralCIRC;
348  if (maRect.GetWidth() == maRect.GetHeight() && aGeo.nShearAngle==0)
349  {
350  switch (meCircleKind) {
351  case SdrCircKind::Full: pID=STR_ObjNamePluralCIRC; break;
352  case SdrCircKind::Section: pID=STR_ObjNamePluralSECT; break;
353  case SdrCircKind::Arc: pID=STR_ObjNamePluralCARC; break;
354  case SdrCircKind::Cut: pID=STR_ObjNamePluralCCUT; break;
355  default: break;
356  }
357  } else {
358  switch (meCircleKind) {
359  case SdrCircKind::Full: pID=STR_ObjNamePluralCIRCE; break;
360  case SdrCircKind::Section: pID=STR_ObjNamePluralSECTE; break;
361  case SdrCircKind::Arc: pID=STR_ObjNamePluralCARCE; break;
362  case SdrCircKind::Cut: pID=STR_ObjNamePluralCCUTE; break;
363  default: break;
364  }
365  }
366  return SvxResId(pID);
367 }
368 
370 {
371  return CloneHelper< SdrCircObj >(rTargetModel);
372 }
373 
375 {
376  if( this == &rObj )
377  return *this;
378  SdrRectObj::operator=(rObj);
379 
380  meCircleKind = rObj.meCircleKind;
381  nStartAngle = rObj.nStartAngle;
382  nEndAngle = rObj.nEndAngle;
383 
384  return *this;
385 }
386 
388 {
390  return basegfx::B2DPolyPolygon(aCircPolygon);
391 }
392 
393 namespace {
394 
395 struct ImpCircUser : public SdrDragStatUserData
396 {
397  tools::Rectangle aR;
398  Point aCenter;
399  Point aP1;
400  long nHgt;
401  long nWdt;
402  long nStart;
403  long nEnd;
404 
405 public:
406  ImpCircUser()
407  : nHgt(0),
408  nWdt(0),
409  nStart(0),
410  nEnd(0)
411  {}
412  void SetCreateParams(SdrDragStat const & rStat);
413 };
414 
415 }
416 
417 sal_uInt32 SdrCircObj::GetHdlCount() const
418 {
420  {
421  return 10;
422  }
423  else
424  {
425  return 8;
426  }
427 }
428 
430 {
431  for (sal_uInt32 nHdlNum=(SdrCircKind::Full==meCircleKind)?2:0; nHdlNum<=9; ++nHdlNum)
432  {
433  Point aPnt;
434  SdrHdlKind eLocalKind(SdrHdlKind::Move);
435  sal_uInt32 nPNum(0);
436 
437  switch (nHdlNum)
438  {
439  case 0:
441  eLocalKind = SdrHdlKind::Circle;
442  nPNum = 1;
443  break;
444  case 1:
445  aPnt = GetAnglePnt(maRect,nEndAngle);
446  eLocalKind = SdrHdlKind::Circle;
447  nPNum = 2;
448  break;
449  case 2:
450  aPnt = maRect.TopLeft();
451  eLocalKind = SdrHdlKind::UpperLeft;
452  break;
453  case 3:
454  aPnt = maRect.TopCenter();
455  eLocalKind = SdrHdlKind::Upper;
456  break;
457  case 4:
458  aPnt = maRect.TopRight();
459  eLocalKind = SdrHdlKind::UpperRight;
460  break;
461  case 5:
462  aPnt = maRect.LeftCenter();
463  eLocalKind = SdrHdlKind::Left;
464  break;
465  case 6:
466  aPnt = maRect.RightCenter();
467  eLocalKind = SdrHdlKind::Right;
468  break;
469  case 7:
470  aPnt = maRect.BottomLeft();
471  eLocalKind = SdrHdlKind::LowerLeft;
472  break;
473  case 8:
474  aPnt = maRect.BottomCenter();
475  eLocalKind = SdrHdlKind::Lower;
476  break;
477  case 9:
478  aPnt = maRect.BottomRight();
479  eLocalKind = SdrHdlKind::LowerRight;
480  break;
481  }
482 
483  if (aGeo.nShearAngle)
484  {
486  }
487 
488  if (aGeo.nRotationAngle)
489  {
491  }
492 
493  std::unique_ptr<SdrHdl> pH(new SdrHdl(aPnt,eLocalKind));
494  pH->SetPointNum(nPNum);
495  pH->SetObj(const_cast<SdrCircObj*>(this));
496  pH->SetRotationAngle(aGeo.nRotationAngle);
497  rHdlList.AddHdl(std::move(pH));
498  }
499 }
500 
501 
503 {
504  return true;
505 }
506 
508 {
509  const bool bAngle(rDrag.GetHdl() && SdrHdlKind::Circle == rDrag.GetHdl()->GetKind());
510 
511  if(bAngle)
512  {
513  if(1 == rDrag.GetHdl()->GetPointNum() || 2 == rDrag.GetHdl()->GetPointNum())
514  {
515  rDrag.SetNoSnap();
516  }
517 
518  return true;
519  }
520 
521  return SdrTextObj::beginSpecialDrag(rDrag);
522 }
523 
525 {
526  const bool bAngle(rDrag.GetHdl() && SdrHdlKind::Circle == rDrag.GetHdl()->GetKind());
527 
528  if(bAngle)
529  {
530  Point aPt(rDrag.GetNow());
531 
532  if (aGeo.nRotationAngle!=0)
534 
535  if (aGeo.nShearAngle!=0)
537 
538  aPt -= maRect.Center();
539 
540  long nWdt = maRect.Right() - maRect.Left();
541  long nHgt = maRect.Bottom() - maRect.Top();
542 
543  if(nWdt>=nHgt)
544  {
545  aPt.setY(BigMulDiv(aPt.Y(),nWdt,nHgt) );
546  }
547  else
548  {
549  aPt.setX(BigMulDiv(aPt.X(),nHgt,nWdt) );
550  }
551 
552  long nAngle=NormAngle36000(GetAngle(aPt));
553 
554  if (rDrag.GetView() && rDrag.GetView()->IsAngleSnapEnabled())
555  {
556  long nSA=rDrag.GetView()->GetSnapAngle();
557 
558  if (nSA!=0)
559  {
560  nAngle+=nSA/2;
561  nAngle/=nSA;
562  nAngle*=nSA;
563  nAngle=NormAngle36000(nAngle);
564  }
565  }
566 
567  if(1 == rDrag.GetHdl()->GetPointNum())
568  {
569  nStartAngle = nAngle;
570  }
571  else if(2 == rDrag.GetHdl()->GetPointNum())
572  {
573  nEndAngle = nAngle;
574  }
575 
576  SetRectsDirty();
577  SetXPolyDirty();
579  SetChanged();
580 
581  return true;
582  }
583  else
584  {
585  return SdrTextObj::applySpecialDrag(rDrag);
586  }
587 }
588 
589 OUString SdrCircObj::getSpecialDragComment(const SdrDragStat& rDrag) const
590 {
591  const bool bCreateComment(rDrag.GetView() && this == rDrag.GetView()->GetCreateObj());
592 
593  if(bCreateComment)
594  {
595  OUStringBuffer aBuf(ImpGetDescriptionStr(STR_ViewCreateObj));
596  const sal_uInt32 nPointCount(rDrag.GetPointCount());
597 
598  if(SdrCircKind::Full != meCircleKind && nPointCount > 2)
599  {
600  const ImpCircUser* pU = static_cast<const ImpCircUser*>(rDrag.GetUser());
601  sal_Int32 nAngle;
602 
603  aBuf.append(" (");
604 
605  if(3 == nPointCount)
606  {
607  nAngle = pU->nStart;
608  }
609  else
610  {
611  nAngle = pU->nEnd;
612  }
613 
614  aBuf.append(SdrModel::GetAngleString(nAngle));
615  aBuf.append(')');
616  }
617 
618  return aBuf.makeStringAndClear();
619  }
620  else
621  {
622  const bool bAngle(rDrag.GetHdl() && SdrHdlKind::Circle == rDrag.GetHdl()->GetKind());
623 
624  if(bAngle)
625  {
626  const sal_Int32 nAngle(1 == rDrag.GetHdl()->GetPointNum() ? nStartAngle : nEndAngle);
627 
628  OUStringBuffer aBuf(ImpGetDescriptionStr(STR_DragCircAngle));
629  aBuf.append(" (");
630  aBuf.append(SdrModel::GetAngleString(nAngle));
631  aBuf.append(')');
632 
633  return aBuf.makeStringAndClear();
634  }
635  else
636  {
637  return SdrTextObj::getSpecialDragComment(rDrag);
638  }
639  }
640 }
641 
642 
643 void ImpCircUser::SetCreateParams(SdrDragStat const & rStat)
644 {
645  rStat.TakeCreateRect(aR);
646  aR.Justify();
647  aCenter=aR.Center();
648  nWdt=aR.Right()-aR.Left();
649  nHgt=aR.Bottom()-aR.Top();
650  nStart=0;
651  nEnd=36000;
652  if (rStat.GetPointCount()>2) {
653  Point aP(rStat.GetPoint(2)-aCenter);
654  if (nWdt==0) aP.setX(0 );
655  if (nHgt==0) aP.setY(0 );
656  if (nWdt>=nHgt) {
657  if (nHgt!=0) aP.setY(aP.Y()*nWdt/nHgt );
658  } else {
659  if (nWdt!=0) aP.setX(aP.X()*nHgt/nWdt );
660  }
661  nStart=NormAngle36000(GetAngle(aP));
662  if (rStat.GetView()!=nullptr && rStat.GetView()->IsAngleSnapEnabled()) {
663  long nSA=rStat.GetView()->GetSnapAngle();
664  if (nSA!=0) { // angle snapping
665  nStart+=nSA/2;
666  nStart/=nSA;
667  nStart*=nSA;
668  nStart=NormAngle36000(nStart);
669  }
670  }
671  aP1 = GetAnglePnt(aR,nStart);
672  nEnd=nStart;
673  } else aP1=aCenter;
674  if (rStat.GetPointCount()>3) {
675  Point aP(rStat.GetPoint(3)-aCenter);
676  if (nWdt>=nHgt) {
677  aP.setY(BigMulDiv(aP.Y(),nWdt,nHgt) );
678  } else {
679  aP.setX(BigMulDiv(aP.X(),nHgt,nWdt) );
680  }
681  nEnd=NormAngle36000(GetAngle(aP));
682  if (rStat.GetView()!=nullptr && rStat.GetView()->IsAngleSnapEnabled()) {
683  long nSA=rStat.GetView()->GetSnapAngle();
684  if (nSA!=0) { // angle snapping
685  nEnd+=nSA/2;
686  nEnd/=nSA;
687  nEnd*=nSA;
688  nEnd=NormAngle36000(nEnd);
689  }
690  }
691  }
692 }
693 
695 {
696  ImpCircUser* pU=static_cast<ImpCircUser*>(rStat.GetUser());
697  if (pU==nullptr) {
698  pU=new ImpCircUser;
699  rStat.SetUser(std::unique_ptr<ImpCircUser>(pU));
700  }
701  pU->SetCreateParams(rStat);
702 }
703 
705 {
706  rStat.SetOrtho4Possible();
707  tools::Rectangle aRect1(rStat.GetStart(), rStat.GetNow());
708  aRect1.Justify();
709  rStat.SetActionRect(aRect1);
710  maRect = aRect1;
711  ImpSetCreateParams(rStat);
712  return true;
713 }
714 
716 {
717  ImpSetCreateParams(rStat);
718  ImpCircUser* pU=static_cast<ImpCircUser*>(rStat.GetUser());
719  rStat.SetActionRect(pU->aR);
720  maRect = pU->aR; // for ObjName
722  nStartAngle=pU->nStart;
723  nEndAngle=pU->nEnd;
725  bSnapRectDirty=true;
726  SetXPolyDirty();
727 
728  // #i103058# push current angle settings to ItemSet to
729  // allow FullDrag visualisation
730  if(rStat.GetPointCount() >= 4)
731  {
733  }
734 
735  return true;
736 }
737 
739 {
740  ImpSetCreateParams(rStat);
741  ImpCircUser* pU=static_cast<ImpCircUser*>(rStat.GetUser());
742  bool bRet = false;
745  bRet=rStat.GetPointCount()>=2;
746  if (bRet) {
747  maRect = pU->aR;
749  }
750  } else {
751  rStat.SetNoSnap(rStat.GetPointCount()>=2);
752  rStat.SetOrtho4Possible(rStat.GetPointCount()<2);
753  bRet=rStat.GetPointCount()>=4;
754  if (bRet) {
755  maRect = pU->aR;
757  nStartAngle=pU->nStart;
758  nEndAngle=pU->nEnd;
759  }
760  }
762  SetRectsDirty();
763  SetXPolyDirty();
765  if (bRet)
766  rStat.SetUser(nullptr);
767  return bRet;
768 }
769 
771 {
772  rStat.SetUser(nullptr);
773 }
774 
776 {
777  rStat.SetNoSnap(rStat.GetPointCount()>=3);
778  rStat.SetOrtho4Possible(rStat.GetPointCount()<3);
780 }
781 
783 {
784  const ImpCircUser* pU = static_cast<const ImpCircUser*>(rDrag.GetUser());
785 
786  if(rDrag.GetPointCount() < 4)
787  {
788  // force to OBJ_CIRC to get full visualisation
789  basegfx::B2DPolyPolygon aRetval(ImpCalcXPolyCirc(SdrCircKind::Full, pU->aR, pU->nStart, pU->nEnd));
790 
791  if(3 == rDrag.GetPointCount())
792  {
793  // add edge to first point on ellipse
794  basegfx::B2DPolygon aNew;
795 
796  aNew.append(basegfx::B2DPoint(pU->aCenter.X(), pU->aCenter.Y()));
797  aNew.append(basegfx::B2DPoint(pU->aP1.X(), pU->aP1.Y()));
798  aRetval.append(aNew);
799  }
800 
801  return aRetval;
802  }
803  else
804  {
805  return basegfx::B2DPolyPolygon(ImpCalcXPolyCirc(meCircleKind, pU->aR, pU->nStart, pU->nEnd));
806  }
807 }
808 
810 {
811  switch (meCircleKind) {
812  case SdrCircKind::Full: return PointerStyle::DrawEllipse;
813  case SdrCircKind::Section: return PointerStyle::DrawPie;
814  case SdrCircKind::Arc: return PointerStyle::DrawArc;
815  case SdrCircKind::Cut: return PointerStyle::DrawCircleCut;
816  default: break;
817  } // switch
818  return PointerStyle::Cross;
819 }
820 
821 void SdrCircObj::NbcMove(const Size& aSiz)
822 {
823  maRect.Move(aSiz);
824  aOutRect.Move(aSiz);
825  maSnapRect.Move(aSiz);
826  SetXPolyDirty();
827  SetRectsDirty(true);
828 }
829 
830 void SdrCircObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
831 {
832  long nAngle0=aGeo.nRotationAngle;
833  bool bNoShearRota=(aGeo.nRotationAngle==0 && aGeo.nShearAngle==0);
834  SdrTextObj::NbcResize(rRef,xFact,yFact);
835  bNoShearRota|=(aGeo.nRotationAngle==0 && aGeo.nShearAngle==0);
837  bool bXMirr=(xFact.GetNumerator()<0) != (xFact.GetDenominator()<0);
838  bool bYMirr=(yFact.GetNumerator()<0) != (yFact.GetDenominator()<0);
839  if (bXMirr || bYMirr) {
840  // At bXMirr!=bYMirr we should actually swap both line ends.
841  // That, however, is pretty bad (because of forced "hard" formatting).
842  // Alternatively, we could implement a bMirrored flag (maybe even
843  // a more general one, e. g. for mirrored text, ...).
844  long nS0=nStartAngle;
845  long nE0=nEndAngle;
846  if (bNoShearRota) {
847  // the RectObj already mirrors at VMirror because of a 180deg rotation
848  if (! (bXMirr && bYMirr)) {
849  long nTmp=nS0;
850  nS0=18000-nE0;
851  nE0=18000-nTmp;
852  }
853  } else { // mirror contorted ellipses
854  if (bXMirr!=bYMirr) {
855  nS0+=nAngle0;
856  nE0+=nAngle0;
857  if (bXMirr) {
858  long nTmp=nS0;
859  nS0=18000-nE0;
860  nE0=18000-nTmp;
861  }
862  if (bYMirr) {
863  long nTmp=nS0;
864  nS0=-nE0;
865  nE0=-nTmp;
866  }
867  nS0-=aGeo.nRotationAngle;
868  nE0-=aGeo.nRotationAngle;
869  }
870  }
871  long nAngleDif=nE0-nS0;
874  if (nAngleDif==36000) nEndAngle+=nAngleDif; // full circle
875  }
876  }
877  SetXPolyDirty();
879 }
880 
881 void SdrCircObj::NbcShear(const Point& rRef, long nAngle, double tn, bool bVShear)
882 {
883  SdrTextObj::NbcShear(rRef,nAngle,tn,bVShear);
884  SetXPolyDirty();
886 }
887 
888 void SdrCircObj::NbcMirror(const Point& rRef1, const Point& rRef2)
889 {
890  bool bFreeMirr=meCircleKind!=SdrCircKind::Full;
891  Point aTmpPt1;
892  Point aTmpPt2;
893  if (bFreeMirr) { // some preparations for using an arbitrary axis of reflection
894  Point aCenter(maRect.Center());
895  long nWdt=maRect.GetWidth()-1;
896  long nHgt=maRect.GetHeight()-1;
897  long nMaxRad=(std::max(nWdt,nHgt)+1) /2;
898  double a;
899  // starting point
900  a = nStartAngle * F_PI18000;
901  aTmpPt1=Point(FRound(cos(a)*nMaxRad),-FRound(sin(a)*nMaxRad));
902  if (nWdt==0) aTmpPt1.setX(0 );
903  if (nHgt==0) aTmpPt1.setY(0 );
904  aTmpPt1+=aCenter;
905  // finishing point
906  a = nEndAngle * F_PI18000;
907  aTmpPt2=Point(FRound(cos(a)*nMaxRad),-FRound(sin(a)*nMaxRad));
908  if (nWdt==0) aTmpPt2.setX(0 );
909  if (nHgt==0) aTmpPt2.setY(0 );
910  aTmpPt2+=aCenter;
911  if (aGeo.nRotationAngle!=0) {
914  }
915  if (aGeo.nShearAngle!=0) {
916  ShearPoint(aTmpPt1,maRect.TopLeft(),aGeo.nTan);
917  ShearPoint(aTmpPt2,maRect.TopLeft(),aGeo.nTan);
918  }
919  }
920  SdrTextObj::NbcMirror(rRef1,rRef2);
921  if (meCircleKind!=SdrCircKind::Full) { // adapt starting and finishing angle
922  MirrorPoint(aTmpPt1,rRef1,rRef2);
923  MirrorPoint(aTmpPt2,rRef1,rRef2);
924  // unrotate:
925  if (aGeo.nRotationAngle!=0) {
926  RotatePoint(aTmpPt1,maRect.TopLeft(),-aGeo.nSin,aGeo.nCos); // -sin for reversion
927  RotatePoint(aTmpPt2,maRect.TopLeft(),-aGeo.nSin,aGeo.nCos); // -sin for reversion
928  }
929  // unshear:
930  if (aGeo.nShearAngle!=0) {
931  ShearPoint(aTmpPt1,maRect.TopLeft(),-aGeo.nTan); // -tan for reversion
932  ShearPoint(aTmpPt2,maRect.TopLeft(),-aGeo.nTan); // -tan for reversion
933  }
934  Point aCenter(maRect.Center());
935  aTmpPt1-=aCenter;
936  aTmpPt2-=aCenter;
937  // because it's mirrored, the angles are swapped, too
938  nStartAngle=GetAngle(aTmpPt2);
939  nEndAngle =GetAngle(aTmpPt1);
940  long nAngleDif=nEndAngle-nStartAngle;
941  nStartAngle=NormAngle36000(nStartAngle);
943  if (nAngleDif==36000) nEndAngle+=nAngleDif; // full circle
944  }
945  SetXPolyDirty();
947 }
948 
950 {
951  return new SdrCircObjGeoData;
952 }
953 
955 {
957  SdrCircObjGeoData& rCGeo=static_cast<SdrCircObjGeoData&>(rGeo);
958  rCGeo.nStartAngle=nStartAngle;
959  rCGeo.nEndAngle =nEndAngle;
960 }
961 
963 {
965  const SdrCircObjGeoData& rCGeo=static_cast<const SdrCircObjGeoData&>(rGeo);
966  nStartAngle=rCGeo.nStartAngle;
967  nEndAngle =rCGeo.nEndAngle;
968  SetXPolyDirty();
970 }
971 
972 static void Union(tools::Rectangle& rR, const Point& rP)
973 {
974  if (rP.X()<rR.Left ()) rR.SetLeft(rP.X() );
975  if (rP.X()>rR.Right ()) rR.SetRight(rP.X() );
976  if (rP.Y()<rR.Top ()) rR.SetTop(rP.Y() );
977  if (rP.Y()>rR.Bottom()) rR.SetBottom(rP.Y() );
978 }
979 
981 {
982  rRect = maRect;
984  const Point aPntStart(GetAnglePnt(maRect,nStartAngle));
985  const Point aPntEnd(GetAnglePnt(maRect,nEndAngle));
986  long a=nStartAngle;
987  long e=nEndAngle;
988  rRect.SetLeft(maRect.Right() );
989  rRect.SetRight(maRect.Left() );
990  rRect.SetTop(maRect.Bottom() );
991  rRect.SetBottom(maRect.Top() );
992  Union(rRect,aPntStart);
993  Union(rRect,aPntEnd);
994  if ((a<=18000 && e>=18000) || (a>e && (a<=18000 || e>=18000))) {
995  Union(rRect,maRect.LeftCenter());
996  }
997  if ((a<=27000 && e>=27000) || (a>e && (a<=27000 || e>=27000))) {
998  Union(rRect,maRect.BottomCenter());
999  }
1000  if (a>e) {
1001  Union(rRect,maRect.RightCenter());
1002  }
1003  if ((a<=9000 && e>=9000) || (a>e && (a<=9000 || e>=9000))) {
1004  Union(rRect,maRect.TopCenter());
1005  }
1007  Union(rRect,maRect.Center());
1008  }
1009  if (aGeo.nRotationAngle!=0) {
1010  Point aDst(rRect.TopLeft());
1011  aDst-=maRect.TopLeft();
1012  Point aDst0(aDst);
1013  RotatePoint(aDst,Point(),aGeo.nSin,aGeo.nCos);
1014  aDst-=aDst0;
1015  rRect.Move(aDst.X(),aDst.Y());
1016  }
1017  }
1018  if (aGeo.nShearAngle!=0) {
1019  long nDst=FRound((rRect.Bottom()-rRect.Top())*aGeo.nTan);
1020  if (aGeo.nShearAngle>0) {
1021  Point aRef(rRect.TopLeft());
1022  rRect.AdjustLeft( -nDst );
1023  Point aTmpPt(rRect.TopLeft());
1024  RotatePoint(aTmpPt,aRef,aGeo.nSin,aGeo.nCos);
1025  aTmpPt-=rRect.TopLeft();
1026  rRect.Move(aTmpPt.X(),aTmpPt.Y());
1027  } else {
1028  rRect.AdjustRight( -nDst );
1029  }
1030  }
1031 }
1032 
1034 {
1035  if (PaintNeedsXPolyCirc()) {
1037  } else {
1039  }
1040 }
1041 
1043 {
1045  tools::Rectangle aSR0(GetSnapRect());
1046  long nWdt0=aSR0.Right()-aSR0.Left();
1047  long nHgt0=aSR0.Bottom()-aSR0.Top();
1048  long nWdt1=rRect.Right()-rRect.Left();
1049  long nHgt1=rRect.Bottom()-rRect.Top();
1050  NbcResize(maSnapRect.TopLeft(),Fraction(nWdt1,nWdt0),Fraction(nHgt1,nHgt0));
1051  NbcMove(Size(rRect.Left()-aSR0.Left(),rRect.Top()-aSR0.Top()));
1052  } else {
1053  maRect=rRect;
1055  }
1056  SetRectsDirty();
1057  SetXPolyDirty();
1059 }
1060 
1062 {
1064  return 1;
1065  } else {
1066  return 3;
1067  }
1068 }
1069 
1070 Point SdrCircObj::GetSnapPoint(sal_uInt32 i) const
1071 {
1072  switch (i) {
1073  case 1 : return GetAnglePnt(maRect,nStartAngle);
1074  case 2 : return GetAnglePnt(maRect,nEndAngle);
1075  default: return maRect.Center();
1076  }
1077 }
1078 
1080 {
1081  SetXPolyDirty();
1082  SdrRectObj::Notify(rBC,rHint);
1084 }
1085 
1086 
1088 {
1089  const SfxItemSet& rSet = GetObjectItemSet();
1090  SdrCircKind eNewKind = rSet.Get(SDRATTR_CIRCKIND).GetValue();
1091 
1092  sal_Int32 nNewStart = rSet.Get(SDRATTR_CIRCSTARTANGLE).GetValue();
1093  sal_Int32 nNewEnd = rSet.Get(SDRATTR_CIRCENDANGLE).GetValue();
1094 
1095  bool bKindChg = meCircleKind != eNewKind;
1096  bool bAngleChg = nNewStart != nStartAngle || nNewEnd != nEndAngle;
1097 
1098  if(bKindChg || bAngleChg)
1099  {
1100  meCircleKind = eNewKind;
1101  nStartAngle = nNewStart;
1102  nEndAngle = nNewEnd;
1103 
1104  if(bKindChg || (meCircleKind != SdrCircKind::Full && bAngleChg))
1105  {
1106  SetXPolyDirty();
1107  SetRectsDirty();
1108  }
1109  }
1110 }
1111 
1113 {
1114  const SfxItemSet& rSet = GetObjectItemSet();
1115 
1116  SdrCircKind eOldKindA = rSet.Get(SDRATTR_CIRCKIND).GetValue();
1117  sal_Int32 nOldStartAngle = rSet.Get(SDRATTR_CIRCSTARTANGLE).GetValue();
1118  sal_Int32 nOldEndAngle = rSet.Get(SDRATTR_CIRCENDANGLE).GetValue();
1119 
1120  if(meCircleKind != eOldKindA || nStartAngle != nOldStartAngle || nEndAngle != nOldEndAngle)
1121  {
1122  // since SetItem() implicitly calls ImpSetAttrToCircInfo()
1123  // setting the item directly is necessary here.
1124  if(meCircleKind != eOldKindA)
1125  {
1127  }
1128 
1129  if(nStartAngle != nOldStartAngle)
1130  {
1132  }
1133 
1134  if(nEndAngle != nOldEndAngle)
1135  {
1137  }
1138 
1139  SetXPolyDirty();
1141  }
1142 }
1143 
1144 SdrObjectUniquePtr SdrCircObj::DoConvertToPolyObj(bool bBezier, bool bAddText) const
1145 {
1146  const bool bFill(meCircleKind != SdrCircKind::Arc);
1148  SdrObjectUniquePtr pRet = ImpConvertMakeObj(basegfx::B2DPolyPolygon(aCircPolygon), bFill, bBezier);
1149 
1150  if(bAddText)
1151  {
1152  pRet = ImpConvertAddText(std::move(pRet), bBezier);
1153  }
1154 
1155  return pRet;
1156 }
1157 
1158 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SdrCircKind
Definition: svdocirc.hxx:39
Point TopLeft() const
B2DPolygon const & createPolygonFromUnitCircle(sal_uInt32 nStartQuadrant=0)
static SVX_DLLPRIVATE void ImpSetCreateParams(SdrDragStat &rStat)
Definition: svdocirc.cxx:694
long GetWidth() const
B2DPoint getCenter() const
virtual void NbcResize(const Point &rRef, const Fraction &xFact, const Fraction &yFact) override
Definition: svdotxtr.cxx:102
void append(const basegfx::B2DPoint &rPoint, sal_uInt32 nCount)
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Detects when a stylesheet is changed.
Definition: svdocirc.cxx:1079
tools::Rectangle GetBoundRect() const
Definition: _xpoly.cxx:396
long GetHeight() const
SdrCircObj & operator=(const SdrCircObj &rObj)
Definition: svdocirc.cxx:374
virtual void SetObjectItemDirect(const SfxPoolItem &rItem)=0
virtual sal_uInt16 GetObjIdentifier() const override
Definition: svdocirc.cxx:169
void ShearPoint(Point &rPnt, const Point &rRef, double tn, bool bVShear=false)
Definition: svdtrans.hxx:122
double getHeight() const
long FRound(double fVal)
virtual SdrObjGeoData * NewGeoData() const override
A derived class must override these 3 methods if it has own geometric data that must be saved for Und...
Definition: svdocirc.cxx:949
#define XATTR_LINEENDWIDTH
Definition: xdef.hxx:97
virtual OUString TakeObjNameSingul() const override
Definition: svdocirc.cxx:311
double nSin
Definition: svdtrans.hxx:219
const Point & GetStart() const
Definition: svddrag.hxx:92
Point BottomLeft() const
GeoStat aGeo
Definition: svdotext.hxx:185
SdrHdlKind
Definition: svdhdl.hxx:52
long AdjustLeft(long nHorzMoveDelta)
bool ImpCanConvTextToCurve() const
Definition: svdotxtr.cxx:424
SVX_DLLPRIVATE basegfx::B2DPolygon ImpCalcXPolyCirc(const SdrCircKind eKind, const tools::Rectangle &rRect1, long nStart, long nEnd) const
Definition: svdocirc.cxx:232
virtual basegfx::B2DPolyPolygon TakeXorPoly() const override
The Xor-Polygon is required by the View to drag the object.
Definition: svdocirc.cxx:387
long nRotationAngle
Definition: svdtrans.hxx:216
sal_uInt32 GetPointNum() const
Definition: svdhdl.hxx:222
virtual void SetBoundRectDirty()
Definition: svdobj.cxx:309
aBuf
virtual void RecalcSnapRect() override
Snap is not done on the BoundRect but if possible on logic coordinates (i.e.
Definition: svdocirc.cxx:1033
static void Union(tools::Rectangle &rR, const Point &rP)
Definition: svdocirc.cxx:972
SdrObjectUniquePtr ImpConvertAddText(SdrObjectUniquePtr pObj, bool bBezier) const
Definition: svdotxtr.cxx:463
const Point & GetPoint(sal_Int32 nNum) const
Definition: svddrag.hxx:90
virtual bool applySpecialDrag(SdrDragStat &rDrag) override
Definition: svdocirc.cxx:524
virtual SdrObjectUniquePtr DoConvertToPolyObj(bool bBezier, bool bAddText) const override
Definition: svdocirc.cxx:1144
virtual sdr::properties::BaseProperties & GetProperties() const
Definition: svdobj.cxx:203
virtual void TakeUnrotatedSnapRect(tools::Rectangle &rRect) const override
Definition: svdocirc.cxx:980
virtual const tools::Rectangle & GetSnapRect() const override
Definition: svdoattr.cxx:48
All geometrical data of an arbitrary object for use in undo/redo.
Definition: svdobj.hxx:226
long NormAngle36000(long a)
Normalize angle to -180.00..179.99.
Definition: svdtrans.cxx:407
virtual bool HasText() const override
Definition: svdotxat.cxx:412
SdrCircKind ToSdrCircKind(SdrObjKind eKind)
Definition: svdocirc.cxx:104
void Move(long nHorzMoveDelta, long nVertMoveDelta)
bool bSnapRectDirty
Definition: svdobj.hxx:928
virtual void NbcMirror(const Point &rRef1, const Point &rRef2) override
Definition: svdotxtr.cxx:232
Point RightCenter() const
Rectangle objects (rectangle, circle, ...)
Definition: svdorect.hxx:39
Provides information about various ZObject properties.
Definition: svdobj.hxx:248
const SdrHdl * GetHdl() const
Definition: svddrag.hxx:101
static OUString GetAngleString(long nAngle)
Definition: svdmodel.cxx:1204
virtual void BrkCreate(SdrDragStat &rStat) override
Definition: svdocirc.cxx:770
virtual bool hasSpecialDrag() const override
The standard transformations (Move,Resize,Rotate,Mirror,Shear) are taken over by the View (TakeXorPol...
Definition: svdocirc.cxx:502
long nEndAngle
Definition: svdocirc.hxx:55
long Right() const
double getWidth() const
OUString SvxResId(const char *pId)
Definition: dialmgr.cxx:28
virtual void SaveGeoData(SdrObjGeoData &rGeo) const override
Definition: svdotext.cxx:1432
virtual void TakeObjInfo(SdrObjTransformInfoRec &rInfo) const override
Definition: svdocirc.cxx:160
virtual bool MovCreate(SdrDragStat &rStat) override
Definition: svdocirc.cxx:715
#define SDRATTR_CIRCENDANGLE
Definition: svddef.hxx:268
Point BottomCenter() const
virtual Point GetSnapPoint(sal_uInt32 i) const override
Definition: svdocirc.cxx:1070
const SfxItemSet & GetObjectItemSet() const
Definition: svdobj.cxx:1878
SdrAngleItem makeSdrCircEndAngleItem(long nAngle)
Definition: sxciaitm.hxx:29
virtual bool BckCreate(SdrDragStat &rStat) override
Definition: svdocirc.cxx:775
tools::Rectangle maRect
Definition: svdotext.hxx:182
void SetOrtho4Possible(bool bOn=true)
Definition: svddrag.hxx:126
void TakeCreateRect(tools::Rectangle &rRect) const
Definition: svddrag.cxx:115
B2DHomMatrix createScaleTranslateB2DHomMatrix(double fScaleX, double fScaleY, double fTranslateX, double fTranslateY)
bool bClosedObj
Definition: svdobj.hxx:941
long Top() const
tools::Rectangle maSnapRect
Definition: svdoattr.hxx:42
Point LeftCenter() const
circle, ellipse
Definition: svdobj.hxx:122
virtual sal_uInt32 GetSnapPointCount() const override
snap to special points of an Object (polygon points, center of circle)
Definition: svdocirc.cxx:1061
virtual void AddToHdlList(SdrHdlList &rHdlList) const override
Definition: svdocirc.cxx:429
SdrCircKind meCircleKind
Definition: svdocirc.hxx:53
SVX_DLLPRIVATE void ImpSetCircInfoToAttr()
Definition: svdocirc.cxx:1112
Point BottomRight() const
void SetNoSnap(bool bOn=true)
Definition: svddrag.hxx:121
virtual bool applySpecialDrag(SdrDragStat &rDrag) override
Definition: svdotxdr.cxx:149
virtual OUString getSpecialDragComment(const SdrDragStat &rDrag) const override
Definition: svdotxdr.cxx:174
const XPolygon & GetXPoly() const
Definition: svdorect.cxx:127
#define F_PI
double nCos
Definition: svdtrans.hxx:220
void SetTop(long v)
uno_Any a
OUString sName
SdrObject * GetCreateObj() const
Definition: svdcrtv.hxx:119
tools::Rectangle aOutRect
Definition: svdobj.hxx:921
SdrPathObjUniquePtr ImpConvertMakeObj(const basegfx::B2DPolyPolygon &rPolyPolygon, bool bClosed, bool bBezier) const
Definition: svdotxtr.cxx:429
virtual std::unique_ptr< sdr::properties::BaseProperties > CreateObjectSpecificProperties() override
Definition: svdocirc.cxx:91
sal_Int32 GetPointCount() const
Definition: svddrag.hxx:91
void MirrorPoint(Point &rPnt, const Point &rRef1, const Point &rRef2)
Definition: svdtrans.cxx:103
void SetRight(long v)
double nTan
Definition: svdtrans.hxx:218
SdrView * GetView() const
Definition: svddrag.hxx:86
bool IsAngleSnapEnabled() const
Definition: svdsnpv.hxx:222
void SetXPolyDirty()
Definition: svdorect.cxx:93
long Bottom() const
virtual void SaveGeoData(SdrObjGeoData &rGeo) const override
Definition: svdocirc.cxx:954
long GetSnapAngle() const
Definition: svdsnpv.hxx:224
#define XATTR_LINESTYLE
Definition: xdef.hxx:90
virtual void NbcResize(const Point &rRef, const Fraction &xFact, const Fraction &yFact) override
Definition: svdocirc.cxx:830
virtual bool beginSpecialDrag(SdrDragStat &rDrag) const override
Definition: svdocirc.cxx:507
#define XATTR_FILLSTYLE
Definition: xdef.hxx:107
virtual bool BegCreate(SdrDragStat &rStat) override
Every object must be able to create itself interactively.
Definition: svdocirc.cxx:704
virtual ~SdrCircObj() override
Definition: svdocirc.cxx:156
OUString GetName() const
Definition: svdobj.cxx:697
long nShearAngle
Definition: svdtrans.hxx:217
SdrAngleItem makeSdrCircStartAngleItem(long nAngle)
Definition: sxciaitm.hxx:25
long BigMulDiv(long nVal, long nMul, long nDiv)
Definition: svdtrans.cxx:558
void transform(const basegfx::B2DHomMatrix &rMatrix)
basegfx::B2DRange b2DRectangleFromRectangle(const ::tools::Rectangle &rRect)
#define XATTR_LINEWIDTH
Definition: xdef.hxx:92
void append(const B2DPolygon &rPolygon, sal_uInt32 nCount=1)
long nStartAngle
Definition: svdocirc.hxx:54
circle section
Definition: svdobj.hxx:123
SdrRectObj & operator=(const SdrRectObj &rCopy)
Definition: svdorect.cxx:250
void setClosed(bool bNew)
void RotatePoint(Point &rPnt, const Point &rRef, double sn, double cs)
Definition: svdtrans.hxx:114
void SetActionRect(const tools::Rectangle &rR)
Definition: svddrag.hxx:157
virtual OUString getSpecialDragComment(const SdrDragStat &rDrag) const override
Definition: svdocirc.cxx:589
virtual basegfx::B2DPolyPolygon TakeCreatePoly(const SdrDragStat &rDrag) const override
Polygon dragged by the user when creating the object.
Definition: svdocirc.cxx:782
long AdjustRight(long nHorzMoveDelta)
sal_Int32 GetDenominator() const
circle arc
Definition: svdobj.hxx:124
SdrObjKind
Definition: svdobj.hxx:116
virtual void RestGeoData(const SdrObjGeoData &rGeo) override
Definition: svdocirc.cxx:962
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
virtual SVX_DLLPRIVATE void RecalcXPoly() override
Subclasses should override RecalcXPoly() by creating an XPolygon instance with new and assigning it t...
Definition: svdocirc.cxx:305
virtual OUString TakeObjNamePlural() const override
Definition: svdocirc.cxx:345
virtual void NbcMirror(const Point &rRef1, const Point &rRef2) override
Definition: svdocirc.cxx:888
OUString ImpGetDescriptionStr(const char *pStrCacheID) const
Definition: svdobj.cxx:1037
virtual sal_uInt32 GetHdlCount() const override
Via GetHdlCount the number of Handles can be retrieved.
Definition: svdocirc.cxx:417
#define XATTR_LINEEND
Definition: xdef.hxx:95
OUString aName
B2DPolygon createPolygonFromEllipseSegment(const B2DPoint &rCenter, double fRadiusX, double fRadiusY, double fStart, double fEnd)
void SetUser(std::unique_ptr< SdrDragStatUserData > pU)
Definition: svddrag.hxx:104
virtual void NbcShear(const Point &rRef, long nAngle, double tn, bool bVShear) override
Definition: svdocirc.cxx:881
void SetBottom(long v)
#define F_PI18000
std::unique_ptr< XPolygon > mpXPoly
Definition: svdorect.hxx:50
B2DPoint getMinimum() const
virtual PointerStyle GetCreatePointer() const override
get the cursor/pointer that signals creating this object
Definition: svdocirc.cxx:809
sal_Int32 GetNumerator() const
static Point GetAnglePnt(const tools::Rectangle &rR, long nAngle)
Definition: svdocirc.cxx:52
virtual bool EndCreate(SdrDragStat &rStat, SdrCreateCmd eCmd) override
Definition: svdocirc.cxx:738
std::unique_ptr< SdrObject, SdrObjectFreeOp > SdrObjectUniquePtr
Definition: svdobj.hxx:114
SdrCircObj(SdrModel &rSdrModel, SdrCircKind eNewKind)
Definition: svdocirc.cxx:117
const Point & GetNow() const
Definition: svddrag.hxx:95
virtual bool beginSpecialDrag(SdrDragStat &rDrag) const
Definition: svdobj.cxx:1284
long GetAngle(const Point &rPnt)
The Y axis points down! The function negates the Y axis, when calculating the angle, such that GetAngle(Point(0,-1))=90 deg.
Definition: svdtrans.cxx:385
long Left() const
PointerStyle
SVX_DLLPRIVATE void ImpSetAttrToCircInfo()
Definition: svdocirc.cxx:1087
virtual void RestGeoData(const SdrObjGeoData &rGeo) override
Definition: svdorect.cxx:576
virtual void SetRectsDirty(bool bNotMyself=false, bool bRecursive=true)
Definition: svdobj.cxx:434
virtual void NbcMove(const Size &aSiz) override
The methods Move, Resize, Rotate, Mirror, Shear, SetSnapRect and SetLogicRect call the corresponding ...
Definition: svdocirc.cxx:821
#define SDRATTR_CIRCSTARTANGLE
Definition: svddef.hxx:267
void SetLeft(long v)
#define XATTR_LINESTARTWIDTH
Definition: xdef.hxx:96
bool LineGeometryUsageIsNecessary() const
Definition: svdobj.cxx:961
#define SDRATTR_CIRCKIND
Definition: svddef.hxx:266
SVX_DLLPRIVATE bool PaintNeedsXPolyCirc() const
Definition: svdocirc.cxx:182
SdrDragStatUserData * GetUser() const
Definition: svddrag.hxx:103
B2DHomMatrix createShearXRotateTranslateB2DHomMatrix(double fShearX, double fRadiant, double fTranslateX, double fTranslateY)
virtual void NbcSetSnapRect(const tools::Rectangle &rRect) override
Definition: svdocirc.cxx:1042
B2DHomMatrix createTranslateB2DHomMatrix(double fTranslateX, double fTranslateY)
SdrCreateCmd
Definition: svdtypes.hxx:27
virtual void SetChanged()
Definition: svdobj.cxx:928
virtual void NbcShear(const Point &rRef, long nAngle, double tn, bool bVShear) override
Definition: svdotxtr.cxx:210
static void ImpJustifyRect(tools::Rectangle &rRect)
Definition: svdotext.cxx:374
Point TopRight() const
Point Center() const
void AddHdl(std::unique_ptr< SdrHdl > pHdl)
Definition: svdhdl.cxx:2294
virtual bool IsFontwork() const
Definition: svdotext.cxx:1724
Point TopCenter() const
virtual SdrCircObj * CloneSdrObject(SdrModel &rTargetModel) const override
Definition: svdocirc.cxx:369
SdrHdlKind GetKind() const
Definition: svdhdl.hxx:194
#define XATTR_LINESTART
Definition: xdef.hxx:94
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Detects when a stylesheet is changed.
Definition: svdorect.cxx:570
rectangle (round corners optional)
Definition: svdobj.hxx:121
virtual std::unique_ptr< sdr::contact::ViewContact > CreateObjectSpecificViewContact() override
Definition: svdocirc.cxx:99