Coverage Report

Created: 2026-02-14 09:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sc/source/ui/drawfunc/fuconrec.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 <fuconrec.hxx>
21
#include <tabvwsh.hxx>
22
#include <drawview.hxx>
23
24
#include <editeng/outlobj.hxx>
25
#include <svx/constructhelper.hxx>
26
// Create default drawing objects via keyboard
27
#include <svx/svdopath.hxx>
28
#include <svx/svdocapt.hxx>
29
#include <svx/svxids.hrc>
30
#include <svx/svdomeas.hxx>
31
#include <osl/diagnose.h>
32
#include <vcl/ptrstyle.hxx>
33
34
#include <basegfx/polygon/b2dpolygon.hxx>
35
#include <basegfx/point/b2dpoint.hxx>
36
37
FuConstRectangle::FuConstRectangle(ScTabViewShell& rViewSh, vcl::Window* pWin, ScDrawView* pViewP,
38
                                   SdrModel& rDoc, const SfxRequest& rReq)
39
0
    : FuConstruct(rViewSh, pWin, pViewP, rDoc, rReq)
40
0
{
41
0
}
42
43
FuConstRectangle::~FuConstRectangle()
44
0
{
45
0
}
46
47
bool FuConstRectangle::MouseButtonDown(const MouseEvent& rMEvt)
48
0
{
49
    // remember button state for creation of own MouseEvents
50
0
    SetMouseButtonCode(rMEvt.GetButtons());
51
52
0
    bool bReturn = FuConstruct::MouseButtonDown(rMEvt);
53
54
0
    if ( rMEvt.IsLeft() && !pView->IsAction() )
55
0
    {
56
0
        Point aPos( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
57
0
        pWindow->CaptureMouse();
58
59
0
        if ( pView->GetCurrentObjIdentifier() == SdrObjKind::Caption )
60
0
        {
61
0
            Size aCaptionSize ( 2268, 1134 ); // 4x2cm
62
63
0
            bReturn = pView->BegCreateCaptionObj( aPos, aCaptionSize );
64
65
            // How do you set the font for writing
66
0
        }
67
0
        else
68
0
            bReturn = pView->BegCreateObj(aPos);
69
70
0
        SdrObject* pObj = pView->GetCreateObj();
71
72
0
        if (pObj)
73
0
        {
74
0
            SfxItemSet aAttr(pObj->getSdrModelFromSdrObject().GetItemPool());
75
0
            SetLineEnds(aAttr, *pObj, aSfxRequest.GetSlot());
76
0
            pObj->SetMergedItemSet(aAttr);
77
0
        }
78
0
    }
79
0
    return bReturn;
80
0
}
81
82
bool FuConstRectangle::MouseButtonUp(const MouseEvent& rMEvt)
83
0
{
84
    // remember button state for creation of own MouseEvents
85
0
    SetMouseButtonCode(rMEvt.GetButtons());
86
87
0
    bool bReturn = false;
88
89
0
    if ( pView->IsCreateObj() && rMEvt.IsLeft() )
90
0
    {
91
0
        pView->EndCreateObj(SdrCreateCmd::ForceEnd);
92
93
0
        if (aSfxRequest.GetSlot() == SID_DRAW_CAPTION_VERTICAL)
94
0
        {
95
            //  set vertical flag for caption object
96
97
0
            const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
98
0
            if (rMarkList.GetMark(0))
99
0
            {
100
0
                SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
101
                //  create OutlinerParaObject now so it can be set to vertical
102
0
                if ( auto pSdrTextObj = DynCastSdrTextObj( pObj) )
103
0
                    pSdrTextObj->ForceOutlinerParaObject();
104
0
                OutlinerParaObject* pOPO = pObj->GetOutlinerParaObject();
105
0
                if( pOPO && !pOPO->IsEffectivelyVertical() )
106
0
                    pOPO->SetVertical( true );
107
0
            }
108
0
        }
109
110
0
        bReturn = true;
111
0
    }
112
0
    return (FuConstruct::MouseButtonUp(rMEvt) || bReturn);
113
0
}
114
115
void FuConstRectangle::Activate()
116
0
{
117
0
    SdrObjKind aObjKind;
118
119
0
    switch (aSfxRequest.GetSlot() )
120
0
    {
121
0
        case SID_DRAW_LINE:
122
0
        case SID_DRAW_XLINE:
123
0
        case SID_LINE_ARROW_END:
124
0
        case SID_LINE_ARROW_CIRCLE:
125
0
        case SID_LINE_ARROW_SQUARE:
126
0
        case SID_LINE_ARROW_START:
127
0
        case SID_LINE_CIRCLE_ARROW:
128
0
        case SID_LINE_SQUARE_ARROW:
129
0
        case SID_LINE_ARROWS:
130
0
            aNewPointer = PointerStyle::DrawLine;
131
0
            aObjKind = SdrObjKind::Line;
132
0
            break;
133
134
0
        case SID_DRAW_MEASURELINE:
135
0
            aNewPointer = PointerStyle::DrawLine;
136
0
            aObjKind = SdrObjKind::Measure;
137
0
            break;
138
139
0
        case SID_DRAW_RECT:
140
0
            aNewPointer = PointerStyle::DrawRect;
141
0
            aObjKind = SdrObjKind::Rectangle;
142
0
            break;
143
144
0
        case SID_DRAW_ELLIPSE:
145
0
            aNewPointer = PointerStyle::DrawEllipse;
146
0
            aObjKind = SdrObjKind::CircleOrEllipse;
147
0
            break;
148
149
0
        case SID_DRAW_CAPTION:
150
0
        case SID_DRAW_CAPTION_VERTICAL:
151
0
            aNewPointer = PointerStyle::DrawCaption;
152
0
            aObjKind = SdrObjKind::Caption;
153
0
            break;
154
155
0
        case SID_TOOL_CONNECTOR:
156
0
        case SID_CONNECTOR_ARROWS:
157
0
        case SID_CONNECTOR_ARROW_START:
158
0
        case SID_CONNECTOR_ARROW_END:
159
0
        case SID_CONNECTOR_CIRCLE_START:
160
0
        case SID_CONNECTOR_CIRCLE_END:
161
0
        case SID_CONNECTOR_CIRCLES:
162
0
        case SID_CONNECTOR_LINE:
163
0
        case SID_CONNECTOR_LINE_ARROW_START:
164
0
        case SID_CONNECTOR_LINE_ARROW_END:
165
0
        case SID_CONNECTOR_LINE_ARROWS:
166
0
        case SID_CONNECTOR_LINE_CIRCLE_START:
167
0
        case SID_CONNECTOR_LINE_CIRCLE_END:
168
0
        case SID_CONNECTOR_LINE_CIRCLES:
169
0
        case SID_CONNECTOR_CURVE:
170
0
        case SID_CONNECTOR_CURVE_ARROW_START:
171
0
        case SID_CONNECTOR_CURVE_ARROW_END:
172
0
        case SID_CONNECTOR_CURVE_ARROWS:
173
0
        case SID_CONNECTOR_CURVE_CIRCLE_START:
174
0
        case SID_CONNECTOR_CURVE_CIRCLE_END:
175
0
        case SID_CONNECTOR_CURVE_CIRCLES:
176
0
        case SID_CONNECTOR_LINES:
177
0
        case SID_CONNECTOR_LINES_ARROW_START:
178
0
        case SID_CONNECTOR_LINES_ARROW_END:
179
0
        case SID_CONNECTOR_LINES_ARROWS:
180
0
        case SID_CONNECTOR_LINES_CIRCLE_START:
181
0
        case SID_CONNECTOR_LINES_CIRCLE_END:
182
0
        case SID_CONNECTOR_LINES_CIRCLES:
183
0
            aNewPointer = PointerStyle::DrawConnect;
184
0
            aObjKind = SdrObjKind::Edge;
185
0
            pView->SetEditMode(SdrViewEditMode::Create);
186
0
            break;
187
188
0
        default:
189
0
            aNewPointer = PointerStyle::Cross;
190
0
            aObjKind = SdrObjKind::Rectangle;
191
0
            break;
192
0
    }
193
194
0
    pView->SetCurrentObj(aObjKind);
195
196
0
    aOldPointer = pWindow->GetPointer();
197
0
    rViewShell.SetActivePointer( aNewPointer );
198
199
0
    FuConstruct::Activate();
200
0
}
201
202
void FuConstRectangle::SetLineEnds(SfxItemSet& rAttr, const SdrObject& rObj, sal_uInt16 nSlotId)
203
0
{
204
0
    ConstructHelper::SetLineEnds(rAttr, rObj, nSlotId, 200);
205
0
}
206
207
void FuConstRectangle::Deactivate()
208
0
{
209
0
    sal_uInt16 nSlotId = aSfxRequest.GetSlot();
210
0
    if( nSlotId == SID_TOOL_CONNECTOR               ||
211
0
        nSlotId == SID_CONNECTOR_ARROW_START        ||
212
0
        nSlotId == SID_CONNECTOR_ARROW_END          ||
213
0
        nSlotId == SID_CONNECTOR_ARROWS             ||
214
0
        nSlotId == SID_CONNECTOR_CIRCLE_START       ||
215
0
        nSlotId == SID_CONNECTOR_CIRCLE_END         ||
216
0
        nSlotId == SID_CONNECTOR_CIRCLES            ||
217
0
        nSlotId == SID_CONNECTOR_LINE               ||
218
0
        nSlotId == SID_CONNECTOR_LINE_ARROW_START   ||
219
0
        nSlotId == SID_CONNECTOR_LINE_ARROW_END     ||
220
0
        nSlotId == SID_CONNECTOR_LINE_ARROWS        ||
221
0
        nSlotId == SID_CONNECTOR_LINE_CIRCLE_START  ||
222
0
        nSlotId == SID_CONNECTOR_LINE_CIRCLE_END    ||
223
0
        nSlotId == SID_CONNECTOR_LINE_CIRCLES       ||
224
0
        nSlotId == SID_CONNECTOR_CURVE              ||
225
0
        nSlotId == SID_CONNECTOR_CURVE_ARROW_START  ||
226
0
        nSlotId == SID_CONNECTOR_CURVE_ARROW_END    ||
227
0
        nSlotId == SID_CONNECTOR_CURVE_ARROWS       ||
228
0
        nSlotId == SID_CONNECTOR_CURVE_CIRCLE_START ||
229
0
        nSlotId == SID_CONNECTOR_CURVE_CIRCLE_END   ||
230
0
        nSlotId == SID_CONNECTOR_CURVE_CIRCLES      ||
231
0
        nSlotId == SID_CONNECTOR_LINES              ||
232
0
        nSlotId == SID_CONNECTOR_LINES_ARROW_START  ||
233
0
        nSlotId == SID_CONNECTOR_LINES_ARROW_END    ||
234
0
        nSlotId == SID_CONNECTOR_LINES_ARROWS       ||
235
0
        nSlotId == SID_CONNECTOR_LINES_CIRCLE_START ||
236
0
        nSlotId == SID_CONNECTOR_LINES_CIRCLE_END   ||
237
0
        nSlotId == SID_CONNECTOR_LINES_CIRCLES )
238
0
    {
239
0
        pView->SetEditMode(SdrViewEditMode::Edit);
240
0
    }
241
0
    FuConstruct::Deactivate();
242
0
    rViewShell.SetActivePointer( aOldPointer );
243
0
}
244
245
// Create default drawing objects via keyboard
246
rtl::Reference<SdrObject> FuConstRectangle::CreateDefaultObject(const sal_uInt16 nID, const tools::Rectangle& rRectangle)
247
0
{
248
0
    rtl::Reference<SdrObject> pObj(SdrObjFactory::MakeNewObject(
249
0
        rDrDoc,
250
0
        pView->GetCurrentObjInventor(),
251
0
        pView->GetCurrentObjIdentifier()));
252
253
0
    if(pObj)
254
0
    {
255
0
        tools::Rectangle aRect(rRectangle);
256
0
        Point aStart = aRect.TopLeft();
257
0
        Point aEnd = aRect.BottomRight();
258
259
0
        switch(nID)
260
0
        {
261
0
            case SID_DRAW_LINE:
262
0
            case SID_DRAW_XLINE:
263
0
            case SID_LINE_ARROW_END:
264
0
            case SID_LINE_ARROW_CIRCLE:
265
0
            case SID_LINE_ARROW_SQUARE:
266
0
            case SID_LINE_ARROW_START:
267
0
            case SID_LINE_CIRCLE_ARROW:
268
0
            case SID_LINE_SQUARE_ARROW:
269
0
            case SID_LINE_ARROWS:
270
0
            {
271
0
                if(auto pPathObj = dynamic_cast<SdrPathObj*>( pObj.get() ))
272
0
                {
273
0
                    sal_Int32 nYMiddle((aRect.Top() + aRect.Bottom()) / 2);
274
0
                    basegfx::B2DPolygon aPoly;
275
0
                    aPoly.append(basegfx::B2DPoint(aStart.X(), nYMiddle));
276
0
                    aPoly.append(basegfx::B2DPoint(aEnd.X(), nYMiddle));
277
0
                    pPathObj->SetPathPoly(basegfx::B2DPolyPolygon(aPoly));
278
0
                }
279
0
                else
280
0
                {
281
0
                    OSL_FAIL("Object is NO line object");
282
0
                }
283
284
0
                break;
285
0
            }
286
287
0
            case SID_DRAW_MEASURELINE:
288
0
            {
289
0
                if(auto pMeasureObj = dynamic_cast<SdrMeasureObj*>( pObj.get() ))
290
0
                {
291
0
                    sal_Int32 nYMiddle((aRect.Top() + aRect.Bottom()) / 2);
292
0
                    pMeasureObj->SetPoint(Point(aStart.X(), nYMiddle), 0);
293
0
                    pMeasureObj->SetPoint(Point(aEnd.X(), nYMiddle), 1);
294
0
                }
295
296
0
                break;
297
0
            }
298
299
0
            case SID_DRAW_CAPTION:
300
0
            case SID_DRAW_CAPTION_VERTICAL:
301
0
            {
302
0
                if(auto pCaptionObj = dynamic_cast<SdrCaptionObj*>( pObj.get() ))
303
0
                {
304
0
                    bool bIsVertical(SID_DRAW_CAPTION_VERTICAL == nID);
305
306
0
                    pCaptionObj->SetVerticalWriting(bIsVertical);
307
308
0
                    if(bIsVertical)
309
0
                    {
310
0
                        SfxItemSet aSet(pObj->GetMergedItemSet());
311
0
                        aSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER));
312
0
                        aSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT));
313
0
                        pObj->SetMergedItemSet(aSet);
314
0
                    }
315
316
                    //  don't set default text, start edit mode instead
317
                    //  (Edit mode is started in ScTabViewShell::ExecDraw, because
318
                    //  it must be handled by FuText)
319
320
0
                    pCaptionObj->SetLogicRect(aRect);
321
0
                    pCaptionObj->SetTailPos(
322
0
                        aRect.TopLeft() - Point(aRect.GetWidth() / 2, aRect.GetHeight() / 2));
323
0
                }
324
0
                else
325
0
                {
326
0
                    OSL_FAIL("Object is NO caption object");
327
0
                }
328
329
0
                break;
330
0
            }
331
332
0
            case SID_TOOL_CONNECTOR:
333
0
            case SID_CONNECTOR_ARROW_START:
334
0
            case SID_CONNECTOR_ARROW_END:
335
0
            case SID_CONNECTOR_ARROWS:
336
0
            case SID_CONNECTOR_CIRCLE_START:
337
0
            case SID_CONNECTOR_CIRCLE_END:
338
0
            case SID_CONNECTOR_CIRCLES:
339
0
            case SID_CONNECTOR_LINE:
340
0
            case SID_CONNECTOR_LINE_ARROW_START:
341
0
            case SID_CONNECTOR_LINE_ARROW_END:
342
0
            case SID_CONNECTOR_LINE_ARROWS:
343
0
            case SID_CONNECTOR_LINE_CIRCLE_START:
344
0
            case SID_CONNECTOR_LINE_CIRCLE_END:
345
0
            case SID_CONNECTOR_LINE_CIRCLES:
346
0
            case SID_CONNECTOR_CURVE:
347
0
            case SID_CONNECTOR_CURVE_ARROW_START:
348
0
            case SID_CONNECTOR_CURVE_ARROW_END:
349
0
            case SID_CONNECTOR_CURVE_ARROWS:
350
0
            case SID_CONNECTOR_CURVE_CIRCLE_START:
351
0
            case SID_CONNECTOR_CURVE_CIRCLE_END:
352
0
            case SID_CONNECTOR_CURVE_CIRCLES:
353
0
            case SID_CONNECTOR_LINES:
354
0
            case SID_CONNECTOR_LINES_ARROW_START:
355
0
            case SID_CONNECTOR_LINES_ARROW_END:
356
0
            case SID_CONNECTOR_LINES_ARROWS:
357
0
            case SID_CONNECTOR_LINES_CIRCLE_START:
358
0
            case SID_CONNECTOR_LINES_CIRCLE_END:
359
0
            case SID_CONNECTOR_LINES_CIRCLES:
360
0
            {
361
0
                if( auto pEdgeObj = dynamic_cast< SdrEdgeObj *>( pObj.get() ) )
362
0
                {
363
0
                    pEdgeObj->SetTailPoint(false, aStart);
364
0
                    pEdgeObj->SetTailPoint(true, aEnd);
365
0
                }
366
0
                else
367
0
                {
368
0
                    OSL_FAIL("Object is NO connector object");
369
0
                }
370
371
0
                break;
372
0
            }
373
374
0
            default:
375
0
            {
376
0
                pObj->SetLogicRect(aRect);
377
378
0
                break;
379
0
            }
380
0
        }
381
382
0
        SfxItemSet aAttr(rDrDoc.GetItemPool());
383
0
        SetLineEnds(aAttr, *pObj, nID);
384
0
        pObj->SetMergedItemSet(aAttr);
385
0
    }
386
387
0
    return pObj;
388
0
}
389
390
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */