LibreOffice Module sw (master) 1
docxtableexport.cxx
Go to the documentation of this file.
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
21
22#include <com/sun/star/text/XTextTable.hpp>
23
25#include <svl/grabbagitem.hxx>
26#include <sax/fshelper.hxx>
27#include <editeng/ulspitem.hxx>
28#include <comphelper/string.hxx>
29#include <editeng/lrspitem.hxx>
30#include <editeng/brushitem.hxx>
32
33#include <fmtfsize.hxx>
34#include <unocoll.hxx>
35#include <formatflysplit.hxx>
37#include <frmatr.hxx>
38#include <swmodule.hxx>
39#include <fmtrowsplt.hxx>
40
41#include "docxexportfilter.hxx"
42#include "docxhelper.hxx"
43
44using namespace com::sun::star;
45using namespace sax_fastparser;
46using namespace oox;
47
48namespace
49{
51OString lcl_padStartToLength(OString const& aString, sal_Int32 nLen, char cFill)
52{
53 if (nLen > aString.getLength())
54 {
55 sal_Int32 nDiff = nLen - aString.getLength();
56 OStringBuffer aBuffer;
57 comphelper::string::padToLength(aBuffer, nDiff, cFill);
58 aBuffer.append(aString);
59 return aBuffer.makeStringAndClear();
60 }
61 else
62 return aString;
63}
64
65//Keep this function in-sync with the one in writerfilter/.../SettingsTable.cxx
66//Since this is not import code, "-1" needs to be handled as the mode that LO will save as.
67//To identify how your code should handle a "-1", look in DocxExport::WriteSettings().
68sal_Int32 lcl_getWordCompatibilityMode(const DocxExport& rDocExport)
69{
70 sal_Int32 nWordCompatibilityMode = rDocExport.getWordCompatibilityModeFromGrabBag();
71
72 // TODO: this is duplicated, better store it in DocxExport member?
74 {
75 if (nWordCompatibilityMode == -1 || 14 < nWordCompatibilityMode)
76 {
77 nWordCompatibilityMode = 14;
78 }
79 }
80
81 return nWordCompatibilityMode;
82}
83
84void CollectFloatingTableAttributes(DocxExport& rExport, const ww8::Frame& rFrame,
85 ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner,
87{
88 // we export the values of the surrounding Frame
89 OString sOrientation;
90 sal_Int32 nValue;
91
92 // If tblpXSpec or tblpYSpec are present, we do not write tblpX or tblpY!
98
101 pAttributes->add(FSNS(XML_w, XML_vertAnchor), sOrientation);
102
103 if (!sTblpYSpec.isEmpty())
104 pAttributes->add(FSNS(XML_w, XML_tblpYSpec), sTblpYSpec);
105
108 pAttributes->add(FSNS(XML_w, XML_horzAnchor), sOrientation);
109
110 if (!sTblpXSpec.isEmpty())
111 pAttributes->add(FSNS(XML_w, XML_tblpXSpec), sTblpXSpec);
112
114 if (nValue != 0)
115 pAttributes->add(FSNS(XML_w, XML_bottomFromText), OString::number(nValue));
116
118 if (nValue != 0)
119 pAttributes->add(FSNS(XML_w, XML_leftFromText), OString::number(nValue));
120
122 if (nValue != 0)
123 pAttributes->add(FSNS(XML_w, XML_rightFromText), OString::number(nValue));
124
126 if (nValue != 0)
127 pAttributes->add(FSNS(XML_w, XML_topFromText), OString::number(nValue));
128
129 if (sTblpXSpec.isEmpty()) // do not write tblpX if tblpXSpec is present
130 {
132 // we need to revert the additional shift introduced by
133 // lcl_DecrementHoriOrientPosition() in writerfilter
134 // 1st: left distance of the table
135 const SwTableBox* pTabBox = pTableTextNodeInfoInner->getTableBox();
136 const SwFrameFormat* pFrameFormat = pTabBox->GetFrameFormat();
137 const SvxBoxItem& rBox = pFrameFormat->GetBox();
138 sal_Int32 nMode = lcl_getWordCompatibilityMode(rExport);
139 if (nMode < 15)
140 {
141 sal_uInt16 nLeftDistance = rBox.GetDistance(SvxBoxItemLine::LEFT);
142 nValue += nLeftDistance;
143 }
144
145 // 2nd: if a left border is given, revert the shift by half the width
146 // from lcl_DecrementHoriOrientPosition() in writerfilter
147 if (const editeng::SvxBorderLine* pLeftBorder = rBox.GetLeft())
148 {
149 tools::Long nWidth = pLeftBorder->GetWidth();
150 nValue += (nWidth / 2);
151 }
152
153 pAttributes->add(FSNS(XML_w, XML_tblpX), OString::number(nValue));
154 }
155
156 if (sTblpYSpec.isEmpty()) // do not write tblpY if tblpYSpec is present
157 {
159 pAttributes->add(FSNS(XML_w, XML_tblpY), OString::number(nValue));
160 }
161}
162}
163
165 ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/)
166{
167}
168
170{
171}
172
174 ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
175{
177
178 // Write the table properties
179 m_pSerializer->startElementNS(XML_w, XML_tblPr);
180
181 static const sal_Int32 aOrder[] = { FSNS(XML_w, XML_tblStyle),
182 FSNS(XML_w, XML_tblpPr),
183 FSNS(XML_w, XML_tblOverlap),
184 FSNS(XML_w, XML_bidiVisual),
185 FSNS(XML_w, XML_tblStyleRowBandSize),
186 FSNS(XML_w, XML_tblStyleColBandSize),
187 FSNS(XML_w, XML_tblW),
188 FSNS(XML_w, XML_jc),
189 FSNS(XML_w, XML_tblCellSpacing),
190 FSNS(XML_w, XML_tblInd),
191 FSNS(XML_w, XML_tblBorders),
192 FSNS(XML_w, XML_shd),
193 FSNS(XML_w, XML_tblLayout),
194 FSNS(XML_w, XML_tblCellMar),
195 FSNS(XML_w, XML_tblLook),
196 FSNS(XML_w, XML_tblPrChange) };
197
198 // postpone the output so that we can later []
199 // prepend the properties before the run
200 // coverity[overrun-buffer-arg : FALSE] - coverity has difficulty with css::uno::Sequence
202
203 tools::Long nPageSize = 0;
204 const char* widthType = "dxa";
205
206 // If actual width of table is relative it should export is as "pct".`
207 const SwTable* pTable = pTableTextNodeInfoInner->getTable();
208 SwFrameFormat* pTableFormat = pTable->GetFrameFormat();
209 const SwFormatFrameSize& rSize = pTableFormat->GetFrameSize();
210 int nWidthPercent = rSize.GetWidthPercent();
211 // If we export a floating table: we use the widthPercent of the surrounding frame
212 const ww8::Frame* pFloatingTableFrame = m_rExport.GetFloatingTableFrame();
213 if (pFloatingTableFrame)
214 {
215 const SwFormatFrameSize& rFrameSize = pFloatingTableFrame->GetFrameFormat().GetFrameSize();
216 nWidthPercent = rFrameSize.GetWidthPercent();
217 }
218
219 uno::Reference<beans::XPropertySet> xPropertySet(
220 SwXTextTables::GetObject(*pTable->GetFrameFormat()), uno::UNO_QUERY);
221 bool isWidthRelative = false;
222 xPropertySet->getPropertyValue("IsWidthRelative") >>= isWidthRelative;
223 if (!isWidthRelative && !nWidthPercent)
224 {
225 // The best fit for "automatic" table placement is relative 100%
226 short nHoriOrient = -1;
227 xPropertySet->getPropertyValue("HoriOrient") >>= nHoriOrient;
228 isWidthRelative = nHoriOrient == text::HoriOrientation::FULL;
229 if (isWidthRelative)
230 nWidthPercent = 100;
231 }
232
233 if (isWidthRelative)
234 {
246 nPageSize = nWidthPercent * 50;
247 widthType = "pct";
248 }
249 else
250 {
251 bool bRelBoxSize = false;
252 // Create the SwWriteTable instance to use col spans (and maybe other infos)
253 GetTablePageSize(pTableTextNodeInfoInner.get(), nPageSize, bRelBoxSize);
254 if (nPageSize == 0)
255 widthType = "auto";
256 }
257
258 // Output the table preferred width
259 m_pSerializer->singleElementNS(XML_w, XML_tblW, FSNS(XML_w, XML_w), OString::number(nPageSize),
260 FSNS(XML_w, XML_type), widthType);
261
262 // Disable layout autofit, as it does not exist in LibreOffice yet
263 m_pSerializer->singleElementNS(XML_w, XML_tblLayout, FSNS(XML_w, XML_type), "fixed");
264
265 // Look for the table style property in the table grab bag
266 const std::map<OUString, css::uno::Any>& rGrabBag
267 = pTableFormat->GetAttrSet().GetItem<SfxGrabBagItem>(RES_FRMATR_GRABBAG)->GetGrabBag();
268
269 // We should clear the TableStyle map. In case of Table inside multiple tables it contains the
270 // table border style of the previous table.
271 std::map<SvxBoxItemLine, css::table::BorderLine2>& rTableStyleConf = m_aTableStyleConfs.back();
272 rTableStyleConf.clear();
273
274 bool bFloatingTableWritten = false;
275 if (pFloatingTableFrame && pFloatingTableFrame->GetFrameFormat().GetFlySplit().GetValue())
276 {
277 rtl::Reference<FastAttributeList> pAttributes = FastSerializerHelper::createAttrList();
278 CollectFloatingTableAttributes(m_rExport, *pFloatingTableFrame, pTableTextNodeInfoInner,
279 pAttributes);
280 m_pSerializer->singleElementNS(XML_w, XML_tblpPr, pAttributes);
281 bFloatingTableWritten = true;
282 // The outer table was floating, make sure potential inner tables are not floating.
284 }
285
286 // Extract properties from grab bag
287 for (const auto& rGrabBagElement : rGrabBag)
288 {
289 if (rGrabBagElement.first == "TableStyleName")
290 {
291 OString sStyleName
292 = OUStringToOString(rGrabBagElement.second.get<OUString>(), RTL_TEXTENCODING_UTF8);
293 m_pSerializer->singleElementNS(XML_w, XML_tblStyle, FSNS(XML_w, XML_val), sStyleName);
294 }
295 else if (rGrabBagElement.first == "TableStyleTopBorder")
296 rTableStyleConf[SvxBoxItemLine::TOP] = rGrabBagElement.second.get<table::BorderLine2>();
297 else if (rGrabBagElement.first == "TableStyleBottomBorder")
298 rTableStyleConf[SvxBoxItemLine::BOTTOM]
299 = rGrabBagElement.second.get<table::BorderLine2>();
300 else if (rGrabBagElement.first == "TableStyleLeftBorder")
301 rTableStyleConf[SvxBoxItemLine::LEFT]
302 = rGrabBagElement.second.get<table::BorderLine2>();
303 else if (rGrabBagElement.first == "TableStyleRightBorder")
304 rTableStyleConf[SvxBoxItemLine::RIGHT]
305 = rGrabBagElement.second.get<table::BorderLine2>();
306 else if (rGrabBagElement.first == "TableStyleLook")
307 {
309 = FastSerializerHelper::createAttrList();
310 const uno::Sequence<beans::PropertyValue> aAttributeList
311 = rGrabBagElement.second.get<uno::Sequence<beans::PropertyValue>>();
312
313 for (const auto& rAttribute : aAttributeList)
314 {
315 if (rAttribute.Name == "val")
316 pAttributeList->add(
317 FSNS(XML_w, XML_val),
318 lcl_padStartToLength(OString::number(rAttribute.Value.get<sal_Int32>(), 16),
319 4, '0'));
320 else
321 {
322 static DocxStringTokenMap const aTokens[]
323 = { { "firstRow", XML_firstRow },
324 { "lastRow", XML_lastRow },
325 { "firstColumn", XML_firstColumn },
326 { "lastColumn", XML_lastColumn },
327 { "noHBand", XML_noHBand },
328 { "noVBand", XML_noVBand },
329 { nullptr, 0 } };
330
331 if (sal_Int32 nToken = DocxStringGetToken(aTokens, rAttribute.Name))
332 pAttributeList->add(FSNS(XML_w, nToken),
333 (rAttribute.Value.get<sal_Int32>() ? "1" : "0"));
334 }
335 }
336
337 m_pSerializer->singleElementNS(XML_w, XML_tblLook, pAttributeList);
338 }
339 else if (rGrabBagElement.first == "TablePosition" &&
340 // skip empty table position (tables in footnotes converted to
341 // floating tables temporarily, don't export this)
342 rGrabBagElement.second != uno::Any())
343 {
344 rtl::Reference<FastAttributeList> attrListTablePos
345 = FastSerializerHelper::createAttrList();
346 const uno::Sequence<beans::PropertyValue> aTablePosition
347 = rGrabBagElement.second.get<uno::Sequence<beans::PropertyValue>>();
348 // look for a surrounding frame and take it's position values
350 if (pFrame)
351 {
352 CollectFloatingTableAttributes(m_rExport, *pFrame, pTableTextNodeInfoInner,
353 attrListTablePos);
354 }
355 else // ( pFrame = 0 )
356 {
357 // we export the values from the grabBag
358 for (const auto& rProp : aTablePosition)
359 {
360 if (rProp.Name == "vertAnchor" && !rProp.Value.get<OUString>().isEmpty())
361 {
362 OString sOrientation
363 = OUStringToOString(rProp.Value.get<OUString>(), RTL_TEXTENCODING_UTF8);
364 attrListTablePos->add(FSNS(XML_w, XML_vertAnchor), sOrientation);
365 }
366 else if (rProp.Name == "tblpYSpec" && !rProp.Value.get<OUString>().isEmpty())
367 {
368 OString sOrientation
369 = OUStringToOString(rProp.Value.get<OUString>(), RTL_TEXTENCODING_UTF8);
370 attrListTablePos->add(FSNS(XML_w, XML_tblpYSpec), sOrientation);
371 }
372 else if (rProp.Name == "horzAnchor" && !rProp.Value.get<OUString>().isEmpty())
373 {
374 OString sOrientation
375 = OUStringToOString(rProp.Value.get<OUString>(), RTL_TEXTENCODING_UTF8);
376 attrListTablePos->add(FSNS(XML_w, XML_horzAnchor), sOrientation);
377 }
378 else if (rProp.Name == "tblpXSpec" && !rProp.Value.get<OUString>().isEmpty())
379 {
380 OString sOrientation
381 = OUStringToOString(rProp.Value.get<OUString>(), RTL_TEXTENCODING_UTF8);
382 attrListTablePos->add(FSNS(XML_w, XML_tblpXSpec), sOrientation);
383 }
384 else if (rProp.Name == "bottomFromText")
385 {
386 sal_Int32 nValue = rProp.Value.get<sal_Int32>();
387 attrListTablePos->add(FSNS(XML_w, XML_bottomFromText),
388 OString::number(nValue));
389 }
390 else if (rProp.Name == "leftFromText")
391 {
392 sal_Int32 nValue = rProp.Value.get<sal_Int32>();
393 attrListTablePos->add(FSNS(XML_w, XML_leftFromText),
394 OString::number(nValue));
395 }
396 else if (rProp.Name == "rightFromText")
397 {
398 sal_Int32 nValue = rProp.Value.get<sal_Int32>();
399 attrListTablePos->add(FSNS(XML_w, XML_rightFromText),
400 OString::number(nValue));
401 }
402 else if (rProp.Name == "topFromText")
403 {
404 sal_Int32 nValue = rProp.Value.get<sal_Int32>();
405 attrListTablePos->add(FSNS(XML_w, XML_topFromText),
406 OString::number(nValue));
407 }
408 else if (rProp.Name == "tblpX")
409 {
410 sal_Int32 nValue = rProp.Value.get<sal_Int32>();
411 attrListTablePos->add(FSNS(XML_w, XML_tblpX), OString::number(nValue));
412 }
413 else if (rProp.Name == "tblpY")
414 {
415 sal_Int32 nValue = rProp.Value.get<sal_Int32>();
416 attrListTablePos->add(FSNS(XML_w, XML_tblpY), OString::number(nValue));
417 }
418 }
419 }
420
421 if (!bFloatingTableWritten)
422 {
423 m_pSerializer->singleElementNS(XML_w, XML_tblpPr, attrListTablePos);
424 }
425 }
426 else
427 SAL_WARN("sw.ww8", "DocxAttributeOutput::TableDefinition: unhandled property: "
428 << rGrabBagElement.first);
429 }
430
431 // Output the table alignment
432 const char* pJcVal;
433 sal_Int32 nIndent = 0;
434 switch (pTableFormat->GetHoriOrient().GetHoriOrient())
435 {
436 case text::HoriOrientation::CENTER:
437 pJcVal = "center";
438 break;
439 case text::HoriOrientation::RIGHT:
440 if (bEcma)
441 pJcVal = "right";
442 else
443 pJcVal = "end";
444 break;
445 default:
447 case text::HoriOrientation::LEFT_AND_WIDTH:
448 {
449 if (bEcma)
450 pJcVal = "left";
451 else
452 pJcVal = "start";
453 nIndent = sal_Int32(pTableFormat->GetLRSpace().GetLeft());
454
455 // Table indentation has different meaning in Word, depending if the table is nested or not.
456 // If nested, tblInd is added to parent table's left spacing and defines left edge position
457 // If not nested, text position of left-most cell must be at absolute X = tblInd
458 // so, table_spacing + table_spacing_to_content = tblInd
459
460 // tdf#106742: since MS Word 2013 (compatibilityMode >= 15), top-level tables are handled the same as nested tables;
461 // if no compatibilityMode is defined (which now should only happen on a new export to .docx),
462 // LO uses a higher compatibility than 2010's 14.
463 sal_Int32 nMode = lcl_getWordCompatibilityMode(m_rExport);
464
465 const SwFrameFormat* pFrameFormat
466 = pTableTextNodeInfoInner->getTableBox()->GetFrameFormat();
467 if ((0 < nMode && nMode <= 14) && m_tableReference.m_nTableDepth == 0)
468 nIndent += pFrameFormat->GetBox().GetDistance(SvxBoxItemLine::LEFT);
469 else
470 {
471 // adjust for SW considering table to start mid-border instead of nested/2013's left-side-of-border.
472 nIndent -= pFrameFormat->GetBox().CalcLineWidth(SvxBoxItemLine::LEFT) / 2;
473 }
474
475 break;
476 }
477 }
478 m_pSerializer->singleElementNS(XML_w, XML_jc, FSNS(XML_w, XML_val), pJcVal);
479
480 // Output the table background color (although cell value still needs to be specified)
481 const SvxBrushItem* pColorProp
482 = pTableFormat->GetAttrSet().GetItem<SvxBrushItem>(RES_BACKGROUND);
483 Color aColor = pColorProp ? pColorProp->GetColor() : COL_AUTO;
484 if (aColor != COL_AUTO)
485 {
486 OString sColor = msfilter::util::ConvertColor(aColor);
487 m_pSerializer->singleElementNS(XML_w, XML_shd, FSNS(XML_w, XML_fill), sColor,
488 FSNS(XML_w, XML_val), "clear");
489 }
490
491 // Output the table borders
492 TableDefaultBorders(pTableTextNodeInfoInner);
493
494 // Output the default cell margins
495 TableDefaultCellMargins(pTableTextNodeInfoInner);
496
497 TableBidi(pTableTextNodeInfoInner);
498
499 // Table indent (need to get written even if == 0)
500 m_pSerializer->singleElementNS(XML_w, XML_tblInd, FSNS(XML_w, XML_w), OString::number(nIndent),
501 FSNS(XML_w, XML_type), "dxa");
502
503 // Merge the marks for the ordered elements
504 m_pSerializer->mergeTopMarks(Tag_TableDefinition);
505
506 m_pSerializer->endElementNS(XML_w, XML_tblPr);
507
508 // Write the table grid infos
509 m_pSerializer->startElementNS(XML_w, XML_tblGrid);
510 sal_Int32 nPrv = 0;
511 ww8::WidthsPtr pColumnWidths = GetColumnWidths(pTableTextNodeInfoInner);
512 for (auto aColumnWidth : *pColumnWidths)
513 {
514 sal_Int32 nWidth = sal_Int32(aColumnWidth) - nPrv;
515 m_pSerializer->singleElementNS(XML_w, XML_gridCol, FSNS(XML_w, XML_w),
516 OString::number(nWidth));
517 nPrv = sal_Int32(aColumnWidth);
518 }
519
520 m_pSerializer->endElementNS(XML_w, XML_tblGrid);
521}
522
524 ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/)
525{
526 // Table defaults should only be created IF m_aTableStyleConf contents haven't come from a table style.
527 // Previously this function wrote out Cell A1 as the table default, causing problems with no benefit.
528}
529
531 ww8::WW8TableNodeInfoInner::Pointer_t const& pTableTextNodeInfoInner)
532{
533 const SwTableBox* pTabBox = pTableTextNodeInfoInner->getTableBox();
534 const SwFrameFormat* pFrameFormat = pTabBox->GetFrameFormat();
535 const SvxBoxItem& rBox = pFrameFormat->GetBox();
537
538 DocxAttributeOutput::ImplCellMargins(m_pSerializer, rBox, XML_tblCellMar, !bEcma);
539}
540
542 ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
543{
544 const SwTable* pTable = pTableTextNodeInfoInner->getTable();
545 const SwTableBox* pTableBox = pTableTextNodeInfoInner->getTableBox();
546 const SwTableLine* pTableRow = pTableBox->GetUpper();
547 const SwFrameFormat* pFormat = pTableBox->GetFrameFormat();
548
549 const SvxBrushItem* pColorProp = pFormat->GetAttrSet().GetItem<SvxBrushItem>(RES_BACKGROUND);
550 Color aColor = pColorProp ? pColorProp->GetColor() : COL_AUTO;
551
552 const SwFrameFormat* pRowFormat = pTableRow->GetFrameFormat();
553 const SvxBrushItem* pRowColorProp
555 if (pRowColorProp && aColor == COL_AUTO)
556 aColor = pRowColorProp->GetColor();
557
558 const SwFrameFormat* pTableFormat = pTable->GetFrameFormat();
559 const SvxBrushItem* pTableColorProp
560 = pTableFormat->GetAttrSet().GetItem<SvxBrushItem>(RES_BACKGROUND);
561 if (pTableColorProp && aColor == COL_AUTO)
562 aColor = pTableColorProp->GetColor();
563
564 const OString sColor = msfilter::util::ConvertColor(aColor);
565
566 const std::map<OUString, css::uno::Any>& rGrabBag
567 = pFormat->GetAttrSet().GetItem<SfxGrabBagItem>(RES_FRMATR_GRABBAG)->GetGrabBag();
568
569 OString sOriginalColor;
570 auto aGrabBagIt = rGrabBag.find("originalColor");
571 if (aGrabBagIt != rGrabBag.end())
572 sOriginalColor
573 = OUStringToOString(aGrabBagIt->second.get<OUString>(), RTL_TEXTENCODING_UTF8);
574
575 if (sOriginalColor != sColor)
576 {
577 // color changed by the user, or no grab bag: write sColor
578 if (sColor != "auto")
579 {
580 m_pSerializer->singleElementNS(XML_w, XML_shd, FSNS(XML_w, XML_fill), sColor,
581 FSNS(XML_w, XML_val), "clear");
582 }
583 }
584 else
585 {
587
588 for (const auto & [ name, val ] : rGrabBag)
589 {
590 if (!val.has<OUString>())
591 continue;
592
593 if (name == "themeFill")
594 AddToAttrList(pAttrList, FSNS(XML_w, XML_themeFill), val.get<OUString>());
595 else if (name == "themeFillTint")
596 AddToAttrList(pAttrList, FSNS(XML_w, XML_themeFillTint), val.get<OUString>());
597 else if (name == "themeFillShade")
598 AddToAttrList(pAttrList, FSNS(XML_w, XML_themeFillShade), val.get<OUString>());
599 else if (name == "fill")
600 AddToAttrList(pAttrList, FSNS(XML_w, XML_fill), val.get<OUString>());
601 else if (name == "themeColor")
602 AddToAttrList(pAttrList, FSNS(XML_w, XML_themeColor), val.get<OUString>());
603 else if (name == "themeTint")
604 AddToAttrList(pAttrList, FSNS(XML_w, XML_themeTint), val.get<OUString>());
605 else if (name == "themeShade")
606 AddToAttrList(pAttrList, FSNS(XML_w, XML_themeShade), val.get<OUString>());
607 else if (name == "color")
608 AddToAttrList(pAttrList, FSNS(XML_w, XML_color), val.get<OUString>());
609 else if (name == "val")
610 AddToAttrList(pAttrList, FSNS(XML_w, XML_val), val.get<OUString>());
611 }
612 m_pSerializer->singleElementNS(XML_w, XML_shd, pAttrList);
613 }
614}
615
617 ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
618{
619 const SwTableBox* pTabBox = pTableTextNodeInfoInner->getTableBox();
620 const SwTableLine* pTabLine = pTabBox->GetUpper();
621
622 bool bRemovePersonalInfo
624
625 // check table row property "HasTextChangesOnly"
628 // tdf#150824 if no tracked table row, is the table in a single redline?
629 // if yes, convert the row to a tracked table row instead of losing its tracking
630 if (nChange == SwRedlineTable::npos)
631 nChange = pTabLine->GetTableRedline();
632 if (nChange != SwRedlineTable::npos)
633 {
634 const SwRedlineTable& aRedlineTable
636 const SwRangeRedline* pRedline = aRedlineTable[nChange];
637 SwTableRowRedline* pTableRowRedline = nullptr;
638 bool bIsInExtra = false;
639
640 // use the original DOCX redline data stored in ExtraRedlineTable,
641 // if it exists and its type wasn't changed
642 const SwExtraRedlineTable& aExtraRedlineTable
644 for (sal_uInt16 nCurRedlinePos = 0; nCurRedlinePos < aExtraRedlineTable.GetSize();
645 ++nCurRedlinePos)
646 {
647 SwExtraRedline* pExtraRedline = aExtraRedlineTable.GetRedline(nCurRedlinePos);
648 pTableRowRedline = dynamic_cast<SwTableRowRedline*>(pExtraRedline);
649 if (pTableRowRedline && &pTableRowRedline->GetTableLine() == pTabLine)
650 {
651 bIsInExtra = true;
652 break;
653 }
654 }
655
656 const SwRedlineData& aRedlineData
657 = bIsInExtra &&
658 // still the same type (an inserted row could become a tracked deleted one)
659 pTableRowRedline->GetRedlineData().GetType()
660 == pRedline->GetRedlineData().GetType()
661 ? pTableRowRedline->GetRedlineData()
662 : pRedline->GetRedlineData();
663
664 // Note: all redline ranges and table row redline (with the same author and timestamp)
665 // use the same redline id in OOXML exported by MSO, but it seems, the recent solution
666 // (different IDs for different ranges, also row changes) is also portable.
667 OString aId(OString::number(m_nRedlineId++));
668 const OUString& rAuthor(SW_MOD()->GetRedlineAuthor(aRedlineData.GetAuthor()));
669 OString aAuthor(OUStringToOString(
670 bRemovePersonalInfo ? "Author" + OUString::number(GetExport().GetInfoID(rAuthor))
671 : rAuthor,
672 RTL_TEXTENCODING_UTF8));
673
674 const DateTime aDateTime = aRedlineData.GetTimeStamp();
675 bool bNoDate = bRemovePersonalInfo
676 || (aDateTime.GetYear() == 1970 && aDateTime.GetMonth() == 1
677 && aDateTime.GetDay() == 1);
678
679 if (bNoDate)
680 m_pSerializer->singleElementNS(
681 XML_w, RedlineType::Delete == pRedline->GetType() ? XML_del : XML_ins,
682 FSNS(XML_w, XML_id), aId, FSNS(XML_w, XML_author), aAuthor);
683 else
684 m_pSerializer->singleElementNS(
685 XML_w, RedlineType::Delete == pRedline->GetType() ? XML_del : XML_ins,
686 FSNS(XML_w, XML_id), aId, FSNS(XML_w, XML_author), aAuthor, FSNS(XML_w, XML_date),
687 DateTimeToOString(aDateTime));
688 return;
689 }
690}
691
693 ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
694{
695 const SwTableBox* pTabBox = pTableTextNodeInfoInner->getTableBox();
696
697 bool bRemovePersonalInfo
699
700 // check table row property "HasTextChangesOnly"
701 SwRedlineTable::size_type nChange = pTabBox->GetRedline();
702 if (nChange != SwRedlineTable::npos)
703 {
704 const SwRedlineTable& aRedlineTable
706 const SwRangeRedline* pRedline = aRedlineTable[nChange];
707 SwTableCellRedline* pTableCellRedline = nullptr;
708 bool bIsInExtra = false;
709
710 // use the original DOCX redline data stored in ExtraRedlineTable,
711 // if it exists and its type wasn't changed
712 const SwExtraRedlineTable& aExtraRedlineTable
714 for (sal_uInt16 nCurRedlinePos = 0; nCurRedlinePos < aExtraRedlineTable.GetSize();
715 ++nCurRedlinePos)
716 {
717 SwExtraRedline* pExtraRedline = aExtraRedlineTable.GetRedline(nCurRedlinePos);
718 pTableCellRedline = dynamic_cast<SwTableCellRedline*>(pExtraRedline);
719 if (pTableCellRedline && &pTableCellRedline->GetTableBox() == pTabBox)
720 {
721 bIsInExtra = true;
722 break;
723 }
724 }
725
726 const SwRedlineData& aRedlineData
727 = bIsInExtra &&
728 // still the same type (an inserted cell could become a tracked deleted one)
729 pRedline->GetRedlineData().GetType() == pRedline->GetRedlineData().GetType()
730 ? pTableCellRedline->GetRedlineData()
731 : pRedline->GetRedlineData();
732
733 // Note: all redline ranges and table row redline (with the same author and timestamp)
734 // use the same redline id in OOXML exported by MSO, but it seems, the recent solution
735 // (different IDs for different ranges, also row changes) is also portable.
736 OString aId(OString::number(m_nRedlineId++));
737 const OUString& rAuthor(SW_MOD()->GetRedlineAuthor(aRedlineData.GetAuthor()));
738 OString aAuthor(OUStringToOString(
739 bRemovePersonalInfo ? "Author" + OUString::number(GetExport().GetInfoID(rAuthor))
740 : rAuthor,
741 RTL_TEXTENCODING_UTF8));
742
743 const DateTime aDateTime = aRedlineData.GetTimeStamp();
744 bool bNoDate = bRemovePersonalInfo
745 || (aDateTime.GetYear() == 1970 && aDateTime.GetMonth() == 1
746 && aDateTime.GetDay() == 1);
747
748 if (bNoDate)
749 m_pSerializer->singleElementNS(
750 XML_w, RedlineType::Delete == pRedline->GetType() ? XML_cellDel : XML_cellIns,
751 FSNS(XML_w, XML_id), aId, FSNS(XML_w, XML_author), aAuthor);
752 else
753 m_pSerializer->singleElementNS(
754 XML_w, RedlineType::Delete == pRedline->GetType() ? XML_cellDel : XML_cellIns,
755 FSNS(XML_w, XML_id), aId, FSNS(XML_w, XML_author), aAuthor, FSNS(XML_w, XML_date),
756 DateTimeToOString(aDateTime));
757 return;
758 }
759}
760
762{
763 const SwTableBox* pTabBox = pTableTextNodeInfoInner->getTableBox();
764 const SwTableLine* pTabLine = pTabBox->GetUpper();
765 const SwFrameFormat* pLineFormat = pTabLine->GetFrameFormat();
766
767 const SwFormatFrameSize& rLSz = pLineFormat->GetFrameSize();
768 if (!(SwFrameSize::Variable != rLSz.GetHeightSizeType() && rLSz.GetHeight()))
769 return;
770
771 sal_Int32 nHeight = rLSz.GetHeight();
772 const char* pRule = nullptr;
773
774 switch (rLSz.GetHeightSizeType())
775 {
777 pRule = "exact";
778 break;
780 pRule = "atLeast";
781 break;
782 default:
783 break;
784 }
785
786 if (pRule)
787 m_pSerializer->singleElementNS(XML_w, XML_trHeight, FSNS(XML_w, XML_val),
788 OString::number(nHeight), FSNS(XML_w, XML_hRule), pRule);
789}
790
792 ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
793{
794 const SwTableBox* pTabBox = pTableTextNodeInfoInner->getTableBox();
795 const SwTableLine* pTabLine = pTabBox->GetUpper();
796 const SwFrameFormat* pLineFormat = pTabLine->GetFrameFormat();
797
798 const SwFormatRowSplit& rSplittable = pLineFormat->GetRowSplit();
799 // if rSplittable is true then no need to write <w:cantSplit w:val="false"/>
800 // as default row prop is allow row to break across page.
801 if (!rSplittable.GetValue())
802 m_pSerializer->singleElementNS(XML_w, XML_cantSplit, FSNS(XML_w, XML_val), "true");
803}
804
806{
807 const SwTable* pTable = pTableTextNodeInfoInner->getTable();
808 const SwFrameFormat* pFrameFormat = pTable->GetFrameFormat();
809
810 if (m_rExport.TrueFrameDirection(*pFrameFormat) == SvxFrameDirection::Horizontal_RL_TB)
811 {
812 m_pSerializer->singleElementNS(XML_w, XML_bidiVisual, FSNS(XML_w, XML_val), "true");
813 }
814}
815
817 ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
818{
819 const SwTableBox* pTabBox = pTableTextNodeInfoInner->getTableBox();
820 const SwFrameFormat* pFrameFormat = pTabBox->GetFrameFormat();
821
822 if (SvxFrameDirection::Vertical_RL_TB == m_rExport.TrueFrameDirection(*pFrameFormat))
823 m_pSerializer->singleElementNS(XML_w, XML_textDirection, FSNS(XML_w, XML_val), "tbRl");
824 else if (SvxFrameDirection::Vertical_LR_BT == m_rExport.TrueFrameDirection(*pFrameFormat))
825 {
826 m_pSerializer->singleElementNS(XML_w, XML_textDirection, FSNS(XML_w, XML_val), "btLr");
827 }
828
829 const SwWriteTableRows& rRows = m_xTableWrt->GetRows();
830 const auto nRow = pTableTextNodeInfoInner->getRow();
831 if (nRow >= rRows.size())
832 {
833 SAL_WARN("sw.ww8", "DocxAttributeOutput::TableCellProperties: out of range row: " << nRow);
834 return;
835 }
836 SwWriteTableRow* pRow = rRows[nRow].get();
837 sal_uInt32 nCell = pTableTextNodeInfoInner->getCell();
838 const SwWriteTableCells& rTableCells = pRow->GetCells();
839 if (nCell >= rTableCells.size())
840 return;
841
842 const SwWriteTableCell* const pCell = pRow->GetCells()[nCell].get();
843 switch (pCell->GetVertOri())
844 {
845 case text::VertOrientation::TOP:
846 break;
847 case text::VertOrientation::CENTER:
848 m_pSerializer->singleElementNS(XML_w, XML_vAlign, FSNS(XML_w, XML_val), "center");
849 break;
850 case text::VertOrientation::BOTTOM:
851 m_pSerializer->singleElementNS(XML_w, XML_vAlign, FSNS(XML_w, XML_val), "bottom");
852 break;
853 }
854}
855
857{
858 // This is called when the nested table ends in a cell, and there's no
859 // paragraph behind that; so we must check for the ends of cell, rows,
860 // tables
861 // ['true' to write an empty paragraph, MS Word insists on that]
862 FinishTableRowCell(pNodeInfoInner, true);
863}
864
866 ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/)
867{
868 SAL_INFO("sw.ww8", "TODO: DocxAttributeOutput::TableOrientation( "
869 "ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )");
870}
871
873 ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/)
874{
875 SAL_INFO("sw.ww8", "TODO: DocxAttributeOutput::TableSpacing( "
876 "ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )");
877}
878
879void DocxAttributeOutput::TableRowEnd(sal_uInt32 /*nDepth*/)
880{
881 SAL_INFO("sw.ww8", "TODO: DocxAttributeOutput::TableRowEnd( sal_uInt32 nDepth = 1 )");
882}
883
884/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
ww8::WidthsPtr GetColumnWidths(ww8::WW8TableNodeInfoInner::Pointer_t const &pTableTextNodeInfoInner)
Definition: wrtww8.cxx:2551
void GetTablePageSize(ww8::WW8TableNodeInfoInner const *pTableTextNodeInfoInner, tools::Long &rPageSize, bool &rRelBoxSize)
Definition: wrtww8.cxx:2557
sal_Int16 GetYear() const
sal_uInt16 GetDay() const
sal_uInt16 GetMonth() const
virtual void TableRowEnd(sal_uInt32 nDepth) override
virtual void TableDefaultBorders(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
virtual void TableRowRedline(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
static OString convertToOOXMLVertOrient(sal_Int16 nOrient)
virtual void TableNodeInfoInner(ww8::WW8TableNodeInfoInner::Pointer_t pNodeInfoInner) override
virtual void TableDefinition(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
virtual void TableBackgrounds(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
virtual void TableInfoRow(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
virtual void TableBidi(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
virtual void TableSpacing(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
std::unique_ptr< SwWriteTable > m_xTableWrt
The current table helper.
virtual void TableHeight(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
static const sal_Int32 Tag_TableDefinition
static OString convertToOOXMLVertOrientRel(sal_Int16 nOrientRel)
virtual void TableInfoCell(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
::sax_fastparser::FSHelperPtr m_pSerializer
Fast serializer to output the data.
virtual DocxExport & GetExport() override
Return the right export class.
sal_Int32 m_nRedlineId
Id of the redline.
virtual void TableVerticalCell(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
DocxExport & m_rExport
Reference to the export, where to get the data from.
static void AddToAttrList(rtl::Reference< sax_fastparser::FastAttributeList > &pAttrList, Args &&... args)
std::vector< std::map< SvxBoxItemLine, css::table::BorderLine2 > > m_aTableStyleConfs
virtual void TableCanSplit(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
static void ImplCellMargins(sax_fastparser::FSHelperPtr const &pSerializer, const SvxBoxItem &rBox, sal_Int32 tag, bool bUseStartEnd, const SvxBoxItem *pDefaultMargins=nullptr)
virtual void TableCellRedline(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
void FinishTableRowCell(ww8::WW8TableNodeInfoInner::Pointer_t const &pInner, bool bForceEmptyParagraph=false)
End cell, row, and even the entire table if necessary.
static OString convertToOOXMLHoriOrientRel(sal_Int16 nOrientRel)
void TableDefaultCellMargins(ww8::WW8TableNodeInfoInner::Pointer_t const &pTableTextNodeInfoInner)
static OString convertToOOXMLHoriOrient(sal_Int16 nOrient, bool bIsPosToggle)
virtual void TableOrientation(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
The class that does all the actual DOCX export-related work.
Definition: docxexport.hxx:75
void SetFloatingTableFrame(const ww8::Frame *pF)
Definition: docxexport.hxx:317
const ww8::Frame * GetFloatingTableFrame() const
Definition: docxexport.hxx:137
DocxExportFilter & GetFilter()
Definition: docxexport.hxx:134
sal_Int32 getWordCompatibilityModeFromGrabBag() const
virtual const SwExtraRedlineTable & GetExtraRedlineTable() const =0
virtual const SwRedlineTable & GetRedlineTable() const =0
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
SvxFrameDirection TrueFrameDirection(const SwFrameFormat &rFlyFormat) const
Right to left?
Definition: wrtw8nds.cxx:1669
SwDoc & m_rDoc
Definition: wrtww8.hxx:576
bool GetValue() const
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
const editeng::SvxBorderLine * GetLeft() const
sal_uInt16 CalcLineWidth(SvxBoxItemLine nLine) const
sal_Int16 GetDistance(SvxBoxItemLine nLine, bool bAllowNegative=false) const
const Color & GetColor() const
tools::Long GetRight() const
tools::Long GetLeft() const
tools::Long GetHeight() const
sal_uInt16 GetUpper() const
sal_uInt16 GetLower() const
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:349
IDocumentSettingAccess const & getIDocumentSettingAccess() const
Definition: doc.cxx:190
Table that holds 'extra' redlines, such as 'table row insert/delete', 'paragraph moves' etc....
Definition: docary.hxx:283
sal_uInt16 GetSize() const
Definition: docary.hxx:297
SwExtraRedline * GetRedline(sal_uInt16 uIndex) const
Definition: docary.hxx:298
Base object for 'Redlines' that are not of 'Ranged' type (like table row insert\delete)
Definition: redline.hxx:289
sal_uInt8 GetWidthPercent() const
Definition: fmtfsize.hxx:91
SwFrameSize GetHeightSizeType() const
Definition: fmtfsize.hxx:80
sal_Int16 GetHoriOrient() const
Definition: fmtornt.hxx:94
SwTwips GetPos() const
Definition: fmtornt.hxx:99
bool IsPosToggle() const
Definition: fmtornt.hxx:102
sal_Int16 GetRelationOrient() const
Definition: fmtornt.hxx:95
Controls if a table row is allowed to split or not.
Definition: fmtrowsplt.hxx:32
sal_Int16 GetRelationOrient() const
Definition: fmtornt.hxx:58
SwTwips GetPos() const
Definition: fmtornt.hxx:62
sal_Int16 GetVertOrient() const
Definition: fmtornt.hxx:57
const SvxBoxItem & GetBox(bool=true) const
Definition: frmatr.hxx:108
const SwFormatFrameSize & GetFrameSize(bool=true) const
Definition: fmtfsize.hxx:104
const SwFormatRowSplit & GetRowSplit(bool=true) const
Definition: fmtrowsplt.hxx:48
const SvxLRSpaceItem & GetLRSpace(bool=true) const
Definition: frmatr.hxx:98
const SwFormatFlySplit & GetFlySplit(bool=true) const
const SwFormatVertOrient & GetVertOrient(bool=true) const
Definition: fmtornt.hxx:113
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:136
const SwFormatHoriOrient & GetHoriOrient(bool=true) const
Definition: fmtornt.hxx:115
const SvxULSpaceItem & GetULSpace(bool=true) const
Definition: frmatr.hxx:100
Style of a layout element.
Definition: frmfmt.hxx:72
RedlineType GetType(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1975
const SwRedlineData & GetRedlineData(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1998
std::size_t GetAuthor() const
Definition: redline.hxx:128
const DateTime & GetTimeStamp() const
Definition: redline.hxx:130
RedlineType GetType() const
Definition: redline.hxx:126
static constexpr size_type npos
Definition: docary.hxx:224
vector_type::size_type size_type
Definition: docary.hxx:223
SwTableBox is one table cell in the document model.
Definition: swtable.hxx:443
SwTableLine * GetUpper()
Definition: swtable.hxx:477
SwRedlineTable::size_type GetRedline() const
Definition: swtable.cxx:2987
SwFrameFormat * GetFrameFormat()
Definition: swtable.hxx:481
Redline that holds information about a table-cell that had some change.
Definition: redline.hxx:321
const SwTableBox & GetTableBox() const
Definition: redline.hxx:334
const SwRedlineData & GetRedlineData() const
Definition: redline.hxx:336
SwTableLine is one table row in the document model.
Definition: swtable.hxx:376
SwFrameFormat * GetFrameFormat()
Definition: swtable.hxx:398
SwRedlineTable::size_type UpdateTextChangesOnly(SwRedlineTable::size_type &rRedlinePos, bool bUpdateProperty=true) const
Definition: swtable.cxx:1751
SwRedlineTable::size_type GetTableRedline() const
Definition: swtable.cxx:1902
Redline that holds information about a table-row that had some change.
Definition: redline.hxx:300
const SwTableLine & GetTableLine() const
Definition: redline.hxx:313
const SwRedlineData & GetRedlineData() const
Definition: redline.hxx:315
SwTable is one table in the document model, containing rows (which contain cells).
Definition: swtable.hxx:113
SwTableFormat * GetFrameFormat()
Definition: swtable.hxx:209
sal_Int16 GetVertOri() const
Definition: wrtswtbl.cxx:38
const SwWriteTableCells & GetCells() const
Definition: wrtswtbl.hxx:135
static css::uno::Reference< css::text::XTextTable > GetObject(SwFrameFormat &rFormat)
Definition: unocoll.cxx:988
size_type size() const
OoxmlVersion getVersion() const
Make exporting a Writer Frame easy.
const SwFrameFormat & GetFrameFormat() const
Get the writer SwFrameFormat that this object describes.
std::shared_ptr< WW8TableNodeInfoInner > Pointer_t
constexpr ::Color COL_AUTO(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
constexpr OUStringLiteral sColor
TOOLS_DLLPUBLIC OString DateTimeToOString(const DateTime &rDateTime)
sal_Int32 DocxStringGetToken(DocxStringTokenMap const *pMap, std::u16string_view rName)
sal_Int16 nValue
@ Fixed
Frame cannot be moved in Var-direction.
@ Variable
Frame is variable in Var-direction.
@ Minimum
Value in Var-direction gives minimum (can be exceeded but not be less).
constexpr sal_Int32 FSNS(sal_Int32 namespc, sal_Int32 element)
constexpr TypedWhichId< SvxBrushItem > RES_BACKGROUND(111)
constexpr TypedWhichId< SfxGrabBagItem > RES_FRMATR_GRABBAG(136)
const char * name
sal_uInt16 nPos
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
bool IsOptionSet(EOption eOption)
OStringBuffer & padToLength(OStringBuffer &rBuffer, sal_Int32 nLength, char cFill='\0')
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
OString ConvertColor(const Color &rColor)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
XML_type
long Long
std::shared_ptr< Widths > WidthsPtr
DefTokenId nToken
sal_uInt32 m_nTableDepth
Remember the current table depth.
#define SW_MOD()
Definition: swmodule.hxx:254
std::unique_ptr< char[]> aBuffer
std::vector< std::unique_ptr< SwWriteTableCell > > SwWriteTableCells
Definition: wrtswtbl.hxx:95