/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace com::sun::star; class ImplConnectMarkerOverlay { // The OverlayObjects sdr::overlay::OverlayObjectList maObjects; // The remembered target object const SdrObject& mrObject; public: ImplConnectMarkerOverlay(const SdrCreateView& rView, SdrObject const & rObject); // The OverlayObjects are cleared using the destructor of OverlayObjectList. // That destructor calls clear() at the list which removes all objects from the // OverlayManager and deletes them. const SdrObject& GetTargetObject() const { return mrObject; } }; ImplConnectMarkerOverlay::ImplConnectMarkerOverlay(const SdrCreateView& rView, SdrObject const & rObject) : mrObject(rObject) { basegfx::B2DPolyPolygon aB2DPolyPolygon(rObject.TakeXorPoly()); for(sal_uInt32 a(0); a < rView.PaintWindowCount(); a++) { SdrPaintWindow* pCandidate = rView.GetPaintWindow(a); const rtl::Reference< sdr::overlay::OverlayManager >& xTargetOverlay = pCandidate->GetOverlayManager(); if(xTargetOverlay.is()) { float fScalingFactor = xTargetOverlay->getOutputDevice().GetDPIScaleFactor(); Size aHalfLogicSize(xTargetOverlay->getOutputDevice().PixelToLogic(Size(4 * fScalingFactor, 4 * fScalingFactor))); // object std::unique_ptr pNew(new sdr::overlay::OverlayPolyPolygonStripedAndFilled( aB2DPolyPolygon)); xTargetOverlay->add(*pNew); maObjects.append(std::move(pNew)); // gluepoints for(sal_uInt16 i(0); i < 4; i++) { SdrGluePoint aGluePoint(rObject.GetVertexGluePoint(i)); const Point& rPosition = aGluePoint.GetAbsolutePos(rObject); basegfx::B2DPoint aTopLeft(rPosition.X() - aHalfLogicSize.Width(), rPosition.Y() - aHalfLogicSize.Height()); basegfx::B2DPoint aBottomRight(rPosition.X() + aHalfLogicSize.Width(), rPosition.Y() + aHalfLogicSize.Height()); basegfx::B2DPolygon aTempPoly; aTempPoly.append(aTopLeft); aTempPoly.append(basegfx::B2DPoint(aBottomRight.getX(), aTopLeft.getY())); aTempPoly.append(aBottomRight); aTempPoly.append(basegfx::B2DPoint(aTopLeft.getX(), aBottomRight.getY())); aTempPoly.setClosed(true); basegfx::B2DPolyPolygon aTempPolyPoly; aTempPolyPoly.append(aTempPoly); std::unique_ptr pNew2(new sdr::overlay::OverlayPolyPolygonStripedAndFilled( aTempPolyPoly)); xTargetOverlay->add(*pNew2); maObjects.append(std::move(pNew2)); } } } } class ImpSdrCreateViewExtraData { // The OverlayObjects for XOR replacement sdr::overlay::OverlayObjectList maObjects; public: ImpSdrCreateViewExtraData(); ~ImpSdrCreateViewExtraData(); void CreateAndShowOverlay(const SdrCreateView& rView, const SdrObject* pObject, const basegfx::B2DPolyPolygon& rPolyPoly); void HideOverlay(); }; ImpSdrCreateViewExtraData::ImpSdrCreateViewExtraData() { } ImpSdrCreateViewExtraData::~ImpSdrCreateViewExtraData() { HideOverlay(); } void ImpSdrCreateViewExtraData::CreateAndShowOverlay(const SdrCreateView& rView, const SdrObject* pObject, const basegfx::B2DPolyPolygon& rPolyPoly) { for(sal_uInt32 a(0); a < rView.PaintWindowCount(); a++) { SdrPaintWindow* pCandidate = rView.GetPaintWindow(a); const rtl::Reference& xOverlayManager = pCandidate->GetOverlayManager(); if (xOverlayManager.is()) { if(pObject) { const sdr::contact::ViewContact& rVC = pObject->GetViewContact(); drawinglayer::primitive2d::Primitive2DContainer aSequence; rVC.getViewIndependentPrimitive2DContainer(aSequence); std::unique_ptr pNew(new sdr::overlay::OverlayPrimitive2DSequenceObject(std::move(aSequence))); xOverlayManager->add(*pNew); maObjects.append(std::move(pNew)); } if(rPolyPoly.count()) { std::unique_ptr pNew(new sdr::overlay::OverlayPolyPolygonStripedAndFilled( rPolyPoly)); xOverlayManager->add(*pNew); maObjects.append(std::move(pNew)); } } } } void ImpSdrCreateViewExtraData::HideOverlay() { // the clear() call of the list removes all objects from the // OverlayManager and deletes them. maObjects.clear(); } // CreateView void SdrCreateView::ImpClearConnectMarker() { mpCoMaOverlay.reset(); } SdrCreateView::SdrCreateView(SdrModel& rSdrModel, OutputDevice* pOut) : SdrDragView(rSdrModel, pOut) , mpCurrentCreate(nullptr) , mpCreatePV(nullptr) , mpCreateViewExtraData(new ImpSdrCreateViewExtraData()) , maCurrentCreatePointer(PointerStyle::Cross) , mnAutoCloseDistPix(5) , mnFreeHandMinDistPix(10) , mnCurrentInvent(SdrInventor::Default) , mnCurrentIdent(SdrObjKind::NONE) , mb1stPointAsCenter(false) , mbUseIncompatiblePathCreateInterface(false) { } SdrCreateView::~SdrCreateView() { ImpClearConnectMarker(); mpCreateViewExtraData.reset(); SdrObject::Free(mpCurrentCreate); } bool SdrCreateView::IsAction() const { return SdrDragView::IsAction() || mpCurrentCreate!=nullptr; } void SdrCreateView::MovAction(const Point& rPnt) { SdrDragView::MovAction(rPnt); if (mpCurrentCreate != nullptr) { MovCreateObj(rPnt); } } void SdrCreateView::EndAction() { if (mpCurrentCreate != nullptr) EndCreateObj(SdrCreateCmd::ForceEnd); SdrDragView::EndAction(); } void SdrCreateView::BckAction() { if (mpCurrentCreate != nullptr) BckCreateObj(); SdrDragView::BckAction(); } void SdrCreateView::BrkAction() { SdrDragView::BrkAction(); BrkCreateObj(); } void SdrCreateView::TakeActionRect(tools::Rectangle& rRect) const { if (mpCurrentCreate != nullptr) { rRect=maDragStat.GetActionRect(); if (rRect.IsEmpty()) { rRect=tools::Rectangle(maDragStat.GetPrev(),maDragStat.GetNow()); } } else { SdrDragView::TakeActionRect(rRect); } } bool SdrCreateView::CheckEdgeMode() { if (mpCurrentCreate != nullptr) { // is managed by EdgeObj if (mnCurrentInvent==SdrInventor::Default && mnCurrentIdent==SdrObjKind::Edge) return false; } if (!IsCreateMode() || mnCurrentInvent!=SdrInventor::Default || mnCurrentIdent!=SdrObjKind::Edge) { ImpClearConnectMarker(); return false; } else { // sal_True, if MouseMove should check Connect return !IsAction(); } } void SdrCreateView::SetConnectMarker(const SdrObjConnection& rCon) { SdrObject* pTargetObject = rCon.pObj; if(pTargetObject) { // if target object changes, throw away overlay object to make room for changes if(mpCoMaOverlay && pTargetObject != &mpCoMaOverlay->GetTargetObject()) { ImpClearConnectMarker(); } if(!mpCoMaOverlay) { mpCoMaOverlay.reset(new ImplConnectMarkerOverlay(*this, *pTargetObject)); } } else { ImpClearConnectMarker(); } } void SdrCreateView::HideConnectMarker() { ImpClearConnectMarker(); } bool SdrCreateView::MouseMove(const MouseEvent& rMEvt, OutputDevice* pWin) { if(CheckEdgeMode() && pWin) { SdrPageView* pPV = GetSdrPageView(); if(pPV) { // TODO: Change default hit tolerance at IsMarkedHit() some time! Point aPos(pWin->PixelToLogic(rMEvt.GetPosPixel())); bool bMarkHit=PickHandle(aPos)!=nullptr || IsMarkedObjHit(aPos); SdrObjConnection aCon; if (!bMarkHit) SdrEdgeObj::ImpFindConnector(aPos,*pPV,aCon,nullptr,pWin); SetConnectMarker(aCon); } } return SdrDragView::MouseMove(rMEvt,pWin); } bool SdrCreateView::IsTextTool() const { return meEditMode==SdrViewEditMode::Create && mnCurrentInvent==SdrInventor::Default && (mnCurrentIdent==SdrObjKind::Text || mnCurrentIdent==SdrObjKind::TitleText || mnCurrentIdent==SdrObjKind::OutlineText); } bool SdrCreateView::IsEdgeTool() const { return meEditMode==SdrViewEditMode::Create && mnCurrentInvent==SdrInventor::Default && (mnCurrentIdent==SdrObjKind::Edge); } bool SdrCreateView::IsMeasureTool() const { return meEditMode==SdrViewEditMode::Create && mnCurrentInvent==SdrInventor::Default && (mnCurrentIdent==SdrObjKind::Measure); } void SdrCreateView::SetCurrentObj(SdrObjKind nIdent, SdrInventor nInvent) { if (mnCurrentInvent!=nInvent || mnCurrentIdent!=nIdent) { mnCurrentInvent=nInvent; mnCurrentIdent=nIdent; SdrObject * pObj = (nIdent == SdrObjKind::NONE) ? nullptr : SdrObjFactory::MakeNewObject( *GetModel(), nInvent, nIdent); if(pObj) { // Using text tool, mouse cursor is usually I-Beam, // crosshairs with tiny I-Beam appears only on MouseButtonDown. if(IsTextTool()) { // Here the correct pointer needs to be used // if the default is set to vertical writing maCurrentCreatePointer = PointerStyle::Text; } else maCurrentCreatePointer = pObj->GetCreatePointer(); SdrObject::Free( pObj ); } else { maCurrentCreatePointer = PointerStyle::Cross; } } CheckEdgeMode(); ImpSetGlueVisible3(IsEdgeTool()); } bool SdrCreateView::ImpBegCreateObj(SdrInventor nInvent, SdrObjKind nIdent, const Point& rPnt, OutputDevice* pOut, sal_Int16 nMinMov, const tools::Rectangle& rLogRect, SdrObject* pPreparedFactoryObject) { bool bRet=false; UnmarkAllObj(); BrkAction(); ImpClearConnectMarker(); mpCreatePV = GetSdrPageView(); if (mpCreatePV != nullptr) { // otherwise no side registered! OUString aLay(maActualLayer); if(nInvent == SdrInventor::Default && nIdent == SdrObjKind::Measure && !maMeasureLayer.isEmpty()) { aLay = maMeasureLayer; } SdrLayerID nLayer = mpCreatePV->GetPage()->GetLayerAdmin().GetLayerID(aLay); if (nLayer==SDRLAYER_NOTFOUND) nLayer = SdrLayerID(0); if (!mpCreatePV->GetLockedLayers().IsSet(nLayer) && mpCreatePV->GetVisibleLayers().IsSet(nLayer)) { if(pPreparedFactoryObject) { mpCurrentCreate = pPreparedFactoryObject; } else { mpCurrentCreate = SdrObjFactory::MakeNewObject( *mpModel, nInvent, nIdent); } Point aPnt(rPnt); if (mnCurrentInvent != SdrInventor::Default || (mnCurrentIdent != SdrObjKind::Edge && mnCurrentIdent != SdrObjKind::FreehandLine && mnCurrentIdent != SdrObjKind::FreehandFill )) { // no snapping for Edge and Freehand aPnt=GetSnapPos(aPnt, mpCreatePV); } if (mpCurrentCreate!=nullptr) { if (mpDefaultStyleSheet!=nullptr) mpCurrentCreate->NbcSetStyleSheet(mpDefaultStyleSheet, false); // SW uses a naked SdrObject for frame construction. Normally, such an // object should not be created. Since it is possible to use it as a helper // object (e.g. in letting the user define an area with the interactive // construction) at least no items should be set at that object. if(nInvent != SdrInventor::Default || nIdent != SdrObjKind::NONE) { mpCurrentCreate->SetMergedItemSet(maDefaultAttr); } if (mpModel && dynamic_cast(mpCurrentCreate) != nullptr) { SfxItemSet aSet(mpModel->GetItemPool()); aSet.Put(XFillColorItem(OUString(),COL_WHITE)); // in case someone turns on Solid aSet.Put(XFillStyleItem(drawing::FillStyle_NONE)); mpCurrentCreate->SetMergedItemSet(aSet); } if (mpModel && nInvent==SdrInventor::Default && (nIdent==SdrObjKind::Text || nIdent==SdrObjKind::TitleText || nIdent==SdrObjKind::OutlineText)) { // default for all text frames: no background, no border SfxItemSet aSet(mpModel->GetItemPool()); aSet.Put(XFillColorItem(OUString(),COL_WHITE)); // in case someone turns on Solid aSet.Put(XFillStyleItem(drawing::FillStyle_NONE)); aSet.Put(XLineColorItem(OUString(),COL_BLACK)); // in case someone turns on Solid aSet.Put(XLineStyleItem(drawing::LineStyle_NONE)); mpCurrentCreate->SetMergedItemSet(aSet); } if (!rLogRect.IsEmpty()) mpCurrentCreate->NbcSetLogicRect(rLogRect); // make sure drag start point is inside WorkArea const tools::Rectangle& rWorkArea = GetWorkArea(); if(!rWorkArea.IsEmpty()) { if(aPnt.X() < rWorkArea.Left()) { aPnt.setX( rWorkArea.Left() ); } if(aPnt.X() > rWorkArea.Right()) { aPnt.setX( rWorkArea.Right() ); } if(aPnt.Y() < rWorkArea.Top()) { aPnt.setY( rWorkArea.Top() ); } if(aPnt.Y() > rWorkArea.Bottom()) { aPnt.setY( rWorkArea.Bottom() ); } } maDragStat.Reset(aPnt); maDragStat.SetView(static_cast(this)); maDragStat.SetPageView(mpCreatePV); maDragStat.SetMinMove(ImpGetMinMovLogic(nMinMov,pOut)); mpDragWin=pOut; if (mpCurrentCreate->BegCreate(maDragStat)) { ShowCreateObj(/*pOut,sal_True*/); bRet=true; } else { SdrObject::Free(mpCurrentCreate); mpCurrentCreate = nullptr; mpCreatePV = nullptr; } } } } return bRet; } bool SdrCreateView::BegCreateObj(const Point& rPnt, OutputDevice* pOut, short nMinMov) { return ImpBegCreateObj(mnCurrentInvent,mnCurrentIdent,rPnt,pOut,nMinMov,tools::Rectangle(), nullptr); } bool SdrCreateView::BegCreatePreparedObject(const Point& rPnt, sal_Int16 nMinMov, SdrObject* pPreparedFactoryObject) { SdrInventor nInvent(mnCurrentInvent); SdrObjKind nIdent(mnCurrentIdent); if(pPreparedFactoryObject) { nInvent = pPreparedFactoryObject->GetObjInventor(); nIdent = pPreparedFactoryObject->GetObjIdentifier(); } return ImpBegCreateObj(nInvent, nIdent, rPnt, nullptr, nMinMov, tools::Rectangle(), pPreparedFactoryObject); } bool SdrCreateView::BegCreateCaptionObj(const Point& rPnt, const Size& rObjSiz, OutputDevice* pOut, short nMinMov) { return ImpBegCreateObj(SdrInventor::Default,SdrObjKind::Caption,rPnt,pOut,nMinMov, tools::Rectangle(rPnt,Size(rObjSiz.Width()+1,rObjSiz.Height()+1)), nullptr); } void SdrCreateView::MovCreateObj(const Point& rPnt) { if (mpCurrentCreate==nullptr) return; Point aPnt(rPnt); if (!maDragStat.IsNoSnap()) { aPnt=GetSnapPos(aPnt, mpCreatePV); } if (IsOrtho()) { if (maDragStat.IsOrtho8Possible()) OrthoDistance8(maDragStat.GetPrev(),aPnt,IsBigOrtho()); else if (maDragStat.IsOrtho4Possible()) OrthoDistance4(maDragStat.GetPrev(),aPnt,IsBigOrtho()); } // If the drag point was limited and Ortho is active, do // the small ortho correction (reduction) -> last parameter to FALSE. bool bDidLimit(ImpLimitToWorkArea(aPnt)); if(bDidLimit && IsOrtho()) { if(maDragStat.IsOrtho8Possible()) OrthoDistance8(maDragStat.GetPrev(), aPnt, false); else if(maDragStat.IsOrtho4Possible()) OrthoDistance4(maDragStat.GetPrev(), aPnt, false); } if (aPnt==maDragStat.GetNow()) return; bool bIsMinMoved(maDragStat.IsMinMoved()); if (!maDragStat.CheckMinMoved(aPnt)) return; if (!bIsMinMoved) maDragStat.NextPoint(); maDragStat.NextMove(aPnt); mpCurrentCreate->MovCreate(maDragStat); // MovCreate changes the object, so use ActionChanged() on it mpCurrentCreate->ActionChanged(); // replace for DrawCreateObjDiff HideCreateObj(); ShowCreateObj(); } void SdrCreateView::SetupObjLayer(const SdrPageView* pPageView, const OUString& aActiveLayer, SdrObject* pObj) { const SdrLayerAdmin& rAd = pPageView->GetPage()->GetLayerAdmin(); SdrLayerID nLayer(0); // #i72535# if(dynamic_cast( pObj) != nullptr) { // for FormControls, force to form layer nLayer = rAd.GetLayerID(rAd.GetControlLayerName()); } else { nLayer = rAd.GetLayerID(aActiveLayer); } if(SDRLAYER_NOTFOUND == nLayer) { nLayer = SdrLayerID(0); } pObj->SetLayer(nLayer); } bool SdrCreateView::EndCreateObj(SdrCreateCmd eCmd) { bool bRet=false; SdrObject* pObjCreated=mpCurrentCreate; if (mpCurrentCreate!=nullptr) { sal_uInt32 nCount=maDragStat.GetPointCount(); if (nCount<=1 && eCmd==SdrCreateCmd::ForceEnd) { BrkCreateObj(); // objects with only a single point don't exist (at least today) return false; // sal_False = event not interpreted } bool bPntsEq=nCount>1; sal_uInt32 i=1; Point aP0=maDragStat.GetPoint(0); while (bPntsEq && iEndCreate(maDragStat,eCmd)) { HideCreateObj(); if (!bPntsEq) { // otherwise Brk, because all points are equal SdrObject* pObj=mpCurrentCreate; mpCurrentCreate=nullptr; SetupObjLayer(mpCreatePV, maActualLayer, pObj); // recognize creation of a new 3D object inside a 3D scene bool bSceneIntoScene(false); E3dScene* pObjScene = dynamic_cast(pObjCreated); E3dScene* pCurrentScene = pObjScene ? dynamic_cast(mpCreatePV->GetCurrentGroup()) : nullptr; if (pCurrentScene) { bool bDidInsert = static_cast(this)->ImpCloneAll3DObjectsToDestScene( pObjScene, pCurrentScene, Point(0, 0)); if(bDidInsert) { // delete object, its content is cloned and inserted SdrObject::Free( pObjCreated ); pObjCreated = nullptr; bSceneIntoScene = true; } } if(!bSceneIntoScene) { // Here an interactively created SdrObject gets added, so // take into account that interaction created an object in // model coordinates. If we have e.g. a GirdOffset, this is a // little bit tricky - we have an object in model coordinates, // so the fetched offset is at the wrong point in principle // since we need to 'substract' the offset here to get to // 'real' model coordinates. But we have nothing better here, // so go for it. // The 2nd a little tricky thing is that this will early-create // a ViewObjectContact for the new SdrObject, but these VOCs // are anyways layouted for being create-on-demand. This will // be adapted/replaced correctly later on. // This *should* be the right place for getting all interactively // created objects, see InsertObjectAtView below that calls // CreateUndoNewObject. basegfx::B2DVector aGridOffset(0.0, 0.0); if(getPossibleGridOffsetForSdrObject(aGridOffset, pObj, mpCreatePV)) { const Size aOffset( basegfx::fround(-aGridOffset.getX()), basegfx::fround(-aGridOffset.getY())); pObj->NbcMove(aOffset); } // do the same as before InsertObjectAtView(pObj, *mpCreatePV); } mpCreatePV = nullptr; bRet=true; // sal_True = event interpreted } else { BrkCreateObj(); } } else { // more points if (eCmd==SdrCreateCmd::ForceEnd || // nothing there -- force ending nCount==0 || // no existing points (should never happen) (nCount<=1 && !maDragStat.IsMinMoved())) { // MinMove not met BrkCreateObj(); } else { // replace for DrawCreateObjDiff HideCreateObj(); ShowCreateObj(); maDragStat.ResetMinMoved(); // NextPoint is at MovCreateObj() bRet=true; } } } return bRet; } void SdrCreateView::BckCreateObj() { if (mpCurrentCreate==nullptr) return; if (maDragStat.GetPointCount()<=2 ) { BrkCreateObj(); } else { HideCreateObj(); maDragStat.PrevPoint(); if (mpCurrentCreate->BckCreate(maDragStat)) { ShowCreateObj(); } else { BrkCreateObj(); } } } void SdrCreateView::BrkCreateObj() { if (mpCurrentCreate!=nullptr) { HideCreateObj(); mpCurrentCreate->BrkCreate(maDragStat); SdrObject::Free( mpCurrentCreate ); mpCurrentCreate = nullptr; mpCreatePV = nullptr; } } void SdrCreateView::ShowCreateObj(/*OutputDevice* pOut, sal_Bool bFull*/) { if(!IsCreateObj() || maDragStat.IsShown()) return; if (mpCurrentCreate) { // for migration from XOR, replace DrawDragObj here to create // overlay objects instead. bool bUseSolidDragging(IsSolidDragging()); // #i101648# check if dragged object is a naked SdrObject (not // a derivation). This is e.g. used in SW Frame construction // as placeholder. Do not use SolidDragging for naked SdrObjects, // they cannot have a valid optical representation if(bUseSolidDragging && SdrObjKind::NONE == mpCurrentCreate->GetObjIdentifier()) { bUseSolidDragging = false; } // check for objects with no fill and no line if(bUseSolidDragging) { const SfxItemSet& rSet = mpCurrentCreate->GetMergedItemSet(); const drawing::FillStyle eFill(rSet.Get(XATTR_FILLSTYLE).GetValue()); const drawing::LineStyle eLine(rSet.Get(XATTR_LINESTYLE).GetValue()); if(drawing::LineStyle_NONE == eLine && drawing::FillStyle_NONE == eFill) { bUseSolidDragging = false; } } // check for form controls if(bUseSolidDragging) { if (dynamic_cast(mpCurrentCreate) != nullptr) { bUseSolidDragging = false; } } // #i101781# force to non-solid dragging when not creating a full circle if(bUseSolidDragging) { SdrCircObj* pCircObj = dynamic_cast(mpCurrentCreate); if(pCircObj && SdrObjKind::CircleOrEllipse != pCircObj->GetObjIdentifier()) { // #i103058# Allow SolidDragging with four points if(maDragStat.GetPointCount() < 4) { bUseSolidDragging = false; } } } if(bUseSolidDragging) { basegfx::B2DPolyPolygon aDragPolyPolygon; if (dynamic_cast(mpCurrentCreate) != nullptr) { // ensure object has some size, necessary for SdrTextObj because // there are still untested divisions by that sizes tools::Rectangle aCurrentSnapRect(mpCurrentCreate->GetSnapRect()); if(aCurrentSnapRect.GetWidth() <= 1 || aCurrentSnapRect.GetHeight() <= 1) { tools::Rectangle aNewRect(maDragStat.GetStart(), maDragStat.GetStart() + Point(2, 2)); mpCurrentCreate->NbcSetSnapRect(aNewRect); } } if (auto pPathObj = dynamic_cast(mpCurrentCreate)) { // The up-to-now created path needs to be set at the object to have something // that can be visualized const basegfx::B2DPolyPolygon aCurrentPolyPolygon(pPathObj->getObjectPolyPolygon(maDragStat)); if(aCurrentPolyPolygon.count()) { pPathObj->NbcSetPathPoly(aCurrentPolyPolygon); } aDragPolyPolygon = pPathObj->getDragPolyPolygon(maDragStat); } // use the SdrObject directly for overlay mpCreateViewExtraData->CreateAndShowOverlay(*this, mpCurrentCreate, aDragPolyPolygon); } else { const ::basegfx::B2DPolyPolygon aPoly(mpCurrentCreate->TakeCreatePoly(maDragStat)); mpCreateViewExtraData->CreateAndShowOverlay(*this, nullptr, aPoly); } // #i101679# Force changed overlay to be shown for(sal_uInt32 a(0); a < PaintWindowCount(); a++) { SdrPaintWindow* pCandidate = GetPaintWindow(a); const rtl::Reference& xOverlayManager = pCandidate->GetOverlayManager(); if (xOverlayManager.is()) { xOverlayManager->flush(); } } } maDragStat.SetShown(true); } void SdrCreateView::HideCreateObj() { if(IsCreateObj() && maDragStat.IsShown()) { // for migration from XOR, replace DrawDragObj here to create // overlay objects instead. mpCreateViewExtraData->HideOverlay(); //DrawCreateObj(pOut,bFull); maDragStat.SetShown(false); } } void SdrCreateView::GetAttributes(SfxItemSet& rTargetSet, bool bOnlyHardAttr) const { if (mpCurrentCreate) { rTargetSet.Put(mpCurrentCreate->GetMergedItemSet()); } else { SdrDragView::GetAttributes(rTargetSet, bOnlyHardAttr); } } bool SdrCreateView::SetAttributes(const SfxItemSet& rSet, bool bReplaceAll) { if (mpCurrentCreate) { mpCurrentCreate->SetMergedItemSetAndBroadcast(rSet, bReplaceAll); return true; } else { return SdrDragView::SetAttributes(rSet,bReplaceAll); } } SfxStyleSheet* SdrCreateView::GetStyleSheet() const { if (mpCurrentCreate != nullptr) { return mpCurrentCreate->GetStyleSheet(); } else { return SdrDragView::GetStyleSheet(); } } void SdrCreateView::SetStyleSheet(SfxStyleSheet* pStyleSheet, bool bDontRemoveHardAttr) { if (mpCurrentCreate != nullptr) { mpCurrentCreate->SetStyleSheet(pStyleSheet,bDontRemoveHardAttr); } else { SdrDragView::SetStyleSheet(pStyleSheet,bDontRemoveHardAttr); } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */