diff options
author | Marco Cecchetti <marco.cecchetti@collabora.com> | 2023-02-05 17:47:34 +0100 |
---|---|---|
committer | Marco Cecchetti <marco.cecchetti@collabora.com> | 2023-03-07 19:30:11 +0000 |
commit | 7adfecb0f5947ae258226c8d1652546f81577026 (patch) | |
tree | 722ef84394ffe68f635945d4fc3ebc48e5b0e122 | |
parent | c596fd59dc75823002bdfd3676d600a56e3bfb5e (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.hxx | 70 | ||||
-rw-r--r-- | include/sfx2/viewsh.hxx | 4 | ||||
-rw-r--r-- | include/vcl/DocWindow.hxx | 30 | ||||
-rw-r--r-- | include/vcl/IDialogRenderable.hxx | 6 | ||||
-rw-r--r-- | include/vcl/ctrl.hxx | 3 | ||||
-rw-r--r-- | include/vcl/svapp.hxx | 2 | ||||
-rw-r--r-- | include/vcl/window.hxx | 2 | ||||
-rw-r--r-- | sc/source/ui/inc/gridwin.hxx | 3 | ||||
-rw-r--r-- | sc/source/ui/view/gridwin.cxx | 2 | ||||
-rw-r--r-- | sd/source/ui/inc/Window.hxx | 4 | ||||
-rw-r--r-- | sd/source/ui/unoidl/unomodel.cxx | 28 | ||||
-rw-r--r-- | sd/source/ui/view/sdwindow.cxx | 2 | ||||
-rw-r--r-- | sfx2/source/view/viewsh.cxx | 5 | ||||
-rw-r--r-- | svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx | 7 | ||||
-rw-r--r-- | svx/source/svdraw/svdpntv.cxx | 3 | ||||
-rw-r--r-- | sw/source/uibase/docvw/edtwin.cxx | 2 | ||||
-rw-r--r-- | sw/source/uibase/inc/edtwin.hxx | 4 | ||||
-rw-r--r-- | sw/source/uibase/uno/unotxdoc.cxx | 21 | ||||
-rw-r--r-- | vcl/Library_vcl.mk | 1 | ||||
-rw-r--r-- | vcl/source/app/svapp.cxx | 3 | ||||
-rw-r--r-- | vcl/source/control/ctrl.cxx | 31 | ||||
-rw-r--r-- | vcl/source/window/DocWindow.cxx | 40 | ||||
-rw-r--r-- | vcl/source/window/mouse.cxx | 24 |
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 ) |