Coverage Report

Created: 2025-12-31 10:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sw/source/uibase/shells/tabsh.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 <hintids.hxx>
21
#include <svl/imageitm.hxx>
22
#include <svl/numformat.hxx>
23
#include <svl/zforlist.hxx>
24
#include <svl/stritem.hxx>
25
#include <svl/whiter.hxx>
26
#include <unotools/moduleoptions.hxx>
27
#include <editeng/lrspitem.hxx>
28
#include <editeng/ulspitem.hxx>
29
#include <editeng/brushitem.hxx>
30
#include <editeng/boxitem.hxx>
31
#include <editeng/shaditem.hxx>
32
#include <editeng/spltitem.hxx>
33
#include <editeng/keepitem.hxx>
34
#include <editeng/lineitem.hxx>
35
#include <editeng/colritem.hxx>
36
#include <editeng/frmdiritem.hxx>
37
#include <svx/numinf.hxx>
38
#include <svx/svddef.hxx>
39
#include <svx/svxdlg.hxx>
40
#include <sfx2/bindings.hxx>
41
#include <vcl/weld/weld.hxx>
42
#include <sfx2/request.hxx>
43
#include <sfx2/dispatch.hxx>
44
#include <sfx2/objface.hxx>
45
#include <sfx2/viewfrm.hxx>
46
#include <vcl/EnumContext.hxx>
47
#include <o3tl/enumrange.hxx>
48
#include <comphelper/lok.hxx>
49
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
50
#include <editeng/itemtype.hxx>
51
#include <osl/diagnose.h>
52
53
#include <fmtornt.hxx>
54
#include <fmtlsplt.hxx>
55
#include <fmtrowsplt.hxx>
56
#include <fmtfsize.hxx>
57
#include <swmodule.hxx>
58
#include <wrtsh.hxx>
59
#include <rootfrm.hxx>
60
#include <wview.hxx>
61
#include <frmatr.hxx>
62
#include <uitool.hxx>
63
#include <inputwin.hxx>
64
#include <uiitems.hxx>
65
#include <tabsh.hxx>
66
#include <swtablerep.hxx>
67
#include <tablemgr.hxx>
68
#include <cellatr.hxx>
69
#include <frmfmt.hxx>
70
#include <swundo.hxx>
71
#include <swtable.hxx>
72
#include <docsh.hxx>
73
#include <tblsel.hxx>
74
#include <viewopt.hxx>
75
#include <tabfrm.hxx>
76
#include <frame.hxx>
77
#include <pagefrm.hxx>
78
#include <cntfrm.hxx>
79
80
#include <strings.hrc>
81
#include <cmdid.h>
82
#include <unobaseclass.hxx>
83
84
#define ShellClass_SwTableShell
85
#include <sfx2/msg.hxx>
86
#include <swslots.hxx>
87
88
#include <swabstdlg.hxx>
89
90
#include <memory>
91
92
using ::editeng::SvxBorderLine;
93
using namespace ::com::sun::star;
94
95
SFX_IMPL_INTERFACE(SwTableShell, SwBaseShell)
96
97
void SwTableShell::InitInterface_Impl()
98
9
{
99
9
    GetStaticInterface()->RegisterPopupMenu(u"table"_ustr);
100
9
    GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Invisible, ToolbarId::Table_Toolbox);
101
9
}
102
103
104
const WhichRangesContainer aUITableAttrRange(svl::Items<
105
    RES_LR_SPACE,                   RES_UL_SPACE,
106
    RES_PAGEDESC,                   RES_BREAK,
107
    RES_BACKGROUND,                 RES_BACKGROUND,
108
    RES_BOX,                        RES_SHADOW,
109
    RES_KEEP,                       RES_KEEP,
110
    RES_LAYOUT_SPLIT,               RES_LAYOUT_SPLIT,
111
    RES_FRAMEDIR,                   RES_FRAMEDIR,
112
    RES_ROW_SPLIT,                  RES_ROW_SPLIT,
113
// #i29550#
114
    RES_COLLAPSING_BORDERS,         RES_COLLAPSING_BORDERS,
115
// <-- collapsing borders
116
    XATTR_FILL_FIRST,               XATTR_FILL_LAST,
117
    SID_ATTR_BORDER_INNER,          SID_ATTR_BORDER_SHADOW,
118
    SID_RULER_BORDERS,              SID_RULER_BORDERS,
119
    SID_ATTR_BRUSH_ROW,             SID_ATTR_BRUSH_TABLE, // ??? This is very strange range
120
//  SID_BACKGRND_DESTINATION,       SID_BACKGRND_DESTINATION, // included into above
121
//  SID_HTML_MODE,                  SID_HTML_MODE, // included into above
122
    FN_TABLE_REP,                   FN_TABLE_REP,
123
    FN_TABLE_SET_VERT_ALIGN,        FN_TABLE_SET_VERT_ALIGN,
124
    FN_TABLE_BOX_TEXTORIENTATION,   FN_TABLE_BOX_TEXTORIENTATION,
125
    FN_PARAM_TABLE_NAME,            FN_PARAM_TABLE_NAME,
126
    FN_PARAM_TABLE_HEADLINE,        FN_PARAM_TABLE_HEADLINE
127
>);
128
129
const WhichRangesContainer& SwuiGetUITableAttrRange()
130
0
{
131
0
    return aUITableAttrRange;
132
0
}
133
134
static void lcl_SetAttr( SwWrtShell &rSh, const SfxPoolItem &rItem )
135
0
{
136
0
    SfxItemSet aSet( rSh.GetView().GetPool(), rItem.Which(), rItem.Which());
137
0
    aSet.Put( rItem );
138
0
    rSh.SetTableAttr( aSet );
139
0
}
140
141
static std::shared_ptr<SwTableRep> lcl_TableParamToItemSet( SfxItemSet& rSet, SwWrtShell &rSh )
142
0
{
143
0
    std::shared_ptr<SwTableRep> pRep;
144
145
0
    SwFrameFormat *pFormat = rSh.GetTableFormat();
146
0
    SwTabCols aCols;
147
0
    rSh.GetTabCols( aCols );
148
149
    //At first get the simple attributes.
150
0
    rSet.Put( SfxStringItem( FN_PARAM_TABLE_NAME, pFormat->GetName().toString()));
151
0
    rSet.Put( SfxUInt16Item( FN_PARAM_TABLE_HEADLINE, rSh.GetRowsToRepeat() ) );
152
0
    rSet.Put( pFormat->GetShadow() );
153
0
    rSet.Put(SfxUInt16Item(FN_TABLE_SET_VERT_ALIGN, rSh.GetBoxAlign()));
154
0
    rSet.Put( pFormat->GetFrameDir() );
155
156
0
    SvxULSpaceItem aULSpace( pFormat->GetULSpace() );
157
0
    rSet.Put( aULSpace );
158
159
0
    const sal_uInt16  nBackgroundDestination = rSh.GetViewOptions()->GetTableDest();
160
0
    rSet.Put(SfxUInt16Item(SID_BACKGRND_DESTINATION, nBackgroundDestination ));
161
0
    std::unique_ptr<SvxBrushItem> aBrush(std::make_unique<SvxBrushItem>(RES_BACKGROUND));
162
0
    if(rSh.GetRowBackground(aBrush))
163
0
    {
164
0
        aBrush->SetWhich(SID_ATTR_BRUSH_ROW);
165
0
        rSet.Put( *aBrush );
166
0
    }
167
0
    else
168
0
        rSet.InvalidateItem(SID_ATTR_BRUSH_ROW);
169
0
    rSh.GetTabBackground(aBrush);
170
0
    aBrush->SetWhich(SID_ATTR_BRUSH_TABLE);
171
0
    rSet.Put( *aBrush );
172
173
    // text direction in boxes
174
0
    std::unique_ptr<SvxFrameDirectionItem> aBoxDirection(std::make_unique<SvxFrameDirectionItem>(SvxFrameDirection::Environment, RES_FRAMEDIR));
175
0
    if(rSh.GetBoxDirection( aBoxDirection ))
176
0
    {
177
0
        aBoxDirection->SetWhich(FN_TABLE_BOX_TEXTORIENTATION);
178
0
        rSet.Put(*aBoxDirection);
179
0
    }
180
181
0
    bool bSelectAll = rSh.StartsWith_() == SwCursorShell::StartsWith::Table && rSh.ExtendedSelectedAll();
182
0
    bool bTableSel = rSh.IsTableMode() || bSelectAll;
183
0
    if(!bTableSel)
184
0
    {
185
0
        rSh.StartAllAction();
186
0
        rSh.Push();
187
0
        rSh.GetView().GetViewFrame().GetDispatcher()->Execute( FN_TABLE_SELECT_ALL );
188
0
    }
189
0
    SvxBoxInfoItem aBoxInfo( SID_ATTR_BORDER_INNER );
190
191
    // Table variant: If multiple table cells are selected.
192
0
    rSh.GetCursor();                  //Thus GetCursorCnt() returns the right thing
193
0
    aBoxInfo.SetTable          ((rSh.IsTableMode() && rSh.GetCursorCnt() > 1) ||
194
0
                                    !bTableSel);
195
    // Always show distance field.
196
0
    aBoxInfo.SetDist           (true);
197
    // Set minimum size in tables and paragraphs.
198
0
    aBoxInfo.SetMinDist( !bTableSel || rSh.IsTableMode() ||
199
0
                            rSh.GetSelectionType() &
200
0
                            (SelectionType::Text | SelectionType::Table));
201
    // Always set the default spacing.
202
0
    aBoxInfo.SetDefDist        (MIN_BORDER_DIST);
203
    // Individual lines can have DontCare status only in tables.
204
0
    aBoxInfo.SetValid( SvxBoxInfoItemValidFlags::DISABLE, !bTableSel || !rSh.IsTableMode() );
205
206
0
    rSet.Put(aBoxInfo);
207
0
    rSh.GetTabBorders( rSet );
208
209
    //row split
210
0
    std::unique_ptr<SwFormatRowSplit> pSplit = rSh.GetRowSplit();
211
0
    if(pSplit)
212
0
        rSet.Put(std::move(pSplit));
213
214
0
    if(!bTableSel)
215
0
    {
216
0
        rSh.ClearMark();
217
0
        rSh.Pop(SwCursorShell::PopMode::DeleteCurrent);
218
0
        rSh.EndAllAction();
219
0
    }
220
221
0
    SwTabCols aTabCols;
222
0
    rSh.GetTabCols( aTabCols );
223
224
    // Pointer will be deleted after the dialogue execution.
225
0
    pRep = std::make_shared<SwTableRep>(aTabCols);
226
0
    pRep->SetSpace(aCols.GetRightMax());
227
228
0
    sal_uInt16 nPercent = 0;
229
0
    auto nWidth = ::GetTableWidth(pFormat, aCols, &nPercent, &rSh );
230
    // The table width is wrong for relative values.
231
0
    if (nPercent)
232
0
        nWidth = pRep->GetSpace() * nPercent / 100;
233
0
    const sal_uInt16 nAlign = pFormat->GetHoriOrient().GetHoriOrient();
234
0
    pRep->SetAlign(nAlign);
235
0
    SvxLRSpaceItem aLRSpace( pFormat->GetLRSpace() );
236
0
    SwTwips nLeft = aLRSpace.ResolveLeft({});
237
0
    SwTwips nRight = aLRSpace.ResolveRight({});
238
0
    if(nAlign != text::HoriOrientation::FULL)
239
0
    {
240
0
        SwTwips nLR = pRep->GetSpace() - nWidth;
241
0
        switch ( nAlign )
242
0
        {
243
0
            case text::HoriOrientation::CENTER:
244
0
                nLeft = nRight = nLR / 2;
245
0
                break;
246
0
            case text::HoriOrientation::LEFT:
247
0
                nRight = nLR;
248
0
                nLeft = 0;
249
0
                break;
250
0
            case text::HoriOrientation::RIGHT:
251
0
                nLeft = nLR;
252
0
                nRight = 0;
253
0
                break;
254
0
            case text::HoriOrientation::LEFT_AND_WIDTH:
255
0
                nRight = nLR - nLeft;
256
0
                break;
257
0
            case text::HoriOrientation::NONE:
258
0
                if(!nPercent)
259
0
                    nWidth = pRep->GetSpace() - nLeft - nRight;
260
0
                break;
261
0
        }
262
0
    }
263
0
    pRep->SetLeftSpace(nLeft);
264
0
    pRep->SetRightSpace(nRight);
265
266
0
    pRep->SetWidth(nWidth);
267
0
    pRep->SetWidthPercent(nPercent);
268
    // Are individual rows / cells are selected, the column processing will be changed.
269
0
    pRep->SetLineSelected(bTableSel && ! rSh.HasWholeTabSelection());
270
0
    rSet.Put(SwPtrItem(FN_TABLE_REP, pRep.get()));
271
0
    return pRep;
272
0
}
273
274
void ItemSetToTableParam( const SfxItemSet& rSet,
275
                                SwWrtShell &rSh )
276
0
{
277
0
    rSh.StartAllAction();
278
0
    rSh.StartUndo( SwUndoId::TABLE_ATTR );
279
280
0
    if(const SfxUInt16Item* pDestItem = rSet.GetItemIfSet(SID_BACKGRND_DESTINATION, false))
281
0
    {
282
0
        SwViewOption aUsrPref( *rSh.GetViewOptions() );
283
0
        aUsrPref.SetTableDest(static_cast<sal_uInt8>(pDestItem->GetValue()));
284
0
        SwModule::get()->ApplyUsrPref(aUsrPref, &rSh.GetView());
285
0
    }
286
0
    bool bBorder = ( SfxItemState::SET == rSet.GetItemState( RES_BOX ) ||
287
0
            SfxItemState::SET == rSet.GetItemState( SID_ATTR_BORDER_INNER ) );
288
0
    const SvxBrushItem* pBackgroundItem = rSet.GetItemIfSet( RES_BACKGROUND, false );
289
0
    const SvxBrushItem* pRowItem = rSet.GetItemIfSet( SID_ATTR_BRUSH_ROW, false );
290
0
    const SvxBrushItem* pTableItem = rSet.GetItemIfSet( SID_ATTR_BRUSH_TABLE, false );
291
0
    bool bBackground = pBackgroundItem || pRowItem || pTableItem;
292
0
    const SwFormatRowSplit* pSplit = rSet.GetItemIfSet( RES_ROW_SPLIT, false );
293
0
    bool bRowSplit = pSplit != nullptr;
294
0
    const SvxFrameDirectionItem* pBoxDirection = rSet.GetItemIfSet( FN_TABLE_BOX_TEXTORIENTATION, false );
295
0
    bool bBoxDirection = pBoxDirection != nullptr;
296
0
    if( bBackground || bBorder || bRowSplit || bBoxDirection)
297
0
    {
298
        // The border will be applied to the present selection.
299
        // If there is no selection, the table will be completely selected.
300
        // The background will always be applied to the current state.
301
0
        bool bTableSel = rSh.IsTableMode();
302
0
        rSh.StartAllAction();
303
304
0
        if(bBackground)
305
0
        {
306
0
            if(pBackgroundItem)
307
0
                rSh.SetBoxBackground( *pBackgroundItem );
308
0
            if(pRowItem)
309
0
            {
310
0
                std::unique_ptr<SvxBrushItem> aBrush(pRowItem->Clone());
311
0
                aBrush->SetWhich(RES_BACKGROUND);
312
0
                rSh.SetRowBackground(*aBrush);
313
0
            }
314
0
            if(pTableItem)
315
0
            {
316
0
                std::unique_ptr<SvxBrushItem> aBrush(pTableItem->Clone());
317
0
                aBrush->SetWhich(RES_BACKGROUND);
318
0
                rSh.SetTabBackground( *aBrush );
319
0
            }
320
0
        }
321
322
0
        if(bBoxDirection)
323
0
        {
324
0
            SvxFrameDirectionItem aDirection( SvxFrameDirection::Environment, RES_FRAMEDIR );
325
0
            aDirection.SetValue(pBoxDirection->GetValue());
326
0
            rSh.SetBoxDirection(aDirection);
327
0
        }
328
329
0
        if(bBorder || bRowSplit)
330
0
        {
331
0
            rSh.Push();
332
0
            if(!bTableSel)
333
0
            {
334
0
                rSh.GetView().GetViewFrame().GetDispatcher()->Execute( FN_TABLE_SELECT_ALL );
335
0
            }
336
0
            if(bBorder)
337
0
                rSh.SetTabBorders( rSet );
338
339
0
            if(bRowSplit)
340
0
            {
341
0
                rSh.SetRowSplit(*pSplit);
342
0
            }
343
344
0
            if(!bTableSel)
345
0
            {
346
0
                rSh.ClearMark();
347
0
            }
348
0
            rSh.Pop(SwCursorShell::PopMode::DeleteCurrent);
349
0
        }
350
351
0
        rSh.EndAllAction();
352
0
    }
353
354
0
    SwTabCols aTabCols;
355
0
    bool bTabCols = false;
356
0
    SwTableRep* pRep = nullptr;
357
0
    SwFrameFormat *pFormat = rSh.GetTableFormat();
358
0
    SfxItemSetFixed<RES_FRMATR_BEGIN, RES_FRMATR_END-1> aSet( rSh.GetAttrPool() );
359
0
    if(const SwPtrItem* pRepItem = rSet.GetItemIfSet( FN_TABLE_REP, false ))
360
0
    {
361
0
        pRep = static_cast<SwTableRep*>(pRepItem->GetValue());
362
363
0
        const SwTwips nWidth = pRep->GetWidth();
364
0
        if ( text::HoriOrientation::FULL == pRep->GetAlign() )
365
0
        {
366
0
            SwFormatHoriOrient aAttr( pFormat->GetHoriOrient() );
367
0
            aAttr.SetHoriOrient( text::HoriOrientation::FULL );
368
0
            aSet.Put( aAttr );
369
0
        }
370
0
        else
371
0
        {
372
0
            SwFormatFrameSize aSz( SwFrameSize::Variable, nWidth );
373
0
            if(pRep->GetWidthPercent())
374
0
            {
375
0
                aSz.SetWidthPercent( static_cast<sal_uInt8>(pRep->GetWidthPercent()) );
376
0
            }
377
0
            aSet.Put(aSz);
378
0
        }
379
380
0
        SvxLRSpaceItem aLRSpace( RES_LR_SPACE );
381
0
        aLRSpace.SetLeft(SvxIndentValue::twips(pRep->GetLeftSpace()));
382
0
        aLRSpace.SetRight(SvxIndentValue::twips(pRep->GetRightSpace()));
383
0
        aSet.Put( aLRSpace );
384
385
0
        sal_Int16 eOrient = pRep->GetAlign();
386
0
        SwFormatHoriOrient aAttr( 0, eOrient );
387
0
        aSet.Put( aAttr );
388
        // The item must only be recorded while manual alignment, so that the
389
        // alignment is not overwritten by the distances while recording.
390
0
        if(eOrient != text::HoriOrientation::NONE)
391
0
            const_cast<SfxItemSet&>(rSet).ClearItem( SID_ATTR_LRSPACE );
392
393
0
        if(pRep->HasColsChanged())
394
0
        {
395
0
            bTabCols = true;
396
0
        }
397
0
    }
398
399
0
    if( const SfxUInt16Item* pHeadlineItem = rSet.GetItemIfSet( FN_PARAM_TABLE_HEADLINE, false ))
400
0
        rSh.SetRowsToRepeat( pHeadlineItem->GetValue() );
401
402
0
    if( const SfxUInt16Item* pAlignItem = rSet.GetItemIfSet( FN_TABLE_SET_VERT_ALIGN, false ))
403
0
        rSh.SetBoxAlign(pAlignItem->GetValue());
404
405
0
    if( const SfxStringItem* pNameItem = rSet.GetItemIfSet( FN_PARAM_TABLE_NAME, false ))
406
0
        rSh.SetTableName( *pFormat, UIName(pNameItem->GetValue()) );
407
408
    // Copy the chosen attributes in the ItemSet.
409
0
    static const sal_uInt16 aIds[] =
410
0
        {
411
0
            RES_PAGEDESC,
412
0
            RES_BREAK,
413
0
            RES_KEEP,
414
0
            RES_LAYOUT_SPLIT,
415
0
            RES_UL_SPACE,
416
0
            RES_SHADOW,
417
0
            RES_FRAMEDIR,
418
            // #i29550#
419
0
            RES_COLLAPSING_BORDERS,
420
            // <-- collapsing borders
421
0
            0
422
0
        };
423
0
    const SfxPoolItem* pItem = nullptr;
424
0
    for( const sal_uInt16* pIds = aIds; *pIds; ++pIds )
425
0
        if( SfxItemState::SET == rSet.GetItemState( *pIds, false, &pItem))
426
0
            aSet.Put( *pItem );
427
428
0
    if(bTabCols)
429
0
    {
430
0
        rSh.GetTabCols( aTabCols );
431
0
        bool bSingleLine = pRep->FillTabCols( aTabCols );
432
0
        rSh.SetTabCols( aTabCols, bSingleLine );
433
0
    }
434
435
0
    if( aSet.Count() )
436
0
        rSh.SetTableAttr( aSet );
437
438
0
    rSh.EndUndo( SwUndoId::TABLE_ATTR );
439
0
    rSh.EndAllAction();
440
0
}
441
442
static void lcl_TabGetMaxLineWidth(const SvxBorderLine* pBorderLine, SvxBorderLine& rBorderLine)
443
0
{
444
0
    if(pBorderLine->GetWidth() > rBorderLine.GetWidth())
445
0
        rBorderLine.SetWidth(pBorderLine->GetWidth());
446
447
0
    rBorderLine.SetBorderLineStyle(pBorderLine->GetBorderLineStyle());
448
0
    rBorderLine.SetColor(pBorderLine->GetColor());
449
0
}
450
451
static bool lcl_BoxesInTrackedRows(const SwWrtShell &rSh, const SwSelBoxes& rBoxes)
452
0
{
453
    // cursor and selection are there only in tracked rows
454
0
    bool bRet = true;
455
0
    SwRedlineTable::size_type nRedlinePos = 0;
456
0
    if ( rBoxes.empty() )
457
0
        bRet = rSh.GetCursor()->GetPointNode().GetTableBox()->GetUpper()->IsTracked(nRedlinePos);
458
0
    else
459
0
    {
460
0
        tools::Long nBoxes = rBoxes.size();
461
0
        SwTableLine* pPrevLine = nullptr;
462
0
        for ( tools::Long i = 0; i < nBoxes; i++ )
463
0
        {
464
0
            SwTableLine* pLine = rBoxes[i]->GetUpper();
465
0
            if ( pLine != pPrevLine )
466
0
                bRet &= pLine->IsTracked(nRedlinePos);
467
0
            pPrevLine = pLine;
468
0
        }
469
0
    }
470
471
0
    return bRet;
472
0
}
473
474
static bool lcl_CursorInDeletedTable(const SwWrtShell &rSh)
475
0
{
476
    // cursor and selection are there only in deleted table in Show Changes mode
477
0
    if ( rSh.GetLayout()->IsHideRedlines() )
478
0
        return false;
479
480
0
    SwTableNode* pTableNd = rSh.GetCursor()->GetPoint()->GetNode().FindTableNode();
481
0
    return pTableNd && pTableNd->GetTable().IsDeleted();
482
0
}
483
484
void SwTableShell::Execute(SfxRequest &rReq)
485
0
{
486
0
    const SfxItemSet* pArgs = rReq.GetArgs();
487
0
    SwWrtShell &rSh = GetShell();
488
489
    // At first the slots which doesn't need a FrameMgr.
490
0
    bool bMore = false;
491
0
    const SfxPoolItem* pItem = nullptr;
492
0
    sal_uInt16 nSlot = rReq.GetSlot();
493
0
    if(pArgs)
494
0
        pArgs->GetItemState(GetPool().GetWhichIDFromSlotID(nSlot), false, &pItem);
495
0
    bool bCallDone = false;
496
0
    switch ( nSlot )
497
0
    {
498
0
        case SID_ATTR_BORDER:
499
0
        {
500
0
            if(!pArgs)
501
0
                break;
502
            // Create items, because we have to rework anyway.
503
0
            std::shared_ptr<SvxBoxItem> aBox(std::make_shared<SvxBoxItem>(RES_BOX));
504
0
            SfxItemSetFixed<RES_BOX, RES_BOX,
505
0
                            SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER>
506
0
                aCoreSet( GetPool() );
507
0
            SvxBoxInfoItem aCoreInfo( SID_ATTR_BORDER_INNER );
508
0
            aCoreSet.Put(aCoreInfo);
509
0
            rSh.GetTabBorders( aCoreSet );
510
0
            const SvxBoxItem& rCoreBox = aCoreSet.Get(RES_BOX);
511
0
            const SvxBoxItem *pBoxItem = pArgs->GetItemIfSet(RES_BOX);
512
0
            if ( pBoxItem )
513
0
            {
514
0
                aBox.reset(pBoxItem->Clone());
515
0
                sal_Int16 nDefValue = MIN_BORDER_DIST;
516
0
                if ( !rReq.IsAPI() )
517
0
                    nDefValue = 55;
518
0
                if (!rReq.IsAPI() || aBox->GetSmallestDistance() < MIN_BORDER_DIST)
519
0
                {
520
0
                    for( SvxBoxItemLine k : o3tl::enumrange<SvxBoxItemLine>() )
521
0
                        aBox->SetDistance( std::max(rCoreBox.GetDistance(k), nDefValue) , k );
522
0
                }
523
0
            }
524
0
            else
525
0
                OSL_ENSURE( false, "where is BoxItem?" );
526
527
            //since the drawing layer also supports borders the which id might be a different one
528
0
            std::shared_ptr<SvxBoxInfoItem> aInfo(std::make_shared<SvxBoxInfoItem>(SID_ATTR_BORDER_INNER));
529
0
            if (const SvxBoxInfoItem* pBoxInfoItem = pArgs->GetItemIfSet(SID_ATTR_BORDER_INNER))
530
0
            {
531
0
                aInfo.reset(pBoxInfoItem->Clone());
532
0
            }
533
0
            else if( const SvxBoxInfoItem* pBoxInfoInnerItem = pArgs->GetItemIfSet(SDRATTR_TABLE_BORDER_INNER))
534
0
            {
535
0
                aInfo.reset(pBoxInfoInnerItem->Clone());
536
0
                aInfo->SetWhich(SID_ATTR_BORDER_INNER);
537
0
            }
538
539
0
            aInfo->SetTable( true );
540
0
            aInfo->SetValid( SvxBoxInfoItemValidFlags::DISABLE, false );
541
542
// The attributes of all lines will be read and the strongest wins.
543
0
            const SvxBorderLine* pBorderLine;
544
0
            SvxBorderLine aBorderLine;
545
0
            if ((pBorderLine = rCoreBox.GetTop()) != nullptr)
546
0
                lcl_TabGetMaxLineWidth(pBorderLine, aBorderLine);
547
0
            if ((pBorderLine = rCoreBox.GetBottom()) != nullptr)
548
0
                lcl_TabGetMaxLineWidth(pBorderLine, aBorderLine);
549
0
            if ((pBorderLine = rCoreBox.GetLeft()) != nullptr)
550
0
                lcl_TabGetMaxLineWidth(pBorderLine, aBorderLine);
551
0
            if ((pBorderLine = rCoreBox.GetRight()) != nullptr)
552
0
                lcl_TabGetMaxLineWidth(pBorderLine, aBorderLine);
553
0
            if ((pBorderLine = aCoreInfo.GetHori()) != nullptr)
554
0
                lcl_TabGetMaxLineWidth(pBorderLine, aBorderLine);
555
0
            if ((pBorderLine = aCoreInfo.GetVert()) != nullptr)
556
0
                lcl_TabGetMaxLineWidth(pBorderLine, aBorderLine);
557
558
0
            if(aBorderLine.GetOutWidth() == 0)
559
0
            {
560
0
                aBorderLine.SetBorderLineStyle(SvxBorderLineStyle::SOLID);
561
0
                aBorderLine.SetWidth( SvxBorderLineWidth::VeryThin );
562
0
            }
563
564
0
            if( aBox->GetTop() != nullptr )
565
0
            {
566
0
                aBox->SetLine(&aBorderLine, SvxBoxItemLine::TOP);
567
0
            }
568
0
            if( aBox->GetBottom() != nullptr )
569
0
            {
570
0
                aBox->SetLine(&aBorderLine, SvxBoxItemLine::BOTTOM);
571
0
            }
572
0
            if( aBox->GetLeft() != nullptr )
573
0
            {
574
0
                aBox->SetLine(&aBorderLine, SvxBoxItemLine::LEFT);
575
0
            }
576
0
            if( aBox->GetRight() != nullptr )
577
0
            {
578
0
                aBox->SetLine(&aBorderLine, SvxBoxItemLine::RIGHT);
579
0
            }
580
0
            if( aInfo->GetHori() != nullptr )
581
0
            {
582
0
                aInfo->SetLine(&aBorderLine, SvxBoxInfoItemLine::HORI);
583
0
            }
584
0
            if( aInfo->GetVert() != nullptr )
585
0
            {
586
0
                aInfo->SetLine(&aBorderLine, SvxBoxInfoItemLine::VERT);
587
0
            }
588
589
0
            aCoreSet.Put( *aBox  );
590
0
            aCoreSet.Put( *aInfo );
591
0
            rSh.SetTabBorders( aCoreSet );
592
593
            // we must record the "real" values because otherwise the lines can't be reconstructed on playtime
594
            // the coding style of the controller (setting lines with width 0) is not transportable via Query/PutValue in
595
            // the SvxBoxItem
596
0
            rReq.AppendItem( *aBox );
597
0
            rReq.AppendItem( *aInfo );
598
0
            bCallDone = true;
599
0
            break;
600
0
        }
601
0
        case FN_INSERT_TABLE:
602
0
            InsertTable( rReq );
603
0
            break;
604
0
        case FN_BREAK_ABOVE_TABLE:
605
0
        {
606
0
            rSh.MoveTable( GotoCurrTable, fnTableStart );
607
0
            rSh.SplitNode( false );
608
0
            break;
609
0
        }
610
0
        case FN_FORMAT_TABLE_DLG:
611
0
        {
612
            //#127012# get the bindings before the dialog is called
613
            // it might happen that this shell is removed after closing the dialog
614
0
            SfxBindings& rBindings = GetView().GetViewFrame().GetBindings();
615
0
            SfxItemSet aCoreSet( GetPool(), aUITableAttrRange);
616
617
0
            FieldUnit eMetric = ::GetDfltMetric(dynamic_cast<SwWebView*>( &rSh.GetView()) != nullptr );
618
0
            SwModule::get()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast< sal_uInt16 >(eMetric)));
619
0
            std::shared_ptr<SwTableRep> xTableRep(::lcl_TableParamToItemSet(aCoreSet, rSh));
620
621
0
            aCoreSet.Put(SfxUInt16Item(SID_HTML_MODE, ::GetHtmlMode(GetView().GetDocShell())));
622
0
            rSh.GetTableAttr(aCoreSet);
623
            // GetTableAttr overwrites the background!
624
0
            std::unique_ptr<SvxBrushItem> aBrush(std::make_unique<SvxBrushItem>(RES_BACKGROUND));
625
0
            if(rSh.GetBoxBackground(aBrush))
626
0
                aCoreSet.Put( *aBrush );
627
0
            else
628
0
                aCoreSet.InvalidateItem( RES_BACKGROUND );
629
630
0
            SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
631
0
            VclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateSwTableTabDlg(GetView().GetFrameWeld(), &aCoreSet, &rSh));
632
633
0
            if (pDlg)
634
0
            {
635
0
                if (pItem)
636
0
                    pDlg->SetCurPageId(static_cast<const SfxStringItem *>(pItem)->GetValue());
637
638
0
                auto xRequest = std::make_shared<SfxRequest>(rReq);
639
0
                rReq.Ignore(); // the 'old' request is not relevant any more
640
641
0
                const bool bTableMode = rSh.IsTableMode();
642
0
                SwPaM* pCursor = bTableMode ? rSh.GetTableCrs() : rSh.GetCursor(); // tdf#142165 use table cursor if in table mode
643
0
                auto vCursors = CopyPaMRing(*pCursor); // tdf#135636 make a copy to use at later apply
644
0
                pDlg->StartExecuteAsync([pDlg, xRequest=std::move(xRequest), xTableRep=std::move(xTableRep),
645
0
                                         &rBindings, &rSh, vCursors=std::move(vCursors), bTableMode](sal_Int32 nResult){
646
0
                    if (RET_OK == nResult)
647
0
                    {
648
0
                        if (!bTableMode && rSh.IsTableMode()) // tdf#140977 drop current table-cursor if setting a replacement
649
0
                            rSh.TableCursorToCursor();        // non-table one
650
651
                        // tdf#135636 set the selection at dialog launch as current selection
652
0
                        rSh.SetSelection(*vCursors->front()); // UpdateCursor() will be called which in the case
653
                                                              // of a table selection should recreate a
654
                                                              // SwShellTableCursor if the selection is more than a single cell
655
656
0
                        if (bTableMode && !rSh.IsTableMode()) // tdf#142721 ensure the new selection is a SwShellTableCursor in
657
0
                            rSh.SelTableBox();                // the case of a single cell
658
659
0
                        const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
660
661
                        //to record FN_INSERT_TABLE correctly
662
0
                        xRequest->SetSlot(FN_FORMAT_TABLE_DLG);
663
0
                        xRequest->Done(*pOutSet);
664
665
0
                        ItemSetToTableParam(*pOutSet, rSh);
666
0
                    }
667
668
0
                    rBindings.Update(SID_RULER_BORDERS);
669
0
                    rBindings.Update(SID_ATTR_TABSTOP);
670
0
                    rBindings.Update(SID_RULER_BORDERS_VERTICAL);
671
0
                    rBindings.Update(SID_ATTR_TABSTOP_VERTICAL);
672
673
0
                    pDlg->disposeOnce();
674
0
                });
675
0
            }
676
0
            else
677
0
            {
678
0
                if (rReq.GetArgs())
679
0
                    ItemSetToTableParam(*rReq.GetArgs(), rSh);
680
681
0
                rBindings.Update(SID_RULER_BORDERS);
682
0
                rBindings.Update(SID_ATTR_TABSTOP);
683
0
                rBindings.Update(SID_RULER_BORDERS_VERTICAL);
684
0
                rBindings.Update(SID_ATTR_TABSTOP_VERTICAL);
685
0
            }
686
687
0
            break;
688
0
        }
689
0
        case SID_ATTR_BRUSH:
690
0
        case SID_ATTR_BRUSH_ROW :
691
0
        case SID_ATTR_BRUSH_TABLE :
692
0
            if(rReq.GetArgs())
693
0
                ItemSetToTableParam(*rReq.GetArgs(), rSh);
694
0
            break;
695
0
        case FN_NUM_FORMAT_TABLE_DLG:
696
0
        {
697
0
            if (SwView* pView = GetActiveView())
698
0
            {
699
0
                FieldUnit eMetric = ::GetDfltMetric(dynamic_cast<SwWebView*>( pView) !=  nullptr );
700
0
                SwModule::get()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast< sal_uInt16 >(eMetric)));
701
0
                SvNumberFormatter* pFormatter = rSh.GetNumberFormatter();
702
0
                auto pCoreSet = std::make_shared<SfxItemSetFixed<SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_INFO>>( GetPool() );
703
704
0
                SfxItemSetFixed<RES_BOXATR_FORMAT, RES_BOXATR_FORMAT,
705
0
                                RES_BOXATR_VALUE, RES_BOXATR_VALUE>
706
0
                     aBoxSet( *pCoreSet->GetPool() );
707
0
                rSh.GetTableBoxFormulaAttrs( aBoxSet );
708
709
                // tdf#132111: if RES_BOXATR_FORMAT state is DEFAULT (no number format set to cell
710
                // explicitly), it's not equal to any specific format (the rules are special, e.g.
711
                // it's considered numeric for empty or number text in SwTableBox::HasNumContent).
712
                // For multiselection, it's INVALID, also not equal to any single format.
713
0
                if (auto pFormat = aBoxSet.GetItemIfSet(RES_BOXATR_FORMAT))
714
0
                    pCoreSet->Put(SfxUInt32Item(SID_ATTR_NUMBERFORMAT_VALUE, pFormat->GetValue()));
715
716
0
                pCoreSet->Put( SvxNumberInfoItem( pFormatter,
717
0
                                    aBoxSet.Get(
718
0
                                        RES_BOXATR_VALUE).GetValue(),
719
0
                                    rSh.GetTableBoxText(), SID_ATTR_NUMBERFORMAT_INFO ));
720
721
0
                SwWrtShell* pSh = &rSh;
722
0
                SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
723
0
                VclPtr<SfxAbstractDialog> pDlg(pFact->CreateNumFormatDialog(GetView().GetFrameWeld(), *pCoreSet));
724
725
0
                pDlg->StartExecuteAsync([pDlg, pCoreSet=std::move(pCoreSet), pSh](sal_uInt32 nResult){
726
0
                    if (RET_OK == nResult)
727
0
                    {
728
0
                        const SvxNumberInfoItem* pNumberFormatItem
729
0
                            = pSh->GetView().GetDocShell()->GetItem( SID_ATTR_NUMBERFORMAT_INFO );
730
731
0
                        if( pNumberFormatItem )
732
0
                        {
733
0
                            for ( sal_uInt32 key : pNumberFormatItem->GetDelFormats() )
734
0
                                pNumberFormatItem->GetNumberFormatter()->DeleteEntry( key );
735
0
                        }
736
737
0
                        const SfxPoolItem* pNumberFormatValueItem =
738
0
                            pDlg->GetOutputItemSet()->GetItemIfSet(
739
0
                                SID_ATTR_NUMBERFORMAT_VALUE, false);
740
0
                        if( pNumberFormatValueItem )
741
0
                        {
742
0
                            SfxItemSetFixed<RES_BOXATR_FORMAT, RES_BOXATR_FORMAT>
743
0
                                    aBoxFormatSet( *pCoreSet->GetPool() );
744
0
                            aBoxFormatSet.Put( SwTableBoxNumFormat(
745
0
                                    static_cast<const SfxUInt32Item*>(pNumberFormatValueItem)->GetValue() ));
746
0
                            pSh->SetTableBoxFormulaAttrs( aBoxFormatSet );
747
748
0
                        }
749
0
                    }
750
751
0
                    pDlg->disposeOnce();
752
0
                });
753
0
            }
754
0
            break;
755
0
        }
756
0
        case FN_CALC_TABLE:
757
0
            rSh.UpdateTable();
758
0
            bCallDone = true;
759
0
            break;
760
0
        case FN_TABLE_DELETE_COL:
761
0
            if ( rSh.DeleteCol() && rSh.HasSelection() )
762
0
                rSh.EnterStdMode();
763
0
            bCallDone = true;
764
0
            break;
765
0
        case FN_END_TABLE:
766
0
            rSh.MoveTable( GotoCurrTable, fnTableEnd );
767
0
            bCallDone = true;
768
0
            break;
769
0
        case FN_START_TABLE:
770
0
            rSh.MoveTable( GotoCurrTable, fnTableStart );
771
0
            bCallDone = true;
772
0
            break;
773
0
        case FN_GOTO_NEXT_CELL:
774
0
        {
775
0
            bool bAppendLine = true;
776
0
            if( pItem )
777
0
                bAppendLine = static_cast<const SfxBoolItem*>(pItem)->GetValue();
778
0
            rReq.SetReturnValue( SfxBoolItem( nSlot,
779
0
                                    rSh.GoNextCell( bAppendLine ) ) );
780
0
            bCallDone = true;
781
0
            break;
782
0
        }
783
0
        case FN_GOTO_PREV_CELL:
784
0
            rReq.SetReturnValue( SfxBoolItem( nSlot, rSh.GoPrevCell() ) );
785
0
            bCallDone = true;
786
0
            break;
787
0
        case FN_TABLE_DELETE_ROW:
788
0
            if ( rSh.DeleteRow() && rSh.HasSelection() )
789
0
                rSh.EnterStdMode();
790
0
            bCallDone = true;
791
0
            break;
792
0
        case FN_TABLE_MERGE_CELLS:
793
0
            if ( rSh.IsTableMode() )
794
0
                switch ( rSh.MergeTab() )
795
0
                {
796
0
                    case TableMergeErr::Ok:
797
0
                         bCallDone = true;
798
0
                         [[fallthrough]];
799
0
                    case TableMergeErr::NoSelection:
800
0
                        break;
801
0
                    case TableMergeErr::TooComplex:
802
0
                    {
803
0
                        std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(GetView().GetFrameWeld(),
804
0
                                                                      VclMessageType::Info, VclButtonsType::Ok,
805
0
                                                                      SwResId(STR_ERR_TABLE_MERGE)));
806
0
                        xInfoBox->run();
807
0
                        break;
808
0
                    }
809
0
                    default:
810
0
                        OSL_ENSURE( false, "unknown return value MergeTab.");
811
0
                        break;
812
0
                }
813
0
            break;
814
0
        case SID_TABLE_MINIMAL_COLUMN_WIDTH:
815
0
        case FN_TABLE_ADJUST_CELLS:
816
0
        case FN_TABLE_BALANCE_CELLS:
817
0
        {
818
0
            bool bBalance = (FN_TABLE_BALANCE_CELLS == nSlot);
819
0
            const bool bNoShrink = FN_TABLE_ADJUST_CELLS == nSlot;
820
0
            if ( rSh.IsAdjustCellWidthAllowed(bBalance) )
821
0
            {
822
0
                {
823
                    // remove actions to make a valid table selection
824
0
                    UnoActionRemoveContext aRemoveContext(rSh.GetDoc());
825
0
                }
826
0
                rSh.AdjustCellWidth(bBalance, bNoShrink);
827
0
            }
828
0
            bCallDone = true;
829
0
            break;
830
0
        }
831
0
        case SID_TABLE_MINIMAL_ROW_HEIGHT:
832
0
        {
833
0
            const SwFormatFrameSize aSz;
834
0
            rSh.SetRowHeight( aSz );
835
0
            bCallDone = true;
836
0
            break;
837
0
        }
838
0
        case FN_TABLE_OPTIMAL_HEIGHT:
839
0
        {
840
0
            rSh.BalanceRowHeight(/*bTstOnly=*/false, /*bOptimize=*/true);
841
0
            rSh.BalanceRowHeight(/*bTstOnly=*/false, /*bOptimize=*/false);
842
0
            bCallDone = true;
843
0
            break;
844
0
        }
845
0
        case FN_TABLE_BALANCE_ROWS:
846
0
            if ( rSh.BalanceRowHeight(true) )
847
0
                rSh.BalanceRowHeight(false);
848
0
            bCallDone = true;
849
0
            break;
850
0
        case FN_TABLE_SELECT_ALL:
851
0
            rSh.EnterStdMode();
852
0
            rSh.MoveTable( GotoCurrTable, fnTableStart );
853
0
            rSh.SttSelect();
854
0
            rSh.MoveTable( GotoCurrTable, fnTableEnd );
855
0
            rSh.EndSelect();
856
0
            bCallDone = true;
857
0
            break;
858
0
        case FN_TABLE_SELECT_COL:
859
0
            rSh.EnterStdMode();
860
0
            rSh.SelectTableCol();
861
0
            bCallDone = true;
862
0
            break;
863
0
        case FN_TABLE_SELECT_ROW:
864
0
            rSh.EnterStdMode();
865
0
            rSh.SelectTableRow();
866
0
            bCallDone = true;
867
0
            break;
868
0
        case FN_TABLE_SET_READ_ONLY_CELLS:
869
0
            rSh.ProtectCells();
870
0
            rSh.ResetSelect( nullptr, false, ScrollSizeMode::ScrollSizeDefault );
871
0
            bCallDone = true;
872
0
            break;
873
0
        case FN_TABLE_UNSET_READ_ONLY_CELLS:
874
0
            rSh.UnProtectCells();
875
0
            bCallDone = true;
876
0
            break;
877
0
        case SID_AUTOFORMAT:
878
0
        {
879
0
            SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
880
0
            VclPtr<AbstractSwAutoFormatDlg> pDlg(pFact->CreateSwAutoFormatDlg(GetView().GetFrameWeld(), &rSh));
881
0
            pDlg->StartExecuteAsync(
882
0
                [pDlg] (sal_Int32 nResult)->void
883
0
                {
884
0
                    if (nResult == RET_OK)
885
0
                        pDlg->Apply();
886
0
                    pDlg->disposeOnce();
887
0
                }
888
0
            );
889
0
            break;
890
0
        }
891
0
        case FN_TABLE_SET_ROW_HEIGHT:
892
0
        {
893
0
            SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
894
0
            VclPtr<AbstractSwTableHeightDlg> pDlg(pFact->CreateSwTableHeightDialog(GetView().GetFrameWeld(), rSh));
895
0
            pDlg->StartExecuteAsync(
896
0
                [pDlg] (sal_Int32 nResult)->void
897
0
                {
898
0
                    if (nResult == RET_OK)
899
0
                        pDlg->Apply();
900
0
                    pDlg->disposeOnce();
901
0
                }
902
0
            );
903
0
            break;
904
0
        }
905
0
        case FN_NUMBER_BULLETS:
906
0
        case FN_NUM_BULLET_ON:
907
0
            OSL_ENSURE( false, "function may not be called now." );
908
0
            break;
909
910
911
        // 2015/06 The following two are deprecated but kept for ascending
912
        // compatibility
913
0
        case FN_TABLE_INSERT_COL:
914
0
        case FN_TABLE_INSERT_ROW:
915
            // fallback
916
0
        case FN_TABLE_INSERT_COL_BEFORE:
917
0
        case FN_TABLE_INSERT_ROW_BEFORE:
918
0
        case FN_TABLE_INSERT_COL_AFTER:
919
0
        case FN_TABLE_INSERT_ROW_AFTER:
920
0
        {
921
0
            bool bColumn = rReq.GetSlot() == FN_TABLE_INSERT_COL_BEFORE
922
0
                           || rReq.GetSlot() == FN_TABLE_INSERT_COL_AFTER
923
0
                           || rReq.GetSlot() == FN_TABLE_INSERT_COL;
924
0
            sal_uInt16 nCount = 0;
925
0
            bool bAfter = true;
926
0
            if (pItem)
927
0
            {
928
0
                nCount = static_cast<const SfxInt16Item* >(pItem)->GetValue();
929
0
                if(const SfxBoolItem* pAfterItem = pArgs->GetItemIfSet(FN_PARAM_INSERT_AFTER))
930
0
                    bAfter = pAfterItem->GetValue();
931
0
            }
932
0
            else if( !rReq.IsAPI() )
933
0
            {
934
0
                SwSelBoxes aBoxes;
935
0
                ::GetTableSel( rSh, aBoxes );
936
0
                if ( !aBoxes.empty() )
937
0
                {
938
0
                    tools::Long maxX = 0;
939
0
                    tools::Long maxY = 0;
940
0
                    tools::Long minX = std::numeric_limits<tools::Long>::max();
941
0
                    tools::Long minY = std::numeric_limits<tools::Long>::max();
942
0
                    tools::Long nbBoxes = aBoxes.size();
943
0
                    for ( tools::Long i = 0; i < nbBoxes; i++ )
944
0
                    {
945
0
                        Point aCoord ( aBoxes[i]->GetCoordinates() );
946
0
                        if ( aCoord.X() < minX ) minX = aCoord.X();
947
0
                        if ( aCoord.X() > maxX ) maxX = aCoord.X();
948
0
                        if ( aCoord.Y() < minY ) minY = aCoord.Y();
949
0
                        if ( aCoord.Y() > maxY ) maxY = aCoord.Y();
950
0
                    }
951
0
                    if (bColumn)
952
0
                        nCount = maxX - minX + 1;
953
0
                    else
954
0
                        nCount = maxY - minY + 1;
955
0
                }
956
0
                bAfter = rReq.GetSlot() == FN_TABLE_INSERT_COL_AFTER
957
0
                         || rReq.GetSlot() == FN_TABLE_INSERT_ROW_AFTER
958
0
                         || rReq.GetSlot() == FN_TABLE_INSERT_ROW
959
0
                         || rReq.GetSlot() == FN_TABLE_INSERT_COL;
960
0
            }
961
962
0
            if( nCount )
963
0
            {
964
                // i74180: Table border patch submitted by chensuchun:
965
                // -->get the SvxBoxInfoItem of the table before insert
966
0
                SfxItemSet aCoreSet( GetPool(), aUITableAttrRange);
967
0
                ::lcl_TableParamToItemSet( aCoreSet, rSh );
968
0
                bool bSetInnerBorders = false;
969
0
                SwUndoId nUndoId = SwUndoId::EMPTY;
970
                // <--End
971
972
0
                if( bColumn )
973
0
                {
974
0
                    rSh.StartUndo( SwUndoId::TABLE_INSCOL );
975
0
                    rSh.InsertCol( nCount, bAfter );
976
0
                    bSetInnerBorders = true;
977
0
                    nUndoId = SwUndoId::TABLE_INSCOL;
978
0
                }
979
0
                else if ( !rSh.IsInRepeatedHeadline() )
980
0
                {
981
0
                    rSh.StartUndo( SwUndoId::TABLE_INSROW );
982
0
                    rSh.InsertRow( nCount, bAfter );
983
0
                    bSetInnerBorders = true;
984
0
                    nUndoId = SwUndoId::TABLE_INSROW;
985
0
                }
986
987
                // -->after inserting,reset the inner table borders
988
0
                if ( bSetInnerBorders )
989
0
                {
990
0
                    const SvxBoxInfoItem& aBoxInfo(aCoreSet.Get(SID_ATTR_BORDER_INNER));
991
0
                    SfxItemSetFixed<SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER> aSet( GetPool() );
992
0
                    aSet.Put( aBoxInfo );
993
0
                    ItemSetToTableParam( aSet, rSh );
994
0
                    rSh.EndUndo( nUndoId );
995
0
                }
996
997
0
                bCallDone = true;
998
0
                break;
999
0
            }
1000
1001
0
            nSlot = bColumn ? FN_TABLE_INSERT_COL_DLG : FN_TABLE_INSERT_ROW_DLG;
1002
1003
0
            [[fallthrough]]; // on Count = 0 appears the dialog
1004
0
        }
1005
0
        case FN_TABLE_INSERT_COL_DLG:
1006
0
        case FN_TABLE_INSERT_ROW_DLG:
1007
0
        {
1008
0
            const SfxSlot* pSlot = GetStaticInterface()->GetSlot(nSlot);
1009
0
            if ( FN_TABLE_INSERT_ROW_DLG != nSlot || !rSh.IsInRepeatedHeadline())
1010
0
            {
1011
0
                auto xRequest = std::make_shared<SfxRequest>(rReq);
1012
0
                rReq.Ignore(); // the 'old' request is not relevant any more
1013
0
                SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
1014
0
                VclPtr<SvxAbstractInsRowColDlg> pDlg(pFact->CreateSvxInsRowColDlg(GetView().GetFrameWeld(),
1015
0
                                                                                        nSlot == FN_TABLE_INSERT_COL_DLG, pSlot->GetCommand()));
1016
0
                pDlg->StartExecuteAsync(
1017
0
                    [this, pDlg, xRequest=std::move(xRequest), nSlot] (sal_Int32 nResult)->void
1018
0
                    {
1019
0
                        if (nResult == RET_OK)
1020
0
                        {
1021
0
                            const TypedWhichId<SfxUInt16Item> nDispatchSlot = (nSlot == FN_TABLE_INSERT_COL_DLG)
1022
0
                                ? FN_TABLE_INSERT_COL_AFTER : FN_TABLE_INSERT_ROW_AFTER;
1023
0
                            SfxUInt16Item aCountItem( nDispatchSlot, pDlg->getInsertCount() );
1024
0
                            SfxBoolItem  aAfter( FN_PARAM_INSERT_AFTER, !pDlg->isInsertBefore() );
1025
0
                            SfxViewFrame& rVFrame = GetView().GetViewFrame();
1026
0
                            rVFrame.GetDispatcher()->ExecuteList(nDispatchSlot,
1027
0
                                SfxCallMode::SYNCHRON|SfxCallMode::RECORD,
1028
0
                                { &aCountItem, &aAfter });
1029
0
                        }
1030
0
                        pDlg->disposeOnce();
1031
0
                        xRequest->Done();
1032
0
                    }
1033
0
                );
1034
0
            }
1035
0
            break;
1036
0
        }
1037
0
        case FN_TABLE_SPLIT_CELLS:
1038
0
        {
1039
0
            tools::Long nCount=0;
1040
0
            bool bHorizontal=true;
1041
0
            bool bProportional = false;
1042
0
            const SfxInt32Item* pSplit = rReq.GetArg<SfxInt32Item>(FN_TABLE_SPLIT_CELLS);
1043
0
            const SfxBoolItem* pHor = rReq.GetArg<SfxBoolItem>(FN_PARAM_1);
1044
0
            const SfxBoolItem* pProp = rReq.GetArg<SfxBoolItem>(FN_PARAM_2);
1045
0
            if ( pSplit )
1046
0
            {
1047
0
                nCount = pSplit->GetValue();
1048
0
                if ( pHor )
1049
0
                    bHorizontal = pHor->GetValue();
1050
0
                if ( pProp )
1051
0
                    bProportional = pProp->GetValue();
1052
0
            }
1053
0
            else
1054
0
            {
1055
0
                SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
1056
0
                SwWrtShell* pSh = &rSh;
1057
0
                const tools::Long nMaxVert = rSh.GetAnyCurRect( CurRectType::Frame ).Width() / MINLAY;
1058
0
                VclPtr<SvxAbstractSplitTableDialog> pDlg(pFact->CreateSvxSplitTableDialog(GetView().GetFrameWeld(), rSh.IsTableVertical(), nMaxVert));
1059
0
                if(rSh.IsSplitVerticalByDefault())
1060
0
                    pDlg->SetSplitVerticalByDefault();
1061
0
                pDlg->StartExecuteAsync([pDlg, pSh](int nResult) {
1062
0
                    if (nResult == RET_OK)
1063
0
                    {
1064
0
                        tools::Long nCount2 = pDlg->GetCount();
1065
0
                        bool bHorizontal2 = pDlg->IsHorizontal();
1066
0
                        bool bProportional2 = pDlg->IsProportional();
1067
1068
                        // tdf#60242: remember choice for next time
1069
0
                        bool bVerticalWasChecked = !pDlg->IsHorizontal();
1070
0
                        pSh->SetSplitVerticalByDefault(bVerticalWasChecked);
1071
1072
0
                        if ( nCount2 > 1 )
1073
0
                            pSh->SplitTab(!bHorizontal2, static_cast< sal_uInt16 >( nCount2-1 ), bProportional2 );
1074
0
                    }
1075
1076
0
                    pDlg->disposeOnce();
1077
0
                });
1078
0
            }
1079
1080
0
            if ( nCount>1 )
1081
0
            {
1082
0
                rSh.SplitTab(!bHorizontal, static_cast< sal_uInt16 >( nCount-1 ), bProportional );
1083
0
                bCallDone = true;
1084
0
            }
1085
0
            else
1086
0
                rReq.Ignore();
1087
0
            break;
1088
0
        }
1089
1090
0
        case FN_TABLE_SPLIT_TABLE:
1091
0
        {
1092
0
            const SfxUInt16Item* pType = rReq.GetArg<SfxUInt16Item>(FN_PARAM_1);
1093
0
            if( pType )
1094
0
            {
1095
0
                switch( static_cast<SplitTable_HeadlineOption>(pType->GetValue()) )
1096
0
                {
1097
0
                    case SplitTable_HeadlineOption::NONE    :
1098
0
                    case SplitTable_HeadlineOption::BorderCopy:
1099
0
                    case SplitTable_HeadlineOption::ContentCopy:
1100
0
                    case SplitTable_HeadlineOption::BoxAttrCopy:
1101
0
                    case SplitTable_HeadlineOption::BoxAttrAllCopy:
1102
0
                        rSh.SplitTable(static_cast<SplitTable_HeadlineOption>(pType->GetValue())) ;
1103
0
                        break;
1104
0
                    default: ;//wrong parameter, do nothing
1105
0
                }
1106
0
            }
1107
0
            else
1108
0
            {
1109
0
                SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
1110
0
                VclPtr<AbstractSplitTableDialog> pDlg(pFact->CreateSplitTableDialog(GetView().GetFrameWeld(), rSh));
1111
1112
0
                SwWrtShell* pSh = &rSh;
1113
1114
0
                pDlg->StartExecuteAsync([pDlg, pSh](int nResult) {
1115
0
                    if (nResult == RET_OK)
1116
0
                    {
1117
0
                        const auto aSplitMode = pDlg->GetSplitMode();
1118
0
                        pSh->SplitTable( aSplitMode );
1119
0
                    }
1120
1121
0
                    pDlg->disposeOnce();
1122
0
                });
1123
0
                rReq.Ignore(); // We're already handling the request in our async bit
1124
0
            }
1125
0
            break;
1126
0
        }
1127
1128
0
        case FN_TABLE_MERGE_TABLE:
1129
0
        {
1130
0
            bool bPrev = rSh.CanMergeTable();
1131
0
            bool bNext = rSh.CanMergeTable( false );
1132
1133
0
            if( bPrev && bNext )
1134
0
            {
1135
0
                SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
1136
0
                ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateTableMergeDialog(GetView().GetFrameWeld(), bPrev));
1137
0
                if( RET_OK != pDlg->Execute())
1138
0
                    bPrev = bNext = false;
1139
0
            }
1140
1141
0
            if( bPrev || bNext )
1142
0
                rSh.MergeTable( bPrev );
1143
0
            break;
1144
0
        }
1145
1146
0
        case FN_TABLE_MODE_FIX       :
1147
0
        case FN_TABLE_MODE_FIX_PROP  :
1148
0
        case FN_TABLE_MODE_VARIABLE  :
1149
0
        {
1150
0
            rSh.SetTableChgMode( FN_TABLE_MODE_FIX == nSlot
1151
0
                                    ? TableChgMode::FixedWidthChangeAbs
1152
0
                                    : FN_TABLE_MODE_FIX_PROP == nSlot
1153
0
                                        ? TableChgMode::FixedWidthChangeProp
1154
0
                                        : TableChgMode::VarWidthChangeAbs );
1155
1156
0
            SfxBindings& rBind = GetView().GetViewFrame().GetBindings();
1157
0
            static const sal_uInt16 aInva[] =
1158
0
                            {   FN_TABLE_MODE_FIX,
1159
0
                                FN_TABLE_MODE_FIX_PROP,
1160
0
                                FN_TABLE_MODE_VARIABLE,
1161
0
                                0
1162
0
                            };
1163
0
            rBind.Invalidate( aInva );
1164
0
            bCallDone = true;
1165
0
            break;
1166
0
        }
1167
0
        case FN_TABLE_AUTOSUM:
1168
0
        {
1169
0
            SfxViewFrame& rVFrame = GetView().GetViewFrame();
1170
0
            rVFrame.GetDispatcher()->Execute(FN_EDIT_FORMULA, SfxCallMode::SYNCHRON);
1171
0
            const sal_uInt16 nId = SwInputChild::GetChildWindowId();
1172
0
            SwInputChild* pChildWin = static_cast<SwInputChild*>(rVFrame.
1173
0
                                                GetChildWindow( nId ));
1174
0
            OUString sSum;
1175
0
            GetShell().GetAutoSum(sSum);
1176
0
            if( pChildWin )
1177
0
                pChildWin->SetFormula( sSum );
1178
1179
0
            break;
1180
0
        }
1181
0
        case FN_TABLE_HEADLINE_REPEAT:
1182
0
            if(0 != rSh.GetRowsToRepeat())
1183
0
                rSh.SetRowsToRepeat( 0 );
1184
0
            else
1185
0
                rSh.SetRowsToRepeat(rSh.GetRowSelectionFromTop());
1186
0
            break;
1187
0
        case FN_TABLE_SELECT_CELL   :
1188
0
            rSh.SelectTableCell();
1189
0
            break;
1190
0
        case FN_TABLE_DELETE_TABLE  :
1191
0
        {
1192
0
            rSh.StartAction();
1193
0
            rSh.StartUndo();
1194
0
            rSh.GetView().GetViewFrame().GetDispatcher()->Execute(FN_TABLE_SELECT_ALL);
1195
0
            rSh.DeleteTable();
1196
0
            rSh.EndUndo();
1197
0
            rSh.EndAction();
1198
            //'this' is already destroyed
1199
0
            return;
1200
0
        }
1201
0
        case SID_ATTR_TABLE_ROW_HEIGHT:
1202
0
        {
1203
0
            const SfxUInt32Item* pItem2 = rReq.GetArg(SID_ATTR_TABLE_ROW_HEIGHT);
1204
0
            if (pItem2)
1205
0
            {
1206
0
                tools::Long nNewHeight = pItem2->GetValue();
1207
0
                std::unique_ptr<SwFormatFrameSize> pHeight = rSh.GetRowHeight();
1208
0
                if ( pHeight )
1209
0
                {
1210
0
                    if (pHeight->GetHeightSizeType() == SwFrameSize::Variable)
1211
0
                        pHeight->SetHeightSizeType(SwFrameSize::Minimum);
1212
0
                    pHeight->SetHeight(nNewHeight);
1213
0
                    rSh.SetRowHeight(*pHeight);
1214
0
                }
1215
0
            }
1216
0
            return;
1217
0
        }
1218
0
        case SID_ATTR_TABLE_COLUMN_WIDTH:
1219
0
        {
1220
0
            const SfxUInt32Item* pItem2 = rReq.GetArg(SID_ATTR_TABLE_COLUMN_WIDTH);
1221
0
            if (pItem2)
1222
0
            {
1223
0
                tools::Long nNewWidth = pItem2->GetValue();
1224
0
                SwTableFUNC aFunc( &rSh );
1225
0
                aFunc.InitTabCols();
1226
0
                aFunc.SetColWidth(aFunc.GetCurColNum(), nNewWidth);
1227
0
            }
1228
0
            return;
1229
0
        }
1230
0
        case SID_ATTR_TABLE_ALIGNMENT:
1231
0
        {
1232
0
            const SfxUInt16Item* pAlignItem = rReq.GetArg<SfxUInt16Item>(SID_ATTR_TABLE_ALIGNMENT);
1233
0
            if (pAlignItem && pAlignItem->GetValue() <= text::HoriOrientation::LEFT_AND_WIDTH)
1234
0
            {
1235
0
                SfxItemSetFixed<RES_FRMATR_BEGIN, RES_FRMATR_END - 1> aSet( GetPool());
1236
0
                rSh.StartUndo(SwUndoId::TABLE_ATTR);
1237
0
                SwFormatHoriOrient aAttr( 0, pAlignItem->GetValue());
1238
1239
0
                const SfxInt32Item* pLeftItem = rReq.GetArg<SfxInt32Item>(SID_ATTR_TABLE_LEFT_SPACE);
1240
0
                const SfxInt32Item* pRightItem = rReq.GetArg<SfxInt32Item>(SID_ATTR_TABLE_RIGHT_SPACE);
1241
1242
0
                SvxLRSpaceItem aLRSpace( RES_LR_SPACE );
1243
0
                SwTwips nLeft = pLeftItem ? pLeftItem->GetValue() : 0;
1244
0
                SwTwips nRight = pRightItem ? pRightItem->GetValue() : 0;
1245
0
                SwTabCols aTabCols;
1246
0
                rSh.GetTabCols(aTabCols);
1247
0
                tools::Long nSpace = aTabCols.GetRightMax();
1248
0
                SwTwips nWidth = nSpace;
1249
0
                switch (pAlignItem->GetValue())
1250
0
                {
1251
0
                    case text::HoriOrientation::LEFT:
1252
0
                        if (MINLAY < nSpace - nRight)
1253
0
                            nWidth = nSpace - nRight;
1254
0
                        else
1255
0
                        {
1256
0
                            nWidth = MINLAY;
1257
0
                            nRight = nSpace - MINLAY;
1258
0
                        }
1259
0
                        nLeft = 0;
1260
0
                        break;
1261
0
                    case text::HoriOrientation::RIGHT:
1262
0
                        if (MINLAY < nSpace - nLeft)
1263
0
                            nWidth = nSpace - nLeft;
1264
0
                        else
1265
0
                        {
1266
0
                            nWidth = MINLAY;
1267
0
                            nLeft = nSpace - MINLAY;
1268
0
                        }
1269
0
                        nRight = 0;
1270
0
                        break;
1271
0
                    case text::HoriOrientation::LEFT_AND_WIDTH:
1272
                        // width doesn't change
1273
0
                        nRight = 0;
1274
0
                        nLeft = std::min(nLeft, nSpace);
1275
0
                        break;
1276
0
                    case text::HoriOrientation::FULL:
1277
0
                        nLeft = nRight = 0;
1278
0
                        break;
1279
0
                    case text::HoriOrientation::CENTER:
1280
0
                        if (MINLAY < nSpace - 2 * nLeft)
1281
0
                            nWidth = nSpace - 2 * nLeft;
1282
0
                        else
1283
0
                        {
1284
0
                            nWidth = MINLAY;
1285
0
                            nLeft = nRight = (nSpace - MINLAY) / 2;
1286
0
                        }
1287
0
                        break;
1288
0
                    case text::HoriOrientation::NONE:
1289
0
                        if (MINLAY < nSpace - nLeft - nRight)
1290
0
                            nWidth = nSpace - nLeft - nRight;
1291
0
                        else
1292
0
                        {
1293
0
                            nWidth = MINLAY;
1294
                            //TODO: keep the previous value - if possible and reduce the 'new one' only
1295
0
                            nLeft = nRight = (nSpace - MINLAY) / 2;
1296
0
                        }
1297
0
                        break;
1298
0
                    default:
1299
0
                        break;
1300
0
                }
1301
0
                SwFormatFrameSize aSz( SwFrameSize::Variable, nWidth );
1302
0
                aSet.Put(aSz);
1303
1304
0
                aLRSpace.SetLeft(SvxIndentValue::twips(nLeft));
1305
0
                aLRSpace.SetRight(SvxIndentValue::twips(nRight));
1306
0
                aSet.Put( aLRSpace );
1307
1308
0
                aSet.Put( aAttr );
1309
0
                rSh.SetTableAttr( aSet );
1310
0
                rSh.EndUndo(SwUndoId::TABLE_ATTR);
1311
0
                static const sal_uInt16 aInva[] =
1312
0
                                {   SID_ATTR_TABLE_LEFT_SPACE,
1313
0
                                    SID_ATTR_TABLE_RIGHT_SPACE,
1314
0
                                    0
1315
0
                                };
1316
0
                GetView().GetViewFrame().GetBindings().Invalidate( aInva );
1317
0
            }
1318
0
            return;
1319
0
        }
1320
0
        default:
1321
0
            bMore = true;
1322
0
    }
1323
1324
0
    if ( !bMore )
1325
0
    {
1326
0
        if(bCallDone)
1327
0
            rReq.Done();
1328
0
        return;
1329
0
    }
1330
1331
    // Now the slots which are working directly on the TableFormat.
1332
0
    switch ( nSlot )
1333
0
    {
1334
0
        case SID_ATTR_ULSPACE:
1335
0
            if(pItem)
1336
0
            {
1337
0
                SvxULSpaceItem aULSpace( *static_cast<const SvxULSpaceItem*>(pItem) );
1338
0
                aULSpace.SetWhich( RES_UL_SPACE );
1339
0
                ::lcl_SetAttr( rSh, aULSpace );
1340
0
            }
1341
0
            break;
1342
1343
0
        case SID_ATTR_LRSPACE:
1344
0
            if(pItem)
1345
0
            {
1346
0
                SfxItemSetFixed<RES_LR_SPACE, RES_LR_SPACE,
1347
0
                                RES_HORI_ORIENT, RES_HORI_ORIENT>  aSet( GetPool() );
1348
0
                SvxLRSpaceItem aLRSpace( *static_cast<const SvxLRSpaceItem*>(pItem) );
1349
0
                aLRSpace.SetWhich( RES_LR_SPACE );
1350
0
                aSet.Put( aLRSpace );
1351
0
                rSh.SetTableAttr( aSet );
1352
0
            }
1353
0
            break;
1354
        // The last case branch which needs a table manager!!
1355
0
        case FN_TABLE_SET_COL_WIDTH:
1356
0
        {
1357
            // Adjust line height (dialogue)
1358
0
            SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
1359
0
            VclPtr<AbstractSwTableWidthDlg> pDlg(pFact->CreateSwTableWidthDlg(GetView().GetFrameWeld(), &rSh));
1360
0
            pDlg->StartExecuteAsync(
1361
0
                [pDlg] (sal_Int32 nResult)->void
1362
0
                {
1363
0
                    if (nResult == RET_OK)
1364
0
                        pDlg->Apply();
1365
0
                    pDlg->disposeOnce();
1366
0
                }
1367
0
            );
1368
0
            break;
1369
0
        }
1370
0
        case SID_TABLE_VERT_NONE:
1371
0
        case SID_TABLE_VERT_CENTER:
1372
0
        case SID_TABLE_VERT_BOTTOM:
1373
0
        {
1374
0
            const sal_uInt16 nAlign = nSlot == SID_TABLE_VERT_NONE ?
1375
0
                                text::VertOrientation::NONE :
1376
0
                                    nSlot == SID_TABLE_VERT_CENTER ?
1377
0
                                        text::VertOrientation::CENTER : text::VertOrientation::BOTTOM;
1378
0
            rSh.SetBoxAlign(nAlign);
1379
0
            bCallDone = true;
1380
0
            break;
1381
0
        }
1382
1383
0
        case SID_ATTR_PARA_SPLIT:
1384
0
            if ( pItem )
1385
0
            {
1386
0
                SwFormatLayoutSplit aSplit( static_cast<const SvxFormatSplitItem*>(pItem)->GetValue());
1387
0
                SfxItemSetFixed<RES_LAYOUT_SPLIT, RES_LAYOUT_SPLIT> aSet(GetPool());
1388
0
                aSet.Put(aSplit);
1389
0
                rSh.SetTableAttr(aSet);
1390
0
            }
1391
0
            break;
1392
1393
0
        case SID_ATTR_PARA_KEEP:
1394
0
            if ( pItem )
1395
0
            {
1396
0
                SvxFormatKeepItem aKeep( *static_cast<const SvxFormatKeepItem*>(pItem) );
1397
0
                aKeep.SetWhich( RES_KEEP );
1398
0
                SfxItemSetFixed<RES_KEEP, RES_KEEP> aSet(GetPool());
1399
0
                aSet.Put(aKeep);
1400
0
                rSh.SetTableAttr(aSet);
1401
0
            }
1402
0
            break;
1403
0
        case FN_TABLE_ROW_SPLIT :
1404
0
        {
1405
0
            const SfxBoolItem* pBool = static_cast<const SfxBoolItem*>(pItem);
1406
0
            std::unique_ptr<SwFormatRowSplit> pSplit;
1407
0
            if(!pBool)
1408
0
            {
1409
0
                pSplit = rSh.GetRowSplit();
1410
0
                if(pSplit)
1411
0
                    pSplit->SetValue(!pSplit->GetValue());
1412
0
                else
1413
0
                   pSplit.reset(new SwFormatRowSplit(true));
1414
0
            }
1415
0
            else
1416
0
            {
1417
0
                pSplit.reset(new SwFormatRowSplit(pBool->GetValue()));
1418
0
            }
1419
0
            rSh.SetRowSplit( *pSplit );
1420
0
            break;
1421
0
        }
1422
1423
0
        default:
1424
0
            OSL_ENSURE( false, "wrong Dispatcher" );
1425
0
            return;
1426
0
    }
1427
0
    if(bCallDone)
1428
0
        rReq.Done();
1429
0
}
1430
1431
void SwTableShell::GetState(SfxItemSet &rSet)
1432
0
{
1433
0
    SfxWhichIter aIter( rSet );
1434
0
    SwWrtShell &rSh = GetShell();
1435
0
    SwFrameFormat *pFormat = rSh.GetTableFormat();
1436
    // os #124829# crash report: in case of an invalid shell selection return immediately
1437
0
    if(!pFormat)
1438
0
        return;
1439
0
    sal_uInt16 nSlot = aIter.FirstWhich();
1440
0
    while ( nSlot )
1441
0
    {
1442
0
        switch ( nSlot )
1443
0
        {
1444
0
            case FN_TABLE_MERGE_CELLS:
1445
0
                if ( !rSh.IsTableMode() )
1446
0
                    rSet.DisableItem(FN_TABLE_MERGE_CELLS);
1447
0
                break;
1448
0
            case SID_TABLE_MINIMAL_COLUMN_WIDTH:
1449
0
            case FN_TABLE_ADJUST_CELLS:
1450
0
                if ( !rSh.IsAdjustCellWidthAllowed() )
1451
0
                    rSet.DisableItem(nSlot);
1452
0
                break;
1453
1454
0
            case FN_TABLE_BALANCE_CELLS:
1455
0
                if ( !rSh.IsAdjustCellWidthAllowed(true) )
1456
0
                    rSet.DisableItem(FN_TABLE_BALANCE_CELLS);
1457
0
                break;
1458
1459
0
            case FN_TABLE_OPTIMAL_HEIGHT:
1460
0
            case FN_TABLE_BALANCE_ROWS:
1461
0
                if ( !rSh.BalanceRowHeight(true) )
1462
0
                    rSet.DisableItem(nSlot);
1463
0
                break;
1464
0
            case FN_OPTIMIZE_TABLE:
1465
0
                if ( !rSh.IsTableMode() &&
1466
0
                        !rSh.IsAdjustCellWidthAllowed() &&
1467
0
                        !rSh.IsAdjustCellWidthAllowed(true) &&
1468
0
                        !rSh.BalanceRowHeight(true) )
1469
0
                    rSet.DisableItem(FN_OPTIMIZE_TABLE);
1470
0
            break;
1471
0
            case SID_INSERT_DIAGRAM:
1472
0
                {
1473
0
                    SvtModuleOptions aMOpt;
1474
0
                    if ( !aMOpt.IsMathInstalled() || rSh.IsTableComplexForChart() )
1475
0
                        rSet.DisableItem(nSlot);
1476
0
                }
1477
0
                break;
1478
1479
0
            case FN_INSERT_TABLE:
1480
0
                if ( rSh.CursorInsideInputField() )
1481
0
                {
1482
0
                    rSet.DisableItem( nSlot );
1483
0
                }
1484
0
                break;
1485
1486
0
            case SID_TABLE_MINIMAL_ROW_HEIGHT:
1487
0
            {
1488
                // Disable if auto height already is enabled.
1489
0
                std::unique_ptr<SwFormatFrameSize> pSz = rSh.GetRowHeight();
1490
0
                if ( pSz )
1491
0
                {
1492
0
                    if ( SwFrameSize::Variable == pSz->GetHeightSizeType() )
1493
0
                        rSet.DisableItem( nSlot );
1494
0
                }
1495
0
                break;
1496
0
            }
1497
0
            case FN_TABLE_INSERT_COL_BEFORE:
1498
0
            case FN_TABLE_INSERT_COL_AFTER:
1499
0
            {
1500
0
                SfxImageItem aImageItem(nSlot);
1501
0
                if (pFormat->GetFrameDir().GetValue() == SvxFrameDirection::Environment)
1502
0
                {
1503
                    // Inherited from superordinate object (page or frame).
1504
                    // If the table spans multiple pages, direction is set by the first page.
1505
0
                    SwIterator<SwTabFrame, SwFrameFormat> aIterT(*pFormat);
1506
0
                    for (SwTabFrame* pFrame = aIterT.First(); pFrame;
1507
0
                        pFrame = static_cast<SwTabFrame*>(pFrame->GetPrecede()))
1508
0
                        aImageItem.SetMirrored(pFrame->IsRightToLeft());
1509
0
                }
1510
0
                else
1511
0
                    aImageItem.SetMirrored(pFormat->GetFrameDir().GetValue() == SvxFrameDirection::Horizontal_RL_TB);
1512
0
                rSet.Put(aImageItem);
1513
0
                break;
1514
0
            }
1515
0
            case FN_TABLE_INSERT_ROW:
1516
0
            case FN_TABLE_INSERT_ROW_AFTER:
1517
0
            case FN_TABLE_INSERT_ROW_DLG:
1518
0
                if ( rSh.IsInRepeatedHeadline() )
1519
0
                    rSet.DisableItem( nSlot );
1520
0
                break;
1521
0
            case RES_LR_SPACE:
1522
0
                rSet.Put(pFormat->GetLRSpace());
1523
0
                break;
1524
0
            case RES_UL_SPACE:
1525
0
                rSet.Put(pFormat->GetULSpace());
1526
0
                break;
1527
1528
0
            case SID_TABLE_VERT_NONE:
1529
0
            case SID_TABLE_VERT_CENTER:
1530
0
            case SID_TABLE_VERT_BOTTOM:
1531
0
            {
1532
0
                const sal_uInt16 nAlign = rSh.GetBoxAlign();
1533
0
                bool bSet = (nSlot == SID_TABLE_VERT_NONE && nAlign == text::VertOrientation::NONE) ||
1534
0
                            (nSlot == SID_TABLE_VERT_CENTER && nAlign == text::VertOrientation::CENTER) ||
1535
0
                            (nSlot == SID_TABLE_VERT_BOTTOM && nAlign == text::VertOrientation::BOTTOM);
1536
0
                rSet.Put(SfxBoolItem(nSlot, bSet));
1537
0
                break;
1538
0
            }
1539
1540
0
            case FN_TABLE_MODE_FIX       :
1541
0
            case FN_TABLE_MODE_FIX_PROP  :
1542
0
            case FN_TABLE_MODE_VARIABLE  :
1543
0
                {
1544
0
                    TableChgMode nMode = rSh.GetTableChgMode();
1545
0
                    bool bSet = (nSlot == FN_TABLE_MODE_FIX && nMode == TableChgMode::FixedWidthChangeAbs) ||
1546
0
                            (nSlot == FN_TABLE_MODE_FIX_PROP && nMode == TableChgMode::FixedWidthChangeProp) ||
1547
0
                            (nSlot == FN_TABLE_MODE_VARIABLE && nMode == TableChgMode::VarWidthChangeAbs);
1548
0
                    rSet.Put(SfxBoolItem(nSlot, bSet));
1549
0
                }
1550
0
                break;
1551
0
            case FN_BREAK_ABOVE_TABLE:
1552
0
                {
1553
                    // exec just moves on top and adds the break, which however makes only sense if the table
1554
                    // is the very first item of the document; the command should be hidden otherwise
1555
0
                    SwContentFrame* pCurFrame = rSh.GetCurrFrame();
1556
0
                    SwPageFrame* pPageFrame = pCurFrame->FindPageFrame();
1557
0
                    SwFrame* pFrame = pPageFrame->Lower();
1558
1559
0
                    while(pFrame && !pFrame->IsContentFrame())
1560
0
                    {
1561
0
                        pFrame = pFrame->GetLower();
1562
0
                    }
1563
1564
0
                    if(pFrame && pFrame->FindTabFrame() != pCurFrame->FindTabFrame())
1565
0
                    {
1566
0
                        rSet.DisableItem(nSlot);
1567
0
                    }
1568
0
                }
1569
0
                break;
1570
0
            case SID_ATTR_PARA_SPLIT:
1571
0
                rSet.Put( pFormat->GetKeep() );
1572
0
                break;
1573
1574
0
            case SID_ATTR_PARA_KEEP:
1575
0
                rSet.Put( pFormat->GetLayoutSplit() );
1576
0
                break;
1577
0
            case FN_TABLE_SPLIT_TABLE:
1578
0
                if ( rSh.IsInHeadline() )
1579
0
                    rSet.DisableItem( nSlot );
1580
0
                break;
1581
0
            case FN_TABLE_MERGE_TABLE:
1582
0
            {
1583
0
                bool bAsk;
1584
0
                if( !rSh.CanMergeTable( true, &bAsk ))
1585
0
                    rSet.DisableItem( nSlot );
1586
0
                break;
1587
0
            }
1588
1589
0
            case FN_TABLE_DELETE_ROW:
1590
0
                {
1591
0
                    SwSelBoxes aBoxes;
1592
0
                    ::GetTableSel( rSh, aBoxes, SwTableSearchType::Row );
1593
0
                    if( ::HasProtectedCells( aBoxes ) || lcl_BoxesInTrackedRows( rSh, aBoxes ) )
1594
0
                        rSet.DisableItem( nSlot );
1595
0
                }
1596
0
                break;
1597
0
            case FN_TABLE_DELETE_COL:
1598
0
                {
1599
0
                    SwSelBoxes aBoxes;
1600
0
                    ::GetTableSel( rSh, aBoxes, SwTableSearchType::Col );
1601
0
                    if( ::HasProtectedCells( aBoxes ) || lcl_CursorInDeletedTable( rSh ) )
1602
0
                        rSet.DisableItem( nSlot );
1603
0
                }
1604
0
                break;
1605
0
            case FN_TABLE_DELETE_TABLE:
1606
0
                if( lcl_CursorInDeletedTable( rSh ) )
1607
0
                    rSet.DisableItem( nSlot );
1608
0
                break;
1609
1610
0
            case FN_TABLE_UNSET_READ_ONLY_CELLS:
1611
                // disable in readonly sections, but enable in protected cells
1612
0
                if( !rSh.CanUnProtectCells() )
1613
0
                    rSet.DisableItem( nSlot );
1614
0
                break;
1615
0
            case RES_ROW_SPLIT:
1616
0
            {
1617
0
                const SwFormatLayoutSplit& rTabSplit = pFormat->GetLayoutSplit();
1618
0
                if ( !rTabSplit.GetValue() )
1619
0
                {
1620
0
                    rSet.DisableItem( nSlot );
1621
0
                }
1622
0
                else
1623
0
                {
1624
0
                    std::unique_ptr<SwFormatRowSplit> pSplit = rSh.GetRowSplit();
1625
0
                    if(pSplit)
1626
0
                        rSet.Put(std::move(pSplit));
1627
0
                    else
1628
0
                        rSet.InvalidateItem( nSlot );
1629
0
                }
1630
0
                break;
1631
0
            }
1632
0
            case FN_TABLE_HEADLINE_REPEAT:
1633
0
                if(0 != rSh.GetRowsToRepeat())
1634
0
                    rSet.Put(SfxBoolItem(nSlot, true));
1635
0
                else if(!rSh.GetRowSelectionFromTop())
1636
0
                    rSet.DisableItem( nSlot );
1637
0
                else
1638
0
                    rSet.Put(SfxBoolItem(nSlot, false));
1639
0
                break;
1640
0
            case FN_TABLE_SELECT_CELL   :
1641
0
                if(rSh.HasBoxSelection())
1642
0
                    rSet.DisableItem( nSlot );
1643
0
                break;
1644
0
            case SID_ATTR_TABLE_ROW_HEIGHT:
1645
0
            {
1646
0
                SfxUInt32Item aRowHeight(SID_ATTR_TABLE_ROW_HEIGHT);
1647
0
                std::unique_ptr<SwFormatFrameSize> pHeight = rSh.GetRowHeight();
1648
0
                if (pHeight)
1649
0
                {
1650
0
                    tools::Long nHeight = pHeight->GetHeight();
1651
0
                    aRowHeight.SetValue(nHeight);
1652
0
                    rSet.Put(aRowHeight);
1653
1654
0
                    if (comphelper::LibreOfficeKit::isActive())
1655
0
                    {
1656
                        // TODO: set correct unit
1657
0
                        MapUnit eTargetUnit = MapUnit::MapInch;
1658
0
                        OUString sHeight = GetMetricText(nHeight,
1659
0
                                            MapUnit::MapTwip, eTargetUnit, nullptr);
1660
1661
0
                        OUString sPayload = ".uno:TableRowHeight=" + sHeight;
1662
1663
0
                        GetViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED,
1664
0
                            OUStringToOString(sPayload, RTL_TEXTENCODING_ASCII_US));
1665
0
                    }
1666
0
                }
1667
0
                break;
1668
0
            }
1669
0
            case SID_ATTR_TABLE_COLUMN_WIDTH:
1670
0
            {
1671
0
                SfxUInt32Item aColumnWidth(SID_ATTR_TABLE_COLUMN_WIDTH);
1672
0
                SwTableFUNC aFunc( &rSh );
1673
0
                aFunc.InitTabCols();
1674
0
                SwTwips nWidth = aFunc.GetColWidth(aFunc.GetCurColNum());
1675
0
                aColumnWidth.SetValue(nWidth);
1676
0
                rSet.Put(aColumnWidth);
1677
1678
0
                if (comphelper::LibreOfficeKit::isActive())
1679
0
                {
1680
                    // TODO: set correct unit
1681
0
                    MapUnit eTargetUnit = MapUnit::MapInch;
1682
0
                    OUString sWidth = GetMetricText(nWidth,
1683
0
                                        MapUnit::MapTwip, eTargetUnit, nullptr);
1684
1685
0
                    OUString sPayload = ".uno:TableColumWidth=" + sWidth;
1686
1687
0
                    GetViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED,
1688
0
                        OUStringToOString(sPayload, RTL_TEXTENCODING_ASCII_US));
1689
0
                }
1690
1691
0
                break;
1692
0
            }
1693
0
            case SID_ATTR_TABLE_ALIGNMENT:
1694
0
            {
1695
0
                const sal_uInt16 nAlign = pFormat->GetHoriOrient().GetHoriOrient();
1696
0
                rSet.Put(SfxUInt16Item(nSlot, nAlign));
1697
0
                break;
1698
0
            }
1699
0
            case SID_ATTR_TABLE_LEFT_SPACE:
1700
0
            case SID_ATTR_TABLE_RIGHT_SPACE:
1701
0
            {
1702
0
                SwTabCols aTabCols;
1703
0
                rSh.GetTabCols(aTabCols);
1704
0
                tools::Long nSpace = aTabCols.GetRightMax();
1705
0
                SvxLRSpaceItem aLRSpace(pFormat->GetLRSpace());
1706
0
                SwTwips nLeft = aLRSpace.ResolveLeft({});
1707
0
                SwTwips nRight = aLRSpace.ResolveRight({});
1708
1709
0
                sal_uInt16 nPercent = 0;
1710
0
                auto nWidth = ::GetTableWidth(pFormat, aTabCols, &nPercent, &rSh );
1711
                // The table width is wrong for relative values.
1712
0
                if (nPercent)
1713
0
                    nWidth = nSpace * nPercent / 100;
1714
0
                const sal_uInt16 nAlign = pFormat->GetHoriOrient().GetHoriOrient();
1715
0
                if(nAlign != text::HoriOrientation::FULL )
1716
0
                {
1717
0
                    SwTwips nLR = nSpace - nWidth;
1718
0
                    switch ( nAlign )
1719
0
                    {
1720
0
                        case text::HoriOrientation::CENTER:
1721
0
                            nLeft = nRight = nLR / 2;
1722
0
                            break;
1723
0
                        case text::HoriOrientation::LEFT:
1724
0
                            nRight = nLR;
1725
0
                            nLeft = 0;
1726
0
                            break;
1727
0
                        case text::HoriOrientation::RIGHT:
1728
0
                            nLeft = nLR;
1729
0
                            nRight = 0;
1730
0
                            break;
1731
0
                        case text::HoriOrientation::LEFT_AND_WIDTH:
1732
0
                            nRight = nLR - nLeft;
1733
0
                            break;
1734
0
                        case text::HoriOrientation::NONE:
1735
0
                            if(!nPercent)
1736
0
                                nWidth = nSpace - nLeft - nRight;
1737
0
                            break;
1738
0
                    }
1739
0
                }
1740
0
                rSet.Put(SfxInt32Item(SID_ATTR_TABLE_LEFT_SPACE, nLeft));
1741
0
                rSet.Put(SfxInt32Item(SID_ATTR_TABLE_RIGHT_SPACE, nRight));
1742
0
                break;
1743
0
            }
1744
0
        }
1745
0
        nSlot = aIter.NextWhich();
1746
0
    }
1747
0
}
1748
1749
SwTableShell::SwTableShell(SwView &_rView) :
1750
6
    SwBaseShell(_rView)
1751
6
{
1752
6
    SetName(u"Table"_ustr);
1753
6
    SfxShell::SetContextName(vcl::EnumContext::GetContextName(vcl::EnumContext::Context::Table));
1754
6
}
1755
1756
void SwTableShell::GetFrameBorderState(SfxItemSet &rSet)
1757
0
{
1758
0
    SfxItemSetFixed<RES_BOX, RES_BOX,
1759
0
                 SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER>  aCoreSet( GetPool() );
1760
0
    SvxBoxInfoItem aBoxInfo( SID_ATTR_BORDER_INNER );
1761
0
    aCoreSet.Put( aBoxInfo );
1762
0
    GetShell().GetTabBorders( aCoreSet );
1763
0
    rSet.Put( aCoreSet );
1764
0
}
1765
1766
void SwTableShell::ExecTableStyle(SfxRequest& rReq)
1767
0
{
1768
0
    SwWrtShell &rSh = GetShell();
1769
0
    const SfxItemSet *pArgs = rReq.GetArgs();
1770
0
    if(!pArgs)
1771
0
        return;
1772
1773
0
    switch ( rReq.GetSlot() )
1774
0
    {
1775
0
        case SID_FRAME_LINESTYLE:
1776
0
        case SID_FRAME_LINECOLOR:
1777
0
            if ( rReq.GetSlot() == SID_FRAME_LINESTYLE )
1778
0
            {
1779
0
                ::editeng::SvxBorderLine aLine;
1780
0
                const ::editeng::SvxBorderLine* pLine = nullptr;
1781
0
                const SfxInt16Item* lineStyleItem = rReq.GetArg<SfxInt16Item>(FN_PARAM_1);
1782
1783
0
                if (lineStyleItem)
1784
0
                {
1785
0
                    const SfxInt16Item* InnerLineWidthItem
1786
0
                        = rReq.GetArg<SfxInt16Item>(FN_PARAM_2);
1787
0
                    const SfxInt16Item* OuterLineWidthItem
1788
0
                        = rReq.GetArg<SfxInt16Item>(FN_PARAM_3);
1789
0
                    const SfxInt16Item* LineDistanceItem
1790
0
                        = rReq.GetArg<SfxInt16Item>(FN_PARAM_4);
1791
1792
0
                    sal_uInt16 InnerLineWidth, OuterLineWidth, LineDistance;
1793
0
                    SvxBorderLineStyle lineStyle
1794
0
                        = static_cast<SvxBorderLineStyle>(lineStyleItem->GetValue());
1795
0
                    InnerLineWidth = InnerLineWidthItem ? InnerLineWidthItem->GetValue() : 0;
1796
0
                    OuterLineWidth = OuterLineWidthItem ? OuterLineWidthItem->GetValue() : 0;
1797
0
                    LineDistance = LineDistanceItem ? LineDistanceItem->GetValue() : 0;
1798
1799
0
                    aLine.GuessLinesWidths(lineStyle, InnerLineWidth, OuterLineWidth, LineDistance);
1800
0
                    pLine = &aLine;
1801
0
                }
1802
0
                else
1803
0
                {
1804
0
                    pLine = pArgs->Get(SID_FRAME_LINESTYLE).GetLine();
1805
0
                }
1806
1807
0
                rSh.SetTabLineStyle( nullptr, true, pLine);
1808
0
            }
1809
0
            else
1810
0
            {
1811
0
                const SvxColorItem &rNewColorItem = pArgs->Get( SID_FRAME_LINECOLOR );
1812
0
                rSh.SetTabLineStyle( &rNewColorItem.GetValue() );
1813
0
            }
1814
1815
0
            rReq.Done();
1816
1817
0
            break;
1818
0
    }
1819
0
}
1820
1821
void SwTableShell::GetLineStyleState(SfxItemSet &rSet)
1822
0
{
1823
0
    SfxItemSetFixed<RES_BOX, RES_BOX,
1824
0
                    SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER>  aCoreSet( GetPool() );
1825
0
    SvxBoxInfoItem aCoreInfo( SID_ATTR_BORDER_INNER );
1826
0
    aCoreSet.Put(aCoreInfo);
1827
0
    GetShell().GetTabBorders( aCoreSet );
1828
1829
0
    const SvxBoxItem& rBoxItem = aCoreSet.Get( RES_BOX );
1830
0
    const SvxBorderLine* pLine = rBoxItem.GetTop();
1831
1832
0
    rSet.Put( SvxColorItem( pLine ? pLine->GetColor() : Color(), SID_FRAME_LINECOLOR ) );
1833
0
    SvxLineItem aLine( SID_FRAME_LINESTYLE );
1834
0
    aLine.SetLine(pLine);
1835
0
    rSet.Put( aLine );
1836
0
}
1837
1838
void SwTableShell::ExecNumberFormat(SfxRequest const & rReq)
1839
0
{
1840
0
    const SfxItemSet* pArgs = rReq.GetArgs();
1841
0
    SwWrtShell &rSh = GetShell();
1842
1843
    // At first the slots, which doesn't need a FrameMgr.
1844
0
    const SfxPoolItem* pItem = nullptr;
1845
0
    const sal_uInt16 nSlot = rReq.GetSlot();
1846
0
    if(pArgs)
1847
0
        pArgs->GetItemState(GetPool().GetWhichIDFromSlotID(nSlot), false, &pItem);
1848
1849
    // Always acquire the language from the current cursor position.
1850
0
    LanguageType eLang = rSh.GetCurLang();
1851
0
    SvNumberFormatter* pFormatter = rSh.GetNumberFormatter();
1852
0
    sal_uInt32 nNumberFormat = NUMBERFORMAT_ENTRY_NOT_FOUND;
1853
0
    SvNumFormatType nFormatType = SvNumFormatType::ALL;
1854
0
    sal_uInt16 nOffset = 0;
1855
1856
0
    switch ( nSlot )
1857
0
    {
1858
0
    case FN_NUMBER_FORMAT:
1859
0
        if( pItem )
1860
0
        {
1861
            // Determine index for string.
1862
0
            OUString aCode( static_cast<const SfxStringItem*>(pItem)->GetValue() );
1863
0
            nNumberFormat = pFormatter->GetEntryKey( aCode, eLang );
1864
0
            if( NUMBERFORMAT_ENTRY_NOT_FOUND == nNumberFormat )
1865
0
            {
1866
                // Re-enter
1867
0
                sal_Int32 nErrPos;
1868
0
                SvNumFormatType nType;
1869
0
                if( !pFormatter->PutEntry( aCode, nErrPos, nType,
1870
0
                                            nNumberFormat, eLang ))
1871
0
                    nNumberFormat = NUMBERFORMAT_ENTRY_NOT_FOUND;
1872
0
            }
1873
0
        }
1874
0
        break;
1875
0
    case FN_NUMBER_STANDARD:        nFormatType = SvNumFormatType::NUMBER; break;
1876
0
    case FN_NUMBER_SCIENTIFIC:      nFormatType = SvNumFormatType::SCIENTIFIC; break;
1877
0
    case FN_NUMBER_DATE:            nFormatType = SvNumFormatType::DATE; break;
1878
0
    case FN_NUMBER_TIME:            nFormatType = SvNumFormatType::TIME; break;
1879
0
    case FN_NUMBER_CURRENCY:        nFormatType = SvNumFormatType::CURRENCY; break;
1880
0
    case FN_NUMBER_PERCENT:         nFormatType = SvNumFormatType::PERCENT; break;
1881
1882
0
    case FN_NUMBER_TWODEC:          // #.##0,00
1883
0
        nFormatType = SvNumFormatType::NUMBER;
1884
0
        nOffset = NF_NUMBER_1000DEC2;
1885
0
        break;
1886
1887
0
    default:
1888
0
        OSL_FAIL("wrong dispatcher");
1889
0
        return;
1890
0
    }
1891
1892
0
    if( nFormatType != SvNumFormatType::ALL )
1893
0
        nNumberFormat = pFormatter->GetStandardFormat( nFormatType, eLang ) + nOffset;
1894
1895
0
    if( NUMBERFORMAT_ENTRY_NOT_FOUND != nNumberFormat )
1896
0
    {
1897
0
        SfxItemSetFixed<RES_BOXATR_FORMAT, RES_BOXATR_FORMAT> aBoxSet( GetPool() );
1898
0
        aBoxSet.Put( SwTableBoxNumFormat( nNumberFormat ));
1899
0
        rSh.SetTableBoxFormulaAttrs( aBoxSet );
1900
0
    }
1901
1902
0
}
1903
1904
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */