diff options
author | Dennis Francis <dennis.francis@collabora.com> | 2020-06-18 18:09:19 +0530 |
---|---|---|
committer | Dennis Francis <dennis.francis@collabora.com> | 2020-07-11 07:34:10 +0200 |
commit | a910703bcbd2d8a767aff3f50185233baf601a32 (patch) | |
tree | 057c8699ec3e41d662ee263b4ca2c1695593d136 /sc | |
parent | 539e4124739feffdceecb5207fdc2428396a9dd4 (diff) |
scPrintTwipsMsgs: Use print logical coordinates for draw objects
as a result LOK_CALLBACK_GRAPHIC(_VIEW)_SELECTION messages will now be
in print-twips.
For tile-rendering, it needs the pixel-aligned coordinates of each
object. The translation of print coordinates to pixel-aligned
coordinates can be done behind the scenes by the
ViewContact/ObjectContact/ViewObjectContact objects associated with the
draw object which uses the cached "grid-offset" for each object
(introduced in the patch "Refactor calc non-linear ViewToDevice
transform"). For doing this, a subclass of FmFormView with a specialized
"createViewSpecificObjectContact" method is used for tile-rendering. The
createViewSpecificObjectContact creates a "proxy" object-contact object
that delegates the grid-offsets queries to the actual ScDrawView
generated ObjectContact. This is needed because currently there is no
way to share the ObjectContact/ViewObjectContact instances between
different SdrPaintWindow's without making changes ~everywhere.
Change-Id: Ifdfb623c8d6dd81700ec4a5dfeeb6b2391a96154
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/98166
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Dennis Francis <dennis.francis@collabora.com>
(cherry picked from commit 345f9480618d0867f6b42a83a7ae1d62c8ef9c0c)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/98161
Tested-by: Jenkins
Diffstat (limited to 'sc')
-rw-r--r-- | sc/source/ui/drawfunc/fusel.cxx | 3 | ||||
-rw-r--r-- | sc/source/ui/inc/viewdata.hxx | 1 | ||||
-rw-r--r-- | sc/source/ui/unoobj/docuno.cxx | 12 | ||||
-rw-r--r-- | sc/source/ui/view/drawview.cxx | 12 | ||||
-rw-r--r-- | sc/source/ui/view/gridwin4.cxx | 70 | ||||
-rw-r--r-- | sc/source/ui/view/tabvwsh2.cxx | 6 | ||||
-rw-r--r-- | sc/source/ui/view/viewdata.cxx | 15 |
7 files changed, 113 insertions, 6 deletions
diff --git a/sc/source/ui/drawfunc/fusel.cxx b/sc/source/ui/drawfunc/fusel.cxx index bb82aa3459bd..e3c306574a73 100644 --- a/sc/source/ui/drawfunc/fusel.cxx +++ b/sc/source/ui/drawfunc/fusel.cxx @@ -338,7 +338,8 @@ bool FuSelection::MouseButtonUp(const MouseEvent& rMEvt) } sal_uInt16 nDrgLog = sal_uInt16 ( pWindow->PixelToLogic(Size(SC_MINDRAGMOVE,0)).Width() ); - Point aPnt( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) ); + auto aLogicPosition = rMEvt.getLogicPosition(); + Point aPnt(aLogicPosition ? *aLogicPosition : pWindow->PixelToLogic(rMEvt.GetPosPixel())); bool bCopy = false; ScViewData& rViewData = rViewShell.GetViewData(); diff --git a/sc/source/ui/inc/viewdata.hxx b/sc/source/ui/inc/viewdata.hxx index 286330adeaee..ab4196a46e82 100644 --- a/sc/source/ui/inc/viewdata.hxx +++ b/sc/source/ui/inc/viewdata.hxx @@ -606,6 +606,7 @@ public: Point GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScVSplitPos eWhich ) const; /// returns the position (top-left corner) of the requested cell in print twips coordinates. Point GetPrintTwipsPos( SCCOL nCol, SCROW nRow ) const; + Point GetPrintTwipsPosFromTileTwips(const Point& rTileTwipsPos) const; /// return json for our cursor position. OString describeCellCursor() const { return describeCellCursorAt(GetCurX(), GetCurY()); } diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx index 4f02c69ae818..a3e3f8c603b4 100644 --- a/sc/source/ui/unoobj/docuno.cxx +++ b/sc/source/ui/unoobj/docuno.cxx @@ -915,12 +915,20 @@ void ScModelObj::setClientZoom(int nTilePixelWidth_, int nTilePixelHeight_, int if (!pViewData) return; - pViewData->SetZoom(Fraction(nTilePixelWidth_ * TWIPS_PER_PIXEL, nTileTwipWidth_), - Fraction(nTilePixelHeight_ * TWIPS_PER_PIXEL, nTileTwipHeight_), true); + const Fraction newZoomX(nTilePixelWidth_ * TWIPS_PER_PIXEL, nTileTwipWidth_); + const Fraction newZoomY(nTilePixelHeight_ * TWIPS_PER_PIXEL, nTileTwipHeight_); + + if (pViewData->GetZoomX() == newZoomX && pViewData->GetZoomY() == newZoomY) + return; + + pViewData->SetZoom(newZoomX, newZoomY, true); // refresh our view's take on other view's cursors & selections pViewData->GetActiveWin()->updateKitOtherCursors(); pViewData->GetActiveWin()->updateOtherKitSelections(); + + if (ScDrawView* pDrawView = pViewData->GetScDrawView()) + pDrawView->resetGridOffsetsForAllSdrPageViews(); } void ScModelObj::getRowColumnHeaders(const tools::Rectangle& rRectangle, tools::JsonWriter& rJsonWriter) diff --git a/sc/source/ui/view/drawview.cxx b/sc/source/ui/view/drawview.cxx index 3fe21ca5dd33..f15b6c57c310 100644 --- a/sc/source/ui/view/drawview.cxx +++ b/sc/source/ui/view/drawview.cxx @@ -997,6 +997,11 @@ bool ScDrawView::calculateGridOffsetForSdrObject( SdrObject& rSdrObject, basegfx::B2DVector& rTarget) const { + if (comphelper::LibreOfficeKit::isActive() && + !comphelper::LibreOfficeKit::isCompatFlagSet( + comphelper::LibreOfficeKit::Compat::scPrintTwipsMsgs)) + return false; + ScGridWindow* pGridWin(pViewData->GetActiveWin()); if(nullptr == pGridWin) @@ -1181,6 +1186,13 @@ namespace sdr::contact bool ObjectContactOfScDrawView::supportsGridOffsets() const { + // Except when scPrintTwipsMsgs flag is active, + // Calc in LOK mode directly sets pixel-aligned logical coordinates for draw-objects. + if (comphelper::LibreOfficeKit::isActive() && + !comphelper::LibreOfficeKit::isCompatFlagSet( + comphelper::LibreOfficeKit::Compat::scPrintTwipsMsgs)) + return false; + // no GridOffset support for printer if(isOutputToPrinter()) { diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx index eb76b69dd590..5054b8745889 100644 --- a/sc/source/ui/view/gridwin4.cxx +++ b/sc/source/ui/view/gridwin4.cxx @@ -35,6 +35,11 @@ #include <sfx2/lokhelper.hxx> #include <svx/svdview.hxx> +#include <svx/svdpagv.hxx> +#include <svx/sdrpagewindow.hxx> +#include <svx/sdr/contact/objectcontactofpageview.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <svx/sdr/contact/viewcontact.hxx> #include <tabvwsh.hxx> #include <gridwin.hxx> @@ -1247,6 +1252,63 @@ namespace nTopLeftTileIndex = nStartIndex; nBottomRightTileIndex = nEndIndex; } + + class ScLOKProxyObjectContact final : public sdr::contact::ObjectContactOfPageView + { + private: + sdr::contact::ObjectContact& mrRealObjectContact; + + public: + explicit ScLOKProxyObjectContact( + sdr::contact::ObjectContact& rRealOC, + SdrPageWindow& rPageWindow, + const sal_Char* pDebugName) : + ObjectContactOfPageView(rPageWindow, pDebugName), + mrRealObjectContact(rRealOC) + { + } + + virtual bool supportsGridOffsets() const override { return true; } + + virtual void calculateGridOffsetForViewOjectContact( + basegfx::B2DVector& rTarget, + const sdr::contact::ViewObjectContact& rClient) const override + { + SdrObject* pTargetSdrObject(rClient.GetViewContact().TryToGetSdrObject()); + if (pTargetSdrObject) + rTarget = pTargetSdrObject->GetViewContact().GetViewObjectContact(mrRealObjectContact).getGridOffset(); + } + }; + + class ScLOKDrawView : public FmFormView + { + public: + ScLOKDrawView(OutputDevice* pOut, ScViewData* pData) : + FmFormView(*pData->GetDocument()->GetDrawLayer(), pOut), + pScDrawView(pData ? pData->GetScDrawView() : nullptr) + { + } + + virtual sdr::contact::ObjectContact* createViewSpecificObjectContact( + SdrPageWindow& rPageWindow, const sal_Char* pDebugName) const override + { + if (!pScDrawView) + return SdrView::createViewSpecificObjectContact(rPageWindow, pDebugName); + + SdrPageView* pPageView(pScDrawView->GetSdrPageView()); + if (!pPageView) + return SdrView::createViewSpecificObjectContact(rPageWindow, pDebugName); + + SdrPageWindow* pSdrPageWindow = pPageView->GetPageWindow(0); + if (!pSdrPageWindow) + return SdrView::createViewSpecificObjectContact(rPageWindow, pDebugName); + + return new ScLOKProxyObjectContact(pSdrPageWindow->GetObjectContact(), rPageWindow, pDebugName); + } + + private: + ScDrawView* pScDrawView; + }; } // anonymous namespace void ScGridWindow::PaintTile( VirtualDevice& rDevice, @@ -1367,7 +1429,12 @@ void ScGridWindow::PaintTile( VirtualDevice& rDevice, ScDrawLayer* pModel = pDoc->GetDrawLayer(); if (pModel) { - mpLOKDrawView.reset( + bool bPrintTwipsMsgs = comphelper::LibreOfficeKit::isCompatFlagSet( + comphelper::LibreOfficeKit::Compat::scPrintTwipsMsgs); + mpLOKDrawView.reset(bPrintTwipsMsgs ? + new ScLOKDrawView( + &rDevice, + pViewData) : new FmFormView( *pModel, &rDevice)); @@ -1378,7 +1445,6 @@ void ScGridWindow::PaintTile( VirtualDevice& rDevice, // draw the content DrawContent(rDevice, aTabInfo, aOutputData, true); - rDevice.SetMapMode(aOriginalMode); // Flag drawn formula cells "unchanged". diff --git a/sc/source/ui/view/tabvwsh2.cxx b/sc/source/ui/view/tabvwsh2.cxx index cee19352fdd8..d2efc23d5559 100644 --- a/sc/source/ui/view/tabvwsh2.cxx +++ b/sc/source/ui/view/tabvwsh2.cxx @@ -330,7 +330,11 @@ void ScTabViewShell::ExecDraw(SfxRequest& rReq) } else { - aInsertPos = GetViewData().getLOKVisibleArea().Center(); + ScViewData& rViewData = GetViewData(); + aInsertPos = rViewData.getLOKVisibleArea().Center(); + if (comphelper::LibreOfficeKit::isCompatFlagSet( + comphelper::LibreOfficeKit::Compat::scPrintTwipsMsgs)) + aInsertPos = rViewData.GetPrintTwipsPosFromTileTwips(aInsertPos); aInsertPos.setX(sc::TwipsToHMM(aInsertPos.X())); aInsertPos.setY(sc::TwipsToHMM(aInsertPos.Y())); diff --git a/sc/source/ui/view/viewdata.cxx b/sc/source/ui/view/viewdata.cxx index 58ee76e99a1f..53839f2481f6 100644 --- a/sc/source/ui/view/viewdata.cxx +++ b/sc/source/ui/view/viewdata.cxx @@ -2436,6 +2436,21 @@ Point ScViewData::GetPrintTwipsPos(SCCOL nCol, SCROW nRow) const return Point(nPosX, nPosY); } +Point ScViewData::GetPrintTwipsPosFromTileTwips(const Point& rTileTwipsPos) const +{ + const long nPixelX = static_cast<long>(rTileTwipsPos.X() * nPPTX); + const long nPixelY = static_cast<long>(rTileTwipsPos.Y() * nPPTY); + SCCOL nCol = 0; + SCROW nRow = 0; + + // The following call (with bTestMerge = false) will not modify any members. + const_cast<ScViewData*>(this)->GetPosFromPixel(nPixelX, nPixelY, SC_SPLIT_TOPLEFT, nCol, nRow, false /* bTestMerge */); + const Point aPixCellPos = GetScrPos(nCol, nRow, SC_SPLIT_TOPLEFT, true /* bAllowNeg */); + const Point aTileTwipsCellPos(aPixCellPos.X() / nPPTX, aPixCellPos.Y() / nPPTY); + const Point aPrintTwipsCellPos = GetPrintTwipsPos(nCol, nRow); + return aPrintTwipsCellPos + (rTileTwipsPos - aTileTwipsCellPos); +} + OString ScViewData::describeCellCursorAt(SCCOL nX, SCROW nY, bool bPixelAligned) const { const bool bPosSizeInPixels = bPixelAligned; |