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