LibreOffice Module sfx2 (master) 1
LokControlHandler.hxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
9
10#pragma once
11
12#include <LibreOfficeKit/LibreOfficeKitEnums.h>
13#include <sfx2/dllapi.h>
14#include <sfx2/lokhelper.hxx>
15#include <svx/svdouno.hxx>
16#include <svx/svditer.hxx>
17#include <vcl/virdev.hxx>
18#include <vcl/DocWindow.hxx>
19#include <com/sun/star/awt/PosSize.hpp>
20#include <com/sun/star/awt/XControl.hpp>
21#include <com/sun/star/awt/XWindow.hpp>
22#include <com/sun/star/awt/XWindowPeer.hpp>
23#include <com/sun/star/awt/XGraphics.hpp>
24#include <com/sun/star/awt/XView.hpp>
27
28#include <sal/log.hxx>
29
30#include <optional>
31
33{
34public:
35 static bool postMouseEvent(const SdrPage* pPage, const SdrView* pDrawView,
36 vcl::DocWindow& rMainWindow, int nType, Point aPointHmm, int nCount,
37 int nButtons, int nModifier)
38 {
39 static std::optional<PointerStyle> eDocPointerStyle;
40
41 o3tl::Length eControlUnitLength = MapToO3tlLength(rMainWindow.GetMapMode().GetMapUnit());
42 SdrObjListIter aIterator(pPage, SdrIterMode::Flat);
43 while (aIterator.IsMore())
44 {
45 SdrObject* pObject = aIterator.Next();
46 SdrUnoObj* pUnoObect = dynamic_cast<SdrUnoObj*>(pObject);
47 if (pUnoObect)
48 {
49 tools::Rectangle aControlRect = pUnoObect->GetLogicRect();
50 tools::Rectangle aControlRectHMM
51 = o3tl::convert(aControlRect, eControlUnitLength, o3tl::Length::mm100);
52
53 if (aControlRectHMM.Contains(aPointHmm))
54 {
55 css::uno::Reference<css::awt::XControl> xControl
56 = pUnoObect->GetUnoControl(*pDrawView, *rMainWindow.GetOutDev());
57 if (!xControl.is())
58 return false;
59
60 css::uno::Reference<css::awt::XWindow> xControlWindow(xControl,
61 css::uno::UNO_QUERY);
62 if (!xControlWindow.is())
63 return false;
64
65 css::uno::Reference<css::awt::XWindowPeer> xWindowPeer(xControl->getPeer());
66
67 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow(xWindowPeer);
68 if (pWindow)
69 {
70 tools::Rectangle aControlRectPx
72 // used by Control::LogicInvalidate
73 pWindow->SetPosPixel(aControlRectPx.TopLeft());
74
75 // when entering into control area save current pointer style
76 // and set pointer style to arrow
77 if (!eDocPointerStyle)
78 {
79 *eDocPointerStyle = rMainWindow.GetPointer();
80 rMainWindow.SetPointer(pWindow->GetPointer());
81 }
82
83 Point aControlRelativePositionHMM = aPointHmm - aControlRectHMM.TopLeft();
84 Point aControlRelativePosition = o3tl::convert(
85 aControlRelativePositionHMM, o3tl::Length::mm100, o3tl::Length::px);
86
87 LokMouseEventData aMouseEventData(nType, aControlRelativePosition, nCount,
88 MouseEventModifiers::SIMPLECLICK,
89 nButtons, nModifier);
90 SfxLokHelper::postMouseEventAsync(pWindow, aMouseEventData);
91 return true;
92 }
93 }
94 }
95 }
96
97 // when exiting from control area restore document pointer style
98 if (eDocPointerStyle)
99 {
100 rMainWindow.SetPointer(*eDocPointerStyle);
101 eDocPointerStyle.reset();
102 }
103 return false;
104 }
105
106 static void drawUnoControl(const SdrView* pDrawView, const SdrUnoObj* pUnoObect,
107 vcl::Window const& rMainWindow, VirtualDevice& rDevice,
108 tools::Rectangle const& rTileRectHMM, double scaleX, double scaleY)
109 {
110 css::uno::Reference<css::awt::XControl> xControl
111 = pUnoObect->GetUnoControl(*pDrawView, *rMainWindow.GetOutDev());
112 if (!xControl.is())
113 return;
114
115 css::uno::Reference<css::awt::XWindow> xControlWindow(xControl, css::uno::UNO_QUERY);
116 if (!xControlWindow.is())
117 return;
118
119 css::uno::Reference<css::awt::XGraphics> xGraphics(rDevice.CreateUnoGraphics());
120 if (!xGraphics.is())
121 return;
122
123 css::uno::Reference<css::awt::XView> xControlView(xControl, css::uno::UNO_QUERY);
124 if (!xControlView.is())
125 return;
126
127 o3tl::Length eControlUnitLength = MapToO3tlLength(rMainWindow.GetMapMode().GetMapUnit());
128 tools::Rectangle aControlRect = pUnoObect->GetLogicRect();
129 tools::Rectangle aObjectRectHMM
130 = o3tl::convert(aControlRect, eControlUnitLength, o3tl::Length::mm100);
131 tools::Rectangle aControltRectPx
133
134 Point aOffsetFromTile(aObjectRectHMM.Left() - rTileRectHMM.Left(),
135 aObjectRectHMM.Top() - rTileRectHMM.Top());
136 tools::Rectangle aRectangleHMM(aOffsetFromTile, aObjectRectHMM.GetSize());
137 tools::Rectangle aRectanglePx
139
140 xControlWindow->setPosSize(aControltRectPx.Left(), aControltRectPx.Top(),
141 aRectanglePx.GetWidth(), aRectanglePx.GetHeight(),
142 css::awt::PosSize::POSSIZE);
143
144 xControlView->setGraphics(xGraphics);
145 // required for getting text label rendered with the correct scale
146 xControlView->setZoom(1, 1);
147
148 xControlView->draw(aRectanglePx.Left() * scaleX, aRectanglePx.Top() * scaleY);
149 }
150
151 static void paintControlTile(const SdrPage* pPage, const SdrView* pDrawView,
152 vcl::Window const& rMainWindow, VirtualDevice& rDevice,
153 Size aOutputSize, tools::Rectangle const& rTileRect)
154 {
155 tools::Rectangle aTileRectHMM
157
158 // Resizes the virtual device so to contain the entries context
159 rDevice.SetOutputSizePixel(aOutputSize);
160
162 MapMode aDeviceMapMode(rDevice.GetMapMode());
163
165 Fraction scaleX = Fraction(aOutputSize.Width(), rTileRect.GetWidth()) * scale;
166 Fraction scaleY = Fraction(aOutputSize.Height(), rTileRect.GetHeight()) * scale;
167 aDeviceMapMode.SetScaleX(scaleX);
168 aDeviceMapMode.SetScaleY(scaleY);
169 aDeviceMapMode.SetMapUnit(MapUnit::MapPixel);
170 rDevice.SetMapMode(aDeviceMapMode);
171
172 o3tl::Length eControlUnitLength = MapToO3tlLength(rMainWindow.GetMapMode().GetMapUnit());
173 SdrObjListIter aIterator(pPage, SdrIterMode::Flat);
174
175 while (aIterator.IsMore())
176 {
177 SdrObject* pObject = aIterator.Next();
178 SdrUnoObj* pUnoObect = dynamic_cast<SdrUnoObj*>(pObject);
179 if (pUnoObect)
180 {
181 tools::Rectangle aControlRect = pUnoObect->GetLogicRect();
182 tools::Rectangle aObjectRectHMM
183 = o3tl::convert(aControlRect, eControlUnitLength, o3tl::Length::mm100);
184
185 // Check if we intersect with the tile rectangle and we
186 // need to draw the control.
187 if (aObjectRectHMM.Overlaps(aTileRectHMM))
188 {
189 drawUnoControl(pDrawView, pUnoObect, rMainWindow, rDevice, aTileRectHMM,
190 double(scaleX), double(scaleY));
191 }
192 }
193 }
194
195 rDevice.Pop();
196 }
197};
198
199/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Fraction conversionFract(o3tl::Length from, o3tl::Length to)
constexpr o3tl::Length MapToO3tlLength(MapUnit eU, o3tl::Length ePixelValue=o3tl::Length::px)
static void paintControlTile(const SdrPage *pPage, const SdrView *pDrawView, vcl::Window const &rMainWindow, VirtualDevice &rDevice, Size aOutputSize, tools::Rectangle const &rTileRect)
static bool postMouseEvent(const SdrPage *pPage, const SdrView *pDrawView, vcl::DocWindow &rMainWindow, int nType, Point aPointHmm, int nCount, int nButtons, int nModifier)
static void drawUnoControl(const SdrView *pDrawView, const SdrUnoObj *pUnoObect, vcl::Window const &rMainWindow, VirtualDevice &rDevice, tools::Rectangle const &rTileRectHMM, double scaleX, double scaleY)
void SetScaleY(const Fraction &rScaleY)
MapUnit GetMapUnit() const
void SetMapUnit(MapUnit eUnit)
void SetScaleX(const Fraction &rScaleX)
css::uno::Reference< css::awt::XGraphics > CreateUnoGraphics()
void SetMapMode()
const MapMode & GetMapMode() const
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
SdrObject * Next()
bool IsMore() const
virtual const tools::Rectangle & GetLogicRect() const override
css::uno::Reference< css::awt::XControl > GetUnoControl(const SdrView &_rView, const OutputDevice &_rOut) const
static void postMouseEventAsync(const VclPtr< vcl::Window > &xWindow, LokMouseEventData const &rLokMouseEventData)
Helper for posting async mouse event.
Definition: lokhelper.cxx:929
constexpr tools::Long Height() const
constexpr tools::Long Width() const
static vcl::Window * GetWindow(const css::uno::Reference< css::awt::XWindow > &rxWindow)
bool SetOutputSizePixel(const Size &rNewSize, bool bErase=true, bool bAlphaMaskTransparent=false)
constexpr tools::Long GetWidth() const
bool Contains(const Point &rPOINT) const
bool Overlaps(const tools::Rectangle &rRect) const
constexpr tools::Long Top() const
constexpr Point TopLeft() const
constexpr Size GetSize() const
constexpr tools::Long GetHeight() const
constexpr tools::Long Left() const
virtual void SetPointer(PointerStyle) override
const MapMode & GetMapMode() const
::OutputDevice const * GetOutDev() const
PointerStyle GetPointer() const
int nCount
EmbeddedObjectRef * pObject
constexpr Point convert(const Point &rPoint, o3tl::Length eFrom, o3tl::Length eTo)
sal_Int32 scale
QPRO_FUNC_TYPE nType