summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Cecchetti <marco.cecchetti@collabora.com>2023-02-05 17:47:34 +0100
committerMarco Cecchetti <marco.cecchetti@collabora.com>2023-03-07 19:30:11 +0000
commit7adfecb0f5947ae258226c8d1652546f81577026 (patch)
tree722ef84394ffe68f635945d4fc3ebc48e5b0e122
parentc596fd59dc75823002bdfd3676d600a56e3bfb5e (diff)
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 <jenkinscollaboraoffice@gmail.com> Reviewed-by: Tomaž Vajngerl <quikee@gmail.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147320 Tested-by: Jenkins Reviewed-by: Marco Cecchetti <marco.cecchetti@collabora.com>
-rw-r--r--include/sfx2/LokControlHandler.hxx70
-rw-r--r--include/sfx2/viewsh.hxx4
-rw-r--r--include/vcl/DocWindow.hxx30
-rw-r--r--include/vcl/IDialogRenderable.hxx6
-rw-r--r--include/vcl/ctrl.hxx3
-rw-r--r--include/vcl/svapp.hxx2
-rw-r--r--include/vcl/window.hxx2
-rw-r--r--sc/source/ui/inc/gridwin.hxx3
-rw-r--r--sc/source/ui/view/gridwin.cxx2
-rw-r--r--sd/source/ui/inc/Window.hxx4
-rw-r--r--sd/source/ui/unoidl/unomodel.cxx28
-rw-r--r--sd/source/ui/view/sdwindow.cxx2
-rw-r--r--sfx2/source/view/viewsh.cxx5
-rw-r--r--svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx7
-rw-r--r--svx/source/svdraw/svdpntv.cxx3
-rw-r--r--sw/source/uibase/docvw/edtwin.cxx2
-rw-r--r--sw/source/uibase/inc/edtwin.hxx4
-rw-r--r--sw/source/uibase/uno/unotxdoc.cxx21
-rw-r--r--vcl/Library_vcl.mk1
-rw-r--r--vcl/source/app/svapp.cxx3
-rw-r--r--vcl/source/control/ctrl.cxx31
-rw-r--r--vcl/source/window/DocWindow.cxx40
-rw-r--r--vcl/source/window/mouse.cxx24
23 files changed, 245 insertions, 52 deletions
diff --git a/include/sfx2/LokControlHandler.hxx b/include/sfx2/LokControlHandler.hxx
index c422afc979cc..dc69787456e5 100644
--- a/include/sfx2/LokControlHandler.hxx
+++ b/include/sfx2/LokControlHandler.hxx
@@ -9,12 +9,13 @@
#pragma once
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
+#include <sfx2/dllapi.h>
#include <sfx2/lokhelper.hxx>
-#include <svx/svditer.hxx>
#include <svx/svdouno.hxx>
-#include <tools/UnitConversion.hxx>
+#include <svx/svditer.hxx>
#include <vcl/virdev.hxx>
-#include <vcl/window.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>
@@ -22,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,
- int nCount, int nButtons, int nModifier)
+ 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())
{
@@ -37,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
@@ -55,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);
@@ -62,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;
}
@@ -93,17 +124,26 @@ 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(),
+ 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);
}
@@ -121,13 +161,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())
@@ -136,7 +178,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 0465fd036d4b..de24ef3ef3c1 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
{
@@ -404,6 +404,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..681ad110410d
--- /dev/null
+++ b/include/vcl/DocWindow.hxx
@@ -0,0 +1,30 @@
+/* -*- 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 6300e27a747a..c71105731cb1 100644
--- a/include/vcl/ctrl.hxx
+++ b/include/vcl/ctrl.hxx
@@ -229,6 +229,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 326b8b3761ea..eacf9e779b5e 100644
--- a/include/vcl/svapp.hxx
+++ b/include/vcl/svapp.hxx
@@ -1365,6 +1365,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 18c590ac9c5c..e595a2ba1690 100644
--- a/include/vcl/window.hxx
+++ b/include/vcl/window.hxx
@@ -1018,7 +1018,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 d88a9462918d..70a6efa616cc 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"
@@ -85,7 +86,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 3f5172ad6a50..c25ba587ae03 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -348,7 +348,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 230633d66ad1..a955e02e3da6 100644
--- a/sd/source/ui/unoidl/unomodel.cxx
+++ b/sd/source/ui/unoidl/unomodel.cxx
@@ -124,6 +124,7 @@
#include <drawinglayer/primitive2d/structuretagprimitive2d.hxx>
#include <sfx2/lokcomponenthelpers.hxx>
+#include <sfx2/LokControlHandler.hxx>
#include <tools/gen.hxx>
#include <tools/debug.hxx>
#include <comphelper/diagnose_ex.hxx>
@@ -2192,6 +2193,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
@@ -2260,6 +2264,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)
@@ -2561,8 +2576,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 09e4b4a32284..b4e94994f9ee 100644
--- a/sfx2/source/view/viewsh.cxx
+++ b/sfx2/source/view/viewsh.cxx
@@ -1628,6 +1628,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 46d2dc9980e2..db458e1245fa 100644
--- a/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx
+++ b/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx
@@ -44,10 +44,10 @@
#include <com/sun/star/container/XContainerListener.hpp>
#include <com/sun/star/container/XContainer.hpp>
-#include <utility>
#include <vcl/canvastools.hxx>
#include <vcl/svapp.hxx>
#include <vcl/window.hxx>
+#include <comphelper/lok.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/scopeguard.hxx>
#include <cppuhelper/implbase.hxx>
@@ -58,6 +58,7 @@
#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <drawinglayer/primitive2d/controlprimitive2d.hxx>
+#include <utility>
/*
Form controls (more precise: UNO Controls) in the drawing layer are ... prone to breakage, since they have some
@@ -279,6 +280,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 901ddd8c0aaf..c9a0df5291e9 100644
--- a/svx/source/svdraw/svdpntv.cxx
+++ b/svx/source/svdraw/svdpntv.cxx
@@ -629,7 +629,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 afdf7fc5a756..b7a63bda7a38 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -5344,7 +5344,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 b5e09726a0b3..aac86d4f8807 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* s_pQuickHlpData;
diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx
index 42ab3bc9b344..b2eec7838274 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>
@@ -3113,6 +3114,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 27197d70b026..9eca7534218e 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -134,6 +134,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 \
$(if $(ENABLE_WASM_STRIP_SPLASH),,vcl/source/window/introwin) \
diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx
index a580a8215cdb..f503310949f2 100644
--- a/vcl/source/app/svapp.cxx
+++ b/vcl/source/app/svapp.cxx
@@ -333,6 +333,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 6d6843b9c6e4..46d1507eb40b 100644
--- a/vcl/source/control/ctrl.cxx
+++ b/vcl/source/control/ctrl.cxx
@@ -17,6 +17,7 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+#include <comphelper/lok.hxx>
#include <o3tl/safeint.hxx>
#include <vcl/svapp.hxx>
#include <vcl/event.hxx>
@@ -25,6 +26,7 @@
#include <vcl/mnemonic.hxx>
#include <vcl/settings.hxx>
#include <vcl/uitest/logger.hxx>
+#include <vcl/DocWindow.hxx>
#include <sal/log.hxx>
#include <textlayout.hxx>
@@ -493,4 +495,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..6123246c5e48
--- /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 fe9e2b0f2444..943543ce0d16 100644
--- a/vcl/source/window/mouse.cxx
+++ b/vcl/source/window/mouse.cxx
@@ -493,30 +493,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 )