Line data Source code
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>
15 : #include <comphelper/sequenceashashmap.hxx>
16 : #include <boost/optional.hpp>
17 :
18 : using namespace com::sun::star;
19 : using namespace oox;
20 :
21 : /// Methods in this class handle values in a table style.
22 1720 : struct DocxTableStyleExport::Impl
23 : {
24 : SwDoc* m_pDoc;
25 : sax_fastparser::FSHelperPtr m_pSerializer;
26 :
27 : void TableStyle(uno::Sequence<beans::PropertyValue>& rStyle);
28 :
29 : /// Handles a boolean value.
30 : void handleBoolean(const OUString& aValue, sal_Int32 nToken);
31 :
32 : /// Export of w:pPr.
33 : void tableStylePPr(uno::Sequence<beans::PropertyValue>& rPPr);
34 : /// Export of w:tblStylePr.
35 : void tableStyleTblStylePr(uno::Sequence<beans::PropertyValue>& rTblStylePr);
36 : /// Export of w:rPr.
37 : void tableStyleRPr(uno::Sequence<beans::PropertyValue>& rRPr);
38 : /// Export of w:rFonts.
39 : void tableStyleRRFonts(uno::Sequence<beans::PropertyValue>& rRFonts);
40 : /// Export of w:lang.
41 : void tableStyleRLang(uno::Sequence<beans::PropertyValue>& rLang);
42 : /// Export of w:ind in a pPr.
43 : void tableStylePInd(uno::Sequence<beans::PropertyValue>& rInd);
44 : /// Export of w:spacing.
45 : void tableStylePSpacing(uno::Sequence<beans::PropertyValue>& rSpacing);
46 : /// Export of w:tblPr.
47 : void tableStyleTblPr(uno::Sequence<beans::PropertyValue>& rTblPr);
48 : /// Export of w:tcPr.
49 : void tableStyleTcPr(uno::Sequence<beans::PropertyValue>& rTcPr);
50 : /// Export of w:tcBorders (and w:tblBorders).
51 : void tableStyleTcBorders(uno::Sequence<beans::PropertyValue>& rTcBorders, sal_Int32 nToken = XML_tcBorders);
52 : /// Export of w:tblInd.
53 : void tableStyleTblInd(uno::Sequence<beans::PropertyValue>& rTblInd);
54 : /// Export of w:tblCellMar (and w:tcMar).
55 : void tableStyleTblCellMar(uno::Sequence<beans::PropertyValue>& rTblCellMar, sal_Int32 nType = XML_tblCellMar);
56 : /// Export of a given table cell border type.
57 : void tableStyleTcBorder(sal_Int32 nToken, const uno::Sequence<beans::PropertyValue>& rTcBorder);
58 : /// Export of w:shd.
59 : void tableStyleShd(uno::Sequence<beans::PropertyValue>& rShd);
60 : /// Export of w:color.
61 : void tableStyleRColor(uno::Sequence<beans::PropertyValue>& rColor);
62 : };
63 :
64 4 : void DocxTableStyleExport::CharFormat(css::uno::Sequence<css::beans::PropertyValue>& rRPr)
65 : {
66 4 : m_pImpl->tableStyleRPr(rRPr);
67 4 : }
68 :
69 68 : void DocxTableStyleExport::CnfStyle(uno::Sequence<beans::PropertyValue>& rAttributeList)
70 : {
71 68 : sax_fastparser::FastAttributeList* pAttributeList = m_pImpl->m_pSerializer->createAttrList();
72 :
73 952 : for (sal_Int32 j = 0; j < rAttributeList.getLength(); ++j)
74 : {
75 884 : if (rAttributeList[j].Name == "val")
76 68 : pAttributeList->add(FSNS(XML_w, XML_val), rtl::OUStringToOString(rAttributeList[j].Value.get<OUString>(), RTL_TEXTENCODING_UTF8));
77 : else
78 : {
79 : static DocxStringTokenMap const aTokens[] =
80 : {
81 : {"firstRow", XML_firstRow},
82 : {"lastRow", XML_lastRow},
83 : {"firstColumn", XML_firstColumn},
84 : {"lastColumn", XML_lastColumn},
85 : {"oddVBand", XML_oddVBand},
86 : {"evenVBand", XML_evenVBand},
87 : {"oddHBand", XML_oddHBand},
88 : {"evenHBand", XML_evenHBand},
89 : {"firstRowFirstColumn", XML_firstRowFirstColumn},
90 : {"firstRowLastColumn", XML_firstRowLastColumn},
91 : {"lastRowFirstColumn", XML_lastRowFirstColumn},
92 : {"lastRowLastColumn", XML_lastRowLastColumn},
93 : {0, 0}
94 : };
95 :
96 816 : if (sal_Int32 nToken = DocxStringGetToken(aTokens, rAttributeList[j].Name))
97 816 : pAttributeList->add(FSNS(XML_w, nToken), rtl::OUStringToOString(rAttributeList[j].Value.get<OUString>(), RTL_TEXTENCODING_UTF8));
98 : }
99 : }
100 :
101 68 : sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
102 68 : m_pImpl->m_pSerializer->singleElementNS(XML_w, XML_cnfStyle, xAttributeList);
103 68 : }
104 :
105 860 : void DocxTableStyleExport::TableStyles(sal_uInt16 nCountStylesToWrite)
106 : {
107 : // Do we have table styles from InteropGrabBag available?
108 860 : uno::Reference<beans::XPropertySet> xPropertySet(m_pImpl->m_pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW);
109 1634 : uno::Sequence<beans::PropertyValue> aInteropGrabBag;
110 860 : xPropertySet->getPropertyValue("InteropGrabBag") >>= aInteropGrabBag;
111 1634 : uno::Sequence<beans::PropertyValue> aTableStyles;
112 9878 : for (sal_Int32 i = 0; i < aInteropGrabBag.getLength(); ++i)
113 : {
114 9792 : if (aInteropGrabBag[i].Name == "tableStyles")
115 : {
116 774 : aInteropGrabBag[i].Value >>= aTableStyles;
117 774 : break;
118 : }
119 : }
120 860 : if (!aTableStyles.getLength())
121 946 : return;
122 : // HACK
123 : // Ms Office seems to have an internal limitation of 4091 styles
124 : // and refuses to load .docx with more, even though the spec seems to allow that;
125 : // so simply if there are more styles, don't export those
126 774 : nCountStylesToWrite = (nCountStylesToWrite > aTableStyles.getLength()) ? aTableStyles.getLength(): nCountStylesToWrite;
127 :
128 2172 : for (sal_Int32 i = 0; i < nCountStylesToWrite; ++i)
129 : {
130 1398 : uno::Sequence<beans::PropertyValue> aTableStyle;
131 1398 : aTableStyles[i].Value >>= aTableStyle;
132 1398 : m_pImpl->TableStyle(aTableStyle);
133 2172 : }
134 : }
135 :
136 2934 : void DocxTableStyleExport::Impl::tableStyleTblCellMar(uno::Sequence<beans::PropertyValue>& rTblCellMar, sal_Int32 nType)
137 : {
138 : static DocxStringTokenMap const aTblCellMarTokens[] =
139 : {
140 : {"left", XML_left},
141 : {"right", XML_right},
142 : {"start", XML_start},
143 : {"end", XML_end},
144 : {"top", XML_top},
145 : {"bottom", XML_bottom},
146 : {0, 0}
147 : };
148 :
149 2934 : if (!rTblCellMar.hasElements())
150 4444 : return;
151 :
152 1424 : m_pSerializer->startElementNS(XML_w, nType, FSEND);
153 7108 : for (sal_Int32 i = 0; i < rTblCellMar.getLength(); ++i)
154 : {
155 5684 : if (sal_Int32 nToken = DocxStringGetToken(aTblCellMarTokens, rTblCellMar[i].Name))
156 : {
157 5684 : comphelper::SequenceAsHashMap aMap(rTblCellMar[i].Value.get< uno::Sequence<beans::PropertyValue> >());
158 : m_pSerializer->singleElementNS(XML_w, nToken,
159 11368 : FSNS(XML_w, XML_w), OString::number(aMap["w"].get<sal_Int32>()),
160 11368 : FSNS(XML_w, XML_type), OUStringToOString(aMap["type"].get<OUString>(), RTL_TEXTENCODING_UTF8).getStr(),
161 22736 : FSEND);
162 : }
163 : }
164 1424 : m_pSerializer->endElementNS(XML_w, nType);
165 : }
166 :
167 6228 : void DocxTableStyleExport::Impl::tableStyleTcBorder(sal_Int32 nToken, const uno::Sequence<beans::PropertyValue>& rTcBorder)
168 : {
169 : static DocxStringTokenMap const aTcBorderTokens[] =
170 : {
171 : {"val", XML_val},
172 : {"sz", XML_sz},
173 : {"color", XML_color},
174 : {"space", XML_space},
175 : {"themeColor", XML_themeColor},
176 : {"themeTint", XML_themeTint},
177 : {0, 0}
178 : };
179 :
180 6228 : if (!rTcBorder.hasElements())
181 6228 : return;
182 :
183 6228 : sax_fastparser::FastAttributeList* pAttributeList = m_pSerializer->createAttrList();
184 30260 : for (sal_Int32 i = 0; i < rTcBorder.getLength(); ++i)
185 24032 : if (sal_Int32 nAttrToken = DocxStringGetToken(aTcBorderTokens, rTcBorder[i].Name))
186 24032 : pAttributeList->add(FSNS(XML_w, nAttrToken), OUStringToOString(rTcBorder[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
187 :
188 6228 : sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
189 6228 : m_pSerializer->singleElementNS(XML_w, nToken, xAttributeList);
190 : }
191 :
192 2934 : void DocxTableStyleExport::Impl::tableStyleTcBorders(uno::Sequence<beans::PropertyValue>& rTcBorders, sal_Int32 nToken)
193 : {
194 : static DocxStringTokenMap const aTcBordersTokens[] =
195 : {
196 : {"left", XML_left},
197 : {"right", XML_right},
198 : {"start", XML_start},
199 : {"end", XML_end},
200 : {"top", XML_top},
201 : {"bottom", XML_bottom},
202 : {"insideH", XML_insideH},
203 : {"insideV", XML_insideV},
204 : {"tl2br", XML_tl2br},
205 : {"tr2bl", XML_tr2bl},
206 : {0, 0}
207 : };
208 :
209 2934 : if (!rTcBorders.hasElements())
210 4114 : return;
211 :
212 1754 : m_pSerializer->startElementNS(XML_w, nToken, FSEND);
213 7982 : for (sal_Int32 i = 0; i < rTcBorders.getLength(); ++i)
214 6228 : if (sal_Int32 nSubToken = DocxStringGetToken(aTcBordersTokens, rTcBorders[i].Name))
215 6228 : tableStyleTcBorder(nSubToken, rTcBorders[i].Value.get< uno::Sequence<beans::PropertyValue> >());
216 1754 : m_pSerializer->endElementNS(XML_w, nToken);
217 : }
218 :
219 1536 : void DocxTableStyleExport::Impl::tableStyleShd(uno::Sequence<beans::PropertyValue>& rShd)
220 : {
221 1536 : if (!rShd.hasElements())
222 2428 : return;
223 :
224 644 : sax_fastparser::FastAttributeList* pAttributeList = m_pSerializer->createAttrList();
225 3356 : for (sal_Int32 i = 0; i < rShd.getLength(); ++i)
226 : {
227 2712 : if (rShd[i].Name == "val")
228 644 : pAttributeList->add(FSNS(XML_w, XML_val), OUStringToOString(rShd[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
229 2068 : else if (rShd[i].Name == "color")
230 644 : pAttributeList->add(FSNS(XML_w, XML_color), OUStringToOString(rShd[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
231 1424 : else if (rShd[i].Name == "fill")
232 644 : pAttributeList->add(FSNS(XML_w, XML_fill), OUStringToOString(rShd[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
233 780 : else if (rShd[i].Name == "themeFill")
234 92 : pAttributeList->add(FSNS(XML_w, XML_themeFill), OUStringToOString(rShd[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
235 688 : else if (rShd[i].Name == "themeFillShade")
236 10 : pAttributeList->add(FSNS(XML_w, XML_themeFillShade), OUStringToOString(rShd[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
237 678 : else if (rShd[i].Name == "themeFillTint")
238 34 : pAttributeList->add(FSNS(XML_w, XML_themeFillTint), OUStringToOString(rShd[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
239 : }
240 644 : sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
241 644 : m_pSerializer->singleElementNS(XML_w, XML_shd, xAttributeList);
242 : }
243 :
244 1192 : void DocxTableStyleExport::Impl::tableStyleRColor(uno::Sequence<beans::PropertyValue>& rColor)
245 : {
246 1192 : if (!rColor.hasElements())
247 1946 : return;
248 :
249 438 : sax_fastparser::FastAttributeList* pAttributeList = m_pSerializer->createAttrList();
250 960 : for (sal_Int32 i = 0; i < rColor.getLength(); ++i)
251 : {
252 522 : if (rColor[i].Name == "val")
253 438 : pAttributeList->add(FSNS(XML_w, XML_val), OUStringToOString(rColor[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
254 84 : else if (rColor[i].Name == "themeColor")
255 66 : pAttributeList->add(FSNS(XML_w, XML_themeColor), OUStringToOString(rColor[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
256 18 : else if (rColor[i].Name == "themeTint")
257 2 : pAttributeList->add(FSNS(XML_w, XML_themeTint), OUStringToOString(rColor[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
258 16 : else if (rColor[i].Name == "themeShade")
259 16 : pAttributeList->add(FSNS(XML_w, XML_themeShade), OUStringToOString(rColor[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
260 : }
261 438 : sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
262 438 : m_pSerializer->singleElementNS(XML_w, XML_color, xAttributeList);
263 : }
264 :
265 1192 : void DocxTableStyleExport::Impl::tableStyleRLang(uno::Sequence<beans::PropertyValue>& rLang)
266 : {
267 1192 : if (!rLang.hasElements())
268 2346 : return;
269 :
270 38 : sax_fastparser::FastAttributeList* pAttributeList = m_pSerializer->createAttrList();
271 82 : for (sal_Int32 i = 0; i < rLang.getLength(); ++i)
272 : {
273 44 : if (rLang[i].Name == "eastAsia")
274 14 : pAttributeList->add(FSNS(XML_w, XML_eastAsia), OUStringToOString(rLang[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
275 30 : else if (rLang[i].Name == "val")
276 12 : pAttributeList->add(FSNS(XML_w, XML_val), OUStringToOString(rLang[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
277 18 : else if (rLang[i].Name == "bidi")
278 18 : pAttributeList->add(FSNS(XML_w, XML_bidi), OUStringToOString(rLang[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
279 : }
280 38 : sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
281 38 : m_pSerializer->singleElementNS(XML_w, XML_lang, xAttributeList);
282 : }
283 :
284 1192 : void DocxTableStyleExport::Impl::tableStyleRRFonts(uno::Sequence<beans::PropertyValue>& rRFonts)
285 : {
286 1192 : if (!rRFonts.hasElements())
287 2342 : return;
288 :
289 42 : sax_fastparser::FastAttributeList* pAttributeList = m_pSerializer->createAttrList();
290 124 : for (sal_Int32 i = 0; i < rRFonts.getLength(); ++i)
291 : {
292 82 : if (rRFonts[i].Name == "eastAsiaTheme")
293 26 : pAttributeList->add(FSNS(XML_w, XML_eastAsiaTheme), OUStringToOString(rRFonts[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
294 56 : else if (rRFonts[i].Name == "asciiTheme")
295 24 : pAttributeList->add(FSNS(XML_w, XML_asciiTheme), OUStringToOString(rRFonts[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
296 32 : else if (rRFonts[i].Name == "cstheme")
297 8 : pAttributeList->add(FSNS(XML_w, XML_cstheme), OUStringToOString(rRFonts[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
298 24 : else if (rRFonts[i].Name == "hAnsiTheme")
299 24 : pAttributeList->add(FSNS(XML_w, XML_hAnsiTheme), OUStringToOString(rRFonts[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
300 : }
301 42 : sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
302 42 : m_pSerializer->singleElementNS(XML_w, XML_rFonts, xAttributeList);
303 : }
304 :
305 542 : void DocxTableStyleExport::Impl::tableStylePSpacing(uno::Sequence<beans::PropertyValue>& rSpacing)
306 : {
307 542 : if (!rSpacing.hasElements())
308 552 : return;
309 :
310 532 : sax_fastparser::FastAttributeList* pAttributeList = m_pSerializer->createAttrList();
311 2466 : for (sal_Int32 i = 0; i < rSpacing.getLength(); ++i)
312 : {
313 1934 : if (rSpacing[i].Name == "after")
314 484 : pAttributeList->add(FSNS(XML_w, XML_after), OUStringToOString(rSpacing[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
315 1450 : else if (rSpacing[i].Name == "before")
316 338 : pAttributeList->add(FSNS(XML_w, XML_before), OUStringToOString(rSpacing[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
317 1112 : else if (rSpacing[i].Name == "line")
318 518 : pAttributeList->add(FSNS(XML_w, XML_line), OUStringToOString(rSpacing[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
319 594 : else if (rSpacing[i].Name == "lineRule")
320 518 : pAttributeList->add(FSNS(XML_w, XML_lineRule), OUStringToOString(rSpacing[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
321 76 : else if (rSpacing[i].Name == "beforeLines")
322 40 : pAttributeList->add(FSNS(XML_w, XML_beforeLines), OUStringToOString(rSpacing[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
323 36 : else if (rSpacing[i].Name == "ParaTopMarginBeforeAutoSpacing")
324 : // Auto spacing will be available in grab bag only if it was set to true
325 0 : pAttributeList->add(FSNS(XML_w, XML_beforeAutospacing), "1");
326 36 : else if (rSpacing[i].Name == "afterLines")
327 36 : pAttributeList->add(FSNS(XML_w, XML_afterLines), OUStringToOString(rSpacing[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
328 0 : else if (rSpacing[i].Name == "ParaBottomMarginAfterAutoSpacing")
329 : // Auto spacing will be available in grab bag only if it was set to true
330 0 : pAttributeList->add(FSNS(XML_w, XML_afterAutospacing), "1");
331 : }
332 532 : sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
333 532 : m_pSerializer->singleElementNS(XML_w, XML_spacing, xAttributeList);
334 : }
335 :
336 542 : void DocxTableStyleExport::Impl::tableStylePInd(uno::Sequence<beans::PropertyValue>& rInd)
337 : {
338 542 : if (!rInd.hasElements())
339 1042 : return;
340 :
341 42 : sax_fastparser::FastAttributeList* pAttributeList = m_pSerializer->createAttrList();
342 116 : for (sal_Int32 i = 0; i < rInd.getLength(); ++i)
343 : {
344 74 : if (rInd[i].Name == "rightChars")
345 32 : pAttributeList->add(FSNS(XML_w, XML_rightChars), OUStringToOString(rInd[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
346 42 : else if (rInd[i].Name == "right")
347 42 : pAttributeList->add(FSNS(XML_w, XML_right), OUStringToOString(rInd[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
348 : }
349 42 : sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
350 42 : m_pSerializer->singleElementNS(XML_w, XML_ind, xAttributeList);
351 : }
352 :
353 1398 : void DocxTableStyleExport::Impl::tableStyleTblInd(uno::Sequence<beans::PropertyValue>& rTblInd)
354 : {
355 1398 : if (!rTblInd.hasElements())
356 1398 : return;
357 :
358 1398 : sax_fastparser::FastAttributeList* pAttributeList = m_pSerializer->createAttrList();
359 4194 : for (sal_Int32 i = 0; i < rTblInd.getLength(); ++i)
360 : {
361 2796 : if (rTblInd[i].Name == "w")
362 1398 : pAttributeList->add(FSNS(XML_w, XML_w), OString::number(rTblInd[i].Value.get<sal_Int32>()));
363 1398 : else if (rTblInd[i].Name == "type")
364 1398 : pAttributeList->add(FSNS(XML_w, XML_type), OUStringToOString(rTblInd[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
365 : }
366 1398 : sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
367 1398 : m_pSerializer->singleElementNS(XML_w, XML_tblInd, xAttributeList);
368 : }
369 :
370 6502 : void DocxTableStyleExport::Impl::handleBoolean(const OUString& aValue, sal_Int32 nToken)
371 : {
372 6502 : if (aValue.isEmpty())
373 11356 : return;
374 1648 : sax_fastparser::FastAttributeList* pAttributeList = m_pSerializer->createAttrList();
375 1648 : if (aValue != "1")
376 248 : pAttributeList->add(FSNS(XML_w, XML_val), OUStringToOString(aValue, RTL_TEXTENCODING_UTF8).getStr());
377 1648 : sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
378 1648 : m_pSerializer->singleElementNS(XML_w, nToken, xAttributeList);
379 : }
380 :
381 2822 : void DocxTableStyleExport::Impl::tableStyleRPr(uno::Sequence<beans::PropertyValue>& rRPr)
382 : {
383 2822 : if (!rRPr.hasElements())
384 4452 : return;
385 :
386 1192 : m_pSerializer->startElementNS(XML_w, XML_rPr, FSEND);
387 :
388 2384 : uno::Sequence<beans::PropertyValue> aRFonts, aLang, aColor, aSpacingSequence;
389 1192 : bool bSequenceFlag = false ;
390 2384 : OUString aB, aBCs, aI, aSz, aSzCs, aCaps, aSmallCaps, aSpacing;
391 3688 : for (sal_Int32 i = 0; i < rRPr.getLength(); ++i)
392 : {
393 2496 : if (rRPr[i].Name == "rFonts")
394 154 : aRFonts = rRPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
395 2342 : else if (rRPr[i].Name == "lang")
396 38 : aLang = rRPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
397 2304 : else if (rRPr[i].Name == "b")
398 772 : aB = rRPr[i].Value.get<OUString>();
399 1532 : else if (rRPr[i].Name == "bCs")
400 724 : aBCs = rRPr[i].Value.get<OUString>();
401 808 : else if (rRPr[i].Name == "i")
402 140 : aI = rRPr[i].Value.get<OUString>();
403 668 : else if (rRPr[i].Name == "color")
404 438 : aColor = rRPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
405 230 : else if (rRPr[i].Name == "sz")
406 128 : aSz = rRPr[i].Value.get<OUString>();
407 102 : else if (rRPr[i].Name == "szCs")
408 90 : aSzCs = rRPr[i].Value.get<OUString>();
409 12 : else if (rRPr[i].Name == "caps")
410 8 : aCaps = rRPr[i].Value.get<OUString>();
411 4 : else if (rRPr[i].Name == "smallCaps")
412 2 : aSmallCaps = rRPr[i].Value.get<OUString>();
413 2 : else if (rRPr[i].Name == "spacing")
414 : {
415 2 : if (rRPr[i].Value.has<OUString>())
416 : {
417 2 : aSpacing = rRPr[i].Value.get<OUString>();
418 : }
419 : else
420 : {
421 0 : aSpacingSequence = rRPr[i].Value.get< uno::Sequence<beans::PropertyValue> >() ;
422 0 : bSequenceFlag = true ; // set the uno::Sequence flag.
423 : }
424 : }
425 : }
426 1192 : tableStyleRRFonts(aRFonts);
427 1192 : tableStyleRLang(aLang);
428 1192 : handleBoolean(aB, XML_b);
429 1192 : handleBoolean(aBCs, XML_bCs);
430 1192 : handleBoolean(aI, XML_i);
431 1192 : handleBoolean(aCaps, XML_caps);
432 1192 : handleBoolean(aSmallCaps, XML_smallCaps);
433 1192 : tableStyleRColor(aColor);
434 1192 : if (bSequenceFlag)
435 : {
436 : m_pSerializer->singleElementNS(XML_w, XML_spacing,
437 0 : FSNS(XML_w, XML_val),OUStringToOString(aSpacingSequence[0].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr(),
438 0 : FSEND);
439 : }
440 1192 : if (!aSpacing.isEmpty())
441 : m_pSerializer->singleElementNS(XML_w, XML_spacing,
442 : FSNS(XML_w, XML_val), OUStringToOString(aSpacing, RTL_TEXTENCODING_UTF8).getStr(),
443 2 : FSEND);
444 1192 : if (!aSz.isEmpty())
445 : m_pSerializer->singleElementNS(XML_w, XML_sz,
446 : FSNS(XML_w, XML_val), OUStringToOString(aSz, RTL_TEXTENCODING_UTF8).getStr(),
447 128 : FSEND);
448 1192 : if (!aSzCs.isEmpty())
449 : m_pSerializer->singleElementNS(XML_w, XML_szCs,
450 : FSNS(XML_w, XML_val), OUStringToOString(aSzCs, RTL_TEXTENCODING_UTF8).getStr(),
451 90 : FSEND);
452 :
453 2384 : m_pSerializer->endElementNS(XML_w, XML_rPr);
454 : }
455 :
456 2818 : void DocxTableStyleExport::Impl::tableStylePPr(uno::Sequence<beans::PropertyValue>& rPPr)
457 : {
458 2818 : if (!rPPr.hasElements())
459 5094 : return;
460 :
461 542 : m_pSerializer->startElementNS(XML_w, XML_pPr, FSEND);
462 :
463 1084 : uno::Sequence<beans::PropertyValue> aSpacing, aInd;
464 542 : bool bWordWrap = false;
465 1084 : OUString aJc, aSnapToGrid;
466 1204 : for (sal_Int32 i = 0; i < rPPr.getLength(); ++i)
467 : {
468 662 : if (rPPr[i].Name == "spacing")
469 532 : aSpacing = rPPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
470 130 : else if (rPPr[i].Name == "ind")
471 46 : aInd = rPPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
472 84 : else if (rPPr[i].Name == "wordWrap")
473 44 : bWordWrap = true;
474 40 : else if (rPPr[i].Name == "jc")
475 38 : aJc = rPPr[i].Value.get<OUString>();
476 2 : else if (rPPr[i].Name == "snapToGrid")
477 2 : aSnapToGrid = rPPr[i].Value.get<OUString>();
478 : }
479 542 : if (bWordWrap)
480 44 : m_pSerializer->singleElementNS(XML_w, XML_wordWrap, FSEND);
481 542 : tableStylePInd(aInd);
482 542 : handleBoolean(aSnapToGrid, XML_snapToGrid);
483 542 : tableStylePSpacing(aSpacing);
484 542 : if (!aJc.isEmpty())
485 : m_pSerializer->singleElementNS(XML_w, XML_jc,
486 : FSNS(XML_w, XML_val), OUStringToOString(aJc, RTL_TEXTENCODING_UTF8).getStr(),
487 38 : FSEND);
488 :
489 1084 : m_pSerializer->endElementNS(XML_w, XML_pPr);
490 : }
491 :
492 1398 : void DocxTableStyleExport::Impl::tableStyleTblPr(uno::Sequence<beans::PropertyValue>& rTblPr)
493 : {
494 1398 : if (!rTblPr.hasElements())
495 1398 : return;
496 :
497 1398 : m_pSerializer->startElementNS(XML_w, XML_tblPr, FSEND);
498 :
499 2796 : uno::Sequence<beans::PropertyValue> aTblInd, aTblBorders, aTblCellMar;
500 2796 : boost::optional<sal_Int32> oTblStyleRowBandSize, oTblStyleColBandSize;
501 4904 : for (sal_Int32 i = 0; i < rTblPr.getLength(); ++i)
502 : {
503 3506 : if (rTblPr[i].Name == "tblStyleRowBandSize")
504 96 : oTblStyleRowBandSize = rTblPr[i].Value.get<sal_Int32>();
505 3410 : else if (rTblPr[i].Name == "tblStyleColBandSize")
506 76 : oTblStyleColBandSize = rTblPr[i].Value.get<sal_Int32>();
507 3334 : else if (rTblPr[i].Name == "tblInd")
508 1398 : aTblInd = rTblPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
509 1936 : else if (rTblPr[i].Name == "tblBorders")
510 540 : aTblBorders = rTblPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
511 1396 : else if (rTblPr[i].Name == "tblCellMar")
512 1396 : aTblCellMar = rTblPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
513 : }
514 1398 : if (oTblStyleRowBandSize)
515 : m_pSerializer->singleElementNS(XML_w, XML_tblStyleRowBandSize,
516 96 : FSNS(XML_w, XML_val), OString::number(oTblStyleRowBandSize.get()),
517 96 : FSEND);
518 1398 : if (oTblStyleColBandSize)
519 : m_pSerializer->singleElementNS(XML_w, XML_tblStyleColBandSize,
520 76 : FSNS(XML_w, XML_val), OString::number(oTblStyleColBandSize.get()),
521 76 : FSEND);
522 1398 : tableStyleTblInd(aTblInd);
523 1398 : tableStyleTcBorders(aTblBorders, XML_tblBorders);
524 1398 : tableStyleTblCellMar(aTblCellMar);
525 :
526 2796 : m_pSerializer->endElementNS(XML_w, XML_tblPr);
527 : }
528 :
529 2818 : void DocxTableStyleExport::Impl::tableStyleTcPr(uno::Sequence<beans::PropertyValue>& rTcPr)
530 : {
531 2818 : if (!rTcPr.hasElements())
532 4100 : return;
533 :
534 1536 : m_pSerializer->startElementNS(XML_w, XML_tcPr, FSEND);
535 :
536 3072 : uno::Sequence<beans::PropertyValue> aShd, aTcBorders, aTcMar;
537 3072 : OUString aVAlign;
538 3452 : for (sal_Int32 i = 0; i < rTcPr.getLength(); ++i)
539 : {
540 1916 : if (rTcPr[i].Name == "shd")
541 644 : aShd = rTcPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
542 1272 : else if (rTcPr[i].Name == "tcBorders")
543 1214 : aTcBorders = rTcPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
544 58 : else if (rTcPr[i].Name == "tcMar")
545 28 : aTcMar = rTcPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
546 30 : else if (rTcPr[i].Name == "vAlign")
547 30 : aVAlign = rTcPr[i].Value.get<OUString>();
548 : }
549 1536 : tableStyleTcBorders(aTcBorders);
550 1536 : tableStyleTblCellMar(aTcMar, XML_tcMar);
551 1536 : tableStyleShd(aShd);
552 1536 : if (!aVAlign.isEmpty())
553 : m_pSerializer->singleElementNS(XML_w, XML_vAlign,
554 : FSNS(XML_w, XML_val), OUStringToOString(aVAlign, RTL_TEXTENCODING_UTF8).getStr(),
555 30 : FSEND);
556 :
557 3072 : m_pSerializer->endElementNS(XML_w, XML_tcPr);
558 : }
559 :
560 1420 : void DocxTableStyleExport::Impl::tableStyleTblStylePr(uno::Sequence<beans::PropertyValue>& rTblStylePr)
561 : {
562 1420 : if (!rTblStylePr.hasElements())
563 1420 : return;
564 :
565 1420 : OUString aType;
566 2840 : uno::Sequence<beans::PropertyValue> aPPr, aRPr, aTblPr, aTcPr;
567 6580 : for (sal_Int32 i = 0; i < rTblStylePr.getLength(); ++i)
568 : {
569 5160 : if (rTblStylePr[i].Name == "type")
570 1420 : aType = rTblStylePr[i].Value.get<OUString>();
571 3740 : else if (rTblStylePr[i].Name == "pPr")
572 92 : aPPr = rTblStylePr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
573 3648 : else if (rTblStylePr[i].Name == "rPr")
574 1024 : aRPr = rTblStylePr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
575 2624 : else if (rTblStylePr[i].Name == "tblPr")
576 1312 : aTblPr = rTblStylePr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
577 1312 : else if (rTblStylePr[i].Name == "tcPr")
578 1312 : aTcPr = rTblStylePr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
579 : }
580 :
581 : m_pSerializer->startElementNS(XML_w, XML_tblStylePr,
582 : FSNS(XML_w, XML_type), OUStringToOString(aType, RTL_TEXTENCODING_UTF8).getStr(),
583 1420 : FSEND);
584 :
585 1420 : tableStylePPr(aPPr);
586 1420 : tableStyleRPr(aRPr);
587 1420 : if (aTblPr.hasElements())
588 0 : tableStyleTblPr(aTblPr);
589 : else
590 : {
591 : // Even if we have an empty container, write it out, as Word does.
592 1420 : m_pSerializer->singleElementNS(XML_w, XML_tblPr, FSEND);
593 : }
594 1420 : tableStyleTcPr(aTcPr);
595 :
596 2840 : m_pSerializer->endElementNS(XML_w, XML_tblStylePr);
597 : }
598 :
599 1398 : void DocxTableStyleExport::Impl::TableStyle(uno::Sequence<beans::PropertyValue>& rStyle)
600 : {
601 1398 : bool bDefault = false, bCustomStyle = false, bQFormat = false, bSemiHidden = false, bUnhideWhenUsed = false;
602 2796 : OUString aStyleId, aName, aBasedOn, aRsid, aUiPriority;
603 2796 : uno::Sequence<beans::PropertyValue> aPPr, aRPr, aTblPr, aTcPr;
604 2796 : std::vector< uno::Sequence<beans::PropertyValue> > aTblStylePrs;
605 12694 : for (sal_Int32 i = 0; i < rStyle.getLength(); ++i)
606 : {
607 11296 : if (rStyle[i].Name == "default")
608 772 : bDefault = rStyle[i].Value.get<sal_Bool>();
609 10524 : else if (rStyle[i].Name == "customStyle")
610 166 : bCustomStyle = rStyle[i].Value.get<sal_Bool>();
611 10358 : else if (rStyle[i].Name == "styleId")
612 1398 : aStyleId = rStyle[i].Value.get<OUString>();
613 8960 : else if (rStyle[i].Name == "name")
614 1398 : aName = rStyle[i].Value.get<OUString>();
615 7562 : else if (rStyle[i].Name == "basedOn")
616 624 : aBasedOn = rStyle[i].Value.get<OUString>();
617 6938 : else if (rStyle[i].Name == "uiPriority")
618 960 : aUiPriority = rStyle[i].Value.get<OUString>();
619 5978 : else if (rStyle[i].Name == "qFormat")
620 136 : bQFormat = true;
621 5842 : else if (rStyle[i].Name == "semiHidden")
622 770 : bSemiHidden = true;
623 5072 : else if (rStyle[i].Name == "unhideWhenUsed")
624 770 : bUnhideWhenUsed = true;
625 4302 : else if (rStyle[i].Name == "rsid")
626 620 : aRsid = rStyle[i].Value.get<OUString>();
627 3682 : else if (rStyle[i].Name == "pPr")
628 460 : aPPr = rStyle[i].Value.get< uno::Sequence<beans::PropertyValue> >();
629 3222 : else if (rStyle[i].Name == "rPr")
630 164 : aRPr = rStyle[i].Value.get< uno::Sequence<beans::PropertyValue> >();
631 3058 : else if (rStyle[i].Name == "tblPr")
632 1398 : aTblPr = rStyle[i].Value.get< uno::Sequence<beans::PropertyValue> >();
633 1660 : else if (rStyle[i].Name == "tcPr")
634 226 : aTcPr = rStyle[i].Value.get< uno::Sequence<beans::PropertyValue> >();
635 1434 : else if (rStyle[i].Name == "tblStylePr")
636 1420 : aTblStylePrs.push_back(rStyle[i].Value.get< uno::Sequence<beans::PropertyValue> >());
637 : }
638 :
639 1398 : sax_fastparser::FastAttributeList* pAttributeList = m_pSerializer->createAttrList();
640 1398 : pAttributeList->add(FSNS(XML_w, XML_type), "table");
641 1398 : if (bDefault)
642 772 : pAttributeList->add(FSNS(XML_w, XML_default), "1");
643 1398 : if (bCustomStyle)
644 166 : pAttributeList->add(FSNS(XML_w, XML_customStyle), "1");
645 1398 : if (!aStyleId.isEmpty())
646 1398 : pAttributeList->add(FSNS(XML_w, XML_styleId), OUStringToOString(aStyleId, RTL_TEXTENCODING_UTF8).getStr());
647 2796 : sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
648 1398 : m_pSerializer->startElementNS(XML_w, XML_style, xAttributeList);
649 :
650 : m_pSerializer->singleElementNS(XML_w, XML_name,
651 : FSNS(XML_w, XML_val), OUStringToOString(aName, RTL_TEXTENCODING_UTF8).getStr(),
652 1398 : FSEND);
653 1398 : if (!aBasedOn.isEmpty())
654 : m_pSerializer->singleElementNS(XML_w, XML_basedOn,
655 : FSNS(XML_w, XML_val), OUStringToOString(aBasedOn, RTL_TEXTENCODING_UTF8).getStr(),
656 624 : FSEND);
657 1398 : if (!aUiPriority.isEmpty())
658 : m_pSerializer->singleElementNS(XML_w, XML_uiPriority,
659 : FSNS(XML_w, XML_val), OUStringToOString(aUiPriority, RTL_TEXTENCODING_UTF8).getStr(),
660 960 : FSEND);
661 1398 : if (bSemiHidden)
662 770 : m_pSerializer->singleElementNS(XML_w, XML_semiHidden, FSEND);
663 1398 : if (bUnhideWhenUsed)
664 770 : m_pSerializer->singleElementNS(XML_w, XML_unhideWhenUsed, FSEND);
665 1398 : if (bQFormat)
666 136 : m_pSerializer->singleElementNS(XML_w, XML_qFormat, FSEND);
667 1398 : if (!aRsid.isEmpty())
668 : m_pSerializer->singleElementNS(XML_w, XML_rsid,
669 : FSNS(XML_w, XML_val), OUStringToOString(aRsid, RTL_TEXTENCODING_UTF8).getStr(),
670 620 : FSEND);
671 :
672 1398 : tableStylePPr(aPPr);
673 1398 : tableStyleRPr(aRPr);
674 1398 : tableStyleTblPr(aTblPr);
675 1398 : tableStyleTcPr(aTcPr);
676 2818 : for (size_t i = 0; i < aTblStylePrs.size(); ++i)
677 1420 : tableStyleTblStylePr(aTblStylePrs[i]);
678 :
679 2796 : m_pSerializer->endElementNS(XML_w, XML_style);
680 1398 : }
681 :
682 4684 : void DocxTableStyleExport::SetSerializer(sax_fastparser::FSHelperPtr pSerializer)
683 : {
684 4684 : m_pImpl->m_pSerializer = pSerializer;
685 4684 : }
686 :
687 860 : DocxTableStyleExport::DocxTableStyleExport(SwDoc* pDoc, sax_fastparser::FSHelperPtr pSerializer)
688 860 : : m_pImpl(new Impl)
689 : {
690 860 : m_pImpl->m_pDoc = pDoc;
691 860 : m_pImpl->m_pSerializer = pSerializer;
692 860 : }
693 :
694 860 : DocxTableStyleExport::~DocxTableStyleExport()
695 : {
696 962 : }
697 :
698 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|