From ed5640d8b587fbcfed7dd7967f3de04b37a76f26 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 11:06:44 +0200 Subject: Adding upstream version 4:7.4.7. Signed-off-by: Daniel Baumann --- sfx2/source/view/lokstarmathhelper.cxx | 174 +++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 sfx2/source/view/lokstarmathhelper.cxx (limited to 'sfx2/source/view/lokstarmathhelper.cxx') diff --git a/sfx2/source/view/lokstarmathhelper.cxx b/sfx2/source/view/lokstarmathhelper.cxx new file mode 100644 index 000000000..9df487595 --- /dev/null +++ b/sfx2/source/view/lokstarmathhelper.cxx @@ -0,0 +1,174 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +css::uno::Reference& LokStarMathHelper::GetXController() +{ + if (!mxController && mpViewShell) + { + if (const SfxInPlaceClient* pIPClient = mpViewShell->GetIPClient()) + { + if (const auto& xEmbObj = pIPClient->GetObject()) + { + css::uno::Reference xComp(xEmbObj->getComponent(), + css::uno::UNO_QUERY); + if (xComp && xComp->supportsService("com.sun.star.formula.FormulaProperties")) + if (css::uno::Reference xModel{ xComp, + css::uno::UNO_QUERY }) + mxController = xModel->getCurrentController(); + } + } + } + + return mxController; +} + +namespace +{ +// Find a child SmGraphicWindow* +vcl::Window* FindSmGraphicWindow(vcl::Window* pWin) +{ + if (!pWin) + return nullptr; + + if (pWin->IsStarMath()) + return pWin; + + pWin = pWin->GetWindow(GetWindowType::FirstChild); + while (pWin) + { + if (vcl::Window* pSmGraphicWindow = FindSmGraphicWindow(pWin)) + return pSmGraphicWindow; + pWin = pWin->GetWindow(GetWindowType::Next); + } + return nullptr; +} + +// Find a child window that corresponds to SmGraphicWidget +vcl::Window* FindChildSmGraphicWidgetWindow(vcl::Window* pWin) +{ + if (!pWin) + return nullptr; + + // The needed window is a VclDrawingArea + if (dynamic_cast(pWin)) + return pWin; + + pWin = pWin->GetWindow(GetWindowType::FirstChild); + while (pWin) + { + if (vcl::Window* pSmGraphicWidgetWindow = FindChildSmGraphicWidgetWindow(pWin)) + return pSmGraphicWidgetWindow; + pWin = pWin->GetWindow(GetWindowType::Next); + } + return nullptr; +} +} + +vcl::Window* LokStarMathHelper::GetGraphicWindow() +{ + if (!mpGraphicWindow) + { + if (const css::uno::Reference& xController = GetXController()) + { + if (const css::uno::Reference xFrame = xController->getFrame()) + { + css::uno::Reference xDockerWin = xFrame->getContainerWindow(); + mpGraphicWindow.set(FindSmGraphicWindow(VCLUnoHelper::GetWindow(xDockerWin))); + } + } + } + + return mpGraphicWindow.get(); +} + +vcl::Window* LokStarMathHelper::GetWidgetWindow() +{ + if (!mpWidgetWindow) + mpWidgetWindow.set(FindChildSmGraphicWidgetWindow(GetGraphicWindow())); + + return mpWidgetWindow.get(); +} + +tools::Rectangle LokStarMathHelper::GetBoundingBox() +{ + if (mpViewShell) + { + if (SfxInPlaceClient* pIPClient = mpViewShell->GetIPClient()) + { + if (vcl::Window* pRootWin = pIPClient->GetEditWin()) + { + if (vcl::Window* pWindow = GetWidgetWindow()) + { + // In all cases, the following code fragment + // returns the bounding box in twips. + // Note: the correct mapmode (representing document zoom) is provided by + // GraphicWindow, not WidgetWindow + const MapMode& aMapMode = GetGraphicWindow()->GetMapMode(); + const auto & [ m, d ] + = o3tl::getConversionMulDiv(o3tl::Length::px, o3tl::Length::twip); + const Fraction& scaleX = aMapMode.GetScaleX(); + const Fraction& scaleY = aMapMode.GetScaleY(); + const auto nXNum = m * scaleX.GetDenominator(); + const auto nXDen = d * scaleX.GetNumerator(); + const auto nYNum = m * scaleY.GetDenominator(); + const auto nYDen = d * scaleY.GetNumerator(); + + Point aOffset + = pWindow->GetOffsetPixelFrom(*pRootWin).scale(nXNum, nXDen, nYNum, nYDen); + Size aSize = pWindow->GetSizePixel().scale(nXNum, nXDen, nYNum, nYDen); + return { aOffset, aSize }; + } + } + } + } + return {}; +} + +bool LokStarMathHelper::postMouseEvent(int nType, int nX, int nY, int nCount, int nButtons, + int nModifier, double fScaleX, double fScaleY) +{ + if (vcl::Window* pWindow = GetWidgetWindow()) + { + Point aMousePos(nX, nY); + tools::Rectangle rBBox = GetBoundingBox(); + if (rBBox.Contains(aMousePos)) + { + int nWinX = nX - rBBox.Left(); + int nWinY = nY - rBBox.Top(); + + // window expects pixels, but the conversion factor + // can depend on the client zoom + Point aPos(nWinX * fScaleX, nWinY * fScaleY); + + LokMouseEventData aMouseEventData(nType, aPos, nCount, MouseEventModifiers::SIMPLECLICK, + nButtons, nModifier); + SfxLokHelper::postMouseEventAsync(pWindow, aMouseEventData); + + return true; + } + } + return false; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ -- cgit v1.2.3