LibreOffice Module sw (master)  1
dflyobj.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 
20 #include <hintids.hxx>
21 #include <comphelper/lok.hxx>
22 #include <tools/mapunit.hxx>
23 #include <svx/svdhdl.hxx>
24 #include <svx/svdtrans.hxx>
25 #include <editeng/protitem.hxx>
26 #include <svx/svdpage.hxx>
27 #include <vcl/canvastools.hxx>
28 #include <vcl/gdimtf.hxx>
29 #include <vcl/svapp.hxx>
30 #include <vcl/ptrstyle.hxx>
31 
32 #include <fmtclds.hxx>
33 #include <fmtornt.hxx>
34 #include <fmtfsize.hxx>
35 #include <fmturl.hxx>
36 #include <viewsh.hxx>
37 #include <frmatr.hxx>
38 #include <doc.hxx>
39 #include <IDocumentUndoRedo.hxx>
40 #include <dflyobj.hxx>
41 #include <flyfrm.hxx>
42 #include <frmfmt.hxx>
43 #include <viewopt.hxx>
44 #include <frmtool.hxx>
45 #include <flyfrms.hxx>
46 #include <ndnotxt.hxx>
47 #include <grfatr.hxx>
48 #include <pagefrm.hxx>
49 #include <rootfrm.hxx>
50 #include <textboxhelper.hxx>
51 #include <wrtsh.hxx>
52 #include <ndgrf.hxx>
53 #include <frmmgr.hxx>
54 
59 
60 // AW: For VCOfDrawVirtObj and stuff
64 #include <sw_primitivetypes2d.hxx>
67 #include <notxtfrm.hxx>
68 
69 using namespace ::com::sun::star;
70 
71 static bool bInResize = false;
72 
73 
74 namespace sdr::contact
75 {
76  namespace {
77 
86  class VCOfSwFlyDrawObj : public ViewContactOfSdrObj
87  {
88  protected:
93  virtual drawinglayer::primitive2d::Primitive2DContainer createViewIndependentPrimitive2DSequence() const override;
94 
95  public:
97  explicit VCOfSwFlyDrawObj(SwFlyDrawObj& rObj)
98  : ViewContactOfSdrObj(rObj)
99  {
100  }
101  };
102 
103  }
104 
105  drawinglayer::primitive2d::Primitive2DContainer VCOfSwFlyDrawObj::createViewIndependentPrimitive2DSequence() const
106  {
107  // currently gets not visualized, return empty sequence
109  }
110 
111 } // end of namespace sdr::contact
112 
113 std::unique_ptr<sdr::properties::BaseProperties> SwFlyDrawObj::CreateObjectSpecificProperties()
114 {
115  // create default properties
116  return std::make_unique<sdr::properties::DefaultProperties>(*this);
117 }
118 
119 std::unique_ptr<sdr::contact::ViewContact> SwFlyDrawObj::CreateObjectSpecificViewContact()
120 {
121  // needs an own VC since createViewIndependentPrimitive2DSequence()
122  // is called when RecalcBoundRect() is used
123  return std::make_unique<sdr::contact::VCOfSwFlyDrawObj>(*this);
124 }
125 
127 : SdrObject(rSdrModel),
128  mbIsTextBox(false)
129 {
130 }
131 
133 {
134 }
135 
136 // SwFlyDrawObj - Factory-Methods
138 {
139  return SdrInventor::Swg;
140 }
141 
143 {
144  return SwFlyDrawObjIdentifier;
145 }
146 
147 // TODO: Need own primitive to get the FlyFrame paint working
149 {
150  namespace {
151 
152  class SwVirtFlyDrawObjPrimitive : public BufferedDecompositionPrimitive2D
153  {
154  private:
157 
158  protected:
160  virtual void create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& rViewInformation) const override;
161 
162  public:
163  SwVirtFlyDrawObjPrimitive(
164  const SwVirtFlyDrawObj& rSwVirtFlyDrawObj,
165  const basegfx::B2DRange &rOuterRange)
166  : BufferedDecompositionPrimitive2D(),
167  mrSwVirtFlyDrawObj(rSwVirtFlyDrawObj),
168  maOuterRange(rOuterRange)
169  {
170  }
171 
172  virtual bool operator==(const BasePrimitive2D& rPrimitive) const override;
173 
174  virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const override;
175 
176  // override to allow callbacks to wrap_DoPaintObject
177  virtual void get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& rViewInformation) const override;
178 
179  // data read access
180  const SwVirtFlyDrawObj& getSwVirtFlyDrawObj() const { return mrSwVirtFlyDrawObj; }
181  const basegfx::B2DRange& getOuterRange() const { return maOuterRange; }
182 
184  virtual sal_uInt32 getPrimitive2DID() const override;
185  };
186 
187  }
188 } // end of namespace drawinglayer::primitive2d
189 
191 {
192  void SwVirtFlyDrawObjPrimitive::create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const
193  {
194  if(getOuterRange().isEmpty())
195  return;
196 
197  // currently this SW object has no primitive representation. As long as this is the case,
198  // create invisible geometry to allow correct HitTest and BoundRect calculations for the
199  // object. Use a filled primitive to get 'inside' as default object hit. The special cases from
200  // the old SwVirtFlyDrawObj::CheckHit implementation are handled now in SwDrawView::PickObj;
201  // this removed the 'hack' to get a view from inside model data or to react on null-tolerance
202  // as it was done in the old implementation
203  rContainer.push_back(
205  true,
206  getOuterRange()));
207  }
208 
209  bool SwVirtFlyDrawObjPrimitive::operator==(const BasePrimitive2D& rPrimitive) const
210  {
211  if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
212  {
213  const SwVirtFlyDrawObjPrimitive& rCompare = static_cast<const SwVirtFlyDrawObjPrimitive&>(rPrimitive);
214 
215  return (&getSwVirtFlyDrawObj() == &rCompare.getSwVirtFlyDrawObj()
216  && getOuterRange() == rCompare.getOuterRange());
217  }
218 
219  return false;
220  }
221 
222  basegfx::B2DRange SwVirtFlyDrawObjPrimitive::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
223  {
224  return getOuterRange();
225  }
226 
227  void SwVirtFlyDrawObjPrimitive::get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& rViewInformation) const
228  {
229  // This is the callback to keep the FlyFrame painting in SW alive as long as it
230  // is not changed to primitives. This is the method which will be called by the processors
231  // when they do not know this primitive (and they do not). Inside wrap_DoPaintObject
232  // there needs to be a test that paint is only done during SW repaints (see there).
233  // Using this mechanism guarantees the correct Z-Order of the VirtualObject-based FlyFrames.
234  getSwVirtFlyDrawObj().wrap_DoPaintObject(rViewInformation);
235 
236  // call parent
237  BufferedDecompositionPrimitive2D::get2DDecomposition(rVisitor, rViewInformation);
238  }
239 
240  // provide unique ID
241  sal_uInt32 SwVirtFlyDrawObjPrimitive::getPrimitive2DID() const
242  {
244  }
245 
246 } // end of namespace drawinglayer::primitive2d
247 
248 // AW: own sdr::contact::ViewContact (VC) sdr::contact::ViewObjectContact (VOC) needed
249 // since offset is defined different from SdrVirtObj's sdr::contact::ViewContactOfVirtObj.
250 // For paint, that offset is used by setting at the OutputDevice; for primitives this is
251 // not possible since we have no OutputDevice, but define the geometry itself.
252 
253 namespace sdr::contact
254 {
255  namespace {
256 
257  class VCOfSwVirtFlyDrawObj : public ViewContactOfVirtObj
258  {
259  protected:
264  virtual drawinglayer::primitive2d::Primitive2DContainer createViewIndependentPrimitive2DSequence() const override;
265 
266  public:
268  explicit VCOfSwVirtFlyDrawObj(SwVirtFlyDrawObj& rObj)
269  : ViewContactOfVirtObj(rObj)
270  {
271  }
272 
274  SwVirtFlyDrawObj& GetSwVirtFlyDrawObj() const
275  {
276  return static_cast<SwVirtFlyDrawObj&>(mrObject);
277  }
278  };
279 
280  }
281 } // end of namespace sdr::contact
282 
283 namespace sdr::contact
284 {
285  drawinglayer::primitive2d::Primitive2DContainer VCOfSwVirtFlyDrawObj::createViewIndependentPrimitive2DSequence() const
286  {
288  const SdrObject& rReferencedObject = GetSwVirtFlyDrawObj().GetReferencedObj();
289 
290  if(dynamic_cast<const SwFlyDrawObj*>( &rReferencedObject) != nullptr)
291  {
292  // create an own specialized primitive which is used as repaint callpoint and HitTest
293  // for HitTest processor (see primitive implementation above)
294  const basegfx::B2DRange aOuterRange(GetSwVirtFlyDrawObj().getOuterBound());
295 
296  if(!aOuterRange.isEmpty())
297  {
299  new drawinglayer::primitive2d::SwVirtFlyDrawObjPrimitive(
300  GetSwVirtFlyDrawObj(),
301  aOuterRange));
302 
303  xRetval = drawinglayer::primitive2d::Primitive2DContainer { xPrimitive };
304  }
305  }
306 
307  return xRetval;
308  }
309 
310 } // end of namespace sdr::contact
311 
313 {
314  basegfx::B2DRange aOuterRange;
315  const SdrObject& rReferencedObject = GetReferencedObj();
316 
317  if(dynamic_cast<const SwFlyDrawObj*>( &rReferencedObject) != nullptr)
318  {
319  const SwFlyFrame* pFlyFrame = GetFlyFrame();
320 
321  if(pFlyFrame)
322  {
323  const tools::Rectangle aOuterRectangle(pFlyFrame->getFrameArea().Pos(), pFlyFrame->getFrameArea().SSize());
324 
325  if(!aOuterRectangle.IsEmpty())
326  {
327  aOuterRange.expand(basegfx::B2DTuple(aOuterRectangle.Left(), aOuterRectangle.Top()));
328  aOuterRange.expand(basegfx::B2DTuple(aOuterRectangle.Right(), aOuterRectangle.Bottom()));
329  }
330  }
331  }
332 
333  return aOuterRange;
334 }
335 
337 {
338  basegfx::B2DRange aInnerRange;
339  const SdrObject& rReferencedObject = GetReferencedObj();
340 
341  if(dynamic_cast<const SwFlyDrawObj*>( &rReferencedObject) != nullptr)
342  {
343  const SwFlyFrame* pFlyFrame = GetFlyFrame();
344 
345  if(pFlyFrame)
346  {
347  const tools::Rectangle aInnerRectangle(pFlyFrame->getFrameArea().Pos() + pFlyFrame->getFramePrintArea().Pos(), pFlyFrame->getFramePrintArea().SSize());
348 
349  if(!aInnerRectangle.IsEmpty())
350  {
351  aInnerRange.expand(basegfx::B2DTuple(aInnerRectangle.Left(), aInnerRectangle.Top()));
352  aInnerRange.expand(basegfx::B2DTuple(aInnerRectangle.Right(), aInnerRectangle.Bottom()));
353  }
354  }
355  }
356 
357  return aInnerRange;
358 }
359 
361 {
362  // RotGrfFlyFrame: Check if this is a SwGrfNode
363  const SwFlyFrame* pFlyFrame(GetFlyFrame());
364 
365  if(nullptr != pFlyFrame && pFlyFrame->Lower() && pFlyFrame->Lower()->IsNoTextFrame())
366  {
367  const SwNoTextFrame *const pNTF(static_cast<const SwNoTextFrame*>(pFlyFrame->Lower()));
368 
369  const SwGrfNode *const pGrfNd(pNTF->GetNode()->GetGrfNode());
370 
371  return nullptr != pGrfNd;
372  }
373 
374  return false;
375 }
376 
378 {
379  // RotGrfFlyFrame: If true, this SdrObject supports only limited rotation.
380  // This is the case for SwGrfNode instances
381  return ContainsSwGrfNode();
382 }
383 
384 void SwVirtFlyDrawObj::Rotate(const Point& rRef, Degree100 nAngle100, double sn, double cs)
385 {
386  if(ContainsSwGrfNode())
387  {
388  // RotGrfFlyFrame: Here is where the positively completed rotate interaction is executed.
389  // Rotation is in 1/100th degree and may be signed (!)
390  Degree10 nAngle10 = toDegree10(nAngle100);
391 
392  while(nAngle10 < 0_deg10)
393  {
394  nAngle10 += 3600_deg10;
395  }
396 
397  SwWrtShell *pShForAngle = nAngle10 ? dynamic_cast<SwWrtShell*>(GetFlyFrame()->getRootFrame()->GetCurrShell()) : nullptr;
398  if (pShForAngle)
399  {
400  // RotGrfFlyFrame: Add transformation to placeholder object
401  Size aSize;
403  SwFlyFrameAttrMgr aMgr(false, pShForAngle, Frmmgr_Type::NONE, nullptr);
404 
405  aMgr.SetRotation(nOldRot, (nOldRot + nAngle10) % 3600_deg10, aSize);
406  }
407  }
408  else
409  {
410  // call parent
411  SdrVirtObj::Rotate(rRef, nAngle100, sn, cs);
412  }
413 }
414 
415 std::unique_ptr<sdr::contact::ViewContact> SwVirtFlyDrawObj::CreateObjectSpecificViewContact()
416 {
417  // need an own ViewContact (VC) to allow creation of a specialized primitive
418  // for being able to visualize the FlyFrames in primitive renderers
419  return std::make_unique<sdr::contact::VCOfSwVirtFlyDrawObj>(*this);
420 }
421 
423  SdrModel& rSdrModel,
424  SdrObject& rNew,
425  SwFlyFrame* pFly)
426 : SdrVirtObj(rSdrModel, rNew),
427  m_pFlyFrame(pFly)
428 {
430  m_bMovProt = rP.IsPosProtected();
432 }
433 
435 {
436  if ( getSdrPageFromSdrObject() ) //Withdraw SdrPage the responsibility.
438 }
439 
441 {
442  return GetFlyFrame()->GetFormat();
443 }
445 {
446  return GetFlyFrame()->GetFormat();
447 }
448 
449 // --> OD #i102707#
450 namespace
451 {
452  class RestoreMapMode
453  {
454  public:
455  explicit RestoreMapMode( SwViewShell const * pViewShell )
456  : mbMapModeRestored( false )
457  , mpOutDev( pViewShell->GetOut() )
458  {
459  if ( pViewShell->getPrePostMapMode() == mpOutDev->GetMapMode() )
460  return;
461 
462  mpOutDev->Push(PushFlags::MAPMODE);
463 
464  GDIMetaFile* pMetaFile = mpOutDev->GetConnectMetaFile();
465  if ( pMetaFile &&
466  pMetaFile->IsRecord() && !pMetaFile->IsPause() )
467  {
468  OSL_FAIL( "MapMode restoration during meta file creation is somehow suspect - using <SetRelativeMapMode(..)>, but not sure, if correct." );
469  mpOutDev->SetRelativeMapMode( pViewShell->getPrePostMapMode() );
470  }
471  else
472  {
473  mpOutDev->SetMapMode( pViewShell->getPrePostMapMode() );
474  }
475 
476  mbMapModeRestored = true;
477  };
478 
479  ~RestoreMapMode()
480  {
481  if ( mbMapModeRestored )
482  {
483  mpOutDev->Pop();
484  }
485  };
486 
487  private:
488  bool mbMapModeRestored;
489  VclPtr<OutputDevice> mpOutDev;
490  };
491 }
492 // <--
493 
495  drawinglayer::geometry::ViewInformation2D const& rViewInformation) const
496 {
498 
499  // Only paint when we have a current shell and a DrawingLayer paint is in progress.
500  // This avoids evtl. problems with renderers which do processing stuff,
501  // but no paints. IsPaintInProgress() depends on SW repaint, so, as long
502  // as SW paints self and calls DrawLayer() for Heaven and Hell, this will
503  // be correct
504  if ( !(pShell && pShell->IsDrawingLayerPaintInProgress()) )
505  return;
506 
507  bool bDrawObject(true);
508 
509  if ( !SwFlyFrame::IsPaint( const_cast<SwVirtFlyDrawObj*>(this), pShell ) )
510  {
511  bDrawObject = false;
512  }
513 
514  if ( !bDrawObject )
515  return;
516 
517  // if there's no viewport set, all fly-frames will be painted,
518  // which is slow, wastes memory, and can cause other trouble.
519  (void) rViewInformation; // suppress "unused parameter" warning
520  assert(comphelper::LibreOfficeKit::isActive() || !rViewInformation.getViewport().isEmpty());
522  return;
523 
524  // it is also necessary to restore the VCL MapMode from ViewInformation since e.g.
525  // the VCL PixelRenderer resets it at the used OutputDevice. Unfortunately, this
526  // excludes shears and rotates which are not expressible in MapMode.
527  // OD #i102707#
528  // new helper class to restore MapMode - restoration, only if
529  // needed and consideration of paint for meta file creation .
530  RestoreMapMode aRestoreMapModeIfNeeded( pShell );
531 
532  // paint the FlyFrame (use standard VCL-Paint)
534 }
535 
537 {
538  rInfo.bMoveAllowed =
539  rInfo.bResizeFreeAllowed = rInfo.bResizePropAllowed = true;
540 
541  // RotGrfFlyFrame: Some rotation may be allowed
543 
544  rInfo.bMirrorFreeAllowed = rInfo.bMirror45Allowed =
545  rInfo.bMirror90Allowed = rInfo.bShearAllowed =
546  rInfo.bCanConvToPath = rInfo.bCanConvToPoly =
548 }
549 
550 // SwVirtFlyDrawObj - Size Determination
551 
553 {
554  if ( GetFlyFrame()->getFrameArea().HasArea() )
555  const_cast<SwVirtFlyDrawObj*>(this)->m_aOutRect = GetFlyFrame()->getFrameArea().SVRect();
556  else
557  const_cast<SwVirtFlyDrawObj*>(this)->m_aOutRect = tools::Rectangle();
558 }
559 
561 {
562  SetRect();
563  return m_aOutRect;
564 }
565 
567 {
568  return GetCurrentBoundRect();
569 }
570 
572 {
573  SetRect();
574 }
575 
577 {
578  SetRect();
579 }
580 
582 {
583  SetRect();
584  return m_aOutRect;
585 }
586 
588 {
590  SetRect();
591  SetChanged();
593  if (m_pUserCall!=nullptr)
594  m_pUserCall->Changed(*this, SdrUserCallType::Resize, aTmp);
595 }
596 
598 {
599  SetRect();
600 }
601 
603 {
604  SetRect();
605  return m_aOutRect;
606 }
607 
609 {
611  SetRect();
612  SetChanged();
614  if (m_pUserCall!=nullptr)
615  m_pUserCall->Changed(*this, SdrUserCallType::Resize, aTmp);
616 }
617 
619 {
620  SetRect();
621 }
622 
624 {
625  const tools::Rectangle aSourceRectangle(GetFlyFrame()->getFrameArea().SVRect());
626  const ::basegfx::B2DRange aSourceRange = vcl::unotools::b2DRectangleFromRectangle(aSourceRectangle);
628 
629  aRetval.append(::basegfx::utils::createPolygonFromRect(aSourceRange));
630 
631  return aRetval;
632 }
633 
634 // SwVirtFlyDrawObj::Move() and Resize()
636 {
637  if(GetFlyFrame()->IsFlyFreeFrame() && static_cast< SwFlyFreeFrame* >(GetFlyFrame())->isTransformableSwFrame())
638  {
639  // RotateFlyFrame3: When we have a change and are in transformed state (e.g. rotation used),
640  // we need to fall back to the un-transformed state to keep the old code below
641  // working properly. Restore FrameArea and use aOutRect from old FrameArea.
642  TransformableSwFrame* pTransformableSwFrame(static_cast<SwFlyFreeFrame*>(GetFlyFrame())->getTransformableSwFrame());
643  pTransformableSwFrame->restoreFrameAreas();
645  }
646 
647  m_aOutRect.Move( rSiz );
648  const Point aOldPos( GetFlyFrame()->getFrameArea().Pos() );
649  const Point aNewPos( m_aOutRect.TopLeft() );
650  const SwRect aFlyRect( m_aOutRect );
651 
652  //If the Fly has an automatic align (right or top),
653  //so preserve the automatic.
654  SwFrameFormat *pFormat = GetFlyFrame()->GetFormat();
655  const sal_Int16 eHori = pFormat->GetHoriOrient().GetHoriOrient();
656  const sal_Int16 eVert = pFormat->GetVertOrient().GetVertOrient();
657  const sal_Int16 eRelHori = pFormat->GetHoriOrient().GetRelationOrient();
658  const sal_Int16 eRelVert = pFormat->GetVertOrient().GetRelationOrient();
659  //On paragraph bound Flys starting from the new position a new
660  //anchor must be set. Anchor and the new RelPos is calculated and
661  //placed by the Fly itself.
662  if( GetFlyFrame()->IsFlyAtContentFrame() )
663  {
664  static_cast<SwFlyAtContentFrame*>(GetFlyFrame())->SetAbsPos( aNewPos );
665  }
666  else
667  {
668  const SwFrameFormat *pTmpFormat = GetFormat();
669  const SwFormatVertOrient &rVert = pTmpFormat->GetVertOrient();
670  const SwFormatHoriOrient &rHori = pTmpFormat->GetHoriOrient();
671  tools::Long lXDiff = aNewPos.X() - aOldPos.X();
672  if( rHori.IsPosToggle() && text::HoriOrientation::NONE == eHori &&
674  lXDiff = -lXDiff;
675 
677  text::HoriOrientation::NONE == eHori )
678  lXDiff = -lXDiff;
679 
680  tools::Long lYDiff = aNewPos.Y() - aOldPos.Y();
681  if( GetFlyFrame()->GetAnchorFrame()->IsVertical() )
682  {
683  //lXDiff -= rVert.GetPos();
684  //lYDiff += rHori.GetPos();
685 
686  if ( GetFlyFrame()->GetAnchorFrame()->IsVertLR() )
687  {
688  lXDiff += rVert.GetPos();
689  lXDiff = -lXDiff;
690  }
691  else
692  {
693  lXDiff -= rVert.GetPos();
694  lYDiff += rHori.GetPos();
695  }
696  }
697  else
698  {
699  lXDiff += rHori.GetPos();
700  lYDiff += rVert.GetPos();
701  }
702 
703  if( GetFlyFrame()->GetAnchorFrame()->IsRightToLeft() &&
704  text::HoriOrientation::NONE != eHori )
705  lXDiff = GetFlyFrame()->GetAnchorFrame()->getFrameArea().Width() -
706  aFlyRect.Width() - lXDiff;
707 
708  const Point aTmp( lXDiff, lYDiff );
709  GetFlyFrame()->ChgRelPos( aTmp );
710  }
711 
712  SwAttrSet aSet( pFormat->GetDoc()->GetAttrPool(),
714  SwFormatHoriOrient aHori( pFormat->GetHoriOrient() );
715  SwFormatVertOrient aVert( pFormat->GetVertOrient() );
716  bool bPut = false;
717 
718  if( !GetFlyFrame()->IsFlyLayFrame() &&
719  ::GetHtmlMode(pFormat->GetDoc()->GetDocShell()) )
720  {
721  //In HTML-Mode only automatic aligns are allowed.
722  //Only we can try a snap to left/right respectively left-/right border
723  const SwFrame* pAnch = GetFlyFrame()->GetAnchorFrame();
724  bool bNextLine = false;
725 
726  if( !GetFlyFrame()->IsAutoPos() || text::RelOrientation::PAGE_FRAME != aHori.GetRelationOrient() )
727  {
728  if( text::RelOrientation::CHAR == eRelHori )
729  {
730  aHori.SetHoriOrient( text::HoriOrientation::LEFT );
731  aHori.SetRelationOrient( text::RelOrientation::CHAR );
732  }
733  else
734  {
735  bNextLine = true;
736  //Horizontal Align:
737  const bool bLeftFrame =
738  aFlyRect.Left() < pAnch->getFrameArea().Left() + pAnch->getFramePrintArea().Left(),
739  bLeftPrt = aFlyRect.Left() + aFlyRect.Width() <
740  pAnch->getFrameArea().Left() + pAnch->getFramePrintArea().Width()/2;
741  if ( bLeftFrame || bLeftPrt )
742  {
743  aHori.SetHoriOrient( text::HoriOrientation::LEFT );
744  aHori.SetRelationOrient( bLeftFrame ? text::RelOrientation::FRAME : text::RelOrientation::PRINT_AREA );
745  }
746  else
747  {
748  const bool bRightFrame = aFlyRect.Left() >
749  pAnch->getFrameArea().Left() + pAnch->getFramePrintArea().Width();
750  aHori.SetHoriOrient( text::HoriOrientation::RIGHT );
751  aHori.SetRelationOrient( bRightFrame ? text::RelOrientation::FRAME : text::RelOrientation::PRINT_AREA );
752  }
753  }
754  aSet.Put( aHori );
755  }
756  //Vertical alignment simply is retained principally,
757  //only on manual align will be switched over.
758  bool bRelChar = text::RelOrientation::CHAR == eRelVert;
759  aVert.SetVertOrient( eVert != text::VertOrientation::NONE ? eVert :
760  GetFlyFrame()->IsFlyInContentFrame() ? text::VertOrientation::CHAR_CENTER :
761  bRelChar && bNextLine ? text::VertOrientation::CHAR_TOP : text::VertOrientation::TOP );
762  if( bRelChar )
763  aVert.SetRelationOrient( text::RelOrientation::CHAR );
764  else
765  aVert.SetRelationOrient( text::RelOrientation::PRINT_AREA );
766  aSet.Put( aVert );
767  bPut = true;
768  }
769 
770  //We want preferably not to lose the automatic alignments.
771  if ( !bPut && bInResize )
772  {
773  if ( text::HoriOrientation::NONE != eHori )
774  {
775  aHori.SetHoriOrient( eHori );
776  aHori.SetRelationOrient( eRelHori );
777  aSet.Put( aHori );
778  bPut = true;
779  }
780  if ( text::VertOrientation::NONE != eVert )
781  {
782  aVert.SetVertOrient( eVert );
783  aVert.SetRelationOrient( eRelVert );
784  aSet.Put( aVert );
785  bPut = true;
786  }
787  }
788  if ( bPut )
789  pFormat->SetFormatAttr( aSet );
790 }
791 
792 
793 void SwVirtFlyDrawObj::NbcCrop(const basegfx::B2DPoint& rRef, double fxFact, double fyFact)
794 {
795  // Get Wrt Shell
796  SwWrtShell *pSh = dynamic_cast<SwWrtShell*>( GetFlyFrame()->getRootFrame()->GetCurrShell() );
797 
798  if (!pSh)
799  {
800  return;
801  }
802 
803  GraphicObject const *pGraphicObject = pSh->GetGraphicObj();
804 
805  if (!pGraphicObject)
806  {
807  return;
808  }
809 
810  // Get graphic object size in 100th of mm
811  const MapMode aMapMode100thmm(MapUnit::Map100thMM);
812  Size aGraphicSize(pGraphicObject->GetPrefSize());
813 
814  if( MapUnit::MapPixel == pGraphicObject->GetPrefMapMode().GetMapUnit() )
815  {
816  aGraphicSize = Application::GetDefaultDevice()->PixelToLogic( aGraphicSize, aMapMode100thmm );
817  }
818  else
819  {
820  aGraphicSize = OutputDevice::LogicToLogic( aGraphicSize, pGraphicObject->GetPrefMapMode(), aMapMode100thmm);
821  }
822 
823  if( aGraphicSize.IsEmpty() )
824  {
825  return ;
826  }
827 
828  const bool bIsTransformableSwFrame(
829  GetFlyFrame()->IsFlyFreeFrame() &&
830  static_cast< SwFlyFreeFrame* >(GetFlyFrame())->isTransformableSwFrame());
831 
832  if(bIsTransformableSwFrame)
833  {
834  // When we have a change and are in transformed state (e.g. rotation used),
835  // we need to fall back to the un-transformed state to keep the old code below
836  // working properly. Restore FrameArea and use aOutRect from old FrameArea.
837  TransformableSwFrame* pTransformableSwFrame(static_cast<SwFlyFreeFrame*>(GetFlyFrame())->getTransformableSwFrame());
838  pTransformableSwFrame->restoreFrameAreas();
840  }
841 
842  // Compute old and new rect. This will give us the deformation to apply to
843  // the object to crop. OldRect is the inner frame, see getFullDragClone()
844  // below where getFramePrintAreaTransformation is used as object geometry for Crop
845  const tools::Rectangle aOldRect(
846  GetFlyFrame()->getFrameArea().TopLeft() + GetFlyFrame()->getFramePrintArea().TopLeft(),
847  GetFlyFrame()->getFramePrintArea().SSize());
848  const tools::Long nOldWidth(aOldRect.GetWidth());
849  const tools::Long nOldHeight(aOldRect.GetHeight());
850 
851  if (!nOldWidth || !nOldHeight)
852  {
853  return;
854  }
855 
856  // rRef is relative to the Crop-Action, si in X/Y-Ranges of [0.0 .. 1.0],
857  // to get the correct absolute position, transform using the old Rect
858  const Point aRef(
859  aOldRect.Left() + basegfx::fround(aOldRect.GetWidth() * rRef.getX()),
860  aOldRect.Top() + basegfx::fround(aOldRect.GetHeight() * rRef.getY()));
861 
862  // apply transformation, use old ResizeRect for now
863  tools::Rectangle aNewRect( aOldRect );
864  ResizeRect(
865  aNewRect,
866  aRef,
867  Fraction(fxFact),
868  Fraction(fyFact));
869 
870  // Get old values for crop in 10th of mm
871  SfxItemSet aSet( pSh->GetAttrPool(), svl::Items<RES_GRFATR_CROPGRF, RES_GRFATR_CROPGRF> );
872  pSh->GetCurAttr( aSet );
873  SwCropGrf aCrop( aSet.Get(RES_GRFATR_CROPGRF) );
874 
875  tools::Rectangle aCropRectangle(
876  convertTwipToMm100(aCrop.GetLeft()),
877  convertTwipToMm100(aCrop.GetTop()),
878  convertTwipToMm100(aCrop.GetRight()),
879  convertTwipToMm100(aCrop.GetBottom()) );
880 
881  // Compute delta to apply
882  double fScaleX = ( aGraphicSize.Width() - aCropRectangle.Left() - aCropRectangle.Right() ) / static_cast<double>(nOldWidth);
883  double fScaleY = ( aGraphicSize.Height() - aCropRectangle.Top() - aCropRectangle.Bottom() ) / static_cast<double>(nOldHeight);
884 
885  sal_Int32 nDiffLeft = aNewRect.Left() - aOldRect.Left();
886  sal_Int32 nDiffTop = aNewRect.Top() - aOldRect.Top();
887  sal_Int32 nDiffRight = aNewRect.Right() - aOldRect.Right();
888  sal_Int32 nDiffBottom = aNewRect.Bottom() - aOldRect.Bottom();
889 
890  // Compute new values in 10th of mm
891  sal_Int32 nLeftCrop = static_cast<sal_Int32>( aCropRectangle.Left() + nDiffLeft * fScaleX );
892  sal_Int32 nTopCrop = static_cast<sal_Int32>( aCropRectangle.Top() + nDiffTop * fScaleY );
893  sal_Int32 nRightCrop = static_cast<sal_Int32>( aCropRectangle.Right() - nDiffRight * fScaleX );
894  sal_Int32 nBottomCrop = static_cast<sal_Int32>( aCropRectangle.Bottom() - nDiffBottom * fScaleY );
895 
896  // Apply values
897  pSh->StartAllAction();
898  // pSh->StartUndo(SwUndoId::START);
899 
900  // Set new crop values in twips
901  aCrop.SetLeft (convertMm100ToTwip(nLeftCrop));
902  aCrop.SetTop (convertMm100ToTwip(nTopCrop));
903  aCrop.SetRight (convertMm100ToTwip(nRightCrop));
904  aCrop.SetBottom(convertMm100ToTwip(nBottomCrop));
905  pSh->SetAttrItem(aCrop);
906 
907  // Set new frame size
908  SwFrameFormat *pFormat = GetFormat();
909  SwFormatFrameSize aSz( pFormat->GetFrameSize() );
910  const tools::Long aNewWidth(aNewRect.GetWidth() + (m_aOutRect.GetWidth() - aOldRect.GetWidth()));
911  const tools::Long aNewHeight(aNewRect.GetHeight() + (m_aOutRect.GetHeight() - aOldRect.GetHeight()));
912  aSz.SetWidth(aNewWidth);
913  aSz.SetHeight(aNewHeight);
914  pFormat->GetDoc()->SetAttr( aSz, *pFormat );
915 
916  // add move - to make result look better. Fill with defaults
917  // for the untransformed case
918  Point aNewTopLeft(aNewRect.TopLeft());
919  const Point aOldTopLeft(aOldRect.TopLeft());
920 
921  if(bIsTransformableSwFrame)
922  {
923  // Need to correct the NewTopLeft position in transformed state to make
924  // the interaction look correct. First, extract rotation
925  basegfx::B2DVector aScale, aTranslate;
926  double fRotate, fShearX;
927  GetFlyFrame()->getFrameAreaTransformation().decompose(aScale, aTranslate, fRotate, fShearX);
928 
929  // calc the center of the unchanged object
930  const basegfx::B2DPoint aFormerCenter(
931  GetFlyFrame()->getFrameAreaTransformation() * basegfx::B2DPoint(0.5, 0.5));
932 
933  // define the existing rotation around that former center
934  const basegfx::B2DHomMatrix aRotFormerCenter(
936  aFormerCenter.getX(),
937  aFormerCenter.getY(),
938  fRotate));
939 
940  // use the new center of the unrotated object, rotate it around the
941  // former center
942  const Point aNewCenter(aNewRect.Center());
943  const basegfx::B2DPoint aRotNewCenter(
944  aRotFormerCenter * basegfx::B2DPoint(aNewCenter.X(), aNewCenter.Y()));
945 
946  // Create the new TopLeft of the unrotated, cropped object by creating
947  // as if re-creating the unrotated geometry
948  aNewTopLeft = Point(
949  basegfx::fround(aRotNewCenter.getX() - (0.5 * aNewRect.getWidth())),
950  basegfx::fround(aRotNewCenter.getY() - (0.5 * aNewRect.getHeight())));
951  }
952 
953  // check if we have movement and execute if yes
954  const Size aDeltaMove(
955  aNewTopLeft.X() - aOldTopLeft.X(),
956  aNewTopLeft.Y() - aOldTopLeft.Y());
957 
958  if(0 != aDeltaMove.Width() || 0 != aDeltaMove.Height())
959  {
960  NbcMove(aDeltaMove);
961  }
962 
963  // pSh->EndUndo(SwUndoId::END);
964  pSh->EndAllAction();
965 }
966 
967 void SwVirtFlyDrawObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
968 {
969  const SwFrame* pTmpFrame = GetFlyFrame()->GetAnchorFrame();
970 
971  if( !pTmpFrame )
972  {
973  pTmpFrame = GetFlyFrame();
974  }
975 
976  const bool bVertX(pTmpFrame->IsVertical());
977  const bool bRTL(pTmpFrame->IsRightToLeft());
978  const bool bVertL2RX(pTmpFrame->IsVertLR());
979  const bool bUseRightEdge((bVertX && !bVertL2RX ) || bRTL);
980  const bool bIsTransformableSwFrame(
981  GetFlyFrame()->IsFlyFreeFrame() &&
982  static_cast< SwFlyFreeFrame* >(GetFlyFrame())->isTransformableSwFrame());
983 
984  if(bIsTransformableSwFrame)
985  {
986  // When we have a change in transformed state, we need to fall back to the
987  // state without possible transformations.
988  // In the Resize case to correctly handle the changes, apply to the transformation
989  // and extract the new, untransformed state from that modified transformation
990  basegfx::B2DHomMatrix aNewMat(GetFlyFrame()->getFrameAreaTransformation());
991  const basegfx::B2DPoint aRef(rRef.X(), rRef.Y());
992 
993  // apply state to already valid transformation
994  aNewMat.translate(-aRef.getX(), -aRef.getY());
995  aNewMat.scale(double(xFact), double(yFact));
996  aNewMat.translate(aRef.getX(), aRef.getY());
997 
998  // get center of transformed state
999  const basegfx::B2DPoint aCenter(aNewMat * basegfx::B2DPoint(0.5, 0.5));
1000 
1001  // decompose to extract scale
1002  basegfx::B2DVector aScale, aTranslate;
1003  double fRotate, fShearX;
1004  aNewMat.decompose(aScale, aTranslate, fRotate, fShearX);
1005  const basegfx::B2DVector aAbsScale(basegfx::absolute(aScale));
1006 
1007  // create new modified, but untransformed OutRect
1009  basegfx::fround(aCenter.getX() - (0.5 * aAbsScale.getX())),
1010  basegfx::fround(aCenter.getY() - (0.5 * aAbsScale.getY())),
1011  basegfx::fround(aCenter.getX() + (0.5 * aAbsScale.getX())),
1012  basegfx::fround(aCenter.getY() + (0.5 * aAbsScale.getY())));
1013 
1014  // restore FrameAreas so that actions below not adapted to new
1015  // full transformations take the correct actions
1016  TransformableSwFrame* pTransformableSwFrame(static_cast<SwFlyFreeFrame*>(GetFlyFrame())->getTransformableSwFrame());
1017  pTransformableSwFrame->restoreFrameAreas();
1018  }
1019  else
1020  {
1021  ResizeRect( m_aOutRect, rRef, xFact, yFact );
1022  }
1023 
1024  // Position may also change, remember old one. This is now already
1025  // the one in the unrotated, old coordinate system
1026  Point aOldPos(bUseRightEdge ? GetFlyFrame()->getFrameArea().TopRight() : GetFlyFrame()->getFrameArea().Pos());
1027 
1028  // get target size in old coordinate system
1029  Size aSz( m_aOutRect.Right() - m_aOutRect.Left() + 1, m_aOutRect.Bottom()- m_aOutRect.Top() + 1 );
1030 
1031  // compare with restored FrameArea
1032  if( aSz != GetFlyFrame()->getFrameArea().SSize() )
1033  {
1034  //The width of the columns should not be too narrow
1035  if ( GetFlyFrame()->Lower() && GetFlyFrame()->Lower()->IsColumnFrame() )
1036  {
1038  const SwBorderAttrs &rAttrs = *aAccess.Get();
1039  tools::Long nMin = rAttrs.CalcLeftLine()+rAttrs.CalcRightLine();
1040  const SwFormatCol& rCol = rAttrs.GetAttrSet().GetCol();
1041  if ( rCol.GetColumns().size() > 1 )
1042  {
1043  for ( const auto &rC : rCol.GetColumns() )
1044  {
1045  nMin += rC.GetLeft() + rC.GetRight() + MINFLY;
1046  }
1047  nMin -= MINFLY;
1048  }
1049  aSz.setWidth( std::max( aSz.Width(), nMin ) );
1050  }
1051 
1052  SwFrameFormat *pFormat = GetFormat();
1053  const SwFormatFrameSize aOldFrameSz( pFormat->GetFrameSize() );
1054  GetFlyFrame()->ChgSize( aSz );
1055  SwFormatFrameSize aFrameSz( pFormat->GetFrameSize() );
1056 
1057  if ( aFrameSz.GetWidthPercent() || aFrameSz.GetHeightPercent() )
1058  {
1059  tools::Long nRelWidth, nRelHeight;
1060  const SwFrame *pRel = GetFlyFrame()->IsFlyLayFrame() ?
1063  const SwViewShell *pSh = GetFlyFrame()->getRootFrame()->GetCurrShell();
1064 
1065  if ( pSh && pRel->IsBodyFrame() &&
1066  pSh->GetViewOptions()->getBrowseMode() &&
1067  pSh->VisArea().HasArea() )
1068  {
1069  nRelWidth = pSh->GetBrowseWidth();
1070  nRelHeight = pSh->VisArea().Height();
1071  const Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() );
1072  nRelHeight -= 2*aBorder.Height();
1073  }
1074  else
1075  {
1076  nRelWidth = pRel->getFramePrintArea().Width();
1077  nRelHeight = pRel->getFramePrintArea().Height();
1078  }
1079 
1080  if ( aFrameSz.GetWidthPercent() && aFrameSz.GetWidthPercent() != SwFormatFrameSize::SYNCED &&
1081  aOldFrameSz.GetWidth() != aFrameSz.GetWidth() )
1082  {
1083  aFrameSz.SetWidthPercent( sal_uInt8(aSz.Width() * 100.0 / nRelWidth + 0.5) );
1084  }
1085 
1086  if ( aFrameSz.GetHeightPercent() && aFrameSz.GetHeightPercent() != SwFormatFrameSize::SYNCED &&
1087  aOldFrameSz.GetHeight() != aFrameSz.GetHeight() )
1088  {
1089  aFrameSz.SetHeightPercent( sal_uInt8(aSz.Height() * 100.0 / nRelHeight + 0.5) );
1090  }
1091 
1092  pFormat->GetDoc()->SetAttr( aFrameSz, *pFormat );
1093  }
1094  }
1095 
1096  //Position can also be changed, get new one
1097  const Point aNewPos(bUseRightEdge ? m_aOutRect.Right() + 1 : m_aOutRect.Left(), m_aOutRect.Top());
1098 
1099  if ( aNewPos == aOldPos )
1100  return;
1101 
1102  // Former late change in aOutRect by ChgSize
1103  // is now taken into account directly by calculating
1104  // aNewPos *after* calling ChgSize (see old code).
1105  // Still need to adapt aOutRect since the 'Move' is already applied
1106  // here (see ResizeRect) and it's the same SdrObject
1107  const Size aDeltaMove(
1108  aNewPos.X() - aOldPos.X(),
1109  aNewPos.Y() - aOldPos.Y());
1110  m_aOutRect.Move(-aDeltaMove.Width(), -aDeltaMove.Height());
1111 
1112  // Now, move as needed (no empty delta which was a hack anyways)
1113  if(bIsTransformableSwFrame)
1114  {
1115  // need to save aOutRect to FrameArea, will be restored to aOutRect in
1116  // SwVirtFlyDrawObj::NbcMove currently for TransformableSwFrames
1118  aFrm.setSwRect(SwRect(m_aOutRect));
1119  }
1120 
1121  // keep old hack - not clear what happens here
1122  bInResize = true;
1123  NbcMove(aDeltaMove);
1124  bInResize = false;
1125 }
1126 
1127 void SwVirtFlyDrawObj::Move(const Size& rSiz)
1128 {
1129  NbcMove( rSiz );
1130  SetChanged();
1132 }
1133 
1134 void SwVirtFlyDrawObj::Resize(const Point& rRef,
1135  const Fraction& xFact, const Fraction& yFact, bool /*bUnsetRelative*/)
1136 {
1137  NbcResize( rRef, xFact, yFact );
1138  SetChanged();
1140 }
1141 
1142 void SwVirtFlyDrawObj::Crop(const basegfx::B2DPoint& rRef, double fxFact, double fyFact)
1143 {
1144  NbcCrop( rRef, fxFact, fyFact );
1145  SetChanged();
1147 }
1148 
1149 // RotGrfFlyFrame: Helper to access possible rotation of Graphic contained in FlyFrame
1151 {
1152  Degree10 nRetval;
1153  const SwNoTextFrame* pNoTx = dynamic_cast< const SwNoTextFrame* >(GetFlyFrame()->Lower());
1154 
1155  if(pNoTx)
1156  {
1157  SwNoTextNode& rNoTNd = const_cast< SwNoTextNode& >(*static_cast<const SwNoTextNode*>(pNoTx->GetNode()));
1158  SwGrfNode* pGrfNd = rNoTNd.GetGrfNode();
1159 
1160  if(nullptr != pGrfNd)
1161  {
1162  const SwAttrSet& rSet = pGrfNd->GetSwAttrSet();
1163  const SwRotationGrf& rRotation = rSet.GetRotationGrf();
1164 
1165  rSize = rRotation.GetUnrotatedSize();
1166  nRetval = rRotation.GetValue();
1167  }
1168  }
1169 
1170  return nRetval;
1171 }
1172 
1174 {
1175  if(ContainsSwGrfNode())
1176  {
1177  Size aSize;
1179  }
1180  else
1181  {
1182  return SdrVirtObj::GetRotateAngle();
1183  }
1184 }
1185 
1187 {
1188  // call parent
1190 
1191  if(pRetval && GetFlyFrame() && ContainsSwGrfNode())
1192  {
1193  // RotGrfFlyFrame3: get inner bounds/transformation
1194  const basegfx::B2DHomMatrix aTargetTransform(GetFlyFrame()->getFramePrintAreaTransformation());
1195 
1196  pRetval->TRSetBaseGeometry(aTargetTransform, basegfx::B2DPolyPolygon());
1197  }
1198 
1199  return pRetval;
1200 }
1201 
1203 {
1204  // RotGrfFlyFrame: Adapt to possible rotated Graphic contained in FlyFrame
1205  if(!GetFlyFrame()->getFrameArea().HasArea())
1206  return;
1207 
1208  // Use InnerBound, OuterBound (same as GetFlyFrame()->getFrameArea().SVRect())
1209  // may have a distance to InnerBound which needs to be taken into account.
1210  // The Graphic is mapped to InnerBound, as is the rotated Graphic.
1211  const basegfx::B2DRange aTargetRange(getInnerBound());
1212 
1213  if(aTargetRange.isEmpty())
1214  return;
1215 
1216  // RotGrfFlyFrame3: get inner bounds/transformation
1217  const basegfx::B2DHomMatrix aTargetTransform(GetFlyFrame()->getFramePrintAreaTransformation());
1218 
1219  // break up matrix
1220  basegfx::B2DTuple aScale;
1221  basegfx::B2DTuple aTranslate;
1222  double fRotate(0.0);
1223  double fShearX(0.0);
1224  aTargetTransform.decompose(aScale, aTranslate, fRotate, fShearX);
1225  basegfx::B2DPoint aPos;
1226 
1227  aPos = aTargetTransform * basegfx::B2DPoint(0.0, 0.0);
1228  rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::UpperLeft, fShearX, fRotate));
1229  aPos = aTargetTransform * basegfx::B2DPoint(0.5, 0.0);
1230  rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::Upper, fShearX, fRotate));
1231  aPos = aTargetTransform * basegfx::B2DPoint(1.0, 0.0);
1232  rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::UpperRight, fShearX, fRotate));
1233  aPos = aTargetTransform * basegfx::B2DPoint(0.0, 0.5);
1234  rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::Left , fShearX, fRotate));
1235  aPos = aTargetTransform * basegfx::B2DPoint(1.0, 0.5);
1236  rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::Right, fShearX, fRotate));
1237  aPos = aTargetTransform * basegfx::B2DPoint(0.0, 1.0);
1238  rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::LowerLeft, fShearX, fRotate));
1239  aPos = aTargetTransform * basegfx::B2DPoint(0.5, 1.0);
1240  rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::Lower, fShearX, fRotate));
1241  aPos = aTargetTransform * basegfx::B2DPoint(1.0, 1.0);
1242  rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::LowerRight, fShearX, fRotate));
1243 }
1244 
1245 // Macro
1246 
1248  const SdrObjMacroHitRec& ) const
1249 {
1250  return PointerStyle::RefHand;
1251 }
1252 
1254 {
1255  const SwFormatURL &rURL = m_pFlyFrame->GetFormat()->GetURL();
1256  return rURL.GetMap() || !rURL.GetURL().isEmpty();
1257 }
1258 
1260 {
1261  const SwFormatURL &rURL = m_pFlyFrame->GetFormat()->GetURL();
1262  if( rURL.GetMap() || !rURL.GetURL().isEmpty() )
1263  {
1264  SwRect aRect;
1265  if ( m_pFlyFrame->Lower() && m_pFlyFrame->Lower()->IsNoTextFrame() )
1266  {
1267  aRect = m_pFlyFrame->getFramePrintArea();
1268  aRect += m_pFlyFrame->getFrameArea().Pos();
1269  }
1270  else
1271  aRect = m_pFlyFrame->getFrameArea();
1272 
1273  if( aRect.IsInside( rRec.aPos ) )
1274  {
1275  aRect.Pos().setX(aRect.Pos().getX() + rRec.nTol);
1276  aRect.Pos().setY(aRect.Pos().getY() + rRec.nTol);
1277  aRect.AddHeight( -(2 * rRec.nTol) );
1278  aRect.AddWidth( -(2 * rRec.nTol) );
1279 
1280  if( aRect.IsInside( rRec.aPos ) )
1281  {
1282  if( !rURL.GetMap() ||
1284  return const_cast<SwVirtFlyDrawObj*>(this);
1285 
1286  return nullptr;
1287  }
1288  }
1289  }
1290  return SdrObject::CheckMacroHit( rRec );
1291 }
1292 
1294 {
1296 }
1297 
1298 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:338
double getY() const
Base class of the Writer layout elements.
Definition: frame.hxx:313
void expand(const B2DTuple &rTuple)
bool IsFlyLayFrame() const
Definition: flyfrm.hxx:217
virtual const SwFlyFrameFormat * GetFormat() const override
Definition: fly.cxx:2877
const basegfx::B2DRange & getViewport() const
virtual void addCropHandles(SdrHdlList &rTarget) const override
Definition: dflyobj.cxx:1202
B2DTuple absolute(const B2DTuple &rTup)
SwDocShell * GetDocShell()
Definition: doc.hxx:1352
SAL_WARN_UNUSED_RESULT Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
tools::Long getWidth() const
bool m_bSizProt
virtual void get2DDecomposition(Primitive2DDecompositionVisitor &rVisitor, const geometry::ViewInformation2D &rViewInformation) const override
basegfx::B2DRange getInnerBound() const
Definition: dflyobj.cxx:336
const SwFormatVertOrient & GetVertOrient(bool=true) const
Definition: fmtornt.hxx:106
void Left(const tools::Long nLeft)
Definition: swrect.hxx:194
void setSwRect(const SwRect &rNew)
Definition: frame.hxx:197
#define MINFLY
Definition: swtypes.hxx:60
SwTwips GetPos() const
Definition: fmtornt.hxx:92
long Long
virtual SdrObjectUniquePtr getFullDragClone() const override
Definition: dflyobj.cxx:1186
const SwRect & getFramePrintArea() const
Definition: frame.hxx:179
static SwCache & GetCache()
Definition: frame.hxx:520
void SetRect() const
Definition: dflyobj.cxx:552
SdrInventor
void Pos(const Point &rNew)
Definition: swrect.hxx:168
RotateFlyFrame3: Helper class when you want to make your SwFrame derivate transformable.
Definition: frame.hxx:234
tools::Rectangle m_aOutRect
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:144
const Size & GetUnrotatedSize() const
Definition: grfatr.hxx:108
bool IsRecord() const
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
bool IsSizeProtected() const
virtual void PaintSwFrame(vcl::RenderContext &rRenderContext, SwRect const &, SwPrintData const *const pPrintData=nullptr) const override
Definition: paintfrm.cxx:3982
static bool bInResize
Definition: dflyobj.cxx:71
sal_Int16 GetRelationOrient() const
Definition: fmtornt.hxx:55
void EndAllAction()
Definition: edws.cxx:97
virtual basegfx::B2DHomMatrix getFrameAreaTransformation() const
Definition: wsfrm.cxx:125
virtual void Rotate(const Point &rRef, Degree100 nAngle, double sn, double cs) override
Definition: dflyobj.cxx:384
SdrObjKind
sal_Int32 GetBrowseWidth() const
Definition: viewsh.cxx:1997
constexpr TypedWhichId< SwFlyFrameFormat > RES_FLYFRMFMT(156)
bool ContainsSwGrfNode() const
Definition: dflyobj.cxx:360
constexpr auto convertTwipToMm100(N n)
const MapMode & getPrePostMapMode() const
Definition: viewsh.hxx:227
static OutputDevice * GetDefaultDevice()
virtual SdrObject * CheckMacroHit(const SdrObjMacroHitRec &rRec) const
Used by the UI to modify the document model.
Definition: wrtsh.hxx:93
tools::Long getHeight() const
virtual void Rotate(const Point &rRef, Degree100 nAngle, double sn, double cs) override
Degree100 toDegree100(Degree10 x)
constexpr TypedWhichId< SwFormatVertOrient > RES_VERT_ORIENT(102)
sal_uInt16 CalcLeftLine() const
Definition: frmtool.hxx:513
tools::Long Left() const
constexpr TypedWhichId< SwFormatHoriOrient > RES_HORI_ORIENT(103)
SdrPage * getSdrPageFromSdrObject() const
void restoreFrameAreas()
Definition: wsfrm.cxx:269
const SwRect & getFrameArea() const
Definition: frame.hxx:178
bool getBrowseMode() const
Definition: viewopt.hxx:472
#define PRIMITIVE2D_ID_SWVIRTFLYDRAWOBJPRIMITIVE2D
void SetAttr(const SfxPoolItem &, SwFormat &)
Set attribute in given format.1y If Undo is enabled, the old values is added to the Undo history...
Definition: docfmt.cxx:451
Degree10 toDegree10(Degree100 x)
basegfx::B2DRange getOuterBound() const
Definition: dflyobj.cxx:312
bool m_bMovProt
static bool isTextBox(const SwFrameFormat *pFormat, sal_uInt16 nType)
Is the frame format a text box?
virtual ~SwFlyDrawObj() override
Definition: dflyobj.cxx:132
tools::Long Bottom() const
constexpr tools::Long GetWidth() const
void Width(tools::Long nNew)
Definition: swrect.hxx:186
bool OnRightPage() const
Definition: frame.hxx:732
Size GetPrefSize() const
const SdrObject & GetReferencedObj() const
virtual ~SwVirtFlyDrawObj() override
Definition: dflyobj.cxx:434
bool IsFlyInContentFrame() const
Definition: flyfrm.hxx:215
virtual bool HasMacro() const override
Definition: dflyobj.cxx:1253
B2IRange fround(const B2DRange &rRange)
virtual void Changed(const SdrObject &rObj, SdrUserCallType eType, const tools::Rectangle &rOldBoundRect)
const SwVirtFlyDrawObj & mrSwVirtFlyDrawObj
Definition: dflyobj.cxx:155
MapMode GetPrefMapMode() const
SwVirtFlyDrawObj(SdrModel &rSdrModel, SdrObject &rNew, SwFlyFrame *pFly)
Definition: dflyobj.cxx:422
bool IsColumnFrame() const
Definition: frame.hxx:1179
virtual PointerStyle GetMacroPointer(const SdrObjMacroHitRec &rRec) const override
Definition: dflyobj.cxx:1247
bool isEmpty() const
virtual void RecalcSnapRect() override
Definition: dflyobj.cxx:576
const SfxItemPool & GetAttrPool() const
Definition: viewsh.hxx:612
void ResizeRect(tools::Rectangle &rRect, const Point &rRef, const Fraction &rxFact, const Fraction &ryFact)
virtual void NbcResize(const Point &rRef, const Fraction &xFact, const Fraction &yFact) override
Definition: dflyobj.cxx:967
Style of a layout element.
Definition: frmfmt.hxx:58
void wrap_DoPaintObject(drawinglayer::geometry::ViewInformation2D const &) const
Definition: dflyobj.cxx:494
const SwFormatCol & GetCol(bool=true) const
Definition: fmtclds.hxx:165
virtual SdrObjKind GetObjIdentifier() const override
Definition: dflyobj.cxx:142
virtual std::unique_ptr< sdr::properties::BaseProperties > CreateObjectSpecificProperties() override
Definition: dflyobj.cxx:113
const SwColumns & GetColumns() const
Definition: fmtclds.hxx:112
const SwRect & VisArea() const
Definition: viewsh.cxx:564
virtual SdrInventor GetObjInventor() const override
Definition: dflyobj.cxx:137
virtual void NbcSetLogicRect(const tools::Rectangle &rRect) override
Definition: dflyobj.cxx:618
bool decompose(B2DTuple &rScale, B2DTuple &rTranslate, double &rRotate, double &rShearX) const
const SwFormatHoriOrient & GetHoriOrient(bool=true) const
Definition: fmtornt.hxx:108
SwPageFrame * FindPageFrame()
Definition: frame.hxx:679
constexpr TypedWhichId< SwCropGrf > RES_GRFATR_CROPGRF(134)
const SwFrame * Lower() const
Definition: layfrm.hxx:101
void SetAttrItem(const SfxPoolItem &, SetAttrMode nFlags=SetAttrMode::DEFAULT, const bool bParagraphSetting=false)
Definition: edatmisc.cxx:112
void BroadcastObjectChange() const
B2DPolygon createPolygonFromRect(const B2DRectangle &rRect, double fRadiusX, double fRadiusY)
sal_uInt16 GetHtmlMode(const SwDocShell *pShell)
Definition: viewopt.cxx:354
virtual void TakeObjInfo(SdrObjTransformInfoRec &rInfo) const override
Definition: dflyobj.cxx:536
const GraphicObject * GetGraphicObj() const
Definition: editsh.cxx:258
virtual void Resize(const Point &rRef, const Fraction &xFact, const Fraction &yFact, bool bUnsetRelative=true) override
Definition: dflyobj.cxx:1134
const SwFormatURL & GetURL(bool=true) const
Definition: fmturl.hxx:78
SwLayoutFrame * GetUpper()
Definition: frame.hxx:677
bool HasArea() const
Definition: swrect.hxx:287
void AddHeight(const tools::Long nAdd)
Definition: swrect.cxx:161
virtual SdrObject * CheckMacroHit(const SdrObjMacroHitRec &rRec) const override
Definition: dflyobj.cxx:1259
void scale(double fX, double fY)
SdrObjUserCall * m_pUserCall
sal_Int16 GetHoriOrient() const
Definition: fmtornt.hxx:87
sal_uInt32 GetOrdNum() const
constexpr auto convertMm100ToTwip(N n)
const SwAttrSet & GetAttrSet() const
Definition: frmtool.hxx:386
void AddWidth(const tools::Long nAdd)
Definition: swrect.cxx:160
MapUnit GetMapUnit() const
virtual void NbcCrop(const basegfx::B2DPoint &rRef, double fxFact, double fyFact) override
Definition: dflyobj.cxx:793
const SwRotationGrf & GetRotationGrf(bool=true) const
Definition: grfatr.hxx:286
const SwDoc * GetDoc() const
The document is set in SwAttrPool now, therefore you always can access it.
Definition: format.hxx:123
void SSize(const Size &rNew)
Definition: swrect.hxx:177
tools::Long Top() const
virtual SdrObject * RemoveObject(size_t nObjNum)
virtual void Move(const Size &rSiz) override
Definition: dflyobj.cxx:1127
SwBorderAttrs * Get()
Definition: frmtool.cxx:2630
constexpr Point TopLeft() const
Degree10 GetValue() const
Definition: grfatr.hxx:109
IMapObject * GetIMapObject(const Point &rPoint, const SwFlyFrame *pFly=nullptr) const
Definition: atrfrm.cxx:3546
basegfx::B2DRange b2DRectangleFromRectangle(const ::tools::Rectangle &rRect)
SAL_WARN_UNUSED_RESULT Point PixelToLogic(const Point &rDevicePt) const
bool IsPause() const
const ImageMap * GetMap() const
Definition: fmturl.hxx:68
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:450
virtual void DoDrawUndo(bool const bDoUndo)=0
Enable/Disable Undo for Drawing objects.
SwFlyFrame * m_pFlyFrame
Definition: dflyobj.hxx:63
void append(const B2DPolygon &rPolygon, sal_uInt32 nCount=1)
virtual const tools::Rectangle & GetLogicRect() const override
Definition: dflyobj.cxx:602
css::uno::Reference< css::graphic::XPrimitive2D > Primitive2DReference
bool IsPosToggle() const
Definition: fmtornt.hxx:95
const SwContentNode * GetNode() const
Definition: notxtfrm.hxx:66
SwFlyFrame * GetFlyFrame()
Definition: dflyobj.hxx:128
virtual Degree100 GetRotateAngle() const override
bool IsVertLR() const
Definition: frame.hxx:976
tools::Rectangle SVRect() const
Definition: swrect.hxx:279
general base class for all free-flowing frames
Definition: flyfrm.hxx:78
sal_Int16 GetRelationOrient() const
Definition: fmtornt.hxx:88
constexpr tools::Long Height() const
unsigned char sal_uInt8
SwPageFrame * GetPageFrame()
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:423
SwTwips GetPos() const
Definition: fmtornt.hxx:59
virtual const tools::Rectangle & GetLastBoundRect() const override
Definition: dflyobj.cxx:566
virtual void SetLogicRect(const tools::Rectangle &rRect) override
Definition: dflyobj.cxx:608
B2DHomMatrix createRotateAroundPoint(double fPointX, double fPointY, double fRadiant)
virtual Size ChgSize(const Size &aNewSize) override
Definition: fly.cxx:2122
bool IsInside(const Point &rPOINT) const
Definition: swrect.cxx:105
bool IsNoTextFrame() const
Definition: frame.hxx:1235
Primitive2DReference createHiddenGeometryPrimitives2D(const basegfx::B2DHomMatrix &rMatrix)
bool IsRightToLeft() const
Definition: frame.hxx:984
virtual void Crop(const basegfx::B2DPoint &rRef, double fxFact, double fyFact) override
Definition: dflyobj.cxx:1142
virtual void NbcSetSnapRect(const tools::Rectangle &rRect) override
Definition: dflyobj.cxx:597
const Size & GetBrowseBorder() const
Definition: viewsh.cxx:1992
std::unique_ptr< SdrObject, SdrObjectFreeOp > SdrObjectUniquePtr
sal_Int16 GetVertOrient() const
Definition: fmtornt.hxx:54
virtual std::unique_ptr< sdr::contact::ViewContact > CreateObjectSpecificViewContact() override
Definition: dflyobj.cxx:415
void translate(double fX, double fY)
static bool IsPaint(SdrObject *pObj, const SwViewShell *pSh)
Definition: paintfrm.cxx:3861
PointerStyle
virtual ::basegfx::B2DPolyPolygon TakeXorPoly() const override
Definition: dflyobj.cxx:623
bool GetCurAttr(SfxItemSet &, const bool bMergeIndentValuesOfNumRule=false) const
Definition: edattr.cxx:177
const SwFormatFrameSize & GetFrameSize(bool=true) const
Definition: fmtfsize.hxx:104
const SwAttrSet & GetSwAttrSet() const
Does node has already its own auto-attributes? Access to SwAttrSet.
Definition: node.hxx:715
virtual Degree100 GetRotateAngle() const override
Definition: dflyobj.cxx:1173
SwFlyDrawObj(SdrModel &rSdrModel)
Definition: dflyobj.cxx:126
virtual const tools::Rectangle & GetSnapRect() const override
Definition: dflyobj.cxx:581
const basegfx::B2DRange maOuterRange
Definition: dflyobj.cxx:156
virtual void RecalcBoundRect() override
Definition: dflyobj.cxx:571
void Move(tools::Long nHorzMoveDelta, tools::Long nVertMoveDelta)
bool IsVertical() const
Definition: frame.hxx:970
virtual std::unique_ptr< sdr::contact::ViewContact > CreateObjectSpecificViewContact() override
Definition: dflyobj.cxx:119
double getX() const
const SvxProtectItem & GetProtect(bool=true) const
Definition: frmatr.hxx:82
const SwFrame * GetAnchorFrame() const
virtual SdrObjectUniquePtr getFullDragClone() const override
SwGrfNode * GetGrfNode()
Definition: ndgrf.hxx:154
virtual bool HasLimitedRotation() const override
Definition: dflyobj.cxx:377
virtual void SetChanged()
void StartAllAction()
For all views of this document.
Definition: edws.cxx:86
bool IsBodyFrame() const
Definition: frame.hxx:1203
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:207
void ChgRelPos(const Point &rAbsPos)
Change the relative position.
Definition: fly.cxx:1120
void Height(tools::Long nNew)
Definition: swrect.hxx:190
bool operator==(const ScCsvLayoutData &rData1, const ScCsvLayoutData &rData2)
bool IsDrawingLayerPaintInProgress() const
Definition: viewsh.hxx:239
virtual void NbcMove(const Size &rSiz) override
Definition: dflyobj.cxx:635
virtual void SetSnapRect(const tools::Rectangle &rRect) override
Definition: dflyobj.cxx:587
tools::Long Right() const
SwRootFrame * getRootFrame()
Definition: frame.hxx:678
void SetRotation(Degree10 nOld, Degree10 nNew, const Size &rUnrotatedSize)
Definition: frmmgr.cxx:600
virtual bool IsTextBox() const override
Definition: dflyobj.cxx:1293
const SwFrameFormat * GetFormat() const
Definition: dflyobj.cxx:440
Point Center() const
void AddHdl(std::unique_ptr< SdrHdl > pHdl)
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1319
bool IsPosProtected() const
constexpr tools::Long GetHeight() const
const OUString & GetURL() const
Definition: fmturl.hxx:66
sal_uInt16 CalcRightLine() const
Definition: frmtool.hxx:519
Degree10 getPossibleRotationFromFraphicFrame(Size &rSize) const
Definition: dflyobj.cxx:1150
virtual const tools::Rectangle & GetCurrentBoundRect() const override
Definition: dflyobj.cxx:560
SwFlyDrawObjIdentifier
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo