include/sfx2/LokControlHandler.hxx | 70 ++++++++++++--- include/sfx2/viewsh.hxx | 4 include/vcl/DocWindow.hxx | 29 ++++++ include/vcl/IDialogRenderable.hxx | 6 + include/vcl/ctrl.hxx | 3 include/vcl/svapp.hxx | 2 include/vcl/window.hxx | 2 sc/source/ui/inc/gridwin.hxx | 3 sc/source/ui/view/gridwin.cxx | 2 sd/source/ui/inc/Window.hxx | 4 sd/source/ui/unoidl/unomodel.cxx | 28 +++++- sd/source/ui/view/sdwindow.cxx | 2 sfx2/source/view/viewsh.cxx | 5 + svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx | 6 + svx/source/svdraw/svdpntv.cxx | 3 sw/source/uibase/docvw/edtwin.cxx | 2 sw/source/uibase/inc/edtwin.hxx | 4 sw/source/uibase/uno/unotxdoc.cxx | 21 ++++ vcl/Library_vcl.mk | 1 vcl/source/app/svapp.cxx | 3 vcl/source/control/ctrl.cxx | 32 ++++++ vcl/source/window/DocWindow.cxx | 40 ++++++++ vcl/source/window/mouse.cxx | 24 ----- 23 files changed, 247 insertions(+), 49 deletions(-)
New commits: commit 4855dbf52bc3f371beef41561d271a9da362171b Author: Marco Cecchetti <marco.cecche...@collabora.com> AuthorDate: Sun Feb 5 17:47:34 2023 +0100 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Tue Feb 7 07:29:38 2023 +0000 lok: form controls: rendering and mouse event forwarding What we got - Most controls rendered on Writer and Impress (on Calc already implemented by Tomaž Vajngerl) - Text labels rendered correctly - Mouse events forwarded to controls - Control state changed on click for Writer and Calc - Control invalidation for all apps - Fixed broken LOK_CALLBACK_MOUSE_POINTER msg - Correct pointer style when mouse is hovering over a control Need to be improved - in impress click method for a control is not executed even if the mouse event is forwarded correctly - avoid not needed control invalidations (as the one occurring on document autosaving) Change-Id: I4d5012af7f90a2c726b6b6b5b068e2be1ed5568a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146569 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> diff --git a/include/sfx2/LokControlHandler.hxx b/include/sfx2/LokControlHandler.hxx index cb48e9eb355b..753585ac65c0 100644 --- a/include/sfx2/LokControlHandler.hxx +++ b/include/sfx2/LokControlHandler.hxx @@ -9,9 +9,13 @@ #pragma once +#include <LibreOfficeKit/LibreOfficeKitEnums.h> #include <sfx2/dllapi.h> +#include <sfx2/lokhelper.hxx> #include <svx/svdouno.hxx> -#include <vcl/window.hxx> +#include <svx/svditer.hxx> +#include <vcl/virdev.hxx> +#include <vcl/DocWindow.hxx> #include <com/sun/star/awt/PosSize.hpp> #include <com/sun/star/awt/XControl.hpp> #include <com/sun/star/awt/XWindow.hpp> @@ -19,14 +23,22 @@ #include <com/sun/star/awt/XGraphics.hpp> #include <com/sun/star/awt/XView.hpp> #include <toolkit/helper/vclunohelper.hxx> +#include <tools/UnitConversion.hxx> + +#include <sal/log.hxx> + +#include <optional> class LokControlHandler { public: static bool postMouseEvent(const SdrPage* pPage, const SdrView* pDrawView, - vcl::Window const& rMainWindow, int nType, Point aPointHmm, + vcl::DocWindow& rMainWindow, int nType, Point aPointHmm, int nCount, int nButtons, int nModifier) { + static std::optional<PointerStyle> eDocPointerStyle; + + o3tl::Length eControlUnitLength = MapToO3tlLength(rMainWindow.GetMapMode().GetMapUnit()); SdrObjListIter aIterator(pPage, SdrIterMode::Flat); while (aIterator.IsMore()) { @@ -34,7 +46,10 @@ public: SdrUnoObj* pUnoObect = dynamic_cast<SdrUnoObj*>(pObject); if (pUnoObect) { - tools::Rectangle aControlRectHMM = pUnoObect->GetLogicRect(); + tools::Rectangle aControlRect = pUnoObect->GetLogicRect(); + tools::Rectangle aControlRectHMM = o3tl::convert( + aControlRect, eControlUnitLength, o3tl::Length::mm100); + if (aControlRectHMM.Contains(aPointHmm)) { css::uno::Reference<css::awt::XControl> xControl @@ -52,6 +67,19 @@ public: VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow(xWindowPeer); if (pWindow) { + tools::Rectangle aControlRectPx = o3tl::convert( + aControlRectHMM, o3tl::Length::mm100, o3tl::Length::px); + // used by Control::LogicInvalidate + pWindow->SetPosPixel(aControlRectPx.TopLeft()); + + // when entering into control area save current pointer style + // and set pointer style to arrow + if (!eDocPointerStyle) + { + *eDocPointerStyle = rMainWindow.GetPointer(); + rMainWindow.SetPointer(pWindow->GetPointer()); + } + Point aControlRelativePositionHMM = aPointHmm - aControlRectHMM.TopLeft(); Point aControlRelativePosition = o3tl::convert( aControlRelativePositionHMM, o3tl::Length::mm100, o3tl::Length::px); @@ -59,13 +87,19 @@ public: LokMouseEventData aMouseEventData(nType, aControlRelativePosition, nCount, MouseEventModifiers::SIMPLECLICK, nButtons, nModifier); - SfxLokHelper::postMouseEventAsync(pWindow, aMouseEventData); return true; } } } } + + // when exiting from control area restore document pointer style + if (eDocPointerStyle) + { + rMainWindow.SetPointer(*eDocPointerStyle); + eDocPointerStyle.reset(); + } return false; } @@ -90,17 +124,27 @@ public: if (!xControlView.is()) return; - tools::Rectangle aObjectRectHMM = pUnoObect->GetLogicRect(); + o3tl::Length eControlUnitLength = MapToO3tlLength(rMainWindow.GetMapMode().GetMapUnit()); + tools::Rectangle aControlRect = pUnoObect->GetLogicRect(); + tools::Rectangle aObjectRectHMM = o3tl::convert( + aControlRect, eControlUnitLength, o3tl::Length::mm100); + tools::Rectangle aControltRectPx = o3tl::convert( + aObjectRectHMM, o3tl::Length::mm100, o3tl::Length::px); + Point aOffsetFromTile(aObjectRectHMM.Left() - rTileRectHMM.Left(), aObjectRectHMM.Top() - rTileRectHMM.Top()); tools::Rectangle aRectangleHMM(aOffsetFromTile, aObjectRectHMM.GetSize()); tools::Rectangle aRectanglePx = o3tl::convert(aRectangleHMM, o3tl::Length::mm100, o3tl::Length::px); - xControlWindow->setPosSize(0, 0, aRectanglePx.GetWidth(), aRectanglePx.GetHeight(), - css::awt::PosSize::POSSIZE); + xControlWindow->setPosSize( + aControltRectPx.Left(), aControltRectPx.Top(), + aRectanglePx.GetWidth(), aRectanglePx.GetHeight(), + css::awt::PosSize::POSSIZE); xControlView->setGraphics(xGraphics); + // required for getting text label rendered with the correct scale + xControlView->setZoom(1,1); xControlView->draw(aRectanglePx.Left() * scaleX, aRectanglePx.Top() * scaleY); } @@ -118,13 +162,15 @@ public: rDevice.Push(vcl::PushFlags::MAPMODE); MapMode aDeviceMapMode(rDevice.GetMapMode()); - const Fraction scale = conversionFract(o3tl::Length::px, o3tl::Length::mm100); - Fraction scaleX = Fraction(aOutputSize.Width(), aTileRectHMM.GetWidth()) * scale; - Fraction scaleY = Fraction(aOutputSize.Height(), aTileRectHMM.GetHeight()) * scale; + const Fraction scale = conversionFract(o3tl::Length::px, o3tl::Length::twip); + Fraction scaleX = Fraction(aOutputSize.Width(), rTileRect.GetWidth()) * scale; + Fraction scaleY = Fraction(aOutputSize.Height(), rTileRect.GetHeight()) * scale; aDeviceMapMode.SetScaleX(scaleX); aDeviceMapMode.SetScaleY(scaleY); + aDeviceMapMode.SetMapUnit(MapUnit::MapPixel); rDevice.SetMapMode(aDeviceMapMode); + o3tl::Length eControlUnitLength = MapToO3tlLength(rMainWindow.GetMapMode().GetMapUnit()); SdrObjListIter aIterator(pPage, SdrIterMode::Flat); while (aIterator.IsMore()) @@ -133,7 +179,9 @@ public: SdrUnoObj* pUnoObect = dynamic_cast<SdrUnoObj*>(pObject); if (pUnoObect) { - tools::Rectangle aObjectRectHMM = pUnoObect->GetLogicRect(); + tools::Rectangle aControlRect = pUnoObect->GetLogicRect(); + tools::Rectangle aObjectRectHMM = o3tl::convert( + aControlRect, eControlUnitLength, o3tl::Length::mm100); // Check if we intersect with the tile rectangle and we // need to draw the control. diff --git a/include/sfx2/viewsh.hxx b/include/sfx2/viewsh.hxx index 1fd0ca894f58..9944b44cbb04 100644 --- a/include/sfx2/viewsh.hxx +++ b/include/sfx2/viewsh.hxx @@ -71,7 +71,7 @@ namespace com::sun::star::frame { class XModel; } namespace com::sun::star::ui { class XContextMenuInterceptor; } namespace com::sun::star::ui { struct ContextMenuExecuteEvent; } namespace com::sun::star::view { class XRenderable; } - +namespace tools { class Rectangle; } enum class SfxPrinterChangeFlags { @@ -383,6 +383,8 @@ public: /// Get the DocId used by Mobile LOKit to load multiple documents. ViewShellDocId GetDocId() const override; + /// ILibreOfficeKitNotifier. Emits a LOK_CALLBACK_INVALIDATE_TILES. + virtual void notifyInvalidation(tools::Rectangle const *) const override; /// See OutlinerViewShell::NotifyOtherViews(). void NotifyOtherViews(int nType, const OString& rKey, const OString& rPayload) override; /// See OutlinerViewShell::NotifyOtherView(). diff --git a/include/vcl/DocWindow.hxx b/include/vcl/DocWindow.hxx new file mode 100644 index 000000000000..3153a0a6f4d3 --- /dev/null +++ b/include/vcl/DocWindow.hxx @@ -0,0 +1,29 @@ +/* -*- 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/. + * + */ + +#ifndef INCLUDED_VCL_DOCWINDOW_HXX +#define INCLUDED_VCL_DOCWINDOW_HXX + +#include <vcl/window.hxx> + +namespace vcl +{ +class VCL_DLLPUBLIC DocWindow : public Window +{ + // inherit all Window constructors + using Window::Window; +public: + virtual void SetPointer( PointerStyle ) override; +}; +} // namespace vcl + +#endif // INCLUDED_VCL_DOCWINDOW_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/vcl/IDialogRenderable.hxx b/include/vcl/IDialogRenderable.hxx index bb5480f1bf4f..d280aad3f006 100644 --- a/include/vcl/IDialogRenderable.hxx +++ b/include/vcl/IDialogRenderable.hxx @@ -13,11 +13,12 @@ #include <config_options.h> #include <vcl/dllapi.h> - #include <rtl/ustring.hxx> #include <vector> +namespace tools { class Rectangle; } + class SfxItemSet; namespace vcl @@ -38,6 +39,9 @@ public: const std::vector<LOKPayloadItem>& rPayload = std::vector<LOKPayloadItem>()) const = 0; virtual void libreOfficeKitViewCallback(int nType, const char* pPayload) const = 0; + + /// Emits a LOK_CALLBACK_INVALIDATE_TILES. + virtual void notifyInvalidation(tools::Rectangle const *) const = 0; }; } // namespace vcl diff --git a/include/vcl/ctrl.hxx b/include/vcl/ctrl.hxx index 17c40ae66067..c59d7e4d0d2b 100644 --- a/include/vcl/ctrl.hxx +++ b/include/vcl/ctrl.hxx @@ -228,6 +228,9 @@ public: vcl::Font GetUnzoomedControlPointFont() const; void SetShowAccelerator (bool val); + + /// Notify the LOK client about an invalidated area. + virtual void LogicInvalidate( const tools::Rectangle* pRectangle ) override; }; #endif // INCLUDED_VCL_CTRL_HXX diff --git a/include/vcl/svapp.hxx b/include/vcl/svapp.hxx index d2c0113ea422..2ca0b06fb50f 100644 --- a/include/vcl/svapp.hxx +++ b/include/vcl/svapp.hxx @@ -1341,6 +1341,8 @@ public: const OUString& rAction, const std::vector<vcl::LOKPayloadItem>& rPayload = std::vector<vcl::LOKPayloadItem>()) const override; virtual void libreOfficeKitViewCallback(int nType, const char* pPayload) const override; + virtual void notifyInvalidation(tools::Rectangle const *) const override; + private: DECL_DLLPRIVATE_STATIC_LINK( Application, PostEventHandler, void*, void ); diff --git a/include/vcl/window.hxx b/include/vcl/window.hxx index 1d18d521b347..14594b672f26 100644 --- a/include/vcl/window.hxx +++ b/include/vcl/window.hxx @@ -1017,7 +1017,7 @@ public: void ReleaseMouse(); bool IsMouseCaptured() const; - void SetPointer( PointerStyle ); + virtual void SetPointer( PointerStyle ); PointerStyle GetPointer() const; void EnableChildPointerOverwrite( bool bOverwrite ); void SetPointerPosPixel( const Point& rPos ); diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx index afdbb7222c35..b9bd9184e18b 100644 --- a/sc/source/ui/inc/gridwin.hxx +++ b/sc/source/ui/inc/gridwin.hxx @@ -19,6 +19,7 @@ #pragma once +#include <vcl/DocWindow.hxx> #include <vcl/transfer.hxx> #include "viewutil.hxx" #include "viewdata.hxx" @@ -84,7 +85,7 @@ namespace sdr::overlay { class OverlayObjectList; } class ScFilterListBox; -class SAL_DLLPUBLIC_RTTI ScGridWindow : public vcl::Window, public DropTargetHelper, public DragSourceHelper +class SAL_DLLPUBLIC_RTTI ScGridWindow : public vcl::DocWindow, public DropTargetHelper, public DragSourceHelper { // ScFilterListBox is always used for selection list friend class ScFilterListBox; diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index 540dce9ba6cf..e5e384fbdd23 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -347,7 +347,7 @@ static bool lcl_GetHyperlinkCell( // WB_DIALOGCONTROL needed for UNO-Controls ScGridWindow::ScGridWindow( vcl::Window* pParent, ScViewData& rData, ScSplitPos eWhichPos ) -: Window( pParent, WB_CLIPCHILDREN | WB_DIALOGCONTROL ), +: DocWindow( pParent, WB_CLIPCHILDREN | WB_DIALOGCONTROL ), DropTargetHelper( this ), DragSourceHelper( this ), maVisibleRange(rData.GetDocument()), diff --git a/sd/source/ui/inc/Window.hxx b/sd/source/ui/inc/Window.hxx index 0464ad32e19e..9763f24e8895 100644 --- a/sd/source/ui/inc/Window.hxx +++ b/sd/source/ui/inc/Window.hxx @@ -21,7 +21,7 @@ #include <tools/gen.hxx> #include <tools/long.hxx> -#include <vcl/window.hxx> +#include <vcl/DocWindow.hxx> #include <vcl/transfer.hxx> class OutlinerView; @@ -41,7 +41,7 @@ class ViewShell; member of the <type>OutputDevice</type> base class. It is calculated to be an integer percent value. */ -class Window : public vcl::Window, public ::DropTargetHelper +class Window : public vcl::DocWindow, public ::DropTargetHelper { public: Window(vcl::Window* pParent); diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx index 9bc5d2667fae..8e02660f628f 100644 --- a/sd/source/ui/unoidl/unomodel.cxx +++ b/sd/source/ui/unoidl/unomodel.cxx @@ -121,6 +121,7 @@ #include <drawinglayer/primitive2d/structuretagprimitive2d.hxx> #include <sfx2/lokcomponenthelpers.hxx> +#include <sfx2/LokControlHandler.hxx> #include <tools/gen.hxx> #include <tools/debug.hxx> #include <tools/diagnose_ex.h> @@ -2220,6 +2221,9 @@ void SdXImpressDocument::paintTile( VirtualDevice& rDevice, if (!pViewSh) return; + // we need to skip tile invalidation for controls on rendering + comphelper::LibreOfficeKit::setTiledPainting(true); + // Setup drawing layer to work properly. Since we use a custom VirtualDevice // for the drawing, SdrPaintView::BeginCompleteRedraw() will call FindPaintWindow() // unsuccessfully and use a temporary window that doesn't keep state. So patch @@ -2288,6 +2292,17 @@ void SdXImpressDocument::paintTile( VirtualDevice& rDevice, if(patchedPageWindow != nullptr) patchedPageWindow->unpatchPaintWindow(previousPaintWindow); + + // Draw Form controls + SdrView* pDrawView = pViewSh->GetDrawView(); + SdrPageView* pPageView = pDrawView->GetSdrPageView(); + SdrPage* pPage = pPageView->GetPage(); + ::sd::Window* pActiveWin = pViewSh->GetActiveWindow(); + ::tools::Rectangle aTileRect(Point(nTilePosX, nTilePosY), Size(nTileWidth, nTileHeight)); + Size aOutputSize(nOutputWidth, nOutputHeight); + LokControlHandler::paintControlTile(pPage, pDrawView, *pActiveWin, rDevice, aOutputSize, aTileRect); + + comphelper::LibreOfficeKit::setTiledPainting(false); } void SdXImpressDocument::selectPart(int nPart, int nSelect) @@ -2590,8 +2605,17 @@ void SdXImpressDocument::postMouseEvent(int nType, int nX, int nY, int nCount, i pViewShell->GetViewShell(), nType, nX, nY, nCount, nButtons, nModifier, fScale, fScale)) return; - const Point aPos(Point(convertTwipToMm100(nX), convertTwipToMm100(nY))); - LokMouseEventData aMouseEventData(nType, aPos, nCount, MouseEventModifiers::SIMPLECLICK, + // try to forward mouse event to control + const Point aPointTwip(nX, nY); + const Point aPointHMM = o3tl::convert(aPointTwip, o3tl::Length::twip, o3tl::Length::mm100); + SdrView* pDrawView = pViewShell->GetDrawView(); + SdrPageView* pPageView = pDrawView->GetSdrPageView(); + SdrPage* pPage = pPageView->GetPage(); + ::sd::Window* pActiveWin = pViewShell->GetActiveWindow(); + if (LokControlHandler::postMouseEvent(pPage, pDrawView, *pActiveWin, nType, aPointHMM, nCount, nButtons, nModifier)) + return; + + LokMouseEventData aMouseEventData(nType, aPointHMM, nCount, MouseEventModifiers::SIMPLECLICK, nButtons, nModifier); SfxLokHelper::postMouseEventAsync(pViewShell->GetActiveWindow(), aMouseEventData); } diff --git a/sd/source/ui/view/sdwindow.cxx b/sd/source/ui/view/sdwindow.cxx index 1ccd7461d7bc..6d5481318e8e 100644 --- a/sd/source/ui/view/sdwindow.cxx +++ b/sd/source/ui/view/sdwindow.cxx @@ -60,7 +60,7 @@ namespace sd { #define MAX_ZOOM 3000 ///< maximal zoom factor Window::Window(vcl::Window* pParent) - : vcl::Window(pParent, WinBits(WB_CLIPCHILDREN | WB_DIALOGCONTROL)), + : vcl::DocWindow(pParent, WinBits(WB_CLIPCHILDREN | WB_DIALOGCONTROL)), DropTargetHelper( this ), maWinPos(0, 0), // precautionary; but the values should be set maViewOrigin(0, 0), // again from the owner of the window diff --git a/sfx2/source/view/viewsh.cxx b/sfx2/source/view/viewsh.cxx index 85cebbdd5c8b..28b133174aef 100644 --- a/sfx2/source/view/viewsh.cxx +++ b/sfx2/source/view/viewsh.cxx @@ -1642,6 +1642,11 @@ ViewShellDocId SfxViewShell::GetDocId() const return pImpl->m_nDocId; } +void SfxViewShell::notifyInvalidation(tools::Rectangle const* pRect) const +{ + SfxLokHelper::notifyInvalidation(this, pRect); +} + void SfxViewShell::NotifyOtherViews(int nType, const OString& rKey, const OString& rPayload) { SfxLokHelper::notifyOtherViews(this, nType, rKey, rPayload); diff --git a/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx b/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx index 4f186b4d9072..e22545e00b1f 100644 --- a/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx +++ b/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx @@ -43,6 +43,8 @@ #include <com/sun/star/container/XContainerListener.hpp> #include <com/sun/star/container/XContainer.hpp> +#include <comphelper/lok.hxx> + #include <vcl/canvastools.hxx> #include <vcl/svapp.hxx> #include <vcl/window.hxx> @@ -276,6 +278,10 @@ namespace sdr::contact { static void adjustControlGeometry_throw( const ControlHolder& _rControl, const tools::Rectangle& _rLogicBoundingRect, const basegfx::B2DHomMatrix& _rViewTransformation, const ::basegfx::B2DHomMatrix& _rZoomLevelNormalization ) { + // In the LOK case, control geometry is handled by LokControlHandler + if (comphelper::LibreOfficeKit::isActive()) + return; + OSL_PRECOND( _rControl.is(), "UnoControlContactHelper::adjustControlGeometry_throw: illegal control!" ); if ( !_rControl.is() ) return; diff --git a/svx/source/svdraw/svdpntv.cxx b/svx/source/svdraw/svdpntv.cxx index 310c024c1972..3f080ecc972c 100644 --- a/svx/source/svdraw/svdpntv.cxx +++ b/svx/source/svdraw/svdpntv.cxx @@ -631,7 +631,8 @@ void SdrPaintView::EndCompleteRedraw(SdrPaintWindow& rPaintWindow, bool bPaintFo { // draw postprocessing, only for known devices // it is necessary to always paint FormLayer - if(bPaintFormLayer) + // In the LOK case control rendering is performed through LokControlHandler + if(!comphelper::LibreOfficeKit::isActive() && bPaintFormLayer) { ImpFormLayerDrawing(rPaintWindow); } diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx index 595fcb391653..4eede8fb0755 100644 --- a/sw/source/uibase/docvw/edtwin.cxx +++ b/sw/source/uibase/docvw/edtwin.cxx @@ -5259,7 +5259,7 @@ void SwEditWin::SetApplyTemplate(const SwApplyTemplate &rTempl) * Ctor */ SwEditWin::SwEditWin(vcl::Window *pParent, SwView &rMyView): - Window(pParent, WinBits(WB_CLIPCHILDREN | WB_DIALOGCONTROL)), + DocWindow(pParent, WinBits(WB_CLIPCHILDREN | WB_DIALOGCONTROL)), DropTargetHelper( this ), DragSourceHelper( this ), diff --git a/sw/source/uibase/inc/edtwin.hxx b/sw/source/uibase/inc/edtwin.hxx index f3361eca3846..56d0bc57815c 100644 --- a/sw/source/uibase/inc/edtwin.hxx +++ b/sw/source/uibase/inc/edtwin.hxx @@ -24,7 +24,7 @@ #include <svx/svdobj.hxx> #include <tools/link.hxx> #include <vcl/timer.hxx> -#include <vcl/window.hxx> +#include <vcl/DocWindow.hxx> #include <vcl/transfer.hxx> #include <swevent.hxx> #include <swtypes.hxx> @@ -56,7 +56,7 @@ class SwTextFrame; To translate the pixel positions from the buffer OutputDevice to the real pixel positions, use the PixelToLogic methods of this class. */ -class SW_DLLPUBLIC SwEditWin final : public vcl::Window, +class SW_DLLPUBLIC SwEditWin final : public vcl::DocWindow, public DropTargetHelper, public DragSourceHelper { static QuickHelpData* m_pQuickHlpData; diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx index 78af58de3184..8deb51ad0e3f 100644 --- a/sw/source/uibase/uno/unotxdoc.cxx +++ b/sw/source/uibase/uno/unotxdoc.cxx @@ -30,6 +30,7 @@ #include <sfx2/bindings.hxx> #include <sfx2/viewfrm.hxx> #include <sfx2/lokhelper.hxx> +#include <sfx2/LokControlHandler.hxx> #include <sfx2/docfile.hxx> #include <sfx2/printer.hxx> #include <toolkit/helper/vclunohelper.hxx> @@ -3109,6 +3110,17 @@ void SwXTextDocument::paintTile( VirtualDevice &rDevice, LokChartHelper::PaintAllChartsOnTile(rDevice, nOutputWidth, nOutputHeight, nTilePosX, nTilePosY, nTileWidth, nTileHeight); + + // Draw Form controls + comphelper::LibreOfficeKit::setTiledPainting(true); + SwDrawModel* pDrawLayer = m_pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel(); + SdrPage* pPage = pDrawLayer->GetPage(sal_uInt16(0)); + SdrView* pDrawView = pViewShell->GetDrawView(); + SwEditWin& rEditWin = m_pDocShell->GetView()->GetEditWin(); + tools::Rectangle aTileRect(Point(nTilePosX, nTilePosY), Size(nTileWidth, nTileHeight)); + Size aOutputSize(nOutputWidth, nOutputHeight); + LokControlHandler::paintControlTile(pPage, pDrawView, rEditWin, rDevice, aOutputSize, aTileRect); + comphelper::LibreOfficeKit::setTiledPainting(false); } Size SwXTextDocument::getDocumentSize() @@ -3664,7 +3676,16 @@ void SwXTextDocument::postMouseEvent(int nType, int nX, int nY, int nCount, int m_pDocShell->GetView(), nType, nX, nY, nCount, nButtons, nModifier, fScale, fScale)) return; + // try to forward mouse event to controls + SwDrawModel* pDrawLayer = m_pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel(); + SdrPage* pPage = pDrawLayer->GetPage(sal_uInt16(0)); + SdrView* pDrawView = pWrtViewShell->GetDrawView(); SwEditWin& rEditWin = m_pDocShell->GetView()->GetEditWin(); + Point aPointTwip(nX, nY); + Point aPointHMMDraw = o3tl::convert(aPointTwip, o3tl::Length::twip, o3tl::Length::mm100); + if (LokControlHandler::postMouseEvent(pPage, pDrawView, rEditWin, nType, aPointHMMDraw, nCount, nButtons, nModifier)) + return; + LokMouseEventData aMouseEventData(nType, Point(nX, nY), nCount, MouseEventModifiers::SIMPLECLICK, nButtons, nModifier); diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index 25f6a0ef9562..ef13c2ac03f8 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -132,6 +132,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/window/dockingarea \ vcl/source/window/dockmgr \ vcl/source/window/dockwin \ + vcl/source/window/DocWindow \ vcl/source/window/event \ vcl/source/window/floatwin \ vcl/source/window/introwin \ diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx index 3579787cacf8..89cb5b61f8ef 100644 --- a/vcl/source/app/svapp.cxx +++ b/vcl/source/app/svapp.cxx @@ -332,6 +332,9 @@ void Application::libreOfficeKitViewCallback(int nType, const char* pPayload) co } } +void Application::notifyInvalidation(tools::Rectangle const* /*pRect*/) const +{ +} namespace { diff --git a/vcl/source/control/ctrl.cxx b/vcl/source/control/ctrl.cxx index aa157c146c0e..689b02f80d79 100644 --- a/vcl/source/control/ctrl.cxx +++ b/vcl/source/control/ctrl.cxx @@ -17,12 +17,15 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ + +#include <comphelper/lok.hxx> #include <vcl/svapp.hxx> #include <vcl/event.hxx> #include <vcl/ctrl.hxx> #include <vcl/decoview.hxx> #include <vcl/settings.hxx> #include <vcl/uitest/logger.hxx> +#include <vcl/DocWindow.hxx> #include <sal/log.hxx> #include <textlayout.hxx> @@ -486,4 +489,33 @@ Control::GetUnzoomedControlPointFont() const return aFont; } +void Control::LogicInvalidate(const tools::Rectangle* pRectangle) +{ + // avoid endless paint/invalidate loop in Impress + if (comphelper::LibreOfficeKit::isTiledPainting()) + return; + + VclPtr<vcl::Window> pParent = GetParentWithLOKNotifier(); + if (!pParent) + return; + + // invalidate only controls that belong to a DocWindow + if (!dynamic_cast<vcl::DocWindow*>(GetParent())) + return; + + tools::Rectangle aResultRectangle; + if (!pRectangle) + { + // we have to invalidate the whole control area not the whole document + aResultRectangle = tools::Rectangle(GetPosPixel(), GetSizePixel()); + } + else + { + aResultRectangle = *pRectangle; + } + + aResultRectangle = PixelToLogic(aResultRectangle, MapMode(MapUnit::MapTwip)); + pParent->GetLOKNotifier()->notifyInvalidation(&aResultRectangle); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/window/DocWindow.cxx b/vcl/source/window/DocWindow.cxx new file mode 100644 index 000000000000..92c6f9f9ecad --- /dev/null +++ b/vcl/source/window/DocWindow.cxx @@ -0,0 +1,40 @@ +/* -*- 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/. + */ + +#include <LibreOfficeKit/LibreOfficeKitEnums.h> + +#include <sal/log.hxx> +#include <vcl/DocWindow.hxx> +#include <vcl/ITiledRenderable.hxx> + + +namespace vcl +{ +void DocWindow::SetPointer( PointerStyle nPointer ) +{ + Window::SetPointer(nPointer); + + VclPtr<vcl::Window> pWin = GetParentWithLOKNotifier(); + if (!pWin) + return; + + PointerStyle aPointer = GetPointer(); + // We don't map all possible pointers hence we need a default + OString aPointerString = "default"; + auto aIt = vcl::gaLOKPointerMap.find(aPointer); + if (aIt != vcl::gaLOKPointerMap.end()) + { + aPointerString = aIt->second; + } + + pWin->GetLOKNotifier()->libreOfficeKitViewCallback(LOK_CALLBACK_MOUSE_POINTER, aPointerString.getStr()); +} +} // namespace vcl + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/window/mouse.cxx b/vcl/source/window/mouse.cxx index c77391f8393a..ae58d7eb63f1 100644 --- a/vcl/source/window/mouse.cxx +++ b/vcl/source/window/mouse.cxx @@ -492,30 +492,6 @@ void Window::SetPointer( PointerStyle nPointer ) // possibly immediately move pointer if ( !mpWindowImpl->mpFrameData->mbInMouseMove && ImplTestMousePointerSet() ) mpWindowImpl->mpFrame->SetPointer( ImplGetMousePointer() ); - - VclPtr<vcl::Window> pWin = GetParentWithLOKNotifier(); - if (!pWin) - return; - - PointerStyle aPointer = GetPointer(); - // We don't map all possible pointers hence we need a default - OString aPointerString = "default"; - auto aIt = vcl::gaLOKPointerMap.find(aPointer); - if (aIt != vcl::gaLOKPointerMap.end()) - { - aPointerString = aIt->second; - } - - // issue mouse pointer events only for document windows - // Doc windows' immediate parent SfxFrameViewWindow_Impl is the one with - // parent notifier set during initialization - if ((ImplGetFrameData()->mbDragging && - ImplGetFrameData()->mpMouseDownWin == this) || - (GetParent()->ImplGetWindowImpl()->mbLOKParentNotifier && - GetParent()->ImplGetWindowImpl()->mnLOKWindowId == 0)) - { - pWin->GetLOKNotifier()->libreOfficeKitViewCallback(LOK_CALLBACK_MOUSE_POINTER, aPointerString.getStr()); - } } void Window::EnableChildPointerOverwrite( bool bOverwrite )