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