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 eCircleKind, const tools::Rectangle& rRect1, long nStart, long nEnd) const
234 {
236  basegfx::B2DPolygon aCircPolygon;
237 
238  if(SdrCircKind::Full == eCircleKind)
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 != eCircleKind);
267  const bool bCloseUsingCenter(SdrCircKind::Section == eCircleKind);
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  return;
677 
678  Point aP(rStat.GetPoint(3)-aCenter);
679  if (nWdt>=nHgt) {
680  aP.setY(BigMulDiv(aP.Y(),nWdt,nHgt) );
681  } else {
682  aP.setX(BigMulDiv(aP.X(),nHgt,nWdt) );
683  }
684  nEnd=NormAngle36000(GetAngle(aP));
685  if (rStat.GetView()!=nullptr && rStat.GetView()->IsAngleSnapEnabled()) {
686  long nSA=rStat.GetView()->GetSnapAngle();
687  if (nSA!=0) { // angle snapping
688  nEnd+=nSA/2;
689  nEnd/=nSA;
690  nEnd*=nSA;
691  nEnd=NormAngle36000(nEnd);
692  }
693  }
694 }
695 
697 {
698  ImpCircUser* pU=static_cast<ImpCircUser*>(rStat.GetUser());
699  if (pU==nullptr) {
700  pU=new ImpCircUser;
701  rStat.SetUser(std::unique_ptr<ImpCircUser>(pU));
702  }
703  pU->SetCreateParams(rStat);
704 }
705 
707 {
708  rStat.SetOrtho4Possible();
709  tools::Rectangle aRect1(rStat.GetStart(), rStat.GetNow());
710  aRect1.Justify();
711  rStat.SetActionRect(aRect1);
712  maRect = aRect1;
713  ImpSetCreateParams(rStat);
714  return true;
715 }
716 
718 {
719  ImpSetCreateParams(rStat);
720  ImpCircUser* pU=static_cast<ImpCircUser*>(rStat.GetUser());
721  rStat.SetActionRect(pU->aR);
722  maRect = pU->aR; // for ObjName
724  nStartAngle=pU->nStart;
725  nEndAngle=pU->nEnd;
727  bSnapRectDirty=true;
728  SetXPolyDirty();
729 
730  // #i103058# push current angle settings to ItemSet to
731  // allow FullDrag visualisation
732  if(rStat.GetPointCount() >= 4)
733  {
735  }
736 
737  return true;
738 }
739 
741 {
742  ImpSetCreateParams(rStat);
743  ImpCircUser* pU=static_cast<ImpCircUser*>(rStat.GetUser());
744  bool bRet = false;
747  bRet=rStat.GetPointCount()>=2;
748  if (bRet) {
749  maRect = pU->aR;
751  }
752  } else {
753  rStat.SetNoSnap(rStat.GetPointCount()>=2);
754  rStat.SetOrtho4Possible(rStat.GetPointCount()<2);
755  bRet=rStat.GetPointCount()>=4;
756  if (bRet) {
757  maRect = pU->aR;
759  nStartAngle=pU->nStart;
760  nEndAngle=pU->nEnd;
761  }
762  }
764  SetRectsDirty();
765  SetXPolyDirty();
767  if (bRet)
768  rStat.SetUser(nullptr);
769  return bRet;
770 }
771 
773 {
774  rStat.SetUser(nullptr);
775 }
776 
778 {
779  rStat.SetNoSnap(rStat.GetPointCount()>=3);
780  rStat.SetOrtho4Possible(rStat.GetPointCount()<3);
782 }
783 
785 {
786  const ImpCircUser* pU = static_cast<const ImpCircUser*>(rDrag.GetUser());
787 
788  if(rDrag.GetPointCount() < 4)
789  {
790  // force to OBJ_CIRC to get full visualisation
791  basegfx::B2DPolyPolygon aRetval(ImpCalcXPolyCirc(SdrCircKind::Full, pU->aR, pU->nStart, pU->nEnd));
792 
793  if(3 == rDrag.GetPointCount())
794  {
795  // add edge to first point on ellipse
796  basegfx::B2DPolygon aNew;
797 
798  aNew.append(basegfx::B2DPoint(pU->aCenter.X(), pU->aCenter.Y()));
799  aNew.append(basegfx::B2DPoint(pU->aP1.X(), pU->aP1.Y()));
800  aRetval.append(aNew);
801  }
802 
803  return aRetval;
804  }
805  else
806  {
807  return basegfx::B2DPolyPolygon(ImpCalcXPolyCirc(meCircleKind, pU->aR, pU->nStart, pU->nEnd));
808  }
809 }
810 
812 {
813  switch (meCircleKind) {
814  case SdrCircKind::Full: return PointerStyle::DrawEllipse;
815  case SdrCircKind::Section: return PointerStyle::DrawPie;
816  case SdrCircKind::Arc: return PointerStyle::DrawArc;
817  case SdrCircKind::Cut: return PointerStyle::DrawCircleCut;
818  default: break;
819  } // switch
820  return PointerStyle::Cross;
821 }
822 
823 void SdrCircObj::NbcMove(const Size& aSiz)
824 {
825  maRect.Move(aSiz);
826  aOutRect.Move(aSiz);
827  maSnapRect.Move(aSiz);
828  SetXPolyDirty();
829  SetRectsDirty(true);
830 }
831 
832 void SdrCircObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
833 {
834  long nAngle0=aGeo.nRotationAngle;
835  bool bNoShearRota=(aGeo.nRotationAngle==0 && aGeo.nShearAngle==0);
836  SdrTextObj::NbcResize(rRef,xFact,yFact);
837  bNoShearRota|=(aGeo.nRotationAngle==0 && aGeo.nShearAngle==0);
839  bool bXMirr=(xFact.GetNumerator()<0) != (xFact.GetDenominator()<0);
840  bool bYMirr=(yFact.GetNumerator()<0) != (yFact.GetDenominator()<0);
841  if (bXMirr || bYMirr) {
842  // At bXMirr!=bYMirr we should actually swap both line ends.
843  // That, however, is pretty bad (because of forced "hard" formatting).
844  // Alternatively, we could implement a bMirrored flag (maybe even
845  // a more general one, e. g. for mirrored text, ...).
846  long nS0=nStartAngle;
847  long nE0=nEndAngle;
848  if (bNoShearRota) {
849  // the RectObj already mirrors at VMirror because of a 180deg rotation
850  if (! (bXMirr && bYMirr)) {
851  long nTmp=nS0;
852  nS0=18000-nE0;
853  nE0=18000-nTmp;
854  }
855  } else { // mirror contorted ellipses
856  if (bXMirr!=bYMirr) {
857  nS0+=nAngle0;
858  nE0+=nAngle0;
859  if (bXMirr) {
860  long nTmp=nS0;
861  nS0=18000-nE0;
862  nE0=18000-nTmp;
863  }
864  if (bYMirr) {
865  long nTmp=nS0;
866  nS0=-nE0;
867  nE0=-nTmp;
868  }
869  nS0-=aGeo.nRotationAngle;
870  nE0-=aGeo.nRotationAngle;
871  }
872  }
873  long nAngleDif=nE0-nS0;
876  if (nAngleDif==36000) nEndAngle+=nAngleDif; // full circle
877  }
878  }
879  SetXPolyDirty();
881 }
882 
883 void SdrCircObj::NbcShear(const Point& rRef, long nAngle, double tn, bool bVShear)
884 {
885  SdrTextObj::NbcShear(rRef,nAngle,tn,bVShear);
886  SetXPolyDirty();
888 }
889 
890 void SdrCircObj::NbcMirror(const Point& rRef1, const Point& rRef2)
891 {
892  bool bFreeMirr=meCircleKind!=SdrCircKind::Full;
893  Point aTmpPt1;
894  Point aTmpPt2;
895  if (bFreeMirr) { // some preparations for using an arbitrary axis of reflection
896  Point aCenter(maRect.Center());
897  long nWdt=maRect.GetWidth()-1;
898  long nHgt=maRect.GetHeight()-1;
899  long nMaxRad=(std::max(nWdt,nHgt)+1) /2;
900  double a;
901  // starting point
902  a = nStartAngle * F_PI18000;
903  aTmpPt1=Point(FRound(cos(a)*nMaxRad),-FRound(sin(a)*nMaxRad));
904  if (nWdt==0) aTmpPt1.setX(0 );
905  if (nHgt==0) aTmpPt1.setY(0 );
906  aTmpPt1+=aCenter;
907  // finishing point
908  a = nEndAngle * F_PI18000;
909  aTmpPt2=Point(FRound(cos(a)*nMaxRad),-FRound(sin(a)*nMaxRad));
910  if (nWdt==0) aTmpPt2.setX(0 );
911  if (nHgt==0) aTmpPt2.setY(0 );
912  aTmpPt2+=aCenter;
913  if (aGeo.nRotationAngle!=0) {
916  }
917  if (aGeo.nShearAngle!=0) {
918  ShearPoint(aTmpPt1,maRect.TopLeft(),aGeo.nTan);
919  ShearPoint(aTmpPt2,maRect.TopLeft(),aGeo.nTan);
920  }
921  }
922  SdrTextObj::NbcMirror(rRef1,rRef2);
923  if (meCircleKind!=SdrCircKind::Full) { // adapt starting and finishing angle
924  MirrorPoint(aTmpPt1,rRef1,rRef2);
925  MirrorPoint(aTmpPt2,rRef1,rRef2);
926  // unrotate:
927  if (aGeo.nRotationAngle!=0) {
928  RotatePoint(aTmpPt1,maRect.TopLeft(),-aGeo.nSin,aGeo.nCos); // -sin for reversion
929  RotatePoint(aTmpPt2,maRect.TopLeft(),-aGeo.nSin,aGeo.nCos); // -sin for reversion
930  }
931  // unshear:
932  if (aGeo.nShearAngle!=0) {
933  ShearPoint(aTmpPt1,maRect.TopLeft(),-aGeo.nTan); // -tan for reversion
934  ShearPoint(aTmpPt2,maRect.TopLeft(),-aGeo.nTan); // -tan for reversion
935  }
936  Point aCenter(maRect.Center());
937  aTmpPt1-=aCenter;
938  aTmpPt2-=aCenter;
939  // because it's mirrored, the angles are swapped, too
940  nStartAngle=GetAngle(aTmpPt2);
941  nEndAngle =GetAngle(aTmpPt1);
942  long nAngleDif=nEndAngle-nStartAngle;
943  nStartAngle=NormAngle36000(nStartAngle);
945  if (nAngleDif==36000) nEndAngle+=nAngleDif; // full circle
946  }
947  SetXPolyDirty();
949 }
950 
952 {
953  return new SdrCircObjGeoData;
954 }
955 
957 {
959  SdrCircObjGeoData& rCGeo=static_cast<SdrCircObjGeoData&>(rGeo);
960  rCGeo.nStartAngle=nStartAngle;
961  rCGeo.nEndAngle =nEndAngle;
962 }
963 
965 {
967  const SdrCircObjGeoData& rCGeo=static_cast<const SdrCircObjGeoData&>(rGeo);
968  nStartAngle=rCGeo.nStartAngle;
969  nEndAngle =rCGeo.nEndAngle;
970  SetXPolyDirty();
972 }
973 
974 static void Union(tools::Rectangle& rR, const Point& rP)
975 {
976  if (rP.X()<rR.Left ()) rR.SetLeft(rP.X() );
977  if (rP.X()>rR.Right ()) rR.SetRight(rP.X() );
978  if (rP.Y()<rR.Top ()) rR.SetTop(rP.Y() );
979  if (rP.Y()>rR.Bottom()) rR.SetBottom(rP.Y() );
980 }
981 
983 {
984  rRect = maRect;
986  const Point aPntStart(GetAnglePnt(maRect,nStartAngle));
987  const Point aPntEnd(GetAnglePnt(maRect,nEndAngle));
988  long a=nStartAngle;
989  long e=nEndAngle;
990  rRect.SetLeft(maRect.Right() );
991  rRect.SetRight(maRect.Left() );
992  rRect.SetTop(maRect.Bottom() );
993  rRect.SetBottom(maRect.Top() );
994  Union(rRect,aPntStart);
995  Union(rRect,aPntEnd);
996  if ((a<=18000 && e>=18000) || (a>e && (a<=18000 || e>=18000))) {
997  Union(rRect,maRect.LeftCenter());
998  }
999  if ((a<=27000 && e>=27000) || (a>e && (a<=27000 || e>=27000))) {
1000  Union(rRect,maRect.BottomCenter());
1001  }
1002  if (a>e) {
1003  Union(rRect,maRect.RightCenter());
1004  }
1005  if ((a<=9000 && e>=9000) || (a>e && (a<=9000 || e>=9000))) {
1006  Union(rRect,maRect.TopCenter());
1007  }
1009  Union(rRect,maRect.Center());
1010  }
1011  if (aGeo.nRotationAngle!=0) {
1012  Point aDst(rRect.TopLeft());
1013  aDst-=maRect.TopLeft();
1014  Point aDst0(aDst);
1015  RotatePoint(aDst,Point(),aGeo.nSin,aGeo.nCos);
1016  aDst-=aDst0;
1017  rRect.Move(aDst.X(),aDst.Y());
1018  }
1019  }
1020  if (aGeo.nShearAngle==0)
1021  return;
1022 
1023  long nDst=FRound((rRect.Bottom()-rRect.Top())*aGeo.nTan);
1024  if (aGeo.nShearAngle>0) {
1025  Point aRef(rRect.TopLeft());
1026  rRect.AdjustLeft( -nDst );
1027  Point aTmpPt(rRect.TopLeft());
1028  RotatePoint(aTmpPt,aRef,aGeo.nSin,aGeo.nCos);
1029  aTmpPt-=rRect.TopLeft();
1030  rRect.Move(aTmpPt.X(),aTmpPt.Y());
1031  } else {
1032  rRect.AdjustRight( -nDst );
1033  }
1034 }
1035 
1037 {
1038  if (PaintNeedsXPolyCirc()) {
1040  } else {
1042  }
1043 }
1044 
1046 {
1048  tools::Rectangle aSR0(GetSnapRect());
1049  long nWdt0=aSR0.Right()-aSR0.Left();
1050  long nHgt0=aSR0.Bottom()-aSR0.Top();
1051  long nWdt1=rRect.Right()-rRect.Left();
1052  long nHgt1=rRect.Bottom()-rRect.Top();
1053  NbcResize(maSnapRect.TopLeft(),Fraction(nWdt1,nWdt0),Fraction(nHgt1,nHgt0));
1054  NbcMove(Size(rRect.Left()-aSR0.Left(),rRect.Top()-aSR0.Top()));
1055  } else {
1056  maRect=rRect;
1058  }
1059  SetRectsDirty();
1060  SetXPolyDirty();
1062 }
1063 
1065 {
1067  return 1;
1068  } else {
1069  return 3;
1070  }
1071 }
1072 
1073 Point SdrCircObj::GetSnapPoint(sal_uInt32 i) const
1074 {
1075  switch (i) {
1076  case 1 : return GetAnglePnt(maRect,nStartAngle);
1077  case 2 : return GetAnglePnt(maRect,nEndAngle);
1078  default: return maRect.Center();
1079  }
1080 }
1081 
1083 {
1084  SetXPolyDirty();
1085  SdrRectObj::Notify(rBC,rHint);
1087 }
1088 
1089 
1091 {
1092  const SfxItemSet& rSet = GetObjectItemSet();
1093  SdrCircKind eNewKind = rSet.Get(SDRATTR_CIRCKIND).GetValue();
1094 
1095  sal_Int32 nNewStart = rSet.Get(SDRATTR_CIRCSTARTANGLE).GetValue();
1096  sal_Int32 nNewEnd = rSet.Get(SDRATTR_CIRCENDANGLE).GetValue();
1097 
1098  bool bKindChg = meCircleKind != eNewKind;
1099  bool bAngleChg = nNewStart != nStartAngle || nNewEnd != nEndAngle;
1100 
1101  if(bKindChg || bAngleChg)
1102  {
1103  meCircleKind = eNewKind;
1104  nStartAngle = nNewStart;
1105  nEndAngle = nNewEnd;
1106 
1107  if(bKindChg || (meCircleKind != SdrCircKind::Full && bAngleChg))
1108  {
1109  SetXPolyDirty();
1110  SetRectsDirty();
1111  }
1112  }
1113 }
1114 
1116 {
1117  const SfxItemSet& rSet = GetObjectItemSet();
1118 
1119  SdrCircKind eOldKindA = rSet.Get(SDRATTR_CIRCKIND).GetValue();
1120  sal_Int32 nOldStartAngle = rSet.Get(SDRATTR_CIRCSTARTANGLE).GetValue();
1121  sal_Int32 nOldEndAngle = rSet.Get(SDRATTR_CIRCENDANGLE).GetValue();
1122 
1123  if(meCircleKind == eOldKindA && nStartAngle == nOldStartAngle && nEndAngle == nOldEndAngle)
1124  return;
1125 
1126  // since SetItem() implicitly calls ImpSetAttrToCircInfo()
1127  // setting the item directly is necessary here.
1128  if(meCircleKind != eOldKindA)
1129  {
1131  }
1132 
1133  if(nStartAngle != nOldStartAngle)
1134  {
1136  }
1137 
1138  if(nEndAngle != nOldEndAngle)
1139  {
1141  }
1142 
1143  SetXPolyDirty();
1145 }
1146 
1147 SdrObjectUniquePtr SdrCircObj::DoConvertToPolyObj(bool bBezier, bool bAddText) const
1148 {
1149  const bool bFill(meCircleKind != SdrCircKind::Arc);
1151  SdrObjectUniquePtr pRet = ImpConvertMakeObj(basegfx::B2DPolyPolygon(aCircPolygon), bFill, bBezier);
1152 
1153  if(bAddText)
1154  {
1155  pRet = ImpConvertAddText(std::move(pRet), bBezier);
1156  }
1157 
1158  return pRet;
1159 }
1160 
1161 /* 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:696
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:1082
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:951
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:1036
static void Union(tools::Rectangle &rR, const Point &rP)
Definition: svdocirc.cxx:974
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:1147
virtual sdr::properties::BaseProperties & GetProperties() const
Definition: svdobj.cxx:204
virtual void TakeUnrotatedSnapRect(tools::Rectangle &rRect) const override
Definition: svdocirc.cxx:982
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:227
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:932
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:249
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:772
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:1440
virtual void TakeObjInfo(SdrObjTransformInfoRec &rInfo) const override
Definition: svdocirc.cxx:161
virtual bool MovCreate(SdrDragStat &rStat) override
Definition: svdocirc.cxx:717
Point BottomCenter() const
virtual Point GetSnapPoint(sal_uInt32 i) const override
Definition: svdocirc.cxx:1073
const SfxItemSet & GetObjectItemSet() const
Definition: svdobj.cxx:1885
SdrAngleItem makeSdrCircEndAngleItem(long nAngle)
Definition: sxciaitm.hxx:29
virtual bool BckCreate(SdrDragStat &rStat) override
Definition: svdocirc.cxx:777
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:945
long Top() const
tools::Rectangle maSnapRect
Definition: svdoattr.hxx:42
Point LeftCenter() const
circle, ellipse
Definition: svdobj.hxx:123
virtual sal_uInt32 GetSnapPointCount() const override
snap to special points of an Object (polygon points, center of circle)
Definition: svdocirc.cxx:1064
virtual void AddToHdlList(SdrHdlList &rHdlList) const override
Definition: svdocirc.cxx:430
SdrCircKind meCircleKind
Definition: svdocirc.hxx:53
SVX_DLLPRIVATE void ImpSetCircInfoToAttr()
Definition: svdocirc.cxx:1115
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:116
tools::Rectangle aOutRect
Definition: svdobj.hxx:925
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:956
long GetSnapAngle() const
Definition: svdsnpv.hxx:224
virtual void NbcResize(const Point &rRef, const Fraction &xFact, const Fraction &yFact) override
Definition: svdocirc.cxx:832
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:706
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:124
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:784
long AdjustRight(long nHorzMoveDelta)
sal_Int32 GetDenominator() const
circle arc
Definition: svdobj.hxx:125
SdrObjKind
Definition: svdobj.hxx:117
virtual void RestGeoData(const SdrObjGeoData &rGeo) override
Definition: svdocirc.cxx:964
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:890
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:883
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:811
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:740
std::unique_ptr< SdrObject, SdrObjectFreeOp > SdrObjectUniquePtr
Definition: svdobj.hxx:115
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:1090
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:823
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:1045
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:2289
constexpr TypedWhichId< SdrAngleItem > SDRATTR_CIRCSTARTANGLE(SDRATTR_CIRC_FIRST+1)
virtual bool IsFontwork() const
Definition: svdotext.cxx:1732
Point TopCenter() const
virtual SdrCircObj * CloneSdrObject(SdrModel &rTargetModel) const override
Definition: svdocirc.cxx: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:122
virtual std::unique_ptr< sdr::contact::ViewContact > CreateObjectSpecificViewContact() override
Definition: svdocirc.cxx:100