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 0 : class FFDataWriterHelper
140 : {
141 : ::sax_fastparser::FSHelperPtr m_pSerializer;
142 0 : void writeCommonStart( const OUString& rName )
143 : {
144 0 : 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 0 : FSEND );
148 0 : m_pSerializer->singleElementNS( XML_w, XML_enabled, FSEND );
149 : m_pSerializer->singleElementNS( XML_w, XML_calcOnExit,
150 : FSNS( XML_w, XML_val ),
151 0 : "0", FSEND );
152 0 : }
153 0 : void writeFinish()
154 : {
155 0 : m_pSerializer->endElementNS( XML_w, XML_ffData );
156 0 : }
157 : public:
158 0 : FFDataWriterHelper( const ::sax_fastparser::FSHelperPtr pSerializer ) : m_pSerializer( pSerializer ){}
159 0 : void WriteFormCheckbox( const OUString& rName, const OUString& rDefault, bool bChecked )
160 : {
161 0 : writeCommonStart( rName );
162 : // Checkbox specific bits
163 0 : m_pSerializer->startElementNS( XML_w, XML_checkBox, FSEND );
164 : // currently hardcoding autosize
165 : // #TODO check if this defaulted
166 0 : m_pSerializer->startElementNS( XML_w, XML_sizeAuto, FSEND );
167 0 : m_pSerializer->endElementNS( XML_w, XML_sizeAuto );
168 0 : 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 0 : if ( bChecked )
175 0 : m_pSerializer->singleElementNS( XML_w, XML_checked, FSEND );
176 0 : m_pSerializer->endElementNS( XML_w, XML_checkBox );
177 0 : writeFinish();
178 0 : }
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 0 : FieldMarkParamsHelper( const sw::mark::IFieldmark& rFieldmark ) : mrFieldmark( rFieldmark ) {}
199 0 : OUString getName() { return mrFieldmark.GetName(); }
200 : template < typename T >
201 0 : bool extractParam( const OUString& rKey, T& rResult )
202 : {
203 0 : bool bResult = false;
204 0 : if ( mrFieldmark.GetParameters() )
205 : {
206 0 : sw::mark::IFieldmark::parameter_map_t::const_iterator it = mrFieldmark.GetParameters()->find( rKey );
207 0 : if ( it != mrFieldmark.GetParameters()->end() )
208 0 : bResult = ( it->second >>= rResult );
209 : }
210 0 : return bResult;
211 : }
212 : };
213 0 : void DocxAttributeOutput::RTLAndCJKState( bool bIsRTL, sal_uInt16 /*nScript*/ )
214 : {
215 0 : if (bIsRTL)
216 0 : m_pSerializer->singleElementNS( XML_w, XML_rtl, FSNS( XML_w, XML_val ), "true", FSEND );
217 0 : }
218 :
219 0 : void DocxAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo )
220 : {
221 0 : if ( m_nColBreakStatus == COLBRK_POSTPONE )
222 0 : m_nColBreakStatus = COLBRK_WRITE;
223 :
224 : // Output table/table row/table cell starts if needed
225 0 : if ( pTextNodeInfo.get() )
226 : {
227 0 : sal_uInt32 nRow = pTextNodeInfo->getRow();
228 0 : sal_uInt32 nCell = pTextNodeInfo->getCell();
229 :
230 : // New cell/row?
231 0 : if ( m_tableReference->m_nTableDepth > 0 && !m_tableReference->m_bTableCellOpen )
232 : {
233 0 : ww8::WW8TableNodeInfoInner::Pointer_t pDeepInner( pTextNodeInfo->getInnerForDepth( m_tableReference->m_nTableDepth ) );
234 0 : if ( pDeepInner->getCell() == 0 )
235 0 : StartTableRow( pDeepInner );
236 :
237 0 : StartTableCell( pDeepInner );
238 : }
239 :
240 0 : 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 0 : sal_uInt32 nCurrentDepth = pTextNodeInfo->getDepth();
246 :
247 0 : if ( nCurrentDepth > m_tableReference->m_nTableDepth )
248 : {
249 : // Start all the tables that begin here
250 0 : for ( sal_uInt32 nDepth = m_tableReference->m_nTableDepth + 1; nDepth <= pTextNodeInfo->getDepth(); ++nDepth )
251 : {
252 0 : ww8::WW8TableNodeInfoInner::Pointer_t pInner( pTextNodeInfo->getInnerForDepth( nDepth ) );
253 :
254 0 : if (m_tableReference->m_pOldTablepInner && m_tableReference->m_pOldTablepInner->getTable() == pInner->getTable() && nCurrentDepth > 1 && nDepth != 1)
255 : {
256 0 : m_tableReference->m_pOldTablepInner = pInner;
257 0 : break;
258 : }
259 : else
260 : {
261 0 : StartTable( pInner );
262 0 : StartTableRow( pInner );
263 0 : StartTableCell( pInner );
264 0 : m_tableReference->m_pOldTablepInner = pInner;
265 : }
266 0 : }
267 :
268 0 : 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 0 : m_pSerializer->mark();
276 :
277 0 : 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 0 : m_pSerializer->mark();
282 :
283 : // no section break in this paragraph yet; can be set in SectionBreak()
284 0 : m_pSectionInfo.reset();
285 :
286 0 : m_bParagraphOpened = true;
287 0 : m_bIsFirstParagraph = false;
288 0 : }
289 :
290 0 : void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner )
291 : {
292 : // write the paragraph properties + the run, already in the correct order
293 0 : 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 0 : ++m_nTextFrameLevel;
298 0 : if( m_nTextFrameLevel == 1 )
299 : {
300 0 : for (size_t nIndex = 0; nIndex < m_aFramesOfParagraph.size(); ++nIndex)
301 : {
302 0 : sw::Frame aFrame = m_aFramesOfParagraph[nIndex];
303 0 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
304 :
305 0 : m_pSerializer->startElementNS(XML_mc, XML_AlternateContent, FSEND);
306 : m_pSerializer->startElementNS(XML_mc, XML_Choice,
307 : XML_Requires, "wps",
308 0 : 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 0 : 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 0 : 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 0 : ww8::WW8TableInfo::Pointer_t pOldTableInfo = m_rExport.mpTableInfo;
329 : //Reset the table infos after saving.
330 0 : m_rExport.mpTableInfo = ww8::WW8TableInfo::Pointer_t(new ww8::WW8TableInfo());
331 :
332 0 : m_rExport.SdrExporter().writeDMLTextFrame(&aFrame, m_anchorId++);
333 0 : m_pSerializer->endElementNS(XML_mc, XML_Choice);
334 0 : 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 0 : m_rExport.mpTableInfo = ww8::WW8TableInfo::Pointer_t(new ww8::WW8TableInfo());
340 : //reset the tableReference.
341 0 : switchHeaderFooter(false,0);
342 :
343 0 : m_pSerializer->startElementNS(XML_mc, XML_Fallback, FSEND);
344 0 : m_rExport.SdrExporter().writeVMLTextFrame(&aFrame);
345 : /* FDO#71834 :Restore the data here after having written the Shape
346 : for further processing.
347 : */
348 0 : switchHeaderFooter(false,-1);
349 0 : m_rExport.mpTableInfo = pOldTableInfo;
350 :
351 0 : m_pSerializer->endElementNS(XML_mc, XML_Fallback);
352 0 : m_pSerializer->endElementNS(XML_mc, XML_AlternateContent);
353 :
354 0 : m_pSerializer->endElementNS( XML_w, XML_r );
355 0 : }
356 :
357 0 : m_aFramesOfParagraph.clear();
358 : }
359 :
360 0 : --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 0 : if(m_nHyperLinkCount > 0)
366 : {
367 0 : for(sal_Int32 nHyperLinkToClose = 0; nHyperLinkToClose < m_nHyperLinkCount; ++nHyperLinkToClose)
368 0 : m_pSerializer->endElementNS( XML_w, XML_hyperlink );
369 0 : m_nHyperLinkCount = 0;
370 : }
371 :
372 0 : m_pSerializer->endElementNS( XML_w, XML_p );
373 :
374 0 : WriteSdtBlock( m_nParagraphSdtPrToken, m_pParagraphSdtPrTokenChildren, m_pParagraphSdtPrDataBindingAttrs );
375 0 : m_pSerializer->mergeTopMarks();
376 :
377 : // Check for end of cell, rows, tables here
378 0 : FinishTableRowCell( pTextNodeInfoInner );
379 :
380 0 : m_bParagraphOpened = false;
381 :
382 0 : }
383 :
384 0 : void DocxAttributeOutput::WriteSdtBlock( sal_Int32& nSdtPrToken, ::sax_fastparser::FastAttributeList* &pSdtPrTokenChildren, ::sax_fastparser::FastAttributeList* &pSdtPrDataBindingAttrs )
385 : {
386 0 : if( nSdtPrToken > 0 || pSdtPrDataBindingAttrs )
387 : {
388 : // sdt start mark
389 0 : m_pSerializer->mark();
390 :
391 0 : m_pSerializer->startElementNS( XML_w, XML_sdt, FSEND );
392 :
393 : // output sdt properties
394 0 : m_pSerializer->startElementNS( XML_w, XML_sdtPr, FSEND );
395 :
396 0 : if( nSdtPrToken > 0 && pSdtPrTokenChildren )
397 : {
398 0 : m_pSerializer->startElement( nSdtPrToken, FSEND );
399 :
400 0 : uno::Sequence<xml::FastAttribute> aChildren = pSdtPrTokenChildren->getFastAttributes();
401 0 : for( sal_Int32 i=0; i < aChildren.getLength(); ++i )
402 0 : m_pSerializer->singleElement( aChildren[i].Token,
403 : FSNS(XML_w, XML_val),
404 0 : rtl::OUStringToOString( aChildren[i].Value, RTL_TEXTENCODING_UTF8 ).getStr(),
405 0 : FSEND );
406 :
407 0 : m_pSerializer->endElement( nSdtPrToken );
408 : }
409 0 : 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 0 : FSEND );
414 0 : else if( nSdtPrToken > 0 )
415 0 : m_pSerializer->singleElement( nSdtPrToken, FSEND );
416 :
417 0 : if( pSdtPrDataBindingAttrs )
418 : {
419 0 : XFastAttributeListRef xAttrList( pSdtPrDataBindingAttrs );
420 0 : m_pSerializer->singleElementNS( XML_w, XML_dataBinding, xAttrList );
421 : }
422 :
423 0 : m_pSerializer->endElementNS( XML_w, XML_sdtPr );
424 :
425 : // sdt contents start tag
426 0 : m_pSerializer->startElementNS( XML_w, XML_sdtContent, FSEND );
427 :
428 : // prepend the tags since the sdt start mark before the paragraph
429 0 : m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND );
430 :
431 : // write the ending tags after the paragraph
432 0 : m_pSerializer->endElementNS( XML_w, XML_sdtContent );
433 0 : m_pSerializer->endElementNS( XML_w, XML_sdt );
434 :
435 : // clear sdt status
436 0 : nSdtPrToken = 0;
437 0 : delete pSdtPrTokenChildren; pSdtPrTokenChildren = NULL;
438 0 : if( pSdtPrDataBindingAttrs )
439 : {
440 : // do not delete yet; it's in xAttrList inside the parser
441 0 : pSdtPrDataBindingAttrs = NULL;
442 : }
443 : }
444 0 : }
445 :
446 0 : void DocxAttributeOutput::FinishTableRowCell( ww8::WW8TableNodeInfoInner::Pointer_t pInner, bool bForceEmptyParagraph )
447 : {
448 0 : if ( pInner.get() )
449 : {
450 : // Where are we in the table
451 0 : sal_uInt32 nRow = pInner->getRow( );
452 :
453 0 : const SwTable *pTable = pInner->getTable( );
454 0 : const SwTableLines& rLines = pTable->GetTabLines( );
455 0 : 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 0 : bool limitWorkaround = ( pInner->getCell() >= 62 && !pInner->isEndOfLine());
463 :
464 0 : if ( pInner->isEndOfCell() && !limitWorkaround )
465 : {
466 0 : if ( bForceEmptyParagraph )
467 0 : m_pSerializer->singleElementNS( XML_w, XML_p, FSEND );
468 :
469 0 : EndTableCell();
470 : }
471 :
472 : // This is a line end
473 0 : if ( pInner->isEndOfLine() )
474 0 : EndTableRow();
475 :
476 : // This is the end of the table
477 0 : if ( pInner->isEndOfLine( ) && ( nRow + 1 ) == nLinesCount )
478 0 : EndTable();
479 : }
480 0 : }
481 :
482 0 : void DocxAttributeOutput::EmptyParagraph()
483 : {
484 0 : m_pSerializer->singleElementNS( XML_w, XML_p, FSEND );
485 0 : }
486 :
487 0 : 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 0 : SwNodeIndex aNextIndex( rNode, 1 );
495 0 : if ( aNextIndex.GetNode().IsTxtNode() )
496 : {
497 0 : const SwTxtNode* pTxtNode = static_cast< SwTxtNode* >( &aNextIndex.GetNode() );
498 0 : m_rExport.OutputSectionBreaks( pTxtNode->GetpSwAttrSet(), *pTxtNode, m_tableReference->m_bTableCellOpen, pTxtNode->GetTxt().isEmpty() );
499 : }
500 0 : else if ( aNextIndex.GetNode().IsTableNode() )
501 : {
502 0 : const SwTableNode* pTableNode = static_cast< SwTableNode* >( &aNextIndex.GetNode() );
503 0 : const SwFrmFmt *pFmt = pTableNode->GetTable().GetFrmFmt();
504 0 : m_rExport.OutputSectionBreaks( &(pFmt->GetAttrSet()), *pTableNode );
505 0 : }
506 0 : }
507 :
508 0 : void DocxAttributeOutput::StartParagraphProperties()
509 : {
510 0 : m_pSerializer->mark( );
511 :
512 0 : m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND );
513 :
514 : // and output the section break now (if it appeared)
515 0 : if ( m_pSectionInfo && (!m_setFootnote))
516 : {
517 0 : m_rExport.SectionProperties( *m_pSectionInfo );
518 0 : m_pSectionInfo.reset();
519 : }
520 :
521 0 : InitCollectedParagraphProperties();
522 0 : }
523 :
524 0 : void DocxAttributeOutput::InitCollectedParagraphProperties()
525 : {
526 0 : 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 0 : sal_Int32 len = sizeof ( aOrder ) / sizeof( sal_Int32 );
572 0 : uno::Sequence< sal_Int32 > aSeqOrder( len );
573 0 : for ( sal_Int32 i = 0; i < len; i++ )
574 0 : aSeqOrder[i] = aOrder[i];
575 :
576 0 : m_pSerializer->mark( aSeqOrder );
577 0 : }
578 :
579 0 : void DocxAttributeOutput::WriteCollectedParagraphProperties()
580 : {
581 0 : 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 0 : if ( m_pParagraphSpacingAttrList )
590 : {
591 0 : XFastAttributeListRef xAttrList( m_pParagraphSpacingAttrList );
592 0 : m_pParagraphSpacingAttrList = NULL;
593 :
594 0 : m_pSerializer->singleElementNS( XML_w, XML_spacing, xAttrList );
595 : }
596 :
597 0 : if ( m_pBackgroundAttrList )
598 : {
599 0 : XFastAttributeListRef xAttrList( m_pBackgroundAttrList );
600 0 : m_pBackgroundAttrList = NULL;
601 :
602 0 : m_pSerializer->singleElementNS( XML_w, XML_shd, xAttrList );
603 : }
604 0 : }
605 :
606 0 : 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 0 : Redline( pRedlineData );
611 :
612 0 : WriteCollectedParagraphProperties();
613 :
614 : // Merge the marks for the ordered elements
615 0 : m_pSerializer->mergeTopMarks( );
616 :
617 : // Write 'Paragraph Mark' properties
618 0 : if ( pRedlineParagraphMarkerDeleted || pRedlineParagraphMarkerInserted || pParagraphMarkerProperties)
619 : {
620 0 : m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
621 :
622 0 : 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 0 : ::sax_fastparser::FastAttributeList *pFontsAttrList_Original = m_pFontsAttrList;
630 0 : ::sax_fastparser::FastAttributeList *pEastAsianLayoutAttrList_Original = m_pEastAsianLayoutAttrList;
631 0 : ::sax_fastparser::FastAttributeList *pCharLangAttrList_Original = m_pCharLangAttrList;
632 0 : m_pFontsAttrList = NULL;
633 0 : m_pEastAsianLayoutAttrList = NULL;
634 0 : m_pCharLangAttrList = NULL;
635 :
636 0 : SfxWhichIter aIter( *pParagraphMarkerProperties );
637 0 : sal_uInt16 nWhichId = aIter.FirstWhich();
638 0 : const SfxPoolItem* pItem = 0;
639 0 : while( nWhichId )
640 : {
641 0 : if( SFX_ITEM_SET == pParagraphMarkerProperties->GetItemState( nWhichId, true, &pItem ))
642 : {
643 : SAL_INFO( "sw.ww8", "nWhichId " << nWhichId);
644 0 : if (isCHRATR( nWhichId ))
645 0 : OutputItem( *pItem );
646 : }
647 0 : nWhichId = aIter.NextWhich();
648 : }
649 :
650 : // Write the collected run properties that are stored in 'm_pFontsAttrList', 'm_pEastAsianLayoutAttrList', 'm_pCharLangAttrList'
651 0 : WriteCollectedRunProperties();
652 :
653 : // Revert back the original values that were stored in 'm_pFontsAttrList', 'm_pEastAsianLayoutAttrList', 'm_pCharLangAttrList'
654 0 : m_pFontsAttrList = pFontsAttrList_Original;
655 0 : m_pEastAsianLayoutAttrList = pEastAsianLayoutAttrList_Original;
656 0 : m_pCharLangAttrList = pCharLangAttrList_Original;
657 : }
658 0 : if ( pRedlineParagraphMarkerDeleted )
659 : {
660 0 : StartRedline( pRedlineParagraphMarkerDeleted );
661 0 : EndRedline( pRedlineParagraphMarkerDeleted );
662 : }
663 0 : if ( pRedlineParagraphMarkerInserted )
664 : {
665 0 : StartRedline( pRedlineParagraphMarkerInserted );
666 0 : EndRedline( pRedlineParagraphMarkerInserted );
667 : }
668 :
669 0 : m_pSerializer->endElementNS( XML_w, XML_rPr );
670 : }
671 :
672 0 : m_pSerializer->endElementNS( XML_w, XML_pPr );
673 :
674 0 : if ( m_nColBreakStatus == COLBRK_WRITE )
675 : {
676 0 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
677 : m_pSerializer->singleElementNS( XML_w, XML_br,
678 0 : FSNS( XML_w, XML_type ), "column", FSEND );
679 0 : m_pSerializer->endElementNS( XML_w, XML_r );
680 :
681 0 : m_nColBreakStatus = COLBRK_NONE;
682 : }
683 :
684 : // merge the properties _before_ the run (strictly speaking, just
685 : // after the start of the paragraph)
686 0 : m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND );
687 0 : }
688 :
689 0 : 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 0 : m_pRedlineData = pRedlineData;
694 :
695 : // this mark is used to be able to enclose the run inside a sdr tag.
696 0 : 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 0 : 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 0 : m_pSerializer->mark(); // let's call it "postponed text"
706 0 : }
707 :
708 0 : void DocxAttributeOutput::EndRun()
709 : {
710 : // Write field starts
711 0 : 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 0 : if ( pIt->bOpen && pIt->pField )
715 : {
716 0 : 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 0 : if ( !pIt->bClose || ( pIt->eType == ww::eUNKNOWN ) )
721 : {
722 0 : if (pIt->pField)
723 0 : delete pIt->pField;
724 0 : pIt = m_Fields.erase( pIt );
725 0 : continue;
726 : }
727 : }
728 0 : ++pIt;
729 : }
730 :
731 : // write the run properties + the text, already in the correct order
732 0 : 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 0 : m_pSerializer->mark(); // let's call it "actual run start"
737 :
738 0 : if ( m_closeHyperlinkInPreviousRun )
739 : {
740 0 : if ( m_startedHyperlink )
741 : {
742 0 : for ( int i = 0; i < m_nFieldsInHyperlink; i++ )
743 : {
744 : // If fields begin before hyperlink then
745 : // it should end before hyperlink close
746 0 : EndField_Impl( m_Fields.back( ) );
747 0 : if (m_Fields.back().pField)
748 0 : delete m_Fields.back().pField;
749 : }
750 0 : m_pSerializer->endElementNS( XML_w, XML_hyperlink );
751 0 : m_startedHyperlink = false;
752 0 : m_nHyperLinkCount--;
753 : }
754 0 : m_closeHyperlinkInPreviousRun = false;
755 : }
756 :
757 : // Write the hyperlink and toc fields starts
758 0 : 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 0 : if ( pIt->bOpen && !pIt->pField )
762 : {
763 0 : StartField_Impl( *pIt, true );
764 :
765 : // Remove the field if no end needs to be written
766 0 : if ( !pIt->bClose ) {
767 0 : if (pIt->pField)
768 0 : delete pIt->pField;
769 0 : pIt = m_Fields.erase( pIt );
770 0 : continue;
771 : }
772 : }
773 0 : ++pIt;
774 : }
775 :
776 : // Start the hyperlink after the fields separators or we would generate invalid file
777 0 : if ( m_pHyperlinkAttrList )
778 : {
779 0 : XFastAttributeListRef xAttrList ( m_pHyperlinkAttrList );
780 :
781 0 : m_pSerializer->startElementNS( XML_w, XML_hyperlink, xAttrList );
782 0 : m_pHyperlinkAttrList = NULL;
783 0 : m_startedHyperlink = true;
784 0 : m_nHyperLinkCount++;
785 0 : m_nFieldsInHyperlink = 0;
786 : }
787 :
788 : // if there is some redlining in the document, output it
789 0 : StartRedline( m_pRedlineData );
790 :
791 0 : DoWriteBookmarks( );
792 0 : DoWriteAnnotationMarks( );
793 :
794 0 : if( m_closeHyperlinkInThisRun && m_startedHyperlink && m_hyperLinkAnchor != "" && m_hyperLinkAnchor.startsWith("_Toc"))
795 : {
796 0 : OUString sToken;
797 0 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
798 0 : m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
799 0 : m_pSerializer->singleElementNS( XML_w, XML_webHidden, FSEND );
800 0 : m_pSerializer->endElementNS( XML_w, XML_rPr );
801 : m_pSerializer->startElementNS( XML_w, XML_fldChar,
802 : FSNS( XML_w, XML_fldCharType ), "begin",
803 0 : FSEND );
804 0 : m_pSerializer->endElementNS( XML_w, XML_fldChar );
805 0 : m_pSerializer->endElementNS( XML_w, XML_r );
806 :
807 :
808 0 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
809 0 : m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
810 0 : m_pSerializer->singleElementNS( XML_w, XML_webHidden, FSEND );
811 0 : m_pSerializer->endElementNS( XML_w, XML_rPr );
812 0 : sToken = "PAGEREF " + m_hyperLinkAnchor + " \\h"; // '\h' Creates a hyperlink to the bookmarked paragraph.
813 0 : DoWriteCmd( sToken );
814 0 : m_pSerializer->endElementNS( XML_w, XML_r );
815 :
816 : // Write the Field separator
817 0 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
818 0 : m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
819 0 : m_pSerializer->singleElementNS( XML_w, XML_webHidden, FSEND );
820 0 : m_pSerializer->endElementNS( XML_w, XML_rPr );
821 : m_pSerializer->singleElementNS( XML_w, XML_fldChar,
822 : FSNS( XML_w, XML_fldCharType ), "separate",
823 0 : FSEND );
824 0 : m_pSerializer->endElementNS( XML_w, XML_r );
825 : }
826 :
827 0 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
828 0 : if(GetExport().bTabInTOC && m_pHyperlinkAttrList)
829 : {
830 0 : RunText(OUString("\t")) ;
831 : }
832 0 : 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 0 : m_pSerializer->mergeTopMarks(); // merges the "actual run start"
836 : // append the actual run end
837 0 : m_pSerializer->endElementNS( XML_w, XML_r );
838 :
839 : // enclose in a sdt block, if necessary
840 0 : WriteSdtBlock( m_nRunSdtPrToken, m_pRunSdtPrTokenChildren, m_pRunSdtPrDataBindingAttrs );
841 0 : m_pSerializer->mergeTopMarks();
842 :
843 0 : WritePostponedMath();
844 :
845 0 : for (std::vector<const SdrObject*>::iterator it = m_aPostponedFormControls.begin(); it != m_aPostponedFormControls.end(); ++it)
846 0 : WritePostponedFormControl(*it);
847 0 : m_aPostponedFormControls.clear();
848 :
849 0 : WritePendingPlaceholder();
850 :
851 : // if there is some redlining in the document, output it
852 0 : EndRedline( m_pRedlineData );
853 :
854 0 : m_pRedlineData = NULL;
855 :
856 0 : if ( m_closeHyperlinkInThisRun )
857 : {
858 0 : if ( m_startedHyperlink )
859 : {
860 0 : if( m_endPageRef )
861 : {
862 : // Hyperlink is started and fldchar "end" needs to be written for PAGEREF
863 0 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
864 0 : m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
865 0 : m_pSerializer->singleElementNS( XML_w, XML_webHidden, FSEND );
866 0 : m_pSerializer->endElementNS( XML_w, XML_rPr );
867 : m_pSerializer->singleElementNS( XML_w, XML_fldChar,
868 : FSNS( XML_w, XML_fldCharType ), "end",
869 0 : FSEND );
870 0 : m_pSerializer->endElementNS( XML_w, XML_r );
871 0 : m_endPageRef = false;
872 0 : m_hyperLinkAnchor = "";
873 : }
874 :
875 0 : m_pSerializer->endElementNS( XML_w, XML_hyperlink );
876 0 : m_startedHyperlink = false;
877 0 : m_nHyperLinkCount--;
878 : }
879 0 : m_closeHyperlinkInThisRun = false;
880 : }
881 :
882 0 : if(!m_startedHyperlink)
883 0 : while ( m_Fields.begin() != m_Fields.end() )
884 : {
885 0 : EndField_Impl( m_Fields.front( ) );
886 0 : if (m_Fields.front().pField)
887 0 : delete m_Fields.front().pField;
888 0 : m_Fields.erase( m_Fields.begin( ) );
889 : }
890 0 : }
891 :
892 0 : void DocxAttributeOutput::DoWriteBookmarks()
893 : {
894 : // Write the start bookmarks
895 0 : for ( std::vector< OString >::const_iterator it = m_rBookmarksStart.begin(), end = m_rBookmarksStart.end();
896 : it != end; ++it )
897 : {
898 0 : const OString& rName = *it;
899 :
900 : // Output the bookmark
901 0 : sal_uInt16 nId = m_nNextBookmarkId++;
902 0 : 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 0 : FSEND );
907 0 : m_sLastOpenedBookmark = rName;
908 : }
909 0 : m_rBookmarksStart.clear();
910 :
911 : // export the end bookmarks
912 0 : for ( std::vector< OString >::const_iterator it = m_rBookmarksEnd.begin(), end = m_rBookmarksEnd.end();
913 : it != end; ++it )
914 : {
915 0 : const OString& rName = *it;
916 :
917 : // Get the id of the bookmark
918 0 : std::map< OString, sal_uInt16 >::iterator pPos = m_rOpenedBookmarksIds.find( rName );
919 0 : if ( pPos != m_rOpenedBookmarksIds.end( ) )
920 : {
921 0 : sal_uInt16 nId = ( *pPos ).second;
922 : m_pSerializer->singleElementNS( XML_w, XML_bookmarkEnd,
923 : FSNS( XML_w, XML_id ), OString::number( nId ).getStr( ),
924 0 : FSEND );
925 0 : m_rOpenedBookmarksIds.erase( rName );
926 : }
927 : }
928 0 : m_rBookmarksEnd.clear();
929 0 : }
930 :
931 0 : void DocxAttributeOutput::DoWriteAnnotationMarks()
932 : {
933 : // Write the start annotation marks
934 0 : for ( std::vector< OString >::const_iterator it = m_rAnnotationMarksStart.begin(), end = m_rAnnotationMarksStart.end();
935 : it != end; ++it )
936 : {
937 0 : 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 0 : if ( m_rOpenedAnnotationMarksIds.end() == m_rOpenedAnnotationMarksIds.find( rName ) )
946 : {
947 0 : sal_uInt16 nId = m_nNextAnnotationMarkId++;
948 0 : m_rOpenedAnnotationMarksIds[rName] = nId;
949 : m_pSerializer->singleElementNS( XML_w, XML_commentRangeStart,
950 : FSNS( XML_w, XML_id ), OString::number( nId ).getStr( ),
951 0 : FSEND );
952 0 : m_sLastOpenedAnnotationMark = rName;
953 : }
954 : }
955 0 : m_rAnnotationMarksStart.clear();
956 :
957 : // export the end annotation marks
958 0 : for ( std::vector< OString >::const_iterator it = m_rAnnotationMarksEnd.begin(), end = m_rAnnotationMarksEnd.end();
959 : it != end; ++it )
960 : {
961 0 : const OString& rName = *it;
962 :
963 : // Get the id of the annotation mark
964 0 : std::map< OString, sal_uInt16 >::iterator pPos = m_rOpenedAnnotationMarksIds.find( rName );
965 0 : if ( pPos != m_rOpenedAnnotationMarksIds.end( ) )
966 : {
967 0 : sal_uInt16 nId = ( *pPos ).second;
968 : m_pSerializer->singleElementNS( XML_w, XML_commentRangeEnd,
969 : FSNS( XML_w, XML_id ), OString::number( nId ).getStr( ),
970 0 : FSEND );
971 0 : m_rOpenedAnnotationMarksIds.erase( rName );
972 :
973 0 : 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 0 : FSEND );
977 0 : m_pSerializer->endElementNS(XML_w, XML_r);
978 : }
979 : }
980 0 : m_rAnnotationMarksEnd.clear();
981 0 : }
982 :
983 0 : void DocxAttributeOutput::WriteFFData( const FieldInfos& rInfos )
984 : {
985 0 : const ::sw::mark::IFieldmark& rFieldmark = *rInfos.pFieldmark;
986 0 : 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 0 : else if ( rInfos.eType == ww::eFORMCHECKBOX )
1005 : {
1006 0 : OUString sName;
1007 0 : bool bChecked = false;
1008 :
1009 0 : FieldMarkParamsHelper params( rFieldmark );
1010 0 : params.extractParam( ODF_FORMCHECKBOX_NAME, sName );
1011 :
1012 0 : const sw::mark::ICheckboxFieldmark* pCheckboxFm = dynamic_cast<const sw::mark::ICheckboxFieldmark*>(&rFieldmark);
1013 0 : if ( pCheckboxFm && pCheckboxFm->IsChecked() )
1014 0 : bChecked = true;
1015 :
1016 0 : FFDataWriterHelper ffdataOut( m_pSerializer );
1017 0 : 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 0 : }
1026 :
1027 0 : void DocxAttributeOutput::StartField_Impl( FieldInfos& rInfos, bool bWriteRun )
1028 : {
1029 0 : if ( m_startedHyperlink )
1030 0 : ++m_nFieldsInHyperlink;
1031 0 : if ( rInfos.pField && rInfos.eType == ww::eUNKNOWN )
1032 : {
1033 : // Expand unsupported fields
1034 0 : RunText( rInfos.pField->GetFieldName() );
1035 : }
1036 0 : else if ( rInfos.eType != ww::eNONE ) // HYPERLINK fields are just commands
1037 : {
1038 0 : if ( bWriteRun )
1039 0 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
1040 :
1041 0 : 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 0 : FSEND );
1072 :
1073 0 : if ( rInfos.pFieldmark )
1074 0 : WriteFFData( rInfos );
1075 :
1076 0 : m_pSerializer->endElementNS( XML_w, XML_fldChar );
1077 :
1078 0 : if ( bWriteRun )
1079 0 : 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 0 : if ( !rInfos.pField )
1084 0 : CmdField_Impl( rInfos );
1085 : }
1086 : }
1087 0 : }
1088 :
1089 0 : void DocxAttributeOutput::DoWriteCmd( const OUString& rCmd )
1090 : {
1091 0 : OUString sCmd = rCmd.trim();
1092 0 : if (sCmd.startsWith("SEQ"))
1093 : {
1094 0 : OUString sSeqName = msfilter::util::findQuotedText(sCmd, "SEQ ", '\\').trim();
1095 0 : m_aSeqBookmarksNames[sSeqName].push_back(m_sLastOpenedBookmark);
1096 : }
1097 : // Write the Field command
1098 0 : m_pSerializer->startElementNS( XML_w, XML_instrText, FSEND );
1099 0 : m_pSerializer->writeEscaped( rCmd );
1100 0 : m_pSerializer->endElementNS( XML_w, XML_instrText );
1101 :
1102 0 : }
1103 :
1104 0 : void DocxAttributeOutput::CmdField_Impl( FieldInfos& rInfos )
1105 : {
1106 0 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
1107 0 : sal_Int32 nNbToken = comphelper::string::getTokenCount(rInfos.sCmd, '\t');
1108 :
1109 0 : for ( sal_Int32 i = 0; i < nNbToken; i++ )
1110 : {
1111 0 : OUString sToken = rInfos.sCmd.getToken( i, '\t' );
1112 0 : if ( rInfos.eType == ww::eCREATEDATE
1113 0 : || rInfos.eType == ww::eSAVEDATE
1114 0 : || rInfos.eType == ww::ePRINTDATE
1115 0 : || rInfos.eType == ww::eDATE
1116 0 : || rInfos.eType == ww::eTIME )
1117 : {
1118 0 : sToken = sToken.replaceAll("NNNN", "dddd");
1119 0 : sToken = sToken.replaceAll("NN", "ddd");
1120 : }
1121 :
1122 : // Write the Field command
1123 0 : DoWriteCmd( sToken );
1124 :
1125 : // Replace tabs by </instrText><tab/><instrText>
1126 0 : if ( i < ( nNbToken - 1 ) )
1127 0 : RunText( OUString( "\t" ) );
1128 0 : }
1129 :
1130 0 : m_pSerializer->endElementNS( XML_w, XML_r );
1131 :
1132 : // Write the Field separator
1133 0 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
1134 : m_pSerializer->singleElementNS( XML_w, XML_fldChar,
1135 : FSNS( XML_w, XML_fldCharType ), "separate",
1136 0 : FSEND );
1137 0 : m_pSerializer->endElementNS( XML_w, XML_r );
1138 0 : }
1139 :
1140 0 : void DocxAttributeOutput::EndField_Impl( FieldInfos& rInfos )
1141 : {
1142 : // The command has to be written before for the hyperlinks
1143 0 : if ( rInfos.pField )
1144 : {
1145 0 : CmdField_Impl( rInfos );
1146 : }
1147 :
1148 : // Write the bookmark start if any
1149 0 : OUString aBkmName( m_sFieldBkm );
1150 0 : 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 0 : if (rInfos.pField ) // For hyperlinks and TOX
1159 : {
1160 : // Write the Field latest value
1161 0 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
1162 0 : OUString sExpand;
1163 0 : if(rInfos.eType == ww::eCITATION)
1164 : {
1165 0 : sExpand = rInfos.pField->ExpandField( false , AUTH_FIELD_TITLE);
1166 : }
1167 : else
1168 : {
1169 0 : sExpand = rInfos.pField->ExpandField( true );
1170 : }
1171 : // newlines embedded in fields are 0x0B in MSO and 0x0A for us
1172 0 : RunText(sExpand.replace(0x0A, 0x0B));
1173 :
1174 0 : m_pSerializer->endElementNS( XML_w, XML_r );
1175 : }
1176 :
1177 : // Write the bookmark end if any
1178 0 : 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 0 : if ( rInfos.bClose )
1189 : {
1190 0 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
1191 : m_pSerializer->singleElementNS( XML_w, XML_fldChar,
1192 : FSNS( XML_w, XML_fldCharType ), "end",
1193 0 : FSEND );
1194 0 : 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 0 : if ( rInfos.pField )
1199 : {
1200 0 : sal_uInt16 nSubType = rInfos.pField->GetSubType( );
1201 0 : bool bIsSetField = rInfos.pField->GetTyp( )->Which( ) == RES_SETEXPFLD;
1202 0 : bool bShowRef = ( !bIsSetField || ( nSubType & nsSwExtendedSubType::SUB_INVISIBLE ) ) ? false : true;
1203 :
1204 0 : 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 0 : }
1225 0 : }
1226 :
1227 0 : void DocxAttributeOutput::StartRunProperties()
1228 : {
1229 : // postpone the output so that we can later [in EndRunProperties()]
1230 : // prepend the properties before the text
1231 0 : m_pSerializer->mark();
1232 :
1233 0 : m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
1234 :
1235 0 : if(GetExport().bHideTabLeaderAndPageNumbers && m_pHyperlinkAttrList )
1236 : {
1237 0 : m_pSerializer->singleElementNS( XML_w, XML_webHidden, FSEND );
1238 : }
1239 0 : InitCollectedRunProperties();
1240 :
1241 : OSL_ASSERT( m_postponedGraphic == NULL );
1242 0 : m_postponedGraphic = new std::list< PostponedGraphic >;
1243 :
1244 : OSL_ASSERT( m_postponedDiagram == NULL );
1245 0 : m_postponedDiagram = new std::list< PostponedDiagram >;
1246 :
1247 : OSL_ASSERT( m_postponedVMLDrawing == NULL );
1248 0 : m_postponedVMLDrawing = new std::list< PostponedDrawing >;
1249 :
1250 : assert(!m_postponedDMLDrawing);
1251 0 : m_postponedDMLDrawing = new std::list< PostponedDrawing >;
1252 :
1253 : assert( !m_postponedOLE );
1254 0 : m_postponedOLE = new std::list< PostponedOLE >;
1255 0 : }
1256 :
1257 0 : void DocxAttributeOutput::InitCollectedRunProperties()
1258 : {
1259 0 : m_pFontsAttrList = NULL;
1260 0 : m_pEastAsianLayoutAttrList = NULL;
1261 0 : 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 0 : sal_Int32 len = sizeof ( aOrder ) / sizeof( sal_Int32 );
1323 0 : uno::Sequence< sal_Int32 > aSeqOrder( len );
1324 0 : for ( sal_Int32 i = 0; i < len; i++ )
1325 0 : aSeqOrder[i] = aOrder[i];
1326 :
1327 0 : m_pSerializer->mark( aSeqOrder );
1328 :
1329 0 : }
1330 :
1331 : namespace
1332 : {
1333 :
1334 0 : struct NameToId
1335 : {
1336 : OUString maName;
1337 : sal_Int32 maId;
1338 : };
1339 :
1340 0 : 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 0 : };
1428 :
1429 0 : boost::optional<sal_Int32> lclGetElementIdForName(const OUString& rName)
1430 : {
1431 0 : sal_Int32 aLength = sizeof (constNameToIdMapping) / sizeof(NameToId);
1432 0 : for (sal_Int32 i=0; i < aLength; ++i)
1433 : {
1434 0 : if (rName == constNameToIdMapping[i].maName)
1435 : {
1436 0 : return constNameToIdMapping[i].maId;
1437 : }
1438 : }
1439 0 : return boost::optional<sal_Int32>();
1440 : }
1441 :
1442 0 : void lclProcessRecursiveGrabBag(sal_Int32 aElementId, const css::uno::Sequence<css::beans::PropertyValue>& rElements, sax_fastparser::FSHelperPtr pSerializer)
1443 : {
1444 0 : css::uno::Sequence<css::beans::PropertyValue> aAttributes;
1445 0 : FastAttributeList* pAttributes = pSerializer->createAttrList();
1446 :
1447 0 : for (sal_Int32 j=0; j < rElements.getLength(); ++j)
1448 : {
1449 0 : if (rElements[j].Name == "attributes")
1450 : {
1451 0 : rElements[j].Value >>= aAttributes;
1452 : }
1453 : }
1454 :
1455 0 : for (sal_Int32 j=0; j < aAttributes.getLength(); ++j)
1456 : {
1457 0 : uno::Any aAny = aAttributes[j].Value;
1458 0 : OString aValue;
1459 :
1460 0 : if(aAny.getValueType() == getCppuType<sal_Int32>())
1461 : {
1462 0 : aValue = OString::number(aAny.get<sal_Int32>());
1463 : }
1464 0 : else if(aAny.getValueType() == getCppuType<OUString>())
1465 : {
1466 0 : aValue = OUStringToOString(aAny.get<OUString>(), RTL_TEXTENCODING_ASCII_US);
1467 : }
1468 :
1469 0 : boost::optional<sal_Int32> aSubElementId = lclGetElementIdForName(aAttributes[j].Name);
1470 0 : if(aSubElementId)
1471 0 : pAttributes->add(*aSubElementId, aValue.getStr());
1472 0 : }
1473 :
1474 0 : XFastAttributeListRef xAttributesList( pAttributes );
1475 :
1476 0 : pSerializer->startElement(aElementId, xAttributesList);
1477 :
1478 0 : for (sal_Int32 j=0; j < rElements.getLength(); ++j)
1479 : {
1480 0 : css::uno::Sequence<css::beans::PropertyValue> aSumElements;
1481 :
1482 0 : boost::optional<sal_Int32> aSubElementId = lclGetElementIdForName(rElements[j].Name);
1483 0 : if(aSubElementId)
1484 : {
1485 0 : rElements[j].Value >>= aSumElements;
1486 0 : lclProcessRecursiveGrabBag(*aSubElementId, aSumElements, pSerializer);
1487 : }
1488 0 : }
1489 :
1490 0 : pSerializer->endElement(aElementId);
1491 0 : }
1492 :
1493 : }
1494 :
1495 0 : void DocxAttributeOutput::WriteCollectedRunProperties()
1496 : {
1497 : // Write all differed properties
1498 0 : if ( m_pFontsAttrList )
1499 : {
1500 0 : XFastAttributeListRef xAttrList( m_pFontsAttrList );
1501 0 : m_pFontsAttrList = NULL;
1502 :
1503 0 : m_pSerializer->singleElementNS( XML_w, XML_rFonts, xAttrList );
1504 : }
1505 :
1506 0 : if ( m_pColorAttrList )
1507 : {
1508 0 : XFastAttributeListRef xAttrList( m_pColorAttrList );
1509 0 : m_pColorAttrList = NULL;
1510 :
1511 0 : m_pSerializer->singleElementNS( XML_w, XML_color, xAttrList );
1512 : }
1513 :
1514 0 : 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 0 : if ( m_pCharLangAttrList )
1523 : {
1524 0 : XFastAttributeListRef xAttrList( m_pCharLangAttrList );
1525 0 : m_pCharLangAttrList = NULL;
1526 :
1527 0 : m_pSerializer->singleElementNS( XML_w, XML_lang, xAttrList );
1528 : }
1529 :
1530 0 : if (m_aTextEffectsGrabBag.getLength() > 0)
1531 : {
1532 0 : for (sal_Int32 i=0; i < m_aTextEffectsGrabBag.getLength(); ++i)
1533 : {
1534 0 : boost::optional<sal_Int32> aElementId = lclGetElementIdForName(m_aTextEffectsGrabBag[i].Name);
1535 0 : if(aElementId)
1536 : {
1537 0 : uno::Sequence<beans::PropertyValue> aGrabBagSeq;
1538 0 : m_aTextEffectsGrabBag[i].Value >>= aGrabBagSeq;
1539 0 : lclProcessRecursiveGrabBag(*aElementId, aGrabBagSeq, m_pSerializer);
1540 : }
1541 0 : }
1542 0 : m_aTextEffectsGrabBag.realloc(0);
1543 : }
1544 0 : }
1545 :
1546 0 : 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 0 : Redline( pRedlineData );
1551 :
1552 0 : WriteCollectedRunProperties();
1553 :
1554 : // Merge the marks for the ordered elements
1555 0 : m_pSerializer->mergeTopMarks();
1556 :
1557 0 : m_pSerializer->endElementNS( XML_w, XML_rPr );
1558 :
1559 : // write footnotes/endnotes if we have any
1560 0 : FootnoteEndnoteReference();
1561 :
1562 0 : WritePostponedGraphic();
1563 :
1564 0 : WritePostponedDiagram();
1565 : //We need to write w:drawing tag after the w:rPr.
1566 0 : WritePostponedChart();
1567 :
1568 : //We need to write w:pict tag after the w:rPr.
1569 0 : WritePostponedVMLDrawing();
1570 0 : WritePostponedDMLDrawing();
1571 :
1572 0 : WritePostponedOLE();
1573 :
1574 : // merge the properties _before_ the run text (strictly speaking, just
1575 : // after the start of the run)
1576 0 : m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND );
1577 0 : }
1578 :
1579 0 : void DocxAttributeOutput::WritePostponedGraphic()
1580 : {
1581 0 : for( std::list< PostponedGraphic >::const_iterator it = m_postponedGraphic->begin();
1582 0 : it != m_postponedGraphic->end();
1583 : ++it )
1584 0 : FlyFrameGraphic( it->grfNode, it->size, it->mOLEFrmFmt, it->mOLENode, it->pSdrObj );
1585 0 : delete m_postponedGraphic;
1586 0 : m_postponedGraphic = NULL;
1587 0 : }
1588 :
1589 0 : void DocxAttributeOutput::WritePostponedDiagram()
1590 : {
1591 0 : for( std::list< PostponedDiagram >::const_iterator it = m_postponedDiagram->begin();
1592 0 : it != m_postponedDiagram->end();
1593 : ++it )
1594 0 : m_rExport.SdrExporter().writeDiagram( it->object, *(it->frame), m_anchorId++ );
1595 0 : delete m_postponedDiagram;
1596 0 : m_postponedDiagram = NULL;
1597 0 : }
1598 :
1599 0 : void DocxAttributeOutput::FootnoteEndnoteRefTag()
1600 : {
1601 0 : if( m_footnoteEndnoteRefTag == 0 )
1602 0 : return;
1603 0 : m_pSerializer->singleElementNS( XML_w, m_footnoteEndnoteRefTag, FSEND );
1604 0 : 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 0 : static void impl_WriteRunText( FSHelperPtr pSerializer, sal_Int32 nTextToken,
1614 : const sal_Unicode* &rBegin, const sal_Unicode* pEnd, bool bMove = true )
1615 : {
1616 0 : const sal_Unicode *pBegin = rBegin;
1617 :
1618 : // skip one character after the end
1619 0 : if ( bMove )
1620 0 : rBegin = pEnd + 1;
1621 :
1622 0 : if ( pBegin >= pEnd )
1623 0 : return; // we want to write at least one character
1624 :
1625 : // we have to add 'preserve' when starting/ending with space
1626 0 : if ( *pBegin == ' ' || *( pEnd - 1 ) == ' ' )
1627 : {
1628 0 : pSerializer->startElementNS( XML_w, nTextToken, FSNS( XML_xml, XML_space ), "preserve", FSEND );
1629 : }
1630 : else
1631 0 : pSerializer->startElementNS( XML_w, nTextToken, FSEND );
1632 :
1633 0 : pSerializer->writeEscaped( OUString( pBegin, pEnd - pBegin ) );
1634 :
1635 0 : pSerializer->endElementNS( XML_w, nTextToken );
1636 : }
1637 :
1638 0 : void DocxAttributeOutput::RunText( const OUString& rText, rtl_TextEncoding /*eCharSet*/ )
1639 : {
1640 0 : if( m_closeHyperlinkInThisRun )
1641 : {
1642 0 : m_closeHyperlinkInPreviousRun = true;
1643 : }
1644 :
1645 : // one text can be split into more <w:t>blah</w:t>'s by line breaks etc.
1646 0 : const sal_Unicode *pBegin = rText.getStr();
1647 0 : const sal_Unicode *pEnd = pBegin + rText.getLength();
1648 :
1649 : // the text run is usually XML_t, with the exception of the deleted text
1650 0 : sal_Int32 nTextToken = XML_t;
1651 0 : if ( m_pRedlineData && m_pRedlineData->GetType() == nsRedlineType_t::REDLINE_DELETE )
1652 0 : nTextToken = XML_delText;
1653 :
1654 0 : for ( const sal_Unicode *pIt = pBegin; pIt < pEnd; ++pIt )
1655 : {
1656 0 : switch ( *pIt )
1657 : {
1658 : case 0x09: // tab
1659 0 : impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt );
1660 0 : m_pSerializer->singleElementNS( XML_w, XML_tab, FSEND );
1661 0 : break;
1662 : case 0x0b: // line break
1663 0 : impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt );
1664 0 : m_pSerializer->singleElementNS( XML_w, XML_br, FSEND );
1665 0 : break;
1666 : case 0x1E: //non-breaking hyphen
1667 0 : impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt );
1668 0 : m_pSerializer->singleElementNS( XML_w, XML_noBreakHyphen, FSEND );
1669 0 : break;
1670 : case 0x1F: //soft (on demand) hyphen
1671 0 : impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt );
1672 0 : m_pSerializer->singleElementNS( XML_w, XML_softHyphen, FSEND );
1673 0 : break;
1674 : default:
1675 0 : if ( *pIt < 0x0020 ) // filter out the control codes
1676 : {
1677 0 : impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt );
1678 : OSL_TRACE( "Ignored control code %x in a text run.", *pIt );
1679 : }
1680 0 : break;
1681 : }
1682 : }
1683 :
1684 0 : impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pEnd, false );
1685 0 : }
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 0 : bool DocxAttributeOutput::AnalyzeURL( const OUString& rUrl, const OUString& rTarget, OUString* pLinkURL, OUString* pMark )
1762 : {
1763 0 : bool bBookMarkOnly = AttributeOutputBase::AnalyzeURL( rUrl, rTarget, pLinkURL, pMark );
1764 :
1765 0 : if ( !pMark->isEmpty() )
1766 : {
1767 0 : OUString sURL = *pLinkURL;
1768 :
1769 0 : if ( bBookMarkOnly )
1770 0 : sURL = FieldString( ww::eHYPERLINK );
1771 : else
1772 0 : sURL = FieldString( ww::eHYPERLINK ) + "\"" + sURL + "\"";
1773 :
1774 0 : sURL += " \\l \"" + *pMark + "\"";
1775 :
1776 0 : if ( !rTarget.isEmpty() )
1777 0 : sURL += " \\n " + rTarget;
1778 :
1779 0 : *pLinkURL = sURL;
1780 : }
1781 :
1782 0 : return bBookMarkOnly;
1783 : }
1784 :
1785 0 : bool DocxAttributeOutput::StartURL( const OUString& rUrl, const OUString& rTarget )
1786 : {
1787 0 : OUString sMark;
1788 0 : OUString sUrl;
1789 :
1790 0 : bool bBookmarkOnly = AnalyzeURL( rUrl, rTarget, &sUrl, &sMark );
1791 :
1792 0 : m_hyperLinkAnchor = sMark;
1793 :
1794 0 : if ( !sMark.isEmpty() && !bBookmarkOnly )
1795 : {
1796 0 : m_rExport.OutputField( NULL, ww::eHYPERLINK, sUrl );
1797 : }
1798 : else
1799 : {
1800 : // Output a hyperlink XML element
1801 0 : m_pHyperlinkAttrList = m_pSerializer->createAttrList();
1802 :
1803 0 : if ( !bBookmarkOnly )
1804 : {
1805 0 : OString sId = OUStringToOString( GetExport().GetFilter().addRelation( m_pSerializer->getOutputStream(),
1806 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
1807 0 : sUrl, true ), RTL_TEXTENCODING_UTF8 );
1808 :
1809 0 : 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 0 : if (sMark.endsWith("|sequence"))
1817 : {
1818 0 : sal_Int32 nPos = sMark.indexOf('!');
1819 0 : if (nPos != -1)
1820 : {
1821 : // Extract <seqname>, the field instruction text has the name quoted.
1822 0 : OUString aSequenceName = sMark.copy(0, nPos);
1823 : // Extract <index>.
1824 0 : sal_uInt32 nIndex = sMark.copy(nPos + 1, sMark.getLength() - nPos - sizeof("|sequence")).toInt32();
1825 0 : std::map<OUString, std::vector<OString> >::iterator it = m_aSeqBookmarksNames.find(aSequenceName);
1826 0 : if (it != m_aSeqBookmarksNames.end())
1827 : {
1828 0 : std::vector<OString>& rNames = it->second;
1829 0 : if (rNames.size() > nIndex)
1830 : // We know the bookmark name for this sequence and this index, do the replacement.
1831 0 : sMark = OStringToOUString(rNames[nIndex], RTL_TEXTENCODING_UTF8);
1832 0 : }
1833 : }
1834 : }
1835 : m_pHyperlinkAttrList->add( FSNS( XML_w, XML_anchor ),
1836 0 : OUStringToOString( sMark, RTL_TEXTENCODING_UTF8 ).getStr( ) );
1837 : }
1838 :
1839 0 : OUString sTarget( rTarget );
1840 0 : 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 0 : }
1845 : }
1846 :
1847 0 : return true;
1848 : }
1849 :
1850 0 : bool DocxAttributeOutput::EndURL()
1851 : {
1852 0 : m_closeHyperlinkInThisRun = true;
1853 0 : if(m_hyperLinkAnchor != "" && m_hyperLinkAnchor.startsWith("_Toc"))
1854 : {
1855 0 : m_endPageRef = true;
1856 : }
1857 0 : return true;
1858 : }
1859 :
1860 0 : void DocxAttributeOutput::FieldVanish( const OUString& rTxt, ww::eField eType )
1861 : {
1862 0 : WriteField_Impl( NULL, eType, rTxt, WRITEFIELD_ALL );
1863 0 : }
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 0 : void DocxAttributeOutput::Redline( const SwRedlineData* pRedlineData)
1869 : {
1870 0 : if ( !pRedlineData )
1871 0 : return;
1872 :
1873 0 : OString aId( OString::number( pRedlineData->GetSeqNo() ) );
1874 0 : const OUString &rAuthor( SW_MOD()->GetRedlineAuthor( pRedlineData->GetAuthor() ) );
1875 0 : OString aAuthor( OUStringToOString( rAuthor, RTL_TEXTENCODING_UTF8 ) );
1876 0 : OString aDate( DateTimeToOString( pRedlineData->GetTimeStamp() ) );
1877 :
1878 0 : switch( pRedlineData->GetType() )
1879 : {
1880 : case nsRedlineType_t::REDLINE_INSERT:
1881 0 : break;
1882 :
1883 : case nsRedlineType_t::REDLINE_DELETE:
1884 0 : 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 0 : FSEND );
1892 :
1893 : // Check if there is any extra data stored in the redline object
1894 0 : 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 0 : m_pSerializer->endElementNS( XML_w, XML_rPrChange );
1940 0 : 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 0 : FSEND );
1948 :
1949 : // Check if there is any extra data stored in the redline object
1950 0 : 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 0 : m_pSerializer->endElementNS( XML_w, XML_pPrChange );
1993 0 : break;
1994 :
1995 : default:
1996 : SAL_WARN("sw.ww8", "Unhandled redline type for export " << pRedlineData->GetType());
1997 0 : break;
1998 0 : }
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 0 : void DocxAttributeOutput::StartRedline( const SwRedlineData * pRedlineData )
2005 : {
2006 0 : if ( !pRedlineData )
2007 0 : return;
2008 :
2009 : // FIXME check if it's necessary to travel over the Next()'s in pRedlineData
2010 :
2011 0 : OString aId( OString::number( m_nRedlineId++ ) );
2012 :
2013 0 : const OUString &rAuthor( SW_MOD()->GetRedlineAuthor( pRedlineData->GetAuthor() ) );
2014 0 : OString aAuthor( OUStringToOString( rAuthor, RTL_TEXTENCODING_UTF8 ) );
2015 :
2016 0 : OString aDate( DateTimeToOString( pRedlineData->GetTimeStamp() ) );
2017 :
2018 0 : 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 0 : FSEND );
2026 0 : 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 0 : FSEND );
2034 0 : break;
2035 :
2036 : case nsRedlineType_t::REDLINE_FORMAT:
2037 : OSL_TRACE( "TODO DocxAttributeOutput::StartRedline()" );
2038 : default:
2039 0 : break;
2040 0 : }
2041 : }
2042 :
2043 0 : void DocxAttributeOutput::EndRedline( const SwRedlineData * pRedlineData )
2044 : {
2045 0 : if ( !pRedlineData )
2046 0 : return;
2047 :
2048 0 : switch ( pRedlineData->GetType() )
2049 : {
2050 : case nsRedlineType_t::REDLINE_INSERT:
2051 0 : m_pSerializer->endElementNS( XML_w, XML_ins );
2052 0 : break;
2053 :
2054 : case nsRedlineType_t::REDLINE_DELETE:
2055 0 : m_pSerializer->endElementNS( XML_w, XML_del );
2056 0 : break;
2057 :
2058 : case nsRedlineType_t::REDLINE_FORMAT:
2059 : OSL_TRACE( "TODO DocxAttributeOutput::EndRedline()" );
2060 0 : 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 0 : void DocxAttributeOutput::ParagraphStyle( sal_uInt16 nStyle )
2072 : {
2073 0 : OString aStyleId(m_rExport.pStyles->GetStyleId(nStyle));
2074 :
2075 0 : m_pSerializer->singleElementNS( XML_w, XML_pStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND );
2076 0 : }
2077 :
2078 0 : 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 0 : 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 0 : const char* pVal = "nil";
2091 0 : if ( pBorderLine && !pBorderLine->isEmpty( ) )
2092 : {
2093 0 : switch (pBorderLine->GetBorderLineStyle())
2094 : {
2095 : case table::BorderLineStyle::SOLID:
2096 0 : pVal = ( sal_Char* )"single";
2097 0 : break;
2098 : case table::BorderLineStyle::DOTTED:
2099 0 : pVal = ( sal_Char* )"dotted";
2100 0 : break;
2101 : case table::BorderLineStyle::DASHED:
2102 0 : pVal = ( sal_Char* )"dashed";
2103 0 : break;
2104 : case table::BorderLineStyle::DOUBLE:
2105 0 : pVal = ( sal_Char* )"double";
2106 0 : break;
2107 : case table::BorderLineStyle::THINTHICK_SMALLGAP:
2108 0 : pVal = ( sal_Char* )"thinThickSmallGap";
2109 0 : 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 0 : pVal = ( sal_Char* )"thickThinSmallGap";
2118 0 : break;
2119 : case table::BorderLineStyle::THICKTHIN_MEDIUMGAP:
2120 0 : pVal = ( sal_Char* )"thickThinMediumGap";
2121 0 : break;
2122 : case table::BorderLineStyle::THICKTHIN_LARGEGAP:
2123 0 : pVal = ( sal_Char* )"thickThinLargeGap";
2124 0 : 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 0 : pVal = ( sal_Char* )"dashSmallGap";
2139 0 : break;
2140 : case table::BorderLineStyle::NONE:
2141 : default:
2142 0 : break;
2143 : }
2144 : }
2145 0 : 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 0 : 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 0 : if( rStyleProps != NULL && pBorderLine && !pBorderLine->isEmpty() &&
2154 0 : pBorderLine->GetBorderLineStyle() == rStyleProps->LineStyle &&
2155 0 : pBorderLine->GetColor() == rStyleProps->Color &&
2156 0 : pBorderLine->GetWidth() == convertMm100ToTwip( rStyleProps->LineWidth ) )
2157 0 : return;
2158 :
2159 0 : pAttr->add( FSNS( XML_w, XML_val ), OString( pVal ) );
2160 :
2161 0 : if ( pBorderLine && !pBorderLine->isEmpty() )
2162 : {
2163 : // Compute the sz attribute
2164 :
2165 : double const fConverted( ::editeng::ConvertBorderWidthToWord(
2166 0 : pBorderLine->GetBorderLineStyle(), pBorderLine->GetWidth()));
2167 : // The unit is the 8th of point
2168 0 : sal_Int32 nWidth = sal_Int32( fConverted / 2.5 );
2169 0 : sal_uInt16 nMinWidth = 2;
2170 0 : sal_uInt16 nMaxWidth = 96;
2171 :
2172 0 : if ( nWidth > nMaxWidth )
2173 0 : nWidth = nMaxWidth;
2174 0 : else if ( nWidth < nMinWidth )
2175 0 : nWidth = nMinWidth;
2176 :
2177 0 : pAttr->add( FSNS( XML_w, XML_sz ), OString::number( nWidth ) );
2178 :
2179 : // Get the distance (in pt)
2180 0 : pAttr->add( FSNS( XML_w, XML_space ), OString::number( nDist / 20 ) );
2181 :
2182 : // Get the color code as an RRGGBB hex value
2183 0 : OString sColor( msfilter::util::ConvertColor( pBorderLine->GetColor( ) ) );
2184 0 : pAttr->add( FSNS( XML_w, XML_color ), sColor );
2185 : }
2186 :
2187 0 : if (bWriteShadow)
2188 : {
2189 : // Set the shadow value
2190 0 : pAttr->add( FSNS( XML_w, XML_shadow ), "1" );
2191 : }
2192 :
2193 0 : XFastAttributeListRef xAttrs( pAttr );
2194 0 : pSerializer->singleElementNS( XML_w, elementToken, xAttrs );
2195 : }
2196 :
2197 0 : static OutputBorderOptions lcl_getTableDefaultBorderOptions(bool bEcma)
2198 : {
2199 0 : OutputBorderOptions rOptions;
2200 :
2201 0 : rOptions.tag = XML_tblBorders;
2202 0 : rOptions.bUseStartEnd = !bEcma;
2203 0 : rOptions.bWriteTag = true;
2204 0 : rOptions.bWriteInsideHV = true;
2205 0 : rOptions.bWriteDistance = false;
2206 0 : rOptions.aShadowLocation = SVX_SHADOW_NONE;
2207 0 : rOptions.bCheckDistanceSize = false;
2208 :
2209 0 : return rOptions;
2210 : }
2211 :
2212 0 : static OutputBorderOptions lcl_getTableCellBorderOptions(bool bEcma)
2213 : {
2214 0 : OutputBorderOptions rOptions;
2215 :
2216 0 : rOptions.tag = XML_tcBorders;
2217 0 : rOptions.bUseStartEnd = !bEcma;
2218 0 : rOptions.bWriteTag = true;
2219 0 : rOptions.bWriteInsideHV = true;
2220 0 : rOptions.bWriteDistance = false;
2221 0 : rOptions.aShadowLocation = SVX_SHADOW_NONE;
2222 0 : rOptions.bCheckDistanceSize = false;
2223 :
2224 0 : return rOptions;
2225 : }
2226 :
2227 0 : static OutputBorderOptions lcl_getBoxBorderOptions()
2228 : {
2229 0 : OutputBorderOptions rOptions;
2230 :
2231 0 : rOptions.tag = XML_pBdr;
2232 0 : rOptions.bUseStartEnd = false;
2233 0 : rOptions.bWriteTag = false;
2234 0 : rOptions.bWriteInsideHV = false;
2235 0 : rOptions.bWriteDistance = true;
2236 0 : rOptions.aShadowLocation = SVX_SHADOW_NONE;
2237 0 : rOptions.bCheckDistanceSize = false;
2238 :
2239 0 : return rOptions;
2240 : }
2241 :
2242 0 : static bool boxHasLineLargerThan31(const SvxBoxItem& rBox)
2243 : {
2244 : return (
2245 0 : ( rBox.GetDistance( BOX_LINE_TOP ) / 20 ) > 31 ||
2246 0 : ( rBox.GetDistance( BOX_LINE_LEFT ) / 20 ) > 31 ||
2247 0 : ( rBox.GetDistance( BOX_LINE_BOTTOM ) / 20 ) > 31 ||
2248 0 : ( rBox.GetDistance( BOX_LINE_RIGHT ) / 20 ) > 31
2249 0 : );
2250 : }
2251 :
2252 0 : 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 0 : };
2267 0 : bool tagWritten = false;
2268 0 : const sal_uInt16* pBrd = aBorders;
2269 :
2270 0 : bool bExportDistanceFromPageEdge = false;
2271 0 : 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 0 : bExportDistanceFromPageEdge = true;
2278 : }
2279 :
2280 0 : bool bWriteInsideH = false;
2281 0 : bool bWriteInsideV = false;
2282 0 : for( int i = 0; i < 4; ++i, ++pBrd )
2283 : {
2284 0 : const SvxBorderLine* pLn = rBox.GetLine( *pBrd );
2285 0 : const table::BorderLine2 *aStyleProps = NULL;
2286 0 : if( rTableStyleConf.find( *pBrd ) != rTableStyleConf.end() )
2287 0 : aStyleProps = &rTableStyleConf[ *pBrd ];
2288 :
2289 0 : if (!tagWritten && rOptions.bWriteTag)
2290 : {
2291 0 : pSerializer->startElementNS( XML_w, rOptions.tag, FSEND );
2292 0 : tagWritten = true;
2293 : }
2294 :
2295 0 : bool bWriteShadow = false;
2296 0 : if (rOptions.aShadowLocation == SVX_SHADOW_NONE)
2297 : {
2298 : // The border has no shadow
2299 : }
2300 0 : 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 0 : 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 0 : sal_uInt16 nDist = 0;
2326 0 : if (rOptions.bWriteDistance)
2327 : {
2328 0 : if (bExportDistanceFromPageEdge)
2329 : {
2330 : // Export 'Distance from Page Edge'
2331 0 : if ( *pBrd == BOX_LINE_TOP)
2332 0 : nDist = pageMargins->nPageMarginTop - rBox.GetDistance( *pBrd );
2333 0 : else if ( *pBrd == BOX_LINE_LEFT)
2334 0 : nDist = pageMargins->nPageMarginLeft - rBox.GetDistance( *pBrd );
2335 0 : else if ( *pBrd == BOX_LINE_BOTTOM)
2336 0 : nDist = pageMargins->nPageMarginBottom - rBox.GetDistance( *pBrd );
2337 0 : else if ( *pBrd == BOX_LINE_RIGHT)
2338 0 : nDist = pageMargins->nPageMarginRight - rBox.GetDistance( *pBrd );
2339 : }
2340 : else
2341 : {
2342 : // Export 'Distance from text'
2343 0 : nDist = rBox.GetDistance( *pBrd );
2344 : }
2345 : }
2346 :
2347 0 : impl_borderLine( pSerializer, aXmlElements[i], pLn, nDist, bWriteShadow, aStyleProps );
2348 :
2349 : // When exporting default borders, we need to export these 2 attr
2350 0 : if ( rOptions.bWriteInsideHV) {
2351 0 : if ( i == 2 )
2352 0 : bWriteInsideH = true;
2353 0 : else if ( i == 3 )
2354 0 : bWriteInsideV = true;
2355 : }
2356 : }
2357 0 : if (bWriteInsideH)
2358 : {
2359 0 : const table::BorderLine2 *aStyleProps = NULL;
2360 0 : if( rTableStyleConf.find( BOX_LINE_BOTTOM ) != rTableStyleConf.end() )
2361 0 : aStyleProps = &rTableStyleConf[ BOX_LINE_BOTTOM ];
2362 0 : impl_borderLine( pSerializer, XML_insideH, rBox.GetLine(BOX_LINE_BOTTOM), 0, false, aStyleProps );
2363 : }
2364 0 : if (bWriteInsideV)
2365 : {
2366 0 : const table::BorderLine2 *aStyleProps = NULL;
2367 0 : if( rTableStyleConf.find( BOX_LINE_RIGHT ) != rTableStyleConf.end() )
2368 0 : aStyleProps = &rTableStyleConf[ BOX_LINE_RIGHT ];
2369 0 : impl_borderLine( pSerializer, XML_insideV, rBox.GetLine(BOX_LINE_RIGHT), 0, false, aStyleProps );
2370 : }
2371 0 : if (tagWritten && rOptions.bWriteTag) {
2372 0 : pSerializer->endElementNS( XML_w, rOptions.tag );
2373 : }
2374 0 : }
2375 :
2376 0 : 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 0 : };
2390 0 : bool tagWritten = false;
2391 0 : const sal_uInt16* pBrd = aBorders;
2392 0 : for( int i = 0; i < 4; ++i, ++pBrd )
2393 : {
2394 0 : sal_Int32 nDist = sal_Int32( rBox.GetDistance( *pBrd ) );
2395 :
2396 0 : 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 0 : const SvxBorderLine* pLn = rBox.GetLine( *pBrd );
2401 0 : if (pLn)
2402 0 : nDist -= pLn->GetWidth() * 0.5;
2403 : }
2404 :
2405 0 : if (pDefaultMargins)
2406 : {
2407 : // Skip output if cell margin == table default margin
2408 0 : if (sal_Int32( pDefaultMargins->GetDistance( *pBrd ) ) == nDist)
2409 0 : continue;
2410 : }
2411 :
2412 0 : if (!tagWritten) {
2413 0 : pSerializer->startElementNS( XML_w, tag, FSEND );
2414 0 : tagWritten = true;
2415 : }
2416 0 : pSerializer->singleElementNS( XML_w, aXmlElements[i],
2417 : FSNS( XML_w, XML_w ), OString::number( nDist ).getStr( ),
2418 : FSNS( XML_w, XML_type ), "dxa",
2419 0 : FSEND );
2420 : }
2421 0 : if (tagWritten) {
2422 0 : pSerializer->endElementNS( XML_w, tag );
2423 : }
2424 0 : }
2425 :
2426 0 : void DocxAttributeOutput::TableCellProperties( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2427 : {
2428 0 : m_pSerializer->startElementNS( XML_w, XML_tcPr, FSEND );
2429 :
2430 0 : const SwTableBox *pTblBox = pTableTextNodeInfoInner->getTableBox( );
2431 :
2432 0 : 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 0 : TableCellRedline( pTableTextNodeInfoInner );
2436 :
2437 : // Cell preferred width
2438 0 : SwTwips nWidth = GetGridCols( pTableTextNodeInfoInner )->at( pTableTextNodeInfoInner->getCell() );
2439 0 : if ( pTableTextNodeInfoInner->getCell() )
2440 0 : 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 0 : FSEND );
2445 :
2446 : // Horizontal spans
2447 0 : const SwWriteTableRows& aRows = m_pTableWrt->GetRows( );
2448 0 : SwWriteTableRow *pRow = aRows[ pTableTextNodeInfoInner->getRow( ) ];
2449 0 : sal_uInt32 nCell = pTableTextNodeInfoInner->getCell();
2450 0 : const SwWriteTableCells *tableCells = &pRow->GetCells();
2451 0 : if (nCell < tableCells->size() )
2452 : {
2453 0 : const SwWriteTableCell *pCell = &pRow->GetCells( )[ pTableTextNodeInfoInner->getCell( ) ];
2454 :
2455 0 : sal_uInt16 nColSpan = pCell->GetColSpan();
2456 0 : if ( nColSpan > 1 )
2457 : m_pSerializer->singleElementNS( XML_w, XML_gridSpan,
2458 : FSNS( XML_w, XML_val ), OString::number( nColSpan ).getStr(),
2459 0 : FSEND );
2460 : }
2461 :
2462 : // Vertical merges
2463 0 : long vSpan = pTblBox->getRowSpan( );
2464 0 : if ( vSpan > 1 )
2465 : {
2466 : m_pSerializer->singleElementNS( XML_w, XML_vMerge,
2467 : FSNS( XML_w, XML_val ), "restart",
2468 0 : FSEND );
2469 : }
2470 0 : else if ( vSpan < 0 )
2471 : {
2472 : m_pSerializer->singleElementNS( XML_w, XML_vMerge,
2473 : FSNS( XML_w, XML_val ), "continue",
2474 0 : FSEND );
2475 : }
2476 :
2477 0 : const SvxBoxItem& rBox = pTblBox->GetFrmFmt( )->GetBox( );
2478 0 : const SvxBoxItem& rDefaultBox = (*tableFirstCells.rbegin())->getTableBox( )->GetFrmFmt( )->GetBox( );
2479 : {
2480 : // The cell borders
2481 0 : impl_borders( m_pSerializer, rBox, lcl_getTableCellBorderOptions(bEcma), NULL, m_aTableStyleConf );
2482 : }
2483 :
2484 0 : TableBackgrounds( pTableTextNodeInfoInner );
2485 :
2486 : {
2487 : // Cell margins
2488 0 : impl_cellMargins( m_pSerializer, rBox, XML_tcMar, !bEcma, &rDefaultBox );
2489 : }
2490 :
2491 0 : TableVerticalCell( pTableTextNodeInfoInner );
2492 :
2493 0 : m_pSerializer->endElementNS( XML_w, XML_tcPr );
2494 0 : }
2495 :
2496 0 : void DocxAttributeOutput::InitTableHelper( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2497 : {
2498 0 : sal_uInt32 nPageSize = 0;
2499 0 : bool bRelBoxSize = false;
2500 :
2501 : // Create the SwWriteTable instance to use col spans (and maybe other infos)
2502 0 : GetTablePageSize( pTableTextNodeInfoInner.get(), nPageSize, bRelBoxSize );
2503 :
2504 0 : const SwTable* pTable = pTableTextNodeInfoInner->getTable( );
2505 0 : const SwFrmFmt *pFmt = pTable->GetFrmFmt( );
2506 0 : SwTwips nTblSz = pFmt->GetFrmSize( ).GetWidth( );
2507 :
2508 0 : const SwHTMLTableLayout *pLayout = pTable->GetHTMLTableLayout();
2509 0 : if( pLayout && pLayout->IsExportable() )
2510 0 : m_pTableWrt = new SwWriteTable( pLayout );
2511 : else
2512 : m_pTableWrt = new SwWriteTable( pTable->GetTabLines(), (sal_uInt16)nPageSize,
2513 0 : (sal_uInt16)nTblSz, false);
2514 0 : }
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 0 : void DocxAttributeOutput::switchHeaderFooter(bool isHeaderFooter, sal_Int32 index)
2524 : {
2525 0 : if( isHeaderFooter && index == 1)
2526 : {
2527 0 : m_oldTableReference->m_bTableCellOpen = m_tableReference->m_bTableCellOpen;
2528 0 : m_oldTableReference->m_nTableDepth = m_tableReference->m_nTableDepth;
2529 0 : m_oldTableReference->m_pOldTablepInner = m_tableReference->m_pOldTablepInner;
2530 0 : m_tableReference->m_bTableCellOpen = false;
2531 0 : m_tableReference->m_nTableDepth = 0;
2532 0 : m_pSectionInfo.reset();
2533 : }
2534 0 : else if( index == -1)
2535 : {
2536 0 : if (m_oldTableReference->m_pOldTablepInner)
2537 : {
2538 0 : *m_tableReference = *m_oldTableReference;
2539 :
2540 : //Reset the oldReference, after copying it back to the original.
2541 0 : m_oldTableReference->m_bTableCellOpen = false ;
2542 0 : m_oldTableReference->m_nTableDepth = 0;
2543 : }
2544 :
2545 : }
2546 : else
2547 : {
2548 0 : m_tableReference->m_bTableCellOpen = false;
2549 0 : m_tableReference->m_nTableDepth = 0;
2550 : }
2551 0 : }
2552 :
2553 0 : void DocxAttributeOutput::StartTable( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2554 : {
2555 0 : m_pSerializer->startElementNS( XML_w, XML_tbl, FSEND );
2556 :
2557 0 : tableFirstCells.push_back(pTableTextNodeInfoInner);
2558 :
2559 0 : InitTableHelper( pTableTextNodeInfoInner );
2560 0 : TableDefinition( pTableTextNodeInfoInner );
2561 0 : }
2562 :
2563 0 : void DocxAttributeOutput::EndTable()
2564 : {
2565 0 : m_pSerializer->endElementNS( XML_w, XML_tbl );
2566 :
2567 0 : if ( m_tableReference->m_nTableDepth > 0 )
2568 0 : --m_tableReference->m_nTableDepth;
2569 :
2570 0 : 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 0 : if( 0 != tableFirstCells.size() )
2576 0 : m_tableReference->m_bTableCellOpen = true;
2577 :
2578 : // Cleans the table helper
2579 0 : delete m_pTableWrt, m_pTableWrt = NULL;
2580 :
2581 0 : m_aTableStyleConf.clear();
2582 0 : }
2583 :
2584 0 : void DocxAttributeOutput::StartTableRow( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2585 : {
2586 0 : m_pSerializer->startElementNS( XML_w, XML_tr, FSEND );
2587 :
2588 : // Output the row properties
2589 0 : m_pSerializer->startElementNS( XML_w, XML_trPr, FSEND );
2590 :
2591 : // Header row: tblHeader
2592 0 : const SwTable *pTable = pTableTextNodeInfoInner->getTable( );
2593 0 : if ( pTable->GetRowsToRepeat( ) > pTableTextNodeInfoInner->getRow( ) )
2594 : m_pSerializer->singleElementNS( XML_w, XML_tblHeader,
2595 : FSNS( XML_w, XML_val ), "true",
2596 0 : FSEND );
2597 :
2598 0 : TableRowRedline( pTableTextNodeInfoInner );
2599 0 : TableHeight( pTableTextNodeInfoInner );
2600 0 : TableCanSplit( pTableTextNodeInfoInner );
2601 :
2602 0 : m_pSerializer->endElementNS( XML_w, XML_trPr );
2603 0 : }
2604 :
2605 0 : void DocxAttributeOutput::EndTableRow( )
2606 : {
2607 0 : m_pSerializer->endElementNS( XML_w, XML_tr );
2608 0 : }
2609 :
2610 0 : void DocxAttributeOutput::StartTableCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2611 : {
2612 0 : if ( !m_pTableWrt )
2613 0 : InitTableHelper( pTableTextNodeInfoInner );
2614 :
2615 0 : m_pSerializer->startElementNS( XML_w, XML_tc, FSEND );
2616 :
2617 : // Write the cell properties here
2618 0 : TableCellProperties( pTableTextNodeInfoInner );
2619 :
2620 0 : m_tableReference->m_bTableCellOpen = true;
2621 0 : }
2622 :
2623 0 : void DocxAttributeOutput::EndTableCell( )
2624 : {
2625 0 : m_pSerializer->endElementNS( XML_w, XML_tc );
2626 :
2627 0 : m_bBtLr = false;
2628 0 : m_tableReference->m_bTableCellOpen = false;
2629 0 : }
2630 :
2631 0 : void DocxAttributeOutput::TableInfoCell( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
2632 : {
2633 0 : }
2634 :
2635 0 : void DocxAttributeOutput::TableInfoRow( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfo*/ )
2636 : {
2637 0 : }
2638 :
2639 0 : void DocxAttributeOutput::TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2640 : {
2641 0 : bool bEcma = GetExport().GetFilter().getVersion( ) == oox::core::ECMA_DIALECT;
2642 :
2643 : // Write the table properties
2644 0 : 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 0 : sal_Int32 len = sizeof ( aOrder ) / sizeof( sal_Int32 );
2669 0 : uno::Sequence< sal_Int32 > aSeqOrder( len );
2670 0 : for ( sal_Int32 i = 0; i < len; i++ )
2671 0 : aSeqOrder[i] = aOrder[i];
2672 :
2673 0 : m_pSerializer->mark( aSeqOrder );
2674 :
2675 0 : sal_uInt32 nPageSize = 0;
2676 0 : const char* widthType = "dxa";
2677 0 : bool bRelBoxSize = false;
2678 :
2679 : // If actual width of table is relative it shoud export is as "auto".
2680 0 : const SwTable *pTable = pTableTextNodeInfoInner->getTable();
2681 0 : SwFrmFmt *pTblFmt = pTable->GetFrmFmt( );
2682 0 : uno::Reference<beans::XPropertySet> xPropertySet(SwXTextTables::GetObject(const_cast<SwFrmFmt&>(*pTable->GetFrmFmt( ))),uno::UNO_QUERY);
2683 0 : bool isWidthRelative = false;
2684 0 : xPropertySet->getPropertyValue("IsWidthRelative") >>= isWidthRelative;
2685 :
2686 0 : if(isWidthRelative)
2687 : {
2688 0 : nPageSize = 0;
2689 0 : widthType = "auto";
2690 : }
2691 : else
2692 : {
2693 : // Create the SwWriteTable instance to use col spans (and maybe other infos)
2694 0 : GetTablePageSize( pTableTextNodeInfoInner.get(), nPageSize, bRelBoxSize );
2695 0 : if(nPageSize == 0)
2696 0 : 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 0 : 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 0 : sw::util::HasItem<SfxGrabBagItem>( pTblFmt->GetAttrSet(), RES_FRMATR_GRABBAG )->GetGrabBag();
2708 :
2709 : // Extract properties from grab bag
2710 0 : std::map<OUString, com::sun::star::uno::Any>::iterator aGrabBagElement;
2711 0 : for( aGrabBagElement = aGrabBag.begin(); aGrabBagElement != aGrabBag.end(); ++aGrabBagElement )
2712 : {
2713 0 : if( aGrabBagElement->first == "TableStyleName")
2714 : {
2715 0 : 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 0 : FSEND );
2719 : }
2720 0 : else if( aGrabBagElement->first == "TableStyleTopBorder" )
2721 0 : m_aTableStyleConf[ BOX_LINE_TOP ] = aGrabBagElement->second.get<table::BorderLine2>();
2722 0 : else if( aGrabBagElement->first == "TableStyleBottomBorder" )
2723 0 : m_aTableStyleConf[ BOX_LINE_BOTTOM ] = aGrabBagElement->second.get<table::BorderLine2>();
2724 0 : else if( aGrabBagElement->first == "TableStyleLeftBorder" )
2725 0 : m_aTableStyleConf[ BOX_LINE_LEFT ] = aGrabBagElement->second.get<table::BorderLine2>();
2726 0 : else if( aGrabBagElement->first == "TableStyleRightBorder" )
2727 0 : m_aTableStyleConf[ BOX_LINE_RIGHT ] = aGrabBagElement->second.get<table::BorderLine2>();
2728 : }
2729 :
2730 : // Output the table alignement
2731 : const char* pJcVal;
2732 0 : sal_Int32 nIndent = 0;
2733 0 : switch ( pTblFmt->GetHoriOrient( ).GetHoriOrient( ) )
2734 : {
2735 : case text::HoriOrientation::CENTER:
2736 0 : pJcVal = "center";
2737 0 : 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 0 : if ( bEcma )
2749 0 : pJcVal = "left";
2750 : else
2751 0 : pJcVal = "start";
2752 0 : 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 0 : if (m_tableReference->m_nTableDepth == 0)
2758 : {
2759 0 : const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
2760 0 : const SwFrmFmt * pFrmFmt = pTabBox->GetFrmFmt();
2761 0 : nIndent += sal_Int32( pFrmFmt->GetBox( ).GetDistance( BOX_LINE_LEFT ) );
2762 : }
2763 0 : break;
2764 : }
2765 : }
2766 : m_pSerializer->singleElementNS( XML_w, XML_jc,
2767 : FSNS( XML_w, XML_val ), pJcVal,
2768 0 : FSEND );
2769 :
2770 : // Output the table borders
2771 0 : TableDefaultBorders( pTableTextNodeInfoInner );
2772 :
2773 : // Output the default cell margins
2774 0 : TableDefaultCellMargins( pTableTextNodeInfoInner );
2775 :
2776 0 : 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 0 : FSEND );
2783 :
2784 : // Merge the marks for the ordered elements
2785 0 : m_pSerializer->mergeTopMarks( );
2786 :
2787 0 : m_pSerializer->endElementNS( XML_w, XML_tblPr );
2788 :
2789 : // Write the table grid infos
2790 0 : m_pSerializer->startElementNS( XML_w, XML_tblGrid, FSEND );
2791 0 : sal_Int32 nPrv = 0;
2792 0 : ww8::WidthsPtr pColumnWidths = GetColumnWidths( pTableTextNodeInfoInner );
2793 0 : for ( ww8::Widths::const_iterator it = pColumnWidths->begin(); it != pColumnWidths->end(); ++it )
2794 : {
2795 0 : 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 0 : FSEND );
2799 0 : nPrv = sal_Int32( *it );
2800 : }
2801 :
2802 0 : m_pSerializer->endElementNS( XML_w, XML_tblGrid );
2803 0 : }
2804 :
2805 0 : void DocxAttributeOutput::TableDefaultBorders( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2806 : {
2807 0 : const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
2808 0 : const SwFrmFmt * pFrmFmt = pTabBox->GetFrmFmt();
2809 :
2810 0 : bool bEcma = GetExport().GetFilter().getVersion( ) == oox::core::ECMA_DIALECT;
2811 :
2812 : // the defaults of the table are taken from the top-left cell
2813 0 : impl_borders( m_pSerializer, pFrmFmt->GetBox( ), lcl_getTableDefaultBorderOptions(bEcma), NULL, m_aTableStyleConf );
2814 0 : }
2815 :
2816 0 : void DocxAttributeOutput::TableDefaultCellMargins( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2817 : {
2818 0 : const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
2819 0 : const SwFrmFmt * pFrmFmt = pTabBox->GetFrmFmt();
2820 0 : const SvxBoxItem& rBox = pFrmFmt->GetBox( );
2821 0 : const bool bEcma = GetExport().GetFilter().getVersion( ) == oox::core::ECMA_DIALECT;
2822 :
2823 0 : impl_cellMargins(m_pSerializer, rBox, XML_tblCellMar, !bEcma);
2824 0 : }
2825 :
2826 0 : void DocxAttributeOutput::TableBackgrounds( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2827 : {
2828 0 : const SwTableBox *pTblBox = pTableTextNodeInfoInner->getTableBox( );
2829 0 : const SwFrmFmt *pFmt = pTblBox->GetFrmFmt( );
2830 :
2831 0 : const SvxBrushItem *aColorProp = sw::util::HasItem<SvxBrushItem>( pFmt->GetAttrSet(), RES_BACKGROUND );
2832 0 : Color aColor = aColorProp ? aColorProp->GetColor() : COL_AUTO;
2833 0 : OString sColor = msfilter::util::ConvertColor( aColor );
2834 :
2835 : std::map<OUString, com::sun::star::uno::Any> aGrabBag =
2836 0 : sw::util::HasItem<SfxGrabBagItem>( pFmt->GetAttrSet(), RES_FRMATR_GRABBAG )->GetGrabBag();
2837 :
2838 0 : OString sOriginalColor;
2839 0 : std::map<OUString, com::sun::star::uno::Any>::iterator aGrabBagElement = aGrabBag.find("fill");
2840 0 : if( aGrabBagElement != aGrabBag.end() )
2841 0 : sOriginalColor = OUStringToOString( aGrabBagElement->second.get<OUString>(), RTL_TEXTENCODING_UTF8 );
2842 :
2843 0 : 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 0 : FSEND );
2850 : }
2851 : else
2852 : {
2853 0 : ::sax_fastparser::FastAttributeList* aAttrList = NULL;
2854 0 : AddToAttrList( aAttrList, FSNS( XML_w, XML_fill ), sColor.getStr() );
2855 :
2856 0 : for( aGrabBagElement = aGrabBag.begin(); aGrabBagElement != aGrabBag.end(); ++aGrabBagElement )
2857 : {
2858 0 : OString sValue = OUStringToOString( aGrabBagElement->second.get<OUString>(), RTL_TEXTENCODING_UTF8 );
2859 0 : if( aGrabBagElement->first == "themeFill")
2860 0 : AddToAttrList( aAttrList, FSNS( XML_w, XML_themeFill ), sValue.getStr() );
2861 0 : else if( aGrabBagElement->first == "themeFillTint")
2862 0 : AddToAttrList( aAttrList, FSNS( XML_w, XML_themeFillTint ), sValue.getStr() );
2863 0 : else if( aGrabBagElement->first == "themeFillShade")
2864 0 : AddToAttrList( aAttrList, FSNS( XML_w, XML_themeFillShade ), sValue.getStr() );
2865 0 : else if( aGrabBagElement->first == "color")
2866 0 : AddToAttrList( aAttrList, FSNS( XML_w, XML_color ), sValue.getStr() );
2867 0 : else if( aGrabBagElement->first == "val")
2868 0 : AddToAttrList( aAttrList, FSNS( XML_w, XML_val ), sValue.getStr() );
2869 0 : }
2870 : m_pSerializer->singleElementNS( XML_w, XML_shd,
2871 0 : XFastAttributeListRef( aAttrList ) );
2872 0 : }
2873 0 : }
2874 :
2875 0 : void DocxAttributeOutput::TableRowRedline( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2876 : {
2877 0 : const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
2878 0 : const SwTableLine * pTabLine = pTabBox->GetUpper();
2879 :
2880 : // search next Redline
2881 0 : const SwExtraRedlineTbl& aExtraRedlineTbl = m_rExport.pDoc->GetExtraRedlineTbl();
2882 0 : for(sal_uInt16 nCurRedlinePos = 0; nCurRedlinePos < aExtraRedlineTbl.GetSize(); ++nCurRedlinePos )
2883 : {
2884 0 : SwExtraRedline* pExtraRedline = aExtraRedlineTbl.GetRedline(nCurRedlinePos);
2885 0 : const SwTableRowRedline* pTableRowRedline = dynamic_cast<const SwTableRowRedline*>(pExtraRedline);
2886 0 : const SwTableLine *pRedTabLine = pTableRowRedline ? &pTableRowRedline->GetTableLine() : NULL;
2887 0 : if (pRedTabLine == pTabLine)
2888 : {
2889 : // Redline for this table row
2890 0 : const SwRedlineData& aRedlineData = pTableRowRedline->GetRedlineData();
2891 0 : sal_uInt16 nRedlineType = aRedlineData.GetType();
2892 0 : switch (nRedlineType)
2893 : {
2894 : case nsRedlineType_t::REDLINE_TABLE_ROW_INSERT:
2895 : case nsRedlineType_t::REDLINE_TABLE_ROW_DELETE:
2896 : {
2897 0 : OString aId( OString::number( m_nRedlineId++ ) );
2898 0 : const OUString &rAuthor( SW_MOD()->GetRedlineAuthor( aRedlineData.GetAuthor() ) );
2899 0 : OString aAuthor( OUStringToOString( rAuthor, RTL_TEXTENCODING_UTF8 ) );
2900 :
2901 0 : OString aDate( DateTimeToOString( aRedlineData.GetTimeStamp() ) );
2902 :
2903 0 : 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 0 : FSEND );
2909 0 : 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 0 : FSEND );
2915 : }
2916 0 : break;
2917 : };
2918 : }
2919 : }
2920 0 : }
2921 :
2922 0 : void DocxAttributeOutput::TableCellRedline( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2923 : {
2924 0 : const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
2925 :
2926 : // search next Redline
2927 0 : const SwExtraRedlineTbl& aExtraRedlineTbl = m_rExport.pDoc->GetExtraRedlineTbl();
2928 0 : for(sal_uInt16 nCurRedlinePos = 0; nCurRedlinePos < aExtraRedlineTbl.GetSize(); ++nCurRedlinePos )
2929 : {
2930 0 : SwExtraRedline* pExtraRedline = aExtraRedlineTbl.GetRedline(nCurRedlinePos);
2931 0 : const SwTableCellRedline* pTableCellRedline = dynamic_cast<const SwTableCellRedline*>(pExtraRedline);
2932 0 : const SwTableBox *pRedTabBox = pTableCellRedline ? &pTableCellRedline->GetTableBox() : NULL;
2933 0 : if (pRedTabBox == pTabBox)
2934 : {
2935 : // Redline for this table cell
2936 0 : const SwRedlineData& aRedlineData = pTableCellRedline->GetRedlineData();
2937 0 : sal_uInt16 nRedlineType = aRedlineData.GetType();
2938 0 : switch (nRedlineType)
2939 : {
2940 : case nsRedlineType_t::REDLINE_TABLE_CELL_INSERT:
2941 : case nsRedlineType_t::REDLINE_TABLE_CELL_DELETE:
2942 : {
2943 0 : OString aId( OString::number( m_nRedlineId++ ) );
2944 0 : const OUString &rAuthor( SW_MOD()->GetRedlineAuthor( aRedlineData.GetAuthor() ) );
2945 0 : OString aAuthor( OUStringToOString( rAuthor, RTL_TEXTENCODING_UTF8 ) );
2946 :
2947 0 : OString aDate( DateTimeToOString( aRedlineData.GetTimeStamp() ) );
2948 :
2949 0 : 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 0 : FSEND );
2955 0 : 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 0 : FSEND );
2961 : }
2962 0 : break;
2963 : };
2964 : }
2965 : }
2966 0 : }
2967 :
2968 0 : void DocxAttributeOutput::TableHeight( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2969 : {
2970 0 : const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
2971 0 : const SwTableLine * pTabLine = pTabBox->GetUpper();
2972 0 : const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();
2973 :
2974 0 : const SwFmtFrmSize& rLSz = pLineFmt->GetFrmSize();
2975 0 : if ( ATT_VAR_SIZE != rLSz.GetHeightSizeType() && rLSz.GetHeight() )
2976 : {
2977 0 : sal_Int32 nHeight = rLSz.GetHeight();
2978 0 : const char *pRule = NULL;
2979 :
2980 0 : switch ( rLSz.GetHeightSizeType() )
2981 : {
2982 0 : case ATT_FIX_SIZE: pRule = "exact"; break;
2983 0 : case ATT_MIN_SIZE: pRule = "atLeast"; break;
2984 0 : default: break;
2985 : }
2986 :
2987 0 : 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 0 : FSEND );
2992 : }
2993 0 : }
2994 :
2995 0 : void DocxAttributeOutput::TableCanSplit( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
2996 : {
2997 0 : const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
2998 0 : const SwTableLine * pTabLine = pTabBox->GetUpper();
2999 0 : const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();
3000 :
3001 0 : const SwFmtRowSplit& rSplittable = pLineFmt->GetRowSplit( );
3002 0 : 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 0 : if( !rSplittable.GetValue( ) )
3006 : m_pSerializer->singleElementNS( XML_w, XML_cantSplit,
3007 : FSNS( XML_w, XML_val ), pCantSplit,
3008 0 : FSEND );
3009 0 : }
3010 :
3011 0 : void DocxAttributeOutput::TableBidi( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
3012 : {
3013 0 : const SwTable * pTable = pTableTextNodeInfoInner->getTable();
3014 0 : const SwFrmFmt * pFrmFmt = pTable->GetFrmFmt();
3015 :
3016 0 : 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 0 : }
3023 :
3024 0 : void DocxAttributeOutput::TableVerticalCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
3025 : {
3026 0 : const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
3027 0 : const SwFrmFmt *pFrmFmt = pTabBox->GetFrmFmt( );
3028 :
3029 0 : 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 0 : 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 0 : SwPaM aPam(*pTabBox->GetSttNd(), 0);
3037 0 : aPam.GetPoint()->nNode++;
3038 0 : if (aPam.GetPoint()->nNode.GetNode().IsTxtNode())
3039 : {
3040 0 : const SwTxtNode& rTxtNode = (const SwTxtNode&)aPam.GetPoint()->nNode.GetNode();
3041 0 : if( const SwAttrSet* pAttrSet = rTxtNode.GetpSwAttrSet())
3042 : {
3043 0 : const SvxCharRotateItem& rCharRotate = pAttrSet->GetCharRotate();
3044 0 : if (rCharRotate.GetValue() == 900)
3045 : {
3046 0 : m_pSerializer->singleElementNS( XML_w, XML_textDirection, FSNS( XML_w, XML_val ), "btLr", FSEND );
3047 0 : m_bBtLr = true;
3048 : }
3049 : }
3050 0 : }
3051 : }
3052 :
3053 0 : const SwWriteTableRows& aRows = m_pTableWrt->GetRows( );
3054 0 : SwWriteTableRow *pRow = aRows[ pTableTextNodeInfoInner->getRow( ) ];
3055 0 : sal_uInt32 nCell = pTableTextNodeInfoInner->getCell();
3056 0 : const SwWriteTableCells *tableCells = &pRow->GetCells();
3057 0 : if (nCell < tableCells->size() )
3058 : {
3059 0 : const SwWriteTableCell *pCell = &pRow->GetCells( )[ pTableTextNodeInfoInner->getCell( ) ];
3060 0 : switch( pCell->GetVertOri())
3061 : {
3062 : case text::VertOrientation::TOP:
3063 0 : break;
3064 : case text::VertOrientation::CENTER:
3065 : m_pSerializer->singleElementNS( XML_w, XML_vAlign,
3066 0 : FSNS( XML_w, XML_val ), "center", FSEND );
3067 0 : break;
3068 : case text::VertOrientation::BOTTOM:
3069 : m_pSerializer->singleElementNS( XML_w, XML_vAlign,
3070 0 : FSNS( XML_w, XML_val ), "bottom", FSEND );
3071 0 : break;
3072 : }
3073 : }
3074 0 : }
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 0 : 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 0 : FinishTableRowCell( pNodeInfoInner, true );
3088 0 : }
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 0 : 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 0 : FSEND );
3115 :
3116 0 : DocDefaults();
3117 0 : LatentStyles();
3118 0 : }
3119 :
3120 0 : sal_Int32 DocxStringGetToken(DocxStringTokenMap const * pMap, const OUString& rName)
3121 : {
3122 0 : OString sName = OUStringToOString(rName, RTL_TEXTENCODING_UTF8);
3123 0 : while (pMap->pToken)
3124 : {
3125 0 : if (sName == pMap->pToken)
3126 0 : return pMap->nToken;
3127 0 : ++pMap;
3128 : }
3129 0 : 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 0 : void DocxAttributeOutput::LatentStyles()
3153 : {
3154 : // Do we have latent styles available?
3155 0 : uno::Reference<beans::XPropertySet> xPropertySet(m_rExport.pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW);
3156 0 : uno::Sequence<beans::PropertyValue> aInteropGrabBag;
3157 0 : xPropertySet->getPropertyValue("InteropGrabBag") >>= aInteropGrabBag;
3158 0 : uno::Sequence<beans::PropertyValue> aLatentStyles;
3159 0 : for (sal_Int32 i = 0; i < aInteropGrabBag.getLength(); ++i)
3160 : {
3161 0 : if (aInteropGrabBag[i].Name == "latentStyles")
3162 : {
3163 0 : aInteropGrabBag[i].Value >>= aLatentStyles;
3164 0 : break;
3165 : }
3166 : }
3167 0 : if (!aLatentStyles.getLength())
3168 0 : return;
3169 :
3170 : // Extract default attributes first.
3171 0 : sax_fastparser::FastAttributeList* pAttributeList = m_pSerializer->createAttrList();
3172 0 : uno::Sequence<beans::PropertyValue> aLsdExceptions;
3173 0 : for (sal_Int32 i = 0; i < aLatentStyles.getLength(); ++i)
3174 : {
3175 0 : if (sal_Int32 nToken = DocxStringGetToken(aDefaultTokens, aLatentStyles[i].Name))
3176 0 : pAttributeList->add(FSNS(XML_w, nToken), OUStringToOString(aLatentStyles[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8));
3177 0 : else if (aLatentStyles[i].Name == "lsdExceptions")
3178 0 : aLatentStyles[i].Value >>= aLsdExceptions;
3179 : }
3180 :
3181 0 : XFastAttributeListRef xAttributeList(pAttributeList);
3182 0 : m_pSerializer->startElementNS(XML_w, XML_latentStyles, xAttributeList);
3183 0 : pAttributeList = 0;
3184 :
3185 : // Then handle the exceptions.
3186 0 : for (sal_Int32 i = 0; i < aLsdExceptions.getLength(); ++i)
3187 : {
3188 0 : pAttributeList = m_pSerializer->createAttrList();
3189 :
3190 0 : uno::Sequence<beans::PropertyValue> aAttributes;
3191 0 : aLsdExceptions[i].Value >>= aAttributes;
3192 0 : for (sal_Int32 j = 0; j < aAttributes.getLength(); ++j)
3193 0 : if (sal_Int32 nToken = DocxStringGetToken(aExceptionTokens, aAttributes[j].Name))
3194 0 : pAttributeList->add(FSNS(XML_w, nToken), OUStringToOString(aAttributes[j].Value.get<OUString>(), RTL_TEXTENCODING_UTF8));
3195 :
3196 0 : xAttributeList = pAttributeList;
3197 0 : m_pSerializer->singleElementNS(XML_w, XML_lsdException, xAttributeList);
3198 0 : pAttributeList = 0;
3199 0 : }
3200 :
3201 0 : m_pSerializer->endElementNS(XML_w, XML_latentStyles);
3202 : }
3203 :
3204 : /// Should the font size we have written out as a default one?
3205 0 : bool lcl_isDefaultFontSize(const SvxFontHeightItem& rFontHeight, SwDoc* pDoc)
3206 : {
3207 0 : 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 0 : SwTxtFmtColl* pDefaultStyle = pDoc->GetTxtCollFromPool(RES_POOLCOLL_STANDARD);
3210 0 : if (pDefaultStyle)
3211 : {
3212 0 : const SfxPoolItem* pItem = 0;
3213 0 : if (pDefaultStyle->GetAttrSet().HasItem(RES_CHRATR_FONTSIZE, &pItem))
3214 0 : return static_cast<const SvxFontHeightItem*>(pItem)->GetHeight() != rFontHeight.GetHeight();
3215 : }
3216 0 : return bRet;
3217 : }
3218 :
3219 0 : void DocxAttributeOutput::OutputDefaultItem(const SfxPoolItem& rHt)
3220 : {
3221 0 : bool bMustWrite = true;
3222 0 : switch (rHt.Which())
3223 : {
3224 : case RES_CHRATR_CASEMAP:
3225 0 : bMustWrite = static_cast< const SvxCaseMapItem& >(rHt).GetCaseMap() != SVX_CASEMAP_NOT_MAPPED;
3226 0 : break;
3227 : case RES_CHRATR_COLOR:
3228 0 : bMustWrite = static_cast< const SvxColorItem& >(rHt).GetValue().GetColor() != COL_AUTO;
3229 0 : break;
3230 : case RES_CHRATR_CONTOUR:
3231 0 : bMustWrite = static_cast< const SvxContourItem& >(rHt).GetValue();
3232 0 : break;
3233 : case RES_CHRATR_CROSSEDOUT:
3234 0 : bMustWrite = static_cast< const SvxCrossedOutItem& >(rHt).GetStrikeout() != STRIKEOUT_NONE;
3235 0 : break;
3236 : case RES_CHRATR_ESCAPEMENT:
3237 0 : bMustWrite = static_cast< const SvxEscapementItem& >(rHt).GetEscapement() != SVX_ESCAPEMENT_OFF;
3238 0 : break;
3239 : case RES_CHRATR_FONT:
3240 0 : bMustWrite = true;
3241 0 : break;
3242 : case RES_CHRATR_FONTSIZE:
3243 0 : bMustWrite = lcl_isDefaultFontSize(static_cast< const SvxFontHeightItem& >(rHt), m_rExport.pDoc);
3244 0 : break;
3245 : case RES_CHRATR_KERNING:
3246 0 : bMustWrite = static_cast< const SvxKerningItem& >(rHt).GetValue() != 0;
3247 0 : break;
3248 : case RES_CHRATR_LANGUAGE:
3249 0 : bMustWrite = true;
3250 0 : break;
3251 : case RES_CHRATR_POSTURE:
3252 0 : bMustWrite = static_cast< const SvxPostureItem& >(rHt).GetPosture() != ITALIC_NONE;
3253 0 : break;
3254 : case RES_CHRATR_SHADOWED:
3255 0 : bMustWrite = static_cast< const SvxShadowedItem& >(rHt).GetValue();
3256 0 : break;
3257 : case RES_CHRATR_UNDERLINE:
3258 0 : bMustWrite = static_cast< const SvxUnderlineItem& >(rHt).GetLineStyle() != UNDERLINE_NONE;
3259 0 : break;
3260 : case RES_CHRATR_WEIGHT:
3261 0 : bMustWrite = static_cast< const SvxWeightItem& >(rHt).GetWeight() != WEIGHT_NORMAL;
3262 0 : break;
3263 : case RES_CHRATR_AUTOKERN:
3264 0 : bMustWrite = static_cast< const SvxAutoKernItem& >(rHt).GetValue();
3265 0 : break;
3266 : case RES_CHRATR_BLINK:
3267 0 : bMustWrite = static_cast< const SvxBlinkItem& >(rHt).GetValue();
3268 0 : break;
3269 : case RES_CHRATR_BACKGROUND:
3270 : {
3271 0 : const SvxBrushItem& rBrushItem = static_cast< const SvxBrushItem& >(rHt);
3272 0 : bMustWrite = (rBrushItem.GetColor() != COL_AUTO ||
3273 0 : rBrushItem.GetShadingValue() != sal_uInt32(ShadingPattern::CLEAR) ||
3274 0 : rBrushItem.GetGraphic() != NULL ||
3275 0 : rBrushItem.GetGraphicObject() != NULL);
3276 : }
3277 0 : break;
3278 :
3279 : case RES_CHRATR_CJK_FONT:
3280 0 : bMustWrite = true;
3281 0 : break;
3282 : case RES_CHRATR_CJK_FONTSIZE:
3283 0 : bMustWrite = false; // we have written it already as RES_CHRATR_FONTSIZE
3284 0 : break;
3285 : case RES_CHRATR_CJK_LANGUAGE:
3286 0 : bMustWrite = true;
3287 0 : break;
3288 : case RES_CHRATR_CJK_POSTURE:
3289 0 : bMustWrite = false; // we have written it already as RES_CHRATR_POSTURE
3290 0 : break;
3291 : case RES_CHRATR_CJK_WEIGHT:
3292 0 : bMustWrite = false; // we have written it already as RES_CHRATR_WEIGHT
3293 0 : break;
3294 :
3295 : case RES_CHRATR_CTL_FONT:
3296 0 : bMustWrite = true;
3297 0 : break;
3298 : case RES_CHRATR_CTL_FONTSIZE:
3299 0 : bMustWrite = static_cast< const SvxFontHeightItem& >(rHt).GetHeight() != 200; // see StyleSheetTable_Impl::StyleSheetTable_Impl() where we set this default
3300 0 : break;
3301 : case RES_CHRATR_CTL_LANGUAGE:
3302 0 : bMustWrite = true;
3303 0 : break;
3304 : case RES_CHRATR_CTL_POSTURE:
3305 0 : bMustWrite = static_cast< const SvxPostureItem& >(rHt).GetPosture() != ITALIC_NONE;
3306 0 : break;
3307 : case RES_CHRATR_CTL_WEIGHT:
3308 0 : bMustWrite = static_cast< const SvxWeightItem& >(rHt).GetWeight() != WEIGHT_NORMAL;
3309 0 : break;
3310 :
3311 : case RES_CHRATR_ROTATE:
3312 0 : bMustWrite = static_cast< const SvxCharRotateItem& >(rHt).GetValue() != 0;
3313 0 : break;
3314 : case RES_CHRATR_EMPHASIS_MARK:
3315 0 : bMustWrite = static_cast< const SvxEmphasisMarkItem& >(rHt).GetValue() != EMPHASISMARK_NONE;
3316 0 : break;
3317 : case RES_CHRATR_TWO_LINES:
3318 0 : bMustWrite = static_cast< const SvxTwoLinesItem& >(rHt).GetValue();
3319 0 : break;
3320 : case RES_CHRATR_SCALEW:
3321 0 : bMustWrite = static_cast< const SvxCharScaleWidthItem& >(rHt).GetValue() != 100;
3322 0 : break;
3323 : case RES_CHRATR_RELIEF:
3324 0 : bMustWrite = static_cast< const SvxCharReliefItem& >(rHt).GetValue() != RELIEF_NONE;
3325 0 : break;
3326 : case RES_CHRATR_HIDDEN:
3327 0 : bMustWrite = static_cast< const SvxCharHiddenItem& >(rHt).GetValue();
3328 0 : break;
3329 : case RES_CHRATR_BOX:
3330 : {
3331 0 : const SvxBoxItem& rBoxItem = static_cast< const SvxBoxItem& >(rHt);
3332 0 : bMustWrite = rBoxItem.GetTop() || rBoxItem.GetLeft() ||
3333 0 : rBoxItem.GetBottom() || rBoxItem.GetRight() ||
3334 0 : rBoxItem.GetDistance();
3335 : }
3336 0 : break;
3337 : case RES_CHRATR_HIGHLIGHT:
3338 : {
3339 0 : const SvxBrushItem& rBrushItem = static_cast< const SvxBrushItem& >(rHt);
3340 0 : bMustWrite = (rBrushItem.GetColor() != COL_AUTO ||
3341 0 : rBrushItem.GetShadingValue() != sal_uInt32(ShadingPattern::CLEAR) ||
3342 0 : rBrushItem.GetGraphic() != NULL ||
3343 0 : rBrushItem.GetGraphicObject() != NULL);
3344 : }
3345 0 : break;
3346 :
3347 : case RES_PARATR_LINESPACING:
3348 0 : bMustWrite = static_cast< const SvxLineSpacingItem& >(rHt).GetInterLineSpaceRule() != SVX_INTER_LINE_SPACE_OFF;
3349 0 : break;
3350 : case RES_PARATR_ADJUST:
3351 0 : bMustWrite = static_cast< const SvxAdjustItem& >(rHt).GetAdjust() != SVX_ADJUST_LEFT;
3352 0 : break;
3353 : case RES_PARATR_SPLIT:
3354 0 : bMustWrite = !static_cast< const SvxFmtSplitItem& >(rHt).GetValue();
3355 0 : break;
3356 : case RES_PARATR_WIDOWS:
3357 0 : bMustWrite = static_cast< const SvxWidowsItem& >(rHt).GetValue();
3358 0 : break;
3359 : case RES_PARATR_TABSTOP:
3360 0 : bMustWrite = static_cast< const SvxTabStopItem& >(rHt).Count() != 0;
3361 0 : break;
3362 : case RES_PARATR_HYPHENZONE:
3363 0 : bMustWrite = static_cast< const SvxHyphenZoneItem& >(rHt).IsHyphen();
3364 0 : break;
3365 : case RES_PARATR_NUMRULE:
3366 0 : bMustWrite = !static_cast< const SwNumRuleItem& >(rHt).GetValue().isEmpty();
3367 0 : break;
3368 : case RES_PARATR_SCRIPTSPACE:
3369 0 : bMustWrite = !static_cast< const SfxBoolItem& >(rHt).GetValue();
3370 0 : break;
3371 : case RES_PARATR_HANGINGPUNCTUATION:
3372 0 : bMustWrite = !static_cast< const SfxBoolItem& >(rHt).GetValue();
3373 0 : break;
3374 : case RES_PARATR_FORBIDDEN_RULES:
3375 0 : bMustWrite = !static_cast< const SfxBoolItem& >(rHt).GetValue();
3376 0 : break;
3377 : case RES_PARATR_VERTALIGN:
3378 0 : bMustWrite = static_cast< const SvxParaVertAlignItem& >(rHt).GetValue() != SvxParaVertAlignItem::AUTOMATIC;
3379 0 : break;
3380 : case RES_PARATR_SNAPTOGRID:
3381 0 : bMustWrite = !static_cast< const SvxParaGridItem& >(rHt).GetValue();
3382 0 : break;
3383 : case RES_CHRATR_GRABBAG:
3384 0 : bMustWrite = true;
3385 0 : break;
3386 :
3387 : default:
3388 : SAL_INFO("sw.ww8", "Unhandled SfxPoolItem with id " << rHt.Which() );
3389 0 : break;
3390 : }
3391 :
3392 0 : if (bMustWrite)
3393 0 : OutputItem(rHt);
3394 0 : }
3395 :
3396 0 : void DocxAttributeOutput::DocDefaults( )
3397 : {
3398 : // Write the '<w:docDefaults>' section here
3399 0 : m_pSerializer->startElementNS(XML_w, XML_docDefaults, FSEND);
3400 :
3401 : // Output the default run properties
3402 0 : m_pSerializer->startElementNS(XML_w, XML_rPrDefault, FSEND);
3403 :
3404 0 : StartStyleProperties(false, 0);
3405 :
3406 0 : for (int i = int(RES_CHRATR_BEGIN); i < int(RES_CHRATR_END); ++i)
3407 0 : OutputDefaultItem(m_rExport.pDoc->GetDefault(i));
3408 :
3409 0 : EndStyleProperties(false);
3410 :
3411 0 : m_pSerializer->endElementNS(XML_w, XML_rPrDefault);
3412 :
3413 : // Output the default paragraph properties
3414 0 : m_pSerializer->startElementNS(XML_w, XML_pPrDefault, FSEND);
3415 :
3416 0 : StartStyleProperties(true, 0);
3417 :
3418 0 : for (int i = int(RES_PARATR_BEGIN); i < int(RES_PARATR_END); ++i)
3419 0 : OutputDefaultItem(m_rExport.pDoc->GetDefault(i));
3420 :
3421 0 : EndStyleProperties(true);
3422 :
3423 0 : m_pSerializer->endElementNS(XML_w, XML_pPrDefault);
3424 :
3425 0 : m_pSerializer->endElementNS(XML_w, XML_docDefaults);
3426 0 : }
3427 :
3428 0 : 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 0 : sal_uInt16 nCountStylesToWrite = MSWORD_MAX_STYLES_LIMIT - nNumberOfStyles;
3435 0 : m_pTableStyleExport->TableStyles(nCountStylesToWrite);
3436 0 : m_pSerializer->endElementNS( XML_w, XML_styles );
3437 0 : }
3438 :
3439 0 : 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 0 : }
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 0 : void DocxAttributeOutput::WriteSrcRect(const SdrObject* pSdrObj )
3453 : {
3454 0 : uno::Reference< drawing::XShape > xShape( ((SdrObject*)pSdrObj)->getUnoShape(), uno::UNO_QUERY );
3455 0 : uno::Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
3456 :
3457 0 : OUString sUrl;
3458 0 : xPropSet->getPropertyValue("GraphicURL") >>= sUrl;
3459 0 : Size aOriginalSize( GraphicObject::CreateGraphicObjectFromURL( sUrl ).GetPrefSize() );
3460 :
3461 0 : ::com::sun::star::text::GraphicCrop aGraphicCropStruct;
3462 0 : xPropSet->getPropertyValue( "GraphicCrop" ) >>= aGraphicCropStruct;
3463 :
3464 0 : const MapMode aMap100mm( MAP_100TH_MM );
3465 0 : const MapMode& mapMode = GraphicObject::CreateGraphicObjectFromURL( sUrl ).GetPrefMapMode();
3466 0 : if( mapMode.GetMapUnit() == MAP_PIXEL )
3467 : {
3468 0 : aOriginalSize = Application::GetDefaultDevice()->PixelToLogic(aOriginalSize, aMap100mm );
3469 : }
3470 :
3471 0 : if ( (0 != aGraphicCropStruct.Left) || (0 != aGraphicCropStruct.Top) || (0 != aGraphicCropStruct.Right) || (0 != aGraphicCropStruct.Bottom) )
3472 : {
3473 0 : double widthMultiplier = 100000.0/aOriginalSize.Width();
3474 0 : double heightMultiplier = 100000.0/aOriginalSize.Height();
3475 :
3476 0 : double left = aGraphicCropStruct.Left * widthMultiplier;
3477 0 : double right = aGraphicCropStruct.Right * widthMultiplier;
3478 0 : double top = aGraphicCropStruct.Top * heightMultiplier;
3479 0 : 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 0 : FSEND );
3487 0 : }
3488 0 : }
3489 :
3490 0 : 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 0 : const SwFrmFmt* pFrmFmt = pGrfNode ? pGrfNode->GetFlyFmt() : pOLEFrmFmt;
3496 : // create the relation ID
3497 0 : OString aRelId;
3498 : sal_Int32 nImageType;
3499 0 : 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 0 : const Graphic* pGraphic = 0;
3517 0 : if (pGrfNode)
3518 0 : pGraphic = &const_cast< Graphic& >( pGrfNode->GetGrf() );
3519 : else
3520 0 : pGraphic = pOLENode->GetGraphic();
3521 :
3522 0 : if (m_aRelIdCache.find(pGraphic) != m_aRelIdCache.end())
3523 : // We already have a RelId for this Graphic.
3524 0 : aRelId = m_aRelIdCache[pGraphic];
3525 : else
3526 : {
3527 : // Not in cache, then need to write it.
3528 0 : m_rDrawingML.SetFS( m_pSerializer ); // to be sure that we write to the right stream
3529 0 : OUString aImageId = m_rDrawingML.WriteImage( *pGraphic );
3530 :
3531 0 : aRelId = OUStringToOString( aImageId, RTL_TEXTENCODING_UTF8 );
3532 0 : m_aRelIdCache[pGraphic] = aRelId;
3533 : }
3534 :
3535 0 : nImageType = XML_embed;
3536 : }
3537 :
3538 0 : m_rExport.SdrExporter().startDMLAnchorInline(pFrmFmt, rSize);
3539 :
3540 : // picture description (used for pic:cNvPr later too)
3541 0 : ::sax_fastparser::FastAttributeList* docPrattrList = m_pSerializer->createAttrList();
3542 0 : docPrattrList->add( XML_id, OString::number( m_anchorId++).getStr());
3543 0 : docPrattrList->add( XML_name, "Picture" );
3544 0 : docPrattrList->add( XML_descr, OUStringToOString( pGrfNode ? pGrfNode->GetDescription() : pOLEFrmFmt->GetObjDescription(), RTL_TEXTENCODING_UTF8 ).getStr());
3545 0 : if( GetExport().GetFilter().getVersion( ) != oox::core::ECMA_DIALECT )
3546 0 : docPrattrList->add( XML_title, OUStringToOString( pGrfNode ? pGrfNode->GetTitle() : pOLEFrmFmt->GetObjTitle(), RTL_TEXTENCODING_UTF8 ).getStr());
3547 0 : XFastAttributeListRef docPrAttrListRef( docPrattrList );
3548 0 : 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 0 : m_pSerializer->endElementNS( XML_wp, XML_docPr );
3555 :
3556 : m_pSerializer->startElementNS( XML_wp, XML_cNvGraphicFramePr,
3557 0 : 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 0 : FSEND );
3563 0 : 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 0 : FSEND );
3568 : m_pSerializer->startElementNS( XML_a, XML_graphicData,
3569 : XML_uri, "http://schemas.openxmlformats.org/drawingml/2006/picture",
3570 0 : FSEND );
3571 :
3572 : m_pSerializer->startElementNS( XML_pic, XML_pic,
3573 : FSNS( XML_xmlns, XML_pic ), "http://schemas.openxmlformats.org/drawingml/2006/picture",
3574 0 : FSEND );
3575 :
3576 : m_pSerializer->startElementNS( XML_pic, XML_nvPicPr,
3577 0 : FSEND );
3578 : // It seems pic:cNvpr and wp:docPr are pretty much the same thing with the same attributes
3579 0 : 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 0 : m_pSerializer->endElementNS( XML_pic, XML_cNvPr );
3586 :
3587 : m_pSerializer->startElementNS( XML_pic, XML_cNvPicPr,
3588 0 : FSEND );
3589 : // TODO change aspect?
3590 : m_pSerializer->singleElementNS( XML_a, XML_picLocks,
3591 : XML_noChangeAspect, "1", XML_noChangeArrowheads, "1",
3592 0 : FSEND );
3593 0 : m_pSerializer->endElementNS( XML_pic, XML_cNvPicPr );
3594 0 : m_pSerializer->endElementNS( XML_pic, XML_nvPicPr );
3595 :
3596 : // the actual picture
3597 : m_pSerializer->startElementNS( XML_pic, XML_blipFill,
3598 0 : 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 0 : if ( aRelId.isEmpty() )
3607 : m_pSerializer->singleElementNS( XML_a, XML_blip,
3608 0 : FSEND );
3609 : else
3610 : m_pSerializer->singleElementNS( XML_a, XML_blip,
3611 : FSNS( XML_r, nImageType ), aRelId.getStr(),
3612 0 : FSEND );
3613 :
3614 0 : if (pSdrObj){
3615 0 : WriteSrcRect(pSdrObj);
3616 : }
3617 :
3618 : m_pSerializer->startElementNS( XML_a, XML_stretch,
3619 0 : FSEND );
3620 : m_pSerializer->singleElementNS( XML_a, XML_fillRect,
3621 0 : FSEND );
3622 0 : m_pSerializer->endElementNS( XML_a, XML_stretch );
3623 0 : 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 0 : FSEND );
3629 : m_pSerializer->startElementNS( XML_a, XML_xfrm,
3630 0 : FSEND );
3631 : m_pSerializer->singleElementNS( XML_a, XML_off,
3632 : XML_x, "0", XML_y, "0",
3633 0 : FSEND );
3634 0 : OString aWidth( OString::number( TwipsToEMU( rSize.Width() ) ) );
3635 0 : 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 0 : FSEND );
3640 0 : m_pSerializer->endElementNS( XML_a, XML_xfrm );
3641 : m_pSerializer->startElementNS( XML_a, XML_prstGeom,
3642 : XML_prst, "rect",
3643 0 : FSEND );
3644 : m_pSerializer->singleElementNS( XML_a, XML_avLst,
3645 0 : FSEND );
3646 0 : m_pSerializer->endElementNS( XML_a, XML_prstGeom );
3647 : m_pSerializer->singleElementNS( XML_a, XML_noFill,
3648 0 : FSEND );
3649 : m_pSerializer->startElementNS( XML_a, XML_ln,
3650 : XML_w, "9525",
3651 0 : FSEND );
3652 : m_pSerializer->singleElementNS( XML_a, XML_noFill,
3653 0 : FSEND );
3654 : m_pSerializer->singleElementNS( XML_a, XML_miter,
3655 : XML_lim, "800000",
3656 0 : FSEND );
3657 : m_pSerializer->singleElementNS( XML_a, XML_headEnd,
3658 0 : FSEND );
3659 : m_pSerializer->singleElementNS( XML_a, XML_tailEnd,
3660 0 : FSEND );
3661 0 : m_pSerializer->endElementNS( XML_a, XML_ln );
3662 :
3663 0 : m_rExport.SdrExporter().writeDMLEffectLst(*pFrmFmt);
3664 :
3665 0 : m_pSerializer->endElementNS( XML_pic, XML_spPr );
3666 :
3667 0 : m_pSerializer->endElementNS( XML_pic, XML_pic );
3668 :
3669 0 : m_pSerializer->endElementNS( XML_a, XML_graphicData );
3670 0 : m_pSerializer->endElementNS( XML_a, XML_graphic );
3671 0 : m_rExport.SdrExporter().endDMLAnchorInline(pFrmFmt);
3672 0 : }
3673 :
3674 0 : void DocxAttributeOutput::WriteOLE2Obj( const SdrObject* pSdrObj, SwOLENode& rOLENode, const Size& rSize, const SwFlyFrmFmt* pFlyFrmFmt )
3675 : {
3676 0 : if( WriteOLEChart( pSdrObj, rSize ))
3677 0 : return;
3678 0 : if( WriteOLEMath( pSdrObj, rOLENode, rSize ))
3679 0 : return;
3680 0 : if( PostponeOLE( pSdrObj, rOLENode, rSize, pFlyFrmFmt ))
3681 0 : 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 0 : bool DocxAttributeOutput::WriteOLEChart( const SdrObject* pSdrObj, const Size& rSize )
3691 : {
3692 0 : uno::Reference< chart2::XChartDocument > xChartDoc;
3693 0 : uno::Reference< drawing::XShape > xShape( ((SdrObject*)pSdrObj)->getUnoShape(), uno::UNO_QUERY );
3694 0 : if( xShape.is() )
3695 : {
3696 0 : uno::Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
3697 0 : if( xPropSet.is() )
3698 0 : xChartDoc.set( xPropSet->getPropertyValue( "Model" ), uno::UNO_QUERY );
3699 : }
3700 :
3701 0 : if( xChartDoc.is() )
3702 : {
3703 0 : m_postponedChart = pSdrObj;
3704 0 : m_postponedChartSize = rSize;
3705 0 : return true;
3706 : }
3707 0 : return false;
3708 : }
3709 :
3710 : /*
3711 : * Write chart hierarchy in w:drawing after end element of w:rPr tag.
3712 : */
3713 0 : void DocxAttributeOutput::WritePostponedChart()
3714 : {
3715 0 : if(m_postponedChart == NULL)
3716 0 : return;
3717 0 : uno::Reference< chart2::XChartDocument > xChartDoc;
3718 0 : uno::Reference< drawing::XShape > xShape( ((SdrObject*)m_postponedChart)->getUnoShape(), uno::UNO_QUERY );
3719 0 : if( xShape.is() )
3720 : {
3721 0 : uno::Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
3722 0 : if( xPropSet.is() )
3723 0 : xChartDoc.set( xPropSet->getPropertyValue( "Model" ), uno::UNO_QUERY );
3724 : }
3725 :
3726 0 : if( xChartDoc.is() )
3727 : {
3728 : OSL_TRACE("DocxAttributeOutput::WriteOLE2Obj: export chart ");
3729 : m_pSerializer->startElementNS( XML_w, XML_drawing,
3730 0 : FSEND );
3731 : m_pSerializer->startElementNS( XML_wp, XML_inline,
3732 : XML_distT, "0", XML_distB, "0", XML_distL, "0", XML_distR, "0",
3733 0 : FSEND );
3734 :
3735 0 : OString aWidth( OString::number( TwipsToEMU( m_postponedChartSize.Width() ) ) );
3736 0 : 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 0 : 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 0 : FSEND );
3745 :
3746 0 : OUString sName("Object 1");
3747 0 : uno::Reference< container::XNamed > xNamed( xShape, uno::UNO_QUERY );
3748 0 : if( xNamed.is() )
3749 0 : 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 0 : FSEND );
3760 :
3761 : m_pSerializer->singleElementNS( XML_wp, XML_cNvGraphicFramePr,
3762 0 : FSEND );
3763 :
3764 : m_pSerializer->startElementNS( XML_a, XML_graphic,
3765 : FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
3766 0 : FSEND );
3767 :
3768 : m_pSerializer->startElementNS( XML_a, XML_graphicData,
3769 : XML_uri, "http://schemas.openxmlformats.org/drawingml/2006/chart",
3770 0 : FSEND );
3771 :
3772 0 : OString aRelId;
3773 : static sal_Int32 nChartCount = 0;
3774 0 : nChartCount++;
3775 0 : uno::Reference< frame::XModel > xModel( xChartDoc, uno::UNO_QUERY );
3776 0 : 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 0 : FSEND );
3783 :
3784 0 : m_pSerializer->endElementNS( XML_a, XML_graphicData );
3785 0 : m_pSerializer->endElementNS( XML_a, XML_graphic );
3786 0 : m_pSerializer->endElementNS( XML_wp, XML_inline );
3787 0 : m_pSerializer->endElementNS( XML_w, XML_drawing );
3788 :
3789 : }
3790 0 : m_postponedChart = NULL;
3791 0 : return;
3792 : }
3793 :
3794 0 : bool DocxAttributeOutput::WriteOLEMath( const SdrObject*, const SwOLENode& rOLENode, const Size& )
3795 : {
3796 0 : uno::Reference < embed::XEmbeddedObject > xObj(const_cast<SwOLENode&>(rOLENode).GetOLEObj().GetOleRef());
3797 0 : SvGlobalName aObjName(xObj->getClassID());
3798 :
3799 0 : if( !SotExchange::IsMath(aObjName) )
3800 0 : return false;
3801 : assert( m_postponedMath == NULL ); // make it a list if there can be more inside one run
3802 0 : m_postponedMath = &rOLENode;
3803 0 : return true;
3804 : }
3805 :
3806 0 : void DocxAttributeOutput::WritePostponedMath()
3807 : {
3808 0 : if( m_postponedMath == NULL )
3809 0 : return;
3810 0 : uno::Reference < embed::XEmbeddedObject > xObj(const_cast<SwOLENode*>(m_postponedMath)->GetOLEObj().GetOleRef());
3811 0 : 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 0 : oox::FormulaExportBase* formulaexport = dynamic_cast<oox::FormulaExportBase*>(dynamic_cast<SfxBaseModel*>(xInterface.get()));
3816 : assert( formulaexport != NULL );
3817 0 : if (formulaexport)
3818 0 : formulaexport->writeFormulaOoxml( m_pSerializer, GetExport().GetFilter().getVersion());
3819 0 : m_postponedMath = NULL;
3820 : }
3821 :
3822 0 : void DocxAttributeOutput::WritePostponedFormControl(const SdrObject* pObject)
3823 : {
3824 0 : if (pObject && pObject->GetObjInventor() == FmFormInventor)
3825 : {
3826 0 : if (SdrUnoObj *pFormObj = PTR_CAST(SdrUnoObj,pObject))
3827 : {
3828 0 : uno::Reference<awt::XControlModel> xControlModel = pFormObj->GetUnoControlModel();
3829 0 : uno::Reference<lang::XServiceInfo> xInfo(xControlModel, uno::UNO_QUERY);
3830 0 : if (xInfo->supportsService("com.sun.star.form.component.DateField"))
3831 : {
3832 : // gather component properties
3833 :
3834 0 : Date aOriginalDate(Date::EMPTY);
3835 0 : OUString sOriginalContent, sDateFormat;
3836 0 : OUString sLocale("en-US");
3837 0 : uno::Sequence<beans::PropertyValue> aGrabBag;
3838 0 : uno::Reference<beans::XPropertySet> xShapePropertySet(pFormObj->getUnoShape(), uno::UNO_QUERY);
3839 0 : if (xShapePropertySet->getPropertyValue(UNO_NAME_MISC_OBJ_INTEROPGRABBAG) >>= aGrabBag)
3840 : {
3841 0 : for (sal_Int32 i=0; i < aGrabBag.getLength(); ++i)
3842 : {
3843 0 : if (aGrabBag[i].Name == "DateFormat")
3844 0 : aGrabBag[i].Value >>= sDateFormat;
3845 0 : else if (aGrabBag[i].Name == "Locale")
3846 0 : aGrabBag[i].Value >>= sLocale;
3847 0 : else if (aGrabBag[i].Name == "OriginalContent")
3848 0 : aGrabBag[i].Value >>= sOriginalContent;
3849 0 : else if (aGrabBag[i].Name == "OriginalDate")
3850 : {
3851 0 : css::util::Date aUNODate;
3852 0 : aGrabBag[i].Value >>= aUNODate;
3853 0 : aOriginalDate.SetDay(aUNODate.Day);
3854 0 : aOriginalDate.SetMonth(aUNODate.Month);
3855 0 : aOriginalDate.SetYear(aUNODate.Year);
3856 : }
3857 : }
3858 : }
3859 0 : uno::Reference<beans::XPropertySet> xPropertySet(xControlModel, uno::UNO_QUERY);
3860 :
3861 0 : OString sDate;
3862 0 : OUString aContentText;
3863 0 : bool bHasDate = false;
3864 0 : css::util::Date aUNODate;
3865 0 : if (xPropertySet->getPropertyValue("Date") >>= aUNODate)
3866 : {
3867 0 : bHasDate = true;
3868 0 : Date aDate(aUNODate.Day, aUNODate.Month, aUNODate.Year);
3869 0 : sDate = DateToOString(aDate);
3870 :
3871 0 : if (aOriginalDate == aDate)
3872 : {
3873 0 : 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 0 : m_pSerializer->startElementNS(XML_w, XML_sdt, FSEND);
3888 0 : m_pSerializer->startElementNS(XML_w, XML_sdtPr, FSEND);
3889 :
3890 0 : if (bHasDate)
3891 : m_pSerializer->startElementNS(XML_w, XML_date,
3892 : FSNS( XML_w, XML_fullDate ), sDate.getStr(),
3893 0 : 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 0 : FSEND);
3901 : m_pSerializer->singleElementNS(XML_w, XML_lid,
3902 : FSNS(XML_w, XML_val),
3903 : rtl::OUStringToOString( sLocale, RTL_TEXTENCODING_UTF8 ).getStr(),
3904 0 : FSEND);
3905 : m_pSerializer->singleElementNS(XML_w, XML_storeMappedDataAs,
3906 : FSNS(XML_w, XML_val), "dateTime",
3907 0 : FSEND);
3908 : m_pSerializer->singleElementNS(XML_w, XML_calendar,
3909 : FSNS(XML_w, XML_val), "gregorian",
3910 0 : FSEND);
3911 :
3912 0 : m_pSerializer->endElementNS(XML_w, XML_date);
3913 0 : m_pSerializer->endElementNS(XML_w, XML_sdtPr);
3914 :
3915 0 : m_pSerializer->startElementNS(XML_w, XML_sdtContent, FSEND);
3916 0 : m_pSerializer->startElementNS(XML_w, XML_r, FSEND);
3917 0 : RunText(aContentText);
3918 0 : m_pSerializer->endElementNS(XML_w, XML_r);
3919 0 : m_pSerializer->endElementNS(XML_w, XML_sdtContent);
3920 :
3921 0 : m_pSerializer->endElementNS(XML_w, XML_sdt);
3922 : }
3923 0 : else if (xInfo->supportsService("com.sun.star.form.component.ComboBox"))
3924 : {
3925 : // gather component properties
3926 :
3927 0 : uno::Reference<beans::XPropertySet> xPropertySet(xControlModel, uno::UNO_QUERY);
3928 0 : OUString sText = xPropertySet->getPropertyValue("Text").get<OUString>();
3929 0 : uno::Sequence<OUString> aItems = xPropertySet->getPropertyValue("StringItemList").get< uno::Sequence<OUString> >();
3930 :
3931 : // output component
3932 :
3933 0 : m_pSerializer->startElementNS(XML_w, XML_sdt, FSEND);
3934 0 : m_pSerializer->startElementNS(XML_w, XML_sdtPr, FSEND);
3935 :
3936 0 : m_pSerializer->startElementNS(XML_w, XML_dropDownList, FSEND);
3937 :
3938 0 : 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 0 : rtl::OUStringToOString( aItems[i], RTL_TEXTENCODING_UTF8 ).getStr(),
3943 : FSNS(XML_w, XML_value),
3944 0 : rtl::OUStringToOString( aItems[i], RTL_TEXTENCODING_UTF8 ).getStr(),
3945 0 : FSEND);
3946 : }
3947 :
3948 0 : m_pSerializer->endElementNS(XML_w, XML_dropDownList);
3949 0 : m_pSerializer->endElementNS(XML_w, XML_sdtPr);
3950 :
3951 0 : m_pSerializer->startElementNS(XML_w, XML_sdtContent, FSEND);
3952 0 : m_pSerializer->startElementNS(XML_w, XML_r, FSEND);
3953 0 : RunText(sText);
3954 0 : m_pSerializer->endElementNS(XML_w, XML_r);
3955 0 : m_pSerializer->endElementNS(XML_w, XML_sdtContent);
3956 :
3957 0 : m_pSerializer->endElementNS(XML_w, XML_sdt);
3958 0 : }
3959 : }
3960 : }
3961 0 : }
3962 :
3963 0 : bool DocxAttributeOutput::PostponeOLE( const SdrObject*, SwOLENode& rNode, const Size& rSize, const SwFlyFrmFmt* pFlyFrmFmt )
3964 : {
3965 0 : if( m_postponedOLE == NULL )
3966 : //cannot be postponed, try to write now
3967 0 : WriteOLE( rNode, rSize, pFlyFrmFmt );
3968 : else
3969 0 : m_postponedOLE->push_back( PostponedOLE( &rNode, rSize, pFlyFrmFmt ) );
3970 0 : return true;
3971 : }
3972 :
3973 : /*
3974 : * Write w:object hierarchy for embedded objects after end element of w:rPr tag.
3975 : */
3976 0 : void DocxAttributeOutput::WritePostponedOLE()
3977 : {
3978 0 : if( m_postponedOLE == NULL )
3979 0 : return;
3980 :
3981 : SAL_INFO( "sw.ww8", OSL_THIS_FUNC );
3982 :
3983 0 : for( std::list< PostponedOLE >::iterator it = m_postponedOLE->begin();
3984 0 : it != m_postponedOLE->end();
3985 : ++it )
3986 : {
3987 0 : WriteOLE( *it->object, it->size, it->frame );
3988 : }
3989 :
3990 : // clear list of postponed objects
3991 0 : delete m_postponedOLE;
3992 0 : m_postponedOLE = NULL;
3993 : }
3994 :
3995 0 : void DocxAttributeOutput::WriteOLE( SwOLENode& rNode, const Size& rSize, const SwFlyFrmFmt* rFlyFrmFmt )
3996 : {
3997 : // get interoperability information about embedded objects
3998 0 : uno::Reference< beans::XPropertySet > xPropSet( m_rExport.pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
3999 0 : OUString pName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
4000 0 : uno::Sequence< beans::PropertyValue > aGrabBag, aObjectsInteropList;
4001 0 : xPropSet->getPropertyValue( pName ) >>= aGrabBag;
4002 0 : for( sal_Int32 i=0; i < aGrabBag.getLength(); ++i )
4003 0 : if ( aGrabBag[i].Name == "EmbeddedObjects" )
4004 : {
4005 0 : aGrabBag[i].Value >>= aObjectsInteropList;
4006 0 : break;
4007 : }
4008 :
4009 0 : SwOLEObj& aObject = rNode.GetOLEObj();
4010 0 : uno::Reference < embed::XEmbeddedObject > xObj( aObject.GetOleRef() );
4011 0 : comphelper::EmbeddedObjectContainer* aContainer = aObject.GetObject().GetContainer();
4012 0 : OUString sObjectName = aContainer->GetEmbeddedObjectName( xObj );
4013 :
4014 : // set some attributes according to the type of the embedded object
4015 0 : OUString sProgID, sMediaType, sRelationType;
4016 0 : for( sal_Int32 i=0; i < aObjectsInteropList.getLength(); ++i )
4017 0 : if ( aObjectsInteropList[i].Name == sObjectName )
4018 : {
4019 0 : aObjectsInteropList[i].Value >>= sProgID;
4020 0 : break;
4021 : }
4022 0 : if( sProgID.startsWith("Excel.Sheet") )
4023 : {
4024 0 : sMediaType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
4025 0 : sRelationType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package";
4026 : }
4027 0 : 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 0 : sMediaType = "application/vnd.openxmlformats-officedocument.oleObject";
4035 0 : sRelationType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject";
4036 : }
4037 :
4038 : // write embedded file
4039 0 : OString sId = m_rExport.WriteOLEObject( aObject, sMediaType, sRelationType );
4040 :
4041 0 : if( sId.isEmpty() )
4042 : {
4043 : // the embedded file could not be saved
4044 : // fallback: save as an image
4045 0 : FlyFrameGraphic( 0, rSize, rFlyFrmFmt, &rNode );
4046 0 : return;
4047 : }
4048 :
4049 : // write preview image
4050 0 : const Graphic* pGraphic = rNode.GetGraphic();
4051 0 : m_rDrawingML.SetFS(m_pSerializer);
4052 0 : OUString sImageId = m_rDrawingML.WriteImage( *pGraphic );
4053 :
4054 0 : m_pSerializer->startElementNS( XML_w, XML_object, FSEND );
4055 :
4056 0 : OStringBuffer sShapeStyle, sShapeId;
4057 0 : sShapeStyle.append( "width:" ).append( double( rSize.Width() ) / 20 )
4058 0 : .append( "pt;height:" ).append( double( rSize.Height() ) / 20 )
4059 0 : .append( "pt" ); //from VMLExport::AddRectangleDimensions(), it does: value/20
4060 0 : 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 0 : 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 0 : FSEND );
4074 :
4075 0 : 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 0 : XML_ProgID, OUStringToOString( sProgID, RTL_TEXTENCODING_UTF8 ).getStr(),
4081 0 : XML_ShapeID, sShapeId.getStr(),
4082 : XML_DrawAspect, "Content",
4083 0 : XML_ObjectID, "_" + OString::number( rand() ),
4084 0 : FSNS( XML_r, XML_id ), sId.getStr(),
4085 0 : FSEND );
4086 :
4087 0 : m_pSerializer->endElementNS( XML_w, XML_object );
4088 : }
4089 :
4090 : /*
4091 : * Write w:pict hierarchy end element of w:rPr tag.
4092 : */
4093 0 : void DocxAttributeOutput::WritePostponedVMLDrawing()
4094 : {
4095 0 : if(m_postponedVMLDrawing == NULL)
4096 0 : return;
4097 :
4098 0 : for( std::list< PostponedDrawing >::iterator it = m_postponedVMLDrawing->begin();
4099 0 : it != m_postponedVMLDrawing->end();
4100 : ++it )
4101 : {
4102 0 : m_rExport.SdrExporter().writeVMLDrawing(it->object, *(it->frame), *(it->point));
4103 : }
4104 0 : delete m_postponedVMLDrawing;
4105 0 : m_postponedVMLDrawing = NULL;
4106 : }
4107 :
4108 0 : void DocxAttributeOutput::WritePostponedDMLDrawing()
4109 : {
4110 0 : if(m_postponedDMLDrawing == NULL)
4111 0 : return;
4112 :
4113 0 : for( std::list< PostponedDrawing >::iterator it = m_postponedDMLDrawing->begin();
4114 0 : it != m_postponedDMLDrawing->end();
4115 : ++it )
4116 : {
4117 0 : if ( IsAlternateContentChoiceOpen() )
4118 0 : m_rExport.SdrExporter().writeDMLDrawing(it->object, (it->frame), m_anchorId++);
4119 : else
4120 0 : m_rExport.SdrExporter().writeDMLAndVMLDrawing(it->object, *(it->frame), *(it->point), m_anchorId++);
4121 : }
4122 0 : delete m_postponedDMLDrawing;
4123 0 : m_postponedDMLDrawing = NULL;
4124 : }
4125 :
4126 0 : void DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame &rFrame, const Point& rNdTopLeft )
4127 : {
4128 0 : m_pSerializer->mark();
4129 :
4130 0 : switch ( rFrame.GetWriterType() )
4131 : {
4132 : case sw::Frame::eGraphic:
4133 : {
4134 0 : const SdrObject* pSdrObj = rFrame.GetFrmFmt().FindRealSdrObject();
4135 0 : const SwNode *pNode = rFrame.GetContent();
4136 0 : const SwGrfNode *pGrfNode = pNode ? pNode->GetGrfNode() : 0;
4137 0 : if ( pGrfNode )
4138 : {
4139 0 : if( m_postponedGraphic == NULL )
4140 0 : 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 0 : m_postponedGraphic->push_back( PostponedGraphic( pGrfNode, rFrame.GetLayoutSize(), 0, 0, pSdrObj));
4144 : }
4145 : }
4146 : }
4147 0 : break;
4148 : case sw::Frame::eDrawing:
4149 : {
4150 0 : const SdrObject* pSdrObj = rFrame.GetFrmFmt().FindRealSdrObject();
4151 0 : if ( pSdrObj )
4152 : {
4153 0 : if ( IsDiagram( pSdrObj ) )
4154 : {
4155 0 : if ( m_postponedDiagram == NULL )
4156 0 : 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 0 : m_postponedDiagram->push_back( PostponedDiagram( pSdrObj, &(rFrame.GetFrmFmt()) ));
4160 : }
4161 : }
4162 : else
4163 : {
4164 0 : if ( m_postponedDMLDrawing == NULL )
4165 : {
4166 0 : if ( IsAlternateContentChoiceOpen() )
4167 0 : m_rExport.SdrExporter().writeDMLDrawing( pSdrObj, &rFrame.GetFrmFmt(), m_anchorId++);
4168 : else
4169 0 : 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 0 : m_postponedDMLDrawing->push_back(PostponedDrawing(pSdrObj, &(rFrame.GetFrmFmt()), &rNdTopLeft));
4174 : }
4175 : }
4176 : }
4177 0 : break;
4178 : case sw::Frame::eTxtBox:
4179 : {
4180 : // The frame output is postponed to the end of the anchor paragraph
4181 0 : bool bDuplicate = false;
4182 0 : const OUString& rName = rFrame.GetFrmFmt().GetName();
4183 0 : unsigned nSize = m_aFramesOfParagraph.size();
4184 0 : for( unsigned nIndex = 0; nIndex < nSize; ++nIndex )
4185 : {
4186 0 : const OUString& rNameExisting = m_aFramesOfParagraph[nIndex].GetFrmFmt().GetName();
4187 :
4188 0 : if (!rName.isEmpty() && !rNameExisting.isEmpty())
4189 : {
4190 0 : if (rName == rNameExisting)
4191 0 : bDuplicate = true;
4192 : }
4193 0 : }
4194 :
4195 0 : if( !bDuplicate )
4196 0 : m_aFramesOfParagraph.push_back(sw::Frame(rFrame));
4197 : }
4198 0 : break;
4199 : case sw::Frame::eOle:
4200 : {
4201 0 : const SwFrmFmt &rFrmFmt = rFrame.GetFrmFmt();
4202 0 : const SdrObject *pSdrObj = rFrmFmt.FindRealSdrObject();
4203 0 : if ( pSdrObj )
4204 : {
4205 0 : SwNodeIndex aIdx(*rFrmFmt.GetCntnt().GetCntntIdx(), 1);
4206 0 : SwOLENode& rOLENd = *aIdx.GetNode().GetOLENode();
4207 0 : WriteOLE2Obj( pSdrObj, rOLENd, rFrame.GetLayoutSize(), dynamic_cast<const SwFlyFrmFmt*>( &rFrmFmt ));
4208 : }
4209 : }
4210 0 : break;
4211 : case sw::Frame::eFormControl:
4212 : {
4213 0 : const SdrObject* pObject = rFrame.GetFrmFmt().FindRealSdrObject();
4214 0 : m_aPostponedFormControls.push_back(pObject);
4215 : }
4216 0 : 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 0 : m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_POSTPONE );
4225 0 : }
4226 :
4227 0 : bool DocxAttributeOutput::IsDiagram( const SdrObject* sdrObject )
4228 : {
4229 0 : uno::Reference< drawing::XShape > xShape( ((SdrObject*)sdrObject)->getUnoShape(), uno::UNO_QUERY );
4230 0 : if ( !xShape.is() )
4231 0 : return false;
4232 :
4233 0 : uno::Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
4234 0 : if ( !xPropSet.is() )
4235 0 : return false;
4236 :
4237 : // if the shape doesn't have the InteropGrabBag property, it's not a diagram
4238 0 : uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
4239 0 : OUString pName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
4240 0 : if ( !xPropSetInfo->hasPropertyByName( pName ) )
4241 0 : return false;
4242 :
4243 0 : uno::Sequence< beans::PropertyValue > propList;
4244 0 : xPropSet->getPropertyValue( pName ) >>= propList;
4245 0 : for ( sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp )
4246 : {
4247 : // if we find any of the diagram components, it's a diagram
4248 0 : OUString propName = propList[nProp].Name;
4249 0 : if ( propName == "OOXData" || propName == "OOXLayout" || propName == "OOXStyle" ||
4250 0 : propName == "OOXColor" || propName == "OOXDrawing")
4251 0 : return true;
4252 0 : }
4253 0 : return false;
4254 : }
4255 :
4256 0 : void DocxAttributeOutput::WriteOutliner(const OutlinerParaObject& rParaObj)
4257 : {
4258 0 : const EditTextObject& rEditObj = rParaObj.GetTextObject();
4259 0 : MSWord_SdrAttrIter aAttrIter( m_rExport, rEditObj, TXT_HFTXTBOX );
4260 :
4261 0 : sal_Int32 nPara = rEditObj.GetParagraphCount();
4262 :
4263 0 : m_pSerializer->startElementNS( XML_w, XML_txbxContent, FSEND );
4264 0 : for (sal_Int32 n = 0; n < nPara; ++n)
4265 : {
4266 0 : if( n )
4267 0 : aAttrIter.NextPara( n );
4268 :
4269 0 : OUString aStr( rEditObj.GetText( n ));
4270 0 : sal_Int32 nAktPos = 0;
4271 0 : sal_Int32 nEnd = aStr.getLength();
4272 :
4273 0 : StartParagraph(ww8::WW8TableNodeInfo::Pointer_t());
4274 :
4275 : // Write paragraph properties.
4276 0 : StartParagraphProperties();
4277 0 : aAttrIter.OutParaAttr(false);
4278 0 : EndParagraphProperties(0, 0, 0, 0);
4279 :
4280 0 : do {
4281 0 : const sal_Int32 nNextAttr = std::min(aAttrIter.WhereNext(), nEnd);
4282 :
4283 0 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
4284 :
4285 : // Write run properties.
4286 0 : m_pSerializer->startElementNS(XML_w, XML_rPr, FSEND);
4287 0 : aAttrIter.OutAttr(nAktPos);
4288 0 : WriteCollectedRunProperties();
4289 0 : m_pSerializer->endElementNS(XML_w, XML_rPr);
4290 :
4291 0 : bool bTxtAtr = aAttrIter.IsTxtAttr( nAktPos );
4292 0 : if( !bTxtAtr )
4293 : {
4294 0 : OUString aOut( aStr.copy( nAktPos, nNextAttr - nAktPos ) );
4295 0 : RunText(aOut);
4296 : }
4297 :
4298 0 : m_pSerializer->endElementNS( XML_w, XML_r );
4299 :
4300 0 : nAktPos = nNextAttr;
4301 0 : aAttrIter.NextPos();
4302 : }
4303 0 : while( nAktPos < nEnd );
4304 : // Word can't handle nested text boxes, so write them on the same level.
4305 0 : ++m_nTextFrameLevel;
4306 0 : EndParagraph(ww8::WW8TableNodeInfoInner::Pointer_t());
4307 0 : --m_nTextFrameLevel;
4308 0 : }
4309 0 : m_pSerializer->endElementNS( XML_w, XML_txbxContent );
4310 0 : }
4311 :
4312 0 : oox::drawingml::DrawingML& DocxAttributeOutput::GetDrawingML()
4313 : {
4314 0 : return m_rDrawingML;
4315 : }
4316 :
4317 0 : 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 0 : bool bQFormat = false, bUnhideWhenUsed = false, bSemiHidden = false, bLocked = false, bDefault = false, bCustomStyle = false;
4321 0 : OUString aLink, aRsid, aUiPriority;
4322 0 : FastAttributeList* pStyleAttributeList = m_pSerializer->createAttrList();
4323 0 : uno::Any aAny;
4324 0 : if (eType == STYLE_TYPE_PARA || eType == STYLE_TYPE_CHAR)
4325 : {
4326 0 : const SwFmt* pFmt = m_rExport.pStyles->GetSwFmt(nId);
4327 0 : pFmt->GetGrabBagItem(aAny);
4328 : }
4329 : else
4330 : {
4331 0 : const SwNumRule* pRule = m_rExport.pStyles->GetSwNumRule(nId);
4332 0 : pRule->GetGrabBagItem(aAny);
4333 : }
4334 0 : const uno::Sequence<beans::PropertyValue>& rGrabBag = aAny.get< uno::Sequence<beans::PropertyValue> >();
4335 :
4336 0 : for (sal_Int32 i = 0; i < rGrabBag.getLength(); ++i)
4337 : {
4338 0 : if (rGrabBag[i].Name == "uiPriority")
4339 0 : aUiPriority = rGrabBag[i].Value.get<OUString>();
4340 0 : else if (rGrabBag[i].Name == "qFormat")
4341 0 : bQFormat = true;
4342 0 : else if (rGrabBag[i].Name == "link")
4343 0 : aLink = rGrabBag[i].Value.get<OUString>();
4344 0 : else if (rGrabBag[i].Name == "rsid")
4345 0 : aRsid = rGrabBag[i].Value.get<OUString>();
4346 0 : else if (rGrabBag[i].Name == "unhideWhenUsed")
4347 0 : bUnhideWhenUsed = true;
4348 0 : else if (rGrabBag[i].Name == "semiHidden")
4349 0 : bSemiHidden = true;
4350 0 : else if (rGrabBag[i].Name == "locked")
4351 0 : bLocked = true;
4352 0 : else if (rGrabBag[i].Name == "default")
4353 0 : bDefault = rGrabBag[i].Value.get<sal_Bool>();
4354 0 : else if (rGrabBag[i].Name == "customStyle")
4355 0 : bCustomStyle = rGrabBag[i].Value.get<sal_Bool>();
4356 : else
4357 : SAL_WARN("sw.ww8", "Unhandled style property: " << rGrabBag[i].Name);
4358 : }
4359 :
4360 0 : const char* pType = 0;
4361 0 : switch (eType)
4362 : {
4363 0 : case STYLE_TYPE_PARA: pType = "paragraph"; break;
4364 0 : case STYLE_TYPE_CHAR: pType = "character"; break;
4365 0 : case STYLE_TYPE_LIST: pType = "numbering"; break;
4366 : }
4367 0 : pStyleAttributeList->add(FSNS( XML_w, XML_type ), pType);
4368 0 : pStyleAttributeList->add(FSNS( XML_w, XML_styleId ), m_rExport.pStyles->GetStyleId(nId).getStr());
4369 0 : if (bDefault)
4370 0 : pStyleAttributeList->add(FSNS(XML_w, XML_default), "1");
4371 0 : if (bCustomStyle)
4372 0 : pStyleAttributeList->add(FSNS(XML_w, XML_customStyle), "1");
4373 0 : XFastAttributeListRef xStyleAttributeList(pStyleAttributeList);
4374 0 : 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 0 : FSEND );
4379 :
4380 0 : 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 0 : FSEND );
4385 : }
4386 :
4387 0 : 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 0 : FSEND );
4392 : }
4393 :
4394 0 : if (!aLink.isEmpty())
4395 : m_pSerializer->singleElementNS(XML_w, XML_link,
4396 : FSNS(XML_w, XML_val), OUStringToOString(aLink, RTL_TEXTENCODING_UTF8).getStr(),
4397 0 : FSEND);
4398 :
4399 0 : if ( bAutoUpdate )
4400 0 : m_pSerializer->singleElementNS( XML_w, XML_autoRedefine, FSEND );
4401 :
4402 0 : if (!aUiPriority.isEmpty())
4403 : m_pSerializer->singleElementNS(XML_w, XML_uiPriority,
4404 : FSNS(XML_w, XML_val), OUStringToOString(aUiPriority, RTL_TEXTENCODING_UTF8).getStr(),
4405 0 : FSEND);
4406 0 : if (bSemiHidden)
4407 0 : m_pSerializer->singleElementNS(XML_w, XML_semiHidden, FSEND);
4408 0 : if (bUnhideWhenUsed)
4409 0 : m_pSerializer->singleElementNS(XML_w, XML_unhideWhenUsed, FSEND);
4410 0 : if (bQFormat)
4411 0 : m_pSerializer->singleElementNS(XML_w, XML_qFormat, FSEND);
4412 0 : if (bLocked)
4413 0 : m_pSerializer->singleElementNS(XML_w, XML_locked, FSEND);
4414 0 : if (!aRsid.isEmpty())
4415 : m_pSerializer->singleElementNS(XML_w, XML_rsid,
4416 : FSNS(XML_w, XML_val), OUStringToOString(aRsid, RTL_TEXTENCODING_UTF8).getStr(),
4417 0 : FSEND);
4418 0 : }
4419 :
4420 0 : void DocxAttributeOutput::EndStyle()
4421 : {
4422 0 : m_pSerializer->endElementNS( XML_w, XML_style );
4423 0 : }
4424 :
4425 0 : void DocxAttributeOutput::StartStyleProperties( bool bParProp, sal_uInt16 /*nStyle*/ )
4426 : {
4427 0 : if ( bParProp )
4428 : {
4429 0 : m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND );
4430 0 : InitCollectedParagraphProperties();
4431 : }
4432 : else
4433 : {
4434 0 : m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
4435 0 : InitCollectedRunProperties();
4436 : }
4437 0 : }
4438 :
4439 0 : void DocxAttributeOutput::EndStyleProperties( bool bParProp )
4440 : {
4441 0 : if ( bParProp )
4442 : {
4443 0 : WriteCollectedParagraphProperties();
4444 :
4445 : // Merge the marks for the ordered elements
4446 0 : m_pSerializer->mergeTopMarks( );
4447 :
4448 0 : m_pSerializer->endElementNS( XML_w, XML_pPr );
4449 : }
4450 : else
4451 : {
4452 0 : WriteCollectedRunProperties();
4453 :
4454 : // Merge the marks for the ordered elements
4455 0 : m_pSerializer->mergeTopMarks();
4456 :
4457 0 : m_pSerializer->endElementNS( XML_w, XML_rPr );
4458 : }
4459 0 : }
4460 :
4461 0 : void lcl_OutlineLevel(sax_fastparser::FSHelperPtr pSerializer, sal_uInt16 nLevel)
4462 : {
4463 0 : 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 0 : FSEND);
4469 0 : }
4470 :
4471 0 : void DocxAttributeOutput::OutlineNumbering( sal_uInt8 nLvl, const SwNumFmt& /*rNFmt*/, const SwFmt& /*rFmt*/ )
4472 : {
4473 0 : lcl_OutlineLevel(m_pSerializer, nLvl);
4474 0 : }
4475 :
4476 0 : void DocxAttributeOutput::ParaOutlineLevel(const SfxUInt16Item& rItem)
4477 : {
4478 0 : if (rItem.GetValue() > 0)
4479 0 : lcl_OutlineLevel(m_pSerializer, rItem.GetValue() - 1);
4480 0 : }
4481 :
4482 0 : void DocxAttributeOutput::PageBreakBefore( bool bBreak )
4483 : {
4484 0 : if ( bBreak )
4485 0 : 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 0 : }
4491 :
4492 0 : void DocxAttributeOutput::SectionBreak( sal_uInt8 nC, const WW8_SepInfo* pSectionInfo )
4493 : {
4494 0 : switch ( nC )
4495 : {
4496 : case msword::ColumnBreak:
4497 : // The column break should be output in the next paragraph...
4498 0 : m_nColBreakStatus = COLBRK_POSTPONE;
4499 0 : break;
4500 : case msword::PageBreak:
4501 0 : if ( pSectionInfo )
4502 : {
4503 : // don't add section properties if this will be the first
4504 : // paragraph in the document
4505 0 : if ( !m_bParagraphOpened && !m_bIsFirstParagraph)
4506 : {
4507 : // Create a dummy paragraph if needed
4508 0 : m_pSerializer->startElementNS( XML_w, XML_p, FSEND );
4509 0 : m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND );
4510 :
4511 0 : m_rExport.SectionProperties( *pSectionInfo );
4512 :
4513 0 : m_pSerializer->endElementNS( XML_w, XML_pPr );
4514 0 : 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 0 : m_pSectionInfo.reset( new WW8_SepInfo( *pSectionInfo ));
4521 : }
4522 : }
4523 : else
4524 : {
4525 0 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
4526 : m_pSerializer->singleElementNS( XML_w, XML_br,
4527 0 : FSNS( XML_w, XML_type ), "page", FSEND );
4528 0 : m_pSerializer->endElementNS( XML_w, XML_r );
4529 : }
4530 0 : break;
4531 : default:
4532 : OSL_TRACE( "Unknown section break to write: %d", nC );
4533 0 : break;
4534 : }
4535 0 : }
4536 :
4537 0 : void DocxAttributeOutput::StartSection()
4538 : {
4539 0 : m_pSerializer->startElementNS( XML_w, XML_sectPr, FSEND );
4540 0 : 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 0 : sal_Int32 len = sizeof ( aOrder ) / sizeof( sal_Int32 );
4572 0 : uno::Sequence< sal_Int32 > aSeqOrder( len );
4573 0 : for ( sal_Int32 i = 0; i < len; i++ )
4574 0 : aSeqOrder[i] = aOrder[i];
4575 :
4576 0 : m_pSerializer->mark( aSeqOrder );
4577 0 : }
4578 :
4579 0 : void DocxAttributeOutput::EndSection()
4580 : {
4581 : // Write the section properties
4582 0 : if ( m_pSectionSpacingAttrList )
4583 : {
4584 0 : XFastAttributeListRef xAttrList( m_pSectionSpacingAttrList );
4585 0 : m_pSectionSpacingAttrList = NULL;
4586 :
4587 0 : m_pSerializer->singleElementNS( XML_w, XML_pgMar, xAttrList );
4588 : }
4589 :
4590 : // Order the elements
4591 0 : m_pSerializer->mergeTopMarks( );
4592 :
4593 0 : m_pSerializer->endElementNS( XML_w, XML_sectPr );
4594 0 : m_bOpenedSectPr = false;
4595 0 : }
4596 :
4597 0 : void DocxAttributeOutput::SectionFormProtection( bool bProtected )
4598 : {
4599 0 : if ( bProtected )
4600 0 : m_pSerializer->singleElementNS( XML_w, XML_formProt, FSEND );
4601 : else
4602 : m_pSerializer->singleElementNS( XML_w, XML_formProt,
4603 0 : FSNS( XML_w, XML_val ), "false", FSEND );
4604 0 : }
4605 :
4606 0 : void DocxAttributeOutput::SectionLineNumbering( sal_uLong nRestartNo, const SwLineNumberInfo& rLnNumInfo )
4607 : {
4608 0 : FastAttributeList* pAttr = m_pSerializer->createAttrList();
4609 0 : pAttr->add( FSNS( XML_w, XML_countBy ), OString::number(rLnNumInfo.GetCountBy()).getStr());
4610 0 : pAttr->add( FSNS( XML_w, XML_restart ), rLnNumInfo.IsRestartEachPage() ? "newPage" : "continuous" );
4611 0 : if( rLnNumInfo.GetPosFromLeft())
4612 0 : pAttr->add( FSNS( XML_w, XML_distance ), OString::number(rLnNumInfo.GetPosFromLeft()).getStr());
4613 0 : if( nRestartNo )
4614 0 : pAttr->add( FSNS( XML_w, XML_start ), OString::number( nRestartNo).getStr());
4615 0 : XFastAttributeListRef xAttrs( pAttr );
4616 0 : m_pSerializer->singleElementNS( XML_w, XML_lnNumType, xAttrs );
4617 0 : }
4618 :
4619 0 : void DocxAttributeOutput::SectionTitlePage()
4620 : {
4621 0 : m_pSerializer->singleElementNS( XML_w, XML_titlePg, FSEND );
4622 0 : }
4623 :
4624 0 : void DocxAttributeOutput::SectionPageBorders( const SwFrmFmt* pFmt, const SwFrmFmt* /*pFirstPageFmt*/ )
4625 : {
4626 : // Output the margins
4627 :
4628 0 : const SvxBoxItem& rBox = pFmt->GetBox( );
4629 :
4630 0 : const SvxBorderLine* pLeft = rBox.GetLeft( );
4631 0 : const SvxBorderLine* pTop = rBox.GetTop( );
4632 0 : const SvxBorderLine* pRight = rBox.GetRight( );
4633 0 : const SvxBorderLine* pBottom = rBox.GetBottom( );
4634 :
4635 0 : if ( pBottom || pTop || pLeft || pRight )
4636 : {
4637 0 : bool bExportDistanceFromPageEdge = false;
4638 0 : 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 0 : 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 0 : FSEND );
4652 :
4653 0 : OutputBorderOptions aOutputBorderOptions = lcl_getBoxBorderOptions();
4654 :
4655 : // Check if the distance is larger than 31 points
4656 0 : aOutputBorderOptions.bCheckDistanceSize = true;
4657 :
4658 : // Check if there is a shadow item
4659 0 : const SfxPoolItem* pItem = GetExport().HasItem( RES_SHADOW );
4660 0 : if ( pItem )
4661 : {
4662 0 : const SvxShadowItem* pShadowItem = (const SvxShadowItem*)pItem;
4663 0 : aOutputBorderOptions.aShadowLocation = pShadowItem->GetLocation();
4664 : }
4665 :
4666 0 : std::map<sal_uInt16, css::table::BorderLine2> aEmptyMap; // empty styles map
4667 : impl_borders( m_pSerializer, rBox, aOutputBorderOptions, &m_pageMargins,
4668 0 : aEmptyMap );
4669 :
4670 0 : m_pSerializer->endElementNS( XML_w, XML_pgBorders );
4671 : }
4672 0 : }
4673 :
4674 0 : void DocxAttributeOutput::SectionBiDi( bool bBiDi )
4675 : {
4676 0 : if ( bBiDi )
4677 0 : m_pSerializer->singleElementNS( XML_w, XML_bidi, FSEND );
4678 0 : }
4679 :
4680 0 : static OString impl_NumberingType( sal_uInt16 nNumberingType )
4681 : {
4682 0 : OString aType;
4683 :
4684 0 : switch ( nNumberingType )
4685 : {
4686 : case SVX_NUM_CHARS_UPPER_LETTER:
4687 0 : case SVX_NUM_CHARS_UPPER_LETTER_N: aType = "upperLetter"; break;
4688 : case SVX_NUM_CHARS_LOWER_LETTER:
4689 0 : case SVX_NUM_CHARS_LOWER_LETTER_N: aType = "lowerLetter"; break;
4690 0 : case SVX_NUM_ROMAN_UPPER: aType = "upperRoman"; break;
4691 0 : case SVX_NUM_ROMAN_LOWER: aType = "lowerRoman"; break;
4692 :
4693 0 : case SVX_NUM_ARABIC: aType = "decimal"; break;
4694 :
4695 : case SVX_NUM_BITMAP:
4696 0 : case SVX_NUM_CHAR_SPECIAL: aType = "bullet"; break;
4697 0 : case style::NumberingType::CHARS_HEBREW: aType = "hebrew1"; break;
4698 :
4699 0 : default: aType = "none"; break;
4700 : }
4701 :
4702 0 : return aType;
4703 : }
4704 :
4705 0 : 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 0 : FastAttributeList* pAttr = m_pSerializer->createAttrList();
4710 :
4711 : // boost::none means no restart: then don't output that attribute if it is negative
4712 0 : if ( oPageRestartNumber )
4713 0 : 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 0 : OString aFmt( impl_NumberingType( nNumType ) );
4717 0 : if ( !aFmt.isEmpty() )
4718 0 : pAttr->add( FSNS( XML_w, XML_fmt ), aFmt.getStr() );
4719 :
4720 0 : XFastAttributeListRef xAttrs( pAttr );
4721 0 : m_pSerializer->singleElementNS( XML_w, XML_pgNumType, xAttrs );
4722 :
4723 : // see 2.6.12 pgNumType (Page Numbering Settings)
4724 0 : OSL_TRACE( "TODO DocxAttributeOutput::SectionPageNumbering()" );
4725 0 : }
4726 :
4727 0 : 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 0 : const char* pType = NULL;
4733 0 : switch ( nBreakCode )
4734 : {
4735 0 : case 1: pType = "nextColumn"; break;
4736 0 : case 2: pType = "nextPage"; break;
4737 0 : case 3: pType = "evenPage"; break;
4738 0 : case 4: pType = "oddPage"; break;
4739 0 : default: pType = "continuous"; break;
4740 : }
4741 :
4742 0 : if ( pType )
4743 : m_pSerializer->singleElementNS( XML_w, XML_type,
4744 : FSNS( XML_w, XML_val ), pType,
4745 0 : FSEND );
4746 0 : }
4747 :
4748 0 : 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 0 : FSEND );
4753 0 : }
4754 :
4755 0 : void DocxAttributeOutput::EndFont() const
4756 : {
4757 0 : m_pSerializer->endElementNS( XML_w, XML_font );
4758 0 : }
4759 :
4760 0 : 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 0 : FSEND );
4765 0 : }
4766 :
4767 0 : void DocxAttributeOutput::FontCharset( sal_uInt8 nCharSet, rtl_TextEncoding nEncoding ) const
4768 : {
4769 0 : FastAttributeList* pAttr = m_pSerializer->createAttrList();
4770 :
4771 0 : OString aCharSet( OString::number( nCharSet, 16 ) );
4772 0 : if ( aCharSet.getLength() == 1 )
4773 0 : aCharSet = OString( "0" ) + aCharSet;
4774 0 : pAttr->add( FSNS( XML_w, XML_val ), aCharSet.getStr());
4775 :
4776 0 : if( GetExport().GetFilter().getVersion( ) != oox::core::ECMA_DIALECT )
4777 : {
4778 0 : if( const char* charset = rtl_getMimeCharsetFromTextEncoding( nEncoding ))
4779 0 : pAttr->add( FSNS( XML_w, XML_characterSet ), charset );
4780 : }
4781 :
4782 0 : m_pSerializer->singleElementNS( XML_w, XML_charset, XFastAttributeListRef( pAttr ));
4783 0 : }
4784 :
4785 0 : void DocxAttributeOutput::FontFamilyType( FontFamily eFamily ) const
4786 : {
4787 0 : const char *pFamily = NULL;
4788 0 : switch ( eFamily )
4789 : {
4790 0 : case FAMILY_ROMAN: pFamily = "roman"; break;
4791 0 : case FAMILY_SWISS: pFamily = "swiss"; break;
4792 0 : case FAMILY_MODERN: pFamily = "modern"; break;
4793 0 : case FAMILY_SCRIPT: pFamily = "script"; break;
4794 0 : case FAMILY_DECORATIVE: pFamily = "decorative"; break;
4795 0 : default: pFamily = "auto"; break; // no font family
4796 : }
4797 :
4798 0 : if ( pFamily )
4799 : m_pSerializer->singleElementNS( XML_w, XML_family,
4800 : FSNS( XML_w, XML_val ), pFamily,
4801 0 : FSEND );
4802 0 : }
4803 :
4804 0 : void DocxAttributeOutput::FontPitchType( FontPitch ePitch ) const
4805 : {
4806 0 : const char *pPitch = NULL;
4807 0 : switch ( ePitch )
4808 : {
4809 0 : case PITCH_VARIABLE: pPitch = "variable"; break;
4810 0 : case PITCH_FIXED: pPitch = "fixed"; break;
4811 0 : default: pPitch = "default"; break; // no info about the pitch
4812 : }
4813 :
4814 0 : if ( pPitch )
4815 : m_pSerializer->singleElementNS( XML_w, XML_pitch,
4816 : FSNS( XML_w, XML_val ), pPitch,
4817 0 : FSEND );
4818 0 : }
4819 :
4820 0 : void DocxAttributeOutput::EmbedFont( const OUString& name, FontFamily family, FontPitch pitch, rtl_TextEncoding encoding )
4821 : {
4822 0 : if( !m_rExport.pDoc->get( IDocumentSettingAccess::EMBED_FONTS ))
4823 0 : 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 0 : OString DocxAttributeOutput::TransHighlightColor( const Color& rColor )
4916 : {
4917 0 : switch (rColor.GetColor())
4918 : {
4919 0 : case 0x000000: return OString("black"); break;
4920 0 : case 0x0000ff: return OString("blue"); break;
4921 0 : case 0x00ffff: return OString("cyan"); break;
4922 0 : case 0x00ff00: return OString("green"); break;
4923 0 : case 0xff00ff: return OString("magenta"); break;
4924 0 : case 0xff0000: return OString("red"); break;
4925 0 : case 0xffff00: return OString("yellow"); break;
4926 0 : case 0xffffff: return OString("white"); break;
4927 0 : case 0x000080: return OString("darkBlue"); break;
4928 0 : case 0x008080: return OString("darkCyan"); break;
4929 0 : case 0x008000: return OString("darkGreen"); break;
4930 0 : case 0x800080: return OString("darkMagenta"); break;
4931 0 : case 0x800000: return OString("darkRed"); break;
4932 0 : case 0x808000: return OString("darkYellow"); break;
4933 0 : case 0x808080: return OString("darkGray"); break;
4934 0 : case 0xC0C0C0: return OString("lightGray"); break;
4935 0 : default: return OString(); break;
4936 : }
4937 : }
4938 :
4939 0 : 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 0 : OString aId( OString::number( nId ) );
4945 :
4946 : m_pSerializer->startElementNS( XML_w, XML_num,
4947 : FSNS( XML_w, XML_numId ), aId.getStr(),
4948 0 : FSEND );
4949 :
4950 : m_pSerializer->singleElementNS( XML_w, XML_abstractNumId,
4951 : FSNS( XML_w, XML_val ), aId.getStr(),
4952 0 : 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 0 : m_pSerializer->endElementNS( XML_w, XML_num );
4963 0 : }
4964 :
4965 0 : 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 0 : FSEND );
4970 0 : }
4971 :
4972 0 : void DocxAttributeOutput::EndAbstractNumbering()
4973 : {
4974 0 : m_pSerializer->endElementNS( XML_w, XML_abstractNum );
4975 0 : }
4976 :
4977 0 : 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 0 : 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 0 : 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 0 : FSEND );
5003 : }
5004 :
5005 : // format
5006 0 : OString aFmt( impl_NumberingType( nNumberingType ) );
5007 :
5008 0 : if ( !aFmt.isEmpty() )
5009 : m_pSerializer->singleElementNS( XML_w, XML_numFmt,
5010 : FSNS( XML_w, XML_val ), aFmt.getStr(),
5011 0 : FSEND );
5012 :
5013 : // suffix
5014 0 : const char *pSuffix = NULL;
5015 0 : switch ( nFollow )
5016 : {
5017 0 : case 1: pSuffix = "space"; break;
5018 0 : case 2: pSuffix = "nothing"; break;
5019 0 : default: /*pSuffix = "tab";*/ break;
5020 : }
5021 0 : if ( pSuffix )
5022 : m_pSerializer->singleElementNS( XML_w, XML_suff,
5023 : FSNS( XML_w, XML_val ), pSuffix,
5024 0 : FSEND );
5025 :
5026 : // text
5027 0 : OUString aText( rNumberingString );
5028 0 : OUStringBuffer aBuffer( aText.getLength() + WW8ListManager::nMaxLevel );
5029 :
5030 0 : const sal_Unicode *pPrev = aText.getStr();
5031 0 : const sal_Unicode *pIt = aText.getStr();
5032 0 : 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 0 : if ( *pIt < sal_Unicode( WW8ListManager::nMaxLevel ) )
5038 : {
5039 0 : aBuffer.append( pPrev, pIt - pPrev );
5040 0 : aBuffer.append( '%' );
5041 0 : aBuffer.append( OUString::number( sal_Int32( *pIt ) + 1 ) );
5042 :
5043 0 : pPrev = pIt + 1;
5044 : }
5045 0 : ++pIt;
5046 : }
5047 0 : if ( pPrev < pIt )
5048 0 : aBuffer.append( pPrev, pIt - pPrev );
5049 :
5050 : // If bullet char is empty, set lvlText as empty
5051 0 : if ( aText.equals ( OUString(sal_Unicode(0)) ) && nNumberingType == SVX_NUM_CHAR_SPECIAL )
5052 : {
5053 0 : m_pSerializer->singleElementNS( XML_w, XML_lvlText, FSNS( XML_w, XML_val ), "", FSEND );
5054 : }
5055 : else
5056 : {
5057 0 : 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 0 : if (nNumberingType == SVX_NUM_BITMAP && pBrush)
5062 : {
5063 0 : int nIndex = m_rExport.GetGrfIndex(*pBrush);
5064 0 : if (nIndex != -1)
5065 : {
5066 : m_pSerializer->singleElementNS(XML_w, XML_lvlPicBulletId,
5067 : FSNS(XML_w, XML_val), OString::number(nIndex).getStr(),
5068 0 : FSEND);
5069 : }
5070 : }
5071 :
5072 : // justification
5073 : const char *pJc;
5074 0 : bool ecmaDialect = ( m_rExport.GetFilter().getVersion() == oox::core::ECMA_DIALECT );
5075 0 : switch ( eAdjust )
5076 : {
5077 0 : case SVX_ADJUST_CENTER: pJc = "center"; break;
5078 0 : case SVX_ADJUST_RIGHT: pJc = !ecmaDialect ? "end" : "right"; break;
5079 0 : default: pJc = !ecmaDialect ? "start" : "left"; break;
5080 : }
5081 : m_pSerializer->singleElementNS( XML_w, XML_lvlJc,
5082 : FSNS( XML_w, XML_val ), pJc,
5083 0 : FSEND );
5084 :
5085 : // indentation
5086 0 : m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND );
5087 0 : if( nListTabPos != 0 )
5088 : {
5089 0 : 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 0 : FSEND );
5094 0 : m_pSerializer->endElementNS( XML_w, XML_tabs );
5095 : }
5096 :
5097 0 : 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 0 : FSEND );
5102 0 : m_pSerializer->endElementNS( XML_w, XML_pPr );
5103 :
5104 : // font
5105 0 : if ( pOutSet )
5106 : {
5107 0 : m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
5108 :
5109 0 : if ( pFont )
5110 : {
5111 0 : GetExport().GetId( *pFont ); // ensure font info is written to fontTable.xml
5112 0 : 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 0 : FSEND );
5119 : }
5120 0 : m_rExport.OutputItemSet( *pOutSet, false, true, i18n::ScriptType::LATIN, m_rExport.mbExportModeRTF );
5121 :
5122 0 : m_pSerializer->endElementNS( XML_w, XML_rPr );
5123 : }
5124 :
5125 : // TODO anything to do about nListTabPos?
5126 :
5127 0 : m_pSerializer->endElementNS( XML_w, XML_lvl );
5128 0 : }
5129 :
5130 0 : void DocxAttributeOutput::CharCaseMap( const SvxCaseMapItem& rCaseMap )
5131 : {
5132 0 : switch ( rCaseMap.GetValue() )
5133 : {
5134 : case SVX_CASEMAP_KAPITAELCHEN:
5135 0 : m_pSerializer->singleElementNS( XML_w, XML_smallCaps, FSEND );
5136 0 : break;
5137 : case SVX_CASEMAP_VERSALIEN:
5138 0 : m_pSerializer->singleElementNS( XML_w, XML_caps, FSEND );
5139 0 : break;
5140 : default: // Something that ooxml does not support
5141 0 : m_pSerializer->singleElementNS( XML_w, XML_smallCaps, FSNS( XML_w, XML_val ), "false", FSEND );
5142 0 : m_pSerializer->singleElementNS( XML_w, XML_caps, FSNS( XML_w, XML_val ), "false", FSEND );
5143 0 : break;
5144 : }
5145 0 : }
5146 :
5147 0 : void DocxAttributeOutput::CharColor( const SvxColorItem& rColor )
5148 : {
5149 0 : const Color aColor( rColor.GetValue() );
5150 0 : OString aColorString;
5151 :
5152 0 : aColorString = msfilter::util::ConvertColor( aColor );
5153 :
5154 0 : AddToAttrList( m_pColorAttrList, FSNS( XML_w, XML_val ), aColorString.getStr() );
5155 0 : }
5156 :
5157 0 : void DocxAttributeOutput::CharContour( const SvxContourItem& rContour )
5158 : {
5159 0 : if ( rContour.GetValue() )
5160 0 : m_pSerializer->singleElementNS( XML_w, XML_outline, FSEND );
5161 : else
5162 0 : m_pSerializer->singleElementNS( XML_w, XML_outline, FSNS( XML_w, XML_val ), "false", FSEND );
5163 0 : }
5164 :
5165 0 : void DocxAttributeOutput::CharCrossedOut( const SvxCrossedOutItem& rCrossedOut )
5166 : {
5167 0 : 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 0 : m_pSerializer->singleElementNS( XML_w, XML_dstrike, FSNS( XML_w, XML_val ), "false", FSEND );
5174 0 : m_pSerializer->singleElementNS( XML_w, XML_strike, FSNS( XML_w, XML_val ), "false", FSEND );
5175 0 : break;
5176 : default:
5177 0 : m_pSerializer->singleElementNS( XML_w, XML_strike, FSEND );
5178 0 : break;
5179 : }
5180 0 : }
5181 :
5182 0 : void DocxAttributeOutput::CharEscapement( const SvxEscapementItem& rEscapement )
5183 : {
5184 0 : OString sIss;
5185 0 : short nEsc = rEscapement.GetEsc(), nProp = rEscapement.GetProp();
5186 0 : if ( !nEsc )
5187 : {
5188 0 : sIss = OString( "baseline" );
5189 0 : nEsc = 0;
5190 0 : nProp = 100;
5191 : }
5192 0 : else if ( DFLT_ESC_PROP == nProp )
5193 : {
5194 0 : if ( DFLT_ESC_SUB == nEsc || DFLT_ESC_AUTO_SUB == nEsc )
5195 0 : sIss = OString( "subscript" );
5196 0 : else if ( DFLT_ESC_SUPER == nEsc || DFLT_ESC_AUTO_SUPER == nEsc )
5197 0 : sIss = OString( "superscript" );
5198 : }
5199 :
5200 0 : if ( !sIss.isEmpty() )
5201 : m_pSerializer->singleElementNS( XML_w, XML_vertAlign,
5202 0 : FSNS( XML_w, XML_val ), sIss.getStr(), FSEND );
5203 :
5204 0 : const SvxFontHeightItem& rItem = static_cast<const SvxFontHeightItem&>(m_rExport.GetItem(RES_CHRATR_FONTSIZE));
5205 0 : if (&rItem != NULL && (sIss.isEmpty() || sIss.match(OString("baseline"))))
5206 : {
5207 0 : long nHeight = rItem.GetHeight();
5208 0 : OString sPos = OString::number( ( nHeight * nEsc + 500 ) / 1000 );
5209 : m_pSerializer->singleElementNS( XML_w, XML_position,
5210 0 : FSNS( XML_w, XML_val ), sPos.getStr( ), FSEND );
5211 :
5212 0 : if( 100 != nProp || sIss.match( OString( "baseline" ) ) )
5213 : {
5214 0 : OString sSize = OString::number( ( nHeight * nProp + 500 ) / 1000 );
5215 : m_pSerializer->singleElementNS( XML_w, XML_sz,
5216 0 : FSNS( XML_w, XML_val ), sSize.getStr( ), FSEND );
5217 0 : }
5218 0 : }
5219 0 : }
5220 :
5221 0 : void DocxAttributeOutput::CharFont( const SvxFontItem& rFont)
5222 : {
5223 0 : GetExport().GetId( rFont ); // ensure font info is written to fontTable.xml
5224 0 : OUString sFontName(rFont.GetFamilyName());
5225 0 : OString sFontNameUtf8 = OUStringToOString(sFontName, RTL_TEXTENCODING_UTF8);
5226 : AddToAttrList( m_pFontsAttrList, 2,
5227 : FSNS( XML_w, XML_ascii ), sFontNameUtf8.getStr(),
5228 0 : FSNS( XML_w, XML_hAnsi ), sFontNameUtf8.getStr() );
5229 0 : }
5230 :
5231 0 : void DocxAttributeOutput::CharFontSize( const SvxFontHeightItem& rFontSize)
5232 : {
5233 0 : OString fontSize = OString::number( ( rFontSize.GetHeight() + 5 ) / 10 );
5234 :
5235 0 : switch ( rFontSize.Which() )
5236 : {
5237 : case RES_CHRATR_FONTSIZE:
5238 : case RES_CHRATR_CJK_FONTSIZE:
5239 0 : m_pSerializer->singleElementNS( XML_w, XML_sz, FSNS( XML_w, XML_val ), fontSize.getStr(), FSEND );
5240 0 : break;
5241 : case RES_CHRATR_CTL_FONTSIZE:
5242 0 : m_pSerializer->singleElementNS( XML_w, XML_szCs, FSNS( XML_w, XML_val ), fontSize.getStr(), FSEND );
5243 0 : break;
5244 0 : }
5245 0 : }
5246 :
5247 0 : void DocxAttributeOutput::CharKerning( const SvxKerningItem& rKerning )
5248 : {
5249 0 : OString aKerning = OString::number( rKerning.GetValue() );
5250 0 : m_pSerializer->singleElementNS( XML_w, XML_spacing, FSNS(XML_w, XML_val), aKerning.getStr(), FSEND );
5251 0 : }
5252 :
5253 0 : void DocxAttributeOutput::CharLanguage( const SvxLanguageItem& rLanguage )
5254 : {
5255 : OString aLanguageCode( OUStringToOString(
5256 0 : LanguageTag( rLanguage.GetLanguage()).getBcp47(),
5257 0 : RTL_TEXTENCODING_UTF8));
5258 :
5259 0 : switch ( rLanguage.Which() )
5260 : {
5261 : case RES_CHRATR_LANGUAGE:
5262 0 : AddToAttrList( m_pCharLangAttrList, FSNS( XML_w, XML_val ), aLanguageCode.getStr() );
5263 0 : break;
5264 : case RES_CHRATR_CJK_LANGUAGE:
5265 0 : AddToAttrList( m_pCharLangAttrList, FSNS( XML_w, XML_eastAsia ), aLanguageCode.getStr() );
5266 0 : break;
5267 : case RES_CHRATR_CTL_LANGUAGE:
5268 0 : AddToAttrList( m_pCharLangAttrList, FSNS( XML_w, XML_bidi ), aLanguageCode.getStr() );
5269 0 : break;
5270 0 : }
5271 0 : }
5272 :
5273 0 : void DocxAttributeOutput::CharPosture( const SvxPostureItem& rPosture )
5274 : {
5275 0 : if ( rPosture.GetPosture() != ITALIC_NONE )
5276 0 : m_pSerializer->singleElementNS( XML_w, XML_i, FSEND );
5277 : else
5278 0 : m_pSerializer->singleElementNS( XML_w, XML_i, FSNS( XML_w, XML_val ), "false", FSEND );
5279 0 : }
5280 :
5281 0 : void DocxAttributeOutput::CharShadow( const SvxShadowedItem& rShadow )
5282 : {
5283 0 : if ( rShadow.GetValue() )
5284 0 : m_pSerializer->singleElementNS( XML_w, XML_shadow, FSEND );
5285 : else
5286 0 : m_pSerializer->singleElementNS( XML_w, XML_shadow, FSNS( XML_w, XML_val ), "false", FSEND );
5287 0 : }
5288 :
5289 0 : void DocxAttributeOutput::CharUnderline( const SvxUnderlineItem& rUnderline )
5290 : {
5291 : const char *pUnderlineValue;
5292 :
5293 0 : switch ( rUnderline.GetLineStyle() )
5294 : {
5295 0 : case UNDERLINE_SINGLE: pUnderlineValue = "single"; break;
5296 0 : case UNDERLINE_BOLD: pUnderlineValue = "thick"; break;
5297 0 : 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 0 : default: pUnderlineValue = "none"; break;
5313 : }
5314 :
5315 0 : Color aUnderlineColor = rUnderline.GetColor();
5316 0 : bool bUnderlineHasColor = aUnderlineColor.GetTransparency() == 0;
5317 0 : 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 0 : FSEND );
5324 : }
5325 : else
5326 : {
5327 : // Underline has no color
5328 0 : m_pSerializer->singleElementNS( XML_w, XML_u, FSNS( XML_w, XML_val ), pUnderlineValue, FSEND );
5329 : }
5330 0 : }
5331 :
5332 0 : void DocxAttributeOutput::CharWeight( const SvxWeightItem& rWeight )
5333 : {
5334 0 : if ( rWeight.GetWeight() == WEIGHT_BOLD )
5335 0 : m_pSerializer->singleElementNS( XML_w, XML_b, FSEND );
5336 : else
5337 0 : m_pSerializer->singleElementNS( XML_w, XML_b, FSNS( XML_w, XML_val ), "false", FSEND );
5338 0 : }
5339 :
5340 0 : void DocxAttributeOutput::CharAutoKern( const SvxAutoKernItem& )
5341 : {
5342 : OSL_TRACE( "TODO DocxAttributeOutput::CharAutoKern()" );
5343 0 : }
5344 :
5345 0 : void DocxAttributeOutput::CharAnimatedText( const SvxBlinkItem& rBlink )
5346 : {
5347 0 : if ( rBlink.GetValue() )
5348 0 : m_pSerializer->singleElementNS(XML_w, XML_effect, FSNS( XML_w, XML_val ), "blinkBackground", FSEND );
5349 : else
5350 0 : m_pSerializer->singleElementNS(XML_w, XML_effect, FSNS( XML_w, XML_val ), "none", FSEND );
5351 0 : }
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 0 : 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 0 : 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 0 : FSEND );
5367 : }
5368 : else
5369 : {
5370 : m_pSerializer->singleElementNS( XML_w, XML_shd,
5371 0 : FSNS( XML_w, XML_fill ), msfilter::util::ConvertColor( rBrush.GetColor() ).getStr(),
5372 : FSNS( XML_w, XML_val ), "clear",
5373 0 : FSEND );
5374 : }
5375 0 : }
5376 :
5377 0 : void DocxAttributeOutput::CharFontCJK( const SvxFontItem& rFont )
5378 : {
5379 0 : OUString sFontName(rFont.GetFamilyName());
5380 0 : OString sFontNameUtf8 = OUStringToOString(sFontName, RTL_TEXTENCODING_UTF8);
5381 0 : AddToAttrList( m_pFontsAttrList, FSNS( XML_w, XML_eastAsia ), sFontNameUtf8.getStr() );
5382 0 : }
5383 :
5384 0 : void DocxAttributeOutput::CharPostureCJK( const SvxPostureItem& rPosture )
5385 : {
5386 0 : if ( rPosture.GetPosture() != ITALIC_NONE )
5387 0 : m_pSerializer->singleElementNS( XML_w, XML_i, FSEND );
5388 : else
5389 0 : m_pSerializer->singleElementNS( XML_w, XML_i, FSNS( XML_w, XML_val ), "false", FSEND );
5390 0 : }
5391 :
5392 0 : void DocxAttributeOutput::CharWeightCJK( const SvxWeightItem& rWeight )
5393 : {
5394 0 : if ( rWeight.GetWeight() == WEIGHT_BOLD )
5395 0 : m_pSerializer->singleElementNS( XML_w, XML_b, FSEND );
5396 : else
5397 0 : m_pSerializer->singleElementNS( XML_w, XML_b, FSNS( XML_w, XML_val ), "false", FSEND );
5398 0 : }
5399 :
5400 0 : void DocxAttributeOutput::CharFontCTL( const SvxFontItem& rFont )
5401 : {
5402 0 : OUString sFontName(rFont.GetFamilyName());
5403 0 : OString sFontNameUtf8 = OUStringToOString(sFontName, RTL_TEXTENCODING_UTF8);
5404 0 : AddToAttrList( m_pFontsAttrList, FSNS( XML_w, XML_cs ), sFontNameUtf8.getStr() );
5405 :
5406 0 : }
5407 :
5408 0 : void DocxAttributeOutput::CharPostureCTL( const SvxPostureItem& rPosture)
5409 : {
5410 0 : if ( rPosture.GetPosture() != ITALIC_NONE )
5411 0 : m_pSerializer->singleElementNS( XML_w, XML_iCs, FSEND );
5412 : else
5413 0 : m_pSerializer->singleElementNS( XML_w, XML_iCs, FSNS( XML_w, XML_val ), "false", FSEND );
5414 0 : }
5415 :
5416 0 : void DocxAttributeOutput::CharWeightCTL( const SvxWeightItem& rWeight )
5417 : {
5418 0 : if ( rWeight.GetWeight() == WEIGHT_BOLD )
5419 0 : m_pSerializer->singleElementNS( XML_w, XML_bCs, FSEND );
5420 : else
5421 0 : m_pSerializer->singleElementNS( XML_w, XML_bCs, FSNS( XML_w, XML_val ), "false", FSEND );
5422 0 : }
5423 :
5424 0 : void DocxAttributeOutput::CharBidiRTL( const SfxPoolItem& )
5425 : {
5426 0 : }
5427 :
5428 0 : void DocxAttributeOutput::CharIdctHint( const SfxPoolItem& )
5429 : {
5430 0 : }
5431 :
5432 0 : void DocxAttributeOutput::CharRotate( const SvxCharRotateItem& rRotate)
5433 : {
5434 : // Not rorated or we the rotation already handled?
5435 0 : if ( !rRotate.GetValue() || m_bBtLr || m_rExport.SdrExporter().getFrameBtLr())
5436 0 : 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 0 : void DocxAttributeOutput::CharEmphasisMark( const SvxEmphasisMarkItem& rEmphasisMark )
5445 : {
5446 : const char *pEmphasis;
5447 :
5448 0 : switch ( rEmphasisMark.GetValue() )
5449 : {
5450 0 : 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 0 : m_pSerializer->singleElementNS( XML_w, XML_em, FSNS( XML_w, XML_val ), pEmphasis, FSEND );
5458 0 : }
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 0 : void DocxAttributeOutput::CharScaleWidth( const SvxCharScaleWidthItem& rScaleWidth )
5486 : {
5487 : m_pSerializer->singleElementNS( XML_w, XML_w,
5488 0 : FSNS( XML_w, XML_val ), OString::number( rScaleWidth.GetValue() ).getStr(), FSEND );
5489 0 : }
5490 :
5491 0 : void DocxAttributeOutput::CharRelief( const SvxCharReliefItem& rRelief )
5492 : {
5493 0 : 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 0 : m_pSerializer->singleElementNS( XML_w, XML_emboss, FSNS( XML_w, XML_val ), "false", FSEND );
5503 0 : m_pSerializer->singleElementNS( XML_w, XML_imprint, FSNS( XML_w, XML_val ), "false", FSEND );
5504 0 : break;
5505 : }
5506 0 : }
5507 :
5508 0 : void DocxAttributeOutput::CharHidden( const SvxCharHiddenItem& rHidden )
5509 : {
5510 0 : if ( rHidden.GetValue() )
5511 0 : m_pSerializer->singleElementNS( XML_w, XML_vanish, FSEND );
5512 : else
5513 0 : m_pSerializer->singleElementNS( XML_w, XML_vanish, FSNS( XML_w, XML_val ), "false", FSEND );
5514 0 : }
5515 :
5516 0 : void DocxAttributeOutput::CharBorder(
5517 : const SvxBorderLine* pAllBorder, const sal_uInt16 nDist, const bool bShadow )
5518 : {
5519 0 : impl_borderLine( m_pSerializer, XML_bdr, pAllBorder, nDist, bShadow );
5520 0 : }
5521 :
5522 0 : void DocxAttributeOutput::CharHighlight( const SvxBrushItem& rHighlight )
5523 : {
5524 0 : const OString sColor = TransHighlightColor( rHighlight.GetColor() );
5525 0 : if ( !sColor.isEmpty() )
5526 : {
5527 : m_pSerializer->singleElementNS( XML_w, XML_highlight,
5528 0 : FSNS( XML_w, XML_val ), sColor.getStr(), FSEND );
5529 0 : }
5530 0 : }
5531 :
5532 0 : void DocxAttributeOutput::TextINetFormat( const SwFmtINetFmt& rLink )
5533 : {
5534 0 : const SwTxtINetFmt* pINetFmt = rLink.GetTxtINetFmt();
5535 0 : const SwCharFmt* pCharFmt = pINetFmt->GetCharFmt();
5536 :
5537 0 : OString aStyleId(m_rExport.pStyles->GetStyleId(m_rExport.GetId(*pCharFmt)));
5538 :
5539 0 : m_pSerializer->singleElementNS( XML_w, XML_rStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND );
5540 0 : }
5541 :
5542 0 : void DocxAttributeOutput::TextCharFormat( const SwFmtCharFmt& rCharFmt )
5543 : {
5544 0 : OString aStyleId(m_rExport.pStyles->GetStyleId(m_rExport.GetId(*rCharFmt.GetCharFmt())));
5545 :
5546 0 : m_pSerializer->singleElementNS( XML_w, XML_rStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND );
5547 0 : }
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 0 : void DocxAttributeOutput::PostitField( const SwField* pFld )
5569 : {
5570 : assert( dynamic_cast< const SwPostItField* >( pFld ));
5571 0 : const SwPostItField* pPostItFld = static_cast<const SwPostItField*>(pFld);
5572 0 : OString aName = OUStringToOString(pPostItFld->GetName(), RTL_TEXTENCODING_UTF8);
5573 0 : sal_Int32 nId = 0;
5574 0 : std::map< OString, sal_uInt16 >::iterator it = m_rOpenedAnnotationMarksIds.find(aName);
5575 0 : if (it != m_rOpenedAnnotationMarksIds.end())
5576 : // If the postit field has an annotation mark associated, we already have an id.
5577 0 : nId = it->second;
5578 : else
5579 : // Otherwise get a new one.
5580 0 : nId = m_nNextAnnotationMarkId++;
5581 0 : m_postitFields.push_back(std::make_pair(pPostItFld, nId));
5582 0 : }
5583 :
5584 0 : void DocxAttributeOutput::WritePostitFieldReference()
5585 : {
5586 0 : while( m_postitFieldsMaxId < m_postitFields.size())
5587 : {
5588 0 : 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 0 : OString idname = OUStringToOString(m_postitFields[m_postitFieldsMaxId].first->GetName(), RTL_TEXTENCODING_UTF8);
5593 0 : std::map< OString, sal_uInt16 >::iterator it = m_rOpenedAnnotationMarksIds.find( idname );
5594 0 : if ( it == m_rOpenedAnnotationMarksIds.end( ) )
5595 0 : m_pSerializer->singleElementNS( XML_w, XML_commentReference, FSNS( XML_w, XML_id ), idstr.getStr(), FSEND );
5596 0 : ++m_postitFieldsMaxId;
5597 0 : }
5598 0 : }
5599 :
5600 0 : void DocxAttributeOutput::WritePostitFields()
5601 : {
5602 0 : for( unsigned int i = 0;
5603 0 : i < m_postitFields.size();
5604 : ++i )
5605 : {
5606 0 : OString idstr = OString::number( m_postitFields[ i ].second);
5607 0 : const SwPostItField* f = m_postitFields[ i ].first;
5608 : m_pSerializer->startElementNS( XML_w, XML_comment, FSNS( XML_w, XML_id ), idstr.getStr(),
5609 0 : FSNS( XML_w, XML_author ), OUStringToOString( f->GetPar1(), RTL_TEXTENCODING_UTF8 ).getStr(),
5610 : FSNS( XML_w, XML_date ), DateTimeToOString(f->GetDateTime()).getStr(),
5611 0 : 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 0 : if( f->GetTextObject() != NULL )
5616 0 : GetExport().WriteOutliner( *f->GetTextObject(), TXT_ATN );
5617 0 : m_pSerializer->endElementNS( XML_w, XML_comment );
5618 0 : }
5619 0 : }
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 0 : void DocxAttributeOutput::WritePendingPlaceholder()
5640 : {
5641 0 : if( pendingPlaceholder == NULL )
5642 0 : 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 0 : void DocxAttributeOutput::WriteExpand( const SwField* pFld )
5669 : {
5670 : // Will be written in the next End Run
5671 0 : OUString sCmd;
5672 0 : m_rExport.OutputField( pFld, ww::eUNKNOWN, sCmd );
5673 0 : }
5674 :
5675 0 : void DocxAttributeOutput::WriteField_Impl( const SwField* pFld, ww::eField eType, const OUString& rFldCmd, sal_uInt8 nMode )
5676 : {
5677 0 : struct FieldInfos infos;
5678 0 : if (pFld)
5679 0 : infos.pField = pFld->CopyField();
5680 0 : infos.sCmd = rFldCmd;
5681 0 : infos.eType = eType;
5682 0 : infos.bClose = WRITEFIELD_CLOSE & nMode;
5683 0 : infos.bOpen = WRITEFIELD_START & nMode;
5684 0 : m_Fields.push_back( infos );
5685 :
5686 0 : if ( pFld )
5687 : {
5688 0 : sal_uInt16 nType = pFld->GetTyp( )->Which( );
5689 0 : sal_uInt16 nSubType = pFld->GetSubType();
5690 :
5691 : // TODO Any other field types here ?
5692 0 : 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 0 : else if ( nType == RES_DROPDOWN )
5698 : {
5699 0 : const SwDropDownField* pDropDown = ( const SwDropDownField* )( pFld );
5700 0 : m_sFieldBkm = pDropDown->GetName( );
5701 : }
5702 0 : }
5703 0 : }
5704 :
5705 0 : void DocxAttributeOutput::WriteFormData_Impl( const ::sw::mark::IFieldmark& rFieldmark )
5706 : {
5707 0 : if ( !m_Fields.empty() )
5708 0 : m_Fields.begin()->pFieldmark = &rFieldmark;
5709 0 : }
5710 :
5711 0 : void DocxAttributeOutput::WriteBookmarks_Impl( std::vector< OUString >& rStarts,
5712 : std::vector< OUString >& rEnds )
5713 : {
5714 0 : for ( std::vector< OUString >::const_iterator it = rStarts.begin(), end = rStarts.end(); it != end; ++it )
5715 : {
5716 0 : OString rName = OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr( );
5717 0 : m_rBookmarksStart.push_back( rName );
5718 0 : }
5719 0 : rStarts.clear();
5720 :
5721 0 : for ( std::vector< OUString >::const_iterator it = rEnds.begin(), end = rEnds.end(); it != end; ++it )
5722 : {
5723 0 : OString rName = OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr( );
5724 0 : m_rBookmarksEnd.push_back( rName );
5725 0 : }
5726 0 : rEnds.clear();
5727 0 : }
5728 :
5729 0 : void DocxAttributeOutput::WriteAnnotationMarks_Impl( std::vector< OUString >& rStarts,
5730 : std::vector< OUString >& rEnds )
5731 : {
5732 0 : for ( std::vector< OUString >::const_iterator it = rStarts.begin(), end = rStarts.end(); it != end; ++it )
5733 : {
5734 0 : OString rName = OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr( );
5735 0 : m_rAnnotationMarksStart.push_back( rName );
5736 0 : }
5737 0 : rStarts.clear();
5738 :
5739 0 : for ( std::vector< OUString >::const_iterator it = rEnds.begin(), end = rEnds.end(); it != end; ++it )
5740 : {
5741 0 : OString rName = OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr( );
5742 0 : m_rAnnotationMarksEnd.push_back( rName );
5743 0 : }
5744 0 : rEnds.clear();
5745 0 : }
5746 :
5747 0 : void DocxAttributeOutput::TextFootnote_Impl( const SwFmtFtn& rFootnote )
5748 : {
5749 0 : const SwEndNoteInfo& rInfo = rFootnote.IsEndNote()?
5750 0 : m_rExport.pDoc->GetEndNoteInfo(): m_rExport.pDoc->GetFtnInfo();
5751 :
5752 : // footnote/endnote run properties
5753 0 : const SwCharFmt* pCharFmt = rInfo.GetAnchorCharFmt( *m_rExport.pDoc );
5754 :
5755 0 : OString aStyleId(m_rExport.pStyles->GetStyleId(m_rExport.GetId(*pCharFmt)));
5756 :
5757 0 : 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 0 : if ( !rFootnote.IsEndNote() )
5763 0 : m_pFootnotesList->add( rFootnote );
5764 : else
5765 0 : m_pEndnotesList->add( rFootnote );
5766 0 : }
5767 :
5768 0 : void DocxAttributeOutput::FootnoteEndnoteReference()
5769 : {
5770 : sal_Int32 nId;
5771 0 : 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 0 : if ( !pFootnote )
5775 0 : pFootnote = m_pEndnotesList->getCurrent( nId );
5776 :
5777 0 : if ( !pFootnote )
5778 0 : return;
5779 :
5780 0 : sal_Int32 nToken = pFootnote->IsEndNote()? XML_endnoteReference: XML_footnoteReference;
5781 :
5782 : // write it
5783 0 : 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 0 : 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 0 : void DocxAttributeOutput::FootnotesEndnotes( bool bFootnotes )
5803 : {
5804 0 : m_setFootnote = true;
5805 0 : const FootnotesVector& rVector = bFootnotes? m_pFootnotesList->getVector(): m_pEndnotesList->getVector();
5806 :
5807 0 : sal_Int32 nBody = bFootnotes? XML_footnotes: XML_endnotes;
5808 0 : 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 0 : FSEND );
5814 :
5815 0 : 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 0 : FSEND );
5822 0 : m_pSerializer->startElementNS( XML_w, XML_p, FSEND );
5823 0 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
5824 :
5825 0 : bool bSeparator = true;
5826 0 : if (bFootnotes)
5827 : {
5828 0 : const SwPageFtnInfo& rFtnInfo = m_rExport.pDoc->GetPageDesc(0).GetFtnInfo();
5829 : // Request a separator only in case the width is larger than zero.
5830 0 : bSeparator = double(rFtnInfo.GetWidth()) > 0;
5831 : }
5832 :
5833 0 : if (bSeparator)
5834 0 : m_pSerializer->singleElementNS( XML_w, XML_separator, FSEND );
5835 0 : m_pSerializer->endElementNS( XML_w, XML_r );
5836 0 : m_pSerializer->endElementNS( XML_w, XML_p );
5837 0 : 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 0 : FSEND );
5844 0 : m_pSerializer->startElementNS( XML_w, XML_p, FSEND );
5845 0 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
5846 0 : m_pSerializer->singleElementNS( XML_w, XML_continuationSeparator, FSEND );
5847 0 : m_pSerializer->endElementNS( XML_w, XML_r );
5848 0 : m_pSerializer->endElementNS( XML_w, XML_p );
5849 0 : m_pSerializer->endElementNS( XML_w, nItem );
5850 :
5851 : // if new special ones are added, update also WriteFootnoteEndnotePr()
5852 :
5853 : // footnotes/endnotes themselves
5854 0 : 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 0 : FSEND );
5859 :
5860 0 : const SwNodeIndex* pIndex = (*i)->GetTxtFtn()->GetStartNode();
5861 : // tag required at the start of each footnote/endnote
5862 0 : m_footnoteEndnoteRefTag = bFootnotes ? XML_footnoteRef : XML_endnoteRef;
5863 :
5864 0 : m_rExport.WriteSpecialText( pIndex->GetIndex() + 1,
5865 0 : pIndex->GetNode().EndOfSectionIndex(),
5866 0 : bFootnotes? TXT_FTN: TXT_EDN );
5867 :
5868 0 : m_pSerializer->endElementNS( XML_w, nItem );
5869 : }
5870 :
5871 0 : m_pSerializer->endElementNS( XML_w, nBody );
5872 :
5873 0 : }
5874 :
5875 0 : void DocxAttributeOutput::WriteFootnoteEndnotePr( ::sax_fastparser::FSHelperPtr fs, int tag,
5876 : const SwEndNoteInfo& info, int listtag )
5877 : {
5878 0 : fs->startElementNS( XML_w, tag, FSEND );
5879 0 : const char* fmt = NULL;
5880 0 : 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 0 : fmt = "lowerRoman";
5895 0 : break;
5896 : case SVX_NUM_ARABIC:
5897 0 : fmt = "decimal";
5898 0 : 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 0 : if( fmt != NULL )
5911 0 : fs->singleElementNS( XML_w, XML_numFmt, FSNS( XML_w, XML_val ), fmt, FSEND );
5912 0 : 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 0 : 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 0 : fs->singleElementNS( XML_w, listtag, FSNS( XML_w, XML_id ), "0", FSEND );
5918 0 : fs->singleElementNS( XML_w, listtag, FSNS( XML_w, XML_id ), "1", FSEND );
5919 : }
5920 0 : fs->endElementNS( XML_w, tag );
5921 0 : }
5922 :
5923 0 : void DocxAttributeOutput::SectFootnoteEndnotePr()
5924 : {
5925 0 : if( HasFootnotes())
5926 0 : WriteFootnoteEndnotePr( m_pSerializer, XML_footnotePr, m_rExport.pDoc->GetFtnInfo(), 0 );
5927 0 : if( HasEndnotes())
5928 0 : WriteFootnoteEndnotePr( m_pSerializer, XML_endnotePr, m_rExport.pDoc->GetEndNoteInfo(), 0 );
5929 0 : }
5930 :
5931 0 : void DocxAttributeOutput::ParaLineSpacing_Impl( short nSpace, short nMulti )
5932 : {
5933 0 : if ( nSpace < 0 )
5934 : {
5935 : AddToAttrList( m_pParagraphSpacingAttrList, 2,
5936 : FSNS( XML_w, XML_lineRule ), "exact",
5937 0 : FSNS( XML_w, XML_line ), OString::number( -nSpace ).getStr() );
5938 : }
5939 0 : else if( nMulti )
5940 : {
5941 : AddToAttrList( m_pParagraphSpacingAttrList, 2,
5942 : FSNS( XML_w, XML_lineRule ), "auto",
5943 0 : FSNS( XML_w, XML_line ), OString::number( nSpace ).getStr() );
5944 : }
5945 0 : else if ( nSpace > 0 )
5946 : {
5947 : AddToAttrList( m_pParagraphSpacingAttrList, 2,
5948 : FSNS( XML_w, XML_lineRule ), "atLeast",
5949 0 : FSNS( XML_w, XML_line ), OString::number( nSpace ).getStr() );
5950 : }
5951 : else
5952 0 : AddToAttrList( m_pParagraphSpacingAttrList, FSNS( XML_w, XML_lineRule ), "auto" );
5953 0 : }
5954 :
5955 0 : void DocxAttributeOutput::ParaAdjust( const SvxAdjustItem& rAdjust )
5956 : {
5957 : const char *pAdjustString;
5958 :
5959 0 : bool bEcma = GetExport().GetFilter().getVersion( ) == oox::core::ECMA_DIALECT;
5960 :
5961 0 : const SfxItemSet* pItems = GetExport().GetCurItemSet();
5962 : const SvxFrameDirectionItem* rFrameDir = pItems?
5963 0 : static_cast< const SvxFrameDirectionItem* >( pItems->GetItem( RES_FRAMEDIR ) ): NULL;
5964 :
5965 0 : short nDir = FRMDIR_ENVIRONMENT;
5966 0 : if( rFrameDir != NULL )
5967 0 : nDir = rFrameDir->GetValue();
5968 0 : if ( nDir == FRMDIR_ENVIRONMENT )
5969 0 : nDir = GetExport( ).GetDefaultFrameDirection( );
5970 0 : bool bRtl = ( nDir == FRMDIR_HORI_RIGHT_TOP );
5971 :
5972 0 : switch ( rAdjust.GetAdjust() )
5973 : {
5974 : case SVX_ADJUST_LEFT:
5975 0 : if ( bEcma )
5976 : {
5977 0 : if ( bRtl )
5978 0 : pAdjustString = "right";
5979 : else
5980 0 : pAdjustString = "left";
5981 : }
5982 0 : else if ( bRtl )
5983 0 : pAdjustString = "end";
5984 : else
5985 0 : pAdjustString = "start";
5986 0 : break;
5987 : case SVX_ADJUST_RIGHT:
5988 0 : if ( bEcma )
5989 : {
5990 0 : if ( bRtl )
5991 0 : pAdjustString = "left";
5992 : else
5993 0 : pAdjustString = "right";
5994 : }
5995 0 : else if ( bRtl )
5996 0 : pAdjustString = "start";
5997 : else
5998 0 : pAdjustString = "end";
5999 0 : break;
6000 : case SVX_ADJUST_BLOCKLINE:
6001 : case SVX_ADJUST_BLOCK:
6002 0 : pAdjustString = "both";
6003 0 : break;
6004 : case SVX_ADJUST_CENTER:
6005 0 : pAdjustString = "center";
6006 0 : break;
6007 : default:
6008 0 : return; // not supported attribute
6009 : }
6010 0 : m_pSerializer->singleElementNS( XML_w, XML_jc, FSNS( XML_w, XML_val ), pAdjustString, FSEND );
6011 : }
6012 :
6013 0 : void DocxAttributeOutput::ParaSplit( const SvxFmtSplitItem& rSplit )
6014 : {
6015 0 : if (rSplit.GetValue())
6016 0 : m_pSerializer->singleElementNS( XML_w, XML_keepLines, FSNS( XML_w, XML_val ), "false", FSEND );
6017 : else
6018 0 : m_pSerializer->singleElementNS( XML_w, XML_keepLines, FSEND );
6019 0 : }
6020 :
6021 0 : void DocxAttributeOutput::ParaWidows( const SvxWidowsItem& rWidows )
6022 : {
6023 0 : if (rWidows.GetValue())
6024 0 : m_pSerializer->singleElementNS( XML_w, XML_widowControl, FSEND );
6025 : else
6026 0 : m_pSerializer->singleElementNS( XML_w, XML_widowControl, FSNS( XML_w, XML_val ), "false", FSEND );
6027 0 : }
6028 :
6029 0 : static void impl_WriteTabElement( FSHelperPtr pSerializer,
6030 : const SvxTabStop& rTab, long /* nCurrentLeft */ )
6031 : {
6032 0 : FastAttributeList *pTabElementAttrList = pSerializer->createAttrList();
6033 :
6034 0 : switch (rTab.GetAdjustment())
6035 : {
6036 : case SVX_TAB_ADJUST_RIGHT:
6037 0 : pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"right") );
6038 0 : break;
6039 : case SVX_TAB_ADJUST_DECIMAL:
6040 0 : pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"decimal") );
6041 0 : break;
6042 : case SVX_TAB_ADJUST_CENTER:
6043 0 : pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"center") );
6044 0 : break;
6045 : case SVX_TAB_ADJUST_DEFAULT:
6046 : case SVX_TAB_ADJUST_LEFT:
6047 : default:
6048 0 : pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"left") );
6049 0 : 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 0 : pTabElementAttrList->add( FSNS( XML_w, XML_pos ), OString::number( rTab.GetTabPos() ) );
6055 :
6056 0 : sal_Unicode cFillChar = rTab.GetFill();
6057 :
6058 0 : if ('.' == cFillChar )
6059 0 : pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "dot" ) );
6060 0 : else if ( '-' == cFillChar )
6061 0 : pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "hyphen" ) );
6062 0 : else if ( sal_Unicode(0xB7) == cFillChar ) // middle dot
6063 0 : pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "middleDot" ) );
6064 0 : else if ( '_' == cFillChar )
6065 0 : pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "underscore" ) );
6066 : else
6067 0 : pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "none" ) );
6068 :
6069 0 : pSerializer->singleElementNS( XML_w, XML_tab, pTabElementAttrList );
6070 0 : }
6071 :
6072 0 : void DocxAttributeOutput::ParaTabStop( const SvxTabStopItem& rTabStop )
6073 : {
6074 0 : const SfxPoolItem* pLR = m_rExport.HasItem( RES_LR_SPACE );
6075 0 : long nCurrentLeft = pLR ? ((const SvxLRSpaceItem*)pLR)->GetTxtLeft() : 0;
6076 :
6077 0 : sal_uInt16 nCount = rTabStop.Count();
6078 :
6079 : // <w:tabs> must contain at least one <w:tab>, so don't write it empty
6080 0 : if( nCount == 0 )
6081 0 : return;
6082 0 : if( nCount == 1 && rTabStop[ 0 ].GetAdjustment() == SVX_TAB_ADJUST_DEFAULT )
6083 : {
6084 0 : GetExport().setDefaultTabStop( rTabStop[ 0 ].GetTabPos());
6085 0 : return;
6086 : }
6087 :
6088 0 : m_pSerializer->startElementNS( XML_w, XML_tabs, FSEND );
6089 :
6090 0 : for (sal_uInt16 i = 0; i < nCount; i++ )
6091 : {
6092 0 : if( rTabStop[i].GetAdjustment() != SVX_TAB_ADJUST_DEFAULT )
6093 0 : impl_WriteTabElement( m_pSerializer, rTabStop[i], nCurrentLeft );
6094 : else
6095 0 : GetExport().setDefaultTabStop( rTabStop[i].GetTabPos());
6096 : }
6097 :
6098 0 : m_pSerializer->endElementNS( XML_w, XML_tabs );
6099 : }
6100 :
6101 0 : void DocxAttributeOutput::ParaHyphenZone( const SvxHyphenZoneItem& rHyphenZone )
6102 : {
6103 : m_pSerializer->singleElementNS( XML_w, XML_suppressAutoHyphens,
6104 0 : FSNS( XML_w, XML_val ), rHyphenZone.IsHyphen( ) ? "false" : "true" ,
6105 0 : FSEND );
6106 0 : }
6107 :
6108 0 : void DocxAttributeOutput::ParaNumRule_Impl( const SwTxtNode* /*pTxtNd*/, sal_Int32 nLvl, sal_Int32 nNumId )
6109 : {
6110 0 : if ( USHRT_MAX != nNumId && 0 != nNumId )
6111 : {
6112 0 : m_pSerializer->startElementNS( XML_w, XML_numPr, FSEND );
6113 0 : m_pSerializer->singleElementNS( XML_w, XML_ilvl, FSNS( XML_w, XML_val ), OString::number( nLvl).getStr(), FSEND );
6114 0 : m_pSerializer->singleElementNS( XML_w, XML_numId, FSNS( XML_w, XML_val ), OString::number( nNumId).getStr(), FSEND );
6115 0 : m_pSerializer->endElementNS( XML_w, XML_numPr );
6116 : }
6117 0 : }
6118 :
6119 0 : void DocxAttributeOutput::ParaScriptSpace( const SfxBoolItem& rScriptSpace )
6120 : {
6121 : m_pSerializer->singleElementNS( XML_w, XML_autoSpaceDE,
6122 0 : FSNS( XML_w, XML_val ), rScriptSpace.GetValue( ) ? "true": "false",
6123 0 : FSEND );
6124 0 : }
6125 :
6126 0 : void DocxAttributeOutput::ParaHangingPunctuation( const SfxBoolItem& rItem )
6127 : {
6128 : m_pSerializer->singleElementNS( XML_w, XML_overflowPunct,
6129 0 : FSNS( XML_w, XML_val ), rItem.GetValue( ) ? "true": "false",
6130 0 : FSEND );
6131 0 : }
6132 :
6133 0 : void DocxAttributeOutput::ParaForbiddenRules( const SfxBoolItem& rItem )
6134 : {
6135 : m_pSerializer->singleElementNS( XML_w, XML_kinsoku,
6136 0 : FSNS( XML_w, XML_val ), rItem.GetValue( ) ? "true": "false",
6137 0 : FSEND );
6138 0 : }
6139 :
6140 0 : void DocxAttributeOutput::ParaVerticalAlign( const SvxParaVertAlignItem& rAlign )
6141 : {
6142 : const char *pAlignString;
6143 :
6144 0 : switch ( rAlign.GetValue() )
6145 : {
6146 : case SvxParaVertAlignItem::BASELINE:
6147 0 : pAlignString = "baseline";
6148 0 : 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 0 : return; // not supported attribute
6163 : }
6164 0 : 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 0 : void DocxAttributeOutput::FormatFrameSize( const SwFmtFrmSize& rSize )
6175 : {
6176 0 : if (m_rExport.SdrExporter().getTextFrameSyntax() && m_rExport.SdrExporter().getFlyFrameSize())
6177 : {
6178 0 : const Size* pSize = m_rExport.SdrExporter().getFlyFrameSize();
6179 0 : m_rExport.SdrExporter().getTextFrameStyle().append(";width:").append(double(pSize->Width()) / 20);
6180 0 : m_rExport.SdrExporter().getTextFrameStyle().append("pt;height:").append(double(pSize->Height()) / 20).append("pt");
6181 : }
6182 0 : else if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
6183 : {
6184 : }
6185 0 : 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 0 : else if ( m_rExport.bOutPageDescs )
6202 : {
6203 0 : FastAttributeList *attrList = m_pSerializer->createAttrList( );
6204 0 : if ( m_rExport.pAktPageDesc->GetLandscape( ) )
6205 0 : attrList->add( FSNS( XML_w, XML_orient ), "landscape" );
6206 :
6207 0 : attrList->add( FSNS( XML_w, XML_w ), OString::number( rSize.GetWidth( ) ) );
6208 0 : attrList->add( FSNS( XML_w, XML_h ), OString::number( rSize.GetHeight( ) ) );
6209 :
6210 0 : XFastAttributeListRef xAttrList( attrList );
6211 0 : attrList = NULL;
6212 :
6213 0 : m_pSerializer->singleElementNS( XML_w, XML_pgSz, xAttrList );
6214 : }
6215 0 : }
6216 :
6217 0 : void DocxAttributeOutput::FormatPaperBin( const SvxPaperBinItem& )
6218 : {
6219 : OSL_TRACE( "TODO DocxAttributeOutput::FormatPaperBin()" );
6220 0 : }
6221 :
6222 0 : void DocxAttributeOutput::FormatLRSpace( const SvxLRSpaceItem& rLRSpace )
6223 : {
6224 0 : bool bEcma = m_rExport.GetFilter().getVersion( ) == oox::core::ECMA_DIALECT;
6225 :
6226 0 : if (m_rExport.SdrExporter().getTextFrameSyntax())
6227 : {
6228 0 : m_rExport.SdrExporter().getTextFrameStyle().append(";mso-wrap-distance-left:").append(double(rLRSpace.GetLeft()) / 20).append("pt");
6229 0 : m_rExport.SdrExporter().getTextFrameStyle().append(";mso-wrap-distance-right:").append(double(rLRSpace.GetRight()) / 20).append("pt");
6230 : }
6231 0 : else if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
6232 : {
6233 : }
6234 0 : 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 0 : else if ( m_rExport.bOutPageDescs )
6241 : {
6242 0 : m_pageMargins.nPageMarginLeft = 0;
6243 0 : m_pageMargins.nPageMarginRight = 0;
6244 :
6245 0 : const SfxPoolItem* pItem = m_rExport.HasItem( RES_BOX );
6246 0 : if ( pItem )
6247 : {
6248 0 : m_pageMargins.nPageMarginRight = ((SvxBoxItem*)pItem)->CalcLineSpace( BOX_LINE_LEFT );
6249 0 : m_pageMargins.nPageMarginLeft = ((SvxBoxItem*)pItem)->CalcLineSpace( BOX_LINE_RIGHT );
6250 : }
6251 : else
6252 0 : m_pageMargins.nPageMarginLeft = m_pageMargins.nPageMarginRight = 0;
6253 :
6254 0 : m_pageMargins.nPageMarginLeft = m_pageMargins.nPageMarginLeft + (sal_uInt16)rLRSpace.GetLeft();
6255 0 : 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 0 : FSNS( XML_w, XML_right ), OString::number( m_pageMargins.nPageMarginRight ).getStr() );
6260 : }
6261 : else
6262 : {
6263 0 : FastAttributeList *pLRSpaceAttrList = m_pSerializer->createAttrList();
6264 0 : if((0 != rLRSpace.GetTxtLeft()) || ((0 == rLRSpace.GetTxtLeft()) && rLRSpace.IsExplicitZeroMarginValLeft()))
6265 : {
6266 0 : pLRSpaceAttrList->add( FSNS( XML_w, ( bEcma ? XML_left : XML_start ) ), OString::number( rLRSpace.GetTxtLeft() ) );
6267 : }
6268 0 : if((0 != rLRSpace.GetRight()) || ((0 == rLRSpace.GetRight()) && rLRSpace.IsExplicitZeroMarginValRight()))
6269 : {
6270 0 : pLRSpaceAttrList->add( FSNS( XML_w, ( bEcma ? XML_right : XML_end ) ), OString::number( rLRSpace.GetRight() ) );
6271 : }
6272 0 : sal_Int32 nFirstLineAdjustment = rLRSpace.GetTxtFirstLineOfst();
6273 0 : if (nFirstLineAdjustment > 0)
6274 0 : pLRSpaceAttrList->add( FSNS( XML_w, XML_firstLine ), OString::number( nFirstLineAdjustment ) );
6275 : else
6276 0 : pLRSpaceAttrList->add( FSNS( XML_w, XML_hanging ), OString::number( - nFirstLineAdjustment ) );
6277 0 : m_pSerializer->singleElementNS( XML_w, XML_ind, pLRSpaceAttrList );
6278 : }
6279 0 : }
6280 :
6281 0 : void DocxAttributeOutput::FormatULSpace( const SvxULSpaceItem& rULSpace )
6282 : {
6283 :
6284 0 : if (m_rExport.SdrExporter().getTextFrameSyntax())
6285 : {
6286 0 : m_rExport.SdrExporter().getTextFrameStyle().append(";mso-wrap-distance-top:").append(double(rULSpace.GetUpper()) / 20).append("pt");
6287 0 : m_rExport.SdrExporter().getTextFrameStyle().append(";mso-wrap-distance-bottom:").append(double(rULSpace.GetLower()) / 20).append("pt");
6288 : }
6289 0 : else if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
6290 : {
6291 : }
6292 0 : 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 0 : else if (m_rExport.bOutPageDescs )
6299 : {
6300 : OSL_ENSURE( m_rExport.GetCurItemSet(), "Impossible" );
6301 0 : if ( !m_rExport.GetCurItemSet() )
6302 0 : return;
6303 :
6304 0 : HdFtDistanceGlue aDistances( *m_rExport.GetCurItemSet() );
6305 :
6306 0 : sal_Int32 nHeader = 0;
6307 0 : if ( aDistances.HasHeader() )
6308 0 : nHeader = sal_Int32( aDistances.dyaHdrTop );
6309 :
6310 : // Page top
6311 0 : m_pageMargins.nPageMarginTop = aDistances.dyaTop;
6312 :
6313 0 : sal_Int32 nFooter = 0;
6314 0 : if ( aDistances.HasFooter() )
6315 0 : nFooter = sal_Int32( aDistances.dyaHdrBottom );
6316 :
6317 : // Page Bottom
6318 0 : 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 0 : 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 0 : if (m_bParaBeforeAutoSpacing && m_nParaBeforeSpacing == rULSpace.GetUpper())
6334 : {
6335 : AddToAttrList( m_pParagraphSpacingAttrList,
6336 0 : FSNS( XML_w, XML_beforeAutospacing ), "1" );
6337 : }
6338 0 : else if (m_bParaBeforeAutoSpacing && m_nParaBeforeSpacing == -1)
6339 : {
6340 : AddToAttrList( m_pParagraphSpacingAttrList,
6341 0 : FSNS( XML_w, XML_beforeAutospacing ), "0" );
6342 : AddToAttrList( m_pParagraphSpacingAttrList,
6343 0 : FSNS( XML_w, XML_before ), OString::number( rULSpace.GetUpper() ).getStr() );
6344 : }
6345 : else
6346 : {
6347 : AddToAttrList( m_pParagraphSpacingAttrList,
6348 0 : FSNS( XML_w, XML_before ), OString::number( rULSpace.GetUpper() ).getStr() );
6349 : }
6350 0 : m_bParaBeforeAutoSpacing = false;
6351 : // check if after auto spacing was set during import and spacing we get from actual object is same
6352 : // that we set in import. If yes just write afterAutoSpacing tag.
6353 0 : if (m_bParaAfterAutoSpacing && m_nParaAfterSpacing == rULSpace.GetLower())
6354 : {
6355 : AddToAttrList( m_pParagraphSpacingAttrList,
6356 0 : FSNS( XML_w, XML_afterAutospacing ), "1" );
6357 : }
6358 0 : else if (m_bParaAfterAutoSpacing && m_nParaAfterSpacing == -1)
6359 : {
6360 : AddToAttrList( m_pParagraphSpacingAttrList,
6361 0 : FSNS( XML_w, XML_afterAutospacing ), "0" );
6362 : AddToAttrList( m_pParagraphSpacingAttrList,
6363 0 : FSNS( XML_w, XML_after ), OString::number( rULSpace.GetLower()).getStr() );
6364 : }
6365 : else
6366 : {
6367 : AddToAttrList( m_pParagraphSpacingAttrList,
6368 0 : FSNS( XML_w, XML_after ), OString::number( rULSpace.GetLower()).getStr() );
6369 : }
6370 0 : m_bParaAfterAutoSpacing = false;
6371 :
6372 0 : if (rULSpace.GetContext())
6373 0 : m_pSerializer->singleElementNS( XML_w, XML_contextualSpacing, FSEND );
6374 : }
6375 : }
6376 :
6377 0 : void DocxAttributeOutput::FormatSurround( const SwFmtSurround& rSurround )
6378 : {
6379 0 : if (m_rExport.SdrExporter().getTextFrameSyntax())
6380 : {
6381 0 : OString sType, sSide;
6382 0 : switch (rSurround.GetSurround())
6383 : {
6384 : case SURROUND_NONE:
6385 0 : sType = "topAndBottom";
6386 0 : break;
6387 : case SURROUND_PARALLEL:
6388 0 : sType = "square";
6389 0 : break;
6390 : case SURROUND_IDEAL:
6391 0 : sType = "square";
6392 0 : sSide = "largest";
6393 0 : break;
6394 : case SURROUND_LEFT:
6395 0 : sType = "square";
6396 0 : sSide = "left";
6397 0 : break;
6398 : case SURROUND_RIGHT:
6399 0 : sType = "square";
6400 0 : sSide = "right";
6401 0 : break;
6402 : case SURROUND_THROUGHT:
6403 : /* empty type and side means throught */
6404 : default:
6405 0 : break;
6406 : }
6407 0 : if (!sType.isEmpty() || !sSide.isEmpty())
6408 : {
6409 0 : m_rExport.SdrExporter().setFlyWrapAttrList(m_pSerializer->createAttrList());
6410 0 : if (!sType.isEmpty())
6411 0 : m_rExport.SdrExporter().getFlyWrapAttrList()->add(XML_type, sType);
6412 0 : if (!sSide.isEmpty())
6413 0 : m_rExport.SdrExporter().getFlyWrapAttrList()->add(XML_side, sSide);
6414 0 : }
6415 : }
6416 0 : else if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
6417 : {
6418 : }
6419 0 : else if ( m_rExport.bOutFlyFrmAttrs )
6420 : {
6421 0 : OString sWrap( "auto" );
6422 0 : switch ( rSurround.GetSurround( ) )
6423 : {
6424 : case SURROUND_NONE:
6425 0 : sWrap = OString( "none" );
6426 0 : break;
6427 : case SURROUND_THROUGHT:
6428 0 : sWrap = OString( "through" );
6429 0 : break;
6430 : case SURROUND_IDEAL:
6431 : case SURROUND_PARALLEL:
6432 : case SURROUND_LEFT:
6433 : case SURROUND_RIGHT:
6434 : default:
6435 0 : sWrap = OString( "around" );
6436 : }
6437 :
6438 0 : AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), FSNS( XML_w, XML_wrap ), sWrap.getStr() );
6439 : }
6440 0 : }
6441 :
6442 0 : void DocxAttributeOutput::FormatVertOrientation( const SwFmtVertOrient& rFlyVert )
6443 : {
6444 0 : if (m_rExport.SdrExporter().getTextFrameSyntax())
6445 : {
6446 0 : m_rExport.SdrExporter().getTextFrameStyle().append(";margin-top:").append(double(rFlyVert.GetPos()) / 20).append("pt");
6447 : }
6448 0 : else if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
6449 : {
6450 : }
6451 0 : else if ( m_rExport.bOutFlyFrmAttrs )
6452 : {
6453 0 : OString sAlign;
6454 0 : switch( rFlyVert.GetVertOrient() )
6455 : {
6456 : case text::VertOrientation::NONE:
6457 0 : break;
6458 : case text::VertOrientation::CENTER:
6459 : case text::VertOrientation::LINE_CENTER:
6460 0 : sAlign = OString( "center" );
6461 0 : break;
6462 : case text::VertOrientation::BOTTOM:
6463 : case text::VertOrientation::LINE_BOTTOM:
6464 0 : sAlign = OString( "bottom" );
6465 0 : break;
6466 : case text::VertOrientation::TOP:
6467 : case text::VertOrientation::LINE_TOP:
6468 : default:
6469 0 : sAlign = OString( "top" );
6470 0 : break;
6471 : }
6472 :
6473 0 : if ( !sAlign.isEmpty() )
6474 0 : AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), FSNS( XML_w, XML_yAlign ), sAlign.getStr() );
6475 : else
6476 0 : AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), FSNS( XML_w, XML_y ),
6477 0 : OString::number( rFlyVert.GetPos() ).getStr() );
6478 :
6479 0 : OString sVAnchor( "page" );
6480 0 : switch ( rFlyVert.GetRelationOrient( ) )
6481 : {
6482 : case text::RelOrientation::CHAR:
6483 : case text::RelOrientation::PRINT_AREA:
6484 : case text::RelOrientation::TEXT_LINE:
6485 0 : sVAnchor = OString( "column" );
6486 0 : break;
6487 : case text::RelOrientation::FRAME:
6488 : case text::RelOrientation::PAGE_LEFT:
6489 : case text::RelOrientation::PAGE_RIGHT:
6490 : case text::RelOrientation::FRAME_LEFT:
6491 : case text::RelOrientation::FRAME_RIGHT:
6492 0 : sVAnchor = OString( "margin" );
6493 0 : break;
6494 : case text::RelOrientation::PAGE_FRAME:
6495 : case text::RelOrientation::PAGE_PRINT_AREA:
6496 : default:
6497 0 : break;
6498 : }
6499 :
6500 0 : AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), FSNS( XML_w, XML_vAnchor ), sVAnchor.getStr() );
6501 : }
6502 0 : }
6503 :
6504 0 : void DocxAttributeOutput::FormatHorizOrientation( const SwFmtHoriOrient& rFlyHori )
6505 : {
6506 0 : if (m_rExport.SdrExporter().getTextFrameSyntax())
6507 : {
6508 0 : m_rExport.SdrExporter().getTextFrameStyle().append(";margin-left:").append(double(rFlyHori.GetPos()) / 20).append("pt");
6509 : }
6510 0 : else if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
6511 : {
6512 : }
6513 0 : else if ( m_rExport.bOutFlyFrmAttrs )
6514 : {
6515 0 : OString sAlign;
6516 0 : switch( rFlyHori.GetHoriOrient() )
6517 : {
6518 : case text::HoriOrientation::NONE:
6519 0 : break;
6520 : case text::HoriOrientation::LEFT:
6521 0 : sAlign = OString( rFlyHori.IsPosToggle( ) ? "inside" : "left" );
6522 0 : break;
6523 : case text::HoriOrientation::RIGHT:
6524 0 : sAlign = OString( rFlyHori.IsPosToggle( ) ? "outside" : "right" );
6525 0 : break;
6526 : case text::HoriOrientation::CENTER:
6527 : case text::HoriOrientation::FULL: // FULL only for tables
6528 : default:
6529 0 : sAlign = OString( "center" );
6530 0 : break;
6531 : }
6532 :
6533 0 : if ( !sAlign.isEmpty() )
6534 0 : AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), FSNS( XML_w, XML_xAlign ), sAlign.getStr() );
6535 : else
6536 0 : AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), FSNS( XML_w, XML_x ),
6537 0 : OString::number( rFlyHori.GetPos() ).getStr() );
6538 :
6539 0 : OString sHAnchor( "page" );
6540 0 : switch ( rFlyHori.GetRelationOrient( ) )
6541 : {
6542 : case text::RelOrientation::CHAR:
6543 : case text::RelOrientation::PRINT_AREA:
6544 0 : sHAnchor = OString( "text" );
6545 0 : break;
6546 : case text::RelOrientation::FRAME:
6547 : case text::RelOrientation::PAGE_LEFT:
6548 : case text::RelOrientation::PAGE_RIGHT:
6549 : case text::RelOrientation::FRAME_LEFT:
6550 : case text::RelOrientation::FRAME_RIGHT:
6551 0 : sHAnchor = OString( "margin" );
6552 0 : break;
6553 : case text::RelOrientation::PAGE_FRAME:
6554 : case text::RelOrientation::PAGE_PRINT_AREA:
6555 : default:
6556 0 : break;
6557 : }
6558 :
6559 0 : AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), FSNS( XML_w, XML_hAnchor ), sHAnchor.getStr() );
6560 : }
6561 0 : }
6562 :
6563 0 : void DocxAttributeOutput::FormatAnchor( const SwFmtAnchor& )
6564 : {
6565 : // Fly frames: anchors here aren't matching the anchors in docx
6566 0 : }
6567 :
6568 0 : boost::optional<sal_Int32> lcl_getDmlAlpha(const SvxBrushItem& rBrush)
6569 : {
6570 0 : boost::optional<sal_Int32> oRet;
6571 0 : sal_Int32 nTransparency = rBrush.GetColor().GetTransparency();
6572 0 : if (nTransparency)
6573 : {
6574 : // Convert transparency to percent
6575 0 : sal_Int8 nTransparencyPercent = SvxBrushItem::TransparencyToPercent(nTransparency);
6576 :
6577 : // Calculate alpha value
6578 : // Consider oox/source/drawingml/color.cxx : getTransparency() function.
6579 0 : sal_Int32 nAlpha = (::oox::drawingml::MAX_PERCENT - ( ::oox::drawingml::PER_PERCENT * nTransparencyPercent ) );
6580 0 : oRet = nAlpha;
6581 : }
6582 0 : return oRet;
6583 : }
6584 :
6585 0 : void DocxAttributeOutput::FormatBackground( const SvxBrushItem& rBrush )
6586 : {
6587 0 : OString sColor = msfilter::util::ConvertColor( rBrush.GetColor().GetRGBColor() );
6588 0 : boost::optional<sal_Int32> oAlpha = lcl_getDmlAlpha(rBrush);
6589 0 : if (m_rExport.SdrExporter().getTextFrameSyntax())
6590 : {
6591 : // Handle 'Opacity'
6592 0 : if (oAlpha)
6593 : {
6594 : // Calculate opacity value
6595 : // Consider oox/source/vml/vmlformatting.cxx : decodeColor() function.
6596 0 : double fOpacity = (double)(*oAlpha) * 65535 / ::oox::drawingml::MAX_PERCENT;
6597 0 : OUString sOpacity = OUString::number(fOpacity) + "f";
6598 :
6599 0 : AddToAttrList( m_rExport.SdrExporter().getFlyFillAttrList(), XML_opacity, OUStringToOString(sOpacity, RTL_TEXTENCODING_UTF8).getStr() );
6600 : }
6601 :
6602 0 : sColor = "#" + sColor;
6603 0 : AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), XML_fillcolor, sColor.getStr() );
6604 : }
6605 0 : else if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
6606 : {
6607 0 : bool bImageBackground = false;
6608 0 : const SfxPoolItem* pItem = GetExport().HasItem(XATTR_FILLSTYLE);
6609 0 : if (pItem)
6610 : {
6611 0 : const XFillStyleItem* pFillStyle = static_cast<const XFillStyleItem*>(pItem);
6612 0 : if(pFillStyle->GetValue() == XFILL_BITMAP)
6613 : {
6614 0 : bImageBackground = true;
6615 : }
6616 : }
6617 0 : if (!bImageBackground)
6618 : {
6619 0 : m_pSerializer->startElementNS(XML_a, XML_solidFill, FSEND);
6620 : m_pSerializer->startElementNS(XML_a, XML_srgbClr,
6621 : XML_val, sColor,
6622 0 : FSEND);
6623 0 : if (oAlpha)
6624 : m_pSerializer->singleElementNS(XML_a, XML_alpha,
6625 0 : XML_val, OString::number(*oAlpha),
6626 0 : FSEND);
6627 0 : m_pSerializer->endElementNS(XML_a, XML_srgbClr);
6628 0 : m_pSerializer->endElementNS(XML_a, XML_solidFill);
6629 : }
6630 : }
6631 0 : else if ( !m_rExport.bOutPageDescs )
6632 : {
6633 0 : if( !m_pBackgroundAttrList )
6634 0 : m_pBackgroundAttrList = m_pSerializer->createAttrList();
6635 :
6636 : // compare fill color with the original fill color
6637 : OString sOriginalFill = rtl::OUStringToOString(
6638 0 : m_pBackgroundAttrList->getOptionalValue( FSNS( XML_w, XML_fill ) ), RTL_TEXTENCODING_UTF8 );
6639 0 : if( sOriginalFill.isEmpty() )
6640 : {
6641 0 : m_pBackgroundAttrList->add( FSNS( XML_w, XML_fill ), sColor.getStr() );
6642 : }
6643 0 : else if ( sOriginalFill != sColor )
6644 : {
6645 : // fill was modified during edition, theme fill attribute must be dropped
6646 0 : delete m_pBackgroundAttrList;
6647 0 : m_pBackgroundAttrList = m_pSerializer->createAttrList();
6648 0 : m_pBackgroundAttrList->add( FSNS( XML_w, XML_fill ), sColor.getStr() );
6649 : }
6650 0 : m_pBackgroundAttrList->add( FSNS( XML_w, XML_val ), "clear" );
6651 0 : }
6652 0 : }
6653 :
6654 0 : void DocxAttributeOutput::FormatFillStyle( const XFillStyleItem& rFillStyle )
6655 : {
6656 0 : if (!m_bIgnoreNextFill)
6657 0 : m_oFillStyle.reset(rFillStyle.GetValue());
6658 : else
6659 0 : m_bIgnoreNextFill = false;
6660 0 : }
6661 :
6662 0 : void DocxAttributeOutput::FormatFillGradient( const XFillGradientItem& rFillGradient )
6663 : {
6664 0 : if (m_oFillStyle && *m_oFillStyle == XFILL_GRADIENT && !m_rExport.SdrExporter().getDMLTextFrameSyntax())
6665 : {
6666 0 : AddToAttrList( m_rExport.SdrExporter().getFlyFillAttrList(), XML_type, "gradient" );
6667 :
6668 0 : const XGradient& rGradient = rFillGradient.GetGradientValue();
6669 0 : OString sStartColor = msfilter::util::ConvertColor(rGradient.GetStartColor());
6670 0 : OString sEndColor = msfilter::util::ConvertColor(rGradient.GetEndColor());
6671 :
6672 : // Calculate the angle that was originally in the imported DOCX file
6673 : // (reverse calculate the angle that was converted in the file
6674 : // /oox/source/vml/vmlformatting.cxx :: FillModel::pushToPropMap
6675 : // and also in
6676 : // /oox/source/drawingml/fillproperties.cxx :: FillProperties::pushToPropMap
6677 0 : sal_Int32 nReverseAngle = 4500 - rGradient.GetAngle();
6678 0 : nReverseAngle = nReverseAngle / 10;
6679 0 : nReverseAngle = (270 - nReverseAngle) % 360;
6680 0 : if (nReverseAngle != 0)
6681 0 : AddToAttrList( m_rExport.SdrExporter().getFlyFillAttrList(),
6682 0 : XML_angle, OString::number( nReverseAngle ).getStr() );
6683 :
6684 0 : OString sColor1 = sStartColor;
6685 0 : OString sColor2 = sEndColor;
6686 :
6687 0 : switch (rGradient.GetGradientStyle())
6688 : {
6689 : case XGRAD_AXIAL:
6690 0 : AddToAttrList( m_rExport.SdrExporter().getFlyFillAttrList(), XML_focus, "50%" );
6691 : // If it is an 'axial' gradient - swap the colors
6692 : // (because in the import process they were imported swapped)
6693 0 : sColor1 = sEndColor;
6694 0 : sColor2 = sStartColor;
6695 0 : break;
6696 0 : case XGRAD_LINEAR: break;
6697 0 : case XGRAD_RADIAL: break;
6698 0 : case XGRAD_ELLIPTICAL: break;
6699 0 : case XGRAD_SQUARE: break;
6700 0 : case XGRAD_RECT: break;
6701 : }
6702 :
6703 0 : sColor1 = "#" + sColor1;
6704 0 : sColor2 = "#" + sColor2;
6705 0 : AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), XML_fillcolor, sColor1.getStr() );
6706 0 : AddToAttrList( m_rExport.SdrExporter().getFlyFillAttrList(), XML_color2, sColor2.getStr() );
6707 : }
6708 0 : else if (m_oFillStyle && *m_oFillStyle == XFILL_GRADIENT && m_rExport.SdrExporter().getDMLTextFrameSyntax())
6709 : {
6710 0 : uno::Reference<beans::XPropertySet> xPropertySet = SwXFrames::GetObject(const_cast<SwFrmFmt&>(m_rExport.mpParentFrame->GetFrmFmt()), FLYCNTTYPE_FRM);
6711 0 : m_rDrawingML.SetFS(m_pSerializer);
6712 0 : m_rDrawingML.WriteGradientFill(xPropertySet);
6713 : }
6714 0 : m_oFillStyle.reset();
6715 0 : }
6716 :
6717 0 : void DocxAttributeOutput::FormatBox( const SvxBoxItem& rBox )
6718 : {
6719 0 : if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
6720 : {
6721 : // <a:gradFill> should be before <a:ln>.
6722 0 : const SfxPoolItem* pItem = GetExport().HasItem(XATTR_FILLSTYLE);
6723 0 : if (pItem)
6724 : {
6725 0 : const XFillStyleItem* pFillStyle = static_cast<const XFillStyleItem*>(pItem);
6726 0 : FormatFillStyle(*pFillStyle);
6727 0 : if (m_oFillStyle && *m_oFillStyle == XFILL_BITMAP)
6728 : {
6729 0 : const SdrObject* pSdrObj = m_rExport.mpParentFrame->GetFrmFmt().FindRealSdrObject();
6730 0 : if (pSdrObj)
6731 : {
6732 0 : uno::Reference< drawing::XShape > xShape( ((SdrObject*)pSdrObj)->getUnoShape(), uno::UNO_QUERY );
6733 0 : uno::Reference< beans::XPropertySet > xPropertySet( xShape, uno::UNO_QUERY );
6734 0 : m_rDrawingML.SetFS(m_pSerializer);
6735 0 : m_rDrawingML.WriteBlipFill( xPropertySet, "BackGraphicURL" );
6736 : }
6737 : }
6738 : }
6739 :
6740 0 : pItem = GetExport().HasItem(XATTR_FILLGRADIENT);
6741 0 : if (pItem)
6742 : {
6743 0 : const XFillGradientItem* pFillGradient = static_cast<const XFillGradientItem*>(pItem);
6744 0 : FormatFillGradient(*pFillGradient);
6745 : }
6746 0 : m_bIgnoreNextFill = true;
6747 : }
6748 0 : if (m_rExport.SdrExporter().getTextFrameSyntax() || m_rExport.SdrExporter().getDMLTextFrameSyntax())
6749 : {
6750 0 : const SvxBorderLine* pLeft = rBox.GetLeft( );
6751 0 : const SvxBorderLine* pTop = rBox.GetTop( );
6752 0 : const SvxBorderLine* pRight = rBox.GetRight( );
6753 0 : const SvxBorderLine* pBottom = rBox.GetBottom( );
6754 :
6755 0 : if (pLeft && pRight && pTop && pBottom &&
6756 0 : *pLeft == *pRight && *pLeft == *pTop && *pLeft == *pBottom)
6757 : {
6758 : // Check border style
6759 0 : editeng::SvxBorderStyle eBorderStyle = pTop->GetBorderLineStyle();
6760 0 : if (eBorderStyle == table::BorderLineStyle::NONE)
6761 : {
6762 0 : if (m_rExport.SdrExporter().getTextFrameSyntax())
6763 : {
6764 0 : AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), 2,
6765 0 : XML_stroked, "f", XML_strokeweight, "0pt" );
6766 : }
6767 : }
6768 : else
6769 : {
6770 0 : OString sColor(msfilter::util::ConvertColor(pTop->GetColor()));
6771 0 : double const fConverted(editeng::ConvertBorderWidthToWord(pTop->GetBorderLineStyle(), pTop->GetWidth()));
6772 :
6773 0 : if (m_rExport.SdrExporter().getTextFrameSyntax())
6774 : {
6775 0 : sColor = "#" + sColor;
6776 0 : sal_Int32 nWidth = sal_Int32(fConverted / 20);
6777 0 : OString sWidth = OString::number(nWidth) + "pt";
6778 0 : AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), 2,
6779 : XML_strokecolor, sColor.getStr(),
6780 0 : XML_strokeweight, sWidth.getStr() );
6781 0 : if( LineStyle_DASH == pTop->GetBorderLineStyle() ) // Line Style is Dash type
6782 0 : AddToAttrList( m_rExport.SdrExporter().getDashLineStyle(),
6783 0 : XML_dashstyle, "dash" );
6784 : }
6785 : else
6786 : {
6787 0 : OString sWidth(OString::number(TwipsToEMU(fConverted)));
6788 : m_pSerializer->startElementNS(XML_a, XML_ln,
6789 : XML_w, sWidth.getStr(),
6790 0 : FSEND);
6791 0 : m_pSerializer->startElementNS(XML_a, XML_solidFill, FSEND);
6792 : m_pSerializer->singleElementNS(XML_a, XML_srgbClr,
6793 : XML_val, sColor,
6794 0 : FSEND);
6795 0 : m_pSerializer->endElementNS(XML_a, XML_solidFill);
6796 0 : if( LineStyle_DASH == pTop->GetBorderLineStyle() ) // Line Style is Dash type
6797 0 : m_pSerializer->singleElementNS(XML_a, XML_prstDash, XML_val, "dash", FSEND);
6798 0 : m_pSerializer->endElementNS(XML_a, XML_ln);
6799 0 : }
6800 : }
6801 : }
6802 :
6803 0 : if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
6804 : {
6805 0 : m_rExport.SdrExporter().getBodyPrAttrList()->add(XML_lIns, OString::number(TwipsToEMU(rBox.GetDistance(BOX_LINE_LEFT))));
6806 0 : m_rExport.SdrExporter().getBodyPrAttrList()->add(XML_tIns, OString::number(TwipsToEMU(rBox.GetDistance(BOX_LINE_TOP))));
6807 0 : m_rExport.SdrExporter().getBodyPrAttrList()->add(XML_rIns, OString::number(TwipsToEMU(rBox.GetDistance(BOX_LINE_RIGHT))));
6808 0 : m_rExport.SdrExporter().getBodyPrAttrList()->add(XML_bIns, OString::number(TwipsToEMU(rBox.GetDistance(BOX_LINE_BOTTOM))));
6809 0 : return;
6810 : }
6811 :
6812 : // v:textbox's inset attribute: inner margin values for textbox text - write only non-default values
6813 0 : double fDistanceLeftTwips = double(rBox.GetDistance(BOX_LINE_LEFT));
6814 0 : double fDistanceTopTwips = double(rBox.GetDistance(BOX_LINE_TOP));
6815 0 : double fDistanceRightTwips = double(rBox.GetDistance(BOX_LINE_RIGHT));
6816 0 : double fDistanceBottomTwips = double(rBox.GetDistance(BOX_LINE_BOTTOM));
6817 :
6818 : // Convert 'TWIPS' to 'INCH' (because in Word the default values are in Inches)
6819 0 : double fDistanceLeftInch = fDistanceLeftTwips / 1440;
6820 0 : double fDistanceTopInch = fDistanceTopTwips / 1440;
6821 0 : double fDistanceRightInch = fDistanceRightTwips / 1440;
6822 0 : double fDistanceBottomInch = fDistanceBottomTwips / 1440;
6823 :
6824 : // This code will write ONLY the non-default values. The values are in 'left','top','right','bottom' order.
6825 : // so 'bottom' is checked if it is default and if it is non-default - all the values will be written
6826 : // otherwise - 'right' is checked if it is default and if it is non-default - all the values except for 'bottom' will be written
6827 : // and so on.
6828 0 : OStringBuffer aInset;
6829 0 : if(!aInset.isEmpty() || fDistanceBottomInch != double(0.05))
6830 0 : aInset.insert(0, "," + OString::number(fDistanceBottomInch) + "in");
6831 :
6832 0 : if(!aInset.isEmpty() || fDistanceRightInch != double(0.1))
6833 0 : aInset.insert(0, "," + OString::number(fDistanceRightInch) + "in");
6834 :
6835 0 : if(!aInset.isEmpty() || fDistanceTopInch != double(0.05))
6836 0 : aInset.insert(0, "," + OString::number(fDistanceTopInch) + "in");
6837 :
6838 0 : if(!aInset.isEmpty() || fDistanceLeftInch != double(0.1))
6839 0 : aInset.insert(0, OString::number(fDistanceLeftInch) + "in");
6840 :
6841 0 : if (!aInset.isEmpty())
6842 0 : m_rExport.SdrExporter().getTextboxAttrList()->add(XML_inset, aInset.makeStringAndClear());
6843 :
6844 0 : return;
6845 : }
6846 :
6847 0 : OutputBorderOptions aOutputBorderOptions = lcl_getBoxBorderOptions();
6848 : // Check if there is a shadow item
6849 0 : const SfxPoolItem* pItem = GetExport().HasItem( RES_SHADOW );
6850 0 : if ( pItem )
6851 : {
6852 0 : const SvxShadowItem* pShadowItem = (const SvxShadowItem*)pItem;
6853 0 : aOutputBorderOptions.aShadowLocation = pShadowItem->GetLocation();
6854 : }
6855 :
6856 0 : if ( !m_bOpenedSectPr || GetWritingHeaderFooter())
6857 : {
6858 : // Not inside a section
6859 :
6860 : // Open the paragraph's borders tag
6861 0 : m_pSerializer->startElementNS( XML_w, XML_pBdr, FSEND );
6862 :
6863 0 : std::map<sal_uInt16, css::table::BorderLine2> aEmptyMap; // empty styles map
6864 : impl_borders( m_pSerializer, rBox, aOutputBorderOptions, &m_pageMargins,
6865 0 : aEmptyMap );
6866 :
6867 : // Close the paragraph's borders tag
6868 0 : m_pSerializer->endElementNS( XML_w, XML_pBdr );
6869 : }
6870 : }
6871 :
6872 0 : void DocxAttributeOutput::FormatColumns_Impl( sal_uInt16 nCols, const SwFmtCol& rCol, bool bEven, SwTwips nPageSize )
6873 : {
6874 : // Get the columns attributes
6875 0 : FastAttributeList *pColsAttrList = m_pSerializer->createAttrList();
6876 :
6877 : pColsAttrList->add( FSNS( XML_w, XML_num ),
6878 0 : OString::number( nCols ). getStr( ) );
6879 :
6880 0 : const char* pEquals = "false";
6881 0 : if ( bEven )
6882 : {
6883 0 : sal_uInt16 nWidth = rCol.GetGutterWidth( true );
6884 : pColsAttrList->add( FSNS( XML_w, XML_space ),
6885 0 : OString::number( nWidth ).getStr( ) );
6886 :
6887 0 : pEquals = "true";
6888 : }
6889 :
6890 0 : pColsAttrList->add( FSNS( XML_w, XML_equalWidth ), pEquals );
6891 :
6892 0 : bool bHasSep = (COLADJ_NONE != rCol.GetLineAdj());
6893 :
6894 0 : pColsAttrList->add( FSNS( XML_w, XML_sep ), bHasSep ? "true" : "false" );
6895 :
6896 : // Write the element
6897 0 : m_pSerializer->startElementNS( XML_w, XML_cols, pColsAttrList );
6898 :
6899 : // Write the columns width if non-equals
6900 0 : const SwColumns & rColumns = rCol.GetColumns( );
6901 0 : if ( !bEven )
6902 : {
6903 0 : for ( sal_uInt16 n = 0; n < nCols; ++n )
6904 : {
6905 0 : FastAttributeList *pColAttrList = m_pSerializer->createAttrList();
6906 0 : sal_uInt16 nWidth = rCol.CalcPrtColWidth( n, ( sal_uInt16 ) nPageSize );
6907 : pColAttrList->add( FSNS( XML_w, XML_w ),
6908 0 : OString::number( nWidth ).getStr( ) );
6909 :
6910 0 : if ( n + 1 != nCols )
6911 : {
6912 0 : sal_uInt16 nSpacing = rColumns[n].GetRight( ) + rColumns[n + 1].GetLeft( );
6913 : pColAttrList->add( FSNS( XML_w, XML_space ),
6914 0 : OString::number( nSpacing ).getStr( ) );
6915 : }
6916 :
6917 0 : m_pSerializer->singleElementNS( XML_w, XML_col, pColAttrList );
6918 : }
6919 : }
6920 :
6921 0 : m_pSerializer->endElementNS( XML_w, XML_cols );
6922 0 : }
6923 :
6924 0 : void DocxAttributeOutput::FormatKeep( const SvxFmtKeepItem& )
6925 : {
6926 0 : m_pSerializer->singleElementNS( XML_w, XML_keepNext, FSEND );
6927 0 : }
6928 :
6929 0 : void DocxAttributeOutput::FormatTextGrid( const SwTextGridItem& rGrid )
6930 : {
6931 0 : FastAttributeList *pGridAttrList = m_pSerializer->createAttrList();
6932 :
6933 0 : OString sGridType;
6934 0 : switch ( rGrid.GetGridType( ) )
6935 : {
6936 : default:
6937 : case GRID_NONE:
6938 0 : sGridType = OString( "default" );
6939 0 : break;
6940 : case GRID_LINES_ONLY:
6941 0 : sGridType = OString( "lines" );
6942 0 : break;
6943 : case GRID_LINES_CHARS:
6944 0 : if ( rGrid.IsSnapToChars( ) )
6945 0 : sGridType = OString( "snapToChars" );
6946 : else
6947 0 : sGridType = OString( "linesAndChars" );
6948 0 : break;
6949 : }
6950 0 : pGridAttrList->add( FSNS( XML_w, XML_type ), sGridType.getStr( ) );
6951 :
6952 0 : sal_uInt16 nHeight = rGrid.GetBaseHeight() + rGrid.GetRubyHeight();
6953 : pGridAttrList->add( FSNS( XML_w, XML_linePitch ),
6954 0 : OString::number( nHeight ).getStr( ) );
6955 :
6956 : pGridAttrList->add( FSNS( XML_w, XML_charSpace ),
6957 0 : OString::number( GridCharacterPitch( rGrid ) ).getStr( ) );
6958 :
6959 0 : m_pSerializer->singleElementNS( XML_w, XML_docGrid, pGridAttrList );
6960 0 : }
6961 :
6962 0 : void DocxAttributeOutput::FormatLineNumbering( const SwFmtLineNumber& rNumbering )
6963 : {
6964 0 : if ( !rNumbering.IsCount( ) )
6965 0 : m_pSerializer->singleElementNS( XML_w, XML_suppressLineNumbers, FSEND );
6966 0 : }
6967 :
6968 0 : void DocxAttributeOutput::FormatFrameDirection( const SvxFrameDirectionItem& rDirection )
6969 : {
6970 0 : OString sTextFlow;
6971 0 : bool bBiDi = false;
6972 0 : short nDir = rDirection.GetValue();
6973 :
6974 0 : if ( nDir == FRMDIR_ENVIRONMENT )
6975 0 : nDir = GetExport( ).GetDefaultFrameDirection( );
6976 :
6977 0 : switch ( nDir )
6978 : {
6979 : default:
6980 : case FRMDIR_HORI_LEFT_TOP:
6981 0 : sTextFlow = OString( "lrTb" );
6982 0 : break;
6983 : case FRMDIR_HORI_RIGHT_TOP:
6984 0 : sTextFlow = OString( "lrTb" );
6985 0 : bBiDi = true;
6986 0 : break;
6987 : case FRMDIR_VERT_TOP_LEFT: // many things but not this one
6988 : case FRMDIR_VERT_TOP_RIGHT:
6989 0 : sTextFlow = OString( "tbRl" );
6990 0 : break;
6991 : }
6992 :
6993 0 : if ( m_rExport.bOutPageDescs )
6994 : {
6995 : m_pSerializer->singleElementNS( XML_w, XML_textDirection,
6996 : FSNS( XML_w, XML_val ), sTextFlow.getStr( ),
6997 0 : FSEND );
6998 0 : if ( bBiDi )
6999 0 : m_pSerializer->singleElementNS( XML_w, XML_bidi, FSEND );
7000 : }
7001 0 : else if ( !m_rExport.bOutFlyFrmAttrs )
7002 : {
7003 0 : if ( bBiDi )
7004 0 : m_pSerializer->singleElementNS( XML_w, XML_bidi, FSNS( XML_w, XML_val ), "1", FSEND );
7005 : else
7006 0 : m_pSerializer->singleElementNS( XML_w, XML_bidi, FSNS( XML_w, XML_val ), "0", FSEND );
7007 0 : }
7008 0 : }
7009 :
7010 0 : void DocxAttributeOutput::ParaGrabBag(const SfxGrabBagItem& rItem)
7011 : {
7012 0 : const std::map<OUString, com::sun::star::uno::Any>& rMap = rItem.GetGrabBag();
7013 0 : for (std::map<OUString, com::sun::star::uno::Any>::const_iterator i = rMap.begin(); i != rMap.end(); ++i)
7014 : {
7015 0 : if (i->first == "MirrorIndents")
7016 0 : m_pSerializer->singleElementNS(XML_w, XML_mirrorIndents, FSEND);
7017 0 : else if (i->first == "ParaTopMarginBeforeAutoSpacing")
7018 : {
7019 0 : m_bParaBeforeAutoSpacing = true;
7020 : // get fixed value which was set during import
7021 0 : i->second >>= m_nParaBeforeSpacing;
7022 0 : m_nParaBeforeSpacing = convertMm100ToTwip(m_nParaBeforeSpacing);
7023 : SAL_INFO("sw.ww8", "DocxAttributeOutput::ParaGrabBag: property =" << i->first << " : m_nParaBeforeSpacing= " << m_nParaBeforeSpacing);
7024 : }
7025 0 : else if (i->first == "ParaBottomMarginAfterAutoSpacing")
7026 : {
7027 0 : m_bParaAfterAutoSpacing = true;
7028 : // get fixed value which was set during import
7029 0 : i->second >>= m_nParaAfterSpacing;
7030 0 : m_nParaAfterSpacing = convertMm100ToTwip(m_nParaAfterSpacing);
7031 : SAL_INFO("sw.ww8", "DocxAttributeOutput::ParaGrabBag: property =" << i->first << " : m_nParaBeforeSpacing= " << m_nParaAfterSpacing);
7032 : }
7033 0 : else if (i->first == "CharThemeFill")
7034 : {
7035 0 : uno::Sequence<beans::PropertyValue> aGrabBagSeq;
7036 0 : i->second >>= aGrabBagSeq;
7037 0 : OUString sThemeFill, sOriginalFill;
7038 0 : for (sal_Int32 j=0; j < aGrabBagSeq.getLength(); ++j)
7039 : {
7040 0 : if (aGrabBagSeq[j].Name == "themeFill")
7041 0 : aGrabBagSeq[j].Value >>= sThemeFill;
7042 0 : else if (aGrabBagSeq[j].Name == "fill")
7043 0 : aGrabBagSeq[j].Value >>= sOriginalFill;
7044 : }
7045 : AddToAttrList(m_pBackgroundAttrList, 2,
7046 : FSNS(XML_w, XML_themeFill), OUStringToOString(sThemeFill, RTL_TEXTENCODING_UTF8).getStr(),
7047 0 : FSNS(XML_w, XML_fill), OUStringToOString(sOriginalFill, RTL_TEXTENCODING_UTF8).getStr());
7048 : }
7049 0 : else if (i->first == "SdtPr")
7050 : {
7051 : uno::Sequence<beans::PropertyValue> aGrabBagSdt =
7052 0 : i->second.get< uno::Sequence<beans::PropertyValue> >();
7053 0 : for (sal_Int32 k=0; k < aGrabBagSdt.getLength(); ++k)
7054 : {
7055 0 : beans::PropertyValue aPropertyValue = aGrabBagSdt[k];
7056 0 : if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartObj" ||
7057 0 : aPropertyValue.Name == "ooxml:CT_SdtPr_docPartList")
7058 : {
7059 0 : if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartObj")
7060 0 : m_nParagraphSdtPrToken = FSNS( XML_w, XML_docPartObj );
7061 0 : else if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartList")
7062 0 : m_nParagraphSdtPrToken = FSNS( XML_w, XML_docPartList );
7063 :
7064 0 : uno::Sequence<beans::PropertyValue> aGrabBag;
7065 0 : aPropertyValue.Value >>= aGrabBag;
7066 0 : for (sal_Int32 j=0; j < aGrabBag.getLength(); ++j)
7067 : {
7068 0 : OUString sValue = aGrabBag[j].Value.get<OUString>();
7069 0 : if (aGrabBag[j].Name == "ooxml:CT_SdtDocPart_docPartGallery")
7070 : AddToAttrList( m_pParagraphSdtPrTokenChildren,
7071 : FSNS( XML_w, XML_docPartGallery ),
7072 0 : rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
7073 0 : else if (aGrabBag[j].Name == "ooxml:CT_SdtDocPart_docPartCategory")
7074 : AddToAttrList( m_pParagraphSdtPrTokenChildren,
7075 : FSNS( XML_w, XML_docPartCategory ),
7076 0 : rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
7077 0 : else if (aGrabBag[j].Name == "ooxml:CT_SdtDocPart_docPartUnique")
7078 0 : AddToAttrList( m_pParagraphSdtPrTokenChildren, FSNS( XML_w, XML_docPartUnique ), "" );
7079 0 : }
7080 : }
7081 0 : else if (aPropertyValue.Name == "ooxml:CT_SdtPr_equation")
7082 0 : m_nParagraphSdtPrToken = FSNS( XML_w, XML_equation );
7083 0 : else if (aPropertyValue.Name == "ooxml:CT_SdtPr_picture")
7084 0 : m_nParagraphSdtPrToken = FSNS( XML_w, XML_picture );
7085 0 : else if (aPropertyValue.Name == "ooxml:CT_SdtPr_citation")
7086 0 : m_nParagraphSdtPrToken = FSNS( XML_w, XML_citation );
7087 0 : else if (aPropertyValue.Name == "ooxml:CT_SdtPr_group")
7088 0 : m_nParagraphSdtPrToken = FSNS( XML_w, XML_group );
7089 0 : }
7090 : }
7091 : else
7092 : SAL_INFO("sw.ww8", "DocxAttributeOutput::ParaGrabBag: unhandled grab bag property " << i->first );
7093 : }
7094 0 : }
7095 :
7096 0 : void DocxAttributeOutput::CharGrabBag( const SfxGrabBagItem& rItem )
7097 : {
7098 0 : const std::map< OUString, com::sun::star::uno::Any >& rMap = rItem.GetGrabBag();
7099 :
7100 : // get original values of theme-derived properties to check if they have changed during the edition
7101 0 : sal_Bool bWriteCSTheme = sal_True;
7102 0 : sal_Bool bWriteAsciiTheme = sal_True;
7103 0 : sal_Bool bWriteEastAsiaTheme = sal_True;
7104 0 : sal_Bool bWriteThemeFontColor = sal_True;
7105 0 : OUString sOriginalValue;
7106 0 : for ( std::map< OUString, com::sun::star::uno::Any >::const_iterator i = rMap.begin(); i != rMap.end(); ++i )
7107 : {
7108 0 : if ( m_pFontsAttrList && i->first == "CharThemeFontNameCs" )
7109 : {
7110 0 : if ( i->second >>= sOriginalValue )
7111 : bWriteCSTheme =
7112 0 : ( m_pFontsAttrList->getOptionalValue( FSNS( XML_w, XML_cs ) ) == sOriginalValue );
7113 : }
7114 0 : else if ( m_pFontsAttrList && i->first == "CharThemeFontNameAscii" )
7115 : {
7116 0 : if ( i->second >>= sOriginalValue )
7117 : bWriteAsciiTheme =
7118 0 : ( m_pFontsAttrList->getOptionalValue( FSNS( XML_w, XML_ascii ) ) == sOriginalValue );
7119 : }
7120 0 : else if ( m_pFontsAttrList && i->first == "CharThemeFontNameEastAsia" )
7121 : {
7122 0 : if ( i->second >>= sOriginalValue )
7123 : bWriteEastAsiaTheme =
7124 0 : ( m_pFontsAttrList->getOptionalValue( FSNS( XML_w, XML_eastAsia ) ) == sOriginalValue );
7125 : }
7126 0 : else if ( m_pColorAttrList && i->first == "CharThemeOriginalColor" )
7127 : {
7128 0 : if ( i->second >>= sOriginalValue )
7129 : bWriteThemeFontColor =
7130 0 : ( m_pColorAttrList->getOptionalValue( FSNS( XML_w, XML_val ) ) == sOriginalValue );
7131 : }
7132 : }
7133 :
7134 : // save theme attributes back to the run properties
7135 0 : OUString str;
7136 0 : for ( std::map< OUString, com::sun::star::uno::Any >::const_iterator i = rMap.begin(); i != rMap.end(); ++i )
7137 : {
7138 0 : if ( i->first == "CharThemeNameAscii" && bWriteAsciiTheme )
7139 : {
7140 0 : i->second >>= str;
7141 : AddToAttrList( m_pFontsAttrList, FSNS( XML_w, XML_asciiTheme ),
7142 0 : OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
7143 : }
7144 0 : else if ( i->first == "CharThemeNameCs" && bWriteCSTheme )
7145 : {
7146 0 : i->second >>= str;
7147 : AddToAttrList( m_pFontsAttrList, FSNS( XML_w, XML_cstheme ),
7148 0 : OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
7149 : }
7150 0 : else if ( i->first == "CharThemeNameEastAsia" && bWriteEastAsiaTheme )
7151 : {
7152 0 : i->second >>= str;
7153 : AddToAttrList( m_pFontsAttrList, FSNS( XML_w, XML_eastAsiaTheme ),
7154 0 : OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
7155 : }
7156 0 : else if ( i->first == "CharThemeNameHAnsi" && bWriteAsciiTheme )
7157 : // this is not a mistake: in LibO we don't directly support the hAnsi family
7158 : // of attributes so we save the same value from ascii attributes instead
7159 : {
7160 0 : i->second >>= str;
7161 : AddToAttrList( m_pFontsAttrList, FSNS( XML_w, XML_hAnsiTheme ),
7162 0 : OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
7163 : }
7164 0 : else if ( i->first == "CharThemeColor" && bWriteThemeFontColor )
7165 : {
7166 0 : i->second >>= str;
7167 : AddToAttrList( m_pColorAttrList, FSNS( XML_w, XML_themeColor ),
7168 0 : OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
7169 : }
7170 0 : else if ( i->first == "CharThemeColorShade" )
7171 : {
7172 0 : i->second >>= str;
7173 : AddToAttrList( m_pColorAttrList, FSNS( XML_w, XML_themeShade ),
7174 0 : OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
7175 : }
7176 0 : else if ( i->first == "CharThemeColorTint" )
7177 : {
7178 0 : i->second >>= str;
7179 : AddToAttrList( m_pColorAttrList, FSNS( XML_w, XML_themeTint ),
7180 0 : OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
7181 : }
7182 0 : else if( i->first == "CharThemeFontNameCs" ||
7183 0 : i->first == "CharThemeFontNameAscii" ||
7184 0 : i->first == "CharThemeFontNameEastAsia" ||
7185 0 : i->first == "CharThemeOriginalColor" )
7186 : {
7187 : // just skip these, they were processed before
7188 : }
7189 0 : else if(i->first == "CharGlowTextEffect" ||
7190 0 : i->first == "CharShadowTextEffect" ||
7191 0 : i->first == "CharReflectionTextEffect" ||
7192 0 : i->first == "CharTextOutlineTextEffect" ||
7193 0 : i->first == "CharTextFillTextEffect" ||
7194 0 : i->first == "CharScene3DTextEffect" ||
7195 0 : i->first == "CharProps3DTextEffect" ||
7196 0 : i->first == "CharLigaturesTextEffect" ||
7197 0 : i->first == "CharNumFormTextEffect" ||
7198 0 : i->first == "CharNumSpacingTextEffect" ||
7199 0 : i->first == "CharStylisticSetsTextEffect" ||
7200 0 : i->first == "CharCntxtAltsTextEffect")
7201 : {
7202 0 : beans::PropertyValue aPropertyValue;
7203 0 : i->second >>= aPropertyValue;
7204 0 : sal_Int32 aLength = m_aTextEffectsGrabBag.getLength();
7205 0 : m_aTextEffectsGrabBag.realloc(m_aTextEffectsGrabBag.getLength() + 1);
7206 0 : m_aTextEffectsGrabBag[aLength] = aPropertyValue;
7207 : }
7208 0 : else if (i->first == "SdtPr")
7209 : {
7210 : uno::Sequence<beans::PropertyValue> aGrabBagSdt =
7211 0 : i->second.get< uno::Sequence<beans::PropertyValue> >();
7212 0 : for (sal_Int32 k=0; k < aGrabBagSdt.getLength(); ++k)
7213 : {
7214 0 : beans::PropertyValue aPropertyValue = aGrabBagSdt[k];
7215 0 : if (aPropertyValue.Name == "ooxml:CT_SdtPr_checkbox")
7216 : {
7217 0 : m_nRunSdtPrToken = FSNS( XML_w14, XML_checkbox );
7218 0 : uno::Sequence<beans::PropertyValue> aGrabBag;
7219 0 : aPropertyValue.Value >>= aGrabBag;
7220 0 : for (sal_Int32 j=0; j < aGrabBag.getLength(); ++j)
7221 : {
7222 0 : OUString sValue = aGrabBag[j].Value.get<OUString>();
7223 0 : if (aGrabBag[j].Name == "ooxml:CT_SdtCheckbox_checked")
7224 : AddToAttrList( m_pRunSdtPrTokenChildren,
7225 : FSNS( XML_w14, XML_checked ),
7226 0 : rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
7227 0 : else if (aGrabBag[j].Name == "ooxml:CT_SdtCheckbox_checkedState")
7228 : AddToAttrList( m_pRunSdtPrTokenChildren,
7229 : FSNS( XML_w14, XML_checkedState ),
7230 0 : rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
7231 0 : else if (aGrabBag[j].Name == "ooxml:CT_SdtCheckbox_uncheckedState")
7232 : AddToAttrList( m_pRunSdtPrTokenChildren,
7233 : FSNS( XML_w14, XML_uncheckedState ),
7234 0 : rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
7235 0 : }
7236 : }
7237 0 : else if (aPropertyValue.Name == "ooxml:CT_SdtPr_dataBinding")
7238 : {
7239 0 : uno::Sequence<beans::PropertyValue> aGrabBag;
7240 0 : aPropertyValue.Value >>= aGrabBag;
7241 0 : for (sal_Int32 j=0; j < aGrabBag.getLength(); ++j)
7242 : {
7243 0 : OUString sValue = aGrabBag[j].Value.get<OUString>();
7244 0 : if (aGrabBag[j].Name == "ooxml:CT_DataBinding_prefixMappings")
7245 : AddToAttrList( m_pRunSdtPrDataBindingAttrs,
7246 : FSNS( XML_w, XML_prefixMappings ),
7247 0 : rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
7248 0 : else if (aGrabBag[j].Name == "ooxml:CT_DataBinding_xpath")
7249 : AddToAttrList( m_pRunSdtPrDataBindingAttrs,
7250 : FSNS( XML_w, XML_xpath ),
7251 0 : rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
7252 0 : else if (aGrabBag[j].Name == "ooxml:CT_DataBinding_storeItemID")
7253 : AddToAttrList( m_pRunSdtPrDataBindingAttrs,
7254 : FSNS( XML_w, XML_storeItemID ),
7255 0 : rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
7256 0 : }
7257 : }
7258 0 : else if (aPropertyValue.Name == "ooxml:CT_SdtPr_text")
7259 0 : m_nRunSdtPrToken = FSNS( XML_w, XML_text );
7260 0 : else if (aPropertyValue.Name == "ooxml:CT_SdtPr_id" && m_nRunSdtPrToken == 0)
7261 : // only write id token as a marker if no other exist
7262 0 : m_nRunSdtPrToken = FSNS( XML_w, XML_id );
7263 0 : }
7264 : }
7265 : else
7266 : SAL_INFO("sw.ww8", "DocxAttributeOutput::CharGrabBag: unhandled grab bag property " << i->first);
7267 0 : }
7268 0 : }
7269 :
7270 0 : DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, FSHelperPtr pSerializer, oox::drawingml::DrawingML* pDrawingML )
7271 : : m_rExport( rExport ),
7272 : m_pSerializer( pSerializer ),
7273 : m_rDrawingML( *pDrawingML ),
7274 : m_pFontsAttrList( NULL ),
7275 : m_pEastAsianLayoutAttrList( NULL ),
7276 : m_pCharLangAttrList( NULL ),
7277 : m_pSectionSpacingAttrList( NULL ),
7278 : m_pParagraphSpacingAttrList( NULL ),
7279 : m_pHyperlinkAttrList( NULL ),
7280 : m_pColorAttrList( NULL ),
7281 : m_pBackgroundAttrList( NULL ),
7282 : m_endPageRef( false ),
7283 0 : m_pFootnotesList( new ::docx::FootnotesList() ),
7284 0 : m_pEndnotesList( new ::docx::FootnotesList() ),
7285 : m_footnoteEndnoteRefTag( 0 ),
7286 : m_pSectionInfo( NULL ),
7287 : m_pRedlineData( NULL ),
7288 : m_nRedlineId( 0 ),
7289 : m_bOpenedSectPr( false ),
7290 : m_bWritingHeaderFooter( false ),
7291 : m_sFieldBkm( ),
7292 : m_nNextBookmarkId( 0 ),
7293 : m_nNextAnnotationMarkId( 0 ),
7294 : m_pTableWrt( NULL ),
7295 : m_bParagraphOpened( false ),
7296 : m_bIsFirstParagraph( true ),
7297 : m_bAlternateContentChoiceOpen( false ),
7298 : m_nColBreakStatus( COLBRK_NONE ),
7299 : m_nTextFrameLevel( 0 ),
7300 : m_closeHyperlinkInThisRun( false ),
7301 : m_closeHyperlinkInPreviousRun( false ),
7302 : m_startedHyperlink( false ),
7303 : m_nHyperLinkCount(0),
7304 : m_nFieldsInHyperlink( 0 ),
7305 : m_postponedGraphic( NULL ),
7306 : m_postponedDiagram( NULL ),
7307 : m_postponedVMLDrawing(NULL),
7308 : m_postponedDMLDrawing(NULL),
7309 : m_postponedOLE( NULL ),
7310 : m_postponedMath( NULL ),
7311 : m_postponedChart( NULL ),
7312 : pendingPlaceholder( NULL ),
7313 : m_postitFieldsMaxId( 0 ),
7314 : m_anchorId( 1 ),
7315 : m_nextFontId( 1 ),
7316 : m_tableReference(new TableReference()),
7317 : m_oldTableReference(new TableReference()),
7318 : m_bIgnoreNextFill(false),
7319 : m_bBtLr(false),
7320 0 : m_pTableStyleExport(new DocxTableStyleExport(rExport.pDoc, pSerializer)),
7321 : m_bParaBeforeAutoSpacing(false),
7322 : m_bParaAfterAutoSpacing(false),
7323 : m_nParaBeforeSpacing(0),
7324 : m_nParaAfterSpacing(0),
7325 : m_setFootnote(false)
7326 : , m_nParagraphSdtPrToken(0)
7327 : , m_pParagraphSdtPrTokenChildren(NULL)
7328 : , m_pParagraphSdtPrDataBindingAttrs(NULL)
7329 : , m_nRunSdtPrToken(0)
7330 : , m_pRunSdtPrTokenChildren(NULL)
7331 0 : , m_pRunSdtPrDataBindingAttrs(NULL)
7332 : {
7333 0 : }
7334 :
7335 0 : DocxAttributeOutput::~DocxAttributeOutput()
7336 : {
7337 0 : delete m_pFontsAttrList, m_pFontsAttrList = NULL;
7338 0 : delete m_pEastAsianLayoutAttrList, m_pEastAsianLayoutAttrList = NULL;
7339 0 : delete m_pCharLangAttrList, m_pCharLangAttrList = NULL;
7340 0 : delete m_pSectionSpacingAttrList, m_pSectionSpacingAttrList = NULL;
7341 0 : delete m_pParagraphSpacingAttrList, m_pParagraphSpacingAttrList = NULL;
7342 0 : delete m_pHyperlinkAttrList, m_pHyperlinkAttrList = NULL;
7343 0 : delete m_pColorAttrList, m_pColorAttrList = NULL;
7344 0 : delete m_pBackgroundAttrList, m_pBackgroundAttrList = NULL;
7345 :
7346 0 : delete m_pFootnotesList, m_pFootnotesList = NULL;
7347 0 : delete m_pEndnotesList, m_pEndnotesList = NULL;
7348 :
7349 0 : delete m_pTableWrt, m_pTableWrt = NULL;
7350 0 : delete m_pParagraphSdtPrTokenChildren; m_pParagraphSdtPrTokenChildren = NULL;
7351 0 : delete m_pParagraphSdtPrDataBindingAttrs; m_pParagraphSdtPrDataBindingAttrs = NULL;
7352 0 : delete m_pRunSdtPrTokenChildren; m_pRunSdtPrTokenChildren = NULL;
7353 0 : delete m_pRunSdtPrDataBindingAttrs; m_pRunSdtPrDataBindingAttrs = NULL;
7354 0 : }
7355 :
7356 0 : DocxExport& DocxAttributeOutput::GetExport()
7357 : {
7358 0 : return m_rExport;
7359 : }
7360 :
7361 0 : void DocxAttributeOutput::SetSerializer( ::sax_fastparser::FSHelperPtr pSerializer )
7362 : {
7363 0 : m_pSerializer = pSerializer;
7364 0 : m_pTableStyleExport->SetSerializer(pSerializer);
7365 0 : }
7366 :
7367 0 : bool DocxAttributeOutput::HasFootnotes() const
7368 : {
7369 0 : return !m_pFootnotesList->isEmpty();
7370 : }
7371 :
7372 0 : bool DocxAttributeOutput::HasEndnotes() const
7373 : {
7374 0 : return !m_pEndnotesList->isEmpty();
7375 : }
7376 :
7377 0 : bool DocxAttributeOutput::HasPostitFields() const
7378 : {
7379 0 : return !m_postitFields.empty();
7380 : }
7381 :
7382 0 : void DocxAttributeOutput::BulletDefinition(int nId, const Graphic& rGraphic, Size aSize)
7383 : {
7384 : m_pSerializer->startElementNS(XML_w, XML_numPicBullet,
7385 : FSNS(XML_w, XML_numPicBulletId), OString::number(nId).getStr(),
7386 0 : FSEND);
7387 :
7388 0 : OStringBuffer aStyle;
7389 : // Size is in twips, we need it in points.
7390 0 : aStyle.append("width:").append(double(aSize.Width()) / 20);
7391 0 : aStyle.append("pt;height:").append(double(aSize.Height()) / 20).append("pt");
7392 0 : m_pSerializer->startElementNS( XML_w, XML_pict, FSEND);
7393 : m_pSerializer->startElementNS( XML_v, XML_shape,
7394 : XML_style, aStyle.getStr(),
7395 : FSNS(XML_o, XML_bullet), "t",
7396 0 : FSEND);
7397 :
7398 0 : m_rDrawingML.SetFS(m_pSerializer);
7399 0 : OUString aRelId = m_rDrawingML.WriteImage(rGraphic);
7400 : m_pSerializer->singleElementNS( XML_v, XML_imagedata,
7401 : FSNS(XML_r, XML_id), OUStringToOString(aRelId, RTL_TEXTENCODING_UTF8),
7402 : FSNS(XML_o, XML_title), "",
7403 0 : FSEND);
7404 :
7405 0 : m_pSerializer->endElementNS(XML_v, XML_shape);
7406 0 : m_pSerializer->endElementNS(XML_w, XML_pict);
7407 :
7408 0 : m_pSerializer->endElementNS(XML_w, XML_numPicBullet);
7409 0 : }
7410 :
7411 0 : void DocxAttributeOutput::AddToAttrList( ::sax_fastparser::FastAttributeList* &pAttrList, sal_Int32 nAttrName, const sal_Char* sAttrValue )
7412 : {
7413 0 : AddToAttrList( pAttrList, 1, nAttrName, sAttrValue );
7414 0 : }
7415 :
7416 0 : void DocxAttributeOutput::AddToAttrList( ::sax_fastparser::FastAttributeList* &pAttrList, sal_Int32 nAttrs, ... )
7417 : {
7418 0 : if( !pAttrList )
7419 0 : pAttrList = m_pSerializer->createAttrList();
7420 :
7421 : va_list args;
7422 0 : va_start( args, nAttrs );
7423 0 : for( sal_Int32 i = 0; i<nAttrs; i++)
7424 : {
7425 0 : sal_Int32 nName = va_arg( args, sal_Int32 );
7426 0 : const char* pValue = va_arg( args, const char* );
7427 0 : if( pValue )
7428 0 : pAttrList->add( nName, pValue );
7429 : }
7430 0 : va_end( args );
7431 0 : }
7432 :
7433 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|