1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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.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>
53 #include <fmtornt.hxx>
54 #include <fmtlsplt.hxx>
55 #include <fmtrowsplt.hxx>
56 #include <fmtfsize.hxx>
57 #include <swmodule.hxx>
59 #include <rootfrm.hxx>
63 #include <inputwin.hxx>
64 #include <uiitems.hxx>
66 #include <swtablerep.hxx>
67 #include <tablemgr.hxx>
68 #include <cellatr.hxx>
71 #include <swtable.hxx>
74 #include <viewopt.hxx>
77 #include <strings.hrc>
79 #include <unobaseclass.hxx>
81 #define ShellClass_SwTableShell
82 #include <sfx2/msg.hxx>
83 #include <swslots.hxx>
85 #include <swabstdlg.hxx>
89 using ::editeng::SvxBorderLine
;
90 using namespace ::com::sun::star
;
92 SFX_IMPL_INTERFACE(SwTableShell
, SwBaseShell
)
94 void SwTableShell::InitInterface_Impl()
96 GetStaticInterface()->RegisterPopupMenu("table");
97 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT
, SfxVisibilityFlags::Invisible
, ToolbarId::Table_Toolbox
);
101 const WhichRangesContainer
aUITableAttrRange(svl::Items
<
102 RES_LR_SPACE
, RES_UL_SPACE
,
103 RES_PAGEDESC
, RES_BREAK
,
104 RES_BACKGROUND
, RES_BACKGROUND
,
107 RES_LAYOUT_SPLIT
, RES_LAYOUT_SPLIT
,
108 RES_FRAMEDIR
, RES_FRAMEDIR
,
109 RES_ROW_SPLIT
, RES_ROW_SPLIT
,
111 RES_COLLAPSING_BORDERS
, RES_COLLAPSING_BORDERS
,
112 // <-- collapsing borders
113 XATTR_FILL_FIRST
, XATTR_FILL_LAST
,
114 SID_ATTR_BORDER_INNER
, SID_ATTR_BORDER_SHADOW
,
115 SID_RULER_BORDERS
, SID_RULER_BORDERS
,
116 SID_ATTR_BRUSH_ROW
, SID_ATTR_BRUSH_TABLE
, // ??? This is very strange range
117 // SID_BACKGRND_DESTINATION, SID_BACKGRND_DESTINATION, // included into above
118 // SID_HTML_MODE, SID_HTML_MODE, // included into above
119 FN_TABLE_REP
, FN_TABLE_REP
,
120 FN_TABLE_SET_VERT_ALIGN
, FN_TABLE_SET_VERT_ALIGN
,
121 FN_TABLE_BOX_TEXTORIENTATION
, FN_TABLE_BOX_TEXTORIENTATION
,
122 FN_PARAM_TABLE_NAME
, FN_PARAM_TABLE_NAME
,
123 FN_PARAM_TABLE_HEADLINE
, FN_PARAM_TABLE_HEADLINE
126 const WhichRangesContainer
& SwuiGetUITableAttrRange()
128 return aUITableAttrRange
;
131 static void lcl_SetAttr( SwWrtShell
&rSh
, const SfxPoolItem
&rItem
)
133 SfxItemSet
aSet( rSh
.GetView().GetPool(), rItem
.Which(), rItem
.Which());
135 rSh
.SetTableAttr( aSet
);
138 static std::shared_ptr
<SwTableRep
> lcl_TableParamToItemSet( SfxItemSet
& rSet
, SwWrtShell
&rSh
)
140 std::shared_ptr
<SwTableRep
> pRep
;
142 SwFrameFormat
*pFormat
= rSh
.GetTableFormat();
144 rSh
.GetTabCols( aCols
);
146 //At first get the simple attributes.
147 rSet
.Put( SfxStringItem( FN_PARAM_TABLE_NAME
, pFormat
->GetName()));
148 rSet
.Put( SfxUInt16Item( FN_PARAM_TABLE_HEADLINE
, rSh
.GetRowsToRepeat() ) );
149 rSet
.Put( pFormat
->GetShadow() );
150 rSet
.Put(SfxUInt16Item(FN_TABLE_SET_VERT_ALIGN
, rSh
.GetBoxAlign()));
151 rSet
.Put( pFormat
->GetFrameDir() );
153 SvxULSpaceItem
aULSpace( pFormat
->GetULSpace() );
154 rSet
.Put( aULSpace
);
156 const sal_uInt16 nBackgroundDestination
= rSh
.GetViewOptions()->GetTableDest();
157 rSet
.Put(SfxUInt16Item(SID_BACKGRND_DESTINATION
, nBackgroundDestination
));
158 std::unique_ptr
<SvxBrushItem
> aBrush(std::make_unique
<SvxBrushItem
>(RES_BACKGROUND
));
159 if(rSh
.GetRowBackground(aBrush
))
161 aBrush
->SetWhich(SID_ATTR_BRUSH_ROW
);
165 rSet
.InvalidateItem(SID_ATTR_BRUSH_ROW
);
166 rSh
.GetTabBackground(aBrush
);
167 aBrush
->SetWhich(SID_ATTR_BRUSH_TABLE
);
170 // text direction in boxes
171 std::unique_ptr
<SvxFrameDirectionItem
> aBoxDirection(std::make_unique
<SvxFrameDirectionItem
>(SvxFrameDirection::Environment
, RES_FRAMEDIR
));
172 if(rSh
.GetBoxDirection( aBoxDirection
))
174 aBoxDirection
->SetWhich(FN_TABLE_BOX_TEXTORIENTATION
);
175 rSet
.Put(*aBoxDirection
);
178 bool bSelectAll
= rSh
.StartsWith_() == SwCursorShell::StartsWith::Table
&& rSh
.ExtendedSelectedAll();
179 bool bTableSel
= rSh
.IsTableMode() || bSelectAll
;
182 rSh
.StartAllAction();
184 rSh
.GetView().GetViewFrame().GetDispatcher()->Execute( FN_TABLE_SELECT_ALL
);
186 SvxBoxInfoItem
aBoxInfo( SID_ATTR_BORDER_INNER
);
188 // Table variant: If multiple table cells are selected.
189 rSh
.GetCursor(); //Thus GetCursorCnt() returns the right thing
190 aBoxInfo
.SetTable ((rSh
.IsTableMode() && rSh
.GetCursorCnt() > 1) ||
192 // Always show distance field.
193 aBoxInfo
.SetDist (true);
194 // Set minimum size in tables and paragraphs.
195 aBoxInfo
.SetMinDist( !bTableSel
|| rSh
.IsTableMode() ||
196 rSh
.GetSelectionType() &
197 (SelectionType::Text
| SelectionType::Table
));
198 // Always set the default spacing.
199 aBoxInfo
.SetDefDist (MIN_BORDER_DIST
);
200 // Individual lines can have DontCare status only in tables.
201 aBoxInfo
.SetValid( SvxBoxInfoItemValidFlags::DISABLE
, !bTableSel
|| !rSh
.IsTableMode() );
204 rSh
.GetTabBorders( rSet
);
207 std::unique_ptr
<SwFormatRowSplit
> pSplit
= rSh
.GetRowSplit();
209 rSet
.Put(std::move(pSplit
));
214 rSh
.Pop(SwCursorShell::PopMode::DeleteCurrent
);
219 rSh
.GetTabCols( aTabCols
);
221 // Pointer will be deleted after the dialogue execution.
222 pRep
= std::make_shared
<SwTableRep
>(aTabCols
);
223 pRep
->SetSpace(aCols
.GetRightMax());
225 sal_uInt16 nPercent
= 0;
226 auto nWidth
= ::GetTableWidth(pFormat
, aCols
, &nPercent
, &rSh
);
227 // The table width is wrong for relative values.
229 nWidth
= pRep
->GetSpace() * nPercent
/ 100;
230 const sal_uInt16 nAlign
= pFormat
->GetHoriOrient().GetHoriOrient();
231 pRep
->SetAlign(nAlign
);
232 SvxLRSpaceItem
aLRSpace( pFormat
->GetLRSpace() );
233 SwTwips nLeft
= aLRSpace
.GetLeft();
234 SwTwips nRight
= aLRSpace
.GetRight();
235 SwTwips nDiff
= pRep
->GetSpace() - nRight
- nLeft
- nWidth
;
236 if(nAlign
!= text::HoriOrientation::FULL
&& std::abs(nDiff
) > 2)
238 SwTwips nLR
= pRep
->GetSpace() - nWidth
;
241 case text::HoriOrientation::CENTER
:
242 nLeft
= nRight
= nLR
/ 2;
244 case text::HoriOrientation::LEFT
:
248 case text::HoriOrientation::RIGHT
:
252 case text::HoriOrientation::LEFT_AND_WIDTH
:
253 nRight
= nLR
- nLeft
;
255 case text::HoriOrientation::NONE
:
257 nWidth
= pRep
->GetSpace() - nLeft
- nRight
;
261 pRep
->SetLeftSpace(nLeft
);
262 pRep
->SetRightSpace(nRight
);
264 pRep
->SetWidth(nWidth
);
265 pRep
->SetWidthPercent(nPercent
);
266 // Are individual rows / cells are selected, the column processing will be changed.
267 pRep
->SetLineSelected(bTableSel
&& ! rSh
.HasWholeTabSelection());
268 rSet
.Put(SwPtrItem(FN_TABLE_REP
, pRep
.get()));
272 void ItemSetToTableParam( const SfxItemSet
& rSet
,
275 rSh
.StartAllAction();
276 rSh
.StartUndo( SwUndoId::TABLE_ATTR
);
278 if(const SfxUInt16Item
* pDestItem
= rSet
.GetItemIfSet(SID_BACKGRND_DESTINATION
, false))
280 SwViewOption
aUsrPref( *rSh
.GetViewOptions() );
281 aUsrPref
.SetTableDest(static_cast<sal_uInt8
>(pDestItem
->GetValue()));
282 SW_MOD()->ApplyUsrPref(aUsrPref
, &rSh
.GetView());
284 bool bBorder
= ( SfxItemState::SET
== rSet
.GetItemState( RES_BOX
) ||
285 SfxItemState::SET
== rSet
.GetItemState( SID_ATTR_BORDER_INNER
) );
286 const SvxBrushItem
* pBackgroundItem
= rSet
.GetItemIfSet( RES_BACKGROUND
, false );
287 const SvxBrushItem
* pRowItem
= rSet
.GetItemIfSet( SID_ATTR_BRUSH_ROW
, false );
288 const SvxBrushItem
* pTableItem
= rSet
.GetItemIfSet( SID_ATTR_BRUSH_TABLE
, false );
289 bool bBackground
= pBackgroundItem
|| pRowItem
|| pTableItem
;
290 const SwFormatRowSplit
* pSplit
= rSet
.GetItemIfSet( RES_ROW_SPLIT
, false );
291 bool bRowSplit
= pSplit
!= nullptr;
292 const SvxFrameDirectionItem
* pBoxDirection
= rSet
.GetItemIfSet( FN_TABLE_BOX_TEXTORIENTATION
, false );
293 bool bBoxDirection
= pBoxDirection
!= nullptr;
294 if( bBackground
|| bBorder
|| bRowSplit
|| bBoxDirection
)
296 // The border will be applied to the present selection.
297 // If there is no selection, the table will be completely selected.
298 // The background will always be applied to the current state.
299 bool bTableSel
= rSh
.IsTableMode();
300 rSh
.StartAllAction();
305 rSh
.SetBoxBackground( *pBackgroundItem
);
308 std::unique_ptr
<SvxBrushItem
> aBrush(pRowItem
->Clone());
309 aBrush
->SetWhich(RES_BACKGROUND
);
310 rSh
.SetRowBackground(*aBrush
);
314 std::unique_ptr
<SvxBrushItem
> aBrush(pTableItem
->Clone());
315 aBrush
->SetWhich(RES_BACKGROUND
);
316 rSh
.SetTabBackground( *aBrush
);
322 SvxFrameDirectionItem
aDirection( SvxFrameDirection::Environment
, RES_FRAMEDIR
);
323 aDirection
.SetValue(pBoxDirection
->GetValue());
324 rSh
.SetBoxDirection(aDirection
);
327 if(bBorder
|| bRowSplit
)
332 rSh
.GetView().GetViewFrame().GetDispatcher()->Execute( FN_TABLE_SELECT_ALL
);
335 rSh
.SetTabBorders( rSet
);
339 rSh
.SetRowSplit(*pSplit
);
346 rSh
.Pop(SwCursorShell::PopMode::DeleteCurrent
);
353 bool bTabCols
= false;
354 SwTableRep
* pRep
= nullptr;
355 SwFrameFormat
*pFormat
= rSh
.GetTableFormat();
356 SfxItemSetFixed
<RES_FRMATR_BEGIN
, RES_FRMATR_END
-1> aSet( rSh
.GetAttrPool() );
357 if(const SwPtrItem
* pRepItem
= rSet
.GetItemIfSet( FN_TABLE_REP
, false ))
359 pRep
= static_cast<SwTableRep
*>(pRepItem
->GetValue());
361 const SwTwips nWidth
= pRep
->GetWidth();
362 if ( text::HoriOrientation::FULL
== pRep
->GetAlign() )
364 SwFormatHoriOrient
aAttr( pFormat
->GetHoriOrient() );
365 aAttr
.SetHoriOrient( text::HoriOrientation::FULL
);
370 SwFormatFrameSize
aSz( SwFrameSize::Variable
, nWidth
);
371 if(pRep
->GetWidthPercent())
373 aSz
.SetWidthPercent( static_cast<sal_uInt8
>(pRep
->GetWidthPercent()) );
378 SvxLRSpaceItem
aLRSpace( RES_LR_SPACE
);
379 aLRSpace
.SetLeft(pRep
->GetLeftSpace());
380 aLRSpace
.SetRight(pRep
->GetRightSpace());
381 aSet
.Put( aLRSpace
);
383 sal_Int16 eOrient
= pRep
->GetAlign();
384 SwFormatHoriOrient
aAttr( 0, eOrient
);
386 // The item must only be recorded while manual alignment, so that the
387 // alignment is not overwritten by the distances while recording.
388 if(eOrient
!= text::HoriOrientation::NONE
)
389 const_cast<SfxItemSet
&>(rSet
).ClearItem( SID_ATTR_LRSPACE
);
391 if(pRep
->HasColsChanged())
397 if( const SfxUInt16Item
* pHeadlineItem
= rSet
.GetItemIfSet( FN_PARAM_TABLE_HEADLINE
, false ))
398 rSh
.SetRowsToRepeat( pHeadlineItem
->GetValue() );
400 if( const SfxUInt16Item
* pAlignItem
= rSet
.GetItemIfSet( FN_TABLE_SET_VERT_ALIGN
, false ))
401 rSh
.SetBoxAlign(pAlignItem
->GetValue());
403 if( const SfxStringItem
* pNameItem
= rSet
.GetItemIfSet( FN_PARAM_TABLE_NAME
, false ))
404 rSh
.SetTableName( *pFormat
, pNameItem
->GetValue() );
406 // Copy the chosen attributes in the ItemSet.
407 static const sal_uInt16 aIds
[] =
417 RES_COLLAPSING_BORDERS
,
418 // <-- collapsing borders
421 const SfxPoolItem
* pItem
= nullptr;
422 for( const sal_uInt16
* pIds
= aIds
; *pIds
; ++pIds
)
423 if( SfxItemState::SET
== rSet
.GetItemState( *pIds
, false, &pItem
))
428 rSh
.GetTabCols( aTabCols
);
429 bool bSingleLine
= pRep
->FillTabCols( aTabCols
);
430 rSh
.SetTabCols( aTabCols
, bSingleLine
);
434 rSh
.SetTableAttr( aSet
);
436 rSh
.EndUndo( SwUndoId::TABLE_ATTR
);
440 static void lcl_TabGetMaxLineWidth(const SvxBorderLine
* pBorderLine
, SvxBorderLine
& rBorderLine
)
442 if(pBorderLine
->GetWidth() > rBorderLine
.GetWidth())
443 rBorderLine
.SetWidth(pBorderLine
->GetWidth());
445 rBorderLine
.SetBorderLineStyle(pBorderLine
->GetBorderLineStyle());
446 rBorderLine
.SetColor(pBorderLine
->GetColor());
449 static bool lcl_BoxesInTrackedRows(SwWrtShell
&rSh
, const SwSelBoxes
& rBoxes
)
451 // cursor and selection are there only in tracked rows
453 SwRedlineTable::size_type nRedlinePos
= 0;
454 if ( rBoxes
.empty() )
455 bRet
= rSh
.GetCursor()->GetPointNode().GetTableBox()->GetUpper()->IsTracked(nRedlinePos
);
458 tools::Long nBoxes
= rBoxes
.size();
459 SwTableLine
* pPrevLine
= nullptr;
460 for ( tools::Long i
= 0; i
< nBoxes
; i
++ )
462 SwTableLine
* pLine
= rBoxes
[i
]->GetUpper();
463 if ( pLine
!= pPrevLine
)
464 bRet
&= pLine
->IsTracked(nRedlinePos
);
472 static bool lcl_CursorInDeletedTable(SwWrtShell
&rSh
)
474 // cursor and selection are there only in deleted table in Show Changes mode
475 if ( rSh
.GetLayout()->IsHideRedlines() )
478 SwTableNode
* pTableNd
= rSh
.GetCursor()->GetPoint()->GetNode().FindTableNode();
479 return pTableNd
&& pTableNd
->GetTable().IsDeleted();
482 void SwTableShell::Execute(SfxRequest
&rReq
)
484 const SfxItemSet
* pArgs
= rReq
.GetArgs();
485 SwWrtShell
&rSh
= GetShell();
487 // At first the slots which doesn't need a FrameMgr.
489 const SfxPoolItem
* pItem
= nullptr;
490 sal_uInt16 nSlot
= rReq
.GetSlot();
492 pArgs
->GetItemState(GetPool().GetWhich(nSlot
), false, &pItem
);
493 bool bCallDone
= false;
496 case SID_ATTR_BORDER
:
500 // Create items, because we have to rework anyway.
501 std::shared_ptr
<SvxBoxItem
> aBox(std::make_shared
<SvxBoxItem
>(RES_BOX
));
502 SfxItemSetFixed
<RES_BOX
, RES_BOX
,
503 SID_ATTR_BORDER_INNER
, SID_ATTR_BORDER_INNER
>
504 aCoreSet( GetPool() );
505 SvxBoxInfoItem
aCoreInfo( SID_ATTR_BORDER_INNER
);
506 aCoreSet
.Put(aCoreInfo
);
507 rSh
.GetTabBorders( aCoreSet
);
508 const SvxBoxItem
& rCoreBox
= aCoreSet
.Get(RES_BOX
);
509 const SvxBoxItem
*pBoxItem
= pArgs
->GetItemIfSet(RES_BOX
);
512 aBox
.reset(pBoxItem
->Clone());
513 sal_Int16 nDefValue
= MIN_BORDER_DIST
;
516 if (!rReq
.IsAPI() || aBox
->GetSmallestDistance() < MIN_BORDER_DIST
)
518 for( SvxBoxItemLine k
: o3tl::enumrange
<SvxBoxItemLine
>() )
519 aBox
->SetDistance( std::max(rCoreBox
.GetDistance(k
), nDefValue
) , k
);
523 OSL_ENSURE( false, "where is BoxItem?" );
525 //since the drawing layer also supports borders the which id might be a different one
526 std::shared_ptr
<SvxBoxInfoItem
> aInfo(std::make_shared
<SvxBoxInfoItem
>(SID_ATTR_BORDER_INNER
));
527 if (const SvxBoxInfoItem
* pBoxInfoItem
= pArgs
->GetItemIfSet(SID_ATTR_BORDER_INNER
))
529 aInfo
.reset(pBoxInfoItem
->Clone());
531 else if( const SvxBoxInfoItem
* pBoxInfoInnerItem
= pArgs
->GetItemIfSet(SDRATTR_TABLE_BORDER_INNER
))
533 aInfo
.reset(pBoxInfoInnerItem
->Clone());
534 aInfo
->SetWhich(SID_ATTR_BORDER_INNER
);
537 aInfo
->SetTable( true );
538 aInfo
->SetValid( SvxBoxInfoItemValidFlags::DISABLE
, false );
540 // The attributes of all lines will be read and the strongest wins.
541 const SvxBorderLine
* pBorderLine
;
542 SvxBorderLine aBorderLine
;
543 if ((pBorderLine
= rCoreBox
.GetTop()) != nullptr)
544 lcl_TabGetMaxLineWidth(pBorderLine
, aBorderLine
);
545 if ((pBorderLine
= rCoreBox
.GetBottom()) != nullptr)
546 lcl_TabGetMaxLineWidth(pBorderLine
, aBorderLine
);
547 if ((pBorderLine
= rCoreBox
.GetLeft()) != nullptr)
548 lcl_TabGetMaxLineWidth(pBorderLine
, aBorderLine
);
549 if ((pBorderLine
= rCoreBox
.GetRight()) != nullptr)
550 lcl_TabGetMaxLineWidth(pBorderLine
, aBorderLine
);
551 if ((pBorderLine
= aCoreInfo
.GetHori()) != nullptr)
552 lcl_TabGetMaxLineWidth(pBorderLine
, aBorderLine
);
553 if ((pBorderLine
= aCoreInfo
.GetVert()) != nullptr)
554 lcl_TabGetMaxLineWidth(pBorderLine
, aBorderLine
);
556 if(aBorderLine
.GetOutWidth() == 0)
558 aBorderLine
.SetBorderLineStyle(SvxBorderLineStyle::SOLID
);
559 aBorderLine
.SetWidth( SvxBorderLineWidth::VeryThin
);
562 if( aBox
->GetTop() != nullptr )
564 aBox
->SetLine(&aBorderLine
, SvxBoxItemLine::TOP
);
566 if( aBox
->GetBottom() != nullptr )
568 aBox
->SetLine(&aBorderLine
, SvxBoxItemLine::BOTTOM
);
570 if( aBox
->GetLeft() != nullptr )
572 aBox
->SetLine(&aBorderLine
, SvxBoxItemLine::LEFT
);
574 if( aBox
->GetRight() != nullptr )
576 aBox
->SetLine(&aBorderLine
, SvxBoxItemLine::RIGHT
);
578 if( aInfo
->GetHori() != nullptr )
580 aInfo
->SetLine(&aBorderLine
, SvxBoxInfoItemLine::HORI
);
582 if( aInfo
->GetVert() != nullptr )
584 aInfo
->SetLine(&aBorderLine
, SvxBoxInfoItemLine::VERT
);
587 aCoreSet
.Put( *aBox
);
588 aCoreSet
.Put( *aInfo
);
589 rSh
.SetTabBorders( aCoreSet
);
591 // we must record the "real" values because otherwise the lines can't be reconstructed on playtime
592 // the coding style of the controller (setting lines with width 0) is not transportable via Query/PutValue in
594 rReq
.AppendItem( *aBox
);
595 rReq
.AppendItem( *aInfo
);
599 case FN_INSERT_TABLE
:
602 case FN_FORMAT_TABLE_DLG
:
604 //#127012# get the bindings before the dialog is called
605 // it might happen that this shell is removed after closing the dialog
606 SfxBindings
& rBindings
= GetView().GetViewFrame().GetBindings();
607 SfxItemSet
aCoreSet( GetPool(), aUITableAttrRange
);
609 FieldUnit eMetric
= ::GetDfltMetric(dynamic_cast<SwWebView
*>( &rSh
.GetView()) != nullptr );
610 SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC
, static_cast< sal_uInt16
>(eMetric
)));
611 std::shared_ptr
<SwTableRep
> pTableRep(::lcl_TableParamToItemSet(aCoreSet
, rSh
));
613 aCoreSet
.Put(SfxUInt16Item(SID_HTML_MODE
, ::GetHtmlMode(GetView().GetDocShell())));
614 rSh
.GetTableAttr(aCoreSet
);
615 // GetTableAttr overwrites the background!
616 std::unique_ptr
<SvxBrushItem
> aBrush(std::make_unique
<SvxBrushItem
>(RES_BACKGROUND
));
617 if(rSh
.GetBoxBackground(aBrush
))
618 aCoreSet
.Put( *aBrush
);
620 aCoreSet
.InvalidateItem( RES_BACKGROUND
);
622 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
623 VclPtr
<SfxAbstractTabDialog
> pDlg(pFact
->CreateSwTableTabDlg(GetView().GetFrameWeld(), &aCoreSet
, &rSh
));
628 pDlg
->SetCurPageId(static_cast<const SfxStringItem
*>(pItem
)->GetValue());
630 auto pRequest
= std::make_shared
<SfxRequest
>(rReq
);
631 rReq
.Ignore(); // the 'old' request is not relevant any more
633 const bool bTableMode
= rSh
.IsTableMode();
634 SwPaM
* pCursor
= bTableMode
? rSh
.GetTableCrs() : rSh
.GetCursor(); // tdf#142165 use table cursor if in table mode
635 auto vCursors
= CopyPaMRing(*pCursor
); // tdf#135636 make a copy to use at later apply
636 pDlg
->StartExecuteAsync([pDlg
, pRequest
, pTableRep
, &rBindings
, &rSh
, vCursors
, bTableMode
](sal_Int32 nResult
){
637 if (RET_OK
== nResult
)
639 if (!bTableMode
&& rSh
.IsTableMode()) // tdf#140977 drop current table-cursor if setting a replacement
640 rSh
.TableCursorToCursor(); // non-table one
642 // tdf#135636 set the selection at dialog launch as current selection
643 rSh
.SetSelection(*vCursors
->front()); // UpdateCursor() will be called which in the case
644 // of a table selection should recreate a
645 // SwShellTableCursor if the selection is more than a single cell
647 if (bTableMode
&& !rSh
.IsTableMode()) // tdf#142721 ensure the new selection is a SwShellTableCursor in
648 rSh
.SelTableBox(); // the case of a single cell
650 const SfxItemSet
* pOutSet
= pDlg
->GetOutputItemSet();
652 //to record FN_INSERT_TABLE correctly
653 pRequest
->SetSlot(FN_FORMAT_TABLE_DLG
);
654 pRequest
->Done(*pOutSet
);
656 ItemSetToTableParam(*pOutSet
, rSh
);
659 rBindings
.Update(SID_RULER_BORDERS
);
660 rBindings
.Update(SID_ATTR_TABSTOP
);
661 rBindings
.Update(SID_RULER_BORDERS_VERTICAL
);
662 rBindings
.Update(SID_ATTR_TABSTOP_VERTICAL
);
670 ItemSetToTableParam(*rReq
.GetArgs(), rSh
);
672 rBindings
.Update(SID_RULER_BORDERS
);
673 rBindings
.Update(SID_ATTR_TABSTOP
);
674 rBindings
.Update(SID_RULER_BORDERS_VERTICAL
);
675 rBindings
.Update(SID_ATTR_TABSTOP_VERTICAL
);
681 case SID_ATTR_BRUSH_ROW
:
682 case SID_ATTR_BRUSH_TABLE
:
684 ItemSetToTableParam(*rReq
.GetArgs(), rSh
);
686 case FN_NUM_FORMAT_TABLE_DLG
:
688 if (SwView
* pView
= GetActiveView())
690 FieldUnit eMetric
= ::GetDfltMetric(dynamic_cast<SwWebView
*>( pView
) != nullptr );
691 SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC
, static_cast< sal_uInt16
>(eMetric
)));
692 SvNumberFormatter
* pFormatter
= rSh
.GetNumberFormatter();
693 auto pCoreSet
= std::make_shared
<SfxItemSetFixed
<SID_ATTR_NUMBERFORMAT_VALUE
, SID_ATTR_NUMBERFORMAT_INFO
>>( GetPool() );
695 SfxItemSetFixed
<RES_BOXATR_FORMAT
, RES_BOXATR_FORMAT
,
696 RES_BOXATR_VALUE
, RES_BOXATR_VALUE
>
697 aBoxSet( *pCoreSet
->GetPool() );
698 rSh
.GetTableBoxFormulaAttrs( aBoxSet
);
700 SfxItemState eState
= aBoxSet
.GetItemState(RES_BOXATR_FORMAT
);
701 if(eState
== SfxItemState::DEFAULT
)
703 pCoreSet
->Put( SfxUInt32Item( SID_ATTR_NUMBERFORMAT_VALUE
,
704 pFormatter
->GetFormatIndex(NF_TEXT
, LANGUAGE_SYSTEM
)));
707 pCoreSet
->Put( SfxUInt32Item( SID_ATTR_NUMBERFORMAT_VALUE
,
709 RES_BOXATR_FORMAT
).GetValue() ));
711 OUString
sCurText( rSh
.GetTableBoxText() );
712 pCoreSet
->Put( SvxNumberInfoItem( pFormatter
,
714 RES_BOXATR_VALUE
).GetValue(),
715 sCurText
, SID_ATTR_NUMBERFORMAT_INFO
));
717 SwWrtShell
* pSh
= &rSh
;
718 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
719 VclPtr
<SfxAbstractDialog
> pDlg(pFact
->CreateNumFormatDialog(GetView().GetFrameWeld(), *pCoreSet
));
721 pDlg
->StartExecuteAsync([pDlg
, pCoreSet
, pSh
](sal_uInt32 nResult
){
722 if (RET_OK
== nResult
)
724 const SvxNumberInfoItem
* pNumberFormatItem
725 = pSh
->GetView().GetDocShell()->GetItem( SID_ATTR_NUMBERFORMAT_INFO
);
727 if( pNumberFormatItem
)
729 for ( sal_uInt32 key
: pNumberFormatItem
->GetDelFormats() )
730 pNumberFormatItem
->GetNumberFormatter()->DeleteEntry( key
);
733 const SfxPoolItem
* pNumberFormatValueItem
=
734 pDlg
->GetOutputItemSet()->GetItemIfSet(
735 SID_ATTR_NUMBERFORMAT_VALUE
, false);
736 if( pNumberFormatValueItem
)
738 SfxItemSetFixed
<RES_BOXATR_FORMAT
, RES_BOXATR_FORMAT
>
739 aBoxFormatSet( *pCoreSet
->GetPool() );
740 aBoxFormatSet
.Put( SwTableBoxNumFormat(
741 static_cast<const SfxUInt32Item
*>(pNumberFormatValueItem
)->GetValue() ));
742 pSh
->SetTableBoxFormulaAttrs( aBoxFormatSet
);
756 case FN_TABLE_DELETE_COL
:
757 if ( rSh
.DeleteCol() && rSh
.HasSelection() )
762 rSh
.MoveTable( GotoCurrTable
, fnTableEnd
);
766 rSh
.MoveTable( GotoCurrTable
, fnTableStart
);
769 case FN_GOTO_NEXT_CELL
:
771 bool bAppendLine
= true;
773 bAppendLine
= static_cast<const SfxBoolItem
*>(pItem
)->GetValue();
774 rReq
.SetReturnValue( SfxBoolItem( nSlot
,
775 rSh
.GoNextCell( bAppendLine
) ) );
779 case FN_GOTO_PREV_CELL
:
780 rReq
.SetReturnValue( SfxBoolItem( nSlot
, rSh
.GoPrevCell() ) );
783 case FN_TABLE_DELETE_ROW
:
784 if ( rSh
.DeleteRow() && rSh
.HasSelection() )
788 case FN_TABLE_MERGE_CELLS
:
789 if ( rSh
.IsTableMode() )
790 switch ( rSh
.MergeTab() )
792 case TableMergeErr::Ok
:
795 case TableMergeErr::NoSelection
:
797 case TableMergeErr::TooComplex
:
799 std::unique_ptr
<weld::MessageDialog
> xInfoBox(Application::CreateMessageDialog(GetView().GetFrameWeld(),
800 VclMessageType::Info
, VclButtonsType::Ok
,
801 SwResId(STR_ERR_TABLE_MERGE
)));
806 OSL_ENSURE( false, "unknown return value MergeTab.");
810 case SID_TABLE_MINIMAL_COLUMN_WIDTH
:
811 case FN_TABLE_ADJUST_CELLS
:
812 case FN_TABLE_BALANCE_CELLS
:
814 bool bBalance
= (FN_TABLE_BALANCE_CELLS
== nSlot
);
815 const bool bNoShrink
= FN_TABLE_ADJUST_CELLS
== nSlot
;
816 if ( rSh
.IsAdjustCellWidthAllowed(bBalance
) )
819 // remove actions to make a valid table selection
820 UnoActionRemoveContext
aRemoveContext(rSh
.GetDoc());
822 rSh
.AdjustCellWidth(bBalance
, bNoShrink
);
827 case SID_TABLE_MINIMAL_ROW_HEIGHT
:
829 const SwFormatFrameSize aSz
;
830 rSh
.SetRowHeight( aSz
);
834 case FN_TABLE_OPTIMAL_HEIGHT
:
836 rSh
.BalanceRowHeight(/*bTstOnly=*/false, /*bOptimize=*/true);
837 rSh
.BalanceRowHeight(/*bTstOnly=*/false, /*bOptimize=*/false);
841 case FN_TABLE_BALANCE_ROWS
:
842 if ( rSh
.BalanceRowHeight(true) )
843 rSh
.BalanceRowHeight(false);
846 case FN_TABLE_SELECT_ALL
:
848 rSh
.MoveTable( GotoCurrTable
, fnTableStart
);
850 rSh
.MoveTable( GotoCurrTable
, fnTableEnd
);
854 case FN_TABLE_SELECT_COL
:
856 rSh
.SelectTableCol();
859 case FN_TABLE_SELECT_ROW
:
861 rSh
.SelectTableRow();
864 case FN_TABLE_SET_READ_ONLY_CELLS
:
866 rSh
.ResetSelect( nullptr, false );
869 case FN_TABLE_UNSET_READ_ONLY_CELLS
:
870 rSh
.UnProtectCells();
875 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
876 ScopedVclPtr
<AbstractSwAutoFormatDlg
> pDlg(pFact
->CreateSwAutoFormatDlg(GetView().GetFrameWeld(), &rSh
));
880 case FN_TABLE_SET_ROW_HEIGHT
:
882 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
883 ScopedVclPtr
<VclAbstractDialog
> pDlg(pFact
->CreateSwTableHeightDialog(GetView().GetFrameWeld(), rSh
));
887 case FN_NUMBER_BULLETS
:
888 case FN_NUM_BULLET_ON
:
889 OSL_ENSURE( false, "function may not be called now." );
893 // 2015/06 The following two are deprecated but kept for ascending
895 case FN_TABLE_INSERT_COL
:
896 case FN_TABLE_INSERT_ROW
:
898 case FN_TABLE_INSERT_COL_BEFORE
:
899 case FN_TABLE_INSERT_ROW_BEFORE
:
900 case FN_TABLE_INSERT_COL_AFTER
:
901 case FN_TABLE_INSERT_ROW_AFTER
:
903 bool bColumn
= rReq
.GetSlot() == FN_TABLE_INSERT_COL_BEFORE
904 || rReq
.GetSlot() == FN_TABLE_INSERT_COL_AFTER
905 || rReq
.GetSlot() == FN_TABLE_INSERT_COL
;
906 sal_uInt16 nCount
= 0;
910 nCount
= static_cast<const SfxInt16Item
* >(pItem
)->GetValue();
911 if(const SfxBoolItem
* pAfterItem
= pArgs
->GetItemIfSet(FN_PARAM_INSERT_AFTER
))
912 bAfter
= pAfterItem
->GetValue();
914 else if( !rReq
.IsAPI() )
917 ::GetTableSel( rSh
, aBoxes
);
918 if ( !aBoxes
.empty() )
920 tools::Long maxX
= 0;
921 tools::Long maxY
= 0;
922 tools::Long minX
= std::numeric_limits
<tools::Long
>::max();
923 tools::Long minY
= std::numeric_limits
<tools::Long
>::max();
924 tools::Long nbBoxes
= aBoxes
.size();
925 for ( tools::Long i
= 0; i
< nbBoxes
; i
++ )
927 Point
aCoord ( aBoxes
[i
]->GetCoordinates() );
928 if ( aCoord
.X() < minX
) minX
= aCoord
.X();
929 if ( aCoord
.X() > maxX
) maxX
= aCoord
.X();
930 if ( aCoord
.Y() < minY
) minY
= aCoord
.Y();
931 if ( aCoord
.Y() > maxY
) maxY
= aCoord
.Y();
934 nCount
= maxX
- minX
+ 1;
936 nCount
= maxY
- minY
+ 1;
938 bAfter
= rReq
.GetSlot() == FN_TABLE_INSERT_COL_AFTER
939 || rReq
.GetSlot() == FN_TABLE_INSERT_ROW_AFTER
940 || rReq
.GetSlot() == FN_TABLE_INSERT_ROW
941 || rReq
.GetSlot() == FN_TABLE_INSERT_COL
;
946 // i74180: Table border patch submitted by chensuchun:
947 // -->get the SvxBoxInfoItem of the table before insert
948 SfxItemSet
aCoreSet( GetPool(), aUITableAttrRange
);
949 ::lcl_TableParamToItemSet( aCoreSet
, rSh
);
950 bool bSetInnerBorders
= false;
951 SwUndoId nUndoId
= SwUndoId::EMPTY
;
956 rSh
.StartUndo( SwUndoId::TABLE_INSCOL
);
957 rSh
.InsertCol( nCount
, bAfter
);
958 bSetInnerBorders
= true;
959 nUndoId
= SwUndoId::TABLE_INSCOL
;
961 else if ( !rSh
.IsInRepeatedHeadline() )
963 rSh
.StartUndo( SwUndoId::TABLE_INSROW
);
964 rSh
.InsertRow( nCount
, bAfter
);
965 bSetInnerBorders
= true;
966 nUndoId
= SwUndoId::TABLE_INSROW
;
969 // -->after inserting,reset the inner table borders
970 if ( bSetInnerBorders
)
972 const SvxBoxInfoItem
& aBoxInfo(aCoreSet
.Get(SID_ATTR_BORDER_INNER
));
973 SfxItemSetFixed
<SID_ATTR_BORDER_INNER
, SID_ATTR_BORDER_INNER
> aSet( GetPool() );
974 aSet
.Put( aBoxInfo
);
975 ItemSetToTableParam( aSet
, rSh
);
976 rSh
.EndUndo( nUndoId
);
983 nSlot
= bColumn
? FN_TABLE_INSERT_COL_DLG
: FN_TABLE_INSERT_ROW_DLG
;
985 [[fallthrough
]]; // on Count = 0 appears the dialog
987 case FN_TABLE_INSERT_COL_DLG
:
988 case FN_TABLE_INSERT_ROW_DLG
:
990 const SfxSlot
* pSlot
= GetStaticInterface()->GetSlot(nSlot
);
991 if ( FN_TABLE_INSERT_ROW_DLG
!= nSlot
|| !rSh
.IsInRepeatedHeadline())
993 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
994 ScopedVclPtr
<SvxAbstractInsRowColDlg
> pDlg(pFact
->CreateSvxInsRowColDlg(GetView().GetFrameWeld(),
995 nSlot
== FN_TABLE_INSERT_COL_DLG
, pSlot
->GetCommand()));
996 if( pDlg
->Execute() == 1 )
998 const TypedWhichId
<SfxUInt16Item
> nDispatchSlot
= (nSlot
== FN_TABLE_INSERT_COL_DLG
)
999 ? FN_TABLE_INSERT_COL_AFTER
: FN_TABLE_INSERT_ROW_AFTER
;
1000 SfxUInt16Item
aCountItem( nDispatchSlot
, pDlg
->getInsertCount() );
1001 SfxBoolItem
aAfter( FN_PARAM_INSERT_AFTER
, !pDlg
->isInsertBefore() );
1002 SfxViewFrame
& rVFrame
= GetView().GetViewFrame();
1003 rVFrame
.GetDispatcher()->ExecuteList(nDispatchSlot
,
1004 SfxCallMode::SYNCHRON
|SfxCallMode::RECORD
,
1005 { &aCountItem
, &aAfter
});
1010 case FN_TABLE_SPLIT_CELLS
:
1012 tools::Long nCount
=0;
1013 bool bHorizontal
=true;
1014 bool bProportional
= false;
1015 const SfxInt32Item
* pSplit
= rReq
.GetArg
<SfxInt32Item
>(FN_TABLE_SPLIT_CELLS
);
1016 const SfxBoolItem
* pHor
= rReq
.GetArg
<SfxBoolItem
>(FN_PARAM_1
);
1017 const SfxBoolItem
* pProp
= rReq
.GetArg
<SfxBoolItem
>(FN_PARAM_2
);
1020 nCount
= pSplit
->GetValue();
1022 bHorizontal
= pHor
->GetValue();
1024 bProportional
= pProp
->GetValue();
1028 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
1029 SwWrtShell
* pSh
= &rSh
;
1030 const tools::Long nMaxVert
= rSh
.GetAnyCurRect( CurRectType::Frame
).Width() / MINLAY
;
1031 VclPtr
<SvxAbstractSplitTableDialog
> pDlg(pFact
->CreateSvxSplitTableDialog(GetView().GetFrameWeld(), rSh
.IsTableVertical(), nMaxVert
));
1032 if(rSh
.IsSplitVerticalByDefault())
1033 pDlg
->SetSplitVerticalByDefault();
1034 pDlg
->StartExecuteAsync([pDlg
, pSh
](int nResult
) {
1035 if (nResult
== RET_OK
)
1037 tools::Long nCount2
= pDlg
->GetCount();
1038 bool bHorizontal2
= pDlg
->IsHorizontal();
1039 bool bProportional2
= pDlg
->IsProportional();
1041 // tdf#60242: remember choice for next time
1042 bool bVerticalWasChecked
= !pDlg
->IsHorizontal();
1043 pSh
->SetSplitVerticalByDefault(bVerticalWasChecked
);
1046 pSh
->SplitTab(!bHorizontal2
, static_cast< sal_uInt16
>( nCount2
-1 ), bProportional2
);
1049 pDlg
->disposeOnce();
1055 rSh
.SplitTab(!bHorizontal
, static_cast< sal_uInt16
>( nCount
-1 ), bProportional
);
1063 case FN_TABLE_SPLIT_TABLE
:
1065 const SfxUInt16Item
* pType
= rReq
.GetArg
<SfxUInt16Item
>(FN_PARAM_1
);
1068 switch( static_cast<SplitTable_HeadlineOption
>(pType
->GetValue()) )
1070 case SplitTable_HeadlineOption::NONE
:
1071 case SplitTable_HeadlineOption::BorderCopy
:
1072 case SplitTable_HeadlineOption::ContentCopy
:
1073 case SplitTable_HeadlineOption::BoxAttrCopy
:
1074 case SplitTable_HeadlineOption::BoxAttrAllCopy
:
1075 rSh
.SplitTable(static_cast<SplitTable_HeadlineOption
>(pType
->GetValue())) ;
1077 default: ;//wrong parameter, do nothing
1082 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
1083 VclPtr
<AbstractSplitTableDialog
> pDlg(pFact
->CreateSplitTableDialog(GetView().GetFrameWeld(), rSh
));
1085 SwWrtShell
* pSh
= &rSh
;
1087 pDlg
->StartExecuteAsync([pDlg
, pSh
](int nResult
) {
1088 if (nResult
== RET_OK
)
1090 const auto aSplitMode
= pDlg
->GetSplitMode();
1091 pSh
->SplitTable( aSplitMode
);
1094 pDlg
->disposeOnce();
1096 rReq
.Ignore(); // We're already handling the request in our async bit
1101 case FN_TABLE_MERGE_TABLE
:
1103 bool bPrev
= rSh
.CanMergeTable();
1104 bool bNext
= rSh
.CanMergeTable( false );
1106 if( bPrev
&& bNext
)
1108 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
1109 ScopedVclPtr
<VclAbstractDialog
> pDlg(pFact
->CreateTableMergeDialog(GetView().GetFrameWeld(), bPrev
));
1110 if( RET_OK
!= pDlg
->Execute())
1111 bPrev
= bNext
= false;
1114 if( bPrev
|| bNext
)
1115 rSh
.MergeTable( bPrev
);
1119 case FN_TABLE_MODE_FIX
:
1120 case FN_TABLE_MODE_FIX_PROP
:
1121 case FN_TABLE_MODE_VARIABLE
:
1123 rSh
.SetTableChgMode( FN_TABLE_MODE_FIX
== nSlot
1124 ? TableChgMode::FixedWidthChangeAbs
1125 : FN_TABLE_MODE_FIX_PROP
== nSlot
1126 ? TableChgMode::FixedWidthChangeProp
1127 : TableChgMode::VarWidthChangeAbs
);
1129 SfxBindings
& rBind
= GetView().GetViewFrame().GetBindings();
1130 static sal_uInt16 aInva
[] =
1131 { FN_TABLE_MODE_FIX
,
1132 FN_TABLE_MODE_FIX_PROP
,
1133 FN_TABLE_MODE_VARIABLE
,
1136 rBind
.Invalidate( aInva
);
1140 case FN_TABLE_AUTOSUM
:
1142 SfxViewFrame
& rVFrame
= GetView().GetViewFrame();
1143 rVFrame
.GetDispatcher()->Execute(FN_EDIT_FORMULA
, SfxCallMode::SYNCHRON
);
1144 const sal_uInt16 nId
= SwInputChild::GetChildWindowId();
1145 SwInputChild
* pChildWin
= static_cast<SwInputChild
*>(rVFrame
.
1146 GetChildWindow( nId
));
1148 GetShell().GetAutoSum(sSum
);
1150 pChildWin
->SetFormula( sSum
);
1154 case FN_TABLE_HEADLINE_REPEAT
:
1155 if(0 != rSh
.GetRowsToRepeat())
1156 rSh
.SetRowsToRepeat( 0 );
1158 rSh
.SetRowsToRepeat(rSh
.GetRowSelectionFromTop());
1160 case FN_TABLE_SELECT_CELL
:
1161 rSh
.SelectTableCell();
1163 case FN_TABLE_DELETE_TABLE
:
1167 rSh
.GetView().GetViewFrame().GetDispatcher()->Execute(FN_TABLE_SELECT_ALL
);
1171 //'this' is already destroyed
1174 case SID_ATTR_TABLE_ROW_HEIGHT
:
1176 const SfxUInt32Item
* pItem2
= rReq
.GetArg
<SfxUInt32Item
>(SID_ATTR_TABLE_ROW_HEIGHT
);
1179 tools::Long nNewHeight
= pItem2
->GetValue();
1180 std::unique_ptr
<SwFormatFrameSize
> pHeight
= rSh
.GetRowHeight();
1183 if (pHeight
->GetHeightSizeType() == SwFrameSize::Variable
)
1184 pHeight
->SetHeightSizeType(SwFrameSize::Minimum
);
1185 pHeight
->SetHeight(nNewHeight
);
1186 rSh
.SetRowHeight(*pHeight
);
1191 case SID_ATTR_TABLE_COLUMN_WIDTH
:
1193 const SfxUInt32Item
* pItem2
= rReq
.GetArg
<SfxUInt32Item
>(SID_ATTR_TABLE_COLUMN_WIDTH
);
1196 tools::Long nNewWidth
= pItem2
->GetValue();
1197 SwTableFUNC
aFunc( &rSh
);
1198 aFunc
.InitTabCols();
1199 aFunc
.SetColWidth(aFunc
.GetCurColNum(), nNewWidth
);
1214 // Now the slots which are working directly on the TableFormat.
1217 case SID_ATTR_ULSPACE
:
1220 SvxULSpaceItem
aULSpace( *static_cast<const SvxULSpaceItem
*>(pItem
) );
1221 aULSpace
.SetWhich( RES_UL_SPACE
);
1222 ::lcl_SetAttr( rSh
, aULSpace
);
1226 case SID_ATTR_LRSPACE
:
1229 SfxItemSetFixed
<RES_LR_SPACE
, RES_LR_SPACE
,
1230 RES_HORI_ORIENT
, RES_HORI_ORIENT
> aSet( GetPool() );
1231 SvxLRSpaceItem
aLRSpace( *static_cast<const SvxLRSpaceItem
*>(pItem
) );
1232 aLRSpace
.SetWhich( RES_LR_SPACE
);
1233 aSet
.Put( aLRSpace
);
1234 rSh
.SetTableAttr( aSet
);
1237 // The last case branch which needs a table manager!!
1238 case FN_TABLE_SET_COL_WIDTH
:
1240 SwTableFUNC
aMgr( &rSh
);
1241 aMgr
.ColWidthDlg(GetView().GetFrameWeld());
1244 case SID_TABLE_VERT_NONE
:
1245 case SID_TABLE_VERT_CENTER
:
1246 case SID_TABLE_VERT_BOTTOM
:
1248 const sal_uInt16 nAlign
= nSlot
== SID_TABLE_VERT_NONE
?
1249 text::VertOrientation::NONE
:
1250 nSlot
== SID_TABLE_VERT_CENTER
?
1251 text::VertOrientation::CENTER
: text::VertOrientation::BOTTOM
;
1252 rSh
.SetBoxAlign(nAlign
);
1257 case SID_ATTR_PARA_SPLIT
:
1260 SwFormatLayoutSplit
aSplit( static_cast<const SvxFormatSplitItem
*>(pItem
)->GetValue());
1261 SfxItemSetFixed
<RES_LAYOUT_SPLIT
, RES_LAYOUT_SPLIT
> aSet(GetPool());
1263 rSh
.SetTableAttr(aSet
);
1267 case SID_ATTR_PARA_KEEP
:
1270 SvxFormatKeepItem
aKeep( *static_cast<const SvxFormatKeepItem
*>(pItem
) );
1271 aKeep
.SetWhich( RES_KEEP
);
1272 SfxItemSetFixed
<RES_KEEP
, RES_KEEP
> aSet(GetPool());
1274 rSh
.SetTableAttr(aSet
);
1277 case FN_TABLE_ROW_SPLIT
:
1279 const SfxBoolItem
* pBool
= static_cast<const SfxBoolItem
*>(pItem
);
1280 std::unique_ptr
<SwFormatRowSplit
> pSplit
;
1283 pSplit
= rSh
.GetRowSplit();
1285 pSplit
->SetValue(!pSplit
->GetValue());
1287 pSplit
.reset(new SwFormatRowSplit(true));
1291 pSplit
.reset(new SwFormatRowSplit(pBool
->GetValue()));
1293 rSh
.SetRowSplit( *pSplit
);
1298 OSL_ENSURE( false, "wrong Dispatcher" );
1305 void SwTableShell::GetState(SfxItemSet
&rSet
)
1307 SfxWhichIter
aIter( rSet
);
1308 SwWrtShell
&rSh
= GetShell();
1309 SwFrameFormat
*pFormat
= rSh
.GetTableFormat();
1310 // os #124829# crash report: in case of an invalid shell selection return immediately
1313 sal_uInt16 nSlot
= aIter
.FirstWhich();
1318 case FN_TABLE_MERGE_CELLS
:
1319 if ( !rSh
.IsTableMode() )
1320 rSet
.DisableItem(FN_TABLE_MERGE_CELLS
);
1322 case SID_TABLE_MINIMAL_COLUMN_WIDTH
:
1323 case FN_TABLE_ADJUST_CELLS
:
1324 if ( !rSh
.IsAdjustCellWidthAllowed() )
1325 rSet
.DisableItem(nSlot
);
1328 case FN_TABLE_BALANCE_CELLS
:
1329 if ( !rSh
.IsAdjustCellWidthAllowed(true) )
1330 rSet
.DisableItem(FN_TABLE_BALANCE_CELLS
);
1333 case FN_TABLE_OPTIMAL_HEIGHT
:
1334 case FN_TABLE_BALANCE_ROWS
:
1335 if ( !rSh
.BalanceRowHeight(true) )
1336 rSet
.DisableItem(nSlot
);
1338 case FN_OPTIMIZE_TABLE
:
1339 if ( !rSh
.IsTableMode() &&
1340 !rSh
.IsAdjustCellWidthAllowed() &&
1341 !rSh
.IsAdjustCellWidthAllowed(true) &&
1342 !rSh
.BalanceRowHeight(true) )
1343 rSet
.DisableItem(FN_OPTIMIZE_TABLE
);
1345 case SID_INSERT_DIAGRAM
:
1347 SvtModuleOptions aMOpt
;
1348 if ( !aMOpt
.IsMath() || rSh
.IsTableComplexForChart() )
1349 rSet
.DisableItem(nSlot
);
1353 case FN_INSERT_TABLE
:
1354 if ( rSh
.CursorInsideInputField() )
1356 rSet
.DisableItem( nSlot
);
1360 case SID_TABLE_MINIMAL_ROW_HEIGHT
:
1362 // Disable if auto height already is enabled.
1363 std::unique_ptr
<SwFormatFrameSize
> pSz
= rSh
.GetRowHeight();
1366 if ( SwFrameSize::Variable
== pSz
->GetHeightSizeType() )
1367 rSet
.DisableItem( nSlot
);
1371 case FN_TABLE_INSERT_COL_BEFORE
:
1372 case FN_TABLE_INSERT_COL_AFTER
:
1374 SfxImageItem
aImageItem(nSlot
);
1375 if (pFormat
->GetFrameDir().GetValue() == SvxFrameDirection::Environment
)
1377 // Inherited from superordinate object (page or frame).
1378 // If the table spans multiple pages, direction is set by the first page.
1379 SwIterator
<SwTabFrame
, SwFrameFormat
> aIterT(*pFormat
);
1380 for (SwTabFrame
* pFrame
= aIterT
.First(); pFrame
;
1381 pFrame
= static_cast<SwTabFrame
*>(pFrame
->GetPrecede()))
1382 aImageItem
.SetMirrored(pFrame
->IsRightToLeft());
1385 aImageItem
.SetMirrored(pFormat
->GetFrameDir().GetValue() == SvxFrameDirection::Horizontal_RL_TB
);
1386 rSet
.Put(aImageItem
);
1389 case FN_TABLE_INSERT_ROW
:
1390 case FN_TABLE_INSERT_ROW_AFTER
:
1391 case FN_TABLE_INSERT_ROW_DLG
:
1392 if ( rSh
.IsInRepeatedHeadline() )
1393 rSet
.DisableItem( nSlot
);
1396 rSet
.Put(pFormat
->GetLRSpace());
1399 rSet
.Put(pFormat
->GetULSpace());
1402 case SID_TABLE_VERT_NONE
:
1403 case SID_TABLE_VERT_CENTER
:
1404 case SID_TABLE_VERT_BOTTOM
:
1406 const sal_uInt16 nAlign
= rSh
.GetBoxAlign();
1407 bool bSet
= (nSlot
== SID_TABLE_VERT_NONE
&& nAlign
== text::VertOrientation::NONE
) ||
1408 (nSlot
== SID_TABLE_VERT_CENTER
&& nAlign
== text::VertOrientation::CENTER
) ||
1409 (nSlot
== SID_TABLE_VERT_BOTTOM
&& nAlign
== text::VertOrientation::BOTTOM
);
1410 rSet
.Put(SfxBoolItem(nSlot
, bSet
));
1414 case FN_TABLE_MODE_FIX
:
1415 case FN_TABLE_MODE_FIX_PROP
:
1416 case FN_TABLE_MODE_VARIABLE
:
1418 TableChgMode nMode
= rSh
.GetTableChgMode();
1419 bool bSet
= (nSlot
== FN_TABLE_MODE_FIX
&& nMode
== TableChgMode::FixedWidthChangeAbs
) ||
1420 (nSlot
== FN_TABLE_MODE_FIX_PROP
&& nMode
== TableChgMode::FixedWidthChangeProp
) ||
1421 (nSlot
== FN_TABLE_MODE_VARIABLE
&& nMode
== TableChgMode::VarWidthChangeAbs
);
1422 rSet
.Put(SfxBoolItem(nSlot
, bSet
));
1426 case SID_ATTR_PARA_SPLIT
:
1427 rSet
.Put( pFormat
->GetKeep() );
1430 case SID_ATTR_PARA_KEEP
:
1431 rSet
.Put( pFormat
->GetLayoutSplit() );
1433 case FN_TABLE_SPLIT_TABLE
:
1434 if ( rSh
.IsInHeadline() )
1435 rSet
.DisableItem( nSlot
);
1437 case FN_TABLE_MERGE_TABLE
:
1440 if( !rSh
.CanMergeTable( true, &bAsk
))
1441 rSet
.DisableItem( nSlot
);
1445 case FN_TABLE_DELETE_ROW
:
1448 ::GetTableSel( rSh
, aBoxes
, SwTableSearchType::Row
);
1449 if( ::HasProtectedCells( aBoxes
) || lcl_BoxesInTrackedRows( rSh
, aBoxes
) )
1450 rSet
.DisableItem( nSlot
);
1453 case FN_TABLE_DELETE_COL
:
1456 ::GetTableSel( rSh
, aBoxes
, SwTableSearchType::Col
);
1457 if( ::HasProtectedCells( aBoxes
) || lcl_CursorInDeletedTable( rSh
) )
1458 rSet
.DisableItem( nSlot
);
1461 case FN_TABLE_DELETE_TABLE
:
1462 if( lcl_CursorInDeletedTable( rSh
) )
1463 rSet
.DisableItem( nSlot
);
1466 case FN_TABLE_UNSET_READ_ONLY_CELLS
:
1467 // disable in readonly sections, but enable in protected cells
1468 if( !rSh
.CanUnProtectCells() )
1469 rSet
.DisableItem( nSlot
);
1473 const SwFormatLayoutSplit
& rTabSplit
= pFormat
->GetLayoutSplit();
1474 if ( !rTabSplit
.GetValue() )
1476 rSet
.DisableItem( nSlot
);
1480 std::unique_ptr
<SwFormatRowSplit
> pSplit
= rSh
.GetRowSplit();
1482 rSet
.Put(std::move(pSplit
));
1484 rSet
.InvalidateItem( nSlot
);
1488 case FN_TABLE_HEADLINE_REPEAT
:
1489 if(0 != rSh
.GetRowsToRepeat())
1490 rSet
.Put(SfxBoolItem(nSlot
, true));
1491 else if(!rSh
.GetRowSelectionFromTop())
1492 rSet
.DisableItem( nSlot
);
1494 rSet
.Put(SfxBoolItem(nSlot
, false));
1496 case FN_TABLE_SELECT_CELL
:
1497 if(rSh
.HasBoxSelection())
1498 rSet
.DisableItem( nSlot
);
1500 case SID_ATTR_TABLE_ROW_HEIGHT
:
1502 SfxUInt32Item
aRowHeight(SID_ATTR_TABLE_ROW_HEIGHT
);
1503 std::unique_ptr
<SwFormatFrameSize
> pHeight
= rSh
.GetRowHeight();
1506 tools::Long nHeight
= pHeight
->GetHeight();
1507 aRowHeight
.SetValue(nHeight
);
1508 rSet
.Put(aRowHeight
);
1510 if (comphelper::LibreOfficeKit::isActive())
1512 // TODO: set correct unit
1513 MapUnit eTargetUnit
= MapUnit::MapInch
;
1514 OUString sHeight
= GetMetricText(nHeight
,
1515 MapUnit::MapTwip
, eTargetUnit
, nullptr);
1517 OUString sPayload
= ".uno:TableRowHeight=" + sHeight
;
1519 GetViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED
,
1520 OUStringToOString(sPayload
, RTL_TEXTENCODING_ASCII_US
));
1525 case SID_ATTR_TABLE_COLUMN_WIDTH
:
1527 SfxUInt32Item
aColumnWidth(SID_ATTR_TABLE_COLUMN_WIDTH
);
1528 SwTableFUNC
aFunc( &rSh
);
1529 aFunc
.InitTabCols();
1530 SwTwips nWidth
= aFunc
.GetColWidth(aFunc
.GetCurColNum());
1531 aColumnWidth
.SetValue(nWidth
);
1532 rSet
.Put(aColumnWidth
);
1534 if (comphelper::LibreOfficeKit::isActive())
1536 // TODO: set correct unit
1537 MapUnit eTargetUnit
= MapUnit::MapInch
;
1538 OUString sWidth
= GetMetricText(nWidth
,
1539 MapUnit::MapTwip
, eTargetUnit
, nullptr);
1541 OUString sPayload
= ".uno:TableColumWidth=" + sWidth
;
1543 GetViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED
,
1544 OUStringToOString(sPayload
, RTL_TEXTENCODING_ASCII_US
));
1550 nSlot
= aIter
.NextWhich();
1554 SwTableShell::SwTableShell(SwView
&_rView
) :
1558 SfxShell::SetContextName(vcl::EnumContext::GetContextName(vcl::EnumContext::Context::Table
));
1561 void SwTableShell::GetFrameBorderState(SfxItemSet
&rSet
)
1563 SfxItemSetFixed
<RES_BOX
, RES_BOX
,
1564 SID_ATTR_BORDER_INNER
, SID_ATTR_BORDER_INNER
> aCoreSet( GetPool() );
1565 SvxBoxInfoItem
aBoxInfo( SID_ATTR_BORDER_INNER
);
1566 aCoreSet
.Put( aBoxInfo
);
1567 GetShell().GetTabBorders( aCoreSet
);
1568 rSet
.Put( aCoreSet
);
1571 void SwTableShell::ExecTableStyle(SfxRequest
& rReq
)
1573 SwWrtShell
&rSh
= GetShell();
1574 const SfxItemSet
*pArgs
= rReq
.GetArgs();
1578 switch ( rReq
.GetSlot() )
1580 case SID_FRAME_LINESTYLE
:
1581 case SID_FRAME_LINECOLOR
:
1582 if ( rReq
.GetSlot() == SID_FRAME_LINESTYLE
)
1584 const SvxLineItem
&rLineItem
= pArgs
->Get( SID_FRAME_LINESTYLE
);
1585 const SvxBorderLine
* pBorderLine
= rLineItem
.GetLine();
1586 rSh
.SetTabLineStyle( nullptr, true, pBorderLine
);
1590 const SvxColorItem
&rNewColorItem
= pArgs
->Get( SID_FRAME_LINECOLOR
);
1591 rSh
.SetTabLineStyle( &rNewColorItem
.GetValue() );
1600 void SwTableShell::GetLineStyleState(SfxItemSet
&rSet
)
1602 SfxItemSetFixed
<RES_BOX
, RES_BOX
,
1603 SID_ATTR_BORDER_INNER
, SID_ATTR_BORDER_INNER
> aCoreSet( GetPool() );
1604 SvxBoxInfoItem
aCoreInfo( SID_ATTR_BORDER_INNER
);
1605 aCoreSet
.Put(aCoreInfo
);
1606 GetShell().GetTabBorders( aCoreSet
);
1608 const SvxBoxItem
& rBoxItem
= aCoreSet
.Get( RES_BOX
);
1609 const SvxBorderLine
* pLine
= rBoxItem
.GetTop();
1611 rSet
.Put( SvxColorItem( pLine
? pLine
->GetColor() : Color(), SID_FRAME_LINECOLOR
) );
1612 SvxLineItem
aLine( SID_FRAME_LINESTYLE
);
1613 aLine
.SetLine(pLine
);
1617 void SwTableShell::ExecNumberFormat(SfxRequest
const & rReq
)
1619 const SfxItemSet
* pArgs
= rReq
.GetArgs();
1620 SwWrtShell
&rSh
= GetShell();
1622 // At first the slots, which doesn't need a FrameMgr.
1623 const SfxPoolItem
* pItem
= nullptr;
1624 const sal_uInt16 nSlot
= rReq
.GetSlot();
1626 pArgs
->GetItemState(GetPool().GetWhich(nSlot
), false, &pItem
);
1628 // Always acquire the language from the current cursor position.
1629 LanguageType eLang
= rSh
.GetCurLang();
1630 SvNumberFormatter
* pFormatter
= rSh
.GetNumberFormatter();
1631 sal_uInt32 nNumberFormat
= NUMBERFORMAT_ENTRY_NOT_FOUND
;
1632 SvNumFormatType nFormatType
= SvNumFormatType::ALL
;
1633 sal_uInt16 nOffset
= 0;
1637 case FN_NUMBER_FORMAT
:
1640 // Determine index for string.
1641 OUString
aCode( static_cast<const SfxStringItem
*>(pItem
)->GetValue() );
1642 nNumberFormat
= pFormatter
->GetEntryKey( aCode
, eLang
);
1643 if( NUMBERFORMAT_ENTRY_NOT_FOUND
== nNumberFormat
)
1647 SvNumFormatType nType
;
1648 if( !pFormatter
->PutEntry( aCode
, nErrPos
, nType
,
1649 nNumberFormat
, eLang
))
1650 nNumberFormat
= NUMBERFORMAT_ENTRY_NOT_FOUND
;
1654 case FN_NUMBER_STANDARD
: nFormatType
= SvNumFormatType::NUMBER
; break;
1655 case FN_NUMBER_SCIENTIFIC
: nFormatType
= SvNumFormatType::SCIENTIFIC
; break;
1656 case FN_NUMBER_DATE
: nFormatType
= SvNumFormatType::DATE
; break;
1657 case FN_NUMBER_TIME
: nFormatType
= SvNumFormatType::TIME
; break;
1658 case FN_NUMBER_CURRENCY
: nFormatType
= SvNumFormatType::CURRENCY
; break;
1659 case FN_NUMBER_PERCENT
: nFormatType
= SvNumFormatType::PERCENT
; break;
1661 case FN_NUMBER_TWODEC
: // #.##0,00
1662 nFormatType
= SvNumFormatType::NUMBER
;
1663 nOffset
= NF_NUMBER_1000DEC2
;
1667 OSL_FAIL("wrong dispatcher");
1671 if( nFormatType
!= SvNumFormatType::ALL
)
1672 nNumberFormat
= pFormatter
->GetStandardFormat( nFormatType
, eLang
) + nOffset
;
1674 if( NUMBERFORMAT_ENTRY_NOT_FOUND
!= nNumberFormat
)
1676 SfxItemSetFixed
<RES_BOXATR_FORMAT
, RES_BOXATR_FORMAT
> aBoxSet( GetPool() );
1677 aBoxSet
.Put( SwTableBoxNumFormat( nNumberFormat
));
1678 rSh
.SetTableBoxFormulaAttrs( aBoxSet
);
1683 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */