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 )

Reply via email to