LibreOffice Module sw (master)  1
docxtablestyleexport.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 
10 #include "docxtablestyleexport.hxx"
11 #include "docxhelper.hxx"
12 #include <doc.hxx>
13 #include <docsh.hxx>
14 #include <oox/token/tokens.hxx>
16 #include <sax/fastattribs.hxx>
17 
18 #include <boost/optional.hpp>
19 
20 #include <com/sun/star/beans/XPropertySet.hpp>
21 #include <com/sun/star/beans/PropertyValue.hpp>
22 
23 using namespace com::sun::star;
24 using namespace oox;
25 
28 {
29 private:
32 
33 public:
34  Impl(SwDoc* pDoc)
35  : m_pDoc(pDoc)
36  {
37  }
38 
39  void TableStyle(const uno::Sequence<beans::PropertyValue>& rStyle);
40 
42  {
43  m_pSerializer = std::move(pSerializer);
44  }
45 
46  const sax_fastparser::FSHelperPtr& getSerializer() const { return m_pSerializer; }
47 
48  SwDoc* getDoc() const { return m_pDoc; }
49 
51  void handleBoolean(const OUString& aValue, sal_Int32 nToken);
52 
54  void tableStylePPr(const uno::Sequence<beans::PropertyValue>& rPPr);
56  void tableStyleTableStylePr(const uno::Sequence<beans::PropertyValue>& rTableStylePr);
58  void tableStyleRPr(const uno::Sequence<beans::PropertyValue>& rRPr);
60  void tableStyleRRFonts(const uno::Sequence<beans::PropertyValue>& rRFonts);
62  void tableStyleRLang(const uno::Sequence<beans::PropertyValue>& rLang);
64  void tableStylePInd(const uno::Sequence<beans::PropertyValue>& rInd);
66  void tableStylePSpacing(const uno::Sequence<beans::PropertyValue>& rSpacing);
68  void tableStyleTablePr(const uno::Sequence<beans::PropertyValue>& rTablePr);
70  void tableStyleTrPr(const uno::Sequence<beans::PropertyValue>& rTrPr);
72  void tableStyleTcPr(const uno::Sequence<beans::PropertyValue>& rTcPr);
74  void tableStyleTcBorders(const uno::Sequence<beans::PropertyValue>& rTcBorders,
75  sal_Int32 nToken = XML_tcBorders);
77  void tableStyleTableInd(const uno::Sequence<beans::PropertyValue>& rTableInd);
79  void tableStyleTableCellMar(const uno::Sequence<beans::PropertyValue>& rTableCellMar,
80  sal_Int32 nType = XML_tblCellMar);
82  void tableStyleTcBorder(sal_Int32 nToken, const uno::Sequence<beans::PropertyValue>& rTcBorder);
84  void tableStyleShd(const uno::Sequence<beans::PropertyValue>& rShd);
86  void tableStyleRColor(const uno::Sequence<beans::PropertyValue>& rColor);
87 };
88 
89 void DocxTableStyleExport::CnfStyle(const uno::Sequence<beans::PropertyValue>& rAttributeList)
90 {
91  sax_fastparser::FastAttributeList* pAttributeList
93 
94  for (const auto& rAttribute : rAttributeList)
95  {
96  if (rAttribute.Name == "val")
97  pAttributeList->add(FSNS(XML_w, XML_val), rAttribute.Value.get<OUString>().toUtf8());
98  else
99  {
100  static DocxStringTokenMap const aTokens[]
101  = { { "firstRow", XML_firstRow },
102  { "lastRow", XML_lastRow },
103  { "firstColumn", XML_firstColumn },
104  { "lastColumn", XML_lastColumn },
105  { "oddVBand", XML_oddVBand },
106  { "evenVBand", XML_evenVBand },
107  { "oddHBand", XML_oddHBand },
108  { "evenHBand", XML_evenHBand },
109  { "firstRowFirstColumn", XML_firstRowFirstColumn },
110  { "firstRowLastColumn", XML_firstRowLastColumn },
111  { "lastRowFirstColumn", XML_lastRowFirstColumn },
112  { "lastRowLastColumn", XML_lastRowLastColumn },
113  { nullptr, 0 } };
114 
115  if (sal_Int32 nToken = DocxStringGetToken(aTokens, rAttribute.Name))
116  pAttributeList->add(FSNS(XML_w, nToken), rAttribute.Value.get<OUString>().toUtf8());
117  }
118  }
119 
120  sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
121  m_pImpl->getSerializer()->singleElementNS(XML_w, XML_cnfStyle, xAttributeList);
122 }
123 
124 void DocxTableStyleExport::TableStyles(sal_Int32 nCountStylesToWrite)
125 {
126  // Do we have table styles from InteropGrabBag available?
127  uno::Reference<beans::XPropertySet> xPropertySet(
128  m_pImpl->getDoc()->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW);
129  uno::Sequence<beans::PropertyValue> aInteropGrabBag;
130  xPropertySet->getPropertyValue("InteropGrabBag") >>= aInteropGrabBag;
131  uno::Sequence<beans::PropertyValue> aTableStyles;
132  auto pProp = std::find_if(
133  aInteropGrabBag.begin(), aInteropGrabBag.end(),
134  [](const beans::PropertyValue& rProp) { return rProp.Name == "tableStyles"; });
135  if (pProp != aInteropGrabBag.end())
136  pProp->Value >>= aTableStyles;
137  if (!aTableStyles.hasElements())
138  return;
139 
140  if (nCountStylesToWrite > aTableStyles.getLength())
141  nCountStylesToWrite = aTableStyles.getLength();
142 
143  for (sal_Int32 i = 0; i < nCountStylesToWrite; ++i)
144  {
145  uno::Sequence<beans::PropertyValue> aTableStyle;
146  aTableStyles[i].Value >>= aTableStyle;
147  m_pImpl->TableStyle(aTableStyle);
148  }
149 }
150 
152  const uno::Sequence<beans::PropertyValue>& rTableCellMar, sal_Int32 nType)
153 {
154  static DocxStringTokenMap const aTableCellMarTokens[]
155  = { { "left", XML_left }, { "right", XML_right }, { "start", XML_start },
156  { "end", XML_end }, { "top", XML_top }, { "bottom", XML_bottom },
157  { nullptr, 0 } };
158 
159  if (!rTableCellMar.hasElements())
160  return;
161 
162  m_pSerializer->startElementNS(XML_w, nType);
163  for (const auto& rProp : rTableCellMar)
164  {
165  if (sal_Int32 nToken = DocxStringGetToken(aTableCellMarTokens, rProp.Name))
166  {
168  rProp.Value.get<uno::Sequence<beans::PropertyValue>>());
169  m_pSerializer->singleElementNS(
170  XML_w, nToken, FSNS(XML_w, XML_w), OString::number(aMap["w"].get<sal_Int32>()),
171  FSNS(XML_w, XML_type), aMap["type"].get<OUString>().toUtf8());
172  }
173  }
174  m_pSerializer->endElementNS(XML_w, nType);
175 }
176 
178  sal_Int32 nToken, const uno::Sequence<beans::PropertyValue>& rTcBorder)
179 {
180  static DocxStringTokenMap const aTcBorderTokens[] = { { "val", XML_val },
181  { "sz", XML_sz },
182  { "color", XML_color },
183  { "space", XML_space },
184  { "themeColor", XML_themeColor },
185  { "themeTint", XML_themeTint },
186  { nullptr, 0 } };
187 
188  if (!rTcBorder.hasElements())
189  return;
190 
191  sax_fastparser::FastAttributeList* pAttributeList
193  for (const auto& rProp : rTcBorder)
194  if (sal_Int32 nAttrToken = DocxStringGetToken(aTcBorderTokens, rProp.Name))
195  pAttributeList->add(FSNS(XML_w, nAttrToken), rProp.Value.get<OUString>().toUtf8());
196 
197  sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
198  m_pSerializer->singleElementNS(XML_w, nToken, xAttributeList);
199 }
200 
202  const uno::Sequence<beans::PropertyValue>& rTcBorders, sal_Int32 nToken)
203 {
204  static DocxStringTokenMap const aTcBordersTokens[] = { { "left", XML_left },
205  { "right", XML_right },
206  { "start", XML_start },
207  { "end", XML_end },
208  { "top", XML_top },
209  { "bottom", XML_bottom },
210  { "insideH", XML_insideH },
211  { "insideV", XML_insideV },
212  { "tl2br", XML_tl2br },
213  { "tr2bl", XML_tr2bl },
214  { nullptr, 0 } };
215 
216  if (!rTcBorders.hasElements())
217  return;
218 
219  m_pSerializer->startElementNS(XML_w, nToken);
220  for (const auto& rTcBorder : rTcBorders)
221  if (sal_Int32 nSubToken = DocxStringGetToken(aTcBordersTokens, rTcBorder.Name))
222  tableStyleTcBorder(nSubToken,
223  rTcBorder.Value.get<uno::Sequence<beans::PropertyValue>>());
224  m_pSerializer->endElementNS(XML_w, nToken);
225 }
226 
227 void DocxTableStyleExport::Impl::tableStyleShd(const uno::Sequence<beans::PropertyValue>& rShd)
228 {
229  if (!rShd.hasElements())
230  return;
231 
232  sax_fastparser::FastAttributeList* pAttributeList
234  for (const auto& rProp : rShd)
235  {
236  if (rProp.Name == "val")
237  pAttributeList->add(FSNS(XML_w, XML_val), rProp.Value.get<OUString>().toUtf8());
238  else if (rProp.Name == "color")
239  pAttributeList->add(FSNS(XML_w, XML_color), rProp.Value.get<OUString>().toUtf8());
240  else if (rProp.Name == "fill")
241  pAttributeList->add(FSNS(XML_w, XML_fill), rProp.Value.get<OUString>().toUtf8());
242  else if (rProp.Name == "themeFill")
243  pAttributeList->add(FSNS(XML_w, XML_themeFill), rProp.Value.get<OUString>().toUtf8());
244  else if (rProp.Name == "themeFillShade")
245  pAttributeList->add(FSNS(XML_w, XML_themeFillShade),
246  rProp.Value.get<OUString>().toUtf8());
247  else if (rProp.Name == "themeFillTint")
248  pAttributeList->add(FSNS(XML_w, XML_themeFillTint),
249  rProp.Value.get<OUString>().toUtf8());
250  }
251  sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
252  m_pSerializer->singleElementNS(XML_w, XML_shd, xAttributeList);
253 }
254 
255 void DocxTableStyleExport::Impl::tableStyleRColor(const uno::Sequence<beans::PropertyValue>& rColor)
256 {
257  if (!rColor.hasElements())
258  return;
259 
260  sax_fastparser::FastAttributeList* pAttributeList
262  for (const auto& rProp : rColor)
263  {
264  if (rProp.Name == "val")
265  pAttributeList->add(FSNS(XML_w, XML_val), rProp.Value.get<OUString>().toUtf8());
266  else if (rProp.Name == "themeColor")
267  pAttributeList->add(FSNS(XML_w, XML_themeColor), rProp.Value.get<OUString>().toUtf8());
268  else if (rProp.Name == "themeTint")
269  pAttributeList->add(FSNS(XML_w, XML_themeTint), rProp.Value.get<OUString>().toUtf8());
270  else if (rProp.Name == "themeShade")
271  pAttributeList->add(FSNS(XML_w, XML_themeShade), rProp.Value.get<OUString>().toUtf8());
272  }
273  sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
274  m_pSerializer->singleElementNS(XML_w, XML_color, xAttributeList);
275 }
276 
277 void DocxTableStyleExport::Impl::tableStyleRLang(const uno::Sequence<beans::PropertyValue>& rLang)
278 {
279  if (!rLang.hasElements())
280  return;
281 
282  sax_fastparser::FastAttributeList* pAttributeList
284  for (const auto& rProp : rLang)
285  {
286  if (rProp.Name == "eastAsia")
287  pAttributeList->add(FSNS(XML_w, XML_eastAsia), rProp.Value.get<OUString>().toUtf8());
288  else if (rProp.Name == "val")
289  pAttributeList->add(FSNS(XML_w, XML_val), rProp.Value.get<OUString>().toUtf8());
290  else if (rProp.Name == "bidi")
291  pAttributeList->add(FSNS(XML_w, XML_bidi), rProp.Value.get<OUString>().toUtf8());
292  }
293  sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
294  m_pSerializer->singleElementNS(XML_w, XML_lang, xAttributeList);
295 }
296 
298  const uno::Sequence<beans::PropertyValue>& rRFonts)
299 {
300  if (!rRFonts.hasElements())
301  return;
302 
303  sax_fastparser::FastAttributeList* pAttributeList
305  for (const auto& rRFont : rRFonts)
306  {
307  if (rRFont.Name == "eastAsiaTheme")
308  pAttributeList->add(FSNS(XML_w, XML_eastAsiaTheme),
309  rRFont.Value.get<OUString>().toUtf8());
310  else if (rRFont.Name == "asciiTheme")
311  pAttributeList->add(FSNS(XML_w, XML_asciiTheme), rRFont.Value.get<OUString>().toUtf8());
312  else if (rRFont.Name == "cstheme")
313  pAttributeList->add(FSNS(XML_w, XML_cstheme), rRFont.Value.get<OUString>().toUtf8());
314  else if (rRFont.Name == "hAnsiTheme")
315  pAttributeList->add(FSNS(XML_w, XML_hAnsiTheme), rRFont.Value.get<OUString>().toUtf8());
316  }
317  sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
318  m_pSerializer->singleElementNS(XML_w, XML_rFonts, xAttributeList);
319 }
320 
322  const uno::Sequence<beans::PropertyValue>& rSpacing)
323 {
324  if (!rSpacing.hasElements())
325  return;
326 
327  sax_fastparser::FastAttributeList* pAttributeList
329  for (const auto& rProp : rSpacing)
330  {
331  if (rProp.Name == "after")
332  pAttributeList->add(FSNS(XML_w, XML_after), rProp.Value.get<OUString>().toUtf8());
333  else if (rProp.Name == "before")
334  pAttributeList->add(FSNS(XML_w, XML_before), rProp.Value.get<OUString>().toUtf8());
335  else if (rProp.Name == "line")
336  pAttributeList->add(FSNS(XML_w, XML_line), rProp.Value.get<OUString>().toUtf8());
337  else if (rProp.Name == "lineRule")
338  pAttributeList->add(FSNS(XML_w, XML_lineRule), rProp.Value.get<OUString>().toUtf8());
339  else if (rProp.Name == "beforeLines")
340  pAttributeList->add(FSNS(XML_w, XML_beforeLines), rProp.Value.get<OUString>().toUtf8());
341  else if (rProp.Name == "ParaTopMarginBeforeAutoSpacing")
342  // Auto spacing will be available in grab bag only if it was set to true
343  pAttributeList->add(FSNS(XML_w, XML_beforeAutospacing), "1");
344  else if (rProp.Name == "afterLines")
345  pAttributeList->add(FSNS(XML_w, XML_afterLines), rProp.Value.get<OUString>().toUtf8());
346  else if (rProp.Name == "ParaBottomMarginAfterAutoSpacing")
347  // Auto spacing will be available in grab bag only if it was set to true
348  pAttributeList->add(FSNS(XML_w, XML_afterAutospacing), "1");
349  }
350  sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
351  m_pSerializer->singleElementNS(XML_w, XML_spacing, xAttributeList);
352 }
353 
354 void DocxTableStyleExport::Impl::tableStylePInd(const uno::Sequence<beans::PropertyValue>& rInd)
355 {
356  if (!rInd.hasElements())
357  return;
358 
359  sax_fastparser::FastAttributeList* pAttributeList
361  for (const auto& rProp : rInd)
362  {
363  if (rProp.Name == "rightChars")
364  pAttributeList->add(FSNS(XML_w, XML_rightChars), rProp.Value.get<OUString>().toUtf8());
365  else if (rProp.Name == "right")
366  pAttributeList->add(FSNS(XML_w, XML_right), rProp.Value.get<OUString>().toUtf8());
367  }
368  sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
369  m_pSerializer->singleElementNS(XML_w, XML_ind, xAttributeList);
370 }
371 
373  const uno::Sequence<beans::PropertyValue>& rTableInd)
374 {
375  if (!rTableInd.hasElements())
376  return;
377 
378  sax_fastparser::FastAttributeList* pAttributeList
380  for (const auto& rProp : rTableInd)
381  {
382  if (rProp.Name == "w")
383  pAttributeList->add(FSNS(XML_w, XML_w), OString::number(rProp.Value.get<sal_Int32>()));
384  else if (rProp.Name == "type")
385  pAttributeList->add(FSNS(XML_w, XML_type), rProp.Value.get<OUString>().toUtf8());
386  }
387  sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
388  m_pSerializer->singleElementNS(XML_w, XML_tblInd, xAttributeList);
389 }
390 
391 void DocxTableStyleExport::Impl::handleBoolean(const OUString& aValue, sal_Int32 nToken)
392 {
393  if (aValue.isEmpty())
394  return;
395  sax_fastparser::FastAttributeList* pAttributeList
397  if (aValue != "1")
398  pAttributeList->add(FSNS(XML_w, XML_val), aValue.toUtf8());
399  sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
400  m_pSerializer->singleElementNS(XML_w, nToken, xAttributeList);
401 }
402 
403 void DocxTableStyleExport::Impl::tableStyleRPr(const uno::Sequence<beans::PropertyValue>& rRPr)
404 {
405  if (!rRPr.hasElements())
406  return;
407 
408  m_pSerializer->startElementNS(XML_w, XML_rPr);
409 
410  uno::Sequence<beans::PropertyValue> aRFonts;
411  uno::Sequence<beans::PropertyValue> aLang;
412  uno::Sequence<beans::PropertyValue> aColor;
413  uno::Sequence<beans::PropertyValue> aSpacingSequence;
414  bool bSequenceFlag = false;
415  OUString aB;
416  OUString aBCs;
417  OUString aI;
418  OUString aSz;
419  OUString aSzCs;
420  OUString aCaps;
421  OUString aSmallCaps;
422  OUString aSpacing;
423  for (const auto& rProp : rRPr)
424  {
425  if (rProp.Name == "rFonts")
426  aRFonts = rProp.Value.get<uno::Sequence<beans::PropertyValue>>();
427  else if (rProp.Name == "lang")
428  aLang = rProp.Value.get<uno::Sequence<beans::PropertyValue>>();
429  else if (rProp.Name == "b")
430  aB = rProp.Value.get<OUString>();
431  else if (rProp.Name == "bCs")
432  aBCs = rProp.Value.get<OUString>();
433  else if (rProp.Name == "i")
434  aI = rProp.Value.get<OUString>();
435  else if (rProp.Name == "color")
436  aColor = rProp.Value.get<uno::Sequence<beans::PropertyValue>>();
437  else if (rProp.Name == "sz")
438  aSz = rProp.Value.get<OUString>();
439  else if (rProp.Name == "szCs")
440  aSzCs = rProp.Value.get<OUString>();
441  else if (rProp.Name == "caps")
442  aCaps = rProp.Value.get<OUString>();
443  else if (rProp.Name == "smallCaps")
444  aSmallCaps = rProp.Value.get<OUString>();
445  else if (rProp.Name == "spacing")
446  {
447  if (rProp.Value.has<OUString>())
448  {
449  aSpacing = rProp.Value.get<OUString>();
450  }
451  else
452  {
453  aSpacingSequence = rProp.Value.get<uno::Sequence<beans::PropertyValue>>();
454  bSequenceFlag = true; // set the uno::Sequence flag.
455  }
456  }
457  }
458  tableStyleRRFonts(aRFonts);
459  tableStyleRLang(aLang);
460  handleBoolean(aB, XML_b);
461  handleBoolean(aBCs, XML_bCs);
462  handleBoolean(aI, XML_i);
463  handleBoolean(aCaps, XML_caps);
464  handleBoolean(aSmallCaps, XML_smallCaps);
465  tableStyleRColor(aColor);
466  if (bSequenceFlag)
467  {
468  m_pSerializer->singleElementNS(XML_w, XML_spacing, FSNS(XML_w, XML_val),
469  aSpacingSequence[0].Value.get<OUString>().toUtf8());
470  }
471  if (!aSpacing.isEmpty())
472  m_pSerializer->singleElementNS(XML_w, XML_spacing, FSNS(XML_w, XML_val), aSpacing.toUtf8());
473  if (!aSz.isEmpty())
474  m_pSerializer->singleElementNS(XML_w, XML_sz, FSNS(XML_w, XML_val), aSz.toUtf8());
475  if (!aSzCs.isEmpty())
476  m_pSerializer->singleElementNS(XML_w, XML_szCs, FSNS(XML_w, XML_val), aSzCs.toUtf8());
477 
478  m_pSerializer->endElementNS(XML_w, XML_rPr);
479 }
480 
481 void DocxTableStyleExport::Impl::tableStylePPr(const uno::Sequence<beans::PropertyValue>& rPPr)
482 {
483  if (!rPPr.hasElements())
484  return;
485 
486  m_pSerializer->startElementNS(XML_w, XML_pPr);
487 
488  uno::Sequence<beans::PropertyValue> aSpacing;
489  uno::Sequence<beans::PropertyValue> aInd;
490  bool bWordWrap = false;
491  OUString aJc;
492  OUString aSnapToGrid;
493  for (const auto& rProp : rPPr)
494  {
495  if (rProp.Name == "spacing")
496  aSpacing = rProp.Value.get<uno::Sequence<beans::PropertyValue>>();
497  else if (rProp.Name == "ind")
498  aInd = rProp.Value.get<uno::Sequence<beans::PropertyValue>>();
499  else if (rProp.Name == "wordWrap")
500  bWordWrap = true;
501  else if (rProp.Name == "jc")
502  aJc = rProp.Value.get<OUString>();
503  else if (rProp.Name == "snapToGrid")
504  aSnapToGrid = rProp.Value.get<OUString>();
505  }
506  if (bWordWrap)
507  m_pSerializer->singleElementNS(XML_w, XML_wordWrap);
508  tableStylePInd(aInd);
509  handleBoolean(aSnapToGrid, XML_snapToGrid);
510  tableStylePSpacing(aSpacing);
511  if (!aJc.isEmpty())
512  m_pSerializer->singleElementNS(XML_w, XML_jc, FSNS(XML_w, XML_val), aJc.toUtf8());
513 
514  m_pSerializer->endElementNS(XML_w, XML_pPr);
515 }
516 
518  const uno::Sequence<beans::PropertyValue>& rTablePr)
519 {
520  if (!rTablePr.hasElements())
521  return;
522 
523  m_pSerializer->startElementNS(XML_w, XML_tblPr);
524 
525  uno::Sequence<beans::PropertyValue> aTableInd;
526  uno::Sequence<beans::PropertyValue> aTableBorders;
527  uno::Sequence<beans::PropertyValue> aTableCellMar;
528  boost::optional<sal_Int32> oTableStyleRowBandSize;
529  boost::optional<sal_Int32> oTableStyleColBandSize;
530  for (const auto& rProp : rTablePr)
531  {
532  if (rProp.Name == "tblStyleRowBandSize")
533  oTableStyleRowBandSize = rProp.Value.get<sal_Int32>();
534  else if (rProp.Name == "tblStyleColBandSize")
535  oTableStyleColBandSize = rProp.Value.get<sal_Int32>();
536  else if (rProp.Name == "tblInd")
537  aTableInd = rProp.Value.get<uno::Sequence<beans::PropertyValue>>();
538  else if (rProp.Name == "tblBorders")
539  aTableBorders = rProp.Value.get<uno::Sequence<beans::PropertyValue>>();
540  else if (rProp.Name == "tblCellMar")
541  aTableCellMar = rProp.Value.get<uno::Sequence<beans::PropertyValue>>();
542  }
543  if (oTableStyleRowBandSize)
544  m_pSerializer->singleElementNS(XML_w, XML_tblStyleRowBandSize, FSNS(XML_w, XML_val),
545  OString::number(oTableStyleRowBandSize.get()));
546  if (oTableStyleColBandSize)
547  m_pSerializer->singleElementNS(XML_w, XML_tblStyleColBandSize, FSNS(XML_w, XML_val),
548  OString::number(oTableStyleColBandSize.get()));
549  tableStyleTableInd(aTableInd);
550  tableStyleTcBorders(aTableBorders, XML_tblBorders);
551  tableStyleTableCellMar(aTableCellMar);
552 
553  m_pSerializer->endElementNS(XML_w, XML_tblPr);
554 }
555 
556 void DocxTableStyleExport::Impl::tableStyleTrPr(const uno::Sequence<beans::PropertyValue>& rTrPr)
557 {
558  if (!rTrPr.hasElements())
559  return;
560 
561  m_pSerializer->startElementNS(XML_w, XML_trPr);
562 
563  for (const auto& rProp : rTrPr)
564  {
565  if (rProp.Name == "tblHeader")
566  m_pSerializer->singleElementNS(XML_w, XML_tblHeader);
567  }
568 
569  m_pSerializer->endElementNS(XML_w, XML_trPr);
570 }
571 
572 void DocxTableStyleExport::Impl::tableStyleTcPr(const uno::Sequence<beans::PropertyValue>& rTcPr)
573 {
574  if (!rTcPr.hasElements())
575  return;
576 
577  m_pSerializer->startElementNS(XML_w, XML_tcPr);
578 
579  uno::Sequence<beans::PropertyValue> aShd;
580  uno::Sequence<beans::PropertyValue> aTcBorders;
581  uno::Sequence<beans::PropertyValue> aTcMar;
582  OUString aVAlign;
583  for (const auto& rProp : rTcPr)
584  {
585  if (rProp.Name == "shd")
586  aShd = rProp.Value.get<uno::Sequence<beans::PropertyValue>>();
587  else if (rProp.Name == "tcBorders")
588  aTcBorders = rProp.Value.get<uno::Sequence<beans::PropertyValue>>();
589  else if (rProp.Name == "tcMar")
590  aTcMar = rProp.Value.get<uno::Sequence<beans::PropertyValue>>();
591  else if (rProp.Name == "vAlign")
592  aVAlign = rProp.Value.get<OUString>();
593  }
594  tableStyleTcBorders(aTcBorders);
595  tableStyleTableCellMar(aTcMar, XML_tcMar);
596  tableStyleShd(aShd);
597  if (!aVAlign.isEmpty())
598  m_pSerializer->singleElementNS(XML_w, XML_vAlign, FSNS(XML_w, XML_val), aVAlign.toUtf8());
599 
600  m_pSerializer->endElementNS(XML_w, XML_tcPr);
601 }
602 
604  const uno::Sequence<beans::PropertyValue>& rTableStylePr)
605 {
606  if (!rTableStylePr.hasElements())
607  return;
608 
609  OUString aType;
610  uno::Sequence<beans::PropertyValue> aPPr;
611  uno::Sequence<beans::PropertyValue> aRPr;
612  uno::Sequence<beans::PropertyValue> aTablePr;
613  uno::Sequence<beans::PropertyValue> aTrPr;
614  uno::Sequence<beans::PropertyValue> aTcPr;
615  for (const auto& rProp : rTableStylePr)
616  {
617  if (rProp.Name == "type")
618  aType = rProp.Value.get<OUString>();
619  else if (rProp.Name == "pPr")
620  aPPr = rProp.Value.get<uno::Sequence<beans::PropertyValue>>();
621  else if (rProp.Name == "rPr")
622  aRPr = rProp.Value.get<uno::Sequence<beans::PropertyValue>>();
623  else if (rProp.Name == "tblPr")
624  aTablePr = rProp.Value.get<uno::Sequence<beans::PropertyValue>>();
625  else if (rProp.Name == "trPr")
626  aTrPr = rProp.Value.get<uno::Sequence<beans::PropertyValue>>();
627  else if (rProp.Name == "tcPr")
628  aTcPr = rProp.Value.get<uno::Sequence<beans::PropertyValue>>();
629  }
630 
631  m_pSerializer->startElementNS(XML_w, XML_tblStylePr, FSNS(XML_w, XML_type), aType.toUtf8());
632 
633  tableStylePPr(aPPr);
634  tableStyleRPr(aRPr);
635  if (aTablePr.hasElements())
636  tableStyleTablePr(aTablePr);
637  else
638  {
639  // Even if we have an empty container, write it out, as Word does.
640  m_pSerializer->singleElementNS(XML_w, XML_tblPr);
641  }
642  tableStyleTrPr(aTrPr);
643  tableStyleTcPr(aTcPr);
644 
645  m_pSerializer->endElementNS(XML_w, XML_tblStylePr);
646 }
647 
648 void DocxTableStyleExport::Impl::TableStyle(const uno::Sequence<beans::PropertyValue>& rStyle)
649 {
650  bool bDefault = false;
651  bool bCustomStyle = false;
652  bool bQFormat = false;
653  bool bSemiHidden = false;
654  bool bUnhideWhenUsed = false;
655  OUString aStyleId;
656  OUString aName;
657  OUString aBasedOn;
658  OUString aRsid;
659  OUString aUiPriority;
660  uno::Sequence<beans::PropertyValue> aPPr;
661  uno::Sequence<beans::PropertyValue> aRPr;
662  uno::Sequence<beans::PropertyValue> aTablePr;
663  uno::Sequence<beans::PropertyValue> aTcPr;
664  std::vector<uno::Sequence<beans::PropertyValue>> aTableStylePrs;
665  for (const auto& rProp : rStyle)
666  {
667  if (rProp.Name == "default")
668  bDefault = rProp.Value.get<bool>();
669  else if (rProp.Name == "customStyle")
670  bCustomStyle = rProp.Value.get<bool>();
671  else if (rProp.Name == "styleId")
672  aStyleId = rProp.Value.get<OUString>();
673  else if (rProp.Name == "name")
674  aName = rProp.Value.get<OUString>();
675  else if (rProp.Name == "basedOn")
676  aBasedOn = rProp.Value.get<OUString>();
677  else if (rProp.Name == "uiPriority")
678  aUiPriority = rProp.Value.get<OUString>();
679  else if (rProp.Name == "qFormat")
680  bQFormat = true;
681  else if (rProp.Name == "semiHidden")
682  bSemiHidden = true;
683  else if (rProp.Name == "unhideWhenUsed")
684  bUnhideWhenUsed = true;
685  else if (rProp.Name == "rsid")
686  aRsid = rProp.Value.get<OUString>();
687  else if (rProp.Name == "pPr")
688  aPPr = rProp.Value.get<uno::Sequence<beans::PropertyValue>>();
689  else if (rProp.Name == "rPr")
690  aRPr = rProp.Value.get<uno::Sequence<beans::PropertyValue>>();
691  else if (rProp.Name == "tblPr")
692  aTablePr = rProp.Value.get<uno::Sequence<beans::PropertyValue>>();
693  else if (rProp.Name == "tcPr")
694  aTcPr = rProp.Value.get<uno::Sequence<beans::PropertyValue>>();
695  else if (rProp.Name == "tblStylePr")
696  aTableStylePrs.push_back(rProp.Value.get<uno::Sequence<beans::PropertyValue>>());
697  }
698 
699  sax_fastparser::FastAttributeList* pAttributeList
701  pAttributeList->add(FSNS(XML_w, XML_type), "table");
702  if (bDefault)
703  pAttributeList->add(FSNS(XML_w, XML_default), "1");
704  if (bCustomStyle)
705  pAttributeList->add(FSNS(XML_w, XML_customStyle), "1");
706  if (!aStyleId.isEmpty())
707  pAttributeList->add(FSNS(XML_w, XML_styleId), aStyleId.toUtf8());
708  sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
709  m_pSerializer->startElementNS(XML_w, XML_style, xAttributeList);
710 
711  m_pSerializer->singleElementNS(XML_w, XML_name, FSNS(XML_w, XML_val), aName.toUtf8());
712  if (!aBasedOn.isEmpty())
713  m_pSerializer->singleElementNS(XML_w, XML_basedOn, FSNS(XML_w, XML_val), aBasedOn.toUtf8());
714  if (!aUiPriority.isEmpty())
715  m_pSerializer->singleElementNS(XML_w, XML_uiPriority, FSNS(XML_w, XML_val),
716  aUiPriority.toUtf8());
717  if (bSemiHidden)
718  m_pSerializer->singleElementNS(XML_w, XML_semiHidden);
719  if (bUnhideWhenUsed)
720  m_pSerializer->singleElementNS(XML_w, XML_unhideWhenUsed);
721  if (bQFormat)
722  m_pSerializer->singleElementNS(XML_w, XML_qFormat);
723  if (!aRsid.isEmpty())
724  m_pSerializer->singleElementNS(XML_w, XML_rsid, FSNS(XML_w, XML_val), aRsid.toUtf8());
725 
726  tableStylePPr(aPPr);
727  tableStyleRPr(aRPr);
728  tableStyleTablePr(aTablePr);
729  tableStyleTcPr(aTcPr);
730  for (const uno::Sequence<beans::PropertyValue>& i : std::as_const(aTableStylePrs))
731  tableStyleTableStylePr(i);
732 
733  m_pSerializer->endElementNS(XML_w, XML_style);
734 }
735 
737 {
738  m_pImpl->setSerializer(pSerializer);
739 }
740 
742  const sax_fastparser::FSHelperPtr& pSerializer)
743  : m_pImpl(std::make_unique<Impl>(pDoc))
744 {
745  m_pImpl->setSerializer(pSerializer);
746 }
747 
749 
750 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void tableStyleTableInd(const uno::Sequence< beans::PropertyValue > &rTableInd)
Export of w:tblInd.
void tableStyleTablePr(const uno::Sequence< beans::PropertyValue > &rTablePr)
Export of w:tblPr.
static FastAttributeList * createAttrList()
css::uno::Reference< css::xml::sax::XFastAttributeList > XFastAttributeListRef
Methods in this class handle values in a table style.
void TableStyle(const uno::Sequence< beans::PropertyValue > &rStyle)
void tableStyleRColor(const uno::Sequence< beans::PropertyValue > &rColor)
Export of w:color.
void tableStyleTableCellMar(const uno::Sequence< beans::PropertyValue > &rTableCellMar, sal_Int32 nType=XML_tblCellMar)
Export of w:tblCellMar (and w:tcMar).
std::unique_ptr< Impl > m_pImpl
Definition: doc.hxx:185
void tableStylePSpacing(const uno::Sequence< beans::PropertyValue > &rSpacing)
Export of w:spacing.
void TableStyles(sal_Int32 nCountStylesToWrite)
void tableStyleTrPr(const uno::Sequence< beans::PropertyValue > &rTrPr)
Export of w:trPr.
void CnfStyle(const css::uno::Sequence< css::beans::PropertyValue > &rAttributeList)
Writes based on grab-bagged para, cell or row properties.
Value
void tableStyleTcBorders(const uno::Sequence< beans::PropertyValue > &rTcBorders, sal_Int32 nToken=XML_tcBorders)
Export of w:tcBorders (and w:tblBorders).
void SetSerializer(const sax_fastparser::FSHelperPtr &pSerializer)
void tableStyleRPr(const uno::Sequence< beans::PropertyValue > &rRPr)
Export of w:rPr.
void tableStyleShd(const uno::Sequence< beans::PropertyValue > &rShd)
Export of w:shd.
void tableStyleTableStylePr(const uno::Sequence< beans::PropertyValue > &rTableStylePr)
Export of w:tblStylePr.
if(nullptr==pCandidateA||nullptr==pCandidateB)
void tableStylePPr(const uno::Sequence< beans::PropertyValue > &rPPr)
Export of w:pPr.
void setSerializer(sax_fastparser::FSHelperPtr pSerializer)
int i
sal_Int32 DocxStringGetToken(DocxStringTokenMap const *pMap, const OUString &rName)
std::shared_ptr< FastSerializerHelper > FSHelperPtr
void tableStyleTcPr(const uno::Sequence< beans::PropertyValue > &rTcPr)
Export of w:tcPr.
void tableStylePInd(const uno::Sequence< beans::PropertyValue > &rInd)
Export of w:ind in a pPr.
void add(sal_Int32 nToken, const sal_Char *pValue)
const sax_fastparser::FSHelperPtr & getSerializer() const
constexpr sal_Int32 FSNS(sal_Int32 namespc, sal_Int32 element)
OString const aName
void handleBoolean(const OUString &aValue, sal_Int32 nToken)
Handles a boolean value.
sax_fastparser::FSHelperPtr m_pSerializer
DocxTableStyleExport(SwDoc *pDoc, const sax_fastparser::FSHelperPtr &pSerializer)
DefTokenId const nToken
void tableStyleTcBorder(sal_Int32 nToken, const uno::Sequence< beans::PropertyValue > &rTcBorder)
Export of a given table cell border type.
void tableStyleRRFonts(const uno::Sequence< beans::PropertyValue > &rRFonts)
Export of w:rFonts.
void tableStyleRLang(const uno::Sequence< beans::PropertyValue > &rLang)
Export of w:lang.