1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <svx/svdcrtv.hxx>
22 #include <svx/xlnclit.hxx>
23 #include <svx/svdocapt.hxx>
24 #include <svx/svdoedge.hxx>
25 #include <svx/svdpagv.hxx>
26 #include <svx/svdpage.hxx>
27 #include <svx/scene3d.hxx>
28 #include <svx/view3d.hxx>
29 #include <svx/xfillit0.hxx>
30 #include <svx/xflclit.hxx>
31 #include <svx/xlineit0.hxx>
32 #include <svx/svdouno.hxx>
33 #include <svx/svdopath.hxx>
34 #include <svx/sdr/overlay/overlaypolypolygon.hxx>
35 #include <svx/sdr/overlay/overlaymanager.hxx>
36 #include <svx/sdrpaintwindow.hxx>
38 #include <svx/svdocirc.hxx>
39 #include <svx/sdr/contact/viewcontact.hxx>
40 #include <svx/sdr/overlay/overlayprimitive2dsequenceobject.hxx>
41 #include <vcl/ptrstyle.hxx>
43 using namespace com::sun::star
;
45 class ImplConnectMarkerOverlay
48 sdr::overlay::OverlayObjectList maObjects
;
50 // The remembered target object
51 const SdrObject
& mrObject
;
54 ImplConnectMarkerOverlay(const SdrCreateView
& rView
, SdrObject
const & rObject
);
56 // The OverlayObjects are cleared using the destructor of OverlayObjectList.
57 // That destructor calls clear() at the list which removes all objects from the
58 // OverlayManager and deletes them.
60 const SdrObject
& GetTargetObject() const { return mrObject
; }
63 ImplConnectMarkerOverlay::ImplConnectMarkerOverlay(const SdrCreateView
& rView
, SdrObject
const & rObject
)
66 basegfx::B2DPolyPolygon
aB2DPolyPolygon(rObject
.TakeXorPoly());
68 for(sal_uInt32
a(0); a
< rView
.PaintWindowCount(); a
++)
70 SdrPaintWindow
* pCandidate
= rView
.GetPaintWindow(a
);
71 const rtl::Reference
< sdr::overlay::OverlayManager
>& xTargetOverlay
= pCandidate
->GetOverlayManager();
73 if(xTargetOverlay
.is())
75 float fScalingFactor
= xTargetOverlay
->getOutputDevice().GetDPIScaleFactor();
76 Size
aHalfLogicSize(xTargetOverlay
->getOutputDevice().PixelToLogic(Size(4 * fScalingFactor
, 4 * fScalingFactor
)));
79 std::unique_ptr
<sdr::overlay::OverlayPolyPolygonStripedAndFilled
> pNew(new sdr::overlay::OverlayPolyPolygonStripedAndFilled(
81 xTargetOverlay
->add(*pNew
);
82 maObjects
.append(std::move(pNew
));
85 for(sal_uInt16
i(0); i
< 4; i
++)
87 SdrGluePoint
aGluePoint(rObject
.GetVertexGluePoint(i
));
88 const Point
& rPosition
= aGluePoint
.GetAbsolutePos(rObject
);
90 basegfx::B2DPoint
aTopLeft(rPosition
.X() - aHalfLogicSize
.Width(), rPosition
.Y() - aHalfLogicSize
.Height());
91 basegfx::B2DPoint
aBottomRight(rPosition
.X() + aHalfLogicSize
.Width(), rPosition
.Y() + aHalfLogicSize
.Height());
93 basegfx::B2DPolygon aTempPoly
;
94 aTempPoly
.append(aTopLeft
);
95 aTempPoly
.append(basegfx::B2DPoint(aBottomRight
.getX(), aTopLeft
.getY()));
96 aTempPoly
.append(aBottomRight
);
97 aTempPoly
.append(basegfx::B2DPoint(aTopLeft
.getX(), aBottomRight
.getY()));
98 aTempPoly
.setClosed(true);
100 basegfx::B2DPolyPolygon aTempPolyPoly
;
101 aTempPolyPoly
.append(aTempPoly
);
103 std::unique_ptr
<sdr::overlay::OverlayPolyPolygonStripedAndFilled
> pNew2(new sdr::overlay::OverlayPolyPolygonStripedAndFilled(
104 std::move(aTempPolyPoly
)));
105 xTargetOverlay
->add(*pNew2
);
106 maObjects
.append(std::move(pNew2
));
112 class ImpSdrCreateViewExtraData
114 // The OverlayObjects for XOR replacement
115 sdr::overlay::OverlayObjectList maObjects
;
118 ImpSdrCreateViewExtraData();
119 ~ImpSdrCreateViewExtraData();
121 void CreateAndShowOverlay(const SdrCreateView
& rView
, const SdrObject
* pObject
, const basegfx::B2DPolyPolygon
& rPolyPoly
);
125 ImpSdrCreateViewExtraData::ImpSdrCreateViewExtraData()
129 ImpSdrCreateViewExtraData::~ImpSdrCreateViewExtraData()
134 void ImpSdrCreateViewExtraData::CreateAndShowOverlay(const SdrCreateView
& rView
, const SdrObject
* pObject
, const basegfx::B2DPolyPolygon
& rPolyPoly
)
136 for(sal_uInt32
a(0); a
< rView
.PaintWindowCount(); a
++)
138 SdrPaintWindow
* pCandidate
= rView
.GetPaintWindow(a
);
139 const rtl::Reference
<sdr::overlay::OverlayManager
>& xOverlayManager
= pCandidate
->GetOverlayManager();
141 if (xOverlayManager
.is())
145 const sdr::contact::ViewContact
& rVC
= pObject
->GetViewContact();
146 drawinglayer::primitive2d::Primitive2DContainer aSequence
;
147 rVC
.getViewIndependentPrimitive2DContainer(aSequence
);
148 std::unique_ptr
<sdr::overlay::OverlayObject
> pNew(new sdr::overlay::OverlayPrimitive2DSequenceObject(std::move(aSequence
)));
150 xOverlayManager
->add(*pNew
);
151 maObjects
.append(std::move(pNew
));
154 if(rPolyPoly
.count())
156 std::unique_ptr
<sdr::overlay::OverlayPolyPolygonStripedAndFilled
> pNew(new sdr::overlay::OverlayPolyPolygonStripedAndFilled(
158 xOverlayManager
->add(*pNew
);
159 maObjects
.append(std::move(pNew
));
165 void ImpSdrCreateViewExtraData::HideOverlay()
167 // the clear() call of the list removes all objects from the
168 // OverlayManager and deletes them.
176 void SdrCreateView::ImpClearConnectMarker()
178 mpCoMaOverlay
.reset();
181 SdrCreateView::SdrCreateView(SdrModel
& rSdrModel
, OutputDevice
* pOut
)
182 : SdrDragView(rSdrModel
, pOut
)
183 , mpCreatePV(nullptr)
184 , mpCreateViewExtraData(new ImpSdrCreateViewExtraData())
185 , maCurrentCreatePointer(PointerStyle::Cross
)
186 , mnAutoCloseDistPix(5)
187 , mnFreeHandMinDistPix(10)
188 , mnCurrentInvent(SdrInventor::Default
)
189 , mnCurrentIdent(SdrObjKind::NONE
)
190 , mb1stPointAsCenter(false)
191 , mbUseIncompatiblePathCreateInterface(false)
195 SdrCreateView::~SdrCreateView()
197 ImpClearConnectMarker();
198 mpCreateViewExtraData
.reset();
201 bool SdrCreateView::IsAction() const
203 return SdrDragView::IsAction() || mpCurrentCreate
!=nullptr;
206 void SdrCreateView::MovAction(const Point
& rPnt
)
208 SdrDragView::MovAction(rPnt
);
209 if (mpCurrentCreate
!= nullptr) {
214 void SdrCreateView::EndAction()
216 if (mpCurrentCreate
!= nullptr) EndCreateObj(SdrCreateCmd::ForceEnd
);
217 SdrDragView::EndAction();
220 void SdrCreateView::BckAction()
222 if (mpCurrentCreate
!= nullptr) BckCreateObj();
223 SdrDragView::BckAction();
226 void SdrCreateView::BrkAction()
228 SdrDragView::BrkAction();
232 void SdrCreateView::TakeActionRect(tools::Rectangle
& rRect
) const
234 if (mpCurrentCreate
!= nullptr)
236 rRect
=maDragStat
.GetActionRect();
239 rRect
=tools::Rectangle(maDragStat
.GetPrev(),maDragStat
.GetNow());
244 SdrDragView::TakeActionRect(rRect
);
248 bool SdrCreateView::CheckEdgeMode()
250 if (mpCurrentCreate
!= nullptr)
252 // is managed by EdgeObj
253 if (mnCurrentInvent
==SdrInventor::Default
&& mnCurrentIdent
==SdrObjKind::Edge
) return false;
256 if (!IsCreateMode() || mnCurrentInvent
!=SdrInventor::Default
|| mnCurrentIdent
!=SdrObjKind::Edge
)
258 ImpClearConnectMarker();
263 // sal_True, if MouseMove should check Connect
268 void SdrCreateView::SetConnectMarker(const SdrObjConnection
& rCon
)
270 SdrObject
* pTargetObject
= rCon
.pObj
;
274 // if target object changes, throw away overlay object to make room for changes
275 if(mpCoMaOverlay
&& pTargetObject
!= &mpCoMaOverlay
->GetTargetObject())
277 ImpClearConnectMarker();
282 mpCoMaOverlay
.reset(new ImplConnectMarkerOverlay(*this, *pTargetObject
));
287 ImpClearConnectMarker();
291 void SdrCreateView::HideConnectMarker()
293 ImpClearConnectMarker();
296 bool SdrCreateView::MouseMove(const MouseEvent
& rMEvt
, OutputDevice
* pWin
)
298 if(CheckEdgeMode() && pWin
)
300 SdrPageView
* pPV
= GetSdrPageView();
304 // TODO: Change default hit tolerance at IsMarkedHit() some time!
305 Point
aPos(pWin
->PixelToLogic(rMEvt
.GetPosPixel()));
306 bool bMarkHit
=PickHandle(aPos
)!=nullptr || IsMarkedObjHit(aPos
);
307 SdrObjConnection aCon
;
308 if (!bMarkHit
) SdrEdgeObj::ImpFindConnector(aPos
,*pPV
,aCon
,nullptr,pWin
);
309 SetConnectMarker(aCon
);
312 return SdrDragView::MouseMove(rMEvt
,pWin
);
315 bool SdrCreateView::IsTextTool() const
317 return meEditMode
==SdrViewEditMode::Create
318 && mnCurrentInvent
==SdrInventor::Default
319 && (mnCurrentIdent
==SdrObjKind::Text
320 || mnCurrentIdent
==SdrObjKind::TitleText
321 || mnCurrentIdent
==SdrObjKind::OutlineText
);
324 bool SdrCreateView::IsEdgeTool() const
326 return meEditMode
==SdrViewEditMode::Create
&& mnCurrentInvent
==SdrInventor::Default
&& (mnCurrentIdent
==SdrObjKind::Edge
);
329 bool SdrCreateView::IsMeasureTool() const
331 return meEditMode
==SdrViewEditMode::Create
&& mnCurrentInvent
==SdrInventor::Default
&& (mnCurrentIdent
==SdrObjKind::Measure
);
334 void SdrCreateView::SetCurrentObj(SdrObjKind nIdent
, SdrInventor nInvent
)
336 if (mnCurrentInvent
!=nInvent
|| mnCurrentIdent
!=nIdent
)
338 mnCurrentInvent
=nInvent
;
339 mnCurrentIdent
=nIdent
;
340 rtl::Reference
<SdrObject
> pObj
= (nIdent
== SdrObjKind::NONE
) ? nullptr :
341 SdrObjFactory::MakeNewObject(
348 // Using text tool, mouse cursor is usually I-Beam,
349 // crosshairs with tiny I-Beam appears only on MouseButtonDown.
352 // Here the correct pointer needs to be used
353 // if the default is set to vertical writing
354 maCurrentCreatePointer
= PointerStyle::Text
;
357 maCurrentCreatePointer
= pObj
->GetCreatePointer();
361 maCurrentCreatePointer
= PointerStyle::Cross
;
366 ImpSetGlueVisible3(IsEdgeTool());
369 bool SdrCreateView::ImpBegCreateObj(SdrInventor nInvent
, SdrObjKind nIdent
, const Point
& rPnt
, OutputDevice
* pOut
,
370 sal_Int16 nMinMov
, const tools::Rectangle
& rLogRect
, SdrObject
* pPreparedFactoryObject
)
376 ImpClearConnectMarker();
378 mpCreatePV
= GetSdrPageView();
380 if (mpCreatePV
!= nullptr)
381 { // otherwise no side registered!
382 OUString
aLay(maActualLayer
);
384 if(nInvent
== SdrInventor::Default
&& nIdent
== SdrObjKind::Measure
&& !maMeasureLayer
.isEmpty())
386 aLay
= maMeasureLayer
;
389 SdrLayerID nLayer
= mpCreatePV
->GetPage()->GetLayerAdmin().GetLayerID(aLay
);
390 if (nLayer
==SDRLAYER_NOTFOUND
) nLayer
= SdrLayerID(0);
391 if (!mpCreatePV
->GetLockedLayers().IsSet(nLayer
) && mpCreatePV
->GetVisibleLayers().IsSet(nLayer
))
393 if(pPreparedFactoryObject
)
395 mpCurrentCreate
= pPreparedFactoryObject
;
399 mpCurrentCreate
= SdrObjFactory::MakeNewObject(
400 GetModel(), nInvent
, nIdent
);
404 if (mnCurrentInvent
!= SdrInventor::Default
|| (mnCurrentIdent
!= SdrObjKind::Edge
&&
405 mnCurrentIdent
!= SdrObjKind::FreehandLine
&&
406 mnCurrentIdent
!= SdrObjKind::FreehandFill
)) { // no snapping for Edge and Freehand
407 aPnt
=GetSnapPos(aPnt
, mpCreatePV
);
409 if (mpCurrentCreate
!=nullptr)
411 if (mpDefaultStyleSheet
!=nullptr) mpCurrentCreate
->NbcSetStyleSheet(mpDefaultStyleSheet
, false);
413 // SW uses a naked SdrObject for frame construction. Normally, such an
414 // object should not be created. Since it is possible to use it as a helper
415 // object (e.g. in letting the user define an area with the interactive
416 // construction) at least no items should be set at that object.
417 if(nInvent
!= SdrInventor::Default
|| nIdent
!= SdrObjKind::NewFrame
)
419 mpCurrentCreate
->SetMergedItemSet(maDefaultAttr
);
422 if (dynamic_cast<const SdrCaptionObj
*>(mpCurrentCreate
.get()) != nullptr)
424 SfxItemSet
aSet(GetModel().GetItemPool());
425 aSet
.Put(XFillColorItem(OUString(),COL_WHITE
)); // in case someone turns on Solid
426 aSet
.Put(XFillStyleItem(drawing::FillStyle_NONE
));
428 mpCurrentCreate
->SetMergedItemSet(aSet
);
430 if (nInvent
== SdrInventor::Default
&& (nIdent
==SdrObjKind::Text
|| nIdent
==SdrObjKind::TitleText
|| nIdent
==SdrObjKind::OutlineText
))
432 // default for all text frames: no background, no border
433 SfxItemSet
aSet(GetModel().GetItemPool());
434 aSet
.Put(XFillColorItem(OUString(),COL_WHITE
)); // in case someone turns on Solid
435 aSet
.Put(XFillStyleItem(drawing::FillStyle_NONE
));
436 aSet
.Put(XLineColorItem(OUString(),COL_BLACK
)); // in case someone turns on Solid
437 aSet
.Put(XLineStyleItem(drawing::LineStyle_NONE
));
439 mpCurrentCreate
->SetMergedItemSet(aSet
);
441 if (!rLogRect
.IsEmpty()) mpCurrentCreate
->NbcSetLogicRect(rLogRect
);
443 // make sure drag start point is inside WorkArea
444 const tools::Rectangle
& rWorkArea
= GetWorkArea();
446 if(!rWorkArea
.IsEmpty())
448 if(aPnt
.X() < rWorkArea
.Left())
450 aPnt
.setX( rWorkArea
.Left() );
453 if(aPnt
.X() > rWorkArea
.Right())
455 aPnt
.setX( rWorkArea
.Right() );
458 if(aPnt
.Y() < rWorkArea
.Top())
460 aPnt
.setY( rWorkArea
.Top() );
463 if(aPnt
.Y() > rWorkArea
.Bottom())
465 aPnt
.setY( rWorkArea
.Bottom() );
469 maDragStat
.Reset(aPnt
);
470 maDragStat
.SetView(static_cast<SdrView
*>(this));
471 maDragStat
.SetPageView(mpCreatePV
);
472 maDragStat
.SetMinMove(ImpGetMinMovLogic(nMinMov
,pOut
));
474 if (mpCurrentCreate
->BegCreate(maDragStat
))
476 ShowCreateObj(/*pOut,sal_True*/);
481 mpCurrentCreate
= nullptr;
482 mpCreatePV
= nullptr;
490 bool SdrCreateView::BegCreateObj(const Point
& rPnt
, OutputDevice
* pOut
, short nMinMov
)
492 return ImpBegCreateObj(mnCurrentInvent
,mnCurrentIdent
,rPnt
,pOut
,nMinMov
,tools::Rectangle(), nullptr);
495 bool SdrCreateView::BegCreatePreparedObject(const Point
& rPnt
, sal_Int16 nMinMov
, SdrObject
* pPreparedFactoryObject
)
497 SdrInventor
nInvent(mnCurrentInvent
);
498 SdrObjKind
nIdent(mnCurrentIdent
);
500 if(pPreparedFactoryObject
)
502 nInvent
= pPreparedFactoryObject
->GetObjInventor();
503 nIdent
= pPreparedFactoryObject
->GetObjIdentifier();
506 return ImpBegCreateObj(nInvent
, nIdent
, rPnt
, nullptr, nMinMov
, tools::Rectangle(), pPreparedFactoryObject
);
509 bool SdrCreateView::BegCreateCaptionObj(const Point
& rPnt
, const Size
& rObjSiz
,
510 OutputDevice
* pOut
, short nMinMov
)
512 return ImpBegCreateObj(SdrInventor::Default
,SdrObjKind::Caption
,rPnt
,pOut
,nMinMov
,
513 tools::Rectangle(rPnt
,Size(rObjSiz
.Width()+1,rObjSiz
.Height()+1)), nullptr);
516 void SdrCreateView::MovCreateObj(const Point
& rPnt
)
518 if (mpCurrentCreate
==nullptr)
522 if (!maDragStat
.IsNoSnap())
524 aPnt
=GetSnapPos(aPnt
, mpCreatePV
);
528 if (maDragStat
.IsOrtho8Possible()) OrthoDistance8(maDragStat
.GetPrev(),aPnt
,IsBigOrtho());
529 else if (maDragStat
.IsOrtho4Possible()) OrthoDistance4(maDragStat
.GetPrev(),aPnt
,IsBigOrtho());
532 // If the drag point was limited and Ortho is active, do
533 // the small ortho correction (reduction) -> last parameter to FALSE.
534 bool bDidLimit(ImpLimitToWorkArea(aPnt
));
535 if(bDidLimit
&& IsOrtho())
537 if(maDragStat
.IsOrtho8Possible())
538 OrthoDistance8(maDragStat
.GetPrev(), aPnt
, false);
539 else if(maDragStat
.IsOrtho4Possible())
540 OrthoDistance4(maDragStat
.GetPrev(), aPnt
, false);
543 if (aPnt
==maDragStat
.GetNow()) return;
544 bool bIsMinMoved(maDragStat
.IsMinMoved());
545 if (!maDragStat
.CheckMinMoved(aPnt
))
548 if (!bIsMinMoved
) maDragStat
.NextPoint();
549 maDragStat
.NextMove(aPnt
);
550 mpCurrentCreate
->MovCreate(maDragStat
);
552 // MovCreate changes the object, so use ActionChanged() on it
553 mpCurrentCreate
->ActionChanged();
555 // replace for DrawCreateObjDiff
560 void SdrCreateView::SetupObjLayer(const SdrPageView
* pPageView
, const OUString
& aActiveLayer
, SdrObject
* pObj
)
562 const SdrLayerAdmin
& rAd
= pPageView
->GetPage()->GetLayerAdmin();
563 SdrLayerID
nLayer(0);
566 if(dynamic_cast<const FmFormObj
*>( pObj
) != nullptr)
568 // for FormControls, force to form layer
569 nLayer
= rAd
.GetLayerID(rAd
.GetControlLayerName());
573 nLayer
= rAd
.GetLayerID(aActiveLayer
);
576 if(SDRLAYER_NOTFOUND
== nLayer
)
578 nLayer
= SdrLayerID(0);
581 pObj
->SetLayer(nLayer
);
584 bool SdrCreateView::EndCreateObj(SdrCreateCmd eCmd
)
587 SdrObject
* pObjCreated
=mpCurrentCreate
.get();
589 if (mpCurrentCreate
!=nullptr)
591 sal_uInt32 nCount
=maDragStat
.GetPointCount();
593 if (nCount
<=1 && eCmd
==SdrCreateCmd::ForceEnd
)
595 BrkCreateObj(); // objects with only a single point don't exist (at least today)
596 return false; // sal_False = event not interpreted
599 bool bPntsEq
=nCount
>1;
601 Point aP0
=maDragStat
.GetPoint(0);
602 while (bPntsEq
&& i
<nCount
) { bPntsEq
=aP0
==maDragStat
.GetPoint(i
); i
++; }
604 if (mpCurrentCreate
->EndCreate(maDragStat
,eCmd
))
610 // otherwise Brk, because all points are equal
611 rtl::Reference
<SdrObject
> pObj
= std::move(mpCurrentCreate
);
613 SetupObjLayer(mpCreatePV
, maActualLayer
, pObj
.get());
615 // recognize creation of a new 3D object inside a 3D scene
616 bool bSceneIntoScene(false);
618 E3dScene
* pObjScene
= DynCastE3dScene(pObjCreated
);
619 E3dScene
* pCurrentScene
= pObjScene
? DynCastE3dScene(mpCreatePV
->GetCurrentGroup()) : nullptr;
622 bool bDidInsert
= static_cast<E3dView
*>(this)->ImpCloneAll3DObjectsToDestScene(
623 pObjScene
, pCurrentScene
, Point(0, 0));
627 pObjCreated
= nullptr;
628 bSceneIntoScene
= true;
634 // Here an interactively created SdrObject gets added, so
635 // take into account that interaction created an object in
636 // model coordinates. If we have e.g. a GirdOffset, this is a
637 // little bit tricky - we have an object in model coordinates,
638 // so the fetched offset is at the wrong point in principle
639 // since we need to 'substract' the offset here to get to
640 // 'real' model coordinates. But we have nothing better here,
642 // The 2nd a little tricky thing is that this will early-create
643 // a ViewObjectContact for the new SdrObject, but these VOCs
644 // are anyways layouted for being create-on-demand. This will
645 // be adapted/replaced correctly later on.
646 // This *should* be the right place for getting all interactively
647 // created objects, see InsertObjectAtView below that calls
648 // CreateUndoNewObject.
649 basegfx::B2DVector
aGridOffset(0.0, 0.0);
650 if(getPossibleGridOffsetForSdrObject(aGridOffset
, pObj
.get(), mpCreatePV
))
653 basegfx::fround(-aGridOffset
.getX()),
654 basegfx::fround(-aGridOffset
.getY()));
656 pObj
->NbcMove(aOffset
);
659 // do the same as before
660 InsertObjectAtView(pObj
.get(), *mpCreatePV
);
663 mpCreatePV
= nullptr;
664 bRet
=true; // sal_True = event interpreted
673 if (eCmd
==SdrCreateCmd::ForceEnd
|| // nothing there -- force ending
674 nCount
==0 || // no existing points (should never happen)
675 (nCount
<=1 && !maDragStat
.IsMinMoved())) { // MinMove not met
680 // replace for DrawCreateObjDiff
683 maDragStat
.ResetMinMoved(); // NextPoint is at MovCreateObj()
691 void SdrCreateView::BckCreateObj()
693 if (mpCurrentCreate
==nullptr)
696 if (maDragStat
.GetPointCount()<=2 )
703 maDragStat
.PrevPoint();
704 if (mpCurrentCreate
->BckCreate(maDragStat
))
715 void SdrCreateView::BrkCreateObj()
717 if (mpCurrentCreate
!=nullptr)
720 mpCurrentCreate
->BrkCreate(maDragStat
);
721 mpCurrentCreate
= nullptr;
722 mpCreatePV
= nullptr;
726 void SdrCreateView::ShowCreateObj(/*OutputDevice* pOut, sal_Bool bFull*/)
728 if(!IsCreateObj() || maDragStat
.IsShown())
733 // for migration from XOR, replace DrawDragObj here to create
734 // overlay objects instead.
735 bool bUseSolidDragging(IsSolidDragging());
737 // #i101648# check if dragged object is a SdrObjKind::NewFrame.
738 // This is e.g. used in SW Frame construction as placeholder.
739 // Do not use SolidDragging for SdrObjKind::NewFrame kind of objects,
740 // they cannot have a valid optical representation.
741 if (bUseSolidDragging
&& SdrObjKind::NewFrame
== mpCurrentCreate
->GetObjIdentifier())
743 bUseSolidDragging
= false;
746 // check for objects with no fill and no line
747 if(bUseSolidDragging
)
749 const SfxItemSet
& rSet
= mpCurrentCreate
->GetMergedItemSet();
750 const drawing::FillStyle
eFill(rSet
.Get(XATTR_FILLSTYLE
).GetValue());
751 const drawing::LineStyle
eLine(rSet
.Get(XATTR_LINESTYLE
).GetValue());
753 if(drawing::LineStyle_NONE
== eLine
&& drawing::FillStyle_NONE
== eFill
)
755 bUseSolidDragging
= false;
759 // check for form controls
760 if(bUseSolidDragging
)
762 if (dynamic_cast<const SdrUnoObj
*>(mpCurrentCreate
.get()) != nullptr)
764 bUseSolidDragging
= false;
768 // #i101781# force to non-solid dragging when not creating a full circle
769 if(bUseSolidDragging
)
771 SdrCircObj
* pCircObj
= dynamic_cast<SdrCircObj
*>(mpCurrentCreate
.get());
773 if(pCircObj
&& SdrObjKind::CircleOrEllipse
!= pCircObj
->GetObjIdentifier())
775 // #i103058# Allow SolidDragging with four points
776 if(maDragStat
.GetPointCount() < 4)
778 bUseSolidDragging
= false;
783 if(bUseSolidDragging
)
785 basegfx::B2DPolyPolygon aDragPolyPolygon
;
787 if (dynamic_cast<const SdrRectObj
*>(mpCurrentCreate
.get()) != nullptr)
789 // ensure object has some size, necessary for SdrTextObj because
790 // there are still untested divisions by that sizes
791 tools::Rectangle
aCurrentSnapRect(mpCurrentCreate
->GetSnapRect());
793 if(aCurrentSnapRect
.GetWidth() <= 1 || aCurrentSnapRect
.GetHeight() <= 1)
795 tools::Rectangle
aNewRect(maDragStat
.GetStart(), maDragStat
.GetStart() + Point(2, 2));
796 mpCurrentCreate
->NbcSetSnapRect(aNewRect
);
800 if (auto pPathObj
= dynamic_cast<SdrPathObj
*>(mpCurrentCreate
.get()))
802 // The up-to-now created path needs to be set at the object to have something
803 // that can be visualized
804 const basegfx::B2DPolyPolygon
aCurrentPolyPolygon(pPathObj
->getObjectPolyPolygon(maDragStat
));
806 if(aCurrentPolyPolygon
.count())
808 pPathObj
->NbcSetPathPoly(aCurrentPolyPolygon
);
811 aDragPolyPolygon
= pPathObj
->getDragPolyPolygon(maDragStat
);
814 // use the SdrObject directly for overlay
815 mpCreateViewExtraData
->CreateAndShowOverlay(*this, mpCurrentCreate
.get(), aDragPolyPolygon
);
819 const ::basegfx::B2DPolyPolygon
aPoly(mpCurrentCreate
->TakeCreatePoly(maDragStat
));
821 mpCreateViewExtraData
->CreateAndShowOverlay(*this, nullptr, aPoly
);
824 // #i101679# Force changed overlay to be shown
825 for(sal_uInt32
a(0); a
< PaintWindowCount(); a
++)
827 SdrPaintWindow
* pCandidate
= GetPaintWindow(a
);
828 const rtl::Reference
<sdr::overlay::OverlayManager
>& xOverlayManager
= pCandidate
->GetOverlayManager();
830 if (xOverlayManager
.is())
832 xOverlayManager
->flush();
837 maDragStat
.SetShown(true);
840 void SdrCreateView::HideCreateObj()
842 if(IsCreateObj() && maDragStat
.IsShown())
844 // for migration from XOR, replace DrawDragObj here to create
845 // overlay objects instead.
846 mpCreateViewExtraData
->HideOverlay();
848 //DrawCreateObj(pOut,bFull);
849 maDragStat
.SetShown(false);
854 void SdrCreateView::GetAttributes(SfxItemSet
& rTargetSet
, bool bOnlyHardAttr
) const
858 rTargetSet
.Put(mpCurrentCreate
->GetMergedItemSet());
862 SdrDragView::GetAttributes(rTargetSet
, bOnlyHardAttr
);
866 bool SdrCreateView::SetAttributes(const SfxItemSet
& rSet
, bool bReplaceAll
)
870 mpCurrentCreate
->SetMergedItemSetAndBroadcast(rSet
, bReplaceAll
);
876 return SdrDragView::SetAttributes(rSet
,bReplaceAll
);
880 SfxStyleSheet
* SdrCreateView::GetStyleSheet() const
882 if (mpCurrentCreate
!= nullptr)
884 return mpCurrentCreate
->GetStyleSheet();
888 return SdrDragView::GetStyleSheet();
892 void SdrCreateView::SetStyleSheet(SfxStyleSheet
* pStyleSheet
, bool bDontRemoveHardAttr
)
894 if (mpCurrentCreate
!= nullptr)
896 mpCurrentCreate
->SetStyleSheet(pStyleSheet
,bDontRemoveHardAttr
);
900 SdrDragView::SetStyleSheet(pStyleSheet
,bDontRemoveHardAttr
);
904 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */