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  aGeo.nRotationAngle ? (36000_deg100 - aGeo.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.reset( new XPolygon(aPolyCirc) );
318 }
319 
321 {
322  const char* pID=STR_ObjNameSingulCIRC;
323  if (maRect.GetWidth() == maRect.GetHeight() && aGeo.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  OUStringBuffer sName(SvxResId(pID));
342 
343  OUString aName(GetName());
344  if (!aName.isEmpty())
345  {
346  sName.append(' ');
347  sName.append('\'');
348  sName.append(aName);
349  sName.append('\'');
350  }
351  return sName.makeStringAndClear();
352 }
353 
355 {
356  const char* pID=STR_ObjNamePluralCIRC;
357  if (maRect.GetWidth() == maRect.GetHeight() && aGeo.nShearAngle==0_deg100)
358  {
359  switch (meCircleKind) {
360  case SdrCircKind::Full: pID=STR_ObjNamePluralCIRC; break;
361  case SdrCircKind::Section: pID=STR_ObjNamePluralSECT; break;
362  case SdrCircKind::Arc: pID=STR_ObjNamePluralCARC; break;
363  case SdrCircKind::Cut: pID=STR_ObjNamePluralCCUT; break;
364  default: break;
365  }
366  } else {
367  switch (meCircleKind) {
368  case SdrCircKind::Full: pID=STR_ObjNamePluralCIRCE; break;
369  case SdrCircKind::Section: pID=STR_ObjNamePluralSECTE; break;
370  case SdrCircKind::Arc: pID=STR_ObjNamePluralCARCE; break;
371  case SdrCircKind::Cut: pID=STR_ObjNamePluralCCUTE; break;
372  default: break;
373  }
374  }
375  return SvxResId(pID);
376 }
377 
379 {
380  return new SdrCircObj(rTargetModel, *this);
381 }
382 
384 {
386  return basegfx::B2DPolyPolygon(aCircPolygon);
387 }
388 
389 namespace {
390 
391 struct ImpCircUser : public SdrDragStatUserData
392 {
393  tools::Rectangle aR;
394  Point aCenter;
395  Point aP1;
396  tools::Long nHgt;
397  tools::Long nWdt;
398  Degree100 nStart;
399  Degree100 nEnd;
400 
401 public:
402  ImpCircUser()
403  : nHgt(0),
404  nWdt(0),
405  nStart(0),
406  nEnd(0)
407  {}
408  void SetCreateParams(SdrDragStat const & rStat);
409 };
410 
411 }
412 
413 sal_uInt32 SdrCircObj::GetHdlCount() const
414 {
416  {
417  return 10;
418  }
419  else
420  {
421  return 8;
422  }
423 }
424 
426 {
427  for (sal_uInt32 nHdlNum=(SdrCircKind::Full==meCircleKind)?2:0; nHdlNum<=9; ++nHdlNum)
428  {
429  Point aPnt;
430  SdrHdlKind eLocalKind(SdrHdlKind::Move);
431  sal_uInt32 nPNum(0);
432 
433  switch (nHdlNum)
434  {
435  case 0:
437  eLocalKind = SdrHdlKind::Circle;
438  nPNum = 1;
439  break;
440  case 1:
441  aPnt = GetAnglePnt(maRect,nEndAngle);
442  eLocalKind = SdrHdlKind::Circle;
443  nPNum = 2;
444  break;
445  case 2:
446  aPnt = maRect.TopLeft();
447  eLocalKind = SdrHdlKind::UpperLeft;
448  break;
449  case 3:
450  aPnt = maRect.TopCenter();
451  eLocalKind = SdrHdlKind::Upper;
452  break;
453  case 4:
454  aPnt = maRect.TopRight();
455  eLocalKind = SdrHdlKind::UpperRight;
456  break;
457  case 5:
458  aPnt = maRect.LeftCenter();
459  eLocalKind = SdrHdlKind::Left;
460  break;
461  case 6:
462  aPnt = maRect.RightCenter();
463  eLocalKind = SdrHdlKind::Right;
464  break;
465  case 7:
466  aPnt = maRect.BottomLeft();
467  eLocalKind = SdrHdlKind::LowerLeft;
468  break;
469  case 8:
470  aPnt = maRect.BottomCenter();
471  eLocalKind = SdrHdlKind::Lower;
472  break;
473  case 9:
474  aPnt = maRect.BottomRight();
475  eLocalKind = SdrHdlKind::LowerRight;
476  break;
477  }
478 
479  if (aGeo.nShearAngle)
480  {
482  }
483 
484  if (aGeo.nRotationAngle)
485  {
487  }
488 
489  std::unique_ptr<SdrHdl> pH(new SdrHdl(aPnt,eLocalKind));
490  pH->SetPointNum(nPNum);
491  pH->SetObj(const_cast<SdrCircObj*>(this));
492  pH->SetRotationAngle(aGeo.nRotationAngle);
493  rHdlList.AddHdl(std::move(pH));
494  }
495 }
496 
497 
499 {
500  return true;
501 }
502 
504 {
505  const bool bAngle(rDrag.GetHdl() && SdrHdlKind::Circle == rDrag.GetHdl()->GetKind());
506 
507  if(bAngle)
508  {
509  if(1 == rDrag.GetHdl()->GetPointNum() || 2 == rDrag.GetHdl()->GetPointNum())
510  {
511  rDrag.SetNoSnap();
512  }
513 
514  return true;
515  }
516 
517  return SdrTextObj::beginSpecialDrag(rDrag);
518 }
519 
521 {
522  const bool bAngle(rDrag.GetHdl() && SdrHdlKind::Circle == rDrag.GetHdl()->GetKind());
523 
524  if(bAngle)
525  {
526  Point aPt(rDrag.GetNow());
527 
528  if (aGeo.nRotationAngle)
530 
531  if (aGeo.nShearAngle)
533 
534  aPt -= maRect.Center();
535 
536  tools::Long nWdt = maRect.Right() - maRect.Left();
537  tools::Long nHgt = maRect.Bottom() - maRect.Top();
538 
539  if(nWdt>=nHgt)
540  {
541  aPt.setY(BigMulDiv(aPt.Y(),nWdt,nHgt) );
542  }
543  else
544  {
545  aPt.setX(BigMulDiv(aPt.X(),nHgt,nWdt) );
546  }
547 
548  Degree100 nAngle=NormAngle36000(GetAngle(aPt));
549 
550  if (rDrag.GetView() && rDrag.GetView()->IsAngleSnapEnabled())
551  {
552  Degree100 nSA=rDrag.GetView()->GetSnapAngle();
553 
554  if (nSA)
555  {
556  nAngle+=nSA/2_deg100;
557  nAngle/=nSA;
558  nAngle*=nSA;
559  nAngle=NormAngle36000(nAngle);
560  }
561  }
562 
563  if(1 == rDrag.GetHdl()->GetPointNum())
564  {
565  nStartAngle = nAngle;
566  }
567  else if(2 == rDrag.GetHdl()->GetPointNum())
568  {
569  nEndAngle = nAngle;
570  }
571 
572  SetRectsDirty();
573  SetXPolyDirty();
575  SetChanged();
576 
577  return true;
578  }
579  else
580  {
581  return SdrTextObj::applySpecialDrag(rDrag);
582  }
583 }
584 
585 OUString SdrCircObj::getSpecialDragComment(const SdrDragStat& rDrag) const
586 {
587  const bool bCreateComment(rDrag.GetView() && this == rDrag.GetView()->GetCreateObj());
588 
589  if(bCreateComment)
590  {
591  OUStringBuffer aBuf(ImpGetDescriptionStr(STR_ViewCreateObj));
592  const sal_uInt32 nPointCount(rDrag.GetPointCount());
593 
594  if(SdrCircKind::Full != meCircleKind && nPointCount > 2)
595  {
596  const ImpCircUser* pU = static_cast<const ImpCircUser*>(rDrag.GetUser());
597  Degree100 nAngle;
598 
599  aBuf.append(" (");
600 
601  if(3 == nPointCount)
602  {
603  nAngle = pU->nStart;
604  }
605  else
606  {
607  nAngle = pU->nEnd;
608  }
609 
610  aBuf.append(SdrModel::GetAngleString(nAngle));
611  aBuf.append(')');
612  }
613 
614  return aBuf.makeStringAndClear();
615  }
616  else
617  {
618  const bool bAngle(rDrag.GetHdl() && SdrHdlKind::Circle == rDrag.GetHdl()->GetKind());
619 
620  if(bAngle)
621  {
622  const Degree100 nAngle(1 == rDrag.GetHdl()->GetPointNum() ? nStartAngle : nEndAngle);
623 
624  OUStringBuffer aBuf(ImpGetDescriptionStr(STR_DragCircAngle));
625  aBuf.append(" (");
626  aBuf.append(SdrModel::GetAngleString(nAngle));
627  aBuf.append(')');
628 
629  return aBuf.makeStringAndClear();
630  }
631  else
632  {
633  return SdrTextObj::getSpecialDragComment(rDrag);
634  }
635  }
636 }
637 
638 
639 void ImpCircUser::SetCreateParams(SdrDragStat const & rStat)
640 {
641  rStat.TakeCreateRect(aR);
642  aR.Justify();
643  aCenter=aR.Center();
644  nWdt=aR.Right()-aR.Left();
645  nHgt=aR.Bottom()-aR.Top();
646  nStart=0_deg100;
647  nEnd=36000_deg100;
648  if (rStat.GetPointCount()>2) {
649  Point aP(rStat.GetPoint(2)-aCenter);
650  if (nWdt==0) aP.setX(0 );
651  if (nHgt==0) aP.setY(0 );
652  if (nWdt>=nHgt) {
653  if (nHgt!=0) aP.setY(aP.Y()*nWdt/nHgt );
654  } else {
655  if (nWdt!=0) aP.setX(aP.X()*nHgt/nWdt );
656  }
657  nStart=NormAngle36000(GetAngle(aP));
658  if (rStat.GetView()!=nullptr && rStat.GetView()->IsAngleSnapEnabled()) {
659  Degree100 nSA=rStat.GetView()->GetSnapAngle();
660  if (nSA) { // angle snapping
661  nStart+=nSA/2_deg100;
662  nStart/=nSA;
663  nStart*=nSA;
664  nStart=NormAngle36000(nStart);
665  }
666  }
667  aP1 = GetAnglePnt(aR,nStart);
668  nEnd=nStart;
669  } else aP1=aCenter;
670  if (rStat.GetPointCount()<=3)
671  return;
672 
673  Point aP(rStat.GetPoint(3)-aCenter);
674  if (nWdt>=nHgt) {
675  aP.setY(BigMulDiv(aP.Y(),nWdt,nHgt) );
676  } else {
677  aP.setX(BigMulDiv(aP.X(),nHgt,nWdt) );
678  }
679  nEnd=NormAngle36000(GetAngle(aP));
680  if (rStat.GetView()!=nullptr && rStat.GetView()->IsAngleSnapEnabled()) {
681  Degree100 nSA=rStat.GetView()->GetSnapAngle();
682  if (nSA) { // angle snapping
683  nEnd+=nSA/2_deg100;
684  nEnd/=nSA;
685  nEnd*=nSA;
686  nEnd=NormAngle36000(nEnd);
687  }
688  }
689 }
690 
692 {
693  ImpCircUser* pU=static_cast<ImpCircUser*>(rStat.GetUser());
694  if (pU==nullptr) {
695  pU=new ImpCircUser;
696  rStat.SetUser(std::unique_ptr<ImpCircUser>(pU));
697  }
698  pU->SetCreateParams(rStat);
699 }
700 
702 {
703  rStat.SetOrtho4Possible();
704  tools::Rectangle aRect1(rStat.GetStart(), rStat.GetNow());
705  aRect1.Justify();
706  rStat.SetActionRect(aRect1);
707  maRect = aRect1;
708  ImpSetCreateParams(rStat);
709  return true;
710 }
711 
713 {
714  ImpSetCreateParams(rStat);
715  ImpCircUser* pU=static_cast<ImpCircUser*>(rStat.GetUser());
716  rStat.SetActionRect(pU->aR);
717  maRect = pU->aR; // for ObjName
719  nStartAngle=pU->nStart;
720  nEndAngle=pU->nEnd;
722  m_bSnapRectDirty=true;
723  SetXPolyDirty();
724 
725  // #i103058# push current angle settings to ItemSet to
726  // allow FullDrag visualisation
727  if(rStat.GetPointCount() >= 4)
728  {
730  }
731 
732  return true;
733 }
734 
736 {
737  ImpSetCreateParams(rStat);
738  ImpCircUser* pU=static_cast<ImpCircUser*>(rStat.GetUser());
739  bool bRet = false;
742  bRet=rStat.GetPointCount()>=2;
743  if (bRet) {
744  maRect = pU->aR;
746  }
747  } else {
748  rStat.SetNoSnap(rStat.GetPointCount()>=2);
749  rStat.SetOrtho4Possible(rStat.GetPointCount()<2);
750  bRet=rStat.GetPointCount()>=4;
751  if (bRet) {
752  maRect = pU->aR;
754  nStartAngle=pU->nStart;
755  nEndAngle=pU->nEnd;
756  }
757  }
759  SetRectsDirty();
760  SetXPolyDirty();
762  if (bRet)
763  rStat.SetUser(nullptr);
764  return bRet;
765 }
766 
768 {
769  rStat.SetUser(nullptr);
770 }
771 
773 {
774  rStat.SetNoSnap(rStat.GetPointCount()>=3);
775  rStat.SetOrtho4Possible(rStat.GetPointCount()<3);
777 }
778 
780 {
781  const ImpCircUser* pU = static_cast<const ImpCircUser*>(rDrag.GetUser());
782 
783  if(rDrag.GetPointCount() < 4)
784  {
785  // force to OBJ_CIRC to get full visualisation
786  basegfx::B2DPolyPolygon aRetval(ImpCalcXPolyCirc(SdrCircKind::Full, pU->aR, pU->nStart, pU->nEnd));
787 
788  if(3 == rDrag.GetPointCount())
789  {
790  // add edge to first point on ellipse
791  basegfx::B2DPolygon aNew;
792 
793  aNew.append(basegfx::B2DPoint(pU->aCenter.X(), pU->aCenter.Y()));
794  aNew.append(basegfx::B2DPoint(pU->aP1.X(), pU->aP1.Y()));
795  aRetval.append(aNew);
796  }
797 
798  return aRetval;
799  }
800  else
801  {
802  return basegfx::B2DPolyPolygon(ImpCalcXPolyCirc(meCircleKind, pU->aR, pU->nStart, pU->nEnd));
803  }
804 }
805 
807 {
808  switch (meCircleKind) {
809  case SdrCircKind::Full: return PointerStyle::DrawEllipse;
810  case SdrCircKind::Section: return PointerStyle::DrawPie;
811  case SdrCircKind::Arc: return PointerStyle::DrawArc;
812  case SdrCircKind::Cut: return PointerStyle::DrawCircleCut;
813  default: break;
814  } // switch
815  return PointerStyle::Cross;
816 }
817 
818 void SdrCircObj::NbcMove(const Size& aSiz)
819 {
820  maRect.Move(aSiz);
821  m_aOutRect.Move(aSiz);
822  maSnapRect.Move(aSiz);
823  SetXPolyDirty();
824  SetRectsDirty(true);
825 }
826 
827 void SdrCircObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
828 {
829  Degree100 nAngle0=aGeo.nRotationAngle;
830  bool bNoShearRota=(aGeo.nRotationAngle==0_deg100 && aGeo.nShearAngle==0_deg100);
831  SdrTextObj::NbcResize(rRef,xFact,yFact);
832  bNoShearRota|=(aGeo.nRotationAngle==0_deg100 && aGeo.nShearAngle==0_deg100);
834  bool bXMirr=(xFact.GetNumerator()<0) != (xFact.GetDenominator()<0);
835  bool bYMirr=(yFact.GetNumerator()<0) != (yFact.GetDenominator()<0);
836  if (bXMirr || bYMirr) {
837  // At bXMirr!=bYMirr we should actually swap both line ends.
838  // That, however, is pretty bad (because of forced "hard" formatting).
839  // Alternatively, we could implement a bMirrored flag (maybe even
840  // a more general one, e. g. for mirrored text, ...).
842  Degree100 nE0=nEndAngle;
843  if (bNoShearRota) {
844  // the RectObj already mirrors at VMirror because of a 180deg rotation
845  if (! (bXMirr && bYMirr)) {
846  Degree100 nTmp=nS0;
847  nS0=18000_deg100-nE0;
848  nE0=18000_deg100-nTmp;
849  }
850  } else { // mirror contorted ellipses
851  if (bXMirr!=bYMirr) {
852  nS0+=nAngle0;
853  nE0+=nAngle0;
854  if (bXMirr) {
855  Degree100 nTmp=nS0;
856  nS0=18000_deg100-nE0;
857  nE0=18000_deg100-nTmp;
858  }
859  if (bYMirr) {
860  Degree100 nTmp=nS0;
861  nS0=-nE0;
862  nE0=-nTmp;
863  }
864  nS0-=aGeo.nRotationAngle;
865  nE0-=aGeo.nRotationAngle;
866  }
867  }
868  Degree100 nAngleDif=nE0-nS0;
871  if (nAngleDif==36000_deg100) nEndAngle+=nAngleDif; // full circle
872  }
873  }
874  SetXPolyDirty();
876 }
877 
878 void SdrCircObj::NbcShear(const Point& rRef, Degree100 nAngle, double tn, bool bVShear)
879 {
880  SdrTextObj::NbcShear(rRef,nAngle,tn,bVShear);
881  SetXPolyDirty();
883 }
884 
885 void SdrCircObj::NbcMirror(const Point& rRef1, const Point& rRef2)
886 {
887  bool bFreeMirr=meCircleKind!=SdrCircKind::Full;
888  Point aTmpPt1;
889  Point aTmpPt2;
890  if (bFreeMirr) { // some preparations for using an arbitrary axis of reflection
891  Point aCenter(maRect.Center());
892  tools::Long nWdt=maRect.GetWidth()-1;
893  tools::Long nHgt=maRect.GetHeight()-1;
894  tools::Long nMaxRad=(std::max(nWdt,nHgt)+1) /2;
895  double a;
896  // starting point
897  a = nStartAngle.get() * F_PI18000;
898  aTmpPt1=Point(FRound(cos(a)*nMaxRad),-FRound(sin(a)*nMaxRad));
899  if (nWdt==0) aTmpPt1.setX(0 );
900  if (nHgt==0) aTmpPt1.setY(0 );
901  aTmpPt1+=aCenter;
902  // finishing point
903  a = nEndAngle.get() * F_PI18000;
904  aTmpPt2=Point(FRound(cos(a)*nMaxRad),-FRound(sin(a)*nMaxRad));
905  if (nWdt==0) aTmpPt2.setX(0 );
906  if (nHgt==0) aTmpPt2.setY(0 );
907  aTmpPt2+=aCenter;
908  if (aGeo.nRotationAngle) {
911  }
912  if (aGeo.nShearAngle) {
915  }
916  }
917  SdrTextObj::NbcMirror(rRef1,rRef2);
918  if (meCircleKind!=SdrCircKind::Full) { // adapt starting and finishing angle
919  MirrorPoint(aTmpPt1,rRef1,rRef2);
920  MirrorPoint(aTmpPt2,rRef1,rRef2);
921  // unrotate:
922  if (aGeo.nRotationAngle) {
923  RotatePoint(aTmpPt1,maRect.TopLeft(),-aGeo.mfSinRotationAngle,aGeo.mfCosRotationAngle); // -sin for reversion
924  RotatePoint(aTmpPt2,maRect.TopLeft(),-aGeo.mfSinRotationAngle,aGeo.mfCosRotationAngle); // -sin for reversion
925  }
926  // unshear:
927  if (aGeo.nShearAngle) {
928  ShearPoint(aTmpPt1,maRect.TopLeft(),-aGeo.mfTanShearAngle); // -tan for reversion
929  ShearPoint(aTmpPt2,maRect.TopLeft(),-aGeo.mfTanShearAngle); // -tan for reversion
930  }
931  Point aCenter(maRect.Center());
932  aTmpPt1-=aCenter;
933  aTmpPt2-=aCenter;
934  // because it's mirrored, the angles are swapped, too
935  nStartAngle=GetAngle(aTmpPt2);
936  nEndAngle =GetAngle(aTmpPt1);
937  Degree100 nAngleDif=nEndAngle-nStartAngle;
938  nStartAngle=NormAngle36000(nStartAngle);
940  if (nAngleDif==36000_deg100) nEndAngle+=nAngleDif; // full circle
941  }
942  SetXPolyDirty();
944 }
945 
946 std::unique_ptr<SdrObjGeoData> SdrCircObj::NewGeoData() const
947 {
948  return std::make_unique<SdrCircObjGeoData>();
949 }
950 
952 {
954  SdrCircObjGeoData& rCGeo=static_cast<SdrCircObjGeoData&>(rGeo);
955  rCGeo.nStartAngle=nStartAngle;
956  rCGeo.nEndAngle =nEndAngle;
957 }
958 
960 {
962  const SdrCircObjGeoData& rCGeo=static_cast<const SdrCircObjGeoData&>(rGeo);
963  nStartAngle=rCGeo.nStartAngle;
964  nEndAngle =rCGeo.nEndAngle;
965  SetXPolyDirty();
967 }
968 
969 static void Union(tools::Rectangle& rR, const Point& rP)
970 {
971  if (rP.X()<rR.Left ()) rR.SetLeft(rP.X() );
972  if (rP.X()>rR.Right ()) rR.SetRight(rP.X() );
973  if (rP.Y()<rR.Top ()) rR.SetTop(rP.Y() );
974  if (rP.Y()>rR.Bottom()) rR.SetBottom(rP.Y() );
975 }
976 
978 {
979  rRect = maRect;
981  const Point aPntStart(GetAnglePnt(maRect,nStartAngle));
982  const Point aPntEnd(GetAnglePnt(maRect,nEndAngle));
985  rRect.SetLeft(maRect.Right() );
986  rRect.SetRight(maRect.Left() );
987  rRect.SetTop(maRect.Bottom() );
988  rRect.SetBottom(maRect.Top() );
989  Union(rRect,aPntStart);
990  Union(rRect,aPntEnd);
991  if ((a<=18000_deg100 && e>=18000_deg100) || (a>e && (a<=18000_deg100 || e>=18000_deg100))) {
992  Union(rRect,maRect.LeftCenter());
993  }
994  if ((a<=27000_deg100 && e>=27000_deg100) || (a>e && (a<=27000_deg100 || e>=27000_deg100))) {
995  Union(rRect,maRect.BottomCenter());
996  }
997  if (a>e) {
998  Union(rRect,maRect.RightCenter());
999  }
1000  if ((a<=9000_deg100 && e>=9000_deg100) || (a>e && (a<=9000_deg100 || e>=9000_deg100))) {
1001  Union(rRect,maRect.TopCenter());
1002  }
1004  Union(rRect,maRect.Center());
1005  }
1006  if (aGeo.nRotationAngle) {
1007  Point aDst(rRect.TopLeft());
1008  aDst-=maRect.TopLeft();
1009  Point aDst0(aDst);
1011  aDst-=aDst0;
1012  rRect.Move(aDst.X(),aDst.Y());
1013  }
1014  }
1015  if (aGeo.nShearAngle==0_deg100)
1016  return;
1017 
1018  tools::Long nDst=FRound((rRect.Bottom()-rRect.Top())*aGeo.mfTanShearAngle);
1019  if (aGeo.nShearAngle>0_deg100) {
1020  Point aRef(rRect.TopLeft());
1021  rRect.AdjustLeft( -nDst );
1022  Point aTmpPt(rRect.TopLeft());
1024  aTmpPt-=rRect.TopLeft();
1025  rRect.Move(aTmpPt.X(),aTmpPt.Y());
1026  } else {
1027  rRect.AdjustRight( -nDst );
1028  }
1029 }
1030 
1032 {
1033  if (PaintNeedsXPolyCirc()) {
1035  } else {
1037  }
1038 }
1039 
1041 {
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  }
1054  SetRectsDirty();
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();
1105  SetRectsDirty();
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:39
Point TopLeft() const
B2DPolygon const & createPolygonFromUnitCircle(sal_uInt32 nStartQuadrant=0)
static SVX_DLLPRIVATE void ImpSetCreateParams(SdrDragStat &rStat)
Definition: svdocirc.cxx:691
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:573
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:123
double getHeight() const
tools::Long AdjustRight(tools::Long nHorzMoveDelta)
bool m_bClosedObj
Definition: svdobj.hxx:892
virtual OUString TakeObjNameSingul() const override
Definition: svdocirc.cxx:320
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:1143
long Long
virtual void RestoreGeoData(const SdrObjGeoData &rGeo) override
Definition: svdocirc.cxx:959
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:383
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:313
aBuf
virtual void RecalcSnapRect() override
Snap is not done on the BoundRect but if possible on logic coordinates (i.e.
Definition: svdocirc.cxx:1031
static void Union(tools::Rectangle &rR, const Point &rP)
Definition: svdocirc.cxx:969
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
tools::Rectangle m_aOutRect
Definition: svdobj.hxx:872
virtual bool applySpecialDrag(SdrDragStat &rDrag) override
Definition: svdocirc.cxx:520
virtual SdrObjectUniquePtr DoConvertToPolyObj(bool bBezier, bool bAddText) const override
Definition: svdocirc.cxx:1142
virtual sdr::properties::BaseProperties & GetProperties() const
Definition: svdobj.cxx:207
virtual void TakeUnrotatedSnapRect(tools::Rectangle &rRect) const override
Definition: svdocirc.cxx:977
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:172
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
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:194
const SdrHdl * GetHdl() const
Definition: svddrag.hxx:101
virtual void BrkCreate(SdrDragStat &rStat) override
Definition: svdocirc.cxx:767
virtual bool hasSpecialDrag() const override
The standard transformations (Move,Resize,Rotate,Mirror,Shear) are taken over by the View (TakeXorPol...
Definition: svdocirc.cxx:498
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:878
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:1443
virtual void TakeObjInfo(SdrObjTransformInfoRec &rInfo) const override
Definition: svdocirc.cxx:169
virtual bool MovCreate(SdrDragStat &rStat) override
Definition: svdocirc.cxx:712
Degree100 nStartAngle
Definition: svdocirc.hxx:54
Point BottomCenter() const
virtual Point GetSnapPoint(sal_uInt32 i) const override
Definition: svdocirc.cxx:1068
tools::Long Bottom() const
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:946
const SfxItemSet & GetObjectItemSet() const
Definition: svdobj.cxx:1952
virtual bool BckCreate(SdrDragStat &rStat) override
Definition: svdocirc.cxx:772
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: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: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:1059
virtual void AddToHdlList(SdrHdlList &rHdlList) const override
Definition: svdocirc.cxx:425
SdrCircKind meCircleKind
Definition: svdocirc.hxx:53
SVX_DLLPRIVATE void ImpSetCircInfoToAttr()
Definition: svdocirc.cxx:1110
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:139
#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:116
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:91
void MirrorPoint(Point &rPnt, const Point &rRef1, const Point &rRef2)
Definition: svdtrans.cxx:105
SdrView * GetView() const
Definition: svddrag.hxx:86
bool IsAngleSnapEnabled() const
Definition: svdsnpv.hxx:223
void SetXPolyDirty()
Definition: svdorect.cxx:105
virtual void SaveGeoData(SdrObjGeoData &rGeo) const override
Definition: svdocirc.cxx:951
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:827
virtual bool beginSpecialDrag(SdrDragStat &rDrag) const override
Definition: svdocirc.cxx:503
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:701
virtual ~SdrCircObj() override
Definition: svdocirc.cxx:165
SdrAngleItem makeSdrCircStartAngleItem(Degree100 nAngle)
Definition: sxciaitm.hxx:25
Degree100 nStartAngle
Definition: svdocirc.hxx:35
OUString GetName() const
Definition: svdobj.cxx:775
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)
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:585
virtual basegfx::B2DPolyPolygon TakeCreatePoly(const SdrDragStat &rDrag) const override
Polygon dragged by the user when creating the object.
Definition: svdocirc.cxx:779
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:354
virtual void NbcMirror(const Point &rRef1, const Point &rRef2) override
Definition: svdocirc.cxx:885
OUString ImpGetDescriptionStr(const char *pStrCacheID) const
Definition: svdobj.cxx:1076
virtual sal_uInt32 GetHdlCount() const override
Via GetHdlCount the number of Handles can be retrieved.
Definition: svdocirc.cxx:413
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:806
sal_Int32 GetNumerator() const
virtual bool EndCreate(SdrDragStat &rStat, SdrCreateCmd eCmd) override
Definition: svdocirc.cxx:735
std::unique_ptr< SdrObject, SdrObjectFreeOp > SdrObjectUniquePtr
Definition: svdobj.hxx:96
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:1323
PointerStyle
SVX_DLLPRIVATE void ImpSetAttrToCircInfo()
Definition: svdocirc.cxx:1085
virtual void SetRectsDirty(bool bNotMyself=false, bool bRecursive=true)
Definition: svdobj.cxx:509
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:818
tools::Long AdjustLeft(tools::Long nHorzMoveDelta)
bool LineGeometryUsageIsNecessary() const
Definition: svdobj.cxx:1039
bool m_bSnapRectDirty
Definition: svdobj.hxx:879
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:103
B2DHomMatrix createShearXRotateTranslateB2DHomMatrix(double fShearX, double fRadiant, double fTranslateX, double fTranslateY)
virtual void NbcSetSnapRect(const tools::Rectangle &rRect) override
Definition: svdocirc.cxx:1040
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:1006
circle arc
Definition: svdobjkind.hxx:33
static void ImpJustifyRect(tools::Rectangle &rRect)
Definition: svdotext.cxx:423
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:1735
Point TopCenter() const
virtual SdrCircObj * CloneSdrObject(SdrModel &rTargetModel) const override
Definition: svdocirc.cxx:378
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:567
virtual std::unique_ptr< sdr::contact::ViewContact > CreateObjectSpecificViewContact() override
Definition: svdocirc.cxx:99