diff options
Diffstat (limited to 'svx')
39 files changed, 623 insertions, 433 deletions
diff --git a/svx/inc/dragmt3d.hxx b/svx/inc/dragmt3d.hxx index 01d9cd6d6469..c5cd6db44878 100644 --- a/svx/inc/dragmt3d.hxx +++ b/svx/inc/dragmt3d.hxx @@ -77,7 +77,9 @@ public: virtual bool EndSdrDrag(bool bCopy) override; // for migration from XOR to overlay - virtual void CreateOverlayGeometry(sdr::overlay::OverlayManager& rOverlayManager) override; + virtual void CreateOverlayGeometry( + sdr::overlay::OverlayManager& rOverlayManager, + const sdr::contact::ObjectContact& rObjectContact) override; }; // Derivative of SdrDragMethod for spinning 3D objects diff --git a/svx/inc/sdr/contact/objectcontactofpageview.hxx b/svx/inc/sdr/contact/objectcontactofpageview.hxx deleted file mode 100644 index 4fb0bef53898..000000000000 --- a/svx/inc/sdr/contact/objectcontactofpageview.hxx +++ /dev/null @@ -1,120 +0,0 @@ -/* -*- 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 . - */ - -#ifndef INCLUDED_SVX_INC_SDR_CONTACT_OBJECTCONTACTOFPAGEVIEW_HXX -#define INCLUDED_SVX_INC_SDR_CONTACT_OBJECTCONTACTOFPAGEVIEW_HXX - -#include <svx/sdr/contact/objectcontact.hxx> -#include <vcl/idle.hxx> - -class SdrPageWindow; -class SdrPage; - -namespace sdr -{ - namespace contact - { - class ObjectContactOfPageView final : public ObjectContact, public Idle - { - // the owner of this ObjectContactOfPageView. Set from constructor and not - // to be changed in any way. - SdrPageWindow& mrPageWindow; - - // Process the whole displaying, the real version - void DoProcessDisplay(DisplayInfo& rDisplayInfo); - - public: - // access to SdrPageWindow - SdrPageWindow& GetPageWindow() const { return mrPageWindow; } - - // access to SdrPage of PageView - SdrPage* GetSdrPage() const; - - // basic constructor, used from SdrPageView. - explicit ObjectContactOfPageView(SdrPageWindow& rPageWindow, - const sal_Char *pDebugName); - virtual ~ObjectContactOfPageView() override; - - // LazyInvalidate request. This is used from the VOCs to mark that they - // got invalidated by an ActionChanged() call. An active view needs to remember - // this and take action on it. Default implementation directly calls back - // triggerLazyInvalidate() which promptly handles the request - virtual void setLazyInvalidate(ViewObjectContact& rVOC) override; - - // call this to support evtl. preparations for repaint - virtual void PrepareProcessDisplay() override; - - // From baseclass Timer, the timeout call triggered by the LazyInvalidate mechanism - virtual void Invoke() final override; - - // Process the whole displaying - virtual void ProcessDisplay(DisplayInfo& rDisplayInfo) override; - - // test if visualizing of entered groups is switched on at all - virtual bool DoVisualizeEnteredGroup() const override; - - // get active group's (the entered group) ViewContact - virtual const ViewContact* getActiveViewContact() const override; - - // Invalidate given rectangle at the window/output which is represented by - // this ObjectContact. - virtual void InvalidatePartOfView(const basegfx::B2DRange& rRange) const override; - - // Get info about the need to visualize GluePoints. The default - // is that it is not necessary. - virtual bool AreGluePointsVisible() const override; - - // check if text animation is allowed. - virtual bool IsTextAnimationAllowed() const override; - - // check if graphic animation is allowed. - virtual bool IsGraphicAnimationAllowed() const override; - - // print? Default is false - virtual bool isOutputToPrinter() const override; - - // recording MetaFile? Default is false - virtual bool isOutputToRecordingMetaFile() const override; - - // pdf export? Default is false - virtual bool isOutputToPDFFile() const override; - - // gray display mode - virtual bool isDrawModeGray() const override; - - // high contrast display mode - virtual bool isDrawModeHighContrast() const override; - - // override access to SdrPageView - virtual SdrPageView* TryToGetSdrPageView() const override; - - // access to OutputDevice. May return 0L like the default implementations do. Override as needed. - virtual OutputDevice* TryToGetOutputDevice() const override; - - /** sets all UNO controls which are associated with this ObjectContact to - design or alive mode. - */ - void SetUNOControlsDesignMode( bool _bDesignMode ) const; - }; - } // end of namespace contact -} // end of namespace sdr - -#endif // INCLUDED_SVX_INC_SDR_CONTACT_OBJECTCONTACTOFPAGEVIEW_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/inc/sdr/contact/viewcontactofsdrole2obj.hxx b/svx/inc/sdr/contact/viewcontactofsdrole2obj.hxx index a00b95b1661d..8d94c6115aa6 100644 --- a/svx/inc/sdr/contact/viewcontactofsdrole2obj.hxx +++ b/svx/inc/sdr/contact/viewcontactofsdrole2obj.hxx @@ -33,8 +33,6 @@ class ViewContactOfSdrOle2Obj : public ViewContactOfSdrRectObj private: // #i123539# allow local buffering of chart data (if chart) drawinglayer::primitive2d::Primitive2DReference mxChartContent; - // used to check if we need to re-calc the transformation - Point maGridOffset; protected: // Create a Object-Specific ViewObjectContact, set ViewContact and diff --git a/svx/source/engine3d/dragmt3d.cxx b/svx/source/engine3d/dragmt3d.cxx index 94d2bd213fbd..36971d34bf6d 100644 --- a/svx/source/engine3d/dragmt3d.cxx +++ b/svx/source/engine3d/dragmt3d.cxx @@ -209,7 +209,9 @@ void E3dDragMethod::MoveSdrDrag(const Point& /*rPnt*/) // Draw the wire frame model // for migration from XOR to overlay -void E3dDragMethod::CreateOverlayGeometry(sdr::overlay::OverlayManager& rOverlayManager) +void E3dDragMethod::CreateOverlayGeometry( + sdr::overlay::OverlayManager& rOverlayManager, + const sdr::contact::ObjectContact& rObjectContact) { const sal_uInt32 nCnt(maGrp.size()); basegfx::B2DPolyPolygon aResult; @@ -249,10 +251,14 @@ void E3dDragMethod::CreateOverlayGeometry(sdr::overlay::OverlayManager& rOverlay if(aResult.count()) { - std::unique_ptr<sdr::overlay::OverlayPolyPolygonStripedAndFilled> pNew(new sdr::overlay::OverlayPolyPolygonStripedAndFilled( - aResult)); - rOverlayManager.add(*pNew); - addToOverlayObjectList(std::move(pNew)); + std::unique_ptr<sdr::overlay::OverlayPolyPolygonStripedAndFilled> pNew( + new sdr::overlay::OverlayPolyPolygonStripedAndFilled( + aResult)); + + insertNewlyCreatedOverlayObjectForSdrDragMethod( + std::move(pNew), + rObjectContact, + rOverlayManager); } } diff --git a/svx/source/engine3d/view3d.cxx b/svx/source/engine3d/view3d.cxx index 8a1b3852f8ae..e3def1a409f6 100644 --- a/svx/source/engine3d/view3d.cxx +++ b/svx/source/engine3d/view3d.cxx @@ -114,22 +114,16 @@ Impl3DMirrorConstructOverlay::Impl3DMirrorConstructOverlay(const E3dView& rView) if(pPV && pPV->PageWindowCount()) { - sdr::contact::ObjectContact& rOC = pPV->GetPageWindow(0)->GetObjectContact(); - sdr::contact::DisplayInfo aDisplayInfo; - - // Do not use the last ViewPort set at the OC at the last ProcessDisplay() - rOC.resetViewPort(); - for(size_t a = 0; a < mnCount; ++a) { SdrObject* pObject = mrView.GetMarkedObjectByIndex(a); if(pObject) { - sdr::contact::ViewContact& rVC = pObject->GetViewContact(); - sdr::contact::ViewObjectContact& rVOC = rVC.GetViewObjectContact(rOC); - - const drawinglayer::primitive2d::Primitive2DContainer aNewSequence(rVOC.getPrimitive2DSequenceHierarchy(aDisplayInfo)); + // use the view-independent primitive representation (without + // evtl. GridOffset, that may be applied to the DragEntry individually) + const drawinglayer::primitive2d::Primitive2DContainer aNewSequence( + pObject->GetViewContact().getViewIndependentPrimitive2DContainer()); maFullOverlay.append(aNewSequence); } } diff --git a/svx/source/sdr/contact/objectcontact.cxx b/svx/source/sdr/contact/objectcontact.cxx index a4d52073dfa1..33839d8c83f0 100644 --- a/svx/source/sdr/contact/objectcontact.cxx +++ b/svx/source/sdr/contact/objectcontact.cxx @@ -31,6 +31,26 @@ using namespace com::sun::star; namespace sdr { namespace contact { +bool ObjectContact::supportsGridOffsets() const +{ + // default does not support GridOffset + return false; +} + +void ObjectContact::calculateGridOffsetForViewOjectContact( + basegfx::B2DVector& /*rTarget*/, + const ViewObjectContact& /*rClient*/) const +{ + // default does not on-demand calculate GridOffset +} + +void ObjectContact::calculateGridOffsetForB2DRange( + basegfx::B2DVector& /*rTarget*/, + const basegfx::B2DRange& /*rB2DRange*/) const +{ + // default does not on-demand calculate GridOffset +} + ObjectContact::ObjectContact() : maViewObjectContactVector(), maPrimitiveAnimator(), @@ -209,6 +229,18 @@ void ObjectContact::resetViewPort() } } +void ObjectContact::resetAllGridOffsets() +{ + const sal_uInt32 nVOCCount(getViewObjectContactCount()); + + for(sal_uInt32 a(0); a < nVOCCount; a++) + { + ViewObjectContact* pVOC(getViewObjectContact(a)); + assert(pVOC && "ObjectContact: ViewObjectContact list Corrupt (!)"); + pVOC->resetGridOffset(); + } +} + }} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sdr/contact/objectcontactofpageview.cxx b/svx/source/sdr/contact/objectcontactofpageview.cxx index 6a2247bcd6c2..0c6ecf0abc3a 100644 --- a/svx/source/sdr/contact/objectcontactofpageview.cxx +++ b/svx/source/sdr/contact/objectcontactofpageview.cxx @@ -19,7 +19,7 @@ #include <config_features.h> -#include <sdr/contact/objectcontactofpageview.hxx> +#include <svx/sdr/contact/objectcontactofpageview.hxx> #include <sdr/contact/viewobjectcontactofunocontrol.hxx> #include <svx/svdpagv.hxx> #include <svx/svdpage.hxx> diff --git a/svx/source/sdr/contact/viewcontact.cxx b/svx/source/sdr/contact/viewcontact.cxx index 0567ff65c473..178c50f22bc1 100644 --- a/svx/source/sdr/contact/viewcontact.cxx +++ b/svx/source/sdr/contact/viewcontact.cxx @@ -25,7 +25,7 @@ #include <basegfx/color/bcolor.hxx> #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> #include <basegfx/matrix/b2dhommatrix.hxx> -#include <sdr/contact/objectcontactofpageview.hxx> +#include <svx/sdr/contact/objectcontactofpageview.hxx> #include <tools/debug.hxx> namespace sdr { namespace contact { diff --git a/svx/source/sdr/contact/viewcontactofe3dscene.cxx b/svx/source/sdr/contact/viewcontactofe3dscene.cxx index 591db03619fb..86ca5f0ed09c 100644 --- a/svx/source/sdr/contact/viewcontactofe3dscene.cxx +++ b/svx/source/sdr/contact/viewcontactofe3dscene.cxx @@ -244,11 +244,8 @@ void ViewContactOfE3dScene::createViewInformation3D(const basegfx::B3DRange& rCo void ViewContactOfE3dScene::createObjectTransformation() { // create 2d Object Transformation from relative point in 2d scene to world - tools::Rectangle aRectangle = GetE3dScene().GetSnapRect(); - // Hack for calc, transform position of object according - // to current zoom so as objects relative position to grid - // appears stable - aRectangle += GetE3dScene().GetGridOffset(); + const tools::Rectangle aRectangle(GetE3dScene().GetSnapRect()); + maObjectTransformation.set(0, 0, aRectangle.getWidth()); maObjectTransformation.set(1, 1, aRectangle.getHeight()); maObjectTransformation.set(0, 2, aRectangle.Left()); diff --git a/svx/source/sdr/contact/viewcontactofgraphic.cxx b/svx/source/sdr/contact/viewcontactofgraphic.cxx index 15de4be75752..2892b3e63eff 100644 --- a/svx/source/sdr/contact/viewcontactofgraphic.cxx +++ b/svx/source/sdr/contact/viewcontactofgraphic.cxx @@ -310,14 +310,10 @@ namespace sdr // take unrotated snap rect for position and size. Directly use model data, not getBoundRect() or getSnapRect() // which will use the primitive data we just create in the near future - tools::Rectangle rRectangle = GetGrafObject().GetGeoRect(); - // Hack for calc, transform position of object according - // to current zoom so as objects relative position to grid - // appears stable - rRectangle += GetGrafObject().GetGridOffset(); + const tools::Rectangle aRectangle(GetGrafObject().GetGeoRect()); const ::basegfx::B2DRange aObjectRange( - rRectangle.Left(), rRectangle.Top(), - rRectangle.Right(), rRectangle.Bottom()); + aRectangle.Left(), aRectangle.Top(), + aRectangle.Right(), aRectangle.Bottom()); // look for mirroring const GeoStat& rGeoStat(GetGrafObject().GetGeoStat()); diff --git a/svx/source/sdr/contact/viewcontactofgroup.cxx b/svx/source/sdr/contact/viewcontactofgroup.cxx index d6a0e98dfcfe..38afca26ff65 100644 --- a/svx/source/sdr/contact/viewcontactofgroup.cxx +++ b/svx/source/sdr/contact/viewcontactofgroup.cxx @@ -71,11 +71,7 @@ namespace sdr else { // append an invisible outline for the cases where no visible content exists - tools::Rectangle aCurrentBoundRect(GetSdrObjGroup().GetLastBoundRect()); - // Hack for calc, transform position of object according - // to current zoom so as objects relative position to grid - // appears stable - aCurrentBoundRect += GetSdrObjGroup().GetGridOffset(); + const tools::Rectangle aCurrentBoundRect(GetSdrObjGroup().GetLastBoundRect()); const basegfx::B2DRange aCurrentRange( aCurrentBoundRect.Left(), aCurrentBoundRect.Top(), aCurrentBoundRect.Right(), aCurrentBoundRect.Bottom()); diff --git a/svx/source/sdr/contact/viewcontactofsdrcaptionobj.cxx b/svx/source/sdr/contact/viewcontactofsdrcaptionobj.cxx index 7fc5effd6cf3..8fe42c1fa6de 100644 --- a/svx/source/sdr/contact/viewcontactofsdrcaptionobj.cxx +++ b/svx/source/sdr/contact/viewcontactofsdrcaptionobj.cxx @@ -63,16 +63,10 @@ namespace sdr false)); // take unrotated snap rect (direct model data) for position and size - tools::Rectangle rRectangle = rCaptionObj.GetGeoRect(); - // Hack for calc, transform position of object according - // to current zoom so as objects relative position to grid - // appears stable - Point aGridOff = rCaptionObj.GetGridOffset(); - rRectangle += aGridOff; - + const tools::Rectangle aRectangle(rCaptionObj.GetGeoRect()); const ::basegfx::B2DRange aObjectRange( - rRectangle.Left(), rRectangle.Top(), - rRectangle.Right(), rRectangle.Bottom()); + aRectangle.Left(), aRectangle.Top(), + aRectangle.Right(), aRectangle.Bottom()); const GeoStat& rGeoStat(rCaptionObj.GetGeoStat()); // fill object matrix @@ -87,11 +81,8 @@ namespace sdr double fCornerRadiusY; drawinglayer::primitive2d::calculateRelativeCornerRadius( rCaptionObj.GetEckenradius(), aObjectRange, fCornerRadiusX, fCornerRadiusY); - ::basegfx::B2DPolygon aTail = rCaptionObj.getTailPolygon(); - // Hack for calc, transform position of tail according - // to current zoom so as objects relative position to grid - // appears stable - aTail.transform( basegfx::utils::createTranslateB2DHomMatrix( aGridOff.X(), aGridOff.Y() ) ); + const basegfx::B2DPolygon aTail(rCaptionObj.getTailPolygon()); + // create primitive. Always create one (even if invisible) to let the decomposition // of SdrCaptionPrimitive2D create needed invisible elements for HitTest and BoundRect const drawinglayer::primitive2d::Primitive2DReference xReference( diff --git a/svx/source/sdr/contact/viewcontactofsdrcircobj.cxx b/svx/source/sdr/contact/viewcontactofsdrcircobj.cxx index 7104edcb227c..8d796643386d 100644 --- a/svx/source/sdr/contact/viewcontactofsdrcircobj.cxx +++ b/svx/source/sdr/contact/viewcontactofsdrcircobj.cxx @@ -50,11 +50,7 @@ namespace sdr false)); // take unrotated snap rect (direct model data) for position and size - tools::Rectangle aRectangle = GetCircObj().GetGeoRect(); - // Hack for calc, transform position of object according - // to current zoom so as objects relative position to grid - // appears stable - aRectangle += GetRectObj().GetGridOffset(); + const tools::Rectangle aRectangle(GetCircObj().GetGeoRect()); const basegfx::B2DRange aObjectRange( aRectangle.Left(), aRectangle.Top(), aRectangle.Right(), aRectangle.Bottom() ); diff --git a/svx/source/sdr/contact/viewcontactofsdredgeobj.cxx b/svx/source/sdr/contact/viewcontactofsdredgeobj.cxx index c22d14e18fa0..37eb5267cd5f 100644 --- a/svx/source/sdr/contact/viewcontactofsdredgeobj.cxx +++ b/svx/source/sdr/contact/viewcontactofsdredgeobj.cxx @@ -40,12 +40,7 @@ namespace sdr drawinglayer::primitive2d::Primitive2DContainer ViewContactOfSdrEdgeObj::createViewIndependentPrimitive2DSequence() const { - basegfx::B2DPolygon aEdgeTrack = GetEdgeObj().getEdgeTrack(); - Point aGridOff = GetEdgeObj().GetGridOffset(); - // Hack for calc, transform position of object according - // to current zoom so as objects relative position to grid - // appears stable - aEdgeTrack.transform( basegfx::utils::createTranslateB2DHomMatrix( aGridOff.X(), aGridOff.Y() ) ); + const basegfx::B2DPolygon aEdgeTrack(GetEdgeObj().getEdgeTrack()); // what to do when no EdgeTrack is provided (HitTest and selectability) ? OSL_ENSURE(0 != aEdgeTrack.count(), "Connectors with no geometry are not allowed (!)"); diff --git a/svx/source/sdr/contact/viewcontactofsdrmediaobj.cxx b/svx/source/sdr/contact/viewcontactofsdrmediaobj.cxx index 90403799d53a..bda8a934109f 100644 --- a/svx/source/sdr/contact/viewcontactofsdrmediaobj.cxx +++ b/svx/source/sdr/contact/viewcontactofsdrmediaobj.cxx @@ -100,11 +100,7 @@ drawinglayer::primitive2d::Primitive2DContainer ViewContactOfSdrMediaObj::create { // create range using the model data directly. This is in SdrTextObj::aRect which i will access using // GetGeoRect() to not trigger any calculations. It's the unrotated geometry which is okay for MediaObjects ATM. - tools::Rectangle aRectangle(GetSdrMediaObj().GetGeoRect()); - // Hack for calc, transform position of object according - // to current zoom so as objects relative position to grid - // appears stable - aRectangle += GetSdrMediaObj().GetGridOffset(); + const tools::Rectangle aRectangle(GetSdrMediaObj().GetGeoRect()); const basegfx::B2DRange aRange( aRectangle.Left(), aRectangle.Top(), aRectangle.Right(), aRectangle.Bottom()); diff --git a/svx/source/sdr/contact/viewcontactofsdrobj.cxx b/svx/source/sdr/contact/viewcontactofsdrobj.cxx index d042186c4d73..ca8abd63a8b4 100644 --- a/svx/source/sdr/contact/viewcontactofsdrobj.cxx +++ b/svx/source/sdr/contact/viewcontactofsdrobj.cxx @@ -29,7 +29,7 @@ #include <basegfx/color/bcolor.hxx> #include <drawinglayer/primitive2d/markerarrayprimitive2d.hxx> #include <drawinglayer/primitive2d/objectinfoprimitive2d.hxx> -#include <sdr/contact/objectcontactofpageview.hxx> +#include <svx/sdr/contact/objectcontactofpageview.hxx> #include <svx/sdrpagewindow.hxx> #include <svx/sdrpaintwindow.hxx> #include <svx/svdhdl.hxx> diff --git a/svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx b/svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx index c3f8666ad1d9..5c4bb784c515 100644 --- a/svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx +++ b/svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx @@ -45,13 +45,13 @@ namespace sdr basegfx::B2DRange ViewContactOfSdrObjCustomShape::getCorrectedTextBoundRect() const { - tools::Rectangle aObjectBound(GetCustomShapeObj().GetGeoRect()); - aObjectBound += GetCustomShapeObj().GetGridOffset(); + const tools::Rectangle aObjectBound(GetCustomShapeObj().GetGeoRect()); tools::Rectangle aTextBound(aObjectBound); GetCustomShapeObj().GetTextBounds(aTextBound); - aTextBound += GetCustomShapeObj().GetGridOffset(); basegfx::B2DRange aTextRange(aTextBound.Left(), aTextBound.Top(), aTextBound.Right(), aTextBound.Bottom()); - const basegfx::B2DRange aObjectRange(aObjectBound.Left(), aObjectBound.Top(), aObjectBound.Right(), aObjectBound.Bottom()); + const basegfx::B2DRange aObjectRange( + aObjectBound.Left(), aObjectBound.Top(), + aObjectBound.Right(), aObjectBound.Bottom()); // no need to correct if no extra text range if(aTextRange != aObjectRange) @@ -118,18 +118,8 @@ namespace sdr const SdrObject* pSdrObjRepresentation = GetCustomShapeObj().GetSdrObjectFromCustomShape(); bool b3DShape(false); - Point aGridOff = GetCustomShapeObj().GetGridOffset(); - if(pSdrObjRepresentation) { - // Hack for calc, transform position of object according - // to current zoom so as objects relative position to grid - // appears stable - // TTTT: Need to check what *exactly* this is doing - in it's current - // form it's indeed pretty much a 'hack' as mentioned above and massively - // in the way for future changes... - const_cast< SdrObject* >( pSdrObjRepresentation )->SetGridOffset( aGridOff ); - // tdf#118498 The processing of SdrObjListIter for SdrIterMode::DeepNoGroups // did change for 3D-Objects, it now correctly enters and iterates the // SdrObjects in the E3dScene (same as for SdrObjGroup). This is more correct @@ -160,10 +150,10 @@ namespace sdr { // take unrotated snap rect as default, then get the // unrotated text box. Rotation needs to be done centered - tools::Rectangle aObjectBound(GetCustomShapeObj().GetGeoRect()); - // hack for calc grid sync - aObjectBound += GetCustomShapeObj().GetGridOffset(); - const basegfx::B2DRange aObjectRange(aObjectBound.Left(), aObjectBound.Top(), aObjectBound.Right(), aObjectBound.Bottom()); + const tools::Rectangle aObjectBound(GetCustomShapeObj().GetGeoRect()); + const basegfx::B2DRange aObjectRange( + aObjectBound.Left(), aObjectBound.Top(), + aObjectBound.Right(), aObjectBound.Bottom()); // #i101684# get the text range unrotated and absolute to the object range const basegfx::B2DRange aTextRange(getCorrectedTextBoundRect()); diff --git a/svx/source/sdr/contact/viewcontactofsdrole2obj.cxx b/svx/source/sdr/contact/viewcontactofsdrole2obj.cxx index 9a538162779f..6a13aaef8682 100644 --- a/svx/source/sdr/contact/viewcontactofsdrole2obj.cxx +++ b/svx/source/sdr/contact/viewcontactofsdrole2obj.cxx @@ -60,12 +60,10 @@ ViewContactOfSdrOle2Obj::~ViewContactOfSdrOle2Obj() basegfx::B2DHomMatrix ViewContactOfSdrOle2Obj::createObjectTransform() const { // take unrotated snap rect (direct model data) for position and size - tools::Rectangle rRectangle = GetOle2Obj().GetGeoRect(); - // Hack for calc, transform position of object according - // to current zoom so as objects relative position to grid - // appears stable - rRectangle += GetOle2Obj().GetGridOffset(); - const basegfx::B2DRange aObjectRange(rRectangle.Left(), rRectangle.Top(), rRectangle.Right(), rRectangle.Bottom()); + const tools::Rectangle aRectangle(GetOle2Obj().GetGeoRect()); + const basegfx::B2DRange aObjectRange( + aRectangle.Left(), aRectangle.Top(), + aRectangle.Right(), aRectangle.Bottom()); // create object matrix const GeoStat& rGeoStat(GetOle2Obj().GetGeoStat()); @@ -100,17 +98,12 @@ drawinglayer::primitive2d::Primitive2DContainer ViewContactOfSdrOle2Obj::createP // #i123539# allow buffering and reuse of local chart data to not need to rebuild it // on every ViewObjectContact::getPrimitive2DSequence call. TTTT: Not needed for // aw080, there this mechanism already works differently - if(mxChartContent.is() - // check if we need to update the transformation primitive wrapping the chart - && maGridOffset == GetOle2Obj().GetGridOffset()) + if(mxChartContent.is()) { xContent = mxChartContent; } else { - // update grid offset - const_cast< ViewContactOfSdrOle2Obj* >(this)->maGridOffset = GetOle2Obj().GetGridOffset(); - // try to get chart primitives and chart range directly from xChartModel basegfx::B2DRange aChartContentRange; const drawinglayer::primitive2d::Primitive2DContainer aChartSequence( diff --git a/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx b/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx index 9005b67a3fb4..28942f7b04de 100644 --- a/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx +++ b/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx @@ -74,11 +74,6 @@ namespace sdr GetPathObj().getText(0), false)); basegfx::B2DPolyPolygon aUnitPolyPolygon(GetPathObj().GetPathPoly()); - Point aGridOff = GetPathObj().GetGridOffset(); - // Hack for calc, transform position of object according - // to current zoom so as objects relative position to grid - // appears stable - aUnitPolyPolygon.transform( basegfx::utils::createTranslateB2DHomMatrix( aGridOff.X(), aGridOff.Y() ) ); sal_uInt32 nPolyCount(ensureGeometry(aUnitPolyPolygon)); // prepare object transformation and unit polygon (direct model data) diff --git a/svx/source/sdr/contact/viewcontactofsdrrectobj.cxx b/svx/source/sdr/contact/viewcontactofsdrrectobj.cxx index f02ba917280c..34734f96e1cd 100644 --- a/svx/source/sdr/contact/viewcontactofsdrrectobj.cxx +++ b/svx/source/sdr/contact/viewcontactofsdrrectobj.cxx @@ -47,14 +47,10 @@ drawinglayer::primitive2d::Primitive2DContainer ViewContactOfSdrRectObj::createV false)); // take unrotated snap rect (direct model data) for position and size - tools::Rectangle rRectangle = GetRectObj().GetGeoRect(); - // Hack for calc, transform position of object according - // to current zoom so as objects relative position to grid - // appears stable - rRectangle += GetRectObj().GetGridOffset(); + const tools::Rectangle aRectangle(GetRectObj().GetGeoRect()); const ::basegfx::B2DRange aObjectRange( - rRectangle.Left(), rRectangle.Top(), - rRectangle.Right(), rRectangle.Bottom() ); + aRectangle.Left(), aRectangle.Top(), + aRectangle.Right(), aRectangle.Bottom() ); const GeoStat& rGeoStat(GetRectObj().GetGeoStat()); diff --git a/svx/source/sdr/contact/viewcontactofunocontrol.cxx b/svx/source/sdr/contact/viewcontactofunocontrol.cxx index 547e2ebc5339..78bdce4d6c2e 100644 --- a/svx/source/sdr/contact/viewcontactofunocontrol.cxx +++ b/svx/source/sdr/contact/viewcontactofunocontrol.cxx @@ -21,7 +21,7 @@ #include <sdr/contact/viewcontactofunocontrol.hxx> #include <sdr/contact/viewobjectcontactofunocontrol.hxx> -#include <sdr/contact/objectcontactofpageview.hxx> +#include <svx/sdr/contact/objectcontactofpageview.hxx> #include <svx/sdr/contact/displayinfo.hxx> #include <svx/svdouno.hxx> #include <svx/svdpagv.hxx> @@ -94,12 +94,7 @@ namespace sdr { namespace contact { // create range. Use model data directly, not getBoundRect()/getSnapRect; these will use // the primitive data themselves in the long run. Use SdrUnoObj's (which is a SdrRectObj) // call to GetGeoRect() to access SdrTextObj::aRect directly and without executing anything - tools::Rectangle aRectangle(GetSdrUnoObj().GetGeoRect()); - // Hack for calc, transform position of object according - // to current zoom so as objects relative position to grid - // appears stable - Point aGridOffset = GetSdrUnoObj().GetGridOffset(); - aRectangle += aGridOffset; + const tools::Rectangle aRectangle(GetSdrUnoObj().GetGeoRect()); const basegfx::B2DRange aRange( aRectangle.Left(), aRectangle.Top(), aRectangle.Right(), aRectangle.Bottom()); diff --git a/svx/source/sdr/contact/viewobjectcontact.cxx b/svx/source/sdr/contact/viewobjectcontact.cxx index e300703bfd74..197113cda630 100644 --- a/svx/source/sdr/contact/viewobjectcontact.cxx +++ b/svx/source/sdr/contact/viewobjectcontact.cxx @@ -36,8 +36,8 @@ #include <drawinglayer/processor2d/baseprocessor2d.hxx> #include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> #include <svx/svdoole2.hxx> - #include <sdr/contact/viewcontactofsdrole2obj.hxx> +#include <drawinglayer/primitive2d/transformprimitive2d.hxx> using namespace com::sun::star; @@ -159,6 +159,7 @@ ViewObjectContact::ViewObjectContact(ObjectContact& rObjectContact, ViewContact& mrViewContact(rViewContact), maObjectRange(), mxPrimitive2DSequence(), + maGridOffset(0.0, 0.0), mbLazyInvalidate(false) { // make the ViewContact remember me @@ -363,8 +364,36 @@ drawinglayer::primitive2d::Primitive2DContainer const & ViewObjectContact::getPr // always update object range when PrimitiveSequence changes const drawinglayer::geometry::ViewInformation2D& rViewInformation2D(GetObjectContact().getViewInformation2D()); - const_cast< ViewObjectContact* >(this)->maObjectRange = - mxPrimitive2DSequence.getB2DRange(rViewInformation2D); + const_cast< ViewObjectContact* >(this)->maObjectRange = mxPrimitive2DSequence.getB2DRange(rViewInformation2D); + + // check and eventually embed to GridOffset transform primitive + if(GetObjectContact().supportsGridOffsets()) + { + const basegfx::B2DVector& rGridOffset(getGridOffset()); + + if(0.0 != rGridOffset.getX() || 0.0 != rGridOffset.getY()) + { + const basegfx::B2DHomMatrix aTranslateGridOffset( + basegfx::utils::createTranslateB2DHomMatrix( + rGridOffset)); + const drawinglayer::primitive2d::Primitive2DReference aEmbed( + new drawinglayer::primitive2d::TransformPrimitive2D( + aTranslateGridOffset, + mxPrimitive2DSequence)); + + // Set values at local data. So for now, the mechanism is to reset some of the + // defining things (mxPrimitive2DSequence, maGridOffset) and re-create the + // buffered data (including maObjectRange). It *could* be changed to keep + // the unmodified PrimitiveSequence and only update the GridOffset, but this + // would require a 2nd instance of maObjectRange and mxPrimitive2DSequence. I + // started doing so, but it just makes the code more complicated. For now, + // just allow re-creation of the PrimitiveSequence (and removing buffered + // decomposed content of it). May be optimized, though. OTOH it only happens + // in calc which traditionally does not have a huge amout of DrawObjects anyways. + const_cast< ViewObjectContact* >(this)->mxPrimitive2DSequence = drawinglayer::primitive2d::Primitive2DContainer { aEmbed }; + const_cast< ViewObjectContact* >(this)->maObjectRange.transform(aTranslateGridOffset); + } + } } // return current Primitive2DContainer @@ -427,6 +456,30 @@ drawinglayer::primitive2d::Primitive2DContainer ViewObjectContact::getPrimitive2 return xSeqRetval; } +// Support getting a GridOffset per object and view for non-linear ViewToDevice +// transformation (calc). On-demand created by delegating to the ObjectContact +// (->View) that has then all needed information +const basegfx::B2DVector& ViewObjectContact::getGridOffset() const +{ + if(0.0 == maGridOffset.getX() && 0.0 == maGridOffset.getY() && GetObjectContact().supportsGridOffsets()) + { + // create on-demand + GetObjectContact().calculateGridOffsetForViewOjectContact(const_cast<ViewObjectContact*>(this)->maGridOffset, *this); + } + + return maGridOffset; +} + +void ViewObjectContact::resetGridOffset() +{ + // reset buffered GridOffset itself + maGridOffset.setX(0.0); + maGridOffset.setY(0.0); + + // also reset sequence to get a re-calculation when GridOffset changes + mxPrimitive2DSequence.clear(); +} + }} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sdr/contact/viewobjectcontactofsdrobj.cxx b/svx/source/sdr/contact/viewobjectcontactofsdrobj.cxx index f0c545e7151b..c6183a2007ba 100644 --- a/svx/source/sdr/contact/viewobjectcontactofsdrobj.cxx +++ b/svx/source/sdr/contact/viewobjectcontactofsdrobj.cxx @@ -22,7 +22,7 @@ #include <svx/sdr/contact/viewcontactofsdrobj.hxx> #include <svx/sdr/contact/objectcontact.hxx> #include <svx/sdr/contact/displayinfo.hxx> -#include <sdr/contact/objectcontactofpageview.hxx> +#include <svx/sdr/contact/objectcontactofpageview.hxx> #include <sdr/contact/viewcontactofsdrole2obj.hxx> #include <svx/sdrpagewindow.hxx> #include <svx/sdrpaintwindow.hxx> diff --git a/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx b/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx index c785a6cdad13..50dcbd25e71e 100644 --- a/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx +++ b/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx @@ -22,7 +22,7 @@ #include <sdr/contact/viewcontactofunocontrol.hxx> #include <svx/sdr/contact/displayinfo.hxx> #include <svx/sdr/properties/properties.hxx> -#include <sdr/contact/objectcontactofpageview.hxx> +#include <svx/sdr/contact/objectcontactofpageview.hxx> #include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> #include <svx/svdouno.hxx> #include <svx/svdpagv.hxx> @@ -918,12 +918,7 @@ namespace sdr { namespace contact { SdrUnoObj* pUnoObject( nullptr ); if ( getUnoObject( pUnoObject ) ) { - Point aGridOffset = pUnoObject->GetGridOffset(); - tools::Rectangle aRect( pUnoObject->GetLogicRect() ); - // Hack for calc, transform position of object according - // to current zoom so as objects relative position to grid - // appears stable - aRect += aGridOffset; + const tools::Rectangle aRect( pUnoObject->GetLogicRect() ); UnoControlContactHelper::adjustControlGeometry_throw( m_aControl, aRect, _rViewTransformation, m_aZoomLevelNormalization ); } else @@ -1086,12 +1081,7 @@ namespace sdr { namespace contact { // knit the model and the control _out_rControl.setModel( xControlModel ); - Point aGridOffset = _rUnoObject.GetGridOffset(); - tools::Rectangle aRect( _rUnoObject.GetLogicRect() ); - // Hack for calc, transform position of object according - // to current zoom so as objects relative position to grid - // appears stable - aRect += aGridOffset; + const tools::Rectangle aRect( _rUnoObject.GetLogicRect() ); // proper geometry UnoControlContactHelper::adjustControlGeometry_throw( @@ -1488,12 +1478,7 @@ namespace sdr { namespace contact { // Do use model data directly to create the correct geometry. Do NOT // use getBoundRect()/getSnapRect() here; these will use the sequence of // primitives themselves in the long run. - tools::Rectangle aSdrGeoData( _rVOC.GetSdrUnoObj().GetGeoRect() ); - Point aGridOffset = _rVOC.GetSdrUnoObj().GetGridOffset(); - // Hack for calc, transform position of object according - // to current zoom so as objects relative position to grid - // appears stable - aSdrGeoData += aGridOffset; + const tools::Rectangle aSdrGeoData( _rVOC.GetSdrUnoObj().GetGeoRect() ); const basegfx::B2DRange aRange( aSdrGeoData.Left(), aSdrGeoData.Top(), diff --git a/svx/source/sdr/overlay/overlayobject.cxx b/svx/source/sdr/overlay/overlayobject.cxx index aae05f9f0b96..d480007d4852 100644 --- a/svx/source/sdr/overlay/overlayobject.cxx +++ b/svx/source/sdr/overlay/overlayobject.cxx @@ -26,8 +26,9 @@ #include <basegfx/polygon/b2dpolypolygon.hxx> #include <basegfx/polygon/b2dpolygontools.hxx> #include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> - +#include <drawinglayer/primitive2d/transformprimitive2d.hxx> namespace sdr { @@ -37,7 +38,8 @@ namespace sdr { const basegfx::B2DRange aPreviousRange(maBaseRange); maBaseRange.reset(); - setPrimitive2DSequence(drawinglayer::primitive2d::Primitive2DContainer()); + resetPrimitive2DSequence(); +// setPrimitive2DSequence(drawinglayer::primitive2d::Primitive2DContainer()); if(getOverlayManager() && !aPreviousRange.isEmpty()) { @@ -91,6 +93,8 @@ namespace sdr OverlayObject::OverlayObject(Color aBaseColor) : Event(), mpOverlayManager(nullptr), + maPrimitive2DSequence(), + maOffset(0.0, 0.0), maBaseColor(aBaseColor), mbIsVisible(true), mbIsHittable(true), @@ -109,8 +113,21 @@ namespace sdr if(getPrimitive2DSequence().empty()) { // no existing sequence; create one - const_cast< OverlayObject* >(this)->setPrimitive2DSequence( - const_cast< OverlayObject* >(this)->createOverlayObjectPrimitive2DSequence()); + const_cast< OverlayObject* >(this)->maPrimitive2DSequence = const_cast< OverlayObject* >(this)->createOverlayObjectPrimitive2DSequence(); + + if(!getOffset().equalZero()) + { + // embed to offset transformation + const basegfx::B2DHomMatrix aTranslateGridOffset( + basegfx::utils::createTranslateB2DHomMatrix( + getOffset())); + const drawinglayer::primitive2d::Primitive2DReference aEmbed( + new drawinglayer::primitive2d::TransformPrimitive2D( + aTranslateGridOffset, + maPrimitive2DSequence)); + + const_cast< OverlayObject* >(this)->maPrimitive2DSequence = drawinglayer::primitive2d::Primitive2DContainer { aEmbed }; + } } return getPrimitive2DSequence(); @@ -170,6 +187,18 @@ namespace sdr } } + void OverlayObject::setOffset(const basegfx::B2DVector& rOffset) + { + if(rOffset != maOffset) + { + // remember new value + maOffset = rOffset; + + // register change (after change) + objectChange(); + } + } + void OverlayObject::Trigger(sal_uInt32 /*nTime*/) { // default does not register again diff --git a/svx/source/sdr/overlay/overlayselection.cxx b/svx/source/sdr/overlay/overlayselection.cxx index 5d22203a4e4e..a1fa52810eb2 100644 --- a/svx/source/sdr/overlay/overlayselection.cxx +++ b/svx/source/sdr/overlay/overlayselection.cxx @@ -196,7 +196,7 @@ namespace sdr || nNewTransparence != mnLastTransparence) { // conditions of last local decomposition have changed, delete - const_cast< OverlaySelection* >(this)->setPrimitive2DSequence(drawinglayer::primitive2d::Primitive2DContainer()); + const_cast< OverlaySelection* >(this)->resetPrimitive2DSequence(); } } diff --git a/svx/source/svdraw/sdrpagewindow.cxx b/svx/source/svdraw/sdrpagewindow.cxx index c722fa883e49..80369f6dbd66 100644 --- a/svx/source/svdraw/sdrpagewindow.cxx +++ b/svx/source/svdraw/sdrpagewindow.cxx @@ -32,7 +32,7 @@ #include <svx/svdview.hxx> #include <svx/svdpagv.hxx> #include <svx/sdrpaintwindow.hxx> -#include <sdr/contact/objectcontactofpageview.hxx> +#include <svx/sdr/contact/objectcontactofpageview.hxx> #include <svx/sdr/contact/displayinfo.hxx> #include <svx/fmview.hxx> #include <basegfx/matrix/b2dhommatrix.hxx> @@ -43,7 +43,7 @@ using namespace ::com::sun::star; struct SdrPageWindow::Impl { // #110094# ObjectContact section - mutable sdr::contact::ObjectContactOfPageView* mpObjectContact; + mutable sdr::contact::ObjectContact* mpObjectContact; // the SdrPageView this window belongs to SdrPageView& mrPageView; @@ -456,8 +456,11 @@ void SdrPageWindow::InvalidatePageWindow(const basegfx::B2DRange& rRange) const sdr::contact::ObjectContact& SdrPageWindow::GetObjectContact() const { if (!mpImpl->mpObjectContact) - mpImpl->mpObjectContact = new sdr::contact::ObjectContactOfPageView( - const_cast<SdrPageWindow&>(*this), "svx::svdraw::SdrPageWindow mpObjectContact" ); + { + mpImpl->mpObjectContact = GetPageView().GetView().createViewSpecificObjectContact( + const_cast<SdrPageWindow&>(*this), + "svx::svdraw::SdrPageWindow mpObjectContact"); + } return *mpImpl->mpObjectContact; } @@ -465,8 +468,11 @@ const sdr::contact::ObjectContact& SdrPageWindow::GetObjectContact() const sdr::contact::ObjectContact& SdrPageWindow::GetObjectContact() { if (!mpImpl->mpObjectContact) - mpImpl->mpObjectContact = new sdr::contact::ObjectContactOfPageView( - *this, "svx::svdraw::SdrPageWindow mpObjectContact" ); + { + mpImpl->mpObjectContact = GetPageView().GetView().createViewSpecificObjectContact( + *this, + "svx::svdraw::SdrPageWindow mpObjectContact" ); + } return *mpImpl->mpObjectContact; } diff --git a/svx/source/svdraw/svdcrtv.cxx b/svx/source/svdraw/svdcrtv.cxx index 5578cb193198..911481038d79 100644 --- a/svx/source/svdraw/svdcrtv.cxx +++ b/svx/source/svdraw/svdcrtv.cxx @@ -641,6 +641,31 @@ bool SdrCreateView::EndCreateObj(SdrCreateCmd eCmd) 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 corretly 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, pCreatePV)) + { + const Size aOffset( + basegfx::fround(-aGridOffset.getX()), + basegfx::fround(-aGridOffset.getY())); + + pObj->NbcMove(aOffset); + } + // do the same as before InsertObjectAtView(pObj, *pCreatePV); } @@ -802,12 +827,8 @@ void SdrCreateView::ShowCreateObj(/*OutputDevice* pOut, sal_Bool bFull*/) } else { - ::basegfx::B2DPolyPolygon aPoly = pCurrentCreate->TakeCreatePoly(maDragStat); - Point aGridOff = pCurrentCreate->GetGridOffset(); - // Hack for calc, transform position of create placeholder - // object according to current zoom so as objects relative - // position to grid appears stable - aPoly.transform( basegfx::utils::createTranslateB2DHomMatrix( aGridOff.X(), aGridOff.Y() ) ); + const ::basegfx::B2DPolyPolygon aPoly(pCurrentCreate->TakeCreatePoly(maDragStat)); + mpCreateViewExtraData->CreateAndShowOverlay(*this, nullptr, aPoly); } diff --git a/svx/source/svdraw/svddrgmt.cxx b/svx/source/svdraw/svddrgmt.cxx index 2c89ca4aabcb..13ee857e655f 100644 --- a/svx/source/svdraw/svddrgmt.cxx +++ b/svx/source/svdraw/svddrgmt.cxx @@ -135,11 +135,12 @@ drawinglayer::primitive2d::Primitive2DContainer SdrDragEntryPolyPolygon::createP } -SdrDragEntrySdrObject::SdrDragEntrySdrObject(const SdrObject& rOriginal, sdr::contact::ObjectContact& rObjectContact, bool bModify) +SdrDragEntrySdrObject::SdrDragEntrySdrObject( + const SdrObject& rOriginal, + bool bModify) : SdrDragEntry(), maOriginal(rOriginal), mpClone(nullptr), - mrObjectContact(rObjectContact), mbModify(bModify) { // add SdrObject parts to transparent overlay stuff @@ -185,16 +186,9 @@ drawinglayer::primitive2d::Primitive2DContainer SdrDragEntrySdrObject::createPri pSource = mpClone; } - // get VOC and Primitive2DContainer - sdr::contact::ViewContact& rVC = pSource->GetViewContact(); - sdr::contact::ViewObjectContact& rVOC = rVC.GetViewObjectContact(mrObjectContact); - sdr::contact::DisplayInfo aDisplayInfo; - - // Do not use the last ViewPort set at the OC from the last ProcessDisplay(), - // here we want the complete primitive sequence without visibility clippings - mrObjectContact.resetViewPort(); - - return rVOC.getPrimitive2DSequenceHierarchy(aDisplayInfo); + // use the view-independent primitive representation (without + // evtl. GridOffset, that may be applied to the DragEntry individually) + return pSource->GetViewContact().getViewIndependentPrimitive2DContainer(); } @@ -338,11 +332,46 @@ void SdrDragMethod::createSdrDragEntries() } } -void SdrDragMethod::createSdrDragEntryForSdrObject(const SdrObject& rOriginal, sdr::contact::ObjectContact& rObjectContact) +void SdrDragMethod::createSdrDragEntryForSdrObject(const SdrObject& rOriginal) { // add full object drag; Clone() at the object has to work // for this - addSdrDragEntry(std::unique_ptr<SdrDragEntry>(new SdrDragEntrySdrObject(rOriginal, rObjectContact, true/*bModify*/))); + addSdrDragEntry(std::unique_ptr<SdrDragEntry>(new SdrDragEntrySdrObject(rOriginal, true/*bModify*/))); +} + +void SdrDragMethod::insertNewlyCreatedOverlayObjectForSdrDragMethod( + std::unique_ptr<sdr::overlay::OverlayObject> pOverlayObject, + const sdr::contact::ObjectContact& rObjectContact, + sdr::overlay::OverlayManager& rOverlayManager) +{ + // check if we have an OverlayObject + if(!pOverlayObject) + { + return; + } + + // add to OverlayManager + rOverlayManager.add(*pOverlayObject); + + // Add GridOffset for non-linear ViewToDevice transformation (calc) + if(rObjectContact.supportsGridOffsets()) + { + const basegfx::B2DRange& rNewRange(pOverlayObject->getBaseRange()); + + if(!rNewRange.isEmpty()) + { + basegfx::B2DVector aOffset(0.0, 0.0); + rObjectContact.calculateGridOffsetForB2DRange(aOffset, rNewRange); + + if(!aOffset.equalZero()) + { + pOverlayObject->setOffset(aOffset); + } + } + } + + // add to local OverlayObjectList - ownership change (!) + maOverlayObjectList.append(std::move(pOverlayObject)); } void SdrDragMethod::createSdrDragEntries_SolidDrag() @@ -364,7 +393,6 @@ void SdrDragMethod::createSdrDragEntries_SolidDrag() { if(pPV->PageWindowCount()) { - sdr::contact::ObjectContact& rOC = pPV->GetPageWindow(0)->GetObjectContact(); SdrObjListIter aIter(*pObject); while(aIter.IsMore()) @@ -386,7 +414,7 @@ void SdrDragMethod::createSdrDragEntries_SolidDrag() { // add full object drag; Clone() at the object has to work // for this - createSdrDragEntryForSdrObject(*pCandidate, rOC); + createSdrDragEntryForSdrObject(*pCandidate); } if(bAddWireframe) @@ -654,7 +682,9 @@ void SdrDragMethod::CancelSdrDrag() typedef std::map< const SdrObject*, SdrObject* > SdrObjectAndCloneMap; -void SdrDragMethod::CreateOverlayGeometry(sdr::overlay::OverlayManager& rOverlayManager) +void SdrDragMethod::CreateOverlayGeometry( + sdr::overlay::OverlayManager& rOverlayManager, + const sdr::contact::ObjectContact& rObjectContact) { // create SdrDragEntries on demand if(maSdrDragEntries.empty()) @@ -764,9 +794,14 @@ void SdrDragMethod::CreateOverlayGeometry(sdr::overlay::OverlayManager& rOverlay if(!aResult.empty()) { - std::unique_ptr<sdr::overlay::OverlayObject> pNewOverlayObject(new sdr::overlay::OverlayPrimitive2DSequenceObject(aResult)); - rOverlayManager.add(*pNewOverlayObject); - addToOverlayObjectList(std::move(pNewOverlayObject)); + std::unique_ptr<sdr::overlay::OverlayObject> pNewOverlayObject( + new sdr::overlay::OverlayPrimitive2DSequenceObject( + aResult)); + + insertNewlyCreatedOverlayObjectForSdrDragMethod( + std::move(pNewOverlayObject), + rObjectContact, + rOverlayManager); } if(!aResultTransparent.empty()) @@ -774,9 +809,14 @@ void SdrDragMethod::CreateOverlayGeometry(sdr::overlay::OverlayManager& rOverlay drawinglayer::primitive2d::Primitive2DReference aUnifiedTransparencePrimitive2D(new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(aResultTransparent, 0.5)); aResultTransparent = drawinglayer::primitive2d::Primitive2DContainer { aUnifiedTransparencePrimitive2D }; - std::unique_ptr<sdr::overlay::OverlayObject> pNewOverlayObject(new sdr::overlay::OverlayPrimitive2DSequenceObject(aResultTransparent)); - rOverlayManager.add(*pNewOverlayObject); - addToOverlayObjectList(std::move(pNewOverlayObject)); + std::unique_ptr<sdr::overlay::OverlayObject> pNewOverlayObject( + new sdr::overlay::OverlayPrimitive2DSequenceObject( + aResultTransparent)); + + insertNewlyCreatedOverlayObjectForSdrDragMethod( + std::move(pNewOverlayObject), + rObjectContact, + rOverlayManager); } } @@ -788,11 +828,17 @@ void SdrDragMethod::CreateOverlayGeometry(sdr::overlay::OverlayManager& rOverlay const basegfx::B2DPoint aTopLeft(aActionRectangle.Left(), aActionRectangle.Top()); const basegfx::B2DPoint aBottomRight(aActionRectangle.Right(), aActionRectangle.Bottom()); - std::unique_ptr<sdr::overlay::OverlayRollingRectangleStriped> pNew(new sdr::overlay::OverlayRollingRectangleStriped( - aTopLeft, aBottomRight, true, false)); + std::unique_ptr<sdr::overlay::OverlayRollingRectangleStriped> pNew( + new sdr::overlay::OverlayRollingRectangleStriped( + aTopLeft, + aBottomRight, + true, + false)); - rOverlayManager.add(*pNew); - addToOverlayObjectList(std::move(pNew)); + insertNewlyCreatedOverlayObjectForSdrDragMethod( + std::move(pNew), + rObjectContact, + rOverlayManager); } } @@ -1159,8 +1205,7 @@ void SdrDragObjOwn::createSdrDragEntries() if(pPV && pPV->PageWindowCount()) { - sdr::contact::ObjectContact& rOC = pPV->GetPageWindow(0)->GetObjectContact(); - addSdrDragEntry(std::unique_ptr<SdrDragEntry>(new SdrDragEntrySdrObject(*mpClone, rOC, false))); + addSdrDragEntry(std::unique_ptr<SdrDragEntry>(new SdrDragEntrySdrObject(*mpClone, false))); // potentially no wireframe needed, full drag works bAddWireframe = false; @@ -1417,19 +1462,15 @@ Pointer SdrDragObjOwn::GetSdrDragPointer() const } -void SdrDragMove::createSdrDragEntryForSdrObject(const SdrObject& rOriginal, sdr::contact::ObjectContact& rObjectContact) +void SdrDragMove::createSdrDragEntryForSdrObject(const SdrObject& rOriginal) { - // for SdrDragMove, use current Primitive2DContainer of SdrObject visualization - // in given ObjectContact directly - sdr::contact::ViewContact& rVC = rOriginal.GetViewContact(); - sdr::contact::ViewObjectContact& rVOC = rVC.GetViewObjectContact(rObjectContact); - sdr::contact::DisplayInfo aDisplayInfo; + // use the view-independent primitive representation (without + // evtl. GridOffset, that may be applied to the DragEntry individually) + addSdrDragEntry( + std::unique_ptr<SdrDragEntry>( + new SdrDragEntryPrimitive2DSequence( + rOriginal.GetViewContact().getViewIndependentPrimitive2DContainer()))); - // Do not use the last ViewPort set at the OC from the last ProcessDisplay(), - // here we want the complete primitive sequence without visible clippings - rObjectContact.resetViewPort(); - - addSdrDragEntry(std::unique_ptr<SdrDragEntry>(new SdrDragEntryPrimitive2DSequence(rVOC.getPrimitive2DSequenceHierarchy(aDisplayInfo)))); } void SdrDragMove::applyCurrentTransformationToSdrObject(SdrObject& rTarget) @@ -1766,8 +1807,7 @@ bool SdrDragResize::BeginSdrDrag() if (pRefHdl!=nullptr && !getSdrDragView().IsResizeAtCenter()) { - // Calc hack to adjust for calc grid - DragStat().SetRef1(pRefHdl->GetPos() - getSdrDragView().GetGridOffset()); + DragStat().SetRef1(pRefHdl->GetPos()); } else { diff --git a/svx/source/svdraw/svddrgv.cxx b/svx/source/svdraw/svddrgv.cxx index 20f14af9c5ce..31132a5bbdef 100644 --- a/svx/source/svdraw/svddrgv.cxx +++ b/svx/source/svdraw/svddrgv.cxx @@ -40,6 +40,7 @@ #include <svx/polypolygoneditor.hxx> #include <basegfx/matrix/b2dhommatrix.hxx> #include <svx/sdr/overlay/overlaymanager.hxx> +#include <svx/sdrpagewindow.hxx> using namespace sdr; @@ -220,6 +221,19 @@ bool SdrDragView::BegDragObj(const Point& rPnt, OutputDevice* pOut, SdrHdl* pHdl } Point aPnt(rPnt); + basegfx::B2DVector aGridOffset(0.0, 0.0); + + // Coordinate maybe affected by GridOffset, so we may need to + // adapt to Model-coordinates here + if(getPossibleGridOffsetForPosition( + aGridOffset, + basegfx::B2DPoint(aPnt.X(), aPnt.Y()), + GetSdrPageView())) + { + aPnt.AdjustX(basegfx::fround(-aGridOffset.getX())); + aPnt.AdjustY(basegfx::fround(-aGridOffset.getY())); + } + if(pHdl == nullptr || pHdl->GetKind() == SdrHdlKind::Move || pHdl->GetKind() == SdrHdlKind::MirrorAxis @@ -508,6 +522,19 @@ void SdrDragView::MovDragObj(const Point& rPnt) if (mpCurrentSdrDragMethod) { Point aPnt(rPnt); + basegfx::B2DVector aGridOffset(0.0, 0.0); + + // Coordinate maybe affected by GridOffset, so we may need to + // adapt to Model-coordinates here + if(getPossibleGridOffsetForPosition( + aGridOffset, + basegfx::B2DPoint(aPnt.X(), aPnt.Y()), + GetSdrPageView())) + { + aPnt.AdjustX(basegfx::fround(-aGridOffset.getX())); + aPnt.AdjustY(basegfx::fround(-aGridOffset.getY())); + } + ImpLimitToWorkArea(aPnt); mpCurrentSdrDragMethod->MoveSdrDrag(aPnt); // this call already makes a Hide()/Show combination } @@ -780,17 +807,35 @@ void SdrDragView::ShowDragObj() { if(mpCurrentSdrDragMethod && !maDragStat.IsShown()) { - for(sal_uInt32 a(0); a < PaintWindowCount(); a++) + // Changed for the GridOffset stuff: No longer iterate over + // SdrPaintWindow(s), but now over SdrPageWindow(s), so doing the + // same as the SdrHdl visualizations (see ::CreateB2dIAObject) do. + // This is needed to get access to a ObjectContact which is needed + // to evtl. process that GridOffset in CreateOverlayGeometry + SdrPageView* pPageView(GetSdrPageView()); + + if(nullptr != pPageView) { - SdrPaintWindow* pCandidate = GetPaintWindow(a); - const rtl::Reference<sdr::overlay::OverlayManager>& xOverlayManager = pCandidate->GetOverlayManager(); - - if (xOverlayManager.is()) + for(sal_uInt32 a(0); a < pPageView->PageWindowCount(); a++) { - mpCurrentSdrDragMethod->CreateOverlayGeometry(*xOverlayManager); + const SdrPageWindow& rPageWindow(*pPageView->GetPageWindow(a)); + const SdrPaintWindow& rPaintWindow(rPageWindow.GetPaintWindow()); - // #i101679# Force changed overlay to be shown - xOverlayManager->flush(); + if(rPaintWindow.OutputToWindow()) + { + const rtl::Reference<sdr::overlay::OverlayManager>& xOverlayManager( + rPaintWindow.GetOverlayManager()); + + if(xOverlayManager.is()) + { + mpCurrentSdrDragMethod->CreateOverlayGeometry( + *xOverlayManager.get(), + rPageWindow.GetObjectContact()); + + // #i101679# Force changed overlay to be shown + xOverlayManager->flush(); + } + } } } diff --git a/svx/source/svdraw/svdedtv1.cxx b/svx/source/svdraw/svdedtv1.cxx index 960dd2c58269..1acf37cd3771 100644 --- a/svx/source/svdraw/svdedtv1.cxx +++ b/svx/source/svdraw/svdedtv1.cxx @@ -1259,8 +1259,6 @@ SfxItemSet SdrEditView::GetGeoAttrFromMarked() const { SfxItemSet aMarkAttr(GetAttrFromMarked(false)); // because of AutoGrowHeight and corner radius tools::Rectangle aRect(GetMarkedObjRect()); - // restore position to that before calc hack - aRect -= GetGridOffset(); if(GetSdrPageView()) { diff --git a/svx/source/svdraw/svdedxv.cxx b/svx/source/svdraw/svdedxv.cxx index 0f7361bbd6d8..66a409c8cfae 100644 --- a/svx/source/svdraw/svdedxv.cxx +++ b/svx/source/svdraw/svdedxv.cxx @@ -261,13 +261,20 @@ void SdrObjEditView::ModelHasChanged() tools::Rectangle aEditArea1; tools::Rectangle aMinArea1; pTextObj->TakeTextEditArea(&aPaperMin1,&aPaperMax1,&aEditArea1,&aMinArea1); - Point aPvOfs(pTextObj->GetTextEditOffset()); - // Hack for calc, transform position of edit object according - // to current zoom so as objects relative position to grid - // appears stable - aEditArea1 += pTextObj->GetGridOffset(); - aMinArea1 += pTextObj->GetGridOffset(); + + // add possible GridOffset to up-to-now view-independent EditAreas + basegfx::B2DVector aGridOffset(0.0, 0.0); + if(getPossibleGridOffsetForSdrObject(aGridOffset, pTextObj, GetSdrPageView())) + { + const Point aOffset( + basegfx::fround(aGridOffset.getX()), + basegfx::fround(aGridOffset.getY())); + + aEditArea1 += aOffset; + aMinArea1 += aOffset; + } + aEditArea1.Move(aPvOfs.X(),aPvOfs.Y()); aMinArea1.Move(aPvOfs.X(),aPvOfs.Y()); tools::Rectangle aNewArea(aMinArea1); @@ -494,7 +501,7 @@ namespace if (!maRange.equal(maLastRange) || maLastTextPrimitives != maTextPrimitives) { // conditions of last local decomposition have changed, delete to force new evaluation - const_cast<TextEditOverlayObject*>(this)->setPrimitive2DSequence(drawinglayer::primitive2d::Primitive2DContainer()); + const_cast<TextEditOverlayObject*>(this)->resetPrimitive2DSequence(); } } @@ -1148,14 +1155,20 @@ bool SdrObjEditView::SdrBeginTextEdit( aTextEditArea = aTextRect; - // Hack for calc, transform position of edit object according - // to current zoom so as objects relative position to grid - // appears stable + // add possible GridOffset to up-to-now view-independent EditAreas + basegfx::B2DVector aGridOffset(0.0, 0.0); + if(getPossibleGridOffsetForSdrObject(aGridOffset, pTextObj, pPV)) + { + const Point aOffset( + basegfx::fround(aGridOffset.getX()), + basegfx::fround(aGridOffset.getY())); + + aTextEditArea += aOffset; + aMinTextEditArea += aOffset; + } Point aPvOfs(pTextObj->GetTextEditOffset()); - aTextEditArea += pTextObj->GetGridOffset(); aTextEditArea.Move(aPvOfs.X(),aPvOfs.Y()); - aMinTextEditArea += pTextObj->GetGridOffset(); aMinTextEditArea.Move(aPvOfs.X(),aPvOfs.Y()); pTextEditCursorBuffer=pWin->GetCursor(); diff --git a/svx/source/svdraw/svdhdl.cxx b/svx/source/svdraw/svdhdl.cxx index 93621e714802..0a51a0a580ef 100644 --- a/svx/source/svdraw/svdhdl.cxx +++ b/svx/source/svdraw/svdhdl.cxx @@ -56,6 +56,8 @@ #include <svx/sdr/overlay/overlaypolypolygon.hxx> #include <vcl/lazydelete.hxx> #include <vcl/BitmapTools.hxx> +#include <svx/sdr/contact/objectcontact.hxx> +#include <svx/sdr/contact/viewcontact.hxx> #include <basegfx/polygon/b2dpolygontools.hxx> #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> @@ -612,12 +614,12 @@ void SdrHdl::CreateB2dIAObject() aPosition, eColIndex, eKindOfMarker, aMoveOutsideOffset); } + // OVERLAYMANAGER - if (pNewOverlayObject) - { - xManager->add(*pNewOverlayObject); - maOverlayGroup.append(std::move(pNewOverlayObject)); - } + insertNewlyCreatedOverlayObjectForSdrHdl( + std::move(pNewOverlayObject), + rPageWindow.GetObjectContact(), + *xManager.get()); } } } @@ -1070,6 +1072,39 @@ BitmapEx SdrHdl::createGluePointBitmap() return ImpGetBitmapEx(BitmapMarkerKind::Glue_Deselected, BitmapColorIndex::LightGreen); } +void SdrHdl::insertNewlyCreatedOverlayObjectForSdrHdl( + std::unique_ptr<sdr::overlay::OverlayObject> pOverlayObject, + const sdr::contact::ObjectContact& rObjectContact, + sdr::overlay::OverlayManager& rOverlayManager) +{ + // check if we have an OverlayObject + if(!pOverlayObject) + { + return; + } + + // Add GridOffset for non-linear ViewToDevice transformation (calc) + if(nullptr != GetObj() && rObjectContact.supportsGridOffsets()) + { + basegfx::B2DVector aOffset(0.0, 0.0); + const sdr::contact::ViewObjectContact& rVOC(GetObj()->GetViewContact().GetViewObjectContact( + const_cast<sdr::contact::ObjectContact&>(rObjectContact))); + + rObjectContact.calculateGridOffsetForViewOjectContact(aOffset, rVOC); + + if(!aOffset.equalZero()) + { + pOverlayObject->setOffset(aOffset); + } + } + + // add to OverlayManager + rOverlayManager.add(*pOverlayObject); + + // add to local OverlayObjectList - ownership change (!) + maOverlayGroup.append(std::move(pOverlayObject)); +} + SdrHdlColor::SdrHdlColor(const Point& rRef, Color aCol, const Size& rSize, bool bLum) : SdrHdl(rRef, SdrHdlKind::Color), aMarkerSize(rSize), @@ -1121,8 +1156,10 @@ void SdrHdlColor::CreateB2dIAObject() )); // OVERLAYMANAGER - xManager->add(*pNewOverlayObject); - maOverlayGroup.append(std::move(pNewOverlayObject)); + insertNewlyCreatedOverlayObjectForSdrHdl( + std::move(pNewOverlayObject), + rPageWindow.GetObjectContact(), + *xManager.get()); } } } @@ -1280,8 +1317,12 @@ void SdrHdlGradient::CreateB2dIAObject() )); pNewOverlayObject->setBaseColor(IsGradient() ? COL_BLACK : COL_BLUE); - xManager->add(*pNewOverlayObject); - maOverlayGroup.append(std::move(pNewOverlayObject)); + + // OVERLAYMANAGER + insertNewlyCreatedOverlayObjectForSdrHdl( + std::move(pNewOverlayObject), + rPageWindow.GetObjectContact(), + *xManager.get()); // arrowhead Point aLeft(aMidPoint.X() + static_cast<sal_Int32>(aPerpend.getX() * fHalfArrowWidth), @@ -1301,8 +1342,11 @@ void SdrHdlGradient::CreateB2dIAObject() IsGradient() ? COL_BLACK : COL_BLUE )); - xManager->add(*pNewOverlayObject); - maOverlayGroup.append(std::move(pNewOverlayObject)); + // OVERLAYMANAGER + insertNewlyCreatedOverlayObjectForSdrHdl( + std::move(pNewOverlayObject), + rPageWindow.GetObjectContact(), + *xManager.get()); } } } @@ -1425,12 +1469,14 @@ void SdrHdlLine::CreateB2dIAObject() aPosition2 )); - // OVERLAYMANAGER // color(?) pNewOverlayObject->setBaseColor(COL_LIGHTRED); - xManager->add(*pNewOverlayObject); - maOverlayGroup.append(std::move(pNewOverlayObject)); + // OVERLAYMANAGER + insertNewlyCreatedOverlayObjectForSdrHdl( + std::move(pNewOverlayObject), + rPageWindow.GetObjectContact(), + *xManager.get()); } } } @@ -1482,15 +1528,18 @@ void SdrHdlBezWgt::CreateB2dIAObject() aPosition1, aPosition2 )); - // OVERLAYMANAGER + // line part is not hittable pNewOverlayObject->setHittable(false); // color(?) pNewOverlayObject->setBaseColor(COL_LIGHTBLUE); - xManager->add(*pNewOverlayObject); - maOverlayGroup.append(std::move(pNewOverlayObject)); + // OVERLAYMANAGER + insertNewlyCreatedOverlayObjectForSdrHdl( + std::move(pNewOverlayObject), + rPageWindow.GetObjectContact(), + *xManager.get()); } } } @@ -1532,11 +1581,13 @@ void E3dVolumeMarker::CreateB2dIAObject() sdr::overlay::OverlayPolyPolygonStripedAndFilled( aWireframePoly)); - // OVERLAYMANAGER pNewOverlayObject->setBaseColor(COL_BLACK); - xManager->add(*pNewOverlayObject); - maOverlayGroup.append(std::move(pNewOverlayObject)); + // OVERLAYMANAGER + insertNewlyCreatedOverlayObjectForSdrHdl( + std::move(pNewOverlayObject), + rPageWindow.GetObjectContact(), + *xManager.get()); } } } @@ -1597,11 +1648,10 @@ void ImpEdgeHdl::CreateB2dIAObject() eKindOfMarker)); // OVERLAYMANAGER - if (pNewOverlayObject) - { - xManager->add(*pNewOverlayObject); - maOverlayGroup.append(std::move(pNewOverlayObject)); - } + insertNewlyCreatedOverlayObjectForSdrHdl( + std::move(pNewOverlayObject), + rPageWindow.GetObjectContact(), + *xManager.get()); } } } @@ -1713,11 +1763,10 @@ void ImpMeasureHdl::CreateB2dIAObject() eKindOfMarker)); // OVERLAYMANAGER - if (pNewOverlayObject) - { - xManager->add(*pNewOverlayObject); - maOverlayGroup.append(std::move(pNewOverlayObject)); - } + insertNewlyCreatedOverlayObjectForSdrHdl( + std::move(pNewOverlayObject), + rPageWindow.GetObjectContact(), + *xManager.get()); } } } @@ -1784,10 +1833,13 @@ void ImpTextframeHdl::CreateB2dIAObject() nRotationAngle * -F_PI18000, true)); // allow animation; the Handle is not shown at text edit time - // OVERLAYMANAGER pNewOverlayObject->setHittable(false); - xManager->add(*pNewOverlayObject); - maOverlayGroup.append(std::move(pNewOverlayObject)); + + // OVERLAYMANAGER + insertNewlyCreatedOverlayObjectForSdrHdl( + std::move(pNewOverlayObject), + rPageWindow.GetObjectContact(), + *xManager.get()); } } } @@ -2395,8 +2447,10 @@ void SdrCropHdl::CreateB2dIAObject() } // OVERLAYMANAGER - xManager->add(*pOverlayObject); - maOverlayGroup.append(std::move(pOverlayObject)); + insertNewlyCreatedOverlayObjectForSdrHdl( + std::move(pOverlayObject), + rPageWindow.GetObjectContact(), + *xManager.get()); } } } @@ -2608,8 +2662,11 @@ void SdrCropViewHdl::CreateB2dIAObject() // only informative object, no hit pNew->setHittable(false); - xManager->add(*pNew); - maOverlayGroup.append(std::move(pNew)); + // OVERLAYMANAGER + insertNewlyCreatedOverlayObjectForSdrHdl( + std::move(pNew), + rPageWindow.GetObjectContact(), + *xManager.get()); } } } diff --git a/svx/source/svdraw/svdmrkv.cxx b/svx/source/svdraw/svdmrkv.cxx index bbad824d3267..8a55f973873d 100644 --- a/svx/source/svdraw/svdmrkv.cxx +++ b/svx/source/svdraw/svdmrkv.cxx @@ -43,6 +43,7 @@ #include <svx/svdovirt.hxx> #include <sdr/overlay/overlayrollingrectangle.hxx> #include <svx/sdr/overlay/overlaymanager.hxx> +#include <svx/sdr/contact/viewcontact.hxx> #include <svx/sdrpaintwindow.hxx> #include <svx/sdrpagewindow.hxx> #include <svx/sdrhittesthelper.hxx> @@ -675,11 +676,6 @@ void SdrMarkView::SetMarkHandles(SfxViewShell* pOtherShell) } } - // apply calc offset to marked object rect - // ( necessary for handles to be displayed in - // correct position ) - Point aGridOff = GetGridOffset(); - // There can be multiple mark views, but we're only interested in the one that has a window associated. const bool bTiledRendering = comphelper::LibreOfficeKit::isActive() && GetFirstOutputDevice() && GetFirstOutputDevice()->GetOutDevType() == OUTDEV_WINDOW; @@ -804,20 +800,13 @@ void SdrMarkView::SetMarkHandles(SfxViewShell* pOtherShell) if (bFrmHdl) { if(!aRect.IsEmpty()) - { // otherwise nothing is found + { + // otherwise nothing is found + const size_t nSiz0(maHdlList.GetHdlCount()); + if( bSingleTextObjMark ) { - const size_t nSiz0=maHdlList.GetHdlCount(); mpMarkedObj->AddToHdlList(maHdlList); - const size_t nSiz1=maHdlList.GetHdlCount(); - for (size_t i=nSiz0; i<nSiz1; ++i) - { - SdrHdl* pHdl=maHdlList.GetHdl(i); - pHdl->SetObj(mpMarkedObj); - pHdl->SetPos( pHdl->GetPos() + aGridOff ); - pHdl->SetPageView(mpMarkedPV); - pHdl->SetObjHdlNum(sal_uInt16(i-nSiz0)); - } } else { @@ -876,6 +865,20 @@ void SdrMarkView::SetMarkHandles(SfxViewShell* pOtherShell) } } } + + const size_t nSiz1(maHdlList.GetHdlCount()); + + // moved setting the missing parameters at SdrHdl here from the + // single loop above (bSingleTextObjMark), this was missing all + // the time. Setting SdrObject is now required to correctly get + // the View-Dependent evtl. GridOffset adapted + for (size_t i=nSiz0; i<nSiz1; ++i) + { + SdrHdl* pHdl=maHdlList.GetHdl(i); + pHdl->SetObj(mpMarkedObj); + pHdl->SetPageView(mpMarkedPV); + pHdl->SetObjHdlNum(sal_uInt16(i-nSiz0)); + } } } else @@ -888,7 +891,19 @@ void SdrMarkView::SetMarkHandles(SfxViewShell* pOtherShell) // Default addCropHandles from SdrObject does nothing. When pMarkedObj is SdrGrafObj, previous // behaviour occurs (code in svx/source/svdraw/svdograf.cxx). When pMarkedObj is SwVirtFlyDrawObj // writer takes the responsibility of adding handles (code in sw/source/core/draw/dflyobj.cxx) + const size_t nSiz0(maHdlList.GetHdlCount()); mpMarkedObj->addCropHandles(maHdlList); + const size_t nSiz1(maHdlList.GetHdlCount()); + + // Was missing: Set infos at SdrCropHdl + for (size_t i=nSiz0; i<nSiz1; ++i) + { + SdrHdl* pHdl=maHdlList.GetHdl(i); + pHdl->SetObj(mpMarkedObj); + pHdl->SetPageView(mpMarkedPV); + pHdl->SetObjHdlNum(sal_uInt16(i-nSiz0)); + } + bDone = true; } @@ -907,7 +922,6 @@ void SdrMarkView::SetMarkHandles(SfxViewShell* pOtherShell) for (size_t i=nSiz0; i<nSiz1; ++i) { SdrHdl* pHdl=maHdlList.GetHdl(i); - pHdl->SetPos( pHdl->GetPos() + aGridOff ); pHdl->SetObj(pObj); pHdl->SetPageView(pPV); pHdl->SetObjHdlNum(sal_uInt16(i-nSiz0)); @@ -1695,6 +1709,83 @@ void SdrMarkView::SetMarkHdlSizePixel(sal_uInt16 nSiz) } } +bool SdrMarkView::getPossibleGridOffsetForSdrObject( + basegfx::B2DVector& rOffset, + const SdrObject* pObj, + const SdrPageView* pPV) const +{ + if(nullptr == pObj || nullptr == pPV) + { + return false; + } + + const OutputDevice* pOutputDevice(GetFirstOutputDevice()); + + if(nullptr == pOutputDevice) + { + return false; + } + + const SdrPageWindow* pSdrPageWindow(pPV->FindPageWindow(*pOutputDevice)); + + if(nullptr == pSdrPageWindow) + { + return false; + } + + const sdr::contact::ObjectContact& rObjectContact(pSdrPageWindow->GetObjectContact()); + + if(!rObjectContact.supportsGridOffsets()) + { + return false; + } + + basegfx::B2DVector aOffset(0.0, 0.0); + const sdr::contact::ViewObjectContact& rVOC(pObj->GetViewContact().GetViewObjectContact( + const_cast<sdr::contact::ObjectContact&>(rObjectContact))); + + rObjectContact.calculateGridOffsetForViewOjectContact(rOffset, rVOC); + + return !rOffset.equalZero(); +} + +bool SdrMarkView::getPossibleGridOffsetForPosition( + basegfx::B2DVector& rOffset, + const basegfx::B2DPoint& rPoint, + const SdrPageView* pPV) const +{ + if(nullptr == pPV) + { + return false; + } + + const OutputDevice* pOutputDevice(GetFirstOutputDevice()); + + if(nullptr == pOutputDevice) + { + return false; + } + + const SdrPageWindow* pSdrPageWindow(pPV->FindPageWindow(*pOutputDevice)); + + if(nullptr == pSdrPageWindow) + { + return false; + } + + const sdr::contact::ObjectContact& rObjectContact(pSdrPageWindow->GetObjectContact()); + + if(!rObjectContact.supportsGridOffsets()) + { + return false; + } + + basegfx::B2DVector aOffset(0.0, 0.0); + rObjectContact.calculateGridOffsetForB2DRange(rOffset, basegfx::B2DRange(rPoint)); + + return !rOffset.equalZero(); +} + SdrObject* SdrMarkView::CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nTol, SdrObject* pObj, SdrPageView* pPV, SdrSearchOptions nOptions, const SdrLayerIDSet* pMVisLay) const { if(((nOptions & SdrSearchOptions::IMPISMASTER) && pObj->IsNotVisibleAsMaster()) || (!pObj->IsVisible())) @@ -1708,8 +1799,16 @@ SdrObject* SdrMarkView::CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nT const bool bTXT(dynamic_cast<const SdrTextObj*>( pObj) != nullptr && static_cast<SdrTextObj*>(pObj)->IsTextFrame()); SdrObject* pRet=nullptr; tools::Rectangle aRect(pObj->GetCurrentBoundRect()); - // hack for calc grid sync - aRect += pObj->GetGridOffset(); + + // add possible GridOffset to up-to-now view-independent BountRect data + basegfx::B2DVector aGridOffset(0.0, 0.0); + if(getPossibleGridOffsetForSdrObject(aGridOffset, pObj, pPV)) + { + aRect += Point( + basegfx::fround(aGridOffset.getX()), + basegfx::fround(aGridOffset.getY())); + } + sal_uInt16 nTol2(nTol); // double tolerance for OLE, text frames and objects in @@ -2009,6 +2108,7 @@ void SdrMarkView::AdjustMarkHdl(SfxViewShell* pOtherShell) SetMarkHandles(pOtherShell); } +// BoundRect in model coordinates, no GridOffset added tools::Rectangle SdrMarkView::GetMarkedObjBoundRect() const { tools::Rectangle aRect; @@ -2016,49 +2116,28 @@ tools::Rectangle SdrMarkView::GetMarkedObjBoundRect() const SdrMark* pM=GetSdrMarkByIndex(nm); SdrObject* pO=pM->GetMarkedSdrObj(); tools::Rectangle aR1(pO->GetCurrentBoundRect()); - // Ensure marked area includes the calc offset - // ( if applicable ) to sync to grid - aR1 += pO->GetGridOffset(); if (aRect.IsEmpty()) aRect=aR1; else aRect.Union(aR1); } return aRect; } -Point SdrMarkView::GetGridOffset() const -{ - Point aOffset; - // calculate the area occupied by the union of each marked object - // ( synced to grid ) and compare to the same unsynced area to calculate - // the offset. Hopefully that's the sensible thing to do - const tools::Rectangle& aGroupSyncedRect = GetMarkedObjRect(); - aOffset = aGroupSyncedRect.TopLeft() - maMarkedObjRectNoOffset.TopLeft(); - return aOffset; -} - +// ObjRect in model coordinates, no GridOffset added const tools::Rectangle& SdrMarkView::GetMarkedObjRect() const { if (mbMarkedObjRectDirty) { const_cast<SdrMarkView*>(this)->mbMarkedObjRectDirty=false; tools::Rectangle aRect; - tools::Rectangle aRect2; for (size_t nm=0; nm<GetMarkedObjectCount(); ++nm) { SdrMark* pM=GetSdrMarkByIndex(nm); SdrObject* pO = pM->GetMarkedSdrObj(); if (!pO) continue; tools::Rectangle aR1(pO->GetSnapRect()); - // apply calc offset to marked object rect - // ( necessary for handles to be displayed in - // correct position ) - if (aRect2.IsEmpty()) aRect2=aR1; - else aRect2.Union( aR1 ); - aR1 += pO->GetGridOffset(); if (aRect.IsEmpty()) aRect=aR1; else aRect.Union(aR1); } const_cast<SdrMarkView*>(this)->maMarkedObjRect=aRect; - const_cast<SdrMarkView*>(this)->maMarkedObjRectNoOffset=aRect2; } return maMarkedObjRect; } diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx index cb104cba5358..7706cfebd826 100644 --- a/svx/source/svdraw/svdobj.cxx +++ b/svx/source/svdraw/svdobj.cxx @@ -890,6 +890,8 @@ void SdrObject::RecalcBoundRect() // central new method which will calculate the BoundRect using primitive geometry if(aOutRect.IsEmpty()) { + // Use view-independent data - we do not want any connections + // to e.g. GridOffset in SdrObject-level const drawinglayer::primitive2d::Primitive2DContainer xPrimitives(GetViewContact().getViewIndependentPrimitive2DContainer()); if(!xPrimitives.empty()) @@ -905,7 +907,6 @@ void SdrObject::RecalcBoundRect() static_cast<long>(floor(aRange.getMinY())), static_cast<long>(ceil(aRange.getMaxX())), static_cast<long>(ceil(aRange.getMaxY()))); - aOutRect -= GetGridOffset(); // don't include grid offset return; } } @@ -1022,8 +1023,6 @@ SdrObject& SdrObject::operator=(const SdrObject& rObj) pGrabBagItem.reset(); if (rObj.pGrabBagItem!=nullptr) pGrabBagItem.reset(static_cast< SfxGrabBagItem* >( rObj.pGrabBagItem->Clone() )); - - aGridOffset = rObj.aGridOffset; return *this; } @@ -1706,7 +1705,6 @@ bool SdrObject::HasTextEdit() const bool SdrObject::Equals(const SdrObject& rOtherObj) const { return (aAnchor.X() == rOtherObj.aAnchor.X() && aAnchor.Y() == rOtherObj.aAnchor.Y() && - aGridOffset.X() == rOtherObj.aGridOffset.X() && aGridOffset.Y() == rOtherObj.aGridOffset.Y() && nOrdNum == rOtherObj.nOrdNum && mnNavigationPosition == rOtherObj.mnNavigationPosition && mbSupportTextIndentingOnLineWidthChange == rOtherObj.mbSupportTextIndentingOnLineWidthChange && mbLineIsOutsideGeometry == rOtherObj.mbLineIsOutsideGeometry && bMarkProt == rOtherObj.bMarkProt && diff --git a/svx/source/svdraw/svdorect.cxx b/svx/source/svdraw/svdorect.cxx index d9b74ea3aaa9..348ef3738842 100644 --- a/svx/source/svdraw/svdorect.cxx +++ b/svx/source/svdraw/svdorect.cxx @@ -316,9 +316,7 @@ void SdrRectObj::AddToHdlList(SdrHdlList& rHdlList) const if(IsTextFrame()) { OSL_ENSURE(!IsTextEditActive(), "Do not use a ImpTextframeHdl for highlighting text in active text edit, this will collide with EditEngine paints (!)"); - // hack for calc grid sync to ensure the hatched area - // for a textbox is displayed at correct position - std::unique_ptr<SdrHdl> pH(new ImpTextframeHdl(maRect + GetGridOffset())); + std::unique_ptr<SdrHdl> pH(new ImpTextframeHdl(maRect)); pH->SetObj(const_cast<SdrRectObj*>(this)); pH->SetRotationAngle(aGeo.nRotationAngle); rHdlList.AddHdl(std::move(pH)); diff --git a/svx/source/svdraw/svdpagv.cxx b/svx/source/svdraw/svdpagv.cxx index ed73fadf7acd..c180fe9b459e 100644 --- a/svx/source/svdraw/svdpagv.cxx +++ b/svx/source/svdraw/svdpagv.cxx @@ -35,7 +35,7 @@ #include <svx/svdtypes.hxx> #include <svx/svdoole2.hxx> -#include <sdr/contact/objectcontactofpageview.hxx> +#include <svx/sdr/contact/objectcontactofpageview.hxx> #include <svx/sdr/contact/viewobjectcontactredirector.hxx> #include <svx/fmview.hxx> diff --git a/svx/source/svdraw/svdview.cxx b/svx/source/svdraw/svdview.cxx index c68bbe443a72..0cee85fe96c3 100644 --- a/svx/source/svdraw/svdview.cxx +++ b/svx/source/svdraw/svdview.cxx @@ -51,6 +51,7 @@ #include <svx/sdr/contact/viewcontact.hxx> #include <drawinglayer/processor2d/contourextractor2d.hxx> #include <drawinglayer/primitive2d/texthierarchyprimitive2d.hxx> +#include <svx/sdr/contact/objectcontactofpageview.hxx> #include <sal/log.hxx> @@ -1470,5 +1471,12 @@ void SdrView::SetMasterPagePaintCaching(bool bOn) } } +// Default ObjectContact is ObjectContactOfPageView +sdr::contact::ObjectContact* SdrView::createViewSpecificObjectContact( + SdrPageWindow& rPageWindow, + const sal_Char* pDebugName) const +{ + return new sdr::contact::ObjectContactOfPageView(rPageWindow, pDebugName); +} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/table/tablehandles.cxx b/svx/source/table/tablehandles.cxx index accbad2739d0..650180b23d3f 100644 --- a/svx/source/table/tablehandles.cxx +++ b/svx/source/table/tablehandles.cxx @@ -172,8 +172,12 @@ void TableEdgeHdl::CreateB2dIAObject() { // create overlay object for visible parts std::unique_ptr<sdr::overlay::OverlayObject> pOverlayObject(new OverlayTableEdge(aVisible, true)); - xManager->add(*pOverlayObject); - maOverlayGroup.append(std::move(pOverlayObject)); + + // OVERLAYMANAGER + insertNewlyCreatedOverlayObjectForSdrHdl( + std::move(pOverlayObject), + rPageWindow.GetObjectContact(), + *xManager.get()); } if(aInvisible.count()) @@ -182,8 +186,12 @@ void TableEdgeHdl::CreateB2dIAObject() // a standard HitTest using the primitives from that overlay object // (see OverlayTableEdge implementation) std::unique_ptr<sdr::overlay::OverlayObject> pOverlayObject(new OverlayTableEdge(aInvisible, false)); - xManager->add(*pOverlayObject); - maOverlayGroup.append(std::move(pOverlayObject)); + + // OVERLAYMANAGER + insertNewlyCreatedOverlayObjectForSdrHdl( + std::move(pOverlayObject), + rPageWindow.GetObjectContact(), + *xManager.get()); } } } @@ -289,8 +297,12 @@ void TableBorderHdl::CreateB2dIAObject() new sdr::overlay::OverlayRectangle(aRange.getMinimum(), aRange.getMaximum(), aHilightColor, fTransparence, fWidth, 0.0, 0.0, bAnimate)); - xManager->add(*pOverlayObject); - maOverlayGroup.append(std::move(pOverlayObject)); + + // OVERLAYMANAGER + insertNewlyCreatedOverlayObjectForSdrHdl( + std::move(pOverlayObject), + rPageWindow.GetObjectContact(), + *xManager.get()); } } } |