/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: */ |