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 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "docxattributeoutput.hxx"
21 : #include "docxhelper.hxx"
22 : #include "docxsdrexport.hxx"
23 : #include "docxexportfilter.hxx"
24 : #include "docxfootnotes.hxx"
25 : #include "writerwordglue.hxx"
26 : #include "ww8par.hxx"
27 : #include "fmtcntnt.hxx"
28 : #include "fmtftn.hxx"
29 : #include "fchrfmt.hxx"
30 : #include "tgrditem.hxx"
31 : #include "fmtruby.hxx"
32 : #include "breakit.hxx"
33 : #include "redline.hxx"
34 : #include "unocoll.hxx"
35 : #include "unoframe.hxx"
36 : #include "wrtww8.hxx"
37 :
38 : #include "wrtww8.hxx"
39 :
40 : #include <comphelper/string.hxx>
41 : #include <oox/token/tokens.hxx>
42 : #include <oox/export/utils.hxx>
43 : #include <oox/mathml/export.hxx>
44 : #include <oox/drawingml/drawingmltypes.hxx>
45 :
46 : #include <editeng/autokernitem.hxx>
47 : #include <editeng/unoprnms.hxx>
48 : #include <editeng/fontitem.hxx>
49 : #include <editeng/tstpitem.hxx>
50 : #include <editeng/spltitem.hxx>
51 : #include <editeng/widwitem.hxx>
52 : #include <editeng/shaditem.hxx>
53 : #include <editeng/brushitem.hxx>
54 : #include <editeng/postitem.hxx>
55 : #include <editeng/wghtitem.hxx>
56 : #include <editeng/kernitem.hxx>
57 : #include <editeng/crossedoutitem.hxx>
58 : #include <editeng/cmapitem.hxx>
59 : #include <editeng/udlnitem.hxx>
60 : #include <editeng/langitem.hxx>
61 : #include <editeng/lspcitem.hxx>
62 : #include <editeng/escapementitem.hxx>
63 : #include <editeng/fhgtitem.hxx>
64 : #include <editeng/colritem.hxx>
65 : #include <editeng/hyphenzoneitem.hxx>
66 : #include <editeng/ulspitem.hxx>
67 : #include <editeng/boxitem.hxx>
68 : #include <editeng/contouritem.hxx>
69 : #include <editeng/shdditem.hxx>
70 : #include <editeng/emphasismarkitem.hxx>
71 : #include <editeng/twolinesitem.hxx>
72 : #include <editeng/charscaleitem.hxx>
73 : #include <editeng/charrotateitem.hxx>
74 : #include <editeng/charreliefitem.hxx>
75 : #include <editeng/paravertalignitem.hxx>
76 : #include <editeng/pgrditem.hxx>
77 : #include <editeng/frmdiritem.hxx>
78 : #include <editeng/blinkitem.hxx>
79 : #include <editeng/charhiddenitem.hxx>
80 : #include <editeng/editobj.hxx>
81 : #include <svx/xfillit0.hxx>
82 : #include <svx/xflgrit.hxx>
83 : #include <svx/fmglob.hxx>
84 : #include <svx/svdouno.hxx>
85 : #include <svl/grabbagitem.hxx>
86 : #include <sfx2/sfxbasemodel.hxx>
87 : #include <tools/datetimeutils.hxx>
88 : #include <svl/whiter.hxx>
89 :
90 : #include <docufld.hxx>
91 : #include <flddropdown.hxx>
92 : #include <fmtclds.hxx>
93 : #include <fmtinfmt.hxx>
94 : #include <fmtrowsplt.hxx>
95 : #include <fmtline.hxx>
96 : #include <ftninfo.hxx>
97 : #include <htmltbl.hxx>
98 : #include <lineinfo.hxx>
99 : #include <ndgrf.hxx>
100 : #include <ndole.hxx>
101 : #include <ndtxt.hxx>
102 : #include <pagedesc.hxx>
103 : #include <paratr.hxx>
104 : #include <charatr.hxx>
105 : #include <swmodule.hxx>
106 : #include <swtable.hxx>
107 : #include <txtftn.hxx>
108 : #include <txtinet.hxx>
109 : #include <fmtautofmt.hxx>
110 : #include <docsh.hxx>
111 : #include <docary.hxx>
112 :
113 : #include <osl/file.hxx>
114 : #include <vcl/embeddedfontshelper.hxx>
115 : #include <svtools/miscopt.hxx>
116 :
117 : #include <com/sun/star/i18n/ScriptType.hpp>
118 : #include <com/sun/star/chart2/XChartDocument.hpp>
119 : #include <com/sun/star/drawing/ShadingPattern.hpp>
120 : #include <com/sun/star/text/GraphicCrop.hpp>
121 :
122 : #include <algorithm>
123 :
124 : #if OSL_DEBUG_LEVEL > 1
125 : #include <stdio.h>
126 : #endif
127 :
128 : using ::editeng::SvxBorderLine;
129 :
130 : using namespace oox;
131 : using namespace docx;
132 : using namespace sax_fastparser;
133 : using namespace nsSwDocInfoSubType;
134 : using namespace nsFieldFlags;
135 : using namespace sw::util;
136 : using namespace ::com::sun::star;
137 : using namespace ::com::sun::star::drawing;
138 :
139 1 : class FFDataWriterHelper
140 : {
141 : ::sax_fastparser::FSHelperPtr m_pSerializer;
142 1 : void writeCommonStart( const OUString& rName )
143 : {
144 1 : m_pSerializer->startElementNS( XML_w, XML_ffData, FSEND );
145 : m_pSerializer->singleElementNS( XML_w, XML_name,
146 : FSNS( XML_w, XML_val ), OUStringToOString( rName, RTL_TEXTENCODING_UTF8 ).getStr(),
147 1 : FSEND );
148 1 : m_pSerializer->singleElementNS( XML_w, XML_enabled, FSEND );
149 : m_pSerializer->singleElementNS( XML_w, XML_calcOnExit,
150 : FSNS( XML_w, XML_val ),
151 1 : "0", FSEND );
152 1 : }
153 1 : void writeFinish()
154 : {
155 1 : m_pSerializer->endElementNS( XML_w, XML_ffData );
156 1 : }
157 : public:
158 1 : FFDataWriterHelper( const ::sax_fastparser::FSHelperPtr pSerializer ) : m_pSerializer( pSerializer ){}
159 1 : void WriteFormCheckbox( const OUString& rName, const OUString& rDefault, bool bChecked )
160 : {
161 1 : writeCommonStart( rName );
162 : // Checkbox specific bits
163 1 : m_pSerializer->startElementNS( XML_w, XML_checkBox, FSEND );
164 : // currently hardcoding autosize
165 : // #TODO check if this defaulted
166 1 : m_pSerializer->startElementNS( XML_w, XML_sizeAuto, FSEND );
167 1 : m_pSerializer->endElementNS( XML_w, XML_sizeAuto );
168 1 : if ( !rDefault.isEmpty() )
169 : {
170 : m_pSerializer->singleElementNS( XML_w, XML_default,
171 : FSNS( XML_w, XML_val ),
172 0 : OUStringToOString( rDefault, RTL_TEXTENCODING_UTF8 ).getStr(), FSEND );
173 : }
174 1 : if ( bChecked )
175 0 : m_pSerializer->singleElementNS( XML_w, XML_checked, FSEND );
176 1 : m_pSerializer->endElementNS( XML_w, XML_checkBox );
177 1 : writeFinish();
178 1 : }
179 0 : void WriteFormText( const OUString& rName, const OUString& rDefault )
180 : {
181 0 : writeCommonStart( rName );
182 0 : if ( !rDefault.isEmpty() )
183 : {
184 0 : m_pSerializer->startElementNS( XML_w, XML_textInput, FSEND );
185 : m_pSerializer->singleElementNS( XML_w, XML_default,
186 : FSNS( XML_w, XML_val ),
187 0 : OUStringToOString( rDefault, RTL_TEXTENCODING_UTF8 ).getStr(), FSEND );
188 0 : m_pSerializer->endElementNS( XML_w, XML_textInput );
189 : }
190 0 : writeFinish();
191 0 : }
192 : };
193 :
194 : class FieldMarkParamsHelper
195 : {
196 : const sw::mark::IFieldmark& mrFieldmark;
197 : public:
198 1 : FieldMarkParamsHelper( const sw::mark::IFieldmark& rFieldmark ) : mrFieldmark( rFieldmark ) {}
199 0 : OUString getName() { return mrFieldmark.GetName(); }
200 : template < typename T >
201 1 : bool extractParam( const OUString& rKey, T& rResult )
202 : {
203 1 : bool bResult = false;
204 1 : if ( mrFieldmark.GetParameters() )
205 : {
206 1 : sw::mark::IFieldmark::parameter_map_t::const_iterator it = mrFieldmark.GetParameters()->find( rKey );
207 1 : if ( it != mrFieldmark.GetParameters()->end() )
208 0 : bResult = ( it->second >>= rResult );
209 : }
210 1 : return bResult;
211 : }
212 : };
213 6489 : void DocxAttributeOutput::RTLAndCJKState( bool bIsRTL, sal_uInt16 /*nScript*/ )
214 : {
215 6489 : if (bIsRTL)
216 23 : m_pSerializer->singleElementNS( XML_w, XML_rtl, FSNS( XML_w, XML_val ), "true", FSEND );
217 6489 : }
218 :
219 5393 : void DocxAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo )
220 : {
221 5393 : if ( m_nColBreakStatus == COLBRK_POSTPONE )
222 2 : m_nColBreakStatus = COLBRK_WRITE;
223 :
224 : // Output table/table row/table cell starts if needed
225 5393 : if ( pTextNodeInfo.get() )
226 : {
227 1602 : sal_uInt32 nRow = pTextNodeInfo->getRow();
228 1602 : sal_uInt32 nCell = pTextNodeInfo->getCell();
229 :
230 : // New cell/row?
231 1602 : if ( m_tableReference->m_nTableDepth > 0 && !m_tableReference->m_bTableCellOpen )
232 : {
233 1295 : ww8::WW8TableNodeInfoInner::Pointer_t pDeepInner( pTextNodeInfo->getInnerForDepth( m_tableReference->m_nTableDepth ) );
234 1295 : if ( pDeepInner->getCell() == 0 )
235 421 : StartTableRow( pDeepInner );
236 :
237 1295 : StartTableCell( pDeepInner );
238 : }
239 :
240 1602 : if ( nRow == 0 && nCell == 0 )
241 : {
242 : // Do we have to start the table?
243 : // [If we are at the right depth already, it means that we
244 : // continue the table cell]
245 175 : sal_uInt32 nCurrentDepth = pTextNodeInfo->getDepth();
246 :
247 175 : if ( nCurrentDepth > m_tableReference->m_nTableDepth )
248 : {
249 : // Start all the tables that begin here
250 186 : for ( sal_uInt32 nDepth = m_tableReference->m_nTableDepth + 1; nDepth <= pTextNodeInfo->getDepth(); ++nDepth )
251 : {
252 99 : ww8::WW8TableNodeInfoInner::Pointer_t pInner( pTextNodeInfo->getInnerForDepth( nDepth ) );
253 :
254 99 : if (m_tableReference->m_pOldTablepInner && m_tableReference->m_pOldTablepInner->getTable() == pInner->getTable() && nCurrentDepth > 1 && nDepth != 1)
255 : {
256 5 : m_tableReference->m_pOldTablepInner = pInner;
257 5 : break;
258 : }
259 : else
260 : {
261 94 : StartTable( pInner );
262 94 : StartTableRow( pInner );
263 94 : StartTableCell( pInner );
264 94 : m_tableReference->m_pOldTablepInner = pInner;
265 : }
266 94 : }
267 :
268 92 : m_tableReference->m_nTableDepth = nCurrentDepth;
269 : }
270 : }
271 : }
272 :
273 : // this mark is used to be able to enclose the paragraph inside a sdr tag.
274 : // We will only know if we have to do that later.
275 5393 : m_pSerializer->mark();
276 :
277 5393 : m_pSerializer->startElementNS( XML_w, XML_p, FSEND );
278 :
279 : // postpone the output of the run (we get it before the paragraph
280 : // properties, but must write it after them)
281 5393 : m_pSerializer->mark();
282 :
283 : // no section break in this paragraph yet; can be set in SectionBreak()
284 5393 : m_pSectionInfo.reset();
285 :
286 5393 : m_bParagraphOpened = true;
287 5393 : m_bIsFirstParagraph = false;
288 5393 : }
289 :
290 5393 : void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner )
291 : {
292 : // write the paragraph properties + the run, already in the correct order
293 5393 : m_pSerializer->mergeTopMarks();
294 :
295 : // Write the anchored frame if any
296 : // Word can't handle nested text boxes, so write them on the same level.
297 5393 : ++m_nTextFrameLevel;
298 5393 : if( m_nTextFrameLevel == 1 )
299 : {
300 4751 : for (size_t nIndex = 0; nIndex < m_aFramesOfParagraph.size(); ++nIndex)
301 : {
302 115 : sw::Frame aFrame = m_aFramesOfParagraph[nIndex];
303 115 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
304 :
305 115 : m_pSerializer->startElementNS(XML_mc, XML_AlternateContent, FSEND);
306 : m_pSerializer->startElementNS(XML_mc, XML_Choice,
307 : XML_Requires, "wps",
308 115 : FSEND);
309 : /**
310 : This is to avoid AltenateContent within another AlternateContent.
311 : So when Choice is Open, only write the DML Drawing instead of both DML
312 : and VML Drawing in another AlternateContent.
313 : **/
314 115 : SetAlternateContentChoiceOpen( true );
315 : /** FDO#71834 :
316 : We should probably be renaming the function
317 : switchHeaderFooter to something like SaveRetrieveTableReference.
318 : Save the table reference attributes before calling WriteDMLTextFrame,
319 : otherwise the StartParagraph function will use the previous existing
320 : table reference attributes since the variable is being shared.
321 : */
322 115 : switchHeaderFooter(true,1);
323 : /** Save the table info's before writing the shape
324 : as there might be a new table that might get
325 : spawned from within the VML & DML block and alter
326 : the contents.
327 : */
328 230 : ww8::WW8TableInfo::Pointer_t pOldTableInfo = m_rExport.mpTableInfo;
329 : //Reset the table infos after saving.
330 115 : m_rExport.mpTableInfo = ww8::WW8TableInfo::Pointer_t(new ww8::WW8TableInfo());
331 :
332 115 : m_rExport.SdrExporter().writeDMLTextFrame(&aFrame, m_anchorId++);
333 115 : m_pSerializer->endElementNS(XML_mc, XML_Choice);
334 115 : SetAlternateContentChoiceOpen( false );
335 :
336 : // Reset table infos, otherwise the depth of the cells will be incorrect,
337 : // in case the text frame had table(s) and we try to export the
338 : // same table second time.
339 115 : m_rExport.mpTableInfo = ww8::WW8TableInfo::Pointer_t(new ww8::WW8TableInfo());
340 : //reset the tableReference.
341 115 : switchHeaderFooter(false,0);
342 :
343 115 : m_pSerializer->startElementNS(XML_mc, XML_Fallback, FSEND);
344 115 : m_rExport.SdrExporter().writeVMLTextFrame(&aFrame);
345 : /* FDO#71834 :Restore the data here after having written the Shape
346 : for further processing.
347 : */
348 115 : switchHeaderFooter(false,-1);
349 115 : m_rExport.mpTableInfo = pOldTableInfo;
350 :
351 115 : m_pSerializer->endElementNS(XML_mc, XML_Fallback);
352 115 : m_pSerializer->endElementNS(XML_mc, XML_AlternateContent);
353 :
354 115 : m_pSerializer->endElementNS( XML_w, XML_r );
355 115 : }
356 :
357 4636 : m_aFramesOfParagraph.clear();
358 : }
359 :
360 5393 : --m_nTextFrameLevel;
361 :
362 : /* If m_nHyperLinkCount > 0 that means hyperlink tag is not yet colsed.
363 : * This is due to nested hyperlink tags. So close it before end of paragraph.
364 : */
365 5393 : if(m_nHyperLinkCount > 0)
366 : {
367 2 : for(sal_Int32 nHyperLinkToClose = 0; nHyperLinkToClose < m_nHyperLinkCount; ++nHyperLinkToClose)
368 1 : m_pSerializer->endElementNS( XML_w, XML_hyperlink );
369 1 : m_nHyperLinkCount = 0;
370 : }
371 :
372 5393 : m_pSerializer->endElementNS( XML_w, XML_p );
373 :
374 5393 : WriteSdtBlock( m_nParagraphSdtPrToken, m_pParagraphSdtPrTokenChildren, m_pParagraphSdtPrDataBindingAttrs );
375 5393 : m_pSerializer->mergeTopMarks();
376 :
377 : // Check for end of cell, rows, tables here
378 5393 : FinishTableRowCell( pTextNodeInfoInner );
379 :
380 5393 : m_bParagraphOpened = false;
381 :
382 5393 : }
383 :
384 11887 : void DocxAttributeOutput::WriteSdtBlock( sal_Int32& nSdtPrToken, ::sax_fastparser::FastAttributeList* &pSdtPrTokenChildren, ::sax_fastparser::FastAttributeList* &pSdtPrDataBindingAttrs )
385 : {
386 11887 : if( nSdtPrToken > 0 || pSdtPrDataBindingAttrs )
387 : {
388 : // sdt start mark
389 55 : m_pSerializer->mark();
390 :
391 55 : m_pSerializer->startElementNS( XML_w, XML_sdt, FSEND );
392 :
393 : // output sdt properties
394 55 : m_pSerializer->startElementNS( XML_w, XML_sdtPr, FSEND );
395 :
396 55 : if( nSdtPrToken > 0 && pSdtPrTokenChildren )
397 : {
398 30 : m_pSerializer->startElement( nSdtPrToken, FSEND );
399 :
400 30 : uno::Sequence<xml::FastAttribute> aChildren = pSdtPrTokenChildren->getFastAttributes();
401 101 : for( sal_Int32 i=0; i < aChildren.getLength(); ++i )
402 71 : m_pSerializer->singleElement( aChildren[i].Token,
403 : FSNS(XML_w, XML_val),
404 71 : rtl::OUStringToOString( aChildren[i].Value, RTL_TEXTENCODING_UTF8 ).getStr(),
405 142 : FSEND );
406 :
407 30 : m_pSerializer->endElement( nSdtPrToken );
408 : }
409 25 : else if( nSdtPrToken == FSNS( XML_w, XML_id ) )
410 : //Word won't open a document with an empty id tag, we fill it with a random number
411 : m_pSerializer->singleElement( nSdtPrToken,
412 : FSNS(XML_w, XML_val), OString::number( rand() ),
413 8 : FSEND );
414 17 : else if( nSdtPrToken > 0 )
415 17 : m_pSerializer->singleElement( nSdtPrToken, FSEND );
416 :
417 55 : if( pSdtPrDataBindingAttrs )
418 : {
419 11 : XFastAttributeListRef xAttrList( pSdtPrDataBindingAttrs );
420 11 : m_pSerializer->singleElementNS( XML_w, XML_dataBinding, xAttrList );
421 : }
422 :
423 55 : m_pSerializer->endElementNS( XML_w, XML_sdtPr );
424 :
425 : // sdt contents start tag
426 55 : m_pSerializer->startElementNS( XML_w, XML_sdtContent, FSEND );
427 :
428 : // prepend the tags since the sdt start mark before the paragraph
429 55 : m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND );
430 :
431 : // write the ending tags after the paragraph
432 55 : m_pSerializer->endElementNS( XML_w, XML_sdtContent );
433 55 : m_pSerializer->endElementNS( XML_w, XML_sdt );
434 :
435 : // clear sdt status
436 55 : nSdtPrToken = 0;
437 55 : delete pSdtPrTokenChildren; pSdtPrTokenChildren = NULL;
438 55 : if( pSdtPrDataBindingAttrs )
439 : {
440 : // do not delete yet; it's in xAttrList inside the parser
441 11 : pSdtPrDataBindingAttrs = NULL;
442 : }
443 : }
444 11887 : }
445 :
446 8379 : void DocxAttributeOutput::FinishTableRowCell( ww8::WW8TableNodeInfoInner::Pointer_t pInner, bool bForceEmptyParagraph )
447 : {
448 8379 : if ( pInner.get() )
449 : {
450 : // Where are we in the table
451 4588 : sal_uInt32 nRow = pInner->getRow( );
452 :
453 4588 : const SwTable *pTable = pInner->getTable( );
454 4588 : const SwTableLines& rLines = pTable->GetTabLines( );
455 4588 : sal_uInt16 nLinesCount = rLines.size( );
456 : // HACK
457 : // msoffice seems to have an internal limitation of 63 columns for tables
458 : // and refuses to load .docx with more, even though the spec seems to allow that;
459 : // so simply if there are more columns, don't close the last one msoffice will handle
460 : // and merge the contents of the remaining ones into it (since we don't close the cell
461 : // here, following ones will not be opened)
462 4588 : bool limitWorkaround = ( pInner->getCell() >= 62 && !pInner->isEndOfLine());
463 :
464 4588 : if ( pInner->isEndOfCell() && !limitWorkaround )
465 : {
466 1389 : if ( bForceEmptyParagraph )
467 0 : m_pSerializer->singleElementNS( XML_w, XML_p, FSEND );
468 :
469 1389 : EndTableCell();
470 : }
471 :
472 : // This is a line end
473 4588 : if ( pInner->isEndOfLine() )
474 515 : EndTableRow();
475 :
476 : // This is the end of the table
477 4588 : if ( pInner->isEndOfLine( ) && ( nRow + 1 ) == nLinesCount )
478 94 : EndTable();
479 : }
480 8379 : }
481 :
482 0 : void DocxAttributeOutput::EmptyParagraph()
483 : {
484 0 : m_pSerializer->singleElementNS( XML_w, XML_p, FSEND );
485 0 : }
486 :
487 5189 : void DocxAttributeOutput::SectionBreaks(const SwTxtNode& rNode)
488 : {
489 : // output page/section breaks
490 : // Writer can have them at the beginning of a paragraph, or at the end, but
491 : // in docx, we have to output them in the paragraph properties of the last
492 : // paragraph in a section. To get it right, we have to switch to the next
493 : // paragraph, and detect the section breaks there.
494 5189 : SwNodeIndex aNextIndex( rNode, 1 );
495 5189 : if ( aNextIndex.GetNode().IsTxtNode() )
496 : {
497 3084 : const SwTxtNode* pTxtNode = static_cast< SwTxtNode* >( &aNextIndex.GetNode() );
498 3084 : m_rExport.OutputSectionBreaks( pTxtNode->GetpSwAttrSet(), *pTxtNode, m_tableReference->m_bTableCellOpen, pTxtNode->GetTxt().isEmpty() );
499 : }
500 2105 : else if ( aNextIndex.GetNode().IsTableNode() )
501 : {
502 26 : const SwTableNode* pTableNode = static_cast< SwTableNode* >( &aNextIndex.GetNode() );
503 26 : const SwFrmFmt *pFmt = pTableNode->GetTable().GetFrmFmt();
504 26 : m_rExport.OutputSectionBreaks( &(pFmt->GetAttrSet()), *pTableNode );
505 5189 : }
506 5189 : }
507 :
508 5388 : void DocxAttributeOutput::StartParagraphProperties()
509 : {
510 5388 : m_pSerializer->mark( );
511 :
512 5388 : m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND );
513 :
514 : // and output the section break now (if it appeared)
515 5388 : if ( m_pSectionInfo && (!m_setFootnote))
516 : {
517 13 : m_rExport.SectionProperties( *m_pSectionInfo );
518 13 : m_pSectionInfo.reset();
519 : }
520 :
521 5388 : InitCollectedParagraphProperties();
522 5388 : }
523 :
524 9028 : void DocxAttributeOutput::InitCollectedParagraphProperties()
525 : {
526 9028 : m_pParagraphSpacingAttrList = NULL;
527 :
528 : // Write the elements in the spec order
529 : static const sal_Int32 aOrder[] =
530 : {
531 : FSNS( XML_w, XML_pStyle ),
532 : FSNS( XML_w, XML_keepNext ),
533 : FSNS( XML_w, XML_keepLines ),
534 : FSNS( XML_w, XML_pageBreakBefore ),
535 : FSNS( XML_w, XML_framePr ),
536 : FSNS( XML_w, XML_widowControl ),
537 : FSNS( XML_w, XML_numPr ),
538 : FSNS( XML_w, XML_suppressLineNumbers ),
539 : FSNS( XML_w, XML_pBdr ),
540 : FSNS( XML_w, XML_shd ),
541 : FSNS( XML_w, XML_tabs ),
542 : FSNS( XML_w, XML_suppressAutoHyphens ),
543 : FSNS( XML_w, XML_kinsoku ),
544 : FSNS( XML_w, XML_wordWrap ),
545 : FSNS( XML_w, XML_overflowPunct ),
546 : FSNS( XML_w, XML_topLinePunct ),
547 : FSNS( XML_w, XML_autoSpaceDE ),
548 : FSNS( XML_w, XML_autoSpaceDN ),
549 : FSNS( XML_w, XML_bidi ),
550 : FSNS( XML_w, XML_adjustRightInd ),
551 : FSNS( XML_w, XML_snapToGrid ),
552 : FSNS( XML_w, XML_spacing ),
553 : FSNS( XML_w, XML_ind ),
554 : FSNS( XML_w, XML_contextualSpacing ),
555 : FSNS( XML_w, XML_mirrorIndents ),
556 : FSNS( XML_w, XML_suppressOverlap ),
557 : FSNS( XML_w, XML_jc ),
558 : FSNS( XML_w, XML_textDirection ),
559 : FSNS( XML_w, XML_textAlignment ),
560 : FSNS( XML_w, XML_textboxTightWrap ),
561 : FSNS( XML_w, XML_outlineLvl ),
562 : FSNS( XML_w, XML_divId ),
563 : FSNS( XML_w, XML_cnfStyle ),
564 : FSNS( XML_w, XML_rPr ),
565 : FSNS( XML_w, XML_sectPr ),
566 : FSNS( XML_w, XML_pPrChange )
567 : };
568 :
569 : // postpone the output so that we can later [in EndParagraphProperties()]
570 : // prepend the properties before the run
571 9028 : sal_Int32 len = sizeof ( aOrder ) / sizeof( sal_Int32 );
572 9028 : uno::Sequence< sal_Int32 > aSeqOrder( len );
573 334036 : for ( sal_Int32 i = 0; i < len; i++ )
574 325008 : aSeqOrder[i] = aOrder[i];
575 :
576 9028 : m_pSerializer->mark( aSeqOrder );
577 9028 : }
578 :
579 9028 : void DocxAttributeOutput::WriteCollectedParagraphProperties()
580 : {
581 9028 : if ( m_rExport.SdrExporter().getFlyAttrList() )
582 : {
583 0 : XFastAttributeListRef xAttrList( m_rExport.SdrExporter().getFlyAttrList() );
584 0 : m_rExport.SdrExporter().setFlyAttrList(NULL);
585 :
586 0 : m_pSerializer->singleElementNS( XML_w, XML_framePr, xAttrList );
587 : }
588 :
589 9028 : if ( m_pParagraphSpacingAttrList )
590 : {
591 4070 : XFastAttributeListRef xAttrList( m_pParagraphSpacingAttrList );
592 4070 : m_pParagraphSpacingAttrList = NULL;
593 :
594 4070 : m_pSerializer->singleElementNS( XML_w, XML_spacing, xAttrList );
595 : }
596 :
597 9028 : if ( m_pBackgroundAttrList )
598 : {
599 24 : XFastAttributeListRef xAttrList( m_pBackgroundAttrList );
600 24 : m_pBackgroundAttrList = NULL;
601 :
602 24 : m_pSerializer->singleElementNS( XML_w, XML_shd, xAttrList );
603 : }
604 9028 : }
605 :
606 5388 : void DocxAttributeOutput::EndParagraphProperties( const SfxItemSet* pParagraphMarkerProperties, const SwRedlineData* pRedlineData, const SwRedlineData* pRedlineParagraphMarkerDeleted, const SwRedlineData* pRedlineParagraphMarkerInserted)
607 : {
608 : // Call the 'Redline' function. This will add redline (change-tracking) information that regards to paragraph properties.
609 : // This includes changes like 'Bold', 'Underline', 'Strikethrough' etc.
610 5388 : Redline( pRedlineData );
611 :
612 5388 : WriteCollectedParagraphProperties();
613 :
614 : // Merge the marks for the ordered elements
615 5388 : m_pSerializer->mergeTopMarks( );
616 :
617 : // Write 'Paragraph Mark' properties
618 5388 : if ( pRedlineParagraphMarkerDeleted || pRedlineParagraphMarkerInserted || pParagraphMarkerProperties)
619 : {
620 3751 : m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
621 :
622 3751 : if(pParagraphMarkerProperties)
623 : {
624 : // The 'm_pFontsAttrList', 'm_pEastAsianLayoutAttrList', 'm_pCharLangAttrList' are used to hold information
625 : // that should be collected by different properties in the core, and are all flushed together
626 : // to the DOCX when the function 'WriteCollectedRunProperties' gets called.
627 : // So we need to store the current status of these lists, so that we can revert back to them when
628 : // we are done exporting the redline attributes.
629 3751 : ::sax_fastparser::FastAttributeList *pFontsAttrList_Original = m_pFontsAttrList;
630 3751 : ::sax_fastparser::FastAttributeList *pEastAsianLayoutAttrList_Original = m_pEastAsianLayoutAttrList;
631 3751 : ::sax_fastparser::FastAttributeList *pCharLangAttrList_Original = m_pCharLangAttrList;
632 3751 : m_pFontsAttrList = NULL;
633 3751 : m_pEastAsianLayoutAttrList = NULL;
634 3751 : m_pCharLangAttrList = NULL;
635 :
636 3751 : SfxWhichIter aIter( *pParagraphMarkerProperties );
637 3751 : sal_uInt16 nWhichId = aIter.FirstWhich();
638 3751 : const SfxPoolItem* pItem = 0;
639 287880 : while( nWhichId )
640 : {
641 280378 : if( SFX_ITEM_SET == pParagraphMarkerProperties->GetItemState( nWhichId, true, &pItem ))
642 : {
643 : SAL_INFO( "sw.ww8", "nWhichId " << nWhichId);
644 30652 : if (isCHRATR( nWhichId ))
645 16866 : OutputItem( *pItem );
646 : }
647 280378 : nWhichId = aIter.NextWhich();
648 : }
649 :
650 : // Write the collected run properties that are stored in 'm_pFontsAttrList', 'm_pEastAsianLayoutAttrList', 'm_pCharLangAttrList'
651 3751 : WriteCollectedRunProperties();
652 :
653 : // Revert back the original values that were stored in 'm_pFontsAttrList', 'm_pEastAsianLayoutAttrList', 'm_pCharLangAttrList'
654 3751 : m_pFontsAttrList = pFontsAttrList_Original;
655 3751 : m_pEastAsianLayoutAttrList = pEastAsianLayoutAttrList_Original;
656 3751 : m_pCharLangAttrList = pCharLangAttrList_Original;
657 : }
658 3751 : if ( pRedlineParagraphMarkerDeleted )
659 : {
660 1 : StartRedline( pRedlineParagraphMarkerDeleted );
661 1 : EndRedline( pRedlineParagraphMarkerDeleted );
662 : }
663 3751 : if ( pRedlineParagraphMarkerInserted )
664 : {
665 1 : StartRedline( pRedlineParagraphMarkerInserted );
666 1 : EndRedline( pRedlineParagraphMarkerInserted );
667 : }
668 :
669 3751 : m_pSerializer->endElementNS( XML_w, XML_rPr );
670 : }
671 :
672 5388 : m_pSerializer->endElementNS( XML_w, XML_pPr );
673 :
674 5388 : if ( m_nColBreakStatus == COLBRK_WRITE )
675 : {
676 2 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
677 : m_pSerializer->singleElementNS( XML_w, XML_br,
678 2 : FSNS( XML_w, XML_type ), "column", FSEND );
679 2 : m_pSerializer->endElementNS( XML_w, XML_r );
680 :
681 2 : m_nColBreakStatus = COLBRK_NONE;
682 : }
683 :
684 : // merge the properties _before_ the run (strictly speaking, just
685 : // after the start of the paragraph)
686 5388 : m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND );
687 5388 : }
688 :
689 6494 : void DocxAttributeOutput::StartRun( const SwRedlineData* pRedlineData, bool /*bSingleEmptyRun*/ )
690 : {
691 : // Don't start redline data here, possibly there is a hyperlink later, and
692 : // that has to be started first.
693 6494 : m_pRedlineData = pRedlineData;
694 :
695 : // this mark is used to be able to enclose the run inside a sdr tag.
696 6494 : m_pSerializer->mark();
697 :
698 : // postpone the output of the start of a run (there are elements that need
699 : // to be written before the start of the run, but we learn which they are
700 : // _inside_ of the run)
701 6494 : m_pSerializer->mark(); // let's call it "postponed run start"
702 :
703 : // postpone the output of the text (we get it before the run properties,
704 : // but must write it after them)
705 6494 : m_pSerializer->mark(); // let's call it "postponed text"
706 6494 : }
707 :
708 6494 : void DocxAttributeOutput::EndRun()
709 : {
710 : // Write field starts
711 13267 : for ( std::vector<FieldInfos>::iterator pIt = m_Fields.begin(); pIt != m_Fields.end(); )
712 : {
713 : // Add the fields starts for all but hyperlinks and TOCs
714 279 : if ( pIt->bOpen && pIt->pField )
715 : {
716 80 : StartField_Impl( *pIt );
717 :
718 : // Remove the field from the stack if only the start has to be written
719 : // Unknown fields sould be removed too
720 80 : if ( !pIt->bClose || ( pIt->eType == ww::eUNKNOWN ) )
721 : {
722 1 : if (pIt->pField)
723 1 : delete pIt->pField;
724 1 : pIt = m_Fields.erase( pIt );
725 1 : continue;
726 : }
727 : }
728 278 : ++pIt;
729 : }
730 :
731 : // write the run properties + the text, already in the correct order
732 6494 : m_pSerializer->mergeTopMarks(); // merges with "postponed text", see above
733 :
734 : // level down, to be able to prepend the actual run start attribute (just
735 : // before "postponed run start")
736 6494 : m_pSerializer->mark(); // let's call it "actual run start"
737 :
738 6494 : if ( m_closeHyperlinkInPreviousRun )
739 : {
740 169 : if ( m_startedHyperlink )
741 : {
742 160 : for ( int i = 0; i < m_nFieldsInHyperlink; i++ )
743 : {
744 : // If fields begin before hyperlink then
745 : // it should end before hyperlink close
746 1 : EndField_Impl( m_Fields.back( ) );
747 1 : if (m_Fields.back().pField)
748 0 : delete m_Fields.back().pField;
749 : }
750 159 : m_pSerializer->endElementNS( XML_w, XML_hyperlink );
751 159 : m_startedHyperlink = false;
752 159 : m_nHyperLinkCount--;
753 : }
754 169 : m_closeHyperlinkInPreviousRun = false;
755 : }
756 :
757 : // Write the hyperlink and toc fields starts
758 13266 : for ( std::vector<FieldInfos>::iterator pIt = m_Fields.begin(); pIt != m_Fields.end(); )
759 : {
760 : // Add the fields starts for hyperlinks, TOCs and index marks
761 278 : if ( pIt->bOpen && !pIt->pField )
762 : {
763 106 : StartField_Impl( *pIt, true );
764 :
765 : // Remove the field if no end needs to be written
766 106 : if ( !pIt->bClose ) {
767 49 : if (pIt->pField)
768 0 : delete pIt->pField;
769 49 : pIt = m_Fields.erase( pIt );
770 49 : continue;
771 : }
772 : }
773 229 : ++pIt;
774 : }
775 :
776 : // Start the hyperlink after the fields separators or we would generate invalid file
777 6494 : if ( m_pHyperlinkAttrList )
778 : {
779 287 : XFastAttributeListRef xAttrList ( m_pHyperlinkAttrList );
780 :
781 287 : m_pSerializer->startElementNS( XML_w, XML_hyperlink, xAttrList );
782 287 : m_pHyperlinkAttrList = NULL;
783 287 : m_startedHyperlink = true;
784 287 : m_nHyperLinkCount++;
785 287 : m_nFieldsInHyperlink = 0;
786 : }
787 :
788 : // if there is some redlining in the document, output it
789 6494 : StartRedline( m_pRedlineData );
790 :
791 6494 : DoWriteBookmarks( );
792 6494 : DoWriteAnnotationMarks( );
793 :
794 6494 : if( m_closeHyperlinkInThisRun && m_startedHyperlink && m_hyperLinkAnchor != "" && m_hyperLinkAnchor.startsWith("_Toc"))
795 : {
796 86 : OUString sToken;
797 86 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
798 86 : m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
799 86 : m_pSerializer->singleElementNS( XML_w, XML_webHidden, FSEND );
800 86 : m_pSerializer->endElementNS( XML_w, XML_rPr );
801 : m_pSerializer->startElementNS( XML_w, XML_fldChar,
802 : FSNS( XML_w, XML_fldCharType ), "begin",
803 86 : FSEND );
804 86 : m_pSerializer->endElementNS( XML_w, XML_fldChar );
805 86 : m_pSerializer->endElementNS( XML_w, XML_r );
806 :
807 :
808 86 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
809 86 : m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
810 86 : m_pSerializer->singleElementNS( XML_w, XML_webHidden, FSEND );
811 86 : m_pSerializer->endElementNS( XML_w, XML_rPr );
812 86 : sToken = "PAGEREF " + m_hyperLinkAnchor + " \\h"; // '\h' Creates a hyperlink to the bookmarked paragraph.
813 86 : DoWriteCmd( sToken );
814 86 : m_pSerializer->endElementNS( XML_w, XML_r );
815 :
816 : // Write the Field separator
817 86 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
818 86 : m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
819 86 : m_pSerializer->singleElementNS( XML_w, XML_webHidden, FSEND );
820 86 : m_pSerializer->endElementNS( XML_w, XML_rPr );
821 : m_pSerializer->singleElementNS( XML_w, XML_fldChar,
822 : FSNS( XML_w, XML_fldCharType ), "separate",
823 86 : FSEND );
824 86 : m_pSerializer->endElementNS( XML_w, XML_r );
825 : }
826 :
827 6494 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
828 6494 : if(GetExport().bTabInTOC && m_pHyperlinkAttrList)
829 : {
830 0 : RunText(OUString("\t")) ;
831 : }
832 6494 : m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND ); // merges with "postponed run start", see above
833 :
834 : // write the run start + the run content
835 6494 : m_pSerializer->mergeTopMarks(); // merges the "actual run start"
836 : // append the actual run end
837 6494 : m_pSerializer->endElementNS( XML_w, XML_r );
838 :
839 : // enclose in a sdt block, if necessary
840 6494 : WriteSdtBlock( m_nRunSdtPrToken, m_pRunSdtPrTokenChildren, m_pRunSdtPrDataBindingAttrs );
841 6494 : m_pSerializer->mergeTopMarks();
842 :
843 6494 : WritePostponedMath();
844 :
845 6496 : for (std::vector<const SdrObject*>::iterator it = m_aPostponedFormControls.begin(); it != m_aPostponedFormControls.end(); ++it)
846 2 : WritePostponedFormControl(*it);
847 6494 : m_aPostponedFormControls.clear();
848 :
849 6494 : WritePendingPlaceholder();
850 :
851 : // if there is some redlining in the document, output it
852 6494 : EndRedline( m_pRedlineData );
853 :
854 6494 : m_pRedlineData = NULL;
855 :
856 6494 : if ( m_closeHyperlinkInThisRun )
857 : {
858 299 : if ( m_startedHyperlink )
859 : {
860 127 : if( m_endPageRef )
861 : {
862 : // Hyperlink is started and fldchar "end" needs to be written for PAGEREF
863 86 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
864 86 : m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
865 86 : m_pSerializer->singleElementNS( XML_w, XML_webHidden, FSEND );
866 86 : m_pSerializer->endElementNS( XML_w, XML_rPr );
867 : m_pSerializer->singleElementNS( XML_w, XML_fldChar,
868 : FSNS( XML_w, XML_fldCharType ), "end",
869 86 : FSEND );
870 86 : m_pSerializer->endElementNS( XML_w, XML_r );
871 86 : m_endPageRef = false;
872 86 : m_hyperLinkAnchor = "";
873 : }
874 :
875 127 : m_pSerializer->endElementNS( XML_w, XML_hyperlink );
876 127 : m_startedHyperlink = false;
877 127 : m_nHyperLinkCount--;
878 : }
879 299 : m_closeHyperlinkInThisRun = false;
880 : }
881 :
882 6494 : if(!m_startedHyperlink)
883 12694 : while ( m_Fields.begin() != m_Fields.end() )
884 : {
885 210 : EndField_Impl( m_Fields.front( ) );
886 210 : if (m_Fields.front().pField)
887 79 : delete m_Fields.front().pField;
888 210 : m_Fields.erase( m_Fields.begin( ) );
889 : }
890 6494 : }
891 :
892 6494 : void DocxAttributeOutput::DoWriteBookmarks()
893 : {
894 : // Write the start bookmarks
895 7275 : for ( std::vector< OString >::const_iterator it = m_rBookmarksStart.begin(), end = m_rBookmarksStart.end();
896 : it != end; ++it )
897 : {
898 781 : const OString& rName = *it;
899 :
900 : // Output the bookmark
901 781 : sal_uInt16 nId = m_nNextBookmarkId++;
902 781 : m_rOpenedBookmarksIds[rName] = nId;
903 : m_pSerializer->singleElementNS( XML_w, XML_bookmarkStart,
904 : FSNS( XML_w, XML_id ), OString::number( nId ).getStr( ),
905 : FSNS( XML_w, XML_name ), rName.getStr(),
906 781 : FSEND );
907 781 : m_sLastOpenedBookmark = rName;
908 : }
909 6494 : m_rBookmarksStart.clear();
910 :
911 : // export the end bookmarks
912 7259 : for ( std::vector< OString >::const_iterator it = m_rBookmarksEnd.begin(), end = m_rBookmarksEnd.end();
913 : it != end; ++it )
914 : {
915 765 : const OString& rName = *it;
916 :
917 : // Get the id of the bookmark
918 765 : std::map< OString, sal_uInt16 >::iterator pPos = m_rOpenedBookmarksIds.find( rName );
919 765 : if ( pPos != m_rOpenedBookmarksIds.end( ) )
920 : {
921 613 : sal_uInt16 nId = ( *pPos ).second;
922 : m_pSerializer->singleElementNS( XML_w, XML_bookmarkEnd,
923 : FSNS( XML_w, XML_id ), OString::number( nId ).getStr( ),
924 613 : FSEND );
925 613 : m_rOpenedBookmarksIds.erase( rName );
926 : }
927 : }
928 6494 : m_rBookmarksEnd.clear();
929 6494 : }
930 :
931 6494 : void DocxAttributeOutput::DoWriteAnnotationMarks()
932 : {
933 : // Write the start annotation marks
934 6500 : for ( std::vector< OString >::const_iterator it = m_rAnnotationMarksStart.begin(), end = m_rAnnotationMarksStart.end();
935 : it != end; ++it )
936 : {
937 6 : const OString& rName = *it;
938 :
939 : // Output the annotation mark
940 : /* Ensure that the existing Annotation Marks are not overwritten
941 : as it causes discrepancy when DocxAttributeOutput::PostitField
942 : refers to this map & while mapping comment id's in document.xml &
943 : comment.xml.
944 : */
945 6 : if ( m_rOpenedAnnotationMarksIds.end() == m_rOpenedAnnotationMarksIds.find( rName ) )
946 : {
947 4 : sal_uInt16 nId = m_nNextAnnotationMarkId++;
948 4 : m_rOpenedAnnotationMarksIds[rName] = nId;
949 : m_pSerializer->singleElementNS( XML_w, XML_commentRangeStart,
950 : FSNS( XML_w, XML_id ), OString::number( nId ).getStr( ),
951 4 : FSEND );
952 4 : m_sLastOpenedAnnotationMark = rName;
953 : }
954 : }
955 6494 : m_rAnnotationMarksStart.clear();
956 :
957 : // export the end annotation marks
958 6498 : for ( std::vector< OString >::const_iterator it = m_rAnnotationMarksEnd.begin(), end = m_rAnnotationMarksEnd.end();
959 : it != end; ++it )
960 : {
961 4 : const OString& rName = *it;
962 :
963 : // Get the id of the annotation mark
964 4 : std::map< OString, sal_uInt16 >::iterator pPos = m_rOpenedAnnotationMarksIds.find( rName );
965 4 : if ( pPos != m_rOpenedAnnotationMarksIds.end( ) )
966 : {
967 4 : sal_uInt16 nId = ( *pPos ).second;
968 : m_pSerializer->singleElementNS( XML_w, XML_commentRangeEnd,
969 : FSNS( XML_w, XML_id ), OString::number( nId ).getStr( ),
970 4 : FSEND );
971 4 : m_rOpenedAnnotationMarksIds.erase( rName );
972 :
973 4 : m_pSerializer->startElementNS(XML_w, XML_r, FSEND);
974 : m_pSerializer->singleElementNS( XML_w, XML_commentReference, FSNS( XML_w, XML_id ),
975 : OString::number( nId ).getStr(),
976 4 : FSEND );
977 4 : m_pSerializer->endElementNS(XML_w, XML_r);
978 : }
979 : }
980 6494 : m_rAnnotationMarksEnd.clear();
981 6494 : }
982 :
983 1 : void DocxAttributeOutput::WriteFFData( const FieldInfos& rInfos )
984 : {
985 1 : const ::sw::mark::IFieldmark& rFieldmark = *rInfos.pFieldmark;
986 1 : if ( rInfos.eType == ww::eFORMDROPDOWN )
987 : {
988 0 : uno::Sequence< OUString> vListEntries;
989 0 : OUString sName, sHelp, sToolTip, sSelected;
990 :
991 0 : FieldMarkParamsHelper params( rFieldmark );
992 0 : params.extractParam( ODF_FORMDROPDOWN_LISTENTRY, vListEntries );
993 0 : sName = params.getName();
994 0 : sal_Int32 nSelectedIndex = 0;
995 :
996 0 : if ( params.extractParam( ODF_FORMDROPDOWN_RESULT, nSelectedIndex ) )
997 : {
998 0 : if (nSelectedIndex < vListEntries.getLength() )
999 0 : sSelected = vListEntries[ nSelectedIndex ];
1000 : }
1001 :
1002 0 : GetExport().DoComboBox( sName, sHelp, sToolTip, sSelected, vListEntries );
1003 : }
1004 1 : else if ( rInfos.eType == ww::eFORMCHECKBOX )
1005 : {
1006 1 : OUString sName;
1007 1 : bool bChecked = false;
1008 :
1009 1 : FieldMarkParamsHelper params( rFieldmark );
1010 1 : params.extractParam( ODF_FORMCHECKBOX_NAME, sName );
1011 :
1012 1 : const sw::mark::ICheckboxFieldmark* pCheckboxFm = dynamic_cast<const sw::mark::ICheckboxFieldmark*>(&rFieldmark);
1013 1 : if ( pCheckboxFm && pCheckboxFm->IsChecked() )
1014 0 : bChecked = true;
1015 :
1016 2 : FFDataWriterHelper ffdataOut( m_pSerializer );
1017 2 : ffdataOut.WriteFormCheckbox( sName, OUString(), bChecked );
1018 : }
1019 0 : else if ( rInfos.eType == ww::eFORMTEXT )
1020 : {
1021 0 : FieldMarkParamsHelper params( rFieldmark );
1022 0 : FFDataWriterHelper ffdataOut( m_pSerializer );
1023 0 : ffdataOut.WriteFormText( params.getName(), OUString() );
1024 : }
1025 1 : }
1026 :
1027 186 : void DocxAttributeOutput::StartField_Impl( FieldInfos& rInfos, bool bWriteRun )
1028 : {
1029 186 : if ( m_startedHyperlink )
1030 1 : ++m_nFieldsInHyperlink;
1031 186 : if ( rInfos.pField && rInfos.eType == ww::eUNKNOWN )
1032 : {
1033 : // Expand unsupported fields
1034 1 : RunText( rInfos.pField->GetFieldName() );
1035 : }
1036 185 : else if ( rInfos.eType != ww::eNONE ) // HYPERLINK fields are just commands
1037 : {
1038 185 : if ( bWriteRun )
1039 106 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
1040 :
1041 185 : if ( rInfos.eType == ww::eFORMDROPDOWN )
1042 : {
1043 : m_pSerializer->startElementNS( XML_w, XML_fldChar,
1044 : FSNS( XML_w, XML_fldCharType ), "begin",
1045 0 : FSEND );
1046 0 : if ( rInfos.pFieldmark && !rInfos.pField )
1047 0 : WriteFFData( rInfos );
1048 0 : if ( rInfos.pField )
1049 : {
1050 0 : const SwDropDownField& rFld2 = *(SwDropDownField*)rInfos.pField;
1051 : uno::Sequence<OUString> aItems =
1052 0 : rFld2.GetItemSequence();
1053 0 : GetExport().DoComboBox(rFld2.GetName(),
1054 : rFld2.GetHelp(),
1055 : rFld2.GetToolTip(),
1056 0 : rFld2.GetSelectedItem(), aItems);
1057 : }
1058 0 : m_pSerializer->endElementNS( XML_w, XML_fldChar );
1059 :
1060 0 : if ( bWriteRun )
1061 0 : m_pSerializer->endElementNS( XML_w, XML_r );
1062 0 : if ( !rInfos.pField )
1063 0 : CmdField_Impl( rInfos );
1064 :
1065 : }
1066 : else
1067 : {
1068 : // Write the field start
1069 : m_pSerializer->startElementNS( XML_w, XML_fldChar,
1070 : FSNS( XML_w, XML_fldCharType ), "begin",
1071 185 : FSEND );
1072 :
1073 185 : if ( rInfos.pFieldmark )
1074 1 : WriteFFData( rInfos );
1075 :
1076 185 : m_pSerializer->endElementNS( XML_w, XML_fldChar );
1077 :
1078 185 : if ( bWriteRun )
1079 106 : m_pSerializer->endElementNS( XML_w, XML_r );
1080 :
1081 : // The hyperlinks fields can't be expanded: the value is
1082 : // normally in the text run
1083 185 : if ( !rInfos.pField )
1084 106 : CmdField_Impl( rInfos );
1085 : }
1086 : }
1087 186 : }
1088 :
1089 277 : void DocxAttributeOutput::DoWriteCmd( const OUString& rCmd )
1090 : {
1091 277 : OUString sCmd = rCmd.trim();
1092 277 : if (sCmd.startsWith("SEQ"))
1093 : {
1094 9 : OUString sSeqName = msfilter::util::findQuotedText(sCmd, "SEQ ", '\\').trim();
1095 9 : m_aSeqBookmarksNames[sSeqName].push_back(m_sLastOpenedBookmark);
1096 : }
1097 : // Write the Field command
1098 277 : m_pSerializer->startElementNS( XML_w, XML_instrText, FSEND );
1099 277 : m_pSerializer->writeEscaped( rCmd );
1100 277 : m_pSerializer->endElementNS( XML_w, XML_instrText );
1101 :
1102 277 : }
1103 :
1104 185 : void DocxAttributeOutput::CmdField_Impl( FieldInfos& rInfos )
1105 : {
1106 185 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
1107 185 : sal_Int32 nNbToken = comphelper::string::getTokenCount(rInfos.sCmd, '\t');
1108 :
1109 376 : for ( sal_Int32 i = 0; i < nNbToken; i++ )
1110 : {
1111 191 : OUString sToken = rInfos.sCmd.getToken( i, '\t' );
1112 191 : if ( rInfos.eType == ww::eCREATEDATE
1113 191 : || rInfos.eType == ww::eSAVEDATE
1114 191 : || rInfos.eType == ww::ePRINTDATE
1115 191 : || rInfos.eType == ww::eDATE
1116 187 : || rInfos.eType == ww::eTIME )
1117 : {
1118 4 : sToken = sToken.replaceAll("NNNN", "dddd");
1119 4 : sToken = sToken.replaceAll("NN", "ddd");
1120 : }
1121 :
1122 : // Write the Field command
1123 191 : DoWriteCmd( sToken );
1124 :
1125 : // Replace tabs by </instrText><tab/><instrText>
1126 191 : if ( i < ( nNbToken - 1 ) )
1127 6 : RunText( OUString( "\t" ) );
1128 191 : }
1129 :
1130 185 : m_pSerializer->endElementNS( XML_w, XML_r );
1131 :
1132 : // Write the Field separator
1133 185 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
1134 : m_pSerializer->singleElementNS( XML_w, XML_fldChar,
1135 : FSNS( XML_w, XML_fldCharType ), "separate",
1136 185 : FSEND );
1137 185 : m_pSerializer->endElementNS( XML_w, XML_r );
1138 185 : }
1139 :
1140 211 : void DocxAttributeOutput::EndField_Impl( FieldInfos& rInfos )
1141 : {
1142 : // The command has to be written before for the hyperlinks
1143 211 : if ( rInfos.pField )
1144 : {
1145 79 : CmdField_Impl( rInfos );
1146 : }
1147 :
1148 : // Write the bookmark start if any
1149 211 : OUString aBkmName( m_sFieldBkm );
1150 211 : if ( !aBkmName.isEmpty() )
1151 : {
1152 : m_pSerializer->singleElementNS( XML_w, XML_bookmarkStart,
1153 : FSNS( XML_w, XML_id ), OString::number( m_nNextBookmarkId ).getStr( ),
1154 : FSNS( XML_w, XML_name ), OUStringToOString( aBkmName, RTL_TEXTENCODING_UTF8 ).getStr( ),
1155 0 : FSEND );
1156 : }
1157 :
1158 211 : if (rInfos.pField ) // For hyperlinks and TOX
1159 : {
1160 : // Write the Field latest value
1161 79 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
1162 79 : OUString sExpand;
1163 79 : if(rInfos.eType == ww::eCITATION)
1164 : {
1165 6 : sExpand = rInfos.pField->ExpandField( false , AUTH_FIELD_TITLE);
1166 : }
1167 : else
1168 : {
1169 73 : sExpand = rInfos.pField->ExpandField( true );
1170 : }
1171 : // newlines embedded in fields are 0x0B in MSO and 0x0A for us
1172 79 : RunText(sExpand.replace(0x0A, 0x0B));
1173 :
1174 79 : m_pSerializer->endElementNS( XML_w, XML_r );
1175 : }
1176 :
1177 : // Write the bookmark end if any
1178 211 : if ( !aBkmName.isEmpty() )
1179 : {
1180 : m_pSerializer->singleElementNS( XML_w, XML_bookmarkEnd,
1181 : FSNS( XML_w, XML_id ), OString::number( m_nNextBookmarkId ).getStr( ),
1182 0 : FSEND );
1183 :
1184 0 : m_nNextBookmarkId++;
1185 : }
1186 :
1187 : // Write the Field end
1188 211 : if ( rInfos.bClose )
1189 : {
1190 186 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
1191 : m_pSerializer->singleElementNS( XML_w, XML_fldChar,
1192 : FSNS( XML_w, XML_fldCharType ), "end",
1193 186 : FSEND );
1194 186 : m_pSerializer->endElementNS( XML_w, XML_r );
1195 : }
1196 : // Write the ref field if a bookmark had to be set and the field
1197 : // should be visible
1198 211 : if ( rInfos.pField )
1199 : {
1200 79 : sal_uInt16 nSubType = rInfos.pField->GetSubType( );
1201 79 : bool bIsSetField = rInfos.pField->GetTyp( )->Which( ) == RES_SETEXPFLD;
1202 79 : bool bShowRef = ( !bIsSetField || ( nSubType & nsSwExtendedSubType::SUB_INVISIBLE ) ) ? false : true;
1203 :
1204 79 : if ( ( !m_sFieldBkm.isEmpty() ) && bShowRef )
1205 : {
1206 : // Write the field beginning
1207 0 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
1208 : m_pSerializer->singleElementNS( XML_w, XML_fldChar,
1209 : FSNS( XML_w, XML_fldCharType ), "begin",
1210 0 : FSEND );
1211 0 : m_pSerializer->endElementNS( XML_w, XML_r );
1212 :
1213 0 : rInfos.sCmd = FieldString( ww::eREF );
1214 0 : rInfos.sCmd += "\"";
1215 0 : rInfos.sCmd += m_sFieldBkm;
1216 0 : rInfos.sCmd += "\" ";
1217 :
1218 : // Clean the field bookmark data to avoid infinite loop
1219 0 : m_sFieldBkm = OUString( );
1220 :
1221 : // Write the end of the field
1222 0 : EndField_Impl( rInfos );
1223 : }
1224 211 : }
1225 211 : }
1226 :
1227 6494 : void DocxAttributeOutput::StartRunProperties()
1228 : {
1229 : // postpone the output so that we can later [in EndRunProperties()]
1230 : // prepend the properties before the text
1231 6494 : m_pSerializer->mark();
1232 :
1233 6494 : m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
1234 :
1235 6494 : if(GetExport().bHideTabLeaderAndPageNumbers && m_pHyperlinkAttrList )
1236 : {
1237 83 : m_pSerializer->singleElementNS( XML_w, XML_webHidden, FSEND );
1238 : }
1239 6494 : InitCollectedRunProperties();
1240 :
1241 : OSL_ASSERT( m_postponedGraphic == NULL );
1242 6494 : m_postponedGraphic = new std::list< PostponedGraphic >;
1243 :
1244 : OSL_ASSERT( m_postponedDiagram == NULL );
1245 6494 : m_postponedDiagram = new std::list< PostponedDiagram >;
1246 :
1247 : OSL_ASSERT( m_postponedVMLDrawing == NULL );
1248 6494 : m_postponedVMLDrawing = new std::list< PostponedDrawing >;
1249 :
1250 : assert(!m_postponedDMLDrawing);
1251 6494 : m_postponedDMLDrawing = new std::list< PostponedDrawing >;
1252 :
1253 : assert( !m_postponedOLE );
1254 6494 : m_postponedOLE = new std::list< PostponedOLE >;
1255 6494 : }
1256 :
1257 11491 : void DocxAttributeOutput::InitCollectedRunProperties()
1258 : {
1259 11491 : m_pFontsAttrList = NULL;
1260 11491 : m_pEastAsianLayoutAttrList = NULL;
1261 11491 : m_pCharLangAttrList = NULL;
1262 :
1263 : // Write the elements in the spec order
1264 : static const sal_Int32 aOrder[] =
1265 : {
1266 : FSNS( XML_w, XML_rStyle ),
1267 : FSNS( XML_w, XML_rFonts ),
1268 : FSNS( XML_w, XML_b ),
1269 : FSNS( XML_w, XML_bCs ),
1270 : FSNS( XML_w, XML_i ),
1271 : FSNS( XML_w, XML_iCs ),
1272 : FSNS( XML_w, XML_caps ),
1273 : FSNS( XML_w, XML_smallCaps ),
1274 : FSNS( XML_w, XML_strike ),
1275 : FSNS( XML_w, XML_dstrike ),
1276 : FSNS( XML_w, XML_outline ),
1277 : FSNS( XML_w, XML_shadow ),
1278 : FSNS( XML_w, XML_emboss ),
1279 : FSNS( XML_w, XML_imprint ),
1280 : FSNS( XML_w, XML_noProof ),
1281 : FSNS( XML_w, XML_snapToGrid ),
1282 : FSNS( XML_w, XML_vanish ),
1283 : FSNS( XML_w, XML_webHidden ),
1284 : FSNS( XML_w, XML_color ),
1285 : FSNS( XML_w, XML_spacing ),
1286 : FSNS( XML_w, XML_w ),
1287 : FSNS( XML_w, XML_kern ),
1288 : FSNS( XML_w, XML_position ),
1289 : FSNS( XML_w, XML_sz ),
1290 : FSNS( XML_w, XML_szCs ),
1291 : FSNS( XML_w, XML_highlight ),
1292 : FSNS( XML_w, XML_u ),
1293 : FSNS( XML_w, XML_effect ),
1294 : FSNS( XML_w, XML_bdr ),
1295 : FSNS( XML_w, XML_shd ),
1296 : FSNS( XML_w, XML_fitText ),
1297 : FSNS( XML_w, XML_vertAlign ),
1298 : FSNS( XML_w, XML_rtl ),
1299 : FSNS( XML_w, XML_cs ),
1300 : FSNS( XML_w, XML_em ),
1301 : FSNS( XML_w, XML_lang ),
1302 : FSNS( XML_w, XML_eastAsianLayout ),
1303 : FSNS( XML_w, XML_specVanish ),
1304 : FSNS( XML_w, XML_oMath ),
1305 : FSNS( XML_w, XML_rPrChange ),
1306 : FSNS( XML_w14, XML_glow ),
1307 : FSNS( XML_w14, XML_shadow ),
1308 : FSNS( XML_w14, XML_reflection ),
1309 : FSNS( XML_w14, XML_textOutline ),
1310 : FSNS( XML_w14, XML_textFill ),
1311 : FSNS( XML_w14, XML_scene3d ),
1312 : FSNS( XML_w14, XML_props3d ),
1313 : FSNS( XML_w14, XML_ligatures ),
1314 : FSNS( XML_w14, XML_numForm ),
1315 : FSNS( XML_w14, XML_numSpacing ),
1316 : FSNS( XML_w14, XML_stylisticSets ),
1317 : FSNS( XML_w14, XML_cntxtAlts ),
1318 : };
1319 :
1320 : // postpone the output so that we can later [in EndParagraphProperties()]
1321 : // prepend the properties before the run
1322 11491 : sal_Int32 len = sizeof ( aOrder ) / sizeof( sal_Int32 );
1323 11491 : uno::Sequence< sal_Int32 > aSeqOrder( len );
1324 609023 : for ( sal_Int32 i = 0; i < len; i++ )
1325 597532 : aSeqOrder[i] = aOrder[i];
1326 :
1327 11491 : m_pSerializer->mark( aSeqOrder );
1328 :
1329 11491 : }
1330 :
1331 : namespace
1332 : {
1333 :
1334 902 : struct NameToId
1335 : {
1336 : OUString maName;
1337 : sal_Int32 maId;
1338 : };
1339 :
1340 22 : const NameToId constNameToIdMapping[] =
1341 : {
1342 : { OUString("glow"), FSNS( XML_w14, XML_glow ) },
1343 : { OUString("shadow"), FSNS( XML_w14, XML_shadow ) },
1344 : { OUString("reflection"), FSNS( XML_w14, XML_reflection ) },
1345 : { OUString("textOutline"), FSNS( XML_w14, XML_textOutline ) },
1346 : { OUString("textFill"), FSNS( XML_w14, XML_textFill ) },
1347 : { OUString("scene3d"), FSNS( XML_w14, XML_scene3d ) },
1348 : { OUString("props3d"), FSNS( XML_w14, XML_props3d ) },
1349 : { OUString("ligatures"), FSNS( XML_w14, XML_ligatures ) },
1350 : { OUString("numForm"), FSNS( XML_w14, XML_numForm ) },
1351 : { OUString("numSpacing"), FSNS( XML_w14, XML_numSpacing ) },
1352 : { OUString("stylisticSets"),FSNS( XML_w14, XML_stylisticSets ) },
1353 : { OUString("cntxtAlts"), FSNS( XML_w14, XML_cntxtAlts ) },
1354 :
1355 : { OUString("val"), FSNS( XML_w14, XML_val ) },
1356 : { OUString("rad"), FSNS( XML_w14, XML_rad ) },
1357 : { OUString("blurRad"), FSNS( XML_w14, XML_blurRad ) },
1358 : { OUString("stA"), FSNS( XML_w14, XML_stA ) },
1359 : { OUString("stPos"), FSNS( XML_w14, XML_stPos ) },
1360 : { OUString("endA"), FSNS( XML_w14, XML_endA ) },
1361 : { OUString("endPos"), FSNS( XML_w14, XML_endPos ) },
1362 : { OUString("dist"), FSNS( XML_w14, XML_dist ) },
1363 : { OUString("dir"), FSNS( XML_w14, XML_dir ) },
1364 : { OUString("fadeDir"), FSNS( XML_w14, XML_fadeDir ) },
1365 : { OUString("sx"), FSNS( XML_w14, XML_sx ) },
1366 : { OUString("sy"), FSNS( XML_w14, XML_sy ) },
1367 : { OUString("kx"), FSNS( XML_w14, XML_kx ) },
1368 : { OUString("ky"), FSNS( XML_w14, XML_ky ) },
1369 : { OUString("algn"), FSNS( XML_w14, XML_algn ) },
1370 : { OUString("w"), FSNS( XML_w14, XML_w ) },
1371 : { OUString("cap"), FSNS( XML_w14, XML_cap ) },
1372 : { OUString("cmpd"), FSNS( XML_w14, XML_cmpd ) },
1373 : { OUString("pos"), FSNS( XML_w14, XML_pos ) },
1374 : { OUString("ang"), FSNS( XML_w14, XML_ang ) },
1375 : { OUString("scaled"), FSNS( XML_w14, XML_scaled ) },
1376 : { OUString("path"), FSNS( XML_w14, XML_path ) },
1377 : { OUString("l"), FSNS( XML_w14, XML_l ) },
1378 : { OUString("t"), FSNS( XML_w14, XML_t ) },
1379 : { OUString("r"), FSNS( XML_w14, XML_r ) },
1380 : { OUString("b"), FSNS( XML_w14, XML_b ) },
1381 : { OUString("lim"), FSNS( XML_w14, XML_lim ) },
1382 : { OUString("prst"), FSNS( XML_w14, XML_prst ) },
1383 : { OUString("rig"), FSNS( XML_w14, XML_rig ) },
1384 : { OUString("lat"), FSNS( XML_w14, XML_lat ) },
1385 : { OUString("lon"), FSNS( XML_w14, XML_lon ) },
1386 : { OUString("rev"), FSNS( XML_w14, XML_rev ) },
1387 : { OUString("h"), FSNS( XML_w14, XML_h ) },
1388 : { OUString("extrusionH"), FSNS( XML_w14, XML_extrusionH ) },
1389 : { OUString("contourW"), FSNS( XML_w14, XML_contourW ) },
1390 : { OUString("prstMaterial"), FSNS( XML_w14, XML_prstMaterial ) },
1391 : { OUString("id"), FSNS( XML_w14, XML_id ) },
1392 :
1393 : { OUString("schemeClr"), FSNS( XML_w14, XML_schemeClr ) },
1394 : { OUString("srgbClr"), FSNS( XML_w14, XML_srgbClr ) },
1395 : { OUString("tint"), FSNS( XML_w14, XML_tint ) },
1396 : { OUString("shade"), FSNS( XML_w14, XML_shade ) },
1397 : { OUString("alpha"), FSNS( XML_w14, XML_alpha ) },
1398 : { OUString("hueMod"), FSNS( XML_w14, XML_hueMod ) },
1399 : { OUString("sat"), FSNS( XML_w14, XML_sat ) },
1400 : { OUString("satOff"), FSNS( XML_w14, XML_satOff ) },
1401 : { OUString("satMod"), FSNS( XML_w14, XML_satMod ) },
1402 : { OUString("lum"), FSNS( XML_w14, XML_lum ) },
1403 : { OUString("lumOff"), FSNS( XML_w14, XML_lumOff ) },
1404 : { OUString("lumMod"), FSNS( XML_w14, XML_lumMod ) },
1405 : { OUString("noFill"), FSNS( XML_w14, XML_noFill ) },
1406 : { OUString("solidFill"), FSNS( XML_w14, XML_solidFill ) },
1407 : { OUString("gradFill"), FSNS( XML_w14, XML_gradFill ) },
1408 : { OUString("gsLst"), FSNS( XML_w14, XML_gsLst ) },
1409 : { OUString("gs"), FSNS( XML_w14, XML_gs ) },
1410 : { OUString("pos"), FSNS( XML_w14, XML_pos ) },
1411 : { OUString("lin"), FSNS( XML_w14, XML_lin ) },
1412 : { OUString("path"), FSNS( XML_w14, XML_path ) },
1413 : { OUString("fillToRect"), FSNS( XML_w14, XML_fillToRect ) },
1414 : { OUString("prstDash"), FSNS( XML_w14, XML_prstDash ) },
1415 : { OUString("round"), FSNS( XML_w14, XML_round ) },
1416 : { OUString("bevel"), FSNS( XML_w14, XML_bevel ) },
1417 : { OUString("miter"), FSNS( XML_w14, XML_miter ) },
1418 : { OUString("camera"), FSNS( XML_w14, XML_camera ) },
1419 : { OUString("lightRig"), FSNS( XML_w14, XML_lightRig ) },
1420 : { OUString("rot"), FSNS( XML_w14, XML_rot ) },
1421 : { OUString("bevelT"), FSNS( XML_w14, XML_bevelT ) },
1422 : { OUString("bevelB"), FSNS( XML_w14, XML_bevelB ) },
1423 : { OUString("extrusionClr"), FSNS( XML_w14, XML_extrusionClr ) },
1424 : { OUString("contourClr"), FSNS( XML_w14, XML_contourClr ) },
1425 : { OUString("styleSet"), FSNS( XML_w14, XML_styleSet ) },
1426 :
1427 11 : };
1428 :
1429 1079 : boost::optional<sal_Int32> lclGetElementIdForName(const OUString& rName)
1430 : {
1431 1079 : sal_Int32 aLength = sizeof (constNameToIdMapping) / sizeof(NameToId);
1432 50207 : for (sal_Int32 i=0; i < aLength; ++i)
1433 : {
1434 49932 : if (rName == constNameToIdMapping[i].maName)
1435 : {
1436 804 : return constNameToIdMapping[i].maId;
1437 : }
1438 : }
1439 275 : return boost::optional<sal_Int32>();
1440 : }
1441 :
1442 343 : void lclProcessRecursiveGrabBag(sal_Int32 aElementId, const css::uno::Sequence<css::beans::PropertyValue>& rElements, sax_fastparser::FSHelperPtr pSerializer)
1443 : {
1444 343 : css::uno::Sequence<css::beans::PropertyValue> aAttributes;
1445 343 : FastAttributeList* pAttributes = pSerializer->createAttrList();
1446 :
1447 879 : for (sal_Int32 j=0; j < rElements.getLength(); ++j)
1448 : {
1449 536 : if (rElements[j].Name == "attributes")
1450 : {
1451 275 : rElements[j].Value >>= aAttributes;
1452 : }
1453 : }
1454 :
1455 804 : for (sal_Int32 j=0; j < aAttributes.getLength(); ++j)
1456 : {
1457 461 : uno::Any aAny = aAttributes[j].Value;
1458 922 : OString aValue;
1459 :
1460 461 : if(aAny.getValueType() == getCppuType<sal_Int32>())
1461 : {
1462 266 : aValue = OString::number(aAny.get<sal_Int32>());
1463 : }
1464 195 : else if(aAny.getValueType() == getCppuType<OUString>())
1465 : {
1466 195 : aValue = OUStringToOString(aAny.get<OUString>(), RTL_TEXTENCODING_ASCII_US);
1467 : }
1468 :
1469 922 : boost::optional<sal_Int32> aSubElementId = lclGetElementIdForName(aAttributes[j].Name);
1470 461 : if(aSubElementId)
1471 461 : pAttributes->add(*aSubElementId, aValue.getStr());
1472 461 : }
1473 :
1474 686 : XFastAttributeListRef xAttributesList( pAttributes );
1475 :
1476 343 : pSerializer->startElement(aElementId, xAttributesList);
1477 :
1478 879 : for (sal_Int32 j=0; j < rElements.getLength(); ++j)
1479 : {
1480 536 : css::uno::Sequence<css::beans::PropertyValue> aSumElements;
1481 :
1482 1072 : boost::optional<sal_Int32> aSubElementId = lclGetElementIdForName(rElements[j].Name);
1483 536 : if(aSubElementId)
1484 : {
1485 261 : rElements[j].Value >>= aSumElements;
1486 261 : lclProcessRecursiveGrabBag(*aSubElementId, aSumElements, pSerializer);
1487 : }
1488 536 : }
1489 :
1490 686 : pSerializer->endElement(aElementId);
1491 343 : }
1492 :
1493 : }
1494 :
1495 15441 : void DocxAttributeOutput::WriteCollectedRunProperties()
1496 : {
1497 : // Write all differed properties
1498 15441 : if ( m_pFontsAttrList )
1499 : {
1500 7023 : XFastAttributeListRef xAttrList( m_pFontsAttrList );
1501 7023 : m_pFontsAttrList = NULL;
1502 :
1503 7023 : m_pSerializer->singleElementNS( XML_w, XML_rFonts, xAttrList );
1504 : }
1505 :
1506 15441 : if ( m_pColorAttrList )
1507 : {
1508 4347 : XFastAttributeListRef xAttrList( m_pColorAttrList );
1509 4347 : m_pColorAttrList = NULL;
1510 :
1511 4347 : m_pSerializer->singleElementNS( XML_w, XML_color, xAttrList );
1512 : }
1513 :
1514 15441 : if ( m_pEastAsianLayoutAttrList )
1515 : {
1516 0 : XFastAttributeListRef xAttrList( m_pEastAsianLayoutAttrList );
1517 0 : m_pEastAsianLayoutAttrList = NULL;
1518 :
1519 0 : m_pSerializer->singleElementNS( XML_w, XML_eastAsianLayout, xAttrList );
1520 : }
1521 :
1522 15441 : if ( m_pCharLangAttrList )
1523 : {
1524 3160 : XFastAttributeListRef xAttrList( m_pCharLangAttrList );
1525 3160 : m_pCharLangAttrList = NULL;
1526 :
1527 3160 : m_pSerializer->singleElementNS( XML_w, XML_lang, xAttrList );
1528 : }
1529 :
1530 15441 : if (m_aTextEffectsGrabBag.getLength() > 0)
1531 : {
1532 123 : for (sal_Int32 i=0; i < m_aTextEffectsGrabBag.getLength(); ++i)
1533 : {
1534 82 : boost::optional<sal_Int32> aElementId = lclGetElementIdForName(m_aTextEffectsGrabBag[i].Name);
1535 82 : if(aElementId)
1536 : {
1537 82 : uno::Sequence<beans::PropertyValue> aGrabBagSeq;
1538 82 : m_aTextEffectsGrabBag[i].Value >>= aGrabBagSeq;
1539 82 : lclProcessRecursiveGrabBag(*aElementId, aGrabBagSeq, m_pSerializer);
1540 : }
1541 82 : }
1542 41 : m_aTextEffectsGrabBag.realloc(0);
1543 : }
1544 15441 : }
1545 :
1546 6494 : void DocxAttributeOutput::EndRunProperties( const SwRedlineData* pRedlineData )
1547 : {
1548 : // Call the 'Redline' function. This will add redline (change-tracking) information that regards to run properties.
1549 : // This includes changes like 'Bold', 'Underline', 'Strikethrough' etc.
1550 6494 : Redline( pRedlineData );
1551 :
1552 6494 : WriteCollectedRunProperties();
1553 :
1554 : // Merge the marks for the ordered elements
1555 6494 : m_pSerializer->mergeTopMarks();
1556 :
1557 6494 : m_pSerializer->endElementNS( XML_w, XML_rPr );
1558 :
1559 : // write footnotes/endnotes if we have any
1560 6494 : FootnoteEndnoteReference();
1561 :
1562 6494 : WritePostponedGraphic();
1563 :
1564 6494 : WritePostponedDiagram();
1565 : //We need to write w:drawing tag after the w:rPr.
1566 6494 : WritePostponedChart();
1567 :
1568 : //We need to write w:pict tag after the w:rPr.
1569 6494 : WritePostponedVMLDrawing();
1570 6494 : WritePostponedDMLDrawing();
1571 :
1572 6494 : WritePostponedOLE();
1573 :
1574 : // merge the properties _before_ the run text (strictly speaking, just
1575 : // after the start of the run)
1576 6494 : m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND );
1577 6494 : }
1578 :
1579 6494 : void DocxAttributeOutput::WritePostponedGraphic()
1580 : {
1581 19617 : for( std::list< PostponedGraphic >::const_iterator it = m_postponedGraphic->begin();
1582 13078 : it != m_postponedGraphic->end();
1583 : ++it )
1584 45 : FlyFrameGraphic( it->grfNode, it->size, it->mOLEFrmFmt, it->mOLENode, it->pSdrObj );
1585 6494 : delete m_postponedGraphic;
1586 6494 : m_postponedGraphic = NULL;
1587 6494 : }
1588 :
1589 6494 : void DocxAttributeOutput::WritePostponedDiagram()
1590 : {
1591 19488 : for( std::list< PostponedDiagram >::const_iterator it = m_postponedDiagram->begin();
1592 12992 : it != m_postponedDiagram->end();
1593 : ++it )
1594 2 : m_rExport.SdrExporter().writeDiagram( it->object, *(it->frame), m_anchorId++ );
1595 6494 : delete m_postponedDiagram;
1596 6494 : m_postponedDiagram = NULL;
1597 6494 : }
1598 :
1599 19 : void DocxAttributeOutput::FootnoteEndnoteRefTag()
1600 : {
1601 19 : if( m_footnoteEndnoteRefTag == 0 )
1602 33 : return;
1603 5 : m_pSerializer->singleElementNS( XML_w, m_footnoteEndnoteRefTag, FSEND );
1604 5 : m_footnoteEndnoteRefTag = 0;
1605 : }
1606 :
1607 : /** Output sal_Unicode* as a run text (<t>the text</t>).
1608 :
1609 : When bMove is true, update rBegin to point _after_ the end of the text +
1610 : 1, meaning that it skips one character after the text. This is to make
1611 : the switch in DocxAttributeOutput::RunText() nicer ;-)
1612 : */
1613 6048 : static void impl_WriteRunText( FSHelperPtr pSerializer, sal_Int32 nTextToken,
1614 : const sal_Unicode* &rBegin, const sal_Unicode* pEnd, bool bMove = true )
1615 : {
1616 6048 : const sal_Unicode *pBegin = rBegin;
1617 :
1618 : // skip one character after the end
1619 6048 : if ( bMove )
1620 1424 : rBegin = pEnd + 1;
1621 :
1622 6048 : if ( pBegin >= pEnd )
1623 6980 : return; // we want to write at least one character
1624 :
1625 : // we have to add 'preserve' when starting/ending with space
1626 5116 : if ( *pBegin == ' ' || *( pEnd - 1 ) == ' ' )
1627 : {
1628 1267 : pSerializer->startElementNS( XML_w, nTextToken, FSNS( XML_xml, XML_space ), "preserve", FSEND );
1629 : }
1630 : else
1631 3849 : pSerializer->startElementNS( XML_w, nTextToken, FSEND );
1632 :
1633 5116 : pSerializer->writeEscaped( OUString( pBegin, pEnd - pBegin ) );
1634 :
1635 5116 : pSerializer->endElementNS( XML_w, nTextToken );
1636 : }
1637 :
1638 4624 : void DocxAttributeOutput::RunText( const OUString& rText, rtl_TextEncoding /*eCharSet*/ )
1639 : {
1640 4624 : if( m_closeHyperlinkInThisRun )
1641 : {
1642 169 : m_closeHyperlinkInPreviousRun = true;
1643 : }
1644 :
1645 : // one text can be split into more <w:t>blah</w:t>'s by line breaks etc.
1646 4624 : const sal_Unicode *pBegin = rText.getStr();
1647 4624 : const sal_Unicode *pEnd = pBegin + rText.getLength();
1648 :
1649 : // the text run is usually XML_t, with the exception of the deleted text
1650 4624 : sal_Int32 nTextToken = XML_t;
1651 4624 : if ( m_pRedlineData && m_pRedlineData->GetType() == nsRedlineType_t::REDLINE_DELETE )
1652 4 : nTextToken = XML_delText;
1653 :
1654 181602 : for ( const sal_Unicode *pIt = pBegin; pIt < pEnd; ++pIt )
1655 : {
1656 176978 : switch ( *pIt )
1657 : {
1658 : case 0x09: // tab
1659 1378 : impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt );
1660 1378 : m_pSerializer->singleElementNS( XML_w, XML_tab, FSEND );
1661 1378 : break;
1662 : case 0x0b: // line break
1663 19 : impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt );
1664 19 : m_pSerializer->singleElementNS( XML_w, XML_br, FSEND );
1665 19 : break;
1666 : case 0x1E: //non-breaking hyphen
1667 1 : impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt );
1668 1 : m_pSerializer->singleElementNS( XML_w, XML_noBreakHyphen, FSEND );
1669 1 : break;
1670 : case 0x1F: //soft (on demand) hyphen
1671 20 : impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt );
1672 20 : m_pSerializer->singleElementNS( XML_w, XML_softHyphen, FSEND );
1673 20 : break;
1674 : default:
1675 175560 : if ( *pIt < 0x0020 ) // filter out the control codes
1676 : {
1677 6 : impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt );
1678 : OSL_TRACE( "Ignored control code %x in a text run.", *pIt );
1679 : }
1680 175560 : break;
1681 : }
1682 : }
1683 :
1684 4624 : impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pEnd, false );
1685 4624 : }
1686 :
1687 0 : void DocxAttributeOutput::RawText( const OUString& /*rText*/, bool /*bForceUnicode*/, rtl_TextEncoding /*eCharSet*/ )
1688 : {
1689 : OSL_TRACE("TODO DocxAttributeOutput::RawText( const String& rText, bool bForceUnicode, rtl_TextEncoding eCharSet )" );
1690 0 : }
1691 :
1692 0 : void DocxAttributeOutput::StartRuby( const SwTxtNode& rNode, sal_Int32 nPos, const SwFmtRuby& rRuby )
1693 : {
1694 : OSL_TRACE("TODO DocxAttributeOutput::StartRuby( const SwTxtNode& rNode, const SwFmtRuby& rRuby )" );
1695 0 : m_pSerializer->startElementNS( XML_w, XML_ruby, FSEND );
1696 0 : m_pSerializer->startElementNS( XML_w, XML_rubyPr, FSEND );
1697 : // hps
1698 : // hpsBaseText
1699 : // hpsRaise
1700 : // lid
1701 : lang::Locale aLocale( SwBreakIt::Get()->GetLocale(
1702 0 : rNode.GetLang( nPos ) ) );
1703 0 : OUString sLang( LanguageTag::convertToBcp47( aLocale) );
1704 : m_pSerializer->singleElementNS( XML_w, XML_lid,
1705 : FSNS( XML_w, XML_val ),
1706 0 : OUStringToOString( sLang, RTL_TEXTENCODING_UTF8 ).getStr( ), FSEND );
1707 :
1708 0 : OString sAlign ( "center" );
1709 0 : switch ( rRuby.GetAdjustment( ) )
1710 : {
1711 : case 0:
1712 0 : sAlign = OString( "left" );
1713 0 : break;
1714 : case 1:
1715 : // Defaults to center
1716 0 : break;
1717 : case 2:
1718 0 : sAlign = OString( "right" );
1719 0 : break;
1720 : case 3:
1721 0 : sAlign = OString( "distributeLetter" );
1722 0 : break;
1723 : case 4:
1724 0 : sAlign = OString( "distributeSpace" );
1725 0 : break;
1726 : default:
1727 0 : break;
1728 : }
1729 : m_pSerializer->singleElementNS( XML_w, XML_rubyAlign,
1730 0 : FSNS( XML_w, XML_val ), sAlign.getStr(), FSEND );
1731 0 : m_pSerializer->endElementNS( XML_w, XML_rubyPr );
1732 :
1733 0 : m_pSerializer->startElementNS( XML_w, XML_rt, FSEND );
1734 0 : StartRun( NULL );
1735 0 : StartRunProperties( );
1736 0 : SwWW8AttrIter aAttrIt( m_rExport, rNode );
1737 0 : aAttrIt.OutAttr( nPos, true );
1738 :
1739 0 : sal_uInt16 nStyle = m_rExport.GetId( *rRuby.GetTxtRuby()->GetCharFmt() );
1740 0 : OString aStyleId(m_rExport.pStyles->GetStyleId(nStyle));
1741 : m_pSerializer->singleElementNS( XML_w, XML_rStyle,
1742 0 : FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND );
1743 :
1744 0 : EndRunProperties( NULL );
1745 0 : RunText( rRuby.GetText( ) );
1746 0 : EndRun( );
1747 0 : m_pSerializer->endElementNS( XML_w, XML_rt );
1748 :
1749 0 : m_pSerializer->startElementNS( XML_w, XML_rubyBase, FSEND );
1750 0 : StartRun( NULL );
1751 0 : }
1752 :
1753 0 : void DocxAttributeOutput::EndRuby()
1754 : {
1755 : OSL_TRACE( "TODO DocxAttributeOutput::EndRuby()" );
1756 0 : EndRun( );
1757 0 : m_pSerializer->endElementNS( XML_w, XML_rubyBase );
1758 0 : m_pSerializer->endElementNS( XML_w, XML_ruby );
1759 0 : }
1760 :
1761 302 : bool DocxAttributeOutput::AnalyzeURL( const OUString& rUrl, const OUString& rTarget, OUString* pLinkURL, OUString* pMark )
1762 : {
1763 302 : bool bBookMarkOnly = AttributeOutputBase::AnalyzeURL( rUrl, rTarget, pLinkURL, pMark );
1764 :
1765 302 : if ( !pMark->isEmpty() )
1766 : {
1767 103 : OUString sURL = *pLinkURL;
1768 :
1769 103 : if ( bBookMarkOnly )
1770 88 : sURL = FieldString( ww::eHYPERLINK );
1771 : else
1772 15 : sURL = FieldString( ww::eHYPERLINK ) + "\"" + sURL + "\"";
1773 :
1774 103 : sURL += " \\l \"" + *pMark + "\"";
1775 :
1776 103 : if ( !rTarget.isEmpty() )
1777 0 : sURL += " \\n " + rTarget;
1778 :
1779 103 : *pLinkURL = sURL;
1780 : }
1781 :
1782 302 : return bBookMarkOnly;
1783 : }
1784 :
1785 302 : bool DocxAttributeOutput::StartURL( const OUString& rUrl, const OUString& rTarget )
1786 : {
1787 302 : OUString sMark;
1788 604 : OUString sUrl;
1789 :
1790 302 : bool bBookmarkOnly = AnalyzeURL( rUrl, rTarget, &sUrl, &sMark );
1791 :
1792 302 : m_hyperLinkAnchor = sMark;
1793 :
1794 302 : if ( !sMark.isEmpty() && !bBookmarkOnly )
1795 : {
1796 15 : m_rExport.OutputField( NULL, ww::eHYPERLINK, sUrl );
1797 : }
1798 : else
1799 : {
1800 : // Output a hyperlink XML element
1801 287 : m_pHyperlinkAttrList = m_pSerializer->createAttrList();
1802 :
1803 287 : if ( !bBookmarkOnly )
1804 : {
1805 199 : OString sId = OUStringToOString( GetExport().GetFilter().addRelation( m_pSerializer->getOutputStream(),
1806 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
1807 398 : sUrl, true ), RTL_TEXTENCODING_UTF8 );
1808 :
1809 199 : m_pHyperlinkAttrList->add( FSNS( XML_r, XML_id), sId.getStr());
1810 : }
1811 : else
1812 : {
1813 : // Is this a link to a sequence? Then try to replace that with a
1814 : // normal bookmark, as Word won't understand our special
1815 : // <seqname>!<index>|sequence syntax.
1816 88 : if (sMark.endsWith("|sequence"))
1817 : {
1818 2 : sal_Int32 nPos = sMark.indexOf('!');
1819 2 : if (nPos != -1)
1820 : {
1821 : // Extract <seqname>, the field instruction text has the name quoted.
1822 2 : OUString aSequenceName = sMark.copy(0, nPos);
1823 : // Extract <index>.
1824 2 : sal_uInt32 nIndex = sMark.copy(nPos + 1, sMark.getLength() - nPos - sizeof("|sequence")).toInt32();
1825 2 : std::map<OUString, std::vector<OString> >::iterator it = m_aSeqBookmarksNames.find(aSequenceName);
1826 2 : if (it != m_aSeqBookmarksNames.end())
1827 : {
1828 2 : std::vector<OString>& rNames = it->second;
1829 2 : if (rNames.size() > nIndex)
1830 : // We know the bookmark name for this sequence and this index, do the replacement.
1831 2 : sMark = OStringToOUString(rNames[nIndex], RTL_TEXTENCODING_UTF8);
1832 2 : }
1833 : }
1834 : }
1835 : m_pHyperlinkAttrList->add( FSNS( XML_w, XML_anchor ),
1836 88 : OUStringToOString( sMark, RTL_TEXTENCODING_UTF8 ).getStr( ) );
1837 : }
1838 :
1839 287 : OUString sTarget( rTarget );
1840 287 : if ( !sTarget.isEmpty() )
1841 : {
1842 0 : OString soTarget = OUStringToOString( sTarget, RTL_TEXTENCODING_UTF8 );
1843 0 : m_pHyperlinkAttrList->add(FSNS( XML_w, XML_tgtFrame ), soTarget.getStr());
1844 287 : }
1845 : }
1846 :
1847 604 : return true;
1848 : }
1849 :
1850 302 : bool DocxAttributeOutput::EndURL()
1851 : {
1852 302 : m_closeHyperlinkInThisRun = true;
1853 302 : if(m_hyperLinkAnchor != "" && m_hyperLinkAnchor.startsWith("_Toc"))
1854 : {
1855 86 : m_endPageRef = true;
1856 : }
1857 302 : return true;
1858 : }
1859 :
1860 42 : void DocxAttributeOutput::FieldVanish( const OUString& rTxt, ww::eField eType )
1861 : {
1862 42 : WriteField_Impl( NULL, eType, rTxt, WRITEFIELD_ALL );
1863 42 : }
1864 :
1865 : // The difference between 'Redline' and 'StartRedline'+'EndRedline' is that:
1866 : // 'Redline' is used for tracked changes of formatting information of a run like Bold, Underline. (the '<w:rPrChange>' is inside the 'run' node)
1867 : // 'StartRedline' is used to output tracked changes of run insertion and deletion (the run is inside the '<w:ins>' node)
1868 11885 : void DocxAttributeOutput::Redline( const SwRedlineData* pRedlineData)
1869 : {
1870 11885 : if ( !pRedlineData )
1871 23759 : return;
1872 :
1873 11 : OString aId( OString::number( pRedlineData->GetSeqNo() ) );
1874 22 : const OUString &rAuthor( SW_MOD()->GetRedlineAuthor( pRedlineData->GetAuthor() ) );
1875 22 : OString aAuthor( OUStringToOString( rAuthor, RTL_TEXTENCODING_UTF8 ) );
1876 22 : OString aDate( DateTimeToOString( pRedlineData->GetTimeStamp() ) );
1877 :
1878 11 : switch( pRedlineData->GetType() )
1879 : {
1880 : case nsRedlineType_t::REDLINE_INSERT:
1881 4 : break;
1882 :
1883 : case nsRedlineType_t::REDLINE_DELETE:
1884 4 : break;
1885 :
1886 : case nsRedlineType_t::REDLINE_FORMAT:
1887 : m_pSerializer->startElementNS( XML_w, XML_rPrChange,
1888 : FSNS( XML_w, XML_id ), aId.getStr(),
1889 : FSNS( XML_w, XML_author ), aAuthor.getStr(),
1890 : FSNS( XML_w, XML_date ), aDate.getStr(),
1891 2 : FSEND );
1892 :
1893 : // Check if there is any extra data stored in the redline object
1894 2 : if (pRedlineData->GetExtraData())
1895 : {
1896 0 : const SwRedlineExtraData* pExtraData = pRedlineData->GetExtraData();
1897 0 : const SwRedlineExtraData_FormattingChanges* pFormattingChanges = dynamic_cast<const SwRedlineExtraData_FormattingChanges*>(pExtraData);
1898 :
1899 : // Check if the extra data is of type 'formatting changes'
1900 0 : if (pFormattingChanges)
1901 : {
1902 : // Get the item set that holds all the changes properties
1903 0 : const SfxItemSet *pChangesSet = pFormattingChanges->GetItemSet();
1904 0 : if (pChangesSet)
1905 : {
1906 0 : m_pSerializer->mark();
1907 :
1908 0 : m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
1909 :
1910 : // The 'm_pFontsAttrList', 'm_pEastAsianLayoutAttrList', 'm_pCharLangAttrList' are used to hold information
1911 : // that should be collected by different properties in the core, and are all flushed together
1912 : // to the DOCX when the function 'WriteCollectedRunProperties' gets called.
1913 : // So we need to store the current status of these lists, so that we can revert back to them when
1914 : // we are done exporting the redline attributes.
1915 0 : ::sax_fastparser::FastAttributeList *pFontsAttrList_Original = m_pFontsAttrList;
1916 0 : ::sax_fastparser::FastAttributeList *pEastAsianLayoutAttrList_Original = m_pEastAsianLayoutAttrList;
1917 0 : ::sax_fastparser::FastAttributeList *pCharLangAttrList_Original = m_pCharLangAttrList;
1918 0 : m_pFontsAttrList = NULL;
1919 0 : m_pEastAsianLayoutAttrList = NULL;
1920 0 : m_pCharLangAttrList = NULL;
1921 :
1922 : // Output the redline item set
1923 0 : m_rExport.OutputItemSet( *pChangesSet, false, true, i18n::ScriptType::LATIN, m_rExport.mbExportModeRTF );
1924 :
1925 : // Write the collected run properties that are stored in 'm_pFontsAttrList', 'm_pEastAsianLayoutAttrList', 'm_pCharLangAttrList'
1926 0 : WriteCollectedRunProperties();
1927 :
1928 : // Revert back the original values that were stored in 'm_pFontsAttrList', 'm_pEastAsianLayoutAttrList', 'm_pCharLangAttrList'
1929 0 : m_pFontsAttrList = pFontsAttrList_Original;
1930 0 : m_pEastAsianLayoutAttrList = pEastAsianLayoutAttrList_Original;
1931 0 : m_pCharLangAttrList = pCharLangAttrList_Original;
1932 :
1933 0 : m_pSerializer->endElementNS( XML_w, XML_rPr );
1934 :
1935 0 : m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND );
1936 : }
1937 : }
1938 : }
1939 2 : m_pSerializer->endElementNS( XML_w, XML_rPrChange );
1940 2 : break;
1941 :
1942 : case nsRedlineType_t::REDLINE_PARAGRAPH_FORMAT:
1943 : m_pSerializer->startElementNS( XML_w, XML_pPrChange,
1944 : FSNS( XML_w, XML_id ), aId.getStr(),
1945 : FSNS( XML_w, XML_author ), aAuthor.getStr(),
1946 : FSNS( XML_w, XML_date ), aDate.getStr(),
1947 1 : FSEND );
1948 :
1949 : // Check if there is any extra data stored in the redline object
1950 1 : if (pRedlineData->GetExtraData())
1951 : {
1952 0 : const SwRedlineExtraData* pExtraData = pRedlineData->GetExtraData();
1953 0 : const SwRedlineExtraData_FormattingChanges* pFormattingChanges = dynamic_cast<const SwRedlineExtraData_FormattingChanges*>(pExtraData);
1954 :
1955 : // Check if the extra data is of type 'formatting changes'
1956 0 : if (pFormattingChanges)
1957 : {
1958 : // Get the item set that holds all the changes properties
1959 0 : const SfxItemSet *pChangesSet = pFormattingChanges->GetItemSet();
1960 0 : if (pChangesSet)
1961 : {
1962 0 : m_pSerializer->mark();
1963 :
1964 0 : m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND );
1965 :
1966 : // The 'm_rExport.SdrExporter().getFlyAttrList()', 'm_pParagraphSpacingAttrList' are used to hold information
1967 : // that should be collected by different properties in the core, and are all flushed together
1968 : // to the DOCX when the function 'WriteCollectedParagraphProperties' gets called.
1969 : // So we need to store the current status of these lists, so that we can revert back to them when
1970 : // we are done exporting the redline attributes.
1971 0 : ::sax_fastparser::FastAttributeList *pFlyAttrList_Original = m_rExport.SdrExporter().getFlyAttrList();
1972 0 : ::sax_fastparser::FastAttributeList *pParagraphSpacingAttrList_Original = m_pParagraphSpacingAttrList;
1973 0 : m_rExport.SdrExporter().setFlyAttrList(NULL);
1974 0 : m_pParagraphSpacingAttrList = NULL;
1975 :
1976 : // Output the redline item set
1977 0 : m_rExport.OutputItemSet( *pChangesSet, true, false, i18n::ScriptType::LATIN, m_rExport.mbExportModeRTF );
1978 :
1979 : // Write the collected paragraph properties that are stored in 'm_rExport.SdrExporter().getFlyAttrList()', 'm_pParagraphSpacingAttrList'
1980 0 : WriteCollectedParagraphProperties();
1981 :
1982 : // Revert back the original values that were stored in 'm_rExport.SdrExporter().getFlyAttrList()', 'm_pParagraphSpacingAttrList'
1983 0 : m_rExport.SdrExporter().setFlyAttrList(pFlyAttrList_Original);
1984 0 : m_pParagraphSpacingAttrList = pParagraphSpacingAttrList_Original;
1985 :
1986 0 : m_pSerializer->endElementNS( XML_w, XML_pPr );
1987 :
1988 0 : m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND );
1989 : }
1990 : }
1991 : }
1992 1 : m_pSerializer->endElementNS( XML_w, XML_pPrChange );
1993 1 : break;
1994 :
1995 : default:
1996 : SAL_WARN("sw.ww8", "Unhandled redline type for export " << pRedlineData->GetType());
1997 0 : break;
1998 11 : }
1999 : }
2000 :
2001 : // The difference between 'Redline' and 'StartRedline'+'EndRedline' is that:
2002 : // 'Redline' is used for tracked changes of formatting information of a run like Bold, Underline. (the '<w:rPrChange>' is inside the 'run' node)
2003 : // 'StartRedline' is used to output tracked changes of run insertion and deletion (the run is inside the '<w:ins>' node)
2004 6496 : void DocxAttributeOutput::StartRedline( const SwRedlineData * pRedlineData )
2005 : {
2006 6496 : if ( !pRedlineData )
2007 12980 : return;
2008 :
2009 : // FIXME check if it's necessary to travel over the Next()'s in pRedlineData
2010 :
2011 12 : OString aId( OString::number( m_nRedlineId++ ) );
2012 :
2013 24 : const OUString &rAuthor( SW_MOD()->GetRedlineAuthor( pRedlineData->GetAuthor() ) );
2014 24 : OString aAuthor( OUStringToOString( rAuthor, RTL_TEXTENCODING_UTF8 ) );
2015 :
2016 24 : OString aDate( DateTimeToOString( pRedlineData->GetTimeStamp() ) );
2017 :
2018 12 : switch ( pRedlineData->GetType() )
2019 : {
2020 : case nsRedlineType_t::REDLINE_INSERT:
2021 : m_pSerializer->startElementNS( XML_w, XML_ins,
2022 : FSNS( XML_w, XML_id ), aId.getStr(),
2023 : FSNS( XML_w, XML_author ), aAuthor.getStr(),
2024 : FSNS( XML_w, XML_date ), aDate.getStr(),
2025 5 : FSEND );
2026 5 : break;
2027 :
2028 : case nsRedlineType_t::REDLINE_DELETE:
2029 : m_pSerializer->startElementNS( XML_w, XML_del,
2030 : FSNS( XML_w, XML_id ), aId.getStr(),
2031 : FSNS( XML_w, XML_author ), aAuthor.getStr(),
2032 : FSNS( XML_w, XML_date ), aDate.getStr(),
2033 5 : FSEND );
2034 5 : break;
2035 :
2036 : case nsRedlineType_t::REDLINE_FORMAT:
2037 : OSL_TRACE( "TODO DocxAttributeOutput::StartRedline()" );
2038 : default:
2039 2 : break;
2040 12 : }
2041 : }
2042 :
2043 6496 : void DocxAttributeOutput::EndRedline( const SwRedlineData * pRedlineData )
2044 : {
2045 6496 : if ( !pRedlineData )
2046 12980 : return;
2047 :
2048 12 : switch ( pRedlineData->GetType() )
2049 : {
2050 : case nsRedlineType_t::REDLINE_INSERT:
2051 5 : m_pSerializer->endElementNS( XML_w, XML_ins );
2052 5 : break;
2053 :
2054 : case nsRedlineType_t::REDLINE_DELETE:
2055 5 : m_pSerializer->endElementNS( XML_w, XML_del );
2056 5 : break;
2057 :
2058 : case nsRedlineType_t::REDLINE_FORMAT:
2059 : OSL_TRACE( "TODO DocxAttributeOutput::EndRedline()" );
2060 2 : break;
2061 : default:
2062 0 : break;
2063 : }
2064 : }
2065 :
2066 0 : void DocxAttributeOutput::FormatDrop( const SwTxtNode& /*rNode*/, const SwFmtDrop& /*rSwFmtDrop*/, sal_uInt16 /*nStyle*/, ww8::WW8TableNodeInfo::Pointer_t /*pTextNodeInfo*/, ww8::WW8TableNodeInfoInner::Pointer_t )
2067 : {
2068 : OSL_TRACE( "TODO DocxAttributeOutput::FormatDrop( const SwTxtNode& rNode, const SwFmtDrop& rSwFmtDrop, sal_uInt16 nStyle )" );
2069 0 : }
2070 :
2071 5189 : void DocxAttributeOutput::ParagraphStyle( sal_uInt16 nStyle )
2072 : {
2073 5189 : OString aStyleId(m_rExport.pStyles->GetStyleId(nStyle));
2074 :
2075 5189 : m_pSerializer->singleElementNS( XML_w, XML_pStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND );
2076 5189 : }
2077 :
2078 9184 : static void impl_borderLine( FSHelperPtr pSerializer, sal_Int32 elementToken, const SvxBorderLine* pBorderLine, sal_uInt16 nDist,
2079 : bool bWriteShadow = false, const table::BorderLine2* rStyleProps = NULL )
2080 : {
2081 9184 : FastAttributeList* pAttr = pSerializer->createAttrList();
2082 :
2083 : // Compute val attribute value
2084 : // Can be one of:
2085 : // single, double,
2086 : // basicWideOutline, basicWideInline
2087 : // OOXml also supports those types of borders, but we'll try to play with the first ones.
2088 : // thickThinMediumGap, thickThinLargeGap, thickThinSmallGap
2089 : // thinThickLargeGap, thinThickMediumGap, thinThickSmallGap
2090 9184 : const char* pVal = "nil";
2091 9184 : if ( pBorderLine && !pBorderLine->isEmpty( ) )
2092 : {
2093 6185 : switch (pBorderLine->GetBorderLineStyle())
2094 : {
2095 : case table::BorderLineStyle::SOLID:
2096 6112 : pVal = ( sal_Char* )"single";
2097 6112 : break;
2098 : case table::BorderLineStyle::DOTTED:
2099 0 : pVal = ( sal_Char* )"dotted";
2100 0 : break;
2101 : case table::BorderLineStyle::DASHED:
2102 8 : pVal = ( sal_Char* )"dashed";
2103 8 : break;
2104 : case table::BorderLineStyle::DOUBLE:
2105 5 : pVal = ( sal_Char* )"double";
2106 5 : break;
2107 : case table::BorderLineStyle::THINTHICK_SMALLGAP:
2108 5 : pVal = ( sal_Char* )"thinThickSmallGap";
2109 5 : break;
2110 : case table::BorderLineStyle::THINTHICK_MEDIUMGAP:
2111 0 : pVal = ( sal_Char* )"thinThickMediumGap";
2112 0 : break;
2113 : case table::BorderLineStyle::THINTHICK_LARGEGAP:
2114 0 : pVal = ( sal_Char* )"thinThickLargeGap";
2115 0 : break;
2116 : case table::BorderLineStyle::THICKTHIN_SMALLGAP:
2117 5 : pVal = ( sal_Char* )"thickThinSmallGap";
2118 5 : break;
2119 : case table::BorderLineStyle::THICKTHIN_MEDIUMGAP:
2120 0 : pVal = ( sal_Char* )"thickThinMediumGap";
2121 0 : break;
2122 : case table::BorderLineStyle::THICKTHIN_LARGEGAP:
2123 30 : pVal = ( sal_Char* )"thickThinLargeGap";
2124 30 : break;
2125 : case table::BorderLineStyle::EMBOSSED:
2126 0 : pVal = ( sal_Char* )"threeDEmboss";
2127 0 : break;
2128 : case table::BorderLineStyle::ENGRAVED:
2129 0 : pVal = ( sal_Char* )"threeDEngrave";
2130 0 : break;
2131 : case table::BorderLineStyle::OUTSET:
2132 0 : pVal = ( sal_Char* )"outset";
2133 0 : break;
2134 : case table::BorderLineStyle::INSET:
2135 0 : pVal = ( sal_Char* )"inset";
2136 0 : break;
2137 : case table::BorderLineStyle::FINE_DASHED:
2138 20 : pVal = ( sal_Char* )"dashSmallGap";
2139 20 : break;
2140 : case table::BorderLineStyle::NONE:
2141 : default:
2142 0 : break;
2143 : }
2144 : }
2145 2999 : else if( rStyleProps == NULL )
2146 : // no line, and no line set by the style either:
2147 : // there is no need to write the property
2148 9350 : return;
2149 :
2150 : // compare the properties with the theme properties before writing them:
2151 : // if they are equal, it means that they were style-defined and there is
2152 : // no need to write them.
2153 23309 : if( rStyleProps != NULL && pBorderLine && !pBorderLine->isEmpty() &&
2154 11678 : pBorderLine->GetBorderLineStyle() == rStyleProps->LineStyle &&
2155 28328 : pBorderLine->GetColor() == rStyleProps->Color &&
2156 3886 : (sal_uInt32) pBorderLine->GetWidth() == MM100_TO_TWIP_UNSIGNED( rStyleProps->LineWidth ) )
2157 3766 : return;
2158 :
2159 2626 : pAttr->add( FSNS( XML_w, XML_val ), OString( pVal ) );
2160 :
2161 2626 : if ( pBorderLine && !pBorderLine->isEmpty() )
2162 : {
2163 : // Compute the sz attribute
2164 :
2165 : double const fConverted( ::editeng::ConvertBorderWidthToWord(
2166 2419 : pBorderLine->GetBorderLineStyle(), pBorderLine->GetWidth()));
2167 : // The unit is the 8th of point
2168 2419 : sal_Int32 nWidth = sal_Int32( fConverted / 2.5 );
2169 2419 : sal_uInt16 nMinWidth = 2;
2170 2419 : sal_uInt16 nMaxWidth = 96;
2171 :
2172 2419 : if ( nWidth > nMaxWidth )
2173 0 : nWidth = nMaxWidth;
2174 2419 : else if ( nWidth < nMinWidth )
2175 12 : nWidth = nMinWidth;
2176 :
2177 2419 : pAttr->add( FSNS( XML_w, XML_sz ), OString::number( nWidth ) );
2178 :
2179 : // Get the distance (in pt)
2180 2419 : pAttr->add( FSNS( XML_w, XML_space ), OString::number( nDist / 20 ) );
2181 :
2182 : // Get the color code as an RRGGBB hex value
2183 2419 : OString sColor( msfilter::util::ConvertColor( pBorderLine->GetColor( ) ) );
2184 2419 : pAttr->add( FSNS( XML_w, XML_color ), sColor );
2185 : }
2186 :
2187 2626 : if (bWriteShadow)
2188 : {
2189 : // Set the shadow value
2190 18 : pAttr->add( FSNS( XML_w, XML_shadow ), "1" );
2191 : }
2192 :
2193 2626 : XFastAttributeListRef xAttrs( pAttr );
2194 2626 : pSerializer->singleElementNS( XML_w, elementToken, xAttrs );
2195 : }
2196 :
2197 94 : static OutputBorderOptions lcl_getTableDefaultBorderOptions(bool bEcma)
2198 : {
2199 94 : OutputBorderOptions rOptions;
2200 :
2201 94 : rOptions.tag = XML_tblBorders;
2202 94 : rOptions.bUseStartEnd = !bEcma;
2203 94 : rOptions.bWriteTag = true;
2204 94 : rOptions.bWriteInsideHV = true;
2205 94 : rOptions.bWriteDistance = false;
2206 94 : rOptions.aShadowLocation = SVX_SHADOW_NONE;
2207 94 : rOptions.bCheckDistanceSize = false;
2208 :
2209 94 : return rOptions;
2210 : }
2211 :
2212 1389 : static OutputBorderOptions lcl_getTableCellBorderOptions(bool bEcma)
2213 : {
2214 1389 : OutputBorderOptions rOptions;
2215 :
2216 1389 : rOptions.tag = XML_tcBorders;
2217 1389 : rOptions.bUseStartEnd = !bEcma;
2218 1389 : rOptions.bWriteTag = true;
2219 1389 : rOptions.bWriteInsideHV = true;
2220 1389 : rOptions.bWriteDistance = false;
2221 1389 : rOptions.aShadowLocation = SVX_SHADOW_NONE;
2222 1389 : rOptions.bCheckDistanceSize = false;
2223 :
2224 1389 : return rOptions;
2225 : }
2226 :
2227 74 : static OutputBorderOptions lcl_getBoxBorderOptions()
2228 : {
2229 74 : OutputBorderOptions rOptions;
2230 :
2231 74 : rOptions.tag = XML_pBdr;
2232 74 : rOptions.bUseStartEnd = false;
2233 74 : rOptions.bWriteTag = false;
2234 74 : rOptions.bWriteInsideHV = false;
2235 74 : rOptions.bWriteDistance = true;
2236 74 : rOptions.aShadowLocation = SVX_SHADOW_NONE;
2237 74 : rOptions.bCheckDistanceSize = false;
2238 :
2239 74 : return rOptions;
2240 : }
2241 :
2242 8 : static bool boxHasLineLargerThan31(const SvxBoxItem& rBox)
2243 : {
2244 : return (
2245 12 : ( rBox.GetDistance( BOX_LINE_TOP ) / 20 ) > 31 ||
2246 4 : ( rBox.GetDistance( BOX_LINE_LEFT ) / 20 ) > 31 ||
2247 8 : ( rBox.GetDistance( BOX_LINE_BOTTOM ) / 20 ) > 31 ||
2248 0 : ( rBox.GetDistance( BOX_LINE_RIGHT ) / 20 ) > 31
2249 8 : );
2250 : }
2251 :
2252 1553 : static void impl_borders( FSHelperPtr pSerializer, const SvxBoxItem& rBox, const OutputBorderOptions& rOptions, PageMargins* pageMargins,
2253 : std::map<sal_uInt16, css::table::BorderLine2> &rTableStyleConf )
2254 : {
2255 : static const sal_uInt16 aBorders[] =
2256 : {
2257 : BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
2258 : };
2259 :
2260 : const sal_Int32 aXmlElements[] =
2261 : {
2262 : XML_top,
2263 : rOptions.bUseStartEnd ? XML_start : XML_left,
2264 : XML_bottom,
2265 : rOptions.bUseStartEnd ? XML_end : XML_right
2266 1553 : };
2267 1553 : bool tagWritten = false;
2268 1553 : const sal_uInt16* pBrd = aBorders;
2269 :
2270 1553 : bool bExportDistanceFromPageEdge = false;
2271 1553 : if ( rOptions.bCheckDistanceSize == true && boxHasLineLargerThan31(rBox) == true )
2272 : {
2273 : // The distance is larger than '31'. This cannot be exported as 'distance from text'.
2274 : // Instead - it should be exported as 'distance from page edge'.
2275 : // This is based on http://wiki.openoffice.org/wiki/Writer/MSInteroperability/PageBorder
2276 : // Specifically 'export case #2'
2277 4 : bExportDistanceFromPageEdge = true;
2278 : }
2279 :
2280 1553 : bool bWriteInsideH = false;
2281 1553 : bool bWriteInsideV = false;
2282 7765 : for( int i = 0; i < 4; ++i, ++pBrd )
2283 : {
2284 6212 : const SvxBorderLine* pLn = rBox.GetLine( *pBrd );
2285 6212 : const table::BorderLine2 *aStyleProps = NULL;
2286 6212 : if( rTableStyleConf.find( *pBrd ) != rTableStyleConf.end() )
2287 2742 : aStyleProps = &rTableStyleConf[ *pBrd ];
2288 :
2289 6212 : if (!tagWritten && rOptions.bWriteTag)
2290 : {
2291 1483 : pSerializer->startElementNS( XML_w, rOptions.tag, FSEND );
2292 1483 : tagWritten = true;
2293 : }
2294 :
2295 6212 : bool bWriteShadow = false;
2296 6212 : if (rOptions.aShadowLocation == SVX_SHADOW_NONE)
2297 : {
2298 : // The border has no shadow
2299 : }
2300 16 : else if (rOptions.aShadowLocation == SVX_SHADOW_BOTTOMRIGHT)
2301 : {
2302 : // Special case of 'Bottom-Right' shadow:
2303 : // If the shadow location is 'Bottom-Right' - then turn on the shadow
2304 : // for ALL the sides. This is because in Word - if you select a shadow
2305 : // for a border - it turn on the shadow for ALL the sides (but shows only
2306 : // the bottom-right one).
2307 : // This is so that no information will be lost if passed through LibreOffice
2308 16 : bWriteShadow = true;
2309 : }
2310 : else
2311 : {
2312 : // If there is a shadow, and it's not the regular 'Bottom-Right',
2313 : // then write only the 'shadowed' sides of the border
2314 0 : if (
2315 0 : ( ( rOptions.aShadowLocation == SVX_SHADOW_TOPLEFT || rOptions.aShadowLocation == SVX_SHADOW_TOPRIGHT ) && *pBrd == BOX_LINE_TOP ) ||
2316 0 : ( ( rOptions.aShadowLocation == SVX_SHADOW_TOPLEFT || rOptions.aShadowLocation == SVX_SHADOW_BOTTOMLEFT ) && *pBrd == BOX_LINE_LEFT ) ||
2317 0 : ( ( rOptions.aShadowLocation == SVX_SHADOW_BOTTOMLEFT || rOptions.aShadowLocation == SVX_SHADOW_BOTTOMRIGHT ) && *pBrd == BOX_LINE_BOTTOM) ||
2318 0 : ( ( rOptions.aShadowLocation == SVX_SHADOW_TOPRIGHT || rOptions.aShadowLocation == SVX_SHADOW_BOTTOMRIGHT ) && *pBrd == BOX_LINE_RIGHT )
2319 : )
2320 : {
2321 0 : bWriteShadow = true;
2322 : }
2323 : }
2324 :
2325 6212 : sal_uInt16 nDist = 0;
2326 6212 : if (rOptions.bWriteDistance)
2327 : {
2328 280 : if (bExportDistanceFromPageEdge)
2329 : {
2330 : // Export 'Distance from Page Edge'
2331 16 : if ( *pBrd == BOX_LINE_TOP)
2332 4 : nDist = pageMargins->nPageMarginTop - rBox.GetDistance( *pBrd );
2333 12 : else if ( *pBrd == BOX_LINE_LEFT)
2334 4 : nDist = pageMargins->nPageMarginLeft - rBox.GetDistance( *pBrd );
2335 8 : else if ( *pBrd == BOX_LINE_BOTTOM)
2336 4 : nDist = pageMargins->nPageMarginBottom - rBox.GetDistance( *pBrd );
2337 4 : else if ( *pBrd == BOX_LINE_RIGHT)
2338 4 : nDist = pageMargins->nPageMarginRight - rBox.GetDistance( *pBrd );
2339 : }
2340 : else
2341 : {
2342 : // Export 'Distance from text'
2343 264 : nDist = rBox.GetDistance( *pBrd );
2344 : }
2345 : }
2346 :
2347 6212 : impl_borderLine( pSerializer, aXmlElements[i], pLn, nDist, bWriteShadow, aStyleProps );
2348 :
2349 : // When exporting default borders, we need to export these 2 attr
2350 6212 : if ( rOptions.bWriteInsideHV) {
2351 5932 : if ( i == 2 )
2352 1483 : bWriteInsideH = true;
2353 4449 : else if ( i == 3 )
2354 1483 : bWriteInsideV = true;
2355 : }
2356 : }
2357 1553 : if (bWriteInsideH)
2358 : {
2359 1483 : const table::BorderLine2 *aStyleProps = NULL;
2360 1483 : if( rTableStyleConf.find( BOX_LINE_BOTTOM ) != rTableStyleConf.end() )
2361 689 : aStyleProps = &rTableStyleConf[ BOX_LINE_BOTTOM ];
2362 1483 : impl_borderLine( pSerializer, XML_insideH, rBox.GetLine(BOX_LINE_BOTTOM), 0, false, aStyleProps );
2363 : }
2364 1553 : if (bWriteInsideV)
2365 : {
2366 1483 : const table::BorderLine2 *aStyleProps = NULL;
2367 1483 : if( rTableStyleConf.find( BOX_LINE_RIGHT ) != rTableStyleConf.end() )
2368 682 : aStyleProps = &rTableStyleConf[ BOX_LINE_RIGHT ];
2369 1483 : impl_borderLine( pSerializer, XML_insideV, rBox.GetLine(BOX_LINE_RIGHT), 0, false, aStyleProps );
2370 : }
2371 1553 : if (tagWritten && rOptions.bWriteTag) {
2372 1483 : pSerializer->endElementNS( XML_w, rOptions.tag );
2373 : }
2374 1553 : }
2375 :
2376 1483 : static void impl_cellMargins( FSHelperPtr pSerializer, const SvxBoxItem& rBox, sal_Int32 tag, bool bUseStartEnd = false, const SvxBoxItem* pDefaultMargins = 0)
2377 : {
2378 : static const sal_uInt16 aBorders[] =
2379 : {
2380 : BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
2381 : };
2382 :
2383 : const sal_Int32 aXmlElements[] =
2384 : {
2385 : XML_top,
2386 : bUseStartEnd ? XML_start : XML_left,
2387 : XML_bottom,
2388 : bUseStartEnd ? XML_end : XML_right
2389 1483 : };
2390 1483 : bool tagWritten = false;
2391 1483 : const sal_uInt16* pBrd = aBorders;
2392 7415 : for( int i = 0; i < 4; ++i, ++pBrd )
2393 : {
2394 5932 : sal_Int32 nDist = sal_Int32( rBox.GetDistance( *pBrd ) );
2395 :
2396 5932 : if ( aBorders[i] == BOX_LINE_LEFT ) {
2397 : // Office's cell margin is measured from the right of the border.
2398 : // While LO's cell spacing is measured from the center of the border.
2399 : // So we add half left-border width to tblIndent value
2400 1483 : const SvxBorderLine* pLn = rBox.GetLine( *pBrd );
2401 1483 : if (pLn)
2402 964 : nDist -= pLn->GetWidth() * 0.5;
2403 : }
2404 :
2405 5932 : if (pDefaultMargins)
2406 : {
2407 : // Skip output if cell margin == table default margin
2408 5556 : if (sal_Int32( pDefaultMargins->GetDistance( *pBrd ) ) == nDist)
2409 4438 : continue;
2410 : }
2411 :
2412 1494 : if (!tagWritten) {
2413 1187 : pSerializer->startElementNS( XML_w, tag, FSEND );
2414 1187 : tagWritten = true;
2415 : }
2416 1494 : pSerializer->singleElementNS( XML_w, aXmlElements[i],
2417 : FSNS( XML_w, XML_w ), OString::number( nDist ).getStr( ),
2418 : FSNS( XML_w, XML_type ), "dxa",
2419 2988 : FSEND );
2420 : }
2421 1483 : if (tagWritten) {
2422 1187 : pSerializer->endElementNS( XML_w, tag );
2423 : }
2424 1483 : }
2425 :
2426 1389 : void DocxAttributeOutput::TableCellProperties( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2427 : {
2428 1389 : m_pSerializer->startElementNS( XML_w, XML_tcPr, FSEND );
2429 :
2430 1389 : const SwTableBox *pTblBox = pTableTextNodeInfoInner->getTableBox( );
2431 :
2432 1389 : bool bEcma = GetExport().GetFilter().getVersion( ) == oox::core::ECMA_DIALECT;
2433 :
2434 : // Output any table cell redlines if there are any attached to this specific cell
2435 1389 : TableCellRedline( pTableTextNodeInfoInner );
2436 :
2437 : // Cell preferred width
2438 1389 : SwTwips nWidth = GetGridCols( pTableTextNodeInfoInner )->at( pTableTextNodeInfoInner->getCell() );
2439 1389 : if ( pTableTextNodeInfoInner->getCell() )
2440 874 : nWidth = nWidth - GetGridCols( pTableTextNodeInfoInner )->at( pTableTextNodeInfoInner->getCell() - 1 );
2441 : m_pSerializer->singleElementNS( XML_w, XML_tcW,
2442 : FSNS( XML_w, XML_w ), OString::number( nWidth ).getStr( ),
2443 : FSNS( XML_w, XML_type ), "dxa",
2444 1389 : FSEND );
2445 :
2446 : // Horizontal spans
2447 1389 : const SwWriteTableRows& aRows = m_pTableWrt->GetRows( );
2448 1389 : SwWriteTableRow *pRow = aRows[ pTableTextNodeInfoInner->getRow( ) ];
2449 1389 : sal_uInt32 nCell = pTableTextNodeInfoInner->getCell();
2450 1389 : const SwWriteTableCells *tableCells = &pRow->GetCells();
2451 1389 : if (nCell < tableCells->size() )
2452 : {
2453 1389 : const SwWriteTableCell *pCell = &pRow->GetCells( )[ pTableTextNodeInfoInner->getCell( ) ];
2454 :
2455 1389 : sal_uInt16 nColSpan = pCell->GetColSpan();
2456 1389 : if ( nColSpan > 1 )
2457 : m_pSerializer->singleElementNS( XML_w, XML_gridSpan,
2458 : FSNS( XML_w, XML_val ), OString::number( nColSpan ).getStr(),
2459 189 : FSEND );
2460 : }
2461 :
2462 : // Vertical merges
2463 1389 : long vSpan = pTblBox->getRowSpan( );
2464 1389 : if ( vSpan > 1 )
2465 : {
2466 : m_pSerializer->singleElementNS( XML_w, XML_vMerge,
2467 : FSNS( XML_w, XML_val ), "restart",
2468 12 : FSEND );
2469 : }
2470 1377 : else if ( vSpan < 0 )
2471 : {
2472 : m_pSerializer->singleElementNS( XML_w, XML_vMerge,
2473 : FSNS( XML_w, XML_val ), "continue",
2474 12 : FSEND );
2475 : }
2476 :
2477 1389 : const SvxBoxItem& rBox = pTblBox->GetFrmFmt( )->GetBox( );
2478 1389 : const SvxBoxItem& rDefaultBox = (*tableFirstCells.rbegin())->getTableBox( )->GetFrmFmt( )->GetBox( );
2479 : {
2480 : // The cell borders
2481 1389 : impl_borders( m_pSerializer, rBox, lcl_getTableCellBorderOptions(bEcma), NULL, m_aTableStyleConf );
2482 : }
2483 :
2484 1389 : TableBackgrounds( pTableTextNodeInfoInner );
2485 :
2486 : {
2487 : // Cell margins
2488 1389 : impl_cellMargins( m_pSerializer, rBox, XML_tcMar, !bEcma, &rDefaultBox );
2489 : }
2490 :
2491 1389 : TableVerticalCell( pTableTextNodeInfoInner );
2492 :
2493 1389 : m_pSerializer->endElementNS( XML_w, XML_tcPr );
2494 1389 : }
2495 :
2496 98 : void DocxAttributeOutput::InitTableHelper( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2497 : {
2498 98 : sal_uInt32 nPageSize = 0;
2499 98 : bool bRelBoxSize = false;
2500 :
2501 : // Create the SwWriteTable instance to use col spans (and maybe other infos)
2502 98 : GetTablePageSize( pTableTextNodeInfoInner.get(), nPageSize, bRelBoxSize );
2503 :
2504 98 : const SwTable* pTable = pTableTextNodeInfoInner->getTable( );
2505 98 : const SwFrmFmt *pFmt = pTable->GetFrmFmt( );
2506 98 : SwTwips nTblSz = pFmt->GetFrmSize( ).GetWidth( );
2507 :
2508 98 : const SwHTMLTableLayout *pLayout = pTable->GetHTMLTableLayout();
2509 98 : if( pLayout && pLayout->IsExportable() )
2510 0 : m_pTableWrt = new SwWriteTable( pLayout );
2511 : else
2512 : m_pTableWrt = new SwWriteTable( pTable->GetTabLines(), (sal_uInt16)nPageSize,
2513 98 : (sal_uInt16)nTblSz, false);
2514 98 : }
2515 :
2516 : /**
2517 : * As we are exporting Header and footer in between when we are exporting document.xml.
2518 : * In this case we are facing issue in table export for header and footer. Because
2519 : * flags for table is getting shared in both export.
2520 : * So we are switching between flags in between exporting "document.xml" and Header & footer
2521 : * export.
2522 : */
2523 799 : void DocxAttributeOutput::switchHeaderFooter(bool isHeaderFooter, sal_Int32 index)
2524 : {
2525 799 : if( isHeaderFooter && index == 1)
2526 : {
2527 191 : m_oldTableReference->m_bTableCellOpen = m_tableReference->m_bTableCellOpen;
2528 191 : m_oldTableReference->m_nTableDepth = m_tableReference->m_nTableDepth;
2529 191 : m_oldTableReference->m_pOldTablepInner = m_tableReference->m_pOldTablepInner;
2530 191 : m_tableReference->m_bTableCellOpen = false;
2531 191 : m_tableReference->m_nTableDepth = 0;
2532 191 : m_pSectionInfo.reset();
2533 : }
2534 608 : else if( index == -1)
2535 : {
2536 413 : if (m_oldTableReference->m_pOldTablepInner)
2537 : {
2538 25 : *m_tableReference = *m_oldTableReference;
2539 :
2540 : //Reset the oldReference, after copying it back to the original.
2541 25 : m_oldTableReference->m_bTableCellOpen = false ;
2542 25 : m_oldTableReference->m_nTableDepth = 0;
2543 : }
2544 :
2545 : }
2546 : else
2547 : {
2548 195 : m_tableReference->m_bTableCellOpen = false;
2549 195 : m_tableReference->m_nTableDepth = 0;
2550 : }
2551 799 : }
2552 :
2553 94 : void DocxAttributeOutput::StartTable( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2554 : {
2555 94 : m_pSerializer->startElementNS( XML_w, XML_tbl, FSEND );
2556 :
2557 94 : tableFirstCells.push_back(pTableTextNodeInfoInner);
2558 :
2559 94 : InitTableHelper( pTableTextNodeInfoInner );
2560 94 : TableDefinition( pTableTextNodeInfoInner );
2561 94 : }
2562 :
2563 94 : void DocxAttributeOutput::EndTable()
2564 : {
2565 94 : m_pSerializer->endElementNS( XML_w, XML_tbl );
2566 :
2567 94 : if ( m_tableReference->m_nTableDepth > 0 )
2568 94 : --m_tableReference->m_nTableDepth;
2569 :
2570 94 : tableFirstCells.pop_back();
2571 :
2572 : // We closed the table; if it is a nested table, the cell that contains it
2573 : // still continues
2574 : // set to true only if we were in a nested table, not otherwise.
2575 94 : if( 0 != tableFirstCells.size() )
2576 10 : m_tableReference->m_bTableCellOpen = true;
2577 :
2578 : // Cleans the table helper
2579 94 : delete m_pTableWrt, m_pTableWrt = NULL;
2580 :
2581 94 : m_aTableStyleConf.clear();
2582 94 : }
2583 :
2584 515 : void DocxAttributeOutput::StartTableRow( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2585 : {
2586 515 : m_pSerializer->startElementNS( XML_w, XML_tr, FSEND );
2587 :
2588 : // Output the row properties
2589 515 : m_pSerializer->startElementNS( XML_w, XML_trPr, FSEND );
2590 :
2591 : // Header row: tblHeader
2592 515 : const SwTable *pTable = pTableTextNodeInfoInner->getTable( );
2593 515 : if ( pTable->GetRowsToRepeat( ) > pTableTextNodeInfoInner->getRow( ) )
2594 : m_pSerializer->singleElementNS( XML_w, XML_tblHeader,
2595 : FSNS( XML_w, XML_val ), "true",
2596 2 : FSEND );
2597 :
2598 515 : TableRowRedline( pTableTextNodeInfoInner );
2599 515 : TableHeight( pTableTextNodeInfoInner );
2600 515 : TableCanSplit( pTableTextNodeInfoInner );
2601 :
2602 515 : m_pSerializer->endElementNS( XML_w, XML_trPr );
2603 515 : }
2604 :
2605 515 : void DocxAttributeOutput::EndTableRow( )
2606 : {
2607 515 : m_pSerializer->endElementNS( XML_w, XML_tr );
2608 515 : }
2609 :
2610 1389 : void DocxAttributeOutput::StartTableCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2611 : {
2612 1389 : if ( !m_pTableWrt )
2613 4 : InitTableHelper( pTableTextNodeInfoInner );
2614 :
2615 1389 : m_pSerializer->startElementNS( XML_w, XML_tc, FSEND );
2616 :
2617 : // Write the cell properties here
2618 1389 : TableCellProperties( pTableTextNodeInfoInner );
2619 :
2620 1389 : m_tableReference->m_bTableCellOpen = true;
2621 1389 : }
2622 :
2623 1389 : void DocxAttributeOutput::EndTableCell( )
2624 : {
2625 1389 : m_pSerializer->endElementNS( XML_w, XML_tc );
2626 :
2627 1389 : m_bBtLr = false;
2628 1389 : m_tableReference->m_bTableCellOpen = false;
2629 1389 : }
2630 :
2631 1602 : void DocxAttributeOutput::TableInfoCell( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
2632 : {
2633 1602 : }
2634 :
2635 0 : void DocxAttributeOutput::TableInfoRow( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfo*/ )
2636 : {
2637 0 : }
2638 :
2639 94 : void DocxAttributeOutput::TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2640 : {
2641 94 : bool bEcma = GetExport().GetFilter().getVersion( ) == oox::core::ECMA_DIALECT;
2642 :
2643 : // Write the table properties
2644 94 : m_pSerializer->startElementNS( XML_w, XML_tblPr, FSEND );
2645 :
2646 : static const sal_Int32 aOrder[] =
2647 : {
2648 : FSNS( XML_w, XML_tblStyle ),
2649 : FSNS( XML_w, XML_tblpPr ),
2650 : FSNS( XML_w, XML_tblOverlap ),
2651 : FSNS( XML_w, XML_bidiVisual ),
2652 : FSNS( XML_w, XML_tblStyleRowBandSize ),
2653 : FSNS( XML_w, XML_tblStyleColBandSize ),
2654 : FSNS( XML_w, XML_tblW ),
2655 : FSNS( XML_w, XML_jc ),
2656 : FSNS( XML_w, XML_tblCellSpacing ),
2657 : FSNS( XML_w, XML_tblInd ),
2658 : FSNS( XML_w, XML_tblBorders ),
2659 : FSNS( XML_w, XML_shd ),
2660 : FSNS( XML_w, XML_tblLayout ),
2661 : FSNS( XML_w, XML_tblCellMar ),
2662 : FSNS( XML_w, XML_tblLook ),
2663 : FSNS( XML_w, XML_tblPrChange )
2664 : };
2665 :
2666 : // postpone the output so that we can later []
2667 : // prepend the properties before the run
2668 94 : sal_Int32 len = sizeof ( aOrder ) / sizeof( sal_Int32 );
2669 94 : uno::Sequence< sal_Int32 > aSeqOrder( len );
2670 1598 : for ( sal_Int32 i = 0; i < len; i++ )
2671 1504 : aSeqOrder[i] = aOrder[i];
2672 :
2673 94 : m_pSerializer->mark( aSeqOrder );
2674 :
2675 94 : sal_uInt32 nPageSize = 0;
2676 94 : const char* widthType = "dxa";
2677 94 : bool bRelBoxSize = false;
2678 :
2679 : // If actual width of table is relative it shoud export is as "auto".
2680 94 : const SwTable *pTable = pTableTextNodeInfoInner->getTable();
2681 94 : SwFrmFmt *pTblFmt = pTable->GetFrmFmt( );
2682 188 : uno::Reference<beans::XPropertySet> xPropertySet(SwXTextTables::GetObject(const_cast<SwFrmFmt&>(*pTable->GetFrmFmt( ))),uno::UNO_QUERY);
2683 94 : bool isWidthRelative = false;
2684 94 : xPropertySet->getPropertyValue("IsWidthRelative") >>= isWidthRelative;
2685 :
2686 94 : if(isWidthRelative)
2687 : {
2688 9 : nPageSize = 0;
2689 9 : widthType = "auto";
2690 : }
2691 : else
2692 : {
2693 : // Create the SwWriteTable instance to use col spans (and maybe other infos)
2694 85 : GetTablePageSize( pTableTextNodeInfoInner.get(), nPageSize, bRelBoxSize );
2695 85 : if(nPageSize == 0)
2696 84 : widthType = "auto";
2697 : }
2698 :
2699 : // Output the table preferred width
2700 : m_pSerializer->singleElementNS( XML_w, XML_tblW,
2701 : FSNS( XML_w, XML_w ), OString::number( nPageSize ).getStr( ),
2702 : FSNS( XML_w, XML_type ), widthType,
2703 94 : FSEND );
2704 :
2705 : // Look for the table style property in the table grab bag
2706 : std::map<OUString, com::sun::star::uno::Any> aGrabBag =
2707 188 : sw::util::HasItem<SfxGrabBagItem>( pTblFmt->GetAttrSet(), RES_FRMATR_GRABBAG )->GetGrabBag();
2708 :
2709 : // Extract properties from grab bag
2710 94 : std::map<OUString, com::sun::star::uno::Any>::iterator aGrabBagElement;
2711 265 : for( aGrabBagElement = aGrabBag.begin(); aGrabBagElement != aGrabBag.end(); ++aGrabBagElement )
2712 : {
2713 171 : if( aGrabBagElement->first == "TableStyleName")
2714 : {
2715 37 : OString sStyleName = OUStringToOString( aGrabBagElement->second.get<OUString>(), RTL_TEXTENCODING_UTF8 );
2716 : m_pSerializer->singleElementNS( XML_w, XML_tblStyle,
2717 : FSNS( XML_w, XML_val ), sStyleName.getStr(),
2718 37 : FSEND );
2719 : }
2720 134 : else if( aGrabBagElement->first == "TableStyleTopBorder" )
2721 34 : m_aTableStyleConf[ BOX_LINE_TOP ] = aGrabBagElement->second.get<table::BorderLine2>();
2722 100 : else if( aGrabBagElement->first == "TableStyleBottomBorder" )
2723 34 : m_aTableStyleConf[ BOX_LINE_BOTTOM ] = aGrabBagElement->second.get<table::BorderLine2>();
2724 66 : else if( aGrabBagElement->first == "TableStyleLeftBorder" )
2725 33 : m_aTableStyleConf[ BOX_LINE_LEFT ] = aGrabBagElement->second.get<table::BorderLine2>();
2726 33 : else if( aGrabBagElement->first == "TableStyleRightBorder" )
2727 33 : m_aTableStyleConf[ BOX_LINE_RIGHT ] = aGrabBagElement->second.get<table::BorderLine2>();
2728 : }
2729 :
2730 : // Output the table alignement
2731 : const char* pJcVal;
2732 94 : sal_Int32 nIndent = 0;
2733 94 : switch ( pTblFmt->GetHoriOrient( ).GetHoriOrient( ) )
2734 : {
2735 : case text::HoriOrientation::CENTER:
2736 11 : pJcVal = "center";
2737 11 : break;
2738 : case text::HoriOrientation::RIGHT:
2739 0 : if ( bEcma )
2740 0 : pJcVal = "right";
2741 : else
2742 0 : pJcVal = "end";
2743 0 : break;
2744 : default:
2745 : case text::HoriOrientation::NONE:
2746 : case text::HoriOrientation::LEFT_AND_WIDTH:
2747 : {
2748 83 : if ( bEcma )
2749 0 : pJcVal = "left";
2750 : else
2751 83 : pJcVal = "start";
2752 83 : nIndent = sal_Int32( pTblFmt->GetLRSpace( ).GetLeft( ) );
2753 : // Table indentation has different meaning in Word, depending if the table is nested or not.
2754 : // If nested, tblInd is added to parent table's left spacing and defines left edge position
2755 : // If not nested, text position of left-most cell must be at absolute X = tblInd
2756 : // so, table_spacing + table_spacing_to_content = tblInd
2757 83 : if (m_tableReference->m_nTableDepth == 0)
2758 : {
2759 81 : const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
2760 81 : const SwFrmFmt * pFrmFmt = pTabBox->GetFrmFmt();
2761 81 : nIndent += sal_Int32( pFrmFmt->GetBox( ).GetDistance( BOX_LINE_LEFT ) );
2762 : }
2763 83 : break;
2764 : }
2765 : }
2766 : m_pSerializer->singleElementNS( XML_w, XML_jc,
2767 : FSNS( XML_w, XML_val ), pJcVal,
2768 94 : FSEND );
2769 :
2770 : // Output the table borders
2771 94 : TableDefaultBorders( pTableTextNodeInfoInner );
2772 :
2773 : // Output the default cell margins
2774 94 : TableDefaultCellMargins( pTableTextNodeInfoInner );
2775 :
2776 94 : TableBidi( pTableTextNodeInfoInner );
2777 :
2778 : // Table indent (need to get written even if == 0)
2779 : m_pSerializer->singleElementNS( XML_w, XML_tblInd,
2780 : FSNS( XML_w, XML_w ), OString::number( nIndent ).getStr( ),
2781 : FSNS( XML_w, XML_type ), "dxa",
2782 94 : FSEND );
2783 :
2784 : // Merge the marks for the ordered elements
2785 94 : m_pSerializer->mergeTopMarks( );
2786 :
2787 94 : m_pSerializer->endElementNS( XML_w, XML_tblPr );
2788 :
2789 : // Write the table grid infos
2790 94 : m_pSerializer->startElementNS( XML_w, XML_tblGrid, FSEND );
2791 94 : sal_Int32 nPrv = 0;
2792 94 : ww8::WidthsPtr pColumnWidths = GetColumnWidths( pTableTextNodeInfoInner );
2793 386 : for ( ww8::Widths::const_iterator it = pColumnWidths->begin(); it != pColumnWidths->end(); ++it )
2794 : {
2795 292 : sal_Int32 nWidth = sal_Int32( *it ) - nPrv;
2796 : m_pSerializer->singleElementNS( XML_w, XML_gridCol,
2797 : FSNS( XML_w, XML_w ), OString::number( nWidth ).getStr( ),
2798 292 : FSEND );
2799 292 : nPrv = sal_Int32( *it );
2800 : }
2801 :
2802 188 : m_pSerializer->endElementNS( XML_w, XML_tblGrid );
2803 94 : }
2804 :
2805 94 : void DocxAttributeOutput::TableDefaultBorders( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2806 : {
2807 94 : const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
2808 94 : const SwFrmFmt * pFrmFmt = pTabBox->GetFrmFmt();
2809 :
2810 94 : bool bEcma = GetExport().GetFilter().getVersion( ) == oox::core::ECMA_DIALECT;
2811 :
2812 : // the defaults of the table are taken from the top-left cell
2813 94 : impl_borders( m_pSerializer, pFrmFmt->GetBox( ), lcl_getTableDefaultBorderOptions(bEcma), NULL, m_aTableStyleConf );
2814 94 : }
2815 :
2816 94 : void DocxAttributeOutput::TableDefaultCellMargins( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2817 : {
2818 94 : const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
2819 94 : const SwFrmFmt * pFrmFmt = pTabBox->GetFrmFmt();
2820 94 : const SvxBoxItem& rBox = pFrmFmt->GetBox( );
2821 94 : const bool bEcma = GetExport().GetFilter().getVersion( ) == oox::core::ECMA_DIALECT;
2822 :
2823 94 : impl_cellMargins(m_pSerializer, rBox, XML_tblCellMar, !bEcma);
2824 94 : }
2825 :
2826 1389 : void DocxAttributeOutput::TableBackgrounds( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2827 : {
2828 1389 : const SwTableBox *pTblBox = pTableTextNodeInfoInner->getTableBox( );
2829 1389 : const SwFrmFmt *pFmt = pTblBox->GetFrmFmt( );
2830 :
2831 1389 : const SvxBrushItem *aColorProp = sw::util::HasItem<SvxBrushItem>( pFmt->GetAttrSet(), RES_BACKGROUND );
2832 1389 : Color aColor = aColorProp ? aColorProp->GetColor() : COL_AUTO;
2833 1389 : OString sColor = msfilter::util::ConvertColor( aColor );
2834 :
2835 : std::map<OUString, com::sun::star::uno::Any> aGrabBag =
2836 2778 : sw::util::HasItem<SfxGrabBagItem>( pFmt->GetAttrSet(), RES_FRMATR_GRABBAG )->GetGrabBag();
2837 :
2838 2778 : OString sOriginalColor;
2839 1389 : std::map<OUString, com::sun::star::uno::Any>::iterator aGrabBagElement = aGrabBag.find("fill");
2840 1389 : if( aGrabBagElement != aGrabBag.end() )
2841 172 : sOriginalColor = OUStringToOString( aGrabBagElement->second.get<OUString>(), RTL_TEXTENCODING_UTF8 );
2842 :
2843 1389 : if ( sOriginalColor != sColor )
2844 : {
2845 : // color changed by the user, or no grab bag: write sColor
2846 : m_pSerializer->singleElementNS( XML_w, XML_shd,
2847 : FSNS( XML_w, XML_fill ), sColor.getStr( ),
2848 : FSNS( XML_w, XML_val ), "clear",
2849 1267 : FSEND );
2850 : }
2851 : else
2852 : {
2853 122 : ::sax_fastparser::FastAttributeList* aAttrList = NULL;
2854 122 : AddToAttrList( aAttrList, FSNS( XML_w, XML_fill ), sColor.getStr() );
2855 :
2856 539 : for( aGrabBagElement = aGrabBag.begin(); aGrabBagElement != aGrabBag.end(); ++aGrabBagElement )
2857 : {
2858 417 : OString sValue = OUStringToOString( aGrabBagElement->second.get<OUString>(), RTL_TEXTENCODING_UTF8 );
2859 417 : if( aGrabBagElement->first == "themeFill")
2860 32 : AddToAttrList( aAttrList, FSNS( XML_w, XML_themeFill ), sValue.getStr() );
2861 385 : else if( aGrabBagElement->first == "themeFillTint")
2862 7 : AddToAttrList( aAttrList, FSNS( XML_w, XML_themeFillTint ), sValue.getStr() );
2863 378 : else if( aGrabBagElement->first == "themeFillShade")
2864 24 : AddToAttrList( aAttrList, FSNS( XML_w, XML_themeFillShade ), sValue.getStr() );
2865 354 : else if( aGrabBagElement->first == "color")
2866 110 : AddToAttrList( aAttrList, FSNS( XML_w, XML_color ), sValue.getStr() );
2867 244 : else if( aGrabBagElement->first == "val")
2868 122 : AddToAttrList( aAttrList, FSNS( XML_w, XML_val ), sValue.getStr() );
2869 417 : }
2870 : m_pSerializer->singleElementNS( XML_w, XML_shd,
2871 122 : XFastAttributeListRef( aAttrList ) );
2872 1389 : }
2873 1389 : }
2874 :
2875 515 : void DocxAttributeOutput::TableRowRedline( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2876 : {
2877 515 : const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
2878 515 : const SwTableLine * pTabLine = pTabBox->GetUpper();
2879 :
2880 : // search next Redline
2881 515 : const SwExtraRedlineTbl& aExtraRedlineTbl = m_rExport.pDoc->GetExtraRedlineTbl();
2882 527 : for(sal_uInt16 nCurRedlinePos = 0; nCurRedlinePos < aExtraRedlineTbl.GetSize(); ++nCurRedlinePos )
2883 : {
2884 12 : SwExtraRedline* pExtraRedline = aExtraRedlineTbl.GetRedline(nCurRedlinePos);
2885 12 : const SwTableRowRedline* pTableRowRedline = dynamic_cast<const SwTableRowRedline*>(pExtraRedline);
2886 12 : const SwTableLine *pRedTabLine = pTableRowRedline ? &pTableRowRedline->GetTableLine() : NULL;
2887 12 : if (pRedTabLine == pTabLine)
2888 : {
2889 : // Redline for this table row
2890 2 : const SwRedlineData& aRedlineData = pTableRowRedline->GetRedlineData();
2891 2 : sal_uInt16 nRedlineType = aRedlineData.GetType();
2892 2 : switch (nRedlineType)
2893 : {
2894 : case nsRedlineType_t::REDLINE_TABLE_ROW_INSERT:
2895 : case nsRedlineType_t::REDLINE_TABLE_ROW_DELETE:
2896 : {
2897 2 : OString aId( OString::number( m_nRedlineId++ ) );
2898 4 : const OUString &rAuthor( SW_MOD()->GetRedlineAuthor( aRedlineData.GetAuthor() ) );
2899 4 : OString aAuthor( OUStringToOString( rAuthor, RTL_TEXTENCODING_UTF8 ) );
2900 :
2901 4 : OString aDate( DateTimeToOString( aRedlineData.GetTimeStamp() ) );
2902 :
2903 2 : if (nRedlineType == nsRedlineType_t::REDLINE_TABLE_ROW_INSERT)
2904 : m_pSerializer->singleElementNS( XML_w, XML_ins,
2905 : FSNS( XML_w, XML_id ), aId.getStr(),
2906 : FSNS( XML_w, XML_author ), aAuthor.getStr(),
2907 : FSNS( XML_w, XML_date ), aDate.getStr(),
2908 1 : FSEND );
2909 1 : else if (nRedlineType == nsRedlineType_t::REDLINE_TABLE_ROW_DELETE)
2910 : m_pSerializer->singleElementNS( XML_w, XML_del,
2911 : FSNS( XML_w, XML_id ), aId.getStr(),
2912 : FSNS( XML_w, XML_author ), aAuthor.getStr(),
2913 : FSNS( XML_w, XML_date ), aDate.getStr(),
2914 3 : FSEND );
2915 : }
2916 2 : break;
2917 : };
2918 : }
2919 : }
2920 515 : }
2921 :
2922 1389 : void DocxAttributeOutput::TableCellRedline( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2923 : {
2924 1389 : const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
2925 :
2926 : // search next Redline
2927 1389 : const SwExtraRedlineTbl& aExtraRedlineTbl = m_rExport.pDoc->GetExtraRedlineTbl();
2928 1413 : for(sal_uInt16 nCurRedlinePos = 0; nCurRedlinePos < aExtraRedlineTbl.GetSize(); ++nCurRedlinePos )
2929 : {
2930 24 : SwExtraRedline* pExtraRedline = aExtraRedlineTbl.GetRedline(nCurRedlinePos);
2931 24 : const SwTableCellRedline* pTableCellRedline = dynamic_cast<const SwTableCellRedline*>(pExtraRedline);
2932 24 : const SwTableBox *pRedTabBox = pTableCellRedline ? &pTableCellRedline->GetTableBox() : NULL;
2933 24 : if (pRedTabBox == pTabBox)
2934 : {
2935 : // Redline for this table cell
2936 2 : const SwRedlineData& aRedlineData = pTableCellRedline->GetRedlineData();
2937 2 : sal_uInt16 nRedlineType = aRedlineData.GetType();
2938 2 : switch (nRedlineType)
2939 : {
2940 : case nsRedlineType_t::REDLINE_TABLE_CELL_INSERT:
2941 : case nsRedlineType_t::REDLINE_TABLE_CELL_DELETE:
2942 : {
2943 2 : OString aId( OString::number( m_nRedlineId++ ) );
2944 4 : const OUString &rAuthor( SW_MOD()->GetRedlineAuthor( aRedlineData.GetAuthor() ) );
2945 4 : OString aAuthor( OUStringToOString( rAuthor, RTL_TEXTENCODING_UTF8 ) );
2946 :
2947 4 : OString aDate( DateTimeToOString( aRedlineData.GetTimeStamp() ) );
2948 :
2949 2 : if (nRedlineType == nsRedlineType_t::REDLINE_TABLE_CELL_INSERT)
2950 : m_pSerializer->singleElementNS( XML_w, XML_cellIns,
2951 : FSNS( XML_w, XML_id ), aId.getStr(),
2952 : FSNS( XML_w, XML_author ), aAuthor.getStr(),
2953 : FSNS( XML_w, XML_date ), aDate.getStr(),
2954 1 : FSEND );
2955 1 : else if (nRedlineType == nsRedlineType_t::REDLINE_TABLE_CELL_DELETE)
2956 : m_pSerializer->singleElementNS( XML_w, XML_cellDel,
2957 : FSNS( XML_w, XML_id ), aId.getStr(),
2958 : FSNS( XML_w, XML_author ), aAuthor.getStr(),
2959 : FSNS( XML_w, XML_date ), aDate.getStr(),
2960 3 : FSEND );
2961 : }
2962 2 : break;
2963 : };
2964 : }
2965 : }
2966 1389 : }
2967 :
2968 515 : void DocxAttributeOutput::TableHeight( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2969 : {
2970 515 : const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
2971 515 : const SwTableLine * pTabLine = pTabBox->GetUpper();
2972 515 : const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();
2973 :
2974 515 : const SwFmtFrmSize& rLSz = pLineFmt->GetFrmSize();
2975 515 : if ( ATT_VAR_SIZE != rLSz.GetHeightSizeType() && rLSz.GetHeight() )
2976 : {
2977 260 : sal_Int32 nHeight = rLSz.GetHeight();
2978 260 : const char *pRule = NULL;
2979 :
2980 260 : switch ( rLSz.GetHeightSizeType() )
2981 : {
2982 0 : case ATT_FIX_SIZE: pRule = "exact"; break;
2983 260 : case ATT_MIN_SIZE: pRule = "atLeast"; break;
2984 0 : default: break;
2985 : }
2986 :
2987 260 : if ( pRule )
2988 : m_pSerializer->singleElementNS( XML_w, XML_trHeight,
2989 : FSNS( XML_w, XML_val ), OString::number( nHeight ).getStr( ),
2990 : FSNS( XML_w, XML_hRule ), pRule,
2991 260 : FSEND );
2992 : }
2993 515 : }
2994 :
2995 515 : void DocxAttributeOutput::TableCanSplit( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2996 : {
2997 515 : const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
2998 515 : const SwTableLine * pTabLine = pTabBox->GetUpper();
2999 515 : const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();
3000 :
3001 515 : const SwFmtRowSplit& rSplittable = pLineFmt->GetRowSplit( );
3002 515 : const char* pCantSplit = ( !rSplittable.GetValue( ) ) ? "true" : "false";
3003 : // if rSplittable is true then no need to write <w:cantSplit w:val="false"/>
3004 : // as default row prop is allow row to break across page.
3005 515 : if( !rSplittable.GetValue( ) )
3006 : m_pSerializer->singleElementNS( XML_w, XML_cantSplit,
3007 : FSNS( XML_w, XML_val ), pCantSplit,
3008 17 : FSEND );
3009 515 : }
3010 :
3011 94 : void DocxAttributeOutput::TableBidi( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
3012 : {
3013 94 : const SwTable * pTable = pTableTextNodeInfoInner->getTable();
3014 94 : const SwFrmFmt * pFrmFmt = pTable->GetFrmFmt();
3015 :
3016 94 : if ( m_rExport.TrueFrameDirection( *pFrmFmt ) == FRMDIR_HORI_RIGHT_TOP )
3017 : {
3018 : m_pSerializer->singleElementNS( XML_w, XML_bidiVisual,
3019 : FSNS( XML_w, XML_val ), "true",
3020 0 : FSEND );
3021 : }
3022 94 : }
3023 :
3024 1389 : void DocxAttributeOutput::TableVerticalCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
3025 : {
3026 1389 : const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
3027 1389 : const SwFrmFmt *pFrmFmt = pTabBox->GetFrmFmt( );
3028 :
3029 1389 : if ( FRMDIR_VERT_TOP_RIGHT == m_rExport.TrueFrameDirection( *pFrmFmt ) )
3030 : m_pSerializer->singleElementNS( XML_w, XML_textDirection,
3031 : FSNS( XML_w, XML_val ), "tbRl",
3032 0 : FSEND );
3033 1389 : else if ( FRMDIR_HORI_LEFT_TOP == m_rExport.TrueFrameDirection( *pFrmFmt ) )
3034 : {
3035 : // Undo the text direction mangling done by the btLr handler in writerfilter::dmapper::DomainMapperTableManager::sprm()
3036 1351 : SwPaM aPam(*pTabBox->GetSttNd(), 0);
3037 1351 : aPam.GetPoint()->nNode++;
3038 1351 : if (aPam.GetPoint()->nNode.GetNode().IsTxtNode())
3039 : {
3040 1346 : const SwTxtNode& rTxtNode = (const SwTxtNode&)aPam.GetPoint()->nNode.GetNode();
3041 1346 : if( const SwAttrSet* pAttrSet = rTxtNode.GetpSwAttrSet())
3042 : {
3043 1288 : const SvxCharRotateItem& rCharRotate = pAttrSet->GetCharRotate();
3044 1288 : if (rCharRotate.GetValue() == 900)
3045 : {
3046 1 : m_pSerializer->singleElementNS( XML_w, XML_textDirection, FSNS( XML_w, XML_val ), "btLr", FSEND );
3047 1 : m_bBtLr = true;
3048 : }
3049 : }
3050 1351 : }
3051 : }
3052 :
3053 1389 : const SwWriteTableRows& aRows = m_pTableWrt->GetRows( );
3054 1389 : SwWriteTableRow *pRow = aRows[ pTableTextNodeInfoInner->getRow( ) ];
3055 1389 : sal_uInt32 nCell = pTableTextNodeInfoInner->getCell();
3056 1389 : const SwWriteTableCells *tableCells = &pRow->GetCells();
3057 1389 : if (nCell < tableCells->size() )
3058 : {
3059 1389 : const SwWriteTableCell *pCell = &pRow->GetCells( )[ pTableTextNodeInfoInner->getCell( ) ];
3060 1389 : switch( pCell->GetVertOri())
3061 : {
3062 : case text::VertOrientation::TOP:
3063 972 : break;
3064 : case text::VertOrientation::CENTER:
3065 : m_pSerializer->singleElementNS( XML_w, XML_vAlign,
3066 197 : FSNS( XML_w, XML_val ), "center", FSEND );
3067 197 : break;
3068 : case text::VertOrientation::BOTTOM:
3069 : m_pSerializer->singleElementNS( XML_w, XML_vAlign,
3070 220 : FSNS( XML_w, XML_val ), "bottom", FSEND );
3071 220 : break;
3072 : }
3073 : }
3074 1389 : }
3075 :
3076 0 : void DocxAttributeOutput::TableNodeInfo( ww8::WW8TableNodeInfo::Pointer_t /*pNodeInfo*/ )
3077 : {
3078 : OSL_TRACE( "TODO: DocxAttributeOutput::TableNodeInfo( ww8::WW8TableNodeInfo::Pointer_t pNodeInfo )" );
3079 0 : }
3080 :
3081 2986 : void DocxAttributeOutput::TableNodeInfoInner( ww8::WW8TableNodeInfoInner::Pointer_t pNodeInfoInner )
3082 : {
3083 : // This is called when the nested table ends in a cell, and there's no
3084 : // paragraph benhind that; so we must check for the ends of cell, rows,
3085 : // tables
3086 : // ['true' to write an empty paragraph, MS Word insists on that]
3087 2986 : FinishTableRowCell( pNodeInfoInner, true );
3088 2986 : }
3089 :
3090 0 : void DocxAttributeOutput::TableOrientation( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
3091 : {
3092 : OSL_TRACE( "TODO: DocxAttributeOutput::TableOrientation( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )" );
3093 0 : }
3094 :
3095 0 : void DocxAttributeOutput::TableSpacing( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
3096 : {
3097 : #if OSL_DEBUG_LEVEL > 1
3098 : fprintf( stderr, "TODO: DocxAttributeOutput::TableSpacing( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )\n" );
3099 : #endif
3100 0 : }
3101 :
3102 0 : void DocxAttributeOutput::TableRowEnd( sal_uInt32 /*nDepth*/ )
3103 : {
3104 : OSL_TRACE( "TODO: DocxAttributeOutput::TableRowEnd( sal_uInt32 nDepth = 1 )" );
3105 0 : }
3106 :
3107 272 : void DocxAttributeOutput::StartStyles()
3108 : {
3109 : m_pSerializer->startElementNS( XML_w, XML_styles,
3110 : FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
3111 : FSNS( XML_xmlns, XML_w14 ), "http://schemas.microsoft.com/office/word/2010/wordml",
3112 : FSNS( XML_xmlns, XML_mc ), "http://schemas.openxmlformats.org/markup-compatibility/2006",
3113 : FSNS( XML_mc, XML_Ignorable ), "w14",
3114 272 : FSEND );
3115 :
3116 272 : DocDefaults();
3117 272 : LatentStyles();
3118 272 : }
3119 :
3120 149246 : sal_Int32 DocxStringGetToken(DocxStringTokenMap const * pMap, const OUString& rName)
3121 : {
3122 149246 : OString sName = OUStringToOString(rName, RTL_TEXTENCODING_UTF8);
3123 610093 : while (pMap->pToken)
3124 : {
3125 460616 : if (sName == pMap->pToken)
3126 149015 : return pMap->nToken;
3127 311601 : ++pMap;
3128 : }
3129 231 : return 0;
3130 : }
3131 :
3132 : DocxStringTokenMap const aDefaultTokens[] = {
3133 : {"defQFormat", XML_defQFormat},
3134 : {"defUnhideWhenUsed", XML_defUnhideWhenUsed},
3135 : {"defSemiHidden", XML_defSemiHidden},
3136 : {"count", XML_count},
3137 : {"defUIPriority", XML_defUIPriority},
3138 : {"defLockedState", XML_defLockedState},
3139 : {0, 0}
3140 : };
3141 :
3142 : DocxStringTokenMap const aExceptionTokens[] = {
3143 : {"name", XML_name},
3144 : {"locked", XML_locked},
3145 : {"uiPriority", XML_uiPriority},
3146 : {"semiHidden", XML_semiHidden},
3147 : {"unhideWhenUsed", XML_unhideWhenUsed},
3148 : {"qFormat", XML_qFormat},
3149 : {0, 0}
3150 : };
3151 :
3152 272 : void DocxAttributeOutput::LatentStyles()
3153 : {
3154 : // Do we have latent styles available?
3155 272 : uno::Reference<beans::XPropertySet> xPropertySet(m_rExport.pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW);
3156 503 : uno::Sequence<beans::PropertyValue> aInteropGrabBag;
3157 272 : xPropertySet->getPropertyValue("InteropGrabBag") >>= aInteropGrabBag;
3158 503 : uno::Sequence<beans::PropertyValue> aLatentStyles;
3159 2816 : for (sal_Int32 i = 0; i < aInteropGrabBag.getLength(); ++i)
3160 : {
3161 2775 : if (aInteropGrabBag[i].Name == "latentStyles")
3162 : {
3163 231 : aInteropGrabBag[i].Value >>= aLatentStyles;
3164 231 : break;
3165 : }
3166 : }
3167 272 : if (!aLatentStyles.getLength())
3168 313 : return;
3169 :
3170 : // Extract default attributes first.
3171 231 : sax_fastparser::FastAttributeList* pAttributeList = m_pSerializer->createAttrList();
3172 462 : uno::Sequence<beans::PropertyValue> aLsdExceptions;
3173 1848 : for (sal_Int32 i = 0; i < aLatentStyles.getLength(); ++i)
3174 : {
3175 1617 : if (sal_Int32 nToken = DocxStringGetToken(aDefaultTokens, aLatentStyles[i].Name))
3176 1386 : pAttributeList->add(FSNS(XML_w, nToken), OUStringToOString(aLatentStyles[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8));
3177 231 : else if (aLatentStyles[i].Name == "lsdExceptions")
3178 231 : aLatentStyles[i].Value >>= aLsdExceptions;
3179 : }
3180 :
3181 462 : XFastAttributeListRef xAttributeList(pAttributeList);
3182 231 : m_pSerializer->startElementNS(XML_w, XML_latentStyles, xAttributeList);
3183 231 : pAttributeList = 0;
3184 :
3185 : // Then handle the exceptions.
3186 44397 : for (sal_Int32 i = 0; i < aLsdExceptions.getLength(); ++i)
3187 : {
3188 44166 : pAttributeList = m_pSerializer->createAttrList();
3189 :
3190 44166 : uno::Sequence<beans::PropertyValue> aAttributes;
3191 44166 : aLsdExceptions[i].Value >>= aAttributes;
3192 184934 : for (sal_Int32 j = 0; j < aAttributes.getLength(); ++j)
3193 140768 : if (sal_Int32 nToken = DocxStringGetToken(aExceptionTokens, aAttributes[j].Name))
3194 140768 : pAttributeList->add(FSNS(XML_w, nToken), OUStringToOString(aAttributes[j].Value.get<OUString>(), RTL_TEXTENCODING_UTF8));
3195 :
3196 44166 : xAttributeList = pAttributeList;
3197 44166 : m_pSerializer->singleElementNS(XML_w, XML_lsdException, xAttributeList);
3198 44166 : pAttributeList = 0;
3199 44166 : }
3200 :
3201 462 : m_pSerializer->endElementNS(XML_w, XML_latentStyles);
3202 : }
3203 :
3204 : /// Should the font size we have written out as a default one?
3205 272 : bool lcl_isDefaultFontSize(const SvxFontHeightItem& rFontHeight, SwDoc* pDoc)
3206 : {
3207 272 : bool bRet = rFontHeight.GetHeight() != 200; // see StyleSheetTable_Impl::StyleSheetTable_Impl() where we set this default
3208 : // Additionally, if the default para style has the same font size, then don't write it here.
3209 272 : SwTxtFmtColl* pDefaultStyle = pDoc->GetTxtCollFromPool(RES_POOLCOLL_STANDARD);
3210 272 : if (pDefaultStyle)
3211 : {
3212 272 : const SfxPoolItem* pItem = 0;
3213 272 : if (pDefaultStyle->GetAttrSet().HasItem(RES_CHRATR_FONTSIZE, &pItem))
3214 62 : return static_cast<const SvxFontHeightItem*>(pItem)->GetHeight() != rFontHeight.GetHeight();
3215 : }
3216 210 : return bRet;
3217 : }
3218 :
3219 17408 : void DocxAttributeOutput::OutputDefaultItem(const SfxPoolItem& rHt)
3220 : {
3221 17408 : bool bMustWrite = true;
3222 17408 : switch (rHt.Which())
3223 : {
3224 : case RES_CHRATR_CASEMAP:
3225 272 : bMustWrite = static_cast< const SvxCaseMapItem& >(rHt).GetCaseMap() != SVX_CASEMAP_NOT_MAPPED;
3226 272 : break;
3227 : case RES_CHRATR_COLOR:
3228 272 : bMustWrite = static_cast< const SvxColorItem& >(rHt).GetValue().GetColor() != COL_AUTO;
3229 272 : break;
3230 : case RES_CHRATR_CONTOUR:
3231 272 : bMustWrite = static_cast< const SvxContourItem& >(rHt).GetValue();
3232 272 : break;
3233 : case RES_CHRATR_CROSSEDOUT:
3234 272 : bMustWrite = static_cast< const SvxCrossedOutItem& >(rHt).GetStrikeout() != STRIKEOUT_NONE;
3235 272 : break;
3236 : case RES_CHRATR_ESCAPEMENT:
3237 272 : bMustWrite = static_cast< const SvxEscapementItem& >(rHt).GetEscapement() != SVX_ESCAPEMENT_OFF;
3238 272 : break;
3239 : case RES_CHRATR_FONT:
3240 272 : bMustWrite = true;
3241 272 : break;
3242 : case RES_CHRATR_FONTSIZE:
3243 272 : bMustWrite = lcl_isDefaultFontSize(static_cast< const SvxFontHeightItem& >(rHt), m_rExport.pDoc);
3244 272 : break;
3245 : case RES_CHRATR_KERNING:
3246 272 : bMustWrite = static_cast< const SvxKerningItem& >(rHt).GetValue() != 0;
3247 272 : break;
3248 : case RES_CHRATR_LANGUAGE:
3249 272 : bMustWrite = true;
3250 272 : break;
3251 : case RES_CHRATR_POSTURE:
3252 272 : bMustWrite = static_cast< const SvxPostureItem& >(rHt).GetPosture() != ITALIC_NONE;
3253 272 : break;
3254 : case RES_CHRATR_SHADOWED:
3255 272 : bMustWrite = static_cast< const SvxShadowedItem& >(rHt).GetValue();
3256 272 : break;
3257 : case RES_CHRATR_UNDERLINE:
3258 272 : bMustWrite = static_cast< const SvxUnderlineItem& >(rHt).GetLineStyle() != UNDERLINE_NONE;
3259 272 : break;
3260 : case RES_CHRATR_WEIGHT:
3261 272 : bMustWrite = static_cast< const SvxWeightItem& >(rHt).GetWeight() != WEIGHT_NORMAL;
3262 272 : break;
3263 : case RES_CHRATR_AUTOKERN:
3264 272 : bMustWrite = static_cast< const SvxAutoKernItem& >(rHt).GetValue();
3265 272 : break;
3266 : case RES_CHRATR_BLINK:
3267 272 : bMustWrite = static_cast< const SvxBlinkItem& >(rHt).GetValue();
3268 272 : break;
3269 : case RES_CHRATR_BACKGROUND:
3270 : {
3271 272 : const SvxBrushItem& rBrushItem = static_cast< const SvxBrushItem& >(rHt);
3272 1360 : bMustWrite = (rBrushItem.GetColor() != COL_AUTO ||
3273 816 : rBrushItem.GetShadingValue() != sal_uInt32(ShadingPattern::CLEAR) ||
3274 2176 : rBrushItem.GetGraphic() != NULL ||
3275 816 : rBrushItem.GetGraphicObject() != NULL);
3276 : }
3277 272 : break;
3278 :
3279 : case RES_CHRATR_CJK_FONT:
3280 272 : bMustWrite = true;
3281 272 : break;
3282 : case RES_CHRATR_CJK_FONTSIZE:
3283 272 : bMustWrite = false; // we have written it already as RES_CHRATR_FONTSIZE
3284 272 : break;
3285 : case RES_CHRATR_CJK_LANGUAGE:
3286 272 : bMustWrite = true;
3287 272 : break;
3288 : case RES_CHRATR_CJK_POSTURE:
3289 272 : bMustWrite = false; // we have written it already as RES_CHRATR_POSTURE
3290 272 : break;
3291 : case RES_CHRATR_CJK_WEIGHT:
3292 272 : bMustWrite = false; // we have written it already as RES_CHRATR_WEIGHT
3293 272 : break;
3294 :
3295 : case RES_CHRATR_CTL_FONT:
3296 272 : bMustWrite = true;
3297 272 : break;
3298 : case RES_CHRATR_CTL_FONTSIZE:
3299 272 : bMustWrite = static_cast< const SvxFontHeightItem& >(rHt).GetHeight() != 200; // see StyleSheetTable_Impl::StyleSheetTable_Impl() where we set this default
3300 272 : break;
3301 : case RES_CHRATR_CTL_LANGUAGE:
3302 272 : bMustWrite = true;
3303 272 : break;
3304 : case RES_CHRATR_CTL_POSTURE:
3305 272 : bMustWrite = static_cast< const SvxPostureItem& >(rHt).GetPosture() != ITALIC_NONE;
3306 272 : break;
3307 : case RES_CHRATR_CTL_WEIGHT:
3308 272 : bMustWrite = static_cast< const SvxWeightItem& >(rHt).GetWeight() != WEIGHT_NORMAL;
3309 272 : break;
3310 :
3311 : case RES_CHRATR_ROTATE:
3312 272 : bMustWrite = static_cast< const SvxCharRotateItem& >(rHt).GetValue() != 0;
3313 272 : break;
3314 : case RES_CHRATR_EMPHASIS_MARK:
3315 272 : bMustWrite = static_cast< const SvxEmphasisMarkItem& >(rHt).GetValue() != EMPHASISMARK_NONE;
3316 272 : break;
3317 : case RES_CHRATR_TWO_LINES:
3318 272 : bMustWrite = static_cast< const SvxTwoLinesItem& >(rHt).GetValue();
3319 272 : break;
3320 : case RES_CHRATR_SCALEW:
3321 272 : bMustWrite = static_cast< const SvxCharScaleWidthItem& >(rHt).GetValue() != 100;
3322 272 : break;
3323 : case RES_CHRATR_RELIEF:
3324 272 : bMustWrite = static_cast< const SvxCharReliefItem& >(rHt).GetValue() != RELIEF_NONE;
3325 272 : break;
3326 : case RES_CHRATR_HIDDEN:
3327 272 : bMustWrite = static_cast< const SvxCharHiddenItem& >(rHt).GetValue();
3328 272 : break;
3329 : case RES_CHRATR_BOX:
3330 : {
3331 272 : const SvxBoxItem& rBoxItem = static_cast< const SvxBoxItem& >(rHt);
3332 816 : bMustWrite = rBoxItem.GetTop() || rBoxItem.GetLeft() ||
3333 1088 : rBoxItem.GetBottom() || rBoxItem.GetRight() ||
3334 544 : rBoxItem.GetDistance();
3335 : }
3336 272 : break;
3337 : case RES_CHRATR_HIGHLIGHT:
3338 : {
3339 272 : const SvxBrushItem& rBrushItem = static_cast< const SvxBrushItem& >(rHt);
3340 1360 : bMustWrite = (rBrushItem.GetColor() != COL_AUTO ||
3341 816 : rBrushItem.GetShadingValue() != sal_uInt32(ShadingPattern::CLEAR) ||
3342 2176 : rBrushItem.GetGraphic() != NULL ||
3343 816 : rBrushItem.GetGraphicObject() != NULL);
3344 : }
3345 272 : break;
3346 :
3347 : case RES_PARATR_LINESPACING:
3348 272 : bMustWrite = static_cast< const SvxLineSpacingItem& >(rHt).GetInterLineSpaceRule() != SVX_INTER_LINE_SPACE_OFF;
3349 272 : break;
3350 : case RES_PARATR_ADJUST:
3351 272 : bMustWrite = static_cast< const SvxAdjustItem& >(rHt).GetAdjust() != SVX_ADJUST_LEFT;
3352 272 : break;
3353 : case RES_PARATR_SPLIT:
3354 272 : bMustWrite = !static_cast< const SvxFmtSplitItem& >(rHt).GetValue();
3355 272 : break;
3356 : case RES_PARATR_WIDOWS:
3357 272 : bMustWrite = static_cast< const SvxWidowsItem& >(rHt).GetValue();
3358 272 : break;
3359 : case RES_PARATR_TABSTOP:
3360 272 : bMustWrite = static_cast< const SvxTabStopItem& >(rHt).Count() != 0;
3361 272 : break;
3362 : case RES_PARATR_HYPHENZONE:
3363 272 : bMustWrite = static_cast< const SvxHyphenZoneItem& >(rHt).IsHyphen();
3364 272 : break;
3365 : case RES_PARATR_NUMRULE:
3366 272 : bMustWrite = !static_cast< const SwNumRuleItem& >(rHt).GetValue().isEmpty();
3367 272 : break;
3368 : case RES_PARATR_SCRIPTSPACE:
3369 272 : bMustWrite = !static_cast< const SfxBoolItem& >(rHt).GetValue();
3370 272 : break;
3371 : case RES_PARATR_HANGINGPUNCTUATION:
3372 272 : bMustWrite = !static_cast< const SfxBoolItem& >(rHt).GetValue();
3373 272 : break;
3374 : case RES_PARATR_FORBIDDEN_RULES:
3375 272 : bMustWrite = !static_cast< const SfxBoolItem& >(rHt).GetValue();
3376 272 : break;
3377 : case RES_PARATR_VERTALIGN:
3378 272 : bMustWrite = static_cast< const SvxParaVertAlignItem& >(rHt).GetValue() != SvxParaVertAlignItem::AUTOMATIC;
3379 272 : break;
3380 : case RES_PARATR_SNAPTOGRID:
3381 272 : bMustWrite = !static_cast< const SvxParaGridItem& >(rHt).GetValue();
3382 272 : break;
3383 : case RES_CHRATR_GRABBAG:
3384 272 : bMustWrite = true;
3385 272 : break;
3386 :
3387 : default:
3388 : SAL_INFO("sw.ww8", "Unhandled SfxPoolItem with id " << rHt.Which() );
3389 4624 : break;
3390 : }
3391 :
3392 17408 : if (bMustWrite)
3393 7714 : OutputItem(rHt);
3394 17408 : }
3395 :
3396 272 : void DocxAttributeOutput::DocDefaults( )
3397 : {
3398 : // Write the '<w:docDefaults>' section here
3399 272 : m_pSerializer->startElementNS(XML_w, XML_docDefaults, FSEND);
3400 :
3401 : // Output the default run properties
3402 272 : m_pSerializer->startElementNS(XML_w, XML_rPrDefault, FSEND);
3403 :
3404 272 : StartStyleProperties(false, 0);
3405 :
3406 12512 : for (int i = int(RES_CHRATR_BEGIN); i < int(RES_CHRATR_END); ++i)
3407 12240 : OutputDefaultItem(m_rExport.pDoc->GetDefault(i));
3408 :
3409 272 : EndStyleProperties(false);
3410 :
3411 272 : m_pSerializer->endElementNS(XML_w, XML_rPrDefault);
3412 :
3413 : // Output the default paragraph properties
3414 272 : m_pSerializer->startElementNS(XML_w, XML_pPrDefault, FSEND);
3415 :
3416 272 : StartStyleProperties(true, 0);
3417 :
3418 5440 : for (int i = int(RES_PARATR_BEGIN); i < int(RES_PARATR_END); ++i)
3419 5168 : OutputDefaultItem(m_rExport.pDoc->GetDefault(i));
3420 :
3421 272 : EndStyleProperties(true);
3422 :
3423 272 : m_pSerializer->endElementNS(XML_w, XML_pPrDefault);
3424 :
3425 272 : m_pSerializer->endElementNS(XML_w, XML_docDefaults);
3426 272 : }
3427 :
3428 272 : void DocxAttributeOutput::EndStyles( sal_uInt16 nNumberOfStyles )
3429 : {
3430 : // HACK
3431 : // Ms Office seems to have an internal limitation of 4091 styles
3432 : // and refuses to load .docx with more, even though the spec seems to allow that;
3433 : // so simply if there are more styles, don't export those
3434 272 : sal_uInt16 nCountStylesToWrite = MSWORD_MAX_STYLES_LIMIT - nNumberOfStyles;
3435 272 : m_pTableStyleExport->TableStyles(nCountStylesToWrite);
3436 272 : m_pSerializer->endElementNS( XML_w, XML_styles );
3437 272 : }
3438 :
3439 3561 : void DocxAttributeOutput::DefaultStyle( sal_uInt16 nStyle )
3440 : {
3441 : // are these the values of enum ww::sti (see ../inc/wwstyles.hxx)?
3442 : #if OSL_DEBUG_LEVEL > 1
3443 : OSL_TRACE( "TODO DocxAttributeOutput::DefaultStyle( sal_uInt16 nStyle )- %d", nStyle );
3444 : #else
3445 : (void) nStyle; // to quiet the warning
3446 : #endif
3447 3561 : }
3448 :
3449 : /* Writes <a:srcRect> tag back to document.xml if a file conatins a cropped image.
3450 : * NOTE : Tested on images of type JPEG,EMF/WMF,BMP, PNG and GIF.
3451 : */
3452 45 : void DocxAttributeOutput::WriteSrcRect(const SdrObject* pSdrObj )
3453 : {
3454 45 : uno::Reference< drawing::XShape > xShape( ((SdrObject*)pSdrObj)->getUnoShape(), uno::UNO_QUERY );
3455 90 : uno::Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
3456 :
3457 90 : OUString sUrl;
3458 45 : xPropSet->getPropertyValue("GraphicURL") >>= sUrl;
3459 45 : Size aOriginalSize( GraphicObject::CreateGraphicObjectFromURL( sUrl ).GetPrefSize() );
3460 :
3461 45 : ::com::sun::star::text::GraphicCrop aGraphicCropStruct;
3462 45 : xPropSet->getPropertyValue( "GraphicCrop" ) >>= aGraphicCropStruct;
3463 :
3464 90 : const MapMode aMap100mm( MAP_100TH_MM );
3465 45 : const MapMode& mapMode = GraphicObject::CreateGraphicObjectFromURL( sUrl ).GetPrefMapMode();
3466 45 : if( mapMode.GetMapUnit() == MAP_PIXEL )
3467 : {
3468 25 : aOriginalSize = Application::GetDefaultDevice()->PixelToLogic(aOriginalSize, aMap100mm );
3469 : }
3470 :
3471 45 : if ( (0 != aGraphicCropStruct.Left) || (0 != aGraphicCropStruct.Top) || (0 != aGraphicCropStruct.Right) || (0 != aGraphicCropStruct.Bottom) )
3472 : {
3473 4 : double widthMultiplier = 100000.0/aOriginalSize.Width();
3474 4 : double heightMultiplier = 100000.0/aOriginalSize.Height();
3475 :
3476 4 : double left = aGraphicCropStruct.Left * widthMultiplier;
3477 4 : double right = aGraphicCropStruct.Right * widthMultiplier;
3478 4 : double top = aGraphicCropStruct.Top * heightMultiplier;
3479 4 : double bottom = aGraphicCropStruct.Bottom * heightMultiplier;
3480 :
3481 : m_pSerializer->singleElementNS( XML_a, XML_srcRect,
3482 : XML_l, I32S(left),
3483 : XML_t, I32S(top),
3484 : XML_r, I32S(right),
3485 : XML_b, I32S(bottom),
3486 4 : FSEND );
3487 45 : }
3488 45 : }
3489 :
3490 48 : void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size& rSize, const SwFlyFrmFmt* pOLEFrmFmt, SwOLENode* pOLENode, const SdrObject* pSdrObj )
3491 : {
3492 : OSL_TRACE( "TODO DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size& rSize, const SwFlyFrmFmt* pOLEFrmFmt, SwOLENode* pOLENode, const SdrObject* pSdrObj ) - some stuff still missing" );
3493 : // detect mis-use of the API
3494 : assert(pGrfNode || (pOLEFrmFmt && pOLENode));
3495 48 : const SwFrmFmt* pFrmFmt = pGrfNode ? pGrfNode->GetFlyFmt() : pOLEFrmFmt;
3496 : // create the relation ID
3497 48 : OString aRelId;
3498 : sal_Int32 nImageType;
3499 48 : if ( pGrfNode && pGrfNode->IsLinkedFile() )
3500 : {
3501 : // linked image, just create the relation
3502 0 : OUString aFileName;
3503 0 : pGrfNode->GetFileFilterNms( &aFileName, 0 );
3504 :
3505 : // TODO Convert the file name to relative for better interoperability
3506 :
3507 0 : aRelId = m_rExport.AddRelation(
3508 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
3509 0 : aFileName );
3510 :
3511 0 : nImageType = XML_link;
3512 : }
3513 : else
3514 : {
3515 : // inline, we also have to write the image itself
3516 48 : const Graphic* pGraphic = 0;
3517 48 : if (pGrfNode)
3518 47 : pGraphic = &const_cast< Graphic& >( pGrfNode->GetGrf() );
3519 : else
3520 1 : pGraphic = pOLENode->GetGraphic();
3521 :
3522 48 : if (m_aRelIdCache.find(pGraphic) != m_aRelIdCache.end())
3523 : // We already have a RelId for this Graphic.
3524 9 : aRelId = m_aRelIdCache[pGraphic];
3525 : else
3526 : {
3527 : // Not in cache, then need to write it.
3528 39 : m_rDrawingML.SetFS( m_pSerializer ); // to be sure that we write to the right stream
3529 39 : OUString aImageId = m_rDrawingML.WriteImage( *pGraphic );
3530 :
3531 39 : aRelId = OUStringToOString( aImageId, RTL_TEXTENCODING_UTF8 );
3532 39 : m_aRelIdCache[pGraphic] = aRelId;
3533 : }
3534 :
3535 48 : nImageType = XML_embed;
3536 : }
3537 :
3538 48 : m_rExport.SdrExporter().startDMLAnchorInline(pFrmFmt, rSize);
3539 :
3540 : // picture description (used for pic:cNvPr later too)
3541 48 : ::sax_fastparser::FastAttributeList* docPrattrList = m_pSerializer->createAttrList();
3542 48 : docPrattrList->add( XML_id, OString::number( m_anchorId++).getStr());
3543 48 : docPrattrList->add( XML_name, "Picture" );
3544 48 : docPrattrList->add( XML_descr, OUStringToOString( pGrfNode ? pGrfNode->GetDescription() : pOLEFrmFmt->GetObjDescription(), RTL_TEXTENCODING_UTF8 ).getStr());
3545 48 : if( GetExport().GetFilter().getVersion( ) != oox::core::ECMA_DIALECT )
3546 48 : docPrattrList->add( XML_title, OUStringToOString( pGrfNode ? pGrfNode->GetTitle() : pOLEFrmFmt->GetObjTitle(), RTL_TEXTENCODING_UTF8 ).getStr());
3547 96 : XFastAttributeListRef docPrAttrListRef( docPrattrList );
3548 48 : m_pSerializer->startElementNS( XML_wp, XML_docPr, docPrAttrListRef );
3549 : // TODO hyperlink
3550 : // m_pSerializer->singleElementNS( XML_a, XML_hlinkClick,
3551 : // FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
3552 : // FSNS( XML_r, XML_id ), "rId4",
3553 : // FSEND );
3554 48 : m_pSerializer->endElementNS( XML_wp, XML_docPr );
3555 :
3556 : m_pSerializer->startElementNS( XML_wp, XML_cNvGraphicFramePr,
3557 48 : FSEND );
3558 : // TODO change aspect?
3559 : m_pSerializer->singleElementNS( XML_a, XML_graphicFrameLocks,
3560 : FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
3561 : XML_noChangeAspect, "1",
3562 48 : FSEND );
3563 48 : m_pSerializer->endElementNS( XML_wp, XML_cNvGraphicFramePr );
3564 :
3565 : m_pSerializer->startElementNS( XML_a, XML_graphic,
3566 : FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
3567 48 : FSEND );
3568 : m_pSerializer->startElementNS( XML_a, XML_graphicData,
3569 : XML_uri, "http://schemas.openxmlformats.org/drawingml/2006/picture",
3570 48 : FSEND );
3571 :
3572 : m_pSerializer->startElementNS( XML_pic, XML_pic,
3573 : FSNS( XML_xmlns, XML_pic ), "http://schemas.openxmlformats.org/drawingml/2006/picture",
3574 48 : FSEND );
3575 :
3576 : m_pSerializer->startElementNS( XML_pic, XML_nvPicPr,
3577 48 : FSEND );
3578 : // It seems pic:cNvpr and wp:docPr are pretty much the same thing with the same attributes
3579 48 : m_pSerializer->startElementNS( XML_pic, XML_cNvPr, docPrAttrListRef );
3580 :
3581 : // TODO hyperlink
3582 : // m_pSerializer->singleElementNS( XML_a, XML_hlinkClick,
3583 : // FSNS( XML_r, XML_id ), "rId4",
3584 : // FSEND );
3585 48 : m_pSerializer->endElementNS( XML_pic, XML_cNvPr );
3586 :
3587 : m_pSerializer->startElementNS( XML_pic, XML_cNvPicPr,
3588 48 : FSEND );
3589 : // TODO change aspect?
3590 : m_pSerializer->singleElementNS( XML_a, XML_picLocks,
3591 : XML_noChangeAspect, "1", XML_noChangeArrowheads, "1",
3592 48 : FSEND );
3593 48 : m_pSerializer->endElementNS( XML_pic, XML_cNvPicPr );
3594 48 : m_pSerializer->endElementNS( XML_pic, XML_nvPicPr );
3595 :
3596 : // the actual picture
3597 : m_pSerializer->startElementNS( XML_pic, XML_blipFill,
3598 48 : FSEND );
3599 :
3600 : /* At this point we are certain that, WriteImage returns empty RelId
3601 : for unhandled graphic type. Therefore we write the picture description
3602 : and not the relation( coz there ain't any), so that the user knows
3603 : there is a image/graphic in the doc but it is broken instead of
3604 : completely discarding it.
3605 : */
3606 48 : if ( aRelId.isEmpty() )
3607 : m_pSerializer->singleElementNS( XML_a, XML_blip,
3608 1 : FSEND );
3609 : else
3610 : m_pSerializer->singleElementNS( XML_a, XML_blip,
3611 : FSNS( XML_r, nImageType ), aRelId.getStr(),
3612 47 : FSEND );
3613 :
3614 48 : if (pSdrObj){
3615 45 : WriteSrcRect(pSdrObj);
3616 : }
3617 :
3618 : m_pSerializer->startElementNS( XML_a, XML_stretch,
3619 48 : FSEND );
3620 : m_pSerializer->singleElementNS( XML_a, XML_fillRect,
3621 48 : FSEND );
3622 48 : m_pSerializer->endElementNS( XML_a, XML_stretch );
3623 48 : m_pSerializer->endElementNS( XML_pic, XML_blipFill );
3624 :
3625 : // TODO setup the right values below
3626 : m_pSerializer->startElementNS( XML_pic, XML_spPr,
3627 : XML_bwMode, "auto",
3628 48 : FSEND );
3629 : m_pSerializer->startElementNS( XML_a, XML_xfrm,
3630 48 : FSEND );
3631 : m_pSerializer->singleElementNS( XML_a, XML_off,
3632 : XML_x, "0", XML_y, "0",
3633 48 : FSEND );
3634 96 : OString aWidth( OString::number( TwipsToEMU( rSize.Width() ) ) );
3635 96 : OString aHeight( OString::number( TwipsToEMU( rSize.Height() ) ) );
3636 : m_pSerializer->singleElementNS( XML_a, XML_ext,
3637 : XML_cx, aWidth.getStr(),
3638 : XML_cy, aHeight.getStr(),
3639 48 : FSEND );
3640 48 : m_pSerializer->endElementNS( XML_a, XML_xfrm );
3641 : m_pSerializer->startElementNS( XML_a, XML_prstGeom,
3642 : XML_prst, "rect",
3643 48 : FSEND );
3644 : m_pSerializer->singleElementNS( XML_a, XML_avLst,
3645 48 : FSEND );
3646 48 : m_pSerializer->endElementNS( XML_a, XML_prstGeom );
3647 : m_pSerializer->singleElementNS( XML_a, XML_noFill,
3648 48 : FSEND );
3649 : m_pSerializer->startElementNS( XML_a, XML_ln,
3650 : XML_w, "9525",
3651 48 : FSEND );
3652 : m_pSerializer->singleElementNS( XML_a, XML_noFill,
3653 48 : FSEND );
3654 : m_pSerializer->singleElementNS( XML_a, XML_miter,
3655 : XML_lim, "800000",
3656 48 : FSEND );
3657 : m_pSerializer->singleElementNS( XML_a, XML_headEnd,
3658 48 : FSEND );
3659 : m_pSerializer->singleElementNS( XML_a, XML_tailEnd,
3660 48 : FSEND );
3661 48 : m_pSerializer->endElementNS( XML_a, XML_ln );
3662 :
3663 48 : m_rExport.SdrExporter().writeDMLEffectLst(*pFrmFmt);
3664 :
3665 48 : m_pSerializer->endElementNS( XML_pic, XML_spPr );
3666 :
3667 48 : m_pSerializer->endElementNS( XML_pic, XML_pic );
3668 :
3669 48 : m_pSerializer->endElementNS( XML_a, XML_graphicData );
3670 48 : m_pSerializer->endElementNS( XML_a, XML_graphic );
3671 96 : m_rExport.SdrExporter().endDMLAnchorInline(pFrmFmt);
3672 48 : }
3673 :
3674 96 : void DocxAttributeOutput::WriteOLE2Obj( const SdrObject* pSdrObj, SwOLENode& rOLENode, const Size& rSize, const SwFlyFrmFmt* pFlyFrmFmt )
3675 : {
3676 96 : if( WriteOLEChart( pSdrObj, rSize ))
3677 20 : return;
3678 76 : if( WriteOLEMath( pSdrObj, rOLENode, rSize ))
3679 69 : return;
3680 7 : if( PostponeOLE( pSdrObj, rOLENode, rSize, pFlyFrmFmt ))
3681 7 : return;
3682 : // Then we fall back to just export the object as a graphic.
3683 0 : if( m_postponedGraphic == NULL )
3684 0 : FlyFrameGraphic( 0, rSize, pFlyFrmFmt, &rOLENode );
3685 : else
3686 : // w:drawing should not be inside w:rPr, so write it out later
3687 0 : m_postponedGraphic->push_back( PostponedGraphic( 0, rSize, pFlyFrmFmt, &rOLENode, 0 ) );
3688 : }
3689 :
3690 96 : bool DocxAttributeOutput::WriteOLEChart( const SdrObject* pSdrObj, const Size& rSize )
3691 : {
3692 96 : uno::Reference< chart2::XChartDocument > xChartDoc;
3693 192 : uno::Reference< drawing::XShape > xShape( ((SdrObject*)pSdrObj)->getUnoShape(), uno::UNO_QUERY );
3694 96 : if( xShape.is() )
3695 : {
3696 96 : uno::Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
3697 96 : if( xPropSet.is() )
3698 96 : xChartDoc.set( xPropSet->getPropertyValue( "Model" ), uno::UNO_QUERY );
3699 : }
3700 :
3701 96 : if( xChartDoc.is() )
3702 : {
3703 20 : m_postponedChart = pSdrObj;
3704 20 : m_postponedChartSize = rSize;
3705 20 : return true;
3706 : }
3707 172 : return false;
3708 : }
3709 :
3710 : /*
3711 : * Write chart hierarchy in w:drawing after end element of w:rPr tag.
3712 : */
3713 6494 : void DocxAttributeOutput::WritePostponedChart()
3714 : {
3715 6494 : if(m_postponedChart == NULL)
3716 6474 : return;
3717 20 : uno::Reference< chart2::XChartDocument > xChartDoc;
3718 40 : uno::Reference< drawing::XShape > xShape( ((SdrObject*)m_postponedChart)->getUnoShape(), uno::UNO_QUERY );
3719 20 : if( xShape.is() )
3720 : {
3721 20 : uno::Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
3722 20 : if( xPropSet.is() )
3723 20 : xChartDoc.set( xPropSet->getPropertyValue( "Model" ), uno::UNO_QUERY );
3724 : }
3725 :
3726 20 : if( xChartDoc.is() )
3727 : {
3728 : OSL_TRACE("DocxAttributeOutput::WriteOLE2Obj: export chart ");
3729 : m_pSerializer->startElementNS( XML_w, XML_drawing,
3730 20 : FSEND );
3731 : m_pSerializer->startElementNS( XML_wp, XML_inline,
3732 : XML_distT, "0", XML_distB, "0", XML_distL, "0", XML_distR, "0",
3733 20 : FSEND );
3734 :
3735 20 : OString aWidth( OString::number( TwipsToEMU( m_postponedChartSize.Width() ) ) );
3736 40 : OString aHeight( OString::number( TwipsToEMU( m_postponedChartSize.Height() ) ) );
3737 : m_pSerializer->singleElementNS( XML_wp, XML_extent,
3738 : XML_cx, aWidth.getStr(),
3739 : XML_cy, aHeight.getStr(),
3740 20 : FSEND );
3741 : // TODO - the right effectExtent, extent including the effect
3742 : m_pSerializer->singleElementNS( XML_wp, XML_effectExtent,
3743 : XML_l, "0", XML_t, "0", XML_r, "0", XML_b, "0",
3744 20 : FSEND );
3745 :
3746 40 : OUString sName("Object 1");
3747 40 : uno::Reference< container::XNamed > xNamed( xShape, uno::UNO_QUERY );
3748 20 : if( xNamed.is() )
3749 20 : sName = xNamed->getName();
3750 :
3751 : /* If there is a scenario where a chart is followed by a shape
3752 : which is being exported as an alternate content then, the
3753 : docPr Id is being repeated, ECMA 20.4.2.5 says that the
3754 : docPr Id should be unique, ensuring the same here.
3755 : */
3756 : m_pSerializer->singleElementNS( XML_wp, XML_docPr,
3757 : XML_id, I32S( m_anchorId++ ),
3758 : XML_name, USS( sName ),
3759 20 : FSEND );
3760 :
3761 : m_pSerializer->singleElementNS( XML_wp, XML_cNvGraphicFramePr,
3762 20 : FSEND );
3763 :
3764 : m_pSerializer->startElementNS( XML_a, XML_graphic,
3765 : FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
3766 20 : FSEND );
3767 :
3768 : m_pSerializer->startElementNS( XML_a, XML_graphicData,
3769 : XML_uri, "http://schemas.openxmlformats.org/drawingml/2006/chart",
3770 20 : FSEND );
3771 :
3772 40 : OString aRelId;
3773 : static sal_Int32 nChartCount = 0;
3774 20 : nChartCount++;
3775 40 : uno::Reference< frame::XModel > xModel( xChartDoc, uno::UNO_QUERY );
3776 20 : aRelId = m_rExport.OutputChart( xModel, nChartCount, m_pSerializer );
3777 :
3778 : m_pSerializer->singleElementNS( XML_c, XML_chart,
3779 : FSNS( XML_xmlns, XML_c ), "http://schemas.openxmlformats.org/drawingml/2006/chart",
3780 : FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
3781 : FSNS( XML_r, XML_id ), aRelId.getStr(),
3782 20 : FSEND );
3783 :
3784 20 : m_pSerializer->endElementNS( XML_a, XML_graphicData );
3785 20 : m_pSerializer->endElementNS( XML_a, XML_graphic );
3786 20 : m_pSerializer->endElementNS( XML_wp, XML_inline );
3787 40 : m_pSerializer->endElementNS( XML_w, XML_drawing );
3788 :
3789 : }
3790 20 : m_postponedChart = NULL;
3791 40 : return;
3792 : }
3793 :
3794 76 : bool DocxAttributeOutput::WriteOLEMath( const SdrObject*, const SwOLENode& rOLENode, const Size& )
3795 : {
3796 76 : uno::Reference < embed::XEmbeddedObject > xObj(const_cast<SwOLENode&>(rOLENode).GetOLEObj().GetOleRef());
3797 152 : SvGlobalName aObjName(xObj->getClassID());
3798 :
3799 76 : if( !SotExchange::IsMath(aObjName) )
3800 7 : return false;
3801 : assert( m_postponedMath == NULL ); // make it a list if there can be more inside one run
3802 69 : m_postponedMath = &rOLENode;
3803 145 : return true;
3804 : }
3805 :
3806 6494 : void DocxAttributeOutput::WritePostponedMath()
3807 : {
3808 6494 : if( m_postponedMath == NULL )
3809 12919 : return;
3810 69 : uno::Reference < embed::XEmbeddedObject > xObj(const_cast<SwOLENode*>(m_postponedMath)->GetOLEObj().GetOleRef());
3811 138 : uno::Reference< uno::XInterface > xInterface( xObj->getComponent(), uno::UNO_QUERY );
3812 : // gcc4.4 (and 4.3 and possibly older) have a problem with dynamic_cast directly to the target class,
3813 : // so help it with an intermediate cast. I'm not sure what exactly the problem is, seems to be unrelated
3814 : // to RTLD_GLOBAL, so most probably a gcc bug.
3815 69 : oox::FormulaExportBase* formulaexport = dynamic_cast<oox::FormulaExportBase*>(dynamic_cast<SfxBaseModel*>(xInterface.get()));
3816 : assert( formulaexport != NULL );
3817 69 : if (formulaexport)
3818 69 : formulaexport->writeFormulaOoxml( m_pSerializer, GetExport().GetFilter().getVersion());
3819 138 : m_postponedMath = NULL;
3820 : }
3821 :
3822 2 : void DocxAttributeOutput::WritePostponedFormControl(const SdrObject* pObject)
3823 : {
3824 2 : if (pObject && pObject->GetObjInventor() == FmFormInventor)
3825 : {
3826 2 : if (SdrUnoObj *pFormObj = PTR_CAST(SdrUnoObj,pObject))
3827 : {
3828 2 : uno::Reference<awt::XControlModel> xControlModel = pFormObj->GetUnoControlModel();
3829 4 : uno::Reference<lang::XServiceInfo> xInfo(xControlModel, uno::UNO_QUERY);
3830 2 : if (xInfo->supportsService("com.sun.star.form.component.DateField"))
3831 : {
3832 : // gather component properties
3833 :
3834 1 : Date aOriginalDate(Date::EMPTY);
3835 2 : OUString sOriginalContent, sDateFormat;
3836 2 : OUString sLocale("en-US");
3837 2 : uno::Sequence<beans::PropertyValue> aGrabBag;
3838 2 : uno::Reference<beans::XPropertySet> xShapePropertySet(pFormObj->getUnoShape(), uno::UNO_QUERY);
3839 1 : if (xShapePropertySet->getPropertyValue(UNO_NAME_MISC_OBJ_INTEROPGRABBAG) >>= aGrabBag)
3840 : {
3841 5 : for (sal_Int32 i=0; i < aGrabBag.getLength(); ++i)
3842 : {
3843 4 : if (aGrabBag[i].Name == "DateFormat")
3844 1 : aGrabBag[i].Value >>= sDateFormat;
3845 3 : else if (aGrabBag[i].Name == "Locale")
3846 1 : aGrabBag[i].Value >>= sLocale;
3847 2 : else if (aGrabBag[i].Name == "OriginalContent")
3848 1 : aGrabBag[i].Value >>= sOriginalContent;
3849 1 : else if (aGrabBag[i].Name == "OriginalDate")
3850 : {
3851 1 : css::util::Date aUNODate;
3852 1 : aGrabBag[i].Value >>= aUNODate;
3853 1 : aOriginalDate.SetDay(aUNODate.Day);
3854 1 : aOriginalDate.SetMonth(aUNODate.Month);
3855 1 : aOriginalDate.SetYear(aUNODate.Year);
3856 : }
3857 : }
3858 : }
3859 2 : uno::Reference<beans::XPropertySet> xPropertySet(xControlModel, uno::UNO_QUERY);
3860 :
3861 2 : OString sDate;
3862 2 : OUString aContentText;
3863 1 : bool bHasDate = false;
3864 1 : css::util::Date aUNODate;
3865 1 : if (xPropertySet->getPropertyValue("Date") >>= aUNODate)
3866 : {
3867 1 : bHasDate = true;
3868 1 : Date aDate(aUNODate.Day, aUNODate.Month, aUNODate.Year);
3869 1 : sDate = DateToOString(aDate);
3870 :
3871 1 : if (aOriginalDate == aDate)
3872 : {
3873 1 : aContentText = sOriginalContent;
3874 : // sDateFormat was extracted from the grab bag
3875 : }
3876 : else
3877 : {
3878 0 : aContentText = OUString::createFromAscii(DateToDDMMYYYYOString(aDate).getStr());
3879 0 : sDateFormat = "dd/MM/yyyy";
3880 : }
3881 : }
3882 : else
3883 0 : aContentText = xPropertySet->getPropertyValue("HelpText").get<OUString>();
3884 :
3885 : // output component
3886 :
3887 1 : m_pSerializer->startElementNS(XML_w, XML_sdt, FSEND);
3888 1 : m_pSerializer->startElementNS(XML_w, XML_sdtPr, FSEND);
3889 :
3890 1 : if (bHasDate)
3891 : m_pSerializer->startElementNS(XML_w, XML_date,
3892 : FSNS( XML_w, XML_fullDate ), sDate.getStr(),
3893 1 : FSEND);
3894 : else
3895 0 : m_pSerializer->startElementNS(XML_w, XML_date, FSEND);
3896 :
3897 : m_pSerializer->singleElementNS(XML_w, XML_dateFormat,
3898 : FSNS(XML_w, XML_val),
3899 : rtl::OUStringToOString( sDateFormat, RTL_TEXTENCODING_UTF8 ).getStr(),
3900 1 : FSEND);
3901 : m_pSerializer->singleElementNS(XML_w, XML_lid,
3902 : FSNS(XML_w, XML_val),
3903 : rtl::OUStringToOString( sLocale, RTL_TEXTENCODING_UTF8 ).getStr(),
3904 1 : FSEND);
3905 : m_pSerializer->singleElementNS(XML_w, XML_storeMappedDataAs,
3906 : FSNS(XML_w, XML_val), "dateTime",
3907 1 : FSEND);
3908 : m_pSerializer->singleElementNS(XML_w, XML_calendar,
3909 : FSNS(XML_w, XML_val), "gregorian",
3910 1 : FSEND);
3911 :
3912 1 : m_pSerializer->endElementNS(XML_w, XML_date);
3913 1 : m_pSerializer->endElementNS(XML_w, XML_sdtPr);
3914 :
3915 1 : m_pSerializer->startElementNS(XML_w, XML_sdtContent, FSEND);
3916 1 : m_pSerializer->startElementNS(XML_w, XML_r, FSEND);
3917 1 : RunText(aContentText);
3918 1 : m_pSerializer->endElementNS(XML_w, XML_r);
3919 1 : m_pSerializer->endElementNS(XML_w, XML_sdtContent);
3920 :
3921 2 : m_pSerializer->endElementNS(XML_w, XML_sdt);
3922 : }
3923 1 : else if (xInfo->supportsService("com.sun.star.form.component.ComboBox"))
3924 : {
3925 : // gather component properties
3926 :
3927 1 : uno::Reference<beans::XPropertySet> xPropertySet(xControlModel, uno::UNO_QUERY);
3928 2 : OUString sText = xPropertySet->getPropertyValue("Text").get<OUString>();
3929 2 : uno::Sequence<OUString> aItems = xPropertySet->getPropertyValue("StringItemList").get< uno::Sequence<OUString> >();
3930 :
3931 : // output component
3932 :
3933 1 : m_pSerializer->startElementNS(XML_w, XML_sdt, FSEND);
3934 1 : m_pSerializer->startElementNS(XML_w, XML_sdtPr, FSEND);
3935 :
3936 1 : m_pSerializer->startElementNS(XML_w, XML_dropDownList, FSEND);
3937 :
3938 3 : for (sal_Int32 i=0; i < aItems.getLength(); ++i)
3939 : {
3940 : m_pSerializer->singleElementNS(XML_w, XML_listItem,
3941 : FSNS(XML_w, XML_displayText),
3942 2 : rtl::OUStringToOString( aItems[i], RTL_TEXTENCODING_UTF8 ).getStr(),
3943 : FSNS(XML_w, XML_value),
3944 2 : rtl::OUStringToOString( aItems[i], RTL_TEXTENCODING_UTF8 ).getStr(),
3945 4 : FSEND);
3946 : }
3947 :
3948 1 : m_pSerializer->endElementNS(XML_w, XML_dropDownList);
3949 1 : m_pSerializer->endElementNS(XML_w, XML_sdtPr);
3950 :
3951 1 : m_pSerializer->startElementNS(XML_w, XML_sdtContent, FSEND);
3952 1 : m_pSerializer->startElementNS(XML_w, XML_r, FSEND);
3953 1 : RunText(sText);
3954 1 : m_pSerializer->endElementNS(XML_w, XML_r);
3955 1 : m_pSerializer->endElementNS(XML_w, XML_sdtContent);
3956 :
3957 2 : m_pSerializer->endElementNS(XML_w, XML_sdt);
3958 2 : }
3959 : }
3960 : }
3961 2 : }
3962 :
3963 7 : bool DocxAttributeOutput::PostponeOLE( const SdrObject*, SwOLENode& rNode, const Size& rSize, const SwFlyFrmFmt* pFlyFrmFmt )
3964 : {
3965 7 : if( m_postponedOLE == NULL )
3966 : //cannot be postponed, try to write now
3967 1 : WriteOLE( rNode, rSize, pFlyFrmFmt );
3968 : else
3969 6 : m_postponedOLE->push_back( PostponedOLE( &rNode, rSize, pFlyFrmFmt ) );
3970 7 : return true;
3971 : }
3972 :
3973 : /*
3974 : * Write w:object hierarchy for embedded objects after end element of w:rPr tag.
3975 : */
3976 6494 : void DocxAttributeOutput::WritePostponedOLE()
3977 : {
3978 6494 : if( m_postponedOLE == NULL )
3979 6494 : return;
3980 :
3981 : SAL_INFO( "sw.ww8", OSL_THIS_FUNC );
3982 :
3983 19500 : for( std::list< PostponedOLE >::iterator it = m_postponedOLE->begin();
3984 13000 : it != m_postponedOLE->end();
3985 : ++it )
3986 : {
3987 6 : WriteOLE( *it->object, it->size, it->frame );
3988 : }
3989 :
3990 : // clear list of postponed objects
3991 6494 : delete m_postponedOLE;
3992 6494 : m_postponedOLE = NULL;
3993 : }
3994 :
3995 7 : void DocxAttributeOutput::WriteOLE( SwOLENode& rNode, const Size& rSize, const SwFlyFrmFmt* rFlyFrmFmt )
3996 : {
3997 : // get interoperability information about embedded objects
3998 7 : uno::Reference< beans::XPropertySet > xPropSet( m_rExport.pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
3999 13 : OUString pName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
4000 13 : uno::Sequence< beans::PropertyValue > aGrabBag, aObjectsInteropList;
4001 7 : xPropSet->getPropertyValue( pName ) >>= aGrabBag;
4002 13 : for( sal_Int32 i=0; i < aGrabBag.getLength(); ++i )
4003 12 : if ( aGrabBag[i].Name == "EmbeddedObjects" )
4004 : {
4005 6 : aGrabBag[i].Value >>= aObjectsInteropList;
4006 6 : break;
4007 : }
4008 :
4009 7 : SwOLEObj& aObject = rNode.GetOLEObj();
4010 13 : uno::Reference < embed::XEmbeddedObject > xObj( aObject.GetOleRef() );
4011 7 : comphelper::EmbeddedObjectContainer* aContainer = aObject.GetObject().GetContainer();
4012 13 : OUString sObjectName = aContainer->GetEmbeddedObjectName( xObj );
4013 :
4014 : // set some attributes according to the type of the embedded object
4015 13 : OUString sProgID, sMediaType, sRelationType;
4016 10 : for( sal_Int32 i=0; i < aObjectsInteropList.getLength(); ++i )
4017 8 : if ( aObjectsInteropList[i].Name == sObjectName )
4018 : {
4019 5 : aObjectsInteropList[i].Value >>= sProgID;
4020 5 : break;
4021 : }
4022 7 : if( sProgID.startsWith("Excel.Sheet") )
4023 : {
4024 2 : sMediaType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
4025 2 : sRelationType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package";
4026 : }
4027 5 : else if( sProgID.startsWith("PowerPoint.Show") )
4028 : {
4029 0 : sMediaType = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
4030 0 : sRelationType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package";
4031 : }
4032 : else
4033 : {
4034 5 : sMediaType = "application/vnd.openxmlformats-officedocument.oleObject";
4035 5 : sRelationType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject";
4036 : }
4037 :
4038 : // write embedded file
4039 13 : OString sId = m_rExport.WriteOLEObject( aObject, sMediaType, sRelationType );
4040 :
4041 7 : if( sId.isEmpty() )
4042 : {
4043 : // the embedded file could not be saved
4044 : // fallback: save as an image
4045 1 : FlyFrameGraphic( 0, rSize, rFlyFrmFmt, &rNode );
4046 8 : return;
4047 : }
4048 :
4049 : // write preview image
4050 6 : const Graphic* pGraphic = rNode.GetGraphic();
4051 6 : m_rDrawingML.SetFS(m_pSerializer);
4052 12 : OUString sImageId = m_rDrawingML.WriteImage( *pGraphic );
4053 :
4054 6 : m_pSerializer->startElementNS( XML_w, XML_object, FSEND );
4055 :
4056 12 : OStringBuffer sShapeStyle, sShapeId;
4057 6 : sShapeStyle.append( "width:" ).append( double( rSize.Width() ) / 20 )
4058 12 : .append( "pt;height:" ).append( double( rSize.Height() ) / 20 )
4059 6 : .append( "pt" ); //from VMLExport::AddRectangleDimensions(), it does: value/20
4060 6 : sShapeId.append( "ole_" ).append( sId );
4061 :
4062 : // shape definition
4063 : m_pSerializer->startElementNS( XML_v, XML_shape,
4064 : XML_id, sShapeId.getStr(),
4065 : XML_style, sShapeStyle.getStr(),
4066 : FSNS( XML_o, XML_ole ), "", //compulsory, even if it's empty
4067 6 : FSEND );
4068 :
4069 : // shape filled with the preview image
4070 : m_pSerializer->singleElementNS( XML_v, XML_imagedata,
4071 : FSNS( XML_r, XML_id ), OUStringToOString( sImageId, RTL_TEXTENCODING_UTF8 ).getStr(),
4072 : FSNS( XML_o, XML_title ), "",
4073 6 : FSEND );
4074 :
4075 6 : m_pSerializer->endElementNS( XML_v, XML_shape );
4076 :
4077 : // OLE object definition
4078 : m_pSerializer->singleElementNS( XML_o, XML_OLEObject,
4079 : XML_Type, "Embed",
4080 12 : XML_ProgID, OUStringToOString( sProgID, RTL_TEXTENCODING_UTF8 ).getStr(),
4081 6 : XML_ShapeID, sShapeId.getStr(),
4082 : XML_DrawAspect, "Content",
4083 12 : XML_ObjectID, "_" + OString::number( rand() ),
4084 6 : FSNS( XML_r, XML_id ), sId.getStr(),
4085 36 : FSEND );
4086 :
4087 12 : m_pSerializer->endElementNS( XML_w, XML_object );
4088 : }
4089 :
4090 : /*
4091 : * Write w:pict hierarchy end element of w:rPr tag.
4092 : */
4093 6494 : void DocxAttributeOutput::WritePostponedVMLDrawing()
4094 : {
4095 6494 : if(m_postponedVMLDrawing == NULL)
4096 6494 : return;
4097 :
4098 19482 : for( std::list< PostponedDrawing >::iterator it = m_postponedVMLDrawing->begin();
4099 12988 : it != m_postponedVMLDrawing->end();
4100 : ++it )
4101 : {
4102 0 : m_rExport.SdrExporter().writeVMLDrawing(it->object, *(it->frame), *(it->point));
4103 : }
4104 6494 : delete m_postponedVMLDrawing;
4105 6494 : m_postponedVMLDrawing = NULL;
4106 : }
4107 :
4108 6494 : void DocxAttributeOutput::WritePostponedDMLDrawing()
4109 : {
4110 6494 : if(m_postponedDMLDrawing == NULL)
4111 6494 : return;
4112 :
4113 19629 : for( std::list< PostponedDrawing >::iterator it = m_postponedDMLDrawing->begin();
4114 13086 : it != m_postponedDMLDrawing->end();
4115 : ++it )
4116 : {
4117 49 : if ( IsAlternateContentChoiceOpen() )
4118 1 : m_rExport.SdrExporter().writeDMLDrawing(it->object, (it->frame), m_anchorId++);
4119 : else
4120 48 : m_rExport.SdrExporter().writeDMLAndVMLDrawing(it->object, *(it->frame), *(it->point), m_anchorId++);
4121 : }
4122 6494 : delete m_postponedDMLDrawing;
4123 6494 : m_postponedDMLDrawing = NULL;
4124 : }
4125 :
4126 430 : void DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame &rFrame, const Point& rNdTopLeft )
4127 : {
4128 430 : m_pSerializer->mark();
4129 :
4130 430 : switch ( rFrame.GetWriterType() )
4131 : {
4132 : case sw::Frame::eGraphic:
4133 : {
4134 47 : const SdrObject* pSdrObj = rFrame.GetFrmFmt().FindRealSdrObject();
4135 47 : const SwNode *pNode = rFrame.GetContent();
4136 47 : const SwGrfNode *pGrfNode = pNode ? pNode->GetGrfNode() : 0;
4137 47 : if ( pGrfNode )
4138 : {
4139 47 : if( m_postponedGraphic == NULL )
4140 2 : FlyFrameGraphic( pGrfNode, rFrame.GetLayoutSize(), 0, 0, pSdrObj);
4141 : else // we are writing out attributes, but w:drawing should not be inside w:rPr,
4142 : { // so write it out later
4143 45 : m_postponedGraphic->push_back( PostponedGraphic( pGrfNode, rFrame.GetLayoutSize(), 0, 0, pSdrObj));
4144 : }
4145 : }
4146 : }
4147 47 : break;
4148 : case sw::Frame::eDrawing:
4149 : {
4150 167 : const SdrObject* pSdrObj = rFrame.GetFrmFmt().FindRealSdrObject();
4151 167 : if ( pSdrObj )
4152 : {
4153 167 : if ( IsDiagram( pSdrObj ) )
4154 : {
4155 3 : if ( m_postponedDiagram == NULL )
4156 1 : m_rExport.SdrExporter().writeDiagram( pSdrObj, rFrame.GetFrmFmt(), m_anchorId++);
4157 : else // we are writing out attributes, but w:drawing should not be inside w:rPr,
4158 : { // so write it out later
4159 2 : m_postponedDiagram->push_back( PostponedDiagram( pSdrObj, &(rFrame.GetFrmFmt()) ));
4160 : }
4161 : }
4162 : else
4163 : {
4164 164 : if ( m_postponedDMLDrawing == NULL )
4165 : {
4166 115 : if ( IsAlternateContentChoiceOpen() )
4167 1 : m_rExport.SdrExporter().writeDMLDrawing( pSdrObj, &rFrame.GetFrmFmt(), m_anchorId++);
4168 : else
4169 114 : m_rExport.SdrExporter().writeDMLAndVMLDrawing( pSdrObj, rFrame.GetFrmFmt(), rNdTopLeft, m_anchorId++);
4170 : }
4171 : else
4172 : // we are writing out attributes, but w:drawing should not be inside w:rPr, so write it out later
4173 49 : m_postponedDMLDrawing->push_back(PostponedDrawing(pSdrObj, &(rFrame.GetFrmFmt()), &rNdTopLeft));
4174 : }
4175 : }
4176 : }
4177 167 : break;
4178 : case sw::Frame::eTxtBox:
4179 : {
4180 : // The frame output is postponed to the end of the anchor paragraph
4181 117 : bool bDuplicate = false;
4182 117 : const OUString& rName = rFrame.GetFrmFmt().GetName();
4183 117 : unsigned nSize = m_aFramesOfParagraph.size();
4184 1069 : for( unsigned nIndex = 0; nIndex < nSize; ++nIndex )
4185 : {
4186 952 : const OUString& rNameExisting = m_aFramesOfParagraph[nIndex].GetFrmFmt().GetName();
4187 :
4188 952 : if (!rName.isEmpty() && !rNameExisting.isEmpty())
4189 : {
4190 948 : if (rName == rNameExisting)
4191 2 : bDuplicate = true;
4192 : }
4193 952 : }
4194 :
4195 117 : if( !bDuplicate )
4196 115 : m_aFramesOfParagraph.push_back(sw::Frame(rFrame));
4197 : }
4198 117 : break;
4199 : case sw::Frame::eOle:
4200 : {
4201 97 : const SwFrmFmt &rFrmFmt = rFrame.GetFrmFmt();
4202 97 : const SdrObject *pSdrObj = rFrmFmt.FindRealSdrObject();
4203 97 : if ( pSdrObj )
4204 : {
4205 96 : SwNodeIndex aIdx(*rFrmFmt.GetCntnt().GetCntntIdx(), 1);
4206 96 : SwOLENode& rOLENd = *aIdx.GetNode().GetOLENode();
4207 96 : WriteOLE2Obj( pSdrObj, rOLENd, rFrame.GetLayoutSize(), dynamic_cast<const SwFlyFrmFmt*>( &rFrmFmt ));
4208 : }
4209 : }
4210 97 : break;
4211 : case sw::Frame::eFormControl:
4212 : {
4213 2 : const SdrObject* pObject = rFrame.GetFrmFmt().FindRealSdrObject();
4214 2 : m_aPostponedFormControls.push_back(pObject);
4215 : }
4216 2 : break;
4217 : default:
4218 : OSL_TRACE( "TODO DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame& rFrame, const Point& rNdTopLeft ) - frame type '%s'\n",
4219 : rFrame.GetWriterType() == sw::Frame::eTxtBox? "eTxtBox":
4220 : ( rFrame.GetWriterType() == sw::Frame::eOle? "eOle": "???" ) );
4221 0 : break;
4222 : }
4223 :
4224 430 : m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_POSTPONE );
4225 430 : }
4226 :
4227 167 : bool DocxAttributeOutput::IsDiagram( const SdrObject* sdrObject )
4228 : {
4229 167 : uno::Reference< drawing::XShape > xShape( ((SdrObject*)sdrObject)->getUnoShape(), uno::UNO_QUERY );
4230 167 : if ( !xShape.is() )
4231 0 : return false;
4232 :
4233 334 : uno::Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
4234 167 : if ( !xPropSet.is() )
4235 0 : return false;
4236 :
4237 : // if the shape doesn't have the InteropGrabBag property, it's not a diagram
4238 334 : uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
4239 334 : OUString pName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
4240 167 : if ( !xPropSetInfo->hasPropertyByName( pName ) )
4241 1 : return false;
4242 :
4243 332 : uno::Sequence< beans::PropertyValue > propList;
4244 166 : xPropSet->getPropertyValue( pName ) >>= propList;
4245 438 : for ( sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp )
4246 : {
4247 : // if we find any of the diagram components, it's a diagram
4248 275 : OUString propName = propList[nProp].Name;
4249 1100 : if ( propName == "OOXData" || propName == "OOXLayout" || propName == "OOXStyle" ||
4250 822 : propName == "OOXColor" || propName == "OOXDrawing")
4251 3 : return true;
4252 272 : }
4253 330 : return false;
4254 : }
4255 :
4256 184 : void DocxAttributeOutput::WriteOutliner(const OutlinerParaObject& rParaObj)
4257 : {
4258 184 : const EditTextObject& rEditObj = rParaObj.GetTextObject();
4259 184 : MSWord_SdrAttrIter aAttrIter( m_rExport, rEditObj, TXT_HFTXTBOX );
4260 :
4261 184 : sal_Int32 nPara = rEditObj.GetParagraphCount();
4262 :
4263 184 : m_pSerializer->startElementNS( XML_w, XML_txbxContent, FSEND );
4264 383 : for (sal_Int32 n = 0; n < nPara; ++n)
4265 : {
4266 199 : if( n )
4267 15 : aAttrIter.NextPara( n );
4268 :
4269 199 : OUString aStr( rEditObj.GetText( n ));
4270 199 : sal_Int32 nAktPos = 0;
4271 199 : sal_Int32 nEnd = aStr.getLength();
4272 :
4273 199 : StartParagraph(ww8::WW8TableNodeInfo::Pointer_t());
4274 :
4275 : // Write paragraph properties.
4276 199 : StartParagraphProperties();
4277 199 : aAttrIter.OutParaAttr(false);
4278 199 : EndParagraphProperties(0, 0, 0, 0);
4279 :
4280 199 : do {
4281 199 : const sal_Int32 nNextAttr = std::min(aAttrIter.WhereNext(), nEnd);
4282 :
4283 199 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
4284 :
4285 : // Write run properties.
4286 199 : m_pSerializer->startElementNS(XML_w, XML_rPr, FSEND);
4287 199 : aAttrIter.OutAttr(nAktPos);
4288 199 : WriteCollectedRunProperties();
4289 199 : m_pSerializer->endElementNS(XML_w, XML_rPr);
4290 :
4291 199 : bool bTxtAtr = aAttrIter.IsTxtAttr( nAktPos );
4292 199 : if( !bTxtAtr )
4293 : {
4294 199 : OUString aOut( aStr.copy( nAktPos, nNextAttr - nAktPos ) );
4295 199 : RunText(aOut);
4296 : }
4297 :
4298 199 : m_pSerializer->endElementNS( XML_w, XML_r );
4299 :
4300 199 : nAktPos = nNextAttr;
4301 199 : aAttrIter.NextPos();
4302 : }
4303 199 : while( nAktPos < nEnd );
4304 : // Word can't handle nested text boxes, so write them on the same level.
4305 199 : ++m_nTextFrameLevel;
4306 199 : EndParagraph(ww8::WW8TableNodeInfoInner::Pointer_t());
4307 199 : --m_nTextFrameLevel;
4308 199 : }
4309 184 : m_pSerializer->endElementNS( XML_w, XML_txbxContent );
4310 184 : }
4311 :
4312 24 : oox::drawingml::DrawingML& DocxAttributeOutput::GetDrawingML()
4313 : {
4314 24 : return m_rDrawingML;
4315 : }
4316 :
4317 8980 : void DocxAttributeOutput::StartStyle( const OUString& rName, StyleType eType,
4318 : sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 /*nWwId*/, sal_uInt16 nId, bool bAutoUpdate )
4319 : {
4320 8980 : bool bQFormat = false, bUnhideWhenUsed = false, bSemiHidden = false, bLocked = false, bDefault = false, bCustomStyle = false;
4321 17960 : OUString aLink, aRsid, aUiPriority;
4322 8980 : FastAttributeList* pStyleAttributeList = m_pSerializer->createAttrList();
4323 17960 : uno::Any aAny;
4324 8980 : if (eType == STYLE_TYPE_PARA || eType == STYLE_TYPE_CHAR)
4325 : {
4326 4725 : const SwFmt* pFmt = m_rExport.pStyles->GetSwFmt(nId);
4327 4725 : pFmt->GetGrabBagItem(aAny);
4328 : }
4329 : else
4330 : {
4331 4255 : const SwNumRule* pRule = m_rExport.pStyles->GetSwNumRule(nId);
4332 4255 : pRule->GetGrabBagItem(aAny);
4333 : }
4334 17960 : const uno::Sequence<beans::PropertyValue>& rGrabBag = aAny.get< uno::Sequence<beans::PropertyValue> >();
4335 :
4336 39312 : for (sal_Int32 i = 0; i < rGrabBag.getLength(); ++i)
4337 : {
4338 30332 : if (rGrabBag[i].Name == "uiPriority")
4339 5702 : aUiPriority = rGrabBag[i].Value.get<OUString>();
4340 24630 : else if (rGrabBag[i].Name == "qFormat")
4341 712 : bQFormat = true;
4342 23918 : else if (rGrabBag[i].Name == "link")
4343 1250 : aLink = rGrabBag[i].Value.get<OUString>();
4344 22668 : else if (rGrabBag[i].Name == "rsid")
4345 6542 : aRsid = rGrabBag[i].Value.get<OUString>();
4346 16126 : else if (rGrabBag[i].Name == "unhideWhenUsed")
4347 4977 : bUnhideWhenUsed = true;
4348 11149 : else if (rGrabBag[i].Name == "semiHidden")
4349 4998 : bSemiHidden = true;
4350 6151 : else if (rGrabBag[i].Name == "locked")
4351 124 : bLocked = true;
4352 6027 : else if (rGrabBag[i].Name == "default")
4353 696 : bDefault = rGrabBag[i].Value.get<sal_Bool>();
4354 5331 : else if (rGrabBag[i].Name == "customStyle")
4355 5331 : bCustomStyle = rGrabBag[i].Value.get<sal_Bool>();
4356 : else
4357 : SAL_WARN("sw.ww8", "Unhandled style property: " << rGrabBag[i].Name);
4358 : }
4359 :
4360 8980 : const char* pType = 0;
4361 8980 : switch (eType)
4362 : {
4363 3368 : case STYLE_TYPE_PARA: pType = "paragraph"; break;
4364 1357 : case STYLE_TYPE_CHAR: pType = "character"; break;
4365 4255 : case STYLE_TYPE_LIST: pType = "numbering"; break;
4366 : }
4367 8980 : pStyleAttributeList->add(FSNS( XML_w, XML_type ), pType);
4368 8980 : pStyleAttributeList->add(FSNS( XML_w, XML_styleId ), m_rExport.pStyles->GetStyleId(nId).getStr());
4369 8980 : if (bDefault)
4370 696 : pStyleAttributeList->add(FSNS(XML_w, XML_default), "1");
4371 8980 : if (bCustomStyle)
4372 5331 : pStyleAttributeList->add(FSNS(XML_w, XML_customStyle), "1");
4373 8980 : XFastAttributeListRef xStyleAttributeList(pStyleAttributeList);
4374 8980 : m_pSerializer->startElementNS( XML_w, XML_style, xStyleAttributeList);
4375 :
4376 : m_pSerializer->singleElementNS( XML_w, XML_name,
4377 : FSNS( XML_w, XML_val ), OUStringToOString( OUString( rName ), RTL_TEXTENCODING_UTF8 ).getStr(),
4378 8980 : FSEND );
4379 :
4380 8980 : if ( nBase != 0x0FFF && eType != STYLE_TYPE_LIST)
4381 : {
4382 : m_pSerializer->singleElementNS( XML_w, XML_basedOn,
4383 : FSNS( XML_w, XML_val ), m_rExport.pStyles->GetStyleId(nBase).getStr(),
4384 3776 : FSEND );
4385 : }
4386 :
4387 8980 : if ( nNext != nId && eType != STYLE_TYPE_LIST)
4388 : {
4389 : m_pSerializer->singleElementNS( XML_w, XML_next,
4390 : FSNS( XML_w, XML_val ), m_rExport.pStyles->GetStyleId(nNext).getStr(),
4391 882 : FSEND );
4392 : }
4393 :
4394 8980 : if (!aLink.isEmpty())
4395 : m_pSerializer->singleElementNS(XML_w, XML_link,
4396 : FSNS(XML_w, XML_val), OUStringToOString(aLink, RTL_TEXTENCODING_UTF8).getStr(),
4397 1250 : FSEND);
4398 :
4399 8980 : if ( bAutoUpdate )
4400 204 : m_pSerializer->singleElementNS( XML_w, XML_autoRedefine, FSEND );
4401 :
4402 8980 : if (!aUiPriority.isEmpty())
4403 : m_pSerializer->singleElementNS(XML_w, XML_uiPriority,
4404 : FSNS(XML_w, XML_val), OUStringToOString(aUiPriority, RTL_TEXTENCODING_UTF8).getStr(),
4405 5702 : FSEND);
4406 8980 : if (bSemiHidden)
4407 4998 : m_pSerializer->singleElementNS(XML_w, XML_semiHidden, FSEND);
4408 8980 : if (bUnhideWhenUsed)
4409 4977 : m_pSerializer->singleElementNS(XML_w, XML_unhideWhenUsed, FSEND);
4410 8980 : if (bQFormat)
4411 712 : m_pSerializer->singleElementNS(XML_w, XML_qFormat, FSEND);
4412 8980 : if (bLocked)
4413 124 : m_pSerializer->singleElementNS(XML_w, XML_locked, FSEND);
4414 8980 : if (!aRsid.isEmpty())
4415 : m_pSerializer->singleElementNS(XML_w, XML_rsid,
4416 : FSNS(XML_w, XML_val), OUStringToOString(aRsid, RTL_TEXTENCODING_UTF8).getStr(),
4417 15522 : FSEND);
4418 8980 : }
4419 :
4420 8980 : void DocxAttributeOutput::EndStyle()
4421 : {
4422 8980 : m_pSerializer->endElementNS( XML_w, XML_style );
4423 8980 : }
4424 :
4425 8637 : void DocxAttributeOutput::StartStyleProperties( bool bParProp, sal_uInt16 /*nStyle*/ )
4426 : {
4427 8637 : if ( bParProp )
4428 : {
4429 3640 : m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND );
4430 3640 : InitCollectedParagraphProperties();
4431 : }
4432 : else
4433 : {
4434 4997 : m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
4435 4997 : InitCollectedRunProperties();
4436 : }
4437 8637 : }
4438 :
4439 8637 : void DocxAttributeOutput::EndStyleProperties( bool bParProp )
4440 : {
4441 8637 : if ( bParProp )
4442 : {
4443 3640 : WriteCollectedParagraphProperties();
4444 :
4445 : // Merge the marks for the ordered elements
4446 3640 : m_pSerializer->mergeTopMarks( );
4447 :
4448 3640 : m_pSerializer->endElementNS( XML_w, XML_pPr );
4449 : }
4450 : else
4451 : {
4452 4997 : WriteCollectedRunProperties();
4453 :
4454 : // Merge the marks for the ordered elements
4455 4997 : m_pSerializer->mergeTopMarks();
4456 :
4457 4997 : m_pSerializer->endElementNS( XML_w, XML_rPr );
4458 : }
4459 8637 : }
4460 :
4461 374 : void lcl_OutlineLevel(sax_fastparser::FSHelperPtr pSerializer, sal_uInt16 nLevel)
4462 : {
4463 374 : if (nLevel >= WW8ListManager::nMaxLevel)
4464 0 : nLevel = WW8ListManager::nMaxLevel - 1;
4465 :
4466 : pSerializer->singleElementNS(XML_w, XML_outlineLvl,
4467 : FSNS(XML_w, XML_val), OString::number(nLevel).getStr(),
4468 374 : FSEND);
4469 374 : }
4470 :
4471 31 : void DocxAttributeOutput::OutlineNumbering( sal_uInt8 nLvl, const SwNumFmt& /*rNFmt*/, const SwFmt& /*rFmt*/ )
4472 : {
4473 31 : lcl_OutlineLevel(m_pSerializer, nLvl);
4474 31 : }
4475 :
4476 2435 : void DocxAttributeOutput::ParaOutlineLevel(const SfxUInt16Item& rItem)
4477 : {
4478 2435 : if (rItem.GetValue() > 0)
4479 343 : lcl_OutlineLevel(m_pSerializer, rItem.GetValue() - 1);
4480 2435 : }
4481 :
4482 4 : void DocxAttributeOutput::PageBreakBefore( bool bBreak )
4483 : {
4484 4 : if ( bBreak )
4485 4 : m_pSerializer->singleElementNS( XML_w, XML_pageBreakBefore, FSEND );
4486 : else
4487 : m_pSerializer->singleElementNS( XML_w, XML_pageBreakBefore,
4488 : FSNS( XML_w, XML_val ), "false",
4489 0 : FSEND );
4490 4 : }
4491 :
4492 108 : void DocxAttributeOutput::SectionBreak( sal_uInt8 nC, const WW8_SepInfo* pSectionInfo )
4493 : {
4494 108 : switch ( nC )
4495 : {
4496 : case msword::ColumnBreak:
4497 : // The column break should be output in the next paragraph...
4498 2 : m_nColBreakStatus = COLBRK_POSTPONE;
4499 2 : break;
4500 : case msword::PageBreak:
4501 106 : if ( pSectionInfo )
4502 : {
4503 : // don't add section properties if this will be the first
4504 : // paragraph in the document
4505 34 : if ( !m_bParagraphOpened && !m_bIsFirstParagraph)
4506 : {
4507 : // Create a dummy paragraph if needed
4508 13 : m_pSerializer->startElementNS( XML_w, XML_p, FSEND );
4509 13 : m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND );
4510 :
4511 13 : m_rExport.SectionProperties( *pSectionInfo );
4512 :
4513 13 : m_pSerializer->endElementNS( XML_w, XML_pPr );
4514 13 : m_pSerializer->endElementNS( XML_w, XML_p );
4515 : }
4516 : else
4517 : {
4518 : // postpone the output of this; it has to be done inside the
4519 : // paragraph properties, so remember it until then
4520 21 : m_pSectionInfo.reset( new WW8_SepInfo( *pSectionInfo ));
4521 : }
4522 : }
4523 : else
4524 : {
4525 72 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
4526 : m_pSerializer->singleElementNS( XML_w, XML_br,
4527 72 : FSNS( XML_w, XML_type ), "page", FSEND );
4528 72 : m_pSerializer->endElementNS( XML_w, XML_r );
4529 : }
4530 106 : break;
4531 : default:
4532 : OSL_TRACE( "Unknown section break to write: %d", nC );
4533 0 : break;
4534 : }
4535 108 : }
4536 :
4537 298 : void DocxAttributeOutput::StartSection()
4538 : {
4539 298 : m_pSerializer->startElementNS( XML_w, XML_sectPr, FSEND );
4540 298 : m_bOpenedSectPr = true;
4541 :
4542 : // Write the elements in the spec order
4543 : static const sal_Int32 aOrder[] =
4544 : {
4545 : FSNS( XML_w, XML_headerReference ),
4546 : FSNS( XML_w, XML_footerReference ),
4547 : FSNS( XML_w, XML_footnotePr ),
4548 : FSNS( XML_w, XML_endnotePr ),
4549 : FSNS( XML_w, XML_type ),
4550 : FSNS( XML_w, XML_pgSz ),
4551 : FSNS( XML_w, XML_pgMar ),
4552 : FSNS( XML_w, XML_paperSrc ),
4553 : FSNS( XML_w, XML_pgBorders ),
4554 : FSNS( XML_w, XML_lnNumType ),
4555 : FSNS( XML_w, XML_pgNumType ),
4556 : FSNS( XML_w, XML_cols ),
4557 : FSNS( XML_w, XML_formProt ),
4558 : FSNS( XML_w, XML_vAlign ),
4559 : FSNS( XML_w, XML_noEndnote ),
4560 : FSNS( XML_w, XML_titlePg ),
4561 : FSNS( XML_w, XML_textDirection ),
4562 : FSNS( XML_w, XML_bidi ),
4563 : FSNS( XML_w, XML_rtlGutter ),
4564 : FSNS( XML_w, XML_docGrid ),
4565 : FSNS( XML_w, XML_printerSettings ),
4566 : FSNS( XML_w, XML_sectPrChange )
4567 : };
4568 :
4569 : // postpone the output so that we can later [in EndParagraphProperties()]
4570 : // prepend the properties before the run
4571 298 : sal_Int32 len = sizeof ( aOrder ) / sizeof( sal_Int32 );
4572 298 : uno::Sequence< sal_Int32 > aSeqOrder( len );
4573 6854 : for ( sal_Int32 i = 0; i < len; i++ )
4574 6556 : aSeqOrder[i] = aOrder[i];
4575 :
4576 298 : m_pSerializer->mark( aSeqOrder );
4577 298 : }
4578 :
4579 298 : void DocxAttributeOutput::EndSection()
4580 : {
4581 : // Write the section properties
4582 298 : if ( m_pSectionSpacingAttrList )
4583 : {
4584 298 : XFastAttributeListRef xAttrList( m_pSectionSpacingAttrList );
4585 298 : m_pSectionSpacingAttrList = NULL;
4586 :
4587 298 : m_pSerializer->singleElementNS( XML_w, XML_pgMar, xAttrList );
4588 : }
4589 :
4590 : // Order the elements
4591 298 : m_pSerializer->mergeTopMarks( );
4592 :
4593 298 : m_pSerializer->endElementNS( XML_w, XML_sectPr );
4594 298 : m_bOpenedSectPr = false;
4595 298 : }
4596 :
4597 298 : void DocxAttributeOutput::SectionFormProtection( bool bProtected )
4598 : {
4599 298 : if ( bProtected )
4600 0 : m_pSerializer->singleElementNS( XML_w, XML_formProt, FSEND );
4601 : else
4602 : m_pSerializer->singleElementNS( XML_w, XML_formProt,
4603 298 : FSNS( XML_w, XML_val ), "false", FSEND );
4604 298 : }
4605 :
4606 1 : void DocxAttributeOutput::SectionLineNumbering( sal_uLong nRestartNo, const SwLineNumberInfo& rLnNumInfo )
4607 : {
4608 1 : FastAttributeList* pAttr = m_pSerializer->createAttrList();
4609 1 : pAttr->add( FSNS( XML_w, XML_countBy ), OString::number(rLnNumInfo.GetCountBy()).getStr());
4610 1 : pAttr->add( FSNS( XML_w, XML_restart ), rLnNumInfo.IsRestartEachPage() ? "newPage" : "continuous" );
4611 1 : if( rLnNumInfo.GetPosFromLeft())
4612 0 : pAttr->add( FSNS( XML_w, XML_distance ), OString::number(rLnNumInfo.GetPosFromLeft()).getStr());
4613 1 : if( nRestartNo )
4614 1 : pAttr->add( FSNS( XML_w, XML_start ), OString::number( nRestartNo).getStr());
4615 1 : XFastAttributeListRef xAttrs( pAttr );
4616 1 : m_pSerializer->singleElementNS( XML_w, XML_lnNumType, xAttrs );
4617 1 : }
4618 :
4619 28 : void DocxAttributeOutput::SectionTitlePage()
4620 : {
4621 28 : m_pSerializer->singleElementNS( XML_w, XML_titlePg, FSEND );
4622 28 : }
4623 :
4624 283 : void DocxAttributeOutput::SectionPageBorders( const SwFrmFmt* pFmt, const SwFrmFmt* /*pFirstPageFmt*/ )
4625 : {
4626 : // Output the margins
4627 :
4628 283 : const SvxBoxItem& rBox = pFmt->GetBox( );
4629 :
4630 283 : const SvxBorderLine* pLeft = rBox.GetLeft( );
4631 283 : const SvxBorderLine* pTop = rBox.GetTop( );
4632 283 : const SvxBorderLine* pRight = rBox.GetRight( );
4633 283 : const SvxBorderLine* pBottom = rBox.GetBottom( );
4634 :
4635 283 : if ( pBottom || pTop || pLeft || pRight )
4636 : {
4637 4 : bool bExportDistanceFromPageEdge = false;
4638 4 : if ( boxHasLineLargerThan31(rBox) == true )
4639 : {
4640 : // The distance is larger than '31'. This cannot be exported as 'distance from text'.
4641 : // Instead - it should be exported as 'distance from page edge'.
4642 : // This is based on http://wiki.openoffice.org/wiki/Writer/MSInteroperability/PageBorder
4643 : // Specifically 'export case #2'
4644 4 : bExportDistanceFromPageEdge = true;
4645 : }
4646 :
4647 : // All distances are relative to the text margins
4648 : m_pSerializer->startElementNS( XML_w, XML_pgBorders,
4649 : FSNS( XML_w, XML_display ), "allPages",
4650 : FSNS( XML_w, XML_offsetFrom ), bExportDistanceFromPageEdge ? "page" : "text",
4651 4 : FSEND );
4652 :
4653 4 : OutputBorderOptions aOutputBorderOptions = lcl_getBoxBorderOptions();
4654 :
4655 : // Check if the distance is larger than 31 points
4656 4 : aOutputBorderOptions.bCheckDistanceSize = true;
4657 :
4658 : // Check if there is a shadow item
4659 4 : const SfxPoolItem* pItem = GetExport().HasItem( RES_SHADOW );
4660 4 : if ( pItem )
4661 : {
4662 2 : const SvxShadowItem* pShadowItem = (const SvxShadowItem*)pItem;
4663 2 : aOutputBorderOptions.aShadowLocation = pShadowItem->GetLocation();
4664 : }
4665 :
4666 4 : std::map<sal_uInt16, css::table::BorderLine2> aEmptyMap; // empty styles map
4667 : impl_borders( m_pSerializer, rBox, aOutputBorderOptions, &m_pageMargins,
4668 4 : aEmptyMap );
4669 :
4670 4 : m_pSerializer->endElementNS( XML_w, XML_pgBorders );
4671 : }
4672 283 : }
4673 :
4674 15 : void DocxAttributeOutput::SectionBiDi( bool bBiDi )
4675 : {
4676 15 : if ( bBiDi )
4677 0 : m_pSerializer->singleElementNS( XML_w, XML_bidi, FSEND );
4678 15 : }
4679 :
4680 1372 : static OString impl_NumberingType( sal_uInt16 nNumberingType )
4681 : {
4682 1372 : OString aType;
4683 :
4684 1372 : switch ( nNumberingType )
4685 : {
4686 : case SVX_NUM_CHARS_UPPER_LETTER:
4687 3 : case SVX_NUM_CHARS_UPPER_LETTER_N: aType = "upperLetter"; break;
4688 : case SVX_NUM_CHARS_LOWER_LETTER:
4689 58 : case SVX_NUM_CHARS_LOWER_LETTER_N: aType = "lowerLetter"; break;
4690 2 : case SVX_NUM_ROMAN_UPPER: aType = "upperRoman"; break;
4691 52 : case SVX_NUM_ROMAN_LOWER: aType = "lowerRoman"; break;
4692 :
4693 733 : case SVX_NUM_ARABIC: aType = "decimal"; break;
4694 :
4695 : case SVX_NUM_BITMAP:
4696 296 : case SVX_NUM_CHAR_SPECIAL: aType = "bullet"; break;
4697 1 : case style::NumberingType::CHARS_HEBREW: aType = "hebrew1"; break;
4698 :
4699 227 : default: aType = "none"; break;
4700 : }
4701 :
4702 1372 : return aType;
4703 : }
4704 :
4705 283 : void DocxAttributeOutput::SectionPageNumbering( sal_uInt16 nNumType, ::boost::optional<sal_uInt16> oPageRestartNumber )
4706 : {
4707 : // FIXME Not called properly with page styles like "First Page"
4708 :
4709 283 : FastAttributeList* pAttr = m_pSerializer->createAttrList();
4710 :
4711 : // boost::none means no restart: then don't output that attribute if it is negative
4712 283 : if ( oPageRestartNumber )
4713 19 : pAttr->add( FSNS( XML_w, XML_start ), OString::number( oPageRestartNumber.get() ) );
4714 :
4715 : // nNumType corresponds to w:fmt. See WW8Export::GetNumId() for more precisions
4716 283 : OString aFmt( impl_NumberingType( nNumType ) );
4717 283 : if ( !aFmt.isEmpty() )
4718 283 : pAttr->add( FSNS( XML_w, XML_fmt ), aFmt.getStr() );
4719 :
4720 566 : XFastAttributeListRef xAttrs( pAttr );
4721 283 : m_pSerializer->singleElementNS( XML_w, XML_pgNumType, xAttrs );
4722 :
4723 : // see 2.6.12 pgNumType (Page Numbering Settings)
4724 283 : OSL_TRACE( "TODO DocxAttributeOutput::SectionPageNumbering()" );
4725 283 : }
4726 :
4727 298 : void DocxAttributeOutput::SectionType( sal_uInt8 nBreakCode )
4728 : {
4729 : /* break code: 0 No break, 1 New column
4730 : 2 New page, 3 Even page, 4 Odd page
4731 : */
4732 298 : const char* pType = NULL;
4733 298 : switch ( nBreakCode )
4734 : {
4735 0 : case 1: pType = "nextColumn"; break;
4736 275 : case 2: pType = "nextPage"; break;
4737 0 : case 3: pType = "evenPage"; break;
4738 0 : case 4: pType = "oddPage"; break;
4739 23 : default: pType = "continuous"; break;
4740 : }
4741 :
4742 298 : if ( pType )
4743 : m_pSerializer->singleElementNS( XML_w, XML_type,
4744 : FSNS( XML_w, XML_val ), pType,
4745 298 : FSEND );
4746 298 : }
4747 :
4748 2026 : void DocxAttributeOutput::StartFont( const OUString& rFamilyName ) const
4749 : {
4750 : m_pSerializer->startElementNS( XML_w, XML_font,
4751 : FSNS( XML_w, XML_name ), OUStringToOString( rFamilyName, RTL_TEXTENCODING_UTF8 ).getStr(),
4752 2026 : FSEND );
4753 2026 : }
4754 :
4755 2026 : void DocxAttributeOutput::EndFont() const
4756 : {
4757 2026 : m_pSerializer->endElementNS( XML_w, XML_font );
4758 2026 : }
4759 :
4760 542 : void DocxAttributeOutput::FontAlternateName( const OUString& rName ) const
4761 : {
4762 : m_pSerializer->singleElementNS( XML_w, XML_altName,
4763 : FSNS( XML_w, XML_val ), OUStringToOString( rName, RTL_TEXTENCODING_UTF8 ).getStr(),
4764 542 : FSEND );
4765 542 : }
4766 :
4767 2026 : void DocxAttributeOutput::FontCharset( sal_uInt8 nCharSet, rtl_TextEncoding nEncoding ) const
4768 : {
4769 2026 : FastAttributeList* pAttr = m_pSerializer->createAttrList();
4770 :
4771 2026 : OString aCharSet( OString::number( nCharSet, 16 ) );
4772 2026 : if ( aCharSet.getLength() == 1 )
4773 2026 : aCharSet = OString( "0" ) + aCharSet;
4774 2026 : pAttr->add( FSNS( XML_w, XML_val ), aCharSet.getStr());
4775 :
4776 2026 : if( GetExport().GetFilter().getVersion( ) != oox::core::ECMA_DIALECT )
4777 : {
4778 2026 : if( const char* charset = rtl_getMimeCharsetFromTextEncoding( nEncoding ))
4779 1698 : pAttr->add( FSNS( XML_w, XML_characterSet ), charset );
4780 : }
4781 :
4782 2026 : m_pSerializer->singleElementNS( XML_w, XML_charset, XFastAttributeListRef( pAttr ));
4783 2026 : }
4784 :
4785 2026 : void DocxAttributeOutput::FontFamilyType( FontFamily eFamily ) const
4786 : {
4787 2026 : const char *pFamily = NULL;
4788 2026 : switch ( eFamily )
4789 : {
4790 1415 : case FAMILY_ROMAN: pFamily = "roman"; break;
4791 552 : case FAMILY_SWISS: pFamily = "swiss"; break;
4792 17 : case FAMILY_MODERN: pFamily = "modern"; break;
4793 0 : case FAMILY_SCRIPT: pFamily = "script"; break;
4794 0 : case FAMILY_DECORATIVE: pFamily = "decorative"; break;
4795 42 : default: pFamily = "auto"; break; // no font family
4796 : }
4797 :
4798 2026 : if ( pFamily )
4799 : m_pSerializer->singleElementNS( XML_w, XML_family,
4800 : FSNS( XML_w, XML_val ), pFamily,
4801 2026 : FSEND );
4802 2026 : }
4803 :
4804 2026 : void DocxAttributeOutput::FontPitchType( FontPitch ePitch ) const
4805 : {
4806 2026 : const char *pPitch = NULL;
4807 2026 : switch ( ePitch )
4808 : {
4809 1960 : case PITCH_VARIABLE: pPitch = "variable"; break;
4810 16 : case PITCH_FIXED: pPitch = "fixed"; break;
4811 50 : default: pPitch = "default"; break; // no info about the pitch
4812 : }
4813 :
4814 2026 : if ( pPitch )
4815 : m_pSerializer->singleElementNS( XML_w, XML_pitch,
4816 : FSNS( XML_w, XML_val ), pPitch,
4817 2026 : FSEND );
4818 2026 : }
4819 :
4820 2026 : void DocxAttributeOutput::EmbedFont( const OUString& name, FontFamily family, FontPitch pitch, rtl_TextEncoding encoding )
4821 : {
4822 2026 : if( !m_rExport.pDoc->get( IDocumentSettingAccess::EMBED_FONTS ))
4823 4052 : return; // no font embedding with this document
4824 0 : EmbedFontStyle( name, XML_embedRegular, family, ITALIC_NONE, WEIGHT_NORMAL, pitch, encoding );
4825 0 : EmbedFontStyle( name, XML_embedBold, family, ITALIC_NONE, WEIGHT_BOLD, pitch, encoding );
4826 0 : EmbedFontStyle( name, XML_embedItalic, family, ITALIC_NORMAL, WEIGHT_NORMAL, pitch, encoding );
4827 0 : EmbedFontStyle( name, XML_embedBoldItalic, family, ITALIC_NORMAL, WEIGHT_BOLD, pitch, encoding );
4828 : }
4829 :
4830 0 : static inline char toHexChar( int value )
4831 : {
4832 0 : return value >= 10 ? value + 'A' - 10 : value + '0';
4833 : }
4834 :
4835 0 : void DocxAttributeOutput::EmbedFontStyle( const OUString& name, int tag, FontFamily family, FontItalic italic,
4836 : FontWeight weight, FontPitch pitch, rtl_TextEncoding encoding )
4837 : {
4838 : // Embed font if at least viewing is allowed (in which case the opening app must check
4839 : // the font license rights too and open either read-only or not use the font for editing).
4840 : OUString fontUrl = EmbeddedFontsHelper::fontFileUrl( name, family, italic, weight, pitch, encoding,
4841 0 : EmbeddedFontsHelper::ViewingAllowed );
4842 0 : if( fontUrl.isEmpty())
4843 0 : return;
4844 : // TODO IDocumentSettingAccess::EMBED_SYSTEM_FONTS
4845 0 : if( !fontFilesMap.count( fontUrl ))
4846 : {
4847 0 : osl::File file( fontUrl );
4848 0 : if( file.open( osl_File_OpenFlag_Read ) != osl::File::E_None )
4849 0 : return;
4850 0 : uno::Reference< com::sun::star::io::XOutputStream > xOutStream = m_rExport.GetFilter().openFragmentStream(
4851 0 : OUString( "word/fonts/font" ) + OUString::number(m_nextFontId) + ".odttf",
4852 0 : "application/vnd.openxmlformats-officedocument.obfuscatedFont" );
4853 : // Not much point in trying hard with the obfuscation key, whoever reads the spec can read the font anyway,
4854 : // so just alter the first and last part of the key.
4855 0 : char fontKeyStr[] = "{00014A78-CABC-4EF0-12AC-5CD89AEFDE00}";
4856 : sal_uInt8 fontKey[ 16 ] = { 0, 0xDE, 0xEF, 0x9A, 0xD8, 0x5C, 0xAC, 0x12, 0xF0, 0x4E,
4857 0 : 0xBC, 0xCA, 0x78, 0x4A, 0x01, 0 };
4858 0 : fontKey[ 0 ] = fontKey[ 15 ] = m_nextFontId % 256;
4859 0 : fontKeyStr[ 1 ] = fontKeyStr[ 35 ] = toHexChar(( m_nextFontId % 256 ) / 16 );
4860 0 : fontKeyStr[ 2 ] = fontKeyStr[ 36 ] = toHexChar(( m_nextFontId % 256 ) % 16 );
4861 : char buffer[ 4096 ];
4862 : sal_uInt64 readSize;
4863 0 : file.read( buffer, 32, readSize );
4864 0 : if( readSize < 32 )
4865 : {
4866 : SAL_WARN( "sw.ww8", "Font file size too small (" << fontUrl << ")" );
4867 0 : xOutStream->closeOutput();
4868 0 : return;
4869 : }
4870 0 : for( int i = 0;
4871 : i < 16;
4872 : ++i )
4873 : {
4874 0 : buffer[ i ] ^= fontKey[ i ];
4875 0 : buffer[ i + 16 ] ^= fontKey[ i ];
4876 : }
4877 0 : xOutStream->writeBytes( uno::Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( buffer ), 32 ));
4878 : for(;;)
4879 : {
4880 : sal_Bool eof;
4881 0 : if( file.isEndOfFile( &eof ) != osl::File::E_None )
4882 : {
4883 : SAL_WARN( "sw.ww8", "Error reading font file " << fontUrl );
4884 0 : xOutStream->closeOutput();
4885 0 : return;
4886 : }
4887 0 : if( eof )
4888 0 : break;
4889 0 : if( file.read( buffer, 4096, readSize ) != osl::File::E_None )
4890 : {
4891 : SAL_WARN( "sw.ww8", "Error reading font file " << fontUrl );
4892 0 : xOutStream->closeOutput();
4893 0 : return;
4894 : }
4895 0 : if( readSize == 0 )
4896 0 : break;
4897 0 : xOutStream->writeBytes( uno::Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( buffer ), readSize ));
4898 0 : }
4899 0 : xOutStream->closeOutput();
4900 0 : OString relId = OUStringToOString( GetExport().GetFilter().addRelation( m_pSerializer->getOutputStream(),
4901 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/font",
4902 0 : OUString( "fonts/font" ) + OUString::number( m_nextFontId ) + ".odttf" ), RTL_TEXTENCODING_UTF8 );
4903 0 : EmbeddedFontRef ref;
4904 0 : ref.relId = relId;
4905 0 : ref.fontKey = fontKeyStr;
4906 0 : fontFilesMap[ fontUrl ] = ref;
4907 0 : ++m_nextFontId;
4908 : }
4909 : m_pSerializer->singleElementNS( XML_w, tag,
4910 0 : FSNS( XML_r, XML_id ), fontFilesMap[ fontUrl ].relId,
4911 0 : FSNS( XML_w, XML_fontKey ), fontFilesMap[ fontUrl ].fontKey,
4912 0 : FSEND );
4913 : }
4914 :
4915 31 : OString DocxAttributeOutput::TransHighlightColor( const Color& rColor )
4916 : {
4917 31 : switch (rColor.GetColor())
4918 : {
4919 3 : case 0x000000: return OString("black"); break;
4920 1 : case 0x0000ff: return OString("blue"); break;
4921 1 : case 0x00ffff: return OString("cyan"); break;
4922 1 : case 0x00ff00: return OString("green"); break;
4923 1 : case 0xff00ff: return OString("magenta"); break;
4924 1 : case 0xff0000: return OString("red"); break;
4925 13 : case 0xffff00: return OString("yellow"); break;
4926 1 : case 0xffffff: return OString("white"); break;
4927 1 : case 0x000080: return OString("darkBlue"); break;
4928 1 : case 0x008080: return OString("darkCyan"); break;
4929 1 : case 0x008000: return OString("darkGreen"); break;
4930 1 : case 0x800080: return OString("darkMagenta"); break;
4931 1 : case 0x800000: return OString("darkRed"); break;
4932 1 : case 0x808000: return OString("darkYellow"); break;
4933 1 : case 0x808080: return OString("darkGray"); break;
4934 2 : case 0xC0C0C0: return OString("lightGray"); break;
4935 0 : default: return OString(); break;
4936 : }
4937 : }
4938 :
4939 121 : void DocxAttributeOutput::NumberingDefinition( sal_uInt16 nId, const SwNumRule &rRule )
4940 : {
4941 : // nId is the same both for abstract numbering definition as well as the
4942 : // numbering definition itself
4943 : // TODO check that this is actually true & fix if not ;-)
4944 121 : OString aId( OString::number( nId ) );
4945 :
4946 : m_pSerializer->startElementNS( XML_w, XML_num,
4947 : FSNS( XML_w, XML_numId ), aId.getStr(),
4948 121 : FSEND );
4949 :
4950 : m_pSerializer->singleElementNS( XML_w, XML_abstractNumId,
4951 : FSNS( XML_w, XML_val ), aId.getStr(),
4952 121 : FSEND );
4953 :
4954 : #if OSL_DEBUG_LEVEL > 1
4955 : // TODO ww8 version writes this, anything to do about it here?
4956 : if ( rRule.IsContinusNum() )
4957 : OSL_TRACE( "TODO DocxAttributeOutput::NumberingDefinition()" );
4958 : #else
4959 : (void) rRule; // to quiet the warning...
4960 : #endif
4961 :
4962 121 : m_pSerializer->endElementNS( XML_w, XML_num );
4963 121 : }
4964 :
4965 121 : void DocxAttributeOutput::StartAbstractNumbering( sal_uInt16 nId )
4966 : {
4967 : m_pSerializer->startElementNS( XML_w, XML_abstractNum,
4968 : FSNS( XML_w, XML_abstractNumId ), OString::number( nId ).getStr(),
4969 121 : FSEND );
4970 121 : }
4971 :
4972 121 : void DocxAttributeOutput::EndAbstractNumbering()
4973 : {
4974 121 : m_pSerializer->endElementNS( XML_w, XML_abstractNum );
4975 121 : }
4976 :
4977 1089 : void DocxAttributeOutput::NumberingLevel( sal_uInt8 nLevel,
4978 : sal_uInt16 nStart,
4979 : sal_uInt16 nNumberingType,
4980 : SvxAdjust eAdjust,
4981 : const sal_uInt8 * /*pNumLvlPos*/,
4982 : sal_uInt8 nFollow,
4983 : const wwFont *pFont,
4984 : const SfxItemSet *pOutSet,
4985 : sal_Int16 nIndentAt,
4986 : sal_Int16 nFirstLineIndex,
4987 : sal_Int16 nListTabPos,
4988 : const OUString &rNumberingString,
4989 : const SvxBrushItem* pBrush)
4990 : {
4991 : m_pSerializer->startElementNS( XML_w, XML_lvl,
4992 : FSNS( XML_w, XML_ilvl ), OString::number( nLevel ).getStr(),
4993 1089 : FSEND );
4994 :
4995 : // start with the nStart value. Do not write w:start if Numbered Lists
4996 : // starts from zero.As it's an optional parameter.
4997 : // refer ECMA 376 Second edition Part-1
4998 1089 : if(!(0 == nLevel && 0 == nStart))
4999 : {
5000 : m_pSerializer->singleElementNS( XML_w, XML_start,
5001 : FSNS( XML_w, XML_val ), OString::number( nStart ).getStr(),
5002 1089 : FSEND );
5003 : }
5004 :
5005 : // format
5006 1089 : OString aFmt( impl_NumberingType( nNumberingType ) );
5007 :
5008 1089 : if ( !aFmt.isEmpty() )
5009 : m_pSerializer->singleElementNS( XML_w, XML_numFmt,
5010 : FSNS( XML_w, XML_val ), aFmt.getStr(),
5011 1089 : FSEND );
5012 :
5013 : // suffix
5014 1089 : const char *pSuffix = NULL;
5015 1089 : switch ( nFollow )
5016 : {
5017 0 : case 1: pSuffix = "space"; break;
5018 227 : case 2: pSuffix = "nothing"; break;
5019 862 : default: /*pSuffix = "tab";*/ break;
5020 : }
5021 1089 : if ( pSuffix )
5022 : m_pSerializer->singleElementNS( XML_w, XML_suff,
5023 : FSNS( XML_w, XML_val ), pSuffix,
5024 227 : FSEND );
5025 :
5026 : // text
5027 1089 : OUString aText( rNumberingString );
5028 2178 : OUStringBuffer aBuffer( aText.getLength() + WW8ListManager::nMaxLevel );
5029 :
5030 1089 : const sal_Unicode *pPrev = aText.getStr();
5031 1089 : const sal_Unicode *pIt = aText.getStr();
5032 4318 : while ( pIt < aText.getStr() + aText.getLength() )
5033 : {
5034 : // convert the level values to %NUMBER form
5035 : // (we don't use pNumLvlPos at all)
5036 : // FIXME so far we support the ww8 limit of levels only
5037 2140 : if ( *pIt < sal_Unicode( WW8ListManager::nMaxLevel ) )
5038 : {
5039 972 : aBuffer.append( pPrev, pIt - pPrev );
5040 972 : aBuffer.append( '%' );
5041 972 : aBuffer.append( OUString::number( sal_Int32( *pIt ) + 1 ) );
5042 :
5043 972 : pPrev = pIt + 1;
5044 : }
5045 2140 : ++pIt;
5046 : }
5047 1089 : if ( pPrev < pIt )
5048 741 : aBuffer.append( pPrev, pIt - pPrev );
5049 :
5050 : // If bullet char is empty, set lvlText as empty
5051 1089 : if ( aText.equals ( OUString(sal_Unicode(0)) ) && nNumberingType == SVX_NUM_CHAR_SPECIAL )
5052 : {
5053 1 : m_pSerializer->singleElementNS( XML_w, XML_lvlText, FSNS( XML_w, XML_val ), "", FSEND );
5054 : }
5055 : else
5056 : {
5057 1088 : m_pSerializer->singleElementNS( XML_w, XML_lvlText,FSNS( XML_w, XML_val ), OUStringToOString( aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ).getStr(), FSEND );
5058 : }
5059 :
5060 : // bullet
5061 1089 : if (nNumberingType == SVX_NUM_BITMAP && pBrush)
5062 : {
5063 3 : int nIndex = m_rExport.GetGrfIndex(*pBrush);
5064 3 : if (nIndex != -1)
5065 : {
5066 : m_pSerializer->singleElementNS(XML_w, XML_lvlPicBulletId,
5067 : FSNS(XML_w, XML_val), OString::number(nIndex).getStr(),
5068 2 : FSEND);
5069 : }
5070 : }
5071 :
5072 : // justification
5073 : const char *pJc;
5074 1089 : bool ecmaDialect = ( m_rExport.GetFilter().getVersion() == oox::core::ECMA_DIALECT );
5075 1089 : switch ( eAdjust )
5076 : {
5077 0 : case SVX_ADJUST_CENTER: pJc = "center"; break;
5078 46 : case SVX_ADJUST_RIGHT: pJc = !ecmaDialect ? "end" : "right"; break;
5079 1043 : default: pJc = !ecmaDialect ? "start" : "left"; break;
5080 : }
5081 : m_pSerializer->singleElementNS( XML_w, XML_lvlJc,
5082 : FSNS( XML_w, XML_val ), pJc,
5083 1089 : FSEND );
5084 :
5085 : // indentation
5086 1089 : m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND );
5087 1089 : if( nListTabPos != 0 )
5088 : {
5089 658 : m_pSerializer->startElementNS( XML_w, XML_tabs, FSEND );
5090 : m_pSerializer->singleElementNS( XML_w, XML_tab,
5091 : FSNS( XML_w, XML_val ), "num",
5092 : FSNS( XML_w, XML_pos ), OString::number( nListTabPos ).getStr(),
5093 658 : FSEND );
5094 658 : m_pSerializer->endElementNS( XML_w, XML_tabs );
5095 : }
5096 :
5097 1089 : sal_Int32 nToken = ecmaDialect ? XML_left : XML_start;
5098 : m_pSerializer->singleElementNS( XML_w, XML_ind,
5099 : FSNS( XML_w, nToken ), OString::number( nIndentAt ).getStr(),
5100 : FSNS( XML_w, XML_hanging ), OString::number( -nFirstLineIndex ).getStr(),
5101 1089 : FSEND );
5102 1089 : m_pSerializer->endElementNS( XML_w, XML_pPr );
5103 :
5104 : // font
5105 1089 : if ( pOutSet )
5106 : {
5107 335 : m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
5108 :
5109 335 : if ( pFont )
5110 : {
5111 296 : GetExport().GetId( *pFont ); // ensure font info is written to fontTable.xml
5112 296 : OString aFamilyName( OUStringToOString( OUString( pFont->GetFamilyName() ), RTL_TEXTENCODING_UTF8 ) );
5113 : m_pSerializer->singleElementNS( XML_w, XML_rFonts,
5114 : FSNS( XML_w, XML_ascii ), aFamilyName.getStr(),
5115 : FSNS( XML_w, XML_hAnsi ), aFamilyName.getStr(),
5116 : FSNS( XML_w, XML_cs ), aFamilyName.getStr(),
5117 : FSNS( XML_w, XML_hint ), "default",
5118 296 : FSEND );
5119 : }
5120 335 : m_rExport.OutputItemSet( *pOutSet, false, true, i18n::ScriptType::LATIN, m_rExport.mbExportModeRTF );
5121 :
5122 335 : m_pSerializer->endElementNS( XML_w, XML_rPr );
5123 : }
5124 :
5125 : // TODO anything to do about nListTabPos?
5126 :
5127 2178 : m_pSerializer->endElementNS( XML_w, XML_lvl );
5128 1089 : }
5129 :
5130 86 : void DocxAttributeOutput::CharCaseMap( const SvxCaseMapItem& rCaseMap )
5131 : {
5132 86 : switch ( rCaseMap.GetValue() )
5133 : {
5134 : case SVX_CASEMAP_KAPITAELCHEN:
5135 16 : m_pSerializer->singleElementNS( XML_w, XML_smallCaps, FSEND );
5136 16 : break;
5137 : case SVX_CASEMAP_VERSALIEN:
5138 45 : m_pSerializer->singleElementNS( XML_w, XML_caps, FSEND );
5139 45 : break;
5140 : default: // Something that ooxml does not support
5141 25 : m_pSerializer->singleElementNS( XML_w, XML_smallCaps, FSNS( XML_w, XML_val ), "false", FSEND );
5142 25 : m_pSerializer->singleElementNS( XML_w, XML_caps, FSNS( XML_w, XML_val ), "false", FSEND );
5143 25 : break;
5144 : }
5145 86 : }
5146 :
5147 4360 : void DocxAttributeOutput::CharColor( const SvxColorItem& rColor )
5148 : {
5149 4360 : const Color aColor( rColor.GetValue() );
5150 4360 : OString aColorString;
5151 :
5152 4360 : aColorString = msfilter::util::ConvertColor( aColor );
5153 :
5154 4360 : AddToAttrList( m_pColorAttrList, FSNS( XML_w, XML_val ), aColorString.getStr() );
5155 4360 : }
5156 :
5157 4 : void DocxAttributeOutput::CharContour( const SvxContourItem& rContour )
5158 : {
5159 4 : if ( rContour.GetValue() )
5160 0 : m_pSerializer->singleElementNS( XML_w, XML_outline, FSEND );
5161 : else
5162 4 : m_pSerializer->singleElementNS( XML_w, XML_outline, FSNS( XML_w, XML_val ), "false", FSEND );
5163 4 : }
5164 :
5165 36 : void DocxAttributeOutput::CharCrossedOut( const SvxCrossedOutItem& rCrossedOut )
5166 : {
5167 36 : switch ( rCrossedOut.GetStrikeout() )
5168 : {
5169 : case STRIKEOUT_DOUBLE:
5170 0 : m_pSerializer->singleElementNS( XML_w, XML_dstrike, FSEND );
5171 0 : break;
5172 : case STRIKEOUT_NONE:
5173 31 : m_pSerializer->singleElementNS( XML_w, XML_dstrike, FSNS( XML_w, XML_val ), "false", FSEND );
5174 31 : m_pSerializer->singleElementNS( XML_w, XML_strike, FSNS( XML_w, XML_val ), "false", FSEND );
5175 31 : break;
5176 : default:
5177 5 : m_pSerializer->singleElementNS( XML_w, XML_strike, FSEND );
5178 5 : break;
5179 : }
5180 36 : }
5181 :
5182 125 : void DocxAttributeOutput::CharEscapement( const SvxEscapementItem& rEscapement )
5183 : {
5184 125 : OString sIss;
5185 125 : short nEsc = rEscapement.GetEsc(), nProp = rEscapement.GetProp();
5186 125 : if ( !nEsc )
5187 : {
5188 27 : sIss = OString( "baseline" );
5189 27 : nEsc = 0;
5190 27 : nProp = 100;
5191 : }
5192 98 : else if ( DFLT_ESC_PROP == nProp )
5193 : {
5194 98 : if ( DFLT_ESC_SUB == nEsc || DFLT_ESC_AUTO_SUB == nEsc )
5195 10 : sIss = OString( "subscript" );
5196 88 : else if ( DFLT_ESC_SUPER == nEsc || DFLT_ESC_AUTO_SUPER == nEsc )
5197 88 : sIss = OString( "superscript" );
5198 : }
5199 :
5200 125 : if ( !sIss.isEmpty() )
5201 : m_pSerializer->singleElementNS( XML_w, XML_vertAlign,
5202 125 : FSNS( XML_w, XML_val ), sIss.getStr(), FSEND );
5203 :
5204 125 : const SvxFontHeightItem& rItem = static_cast<const SvxFontHeightItem&>(m_rExport.GetItem(RES_CHRATR_FONTSIZE));
5205 125 : if (&rItem != NULL && (sIss.isEmpty() || sIss.match(OString("baseline"))))
5206 : {
5207 27 : long nHeight = rItem.GetHeight();
5208 27 : OString sPos = OString::number( ( nHeight * nEsc + 500 ) / 1000 );
5209 : m_pSerializer->singleElementNS( XML_w, XML_position,
5210 27 : FSNS( XML_w, XML_val ), sPos.getStr( ), FSEND );
5211 :
5212 27 : if( 100 != nProp || sIss.match( OString( "baseline" ) ) )
5213 : {
5214 27 : OString sSize = OString::number( ( nHeight * nProp + 500 ) / 1000 );
5215 : m_pSerializer->singleElementNS( XML_w, XML_sz,
5216 27 : FSNS( XML_w, XML_val ), sSize.getStr( ), FSEND );
5217 27 : }
5218 125 : }
5219 125 : }
5220 :
5221 5706 : void DocxAttributeOutput::CharFont( const SvxFontItem& rFont)
5222 : {
5223 5706 : GetExport().GetId( rFont ); // ensure font info is written to fontTable.xml
5224 5706 : OUString sFontName(rFont.GetFamilyName());
5225 11412 : OString sFontNameUtf8 = OUStringToOString(sFontName, RTL_TEXTENCODING_UTF8);
5226 : AddToAttrList( m_pFontsAttrList, 2,
5227 : FSNS( XML_w, XML_ascii ), sFontNameUtf8.getStr(),
5228 11412 : FSNS( XML_w, XML_hAnsi ), sFontNameUtf8.getStr() );
5229 5706 : }
5230 :
5231 13823 : void DocxAttributeOutput::CharFontSize( const SvxFontHeightItem& rFontSize)
5232 : {
5233 13823 : OString fontSize = OString::number( ( rFontSize.GetHeight() + 5 ) / 10 );
5234 :
5235 13823 : switch ( rFontSize.Which() )
5236 : {
5237 : case RES_CHRATR_FONTSIZE:
5238 : case RES_CHRATR_CJK_FONTSIZE:
5239 7996 : m_pSerializer->singleElementNS( XML_w, XML_sz, FSNS( XML_w, XML_val ), fontSize.getStr(), FSEND );
5240 7996 : break;
5241 : case RES_CHRATR_CTL_FONTSIZE:
5242 5827 : m_pSerializer->singleElementNS( XML_w, XML_szCs, FSNS( XML_w, XML_val ), fontSize.getStr(), FSEND );
5243 5827 : break;
5244 13823 : }
5245 13823 : }
5246 :
5247 177 : void DocxAttributeOutput::CharKerning( const SvxKerningItem& rKerning )
5248 : {
5249 177 : OString aKerning = OString::number( rKerning.GetValue() );
5250 177 : m_pSerializer->singleElementNS( XML_w, XML_spacing, FSNS(XML_w, XML_val), aKerning.getStr(), FSEND );
5251 177 : }
5252 :
5253 6175 : void DocxAttributeOutput::CharLanguage( const SvxLanguageItem& rLanguage )
5254 : {
5255 : OString aLanguageCode( OUStringToOString(
5256 12350 : LanguageTag( rLanguage.GetLanguage()).getBcp47(),
5257 6175 : RTL_TEXTENCODING_UTF8));
5258 :
5259 6175 : switch ( rLanguage.Which() )
5260 : {
5261 : case RES_CHRATR_LANGUAGE:
5262 2519 : AddToAttrList( m_pCharLangAttrList, FSNS( XML_w, XML_val ), aLanguageCode.getStr() );
5263 2519 : break;
5264 : case RES_CHRATR_CJK_LANGUAGE:
5265 1350 : AddToAttrList( m_pCharLangAttrList, FSNS( XML_w, XML_eastAsia ), aLanguageCode.getStr() );
5266 1350 : break;
5267 : case RES_CHRATR_CTL_LANGUAGE:
5268 2306 : AddToAttrList( m_pCharLangAttrList, FSNS( XML_w, XML_bidi ), aLanguageCode.getStr() );
5269 2306 : break;
5270 6175 : }
5271 6175 : }
5272 :
5273 1080 : void DocxAttributeOutput::CharPosture( const SvxPostureItem& rPosture )
5274 : {
5275 1080 : if ( rPosture.GetPosture() != ITALIC_NONE )
5276 981 : m_pSerializer->singleElementNS( XML_w, XML_i, FSEND );
5277 : else
5278 99 : m_pSerializer->singleElementNS( XML_w, XML_i, FSNS( XML_w, XML_val ), "false", FSEND );
5279 1080 : }
5280 :
5281 1 : void DocxAttributeOutput::CharShadow( const SvxShadowedItem& rShadow )
5282 : {
5283 1 : if ( rShadow.GetValue() )
5284 0 : m_pSerializer->singleElementNS( XML_w, XML_shadow, FSEND );
5285 : else
5286 1 : m_pSerializer->singleElementNS( XML_w, XML_shadow, FSNS( XML_w, XML_val ), "false", FSEND );
5287 1 : }
5288 :
5289 245 : void DocxAttributeOutput::CharUnderline( const SvxUnderlineItem& rUnderline )
5290 : {
5291 : const char *pUnderlineValue;
5292 :
5293 245 : switch ( rUnderline.GetLineStyle() )
5294 : {
5295 186 : case UNDERLINE_SINGLE: pUnderlineValue = "single"; break;
5296 1 : case UNDERLINE_BOLD: pUnderlineValue = "thick"; break;
5297 2 : case UNDERLINE_DOUBLE: pUnderlineValue = "double"; break;
5298 0 : case UNDERLINE_DOTTED: pUnderlineValue = "dotted"; break;
5299 0 : case UNDERLINE_DASH: pUnderlineValue = "dash"; break;
5300 0 : case UNDERLINE_DASHDOT: pUnderlineValue = "dotDash"; break;
5301 0 : case UNDERLINE_DASHDOTDOT: pUnderlineValue = "dotDotDash"; break;
5302 0 : case UNDERLINE_WAVE: pUnderlineValue = "wave"; break;
5303 0 : case UNDERLINE_BOLDDOTTED: pUnderlineValue = "dottedHeavy"; break;
5304 0 : case UNDERLINE_BOLDDASH: pUnderlineValue = "dashedHeavy"; break;
5305 0 : case UNDERLINE_LONGDASH: pUnderlineValue = "dashLongHeavy"; break;
5306 0 : case UNDERLINE_BOLDLONGDASH: pUnderlineValue = "dashLongHeavy"; break;
5307 0 : case UNDERLINE_BOLDDASHDOT: pUnderlineValue = "dashDotHeavy"; break;
5308 0 : case UNDERLINE_BOLDDASHDOTDOT: pUnderlineValue = "dashDotDotHeavy"; break;
5309 0 : case UNDERLINE_BOLDWAVE: pUnderlineValue = "wavyHeavy"; break;
5310 0 : case UNDERLINE_DOUBLEWAVE: pUnderlineValue = "wavyDouble"; break;
5311 : case UNDERLINE_NONE: // fall through
5312 56 : default: pUnderlineValue = "none"; break;
5313 : }
5314 :
5315 245 : Color aUnderlineColor = rUnderline.GetColor();
5316 245 : bool bUnderlineHasColor = aUnderlineColor.GetTransparency() == 0;
5317 245 : if (bUnderlineHasColor)
5318 : {
5319 : // Underline has a color
5320 : m_pSerializer->singleElementNS( XML_w, XML_u,
5321 : FSNS( XML_w, XML_val ), pUnderlineValue,
5322 : FSNS( XML_w, XML_color ), msfilter::util::ConvertColor( aUnderlineColor ).getStr(),
5323 23 : FSEND );
5324 : }
5325 : else
5326 : {
5327 : // Underline has no color
5328 222 : m_pSerializer->singleElementNS( XML_w, XML_u, FSNS( XML_w, XML_val ), pUnderlineValue, FSEND );
5329 : }
5330 245 : }
5331 :
5332 3202 : void DocxAttributeOutput::CharWeight( const SvxWeightItem& rWeight )
5333 : {
5334 3202 : if ( rWeight.GetWeight() == WEIGHT_BOLD )
5335 3066 : m_pSerializer->singleElementNS( XML_w, XML_b, FSEND );
5336 : else
5337 136 : m_pSerializer->singleElementNS( XML_w, XML_b, FSNS( XML_w, XML_val ), "false", FSEND );
5338 3202 : }
5339 :
5340 1149 : void DocxAttributeOutput::CharAutoKern( const SvxAutoKernItem& )
5341 : {
5342 : OSL_TRACE( "TODO DocxAttributeOutput::CharAutoKern()" );
5343 1149 : }
5344 :
5345 6 : void DocxAttributeOutput::CharAnimatedText( const SvxBlinkItem& rBlink )
5346 : {
5347 6 : if ( rBlink.GetValue() )
5348 0 : m_pSerializer->singleElementNS(XML_w, XML_effect, FSNS( XML_w, XML_val ), "blinkBackground", FSEND );
5349 : else
5350 6 : m_pSerializer->singleElementNS(XML_w, XML_effect, FSNS( XML_w, XML_val ), "none", FSEND );
5351 6 : }
5352 :
5353 : #define MSWORD_CH_SHADING_FILL "FFFFFF" // The attribute w:fill of w:shd, for MS-Word's character shading,
5354 : #define MSWORD_CH_SHADING_COLOR "auto" // The attribute w:color of w:shd, for MS-Word's character shading,
5355 : #define MSWORD_CH_SHADING_VAL "pct15" // The attribute w:value of w:shd, for MS-Word's character shading,
5356 :
5357 43 : void DocxAttributeOutput::CharBackground( const SvxBrushItem& rBrush )
5358 : {
5359 : // Check if the brush shading pattern is 'PCT15'. If so - write it back to the DOCX
5360 43 : if (rBrush.GetShadingValue() == +ShadingPattern::PCT15)
5361 : {
5362 : m_pSerializer->singleElementNS( XML_w, XML_shd,
5363 : FSNS( XML_w, XML_val ), MSWORD_CH_SHADING_VAL,
5364 : FSNS( XML_w, XML_color ), MSWORD_CH_SHADING_COLOR,
5365 : FSNS( XML_w, XML_fill ), MSWORD_CH_SHADING_FILL,
5366 1 : FSEND );
5367 : }
5368 : else
5369 : {
5370 : m_pSerializer->singleElementNS( XML_w, XML_shd,
5371 42 : FSNS( XML_w, XML_fill ), msfilter::util::ConvertColor( rBrush.GetColor() ).getStr(),
5372 : FSNS( XML_w, XML_val ), "clear",
5373 42 : FSEND );
5374 : }
5375 43 : }
5376 :
5377 2640 : void DocxAttributeOutput::CharFontCJK( const SvxFontItem& rFont )
5378 : {
5379 2640 : OUString sFontName(rFont.GetFamilyName());
5380 5280 : OString sFontNameUtf8 = OUStringToOString(sFontName, RTL_TEXTENCODING_UTF8);
5381 5280 : AddToAttrList( m_pFontsAttrList, FSNS( XML_w, XML_eastAsia ), sFontNameUtf8.getStr() );
5382 2640 : }
5383 :
5384 240 : void DocxAttributeOutput::CharPostureCJK( const SvxPostureItem& rPosture )
5385 : {
5386 240 : if ( rPosture.GetPosture() != ITALIC_NONE )
5387 214 : m_pSerializer->singleElementNS( XML_w, XML_i, FSEND );
5388 : else
5389 26 : m_pSerializer->singleElementNS( XML_w, XML_i, FSNS( XML_w, XML_val ), "false", FSEND );
5390 240 : }
5391 :
5392 1184 : void DocxAttributeOutput::CharWeightCJK( const SvxWeightItem& rWeight )
5393 : {
5394 1184 : if ( rWeight.GetWeight() == WEIGHT_BOLD )
5395 1122 : m_pSerializer->singleElementNS( XML_w, XML_b, FSEND );
5396 : else
5397 62 : m_pSerializer->singleElementNS( XML_w, XML_b, FSNS( XML_w, XML_val ), "false", FSEND );
5398 1184 : }
5399 :
5400 5395 : void DocxAttributeOutput::CharFontCTL( const SvxFontItem& rFont )
5401 : {
5402 5395 : OUString sFontName(rFont.GetFamilyName());
5403 10790 : OString sFontNameUtf8 = OUStringToOString(sFontName, RTL_TEXTENCODING_UTF8);
5404 10790 : AddToAttrList( m_pFontsAttrList, FSNS( XML_w, XML_cs ), sFontNameUtf8.getStr() );
5405 :
5406 5395 : }
5407 :
5408 567 : void DocxAttributeOutput::CharPostureCTL( const SvxPostureItem& rPosture)
5409 : {
5410 567 : if ( rPosture.GetPosture() != ITALIC_NONE )
5411 543 : m_pSerializer->singleElementNS( XML_w, XML_iCs, FSEND );
5412 : else
5413 24 : m_pSerializer->singleElementNS( XML_w, XML_iCs, FSNS( XML_w, XML_val ), "false", FSEND );
5414 567 : }
5415 :
5416 1136 : void DocxAttributeOutput::CharWeightCTL( const SvxWeightItem& rWeight )
5417 : {
5418 1136 : if ( rWeight.GetWeight() == WEIGHT_BOLD )
5419 1103 : m_pSerializer->singleElementNS( XML_w, XML_bCs, FSEND );
5420 : else
5421 33 : m_pSerializer->singleElementNS( XML_w, XML_bCs, FSNS( XML_w, XML_val ), "false", FSEND );
5422 1136 : }
5423 :
5424 272 : void DocxAttributeOutput::CharBidiRTL( const SfxPoolItem& )
5425 : {
5426 272 : }
5427 :
5428 296 : void DocxAttributeOutput::CharIdctHint( const SfxPoolItem& )
5429 : {
5430 296 : }
5431 :
5432 3 : void DocxAttributeOutput::CharRotate( const SvxCharRotateItem& rRotate)
5433 : {
5434 : // Not rorated or we the rotation already handled?
5435 3 : if ( !rRotate.GetValue() || m_bBtLr || m_rExport.SdrExporter().getFrameBtLr())
5436 6 : return;
5437 :
5438 0 : AddToAttrList( m_pEastAsianLayoutAttrList, FSNS( XML_w, XML_vert ), "true" );
5439 :
5440 0 : if (rRotate.IsFitToLine())
5441 0 : AddToAttrList( m_pEastAsianLayoutAttrList, FSNS( XML_w, XML_vertCompress ), "true" );
5442 : }
5443 :
5444 1 : void DocxAttributeOutput::CharEmphasisMark( const SvxEmphasisMarkItem& rEmphasisMark )
5445 : {
5446 : const char *pEmphasis;
5447 :
5448 1 : switch ( rEmphasisMark.GetValue() )
5449 : {
5450 1 : case EMPHASISMARK_NONE: pEmphasis = "none"; break;
5451 0 : case EMPHASISMARK_SIDE_DOTS: pEmphasis = "dot"; break;
5452 0 : case EMPHASISMARK_CIRCLE_ABOVE: pEmphasis = "circle"; break;
5453 0 : case EMPHASISMARK_DOTS_BELOW: pEmphasis = "underDot"; break;
5454 0 : default: pEmphasis = "comma"; break;
5455 : }
5456 :
5457 1 : m_pSerializer->singleElementNS( XML_w, XML_em, FSNS( XML_w, XML_val ), pEmphasis, FSEND );
5458 1 : }
5459 :
5460 0 : void DocxAttributeOutput::CharTwoLines( const SvxTwoLinesItem& rTwoLines )
5461 : {
5462 0 : if ( !rTwoLines.GetValue() )
5463 0 : return;
5464 :
5465 0 : AddToAttrList( m_pEastAsianLayoutAttrList, FSNS( XML_w, XML_combine ), "true" );
5466 :
5467 0 : sal_Unicode cStart = rTwoLines.GetStartBracket();
5468 0 : sal_Unicode cEnd = rTwoLines.GetEndBracket();
5469 :
5470 0 : if (!cStart && !cEnd)
5471 0 : return;
5472 :
5473 0 : OString sBracket;
5474 0 : if ((cStart == '{') || (cEnd == '}'))
5475 0 : sBracket = (sal_Char *)"curly";
5476 0 : else if ((cStart == '<') || (cEnd == '>'))
5477 0 : sBracket = (sal_Char *)"angle";
5478 0 : else if ((cStart == '[') || (cEnd == ']'))
5479 0 : sBracket = (sal_Char *)"square";
5480 : else
5481 0 : sBracket = (sal_Char *)"round";
5482 0 : AddToAttrList( m_pEastAsianLayoutAttrList, FSNS( XML_w, XML_combineBrackets ), sBracket.getStr() );
5483 : }
5484 :
5485 3 : void DocxAttributeOutput::CharScaleWidth( const SvxCharScaleWidthItem& rScaleWidth )
5486 : {
5487 : m_pSerializer->singleElementNS( XML_w, XML_w,
5488 3 : FSNS( XML_w, XML_val ), OString::number( rScaleWidth.GetValue() ).getStr(), FSEND );
5489 3 : }
5490 :
5491 3 : void DocxAttributeOutput::CharRelief( const SvxCharReliefItem& rRelief )
5492 : {
5493 3 : switch ( rRelief.GetValue() )
5494 : {
5495 : case RELIEF_EMBOSSED:
5496 0 : m_pSerializer->singleElementNS( XML_w, XML_emboss, FSEND );
5497 0 : break;
5498 : case RELIEF_ENGRAVED:
5499 0 : m_pSerializer->singleElementNS( XML_w, XML_imprint, FSEND );
5500 0 : break;
5501 : default:
5502 3 : m_pSerializer->singleElementNS( XML_w, XML_emboss, FSNS( XML_w, XML_val ), "false", FSEND );
5503 3 : m_pSerializer->singleElementNS( XML_w, XML_imprint, FSNS( XML_w, XML_val ), "false", FSEND );
5504 3 : break;
5505 : }
5506 3 : }
5507 :
5508 109 : void DocxAttributeOutput::CharHidden( const SvxCharHiddenItem& rHidden )
5509 : {
5510 109 : if ( rHidden.GetValue() )
5511 22 : m_pSerializer->singleElementNS( XML_w, XML_vanish, FSEND );
5512 : else
5513 87 : m_pSerializer->singleElementNS( XML_w, XML_vanish, FSNS( XML_w, XML_val ), "false", FSEND );
5514 109 : }
5515 :
5516 6 : void DocxAttributeOutput::CharBorder(
5517 : const SvxBorderLine* pAllBorder, const sal_uInt16 nDist, const bool bShadow )
5518 : {
5519 6 : impl_borderLine( m_pSerializer, XML_bdr, pAllBorder, nDist, bShadow );
5520 6 : }
5521 :
5522 31 : void DocxAttributeOutput::CharHighlight( const SvxBrushItem& rHighlight )
5523 : {
5524 31 : const OString sColor = TransHighlightColor( rHighlight.GetColor() );
5525 31 : if ( !sColor.isEmpty() )
5526 : {
5527 : m_pSerializer->singleElementNS( XML_w, XML_highlight,
5528 31 : FSNS( XML_w, XML_val ), sColor.getStr(), FSEND );
5529 31 : }
5530 31 : }
5531 :
5532 385 : void DocxAttributeOutput::TextINetFormat( const SwFmtINetFmt& rLink )
5533 : {
5534 385 : const SwTxtINetFmt* pINetFmt = rLink.GetTxtINetFmt();
5535 385 : const SwCharFmt* pCharFmt = pINetFmt->GetCharFmt();
5536 :
5537 385 : OString aStyleId(m_rExport.pStyles->GetStyleId(m_rExport.GetId(*pCharFmt)));
5538 :
5539 385 : m_pSerializer->singleElementNS( XML_w, XML_rStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND );
5540 385 : }
5541 :
5542 51 : void DocxAttributeOutput::TextCharFormat( const SwFmtCharFmt& rCharFmt )
5543 : {
5544 51 : OString aStyleId(m_rExport.pStyles->GetStyleId(m_rExport.GetId(*rCharFmt.GetCharFmt())));
5545 :
5546 51 : m_pSerializer->singleElementNS( XML_w, XML_rStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND );
5547 51 : }
5548 :
5549 0 : void DocxAttributeOutput::RefField( const SwField& rFld, const OUString& rRef )
5550 : {
5551 0 : sal_uInt16 nType = rFld.GetTyp( )->Which( );
5552 0 : if ( nType == RES_GETEXPFLD )
5553 : {
5554 0 : OUString sCmd = FieldString( ww::eREF );
5555 0 : sCmd += "\"" + rRef + "\" ";
5556 :
5557 0 : m_rExport.OutputField( &rFld, ww::eREF, sCmd );
5558 : }
5559 :
5560 : // There is nothing to do here for the set fields
5561 0 : }
5562 :
5563 0 : void DocxAttributeOutput::HiddenField( const SwField& /*rFld*/ )
5564 : {
5565 : OSL_TRACE( "TODO DocxAttributeOutput::HiddenField()" );
5566 0 : }
5567 :
5568 5 : void DocxAttributeOutput::PostitField( const SwField* pFld )
5569 : {
5570 : assert( dynamic_cast< const SwPostItField* >( pFld ));
5571 5 : const SwPostItField* pPostItFld = static_cast<const SwPostItField*>(pFld);
5572 5 : OString aName = OUStringToOString(pPostItFld->GetName(), RTL_TEXTENCODING_UTF8);
5573 5 : sal_Int32 nId = 0;
5574 5 : std::map< OString, sal_uInt16 >::iterator it = m_rOpenedAnnotationMarksIds.find(aName);
5575 5 : if (it != m_rOpenedAnnotationMarksIds.end())
5576 : // If the postit field has an annotation mark associated, we already have an id.
5577 4 : nId = it->second;
5578 : else
5579 : // Otherwise get a new one.
5580 1 : nId = m_nNextAnnotationMarkId++;
5581 5 : m_postitFields.push_back(std::make_pair(pPostItFld, nId));
5582 5 : }
5583 :
5584 6489 : void DocxAttributeOutput::WritePostitFieldReference()
5585 : {
5586 12983 : while( m_postitFieldsMaxId < m_postitFields.size())
5587 : {
5588 5 : OString idstr = OString::number(m_postitFields[m_postitFieldsMaxId].second);
5589 :
5590 : // In case this file is inside annotation marks, we want to write the
5591 : // comment reference after the annotation mark is closed, not here.
5592 10 : OString idname = OUStringToOString(m_postitFields[m_postitFieldsMaxId].first->GetName(), RTL_TEXTENCODING_UTF8);
5593 5 : std::map< OString, sal_uInt16 >::iterator it = m_rOpenedAnnotationMarksIds.find( idname );
5594 5 : if ( it == m_rOpenedAnnotationMarksIds.end( ) )
5595 1 : m_pSerializer->singleElementNS( XML_w, XML_commentReference, FSNS( XML_w, XML_id ), idstr.getStr(), FSEND );
5596 5 : ++m_postitFieldsMaxId;
5597 5 : }
5598 6489 : }
5599 :
5600 3 : void DocxAttributeOutput::WritePostitFields()
5601 : {
5602 16 : for( unsigned int i = 0;
5603 8 : i < m_postitFields.size();
5604 : ++i )
5605 : {
5606 5 : OString idstr = OString::number( m_postitFields[ i ].second);
5607 5 : const SwPostItField* f = m_postitFields[ i ].first;
5608 : m_pSerializer->startElementNS( XML_w, XML_comment, FSNS( XML_w, XML_id ), idstr.getStr(),
5609 5 : FSNS( XML_w, XML_author ), OUStringToOString( f->GetPar1(), RTL_TEXTENCODING_UTF8 ).getStr(),
5610 : FSNS( XML_w, XML_date ), DateTimeToOString(f->GetDateTime()).getStr(),
5611 10 : FSNS( XML_w, XML_initials ), OUStringToOString( f->GetInitials(), RTL_TEXTENCODING_UTF8 ).getStr(), FSEND );
5612 : // Check for the text object existing, it seems that it can be NULL when saving a newly created
5613 : // comment without giving focus back to the main document. As GetTxt() is empty in that case as well,
5614 : // that is probably a bug in the Writer core.
5615 5 : if( f->GetTextObject() != NULL )
5616 5 : GetExport().WriteOutliner( *f->GetTextObject(), TXT_ATN );
5617 5 : m_pSerializer->endElementNS( XML_w, XML_comment );
5618 5 : }
5619 3 : }
5620 :
5621 0 : bool DocxAttributeOutput::DropdownField( const SwField* pFld )
5622 : {
5623 0 : bool bExpand = false;
5624 :
5625 0 : ww::eField eType = ww::eFORMDROPDOWN;
5626 0 : OUString sCmd = FieldString( eType );
5627 0 : GetExport( ).OutputField( pFld, eType, sCmd );
5628 :
5629 0 : return bExpand;
5630 : }
5631 :
5632 0 : bool DocxAttributeOutput::PlaceholderField( const SwField* pFld )
5633 : {
5634 : assert( pendingPlaceholder == NULL );
5635 0 : pendingPlaceholder = pFld;
5636 0 : return false; // do not expand
5637 : }
5638 :
5639 6494 : void DocxAttributeOutput::WritePendingPlaceholder()
5640 : {
5641 6494 : if( pendingPlaceholder == NULL )
5642 12988 : return;
5643 0 : const SwField* pFld = pendingPlaceholder;
5644 0 : pendingPlaceholder = NULL;
5645 0 : m_pSerializer->startElementNS( XML_w, XML_sdt, FSEND );
5646 0 : m_pSerializer->startElementNS( XML_w, XML_sdtPr, FSEND );
5647 0 : if( !pFld->GetPar2().isEmpty())
5648 : m_pSerializer->singleElementNS( XML_w, XML_alias,
5649 0 : FSNS( XML_w, XML_val ), OUStringToOString( pFld->GetPar2(), RTL_TEXTENCODING_UTF8 ), FSEND );
5650 0 : m_pSerializer->singleElementNS( XML_w, XML_temporary, FSEND );
5651 0 : m_pSerializer->singleElementNS( XML_w, XML_showingPlcHdr, FSEND );
5652 0 : m_pSerializer->singleElementNS( XML_w, XML_text, FSEND );
5653 0 : m_pSerializer->endElementNS( XML_w, XML_sdtPr );
5654 0 : m_pSerializer->startElementNS( XML_w, XML_sdtContent, FSEND );
5655 0 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
5656 0 : RunText( pFld->GetPar1());
5657 0 : m_pSerializer->endElementNS( XML_w, XML_r );
5658 0 : m_pSerializer->endElementNS( XML_w, XML_sdtContent );
5659 0 : m_pSerializer->endElementNS( XML_w, XML_sdt );
5660 : }
5661 :
5662 0 : void DocxAttributeOutput::SetField( const SwField& rFld, ww::eField eType, const OUString& rCmd )
5663 : {
5664 : // field bookmarks are handled in the EndRun method
5665 0 : GetExport().OutputField(&rFld, eType, rCmd );
5666 0 : }
5667 :
5668 1 : void DocxAttributeOutput::WriteExpand( const SwField* pFld )
5669 : {
5670 : // Will be written in the next End Run
5671 1 : OUString sCmd;
5672 1 : m_rExport.OutputField( pFld, ww::eUNKNOWN, sCmd );
5673 1 : }
5674 :
5675 260 : void DocxAttributeOutput::WriteField_Impl( const SwField* pFld, ww::eField eType, const OUString& rFldCmd, sal_uInt8 nMode )
5676 : {
5677 260 : struct FieldInfos infos;
5678 260 : if (pFld)
5679 80 : infos.pField = pFld->CopyField();
5680 260 : infos.sCmd = rFldCmd;
5681 260 : infos.eType = eType;
5682 260 : infos.bClose = WRITEFIELD_CLOSE & nMode;
5683 260 : infos.bOpen = WRITEFIELD_START & nMode;
5684 260 : m_Fields.push_back( infos );
5685 :
5686 260 : if ( pFld )
5687 : {
5688 80 : sal_uInt16 nType = pFld->GetTyp( )->Which( );
5689 80 : sal_uInt16 nSubType = pFld->GetSubType();
5690 :
5691 : // TODO Any other field types here ?
5692 80 : if ( ( nType == RES_SETEXPFLD ) && ( nSubType & nsSwGetSetExpType::GSE_STRING ) )
5693 : {
5694 0 : const SwSetExpField *pSet = ( const SwSetExpField* )( pFld );
5695 0 : m_sFieldBkm = pSet->GetPar1( );
5696 : }
5697 80 : else if ( nType == RES_DROPDOWN )
5698 : {
5699 0 : const SwDropDownField* pDropDown = ( const SwDropDownField* )( pFld );
5700 0 : m_sFieldBkm = pDropDown->GetName( );
5701 : }
5702 260 : }
5703 260 : }
5704 :
5705 1 : void DocxAttributeOutput::WriteFormData_Impl( const ::sw::mark::IFieldmark& rFieldmark )
5706 : {
5707 1 : if ( !m_Fields.empty() )
5708 1 : m_Fields.begin()->pFieldmark = &rFieldmark;
5709 1 : }
5710 :
5711 11680 : void DocxAttributeOutput::WriteBookmarks_Impl( std::vector< OUString >& rStarts,
5712 : std::vector< OUString >& rEnds )
5713 : {
5714 12461 : for ( std::vector< OUString >::const_iterator it = rStarts.begin(), end = rStarts.end(); it != end; ++it )
5715 : {
5716 781 : OString rName = OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr( );
5717 781 : m_rBookmarksStart.push_back( rName );
5718 781 : }
5719 11680 : rStarts.clear();
5720 :
5721 12445 : for ( std::vector< OUString >::const_iterator it = rEnds.begin(), end = rEnds.end(); it != end; ++it )
5722 : {
5723 765 : OString rName = OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr( );
5724 765 : m_rBookmarksEnd.push_back( rName );
5725 765 : }
5726 11680 : rEnds.clear();
5727 11680 : }
5728 :
5729 11678 : void DocxAttributeOutput::WriteAnnotationMarks_Impl( std::vector< OUString >& rStarts,
5730 : std::vector< OUString >& rEnds )
5731 : {
5732 11684 : for ( std::vector< OUString >::const_iterator it = rStarts.begin(), end = rStarts.end(); it != end; ++it )
5733 : {
5734 6 : OString rName = OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr( );
5735 6 : m_rAnnotationMarksStart.push_back( rName );
5736 6 : }
5737 11678 : rStarts.clear();
5738 :
5739 11682 : for ( std::vector< OUString >::const_iterator it = rEnds.begin(), end = rEnds.end(); it != end; ++it )
5740 : {
5741 4 : OString rName = OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr( );
5742 4 : m_rAnnotationMarksEnd.push_back( rName );
5743 4 : }
5744 11678 : rEnds.clear();
5745 11678 : }
5746 :
5747 5 : void DocxAttributeOutput::TextFootnote_Impl( const SwFmtFtn& rFootnote )
5748 : {
5749 5 : const SwEndNoteInfo& rInfo = rFootnote.IsEndNote()?
5750 5 : m_rExport.pDoc->GetEndNoteInfo(): m_rExport.pDoc->GetFtnInfo();
5751 :
5752 : // footnote/endnote run properties
5753 5 : const SwCharFmt* pCharFmt = rInfo.GetAnchorCharFmt( *m_rExport.pDoc );
5754 :
5755 5 : OString aStyleId(m_rExport.pStyles->GetStyleId(m_rExport.GetId(*pCharFmt)));
5756 :
5757 5 : m_pSerializer->singleElementNS( XML_w, XML_rStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND );
5758 :
5759 : // remember the footnote/endnote to
5760 : // 1) write the footnoteReference/endnoteReference in EndRunProperties()
5761 : // 2) be able to dump them all to footnotes.xml/endnotes.xml
5762 5 : if ( !rFootnote.IsEndNote() )
5763 3 : m_pFootnotesList->add( rFootnote );
5764 : else
5765 2 : m_pEndnotesList->add( rFootnote );
5766 5 : }
5767 :
5768 6494 : void DocxAttributeOutput::FootnoteEndnoteReference()
5769 : {
5770 : sal_Int32 nId;
5771 6494 : const SwFmtFtn *pFootnote = m_pFootnotesList->getCurrent( nId );
5772 :
5773 : // both cannot be set at the same time - if they are, it's a bug
5774 6494 : if ( !pFootnote )
5775 6491 : pFootnote = m_pEndnotesList->getCurrent( nId );
5776 :
5777 6494 : if ( !pFootnote )
5778 12983 : return;
5779 :
5780 5 : sal_Int32 nToken = pFootnote->IsEndNote()? XML_endnoteReference: XML_footnoteReference;
5781 :
5782 : // write it
5783 5 : if ( pFootnote->GetNumStr().isEmpty() )
5784 : {
5785 : // autonumbered
5786 : m_pSerializer->singleElementNS( XML_w, nToken,
5787 : FSNS( XML_w, XML_id ), OString::number( nId ).getStr(),
5788 5 : FSEND );
5789 : }
5790 : else
5791 : {
5792 : // not autonumbered
5793 : m_pSerializer->singleElementNS( XML_w, nToken,
5794 : FSNS( XML_w, XML_customMarkFollows ), "1",
5795 : FSNS( XML_w, XML_id ), OString::number( nId ).getStr(),
5796 0 : FSEND );
5797 :
5798 0 : RunText( pFootnote->GetNumStr() );
5799 : }
5800 : }
5801 :
5802 3 : void DocxAttributeOutput::FootnotesEndnotes( bool bFootnotes )
5803 : {
5804 3 : m_setFootnote = true;
5805 3 : const FootnotesVector& rVector = bFootnotes? m_pFootnotesList->getVector(): m_pEndnotesList->getVector();
5806 :
5807 3 : sal_Int32 nBody = bFootnotes? XML_footnotes: XML_endnotes;
5808 3 : sal_Int32 nItem = bFootnotes? XML_footnote: XML_endnote;
5809 :
5810 : m_pSerializer->startElementNS( XML_w, nBody,
5811 : FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
5812 : FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
5813 3 : FSEND );
5814 :
5815 3 : sal_Int32 nIndex = 0;
5816 :
5817 : // separator
5818 : m_pSerializer->startElementNS( XML_w, nItem,
5819 : FSNS( XML_w, XML_id ), OString::number( nIndex++ ).getStr(),
5820 : FSNS( XML_w, XML_type ), "separator",
5821 3 : FSEND );
5822 3 : m_pSerializer->startElementNS( XML_w, XML_p, FSEND );
5823 3 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
5824 :
5825 3 : bool bSeparator = true;
5826 3 : if (bFootnotes)
5827 : {
5828 2 : const SwPageFtnInfo& rFtnInfo = m_rExport.pDoc->GetPageDesc(0).GetFtnInfo();
5829 : // Request a separator only in case the width is larger than zero.
5830 2 : bSeparator = double(rFtnInfo.GetWidth()) > 0;
5831 : }
5832 :
5833 3 : if (bSeparator)
5834 2 : m_pSerializer->singleElementNS( XML_w, XML_separator, FSEND );
5835 3 : m_pSerializer->endElementNS( XML_w, XML_r );
5836 3 : m_pSerializer->endElementNS( XML_w, XML_p );
5837 3 : m_pSerializer->endElementNS( XML_w, nItem );
5838 :
5839 : // separator
5840 : m_pSerializer->startElementNS( XML_w, nItem,
5841 : FSNS( XML_w, XML_id ), OString::number( nIndex++ ).getStr(),
5842 : FSNS( XML_w, XML_type ), "continuationSeparator",
5843 3 : FSEND );
5844 3 : m_pSerializer->startElementNS( XML_w, XML_p, FSEND );
5845 3 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
5846 3 : m_pSerializer->singleElementNS( XML_w, XML_continuationSeparator, FSEND );
5847 3 : m_pSerializer->endElementNS( XML_w, XML_r );
5848 3 : m_pSerializer->endElementNS( XML_w, XML_p );
5849 3 : m_pSerializer->endElementNS( XML_w, nItem );
5850 :
5851 : // if new special ones are added, update also WriteFootnoteEndnotePr()
5852 :
5853 : // footnotes/endnotes themselves
5854 8 : for ( FootnotesVector::const_iterator i = rVector.begin(); i != rVector.end(); ++i, ++nIndex )
5855 : {
5856 : m_pSerializer->startElementNS( XML_w, nItem,
5857 : FSNS( XML_w, XML_id ), OString::number( nIndex ).getStr(),
5858 5 : FSEND );
5859 :
5860 5 : const SwNodeIndex* pIndex = (*i)->GetTxtFtn()->GetStartNode();
5861 : // tag required at the start of each footnote/endnote
5862 5 : m_footnoteEndnoteRefTag = bFootnotes ? XML_footnoteRef : XML_endnoteRef;
5863 :
5864 5 : m_rExport.WriteSpecialText( pIndex->GetIndex() + 1,
5865 5 : pIndex->GetNode().EndOfSectionIndex(),
5866 15 : bFootnotes? TXT_FTN: TXT_EDN );
5867 :
5868 5 : m_pSerializer->endElementNS( XML_w, nItem );
5869 : }
5870 :
5871 3 : m_pSerializer->endElementNS( XML_w, nBody );
5872 :
5873 3 : }
5874 :
5875 6 : void DocxAttributeOutput::WriteFootnoteEndnotePr( ::sax_fastparser::FSHelperPtr fs, int tag,
5876 : const SwEndNoteInfo& info, int listtag )
5877 : {
5878 6 : fs->startElementNS( XML_w, tag, FSEND );
5879 6 : const char* fmt = NULL;
5880 6 : switch( info.aFmt.GetNumberingType())
5881 : {
5882 : case SVX_NUM_CHARS_UPPER_LETTER_N: // fall through, map to upper letters
5883 : case SVX_NUM_CHARS_UPPER_LETTER:
5884 0 : fmt = "upperLetter";
5885 0 : break;
5886 : case SVX_NUM_CHARS_LOWER_LETTER_N: // fall through, map to lower letters
5887 : case SVX_NUM_CHARS_LOWER_LETTER:
5888 0 : fmt = "lowerLetter";
5889 0 : break;
5890 : case SVX_NUM_ROMAN_UPPER:
5891 0 : fmt = "upperRoman";
5892 0 : break;
5893 : case SVX_NUM_ROMAN_LOWER:
5894 2 : fmt = "lowerRoman";
5895 2 : break;
5896 : case SVX_NUM_ARABIC:
5897 4 : fmt = "decimal";
5898 4 : break;
5899 : case SVX_NUM_NUMBER_NONE:
5900 0 : fmt = "none";
5901 0 : break;
5902 : case SVX_NUM_CHAR_SPECIAL:
5903 0 : fmt = "bullet";
5904 0 : break;
5905 : case SVX_NUM_PAGEDESC:
5906 : case SVX_NUM_BITMAP:
5907 : default:
5908 0 : break; // no format
5909 : }
5910 6 : if( fmt != NULL )
5911 6 : fs->singleElementNS( XML_w, XML_numFmt, FSNS( XML_w, XML_val ), fmt, FSEND );
5912 6 : if( info.nFtnOffset != 0 )
5913 : fs->singleElementNS( XML_w, XML_numStart, FSNS( XML_w, XML_val ),
5914 0 : OString::number( info.nFtnOffset + 1).getStr(), FSEND );
5915 6 : if( listtag != 0 ) // we are writing to settings.xml, write also special footnote/endnote list
5916 : { // there are currently only two hardcoded ones ( see FootnotesEndnotes())
5917 3 : fs->singleElementNS( XML_w, listtag, FSNS( XML_w, XML_id ), "0", FSEND );
5918 3 : fs->singleElementNS( XML_w, listtag, FSNS( XML_w, XML_id ), "1", FSEND );
5919 : }
5920 6 : fs->endElementNS( XML_w, tag );
5921 6 : }
5922 :
5923 298 : void DocxAttributeOutput::SectFootnoteEndnotePr()
5924 : {
5925 298 : if( HasFootnotes())
5926 2 : WriteFootnoteEndnotePr( m_pSerializer, XML_footnotePr, m_rExport.pDoc->GetFtnInfo(), 0 );
5927 298 : if( HasEndnotes())
5928 1 : WriteFootnoteEndnotePr( m_pSerializer, XML_endnotePr, m_rExport.pDoc->GetEndNoteInfo(), 0 );
5929 298 : }
5930 :
5931 1593 : void DocxAttributeOutput::ParaLineSpacing_Impl( short nSpace, short nMulti )
5932 : {
5933 1593 : if ( nSpace < 0 )
5934 : {
5935 : AddToAttrList( m_pParagraphSpacingAttrList, 2,
5936 : FSNS( XML_w, XML_lineRule ), "exact",
5937 75 : FSNS( XML_w, XML_line ), OString::number( -nSpace ).getStr() );
5938 : }
5939 1518 : else if( nMulti )
5940 : {
5941 : AddToAttrList( m_pParagraphSpacingAttrList, 2,
5942 : FSNS( XML_w, XML_lineRule ), "auto",
5943 1256 : FSNS( XML_w, XML_line ), OString::number( nSpace ).getStr() );
5944 : }
5945 262 : else if ( nSpace > 0 )
5946 : {
5947 : AddToAttrList( m_pParagraphSpacingAttrList, 2,
5948 : FSNS( XML_w, XML_lineRule ), "atLeast",
5949 262 : FSNS( XML_w, XML_line ), OString::number( nSpace ).getStr() );
5950 : }
5951 : else
5952 0 : AddToAttrList( m_pParagraphSpacingAttrList, FSNS( XML_w, XML_lineRule ), "auto" );
5953 1593 : }
5954 :
5955 2214 : void DocxAttributeOutput::ParaAdjust( const SvxAdjustItem& rAdjust )
5956 : {
5957 : const char *pAdjustString;
5958 :
5959 2214 : bool bEcma = GetExport().GetFilter().getVersion( ) == oox::core::ECMA_DIALECT;
5960 :
5961 2214 : const SfxItemSet* pItems = GetExport().GetCurItemSet();
5962 : const SvxFrameDirectionItem* rFrameDir = pItems?
5963 2214 : static_cast< const SvxFrameDirectionItem* >( pItems->GetItem( RES_FRAMEDIR ) ): NULL;
5964 :
5965 2214 : short nDir = FRMDIR_ENVIRONMENT;
5966 2214 : if( rFrameDir != NULL )
5967 2147 : nDir = rFrameDir->GetValue();
5968 2214 : if ( nDir == FRMDIR_ENVIRONMENT )
5969 81 : nDir = GetExport( ).GetDefaultFrameDirection( );
5970 2214 : bool bRtl = ( nDir == FRMDIR_HORI_RIGHT_TOP );
5971 :
5972 2214 : switch ( rAdjust.GetAdjust() )
5973 : {
5974 : case SVX_ADJUST_LEFT:
5975 534 : if ( bEcma )
5976 : {
5977 0 : if ( bRtl )
5978 0 : pAdjustString = "right";
5979 : else
5980 0 : pAdjustString = "left";
5981 : }
5982 534 : else if ( bRtl )
5983 1 : pAdjustString = "end";
5984 : else
5985 533 : pAdjustString = "start";
5986 534 : break;
5987 : case SVX_ADJUST_RIGHT:
5988 315 : if ( bEcma )
5989 : {
5990 0 : if ( bRtl )
5991 0 : pAdjustString = "left";
5992 : else
5993 0 : pAdjustString = "right";
5994 : }
5995 315 : else if ( bRtl )
5996 3 : pAdjustString = "start";
5997 : else
5998 312 : pAdjustString = "end";
5999 315 : break;
6000 : case SVX_ADJUST_BLOCKLINE:
6001 : case SVX_ADJUST_BLOCK:
6002 605 : pAdjustString = "both";
6003 605 : break;
6004 : case SVX_ADJUST_CENTER:
6005 760 : pAdjustString = "center";
6006 760 : break;
6007 : default:
6008 2214 : return; // not supported attribute
6009 : }
6010 2214 : m_pSerializer->singleElementNS( XML_w, XML_jc, FSNS( XML_w, XML_val ), pAdjustString, FSEND );
6011 : }
6012 :
6013 112 : void DocxAttributeOutput::ParaSplit( const SvxFmtSplitItem& rSplit )
6014 : {
6015 112 : if (rSplit.GetValue())
6016 2 : m_pSerializer->singleElementNS( XML_w, XML_keepLines, FSNS( XML_w, XML_val ), "false", FSEND );
6017 : else
6018 110 : m_pSerializer->singleElementNS( XML_w, XML_keepLines, FSEND );
6019 112 : }
6020 :
6021 1190 : void DocxAttributeOutput::ParaWidows( const SvxWidowsItem& rWidows )
6022 : {
6023 1190 : if (rWidows.GetValue())
6024 398 : m_pSerializer->singleElementNS( XML_w, XML_widowControl, FSEND );
6025 : else
6026 792 : m_pSerializer->singleElementNS( XML_w, XML_widowControl, FSNS( XML_w, XML_val ), "false", FSEND );
6027 1190 : }
6028 :
6029 1248 : static void impl_WriteTabElement( FSHelperPtr pSerializer,
6030 : const SvxTabStop& rTab, long /* nCurrentLeft */ )
6031 : {
6032 1248 : FastAttributeList *pTabElementAttrList = pSerializer->createAttrList();
6033 :
6034 1248 : switch (rTab.GetAdjustment())
6035 : {
6036 : case SVX_TAB_ADJUST_RIGHT:
6037 416 : pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"right") );
6038 416 : break;
6039 : case SVX_TAB_ADJUST_DECIMAL:
6040 1 : pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"decimal") );
6041 1 : break;
6042 : case SVX_TAB_ADJUST_CENTER:
6043 185 : pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"center") );
6044 185 : break;
6045 : case SVX_TAB_ADJUST_DEFAULT:
6046 : case SVX_TAB_ADJUST_LEFT:
6047 : default:
6048 646 : pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"left") );
6049 646 : break;
6050 : }
6051 :
6052 : // Because GetTabPos already includes indent, we don't need to add nCurrentLeft (CurrentLeft is indentation information)
6053 : //pTabElementAttrList->add( FSNS( XML_w, XML_pos ), OString::valueOf( rTab.GetTabPos() + nCurrentLeft ) );
6054 1248 : pTabElementAttrList->add( FSNS( XML_w, XML_pos ), OString::number( rTab.GetTabPos() ) );
6055 :
6056 1248 : sal_Unicode cFillChar = rTab.GetFill();
6057 :
6058 1248 : if ('.' == cFillChar )
6059 157 : pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "dot" ) );
6060 1091 : else if ( '-' == cFillChar )
6061 0 : pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "hyphen" ) );
6062 1091 : else if ( sal_Unicode(0xB7) == cFillChar ) // middle dot
6063 0 : pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "middleDot" ) );
6064 1091 : else if ( '_' == cFillChar )
6065 0 : pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "underscore" ) );
6066 : else
6067 1091 : pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "none" ) );
6068 :
6069 1248 : pSerializer->singleElementNS( XML_w, XML_tab, pTabElementAttrList );
6070 1248 : }
6071 :
6072 1360 : void DocxAttributeOutput::ParaTabStop( const SvxTabStopItem& rTabStop )
6073 : {
6074 1360 : const SfxPoolItem* pLR = m_rExport.HasItem( RES_LR_SPACE );
6075 1360 : long nCurrentLeft = pLR ? ((const SvxLRSpaceItem*)pLR)->GetTxtLeft() : 0;
6076 :
6077 1360 : sal_uInt16 nCount = rTabStop.Count();
6078 :
6079 : // <w:tabs> must contain at least one <w:tab>, so don't write it empty
6080 1360 : if( nCount == 0 )
6081 8 : return;
6082 1352 : if( nCount == 1 && rTabStop[ 0 ].GetAdjustment() == SVX_TAB_ADJUST_DEFAULT )
6083 : {
6084 668 : GetExport().setDefaultTabStop( rTabStop[ 0 ].GetTabPos());
6085 668 : return;
6086 : }
6087 :
6088 684 : m_pSerializer->startElementNS( XML_w, XML_tabs, FSEND );
6089 :
6090 1932 : for (sal_uInt16 i = 0; i < nCount; i++ )
6091 : {
6092 1248 : if( rTabStop[i].GetAdjustment() != SVX_TAB_ADJUST_DEFAULT )
6093 1248 : impl_WriteTabElement( m_pSerializer, rTabStop[i], nCurrentLeft );
6094 : else
6095 0 : GetExport().setDefaultTabStop( rTabStop[i].GetTabPos());
6096 : }
6097 :
6098 684 : m_pSerializer->endElementNS( XML_w, XML_tabs );
6099 : }
6100 :
6101 475 : void DocxAttributeOutput::ParaHyphenZone( const SvxHyphenZoneItem& rHyphenZone )
6102 : {
6103 : m_pSerializer->singleElementNS( XML_w, XML_suppressAutoHyphens,
6104 475 : FSNS( XML_w, XML_val ), rHyphenZone.IsHyphen( ) ? "false" : "true" ,
6105 475 : FSEND );
6106 475 : }
6107 :
6108 419 : void DocxAttributeOutput::ParaNumRule_Impl( const SwTxtNode* /*pTxtNd*/, sal_Int32 nLvl, sal_Int32 nNumId )
6109 : {
6110 419 : if ( USHRT_MAX != nNumId && 0 != nNumId )
6111 : {
6112 401 : m_pSerializer->startElementNS( XML_w, XML_numPr, FSEND );
6113 401 : m_pSerializer->singleElementNS( XML_w, XML_ilvl, FSNS( XML_w, XML_val ), OString::number( nLvl).getStr(), FSEND );
6114 401 : m_pSerializer->singleElementNS( XML_w, XML_numId, FSNS( XML_w, XML_val ), OString::number( nNumId).getStr(), FSEND );
6115 401 : m_pSerializer->endElementNS( XML_w, XML_numPr );
6116 : }
6117 419 : }
6118 :
6119 18 : void DocxAttributeOutput::ParaScriptSpace( const SfxBoolItem& rScriptSpace )
6120 : {
6121 : m_pSerializer->singleElementNS( XML_w, XML_autoSpaceDE,
6122 18 : FSNS( XML_w, XML_val ), rScriptSpace.GetValue( ) ? "true": "false",
6123 18 : FSEND );
6124 18 : }
6125 :
6126 68 : void DocxAttributeOutput::ParaHangingPunctuation( const SfxBoolItem& rItem )
6127 : {
6128 : m_pSerializer->singleElementNS( XML_w, XML_overflowPunct,
6129 68 : FSNS( XML_w, XML_val ), rItem.GetValue( ) ? "true": "false",
6130 68 : FSEND );
6131 68 : }
6132 :
6133 18 : void DocxAttributeOutput::ParaForbiddenRules( const SfxBoolItem& rItem )
6134 : {
6135 : m_pSerializer->singleElementNS( XML_w, XML_kinsoku,
6136 18 : FSNS( XML_w, XML_val ), rItem.GetValue( ) ? "true": "false",
6137 18 : FSEND );
6138 18 : }
6139 :
6140 33 : void DocxAttributeOutput::ParaVerticalAlign( const SvxParaVertAlignItem& rAlign )
6141 : {
6142 : const char *pAlignString;
6143 :
6144 33 : switch ( rAlign.GetValue() )
6145 : {
6146 : case SvxParaVertAlignItem::BASELINE:
6147 33 : pAlignString = "baseline";
6148 33 : break;
6149 : case SvxParaVertAlignItem::TOP:
6150 0 : pAlignString = "top";
6151 0 : break;
6152 : case SvxParaVertAlignItem::CENTER:
6153 0 : pAlignString = "center";
6154 0 : break;
6155 : case SvxParaVertAlignItem::BOTTOM:
6156 0 : pAlignString = "bottom";
6157 0 : break;
6158 : case SvxParaVertAlignItem::AUTOMATIC:
6159 0 : pAlignString = "auto";
6160 0 : break;
6161 : default:
6162 33 : return; // not supported attribute
6163 : }
6164 33 : m_pSerializer->singleElementNS( XML_w, XML_textAlignment, FSNS( XML_w, XML_val ), pAlignString, FSEND );
6165 : }
6166 :
6167 0 : void DocxAttributeOutput::ParaSnapToGrid( const SvxParaGridItem& rGrid )
6168 : {
6169 : m_pSerializer->singleElementNS( XML_w, XML_snapToGrid,
6170 0 : FSNS( XML_w, XML_val ), rGrid.GetValue( ) ? "true": "false",
6171 0 : FSEND );
6172 0 : }
6173 :
6174 528 : void DocxAttributeOutput::FormatFrameSize( const SwFmtFrmSize& rSize )
6175 : {
6176 528 : if (m_rExport.SdrExporter().getTextFrameSyntax() && m_rExport.SdrExporter().getFlyFrameSize())
6177 : {
6178 115 : const Size* pSize = m_rExport.SdrExporter().getFlyFrameSize();
6179 115 : m_rExport.SdrExporter().getTextFrameStyle().append(";width:").append(double(pSize->Width()) / 20);
6180 115 : m_rExport.SdrExporter().getTextFrameStyle().append("pt;height:").append(double(pSize->Height()) / 20).append("pt");
6181 : }
6182 413 : else if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
6183 : {
6184 : }
6185 298 : else if ( m_rExport.bOutFlyFrmAttrs )
6186 : {
6187 0 : if ( rSize.GetWidth() && rSize.GetWidthSizeType() == ATT_FIX_SIZE )
6188 0 : AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(),
6189 0 : FSNS( XML_w, XML_w ), OString::number( rSize.GetWidth( ) ).getStr() );
6190 :
6191 0 : if ( rSize.GetHeight() )
6192 : {
6193 0 : OString sRule( "exact" );
6194 0 : if ( rSize.GetHeightSizeType() == ATT_MIN_SIZE )
6195 0 : sRule = OString( "atLeast" );
6196 0 : AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), 2,
6197 : FSNS( XML_w, XML_hRule ), sRule.getStr(),
6198 0 : FSNS( XML_w, XML_h ), OString::number( rSize.GetHeight( ) ).getStr() );
6199 : }
6200 : }
6201 298 : else if ( m_rExport.bOutPageDescs )
6202 : {
6203 298 : FastAttributeList *attrList = m_pSerializer->createAttrList( );
6204 298 : if ( m_rExport.pAktPageDesc->GetLandscape( ) )
6205 8 : attrList->add( FSNS( XML_w, XML_orient ), "landscape" );
6206 :
6207 298 : attrList->add( FSNS( XML_w, XML_w ), OString::number( rSize.GetWidth( ) ) );
6208 298 : attrList->add( FSNS( XML_w, XML_h ), OString::number( rSize.GetHeight( ) ) );
6209 :
6210 298 : XFastAttributeListRef xAttrList( attrList );
6211 298 : attrList = NULL;
6212 :
6213 298 : m_pSerializer->singleElementNS( XML_w, XML_pgSz, xAttrList );
6214 : }
6215 528 : }
6216 :
6217 0 : void DocxAttributeOutput::FormatPaperBin( const SvxPaperBinItem& )
6218 : {
6219 : OSL_TRACE( "TODO DocxAttributeOutput::FormatPaperBin()" );
6220 0 : }
6221 :
6222 1936 : void DocxAttributeOutput::FormatLRSpace( const SvxLRSpaceItem& rLRSpace )
6223 : {
6224 1936 : bool bEcma = m_rExport.GetFilter().getVersion( ) == oox::core::ECMA_DIALECT;
6225 :
6226 1936 : if (m_rExport.SdrExporter().getTextFrameSyntax())
6227 : {
6228 115 : m_rExport.SdrExporter().getTextFrameStyle().append(";mso-wrap-distance-left:").append(double(rLRSpace.GetLeft()) / 20).append("pt");
6229 115 : m_rExport.SdrExporter().getTextFrameStyle().append(";mso-wrap-distance-right:").append(double(rLRSpace.GetRight()) / 20).append("pt");
6230 : }
6231 1821 : else if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
6232 : {
6233 : }
6234 1706 : else if ( m_rExport.bOutFlyFrmAttrs )
6235 : {
6236 0 : AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), FSNS( XML_w, XML_hSpace ),
6237 : OString::number(
6238 0 : ( rLRSpace.GetLeft() + rLRSpace.GetRight() ) / 2 ).getStr() );
6239 : }
6240 1706 : else if ( m_rExport.bOutPageDescs )
6241 : {
6242 298 : m_pageMargins.nPageMarginLeft = 0;
6243 298 : m_pageMargins.nPageMarginRight = 0;
6244 :
6245 298 : const SfxPoolItem* pItem = m_rExport.HasItem( RES_BOX );
6246 298 : if ( pItem )
6247 : {
6248 4 : m_pageMargins.nPageMarginRight = ((SvxBoxItem*)pItem)->CalcLineSpace( BOX_LINE_LEFT );
6249 4 : m_pageMargins.nPageMarginLeft = ((SvxBoxItem*)pItem)->CalcLineSpace( BOX_LINE_RIGHT );
6250 : }
6251 : else
6252 294 : m_pageMargins.nPageMarginLeft = m_pageMargins.nPageMarginRight = 0;
6253 :
6254 298 : m_pageMargins.nPageMarginLeft = m_pageMargins.nPageMarginLeft + (sal_uInt16)rLRSpace.GetLeft();
6255 298 : m_pageMargins.nPageMarginRight = m_pageMargins.nPageMarginRight + (sal_uInt16)rLRSpace.GetRight();
6256 :
6257 : AddToAttrList( m_pSectionSpacingAttrList, 2,
6258 : FSNS( XML_w, XML_left ), OString::number( m_pageMargins.nPageMarginLeft ).getStr(),
6259 298 : FSNS( XML_w, XML_right ), OString::number( m_pageMargins.nPageMarginRight ).getStr() );
6260 : }
6261 : else
6262 : {
6263 1408 : FastAttributeList *pLRSpaceAttrList = m_pSerializer->createAttrList();
6264 1408 : if((0 != rLRSpace.GetTxtLeft()) || ((0 == rLRSpace.GetTxtLeft()) && rLRSpace.IsExplicitZeroMarginValLeft()))
6265 : {
6266 807 : pLRSpaceAttrList->add( FSNS( XML_w, ( bEcma ? XML_left : XML_start ) ), OString::number( rLRSpace.GetTxtLeft() ) );
6267 : }
6268 1408 : if((0 != rLRSpace.GetRight()) || ((0 == rLRSpace.GetRight()) && rLRSpace.IsExplicitZeroMarginValRight()))
6269 : {
6270 668 : pLRSpaceAttrList->add( FSNS( XML_w, ( bEcma ? XML_right : XML_end ) ), OString::number( rLRSpace.GetRight() ) );
6271 : }
6272 1408 : sal_Int32 nFirstLineAdjustment = rLRSpace.GetTxtFirstLineOfst();
6273 1408 : if (nFirstLineAdjustment > 0)
6274 74 : pLRSpaceAttrList->add( FSNS( XML_w, XML_firstLine ), OString::number( nFirstLineAdjustment ) );
6275 : else
6276 1334 : pLRSpaceAttrList->add( FSNS( XML_w, XML_hanging ), OString::number( - nFirstLineAdjustment ) );
6277 1408 : m_pSerializer->singleElementNS( XML_w, XML_ind, pLRSpaceAttrList );
6278 : }
6279 1936 : }
6280 :
6281 4183 : void DocxAttributeOutput::FormatULSpace( const SvxULSpaceItem& rULSpace )
6282 : {
6283 :
6284 4183 : if (m_rExport.SdrExporter().getTextFrameSyntax())
6285 : {
6286 114 : m_rExport.SdrExporter().getTextFrameStyle().append(";mso-wrap-distance-top:").append(double(rULSpace.GetUpper()) / 20).append("pt");
6287 114 : m_rExport.SdrExporter().getTextFrameStyle().append(";mso-wrap-distance-bottom:").append(double(rULSpace.GetLower()) / 20).append("pt");
6288 : }
6289 4069 : else if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
6290 : {
6291 : }
6292 3955 : else if ( m_rExport.bOutFlyFrmAttrs )
6293 : {
6294 0 : AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), FSNS( XML_w, XML_vSpace ),
6295 : OString::number(
6296 0 : ( rULSpace.GetLower() + rULSpace.GetUpper() ) / 2 ).getStr() );
6297 : }
6298 3955 : else if (m_rExport.bOutPageDescs )
6299 : {
6300 : OSL_ENSURE( m_rExport.GetCurItemSet(), "Impossible" );
6301 298 : if ( !m_rExport.GetCurItemSet() )
6302 4183 : return;
6303 :
6304 298 : HdFtDistanceGlue aDistances( *m_rExport.GetCurItemSet() );
6305 :
6306 298 : sal_Int32 nHeader = 0;
6307 298 : if ( aDistances.HasHeader() )
6308 56 : nHeader = sal_Int32( aDistances.dyaHdrTop );
6309 :
6310 : // Page top
6311 298 : m_pageMargins.nPageMarginTop = aDistances.dyaTop;
6312 :
6313 298 : sal_Int32 nFooter = 0;
6314 298 : if ( aDistances.HasFooter() )
6315 68 : nFooter = sal_Int32( aDistances.dyaHdrBottom );
6316 :
6317 : // Page Bottom
6318 298 : m_pageMargins.nPageMarginBottom = aDistances.dyaBottom;
6319 :
6320 : AddToAttrList( m_pSectionSpacingAttrList, 5,
6321 : FSNS( XML_w, XML_header ), OString::number( nHeader ).getStr(),
6322 : FSNS( XML_w, XML_top ), OString::number( m_pageMargins.nPageMarginTop ).getStr(),
6323 : FSNS( XML_w, XML_footer ), OString::number( nFooter ).getStr(),
6324 : FSNS( XML_w, XML_bottom ), OString::number( m_pageMargins.nPageMarginBottom ).getStr(),
6325 : // FIXME Page Gutter is not handled ATM, setting to 0 as it's mandatory for OOXML
6326 298 : FSNS( XML_w, XML_gutter ), "0" );
6327 : }
6328 : else
6329 : {
6330 : SAL_INFO("sw.ww8", "DocxAttributeOutput::FormatULSpace: setting spacing" << rULSpace.GetUpper() );
6331 : // check if before auto spacing was set during import and spacing we get from actual object is same
6332 : // that we set in import. If yes just write beforeAutoSpacing tag.
6333 3657 : if (m_bParaBeforeAutoSpacing && m_nParaBeforeSpacing == rULSpace.GetUpper())
6334 : {
6335 : AddToAttrList( m_pParagraphSpacingAttrList,
6336 57 : FSNS( XML_w, XML_beforeAutospacing ), "1" );
6337 : }
6338 : else
6339 : {
6340 : AddToAttrList( m_pParagraphSpacingAttrList,
6341 3600 : FSNS( XML_w, XML_before ), OString::number( rULSpace.GetUpper() ).getStr() );
6342 : }
6343 3657 : m_bParaBeforeAutoSpacing = false;
6344 : // check if after auto spacing was set during import and spacing we get from actual object is same
6345 : // that we set in import. If yes just write afterAutoSpacing tag.
6346 3657 : if (m_bParaAfterAutoSpacing && m_nParaAfterSpacing == rULSpace.GetLower())
6347 : {
6348 : AddToAttrList( m_pParagraphSpacingAttrList,
6349 57 : FSNS( XML_w, XML_afterAutospacing ), "1" );
6350 : }
6351 : else
6352 : {
6353 : AddToAttrList( m_pParagraphSpacingAttrList,
6354 3600 : FSNS( XML_w, XML_after ), OString::number( rULSpace.GetLower()).getStr() );
6355 : }
6356 3657 : m_bParaAfterAutoSpacing = false;
6357 :
6358 3657 : if (rULSpace.GetContext())
6359 251 : m_pSerializer->singleElementNS( XML_w, XML_contextualSpacing, FSEND );
6360 : }
6361 : }
6362 :
6363 230 : void DocxAttributeOutput::FormatSurround( const SwFmtSurround& rSurround )
6364 : {
6365 230 : if (m_rExport.SdrExporter().getTextFrameSyntax())
6366 : {
6367 230 : OString sType, sSide;
6368 115 : switch (rSurround.GetSurround())
6369 : {
6370 : case SURROUND_NONE:
6371 0 : sType = "topAndBottom";
6372 0 : break;
6373 : case SURROUND_PARALLEL:
6374 26 : sType = "square";
6375 26 : break;
6376 : case SURROUND_IDEAL:
6377 8 : sType = "square";
6378 8 : sSide = "largest";
6379 8 : break;
6380 : case SURROUND_LEFT:
6381 0 : sType = "square";
6382 0 : sSide = "left";
6383 0 : break;
6384 : case SURROUND_RIGHT:
6385 0 : sType = "square";
6386 0 : sSide = "right";
6387 0 : break;
6388 : case SURROUND_THROUGHT:
6389 : /* empty type and side means throught */
6390 : default:
6391 81 : break;
6392 : }
6393 115 : if (!sType.isEmpty() || !sSide.isEmpty())
6394 : {
6395 34 : m_rExport.SdrExporter().setFlyWrapAttrList(m_pSerializer->createAttrList());
6396 34 : if (!sType.isEmpty())
6397 34 : m_rExport.SdrExporter().getFlyWrapAttrList()->add(XML_type, sType);
6398 34 : if (!sSide.isEmpty())
6399 8 : m_rExport.SdrExporter().getFlyWrapAttrList()->add(XML_side, sSide);
6400 115 : }
6401 : }
6402 115 : else if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
6403 : {
6404 : }
6405 0 : else if ( m_rExport.bOutFlyFrmAttrs )
6406 : {
6407 0 : OString sWrap( "auto" );
6408 0 : switch ( rSurround.GetSurround( ) )
6409 : {
6410 : case SURROUND_NONE:
6411 0 : sWrap = OString( "none" );
6412 0 : break;
6413 : case SURROUND_THROUGHT:
6414 0 : sWrap = OString( "through" );
6415 0 : break;
6416 : case SURROUND_IDEAL:
6417 : case SURROUND_PARALLEL:
6418 : case SURROUND_LEFT:
6419 : case SURROUND_RIGHT:
6420 : default:
6421 0 : sWrap = OString( "around" );
6422 : }
6423 :
6424 0 : AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), FSNS( XML_w, XML_wrap ), sWrap.getStr() );
6425 : }
6426 230 : }
6427 :
6428 230 : void DocxAttributeOutput::FormatVertOrientation( const SwFmtVertOrient& rFlyVert )
6429 : {
6430 230 : if (m_rExport.SdrExporter().getTextFrameSyntax())
6431 : {
6432 115 : m_rExport.SdrExporter().getTextFrameStyle().append(";margin-top:").append(double(rFlyVert.GetPos()) / 20).append("pt");
6433 : }
6434 115 : else if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
6435 : {
6436 : }
6437 0 : else if ( m_rExport.bOutFlyFrmAttrs )
6438 : {
6439 0 : OString sAlign;
6440 0 : switch( rFlyVert.GetVertOrient() )
6441 : {
6442 : case text::VertOrientation::NONE:
6443 0 : break;
6444 : case text::VertOrientation::CENTER:
6445 : case text::VertOrientation::LINE_CENTER:
6446 0 : sAlign = OString( "center" );
6447 0 : break;
6448 : case text::VertOrientation::BOTTOM:
6449 : case text::VertOrientation::LINE_BOTTOM:
6450 0 : sAlign = OString( "bottom" );
6451 0 : break;
6452 : case text::VertOrientation::TOP:
6453 : case text::VertOrientation::LINE_TOP:
6454 : default:
6455 0 : sAlign = OString( "top" );
6456 0 : break;
6457 : }
6458 :
6459 0 : if ( !sAlign.isEmpty() )
6460 0 : AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), FSNS( XML_w, XML_yAlign ), sAlign.getStr() );
6461 : else
6462 0 : AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), FSNS( XML_w, XML_y ),
6463 0 : OString::number( rFlyVert.GetPos() ).getStr() );
6464 :
6465 0 : OString sVAnchor( "page" );
6466 0 : switch ( rFlyVert.GetRelationOrient( ) )
6467 : {
6468 : case text::RelOrientation::CHAR:
6469 : case text::RelOrientation::PRINT_AREA:
6470 : case text::RelOrientation::TEXT_LINE:
6471 0 : sVAnchor = OString( "column" );
6472 0 : break;
6473 : case text::RelOrientation::FRAME:
6474 : case text::RelOrientation::PAGE_LEFT:
6475 : case text::RelOrientation::PAGE_RIGHT:
6476 : case text::RelOrientation::FRAME_LEFT:
6477 : case text::RelOrientation::FRAME_RIGHT:
6478 0 : sVAnchor = OString( "margin" );
6479 0 : break;
6480 : case text::RelOrientation::PAGE_FRAME:
6481 : case text::RelOrientation::PAGE_PRINT_AREA:
6482 : default:
6483 0 : break;
6484 : }
6485 :
6486 0 : AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), FSNS( XML_w, XML_vAnchor ), sVAnchor.getStr() );
6487 : }
6488 230 : }
6489 :
6490 230 : void DocxAttributeOutput::FormatHorizOrientation( const SwFmtHoriOrient& rFlyHori )
6491 : {
6492 230 : if (m_rExport.SdrExporter().getTextFrameSyntax())
6493 : {
6494 115 : m_rExport.SdrExporter().getTextFrameStyle().append(";margin-left:").append(double(rFlyHori.GetPos()) / 20).append("pt");
6495 : }
6496 115 : else if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
6497 : {
6498 : }
6499 0 : else if ( m_rExport.bOutFlyFrmAttrs )
6500 : {
6501 0 : OString sAlign;
6502 0 : switch( rFlyHori.GetHoriOrient() )
6503 : {
6504 : case text::HoriOrientation::NONE:
6505 0 : break;
6506 : case text::HoriOrientation::LEFT:
6507 0 : sAlign = OString( rFlyHori.IsPosToggle( ) ? "inside" : "left" );
6508 0 : break;
6509 : case text::HoriOrientation::RIGHT:
6510 0 : sAlign = OString( rFlyHori.IsPosToggle( ) ? "outside" : "right" );
6511 0 : break;
6512 : case text::HoriOrientation::CENTER:
6513 : case text::HoriOrientation::FULL: // FULL only for tables
6514 : default:
6515 0 : sAlign = OString( "center" );
6516 0 : break;
6517 : }
6518 :
6519 0 : if ( !sAlign.isEmpty() )
6520 0 : AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), FSNS( XML_w, XML_xAlign ), sAlign.getStr() );
6521 : else
6522 0 : AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), FSNS( XML_w, XML_x ),
6523 0 : OString::number( rFlyHori.GetPos() ).getStr() );
6524 :
6525 0 : OString sHAnchor( "page" );
6526 0 : switch ( rFlyHori.GetRelationOrient( ) )
6527 : {
6528 : case text::RelOrientation::CHAR:
6529 : case text::RelOrientation::PRINT_AREA:
6530 0 : sHAnchor = OString( "text" );
6531 0 : break;
6532 : case text::RelOrientation::FRAME:
6533 : case text::RelOrientation::PAGE_LEFT:
6534 : case text::RelOrientation::PAGE_RIGHT:
6535 : case text::RelOrientation::FRAME_LEFT:
6536 : case text::RelOrientation::FRAME_RIGHT:
6537 0 : sHAnchor = OString( "margin" );
6538 0 : break;
6539 : case text::RelOrientation::PAGE_FRAME:
6540 : case text::RelOrientation::PAGE_PRINT_AREA:
6541 : default:
6542 0 : break;
6543 : }
6544 :
6545 0 : AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), FSNS( XML_w, XML_hAnchor ), sHAnchor.getStr() );
6546 : }
6547 230 : }
6548 :
6549 230 : void DocxAttributeOutput::FormatAnchor( const SwFmtAnchor& )
6550 : {
6551 : // Fly frames: anchors here aren't matching the anchors in docx
6552 230 : }
6553 :
6554 191 : boost::optional<sal_Int32> lcl_getDmlAlpha(const SvxBrushItem& rBrush)
6555 : {
6556 191 : boost::optional<sal_Int32> oRet;
6557 191 : sal_Int32 nTransparency = rBrush.GetColor().GetTransparency();
6558 191 : if (nTransparency)
6559 : {
6560 : // Convert transparency to percent
6561 21 : sal_Int8 nTransparencyPercent = SvxBrushItem::TransparencyToPercent(nTransparency);
6562 :
6563 : // Calculate alpha value
6564 : // Consider oox/source/drawingml/color.cxx : getTransparency() function.
6565 21 : sal_Int32 nAlpha = (::oox::drawingml::MAX_PERCENT - ( ::oox::drawingml::PER_PERCENT * nTransparencyPercent ) );
6566 21 : oRet = nAlpha;
6567 : }
6568 191 : return oRet;
6569 : }
6570 :
6571 191 : void DocxAttributeOutput::FormatBackground( const SvxBrushItem& rBrush )
6572 : {
6573 191 : OString sColor = msfilter::util::ConvertColor( rBrush.GetColor().GetRGBColor() );
6574 382 : boost::optional<sal_Int32> oAlpha = lcl_getDmlAlpha(rBrush);
6575 191 : if (m_rExport.SdrExporter().getTextFrameSyntax())
6576 : {
6577 : // Handle 'Opacity'
6578 81 : if (oAlpha)
6579 : {
6580 : // Calculate opacity value
6581 : // Consider oox/source/vml/vmlformatting.cxx : decodeColor() function.
6582 10 : double fOpacity = (double)(*oAlpha) * 65535 / ::oox::drawingml::MAX_PERCENT;
6583 10 : OUString sOpacity = OUString::number(fOpacity) + "f";
6584 :
6585 10 : AddToAttrList( m_rExport.SdrExporter().getFlyFillAttrList(), XML_opacity, OUStringToOString(sOpacity, RTL_TEXTENCODING_UTF8).getStr() );
6586 : }
6587 :
6588 81 : sColor = "#" + sColor;
6589 81 : AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), XML_fillcolor, sColor.getStr() );
6590 : }
6591 110 : else if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
6592 : {
6593 81 : bool bImageBackground = false;
6594 81 : const SfxPoolItem* pItem = GetExport().HasItem(XATTR_FILLSTYLE);
6595 81 : if (pItem)
6596 : {
6597 81 : const XFillStyleItem* pFillStyle = static_cast<const XFillStyleItem*>(pItem);
6598 81 : if(pFillStyle->GetValue() == XFILL_BITMAP)
6599 : {
6600 0 : bImageBackground = true;
6601 : }
6602 : }
6603 81 : if (!bImageBackground)
6604 : {
6605 81 : m_pSerializer->startElementNS(XML_a, XML_solidFill, FSEND);
6606 : m_pSerializer->startElementNS(XML_a, XML_srgbClr,
6607 : XML_val, sColor,
6608 81 : FSEND);
6609 81 : if (oAlpha)
6610 : m_pSerializer->singleElementNS(XML_a, XML_alpha,
6611 10 : XML_val, OString::number(*oAlpha),
6612 10 : FSEND);
6613 81 : m_pSerializer->endElementNS(XML_a, XML_srgbClr);
6614 81 : m_pSerializer->endElementNS(XML_a, XML_solidFill);
6615 : }
6616 : }
6617 29 : else if ( !m_rExport.bOutPageDescs )
6618 : {
6619 24 : if( !m_pBackgroundAttrList )
6620 16 : m_pBackgroundAttrList = m_pSerializer->createAttrList();
6621 :
6622 : // compare fill color with the original fill color
6623 : OString sOriginalFill = rtl::OUStringToOString(
6624 24 : m_pBackgroundAttrList->getOptionalValue( FSNS( XML_w, XML_fill ) ), RTL_TEXTENCODING_UTF8 );
6625 24 : if( sOriginalFill.isEmpty() )
6626 : {
6627 16 : m_pBackgroundAttrList->add( FSNS( XML_w, XML_fill ), sColor.getStr() );
6628 : }
6629 8 : else if ( sOriginalFill != sColor )
6630 : {
6631 : // fill was modified during edition, theme fill attribute must be dropped
6632 0 : delete m_pBackgroundAttrList;
6633 0 : m_pBackgroundAttrList = m_pSerializer->createAttrList();
6634 0 : m_pBackgroundAttrList->add( FSNS( XML_w, XML_fill ), sColor.getStr() );
6635 : }
6636 24 : m_pBackgroundAttrList->add( FSNS( XML_w, XML_val ), "clear" );
6637 191 : }
6638 191 : }
6639 :
6640 643 : void DocxAttributeOutput::FormatFillStyle( const XFillStyleItem& rFillStyle )
6641 : {
6642 643 : if (!m_bIgnoreNextFill)
6643 528 : m_oFillStyle.reset(rFillStyle.GetValue());
6644 : else
6645 115 : m_bIgnoreNextFill = false;
6646 643 : }
6647 :
6648 33 : void DocxAttributeOutput::FormatFillGradient( const XFillGradientItem& rFillGradient )
6649 : {
6650 33 : if (m_oFillStyle && *m_oFillStyle == XFILL_GRADIENT && !m_rExport.SdrExporter().getDMLTextFrameSyntax())
6651 : {
6652 11 : AddToAttrList( m_rExport.SdrExporter().getFlyFillAttrList(), XML_type, "gradient" );
6653 :
6654 11 : const XGradient& rGradient = rFillGradient.GetGradientValue();
6655 11 : OString sStartColor = msfilter::util::ConvertColor(rGradient.GetStartColor());
6656 22 : OString sEndColor = msfilter::util::ConvertColor(rGradient.GetEndColor());
6657 :
6658 : // Calculate the angle that was originally in the imported DOCX file
6659 : // (reverse calculate the angle that was converted in the file
6660 : // /oox/source/vml/vmlformatting.cxx :: FillModel::pushToPropMap
6661 : // and also in
6662 : // /oox/source/drawingml/fillproperties.cxx :: FillProperties::pushToPropMap
6663 11 : sal_Int32 nReverseAngle = 4500 - rGradient.GetAngle();
6664 11 : nReverseAngle = nReverseAngle / 10;
6665 11 : nReverseAngle = (270 - nReverseAngle) % 360;
6666 11 : if (nReverseAngle != 0)
6667 8 : AddToAttrList( m_rExport.SdrExporter().getFlyFillAttrList(),
6668 16 : XML_angle, OString::number( nReverseAngle ).getStr() );
6669 :
6670 22 : OString sColor1 = sStartColor;
6671 22 : OString sColor2 = sEndColor;
6672 :
6673 11 : switch (rGradient.GetGradientStyle())
6674 : {
6675 : case XGRAD_AXIAL:
6676 3 : AddToAttrList( m_rExport.SdrExporter().getFlyFillAttrList(), XML_focus, "50%" );
6677 : // If it is an 'axial' gradient - swap the colors
6678 : // (because in the import process they were imported swapped)
6679 3 : sColor1 = sEndColor;
6680 3 : sColor2 = sStartColor;
6681 3 : break;
6682 8 : case XGRAD_LINEAR: break;
6683 0 : case XGRAD_RADIAL: break;
6684 0 : case XGRAD_ELLIPTICAL: break;
6685 0 : case XGRAD_SQUARE: break;
6686 0 : case XGRAD_RECT: break;
6687 : }
6688 :
6689 11 : sColor1 = "#" + sColor1;
6690 11 : sColor2 = "#" + sColor2;
6691 11 : AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), XML_fillcolor, sColor1.getStr() );
6692 22 : AddToAttrList( m_rExport.SdrExporter().getFlyFillAttrList(), XML_color2, sColor2.getStr() );
6693 : }
6694 22 : else if (m_oFillStyle && *m_oFillStyle == XFILL_GRADIENT && m_rExport.SdrExporter().getDMLTextFrameSyntax())
6695 : {
6696 11 : uno::Reference<beans::XPropertySet> xPropertySet = SwXFrames::GetObject(const_cast<SwFrmFmt&>(m_rExport.mpParentFrame->GetFrmFmt()), FLYCNTTYPE_FRM);
6697 11 : m_rDrawingML.SetFS(m_pSerializer);
6698 11 : m_rDrawingML.WriteGradientFill(xPropertySet);
6699 : }
6700 33 : m_oFillStyle.reset();
6701 33 : }
6702 :
6703 300 : void DocxAttributeOutput::FormatBox( const SvxBoxItem& rBox )
6704 : {
6705 300 : if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
6706 : {
6707 : // <a:gradFill> should be before <a:ln>.
6708 115 : const SfxPoolItem* pItem = GetExport().HasItem(XATTR_FILLSTYLE);
6709 115 : if (pItem)
6710 : {
6711 115 : const XFillStyleItem* pFillStyle = static_cast<const XFillStyleItem*>(pItem);
6712 115 : FormatFillStyle(*pFillStyle);
6713 115 : if (m_oFillStyle && *m_oFillStyle == XFILL_BITMAP)
6714 : {
6715 1 : const SdrObject* pSdrObj = m_rExport.mpParentFrame->GetFrmFmt().FindRealSdrObject();
6716 1 : if (pSdrObj)
6717 : {
6718 1 : uno::Reference< drawing::XShape > xShape( ((SdrObject*)pSdrObj)->getUnoShape(), uno::UNO_QUERY );
6719 2 : uno::Reference< beans::XPropertySet > xPropertySet( xShape, uno::UNO_QUERY );
6720 1 : m_rDrawingML.SetFS(m_pSerializer);
6721 2 : m_rDrawingML.WriteBlipFill( xPropertySet, "BackGraphicURL" );
6722 : }
6723 : }
6724 : }
6725 :
6726 115 : pItem = GetExport().HasItem(XATTR_FILLGRADIENT);
6727 115 : if (pItem)
6728 : {
6729 11 : const XFillGradientItem* pFillGradient = static_cast<const XFillGradientItem*>(pItem);
6730 11 : FormatFillGradient(*pFillGradient);
6731 : }
6732 115 : m_bIgnoreNextFill = true;
6733 : }
6734 300 : if (m_rExport.SdrExporter().getTextFrameSyntax() || m_rExport.SdrExporter().getDMLTextFrameSyntax())
6735 : {
6736 230 : const SvxBorderLine* pLeft = rBox.GetLeft( );
6737 230 : const SvxBorderLine* pTop = rBox.GetTop( );
6738 230 : const SvxBorderLine* pRight = rBox.GetRight( );
6739 230 : const SvxBorderLine* pBottom = rBox.GetBottom( );
6740 :
6741 626 : if (pLeft && pRight && pTop && pBottom &&
6742 626 : *pLeft == *pRight && *pLeft == *pTop && *pLeft == *pBottom)
6743 : {
6744 : // Check border style
6745 198 : editeng::SvxBorderStyle eBorderStyle = pTop->GetBorderLineStyle();
6746 198 : if (eBorderStyle == table::BorderLineStyle::NONE)
6747 : {
6748 24 : if (m_rExport.SdrExporter().getTextFrameSyntax())
6749 : {
6750 12 : AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), 2,
6751 12 : XML_stroked, "f", XML_strokeweight, "0pt" );
6752 : }
6753 : }
6754 : else
6755 : {
6756 174 : OString sColor(msfilter::util::ConvertColor(pTop->GetColor()));
6757 174 : double const fConverted(editeng::ConvertBorderWidthToWord(pTop->GetBorderLineStyle(), pTop->GetWidth()));
6758 :
6759 174 : if (m_rExport.SdrExporter().getTextFrameSyntax())
6760 : {
6761 87 : sColor = "#" + sColor;
6762 87 : sal_Int32 nWidth = sal_Int32(fConverted / 20);
6763 87 : OString sWidth = OString::number(nWidth) + "pt";
6764 87 : AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), 2,
6765 : XML_strokecolor, sColor.getStr(),
6766 174 : XML_strokeweight, sWidth.getStr() );
6767 87 : if( LineStyle_DASH == pTop->GetBorderLineStyle() ) // Line Style is Dash type
6768 5 : AddToAttrList( m_rExport.SdrExporter().getDashLineStyle(),
6769 5 : XML_dashstyle, "dash" );
6770 : }
6771 : else
6772 : {
6773 87 : OString sWidth(OString::number(TwipsToEMU(fConverted)));
6774 : m_pSerializer->startElementNS(XML_a, XML_ln,
6775 : XML_w, sWidth.getStr(),
6776 87 : FSEND);
6777 87 : m_pSerializer->startElementNS(XML_a, XML_solidFill, FSEND);
6778 : m_pSerializer->singleElementNS(XML_a, XML_srgbClr,
6779 : XML_val, sColor,
6780 87 : FSEND);
6781 87 : m_pSerializer->endElementNS(XML_a, XML_solidFill);
6782 87 : if( LineStyle_DASH == pTop->GetBorderLineStyle() ) // Line Style is Dash type
6783 5 : m_pSerializer->singleElementNS(XML_a, XML_prstDash, XML_val, "dash", FSEND);
6784 87 : m_pSerializer->endElementNS(XML_a, XML_ln);
6785 174 : }
6786 : }
6787 : }
6788 :
6789 230 : if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
6790 : {
6791 115 : m_rExport.SdrExporter().getBodyPrAttrList()->add(XML_lIns, OString::number(TwipsToEMU(rBox.GetDistance(BOX_LINE_LEFT))));
6792 115 : m_rExport.SdrExporter().getBodyPrAttrList()->add(XML_tIns, OString::number(TwipsToEMU(rBox.GetDistance(BOX_LINE_TOP))));
6793 115 : m_rExport.SdrExporter().getBodyPrAttrList()->add(XML_rIns, OString::number(TwipsToEMU(rBox.GetDistance(BOX_LINE_RIGHT))));
6794 115 : m_rExport.SdrExporter().getBodyPrAttrList()->add(XML_bIns, OString::number(TwipsToEMU(rBox.GetDistance(BOX_LINE_BOTTOM))));
6795 115 : return;
6796 : }
6797 :
6798 : // v:textbox's inset attribute: inner margin values for textbox text - write only non-default values
6799 115 : double fDistanceLeftTwips = double(rBox.GetDistance(BOX_LINE_LEFT));
6800 115 : double fDistanceTopTwips = double(rBox.GetDistance(BOX_LINE_TOP));
6801 115 : double fDistanceRightTwips = double(rBox.GetDistance(BOX_LINE_RIGHT));
6802 115 : double fDistanceBottomTwips = double(rBox.GetDistance(BOX_LINE_BOTTOM));
6803 :
6804 : // Convert 'TWIPS' to 'INCH' (because in Word the default values are in Inches)
6805 115 : double fDistanceLeftInch = fDistanceLeftTwips / 1440;
6806 115 : double fDistanceTopInch = fDistanceTopTwips / 1440;
6807 115 : double fDistanceRightInch = fDistanceRightTwips / 1440;
6808 115 : double fDistanceBottomInch = fDistanceBottomTwips / 1440;
6809 :
6810 : // This code will write ONLY the non-default values. The values are in 'left','top','right','bottom' order.
6811 : // so 'bottom' is checked if it is default and if it is non-default - all the values will be written
6812 : // otherwise - 'right' is checked if it is default and if it is non-default - all the values except for 'bottom' will be written
6813 : // and so on.
6814 115 : OStringBuffer aInset;
6815 115 : if(!aInset.isEmpty() || fDistanceBottomInch != double(0.05))
6816 59 : aInset.insert(0, "," + OString::number(fDistanceBottomInch) + "in");
6817 :
6818 115 : if(!aInset.isEmpty() || fDistanceRightInch != double(0.1))
6819 60 : aInset.insert(0, "," + OString::number(fDistanceRightInch) + "in");
6820 :
6821 115 : if(!aInset.isEmpty() || fDistanceTopInch != double(0.05))
6822 60 : aInset.insert(0, "," + OString::number(fDistanceTopInch) + "in");
6823 :
6824 115 : if(!aInset.isEmpty() || fDistanceLeftInch != double(0.1))
6825 61 : aInset.insert(0, OString::number(fDistanceLeftInch) + "in");
6826 :
6827 115 : if (!aInset.isEmpty())
6828 61 : m_rExport.SdrExporter().getTextboxAttrList()->add(XML_inset, aInset.makeStringAndClear());
6829 :
6830 115 : return;
6831 : }
6832 :
6833 70 : OutputBorderOptions aOutputBorderOptions = lcl_getBoxBorderOptions();
6834 : // Check if there is a shadow item
6835 70 : const SfxPoolItem* pItem = GetExport().HasItem( RES_SHADOW );
6836 70 : if ( pItem )
6837 : {
6838 4 : const SvxShadowItem* pShadowItem = (const SvxShadowItem*)pItem;
6839 4 : aOutputBorderOptions.aShadowLocation = pShadowItem->GetLocation();
6840 : }
6841 :
6842 70 : if ( !m_bOpenedSectPr || GetWritingHeaderFooter())
6843 : {
6844 : // Not inside a section
6845 :
6846 : // Open the paragraph's borders tag
6847 66 : m_pSerializer->startElementNS( XML_w, XML_pBdr, FSEND );
6848 :
6849 66 : std::map<sal_uInt16, css::table::BorderLine2> aEmptyMap; // empty styles map
6850 : impl_borders( m_pSerializer, rBox, aOutputBorderOptions, &m_pageMargins,
6851 66 : aEmptyMap );
6852 :
6853 : // Close the paragraph's borders tag
6854 66 : m_pSerializer->endElementNS( XML_w, XML_pBdr );
6855 : }
6856 : }
6857 :
6858 9 : void DocxAttributeOutput::FormatColumns_Impl( sal_uInt16 nCols, const SwFmtCol& rCol, bool bEven, SwTwips nPageSize )
6859 : {
6860 : // Get the columns attributes
6861 9 : FastAttributeList *pColsAttrList = m_pSerializer->createAttrList();
6862 :
6863 : pColsAttrList->add( FSNS( XML_w, XML_num ),
6864 9 : OString::number( nCols ). getStr( ) );
6865 :
6866 9 : const char* pEquals = "false";
6867 9 : if ( bEven )
6868 : {
6869 6 : sal_uInt16 nWidth = rCol.GetGutterWidth( true );
6870 : pColsAttrList->add( FSNS( XML_w, XML_space ),
6871 6 : OString::number( nWidth ).getStr( ) );
6872 :
6873 6 : pEquals = "true";
6874 : }
6875 :
6876 9 : pColsAttrList->add( FSNS( XML_w, XML_equalWidth ), pEquals );
6877 :
6878 9 : bool bHasSep = (COLADJ_NONE != rCol.GetLineAdj());
6879 :
6880 9 : pColsAttrList->add( FSNS( XML_w, XML_sep ), bHasSep ? "true" : "false" );
6881 :
6882 : // Write the element
6883 9 : m_pSerializer->startElementNS( XML_w, XML_cols, pColsAttrList );
6884 :
6885 : // Write the columns width if non-equals
6886 9 : const SwColumns & rColumns = rCol.GetColumns( );
6887 9 : if ( !bEven )
6888 : {
6889 13 : for ( sal_uInt16 n = 0; n < nCols; ++n )
6890 : {
6891 10 : FastAttributeList *pColAttrList = m_pSerializer->createAttrList();
6892 10 : sal_uInt16 nWidth = rCol.CalcPrtColWidth( n, ( sal_uInt16 ) nPageSize );
6893 : pColAttrList->add( FSNS( XML_w, XML_w ),
6894 10 : OString::number( nWidth ).getStr( ) );
6895 :
6896 10 : if ( n + 1 != nCols )
6897 : {
6898 7 : sal_uInt16 nSpacing = rColumns[n].GetRight( ) + rColumns[n + 1].GetLeft( );
6899 : pColAttrList->add( FSNS( XML_w, XML_space ),
6900 7 : OString::number( nSpacing ).getStr( ) );
6901 : }
6902 :
6903 10 : m_pSerializer->singleElementNS( XML_w, XML_col, pColAttrList );
6904 : }
6905 : }
6906 :
6907 9 : m_pSerializer->endElementNS( XML_w, XML_cols );
6908 9 : }
6909 :
6910 545 : void DocxAttributeOutput::FormatKeep( const SvxFmtKeepItem& )
6911 : {
6912 545 : m_pSerializer->singleElementNS( XML_w, XML_keepNext, FSEND );
6913 545 : }
6914 :
6915 282 : void DocxAttributeOutput::FormatTextGrid( const SwTextGridItem& rGrid )
6916 : {
6917 282 : FastAttributeList *pGridAttrList = m_pSerializer->createAttrList();
6918 :
6919 282 : OString sGridType;
6920 282 : switch ( rGrid.GetGridType( ) )
6921 : {
6922 : default:
6923 : case GRID_NONE:
6924 282 : sGridType = OString( "default" );
6925 282 : break;
6926 : case GRID_LINES_ONLY:
6927 0 : sGridType = OString( "lines" );
6928 0 : break;
6929 : case GRID_LINES_CHARS:
6930 0 : if ( rGrid.IsSnapToChars( ) )
6931 0 : sGridType = OString( "snapToChars" );
6932 : else
6933 0 : sGridType = OString( "linesAndChars" );
6934 0 : break;
6935 : }
6936 282 : pGridAttrList->add( FSNS( XML_w, XML_type ), sGridType.getStr( ) );
6937 :
6938 282 : sal_uInt16 nHeight = rGrid.GetBaseHeight() + rGrid.GetRubyHeight();
6939 : pGridAttrList->add( FSNS( XML_w, XML_linePitch ),
6940 282 : OString::number( nHeight ).getStr( ) );
6941 :
6942 : pGridAttrList->add( FSNS( XML_w, XML_charSpace ),
6943 282 : OString::number( GridCharacterPitch( rGrid ) ).getStr( ) );
6944 :
6945 282 : m_pSerializer->singleElementNS( XML_w, XML_docGrid, pGridAttrList );
6946 282 : }
6947 :
6948 562 : void DocxAttributeOutput::FormatLineNumbering( const SwFmtLineNumber& rNumbering )
6949 : {
6950 562 : if ( !rNumbering.IsCount( ) )
6951 559 : m_pSerializer->singleElementNS( XML_w, XML_suppressLineNumbers, FSEND );
6952 562 : }
6953 :
6954 787 : void DocxAttributeOutput::FormatFrameDirection( const SvxFrameDirectionItem& rDirection )
6955 : {
6956 787 : OString sTextFlow;
6957 787 : bool bBiDi = false;
6958 787 : short nDir = rDirection.GetValue();
6959 :
6960 787 : if ( nDir == FRMDIR_ENVIRONMENT )
6961 15 : nDir = GetExport( ).GetDefaultFrameDirection( );
6962 :
6963 787 : switch ( nDir )
6964 : {
6965 : default:
6966 : case FRMDIR_HORI_LEFT_TOP:
6967 779 : sTextFlow = OString( "lrTb" );
6968 779 : break;
6969 : case FRMDIR_HORI_RIGHT_TOP:
6970 8 : sTextFlow = OString( "lrTb" );
6971 8 : bBiDi = true;
6972 8 : break;
6973 : case FRMDIR_VERT_TOP_LEFT: // many things but not this one
6974 : case FRMDIR_VERT_TOP_RIGHT:
6975 0 : sTextFlow = OString( "tbRl" );
6976 0 : break;
6977 : }
6978 :
6979 787 : if ( m_rExport.bOutPageDescs )
6980 : {
6981 : m_pSerializer->singleElementNS( XML_w, XML_textDirection,
6982 : FSNS( XML_w, XML_val ), sTextFlow.getStr( ),
6983 298 : FSEND );
6984 298 : if ( bBiDi )
6985 4 : m_pSerializer->singleElementNS( XML_w, XML_bidi, FSEND );
6986 : }
6987 489 : else if ( !m_rExport.bOutFlyFrmAttrs )
6988 : {
6989 489 : if ( bBiDi )
6990 4 : m_pSerializer->singleElementNS( XML_w, XML_bidi, FSNS( XML_w, XML_val ), "1", FSEND );
6991 : else
6992 485 : m_pSerializer->singleElementNS( XML_w, XML_bidi, FSNS( XML_w, XML_val ), "0", FSEND );
6993 787 : }
6994 787 : }
6995 :
6996 374 : void DocxAttributeOutput::ParaGrabBag(const SfxGrabBagItem& rItem)
6997 : {
6998 374 : const std::map<OUString, com::sun::star::uno::Any>& rMap = rItem.GetGrabBag();
6999 532 : for (std::map<OUString, com::sun::star::uno::Any>::const_iterator i = rMap.begin(); i != rMap.end(); ++i)
7000 : {
7001 158 : if (i->first == "MirrorIndents")
7002 1 : m_pSerializer->singleElementNS(XML_w, XML_mirrorIndents, FSEND);
7003 157 : else if (i->first == "ParaTopMarginBeforeAutoSpacing")
7004 : {
7005 57 : m_bParaBeforeAutoSpacing = true;
7006 : // get fixed value which was set during import
7007 57 : i->second >>= m_nParaBeforeSpacing;
7008 57 : m_nParaBeforeSpacing = MM100_TO_TWIP(m_nParaBeforeSpacing);
7009 : SAL_INFO("sw.ww8", "DocxAttributeOutput::ParaGrabBag: property =" << i->first << " : m_nParaBeforeSpacing= " << m_nParaBeforeSpacing);
7010 : }
7011 100 : else if (i->first == "ParaBottomMarginAfterAutoSpacing")
7012 : {
7013 57 : m_bParaAfterAutoSpacing = true;
7014 : // get fixed value which was set during import
7015 57 : i->second >>= m_nParaAfterSpacing;
7016 57 : m_nParaAfterSpacing = MM100_TO_TWIP(m_nParaAfterSpacing);
7017 : SAL_INFO("sw.ww8", "DocxAttributeOutput::ParaGrabBag: property =" << i->first << " : m_nParaBeforeSpacing= " << m_nParaAfterSpacing);
7018 : }
7019 43 : else if (i->first == "CharThemeFill")
7020 : {
7021 8 : uno::Sequence<beans::PropertyValue> aGrabBagSeq;
7022 8 : i->second >>= aGrabBagSeq;
7023 16 : OUString sThemeFill, sOriginalFill;
7024 33 : for (sal_Int32 j=0; j < aGrabBagSeq.getLength(); ++j)
7025 : {
7026 25 : if (aGrabBagSeq[j].Name == "themeFill")
7027 1 : aGrabBagSeq[j].Value >>= sThemeFill;
7028 24 : else if (aGrabBagSeq[j].Name == "fill")
7029 8 : aGrabBagSeq[j].Value >>= sOriginalFill;
7030 : }
7031 : AddToAttrList(m_pBackgroundAttrList, 2,
7032 : FSNS(XML_w, XML_themeFill), OUStringToOString(sThemeFill, RTL_TEXTENCODING_UTF8).getStr(),
7033 16 : FSNS(XML_w, XML_fill), OUStringToOString(sOriginalFill, RTL_TEXTENCODING_UTF8).getStr());
7034 : }
7035 35 : else if (i->first == "SdtPr")
7036 : {
7037 : uno::Sequence<beans::PropertyValue> aGrabBagSdt =
7038 35 : i->second.get< uno::Sequence<beans::PropertyValue> >();
7039 115 : for (sal_Int32 k=0; k < aGrabBagSdt.getLength(); ++k)
7040 : {
7041 80 : beans::PropertyValue aPropertyValue = aGrabBagSdt[k];
7042 126 : if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartObj" ||
7043 46 : aPropertyValue.Name == "ooxml:CT_SdtPr_docPartList")
7044 : {
7045 34 : if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartObj")
7046 34 : m_nParagraphSdtPrToken = FSNS( XML_w, XML_docPartObj );
7047 0 : else if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartList")
7048 0 : m_nParagraphSdtPrToken = FSNS( XML_w, XML_docPartList );
7049 :
7050 34 : uno::Sequence<beans::PropertyValue> aGrabBag;
7051 34 : aPropertyValue.Value >>= aGrabBag;
7052 102 : for (sal_Int32 j=0; j < aGrabBag.getLength(); ++j)
7053 : {
7054 68 : OUString sValue = aGrabBag[j].Value.get<OUString>();
7055 68 : if (aGrabBag[j].Name == "ooxml:CT_SdtDocPart_docPartGallery")
7056 : AddToAttrList( m_pParagraphSdtPrTokenChildren,
7057 : FSNS( XML_w, XML_docPartGallery ),
7058 34 : rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
7059 34 : else if (aGrabBag[j].Name == "ooxml:CT_SdtDocPart_docPartCategory")
7060 : AddToAttrList( m_pParagraphSdtPrTokenChildren,
7061 : FSNS( XML_w, XML_docPartCategory ),
7062 0 : rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
7063 34 : else if (aGrabBag[j].Name == "ooxml:CT_SdtDocPart_docPartUnique")
7064 34 : AddToAttrList( m_pParagraphSdtPrTokenChildren, FSNS( XML_w, XML_docPartUnique ), "" );
7065 102 : }
7066 : }
7067 46 : else if (aPropertyValue.Name == "ooxml:CT_SdtPr_equation")
7068 0 : m_nParagraphSdtPrToken = FSNS( XML_w, XML_equation );
7069 46 : else if (aPropertyValue.Name == "ooxml:CT_SdtPr_picture")
7070 1 : m_nParagraphSdtPrToken = FSNS( XML_w, XML_picture );
7071 45 : else if (aPropertyValue.Name == "ooxml:CT_SdtPr_citation")
7072 4 : m_nParagraphSdtPrToken = FSNS( XML_w, XML_citation );
7073 41 : else if (aPropertyValue.Name == "ooxml:CT_SdtPr_group")
7074 1 : m_nParagraphSdtPrToken = FSNS( XML_w, XML_group );
7075 115 : }
7076 : }
7077 : else
7078 : SAL_INFO("sw.ww8", "DocxAttributeOutput::ParaGrabBag: unhandled grab bag property " << i->first );
7079 : }
7080 374 : }
7081 :
7082 4775 : void DocxAttributeOutput::CharGrabBag( const SfxGrabBagItem& rItem )
7083 : {
7084 4775 : const std::map< OUString, com::sun::star::uno::Any >& rMap = rItem.GetGrabBag();
7085 :
7086 : // get original values of theme-derived properties to check if they have changed during the edition
7087 4775 : sal_Bool bWriteCSTheme = sal_True;
7088 4775 : sal_Bool bWriteAsciiTheme = sal_True;
7089 4775 : sal_Bool bWriteEastAsiaTheme = sal_True;
7090 4775 : sal_Bool bWriteThemeFontColor = sal_True;
7091 4775 : OUString sOriginalValue;
7092 16207 : for ( std::map< OUString, com::sun::star::uno::Any >::const_iterator i = rMap.begin(); i != rMap.end(); ++i )
7093 : {
7094 11432 : if ( m_pFontsAttrList && i->first == "CharThemeFontNameCs" )
7095 : {
7096 864 : if ( i->second >>= sOriginalValue )
7097 : bWriteCSTheme =
7098 864 : ( m_pFontsAttrList->getOptionalValue( FSNS( XML_w, XML_cs ) ) == sOriginalValue );
7099 : }
7100 10568 : else if ( m_pFontsAttrList && i->first == "CharThemeFontNameAscii" )
7101 : {
7102 887 : if ( i->second >>= sOriginalValue )
7103 : bWriteAsciiTheme =
7104 887 : ( m_pFontsAttrList->getOptionalValue( FSNS( XML_w, XML_ascii ) ) == sOriginalValue );
7105 : }
7106 9681 : else if ( m_pFontsAttrList && i->first == "CharThemeFontNameEastAsia" )
7107 : {
7108 1087 : if ( i->second >>= sOriginalValue )
7109 : bWriteEastAsiaTheme =
7110 1087 : ( m_pFontsAttrList->getOptionalValue( FSNS( XML_w, XML_eastAsia ) ) == sOriginalValue );
7111 : }
7112 8594 : else if ( m_pColorAttrList && i->first == "CharThemeOriginalColor" )
7113 : {
7114 3801 : if ( i->second >>= sOriginalValue )
7115 : bWriteThemeFontColor =
7116 3801 : ( m_pColorAttrList->getOptionalValue( FSNS( XML_w, XML_val ) ) == sOriginalValue );
7117 : }
7118 : }
7119 :
7120 : // save theme attributes back to the run properties
7121 9550 : OUString str;
7122 16207 : for ( std::map< OUString, com::sun::star::uno::Any >::const_iterator i = rMap.begin(); i != rMap.end(); ++i )
7123 : {
7124 11432 : if ( i->first == "CharThemeNameAscii" && bWriteAsciiTheme )
7125 : {
7126 859 : i->second >>= str;
7127 : AddToAttrList( m_pFontsAttrList, FSNS( XML_w, XML_asciiTheme ),
7128 859 : OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
7129 : }
7130 10573 : else if ( i->first == "CharThemeNameCs" && bWriteCSTheme )
7131 : {
7132 851 : i->second >>= str;
7133 : AddToAttrList( m_pFontsAttrList, FSNS( XML_w, XML_cstheme ),
7134 851 : OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
7135 : }
7136 9722 : else if ( i->first == "CharThemeNameEastAsia" && bWriteEastAsiaTheme )
7137 : {
7138 1074 : i->second >>= str;
7139 : AddToAttrList( m_pFontsAttrList, FSNS( XML_w, XML_eastAsiaTheme ),
7140 1074 : OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
7141 : }
7142 8648 : else if ( i->first == "CharThemeNameHAnsi" && bWriteAsciiTheme )
7143 : // this is not a mistake: in LibO we don't directly support the hAnsi family
7144 : // of attributes so we save the same value from ascii attributes instead
7145 : {
7146 857 : i->second >>= str;
7147 : AddToAttrList( m_pFontsAttrList, FSNS( XML_w, XML_hAnsiTheme ),
7148 857 : OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
7149 : }
7150 7791 : else if ( i->first == "CharThemeColor" && bWriteThemeFontColor )
7151 : {
7152 616 : i->second >>= str;
7153 : AddToAttrList( m_pColorAttrList, FSNS( XML_w, XML_themeColor ),
7154 616 : OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
7155 : }
7156 7175 : else if ( i->first == "CharThemeColorShade" )
7157 : {
7158 254 : i->second >>= str;
7159 : AddToAttrList( m_pColorAttrList, FSNS( XML_w, XML_themeShade ),
7160 254 : OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
7161 : }
7162 6921 : else if ( i->first == "CharThemeColorTint" )
7163 : {
7164 88 : i->second >>= str;
7165 : AddToAttrList( m_pColorAttrList, FSNS( XML_w, XML_themeTint ),
7166 88 : OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
7167 : }
7168 19634 : else if( i->first == "CharThemeFontNameCs" ||
7169 11047 : i->first == "CharThemeFontNameAscii" ||
7170 15903 : i->first == "CharThemeFontNameEastAsia" ||
7171 3991 : i->first == "CharThemeOriginalColor" )
7172 : {
7173 : // just skip these, they were processed before
7174 : }
7175 564 : else if(i->first == "CharGlowTextEffect" ||
7176 362 : i->first == "CharShadowTextEffect" ||
7177 350 : i->first == "CharReflectionTextEffect" ||
7178 333 : i->first == "CharTextOutlineTextEffect" ||
7179 313 : i->first == "CharTextFillTextEffect" ||
7180 304 : i->first == "CharScene3DTextEffect" ||
7181 298 : i->first == "CharProps3DTextEffect" ||
7182 285 : i->first == "CharLigaturesTextEffect" ||
7183 272 : i->first == "CharNumFormTextEffect" ||
7184 260 : i->first == "CharNumSpacingTextEffect" ||
7185 431 : i->first == "CharStylisticSetsTextEffect" ||
7186 114 : i->first == "CharCntxtAltsTextEffect")
7187 : {
7188 82 : beans::PropertyValue aPropertyValue;
7189 82 : i->second >>= aPropertyValue;
7190 82 : sal_Int32 aLength = m_aTextEffectsGrabBag.getLength();
7191 82 : m_aTextEffectsGrabBag.realloc(m_aTextEffectsGrabBag.getLength() + 1);
7192 82 : m_aTextEffectsGrabBag[aLength] = aPropertyValue;
7193 : }
7194 108 : else if (i->first == "SdtPr")
7195 : {
7196 : uno::Sequence<beans::PropertyValue> aGrabBagSdt =
7197 20 : i->second.get< uno::Sequence<beans::PropertyValue> >();
7198 63 : for (sal_Int32 k=0; k < aGrabBagSdt.getLength(); ++k)
7199 : {
7200 43 : beans::PropertyValue aPropertyValue = aGrabBagSdt[k];
7201 43 : if (aPropertyValue.Name == "ooxml:CT_SdtPr_checkbox")
7202 : {
7203 1 : m_nRunSdtPrToken = FSNS( XML_w14, XML_checkbox );
7204 1 : uno::Sequence<beans::PropertyValue> aGrabBag;
7205 1 : aPropertyValue.Value >>= aGrabBag;
7206 4 : for (sal_Int32 j=0; j < aGrabBag.getLength(); ++j)
7207 : {
7208 3 : OUString sValue = aGrabBag[j].Value.get<OUString>();
7209 3 : if (aGrabBag[j].Name == "ooxml:CT_SdtCheckbox_checked")
7210 : AddToAttrList( m_pRunSdtPrTokenChildren,
7211 : FSNS( XML_w14, XML_checked ),
7212 1 : rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
7213 2 : else if (aGrabBag[j].Name == "ooxml:CT_SdtCheckbox_checkedState")
7214 : AddToAttrList( m_pRunSdtPrTokenChildren,
7215 : FSNS( XML_w14, XML_checkedState ),
7216 1 : rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
7217 1 : else if (aGrabBag[j].Name == "ooxml:CT_SdtCheckbox_uncheckedState")
7218 : AddToAttrList( m_pRunSdtPrTokenChildren,
7219 : FSNS( XML_w14, XML_uncheckedState ),
7220 1 : rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
7221 4 : }
7222 : }
7223 42 : else if (aPropertyValue.Name == "ooxml:CT_SdtPr_dataBinding")
7224 : {
7225 11 : uno::Sequence<beans::PropertyValue> aGrabBag;
7226 11 : aPropertyValue.Value >>= aGrabBag;
7227 44 : for (sal_Int32 j=0; j < aGrabBag.getLength(); ++j)
7228 : {
7229 33 : OUString sValue = aGrabBag[j].Value.get<OUString>();
7230 33 : if (aGrabBag[j].Name == "ooxml:CT_DataBinding_prefixMappings")
7231 : AddToAttrList( m_pRunSdtPrDataBindingAttrs,
7232 : FSNS( XML_w, XML_prefixMappings ),
7233 11 : rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
7234 22 : else if (aGrabBag[j].Name == "ooxml:CT_DataBinding_xpath")
7235 : AddToAttrList( m_pRunSdtPrDataBindingAttrs,
7236 : FSNS( XML_w, XML_xpath ),
7237 11 : rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
7238 11 : else if (aGrabBag[j].Name == "ooxml:CT_DataBinding_storeItemID")
7239 : AddToAttrList( m_pRunSdtPrDataBindingAttrs,
7240 : FSNS( XML_w, XML_storeItemID ),
7241 11 : rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
7242 44 : }
7243 : }
7244 31 : else if (aPropertyValue.Name == "ooxml:CT_SdtPr_text")
7245 11 : m_nRunSdtPrToken = FSNS( XML_w, XML_text );
7246 20 : else if (aPropertyValue.Name == "ooxml:CT_SdtPr_id" && m_nRunSdtPrToken == 0)
7247 : // only write id token as a marker if no other exist
7248 20 : m_nRunSdtPrToken = FSNS( XML_w, XML_id );
7249 63 : }
7250 : }
7251 : else
7252 : SAL_INFO("sw.ww8", "DocxAttributeOutput::CharGrabBag: unhandled grab bag property " << i->first);
7253 4775 : }
7254 4775 : }
7255 :
7256 272 : DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, FSHelperPtr pSerializer, oox::drawingml::DrawingML* pDrawingML )
7257 : : m_rExport( rExport ),
7258 : m_pSerializer( pSerializer ),
7259 : m_rDrawingML( *pDrawingML ),
7260 : m_pFontsAttrList( NULL ),
7261 : m_pEastAsianLayoutAttrList( NULL ),
7262 : m_pCharLangAttrList( NULL ),
7263 : m_pSectionSpacingAttrList( NULL ),
7264 : m_pParagraphSpacingAttrList( NULL ),
7265 : m_pHyperlinkAttrList( NULL ),
7266 : m_pColorAttrList( NULL ),
7267 : m_pBackgroundAttrList( NULL ),
7268 : m_endPageRef( false ),
7269 0 : m_pFootnotesList( new ::docx::FootnotesList() ),
7270 0 : m_pEndnotesList( new ::docx::FootnotesList() ),
7271 : m_footnoteEndnoteRefTag( 0 ),
7272 : m_pSectionInfo( NULL ),
7273 : m_pRedlineData( NULL ),
7274 : m_nRedlineId( 0 ),
7275 : m_bOpenedSectPr( false ),
7276 : m_bWritingHeaderFooter( false ),
7277 : m_sFieldBkm( ),
7278 : m_nNextBookmarkId( 0 ),
7279 : m_nNextAnnotationMarkId( 0 ),
7280 : m_pTableWrt( NULL ),
7281 : m_bParagraphOpened( false ),
7282 : m_bIsFirstParagraph( true ),
7283 : m_bAlternateContentChoiceOpen( false ),
7284 : m_nColBreakStatus( COLBRK_NONE ),
7285 : m_nTextFrameLevel( 0 ),
7286 : m_closeHyperlinkInThisRun( false ),
7287 : m_closeHyperlinkInPreviousRun( false ),
7288 : m_startedHyperlink( false ),
7289 : m_nHyperLinkCount(0),
7290 : m_nFieldsInHyperlink( 0 ),
7291 : m_postponedGraphic( NULL ),
7292 : m_postponedDiagram( NULL ),
7293 : m_postponedVMLDrawing(NULL),
7294 : m_postponedDMLDrawing(NULL),
7295 : m_postponedOLE( NULL ),
7296 : m_postponedMath( NULL ),
7297 : m_postponedChart( NULL ),
7298 : pendingPlaceholder( NULL ),
7299 : m_postitFieldsMaxId( 0 ),
7300 : m_anchorId( 1 ),
7301 : m_nextFontId( 1 ),
7302 : m_tableReference(new TableReference()),
7303 : m_oldTableReference(new TableReference()),
7304 : m_bIgnoreNextFill(false),
7305 : m_bBtLr(false),
7306 272 : m_pTableStyleExport(new DocxTableStyleExport(rExport.pDoc, pSerializer)),
7307 : m_bParaBeforeAutoSpacing(false),
7308 : m_bParaAfterAutoSpacing(false),
7309 : m_nParaBeforeSpacing(0),
7310 : m_nParaAfterSpacing(0),
7311 : m_setFootnote(false)
7312 : , m_nParagraphSdtPrToken(0)
7313 : , m_pParagraphSdtPrTokenChildren(NULL)
7314 : , m_pParagraphSdtPrDataBindingAttrs(NULL)
7315 : , m_nRunSdtPrToken(0)
7316 : , m_pRunSdtPrTokenChildren(NULL)
7317 544 : , m_pRunSdtPrDataBindingAttrs(NULL)
7318 : {
7319 272 : }
7320 :
7321 816 : DocxAttributeOutput::~DocxAttributeOutput()
7322 : {
7323 272 : delete m_pFontsAttrList, m_pFontsAttrList = NULL;
7324 272 : delete m_pEastAsianLayoutAttrList, m_pEastAsianLayoutAttrList = NULL;
7325 272 : delete m_pCharLangAttrList, m_pCharLangAttrList = NULL;
7326 272 : delete m_pSectionSpacingAttrList, m_pSectionSpacingAttrList = NULL;
7327 272 : delete m_pParagraphSpacingAttrList, m_pParagraphSpacingAttrList = NULL;
7328 272 : delete m_pHyperlinkAttrList, m_pHyperlinkAttrList = NULL;
7329 272 : delete m_pColorAttrList, m_pColorAttrList = NULL;
7330 272 : delete m_pBackgroundAttrList, m_pBackgroundAttrList = NULL;
7331 :
7332 272 : delete m_pFootnotesList, m_pFootnotesList = NULL;
7333 272 : delete m_pEndnotesList, m_pEndnotesList = NULL;
7334 :
7335 272 : delete m_pTableWrt, m_pTableWrt = NULL;
7336 272 : delete m_pParagraphSdtPrTokenChildren; m_pParagraphSdtPrTokenChildren = NULL;
7337 272 : delete m_pParagraphSdtPrDataBindingAttrs; m_pParagraphSdtPrDataBindingAttrs = NULL;
7338 272 : delete m_pRunSdtPrTokenChildren; m_pRunSdtPrTokenChildren = NULL;
7339 272 : delete m_pRunSdtPrDataBindingAttrs; m_pRunSdtPrDataBindingAttrs = NULL;
7340 544 : }
7341 :
7342 43519 : DocxExport& DocxAttributeOutput::GetExport()
7343 : {
7344 43519 : return m_rExport;
7345 : }
7346 :
7347 1468 : void DocxAttributeOutput::SetSerializer( ::sax_fastparser::FSHelperPtr pSerializer )
7348 : {
7349 1468 : m_pSerializer = pSerializer;
7350 1468 : m_pTableStyleExport->SetSerializer(pSerializer);
7351 1468 : }
7352 :
7353 842 : bool DocxAttributeOutput::HasFootnotes() const
7354 : {
7355 842 : return !m_pFootnotesList->isEmpty();
7356 : }
7357 :
7358 842 : bool DocxAttributeOutput::HasEndnotes() const
7359 : {
7360 842 : return !m_pEndnotesList->isEmpty();
7361 : }
7362 :
7363 272 : bool DocxAttributeOutput::HasPostitFields() const
7364 : {
7365 272 : return !m_postitFields.empty();
7366 : }
7367 :
7368 3 : void DocxAttributeOutput::BulletDefinition(int nId, const Graphic& rGraphic, Size aSize)
7369 : {
7370 : m_pSerializer->startElementNS(XML_w, XML_numPicBullet,
7371 : FSNS(XML_w, XML_numPicBulletId), OString::number(nId).getStr(),
7372 3 : FSEND);
7373 :
7374 3 : OStringBuffer aStyle;
7375 : // Size is in twips, we need it in points.
7376 3 : aStyle.append("width:").append(double(aSize.Width()) / 20);
7377 3 : aStyle.append("pt;height:").append(double(aSize.Height()) / 20).append("pt");
7378 3 : m_pSerializer->startElementNS( XML_w, XML_pict, FSEND);
7379 : m_pSerializer->startElementNS( XML_v, XML_shape,
7380 : XML_style, aStyle.getStr(),
7381 : FSNS(XML_o, XML_bullet), "t",
7382 3 : FSEND);
7383 :
7384 3 : m_rDrawingML.SetFS(m_pSerializer);
7385 6 : OUString aRelId = m_rDrawingML.WriteImage(rGraphic);
7386 : m_pSerializer->singleElementNS( XML_v, XML_imagedata,
7387 : FSNS(XML_r, XML_id), OUStringToOString(aRelId, RTL_TEXTENCODING_UTF8),
7388 : FSNS(XML_o, XML_title), "",
7389 3 : FSEND);
7390 :
7391 3 : m_pSerializer->endElementNS(XML_v, XML_shape);
7392 3 : m_pSerializer->endElementNS(XML_w, XML_pict);
7393 :
7394 6 : m_pSerializer->endElementNS(XML_w, XML_numPicBullet);
7395 3 : }
7396 :
7397 31144 : void DocxAttributeOutput::AddToAttrList( ::sax_fastparser::FastAttributeList* &pAttrList, sal_Int32 nAttrName, const sal_Char* sAttrValue )
7398 : {
7399 31144 : AddToAttrList( pAttrList, 1, nAttrName, sAttrValue );
7400 31144 : }
7401 :
7402 39146 : void DocxAttributeOutput::AddToAttrList( ::sax_fastparser::FastAttributeList* &pAttrList, sal_Int32 nAttrs, ... )
7403 : {
7404 39146 : if( !pAttrList )
7405 19115 : pAttrList = m_pSerializer->createAttrList();
7406 :
7407 : va_list args;
7408 39146 : va_start( args, nAttrs );
7409 87188 : for( sal_Int32 i = 0; i<nAttrs; i++)
7410 : {
7411 48042 : sal_Int32 nName = va_arg( args, sal_Int32 );
7412 48042 : const char* pValue = va_arg( args, const char* );
7413 48042 : if( pValue )
7414 48042 : pAttrList->add( nName, pValue );
7415 : }
7416 39146 : va_end( args );
7417 39179 : }
7418 :
7419 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|