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 #include <rtl/ustrbuf.hxx>
27 
28 #include <svx/dialmgr.hxx>
29 #include <svx/strings.hrc>
30 
33 #include <svx/svddrag.hxx>
34 #include <svx/svdmodel.hxx>
35 #include <svx/svdocirc.hxx>
36 #include <svx/svdopath.hxx>
37 #include <svx/svdtrans.hxx>
38 #include <svx/svdview.hxx>
39 #include <svx/sxciaitm.hxx>
40 #include <sxcikitm.hxx>
41 #include <svx/xfillit0.hxx>
42 #include <svx/xlineit0.hxx>
43 #include <svx/xlnedit.hxx>
44 #include <svx/xlnedwit.hxx>
45 #include <svx/xlnstit.hxx>
46 #include <svx/xlnstwit.hxx>
47 #include <svx/xlnwtit.hxx>
48 #include <vcl/canvastools.hxx>
49 #include <vcl/ptrstyle.hxx>
50 
51 using namespace com::sun::star;
52 
53 static Point GetAnglePnt(const tools::Rectangle& rR, Degree100 nAngle)
54 {
55  Point aCenter(rR.Center());
56  tools::Long nWdt=rR.Right()-rR.Left();
57  tools::Long nHgt=rR.Bottom()-rR.Top();
58  tools::Long nMaxRad=(std::max(nWdt,nHgt)+1) /2;
59  double a = nAngle.get() * 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_deg100;
123  nEndAngle=36000_deg100;
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_deg100;
135  nEndAngle=36000_deg100;
136  meCircleKind=eNewKind;
137  bClosedObj=eNewKind!=SdrCircKind::Arc;
138 }
139 
141  SdrModel& rSdrModel,
142  SdrCircKind eNewKind,
143  const tools::Rectangle& rRect,
144  Degree100 nNewStartAngle,
145  Degree100 nNewEndAngle)
146 : SdrRectObj(rSdrModel, rRect)
147 {
148  Degree100 nAngleDif=nNewEndAngle-nNewStartAngle;
149  nStartAngle=NormAngle36000(nNewStartAngle);
150  nEndAngle=NormAngle36000(nNewEndAngle);
151  if (nAngleDif==36000_deg100) 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 
233 {
235  basegfx::B2DPolygon aCircPolygon;
236 
237  if(SdrCircKind::Full == eCircleKind)
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.get()) % 36000) / 18000.0) * F_PI);
257  const double fEnd((((36000 - nStart.get()) % 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 != eCircleKind);
266  const bool bCloseUsingCenter(SdrCircKind::Section == eCircleKind);
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)
295  aGeo.nRotationAngle ? (36000_deg100 - aGeo.nRotationAngle).get() * 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_deg100)
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_deg100)
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  tools::Long nHgt;
401  tools::Long nWdt;
402  Degree100 nStart;
403  Degree100 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)
534 
535  if (aGeo.nShearAngle)
537 
538  aPt -= maRect.Center();
539 
540  tools::Long nWdt = maRect.Right() - maRect.Left();
541  tools::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  Degree100 nAngle=NormAngle36000(GetAngle(aPt));
553 
554  if (rDrag.GetView() && rDrag.GetView()->IsAngleSnapEnabled())
555  {
556  Degree100 nSA=rDrag.GetView()->GetSnapAngle();
557 
558  if (nSA)
559  {
560  nAngle+=nSA/2_deg100;
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  Degree100 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 Degree100 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_deg100;
651  nEnd=36000_deg100;
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  Degree100 nSA=rStat.GetView()->GetSnapAngle();
664  if (nSA) { // angle snapping
665  nStart+=nSA/2_deg100;
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  return;
676 
677  Point aP(rStat.GetPoint(3)-aCenter);
678  if (nWdt>=nHgt) {
679  aP.setY(BigMulDiv(aP.Y(),nWdt,nHgt) );
680  } else {
681  aP.setX(BigMulDiv(aP.X(),nHgt,nWdt) );
682  }
683  nEnd=NormAngle36000(GetAngle(aP));
684  if (rStat.GetView()!=nullptr && rStat.GetView()->IsAngleSnapEnabled()) {
685  Degree100 nSA=rStat.GetView()->GetSnapAngle();
686  if (nSA) { // angle snapping
687  nEnd+=nSA/2_deg100;
688  nEnd/=nSA;
689  nEnd*=nSA;
690  nEnd=NormAngle36000(nEnd);
691  }
692  }
693 }
694 
696 {
697  ImpCircUser* pU=static_cast<ImpCircUser*>(rStat.GetUser());
698  if (pU==nullptr) {
699  pU=new ImpCircUser;
700  rStat.SetUser(std::unique_ptr<ImpCircUser>(pU));
701  }
702  pU->SetCreateParams(rStat);
703 }
704 
706 {
707  rStat.SetOrtho4Possible();
708  tools::Rectangle aRect1(rStat.GetStart(), rStat.GetNow());
709  aRect1.Justify();
710  rStat.SetActionRect(aRect1);
711  maRect = aRect1;
712  ImpSetCreateParams(rStat);
713  return true;
714 }
715 
717 {
718  ImpSetCreateParams(rStat);
719  ImpCircUser* pU=static_cast<ImpCircUser*>(rStat.GetUser());
720  rStat.SetActionRect(pU->aR);
721  maRect = pU->aR; // for ObjName
723  nStartAngle=pU->nStart;
724  nEndAngle=pU->nEnd;
726  bSnapRectDirty=true;
727  SetXPolyDirty();
728 
729  // #i103058# push current angle settings to ItemSet to
730  // allow FullDrag visualisation
731  if(rStat.GetPointCount() >= 4)
732  {
734  }
735 
736  return true;
737 }
738 
740 {
741  ImpSetCreateParams(rStat);
742  ImpCircUser* pU=static_cast<ImpCircUser*>(rStat.GetUser());
743  bool bRet = false;
746  bRet=rStat.GetPointCount()>=2;
747  if (bRet) {
748  maRect = pU->aR;
750  }
751  } else {
752  rStat.SetNoSnap(rStat.GetPointCount()>=2);
753  rStat.SetOrtho4Possible(rStat.GetPointCount()<2);
754  bRet=rStat.GetPointCount()>=4;
755  if (bRet) {
756  maRect = pU->aR;
758  nStartAngle=pU->nStart;
759  nEndAngle=pU->nEnd;
760  }
761  }
763  SetRectsDirty();
764  SetXPolyDirty();
766  if (bRet)
767  rStat.SetUser(nullptr);
768  return bRet;
769 }
770 
772 {
773  rStat.SetUser(nullptr);
774 }
775 
777 {
778  rStat.SetNoSnap(rStat.GetPointCount()>=3);
779  rStat.SetOrtho4Possible(rStat.GetPointCount()<3);
781 }
782 
784 {
785  const ImpCircUser* pU = static_cast<const ImpCircUser*>(rDrag.GetUser());
786 
787  if(rDrag.GetPointCount() < 4)
788  {
789  // force to OBJ_CIRC to get full visualisation
790  basegfx::B2DPolyPolygon aRetval(ImpCalcXPolyCirc(SdrCircKind::Full, pU->aR, pU->nStart, pU->nEnd));
791 
792  if(3 == rDrag.GetPointCount())
793  {
794  // add edge to first point on ellipse
795  basegfx::B2DPolygon aNew;
796 
797  aNew.append(basegfx::B2DPoint(pU->aCenter.X(), pU->aCenter.Y()));
798  aNew.append(basegfx::B2DPoint(pU->aP1.X(), pU->aP1.Y()));
799  aRetval.append(aNew);
800  }
801 
802  return aRetval;
803  }
804  else
805  {
806  return basegfx::B2DPolyPolygon(ImpCalcXPolyCirc(meCircleKind, pU->aR, pU->nStart, pU->nEnd));
807  }
808 }
809 
811 {
812  switch (meCircleKind) {
813  case SdrCircKind::Full: return PointerStyle::DrawEllipse;
814  case SdrCircKind::Section: return PointerStyle::DrawPie;
815  case SdrCircKind::Arc: return PointerStyle::DrawArc;
816  case SdrCircKind::Cut: return PointerStyle::DrawCircleCut;
817  default: break;
818  } // switch
819  return PointerStyle::Cross;
820 }
821 
822 void SdrCircObj::NbcMove(const Size& aSiz)
823 {
824  maRect.Move(aSiz);
825  aOutRect.Move(aSiz);
826  maSnapRect.Move(aSiz);
827  SetXPolyDirty();
828  SetRectsDirty(true);
829 }
830 
831 void SdrCircObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
832 {
833  Degree100 nAngle0=aGeo.nRotationAngle;
834  bool bNoShearRota=(aGeo.nRotationAngle==0_deg100 && aGeo.nShearAngle==0_deg100);
835  SdrTextObj::NbcResize(rRef,xFact,yFact);
836  bNoShearRota|=(aGeo.nRotationAngle==0_deg100 && aGeo.nShearAngle==0_deg100);
838  bool bXMirr=(xFact.GetNumerator()<0) != (xFact.GetDenominator()<0);
839  bool bYMirr=(yFact.GetNumerator()<0) != (yFact.GetDenominator()<0);
840  if (bXMirr || bYMirr) {
841  // At bXMirr!=bYMirr we should actually swap both line ends.
842  // That, however, is pretty bad (because of forced "hard" formatting).
843  // Alternatively, we could implement a bMirrored flag (maybe even
844  // a more general one, e. g. for mirrored text, ...).
846  Degree100 nE0=nEndAngle;
847  if (bNoShearRota) {
848  // the RectObj already mirrors at VMirror because of a 180deg rotation
849  if (! (bXMirr && bYMirr)) {
850  Degree100 nTmp=nS0;
851  nS0=18000_deg100-nE0;
852  nE0=18000_deg100-nTmp;
853  }
854  } else { // mirror contorted ellipses
855  if (bXMirr!=bYMirr) {
856  nS0+=nAngle0;
857  nE0+=nAngle0;
858  if (bXMirr) {
859  Degree100 nTmp=nS0;
860  nS0=18000_deg100-nE0;
861  nE0=18000_deg100-nTmp;
862  }
863  if (bYMirr) {
864  Degree100 nTmp=nS0;
865  nS0=-nE0;
866  nE0=-nTmp;
867  }
868  nS0-=aGeo.nRotationAngle;
869  nE0-=aGeo.nRotationAngle;
870  }
871  }
872  Degree100 nAngleDif=nE0-nS0;
875  if (nAngleDif==36000_deg100) nEndAngle+=nAngleDif; // full circle
876  }
877  }
878  SetXPolyDirty();
880 }
881 
882 void SdrCircObj::NbcShear(const Point& rRef, Degree100 nAngle, double tn, bool bVShear)
883 {
884  SdrTextObj::NbcShear(rRef,nAngle,tn,bVShear);
885  SetXPolyDirty();
887 }
888 
889 void SdrCircObj::NbcMirror(const Point& rRef1, const Point& rRef2)
890 {
891  bool bFreeMirr=meCircleKind!=SdrCircKind::Full;
892  Point aTmpPt1;
893  Point aTmpPt2;
894  if (bFreeMirr) { // some preparations for using an arbitrary axis of reflection
895  Point aCenter(maRect.Center());
896  tools::Long nWdt=maRect.GetWidth()-1;
897  tools::Long nHgt=maRect.GetHeight()-1;
898  tools::Long nMaxRad=(std::max(nWdt,nHgt)+1) /2;
899  double a;
900  // starting point
901  a = nStartAngle.get() * F_PI18000;
902  aTmpPt1=Point(FRound(cos(a)*nMaxRad),-FRound(sin(a)*nMaxRad));
903  if (nWdt==0) aTmpPt1.setX(0 );
904  if (nHgt==0) aTmpPt1.setY(0 );
905  aTmpPt1+=aCenter;
906  // finishing point
907  a = nEndAngle.get() * F_PI18000;
908  aTmpPt2=Point(FRound(cos(a)*nMaxRad),-FRound(sin(a)*nMaxRad));
909  if (nWdt==0) aTmpPt2.setX(0 );
910  if (nHgt==0) aTmpPt2.setY(0 );
911  aTmpPt2+=aCenter;
912  if (aGeo.nRotationAngle) {
915  }
916  if (aGeo.nShearAngle) {
919  }
920  }
921  SdrTextObj::NbcMirror(rRef1,rRef2);
922  if (meCircleKind!=SdrCircKind::Full) { // adapt starting and finishing angle
923  MirrorPoint(aTmpPt1,rRef1,rRef2);
924  MirrorPoint(aTmpPt2,rRef1,rRef2);
925  // unrotate:
926  if (aGeo.nRotationAngle) {
927  RotatePoint(aTmpPt1,maRect.TopLeft(),-aGeo.mfSinRotationAngle,aGeo.mfCosRotationAngle); // -sin for reversion
928  RotatePoint(aTmpPt2,maRect.TopLeft(),-aGeo.mfSinRotationAngle,aGeo.mfCosRotationAngle); // -sin for reversion
929  }
930  // unshear:
931  if (aGeo.nShearAngle) {
932  ShearPoint(aTmpPt1,maRect.TopLeft(),-aGeo.mfTanShearAngle); // -tan for reversion
933  ShearPoint(aTmpPt2,maRect.TopLeft(),-aGeo.mfTanShearAngle); // -tan for reversion
934  }
935  Point aCenter(maRect.Center());
936  aTmpPt1-=aCenter;
937  aTmpPt2-=aCenter;
938  // because it's mirrored, the angles are swapped, too
939  nStartAngle=GetAngle(aTmpPt2);
940  nEndAngle =GetAngle(aTmpPt1);
941  Degree100 nAngleDif=nEndAngle-nStartAngle;
942  nStartAngle=NormAngle36000(nStartAngle);
944  if (nAngleDif==36000_deg100) nEndAngle+=nAngleDif; // full circle
945  }
946  SetXPolyDirty();
948 }
949 
951 {
952  return new SdrCircObjGeoData;
953 }
954 
956 {
958  SdrCircObjGeoData& rCGeo=static_cast<SdrCircObjGeoData&>(rGeo);
959  rCGeo.nStartAngle=nStartAngle;
960  rCGeo.nEndAngle =nEndAngle;
961 }
962 
964 {
966  const SdrCircObjGeoData& rCGeo=static_cast<const SdrCircObjGeoData&>(rGeo);
967  nStartAngle=rCGeo.nStartAngle;
968  nEndAngle =rCGeo.nEndAngle;
969  SetXPolyDirty();
971 }
972 
973 static void Union(tools::Rectangle& rR, const Point& rP)
974 {
975  if (rP.X()<rR.Left ()) rR.SetLeft(rP.X() );
976  if (rP.X()>rR.Right ()) rR.SetRight(rP.X() );
977  if (rP.Y()<rR.Top ()) rR.SetTop(rP.Y() );
978  if (rP.Y()>rR.Bottom()) rR.SetBottom(rP.Y() );
979 }
980 
982 {
983  rRect = maRect;
985  const Point aPntStart(GetAnglePnt(maRect,nStartAngle));
986  const Point aPntEnd(GetAnglePnt(maRect,nEndAngle));
989  rRect.SetLeft(maRect.Right() );
990  rRect.SetRight(maRect.Left() );
991  rRect.SetTop(maRect.Bottom() );
992  rRect.SetBottom(maRect.Top() );
993  Union(rRect,aPntStart);
994  Union(rRect,aPntEnd);
995  if ((a<=18000_deg100 && e>=18000_deg100) || (a>e && (a<=18000_deg100 || e>=18000_deg100))) {
996  Union(rRect,maRect.LeftCenter());
997  }
998  if ((a<=27000_deg100 && e>=27000_deg100) || (a>e && (a<=27000_deg100 || e>=27000_deg100))) {
999  Union(rRect,maRect.BottomCenter());
1000  }
1001  if (a>e) {
1002  Union(rRect,maRect.RightCenter());
1003  }
1004  if ((a<=9000_deg100 && e>=9000_deg100) || (a>e && (a<=9000_deg100 || e>=9000_deg100))) {
1005  Union(rRect,maRect.TopCenter());
1006  }
1008  Union(rRect,maRect.Center());
1009  }
1010  if (aGeo.nRotationAngle) {
1011  Point aDst(rRect.TopLeft());
1012  aDst-=maRect.TopLeft();
1013  Point aDst0(aDst);
1015  aDst-=aDst0;
1016  rRect.Move(aDst.X(),aDst.Y());
1017  }
1018  }
1019  if (aGeo.nShearAngle==0_deg100)
1020  return;
1021 
1022  tools::Long nDst=FRound((rRect.Bottom()-rRect.Top())*aGeo.mfTanShearAngle);
1023  if (aGeo.nShearAngle>0_deg100) {
1024  Point aRef(rRect.TopLeft());
1025  rRect.AdjustLeft( -nDst );
1026  Point aTmpPt(rRect.TopLeft());
1028  aTmpPt-=rRect.TopLeft();
1029  rRect.Move(aTmpPt.X(),aTmpPt.Y());
1030  } else {
1031  rRect.AdjustRight( -nDst );
1032  }
1033 }
1034 
1036 {
1037  if (PaintNeedsXPolyCirc()) {
1039  } else {
1041  }
1042 }
1043 
1045 {
1047  tools::Rectangle aSR0(GetSnapRect());
1048  tools::Long nWdt0=aSR0.Right()-aSR0.Left();
1049  tools::Long nHgt0=aSR0.Bottom()-aSR0.Top();
1050  tools::Long nWdt1=rRect.Right()-rRect.Left();
1051  tools::Long nHgt1=rRect.Bottom()-rRect.Top();
1052  NbcResize(maSnapRect.TopLeft(),Fraction(nWdt1,nWdt0),Fraction(nHgt1,nHgt0));
1053  NbcMove(Size(rRect.Left()-aSR0.Left(),rRect.Top()-aSR0.Top()));
1054  } else {
1055  maRect=rRect;
1057  }
1058  SetRectsDirty();
1059  SetXPolyDirty();
1061 }
1062 
1064 {
1066  return 1;
1067  } else {
1068  return 3;
1069  }
1070 }
1071 
1072 Point SdrCircObj::GetSnapPoint(sal_uInt32 i) const
1073 {
1074  switch (i) {
1075  case 1 : return GetAnglePnt(maRect,nStartAngle);
1076  case 2 : return GetAnglePnt(maRect,nEndAngle);
1077  default: return maRect.Center();
1078  }
1079 }
1080 
1082 {
1083  SetXPolyDirty();
1084  SdrRectObj::Notify(rBC,rHint);
1086 }
1087 
1088 
1090 {
1091  const SfxItemSet& rSet = GetObjectItemSet();
1092  SdrCircKind eNewKind = rSet.Get(SDRATTR_CIRCKIND).GetValue();
1093 
1094  Degree100 nNewStart = rSet.Get(SDRATTR_CIRCSTARTANGLE).GetValue();
1095  Degree100 nNewEnd = rSet.Get(SDRATTR_CIRCENDANGLE).GetValue();
1096 
1097  bool bKindChg = meCircleKind != eNewKind;
1098  bool bAngleChg = nNewStart != nStartAngle || nNewEnd != nEndAngle;
1099 
1100  if(bKindChg || bAngleChg)
1101  {
1102  meCircleKind = eNewKind;
1103  nStartAngle = nNewStart;
1104  nEndAngle = nNewEnd;
1105 
1106  if(bKindChg || (meCircleKind != SdrCircKind::Full && bAngleChg))
1107  {
1108  SetXPolyDirty();
1109  SetRectsDirty();
1110  }
1111  }
1112 }
1113 
1115 {
1116  const SfxItemSet& rSet = GetObjectItemSet();
1117 
1118  SdrCircKind eOldKindA = rSet.Get(SDRATTR_CIRCKIND).GetValue();
1119  Degree100 nOldStartAngle = rSet.Get(SDRATTR_CIRCSTARTANGLE).GetValue();
1120  Degree100 nOldEndAngle = rSet.Get(SDRATTR_CIRCENDANGLE).GetValue();
1121 
1122  if(meCircleKind == eOldKindA && nStartAngle == nOldStartAngle && nEndAngle == nOldEndAngle)
1123  return;
1124 
1125  // since SetItem() implicitly calls ImpSetAttrToCircInfo()
1126  // setting the item directly is necessary here.
1127  if(meCircleKind != eOldKindA)
1128  {
1130  }
1131 
1132  if(nStartAngle != nOldStartAngle)
1133  {
1135  }
1136 
1137  if(nEndAngle != nOldEndAngle)
1138  {
1140  }
1141 
1142  SetXPolyDirty();
1144 }
1145 
1146 SdrObjectUniquePtr SdrCircObj::DoConvertToPolyObj(bool bBezier, bool bAddText) const
1147 {
1148  const bool bFill(meCircleKind != SdrCircKind::Arc);
1150  SdrObjectUniquePtr pRet = ImpConvertMakeObj(basegfx::B2DPolyPolygon(aCircPolygon), bFill, bBezier);
1151 
1152  if(bAddText)
1153  {
1154  pRet = ImpConvertAddText(std::move(pRet), bBezier);
1155  }
1156 
1157  return pRet;
1158 }
1159 
1160 /* 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:695
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:1081
constexpr TypedWhichId< XLineEndItem > XATTR_LINEEND(XATTR_LINE_FIRST+5)
tools::Rectangle GetBoundRect() const
Definition: _xpoly.cxx:396
SdrCircObj & operator=(const SdrCircObj &rObj)
Definition: svdocirc.cxx:374
constexpr TypedWhichId< XLineStartItem > XATTR_LINESTART(XATTR_LINE_FIRST+4)
virtual void SetObjectItemDirect(const SfxPoolItem &rItem)=0
void ShearPoint(Point &rPnt, const Point &rRef, double tn, bool bVShear=false)
Definition: svdtrans.hxx:123
double getHeight() const
tools::Long AdjustRight(tools::Long nHorzMoveDelta)
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:950
virtual OUString TakeObjNameSingul() const override
Definition: svdocirc.cxx:311
const Point & GetStart() const
Definition: svddrag.hxx:92
static Point GetAnglePnt(const tools::Rectangle &rR, Degree100 nAngle)
Definition: svdocirc.cxx:53
rectangle (round corners optional)
Definition: svdobjkind.hxx:30
Point BottomLeft() const
GeoStat aGeo
Definition: svdotext.hxx:185
SdrHdlKind
Definition: svdhdl.hxx:52
static OUString GetAngleString(Degree100 nAngle)
Definition: svdmodel.cxx:1205
long Long
bool ImpCanConvTextToCurve() const
Definition: svdotxtr.cxx:424
constexpr TypedWhichId< XFillStyleItem > XATTR_FILLSTYLE(XATTR_FILL_FIRST)
virtual basegfx::B2DPolyPolygon TakeXorPoly() const override
The Xor-Polygon is required by the View to drag the object.
Definition: svdocirc.cxx:387
constexpr TypedWhichId< XLineWidthItem > XATTR_LINEWIDTH(XATTR_LINE_FIRST+2)
double mfSinRotationAngle
Definition: svdtrans.hxx:220
sal_uInt32 GetPointNum() const
Definition: svdhdl.hxx:222
virtual void SetBoundRectDirty()
Definition: svdobj.cxx:310
aBuf
virtual void RecalcSnapRect() override
Snap is not done on the BoundRect but if possible on logic coordinates (i.e.
Definition: svdocirc.cxx:1035
static void Union(tools::Rectangle &rR, const Point &rP)
Definition: svdocirc.cxx:973
circle section
Definition: svdobjkind.hxx:32
tools::Long GetWidth() const
SdrObjectUniquePtr ImpConvertAddText(SdrObjectUniquePtr pObj, bool bBezier) const
Definition: svdotxtr.cxx:463
constexpr TypedWhichId< XLineStyleItem > XATTR_LINESTYLE(XATTR_LINE_FIRST)
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:1146
virtual sdr::properties::BaseProperties & GetProperties() const
Definition: svdobj.cxx:204
virtual void TakeUnrotatedSnapRect(tools::Rectangle &rRect) const override
Definition: svdocirc.cxx:981
virtual const tools::Rectangle & GetSnapRect() const override
Definition: svdoattr.cxx:44
All geometrical data of an arbitrary object for use in undo/redo.
Definition: svdobj.hxx:175
Degree100 nEndAngle
Definition: svdocirc.hxx:55
SdrObjKind
Definition: svdobjkind.hxx:24
void SetRight(tools::Long v)
virtual bool HasText() const override
Definition: svdotxat.cxx:416
constexpr TypedWhichId< SdrCircKindItem > SDRATTR_CIRCKIND(SDRATTR_CIRC_FIRST+0)
SdrCircKind ToSdrCircKind(SdrObjKind eKind)
Definition: svdocirc.cxx:104
bool bSnapRectDirty
Definition: svdobj.hxx:882
virtual void NbcMirror(const Point &rRef1, const Point &rRef2) override
Definition: svdotxtr.cxx:232
Point RightCenter() const
circle, ellipse
Definition: svdobjkind.hxx:31
Rectangle objects (rectangle, circle, ...)
Definition: svdorect.hxx:39
Provides information about various ZObject properties.
Definition: svdobj.hxx:197
const SdrHdl * GetHdl() const
Definition: svddrag.hxx:101
virtual void BrkCreate(SdrDragStat &rStat) override
Definition: svdocirc.cxx:771
virtual bool hasSpecialDrag() const override
The standard transformations (Move,Resize,Rotate,Mirror,Shear) are taken over by the View (TakeXorPol...
Definition: svdocirc.cxx:502
constexpr TypedWhichId< SdrAngleItem > SDRATTR_CIRCENDANGLE(SDRATTR_CIRC_FIRST+2)
double getWidth() const
tools::Long Left() const
virtual void NbcShear(const Point &rRef, Degree100 nAngle, double tn, bool bVShear) override
Definition: svdocirc.cxx:882
void SetLeft(tools::Long v)
OUString SvxResId(const char *pId)
Definition: dialmgr.cxx:25
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
virtual void SaveGeoData(SdrObjGeoData &rGeo) const override
Definition: svdotext.cxx:1440
virtual void TakeObjInfo(SdrObjTransformInfoRec &rInfo) const override
Definition: svdocirc.cxx:160
virtual bool MovCreate(SdrDragStat &rStat) override
Definition: svdocirc.cxx:716
Degree100 nStartAngle
Definition: svdocirc.hxx:54
Point BottomCenter() const
virtual Point GetSnapPoint(sal_uInt32 i) const override
Definition: svdocirc.cxx:1072
tools::Long Bottom() const
const SfxItemSet & GetObjectItemSet() const
Definition: svdobj.cxx:1897
virtual bool BckCreate(SdrDragStat &rStat) override
Definition: svdocirc.cxx:776
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)
Degree100 NormAngle36000(Degree100 deg100)
Normalize angle to -180.00..179.99.
Definition: svdtrans.cxx:408
tools::Long BigMulDiv(tools::Long nVal, tools::Long nMul, tools::Long nDiv)
Definition: svdtrans.cxx:560
bool bClosedObj
Definition: svdobj.hxx:895
virtual void NbcShear(const Point &rRef, Degree100 nAngle, double tn, bool bVShear) override
Definition: svdotxtr.cxx:210
tools::Rectangle maSnapRect
Definition: svdoattr.hxx:42
Point LeftCenter() const
double mfTanShearAngle
Definition: svdtrans.hxx:219
virtual sal_uInt32 GetSnapPointCount() const override
snap to special points of an Object (polygon points, center of circle)
Definition: svdocirc.cxx:1063
virtual void AddToHdlList(SdrHdlList &rHdlList) const override
Definition: svdocirc.cxx:429
SdrCircKind meCircleKind
Definition: svdocirc.hxx:53
SVX_DLLPRIVATE void ImpSetCircInfoToAttr()
Definition: svdocirc.cxx:1114
Point BottomRight() const
void SetNoSnap(bool bOn=true)
Definition: svddrag.hxx:121
UNDERLYING_TYPE get() const
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:128
#define F_PI
constexpr TypedWhichId< XLineStartWidthItem > XATTR_LINESTARTWIDTH(XATTR_LINE_FIRST+6)
virtual SdrObjKind GetObjIdentifier() const override
Definition: svdocirc.cxx:169
uno_Any a
OUString sName
SdrObject * GetCreateObj() const
Definition: svdcrtv.hxx:116
tools::Long FRound(double fVal)
tools::Rectangle aOutRect
Definition: svdobj.hxx:875
SdrPathObjUniquePtr ImpConvertMakeObj(const basegfx::B2DPolyPolygon &rPolyPolygon, bool bClosed, bool bBezier) const
Definition: svdotxtr.cxx:429
Degree100 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:386
constexpr TypedWhichId< XLineEndWidthItem > XATTR_LINEENDWIDTH(XATTR_LINE_FIRST+7)
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:104
SdrView * GetView() const
Definition: svddrag.hxx:86
bool IsAngleSnapEnabled() const
Definition: svdsnpv.hxx:223
void SetXPolyDirty()
Definition: svdorect.cxx:94
virtual void SaveGeoData(SdrObjGeoData &rGeo) const override
Definition: svdocirc.cxx:955
void SetTop(tools::Long v)
void SetBottom(tools::Long v)
virtual void NbcResize(const Point &rRef, const Fraction &xFact, const Fraction &yFact) override
Definition: svdocirc.cxx:831
virtual bool beginSpecialDrag(SdrDragStat &rDrag) const override
Definition: svdocirc.cxx:507
Degree100 GetSnapAngle() const
Definition: svdsnpv.hxx:225
tools::Long Top() const
virtual bool BegCreate(SdrDragStat &rStat) override
Every object must be able to create itself interactively.
Definition: svdocirc.cxx:705
virtual ~SdrCircObj() override
Definition: svdocirc.cxx:156
SdrAngleItem makeSdrCircStartAngleItem(Degree100 nAngle)
Definition: sxciaitm.hxx:25
Degree100 nStartAngle
Definition: svdocirc.hxx:35
OUString GetName() const
Definition: svdobj.cxx:701
void transform(const basegfx::B2DHomMatrix &rMatrix)
basegfx::B2DRange b2DRectangleFromRectangle(const ::tools::Rectangle &rRect)
Degree100 nEndAngle
Definition: svdocirc.hxx:36
void append(const B2DPolygon &rPolygon, sal_uInt32 nCount=1)
SdrRectObj & operator=(const SdrRectObj &rCopy)
Definition: svdorect.cxx:251
void setClosed(bool bNew)
void RotatePoint(Point &rPnt, const Point &rRef, double sn, double cs)
Definition: svdtrans.hxx:115
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:783
sal_Int32 GetDenominator() const
virtual void RestGeoData(const SdrObjGeoData &rGeo) override
Definition: svdocirc.cxx:963
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:889
OUString ImpGetDescriptionStr(const char *pStrCacheID) const
Definition: svdobj.cxx:1041
virtual sal_uInt32 GetHdlCount() const override
Via GetHdlCount the number of Handles can be retrieved.
Definition: svdocirc.cxx:417
Degree100 nRotationAngle
Definition: svdtrans.hxx:217
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
double mfCosRotationAngle
Definition: svdtrans.hxx:221
#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:810
sal_Int32 GetNumerator() const
virtual bool EndCreate(SdrDragStat &rStat, SdrCreateCmd eCmd) override
Definition: svdocirc.cxx:739
std::unique_ptr< SdrObject, SdrObjectFreeOp > SdrObjectUniquePtr
Definition: svdobj.hxx:99
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:1288
PointerStyle
SVX_DLLPRIVATE void ImpSetAttrToCircInfo()
Definition: svdocirc.cxx:1089
virtual void RestGeoData(const SdrObjGeoData &rGeo) override
Definition: svdorect.cxx:577
virtual void SetRectsDirty(bool bNotMyself=false, bool bRecursive=true)
Definition: svdobj.cxx:435
tools::Long GetHeight() const
void Move(tools::Long nHorzMoveDelta, tools::Long nVertMoveDelta)
virtual void NbcMove(const Size &aSiz) override
The methods Move, Resize, Rotate, Mirror, Shear, SetSnapRect and SetLogicRect call the corresponding ...
Definition: svdocirc.cxx:822
tools::Long AdjustLeft(tools::Long nHorzMoveDelta)
bool LineGeometryUsageIsNecessary() const
Definition: svdobj.cxx:965
SVX_DLLPRIVATE basegfx::B2DPolygon ImpCalcXPolyCirc(const SdrCircKind eKind, const tools::Rectangle &rRect1, Degree100 nStart, Degree100 nEnd) const
Definition: svdocirc.cxx:232
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:1044
B2DHomMatrix createTranslateB2DHomMatrix(double fTranslateX, double fTranslateY)
SdrCreateCmd
Definition: svdtypes.hxx:27
SdrAngleItem makeSdrCircEndAngleItem(Degree100 nAngle)
Definition: sxciaitm.hxx:30
virtual void SetChanged()
Definition: svdobj.cxx:932
circle arc
Definition: svdobjkind.hxx:33
static void ImpJustifyRect(tools::Rectangle &rRect)
Definition: svdotext.cxx:374
Degree100 nShearAngle
Definition: svdtrans.hxx:218
Point TopRight() const
tools::Long Right() const
Point Center() const
void AddHdl(std::unique_ptr< SdrHdl > pHdl)
Definition: svdhdl.cxx:2289
constexpr TypedWhichId< SdrAngleItem > SDRATTR_CIRCSTARTANGLE(SDRATTR_CIRC_FIRST+1)
virtual bool IsFontwork() const
Definition: svdotext.cxx:1732
Point TopCenter() const
virtual SdrCircObj * CloneSdrObject(SdrModel &rTargetModel) const override
Definition: svdocirc.cxx:369
SdrHdlKind GetKind() const
Definition: svdhdl.hxx:194
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Detects when a stylesheet is changed.
Definition: svdorect.cxx:571
virtual std::unique_ptr< sdr::contact::ViewContact > CreateObjectSpecificViewContact() override
Definition: svdocirc.cxx:99