Coverage Report

Created: 2026-05-16 09:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sd/source/ui/uitest/uiobject.cxx
Line
Count
Source
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
#include <memory>
11
#include <uiobject.hxx>
12
13
#include <Window.hxx>
14
#include <DrawViewShell.hxx>
15
#include <sdpage.hxx>
16
17
#include <sfx2/sidebar/Sidebar.hxx>
18
#include <sfx2/sfxsids.hrc>
19
#include <sfx2/viewfrm.hxx>
20
#include <tools/debug.hxx>
21
#include <utility>
22
23
namespace
24
{
25
class ImpressSdrObject : public UIObject
26
{
27
public:
28
    ImpressSdrObject(const VclPtr<sd::Window>& xImpressWin, OUString aName);
29
30
    virtual bool equals(const UIObject& rOther) const override;
31
32
    virtual StringMap get_state() override;
33
34
    virtual void execute(const OUString& rAction, const StringMap& rParameters) override;
35
36
    virtual OUString get_type() const override;
37
38
private:
39
    VclPtr<sd::Window> mxWindow;
40
41
    OUString maName;
42
};
43
44
sd::DrawViewShell* getViewShell(const VclPtr<sd::Window>& xWindow)
45
0
{
46
0
    sd::DrawViewShell* pViewShell = dynamic_cast<sd::DrawViewShell*>(xWindow->GetViewShell());
47
0
    assert(pViewShell);
48
49
0
    return pViewShell;
50
0
}
51
52
OUString getObjectName(SdrObject const* pObject)
53
0
{
54
0
    if (pObject->GetName().isEmpty())
55
0
        return "Unnamed Drawinglayer object " + OUString::number(pObject->GetOrdNum());
56
0
    else
57
0
        return pObject->GetName();
58
0
}
59
60
SdrObject* getObject(const VclPtr<sd::Window>& xWindow, std::u16string_view rName)
61
0
{
62
0
    SdrPage* pPage = getViewShell(xWindow)->getCurrentPage();
63
64
0
    if (!pPage)
65
0
        return nullptr;
66
67
0
    for (const rtl::Reference<SdrObject>& pObj : *pPage)
68
0
        if (rName == getObjectName(pObj.get()))
69
0
            return pObj.get();
70
71
0
    return nullptr;
72
0
}
73
}
74
75
ImpressSdrObject::ImpressSdrObject(const VclPtr<sd::Window>& xImpressWin, OUString aName)
76
0
    : mxWindow(xImpressWin)
77
0
    , maName(std::move(aName))
78
0
{
79
0
}
80
81
bool ImpressSdrObject::equals(const UIObject& rOther) const
82
0
{
83
0
    const ImpressSdrObject* pOther = dynamic_cast<const ImpressSdrObject*>(&rOther);
84
0
    if (!pOther)
85
0
        return false;
86
0
    return mxWindow.get() == pOther->mxWindow.get();
87
0
}
88
89
StringMap ImpressSdrObject::get_state()
90
0
{
91
0
    StringMap aMap;
92
0
    SdrObject* pObject = getObject(mxWindow, maName);
93
94
0
    if (!pObject)
95
0
        return aMap;
96
97
0
    aMap[u"Name"_ustr] = pObject->GetName();
98
0
    aMap[u"Description"_ustr] = pObject->GetDescription();
99
0
    aMap[u"Title"_ustr] = pObject->GetTitle();
100
0
    aMap[u"Z-Order"_ustr] = OUString::number(pObject->GetOrdNum());
101
0
    aMap[u"Layer"_ustr] = OUString::number(pObject->GetLayer().get());
102
0
    aMap[u"IsGroupObject"_ustr] = OUString::boolean(pObject->IsGroupObject());
103
0
    aMap[u"IsPolyObject"_ustr] = OUString::boolean(pObject->IsPolyObj());
104
0
    aMap[u"PointCount"_ustr] = OUString::number(pObject->GetPointCount());
105
0
    aMap[u"HasTextEdit"_ustr] = OUString::boolean(pObject->HasTextEdit());
106
0
    aMap[u"HasMacro"_ustr] = OUString::boolean(pObject->HasMacro());
107
0
    aMap[u"IsClosed"_ustr] = OUString::boolean(pObject->IsClosedObj());
108
0
    aMap[u"IsEdgeObject"_ustr] = OUString::boolean(pObject->IsEdgeObj());
109
0
    aMap[u"Is3DObject"_ustr] = OUString::boolean(pObject->Is3DObj());
110
0
    aMap[u"IsUNOObject"_ustr] = OUString::boolean(pObject->IsUnoObj());
111
0
    aMap[u"MoveProtected"_ustr] = OUString::boolean(pObject->IsMoveProtect());
112
0
    aMap[u"ResizeProtected"_ustr] = OUString::boolean(pObject->IsResizeProtect());
113
0
    aMap[u"Printable"_ustr] = OUString::boolean(pObject->IsPrintable());
114
0
    aMap[u"Visible"_ustr] = OUString::boolean(pObject->IsVisible());
115
0
    aMap[u"HasText"_ustr] = OUString::boolean(pObject->HasText());
116
117
0
    return aMap;
118
0
}
119
120
void ImpressSdrObject::execute(const OUString& rAction, const StringMap& rParameters)
121
0
{
122
0
    SdrObject* pObj = getObject(mxWindow, maName);
123
0
    if (!pObj)
124
0
        return;
125
126
0
    if (rAction == "MOVE")
127
0
    {
128
0
        auto itrNX = rParameters.find(u"X"_ustr);
129
0
        if (itrNX == rParameters.end())
130
0
            throw css::uno::RuntimeException(u"missing parameter X"_ustr);
131
132
0
        auto itrNY = rParameters.find(u"Y"_ustr);
133
0
        if (itrNY == rParameters.end())
134
0
            throw css::uno::RuntimeException(u"missing parameter Y"_ustr);
135
136
0
        tools::Long nX = itrNX->second.toInt32();
137
0
        tools::Long nY = itrNY->second.toInt32();
138
0
        Size aMoveRange(nX, nY);
139
0
        pObj->Move(aMoveRange);
140
0
    }
141
0
    else if (rAction == "RESIZE")
142
0
    {
143
0
        auto itrNX = rParameters.find(u"X"_ustr);
144
0
        if (itrNX == rParameters.end())
145
0
            throw css::uno::RuntimeException(u"missing parameter X"_ustr);
146
147
0
        auto itrNY = rParameters.find(u"Y"_ustr);
148
0
        if (itrNY == rParameters.end())
149
0
            throw css::uno::RuntimeException(u"missing parameter Y"_ustr);
150
151
0
        tools::Long nX = itrNX->second.toInt32();
152
0
        tools::Long nY = itrNY->second.toInt32();
153
0
        Point aPos(nX, nY);
154
155
0
        auto itrFracX = rParameters.find(u"FRAC_X"_ustr);
156
0
        if (itrFracX == rParameters.end())
157
0
            throw css::uno::RuntimeException(u"missing parameter FRAC_X"_ustr);
158
0
        double nFracX = itrFracX->second.toDouble();
159
160
0
        auto itrFracY = rParameters.find(u"FRAC_Y"_ustr);
161
0
        if (itrFracY == rParameters.end())
162
0
            throw css::uno::RuntimeException(u"missing parameter FRAC_Y"_ustr);
163
0
        double nFracY = itrFracY->second.toDouble();
164
0
        pObj->Resize(aPos, nFracX, nFracY, true /*bRelative*/);
165
0
    }
166
0
    else if (rAction == "CROP")
167
0
    {
168
        // RotateFlyFrame3: Note: Crop does nothing at SdrObject
169
        // anymore, see comment at SdrObject::NbcCrop
170
0
        auto itrNX = rParameters.find(u"X"_ustr);
171
0
        if (itrNX == rParameters.end())
172
0
            throw css::uno::RuntimeException(u"missing parameter X"_ustr);
173
174
0
        auto itrNY = rParameters.find(u"Y"_ustr);
175
0
        if (itrNY == rParameters.end())
176
0
            throw css::uno::RuntimeException(u"missing parameter Y"_ustr);
177
178
0
        const double fX(itrNX->second.toDouble());
179
0
        const double fY(itrNY->second.toDouble());
180
0
        const basegfx::B2DPoint aPos(fX, fY);
181
182
0
        auto itrFracX = rParameters.find(u"FRAC_X"_ustr);
183
0
        if (itrFracX == rParameters.end())
184
0
            throw css::uno::RuntimeException(u"missing parameter FRAC_X"_ustr);
185
0
        const double fFracX(itrFracX->second.toDouble());
186
187
0
        auto itrFracY = rParameters.find(u"FRAC_Y"_ustr);
188
0
        if (itrFracY == rParameters.end())
189
0
            throw css::uno::RuntimeException(u"missing parameter FRAC_Y"_ustr);
190
0
        const double fFracY(itrFracY->second.toDouble());
191
192
0
        pObj->Crop(aPos, fFracX, fFracY);
193
0
    }
194
0
    else if (rAction == "ROTATE")
195
0
    {
196
0
        auto itrNX = rParameters.find(u"X"_ustr);
197
0
        if (itrNX == rParameters.end())
198
0
            throw css::uno::RuntimeException(u"missing parameter X"_ustr);
199
200
0
        auto itrNY = rParameters.find(u"Y"_ustr);
201
0
        if (itrNY == rParameters.end())
202
0
            throw css::uno::RuntimeException(u"missing parameter Y"_ustr);
203
204
0
        tools::Long nX = itrNX->second.toInt32();
205
0
        tools::Long nY = itrNY->second.toInt32();
206
0
        Point aPos(nX, nY);
207
208
0
        auto itrAngle = rParameters.find(u"ANGLE"_ustr);
209
0
        if (itrAngle == rParameters.end())
210
0
            throw css::uno::RuntimeException(u"missing parameter ANGLE"_ustr);
211
212
0
        double nAngle = itrAngle->second.toDouble();
213
0
        pObj->Rotate(aPos, Degree100(sal_Int32(nAngle)), 0, 0);
214
0
    }
215
0
    else if (rAction == "Mirror")
216
0
    {
217
0
        pObj->Mirror(Point(), Point());
218
0
    }
219
0
    else if (rAction == "SHEAR")
220
0
    {
221
0
        pObj->Shear(Point(), 0_deg100 /*nAngle*/, 0, false);
222
0
    }
223
0
}
224
225
0
OUString ImpressSdrObject::get_type() const { return u"ImpressSdrObject"_ustr; }
226
227
ImpressWindowUIObject::ImpressWindowUIObject(const VclPtr<sd::Window>& xWindow)
228
0
    : WindowUIObject(xWindow)
229
0
    , mxWindow(xWindow)
230
0
{
231
0
}
232
233
StringMap ImpressWindowUIObject::get_state()
234
0
{
235
0
    StringMap aMap = WindowUIObject::get_state();
236
237
0
    aMap[u"SelectedText"_ustr] = getViewShell(mxWindow)->GetSelectionText(false);
238
0
    aMap[u"CurrentSlide"_ustr] = OUString::number(getViewShell(mxWindow)->GetCurPagePos() + 1);
239
0
    aMap[u"Zoom"_ustr] = OUString::number(getViewShell(mxWindow)->GetZoom());
240
241
0
    return aMap;
242
0
}
243
244
void ImpressWindowUIObject::execute(const OUString& rAction, const StringMap& rParameters)
245
0
{
246
0
    if (rAction == "SET")
247
0
    {
248
0
        if (rParameters.find(u"ZOOM"_ustr) != rParameters.end())
249
0
        {
250
0
            auto itr = rParameters.find(u"ZOOM"_ustr);
251
0
            OUString aVal = itr->second;
252
0
            sal_Int32 nVal = aVal.toInt32();
253
0
            getViewShell(mxWindow)->SetZoom(nVal);
254
0
        }
255
0
    }
256
0
    else if (rAction == "GOTO")
257
0
    {
258
0
        if (rParameters.find(u"PAGE"_ustr) != rParameters.end())
259
0
        {
260
0
            auto itr = rParameters.find(u"PAGE"_ustr);
261
0
            OUString aVal = itr->second;
262
0
            sal_Int32 nVal = aVal.toInt32();
263
0
            getViewShell(mxWindow)->SwitchPage(nVal - 1);
264
0
        }
265
0
    }
266
0
    else if (rAction == "SELECT")
267
0
    {
268
0
        if (rParameters.find(u"OBJECT"_ustr) != rParameters.end())
269
0
        {
270
0
            auto itr = rParameters.find(u"OBJECT"_ustr);
271
0
            OUString aName = itr->second;
272
0
            SdrObject* pObj = getObject(mxWindow, aName);
273
0
            SdrPageView* pPageView = getViewShell(mxWindow)->GetView()->GetSdrPageView();
274
0
            getViewShell(mxWindow)->GetView()->MarkObj(pObj, pPageView);
275
0
        }
276
0
    }
277
0
    else if (rAction == "SIDEBAR")
278
0
    {
279
0
        SfxViewFrame* pViewFrm = SfxViewFrame::Current();
280
0
        assert(pViewFrm && "ImpressWindowUIObject::execute: no viewframe");
281
0
        pViewFrm->ShowChildWindow(SID_SIDEBAR);
282
283
0
        auto itr = rParameters.find(u"PANEL"_ustr);
284
0
        if (itr != rParameters.end())
285
0
        {
286
0
            OUString aVal = itr->second;
287
0
            ::sfx2::sidebar::Sidebar::ShowPanel(aVal, pViewFrm->GetFrame().GetFrameInterface());
288
0
        }
289
0
    }
290
0
    else if (rAction == "DESELECT")
291
0
    {
292
0
        getViewShell(mxWindow)->GetView()->UnMarkAll();
293
0
    }
294
0
    else
295
0
        WindowUIObject::execute(rAction, rParameters);
296
0
}
297
298
std::unique_ptr<UIObject> ImpressWindowUIObject::get_child(const OUString& rID)
299
0
{
300
0
    return std::unique_ptr<UIObject>(new ImpressSdrObject(mxWindow, rID));
301
0
}
302
303
std::set<OUString> ImpressWindowUIObject::get_children() const
304
0
{
305
0
    SdrPage* pPage = getViewShell(mxWindow)->getCurrentPage();
306
307
0
    std::set<OUString> aRet;
308
0
    if (!pPage)
309
0
        return aRet;
310
311
0
    for (const rtl::Reference<SdrObject>& pObject : *pPage)
312
0
        aRet.insert(getObjectName(pObject.get()));
313
314
0
    return aRet;
315
0
}
316
317
0
OUString ImpressWindowUIObject::get_name() const { return u"ImpressWindowUIObject"_ustr; }
318
319
std::unique_ptr<UIObject> ImpressWindowUIObject::create(vcl::Window* pWindow)
320
0
{
321
0
    sd::Window* pWin = dynamic_cast<sd::Window*>(pWindow);
322
    assert(pWin);
323
0
    return std::unique_ptr<UIObject>(new ImpressWindowUIObject(pWin));
324
0
}
325
326
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */