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