Coverage Report

Created: 2026-10-14 09:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sd/source/ui/table/tablefunction.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 <sal/config.h>
21
#include <com/sun/star/uno/XComponentContext.hpp>
22
#include <com/sun/star/drawing/XSelectionFunction.hpp>
23
24
#include <comphelper/lok.hxx>
25
26
#include <svx/svdotable.hxx>
27
#include <svx/svxids.hrc>
28
#include <svx/svdpagv.hxx>
29
#include <svx/svxdlg.hxx>
30
31
#include <svl/intitem.hxx>
32
#include <svl/stritem.hxx>
33
#include <sfx2/viewfrm.hxx>
34
#include <sfx2/bindings.hxx>
35
#include <sfx2/request.hxx>
36
#include <sfx2/sidebar/Sidebar.hxx>
37
#include <svl/style.hxx>
38
#include <comphelper/diagnose_ex.hxx>
39
40
#include <tablefunction.hxx>
41
#include <DrawViewShell.hxx>
42
#include <drawdoc.hxx>
43
#include <sdpage.hxx>
44
#include <Window.hxx>
45
#include <drawview.hxx>
46
#include <sdmod.hxx>
47
48
#include <memory>
49
50
using namespace ::sd;
51
using namespace sdr::table;
52
using namespace ::com::sun::star;
53
using namespace ::com::sun::star::uno;
54
using namespace ::com::sun::star::container;
55
56
namespace sd
57
{
58
59
static void apply_table_style( SdrTableObj* pObj, SdrModel const * pModel, const OUString& sTableStyle )
60
0
{
61
0
    if( !(pModel && pObj) )
62
0
        return;
63
64
0
    Reference< XNameAccess > xPool(
65
0
        static_cast< cppu::OWeakObject* >( pModel->GetStyleSheetPool() ), css::uno::UNO_QUERY );
66
0
    if( !xPool.is() )
67
0
        return;
68
69
0
    try
70
0
    {
71
0
        Reference< XNameContainer > xTableFamily( xPool->getByName( u"table"_ustr ), UNO_QUERY_THROW );
72
0
        OUString aStdName( u"default"_ustr );
73
0
        if( !sTableStyle.isEmpty() )
74
0
            aStdName = sTableStyle;
75
0
        Reference< XIndexAccess > xStyle( xTableFamily->getByName( aStdName ), UNO_QUERY_THROW );
76
0
        pObj->setTableStyle( xStyle );
77
0
    }
78
0
    catch( Exception& )
79
0
    {
80
0
        TOOLS_WARN_EXCEPTION( "sd", "sd::apply_default_table_style()");
81
0
    }
82
0
}
83
84
static void InsertTableImpl(const DrawViewShell* pShell,
85
                            ::sd::View* pView,
86
                            sal_Int32 nColumns,
87
                            sal_Int32 nRows,
88
                            const OUString& sTableStyle)
89
0
{
90
0
    ::tools::Rectangle aRect;
91
92
0
    SdrObject* pPickObj = pView->GetEmptyPresentationObject( PresObjKind::Table );
93
0
    if( pPickObj )
94
0
    {
95
0
        aRect = pPickObj->GetLogicRect();
96
0
        aRect.setHeight( 200 );
97
0
    }
98
0
    else
99
0
    {
100
0
        Size aSize(14100, 200);
101
102
0
        Point aPos;
103
0
        ::tools::Rectangle aWinRect(aPos, pShell->GetActiveWindow()->GetOutputSizePixel());
104
0
        aWinRect = pShell->GetActiveWindow()->PixelToLogic(aWinRect);
105
106
        // make sure that the default size of the table fits on the paper and is inside the viewing area.
107
        // if zoomed in close, don't make the table bigger than the viewing window.
108
0
        Size aMaxSize = pShell->getCurrentPage()->GetSize();
109
110
0
        if (comphelper::LibreOfficeKit::isActive())
111
0
        {
112
            // aWinRect is nonsensical in the LOK case
113
0
            aWinRect = ::tools::Rectangle(aPos, aMaxSize);
114
0
        }
115
0
        else
116
0
        {
117
0
            if( aMaxSize.Height() > aWinRect.getOpenHeight() )
118
0
                aMaxSize.setHeight( aWinRect.getOpenHeight() );
119
0
            if( aMaxSize.Width() > aWinRect.getOpenWidth() )
120
0
                aMaxSize.setWidth( aWinRect.getOpenWidth() );
121
0
        }
122
123
0
        if( aSize.Width() > aMaxSize.getWidth() )
124
0
            aSize.setWidth( aMaxSize.getWidth() );
125
126
        // adjust height based on # of rows.
127
0
        if( nRows > 0 )
128
0
        {
129
0
            aSize.setHeight( aSize.Height() * nRows );
130
0
            if( aSize.Height() > aMaxSize.getHeight() )
131
0
                aSize.setHeight( aMaxSize.getHeight() );
132
0
        }
133
134
0
        aPos = aWinRect.Center();
135
0
        aPos.AdjustX( -(aSize.Width() / 2) );
136
0
        aPos.AdjustY( -(aSize.Height() / 2) );
137
0
        aRect = ::tools::Rectangle(aPos, aSize);
138
0
    }
139
140
0
    rtl::Reference<sdr::table::SdrTableObj> pObj = new sdr::table::SdrTableObj(
141
0
        *pShell->GetDoc(), // TTTT should be reference
142
0
        aRect,
143
0
        nColumns,
144
0
        nRows);
145
0
    pObj->NbcSetStyleSheet( pShell->GetDoc()->GetDefaultStyleSheet(), true );
146
0
    apply_table_style( pObj.get(), pShell->GetDoc(), sTableStyle );
147
0
    SdrPageView* pPV = pView->GetSdrPageView();
148
149
    // #i123359# if an object is to be replaced/manipulated it may be that it is in text edit mode,
150
    // so to be on the safe side call SdrEndTextEdit here
151
0
    SdrTextObj* pCheckForTextEdit = DynCastSdrTextObj(pPickObj);
152
153
0
    if(pCheckForTextEdit && pCheckForTextEdit->IsInEditMode())
154
0
    {
155
0
        pView->SdrEndTextEdit();
156
0
    }
157
158
    // if we have a pick obj we need to make this new ole a pres obj replacing the current pick obj
159
0
    if( pPickObj )
160
0
    {
161
0
        SdPage* pPage = static_cast< SdPage* >(pPickObj->getSdrPageFromSdrObject());
162
0
        if(pPage && pPage->IsPresObj(pPickObj))
163
0
        {
164
0
            pObj->SetUserCall( pPickObj->GetUserCall() );
165
0
            pPage->InsertPresObj( pObj.get(), PresObjKind::Table );
166
0
        }
167
0
    }
168
169
0
    pShell->GetParentWindow()->GrabFocus();
170
0
    if( pPickObj )
171
0
        pView->ReplaceObjectAtView(pPickObj, *pPV, pObj.get() );
172
0
    else
173
0
        pView->InsertObjectAtView(pObj.get(), *pPV, SdrInsertFlags::SETDEFLAYER);
174
0
}
175
176
void DrawViewShell::FuTable(SfxRequest& rReq)
177
0
{
178
0
    switch( rReq.GetSlot() )
179
0
    {
180
0
    case SID_INSERT_TABLE:
181
0
    {
182
0
        sal_Int32 nColumns = 0;
183
0
        sal_Int32 nRows = 0;
184
0
        OUString sTableStyle;
185
0
        DrawViewShell* pShell = this;
186
0
        ::sd::View* pView = mpView;
187
188
0
        const SfxUInt16Item* pCols = rReq.GetArg(SID_ATTR_TABLE_COLUMN);
189
0
        const SfxUInt16Item* pRows = rReq.GetArg(SID_ATTR_TABLE_ROW);
190
0
        const SfxStringItem* pStyle = rReq.GetArg(SID_TABLE_STYLE);
191
192
0
        if( pCols )
193
0
            nColumns = pCols->GetValue();
194
195
0
        if( pRows )
196
0
            nRows = pRows->GetValue();
197
198
0
        if( pStyle )
199
0
            sTableStyle = pStyle->GetValue();
200
201
0
        if( (nColumns == 0) || (nRows == 0) )
202
0
        {
203
0
            SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
204
0
            std::shared_ptr<SvxAbstractNewTableDialog> pDlg( pFact->CreateSvxNewTableDialog(rReq.GetFrameWeld()) );
205
206
0
            weld::DialogController::runAsync(pDlg->getDialogController(),
207
0
                [pDlg, pShell, pView, sTableStyle] (sal_Int32 nResult) {
208
0
                    if (nResult == RET_OK)
209
0
                    {
210
0
                        sal_Int32 nColumnsIn = pDlg->getColumns();
211
0
                        sal_Int32 nRowsIn = pDlg->getRows();
212
213
0
                        InsertTableImpl(pShell, pView, nColumnsIn, nRowsIn, sTableStyle);
214
0
                    }
215
0
                });
216
0
        }
217
0
        else
218
0
        {
219
0
            InsertTableImpl(pShell, pView, nColumns, nRows, sTableStyle);
220
0
        }
221
222
0
        rReq.Ignore();
223
0
        SfxViewShell* pViewShell = GetViewShell();
224
0
        assert(pViewShell!=nullptr);
225
0
        SfxBindings& rBindings = pViewShell->GetViewFrame().GetBindings();
226
0
        rBindings.Invalidate( SID_INSERT_TABLE, true );
227
0
        break;
228
0
    }
229
0
    case SID_TABLEDESIGN:
230
0
    {
231
        // First make sure that the sidebar is visible
232
0
        if (SfxViewFrame* pViewFrame = GetViewFrame())
233
0
        {
234
0
            pViewFrame->ShowChildWindow(SID_SIDEBAR);
235
0
            ::sfx2::sidebar::Sidebar::TogglePanel(
236
0
                u"SdTableDesignPanel",
237
0
                pViewFrame->GetFrame().GetFrameInterface());
238
239
0
            Cancel();
240
0
            rReq.Done ();
241
0
        }
242
0
        break;
243
0
    }
244
0
    default:
245
0
        break;
246
0
    }
247
0
}
248
249
void DrawViewShell::GetTableMenuState( SfxItemSet &rSet )
250
0
{
251
0
    OUString aActiveLayer = mpDrawView->GetActiveLayer();
252
0
    SdrPageView* pPV = mpDrawView->GetSdrPageView();
253
254
0
    if(
255
0
        ( !aActiveLayer.isEmpty() && pPV && ( pPV->IsLayerLocked(aActiveLayer) ||
256
0
        !pPV->IsLayerVisible(aActiveLayer) ) ) ||
257
0
        SdModule::get()->GetWaterCan() )
258
0
    {
259
0
        rSet.DisableItem( SID_INSERT_TABLE );
260
0
    }
261
0
}
262
263
void CreateTableFromRTF( SvStream& rStream, SdDrawDocument* pModel )
264
0
{
265
0
    rStream.Seek( 0 );
266
267
0
    if( !pModel )
268
0
        return;
269
270
0
    SdrPage* pPage = pModel->GetPage(0);
271
0
    if( !pPage )
272
0
        return;
273
274
0
    Size aSize( 200, 200 );
275
0
    ::tools::Rectangle aRect (Point(), aSize);
276
0
    rtl::Reference<sdr::table::SdrTableObj> pObj = new sdr::table::SdrTableObj(
277
0
        *pModel,
278
0
        aRect,
279
0
        1,
280
0
        1);
281
0
    pObj->NbcSetStyleSheet( pModel->GetDefaultStyleSheet(), true );
282
0
    apply_table_style( pObj.get(), pModel, OUString() );
283
284
0
    pPage->NbcInsertObject( pObj.get() );
285
286
0
    sdr::table::ImportAsRTF( rStream, *pObj );
287
0
}
288
289
void CreateTableFromHTML(SvStream& rStream, SdDrawDocument* pModel)
290
0
{
291
0
    rStream.Seek( 0 );
292
293
0
    if( !pModel )
294
0
        return;
295
296
0
    SdrPage* pPage = pModel->GetPage(0);
297
0
    if( !pPage )
298
0
        return;
299
300
0
    Size aSize( 200, 200 );
301
0
    ::tools::Rectangle aRect (Point(), aSize);
302
0
    rtl::Reference<sdr::table::SdrTableObj> pObj = new sdr::table::SdrTableObj(
303
0
        *pModel,
304
0
        aRect,
305
0
        1,
306
0
        1);
307
0
    pObj->NbcSetStyleSheet( pModel->GetDefaultStyleSheet(), true );
308
0
    apply_table_style( pObj.get(), pModel, OUString() );
309
310
0
    pPage->NbcInsertObject( pObj.get() );
311
312
0
    sdr::table::ImportAsHTML( rStream, *pObj );
313
0
}
314
315
}
316
317
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */