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