Coverage Report

Created: 2026-04-09 11:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sc/source/ui/drawfunc/fuconpol.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
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#include <fuconpol.hxx>
21
#include <tabvwsh.hxx>
22
#include <drawview.hxx>
23
24
// Create default drawing objects via keyboard
25
#include <svx/svdopath.hxx>
26
#include <svx/svxids.hrc>
27
#include <osl/diagnose.h>
28
#include <vcl/ptrstyle.hxx>
29
#include <basegfx/polygon/b2dpolygon.hxx>
30
#include <basegfx/point/b2dpoint.hxx>
31
32
FuConstPolygon::FuConstPolygon(ScTabViewShell& rViewSh, vcl::Window* pWin, ScDrawView* pViewP,
33
                               SdrModel& rDoc, const SfxRequest& rReq)
34
0
    : FuConstruct(rViewSh, pWin, pViewP, rDoc, rReq)
35
0
{
36
0
}
37
38
FuConstPolygon::~FuConstPolygon()
39
0
{
40
0
}
41
42
bool FuConstPolygon::MouseButtonDown(const MouseEvent& rMEvt)
43
0
{
44
    // remember button state for creation of own MouseEvents
45
0
    SetMouseButtonCode(rMEvt.GetButtons());
46
47
0
    bool bReturn = FuConstruct::MouseButtonDown(rMEvt);
48
49
0
    SdrViewEvent aVEvt;
50
0
    (void)pView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
51
0
    if (aVEvt.meEvent == SdrEventKind::BeginTextEdit)
52
0
    {
53
        // Text input not allowed here
54
0
        aVEvt.meEvent = SdrEventKind::BeginDragObj;
55
0
        pView->EnableExtendedMouseEventDispatcher(false);
56
0
    }
57
0
    else
58
0
    {
59
0
        pView->EnableExtendedMouseEventDispatcher(true);
60
0
    }
61
62
0
    if ( pView->MouseButtonDown(rMEvt, pWindow->GetOutDev()) )
63
0
        bReturn = true;
64
65
0
    return bReturn;
66
0
}
67
68
bool FuConstPolygon::MouseMove(const MouseEvent& rMEvt)
69
0
{
70
0
    pView->MouseMove(rMEvt, pWindow->GetOutDev());
71
0
    return FuConstruct::MouseMove(rMEvt);
72
0
}
73
74
bool FuConstPolygon::MouseButtonUp(const MouseEvent& rMEvt)
75
0
{
76
    // remember button state for creation of own MouseEvents
77
0
    SetMouseButtonCode(rMEvt.GetButtons());
78
79
0
    bool bReturn = false;
80
0
    bool bSimple = false;
81
82
0
    SdrViewEvent aVEvt;
83
0
    (void)pView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONUP, aVEvt);
84
85
0
    pView->MouseButtonUp(rMEvt, pWindow->GetOutDev());
86
87
0
    if (aVEvt.meEvent == SdrEventKind::EndCreate)
88
0
    {
89
0
        bReturn = true;
90
0
        bSimple = true;         // Do not pass on double-click
91
0
    }
92
93
0
    bool bParent;
94
0
    if (bSimple)
95
0
        bParent = FuConstruct::SimpleMouseButtonUp(rMEvt);
96
0
    else
97
0
        bParent = FuConstruct::MouseButtonUp(rMEvt);
98
99
0
    return (bParent || bReturn);
100
0
}
101
102
void FuConstPolygon::Activate()
103
0
{
104
0
    pView->EnableExtendedMouseEventDispatcher(true);
105
106
0
    SdrObjKind eKind;
107
108
0
    switch (GetSlotID())
109
0
    {
110
0
        case SID_DRAW_POLYGON_NOFILL:
111
0
        case SID_DRAW_XPOLYGON_NOFILL:
112
0
        {
113
0
            eKind = SdrObjKind::PolyLine;
114
0
        }
115
0
        break;
116
117
0
        case SID_DRAW_POLYGON:
118
0
        case SID_DRAW_XPOLYGON:
119
0
        {
120
0
            eKind = SdrObjKind::Polygon;
121
0
        }
122
0
        break;
123
124
0
        case SID_DRAW_BEZIER_NOFILL:
125
0
        {
126
0
            eKind = SdrObjKind::PathLine;
127
0
        }
128
0
        break;
129
130
0
        case SID_DRAW_BEZIER_FILL:
131
0
        {
132
0
            eKind = SdrObjKind::PathFill;
133
0
        }
134
0
        break;
135
136
0
        case SID_DRAW_FREELINE_NOFILL:
137
0
        {
138
0
            eKind = SdrObjKind::FreehandLine;
139
0
        }
140
0
        break;
141
142
0
        case SID_DRAW_FREELINE:
143
0
        {
144
0
            eKind = SdrObjKind::FreehandFill;
145
0
        }
146
0
        break;
147
148
0
        default:
149
0
        {
150
0
            eKind = SdrObjKind::PathLine;
151
0
        }
152
0
        break;
153
0
    }
154
155
0
    pView->SetCurrentObj(eKind);
156
157
0
    pView->SetEditMode(SdrViewEditMode::Create);
158
159
0
    FuConstruct::Activate();
160
161
0
    aNewPointer = PointerStyle::DrawPolygon;
162
0
    aOldPointer = pWindow->GetPointer();
163
0
    rViewShell.SetActivePointer( aNewPointer );
164
0
}
165
166
void FuConstPolygon::Deactivate()
167
0
{
168
0
    pView->SetEditMode(SdrViewEditMode::Edit);
169
170
0
    pView->EnableExtendedMouseEventDispatcher(false);
171
172
0
    FuConstruct::Deactivate();
173
174
0
    rViewShell.SetActivePointer( aOldPointer );
175
0
}
176
177
// Create default drawing objects via keyboard
178
rtl::Reference<SdrObject> FuConstPolygon::CreateDefaultObject(const sal_uInt16 nID, const tools::Rectangle& rRectangle)
179
0
{
180
    // case SID_DRAW_XPOLYGON:
181
    // case SID_DRAW_XPOLYGON_NOFILL:
182
    // case SID_DRAW_POLYGON:
183
    // case SID_DRAW_POLYGON_NOFILL:
184
    // case SID_DRAW_BEZIER_FILL:
185
    // case SID_DRAW_BEZIER_NOFILL:
186
    // case SID_DRAW_FREELINE:
187
    // case SID_DRAW_FREELINE_NOFILL:
188
189
0
    rtl::Reference<SdrObject> pObj(SdrObjFactory::MakeNewObject(
190
0
        rDrDoc,
191
0
        pView->GetCurrentObjInventor(),
192
0
        pView->GetCurrentObjIdentifier()));
193
194
0
    if(pObj)
195
0
    {
196
0
        if(dynamic_cast<const SdrPathObj*>( pObj.get() ) !=  nullptr)
197
0
        {
198
0
            basegfx::B2DPolyPolygon aPoly;
199
200
0
            switch(nID)
201
0
            {
202
0
                case SID_DRAW_BEZIER_FILL:
203
0
                case SID_DRAW_BEZIER_NOFILL:
204
0
                {
205
0
                    basegfx::B2DPolygon aInnerPoly;
206
207
0
                    aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Bottom()));
208
209
0
                    const basegfx::B2DPoint aCenterBottom(rRectangle.Center().X(), rRectangle.Bottom());
210
0
                    aInnerPoly.appendBezierSegment(
211
0
                        aCenterBottom,
212
0
                        aCenterBottom,
213
0
                        basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Center().Y()));
214
215
0
                    const basegfx::B2DPoint aCenterTop(rRectangle.Center().X(), rRectangle.Top());
216
0
                    aInnerPoly.appendBezierSegment(
217
0
                        aCenterTop,
218
0
                        aCenterTop,
219
0
                        basegfx::B2DPoint(rRectangle.Right(), rRectangle.Top()));
220
221
0
                    aPoly.append(aInnerPoly);
222
0
                    break;
223
0
                }
224
0
                case SID_DRAW_FREELINE:
225
0
                case SID_DRAW_FREELINE_NOFILL:
226
0
                {
227
0
                    basegfx::B2DPolygon aInnerPoly;
228
229
0
                    aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Bottom()));
230
231
0
                    aInnerPoly.appendBezierSegment(
232
0
                        basegfx::B2DPoint(rRectangle.Left(), rRectangle.Top()),
233
0
                        basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Top()),
234
0
                        basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Center().Y()));
235
236
0
                    aInnerPoly.appendBezierSegment(
237
0
                        basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Bottom()),
238
0
                        basegfx::B2DPoint(rRectangle.Right(), rRectangle.Bottom()),
239
0
                        basegfx::B2DPoint(rRectangle.Right(), rRectangle.Top()));
240
241
0
                    aPoly.append(aInnerPoly);
242
0
                    break;
243
0
                }
244
0
                case SID_DRAW_XPOLYGON:
245
0
                case SID_DRAW_XPOLYGON_NOFILL:
246
0
                case SID_DRAW_POLYGON:
247
0
                case SID_DRAW_POLYGON_NOFILL:
248
0
                {
249
0
                    basegfx::B2DPolygon aInnerPoly;
250
0
                    const sal_Int32 nWdt(rRectangle.GetWidth());
251
0
                    const sal_Int32 nHgt(rRectangle.GetHeight());
252
253
0
                    aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Bottom()));
254
0
                    aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + (nWdt * 30) / 100, rRectangle.Top() + (nHgt * 70) / 100));
255
0
                    aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Top() + (nHgt * 15) / 100));
256
0
                    aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + (nWdt * 65) / 100, rRectangle.Top()));
257
0
                    aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + nWdt, rRectangle.Top() + (nHgt * 30) / 100));
258
0
                    aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + (nWdt * 80) / 100, rRectangle.Top() + (nHgt * 50) / 100));
259
0
                    aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + (nWdt * 80) / 100, rRectangle.Top() + (nHgt * 75) / 100));
260
0
                    aInnerPoly.append(basegfx::B2DPoint(rRectangle.Bottom(), rRectangle.Right()));
261
262
0
                    if(SID_DRAW_POLYGON_NOFILL == nID)
263
0
                    {
264
0
                        aInnerPoly.append(basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Bottom()));
265
0
                    }
266
0
                    else
267
0
                    {
268
0
                        aInnerPoly.setClosed(true);
269
0
                    }
270
271
0
                    aPoly.append(aInnerPoly);
272
0
                    break;
273
0
                }
274
0
            }
275
276
0
            static_cast<SdrPathObj*>(pObj.get())->SetPathPoly(aPoly);
277
0
        }
278
0
        else
279
0
        {
280
0
            OSL_FAIL("Object is NO path object");
281
0
        }
282
283
0
        pObj->SetLogicRect(rRectangle);
284
0
    }
285
286
0
    return pObj;
287
0
}
288
289
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */