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  m_bClosedObj=eNewKind!=SdrCircKind::Arc;
126 }
127 
128 SdrCircObj::SdrCircObj(SdrModel& rSdrModel, SdrCircObj const & rSource)
129 : SdrRectObj(rSdrModel, rSource)
130 {
131  meCircleKind = rSource.meCircleKind;
132  nStartAngle = rSource.nStartAngle;
133  nEndAngle = rSource.nEndAngle;
134  m_bClosedObj = rSource.m_bClosedObj;
135 }
136 
138  SdrModel& rSdrModel,
139  SdrCircKind eNewKind,
140  const tools::Rectangle& rRect)
141 : SdrRectObj(rSdrModel, rRect)
142 {
143  nStartAngle=0_deg100;
144  nEndAngle=36000_deg100;
145  meCircleKind=eNewKind;
146  m_bClosedObj=eNewKind!=SdrCircKind::Arc;
147 }
148 
150  SdrModel& rSdrModel,
151  SdrCircKind eNewKind,
152  const tools::Rectangle& rRect,
153  Degree100 nNewStartAngle,
154  Degree100 nNewEndAngle)
155 : SdrRectObj(rSdrModel, rRect)
156 {
157  Degree100 nAngleDif=nNewEndAngle-nNewStartAngle;
158  nStartAngle=NormAngle36000(nNewStartAngle);
159  nEndAngle=NormAngle36000(nNewEndAngle);
160  if (nAngleDif==36000_deg100) nEndAngle+=nAngleDif; // full circle
161  meCircleKind=eNewKind;
162  m_bClosedObj=eNewKind!=SdrCircKind::Arc;
163 }
164 
166 {
167 }
168 
170 {
171  bool bCanConv=!HasText() || ImpCanConvTextToCurve();
172  rInfo.bEdgeRadiusAllowed = false;
173  rInfo.bCanConvToPath=bCanConv;
174  rInfo.bCanConvToPoly=bCanConv;
176 }
177 
179 {
180  switch (meCircleKind)
181  {
182  case SdrCircKind::Full: return OBJ_CIRC;
183  case SdrCircKind::Section: return OBJ_SECT;
184  case SdrCircKind::Cut: return OBJ_CCUT;
185  case SdrCircKind::Arc: return OBJ_CARC;
186  default: assert(false);
187  }
188  return OBJ_CIRC;
189 }
190 
192 {
193  // XPoly is necessary for all rotated ellipse objects, circle and
194  // ellipse segments.
195  // If not WIN, then (for now) also for circle/ellipse segments and circle/
196  // ellipse arcs (for precision)
198  // If not WIN, then for everything except full circle (for now!)
199  if (meCircleKind!=SdrCircKind::Full) bNeed = true;
200 
201  const SfxItemSet& rSet = GetObjectItemSet();
202  if(!bNeed)
203  {
204  // XPoly is necessary for everything that isn't LineSolid or LineNone
205  drawing::LineStyle eLine = rSet.Get(XATTR_LINESTYLE).GetValue();
206  bNeed = eLine != drawing::LineStyle_NONE && eLine != drawing::LineStyle_SOLID;
207 
208  // XPoly is necessary for thick lines
209  if(!bNeed && eLine != drawing::LineStyle_NONE)
210  bNeed = rSet.Get(XATTR_LINEWIDTH).GetValue() != 0;
211 
212  // XPoly is necessary for circle arcs with line ends
213  if(!bNeed && meCircleKind == SdrCircKind::Arc)
214  {
215  // start of the line is here if StartPolygon, StartWidth!=0
216  bNeed=rSet.Get(XATTR_LINESTART).GetLineStartValue().count() != 0 &&
217  rSet.Get(XATTR_LINESTARTWIDTH).GetValue() != 0;
218 
219  if(!bNeed)
220  {
221  // end of the line is here if EndPolygon, EndWidth!=0
222  bNeed = rSet.Get(XATTR_LINEEND).GetLineEndValue().count() != 0 &&
223  rSet.Get(XATTR_LINEENDWIDTH).GetValue() != 0;
224  }
225  }
226  }
227 
228  // XPoly is necessary if Fill !=None and !=Solid
229  if(!bNeed && meCircleKind != SdrCircKind::Arc)
230  {
231  drawing::FillStyle eFill=rSet.Get(XATTR_FILLSTYLE).GetValue();
232  bNeed = eFill != drawing::FillStyle_NONE && eFill != drawing::FillStyle_SOLID;
233  }
234 
235  if(!bNeed && meCircleKind != SdrCircKind::Full && nStartAngle == nEndAngle)
236  bNeed = true; // otherwise we're drawing a full circle
237 
238  return bNeed;
239 }
240 
242 {
244  basegfx::B2DPolygon aCircPolygon;
245 
246  if(SdrCircKind::Full == eCircleKind)
247  {
248  // create full circle. Do not use createPolygonFromEllipse; it's necessary
249  // to get the start point to the bottom of the circle to keep compatible to
250  // old geometry creation
252 
253  // needs own scaling and translation from unit circle to target size (same as
254  // would be in createPolygonFromEllipse)
255  const basegfx::B2DPoint aCenter(aRange.getCenter());
257  aRange.getWidth() / 2.0, aRange.getHeight() / 2.0,
258  aCenter.getX(), aCenter.getY()));
259  aCircPolygon.transform(aMatrix);
260  }
261  else
262  {
263  // mirror start, end for geometry creation since model coordinate system is mirrored in Y
264  // #i111715# increase numerical correctness by first dividing and not using F_PI1800
265  const double fStart((((36000 - nEnd.get()) % 36000) / 18000.0) * F_PI);
266  const double fEnd((((36000 - nStart.get()) % 36000) / 18000.0) * F_PI);
267 
268  // create circle segment. This is not closed by default
270  aRange.getCenter(), aRange.getWidth() / 2.0, aRange.getHeight() / 2.0,
271  fStart, fEnd);
272 
273  // check closing states
274  const bool bCloseSegment(SdrCircKind::Arc != eCircleKind);
275  const bool bCloseUsingCenter(SdrCircKind::Section == eCircleKind);
276 
277  if(bCloseSegment)
278  {
279  if(bCloseUsingCenter)
280  {
281  // add center point at start (for historical reasons)
282  basegfx::B2DPolygon aSector;
283  aSector.append(aRange.getCenter());
284  aSector.append(aCircPolygon);
285  aCircPolygon = aSector;
286  }
287 
288  // close
289  aCircPolygon.setClosed(true);
290  }
291  }
292 
293  // #i76950#
295  {
296  // translate top left to (0,0)
297  const basegfx::B2DPoint aTopLeft(aRange.getMinimum());
299  -aTopLeft.getX(), -aTopLeft.getY()));
300 
301  // shear, rotate and back to top left (if needed)
304  maGeo.nRotationAngle ? (36000_deg100 - maGeo.nRotationAngle).get() * F_PI18000 : 0.0,
305  aTopLeft) * aMatrix;
306 
307  // apply transformation
308  aCircPolygon.transform(aMatrix);
309  }
310 
311  return aCircPolygon;
312 }
313 
315 {
317  mpXPoly = XPolygon(aPolyCirc);
318 }
319 
321 {
322  TranslateId pID=STR_ObjNameSingulCIRC;
323  if (maRect.GetWidth() == maRect.GetHeight() && maGeo.nShearAngle==0_deg100)
324  {
325  switch (meCircleKind) {
326  case SdrCircKind::Full: pID=STR_ObjNameSingulCIRC; break;
327  case SdrCircKind::Section: pID=STR_ObjNameSingulSECT; break;
328  case SdrCircKind::Arc: pID=STR_ObjNameSingulCARC; break;
329  case SdrCircKind::Cut: pID=STR_ObjNameSingulCCUT; break;
330  default: break;
331  }
332  } else {
333  switch (meCircleKind) {
334  case SdrCircKind::Full: pID=STR_ObjNameSingulCIRCE; break;
335  case SdrCircKind::Section: pID=STR_ObjNameSingulSECTE; break;
336  case SdrCircKind::Arc: pID=STR_ObjNameSingulCARCE; break;
337  case SdrCircKind::Cut: pID=STR_ObjNameSingulCCUTE; break;
338  default: break;
339  }
340  }
341  OUString sName(SvxResId(pID));
342 
343  OUString aName(GetName());
344  if (!aName.isEmpty())
345  sName += " '" + aName + "'";
346  return sName;
347 }
348 
350 {
351  TranslateId pID=STR_ObjNamePluralCIRC;
352  if (maRect.GetWidth() == maRect.GetHeight() && maGeo.nShearAngle==0_deg100)
353  {
354  switch (meCircleKind) {
355  case SdrCircKind::Full: pID=STR_ObjNamePluralCIRC; break;
356  case SdrCircKind::Section: pID=STR_ObjNamePluralSECT; break;
357  case SdrCircKind::Arc: pID=STR_ObjNamePluralCARC; break;
358  case SdrCircKind::Cut: pID=STR_ObjNamePluralCCUT; break;
359  default: break;
360  }
361  } else {
362  switch (meCircleKind) {
363  case SdrCircKind::Full: pID=STR_ObjNamePluralCIRCE; break;
364  case SdrCircKind::Section: pID=STR_ObjNamePluralSECTE; break;
365  case SdrCircKind::Arc: pID=STR_ObjNamePluralCARCE; break;
366  case SdrCircKind::Cut: pID=STR_ObjNamePluralCCUTE; break;
367  default: break;
368  }
369  }
370  return SvxResId(pID);
371 }
372 
374 {
375  return new SdrCircObj(rTargetModel, *this);
376 }
377 
379 {
381  return basegfx::B2DPolyPolygon(aCircPolygon);
382 }
383 
384 namespace {
385 
386 struct ImpCircUser : public SdrDragStatUserData
387 {
388  tools::Rectangle aR;
389  Point aCenter;
390  Point aP1;
391  tools::Long nHgt;
392  tools::Long nWdt;
393  Degree100 nStart;
394  Degree100 nEnd;
395 
396 public:
397  ImpCircUser()
398  : nHgt(0),
399  nWdt(0),
400  nStart(0),
401  nEnd(0)
402  {}
403  void SetCreateParams(SdrDragStat const & rStat);
404 };
405 
406 }
407 
408 sal_uInt32 SdrCircObj::GetHdlCount() const
409 {
411  {
412  return 10;
413  }
414  else
415  {
416  return 8;
417  }
418 }
419 
421 {
422  for (sal_uInt32 nHdlNum=(SdrCircKind::Full==meCircleKind)?2:0; nHdlNum<=9; ++nHdlNum)
423  {
424  Point aPnt;
425  SdrHdlKind eLocalKind(SdrHdlKind::Move);
426  sal_uInt32 nPNum(0);
427 
428  switch (nHdlNum)
429  {
430  case 0:
432  eLocalKind = SdrHdlKind::Circle;
433  nPNum = 1;
434  break;
435  case 1:
436  aPnt = GetAnglePnt(maRect,nEndAngle);
437  eLocalKind = SdrHdlKind::Circle;
438  nPNum = 2;
439  break;
440  case 2:
441  aPnt = maRect.TopLeft();
442  eLocalKind = SdrHdlKind::UpperLeft;
443  break;
444  case 3:
445  aPnt = maRect.TopCenter();
446  eLocalKind = SdrHdlKind::Upper;
447  break;
448  case 4:
449  aPnt = maRect.TopRight();
450  eLocalKind = SdrHdlKind::UpperRight;
451  break;
452  case 5:
453  aPnt = maRect.LeftCenter();
454  eLocalKind = SdrHdlKind::Left;
455  break;
456  case 6:
457  aPnt = maRect.RightCenter();
458  eLocalKind = SdrHdlKind::Right;
459  break;
460  case 7:
461  aPnt = maRect.BottomLeft();
462  eLocalKind = SdrHdlKind::LowerLeft;
463  break;
464  case 8:
465  aPnt = maRect.BottomCenter();
466  eLocalKind = SdrHdlKind::Lower;
467  break;
468  case 9:
469  aPnt = maRect.BottomRight();
470  eLocalKind = SdrHdlKind::LowerRight;
471  break;
472  }
473 
474  if (maGeo.nShearAngle)
475  {
477  }
478 
479  if (maGeo.nRotationAngle)
480  {
482  }
483 
484  std::unique_ptr<SdrHdl> pH(new SdrHdl(aPnt,eLocalKind));
485  pH->SetPointNum(nPNum);
486  pH->SetObj(const_cast<SdrCircObj*>(this));
487  pH->SetRotationAngle(maGeo.nRotationAngle);
488  rHdlList.AddHdl(std::move(pH));
489  }
490 }
491 
492 
494 {
495  return true;
496 }
497 
499 {
500  const bool bAngle(rDrag.GetHdl() && SdrHdlKind::Circle == rDrag.GetHdl()->GetKind());
501 
502  if(bAngle)
503  {
504  if(1 == rDrag.GetHdl()->GetPointNum() || 2 == rDrag.GetHdl()->GetPointNum())
505  {
506  rDrag.SetNoSnap();
507  }
508 
509  return true;
510  }
511 
512  return SdrTextObj::beginSpecialDrag(rDrag);
513 }
514 
516 {
517  const bool bAngle(rDrag.GetHdl() && SdrHdlKind::Circle == rDrag.GetHdl()->GetKind());
518 
519  if(bAngle)
520  {
521  Point aPt(rDrag.GetNow());
522 
523  if (maGeo.nRotationAngle)
525 
526  if (maGeo.nShearAngle)
528 
529  aPt -= maRect.Center();
530 
531  tools::Long nWdt = maRect.Right() - maRect.Left();
532  tools::Long nHgt = maRect.Bottom() - maRect.Top();
533 
534  if(nWdt>=nHgt)
535  {
536  aPt.setY(BigMulDiv(aPt.Y(),nWdt,nHgt) );
537  }
538  else
539  {
540  aPt.setX(BigMulDiv(aPt.X(),nHgt,nWdt) );
541  }
542 
543  Degree100 nAngle=NormAngle36000(GetAngle(aPt));
544 
545  if (rDrag.GetView() && rDrag.GetView()->IsAngleSnapEnabled())
546  {
547  Degree100 nSA=rDrag.GetView()->GetSnapAngle();
548 
549  if (nSA)
550  {
551  nAngle+=nSA/2_deg100;
552  nAngle/=nSA;
553  nAngle*=nSA;
554  nAngle=NormAngle36000(nAngle);
555  }
556  }
557 
558  if(1 == rDrag.GetHdl()->GetPointNum())
559  {
560  nStartAngle = nAngle;
561  }
562  else if(2 == rDrag.GetHdl()->GetPointNum())
563  {
564  nEndAngle = nAngle;
565  }
566 
568  SetXPolyDirty();
570  SetChanged();
571 
572  return true;
573  }
574  else
575  {
576  return SdrTextObj::applySpecialDrag(rDrag);
577  }
578 }
579 
580 OUString SdrCircObj::getSpecialDragComment(const SdrDragStat& rDrag) const
581 {
582  const bool bCreateComment(rDrag.GetView() && this == rDrag.GetView()->GetCreateObj());
583 
584  if(bCreateComment)
585  {
586  OUStringBuffer aBuf(ImpGetDescriptionStr(STR_ViewCreateObj));
587  const sal_uInt32 nPointCount(rDrag.GetPointCount());
588 
589  if(SdrCircKind::Full != meCircleKind && nPointCount > 2)
590  {
591  const ImpCircUser* pU = static_cast<const ImpCircUser*>(rDrag.GetUser());
592  Degree100 nAngle;
593 
594  aBuf.append(" (");
595 
596  if(3 == nPointCount)
597  {
598  nAngle = pU->nStart;
599  }
600  else
601  {
602  nAngle = pU->nEnd;
603  }
604 
605  aBuf.append(SdrModel::GetAngleString(nAngle));
606  aBuf.append(')');
607  }
608 
609  return aBuf.makeStringAndClear();
610  }
611  else
612  {
613  const bool bAngle(rDrag.GetHdl() && SdrHdlKind::Circle == rDrag.GetHdl()->GetKind());
614 
615  if(bAngle)
616  {
617  const Degree100 nAngle(1 == rDrag.GetHdl()->GetPointNum() ? nStartAngle : nEndAngle);
618 
619  return ImpGetDescriptionStr(STR_DragCircAngle) +
620  " (" +
621  SdrModel::GetAngleString(nAngle) +
622  ")";
623  }
624  else
625  {
626  return SdrTextObj::getSpecialDragComment(rDrag);
627  }
628  }
629 }
630 
631 
632 void ImpCircUser::SetCreateParams(SdrDragStat const & rStat)
633 {
634  rStat.TakeCreateRect(aR);
635  aR.Justify();
636  aCenter=aR.Center();
637  nWdt=aR.Right()-aR.Left();
638  nHgt=aR.Bottom()-aR.Top();
639  nStart=0_deg100;
640  nEnd=36000_deg100;
641  if (rStat.GetPointCount()>2) {
642  Point aP(rStat.GetPoint(2)-aCenter);
643  if (nWdt==0) aP.setX(0 );
644  if (nHgt==0) aP.setY(0 );
645  if (nWdt>=nHgt) {
646  if (nHgt!=0) aP.setY(aP.Y()*nWdt/nHgt );
647  } else {
648  if (nWdt!=0) aP.setX(aP.X()*nHgt/nWdt );
649  }
650  nStart=NormAngle36000(GetAngle(aP));
651  if (rStat.GetView()!=nullptr && rStat.GetView()->IsAngleSnapEnabled()) {
652  Degree100 nSA=rStat.GetView()->GetSnapAngle();
653  if (nSA) { // angle snapping
654  nStart+=nSA/2_deg100;
655  nStart/=nSA;
656  nStart*=nSA;
657  nStart=NormAngle36000(nStart);
658  }
659  }
660  aP1 = GetAnglePnt(aR,nStart);
661  nEnd=nStart;
662  } else aP1=aCenter;
663  if (rStat.GetPointCount()<=3)
664  return;
665 
666  Point aP(rStat.GetPoint(3)-aCenter);
667  if (nWdt>=nHgt) {
668  aP.setY(BigMulDiv(aP.Y(),nWdt,nHgt) );
669  } else {
670  aP.setX(BigMulDiv(aP.X(),nHgt,nWdt) );
671  }
672  nEnd=NormAngle36000(GetAngle(aP));
673  if (rStat.GetView()!=nullptr && rStat.GetView()->IsAngleSnapEnabled()) {
674  Degree100 nSA=rStat.GetView()->GetSnapAngle();
675  if (nSA) { // angle snapping
676  nEnd+=nSA/2_deg100;
677  nEnd/=nSA;
678  nEnd*=nSA;
679  nEnd=NormAngle36000(nEnd);
680  }
681  }
682 }
683 
685 {
686  ImpCircUser* pU=static_cast<ImpCircUser*>(rStat.GetUser());
687  if (pU==nullptr) {
688  pU=new ImpCircUser;
689  rStat.SetUser(std::unique_ptr<ImpCircUser>(pU));
690  }
691  pU->SetCreateParams(rStat);
692 }
693 
695 {
696  rStat.SetOrtho4Possible();
697  tools::Rectangle aRect1(rStat.GetStart(), rStat.GetNow());
698  aRect1.Justify();
699  rStat.SetActionRect(aRect1);
700  maRect = aRect1;
701  ImpSetCreateParams(rStat);
702  return true;
703 }
704 
706 {
707  ImpSetCreateParams(rStat);
708  ImpCircUser* pU=static_cast<ImpCircUser*>(rStat.GetUser());
709  rStat.SetActionRect(pU->aR);
710  maRect = pU->aR; // for ObjName
712  nStartAngle=pU->nStart;
713  nEndAngle=pU->nEnd;
715  m_bSnapRectDirty=true;
716  SetXPolyDirty();
717 
718  // #i103058# push current angle settings to ItemSet to
719  // allow FullDrag visualisation
720  if(rStat.GetPointCount() >= 4)
721  {
723  }
724 
725  return true;
726 }
727 
729 {
730  ImpSetCreateParams(rStat);
731  ImpCircUser* pU=static_cast<ImpCircUser*>(rStat.GetUser());
732  bool bRet = false;
735  bRet=rStat.GetPointCount()>=2;
736  if (bRet) {
737  maRect = pU->aR;
739  }
740  } else {
741  rStat.SetNoSnap(rStat.GetPointCount()>=2);
742  rStat.SetOrtho4Possible(rStat.GetPointCount()<2);
743  bRet=rStat.GetPointCount()>=4;
744  if (bRet) {
745  maRect = pU->aR;
747  nStartAngle=pU->nStart;
748  nEndAngle=pU->nEnd;
749  }
750  }
753  SetXPolyDirty();
755  if (bRet)
756  rStat.SetUser(nullptr);
757  return bRet;
758 }
759 
761 {
762  rStat.SetUser(nullptr);
763 }
764 
766 {
767  rStat.SetNoSnap(rStat.GetPointCount()>=3);
768  rStat.SetOrtho4Possible(rStat.GetPointCount()<3);
770 }
771 
773 {
774  const ImpCircUser* pU = static_cast<const ImpCircUser*>(rDrag.GetUser());
775 
776  if(rDrag.GetPointCount() < 4)
777  {
778  // force to OBJ_CIRC to get full visualisation
779  basegfx::B2DPolyPolygon aRetval(ImpCalcXPolyCirc(SdrCircKind::Full, pU->aR, pU->nStart, pU->nEnd));
780 
781  if(3 == rDrag.GetPointCount())
782  {
783  // add edge to first point on ellipse
784  basegfx::B2DPolygon aNew;
785 
786  aNew.append(basegfx::B2DPoint(pU->aCenter.X(), pU->aCenter.Y()));
787  aNew.append(basegfx::B2DPoint(pU->aP1.X(), pU->aP1.Y()));
788  aRetval.append(aNew);
789  }
790 
791  return aRetval;
792  }
793  else
794  {
795  return basegfx::B2DPolyPolygon(ImpCalcXPolyCirc(meCircleKind, pU->aR, pU->nStart, pU->nEnd));
796  }
797 }
798 
800 {
801  switch (meCircleKind) {
802  case SdrCircKind::Full: return PointerStyle::DrawEllipse;
803  case SdrCircKind::Section: return PointerStyle::DrawPie;
804  case SdrCircKind::Arc: return PointerStyle::DrawArc;
805  case SdrCircKind::Cut: return PointerStyle::DrawCircleCut;
806  default: break;
807  } // switch
808  return PointerStyle::Cross;
809 }
810 
811 void SdrCircObj::NbcMove(const Size& aSiz)
812 {
813  maRect.Move(aSiz);
814  m_aOutRect.Move(aSiz);
815  maSnapRect.Move(aSiz);
816  SetXPolyDirty();
818 }
819 
820 void SdrCircObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
821 {
822  Degree100 nAngle0 = maGeo.nRotationAngle;
823  bool bNoShearRota = (maGeo.nRotationAngle == 0_deg100 && maGeo.nShearAngle == 0_deg100);
824  SdrTextObj::NbcResize(rRef,xFact,yFact);
825  bNoShearRota |= (maGeo.nRotationAngle == 0_deg100 && maGeo.nShearAngle == 0_deg100);
827  bool bXMirr=(xFact.GetNumerator()<0) != (xFact.GetDenominator()<0);
828  bool bYMirr=(yFact.GetNumerator()<0) != (yFact.GetDenominator()<0);
829  if (bXMirr || bYMirr) {
830  // At bXMirr!=bYMirr we should actually swap both line ends.
831  // That, however, is pretty bad (because of forced "hard" formatting).
832  // Alternatively, we could implement a bMirrored flag (maybe even
833  // a more general one, e. g. for mirrored text, ...).
835  Degree100 nE0=nEndAngle;
836  if (bNoShearRota) {
837  // the RectObj already mirrors at VMirror because of a 180deg rotation
838  if (! (bXMirr && bYMirr)) {
839  Degree100 nTmp=nS0;
840  nS0=18000_deg100-nE0;
841  nE0=18000_deg100-nTmp;
842  }
843  } else { // mirror contorted ellipses
844  if (bXMirr!=bYMirr) {
845  nS0+=nAngle0;
846  nE0+=nAngle0;
847  if (bXMirr) {
848  Degree100 nTmp=nS0;
849  nS0=18000_deg100-nE0;
850  nE0=18000_deg100-nTmp;
851  }
852  if (bYMirr) {
853  Degree100 nTmp=nS0;
854  nS0=-nE0;
855  nE0=-nTmp;
856  }
857  nS0 -= maGeo.nRotationAngle;
858  nE0 -= maGeo.nRotationAngle;
859  }
860  }
861  Degree100 nAngleDif=nE0-nS0;
864  if (nAngleDif==36000_deg100) nEndAngle+=nAngleDif; // full circle
865  }
866  }
867  SetXPolyDirty();
869 }
870 
871 void SdrCircObj::NbcShear(const Point& rRef, Degree100 nAngle, double tn, bool bVShear)
872 {
873  SdrTextObj::NbcShear(rRef,nAngle,tn,bVShear);
874  SetXPolyDirty();
876 }
877 
878 void SdrCircObj::NbcMirror(const Point& rRef1, const Point& rRef2)
879 {
880  bool bFreeMirr=meCircleKind!=SdrCircKind::Full;
881  Point aTmpPt1;
882  Point aTmpPt2;
883  if (bFreeMirr) { // some preparations for using an arbitrary axis of reflection
884  Point aCenter(maRect.Center());
885  tools::Long nWdt=maRect.GetWidth()-1;
886  tools::Long nHgt=maRect.GetHeight()-1;
887  tools::Long nMaxRad=(std::max(nWdt,nHgt)+1) /2;
888  double a;
889  // starting point
890  a = nStartAngle.get() * F_PI18000;
891  aTmpPt1=Point(FRound(cos(a)*nMaxRad),-FRound(sin(a)*nMaxRad));
892  if (nWdt==0) aTmpPt1.setX(0 );
893  if (nHgt==0) aTmpPt1.setY(0 );
894  aTmpPt1+=aCenter;
895  // finishing point
896  a = nEndAngle.get() * F_PI18000;
897  aTmpPt2=Point(FRound(cos(a)*nMaxRad),-FRound(sin(a)*nMaxRad));
898  if (nWdt==0) aTmpPt2.setX(0 );
899  if (nHgt==0) aTmpPt2.setY(0 );
900  aTmpPt2+=aCenter;
901  if (maGeo.nRotationAngle)
902  {
905  }
906  if (maGeo.nShearAngle)
907  {
910  }
911  }
912  SdrTextObj::NbcMirror(rRef1,rRef2);
913  if (meCircleKind!=SdrCircKind::Full) { // adapt starting and finishing angle
914  MirrorPoint(aTmpPt1,rRef1,rRef2);
915  MirrorPoint(aTmpPt2,rRef1,rRef2);
916  // unrotate:
917  if (maGeo.nRotationAngle)
918  {
919  RotatePoint(aTmpPt1, maRect.TopLeft(), -maGeo.mfSinRotationAngle, maGeo.mfCosRotationAngle); // -sin for reversion
920  RotatePoint(aTmpPt2, maRect.TopLeft(), -maGeo.mfSinRotationAngle, maGeo.mfCosRotationAngle); // -sin for reversion
921  }
922  // unshear:
923  if (maGeo.nShearAngle)
924  {
925  ShearPoint(aTmpPt1, maRect.TopLeft(), -maGeo.mfTanShearAngle); // -tan for reversion
926  ShearPoint(aTmpPt2, maRect.TopLeft(), -maGeo.mfTanShearAngle); // -tan for reversion
927  }
928  Point aCenter(maRect.Center());
929  aTmpPt1-=aCenter;
930  aTmpPt2-=aCenter;
931  // because it's mirrored, the angles are swapped, too
932  nStartAngle=GetAngle(aTmpPt2);
933  nEndAngle =GetAngle(aTmpPt1);
934  Degree100 nAngleDif=nEndAngle-nStartAngle;
935  nStartAngle=NormAngle36000(nStartAngle);
937  if (nAngleDif==36000_deg100) nEndAngle+=nAngleDif; // full circle
938  }
939  SetXPolyDirty();
941 }
942 
943 std::unique_ptr<SdrObjGeoData> SdrCircObj::NewGeoData() const
944 {
945  return std::make_unique<SdrCircObjGeoData>();
946 }
947 
949 {
951  SdrCircObjGeoData& rCGeo=static_cast<SdrCircObjGeoData&>(rGeo);
952  rCGeo.nStartAngle=nStartAngle;
953  rCGeo.nEndAngle =nEndAngle;
954 }
955 
957 {
959  const SdrCircObjGeoData& rCGeo=static_cast<const SdrCircObjGeoData&>(rGeo);
960  nStartAngle=rCGeo.nStartAngle;
961  nEndAngle =rCGeo.nEndAngle;
962  SetXPolyDirty();
964 }
965 
966 static void Union(tools::Rectangle& rR, const Point& rP)
967 {
968  if (rP.X()<rR.Left ()) rR.SetLeft(rP.X() );
969  if (rP.X()>rR.Right ()) rR.SetRight(rP.X() );
970  if (rP.Y()<rR.Top ()) rR.SetTop(rP.Y() );
971  if (rP.Y()>rR.Bottom()) rR.SetBottom(rP.Y() );
972 }
973 
975 {
976  rRect = maRect;
978  const Point aPntStart(GetAnglePnt(maRect,nStartAngle));
979  const Point aPntEnd(GetAnglePnt(maRect,nEndAngle));
982  rRect.SetLeft(maRect.Right() );
983  rRect.SetRight(maRect.Left() );
984  rRect.SetTop(maRect.Bottom() );
985  rRect.SetBottom(maRect.Top() );
986  Union(rRect,aPntStart);
987  Union(rRect,aPntEnd);
988  if ((a<=18000_deg100 && e>=18000_deg100) || (a>e && (a<=18000_deg100 || e>=18000_deg100))) {
989  Union(rRect,maRect.LeftCenter());
990  }
991  if ((a<=27000_deg100 && e>=27000_deg100) || (a>e && (a<=27000_deg100 || e>=27000_deg100))) {
992  Union(rRect,maRect.BottomCenter());
993  }
994  if (a>e) {
995  Union(rRect,maRect.RightCenter());
996  }
997  if ((a<=9000_deg100 && e>=9000_deg100) || (a>e && (a<=9000_deg100 || e>=9000_deg100))) {
998  Union(rRect,maRect.TopCenter());
999  }
1001  Union(rRect,maRect.Center());
1002  }
1003  if (maGeo.nRotationAngle)
1004  {
1005  Point aDst(rRect.TopLeft());
1006  aDst-=maRect.TopLeft();
1007  Point aDst0(aDst);
1009  aDst-=aDst0;
1010  rRect.Move(aDst.X(),aDst.Y());
1011  }
1012  }
1013  if (maGeo.nShearAngle==0_deg100)
1014  return;
1015 
1016  tools::Long nDst = FRound((rRect.Bottom() - rRect.Top()) * maGeo.mfTanShearAngle);
1017  if (maGeo.nShearAngle > 0_deg100)
1018  {
1019  Point aRef(rRect.TopLeft());
1020  rRect.AdjustLeft( -nDst );
1021  Point aTmpPt(rRect.TopLeft());
1023  aTmpPt-=rRect.TopLeft();
1024  rRect.Move(aTmpPt.X(),aTmpPt.Y());
1025  } else {
1026  rRect.AdjustRight( -nDst );
1027  }
1028 }
1029 
1031 {
1032  if (PaintNeedsXPolyCirc()) {
1034  } else {
1036  }
1037 }
1038 
1040 {
1042  {
1043  tools::Rectangle aSR0(GetSnapRect());
1044  tools::Long nWdt0=aSR0.Right()-aSR0.Left();
1045  tools::Long nHgt0=aSR0.Bottom()-aSR0.Top();
1046  tools::Long nWdt1=rRect.Right()-rRect.Left();
1047  tools::Long nHgt1=rRect.Bottom()-rRect.Top();
1048  NbcResize(maSnapRect.TopLeft(),Fraction(nWdt1,nWdt0),Fraction(nHgt1,nHgt0));
1049  NbcMove(Size(rRect.Left()-aSR0.Left(),rRect.Top()-aSR0.Top()));
1050  } else {
1051  maRect=rRect;
1053  }
1055  SetXPolyDirty();
1057 }
1058 
1060 {
1062  return 1;
1063  } else {
1064  return 3;
1065  }
1066 }
1067 
1068 Point SdrCircObj::GetSnapPoint(sal_uInt32 i) const
1069 {
1070  switch (i) {
1071  case 1 : return GetAnglePnt(maRect,nStartAngle);
1072  case 2 : return GetAnglePnt(maRect,nEndAngle);
1073  default: return maRect.Center();
1074  }
1075 }
1076 
1078 {
1079  SetXPolyDirty();
1080  SdrRectObj::Notify(rBC,rHint);
1082 }
1083 
1084 
1086 {
1087  const SfxItemSet& rSet = GetObjectItemSet();
1088  SdrCircKind eNewKind = rSet.Get(SDRATTR_CIRCKIND).GetValue();
1089 
1090  Degree100 nNewStart = rSet.Get(SDRATTR_CIRCSTARTANGLE).GetValue();
1091  Degree100 nNewEnd = rSet.Get(SDRATTR_CIRCENDANGLE).GetValue();
1092 
1093  bool bKindChg = meCircleKind != eNewKind;
1094  bool bAngleChg = nNewStart != nStartAngle || nNewEnd != nEndAngle;
1095 
1096  if(bKindChg || bAngleChg)
1097  {
1098  meCircleKind = eNewKind;
1099  nStartAngle = nNewStart;
1100  nEndAngle = nNewEnd;
1101 
1102  if(bKindChg || (meCircleKind != SdrCircKind::Full && bAngleChg))
1103  {
1104  SetXPolyDirty();
1106  }
1107  }
1108 }
1109 
1111 {
1112  const SfxItemSet& rSet = GetObjectItemSet();
1113 
1114  SdrCircKind eOldKindA = rSet.Get(SDRATTR_CIRCKIND).GetValue();
1115  Degree100 nOldStartAngle = rSet.Get(SDRATTR_CIRCSTARTANGLE).GetValue();
1116  Degree100 nOldEndAngle = rSet.Get(SDRATTR_CIRCENDANGLE).GetValue();
1117 
1118  if(meCircleKind == eOldKindA && nStartAngle == nOldStartAngle && nEndAngle == nOldEndAngle)
1119  return;
1120 
1121  // since SetItem() implicitly calls ImpSetAttrToCircInfo()
1122  // setting the item directly is necessary here.
1123  if(meCircleKind != eOldKindA)
1124  {
1126  }
1127 
1128  if(nStartAngle != nOldStartAngle)
1129  {
1131  }
1132 
1133  if(nEndAngle != nOldEndAngle)
1134  {
1136  }
1137 
1138  SetXPolyDirty();
1140 }
1141 
1142 SdrObjectUniquePtr SdrCircObj::DoConvertToPolyObj(bool bBezier, bool bAddText) const
1143 {
1144  const bool bFill(meCircleKind != SdrCircKind::Arc);
1146  SdrObjectUniquePtr pRet = ImpConvertMakeObj(basegfx::B2DPolyPolygon(aCircPolygon), bFill, bBezier);
1147 
1148  if(bAddText)
1149  {
1150  pRet = ImpConvertAddText(std::move(pRet), bBezier);
1151  }
1152 
1153  return pRet;
1154 }
1155 
1156 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SdrCircKind
Definition: svdocirc.hxx:38
B2DPolygon const & createPolygonFromUnitCircle(sal_uInt32 nStartQuadrant=0)
static SVX_DLLPRIVATE void ImpSetCreateParams(SdrDragStat &rStat)
Definition: svdocirc.cxx:684
B2DPoint getCenter() const
virtual void NbcResize(const Point &rRef, const Fraction &xFact, const Fraction &yFact) override
Definition: svdotxtr.cxx:102
virtual void RestoreGeoData(const SdrObjGeoData &rGeo) override
Definition: svdorect.cxx:562
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:1077
constexpr TypedWhichId< XLineEndItem > XATTR_LINEEND(XATTR_LINE_FIRST+5)
tools::Rectangle GetBoundRect() const
Definition: _xpoly.cxx:396
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:122
double getHeight() const
tools::Long AdjustRight(tools::Long nHorzMoveDelta)
bool m_bClosedObj
Definition: svdobj.hxx:896
virtual OUString TakeObjNameSingul() const override
Definition: svdocirc.cxx:320
constexpr tools::Long Left() const
const Point & GetStart() const
Definition: svddrag.hxx:102
static Point GetAnglePnt(const tools::Rectangle &rR, Degree100 nAngle)
Definition: svdocirc.cxx:53
rectangle (round corners optional)
Definition: svdobjkind.hxx:30
SdrHdlKind
Definition: svdhdl.hxx:52
static OUString GetAngleString(Degree100 nAngle)
Definition: svdmodel.cxx:1096
constexpr Point RightCenter() const
std::optional< XPolygon > mpXPoly
Definition: svdorect.hxx:49
long Long
virtual void RestoreGeoData(const SdrObjGeoData &rGeo) override
Definition: svdocirc.cxx:956
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:378
constexpr TypedWhichId< XLineWidthItem > XATTR_LINEWIDTH(XATTR_LINE_FIRST+2)
double mfSinRotationAngle
Definition: svdtrans.hxx:219
sal_uInt32 GetPointNum() const
Definition: svdhdl.hxx:222
virtual void SetBoundRectDirty()
Definition: svdobj.cxx:316
aBuf
virtual void RecalcSnapRect() override
Snap is not done on the BoundRect but if possible on logic coordinates (i.e.
Definition: svdocirc.cxx:1030
static void Union(tools::Rectangle &rR, const Point &rP)
Definition: svdocirc.cxx:966
circle section
Definition: svdobjkind.hxx:32
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:100
constexpr Point BottomCenter() const
tools::Rectangle m_aOutRect
Definition: svdobj.hxx:876
virtual bool applySpecialDrag(SdrDragStat &rDrag) override
Definition: svdocirc.cxx:515
virtual SdrObjectUniquePtr DoConvertToPolyObj(bool bBezier, bool bAddText) const override
Definition: svdocirc.cxx:1142
virtual sdr::properties::BaseProperties & GetProperties() const
Definition: svdobj.cxx:210
virtual void TakeUnrotatedSnapRect(tools::Rectangle &rRect) const override
Definition: svdocirc.cxx:974
virtual const tools::Rectangle & GetSnapRect() const override
Definition: svdoattr.cxx:49
All geometrical data of an arbitrary object for use in undo/redo.
Definition: svdobj.hxx:173
Degree100 nEndAngle
Definition: svdocirc.hxx:54
SdrObjKind
Definition: svdobjkind.hxx:24
virtual bool HasText() const override
Definition: svdotxat.cxx:417
constexpr TypedWhichId< SdrCircKindItem > SDRATTR_CIRCKIND(SDRATTR_CIRC_FIRST+0)
SdrCircKind ToSdrCircKind(SdrObjKind eKind)
Definition: svdocirc.cxx:104
virtual void NbcMirror(const Point &rRef1, const Point &rRef2) override
Definition: svdotxtr.cxx:232
circle, ellipse
Definition: svdobjkind.hxx:31
Rectangle objects (rectangle, circle, ...)
Definition: svdorect.hxx:38
Provides information about various ZObject properties.
Definition: svdobj.hxx:195
const SdrHdl * GetHdl() const
Definition: svddrag.hxx:111
virtual void BrkCreate(SdrDragStat &rStat) override
Definition: svdocirc.cxx:760
virtual bool hasSpecialDrag() const override
The standard transformations (Move,Resize,Rotate,Mirror,Shear) are taken over by the View (TakeXorPol...
Definition: svdocirc.cxx:493
constexpr TypedWhichId< SdrAngleItem > SDRATTR_CIRCENDANGLE(SDRATTR_CIRC_FIRST+2)
double getWidth() const
virtual void NbcShear(const Point &rRef, Degree100 nAngle, double tn, bool bVShear) override
Definition: svdocirc.cxx:871
virtual void SaveGeoData(SdrObjGeoData &rGeo) const override
Definition: svdotext.cxx:1408
virtual void TakeObjInfo(SdrObjTransformInfoRec &rInfo) const override
Definition: svdocirc.cxx:169
virtual bool MovCreate(SdrDragStat &rStat) override
Definition: svdocirc.cxx:705
Degree100 nStartAngle
Definition: svdocirc.hxx:53
constexpr Point BottomLeft() const
OUString SvxResId(TranslateId aId)
Definition: dialmgr.cxx:24
constexpr Point TopCenter() const
virtual Point GetSnapPoint(sal_uInt32 i) const override
Definition: svdocirc.cxx:1068
virtual std::unique_ptr< 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:943
const SfxItemSet & GetObjectItemSet() const
Definition: svdobj.cxx:1973
virtual bool BckCreate(SdrDragStat &rStat) override
Definition: svdocirc.cxx:765
tools::Rectangle maRect
Definition: svdotext.hxx:170
void SetOrtho4Possible(bool bOn=true)
Definition: svddrag.hxx:136
constexpr tools::Long GetWidth() const
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:409
tools::Long BigMulDiv(tools::Long nVal, tools::Long nMul, tools::Long nDiv)
Definition: svdtrans.cxx:561
virtual void NbcShear(const Point &rRef, Degree100 nAngle, double tn, bool bVShear) override
Definition: svdotxtr.cxx:210
tools::Rectangle maSnapRect
Definition: svdoattr.hxx:41
double mfTanShearAngle
Definition: svdtrans.hxx:218
virtual sal_uInt32 GetSnapPointCount() const override
snap to special points of an Object (polygon points, center of circle)
Definition: svdocirc.cxx:1059
virtual void AddToHdlList(SdrHdlList &rHdlList) const override
Definition: svdocirc.cxx:420
virtual void SetBoundAndSnapRectsDirty(bool bNotMyself=false, bool bRecursive=true)
Definition: svdobj.cxx:510
SdrCircKind meCircleKind
Definition: svdocirc.hxx:52
constexpr void SetLeft(tools::Long v)
SVX_DLLPRIVATE void ImpSetCircInfoToAttr()
Definition: svdocirc.cxx:1110
void SetNoSnap(bool bOn=true)
Definition: svddrag.hxx:131
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:136
#define F_PI
constexpr TypedWhichId< XLineStartWidthItem > XATTR_LINESTARTWIDTH(XATTR_LINE_FIRST+6)
virtual SdrObjKind GetObjIdentifier() const override
Definition: svdocirc.cxx:178
uno_Any a
OUString sName
SdrObject * GetCreateObj() const
Definition: svdcrtv.hxx:120
tools::Long FRound(double fVal)
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:387
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:101
void MirrorPoint(Point &rPnt, const Point &rRef1, const Point &rRef2)
Definition: svdtrans.cxx:105
OUString ImpGetDescriptionStr(TranslateId pStrCacheID) const
Definition: svdobj.cxx:1097
SdrView * GetView() const
Definition: svddrag.hxx:96
bool IsAngleSnapEnabled() const
Definition: svdsnpv.hxx:222
void SetXPolyDirty()
Definition: svdorect.cxx:102
constexpr tools::Long Right() const
virtual void SaveGeoData(SdrObjGeoData &rGeo) const override
Definition: svdocirc.cxx:948
constexpr tools::Long Top() const
constexpr void SetRight(tools::Long v)
virtual void NbcResize(const Point &rRef, const Fraction &xFact, const Fraction &yFact) override
Definition: svdocirc.cxx:820
constexpr void SetBottom(tools::Long v)
virtual bool beginSpecialDrag(SdrDragStat &rDrag) const override
Definition: svdocirc.cxx:498
Degree100 GetSnapAngle() const
Definition: svdsnpv.hxx:224
virtual bool BegCreate(SdrDragStat &rStat) override
Every object must be able to create itself interactively.
Definition: svdocirc.cxx:694
virtual ~SdrCircObj() override
Definition: svdocirc.cxx:165
SdrAngleItem makeSdrCircStartAngleItem(Degree100 nAngle)
Definition: sxciaitm.hxx:25
Degree100 nStartAngle
Definition: svdocirc.hxx:34
constexpr Point LeftCenter() const
constexpr void SetTop(tools::Long v)
OUString GetName() const
Definition: svdobj.cxx:802
constexpr Point Center() const
void transform(const basegfx::B2DHomMatrix &rMatrix)
constexpr Point TopLeft() const
basegfx::B2DRange b2DRectangleFromRectangle(const ::tools::Rectangle &rRect)
constexpr tools::Long Bottom() const
Degree100 nEndAngle
Definition: svdocirc.hxx:35
void append(const B2DPolygon &rPolygon, sal_uInt32 nCount=1)
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:167
virtual OUString getSpecialDragComment(const SdrDragStat &rDrag) const override
Definition: svdocirc.cxx:580
virtual basegfx::B2DPolyPolygon TakeCreatePoly(const SdrDragStat &rDrag) const override
Polygon dragged by the user when creating the object.
Definition: svdocirc.cxx:772
sal_Int32 GetDenominator() const
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:314
virtual OUString TakeObjNamePlural() const override
Definition: svdocirc.cxx:349
virtual void NbcMirror(const Point &rRef1, const Point &rRef2) override
Definition: svdocirc.cxx:878
GeoStat maGeo
Definition: svdotext.hxx:173
virtual sal_uInt32 GetHdlCount() const override
Via GetHdlCount the number of Handles can be retrieved.
Definition: svdocirc.cxx:408
Degree100 nRotationAngle
Definition: svdtrans.hxx:216
OUString aName
constexpr Point TopRight() const
B2DPolygon createPolygonFromEllipseSegment(const B2DPoint &rCenter, double fRadiusX, double fRadiusY, double fStart, double fEnd)
void SetUser(std::unique_ptr< SdrDragStatUserData > pU)
Definition: svddrag.hxx:114
double mfCosRotationAngle
Definition: svdtrans.hxx:220
#define F_PI18000
B2DPoint getMinimum() const
virtual PointerStyle GetCreatePointer() const override
get the cursor/pointer that signals creating this object
Definition: svdocirc.cxx:799
sal_Int32 GetNumerator() const
virtual bool EndCreate(SdrDragStat &rStat, SdrCreateCmd eCmd) override
Definition: svdocirc.cxx:728
std::unique_ptr< SdrObject, SdrObjectFreeOp > SdrObjectUniquePtr
Definition: svdobj.hxx:97
SdrCircObj(SdrModel &rSdrModel, SdrCircKind eNewKind)
Definition: svdocirc.cxx:117
const Point & GetNow() const
Definition: svddrag.hxx:105
virtual bool beginSpecialDrag(SdrDragStat &rDrag) const
Definition: svdobj.cxx:1344
PointerStyle
SVX_DLLPRIVATE void ImpSetAttrToCircInfo()
Definition: svdocirc.cxx:1085
constexpr Point BottomRight() 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:811
tools::Long AdjustLeft(tools::Long nHorzMoveDelta)
bool LineGeometryUsageIsNecessary() const
Definition: svdobj.cxx:1065
bool m_bSnapRectDirty
Definition: svdobj.hxx:883
SVX_DLLPRIVATE basegfx::B2DPolygon ImpCalcXPolyCirc(const SdrCircKind eKind, const tools::Rectangle &rRect1, Degree100 nStart, Degree100 nEnd) const
Definition: svdocirc.cxx:241
SVX_DLLPRIVATE bool PaintNeedsXPolyCirc() const
Definition: svdocirc.cxx:191
SdrDragStatUserData * GetUser() const
Definition: svddrag.hxx:113
B2DHomMatrix createShearXRotateTranslateB2DHomMatrix(double fShearX, double fRadiant, double fTranslateX, double fTranslateY)
virtual void NbcSetSnapRect(const tools::Rectangle &rRect) override
Definition: svdocirc.cxx:1039
B2DHomMatrix createTranslateB2DHomMatrix(double fTranslateX, double fTranslateY)
SdrCreateCmd
Definition: svdtypes.hxx:26
SdrAngleItem makeSdrCircEndAngleItem(Degree100 nAngle)
Definition: sxciaitm.hxx:30
virtual void SetChanged()
Definition: svdobj.cxx:1032
circle arc
Definition: svdobjkind.hxx:33
static void ImpJustifyRect(tools::Rectangle &rRect)
Definition: svdotext.cxx:420
Degree100 nShearAngle
Definition: svdtrans.hxx:217
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:1711
virtual SdrCircObj * CloneSdrObject(SdrModel &rTargetModel) const override
Definition: svdocirc.cxx:373
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:556
constexpr tools::Long GetHeight() const
virtual std::unique_ptr< sdr::contact::ViewContact > CreateObjectSpecificViewContact() override
Definition: svdocirc.cxx:99