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, long nAngle)
54 {
55  Point aCenter(rR.Center());
56  long nWdt=rR.Right()-rR.Left();
57  long nHgt=rR.Bottom()-rR.Top();
58  long nMaxRad=(std::max(nWdt,nHgt)+1) /2;
59  double a;
60  a = nAngle * F_PI18000;
61  Point aRetval(FRound(cos(a)*nMaxRad),-FRound(sin(a)*nMaxRad));
62  if (nWdt==0) aRetval.setX(0 );
63  if (nHgt==0) aRetval.setY(0 );
64  if (nWdt!=nHgt) {
65  if (nWdt>nHgt) {
66  if (nWdt!=0) {
67  // stop possible overruns for very large objects
68  if (std::abs(nHgt)>32767 || std::abs(aRetval.Y())>32767) {
69  aRetval.setY(BigMulDiv(aRetval.Y(),nHgt,nWdt) );
70  } else {
71  aRetval.setY(aRetval.Y()*nHgt/nWdt );
72  }
73  }
74  } else {
75  if (nHgt!=0) {
76  // stop possible overruns for very large objects
77  if (std::abs(nWdt)>32767 || std::abs(aRetval.X())>32767) {
78  aRetval.setX(BigMulDiv(aRetval.X(),nWdt,nHgt) );
79  } else {
80  aRetval.setX(aRetval.X()*nWdt/nHgt );
81  }
82  }
83  }
84  }
85  aRetval+=aCenter;
86  return aRetval;
87 }
88 
89 
90 // BaseProperties section
91 
92 std::unique_ptr<sdr::properties::BaseProperties> SdrCircObj::CreateObjectSpecificProperties()
93 {
94  return std::make_unique<sdr::properties::CircleProperties>(*this);
95 }
96 
97 
98 // DrawContact section
99 
100 std::unique_ptr<sdr::contact::ViewContact> SdrCircObj::CreateObjectSpecificViewContact()
101 {
102  return std::make_unique<sdr::contact::ViewContactOfSdrCircObj>(*this);
103 }
104 
106 {
107  switch (eKind)
108  {
109  case OBJ_CIRC: return SdrCircKind::Full;
110  case OBJ_SECT: return SdrCircKind::Section;
111  case OBJ_CARC: return SdrCircKind::Arc;
112  case OBJ_CCUT: return SdrCircKind::Cut;
113  default: assert(false);
114  }
115  return SdrCircKind::Full;
116 }
117 
119  SdrModel& rSdrModel,
120  SdrCircKind eNewKind)
121 : SdrRectObj(rSdrModel)
122 {
123  nStartAngle=0;
124  nEndAngle=36000;
125  meCircleKind=eNewKind;
126  bClosedObj=eNewKind!=SdrCircKind::Arc;
127 }
128 
130  SdrModel& rSdrModel,
131  SdrCircKind eNewKind,
132  const tools::Rectangle& rRect)
133 : SdrRectObj(rSdrModel, rRect)
134 {
135  nStartAngle=0;
136  nEndAngle=36000;
137  meCircleKind=eNewKind;
138  bClosedObj=eNewKind!=SdrCircKind::Arc;
139 }
140 
142  SdrModel& rSdrModel,
143  SdrCircKind eNewKind,
144  const tools::Rectangle& rRect,
145  long nNewStartWink,
146  long nNewEndWink)
147 : SdrRectObj(rSdrModel, rRect)
148 {
149  long nAngleDif=nNewEndWink-nNewStartWink;
150  nStartAngle=NormAngle36000(nNewStartWink);
151  nEndAngle=NormAngle36000(nNewEndWink);
152  if (nAngleDif==36000) nEndAngle+=nAngleDif; // full circle
153  meCircleKind=eNewKind;
154  bClosedObj=eNewKind!=SdrCircKind::Arc;
155 }
156 
158 {
159 }
160 
162 {
163  bool bCanConv=!HasText() || ImpCanConvTextToCurve();
164  rInfo.bEdgeRadiusAllowed = false;
165  rInfo.bCanConvToPath=bCanConv;
166  rInfo.bCanConvToPoly=bCanConv;
168 }
169 
171 {
172  switch (meCircleKind)
173  {
174  case SdrCircKind::Full: return OBJ_CIRC;
175  case SdrCircKind::Section: return OBJ_SECT;
176  case SdrCircKind::Cut: return OBJ_CCUT;
177  case SdrCircKind::Arc: return OBJ_CARC;
178  default: assert(false);
179  }
180  return OBJ_CIRC;
181 }
182 
184 {
185  // XPoly is necessary for all rotated ellipse objects, circle and
186  // ellipse segments.
187  // If not WIN, then (for now) also for circle/ellipse segments and circle/
188  // ellipse arcs (for precision)
190  // If not WIN, then for everything except full circle (for now!)
191  if (meCircleKind!=SdrCircKind::Full) bNeed = true;
192 
193  const SfxItemSet& rSet = GetObjectItemSet();
194  if(!bNeed)
195  {
196  // XPoly is necessary for everything that isn't LineSolid or LineNone
197  drawing::LineStyle eLine = rSet.Get(XATTR_LINESTYLE).GetValue();
198  bNeed = eLine != drawing::LineStyle_NONE && eLine != drawing::LineStyle_SOLID;
199 
200  // XPoly is necessary for thick lines
201  if(!bNeed && eLine != drawing::LineStyle_NONE)
202  bNeed = rSet.Get(XATTR_LINEWIDTH).GetValue() != 0;
203 
204  // XPoly is necessary for circle arcs with line ends
205  if(!bNeed && meCircleKind == SdrCircKind::Arc)
206  {
207  // start of the line is here if StartPolygon, StartWidth!=0
208  bNeed=rSet.Get(XATTR_LINESTART).GetLineStartValue().count() != 0 &&
209  rSet.Get(XATTR_LINESTARTWIDTH).GetValue() != 0;
210 
211  if(!bNeed)
212  {
213  // end of the line is here if EndPolygon, EndWidth!=0
214  bNeed = rSet.Get(XATTR_LINEEND).GetLineEndValue().count() != 0 &&
215  rSet.Get(XATTR_LINEENDWIDTH).GetValue() != 0;
216  }
217  }
218  }
219 
220  // XPoly is necessary if Fill !=None and !=Solid
221  if(!bNeed && meCircleKind != SdrCircKind::Arc)
222  {
223  drawing::FillStyle eFill=rSet.Get(XATTR_FILLSTYLE).GetValue();
224  bNeed = eFill != drawing::FillStyle_NONE && eFill != drawing::FillStyle_SOLID;
225  }
226 
227  if(!bNeed && meCircleKind != SdrCircKind::Full && nStartAngle == nEndAngle)
228  bNeed = true; // otherwise we're drawing a full circle
229 
230  return bNeed;
231 }
232 
233 basegfx::B2DPolygon SdrCircObj::ImpCalcXPolyCirc(const SdrCircKind eCicrleKind, const tools::Rectangle& rRect1, long nStart, long nEnd) const
234 {
236  basegfx::B2DPolygon aCircPolygon;
237 
238  if(SdrCircKind::Full == eCicrleKind)
239  {
240  // create full circle. Do not use createPolygonFromEllipse; it's necessary
241  // to get the start point to the bottom of the circle to keep compatible to
242  // old geometry creation
244 
245  // needs own scaling and translation from unit circle to target size (same as
246  // would be in createPolygonFromEllipse)
247  const basegfx::B2DPoint aCenter(aRange.getCenter());
249  aRange.getWidth() / 2.0, aRange.getHeight() / 2.0,
250  aCenter.getX(), aCenter.getY()));
251  aCircPolygon.transform(aMatrix);
252  }
253  else
254  {
255  // mirror start, end for geometry creation since model coordinate system is mirrored in Y
256  // #i111715# increase numerical correctness by first dividing and not using F_PI1800
257  const double fStart((((36000 - nEnd) % 36000) / 18000.0) * F_PI);
258  const double fEnd((((36000 - nStart) % 36000) / 18000.0) * F_PI);
259 
260  // create circle segment. This is not closed by default
262  aRange.getCenter(), aRange.getWidth() / 2.0, aRange.getHeight() / 2.0,
263  fStart, fEnd);
264 
265  // check closing states
266  const bool bCloseSegment(SdrCircKind::Arc != eCicrleKind);
267  const bool bCloseUsingCenter(SdrCircKind::Section == eCicrleKind);
268 
269  if(bCloseSegment)
270  {
271  if(bCloseUsingCenter)
272  {
273  // add center point at start (for historical reasons)
274  basegfx::B2DPolygon aSector;
275  aSector.append(aRange.getCenter());
276  aSector.append(aCircPolygon);
277  aCircPolygon = aSector;
278  }
279 
280  // close
281  aCircPolygon.setClosed(true);
282  }
283  }
284 
285  // #i76950#
287  {
288  // translate top left to (0,0)
289  const basegfx::B2DPoint aTopLeft(aRange.getMinimum());
291  -aTopLeft.getX(), -aTopLeft.getY()));
292 
293  // shear, rotate and back to top left (if needed)
295  aGeo.nShearAngle ? tan((36000 - aGeo.nShearAngle) * F_PI18000) : 0.0,
296  aGeo.nRotationAngle ? (36000 - aGeo.nRotationAngle) * F_PI18000 : 0.0,
297  aTopLeft) * aMatrix;
298 
299  // apply transformation
300  aCircPolygon.transform(aMatrix);
301  }
302 
303  return aCircPolygon;
304 }
305 
307 {
309  mpXPoly.reset( new XPolygon(aPolyCirc) );
310 }
311 
313 {
314  const char* pID=STR_ObjNameSingulCIRC;
315  if (maRect.GetWidth() == maRect.GetHeight() && aGeo.nShearAngle==0)
316  {
317  switch (meCircleKind) {
318  case SdrCircKind::Full: pID=STR_ObjNameSingulCIRC; break;
319  case SdrCircKind::Section: pID=STR_ObjNameSingulSECT; break;
320  case SdrCircKind::Arc: pID=STR_ObjNameSingulCARC; break;
321  case SdrCircKind::Cut: pID=STR_ObjNameSingulCCUT; break;
322  default: break;
323  }
324  } else {
325  switch (meCircleKind) {
326  case SdrCircKind::Full: pID=STR_ObjNameSingulCIRCE; break;
327  case SdrCircKind::Section: pID=STR_ObjNameSingulSECTE; break;
328  case SdrCircKind::Arc: pID=STR_ObjNameSingulCARCE; break;
329  case SdrCircKind::Cut: pID=STR_ObjNameSingulCCUTE; break;
330  default: break;
331  }
332  }
333  OUStringBuffer sName(SvxResId(pID));
334 
335  OUString aName(GetName());
336  if (!aName.isEmpty())
337  {
338  sName.append(' ');
339  sName.append('\'');
340  sName.append(aName);
341  sName.append('\'');
342  }
343  return sName.makeStringAndClear();
344 }
345 
347 {
348  const char* pID=STR_ObjNamePluralCIRC;
349  if (maRect.GetWidth() == maRect.GetHeight() && aGeo.nShearAngle==0)
350  {
351  switch (meCircleKind) {
352  case SdrCircKind::Full: pID=STR_ObjNamePluralCIRC; break;
353  case SdrCircKind::Section: pID=STR_ObjNamePluralSECT; break;
354  case SdrCircKind::Arc: pID=STR_ObjNamePluralCARC; break;
355  case SdrCircKind::Cut: pID=STR_ObjNamePluralCCUT; break;
356  default: break;
357  }
358  } else {
359  switch (meCircleKind) {
360  case SdrCircKind::Full: pID=STR_ObjNamePluralCIRCE; break;
361  case SdrCircKind::Section: pID=STR_ObjNamePluralSECTE; break;
362  case SdrCircKind::Arc: pID=STR_ObjNamePluralCARCE; break;
363  case SdrCircKind::Cut: pID=STR_ObjNamePluralCCUTE; break;
364  default: break;
365  }
366  }
367  return SvxResId(pID);
368 }
369 
371 {
372  return CloneHelper< SdrCircObj >(rTargetModel);
373 }
374 
376 {
377  if( this == &rObj )
378  return *this;
379  SdrRectObj::operator=(rObj);
380 
381  meCircleKind = rObj.meCircleKind;
382  nStartAngle = rObj.nStartAngle;
383  nEndAngle = rObj.nEndAngle;
384 
385  return *this;
386 }
387 
389 {
391  return basegfx::B2DPolyPolygon(aCircPolygon);
392 }
393 
394 namespace {
395 
396 struct ImpCircUser : public SdrDragStatUserData
397 {
398  tools::Rectangle aR;
399  Point aCenter;
400  Point aP1;
401  long nHgt;
402  long nWdt;
403  long nStart;
404  long nEnd;
405 
406 public:
407  ImpCircUser()
408  : nHgt(0),
409  nWdt(0),
410  nStart(0),
411  nEnd(0)
412  {}
413  void SetCreateParams(SdrDragStat const & rStat);
414 };
415 
416 }
417 
418 sal_uInt32 SdrCircObj::GetHdlCount() const
419 {
421  {
422  return 10;
423  }
424  else
425  {
426  return 8;
427  }
428 }
429 
431 {
432  for (sal_uInt32 nHdlNum=(SdrCircKind::Full==meCircleKind)?2:0; nHdlNum<=9; ++nHdlNum)
433  {
434  Point aPnt;
435  SdrHdlKind eLocalKind(SdrHdlKind::Move);
436  sal_uInt32 nPNum(0);
437 
438  switch (nHdlNum)
439  {
440  case 0:
442  eLocalKind = SdrHdlKind::Circle;
443  nPNum = 1;
444  break;
445  case 1:
446  aPnt = GetAnglePnt(maRect,nEndAngle);
447  eLocalKind = SdrHdlKind::Circle;
448  nPNum = 2;
449  break;
450  case 2:
451  aPnt = maRect.TopLeft();
452  eLocalKind = SdrHdlKind::UpperLeft;
453  break;
454  case 3:
455  aPnt = maRect.TopCenter();
456  eLocalKind = SdrHdlKind::Upper;
457  break;
458  case 4:
459  aPnt = maRect.TopRight();
460  eLocalKind = SdrHdlKind::UpperRight;
461  break;
462  case 5:
463  aPnt = maRect.LeftCenter();
464  eLocalKind = SdrHdlKind::Left;
465  break;
466  case 6:
467  aPnt = maRect.RightCenter();
468  eLocalKind = SdrHdlKind::Right;
469  break;
470  case 7:
471  aPnt = maRect.BottomLeft();
472  eLocalKind = SdrHdlKind::LowerLeft;
473  break;
474  case 8:
475  aPnt = maRect.BottomCenter();
476  eLocalKind = SdrHdlKind::Lower;
477  break;
478  case 9:
479  aPnt = maRect.BottomRight();
480  eLocalKind = SdrHdlKind::LowerRight;
481  break;
482  }
483 
484  if (aGeo.nShearAngle)
485  {
487  }
488 
489  if (aGeo.nRotationAngle)
490  {
492  }
493 
494  std::unique_ptr<SdrHdl> pH(new SdrHdl(aPnt,eLocalKind));
495  pH->SetPointNum(nPNum);
496  pH->SetObj(const_cast<SdrCircObj*>(this));
497  pH->SetRotationAngle(aGeo.nRotationAngle);
498  rHdlList.AddHdl(std::move(pH));
499  }
500 }
501 
502 
504 {
505  return true;
506 }
507 
509 {
510  const bool bAngle(rDrag.GetHdl() && SdrHdlKind::Circle == rDrag.GetHdl()->GetKind());
511 
512  if(bAngle)
513  {
514  if(1 == rDrag.GetHdl()->GetPointNum() || 2 == rDrag.GetHdl()->GetPointNum())
515  {
516  rDrag.SetNoSnap();
517  }
518 
519  return true;
520  }
521 
522  return SdrTextObj::beginSpecialDrag(rDrag);
523 }
524 
526 {
527  const bool bAngle(rDrag.GetHdl() && SdrHdlKind::Circle == rDrag.GetHdl()->GetKind());
528 
529  if(bAngle)
530  {
531  Point aPt(rDrag.GetNow());
532 
533  if (aGeo.nRotationAngle!=0)
535 
536  if (aGeo.nShearAngle!=0)
538 
539  aPt -= maRect.Center();
540 
541  long nWdt = maRect.Right() - maRect.Left();
542  long nHgt = maRect.Bottom() - maRect.Top();
543 
544  if(nWdt>=nHgt)
545  {
546  aPt.setY(BigMulDiv(aPt.Y(),nWdt,nHgt) );
547  }
548  else
549  {
550  aPt.setX(BigMulDiv(aPt.X(),nHgt,nWdt) );
551  }
552 
553  long nAngle=NormAngle36000(GetAngle(aPt));
554 
555  if (rDrag.GetView() && rDrag.GetView()->IsAngleSnapEnabled())
556  {
557  long nSA=rDrag.GetView()->GetSnapAngle();
558 
559  if (nSA!=0)
560  {
561  nAngle+=nSA/2;
562  nAngle/=nSA;
563  nAngle*=nSA;
564  nAngle=NormAngle36000(nAngle);
565  }
566  }
567 
568  if(1 == rDrag.GetHdl()->GetPointNum())
569  {
570  nStartAngle = nAngle;
571  }
572  else if(2 == rDrag.GetHdl()->GetPointNum())
573  {
574  nEndAngle = nAngle;
575  }
576 
577  SetRectsDirty();
578  SetXPolyDirty();
580  SetChanged();
581 
582  return true;
583  }
584  else
585  {
586  return SdrTextObj::applySpecialDrag(rDrag);
587  }
588 }
589 
590 OUString SdrCircObj::getSpecialDragComment(const SdrDragStat& rDrag) const
591 {
592  const bool bCreateComment(rDrag.GetView() && this == rDrag.GetView()->GetCreateObj());
593 
594  if(bCreateComment)
595  {
596  OUStringBuffer aBuf(ImpGetDescriptionStr(STR_ViewCreateObj));
597  const sal_uInt32 nPointCount(rDrag.GetPointCount());
598 
599  if(SdrCircKind::Full != meCircleKind && nPointCount > 2)
600  {
601  const ImpCircUser* pU = static_cast<const ImpCircUser*>(rDrag.GetUser());
602  sal_Int32 nAngle;
603 
604  aBuf.append(" (");
605 
606  if(3 == nPointCount)
607  {
608  nAngle = pU->nStart;
609  }
610  else
611  {
612  nAngle = pU->nEnd;
613  }
614 
615  aBuf.append(SdrModel::GetAngleString(nAngle));
616  aBuf.append(')');
617  }
618 
619  return aBuf.makeStringAndClear();
620  }
621  else
622  {
623  const bool bAngle(rDrag.GetHdl() && SdrHdlKind::Circle == rDrag.GetHdl()->GetKind());
624 
625  if(bAngle)
626  {
627  const sal_Int32 nAngle(1 == rDrag.GetHdl()->GetPointNum() ? nStartAngle : nEndAngle);
628 
629  OUStringBuffer aBuf(ImpGetDescriptionStr(STR_DragCircAngle));
630  aBuf.append(" (");
631  aBuf.append(SdrModel::GetAngleString(nAngle));
632  aBuf.append(')');
633 
634  return aBuf.makeStringAndClear();
635  }
636  else
637  {
638  return SdrTextObj::getSpecialDragComment(rDrag);
639  }
640  }
641 }
642 
643 
644 void ImpCircUser::SetCreateParams(SdrDragStat const & rStat)
645 {
646  rStat.TakeCreateRect(aR);
647  aR.Justify();
648  aCenter=aR.Center();
649  nWdt=aR.Right()-aR.Left();
650  nHgt=aR.Bottom()-aR.Top();
651  nStart=0;
652  nEnd=36000;
653  if (rStat.GetPointCount()>2) {
654  Point aP(rStat.GetPoint(2)-aCenter);
655  if (nWdt==0) aP.setX(0 );
656  if (nHgt==0) aP.setY(0 );
657  if (nWdt>=nHgt) {
658  if (nHgt!=0) aP.setY(aP.Y()*nWdt/nHgt );
659  } else {
660  if (nWdt!=0) aP.setX(aP.X()*nHgt/nWdt );
661  }
662  nStart=NormAngle36000(GetAngle(aP));
663  if (rStat.GetView()!=nullptr && rStat.GetView()->IsAngleSnapEnabled()) {
664  long nSA=rStat.GetView()->GetSnapAngle();
665  if (nSA!=0) { // angle snapping
666  nStart+=nSA/2;
667  nStart/=nSA;
668  nStart*=nSA;
669  nStart=NormAngle36000(nStart);
670  }
671  }
672  aP1 = GetAnglePnt(aR,nStart);
673  nEnd=nStart;
674  } else aP1=aCenter;
675  if (rStat.GetPointCount()>3) {
676  Point aP(rStat.GetPoint(3)-aCenter);
677  if (nWdt>=nHgt) {
678  aP.setY(BigMulDiv(aP.Y(),nWdt,nHgt) );
679  } else {
680  aP.setX(BigMulDiv(aP.X(),nHgt,nWdt) );
681  }
682  nEnd=NormAngle36000(GetAngle(aP));
683  if (rStat.GetView()!=nullptr && rStat.GetView()->IsAngleSnapEnabled()) {
684  long nSA=rStat.GetView()->GetSnapAngle();
685  if (nSA!=0) { // angle snapping
686  nEnd+=nSA/2;
687  nEnd/=nSA;
688  nEnd*=nSA;
689  nEnd=NormAngle36000(nEnd);
690  }
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  long nAngle0=aGeo.nRotationAngle;
834  bool bNoShearRota=(aGeo.nRotationAngle==0 && aGeo.nShearAngle==0);
835  SdrTextObj::NbcResize(rRef,xFact,yFact);
836  bNoShearRota|=(aGeo.nRotationAngle==0 && aGeo.nShearAngle==0);
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, ...).
845  long nS0=nStartAngle;
846  long nE0=nEndAngle;
847  if (bNoShearRota) {
848  // the RectObj already mirrors at VMirror because of a 180deg rotation
849  if (! (bXMirr && bYMirr)) {
850  long nTmp=nS0;
851  nS0=18000-nE0;
852  nE0=18000-nTmp;
853  }
854  } else { // mirror contorted ellipses
855  if (bXMirr!=bYMirr) {
856  nS0+=nAngle0;
857  nE0+=nAngle0;
858  if (bXMirr) {
859  long nTmp=nS0;
860  nS0=18000-nE0;
861  nE0=18000-nTmp;
862  }
863  if (bYMirr) {
864  long nTmp=nS0;
865  nS0=-nE0;
866  nE0=-nTmp;
867  }
868  nS0-=aGeo.nRotationAngle;
869  nE0-=aGeo.nRotationAngle;
870  }
871  }
872  long nAngleDif=nE0-nS0;
875  if (nAngleDif==36000) nEndAngle+=nAngleDif; // full circle
876  }
877  }
878  SetXPolyDirty();
880 }
881 
882 void SdrCircObj::NbcShear(const Point& rRef, long 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  long nWdt=maRect.GetWidth()-1;
897  long nHgt=maRect.GetHeight()-1;
898  long nMaxRad=(std::max(nWdt,nHgt)+1) /2;
899  double a;
900  // starting point
901  a = nStartAngle * 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 * 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!=0) {
915  }
916  if (aGeo.nShearAngle!=0) {
917  ShearPoint(aTmpPt1,maRect.TopLeft(),aGeo.nTan);
918  ShearPoint(aTmpPt2,maRect.TopLeft(),aGeo.nTan);
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!=0) {
927  RotatePoint(aTmpPt1,maRect.TopLeft(),-aGeo.nSin,aGeo.nCos); // -sin for reversion
928  RotatePoint(aTmpPt2,maRect.TopLeft(),-aGeo.nSin,aGeo.nCos); // -sin for reversion
929  }
930  // unshear:
931  if (aGeo.nShearAngle!=0) {
932  ShearPoint(aTmpPt1,maRect.TopLeft(),-aGeo.nTan); // -tan for reversion
933  ShearPoint(aTmpPt2,maRect.TopLeft(),-aGeo.nTan); // -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  long nAngleDif=nEndAngle-nStartAngle;
942  nStartAngle=NormAngle36000(nStartAngle);
944  if (nAngleDif==36000) 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));
987  long a=nStartAngle;
988  long e=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 && e>=18000) || (a>e && (a<=18000 || e>=18000))) {
996  Union(rRect,maRect.LeftCenter());
997  }
998  if ((a<=27000 && e>=27000) || (a>e && (a<=27000 || e>=27000))) {
999  Union(rRect,maRect.BottomCenter());
1000  }
1001  if (a>e) {
1002  Union(rRect,maRect.RightCenter());
1003  }
1004  if ((a<=9000 && e>=9000) || (a>e && (a<=9000 || e>=9000))) {
1005  Union(rRect,maRect.TopCenter());
1006  }
1008  Union(rRect,maRect.Center());
1009  }
1010  if (aGeo.nRotationAngle!=0) {
1011  Point aDst(rRect.TopLeft());
1012  aDst-=maRect.TopLeft();
1013  Point aDst0(aDst);
1014  RotatePoint(aDst,Point(),aGeo.nSin,aGeo.nCos);
1015  aDst-=aDst0;
1016  rRect.Move(aDst.X(),aDst.Y());
1017  }
1018  }
1019  if (aGeo.nShearAngle!=0) {
1020  long nDst=FRound((rRect.Bottom()-rRect.Top())*aGeo.nTan);
1021  if (aGeo.nShearAngle>0) {
1022  Point aRef(rRect.TopLeft());
1023  rRect.AdjustLeft( -nDst );
1024  Point aTmpPt(rRect.TopLeft());
1025  RotatePoint(aTmpPt,aRef,aGeo.nSin,aGeo.nCos);
1026  aTmpPt-=rRect.TopLeft();
1027  rRect.Move(aTmpPt.X(),aTmpPt.Y());
1028  } else {
1029  rRect.AdjustRight( -nDst );
1030  }
1031  }
1032 }
1033 
1035 {
1036  if (PaintNeedsXPolyCirc()) {
1038  } else {
1040  }
1041 }
1042 
1044 {
1046  tools::Rectangle aSR0(GetSnapRect());
1047  long nWdt0=aSR0.Right()-aSR0.Left();
1048  long nHgt0=aSR0.Bottom()-aSR0.Top();
1049  long nWdt1=rRect.Right()-rRect.Left();
1050  long nHgt1=rRect.Bottom()-rRect.Top();
1051  NbcResize(maSnapRect.TopLeft(),Fraction(nWdt1,nWdt0),Fraction(nHgt1,nHgt0));
1052  NbcMove(Size(rRect.Left()-aSR0.Left(),rRect.Top()-aSR0.Top()));
1053  } else {
1054  maRect=rRect;
1056  }
1057  SetRectsDirty();
1058  SetXPolyDirty();
1060 }
1061 
1063 {
1065  return 1;
1066  } else {
1067  return 3;
1068  }
1069 }
1070 
1071 Point SdrCircObj::GetSnapPoint(sal_uInt32 i) const
1072 {
1073  switch (i) {
1074  case 1 : return GetAnglePnt(maRect,nStartAngle);
1075  case 2 : return GetAnglePnt(maRect,nEndAngle);
1076  default: return maRect.Center();
1077  }
1078 }
1079 
1081 {
1082  SetXPolyDirty();
1083  SdrRectObj::Notify(rBC,rHint);
1085 }
1086 
1087 
1089 {
1090  const SfxItemSet& rSet = GetObjectItemSet();
1091  SdrCircKind eNewKind = rSet.Get(SDRATTR_CIRCKIND).GetValue();
1092 
1093  sal_Int32 nNewStart = rSet.Get(SDRATTR_CIRCSTARTANGLE).GetValue();
1094  sal_Int32 nNewEnd = rSet.Get(SDRATTR_CIRCENDANGLE).GetValue();
1095 
1096  bool bKindChg = meCircleKind != eNewKind;
1097  bool bAngleChg = nNewStart != nStartAngle || nNewEnd != nEndAngle;
1098 
1099  if(bKindChg || bAngleChg)
1100  {
1101  meCircleKind = eNewKind;
1102  nStartAngle = nNewStart;
1103  nEndAngle = nNewEnd;
1104 
1105  if(bKindChg || (meCircleKind != SdrCircKind::Full && bAngleChg))
1106  {
1107  SetXPolyDirty();
1108  SetRectsDirty();
1109  }
1110  }
1111 }
1112 
1114 {
1115  const SfxItemSet& rSet = GetObjectItemSet();
1116 
1117  SdrCircKind eOldKindA = rSet.Get(SDRATTR_CIRCKIND).GetValue();
1118  sal_Int32 nOldStartAngle = rSet.Get(SDRATTR_CIRCSTARTANGLE).GetValue();
1119  sal_Int32 nOldEndAngle = rSet.Get(SDRATTR_CIRCENDANGLE).GetValue();
1120 
1121  if(meCircleKind != eOldKindA || nStartAngle != nOldStartAngle || nEndAngle != nOldEndAngle)
1122  {
1123  // since SetItem() implicitly calls ImpSetAttrToCircInfo()
1124  // setting the item directly is necessary here.
1125  if(meCircleKind != eOldKindA)
1126  {
1128  }
1129 
1130  if(nStartAngle != nOldStartAngle)
1131  {
1133  }
1134 
1135  if(nEndAngle != nOldEndAngle)
1136  {
1138  }
1139 
1140  SetXPolyDirty();
1142  }
1143 }
1144 
1145 SdrObjectUniquePtr SdrCircObj::DoConvertToPolyObj(bool bBezier, bool bAddText) const
1146 {
1147  const bool bFill(meCircleKind != SdrCircKind::Arc);
1149  SdrObjectUniquePtr pRet = ImpConvertMakeObj(basegfx::B2DPolyPolygon(aCircPolygon), bFill, bBezier);
1150 
1151  if(bAddText)
1152  {
1153  pRet = ImpConvertAddText(std::move(pRet), bBezier);
1154  }
1155 
1156  return pRet;
1157 }
1158 
1159 /* 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
long GetWidth() const
B2DPoint getCenter() const
virtual void NbcResize(const Point &rRef, const Fraction &xFact, const Fraction &yFact) override
Definition: svdotxtr.cxx:102
void append(const basegfx::B2DPoint &rPoint, sal_uInt32 nCount)
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Detects when a stylesheet is changed.
Definition: svdocirc.cxx:1080
constexpr TypedWhichId< XLineEndItem > XATTR_LINEEND(XATTR_LINE_FIRST+5)
tools::Rectangle GetBoundRect() const
Definition: _xpoly.cxx:396
long GetHeight() const
SdrCircObj & operator=(const SdrCircObj &rObj)
Definition: svdocirc.cxx:375
constexpr TypedWhichId< XLineStartItem > XATTR_LINESTART(XATTR_LINE_FIRST+4)
virtual void SetObjectItemDirect(const SfxPoolItem &rItem)=0
virtual sal_uInt16 GetObjIdentifier() const override
Definition: svdocirc.cxx:170
void ShearPoint(Point &rPnt, const Point &rRef, double tn, bool bVShear=false)
Definition: svdtrans.hxx:122
double getHeight() const
long FRound(double fVal)
virtual SdrObjGeoData * NewGeoData() const override
A derived class must override these 3 methods if it has own geometric data that must be saved for Und...
Definition: svdocirc.cxx:950
virtual OUString TakeObjNameSingul() const override
Definition: svdocirc.cxx:312
double nSin
Definition: svdtrans.hxx:219
const Point & GetStart() const
Definition: svddrag.hxx:92
Point BottomLeft() const
GeoStat aGeo
Definition: svdotext.hxx:185
SdrHdlKind
Definition: svdhdl.hxx:52
long AdjustLeft(long nHorzMoveDelta)
bool ImpCanConvTextToCurve() const
Definition: svdotxtr.cxx:424
SVX_DLLPRIVATE basegfx::B2DPolygon ImpCalcXPolyCirc(const SdrCircKind eKind, const tools::Rectangle &rRect1, long nStart, long nEnd) const
Definition: svdocirc.cxx:233
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:388
long nRotationAngle
Definition: svdtrans.hxx:216
constexpr TypedWhichId< XLineWidthItem > XATTR_LINEWIDTH(XATTR_LINE_FIRST+2)
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:1034
static void Union(tools::Rectangle &rR, const Point &rP)
Definition: svdocirc.cxx:973
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:525
virtual SdrObjectUniquePtr DoConvertToPolyObj(bool bBezier, bool bAddText) const override
Definition: svdocirc.cxx:1145
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:48
All geometrical data of an arbitrary object for use in undo/redo.
Definition: svdobj.hxx:226
long NormAngle36000(long a)
Normalize angle to -180.00..179.99.
Definition: svdtrans.cxx:408
virtual bool HasText() const override
Definition: svdotxat.cxx:412
constexpr TypedWhichId< SdrCircKindItem > SDRATTR_CIRCKIND(SDRATTR_CIRC_FIRST+0)
SdrCircKind ToSdrCircKind(SdrObjKind eKind)
Definition: svdocirc.cxx:105
void Move(long nHorzMoveDelta, long nVertMoveDelta)
bool bSnapRectDirty
Definition: svdobj.hxx:929
virtual void NbcMirror(const Point &rRef1, const Point &rRef2) override
Definition: svdotxtr.cxx:232
Point RightCenter() const
Rectangle objects (rectangle, circle, ...)
Definition: svdorect.hxx:39
Provides information about various ZObject properties.
Definition: svdobj.hxx:248
const SdrHdl * GetHdl() const
Definition: svddrag.hxx:101
static OUString GetAngleString(long nAngle)
Definition: svdmodel.cxx:1205
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:503
constexpr TypedWhichId< SdrAngleItem > SDRATTR_CIRCENDANGLE(SDRATTR_CIRC_FIRST+2)
long nEndAngle
Definition: svdocirc.hxx:55
long Right() const
double getWidth() const
OUString SvxResId(const char *pId)
Definition: dialmgr.cxx:28
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
virtual void SaveGeoData(SdrObjGeoData &rGeo) const override
Definition: svdotext.cxx:1432
virtual void TakeObjInfo(SdrObjTransformInfoRec &rInfo) const override
Definition: svdocirc.cxx:161
virtual bool MovCreate(SdrDragStat &rStat) override
Definition: svdocirc.cxx:716
Point BottomCenter() const
virtual Point GetSnapPoint(sal_uInt32 i) const override
Definition: svdocirc.cxx:1071
const SfxItemSet & GetObjectItemSet() const
Definition: svdobj.cxx:1884
SdrAngleItem makeSdrCircEndAngleItem(long nAngle)
Definition: sxciaitm.hxx:29
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)
bool bClosedObj
Definition: svdobj.hxx:942
long Top() const
tools::Rectangle maSnapRect
Definition: svdoattr.hxx:42
Point LeftCenter() const
circle, ellipse
Definition: svdobj.hxx:122
virtual sal_uInt32 GetSnapPointCount() const override
snap to special points of an Object (polygon points, center of circle)
Definition: svdocirc.cxx:1062
virtual void AddToHdlList(SdrHdlList &rHdlList) const override
Definition: svdocirc.cxx:430
SdrCircKind meCircleKind
Definition: svdocirc.hxx:53
SVX_DLLPRIVATE void ImpSetCircInfoToAttr()
Definition: svdocirc.cxx:1113
Point BottomRight() const
void SetNoSnap(bool bOn=true)
Definition: svddrag.hxx:121
virtual bool applySpecialDrag(SdrDragStat &rDrag) override
Definition: svdotxdr.cxx:149
virtual OUString getSpecialDragComment(const SdrDragStat &rDrag) const override
Definition: svdotxdr.cxx:174
const XPolygon & GetXPoly() const
Definition: svdorect.cxx:128
#define F_PI
double nCos
Definition: svdtrans.hxx:220
void SetTop(long v)
constexpr TypedWhichId< XLineStartWidthItem > XATTR_LINESTARTWIDTH(XATTR_LINE_FIRST+6)
uno_Any a
OUString sName
SdrObject * GetCreateObj() const
Definition: svdcrtv.hxx:119
tools::Rectangle aOutRect
Definition: svdobj.hxx:922
SdrPathObjUniquePtr ImpConvertMakeObj(const basegfx::B2DPolyPolygon &rPolyPolygon, bool bClosed, bool bBezier) const
Definition: svdotxtr.cxx:429
constexpr TypedWhichId< XLineEndWidthItem > XATTR_LINEENDWIDTH(XATTR_LINE_FIRST+7)
virtual std::unique_ptr< sdr::properties::BaseProperties > CreateObjectSpecificProperties() override
Definition: svdocirc.cxx:92
sal_Int32 GetPointCount() const
Definition: svddrag.hxx:91
void MirrorPoint(Point &rPnt, const Point &rRef1, const Point &rRef2)
Definition: svdtrans.cxx:104
void SetRight(long v)
double nTan
Definition: svdtrans.hxx:218
SdrView * GetView() const
Definition: svddrag.hxx:86
bool IsAngleSnapEnabled() const
Definition: svdsnpv.hxx:222
void SetXPolyDirty()
Definition: svdorect.cxx:94
long Bottom() const
virtual void SaveGeoData(SdrObjGeoData &rGeo) const override
Definition: svdocirc.cxx:955
long GetSnapAngle() const
Definition: svdsnpv.hxx:224
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:508
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:157
OUString GetName() const
Definition: svdobj.cxx:698
long nShearAngle
Definition: svdtrans.hxx:217
SdrAngleItem makeSdrCircStartAngleItem(long nAngle)
Definition: sxciaitm.hxx:25
long BigMulDiv(long nVal, long nMul, long nDiv)
Definition: svdtrans.cxx:559
void transform(const basegfx::B2DHomMatrix &rMatrix)
basegfx::B2DRange b2DRectangleFromRectangle(const ::tools::Rectangle &rRect)
void append(const B2DPolygon &rPolygon, sal_uInt32 nCount=1)
long nStartAngle
Definition: svdocirc.hxx:54
circle section
Definition: svdobj.hxx:123
SdrRectObj & operator=(const SdrRectObj &rCopy)
Definition: svdorect.cxx:251
void setClosed(bool bNew)
void RotatePoint(Point &rPnt, const Point &rRef, double sn, double cs)
Definition: svdtrans.hxx:114
void SetActionRect(const tools::Rectangle &rR)
Definition: svddrag.hxx:157
virtual OUString getSpecialDragComment(const SdrDragStat &rDrag) const override
Definition: svdocirc.cxx:590
virtual basegfx::B2DPolyPolygon TakeCreatePoly(const SdrDragStat &rDrag) const override
Polygon dragged by the user when creating the object.
Definition: svdocirc.cxx:783
long AdjustRight(long nHorzMoveDelta)
sal_Int32 GetDenominator() const
circle arc
Definition: svdobj.hxx:124
SdrObjKind
Definition: svdobj.hxx:116
virtual void RestGeoData(const SdrObjGeoData &rGeo) override
Definition: svdocirc.cxx: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:306
virtual OUString TakeObjNamePlural() const override
Definition: svdocirc.cxx:346
virtual void NbcMirror(const Point &rRef1, const Point &rRef2) override
Definition: svdocirc.cxx:889
OUString ImpGetDescriptionStr(const char *pStrCacheID) const
Definition: svdobj.cxx:1038
virtual sal_uInt32 GetHdlCount() const override
Via GetHdlCount the number of Handles can be retrieved.
Definition: svdocirc.cxx:418
OUString aName
B2DPolygon createPolygonFromEllipseSegment(const B2DPoint &rCenter, double fRadiusX, double fRadiusY, double fStart, double fEnd)
void SetUser(std::unique_ptr< SdrDragStatUserData > pU)
Definition: svddrag.hxx:104
virtual void NbcShear(const Point &rRef, long nAngle, double tn, bool bVShear) override
Definition: svdocirc.cxx:882
void SetBottom(long v)
#define F_PI18000
std::unique_ptr< XPolygon > mpXPoly
Definition: svdorect.hxx:50
B2DPoint getMinimum() const
virtual PointerStyle GetCreatePointer() const override
get the cursor/pointer that signals creating this object
Definition: svdocirc.cxx:810
sal_Int32 GetNumerator() const
static Point GetAnglePnt(const tools::Rectangle &rR, long nAngle)
Definition: svdocirc.cxx:53
virtual bool EndCreate(SdrDragStat &rStat, SdrCreateCmd eCmd) override
Definition: svdocirc.cxx:739
std::unique_ptr< SdrObject, SdrObjectFreeOp > SdrObjectUniquePtr
Definition: svdobj.hxx:114
SdrCircObj(SdrModel &rSdrModel, SdrCircKind eNewKind)
Definition: svdocirc.cxx:118
const Point & GetNow() const
Definition: svddrag.hxx:95
virtual bool beginSpecialDrag(SdrDragStat &rDrag) const
Definition: svdobj.cxx:1285
long GetAngle(const Point &rPnt)
The Y axis points down! The function negates the Y axis, when calculating the angle, such that GetAngle(Point(0,-1))=90 deg.
Definition: svdtrans.cxx:386
long Left() const
PointerStyle
SVX_DLLPRIVATE void ImpSetAttrToCircInfo()
Definition: svdocirc.cxx:1088
virtual void RestGeoData(const SdrObjGeoData &rGeo) override
Definition: svdorect.cxx:577
virtual void SetRectsDirty(bool bNotMyself=false, bool bRecursive=true)
Definition: svdobj.cxx:435
virtual void NbcMove(const Size &aSiz) override
The methods Move, Resize, Rotate, Mirror, Shear, SetSnapRect and SetLogicRect call the corresponding ...
Definition: svdocirc.cxx:822
void SetLeft(long v)
bool LineGeometryUsageIsNecessary() const
Definition: svdobj.cxx:962
SVX_DLLPRIVATE bool PaintNeedsXPolyCirc() const
Definition: svdocirc.cxx:183
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:1043
B2DHomMatrix createTranslateB2DHomMatrix(double fTranslateX, double fTranslateY)
SdrCreateCmd
Definition: svdtypes.hxx:27
virtual void SetChanged()
Definition: svdobj.cxx:929
virtual void NbcShear(const Point &rRef, long nAngle, double tn, bool bVShear) override
Definition: svdotxtr.cxx:210
static void ImpJustifyRect(tools::Rectangle &rRect)
Definition: svdotext.cxx:374
Point TopRight() const
Point Center() const
void AddHdl(std::unique_ptr< SdrHdl > pHdl)
Definition: svdhdl.cxx:2294
constexpr TypedWhichId< SdrAngleItem > SDRATTR_CIRCSTARTANGLE(SDRATTR_CIRC_FIRST+1)
virtual bool IsFontwork() const
Definition: svdotext.cxx:1724
Point TopCenter() const
virtual SdrCircObj * CloneSdrObject(SdrModel &rTargetModel) const override
Definition: svdocirc.cxx:370
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
rectangle (round corners optional)
Definition: svdobj.hxx:121
virtual std::unique_ptr< sdr::contact::ViewContact > CreateObjectSpecificViewContact() override
Definition: svdocirc.cxx:100