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 "docxexportfilter.hxx"
22 : #include "docxfootnotes.hxx"
23 : #include "writerwordglue.hxx"
24 : #include "ww8par.hxx"
25 : #include "fmtcntnt.hxx"
26 : #include "fchrfmt.hxx"
27 : #include "tgrditem.hxx"
28 : #include "fmtruby.hxx"
29 : #include "breakit.hxx"
30 :
31 : #include <comphelper/string.hxx>
32 : #include <oox/token/tokens.hxx>
33 : #include <oox/export/utils.hxx>
34 : #include <oox/mathml/export.hxx>
35 :
36 : #include <i18npool/languagetag.hxx>
37 :
38 : #include <editeng/fontitem.hxx>
39 : #include <editeng/tstpitem.hxx>
40 : #include <editeng/spltitem.hxx>
41 : #include <editeng/widwitem.hxx>
42 : #include <editeng/shaditem.hxx>
43 : #include <editeng/brshitem.hxx>
44 : #include <editeng/postitem.hxx>
45 : #include <editeng/wghtitem.hxx>
46 : #include <editeng/kernitem.hxx>
47 : #include <editeng/crsditem.hxx>
48 : #include <editeng/cmapitem.hxx>
49 : #include <editeng/udlnitem.hxx>
50 : #include <editeng/langitem.hxx>
51 : #include <editeng/escpitem.hxx>
52 : #include <editeng/fhgtitem.hxx>
53 : #include <editeng/colritem.hxx>
54 : #include <editeng/hyznitem.hxx>
55 : #include <editeng/ulspitem.hxx>
56 : #include <editeng/boxitem.hxx>
57 : #include <editeng/cntritem.hxx>
58 : #include <editeng/shdditem.hxx>
59 : #include <editeng/emphitem.hxx>
60 : #include <editeng/twolinesitem.hxx>
61 : #include <editeng/charscaleitem.hxx>
62 : #include <editeng/charrotateitem.hxx>
63 : #include <editeng/charreliefitem.hxx>
64 : #include <editeng/paravertalignitem.hxx>
65 : #include <editeng/pgrditem.hxx>
66 : #include <editeng/frmdiritem.hxx>
67 : #include <editeng/blnkitem.hxx>
68 : #include <editeng/charhiddenitem.hxx>
69 : #include <editeng/opaqitem.hxx>
70 : #include <editeng/editobj.hxx>
71 : #include <svx/svdmodel.hxx>
72 : #include <svx/svdobj.hxx>
73 : #include <sfx2/sfxbasemodel.hxx>
74 :
75 : #include <anchoredobject.hxx>
76 : #include <docufld.hxx>
77 : #include <flddropdown.hxx>
78 : #include <fmtanchr.hxx>
79 : #include <fmtclds.hxx>
80 : #include <fmtinfmt.hxx>
81 : #include <fmtrowsplt.hxx>
82 : #include <fmtline.hxx>
83 : #include <frmatr.hxx>
84 : #include <ftninfo.hxx>
85 : #include <htmltbl.hxx>
86 : #include <lineinfo.hxx>
87 : #include <ndgrf.hxx>
88 : #include <ndole.hxx>
89 : #include <ndtxt.hxx>
90 : #include <pagedesc.hxx>
91 : #include <paratr.hxx>
92 : #include <swmodule.hxx>
93 : #include <swtable.hxx>
94 : #include <txtftn.hxx>
95 : #include <txtinet.hxx>
96 :
97 : #include <osl/file.hxx>
98 : #include <vcl/temporaryfonts.hxx>
99 :
100 : #include <com/sun/star/i18n/ScriptType.hpp>
101 : #include <com/sun/star/chart2/XChartDocument.hpp>
102 :
103 : #if OSL_DEBUG_LEVEL > 1
104 : #include <stdio.h>
105 : #endif
106 :
107 : using ::editeng::SvxBorderLine;
108 :
109 : using namespace oox;
110 : using namespace docx;
111 : using namespace sax_fastparser;
112 : using namespace nsSwDocInfoSubType;
113 : using namespace nsFieldFlags;
114 : using namespace sw::util;
115 : using namespace ::com::sun::star;
116 :
117 0 : class FFDataWriterHelper
118 : {
119 : ::sax_fastparser::FSHelperPtr m_pSerializer;
120 0 : void writeCommonStart( const rtl::OUString& rName )
121 : {
122 0 : m_pSerializer->startElementNS( XML_w, XML_ffData, FSEND );
123 : m_pSerializer->singleElementNS( XML_w, XML_name,
124 : FSNS( XML_w, XML_val ), OUStringToOString( rName, RTL_TEXTENCODING_UTF8 ).getStr(),
125 0 : FSEND );
126 0 : m_pSerializer->singleElementNS( XML_w, XML_enabled, FSEND );
127 : m_pSerializer->singleElementNS( XML_w, XML_calcOnExit,
128 : FSNS( XML_w, XML_val ),
129 0 : "0", FSEND );
130 0 : }
131 0 : void writeFinish()
132 : {
133 0 : m_pSerializer->endElementNS( XML_w, XML_ffData );
134 0 : }
135 : public:
136 0 : FFDataWriterHelper( const ::sax_fastparser::FSHelperPtr pSerializer ) : m_pSerializer( pSerializer ){}
137 0 : void WriteFormCheckbox( const rtl::OUString& rName, const rtl::OUString& rDefault, bool bChecked )
138 : {
139 0 : writeCommonStart( rName );
140 : // Checkbox specific bits
141 0 : m_pSerializer->startElementNS( XML_w, XML_checkBox, FSEND );
142 : // currently hardcoding autosize
143 : // #TODO check if this defaulted
144 0 : m_pSerializer->startElementNS( XML_w, XML_sizeAuto, FSEND );
145 0 : m_pSerializer->endElementNS( XML_w, XML_sizeAuto );
146 0 : if ( !rDefault.isEmpty() )
147 : {
148 : m_pSerializer->singleElementNS( XML_w, XML_default,
149 : FSNS( XML_w, XML_val ),
150 0 : rtl::OUStringToOString( rDefault, RTL_TEXTENCODING_UTF8 ).getStr(), FSEND );
151 : }
152 0 : if ( bChecked )
153 0 : m_pSerializer->singleElementNS( XML_w, XML_checked, FSEND );
154 0 : m_pSerializer->endElementNS( XML_w, XML_checkBox );
155 0 : writeFinish();
156 0 : }
157 0 : void WriteFormText( const rtl::OUString& rName, const rtl::OUString& rDefault )
158 : {
159 0 : writeCommonStart( rName );
160 0 : if ( !rDefault.isEmpty() )
161 : {
162 0 : m_pSerializer->startElementNS( XML_w, XML_textInput, FSEND );
163 : m_pSerializer->singleElementNS( XML_w, XML_default,
164 : FSNS( XML_w, XML_val ),
165 0 : rtl::OUStringToOString( rDefault, RTL_TEXTENCODING_UTF8 ).getStr(), FSEND );
166 0 : m_pSerializer->endElementNS( XML_w, XML_textInput );
167 : }
168 0 : writeFinish();
169 0 : }
170 : };
171 :
172 : class FieldMarkParamsHelper
173 : {
174 : const sw::mark::IFieldmark& mrFieldmark;
175 : public:
176 0 : FieldMarkParamsHelper( const sw::mark::IFieldmark& rFieldmark ) : mrFieldmark( rFieldmark ) {}
177 0 : rtl::OUString getName() { return mrFieldmark.GetName(); }
178 : template < typename T >
179 0 : bool extractParam( const rtl::OUString& rKey, T& rResult )
180 : {
181 0 : bool bResult = false;
182 0 : if ( mrFieldmark.GetParameters() )
183 : {
184 0 : sw::mark::IFieldmark::parameter_map_t::const_iterator it = mrFieldmark.GetParameters()->find( rKey );
185 0 : if ( it != mrFieldmark.GetParameters()->end() )
186 0 : bResult = ( it->second >>= rResult );
187 : }
188 0 : return bResult;
189 : }
190 : };
191 109 : void DocxAttributeOutput::RTLAndCJKState( bool bIsRTL, sal_uInt16 /*nScript*/ )
192 : {
193 109 : if (bIsRTL)
194 0 : m_pSerializer->singleElementNS( XML_w, XML_rtl, FSNS( XML_w, XML_val ), "true", FSEND );
195 109 : }
196 :
197 86 : void DocxAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo )
198 : {
199 86 : if ( m_nColBreakStatus == COLBRK_POSTPONE )
200 0 : m_nColBreakStatus = COLBRK_WRITE;
201 :
202 : // Output table/table row/table cell starts if needed
203 86 : if ( pTextNodeInfo.get() )
204 : {
205 38 : sal_uInt32 nRow = pTextNodeInfo->getRow();
206 38 : sal_uInt32 nCell = pTextNodeInfo->getCell();
207 :
208 : // New cell/row?
209 38 : if ( m_nTableDepth > 0 && !m_bTableCellOpen )
210 : {
211 33 : ww8::WW8TableNodeInfoInner::Pointer_t pDeepInner( pTextNodeInfo->getInnerForDepth( m_nTableDepth ) );
212 33 : if ( pDeepInner->getCell() == 0 )
213 7 : StartTableRow( pDeepInner );
214 :
215 33 : StartTableCell( pDeepInner );
216 : }
217 :
218 38 : if ( nRow == 0 && nCell == 0 )
219 : {
220 : // Do we have to start the table?
221 : // [If we are at the rigth depth already, it means that we
222 : // continue the table cell]
223 5 : sal_uInt32 nCurrentDepth = pTextNodeInfo->getDepth();
224 :
225 5 : if ( nCurrentDepth > m_nTableDepth )
226 : {
227 : // Start all the tables that begin here
228 10 : for ( sal_uInt32 nDepth = m_nTableDepth + 1; nDepth <= pTextNodeInfo->getDepth(); ++nDepth )
229 : {
230 5 : ww8::WW8TableNodeInfoInner::Pointer_t pInner( pTextNodeInfo->getInnerForDepth( nDepth ) );
231 :
232 5 : StartTable( pInner );
233 5 : StartTableRow( pInner );
234 5 : StartTableCell( pInner );
235 5 : }
236 :
237 5 : m_nTableDepth = nCurrentDepth;
238 : }
239 : }
240 : }
241 :
242 86 : m_pSerializer->startElementNS( XML_w, XML_p, FSEND );
243 :
244 : // postpone the output of the run (we get it before the paragraph
245 : // properties, but must write it after them)
246 86 : m_pSerializer->mark();
247 :
248 : // no section break in this paragraph yet; can be set in SectionBreak()
249 86 : m_pSectionInfo.reset();
250 :
251 86 : m_bParagraphOpened = true;
252 86 : }
253 :
254 86 : void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner )
255 : {
256 : // write the paragraph properties + the run, already in the correct order
257 86 : m_pSerializer->mergeTopMarks();
258 86 : m_pSerializer->endElementNS( XML_w, XML_p );
259 :
260 : // Check for end of cell, rows, tables here
261 86 : FinishTableRowCell( pTextNodeInfoInner );
262 :
263 86 : m_bParagraphOpened = false;
264 :
265 : // Write the anchored frame if any
266 86 : if ( m_pParentFrame )
267 : {
268 0 : sw::Frame *pParentFrame = m_pParentFrame;
269 0 : m_pParentFrame = NULL;
270 :
271 0 : const SwFrmFmt& rFrmFmt = pParentFrame->GetFrmFmt( );
272 0 : const SwNodeIndex* pNodeIndex = rFrmFmt.GetCntnt().GetCntntIdx();
273 :
274 0 : sal_uLong nStt = pNodeIndex ? pNodeIndex->GetIndex()+1 : 0;
275 0 : sal_uLong nEnd = pNodeIndex ? pNodeIndex->GetNode().EndOfSectionIndex() : 0;
276 :
277 0 : m_rExport.SaveData( nStt, nEnd );
278 :
279 0 : m_rExport.mpParentFrame = pParentFrame;
280 :
281 0 : m_rExport.WriteText( );
282 :
283 0 : m_rExport.RestoreData();
284 :
285 0 : delete pParentFrame;
286 : }
287 86 : }
288 :
289 162 : void DocxAttributeOutput::FinishTableRowCell( ww8::WW8TableNodeInfoInner::Pointer_t pInner, bool bForceEmptyParagraph )
290 : {
291 162 : if ( pInner.get() )
292 : {
293 : // Where are we in the table
294 114 : sal_uInt32 nRow = pInner->getRow( );
295 :
296 114 : const SwTable *pTable = pInner->getTable( );
297 114 : const SwTableLines& rLines = pTable->GetTabLines( );
298 114 : sal_uInt16 nLinesCount = rLines.size( );
299 : // HACK
300 : // msoffice seems to have an internal limitation of 63 columns for tables
301 : // and refuses to load .docx with more, even though the spec seems to allow that;
302 : // so simply if there are more columns, don't close the last one msoffice will handle
303 : // and merge the contents of the remaining ones into it (since we don't close the cell
304 : // here, following ones will not be opened)
305 114 : bool limitWorkaround = ( pInner->getCell() >= 62 && !pInner->isEndOfLine());
306 :
307 114 : if ( pInner->isEndOfCell() && !limitWorkaround )
308 : {
309 38 : if ( bForceEmptyParagraph )
310 0 : m_pSerializer->singleElementNS( XML_w, XML_p, FSEND );
311 :
312 38 : EndTableCell();
313 : }
314 :
315 : // This is a line end
316 114 : if ( pInner->isEndOfLine() )
317 12 : EndTableRow();
318 :
319 : // This is the end of the table
320 114 : if ( pInner->isEndOfLine( ) && ( nRow + 1 ) == nLinesCount )
321 5 : EndTable();
322 : }
323 162 : }
324 :
325 0 : void DocxAttributeOutput::EmptyParagraph()
326 : {
327 0 : m_pSerializer->singleElementNS( XML_w, XML_p, FSEND );
328 0 : }
329 :
330 85 : void DocxAttributeOutput::StartParagraphProperties( const SwTxtNode& rNode )
331 : {
332 : // output page/section breaks
333 : // Writer can have them at the beginning of a paragraph, or at the end, but
334 : // in docx, we have to output them in the paragraph properties of the last
335 : // paragraph in a section. To get it right, we have to switch to the next
336 : // paragraph, and detect the section breaks there.
337 85 : SwNodeIndex aNextIndex( rNode, 1 );
338 85 : if ( aNextIndex.GetNode().IsTxtNode() )
339 : {
340 18 : const SwTxtNode* pTxtNode = static_cast< SwTxtNode* >( &aNextIndex.GetNode() );
341 18 : m_rExport.OutputSectionBreaks( pTxtNode->GetpSwAttrSet(), *pTxtNode );
342 : }
343 67 : else if ( aNextIndex.GetNode().IsTableNode() )
344 : {
345 5 : const SwTableNode* pTableNode = static_cast< SwTableNode* >( &aNextIndex.GetNode() );
346 5 : const SwFrmFmt *pFmt = pTableNode->GetTable().GetFrmFmt();
347 5 : m_rExport.OutputSectionBreaks( &(pFmt->GetAttrSet()), *pTableNode );
348 : }
349 :
350 85 : m_pSerializer->mark( );
351 :
352 85 : m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND );
353 :
354 : // and output the section break now (if it appeared)
355 85 : if ( m_pSectionInfo )
356 : {
357 0 : m_rExport.SectionProperties( *m_pSectionInfo );
358 0 : m_pSectionInfo.reset();
359 : }
360 :
361 85 : InitCollectedParagraphProperties();
362 85 : }
363 :
364 234 : void DocxAttributeOutput::InitCollectedParagraphProperties()
365 : {
366 234 : m_pParagraphSpacingAttrList = NULL;
367 :
368 : // Write the elements in the spec order
369 : static const sal_Int32 aOrder[] =
370 : {
371 : FSNS( XML_w, XML_pStyle ),
372 : FSNS( XML_w, XML_keepNext ),
373 : FSNS( XML_w, XML_keepLines ),
374 : FSNS( XML_w, XML_pageBreakBefore ),
375 : FSNS( XML_w, XML_framePr ),
376 : FSNS( XML_w, XML_widowControl ),
377 : FSNS( XML_w, XML_numPr ),
378 : FSNS( XML_w, XML_suppressLineNumbers ),
379 : FSNS( XML_w, XML_pBdr ),
380 : FSNS( XML_w, XML_shd ),
381 : FSNS( XML_w, XML_tabs ),
382 : FSNS( XML_w, XML_suppressAutoHyphens ),
383 : FSNS( XML_w, XML_kinsoku ),
384 : FSNS( XML_w, XML_wordWrap ),
385 : FSNS( XML_w, XML_overflowPunct ),
386 : FSNS( XML_w, XML_topLinePunct ),
387 : FSNS( XML_w, XML_autoSpaceDE ),
388 : FSNS( XML_w, XML_autoSpaceDN ),
389 : FSNS( XML_w, XML_bidi ),
390 : FSNS( XML_w, XML_adjustRightInd ),
391 : FSNS( XML_w, XML_snapToGrid ),
392 : FSNS( XML_w, XML_spacing ),
393 : FSNS( XML_w, XML_ind ),
394 : FSNS( XML_w, XML_contextualSpacing ),
395 : FSNS( XML_w, XML_mirrorIndents ),
396 : FSNS( XML_w, XML_suppressOverlap ),
397 : FSNS( XML_w, XML_jc ),
398 : FSNS( XML_w, XML_textDirection ),
399 : FSNS( XML_w, XML_textAlignment ),
400 : FSNS( XML_w, XML_textboxTightWrap ),
401 : FSNS( XML_w, XML_outlineLvl ),
402 : FSNS( XML_w, XML_divId ),
403 : FSNS( XML_w, XML_cnfStyle ),
404 : FSNS( XML_w, XML_rPr ),
405 : FSNS( XML_w, XML_sectPr ),
406 : FSNS( XML_w, XML_pPrChange )
407 : };
408 :
409 : // postpone the output so that we can later [in EndParagraphProperties()]
410 : // prepend the properties before the run
411 234 : sal_Int32 len = sizeof ( aOrder ) / sizeof( sal_Int32 );
412 234 : uno::Sequence< sal_Int32 > aSeqOrder( len );
413 8658 : for ( sal_Int32 i = 0; i < len; i++ )
414 8424 : aSeqOrder[i] = aOrder[i];
415 :
416 234 : m_pSerializer->mark( aSeqOrder );
417 234 : }
418 :
419 234 : void DocxAttributeOutput::WriteCollectedParagraphProperties()
420 : {
421 234 : if ( m_pFlyAttrList )
422 : {
423 0 : XFastAttributeListRef xAttrList( m_pFlyAttrList );
424 0 : m_pFlyAttrList = NULL;
425 :
426 0 : m_pSerializer->singleElementNS( XML_w, XML_framePr, xAttrList );
427 : }
428 :
429 234 : if ( m_pParagraphSpacingAttrList )
430 : {
431 83 : XFastAttributeListRef xAttrList( m_pParagraphSpacingAttrList );
432 83 : m_pParagraphSpacingAttrList = NULL;
433 :
434 83 : m_pSerializer->singleElementNS( XML_w, XML_spacing, xAttrList );
435 : }
436 :
437 : // Merge the marks for the ordered elements
438 234 : m_pSerializer->mergeTopMarks( );
439 234 : }
440 :
441 85 : void DocxAttributeOutput::EndParagraphProperties()
442 : {
443 85 : WriteCollectedParagraphProperties();
444 :
445 85 : m_pSerializer->endElementNS( XML_w, XML_pPr );
446 :
447 85 : if ( m_nColBreakStatus == COLBRK_WRITE )
448 : {
449 0 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
450 : m_pSerializer->singleElementNS( XML_w, XML_br,
451 0 : FSNS( XML_w, XML_type ), "column", FSEND );
452 0 : m_pSerializer->endElementNS( XML_w, XML_r );
453 :
454 0 : m_nColBreakStatus = COLBRK_NONE;
455 : }
456 :
457 : // merge the properties _before_ the run (strictly speaking, just
458 : // after the start of the paragraph)
459 85 : m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND );
460 85 : }
461 :
462 110 : void DocxAttributeOutput::StartRun( const SwRedlineData* pRedlineData, bool /*bSingleEmptyRun*/ )
463 : {
464 : // Don't start redline data here, possibly there is a hyperlink later, and
465 : // that has to be started first.
466 110 : m_pRedlineData = pRedlineData;
467 :
468 : // postpone the output of the start of a run (there are elements that need
469 : // to be written before the start of the run, but we learn which they are
470 : // _inside_ of the run)
471 110 : m_pSerializer->mark(); // let's call it "postponed run start"
472 :
473 : // postpone the output of the text (we get it before the run properties,
474 : // but must write it after them)
475 110 : m_pSerializer->mark(); // let's call it "postponed text"
476 110 : }
477 :
478 110 : void DocxAttributeOutput::EndRun()
479 : {
480 : // Write field starts
481 222 : for ( std::vector<FieldInfos>::iterator pIt = m_Fields.begin(); pIt != m_Fields.end(); )
482 : {
483 : // Add the fields starts for all but hyperlinks and TOCs
484 2 : if ( pIt->bOpen && pIt->pField )
485 : {
486 0 : StartField_Impl( *pIt );
487 :
488 : // Remove the field from the stack if only the start has to be written
489 : // Unknown fields sould be removed too
490 0 : if ( !pIt->bClose || ( pIt->eType == ww::eUNKNOWN ) )
491 : {
492 0 : pIt = m_Fields.erase( pIt );
493 0 : continue;
494 : }
495 : }
496 2 : ++pIt;
497 : }
498 :
499 : // write the run properties + the text, already in the correct order
500 110 : m_pSerializer->mergeTopMarks(); // merges with "postponed text", see above
501 :
502 : // level down, to be able to prepend the actual run start attribute (just
503 : // before "postponed run start")
504 110 : m_pSerializer->mark(); // let's call it "actual run start"
505 :
506 110 : if ( m_closeHyperlinkInPreviousRun )
507 : {
508 2 : if ( m_startedHyperlink )
509 : {
510 1 : m_pSerializer->endElementNS( XML_w, XML_hyperlink );
511 1 : m_startedHyperlink = false;
512 : }
513 2 : m_closeHyperlinkInPreviousRun = false;
514 : }
515 :
516 : // Write the hyperlink and toc fields starts
517 222 : for ( std::vector<FieldInfos>::iterator pIt = m_Fields.begin(); pIt != m_Fields.end(); )
518 : {
519 : // Add the fields starts for hyperlinks, TOCs and index marks
520 2 : if ( pIt->bOpen && !pIt->pField )
521 : {
522 2 : StartField_Impl( *pIt, sal_True );
523 :
524 : // Remove the field if no end needs to be written
525 2 : if ( !pIt->bClose ) {
526 0 : pIt = m_Fields.erase( pIt );
527 0 : continue;
528 : }
529 : }
530 2 : ++pIt;
531 : }
532 :
533 : // Start the hyperlink after the fields separators or we would generate invalid file
534 110 : if ( m_pHyperlinkAttrList )
535 : {
536 1 : XFastAttributeListRef xAttrList ( m_pHyperlinkAttrList );
537 :
538 1 : m_pSerializer->startElementNS( XML_w, XML_hyperlink, xAttrList );
539 1 : m_pHyperlinkAttrList = NULL;
540 1 : m_startedHyperlink = true;
541 : }
542 :
543 : // if there is some redlining in the document, output it
544 110 : StartRedline();
545 :
546 110 : DoWriteBookmarks( );
547 110 : WriteCommentRanges();
548 :
549 110 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
550 110 : m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND ); // merges with "postponed run start", see above
551 :
552 : // write the run start + the run content
553 110 : m_pSerializer->mergeTopMarks(); // merges the "actual run start"
554 :
555 : // append the actual run end
556 110 : m_pSerializer->endElementNS( XML_w, XML_r );
557 :
558 110 : WritePostponedMath();
559 :
560 110 : if ( m_closeHyperlinkInThisRun )
561 : {
562 1 : if ( m_startedHyperlink )
563 : {
564 0 : m_pSerializer->endElementNS( XML_w, XML_hyperlink );
565 0 : m_startedHyperlink = false;
566 : }
567 1 : m_closeHyperlinkInThisRun = false;
568 : }
569 :
570 222 : while ( m_Fields.begin() != m_Fields.end() )
571 : {
572 2 : EndField_Impl( m_Fields.front( ) );
573 2 : m_Fields.erase( m_Fields.begin( ) );
574 : }
575 :
576 : // if there is some redlining in the document, output it
577 110 : EndRedline();
578 110 : }
579 :
580 110 : void DocxAttributeOutput::WriteCommentRanges()
581 : {
582 110 : if (m_bPostitStart)
583 : {
584 1 : m_bPostitStart = false;
585 1 : OString idstr = OString::valueOf( sal_Int32( m_postitFieldsMaxId ));
586 1 : m_pSerializer->singleElementNS( XML_w, XML_commentRangeStart, FSNS( XML_w, XML_id ), idstr.getStr(), FSEND );
587 : }
588 110 : if (m_bPostitEnd)
589 : {
590 1 : m_bPostitEnd = false;
591 1 : OString idstr = OString::valueOf( sal_Int32( m_postitFieldsMaxId ));
592 1 : m_pSerializer->singleElementNS( XML_w, XML_commentRangeEnd, FSNS( XML_w, XML_id ), idstr.getStr(), FSEND );
593 : }
594 110 : }
595 :
596 110 : void DocxAttributeOutput::DoWriteBookmarks()
597 : {
598 : // Write the start bookmarks
599 113 : for ( std::vector< OString >::const_iterator it = m_rMarksStart.begin(), end = m_rMarksStart.end();
600 : it != end; ++it )
601 : {
602 3 : const OString& rName = *it;
603 :
604 : // Output the bookmark
605 3 : sal_uInt16 nId = m_nNextMarkId++;
606 3 : m_rOpenedMarksIds[rName] = nId;
607 : m_pSerializer->singleElementNS( XML_w, XML_bookmarkStart,
608 : FSNS( XML_w, XML_id ), OString::valueOf( sal_Int32( nId ) ).getStr( ),
609 : FSNS( XML_w, XML_name ), rName.getStr(),
610 3 : FSEND );
611 : }
612 110 : m_rMarksStart.clear();
613 :
614 : // export the end bookmarks
615 113 : for ( std::vector< OString >::const_iterator it = m_rMarksEnd.begin(), end = m_rMarksEnd.end();
616 : it != end; ++it )
617 : {
618 3 : const OString& rName = *it;
619 :
620 : // Get the id of the bookmark
621 3 : std::map< OString, sal_uInt16 >::iterator pPos = m_rOpenedMarksIds.find( rName );
622 3 : if ( pPos != m_rOpenedMarksIds.end( ) )
623 : {
624 3 : sal_uInt16 nId = ( *pPos ).second;
625 : m_pSerializer->singleElementNS( XML_w, XML_bookmarkEnd,
626 : FSNS( XML_w, XML_id ), OString::valueOf( sal_Int32( nId ) ).getStr( ),
627 3 : FSEND );
628 3 : m_rOpenedMarksIds.erase( rName );
629 : }
630 : }
631 110 : m_rMarksEnd.clear();
632 110 : }
633 :
634 0 : void DocxAttributeOutput::WriteFFData( const FieldInfos& rInfos )
635 : {
636 0 : const ::sw::mark::IFieldmark& rFieldmark = *rInfos.pFieldmark;
637 0 : if ( rInfos.eType == ww::eFORMDROPDOWN )
638 : {
639 0 : uno::Sequence< ::rtl::OUString> vListEntries;
640 0 : rtl::OUString sName, sHelp, sToolTip, sSelected;
641 :
642 0 : FieldMarkParamsHelper params( rFieldmark );
643 0 : params.extractParam( ODF_FORMDROPDOWN_LISTENTRY, vListEntries );
644 0 : sName = params.getName();
645 0 : sal_Int32 nSelectedIndex = 0;
646 :
647 0 : if ( params.extractParam( ODF_FORMDROPDOWN_RESULT, nSelectedIndex ) )
648 : {
649 0 : if (nSelectedIndex < vListEntries.getLength() )
650 0 : sSelected = vListEntries[ nSelectedIndex ];
651 : }
652 :
653 0 : GetExport().DoComboBox( sName, sHelp, sToolTip, sSelected, vListEntries );
654 : }
655 0 : else if ( rInfos.eType == ww::eFORMCHECKBOX )
656 : {
657 0 : rtl::OUString sName;
658 0 : bool bChecked = false;
659 :
660 0 : FieldMarkParamsHelper params( rFieldmark );
661 0 : params.extractParam( ODF_FORMCHECKBOX_NAME, sName );
662 :
663 0 : const sw::mark::ICheckboxFieldmark* pCheckboxFm = dynamic_cast<const sw::mark::ICheckboxFieldmark*>(&rFieldmark);
664 0 : if ( pCheckboxFm && pCheckboxFm->IsChecked() )
665 0 : bChecked = true;
666 :
667 0 : FFDataWriterHelper ffdataOut( m_pSerializer );
668 0 : ffdataOut.WriteFormCheckbox( sName, rtl::OUString(), bChecked );
669 : }
670 0 : else if ( rInfos.eType == ww::eFORMTEXT )
671 : {
672 0 : FieldMarkParamsHelper params( rFieldmark );
673 0 : FFDataWriterHelper ffdataOut( m_pSerializer );
674 0 : ffdataOut.WriteFormText( params.getName(), rtl::OUString() );
675 : }
676 0 : }
677 :
678 2 : void DocxAttributeOutput::StartField_Impl( FieldInfos& rInfos, bool bWriteRun )
679 : {
680 2 : if ( rInfos.pField && rInfos.eType == ww::eUNKNOWN )
681 : {
682 : // Expand unsupported fields
683 0 : RunText( rInfos.pField->GetFieldName() );
684 : }
685 2 : else if ( rInfos.eType != ww::eNONE ) // HYPERLINK fields are just commands
686 : {
687 2 : if ( bWriteRun )
688 2 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
689 :
690 2 : if ( rInfos.eType == ww::eFORMDROPDOWN )
691 : {
692 : m_pSerializer->startElementNS( XML_w, XML_fldChar,
693 : FSNS( XML_w, XML_fldCharType ), "begin",
694 0 : FSEND );
695 0 : if ( rInfos.pFieldmark && !rInfos.pField )
696 0 : WriteFFData( rInfos );
697 0 : if ( rInfos.pField )
698 : {
699 0 : const SwDropDownField& rFld2 = *(SwDropDownField*)rInfos.pField;
700 : uno::Sequence<rtl::OUString> aItems =
701 0 : rFld2.GetItemSequence();
702 0 : GetExport().DoComboBox(rFld2.GetName(),
703 0 : rFld2.GetHelp(),
704 0 : rFld2.GetToolTip(),
705 0 : rFld2.GetSelectedItem(), aItems);
706 : }
707 0 : m_pSerializer->endElementNS( XML_w, XML_fldChar );
708 :
709 0 : if ( bWriteRun )
710 0 : m_pSerializer->endElementNS( XML_w, XML_r );
711 0 : if ( !rInfos.pField )
712 0 : CmdField_Impl( rInfos );
713 :
714 : }
715 : else
716 : {
717 : // Write the field start
718 : m_pSerializer->startElementNS( XML_w, XML_fldChar,
719 : FSNS( XML_w, XML_fldCharType ), "begin",
720 2 : FSEND );
721 :
722 2 : if ( rInfos.pFieldmark )
723 0 : WriteFFData( rInfos );
724 :
725 2 : m_pSerializer->endElementNS( XML_w, XML_fldChar );
726 :
727 2 : if ( bWriteRun )
728 2 : m_pSerializer->endElementNS( XML_w, XML_r );
729 :
730 : // The hyperlinks fields can't be expanded: the value is
731 : // normally in the text run
732 2 : if ( !rInfos.pField )
733 2 : CmdField_Impl( rInfos );
734 : }
735 : }
736 2 : }
737 :
738 2 : void DocxAttributeOutput::DoWriteCmd( String& rCmd )
739 : {
740 : // Write the Field command
741 2 : m_pSerializer->startElementNS( XML_w, XML_instrText, FSEND );
742 2 : m_pSerializer->writeEscaped( OUString( rCmd ) );
743 2 : m_pSerializer->endElementNS( XML_w, XML_instrText );
744 :
745 2 : }
746 :
747 2 : void DocxAttributeOutput::CmdField_Impl( FieldInfos& rInfos )
748 : {
749 2 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
750 2 : xub_StrLen nNbToken = comphelper::string::getTokenCount(rInfos.sCmd, '\t');
751 :
752 4 : for ( xub_StrLen i = 0; i < nNbToken; i++ )
753 : {
754 2 : String sToken = rInfos.sCmd.GetToken( i, '\t' );
755 2 : if ( rInfos.eType == ww::eCREATEDATE
756 : || rInfos.eType == ww::eSAVEDATE
757 : || rInfos.eType == ww::ePRINTDATE
758 : || rInfos.eType == ww::eDATE
759 : || rInfos.eType == ww::eTIME )
760 : {
761 0 : sToken.SearchAndReplaceAll( String( "NNNN" ), String( "dddd" ) );
762 0 : sToken.SearchAndReplaceAll( String( "NN" ), String( "ddd" ) );
763 : }
764 : // Write the Field command
765 2 : DoWriteCmd( sToken );
766 :
767 : // Replace tabs by </instrText><tab/><instrText>
768 2 : if ( i < ( nNbToken - 1 ) )
769 0 : RunText( rtl::OUString( "\t" ) );
770 2 : }
771 :
772 2 : m_pSerializer->endElementNS( XML_w, XML_r );
773 :
774 : // Write the Field separator
775 2 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
776 : m_pSerializer->singleElementNS( XML_w, XML_fldChar,
777 : FSNS( XML_w, XML_fldCharType ), "separate",
778 2 : FSEND );
779 2 : m_pSerializer->endElementNS( XML_w, XML_r );
780 2 : }
781 :
782 2 : void DocxAttributeOutput::EndField_Impl( FieldInfos& rInfos )
783 : {
784 : // The command has to be written before for the hyperlinks
785 2 : if ( rInfos.pField )
786 : {
787 0 : CmdField_Impl( rInfos );
788 : }
789 :
790 : // Write the bookmark start if any
791 2 : OUString aBkmName( m_sFieldBkm );
792 2 : if ( !aBkmName.isEmpty() )
793 : {
794 : m_pSerializer->singleElementNS( XML_w, XML_bookmarkStart,
795 : FSNS( XML_w, XML_id ), OString::valueOf( sal_Int32( m_nNextMarkId ) ).getStr( ),
796 : FSNS( XML_w, XML_name ), OUStringToOString( aBkmName, RTL_TEXTENCODING_UTF8 ).getStr( ),
797 0 : FSEND );
798 : }
799 :
800 2 : if (rInfos.pField ) // For hyperlinks and TOX
801 : {
802 : // Write the Field latest value
803 0 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
804 :
805 0 : String sExpand( rInfos.pField->ExpandField( true ) );
806 : // newlines embedded in fields are 0x0B in MSO and 0x0A for us
807 0 : sExpand.SearchAndReplaceAll( 0x0A, 0x0B );
808 0 : RunText( sExpand );
809 :
810 0 : m_pSerializer->endElementNS( XML_w, XML_r );
811 : }
812 :
813 : // Write the bookmark end if any
814 2 : if ( !aBkmName.isEmpty() )
815 : {
816 : m_pSerializer->singleElementNS( XML_w, XML_bookmarkEnd,
817 : FSNS( XML_w, XML_id ), OString::valueOf( sal_Int32( m_nNextMarkId ) ).getStr( ),
818 0 : FSEND );
819 :
820 0 : m_nNextMarkId++;
821 : }
822 :
823 : // Write the Field end
824 2 : if ( rInfos.bClose )
825 : {
826 2 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
827 : m_pSerializer->singleElementNS( XML_w, XML_fldChar,
828 : FSNS( XML_w, XML_fldCharType ), "end",
829 2 : FSEND );
830 2 : m_pSerializer->endElementNS( XML_w, XML_r );
831 : }
832 : // Write the ref field if a bookmark had to be set and the field
833 : // should be visible
834 2 : if ( rInfos.pField )
835 : {
836 0 : sal_uInt16 nSubType = rInfos.pField->GetSubType( );
837 0 : bool bIsSetField = rInfos.pField->GetTyp( )->Which( ) == RES_SETEXPFLD;
838 0 : bool bShowRef = ( !bIsSetField || ( nSubType & nsSwExtendedSubType::SUB_INVISIBLE ) ) ? false : true;
839 :
840 0 : if ( ( m_sFieldBkm.Len( ) > 0 ) && bShowRef )
841 : {
842 : // Write the field beginning
843 0 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
844 : m_pSerializer->singleElementNS( XML_w, XML_fldChar,
845 : FSNS( XML_w, XML_fldCharType ), "begin",
846 0 : FSEND );
847 0 : m_pSerializer->endElementNS( XML_w, XML_r );
848 :
849 0 : rInfos.sCmd = FieldString( ww::eREF );
850 0 : rInfos.sCmd.AppendAscii( "\"" );
851 0 : rInfos.sCmd += m_sFieldBkm;
852 0 : rInfos.sCmd.AppendAscii( "\" " );
853 :
854 : // Clean the field bookmark data to avoid infinite loop
855 0 : m_sFieldBkm = String( );
856 :
857 : // Write the end of the field
858 0 : EndField_Impl( rInfos );
859 : }
860 2 : }
861 2 : }
862 :
863 110 : void DocxAttributeOutput::StartRunProperties()
864 : {
865 : // postpone the output so that we can later [in EndRunProperties()]
866 : // prepend the properties before the text
867 110 : m_pSerializer->mark();
868 :
869 110 : m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
870 :
871 110 : InitCollectedRunProperties();
872 :
873 : OSL_ASSERT( m_postponedGraphic == NULL );
874 110 : m_postponedGraphic = new std::list< PostponedGraphic >;
875 110 : }
876 :
877 274 : void DocxAttributeOutput::InitCollectedRunProperties()
878 : {
879 274 : m_pFontsAttrList = NULL;
880 274 : m_pEastAsianLayoutAttrList = NULL;
881 274 : m_pCharLangAttrList = NULL;
882 :
883 : // Write the elements in the spec order
884 : static const sal_Int32 aOrder[] =
885 : {
886 : FSNS( XML_w, XML_rStyle ),
887 : FSNS( XML_w, XML_rFonts ),
888 : FSNS( XML_w, XML_b ),
889 : FSNS( XML_w, XML_bCs ),
890 : FSNS( XML_w, XML_i ),
891 : FSNS( XML_w, XML_iCs ),
892 : FSNS( XML_w, XML_caps ),
893 : FSNS( XML_w, XML_smallCaps ),
894 : FSNS( XML_w, XML_strike ),
895 : FSNS( XML_w, XML_dstrike ),
896 : FSNS( XML_w, XML_outline ),
897 : FSNS( XML_w, XML_shadow ),
898 : FSNS( XML_w, XML_emboss ),
899 : FSNS( XML_w, XML_imprint ),
900 : FSNS( XML_w, XML_noProof ),
901 : FSNS( XML_w, XML_snapToGrid ),
902 : FSNS( XML_w, XML_vanish ),
903 : FSNS( XML_w, XML_webHidden ),
904 : FSNS( XML_w, XML_color ),
905 : FSNS( XML_w, XML_spacing ),
906 : FSNS( XML_w, XML_w ),
907 : FSNS( XML_w, XML_kern ),
908 : FSNS( XML_w, XML_position ),
909 : FSNS( XML_w, XML_sz ),
910 : FSNS( XML_w, XML_szCs ),
911 : FSNS( XML_w, XML_highlight ),
912 : FSNS( XML_w, XML_u ),
913 : FSNS( XML_w, XML_effect ),
914 : FSNS( XML_w, XML_bdr ),
915 : FSNS( XML_w, XML_shd ),
916 : FSNS( XML_w, XML_fitText ),
917 : FSNS( XML_w, XML_vertAlign ),
918 : FSNS( XML_w, XML_rtl ),
919 : FSNS( XML_w, XML_cs ),
920 : FSNS( XML_w, XML_em ),
921 : FSNS( XML_w, XML_lang ),
922 : FSNS( XML_w, XML_eastAsianLayout ),
923 : FSNS( XML_w, XML_specVanish ),
924 : FSNS( XML_w, XML_oMath ),
925 : FSNS( XML_w, XML_rPrChange )
926 : };
927 :
928 : // postpone the output so that we can later [in EndParagraphProperties()]
929 : // prepend the properties before the run
930 274 : sal_Int32 len = sizeof ( aOrder ) / sizeof( sal_Int32 );
931 274 : uno::Sequence< sal_Int32 > aSeqOrder( len );
932 11234 : for ( sal_Int32 i = 0; i < len; i++ )
933 10960 : aSeqOrder[i] = aOrder[i];
934 :
935 274 : m_pSerializer->mark( aSeqOrder );
936 :
937 274 : }
938 :
939 274 : void DocxAttributeOutput::WriteCollectedRunProperties()
940 : {
941 : // Write all differed properties
942 274 : if ( m_pFontsAttrList )
943 : {
944 123 : XFastAttributeListRef xAttrList( m_pFontsAttrList );
945 123 : m_pFontsAttrList = NULL;
946 :
947 123 : m_pSerializer->singleElementNS( XML_w, XML_rFonts, xAttrList );
948 : }
949 :
950 274 : if ( m_pEastAsianLayoutAttrList )
951 : {
952 0 : XFastAttributeListRef xAttrList( m_pEastAsianLayoutAttrList );
953 0 : m_pEastAsianLayoutAttrList = NULL;
954 :
955 0 : m_pSerializer->singleElementNS( XML_w, XML_eastAsianLayout, xAttrList );
956 : }
957 :
958 274 : if ( m_pCharLangAttrList )
959 : {
960 57 : XFastAttributeListRef xAttrList( m_pCharLangAttrList );
961 57 : m_pCharLangAttrList = NULL;
962 :
963 57 : m_pSerializer->singleElementNS( XML_w, XML_lang, xAttrList );
964 : }
965 :
966 : // Merge the marks for the ordered elements
967 274 : m_pSerializer->mergeTopMarks();
968 274 : }
969 :
970 110 : void DocxAttributeOutput::EndRunProperties( const SwRedlineData* /*pRedlineData*/ )
971 : {
972 110 : WriteCollectedRunProperties();
973 :
974 110 : m_pSerializer->endElementNS( XML_w, XML_rPr );
975 :
976 : // write footnotes/endnotes if we have any
977 110 : FootnoteEndnoteReference();
978 :
979 110 : WritePostponedGraphic();
980 :
981 : // merge the properties _before_ the run text (strictly speaking, just
982 : // after the start of the run)
983 110 : m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND );
984 110 : }
985 :
986 110 : void DocxAttributeOutput::WritePostponedGraphic()
987 : {
988 330 : for( std::list< PostponedGraphic >::const_iterator it = m_postponedGraphic->begin();
989 220 : it != m_postponedGraphic->end();
990 : ++it )
991 0 : FlyFrameGraphic( it->grfNode, it->size );
992 110 : delete m_postponedGraphic;
993 110 : m_postponedGraphic = NULL;
994 110 : }
995 :
996 0 : void DocxAttributeOutput::FootnoteEndnoteRefTag()
997 : {
998 0 : if( m_footnoteEndnoteRefTag == 0 )
999 0 : return;
1000 0 : m_pSerializer->singleElementNS( XML_w, m_footnoteEndnoteRefTag, FSEND );
1001 0 : m_footnoteEndnoteRefTag = 0;
1002 : }
1003 :
1004 : /** Output sal_Unicode* as a run text (<t>the text</t>).
1005 :
1006 : When bMove is true, update rBegin to point _after_ the end of the text +
1007 : 1, meaning that it skips one character after the text. This is to make
1008 : the switch in DocxAttributeOutput::RunText() nicer ;-)
1009 : */
1010 30 : static void impl_WriteRunText( FSHelperPtr pSerializer, sal_Int32 nTextToken,
1011 : const sal_Unicode* &rBegin, const sal_Unicode* pEnd, bool bMove = true )
1012 : {
1013 30 : const sal_Unicode *pBegin = rBegin;
1014 :
1015 : // skip one character after the end
1016 30 : if ( bMove )
1017 0 : rBegin = pEnd + 1;
1018 :
1019 30 : if ( pBegin >= pEnd )
1020 31 : return; // we want to write at least one character
1021 :
1022 : // we have to add 'preserve' when starting/ending with space
1023 29 : if ( *pBegin == sal_Unicode( ' ' ) || *( pEnd - 1 ) == sal_Unicode( ' ' ) )
1024 : {
1025 5 : pSerializer->startElementNS( XML_w, nTextToken, FSNS( XML_xml, XML_space ), "preserve", FSEND );
1026 : }
1027 : else
1028 24 : pSerializer->startElementNS( XML_w, nTextToken, FSEND );
1029 :
1030 29 : pSerializer->writeEscaped( OUString( pBegin, pEnd - pBegin ) );
1031 :
1032 29 : pSerializer->endElementNS( XML_w, nTextToken );
1033 : }
1034 :
1035 30 : void DocxAttributeOutput::RunText( const String& rText, rtl_TextEncoding /*eCharSet*/ )
1036 : {
1037 30 : if( m_closeHyperlinkInThisRun )
1038 : {
1039 2 : m_closeHyperlinkInPreviousRun = true;
1040 2 : m_closeHyperlinkInThisRun = false;
1041 : }
1042 30 : OUString aText( rText );
1043 :
1044 : // one text can be split into more <w:t>blah</w:t>'s by line breaks etc.
1045 30 : const sal_Unicode *pBegin = aText.getStr();
1046 30 : const sal_Unicode *pEnd = pBegin + aText.getLength();
1047 :
1048 : // the text run is usually XML_t, with the exception of the deleted text
1049 30 : sal_Int32 nTextToken = XML_t;
1050 30 : if ( m_pRedlineData && m_pRedlineData->GetType() == nsRedlineType_t::REDLINE_DELETE )
1051 1 : nTextToken = XML_delText;
1052 :
1053 688 : for ( const sal_Unicode *pIt = pBegin; pIt < pEnd; ++pIt )
1054 : {
1055 658 : switch ( *pIt )
1056 : {
1057 : case 0x09: // tab
1058 0 : impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt );
1059 0 : m_pSerializer->singleElementNS( XML_w, XML_tab, FSEND );
1060 0 : break;
1061 : case 0x0b: // line break
1062 0 : impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt );
1063 0 : m_pSerializer->singleElementNS( XML_w, XML_br, FSEND );
1064 0 : break;
1065 : case 0x1E: //non-breaking hyphen
1066 0 : impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt );
1067 0 : m_pSerializer->singleElementNS( XML_w, XML_noBreakHyphen, FSEND );
1068 0 : break;
1069 : case 0x1F: //soft (on demand) hyphen
1070 0 : impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt );
1071 0 : m_pSerializer->singleElementNS( XML_w, XML_softHyphen, FSEND );
1072 0 : break;
1073 : default:
1074 658 : if ( *pIt < 0x0020 ) // filter out the control codes
1075 : {
1076 0 : impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt );
1077 : OSL_TRACE( "Ignored control code %x in a text run.", *pIt );
1078 : }
1079 658 : break;
1080 : }
1081 : }
1082 :
1083 30 : impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pEnd, false );
1084 30 : }
1085 :
1086 0 : void DocxAttributeOutput::RawText( const String& /*rText*/, bool /*bForceUnicode*/, rtl_TextEncoding /*eCharSet*/ )
1087 : {
1088 : OSL_TRACE("TODO DocxAttributeOutput::RawText( const String& rText, bool bForceUnicode, rtl_TextEncoding eCharSet )" );
1089 0 : }
1090 :
1091 0 : void DocxAttributeOutput::StartRuby( const SwTxtNode& rNode, xub_StrLen nPos, const SwFmtRuby& rRuby )
1092 : {
1093 : OSL_TRACE("TODO DocxAttributeOutput::StartRuby( const SwTxtNode& rNode, const SwFmtRuby& rRuby )" );
1094 0 : m_pSerializer->startElementNS( XML_w, XML_ruby, FSEND );
1095 0 : m_pSerializer->startElementNS( XML_w, XML_rubyPr, FSEND );
1096 : // hps
1097 : // hpsBaseText
1098 : // hpsRaise
1099 : // lid
1100 : lang::Locale aLocale( SwBreakIt::Get()->GetLocale(
1101 0 : rNode.GetLang( nPos ) ) );
1102 0 : OUString sLang( aLocale.Language );
1103 0 : if ( !aLocale.Country.isEmpty() )
1104 0 : sLang += OUString( "-" ) + OUString( aLocale.Country );
1105 : m_pSerializer->singleElementNS( XML_w, XML_lid,
1106 : FSNS( XML_w, XML_val ),
1107 0 : OUStringToOString( sLang, RTL_TEXTENCODING_UTF8 ).getStr( ), FSEND );
1108 :
1109 0 : OString sAlign ( "center" );
1110 0 : switch ( rRuby.GetAdjustment( ) )
1111 : {
1112 : case 0:
1113 0 : sAlign = OString( "left" );
1114 0 : break;
1115 : case 1:
1116 : // Defaults to center
1117 0 : break;
1118 : case 2:
1119 0 : sAlign = OString( "right" );
1120 0 : break;
1121 : case 3:
1122 0 : sAlign = OString( "distributeLetter" );
1123 0 : break;
1124 : case 4:
1125 0 : sAlign = OString( "distributeSpace" );
1126 0 : break;
1127 : default:
1128 0 : break;
1129 : }
1130 : m_pSerializer->singleElementNS( XML_w, XML_rubyAlign,
1131 0 : FSNS( XML_w, XML_val ), sAlign.getStr(), FSEND );
1132 0 : m_pSerializer->endElementNS( XML_w, XML_rubyPr );
1133 :
1134 0 : m_pSerializer->startElementNS( XML_w, XML_rt, FSEND );
1135 0 : StartRun( NULL );
1136 0 : StartRunProperties( );
1137 0 : SwWW8AttrIter aAttrIt( m_rExport, rNode );
1138 0 : aAttrIt.OutAttr( nPos, true );
1139 0 : sal_uInt16 nStyle = m_rExport.GetId( *rRuby.GetTxtRuby()->GetCharFmt() );
1140 0 : OString aStyleId( "style" );
1141 0 : aStyleId += OString::valueOf( sal_Int32( nStyle ) );
1142 : m_pSerializer->singleElementNS( XML_w, XML_rStyle,
1143 0 : FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND );
1144 0 : EndRunProperties( NULL );
1145 0 : RunText( rRuby.GetText( ) );
1146 0 : EndRun( );
1147 0 : m_pSerializer->endElementNS( XML_w, XML_rt );
1148 :
1149 0 : m_pSerializer->startElementNS( XML_w, XML_rubyBase, FSEND );
1150 0 : StartRun( NULL );
1151 0 : }
1152 :
1153 0 : void DocxAttributeOutput::EndRuby()
1154 : {
1155 : OSL_TRACE( "TODO DocxAttributeOutput::EndRuby()" );
1156 0 : EndRun( );
1157 0 : m_pSerializer->endElementNS( XML_w, XML_rubyBase );
1158 0 : m_pSerializer->endElementNS( XML_w, XML_ruby );
1159 0 : }
1160 :
1161 3 : bool DocxAttributeOutput::AnalyzeURL( const String& rUrl, const String& rTarget, String* pLinkURL, String* pMark )
1162 : {
1163 3 : bool bBookMarkOnly = AttributeOutputBase::AnalyzeURL( rUrl, rTarget, pLinkURL, pMark );
1164 :
1165 3 : String sURL = *pLinkURL;
1166 3 : String sMark = *pMark;
1167 :
1168 3 : bool bOutputField = sMark.Len();
1169 :
1170 3 : if ( bOutputField )
1171 : {
1172 2 : if ( bBookMarkOnly )
1173 0 : sURL = FieldString( ww::eHYPERLINK );
1174 : else
1175 : {
1176 2 : String sFld( FieldString( ww::eHYPERLINK ) );
1177 2 : sFld.AppendAscii( "\"" );
1178 2 : sURL.Insert( sFld, 0 );
1179 2 : sURL += '\"';
1180 : }
1181 :
1182 2 : if ( sMark.Len() )
1183 2 : ( ( sURL.AppendAscii( " \\l \"" ) ) += sMark ) += '\"';
1184 :
1185 2 : if ( rTarget.Len() )
1186 0 : ( sURL.AppendAscii( " \\n " ) ) += rTarget;
1187 : }
1188 :
1189 3 : *pLinkURL = sURL;
1190 3 : *pMark = sMark;
1191 :
1192 3 : return bBookMarkOnly;
1193 : }
1194 :
1195 3 : bool DocxAttributeOutput::StartURL( const String& rUrl, const String& rTarget )
1196 : {
1197 3 : String sMark;
1198 3 : String sUrl;
1199 :
1200 3 : bool bBookmarkOnly = AnalyzeURL( rUrl, rTarget, &sUrl, &sMark );
1201 :
1202 3 : if ( sMark.Len() && !bBookmarkOnly )
1203 : {
1204 2 : m_rExport.OutputField( NULL, ww::eHYPERLINK, sUrl );
1205 : }
1206 : else
1207 : {
1208 : // Output a hyperlink XML element
1209 1 : m_pHyperlinkAttrList = m_pSerializer->createAttrList();
1210 :
1211 1 : if ( !bBookmarkOnly )
1212 : {
1213 1 : OUString osUrl( sUrl );
1214 :
1215 1 : OString sId = rtl::OUStringToOString( GetExport().GetFilter().addRelation( m_pSerializer->getOutputStream(),
1216 : S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" ),
1217 2 : osUrl, true ), RTL_TEXTENCODING_UTF8 );
1218 :
1219 1 : m_pHyperlinkAttrList->add( FSNS( XML_r, XML_id), sId.getStr());
1220 : }
1221 : else
1222 : m_pHyperlinkAttrList->add( FSNS( XML_w, XML_anchor ),
1223 0 : OUStringToOString( OUString( sMark ), RTL_TEXTENCODING_UTF8 ).getStr( ) );
1224 :
1225 1 : OUString sTarget( rTarget );
1226 1 : if ( !sTarget.isEmpty() )
1227 : {
1228 0 : OString soTarget = OUStringToOString( sTarget, RTL_TEXTENCODING_UTF8 );
1229 0 : m_pHyperlinkAttrList->add(FSNS( XML_w, XML_tgtFrame ), soTarget.getStr());
1230 1 : }
1231 : }
1232 :
1233 3 : return true;
1234 : }
1235 :
1236 3 : bool DocxAttributeOutput::EndURL()
1237 : {
1238 3 : m_closeHyperlinkInThisRun = true;
1239 3 : return true;
1240 : }
1241 :
1242 0 : void DocxAttributeOutput::FieldVanish( const String& rTxt, ww::eField eType )
1243 : {
1244 0 : WriteField_Impl( NULL, eType, rTxt, WRITEFIELD_ALL );
1245 0 : }
1246 :
1247 0 : void DocxAttributeOutput::Redline( const SwRedlineData* /*pRedline*/ )
1248 : {
1249 : OSL_TRACE( "TODO DocxAttributeOutput::Redline( const SwRedlineData* pRedline )" );
1250 0 : }
1251 :
1252 110 : void DocxAttributeOutput::StartRedline()
1253 : {
1254 110 : if ( !m_pRedlineData )
1255 110 : return;
1256 1 : const SwRedlineData* pRedlineData = m_pRedlineData;
1257 :
1258 : // FIXME check if it's necessary to travel over the Next()'s in pRedlineData
1259 :
1260 1 : OString aId( OString::valueOf( m_nRedlineId++ ) );
1261 :
1262 1 : const String &rAuthor( SW_MOD()->GetRedlineAuthor( pRedlineData->GetAuthor() ) );
1263 1 : OString aAuthor( OUStringToOString( rAuthor, RTL_TEXTENCODING_UTF8 ) );
1264 :
1265 1 : OString aDate( msfilter::util::DateTimeToOString( pRedlineData->GetTimeStamp() ) );
1266 :
1267 1 : switch ( pRedlineData->GetType() )
1268 : {
1269 : case nsRedlineType_t::REDLINE_INSERT:
1270 : m_pSerializer->startElementNS( XML_w, XML_ins,
1271 : FSNS( XML_w, XML_id ), aId.getStr(),
1272 : FSNS( XML_w, XML_author ), aAuthor.getStr(),
1273 : FSNS( XML_w, XML_date ), aDate.getStr(),
1274 0 : FSEND );
1275 0 : break;
1276 :
1277 : case nsRedlineType_t::REDLINE_DELETE:
1278 : m_pSerializer->startElementNS( XML_w, XML_del,
1279 : FSNS( XML_w, XML_id ), aId.getStr(),
1280 : FSNS( XML_w, XML_author ), aAuthor.getStr(),
1281 : FSNS( XML_w, XML_date ), aDate.getStr(),
1282 1 : FSEND );
1283 1 : break;
1284 :
1285 : case nsRedlineType_t::REDLINE_FORMAT:
1286 : OSL_TRACE( "TODO DocxAttributeOutput::StartRedline()" );
1287 : default:
1288 0 : break;
1289 1 : }
1290 : }
1291 :
1292 110 : void DocxAttributeOutput::EndRedline()
1293 : {
1294 110 : if ( !m_pRedlineData )
1295 219 : return;
1296 :
1297 1 : switch ( m_pRedlineData->GetType() )
1298 : {
1299 : case nsRedlineType_t::REDLINE_INSERT:
1300 0 : m_pSerializer->endElementNS( XML_w, XML_ins );
1301 0 : break;
1302 :
1303 : case nsRedlineType_t::REDLINE_DELETE:
1304 1 : m_pSerializer->endElementNS( XML_w, XML_del );
1305 1 : break;
1306 :
1307 : case nsRedlineType_t::REDLINE_FORMAT:
1308 : OSL_TRACE( "TODO DocxAttributeOutput::EndRedline()" );
1309 0 : break;
1310 : default:
1311 0 : break;
1312 : }
1313 :
1314 1 : m_pRedlineData = NULL;
1315 : }
1316 :
1317 0 : void DocxAttributeOutput::FormatDrop( const SwTxtNode& /*rNode*/, const SwFmtDrop& /*rSwFmtDrop*/, sal_uInt16 /*nStyle*/, ww8::WW8TableNodeInfo::Pointer_t /*pTextNodeInfo*/, ww8::WW8TableNodeInfoInner::Pointer_t )
1318 : {
1319 : OSL_TRACE( "TODO DocxAttributeOutput::FormatDrop( const SwTxtNode& rNode, const SwFmtDrop& rSwFmtDrop, sal_uInt16 nStyle )" );
1320 0 : }
1321 :
1322 85 : void DocxAttributeOutput::ParagraphStyle( sal_uInt16 nStyle )
1323 : {
1324 85 : OString aStyleId( "style" );
1325 85 : aStyleId += OString::valueOf( sal_Int32( nStyle ) );
1326 :
1327 85 : m_pSerializer->singleElementNS( XML_w, XML_pStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND );
1328 85 : }
1329 :
1330 85 : static OString impl_ConvertColor( const Color &rColor )
1331 : {
1332 85 : OString color( "auto" );
1333 85 : if ( rColor.GetColor() != COL_AUTO )
1334 : {
1335 38 : const char pHexDigits[] = "0123456789ABCDEF";
1336 38 : char pBuffer[] = "000000";
1337 :
1338 38 : pBuffer[0] = pHexDigits[ ( rColor.GetRed() >> 4 ) & 0x0F ];
1339 38 : pBuffer[1] = pHexDigits[ rColor.GetRed() & 0x0F ];
1340 38 : pBuffer[2] = pHexDigits[ ( rColor.GetGreen() >> 4 ) & 0x0F ];
1341 38 : pBuffer[3] = pHexDigits[ rColor.GetGreen() & 0x0F ];
1342 38 : pBuffer[4] = pHexDigits[ ( rColor.GetBlue() >> 4 ) & 0x0F ];
1343 38 : pBuffer[5] = pHexDigits[ rColor.GetBlue() & 0x0F ];
1344 :
1345 38 : color = OString( pBuffer );
1346 : }
1347 85 : return color;
1348 : }
1349 :
1350 118 : static void impl_borderLine( FSHelperPtr pSerializer, sal_Int32 elementToken, const SvxBorderLine* pBorderLine, sal_uInt16 nDist )
1351 : {
1352 118 : FastAttributeList* pAttr = pSerializer->createAttrList();
1353 :
1354 :
1355 : // Compute val attribute value
1356 : // Can be one of:
1357 : // single, double,
1358 : // basicWideOutline, basicWideInline
1359 : // OOXml also supports those types of borders, but we'll try to play with the first ones.
1360 : // thickThinMediumGap, thickThinLargeGap, thickThinSmallGap
1361 : // thinThickLargeGap, thinThickMediumGap, thinThickSmallGap
1362 118 : const char* pVal = "none";
1363 118 : if ( pBorderLine && !pBorderLine->isEmpty( ) )
1364 : {
1365 20 : switch (pBorderLine->GetBorderLineStyle())
1366 : {
1367 : case table::BorderLineStyle::SOLID:
1368 20 : pVal = ( sal_Char* )"single";
1369 20 : break;
1370 : case table::BorderLineStyle::DOTTED:
1371 0 : pVal = ( sal_Char* )"dotted";
1372 0 : break;
1373 : case table::BorderLineStyle::DASHED:
1374 0 : pVal = ( sal_Char* )"dashed";
1375 0 : break;
1376 : case table::BorderLineStyle::DOUBLE:
1377 0 : pVal = ( sal_Char* )"double";
1378 0 : break;
1379 : case table::BorderLineStyle::THINTHICK_SMALLGAP:
1380 0 : pVal = ( sal_Char* )"thinThickSmallGap";
1381 0 : break;
1382 : case table::BorderLineStyle::THINTHICK_MEDIUMGAP:
1383 0 : pVal = ( sal_Char* )"thinThickMediumGap";
1384 0 : break;
1385 : case table::BorderLineStyle::THINTHICK_LARGEGAP:
1386 0 : pVal = ( sal_Char* )"thinThickLargeGap";
1387 0 : break;
1388 : case table::BorderLineStyle::THICKTHIN_SMALLGAP:
1389 0 : pVal = ( sal_Char* )"thickThinSmallGap";
1390 0 : break;
1391 : case table::BorderLineStyle::THICKTHIN_MEDIUMGAP:
1392 0 : pVal = ( sal_Char* )"thickThinMediumGap";
1393 0 : break;
1394 : case table::BorderLineStyle::THICKTHIN_LARGEGAP:
1395 0 : pVal = ( sal_Char* )"thickThinLargeGap";
1396 0 : break;
1397 : case table::BorderLineStyle::EMBOSSED:
1398 0 : pVal = ( sal_Char* )"threeDEmboss";
1399 0 : break;
1400 : case table::BorderLineStyle::ENGRAVED:
1401 0 : pVal = ( sal_Char* )"threeDEngrave";
1402 0 : break;
1403 : case table::BorderLineStyle::OUTSET:
1404 0 : pVal = ( sal_Char* )"outset";
1405 0 : break;
1406 : case table::BorderLineStyle::INSET:
1407 0 : pVal = ( sal_Char* )"inset";
1408 0 : break;
1409 : case table::BorderLineStyle::FINE_DASHED:
1410 0 : pVal = ( sal_Char* )"dashSmallGap";
1411 0 : break;
1412 : case table::BorderLineStyle::NONE:
1413 : default:
1414 0 : break;
1415 : }
1416 : }
1417 :
1418 118 : pAttr->add( FSNS( XML_w, XML_val ), OString( pVal ) );
1419 :
1420 118 : if ( pBorderLine && !pBorderLine->isEmpty() )
1421 : {
1422 : // Compute the sz attribute
1423 :
1424 : double const fConverted( ::editeng::ConvertBorderWidthToWord(
1425 20 : pBorderLine->GetBorderLineStyle(), pBorderLine->GetWidth()));
1426 : // The unit is the 8th of point
1427 20 : sal_Int32 nWidth = sal_Int32( fConverted / 2.5 );
1428 20 : sal_uInt16 nMinWidth = 2;
1429 20 : sal_uInt16 nMaxWidth = 96;
1430 :
1431 20 : if ( nWidth > nMaxWidth )
1432 0 : nWidth = nMaxWidth;
1433 20 : else if ( nWidth < nMinWidth )
1434 0 : nWidth = nMinWidth;
1435 :
1436 20 : pAttr->add( FSNS( XML_w, XML_sz ), OString::valueOf( sal_Int32( nWidth ) ) );
1437 :
1438 : // Get the distance (in pt)
1439 20 : pAttr->add( FSNS( XML_w, XML_space ), OString::valueOf( sal_Int32( nDist / 20 ) ) );
1440 :
1441 : // Get the color code as an RRGGBB hex value
1442 20 : OString sColor( impl_ConvertColor( pBorderLine->GetColor( ) ) );
1443 20 : pAttr->add( FSNS( XML_w, XML_color ), sColor );
1444 : }
1445 :
1446 118 : XFastAttributeListRef xAttrs( pAttr );
1447 118 : pSerializer->singleElementNS( XML_w, elementToken, xAttrs );
1448 118 : }
1449 :
1450 43 : static void impl_pageBorders( FSHelperPtr pSerializer, const SvxBoxItem& rBox, sal_Int32 tag, bool bUseStartEnd = false, bool bWriteTag = true, const SvxBoxItem* pDefaultBorders = 0)
1451 : {
1452 : static const sal_uInt16 aBorders[] =
1453 : {
1454 : BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
1455 : };
1456 :
1457 : const sal_Int32 aXmlElements[] =
1458 : {
1459 : XML_top,
1460 : bUseStartEnd ? XML_start : XML_left,
1461 : XML_bottom,
1462 : bUseStartEnd ? XML_end : XML_right
1463 43 : };
1464 43 : bool tagWritten = false;
1465 43 : const sal_uInt16* pBrd = aBorders;
1466 215 : for( int i = 0; i < 4; ++i, ++pBrd )
1467 : {
1468 172 : const SvxBorderLine* pLn = rBox.GetLine( *pBrd );
1469 172 : if ( pDefaultBorders && pLn )
1470 : {
1471 72 : const SvxBorderLine* pRefLn = pDefaultBorders->GetLine( *pBrd );
1472 :
1473 : // If border is equal to default border: do not output
1474 72 : if ( pRefLn && *pLn == *pRefLn) {
1475 64 : continue;
1476 : }
1477 : }
1478 :
1479 108 : if (!tagWritten && bWriteTag) {
1480 32 : pSerializer->startElementNS( XML_w, tag, FSEND );
1481 32 : tagWritten = true;
1482 : }
1483 :
1484 108 : impl_borderLine( pSerializer, aXmlElements[i], pLn, 0 );
1485 :
1486 : // When exporting default borders, we need to export these 2 attr
1487 108 : if ( pDefaultBorders == 0 ) {
1488 20 : if ( i == 2 )
1489 5 : impl_borderLine( pSerializer, XML_insideH, pLn, 0 );
1490 15 : else if ( i == 3 )
1491 5 : impl_borderLine( pSerializer, XML_insideV, pLn, 0 );
1492 : }
1493 : }
1494 43 : if (tagWritten && bWriteTag) {
1495 32 : pSerializer->endElementNS( XML_w, tag );
1496 : }
1497 43 : }
1498 :
1499 43 : static void impl_cellMargins( FSHelperPtr pSerializer, const SvxBoxItem& rBox, sal_Int32 tag, bool bUseStartEnd = false, const SvxBoxItem* pDefaultMargins = 0)
1500 : {
1501 : static const sal_uInt16 aBorders[] =
1502 : {
1503 : BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
1504 : };
1505 :
1506 : const sal_Int32 aXmlElements[] =
1507 : {
1508 : XML_top,
1509 : bUseStartEnd ? XML_start : XML_left,
1510 : XML_bottom,
1511 : bUseStartEnd ? XML_end : XML_right
1512 43 : };
1513 43 : bool tagWritten = false;
1514 43 : const sal_uInt16* pBrd = aBorders;
1515 215 : for( int i = 0; i < 4; ++i, ++pBrd )
1516 : {
1517 172 : sal_Int32 nDist = sal_Int32( rBox.GetDistance( *pBrd ) );
1518 :
1519 172 : if ( aBorders[i] == BOX_LINE_LEFT ) {
1520 : // Office's cell margin is measured from the right of the border.
1521 : // While LO's cell spacing is measured from the center of the border.
1522 : // So we add half left-border width to tblIndent value
1523 43 : const SvxBorderLine* pLn = rBox.GetLine( *pBrd );
1524 43 : if (pLn)
1525 20 : nDist -= pLn->GetWidth() * 0.5;
1526 : }
1527 :
1528 172 : if (pDefaultMargins)
1529 : {
1530 : // Skip output if cell margin == table default margin
1531 152 : if (sal_Int32( pDefaultMargins->GetDistance( *pBrd ) ) == nDist)
1532 134 : continue;
1533 : }
1534 :
1535 38 : if (!tagWritten) {
1536 23 : pSerializer->startElementNS( XML_w, tag, FSEND );
1537 23 : tagWritten = true;
1538 : }
1539 38 : pSerializer->singleElementNS( XML_w, aXmlElements[i],
1540 : FSNS( XML_w, XML_w ), OString::valueOf( nDist ).getStr( ),
1541 : FSNS( XML_w, XML_type ), "dxa",
1542 76 : FSEND );
1543 : }
1544 43 : if (tagWritten) {
1545 23 : pSerializer->endElementNS( XML_w, tag );
1546 : }
1547 43 : }
1548 :
1549 38 : void DocxAttributeOutput::TableCellProperties( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1550 : {
1551 38 : m_pSerializer->startElementNS( XML_w, XML_tcPr, FSEND );
1552 :
1553 38 : const SwTableBox *pTblBox = pTableTextNodeInfoInner->getTableBox( );
1554 :
1555 38 : bool bEcma = GetExport().GetFilter().getVersion( ) == oox::core::ECMA_DIALECT;
1556 :
1557 : // Cell prefered width
1558 38 : SwTwips nWidth = GetGridCols( pTableTextNodeInfoInner )->at( pTableTextNodeInfoInner->getCell() );
1559 38 : if ( pTableTextNodeInfoInner->getCell() )
1560 26 : nWidth = nWidth - GetGridCols( pTableTextNodeInfoInner )->at( pTableTextNodeInfoInner->getCell() - 1 );
1561 : m_pSerializer->singleElementNS( XML_w, XML_tcW,
1562 : FSNS( XML_w, XML_w ), OString::valueOf( sal_Int32( nWidth ) ).getStr( ),
1563 : FSNS( XML_w, XML_type ), "dxa",
1564 38 : FSEND );
1565 :
1566 : // Horizontal spans
1567 38 : const SwWriteTableRows& aRows = m_pTableWrt->GetRows( );
1568 38 : SwWriteTableRow *pRow = aRows[ pTableTextNodeInfoInner->getRow( ) ];
1569 38 : const SwWriteTableCell *pCell = &pRow->GetCells( )[ pTableTextNodeInfoInner->getCell( ) ];
1570 :
1571 38 : sal_uInt16 nColSpan = pCell->GetColSpan();
1572 38 : if ( nColSpan > 1 )
1573 : m_pSerializer->singleElementNS( XML_w, XML_gridSpan,
1574 : FSNS( XML_w, XML_val ), OString::valueOf( sal_Int32( nColSpan ) ).getStr(),
1575 0 : FSEND );
1576 :
1577 : // Vertical merges
1578 38 : long vSpan = pTblBox->getRowSpan( );
1579 38 : if ( vSpan > 1 )
1580 : {
1581 : m_pSerializer->singleElementNS( XML_w, XML_vMerge,
1582 : FSNS( XML_w, XML_val ), "restart",
1583 0 : FSEND );
1584 : }
1585 38 : else if ( vSpan < 0 )
1586 : {
1587 : m_pSerializer->singleElementNS( XML_w, XML_vMerge,
1588 : FSNS( XML_w, XML_val ), "continue",
1589 0 : FSEND );
1590 : }
1591 :
1592 38 : const SvxBoxItem& rBox = pTblBox->GetFrmFmt( )->GetBox( );
1593 38 : const SvxBoxItem& rDefaultBox = (*tableFirstCells.rbegin())->getTableBox( )->GetFrmFmt( )->GetBox( );
1594 : {
1595 : // The cell borders
1596 38 : impl_pageBorders( m_pSerializer, rBox, XML_tcBorders, !bEcma, true, &rDefaultBox );
1597 : }
1598 :
1599 38 : TableBackgrounds( pTableTextNodeInfoInner );
1600 :
1601 : {
1602 : // Cell margins
1603 38 : impl_cellMargins( m_pSerializer, rBox, XML_tcMar, !bEcma, &rDefaultBox );
1604 : }
1605 :
1606 38 : TableVerticalCell( pTableTextNodeInfoInner );
1607 :
1608 38 : m_pSerializer->endElementNS( XML_w, XML_tcPr );
1609 38 : }
1610 :
1611 5 : void DocxAttributeOutput::InitTableHelper( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1612 : {
1613 5 : sal_uInt32 nPageSize = 0;
1614 5 : bool bRelBoxSize = false;
1615 :
1616 : // Create the SwWriteTable instance to use col spans (and maybe other infos)
1617 5 : GetTablePageSize( pTableTextNodeInfoInner.get(), nPageSize, bRelBoxSize );
1618 :
1619 5 : const SwTable* pTable = pTableTextNodeInfoInner->getTable( );
1620 5 : const SwFrmFmt *pFmt = pTable->GetFrmFmt( );
1621 5 : SwTwips nTblSz = pFmt->GetFrmSize( ).GetWidth( );
1622 :
1623 5 : const SwHTMLTableLayout *pLayout = pTable->GetHTMLTableLayout();
1624 5 : if( pLayout && pLayout->IsExportable() )
1625 0 : m_pTableWrt = new SwWriteTable( pLayout );
1626 : else
1627 : m_pTableWrt = new SwWriteTable( pTable->GetTabLines(), (sal_uInt16)nPageSize,
1628 5 : (sal_uInt16)nTblSz, false);
1629 5 : }
1630 :
1631 5 : void DocxAttributeOutput::StartTable( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1632 : {
1633 5 : m_pSerializer->startElementNS( XML_w, XML_tbl, FSEND );
1634 :
1635 5 : tableFirstCells.push_back(pTableTextNodeInfoInner);
1636 :
1637 5 : InitTableHelper( pTableTextNodeInfoInner );
1638 5 : TableDefinition( pTableTextNodeInfoInner );
1639 5 : }
1640 :
1641 5 : void DocxAttributeOutput::EndTable()
1642 : {
1643 5 : m_pSerializer->endElementNS( XML_w, XML_tbl );
1644 :
1645 5 : if ( m_nTableDepth > 0 )
1646 5 : --m_nTableDepth;
1647 :
1648 5 : tableFirstCells.pop_back();
1649 :
1650 : // We closed the table; if it is a nested table, the cell that contains it
1651 : // still continues
1652 5 : m_bTableCellOpen = true;
1653 :
1654 : // Cleans the table helper
1655 5 : delete m_pTableWrt, m_pTableWrt = NULL;
1656 5 : }
1657 :
1658 12 : void DocxAttributeOutput::StartTableRow( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1659 : {
1660 12 : m_pSerializer->startElementNS( XML_w, XML_tr, FSEND );
1661 :
1662 : // Output the row properties
1663 12 : m_pSerializer->startElementNS( XML_w, XML_trPr, FSEND );
1664 :
1665 : // Header row: tblHeader
1666 12 : const SwTable *pTable = pTableTextNodeInfoInner->getTable( );
1667 12 : if ( pTable->GetRowsToRepeat( ) > pTableTextNodeInfoInner->getRow( ) )
1668 : m_pSerializer->singleElementNS( XML_w, XML_tblHeader,
1669 : FSNS( XML_w, XML_val ), "true",
1670 0 : FSEND );
1671 :
1672 12 : TableHeight( pTableTextNodeInfoInner );
1673 12 : TableCanSplit( pTableTextNodeInfoInner );
1674 :
1675 12 : m_pSerializer->endElementNS( XML_w, XML_trPr );
1676 12 : }
1677 :
1678 12 : void DocxAttributeOutput::EndTableRow( )
1679 : {
1680 12 : m_pSerializer->endElementNS( XML_w, XML_tr );
1681 12 : }
1682 :
1683 38 : void DocxAttributeOutput::StartTableCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1684 : {
1685 38 : if ( !m_pTableWrt )
1686 0 : InitTableHelper( pTableTextNodeInfoInner );
1687 :
1688 38 : m_pSerializer->startElementNS( XML_w, XML_tc, FSEND );
1689 :
1690 : // Write the cell properties here
1691 38 : TableCellProperties( pTableTextNodeInfoInner );
1692 :
1693 38 : m_bTableCellOpen = true;
1694 38 : }
1695 :
1696 38 : void DocxAttributeOutput::EndTableCell( )
1697 : {
1698 38 : m_pSerializer->endElementNS( XML_w, XML_tc );
1699 :
1700 38 : m_bTableCellOpen = false;
1701 38 : }
1702 :
1703 38 : void DocxAttributeOutput::TableInfoCell( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
1704 : {
1705 38 : }
1706 :
1707 0 : void DocxAttributeOutput::TableInfoRow( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfo*/ )
1708 : {
1709 0 : }
1710 :
1711 5 : void DocxAttributeOutput::TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1712 : {
1713 5 : bool bEcma = GetExport().GetFilter().getVersion( ) == oox::core::ECMA_DIALECT;
1714 :
1715 : // Write the table properties
1716 5 : m_pSerializer->startElementNS( XML_w, XML_tblPr, FSEND );
1717 :
1718 : static const sal_Int32 aOrder[] =
1719 : {
1720 : FSNS( XML_w, XML_tblStyle ),
1721 : FSNS( XML_w, XML_tblpPr ),
1722 : FSNS( XML_w, XML_tblOverlap ),
1723 : FSNS( XML_w, XML_bidiVisual ),
1724 : FSNS( XML_w, XML_tblStyleRowBandSize ),
1725 : FSNS( XML_w, XML_tblStyleColBandSize ),
1726 : FSNS( XML_w, XML_tblW ),
1727 : FSNS( XML_w, XML_jc ),
1728 : FSNS( XML_w, XML_tblCellSpacing ),
1729 : FSNS( XML_w, XML_tblInd ),
1730 : FSNS( XML_w, XML_tblBorders ),
1731 : FSNS( XML_w, XML_shd ),
1732 : FSNS( XML_w, XML_tblLayout ),
1733 : FSNS( XML_w, XML_tblCellMar ),
1734 : FSNS( XML_w, XML_tblLook ),
1735 : FSNS( XML_w, XML_tblPrChange )
1736 : };
1737 :
1738 : // postpone the output so that we can later []
1739 : // prepend the properties before the run
1740 5 : sal_Int32 len = sizeof ( aOrder ) / sizeof( sal_Int32 );
1741 5 : uno::Sequence< sal_Int32 > aSeqOrder( len );
1742 85 : for ( sal_Int32 i = 0; i < len; i++ )
1743 80 : aSeqOrder[i] = aOrder[i];
1744 :
1745 5 : m_pSerializer->mark( aSeqOrder );
1746 :
1747 5 : sal_uInt32 nPageSize = 0;
1748 5 : bool bRelBoxSize = false;
1749 :
1750 : // Create the SwWriteTable instance to use col spans (and maybe other infos)
1751 5 : GetTablePageSize( pTableTextNodeInfoInner.get(), nPageSize, bRelBoxSize );
1752 :
1753 : // Output the table prefered width
1754 5 : if ( nPageSize != 0 )
1755 : m_pSerializer->singleElementNS( XML_w, XML_tblW,
1756 : FSNS( XML_w, XML_w ), OString::valueOf( sal_Int32( nPageSize ) ).getStr( ),
1757 : FSNS( XML_w, XML_type ), "dxa",
1758 0 : FSEND );
1759 :
1760 : // Output the table alignement
1761 5 : const SwTable *pTable = pTableTextNodeInfoInner->getTable();
1762 5 : SwFrmFmt *pTblFmt = pTable->GetFrmFmt( );
1763 : const char* pJcVal;
1764 5 : sal_Int32 nIndent = 0;
1765 5 : switch ( pTblFmt->GetHoriOrient( ).GetHoriOrient( ) )
1766 : {
1767 : case text::HoriOrientation::CENTER:
1768 0 : pJcVal = "center";
1769 0 : break;
1770 : case text::HoriOrientation::RIGHT:
1771 0 : if ( bEcma )
1772 0 : pJcVal = "right";
1773 : else
1774 0 : pJcVal = "end";
1775 0 : break;
1776 : default:
1777 : case text::HoriOrientation::NONE:
1778 : case text::HoriOrientation::LEFT_AND_WIDTH:
1779 : {
1780 5 : if ( bEcma )
1781 0 : pJcVal = "left";
1782 : else
1783 5 : pJcVal = "start";
1784 5 : nIndent = sal_Int32( pTblFmt->GetLRSpace( ).GetLeft( ) );
1785 5 : break;
1786 : }
1787 : }
1788 : m_pSerializer->singleElementNS( XML_w, XML_jc,
1789 : FSNS( XML_w, XML_val ), pJcVal,
1790 5 : FSEND );
1791 :
1792 : // Output the table borders
1793 5 : TableDefaultBorders( pTableTextNodeInfoInner );
1794 :
1795 : // Output the default cell margins
1796 5 : TableDefaultCellMargins( pTableTextNodeInfoInner, nIndent );
1797 :
1798 5 : TableBidi( pTableTextNodeInfoInner );
1799 :
1800 : // Table indent (need to get written even if == 0)
1801 : m_pSerializer->singleElementNS( XML_w, XML_tblInd,
1802 : FSNS( XML_w, XML_w ), OString::valueOf( nIndent ).getStr( ),
1803 : FSNS( XML_w, XML_type ), "dxa",
1804 5 : FSEND );
1805 :
1806 : // Merge the marks for the ordered elements
1807 5 : m_pSerializer->mergeTopMarks( );
1808 :
1809 5 : m_pSerializer->endElementNS( XML_w, XML_tblPr );
1810 :
1811 : // Write the table grid infos
1812 5 : m_pSerializer->startElementNS( XML_w, XML_tblGrid, FSEND );
1813 5 : sal_Int32 nPrv = 0;
1814 5 : ww8::GridColsPtr pGridCols = GetGridCols( pTableTextNodeInfoInner );
1815 21 : for ( ww8::GridCols::const_iterator it = pGridCols->begin(); it != pGridCols->end(); ++it )
1816 : {
1817 16 : sal_Int32 nWidth = sal_Int32( *it ) - nPrv;
1818 : m_pSerializer->singleElementNS( XML_w, XML_gridCol,
1819 : FSNS( XML_w, XML_w ), OString::valueOf( nWidth ).getStr( ),
1820 16 : FSEND );
1821 16 : nPrv = sal_Int32( *it );
1822 : }
1823 :
1824 5 : m_pSerializer->endElementNS( XML_w, XML_tblGrid );
1825 5 : }
1826 :
1827 5 : void DocxAttributeOutput::TableDefaultBorders( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1828 : {
1829 5 : const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
1830 5 : const SwFrmFmt * pFrmFmt = pTabBox->GetFrmFmt();
1831 :
1832 5 : bool bEcma = GetExport().GetFilter().getVersion( ) == oox::core::ECMA_DIALECT;
1833 :
1834 : // the defaults of the table are taken from the top-left cell
1835 5 : impl_pageBorders( m_pSerializer, pFrmFmt->GetBox( ), XML_tblBorders, !bEcma, true );
1836 5 : }
1837 :
1838 5 : void DocxAttributeOutput::TableDefaultCellMargins( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner, sal_Int32& tblIndent )
1839 : {
1840 5 : const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
1841 5 : const SwFrmFmt * pFrmFmt = pTabBox->GetFrmFmt();
1842 5 : const SvxBoxItem& rBox = pFrmFmt->GetBox( );
1843 5 : const bool bEcma = GetExport().GetFilter().getVersion( ) == oox::core::ECMA_DIALECT;
1844 :
1845 5 : impl_cellMargins(m_pSerializer, rBox, XML_tblCellMar, !bEcma);
1846 :
1847 : // add table cell left margin to tblIndent
1848 5 : tblIndent += sal_Int32( rBox.GetDistance( BOX_LINE_LEFT ) );
1849 5 : }
1850 :
1851 38 : void DocxAttributeOutput::TableBackgrounds( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1852 : {
1853 38 : const SwTableBox *pTblBox = pTableTextNodeInfoInner->getTableBox( );
1854 38 : const SwFrmFmt *pFmt = pTblBox->GetFrmFmt( );
1855 38 : const SfxPoolItem *pI = NULL;
1856 :
1857 38 : Color aColor;
1858 38 : if ( SFX_ITEM_ON == pFmt->GetAttrSet().GetItemState( RES_BACKGROUND, false, &pI ) )
1859 0 : aColor = dynamic_cast<const SvxBrushItem *>(pI)->GetColor();
1860 : else
1861 38 : aColor = COL_AUTO;
1862 :
1863 38 : OString sColor = impl_ConvertColor( aColor );
1864 : m_pSerializer->singleElementNS( XML_w, XML_shd,
1865 : FSNS( XML_w, XML_fill ), sColor.getStr( ),
1866 : FSNS( XML_w, XML_val ), "clear",
1867 38 : FSEND );
1868 38 : }
1869 :
1870 12 : void DocxAttributeOutput::TableHeight( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1871 : {
1872 12 : const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
1873 12 : const SwTableLine * pTabLine = pTabBox->GetUpper();
1874 12 : const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();
1875 :
1876 12 : const SwFmtFrmSize& rLSz = pLineFmt->GetFrmSize();
1877 12 : if ( ATT_VAR_SIZE != rLSz.GetHeightSizeType() && rLSz.GetHeight() )
1878 : {
1879 0 : sal_Int32 nHeight = rLSz.GetHeight();
1880 0 : const char *pRule = NULL;
1881 :
1882 0 : switch ( rLSz.GetHeightSizeType() )
1883 : {
1884 0 : case ATT_FIX_SIZE: pRule = "exact"; break;
1885 0 : case ATT_MIN_SIZE: pRule = "atLeast"; break;
1886 0 : default: break;
1887 : }
1888 :
1889 0 : if ( pRule )
1890 : m_pSerializer->singleElementNS( XML_w, XML_trHeight,
1891 : FSNS( XML_w, XML_val ), OString::valueOf( nHeight ).getStr( ),
1892 : FSNS( XML_w, XML_hRule ), pRule,
1893 0 : FSEND );
1894 : }
1895 12 : }
1896 :
1897 12 : void DocxAttributeOutput::TableCanSplit( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1898 : {
1899 12 : const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
1900 12 : const SwTableLine * pTabLine = pTabBox->GetUpper();
1901 12 : const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();
1902 :
1903 12 : const SwFmtRowSplit& rSplittable = pLineFmt->GetRowSplit( );
1904 12 : const char* pCantSplit = ( !rSplittable.GetValue( ) ) ? "true" : "false";
1905 :
1906 : m_pSerializer->singleElementNS( XML_w, XML_cantSplit,
1907 : FSNS( XML_w, XML_val ), pCantSplit,
1908 12 : FSEND );
1909 12 : }
1910 :
1911 5 : void DocxAttributeOutput::TableBidi( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1912 : {
1913 5 : const SwTable * pTable = pTableTextNodeInfoInner->getTable();
1914 5 : const SwFrmFmt * pFrmFmt = pTable->GetFrmFmt();
1915 :
1916 5 : if ( m_rExport.TrueFrameDirection( *pFrmFmt ) == FRMDIR_HORI_RIGHT_TOP )
1917 : {
1918 : m_pSerializer->singleElementNS( XML_w, XML_bidiVisual,
1919 : FSNS( XML_w, XML_val ), "true",
1920 0 : FSEND );
1921 : }
1922 5 : }
1923 :
1924 38 : void DocxAttributeOutput::TableVerticalCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1925 : {
1926 38 : const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
1927 38 : const SwFrmFmt *pFrmFmt = pTabBox->GetFrmFmt( );
1928 :
1929 38 : if ( FRMDIR_VERT_TOP_RIGHT == m_rExport.TrueFrameDirection( *pFrmFmt ) )
1930 : m_pSerializer->singleElementNS( XML_w, XML_textDirection,
1931 : FSNS( XML_w, XML_val ), "tbRl",
1932 0 : FSEND );
1933 :
1934 38 : const SwWriteTableRows& aRows = m_pTableWrt->GetRows( );
1935 38 : SwWriteTableRow *pRow = aRows[ pTableTextNodeInfoInner->getRow( ) ];
1936 38 : const SwWriteTableCell *pCell = &pRow->GetCells( )[ pTableTextNodeInfoInner->getCell( ) ];
1937 38 : switch( pCell->GetVertOri())
1938 : {
1939 : case text::VertOrientation::TOP:
1940 38 : break;
1941 : case text::VertOrientation::CENTER:
1942 : m_pSerializer->singleElementNS( XML_w, XML_vAlign,
1943 0 : FSNS( XML_w, XML_val ), "center", FSEND );
1944 0 : break;
1945 : case text::VertOrientation::BOTTOM:
1946 : m_pSerializer->singleElementNS( XML_w, XML_vAlign,
1947 0 : FSNS( XML_w, XML_val ), "bottom", FSEND );
1948 0 : break;
1949 : }
1950 38 : }
1951 :
1952 0 : void DocxAttributeOutput::TableNodeInfo( ww8::WW8TableNodeInfo::Pointer_t /*pNodeInfo*/ )
1953 : {
1954 : OSL_TRACE( "TODO: DocxAttributeOutput::TableNodeInfo( ww8::WW8TableNodeInfo::Pointer_t pNodeInfo )" );
1955 0 : }
1956 :
1957 76 : void DocxAttributeOutput::TableNodeInfoInner( ww8::WW8TableNodeInfoInner::Pointer_t pNodeInfoInner )
1958 : {
1959 : // This is called when the nested table ends in a cell, and there's no
1960 : // paragraph benhind that; so we must check for the ends of cell, rows,
1961 : // tables
1962 : // ['true' to write an empty paragraph, MS Word insists on that]
1963 76 : FinishTableRowCell( pNodeInfoInner, true );
1964 76 : }
1965 :
1966 0 : void DocxAttributeOutput::TableOrientation( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
1967 : {
1968 : OSL_TRACE( "TODO: DocxAttributeOutput::TableOrientation( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )" );
1969 0 : }
1970 :
1971 0 : void DocxAttributeOutput::TableSpacing( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
1972 : {
1973 : #if OSL_DEBUG_LEVEL > 1
1974 : fprintf( stderr, "TODO: DocxAttributeOutput::TableSpacing( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )\n" );
1975 : #endif
1976 0 : }
1977 :
1978 0 : void DocxAttributeOutput::TableRowEnd( sal_uInt32 /*nDepth*/ )
1979 : {
1980 : OSL_TRACE( "TODO: DocxAttributeOutput::TableRowEnd( sal_uInt32 nDepth = 1 )" );
1981 0 : }
1982 :
1983 24 : void DocxAttributeOutput::StartStyles()
1984 : {
1985 : m_pSerializer->startElementNS( XML_w, XML_styles,
1986 : FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
1987 24 : FSEND );
1988 24 : }
1989 :
1990 24 : void DocxAttributeOutput::EndStyles( sal_uInt16 /*nNumberOfStyles*/ )
1991 : {
1992 24 : m_pSerializer->endElementNS( XML_w, XML_styles );
1993 24 : }
1994 :
1995 336 : void DocxAttributeOutput::DefaultStyle( sal_uInt16 nStyle )
1996 : {
1997 : // are these the values of enum ww::sti (see ../inc/wwstyles.hxx)?
1998 : #if OSL_DEBUG_LEVEL > 1
1999 : OSL_TRACE( "TODO DocxAttributeOutput::DefaultStyle( sal_uInt16 nStyle )- %d", nStyle );
2000 : #else
2001 : (void) nStyle; // to quiet the warning
2002 : #endif
2003 336 : }
2004 :
2005 1 : void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size& rSize, const SwFlyFrmFmt* pOLEFrmFmt, SwOLENode* pOLENode )
2006 : {
2007 : OSL_TRACE( "TODO DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size& rSize, const SwFlyFrmFmt* pOLEFrmFmt, SwOLENode* pOLENode ) - some stuff still missing" );
2008 : // detect mis-use of the API
2009 : assert(pGrfNode || (pOLEFrmFmt && pOLENode));
2010 1 : const SwFrmFmt* pFrmFmt = pGrfNode ? pGrfNode->GetFlyFmt() : pOLEFrmFmt;
2011 : // create the relation ID
2012 1 : OString aRelId;
2013 : sal_Int32 nImageType;
2014 1 : if ( pGrfNode && pGrfNode->IsLinkedFile() )
2015 : {
2016 : // linked image, just create the relation
2017 0 : String aFileName;
2018 0 : pGrfNode->GetFileFilterNms( &aFileName, 0 );
2019 :
2020 : // TODO Convert the file name to relative for better interoperability
2021 :
2022 : aRelId = m_rExport.AddRelation(
2023 : S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" ),
2024 0 : OUString( aFileName ) );
2025 :
2026 0 : nImageType = XML_link;
2027 : }
2028 : else
2029 : {
2030 : // inline, we also have to write the image itself
2031 1 : Graphic* pGraphic = 0;
2032 1 : if (pGrfNode)
2033 0 : pGraphic = &const_cast< Graphic& >( pGrfNode->GetGrf() );
2034 : else
2035 1 : pGraphic = pOLENode->GetGraphic();
2036 :
2037 1 : m_rDrawingML.SetFS( m_pSerializer ); // to be sure that we write to the right stream
2038 1 : OUString aImageId = m_rDrawingML.WriteImage( *pGraphic );
2039 :
2040 1 : aRelId = OUStringToOString( aImageId, RTL_TEXTENCODING_UTF8 );
2041 :
2042 1 : nImageType = XML_embed;
2043 : }
2044 :
2045 1 : if ( aRelId.isEmpty() )
2046 1 : return;
2047 :
2048 : m_pSerializer->startElementNS( XML_w, XML_drawing,
2049 1 : FSEND );
2050 1 : bool isAnchor = pFrmFmt->GetAnchor().GetAnchorId() != FLY_AS_CHAR;
2051 1 : if( isAnchor )
2052 : {
2053 1 : ::sax_fastparser::FastAttributeList* attrList = m_pSerializer->createAttrList();
2054 1 : attrList->add( XML_behindDoc, pFrmFmt->GetOpaque().GetValue() ? "0" : "1" );
2055 1 : attrList->add( XML_distT, "0" );
2056 1 : attrList->add( XML_distB, "0" );
2057 1 : attrList->add( XML_distL, "0" );
2058 1 : attrList->add( XML_distR, "0" );
2059 1 : attrList->add( XML_simplePos, "0" );
2060 1 : attrList->add( XML_locked, "0" );
2061 1 : attrList->add( XML_layoutInCell, "1" );
2062 1 : attrList->add( XML_allowOverlap, "1" ); // TODO
2063 1 : if( const SdrObject* pObj = pFrmFmt->FindRealSdrObject())
2064 1 : attrList->add( XML_relativeHeight, OString::valueOf( sal_Int32( pObj->GetOrdNum())));
2065 1 : m_pSerializer->startElementNS( XML_wp, XML_anchor, XFastAttributeListRef( attrList ));
2066 1 : m_pSerializer->singleElementNS( XML_wp, XML_simplePos, XML_x, "0", XML_y, "0", FSEND ); // required, unused
2067 : const char* relativeFromH;
2068 : const char* relativeFromV;
2069 1 : switch( pFrmFmt->GetAnchor().GetAnchorId())
2070 : {
2071 : case FLY_AT_PAGE:
2072 0 : relativeFromV = relativeFromH = "page";
2073 0 : break;
2074 : case FLY_AT_PARA:
2075 1 : relativeFromH = "column";
2076 1 : relativeFromV = "paragraph";
2077 1 : break;
2078 : case FLY_AT_CHAR:
2079 : default:
2080 : // We apply the same conversion that we do in import
2081 : // (see writerfilter/source/dmapper/GraphicHelper.cxx)
2082 0 : switch (pFrmFmt->GetVertOrient().GetRelationOrient() )
2083 : {
2084 : case text::RelOrientation::PAGE_PRINT_AREA:
2085 0 : relativeFromV = "margin";
2086 0 : break;
2087 : case text::RelOrientation::PAGE_FRAME:
2088 0 : relativeFromV = "page";
2089 0 : break;
2090 : case text::RelOrientation::FRAME:
2091 0 : relativeFromV = "paragraph";
2092 0 : break;
2093 : case text::RelOrientation::TEXT_LINE:
2094 : default:
2095 0 : relativeFromV = "line";
2096 : }
2097 0 : switch (pFrmFmt->GetHoriOrient().GetRelationOrient() )
2098 : {
2099 : case text::RelOrientation::PAGE_PRINT_AREA:
2100 0 : relativeFromH = "margin";
2101 0 : break;
2102 : case text::RelOrientation::PAGE_FRAME:
2103 0 : relativeFromH = "page";
2104 0 : break;
2105 : case text::RelOrientation::CHAR:
2106 0 : relativeFromH = "character";
2107 0 : break;
2108 : case text::RelOrientation::FRAME:
2109 : default:
2110 0 : relativeFromH = "column";
2111 : }
2112 0 : break;
2113 : };
2114 1 : Point pos( 0, 0 );
2115 1 : if( const SwFlyFrmFmt* flyfmt = dynamic_cast<const SwFlyFrmFmt*>(pFrmFmt)) // TODO is always true?
2116 1 : pos = flyfmt->GetAnchoredObj()->GetCurrRelPos();
2117 1 : OString x( OString::valueOf( TwipsToEMU( pos.X())));
2118 1 : OString y( OString::valueOf( TwipsToEMU( pos.Y())));
2119 1 : m_pSerializer->startElementNS( XML_wp, XML_positionH, XML_relativeFrom, relativeFromH, FSEND );
2120 1 : m_pSerializer->startElementNS( XML_wp, XML_posOffset, FSEND );
2121 1 : m_pSerializer->write( x.getStr() );
2122 1 : m_pSerializer->endElementNS( XML_wp, XML_posOffset );
2123 1 : m_pSerializer->endElementNS( XML_wp, XML_positionH );
2124 1 : m_pSerializer->startElementNS( XML_wp, XML_positionV, XML_relativeFrom, relativeFromV, FSEND );
2125 1 : m_pSerializer->startElementNS( XML_wp, XML_posOffset, FSEND );
2126 1 : m_pSerializer->write( y.getStr() );
2127 1 : m_pSerializer->endElementNS( XML_wp, XML_posOffset );
2128 1 : m_pSerializer->endElementNS( XML_wp, XML_positionV );
2129 : }
2130 : else
2131 : {
2132 : m_pSerializer->startElementNS( XML_wp, XML_inline,
2133 : XML_distT, "0", XML_distB, "0", XML_distL, "0", XML_distR, "0",
2134 0 : FSEND );
2135 : }
2136 : // now the common parts
2137 : // extent of the image
2138 1 : OString aWidth( OString::valueOf( TwipsToEMU( rSize.Width() ) ) );
2139 1 : OString aHeight( OString::valueOf( TwipsToEMU( rSize.Height() ) ) );
2140 : m_pSerializer->singleElementNS( XML_wp, XML_extent,
2141 : XML_cx, aWidth.getStr(),
2142 : XML_cy, aHeight.getStr(),
2143 1 : FSEND );
2144 : // TODO - the right effectExtent, extent including the effect
2145 : m_pSerializer->singleElementNS( XML_wp, XML_effectExtent,
2146 : XML_l, "0", XML_t, "0", XML_r, "0", XML_b, "0",
2147 1 : FSEND );
2148 :
2149 1 : if( isAnchor )
2150 : {
2151 1 : switch( pFrmFmt->GetSurround().GetValue())
2152 : {
2153 : case SURROUND_NONE:
2154 0 : m_pSerializer->singleElementNS( XML_wp, XML_wrapTopAndBottom, FSEND );
2155 0 : break;
2156 : case SURROUND_THROUGHT:
2157 0 : m_pSerializer->singleElementNS( XML_wp, XML_wrapNone, FSEND );
2158 0 : break;
2159 : case SURROUND_PARALLEL:
2160 : m_pSerializer->singleElementNS( XML_wp, XML_wrapSquare,
2161 0 : XML_wrapText, "bothSides", FSEND );
2162 0 : break;
2163 : case SURROUND_IDEAL:
2164 : default:
2165 : m_pSerializer->singleElementNS( XML_wp, XML_wrapSquare,
2166 1 : XML_wrapText, "largest", FSEND );
2167 1 : break;
2168 : }
2169 : }
2170 : // picture description (used for pic:cNvPr later too)
2171 1 : ::sax_fastparser::FastAttributeList* docPrattrList = m_pSerializer->createAttrList();
2172 1 : docPrattrList->add( XML_id, OString::valueOf( sal_Int32( m_anchorId++ )).getStr());
2173 1 : docPrattrList->add( XML_name, "Picture" );
2174 1 : docPrattrList->add( XML_descr, OUStringToOString( pGrfNode ? pGrfNode->GetDescription() : pOLEFrmFmt->GetObjDescription(), RTL_TEXTENCODING_UTF8 ).getStr());
2175 1 : if( GetExport().GetFilter().getVersion( ) != oox::core::ECMA_DIALECT )
2176 1 : docPrattrList->add( XML_title, OUStringToOString( pGrfNode ? pGrfNode->GetTitle() : pOLEFrmFmt->GetObjTitle(), RTL_TEXTENCODING_UTF8 ).getStr());
2177 1 : XFastAttributeListRef docPrAttrListRef( docPrattrList );
2178 1 : m_pSerializer->startElementNS( XML_wp, XML_docPr, docPrAttrListRef );
2179 : // TODO hyperlink
2180 : // m_pSerializer->singleElementNS( XML_a, XML_hlinkClick,
2181 : // FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
2182 : // FSNS( XML_r, XML_id ), "rId4",
2183 : // FSEND );
2184 1 : m_pSerializer->endElementNS( XML_wp, XML_docPr );
2185 :
2186 : m_pSerializer->startElementNS( XML_wp, XML_cNvGraphicFramePr,
2187 1 : FSEND );
2188 : // TODO change aspect?
2189 : m_pSerializer->singleElementNS( XML_a, XML_graphicFrameLocks,
2190 : FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
2191 : XML_noChangeAspect, "1",
2192 1 : FSEND );
2193 1 : m_pSerializer->endElementNS( XML_wp, XML_cNvGraphicFramePr );
2194 :
2195 : m_pSerializer->startElementNS( XML_a, XML_graphic,
2196 : FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
2197 1 : FSEND );
2198 : m_pSerializer->startElementNS( XML_a, XML_graphicData,
2199 : XML_uri, "http://schemas.openxmlformats.org/drawingml/2006/picture",
2200 1 : FSEND );
2201 :
2202 : m_pSerializer->startElementNS( XML_pic, XML_pic,
2203 : FSNS( XML_xmlns, XML_pic ), "http://schemas.openxmlformats.org/drawingml/2006/picture",
2204 1 : FSEND );
2205 :
2206 : m_pSerializer->startElementNS( XML_pic, XML_nvPicPr,
2207 1 : FSEND );
2208 : // It seems pic:cNvpr and wp:docPr are pretty much the same thing with the same attributes
2209 1 : m_pSerializer->startElementNS( XML_pic, XML_cNvPr, docPrAttrListRef );
2210 :
2211 : // TODO hyperlink
2212 : // m_pSerializer->singleElementNS( XML_a, XML_hlinkClick,
2213 : // FSNS( XML_r, XML_id ), "rId4",
2214 : // FSEND );
2215 1 : m_pSerializer->endElementNS( XML_pic, XML_cNvPr );
2216 :
2217 : m_pSerializer->startElementNS( XML_pic, XML_cNvPicPr,
2218 1 : FSEND );
2219 : // TODO change aspect?
2220 : m_pSerializer->singleElementNS( XML_a, XML_picLocks,
2221 : XML_noChangeAspect, "1", XML_noChangeArrowheads, "1",
2222 1 : FSEND );
2223 1 : m_pSerializer->endElementNS( XML_pic, XML_cNvPicPr );
2224 1 : m_pSerializer->endElementNS( XML_pic, XML_nvPicPr );
2225 :
2226 : // the actual picture
2227 : m_pSerializer->startElementNS( XML_pic, XML_blipFill,
2228 1 : FSEND );
2229 : m_pSerializer->singleElementNS( XML_a, XML_blip,
2230 : FSNS( XML_r, nImageType ), aRelId.getStr(),
2231 1 : FSEND );
2232 : m_pSerializer->singleElementNS( XML_a, XML_srcRect,
2233 1 : FSEND );
2234 : m_pSerializer->startElementNS( XML_a, XML_stretch,
2235 1 : FSEND );
2236 : m_pSerializer->singleElementNS( XML_a, XML_fillRect,
2237 1 : FSEND );
2238 1 : m_pSerializer->endElementNS( XML_a, XML_stretch );
2239 1 : m_pSerializer->endElementNS( XML_pic, XML_blipFill );
2240 :
2241 : // TODO setup the right values below
2242 : m_pSerializer->startElementNS( XML_pic, XML_spPr,
2243 : XML_bwMode, "auto",
2244 1 : FSEND );
2245 : m_pSerializer->startElementNS( XML_a, XML_xfrm,
2246 1 : FSEND );
2247 : m_pSerializer->singleElementNS( XML_a, XML_off,
2248 : XML_x, "0", XML_y, "0",
2249 1 : FSEND );
2250 : m_pSerializer->singleElementNS( XML_a, XML_ext,
2251 : XML_cx, aWidth.getStr(),
2252 : XML_cy, aHeight.getStr(),
2253 1 : FSEND );
2254 1 : m_pSerializer->endElementNS( XML_a, XML_xfrm );
2255 : m_pSerializer->startElementNS( XML_a, XML_prstGeom,
2256 : XML_prst, "rect",
2257 1 : FSEND );
2258 : m_pSerializer->singleElementNS( XML_a, XML_avLst,
2259 1 : FSEND );
2260 1 : m_pSerializer->endElementNS( XML_a, XML_prstGeom );
2261 : m_pSerializer->singleElementNS( XML_a, XML_noFill,
2262 1 : FSEND );
2263 : m_pSerializer->startElementNS( XML_a, XML_ln,
2264 : XML_w, "9525",
2265 1 : FSEND );
2266 : m_pSerializer->singleElementNS( XML_a, XML_noFill,
2267 1 : FSEND );
2268 : m_pSerializer->singleElementNS( XML_a, XML_miter,
2269 : XML_lim, "800000",
2270 1 : FSEND );
2271 : m_pSerializer->singleElementNS( XML_a, XML_headEnd,
2272 1 : FSEND );
2273 : m_pSerializer->singleElementNS( XML_a, XML_tailEnd,
2274 1 : FSEND );
2275 1 : m_pSerializer->endElementNS( XML_a, XML_ln );
2276 :
2277 : // Output effects
2278 1 : SvxShadowItem aShadowItem = pFrmFmt->GetShadow();
2279 1 : if ( aShadowItem.GetLocation() != SVX_SHADOW_NONE )
2280 : {
2281 : // Distance is measured diagonally from corner
2282 0 : double nShadowDist = sqrt((aShadowItem.GetWidth()*aShadowItem.GetWidth())*2.0);
2283 0 : OString aShadowDist( OString::valueOf( TwipsToEMU( nShadowDist ) ) );
2284 0 : OString aShadowColor = impl_ConvertColor( aShadowItem.GetColor() );
2285 0 : sal_uInt32 nShadowDir = 0;
2286 0 : switch ( aShadowItem.GetLocation() )
2287 : {
2288 0 : case SVX_SHADOW_TOPLEFT: nShadowDir = 13500000; break;
2289 0 : case SVX_SHADOW_TOPRIGHT: nShadowDir = 18900000; break;
2290 0 : case SVX_SHADOW_BOTTOMLEFT: nShadowDir = 8100000; break;
2291 0 : case SVX_SHADOW_BOTTOMRIGHT: nShadowDir = 2700000; break;
2292 : case SVX_SHADOW_NONE:
2293 : case SVX_SHADOW_END:
2294 0 : break;
2295 : }
2296 0 : OString aShadowDir( OString::valueOf( long(nShadowDir) ) );
2297 :
2298 0 : m_pSerializer->startElementNS( XML_a, XML_effectLst, FSEND );
2299 : m_pSerializer->startElementNS( XML_a, XML_outerShdw,
2300 : XML_dist, aShadowDist.getStr(),
2301 0 : XML_dir, aShadowDir.getStr(), FSEND );
2302 : m_pSerializer->singleElementNS( XML_a, XML_srgbClr,
2303 0 : XML_val, aShadowColor.getStr(), FSEND );
2304 0 : m_pSerializer->endElementNS( XML_a, XML_outerShdw );
2305 0 : m_pSerializer->endElementNS( XML_a, XML_effectLst );
2306 : }
2307 :
2308 1 : m_pSerializer->endElementNS( XML_pic, XML_spPr );
2309 :
2310 1 : m_pSerializer->endElementNS( XML_pic, XML_pic );
2311 :
2312 1 : m_pSerializer->endElementNS( XML_a, XML_graphicData );
2313 1 : m_pSerializer->endElementNS( XML_a, XML_graphic );
2314 1 : m_pSerializer->endElementNS( XML_wp, isAnchor ? XML_anchor : XML_inline );
2315 :
2316 1 : m_pSerializer->endElementNS( XML_w, XML_drawing );
2317 : }
2318 :
2319 43 : void DocxAttributeOutput::WriteOLE2Obj( const SdrObject* pSdrObj, SwOLENode& rOLENode, const Size& rSize, const SwFlyFrmFmt* pFlyFrmFmt )
2320 : {
2321 43 : if( WriteOLEChart( pSdrObj, rSize ))
2322 0 : return;
2323 43 : if( WriteOLEMath( pSdrObj, rOLENode, rSize ))
2324 42 : return;
2325 : // Then we fall back to just export the object as a graphic.
2326 1 : FlyFrameGraphic( 0, rSize, pFlyFrmFmt, &rOLENode );
2327 : }
2328 :
2329 43 : bool DocxAttributeOutput::WriteOLEChart( const SdrObject* pSdrObj, const Size& rSize )
2330 : {
2331 43 : uno::Reference< chart2::XChartDocument > xChartDoc;
2332 43 : uno::Reference< drawing::XShape > xShape( ((SdrObject*)pSdrObj)->getUnoShape(), uno::UNO_QUERY );
2333 43 : if( xShape.is() )
2334 : {
2335 43 : uno::Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
2336 43 : if( xPropSet.is() )
2337 43 : xChartDoc.set( xPropSet->getPropertyValue( "Model" ), uno::UNO_QUERY );
2338 : }
2339 :
2340 43 : if( xChartDoc.is() )
2341 : {
2342 : OSL_TRACE("DocxAttributeOutput::WriteOLE2Obj: export chart ");
2343 : m_pSerializer->startElementNS( XML_w, XML_drawing,
2344 0 : FSEND );
2345 : m_pSerializer->startElementNS( XML_wp, XML_inline,
2346 : XML_distT, "0", XML_distB, "0", XML_distL, "0", XML_distR, "0",
2347 0 : FSEND );
2348 :
2349 0 : OString aWidth( OString::valueOf( TwipsToEMU( rSize.Width() ) ) );
2350 0 : OString aHeight( OString::valueOf( TwipsToEMU( rSize.Height() ) ) );
2351 : m_pSerializer->singleElementNS( XML_wp, XML_extent,
2352 : XML_cx, aWidth.getStr(),
2353 : XML_cy, aHeight.getStr(),
2354 0 : FSEND );
2355 : // TODO - the right effectExtent, extent including the effect
2356 : m_pSerializer->singleElementNS( XML_wp, XML_effectExtent,
2357 : XML_l, "0", XML_t, "0", XML_r, "0", XML_b, "0",
2358 0 : FSEND );
2359 :
2360 : // should get the unique id
2361 0 : sal_Int32 nID = 1;
2362 0 : OUString sName("Object 1");
2363 0 : uno::Reference< container::XNamed > xNamed( xShape, uno::UNO_QUERY );
2364 0 : if( xNamed.is() )
2365 0 : sName = xNamed->getName();
2366 :
2367 : m_pSerializer->singleElementNS( XML_wp, XML_docPr,
2368 : XML_id, I32S( nID ),
2369 : XML_name, USS( sName ),
2370 0 : FSEND );
2371 :
2372 : m_pSerializer->singleElementNS( XML_wp, XML_cNvGraphicFramePr,
2373 0 : FSEND );
2374 :
2375 : m_pSerializer->startElementNS( XML_a, XML_graphic,
2376 : FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
2377 0 : FSEND );
2378 :
2379 : m_pSerializer->startElementNS( XML_a, XML_graphicData,
2380 : XML_uri, "http://schemas.openxmlformats.org/drawingml/2006/chart",
2381 0 : FSEND );
2382 :
2383 0 : OString aRelId;
2384 : static sal_Int32 nChartCount = 0;
2385 0 : nChartCount++;
2386 0 : uno::Reference< frame::XModel > xModel( xChartDoc, uno::UNO_QUERY );
2387 0 : aRelId = m_rExport.OutputChart( xModel, nChartCount );
2388 :
2389 : m_pSerializer->singleElementNS( XML_c, XML_chart,
2390 : FSNS( XML_xmlns, XML_c ), "http://schemas.openxmlformats.org/drawingml/2006/chart",
2391 : FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
2392 : FSNS( XML_r, XML_id ), aRelId.getStr(),
2393 0 : FSEND );
2394 :
2395 0 : m_pSerializer->endElementNS( XML_a, XML_graphicData );
2396 0 : m_pSerializer->endElementNS( XML_a, XML_graphic );
2397 0 : m_pSerializer->endElementNS( XML_wp, XML_inline );
2398 0 : m_pSerializer->endElementNS( XML_w, XML_drawing );
2399 :
2400 0 : return true;
2401 : }
2402 43 : return false;
2403 : }
2404 :
2405 43 : bool DocxAttributeOutput::WriteOLEMath( const SdrObject*, const SwOLENode& rOLENode, const Size& )
2406 : {
2407 43 : uno::Reference < embed::XEmbeddedObject > xObj(const_cast<SwOLENode&>(rOLENode).GetOLEObj().GetOleRef());
2408 43 : sal_Int64 nAspect = rOLENode.GetAspect();
2409 43 : svt::EmbeddedObjectRef aObjRef( xObj, nAspect );
2410 43 : SvGlobalName aObjName(aObjRef->getClassID());
2411 :
2412 43 : if( !SotExchange::IsMath(aObjName) )
2413 1 : return false;
2414 : assert( m_postponedMath == NULL ); // make it a list if there can be more inside one run
2415 42 : m_postponedMath = &rOLENode;
2416 42 : return true;
2417 : }
2418 :
2419 110 : void DocxAttributeOutput::WritePostponedMath()
2420 : {
2421 110 : if( m_postponedMath == NULL )
2422 110 : return;
2423 42 : uno::Reference < embed::XEmbeddedObject > xObj(const_cast<SwOLENode*>(m_postponedMath)->GetOLEObj().GetOleRef());
2424 42 : uno::Reference< uno::XInterface > xInterface( xObj->getComponent(), uno::UNO_QUERY );
2425 : // gcc4.4 (and 4.3 and possibly older) have a problem with dynamic_cast directly to the target class,
2426 : // so help it with an intermediate cast. I'm not sure what exactly the problem is, seems to be unrelated
2427 : // to RTLD_GLOBAL, so most probably a gcc bug.
2428 42 : oox::FormulaExportBase* formulaexport = dynamic_cast<oox::FormulaExportBase*>(dynamic_cast<SfxBaseModel*>(xInterface.get()));
2429 : assert( formulaexport != NULL );
2430 42 : formulaexport->writeFormulaOoxml( m_pSerializer, GetExport().GetFilter().getVersion());
2431 42 : m_postponedMath = NULL;
2432 : }
2433 :
2434 43 : void DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame &rFrame, const Point& /*rNdTopLeft*/ )
2435 : {
2436 43 : m_pSerializer->mark();
2437 :
2438 43 : switch ( rFrame.GetWriterType() )
2439 : {
2440 : case sw::Frame::eGraphic:
2441 : {
2442 0 : const SwNode *pNode = rFrame.GetContent();
2443 0 : const SwGrfNode *pGrfNode = pNode ? pNode->GetGrfNode() : 0;
2444 0 : if ( pGrfNode )
2445 : {
2446 0 : if( m_postponedGraphic == NULL )
2447 0 : FlyFrameGraphic( pGrfNode, rFrame.GetLayoutSize() );
2448 : else // we are writting out attributes, but w:drawing should not be inside w:rPr,
2449 : { // so write it out later
2450 0 : m_postponedGraphic->push_back( PostponedGraphic( pGrfNode, rFrame.GetLayoutSize()));
2451 : }
2452 : }
2453 : }
2454 0 : break;
2455 : case sw::Frame::eDrawing:
2456 : {
2457 0 : const SdrObject* pSdrObj = rFrame.GetFrmFmt().FindRealSdrObject();
2458 0 : if ( pSdrObj )
2459 : {
2460 0 : bool bSwapInPage = false;
2461 0 : if ( !pSdrObj->GetPage() )
2462 : {
2463 0 : if ( SdrModel* pModel = m_rExport.pDoc->GetDrawModel() )
2464 : {
2465 0 : if ( SdrPage *pPage = pModel->GetPage( 0 ) )
2466 : {
2467 0 : bSwapInPage = true;
2468 0 : const_cast< SdrObject* >( pSdrObj )->SetPage( pPage );
2469 : }
2470 : }
2471 : }
2472 :
2473 : m_pSerializer->startElementNS( XML_w, XML_pict,
2474 0 : FSEND );
2475 :
2476 0 : m_rExport.VMLExporter().AddSdrObject( *pSdrObj );
2477 :
2478 0 : m_pSerializer->endElementNS( XML_w, XML_pict );
2479 :
2480 0 : if ( bSwapInPage )
2481 0 : const_cast< SdrObject* >( pSdrObj )->SetPage( 0 );
2482 : }
2483 : }
2484 0 : break;
2485 : case sw::Frame::eTxtBox:
2486 : {
2487 : // The frame output is postponed to the end of the anchor paragraph
2488 0 : m_pParentFrame = new sw::Frame(rFrame);
2489 : }
2490 0 : break;
2491 : case sw::Frame::eOle:
2492 : {
2493 43 : const SwFrmFmt &rFrmFmt = rFrame.GetFrmFmt();
2494 43 : const SdrObject *pSdrObj = rFrmFmt.FindRealSdrObject();
2495 43 : if ( pSdrObj )
2496 : {
2497 43 : SwNodeIndex aIdx(*rFrmFmt.GetCntnt().GetCntntIdx(), 1);
2498 43 : SwOLENode& rOLENd = *aIdx.GetNode().GetOLENode();
2499 43 : WriteOLE2Obj( pSdrObj, rOLENd, rFrame.GetLayoutSize(), dynamic_cast<const SwFlyFrmFmt*>( &rFrmFmt ));
2500 : }
2501 : }
2502 43 : break;
2503 : default:
2504 : OSL_TRACE( "TODO DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame& rFrame, const Point& rNdTopLeft ) - frame type '%s'\n",
2505 : rFrame.GetWriterType() == sw::Frame::eTxtBox? "eTxtBox":
2506 : ( rFrame.GetWriterType() == sw::Frame::eOle? "eOle":
2507 : ( rFrame.GetWriterType() == sw::Frame::eFormControl? "eFormControl": "???" ) ) );
2508 0 : break;
2509 : }
2510 :
2511 43 : m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_POSTPONE );
2512 43 : }
2513 :
2514 0 : void DocxAttributeOutput::WriteOutliner(const OutlinerParaObject& rParaObj)
2515 : {
2516 0 : const EditTextObject& rEditObj = rParaObj.GetTextObject();
2517 0 : MSWord_SdrAttrIter aAttrIter( m_rExport, rEditObj, TXT_HFTXTBOX );
2518 :
2519 0 : sal_uInt16 nPara = rEditObj.GetParagraphCount();
2520 :
2521 0 : m_pSerializer->startElementNS( XML_w, XML_textbox, FSEND );
2522 0 : m_pSerializer->startElementNS( XML_w, XML_txbxContent, FSEND );
2523 0 : for (sal_uInt16 n = 0; n < nPara; ++n)
2524 : {
2525 0 : if( n )
2526 0 : aAttrIter.NextPara( n );
2527 :
2528 0 : String aStr( rEditObj.GetText( n ));
2529 0 : xub_StrLen nAktPos = 0;
2530 0 : xub_StrLen nEnd = aStr.Len();
2531 :
2532 0 : m_pSerializer->startElementNS( XML_w, XML_p, FSEND );
2533 0 : do {
2534 0 : xub_StrLen nNextAttr = aAttrIter.WhereNext();
2535 0 : if( nNextAttr > nEnd )
2536 0 : nNextAttr = nEnd;
2537 :
2538 0 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
2539 0 : bool bTxtAtr = aAttrIter.IsTxtAttr( nAktPos );
2540 0 : if( !bTxtAtr )
2541 : {
2542 0 : String aOut( aStr.Copy( nAktPos, nNextAttr - nAktPos ) );
2543 0 : RunText(aOut);
2544 : }
2545 :
2546 0 : m_pSerializer->endElementNS( XML_w, XML_r );
2547 :
2548 0 : nAktPos = nNextAttr;
2549 0 : aAttrIter.NextPos();
2550 : }
2551 : while( nAktPos < nEnd );
2552 0 : m_pSerializer->endElementNS( XML_w, XML_p );
2553 0 : }
2554 0 : m_pSerializer->endElementNS( XML_w, XML_txbxContent );
2555 0 : m_pSerializer->endElementNS( XML_w, XML_textbox );
2556 0 : }
2557 :
2558 0 : oox::drawingml::DrawingML& DocxAttributeOutput::GetDrawingML()
2559 : {
2560 0 : return m_rDrawingML;
2561 : }
2562 :
2563 164 : void DocxAttributeOutput::StartStyle( const String& rName, bool bPapFmt,
2564 : sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 /*nWwId*/, sal_uInt16 nId, bool bAutoUpdate )
2565 : {
2566 164 : OString aStyle( "style" );
2567 :
2568 : m_pSerializer->startElementNS( XML_w, XML_style,
2569 : FSNS( XML_w, XML_type ), bPapFmt? "paragraph": "character", // FIXME is this correct?
2570 328 : FSNS( XML_w, XML_styleId ), OString( aStyle + OString::valueOf( sal_Int32( nId ) ) ).getStr(),
2571 164 : FSEND );
2572 :
2573 : m_pSerializer->singleElementNS( XML_w, XML_name,
2574 : FSNS( XML_w, XML_val ), OUStringToOString( OUString( rName ), RTL_TEXTENCODING_UTF8 ).getStr(),
2575 164 : FSEND );
2576 :
2577 164 : if ( nBase != 0x0FFF )
2578 : {
2579 : m_pSerializer->singleElementNS( XML_w, XML_basedOn,
2580 262 : FSNS( XML_w, XML_val ), OString( aStyle + OString::valueOf( sal_Int32( nBase ) ) ).getStr(),
2581 131 : FSEND );
2582 : }
2583 :
2584 : m_pSerializer->singleElementNS( XML_w, XML_next,
2585 328 : FSNS( XML_w, XML_val ), OString( aStyle + OString::valueOf( sal_Int32( nNext ) ) ).getStr(),
2586 164 : FSEND );
2587 :
2588 164 : if ( bAutoUpdate )
2589 0 : m_pSerializer->singleElementNS( XML_w, XML_autoRedefine, FSEND );
2590 164 : }
2591 :
2592 164 : void DocxAttributeOutput::EndStyle()
2593 : {
2594 164 : m_pSerializer->endElementNS( XML_w, XML_style );
2595 164 : }
2596 :
2597 313 : void DocxAttributeOutput::StartStyleProperties( bool bParProp, sal_uInt16 /*nStyle*/ )
2598 : {
2599 313 : if ( bParProp )
2600 : {
2601 149 : m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND );
2602 149 : InitCollectedParagraphProperties();
2603 : }
2604 : else
2605 : {
2606 164 : m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
2607 164 : InitCollectedRunProperties();
2608 : }
2609 313 : }
2610 :
2611 313 : void DocxAttributeOutput::EndStyleProperties( bool bParProp )
2612 : {
2613 313 : if ( bParProp )
2614 : {
2615 149 : WriteCollectedParagraphProperties();
2616 149 : m_pSerializer->endElementNS( XML_w, XML_pPr );
2617 : }
2618 : else
2619 : {
2620 164 : WriteCollectedRunProperties();
2621 164 : m_pSerializer->endElementNS( XML_w, XML_rPr );
2622 : }
2623 313 : }
2624 :
2625 0 : void DocxAttributeOutput::OutlineNumbering( sal_uInt8 nLvl, const SwNumFmt& /*rNFmt*/, const SwFmt& /*rFmt*/ )
2626 : {
2627 0 : if ( nLvl >= WW8ListManager::nMaxLevel )
2628 0 : nLvl = WW8ListManager::nMaxLevel - 1;
2629 :
2630 : m_pSerializer->singleElementNS( XML_w, XML_outlineLvl,
2631 : FSNS( XML_w, XML_val ), OString::valueOf( sal_Int32( nLvl ) ).getStr( ),
2632 0 : FSEND );
2633 0 : }
2634 :
2635 0 : void DocxAttributeOutput::PageBreakBefore( bool bBreak )
2636 : {
2637 0 : if ( bBreak )
2638 0 : m_pSerializer->singleElementNS( XML_w, XML_pageBreakBefore, FSEND );
2639 : else
2640 : m_pSerializer->singleElementNS( XML_w, XML_pageBreakBefore,
2641 : FSNS( XML_w, XML_val ), "false",
2642 0 : FSEND );
2643 0 : }
2644 :
2645 0 : void DocxAttributeOutput::SectionBreak( sal_uInt8 nC, const WW8_SepInfo* pSectionInfo )
2646 : {
2647 0 : switch ( nC )
2648 : {
2649 : case msword::ColumnBreak:
2650 : // The column break should be output in the next paragraph...
2651 0 : m_nColBreakStatus = COLBRK_POSTPONE;
2652 0 : break;
2653 : case msword::PageBreak:
2654 0 : if ( pSectionInfo )
2655 : {
2656 0 : if ( !m_bParagraphOpened )
2657 : {
2658 : // Create a dummy paragraph if needed
2659 0 : m_pSerializer->startElementNS( XML_w, XML_p, FSEND );
2660 0 : m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND );
2661 :
2662 0 : m_rExport.SectionProperties( *pSectionInfo );
2663 :
2664 0 : m_pSerializer->endElementNS( XML_w, XML_pPr );
2665 0 : m_pSerializer->endElementNS( XML_w, XML_p );
2666 : }
2667 : else
2668 : {
2669 : // postpone the output of this; it has to be done inside the
2670 : // paragraph properties, so remember it until then
2671 0 : m_pSectionInfo.reset( new WW8_SepInfo( *pSectionInfo ));
2672 : }
2673 : }
2674 : else
2675 : {
2676 0 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
2677 : m_pSerializer->singleElementNS( XML_w, XML_br,
2678 0 : FSNS( XML_w, XML_type ), "page", FSEND );
2679 0 : m_pSerializer->endElementNS( XML_w, XML_r );
2680 : }
2681 0 : break;
2682 : default:
2683 : OSL_TRACE( "Unknown section break to write: %d", nC );
2684 0 : break;
2685 : }
2686 0 : }
2687 :
2688 24 : void DocxAttributeOutput::StartSection()
2689 : {
2690 24 : m_pSerializer->startElementNS( XML_w, XML_sectPr, FSEND );
2691 24 : m_bOpenedSectPr = true;
2692 :
2693 : // Write the elements in the spec order
2694 : static const sal_Int32 aOrder[] =
2695 : {
2696 : FSNS( XML_w, XML_headerReference ),
2697 : FSNS( XML_w, XML_footerReference ),
2698 : FSNS( XML_w, XML_footnotePr ),
2699 : FSNS( XML_w, XML_endnotePr ),
2700 : FSNS( XML_w, XML_type ),
2701 : FSNS( XML_w, XML_pgSz ),
2702 : FSNS( XML_w, XML_pgMar ),
2703 : FSNS( XML_w, XML_paperSrc ),
2704 : FSNS( XML_w, XML_pgBorders ),
2705 : FSNS( XML_w, XML_lnNumType ),
2706 : FSNS( XML_w, XML_pgNumType ),
2707 : FSNS( XML_w, XML_cols ),
2708 : FSNS( XML_w, XML_formProt ),
2709 : FSNS( XML_w, XML_vAlign ),
2710 : FSNS( XML_w, XML_noEndnote ),
2711 : FSNS( XML_w, XML_titlePg ),
2712 : FSNS( XML_w, XML_textDirection ),
2713 : FSNS( XML_w, XML_bidi ),
2714 : FSNS( XML_w, XML_rtlGutter ),
2715 : FSNS( XML_w, XML_docGrid ),
2716 : FSNS( XML_w, XML_printerSettings ),
2717 : FSNS( XML_w, XML_sectPrChange )
2718 : };
2719 :
2720 : // postpone the output so that we can later [in EndParagraphProperties()]
2721 : // prepend the properties before the run
2722 24 : sal_Int32 len = sizeof ( aOrder ) / sizeof( sal_Int32 );
2723 24 : uno::Sequence< sal_Int32 > aSeqOrder( len );
2724 552 : for ( sal_Int32 i = 0; i < len; i++ )
2725 528 : aSeqOrder[i] = aOrder[i];
2726 :
2727 24 : m_pSerializer->mark( aSeqOrder );
2728 24 : }
2729 :
2730 24 : void DocxAttributeOutput::EndSection()
2731 : {
2732 : // Write the section properties
2733 24 : if ( m_pSectionSpacingAttrList )
2734 : {
2735 24 : XFastAttributeListRef xAttrList( m_pSectionSpacingAttrList );
2736 24 : m_pSectionSpacingAttrList = NULL;
2737 :
2738 24 : m_pSerializer->singleElementNS( XML_w, XML_pgMar, xAttrList );
2739 : }
2740 :
2741 : // Order the elements
2742 24 : m_pSerializer->mergeTopMarks( );
2743 :
2744 24 : m_pSerializer->endElementNS( XML_w, XML_sectPr );
2745 24 : m_bOpenedSectPr = false;
2746 24 : }
2747 :
2748 24 : void DocxAttributeOutput::SectionFormProtection( bool bProtected )
2749 : {
2750 24 : if ( bProtected )
2751 0 : m_pSerializer->singleElementNS( XML_w, XML_formProt, FSEND );
2752 : else
2753 : m_pSerializer->singleElementNS( XML_w, XML_formProt,
2754 24 : FSNS( XML_w, XML_val ), "false", FSEND );
2755 24 : }
2756 :
2757 0 : void DocxAttributeOutput::SectionLineNumbering( sal_uLong nRestartNo, const SwLineNumberInfo& rLnNumInfo )
2758 : {
2759 0 : FastAttributeList* pAttr = m_pSerializer->createAttrList();
2760 0 : pAttr->add( FSNS( XML_w, XML_countBy ), OString::valueOf(static_cast<sal_Int32>(rLnNumInfo.GetCountBy())).getStr());
2761 0 : pAttr->add( FSNS( XML_w, XML_restart ), rLnNumInfo.IsRestartEachPage() ? "newPage" : "continuous" );
2762 0 : if( rLnNumInfo.GetPosFromLeft())
2763 0 : pAttr->add( FSNS( XML_w, XML_distance ), OString::valueOf(static_cast<sal_Int32>(rLnNumInfo.GetPosFromLeft())).getStr());
2764 0 : if( nRestartNo )
2765 0 : pAttr->add( FSNS( XML_w, XML_start ), OString::valueOf( long( nRestartNo )).getStr());
2766 0 : XFastAttributeListRef xAttrs( pAttr );
2767 0 : m_pSerializer->singleElementNS( XML_w, XML_lnNumType, xAttrs );
2768 0 : }
2769 :
2770 0 : void DocxAttributeOutput::SectionTitlePage()
2771 : {
2772 0 : m_pSerializer->singleElementNS( XML_w, XML_titlePg, FSEND );
2773 0 : }
2774 :
2775 24 : void DocxAttributeOutput::SectionPageBorders( const SwFrmFmt* pFmt, const SwFrmFmt* /*pFirstPageFmt*/ )
2776 : {
2777 : // Output the margins
2778 :
2779 24 : const SvxBoxItem& rBox = pFmt->GetBox( );
2780 :
2781 24 : const SvxBorderLine* pBottom = rBox.GetBottom( );
2782 24 : const SvxBorderLine* pTop = rBox.GetTop( );
2783 24 : const SvxBorderLine* pLeft = rBox.GetLeft( );
2784 24 : const SvxBorderLine* pRight = rBox.GetRight( );
2785 :
2786 24 : if ( pBottom || pTop || pLeft || pRight )
2787 : {
2788 : // All distances are relative to the text margins
2789 : m_pSerializer->startElementNS( XML_w, XML_pgBorders,
2790 : FSNS( XML_w, XML_display ), "allPages",
2791 : FSNS( XML_w, XML_offsetFrom ), "text",
2792 0 : FSEND );
2793 :
2794 0 : m_pSerializer->mark();
2795 :
2796 0 : m_pSerializer->endElementNS( XML_w, XML_pgBorders );
2797 0 : m_pSerializer->mark();
2798 : }
2799 24 : }
2800 :
2801 0 : void DocxAttributeOutput::SectionBiDi( bool bBiDi )
2802 : {
2803 0 : if ( bBiDi )
2804 0 : m_pSerializer->singleElementNS( XML_w, XML_bidi, FSEND );
2805 0 : }
2806 :
2807 24 : static OString impl_NumberingType( sal_uInt16 nNumberingType )
2808 : {
2809 24 : OString aType;
2810 :
2811 24 : switch ( nNumberingType )
2812 : {
2813 : case SVX_NUM_CHARS_UPPER_LETTER:
2814 0 : case SVX_NUM_CHARS_UPPER_LETTER_N: aType = "upperLetter"; break;
2815 : case SVX_NUM_CHARS_LOWER_LETTER:
2816 0 : case SVX_NUM_CHARS_LOWER_LETTER_N: aType = "lowerLetter"; break;
2817 0 : case SVX_NUM_ROMAN_UPPER: aType = "upperRoman"; break;
2818 0 : case SVX_NUM_ROMAN_LOWER: aType = "lowerRoman"; break;
2819 :
2820 24 : case SVX_NUM_ARABIC: aType = "decimal"; break;
2821 :
2822 : case SVX_NUM_BITMAP:
2823 0 : case SVX_NUM_CHAR_SPECIAL: aType = "bullet"; break;
2824 :
2825 0 : default: aType = "none"; break;
2826 : }
2827 :
2828 24 : return aType;
2829 : }
2830 :
2831 24 : void DocxAttributeOutput::SectionPageNumbering( sal_uInt16 nNumType, sal_uInt16 nPageRestartNumber )
2832 : {
2833 : // FIXME Not called properly with page styles like "First Page"
2834 :
2835 24 : FastAttributeList* pAttr = m_pSerializer->createAttrList();
2836 :
2837 : // 0 means no restart: then don't output that attribute if 0
2838 24 : if ( nPageRestartNumber > 0 )
2839 0 : pAttr->add( FSNS( XML_w, XML_start ), OString::valueOf( sal_Int32( nPageRestartNumber ) ) );
2840 :
2841 : // nNumType corresponds to w:fmt. See WW8Export::GetNumId() for more precisions
2842 24 : OString aFmt( impl_NumberingType( nNumType ) );
2843 24 : if ( !aFmt.isEmpty() )
2844 24 : pAttr->add( FSNS( XML_w, XML_fmt ), aFmt.getStr() );
2845 :
2846 24 : XFastAttributeListRef xAttrs( pAttr );
2847 24 : m_pSerializer->singleElementNS( XML_w, XML_pgNumType, xAttrs );
2848 :
2849 : // see 2.6.12 pgNumType (Page Numbering Settings)
2850 24 : OSL_TRACE( "TODO DocxAttributeOutput::SectionPageNumbering()" );
2851 24 : }
2852 :
2853 24 : void DocxAttributeOutput::SectionType( sal_uInt8 nBreakCode )
2854 : {
2855 : /* break code: 0 No break, 1 New column
2856 : 2 New page, 3 Even page, 4 Odd page
2857 : */
2858 24 : const char* pType = NULL;
2859 24 : switch ( nBreakCode )
2860 : {
2861 0 : case 1: pType = "nextColumn"; break;
2862 24 : case 2: pType = "nextPage"; break;
2863 0 : case 3: pType = "evenPage"; break;
2864 0 : case 4: pType = "oddPage"; break;
2865 0 : default: pType = "continuous"; break;
2866 : }
2867 :
2868 24 : if ( pType )
2869 : m_pSerializer->singleElementNS( XML_w, XML_type,
2870 : FSNS( XML_w, XML_val ), pType,
2871 24 : FSEND );
2872 24 : }
2873 :
2874 168 : void DocxAttributeOutput::StartFont( const String& rFamilyName ) const
2875 : {
2876 : m_pSerializer->startElementNS( XML_w, XML_font,
2877 : FSNS( XML_w, XML_name ), OUStringToOString( OUString( rFamilyName ), RTL_TEXTENCODING_UTF8 ).getStr(),
2878 168 : FSEND );
2879 168 : }
2880 :
2881 168 : void DocxAttributeOutput::EndFont() const
2882 : {
2883 168 : m_pSerializer->endElementNS( XML_w, XML_font );
2884 168 : }
2885 :
2886 83 : void DocxAttributeOutput::FontAlternateName( const String& rName ) const
2887 : {
2888 : m_pSerializer->singleElementNS( XML_w, XML_altName,
2889 : FSNS( XML_w, XML_val ), OUStringToOString( OUString( rName ), RTL_TEXTENCODING_UTF8 ).getStr(),
2890 83 : FSEND );
2891 83 : }
2892 :
2893 168 : void DocxAttributeOutput::FontCharset( sal_uInt8 nCharSet, rtl_TextEncoding nEncoding ) const
2894 : {
2895 168 : FastAttributeList* pAttr = m_pSerializer->createAttrList();
2896 :
2897 168 : OString aCharSet( OString::valueOf( sal_Int32( nCharSet ), 16 ) );
2898 168 : if ( aCharSet.getLength() == 1 )
2899 72 : aCharSet = OString( "0" ) + aCharSet;
2900 168 : pAttr->add( FSNS( XML_w, XML_val ), aCharSet.getStr());
2901 :
2902 168 : if( GetExport().GetFilter().getVersion( ) != oox::core::ECMA_DIALECT )
2903 : {
2904 168 : if( const char* charset = rtl_getMimeCharsetFromTextEncoding( nEncoding ))
2905 78 : pAttr->add( FSNS( XML_w, XML_characterSet ), charset );
2906 : }
2907 :
2908 168 : m_pSerializer->singleElementNS( XML_w, XML_charset, XFastAttributeListRef( pAttr ));
2909 168 : }
2910 :
2911 168 : void DocxAttributeOutput::FontFamilyType( FontFamily eFamily ) const
2912 : {
2913 168 : const char *pFamily = NULL;
2914 168 : switch ( eFamily )
2915 : {
2916 120 : case FAMILY_ROMAN: pFamily = "roman"; break;
2917 48 : case FAMILY_SWISS: pFamily = "swiss"; break;
2918 0 : case FAMILY_MODERN: pFamily = "modern"; break;
2919 0 : case FAMILY_SCRIPT: pFamily = "script"; break;
2920 0 : case FAMILY_DECORATIVE: pFamily = "decorative"; break;
2921 0 : default: pFamily = "auto"; break; // no font family
2922 : }
2923 :
2924 168 : if ( pFamily )
2925 : m_pSerializer->singleElementNS( XML_w, XML_family,
2926 : FSNS( XML_w, XML_val ), pFamily,
2927 168 : FSEND );
2928 168 : }
2929 :
2930 168 : void DocxAttributeOutput::FontPitchType( FontPitch ePitch ) const
2931 : {
2932 168 : const char *pPitch = NULL;
2933 168 : switch ( ePitch )
2934 : {
2935 102 : case PITCH_VARIABLE: pPitch = "variable"; break;
2936 0 : case PITCH_FIXED: pPitch = "fixed"; break;
2937 66 : default: pPitch = "default"; break; // no info about the pitch
2938 : }
2939 :
2940 168 : if ( pPitch )
2941 : m_pSerializer->singleElementNS( XML_w, XML_pitch,
2942 : FSNS( XML_w, XML_val ), pPitch,
2943 168 : FSEND );
2944 168 : }
2945 :
2946 168 : void DocxAttributeOutput::EmbedFont( const OUString& name )
2947 : {
2948 168 : if( !m_rExport.pDoc->get( IDocumentSettingAccess::EMBED_FONTS ))
2949 336 : return; // no font embedding with this document
2950 0 : EmbedFontStyle( name, XML_embedRegular, "" );
2951 0 : EmbedFontStyle( name, XML_embedBold, "b" );
2952 0 : EmbedFontStyle( name, XML_embedItalic, "i" );
2953 0 : EmbedFontStyle( name, XML_embedBoldItalic, "bi" );
2954 : }
2955 :
2956 0 : static inline char toHexChar( int value )
2957 : {
2958 0 : return value >= 10 ? value + 'A' - 10 : value + '0';
2959 : }
2960 :
2961 0 : void DocxAttributeOutput::EmbedFontStyle( const OUString& name, int tag, const char* style )
2962 : {
2963 0 : OUString fontUrl = TemporaryFonts::fileUrlForFont( name, style );
2964 : // If a temporary font file exists for this font, assume it was embedded
2965 : // and embed it again.
2966 : // TODO IDocumentSettingAccess::EMBED_SYSTEM_FONTS
2967 0 : osl::File file( fontUrl );
2968 0 : if( file.open( osl_File_OpenFlag_Write ) != osl::File::E_None )
2969 : return;
2970 0 : uno::Reference< com::sun::star::io::XOutputStream > xOutStream = m_rExport.GetFilter().openFragmentStream(
2971 0 : OUString( "word/fonts/font" ) + OUString::valueOf( static_cast< sal_Int32 >( m_nextFontId )) + ".ttf",
2972 0 : "application/vnd.openxmlformats-officedocument.obfuscatedFont" );
2973 : // Not much point in trying hard with the obfuscation key, whoever reads the spec can read the font anyway,
2974 : // so just alter the first and last part of the key.
2975 0 : char fontKeyStr[] = "{00014A78-CABC-4EF0-12AC-5CD89AEFDE00}";
2976 : sal_uInt8 fontKey[ 16 ] = { 0, 0xDE, 0xEF, 0x9A, 0xD8, 0x5C, 0xAC, 0x12, 0xF0, 0x4E,
2977 0 : 0xBC, 0xCA, 0x78, 0x4A, 0x01, 0 };
2978 0 : fontKey[ 0 ] = fontKey[ 15 ] = m_nextFontId % 256;
2979 0 : fontKeyStr[ 1 ] = fontKeyStr[ 35 ] = toHexChar(( m_nextFontId % 256 ) / 16 );
2980 0 : fontKeyStr[ 2 ] = fontKeyStr[ 36 ] = toHexChar(( m_nextFontId % 256 ) % 16 );
2981 : char buffer[ 4096 ];
2982 : sal_uInt64 readSize;
2983 0 : file.read( buffer, 32, readSize );
2984 0 : if( readSize < 32 )
2985 : {
2986 : SAL_WARN( "sw.ww8", "Font file size too small (" << fontUrl << ")" );
2987 0 : xOutStream->closeOutput();
2988 : return;
2989 : }
2990 0 : for( int i = 0;
2991 : i < 16;
2992 : ++i )
2993 : {
2994 0 : buffer[ i ] ^= fontKey[ i ];
2995 0 : buffer[ i + 16 ] ^= fontKey[ i ];
2996 : }
2997 0 : xOutStream->writeBytes( uno::Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( buffer ), 32 ));
2998 0 : for(;;)
2999 : {
3000 : sal_Bool eof;
3001 0 : if( file.isEndOfFile( &eof ) != osl::File::E_None )
3002 : {
3003 : SAL_WARN( "sw.ww8", "Error reading font file " << fontUrl );
3004 0 : xOutStream->closeOutput();
3005 : return;
3006 : }
3007 0 : if( eof )
3008 : break;
3009 0 : if( file.read( buffer, 4096, readSize ) != osl::File::E_None )
3010 : {
3011 : SAL_WARN( "sw.ww8", "Error reading font file " << fontUrl );
3012 0 : xOutStream->closeOutput();
3013 : return;
3014 : }
3015 0 : if( readSize == 0 )
3016 : break;
3017 0 : xOutStream->writeBytes( uno::Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( buffer ), readSize ));
3018 : }
3019 0 : xOutStream->closeOutput();
3020 0 : OString relId = OUStringToOString( GetExport().GetFilter().addRelation( m_pSerializer->getOutputStream(),
3021 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/font",
3022 0 : OUString( "fonts/font" ) + OUString::valueOf( static_cast< sal_Int32 >( m_nextFontId )) + ".ttf" ), RTL_TEXTENCODING_UTF8 );
3023 : m_pSerializer->singleElementNS( XML_w, tag,
3024 : FSNS( XML_r, XML_id ), relId.getStr(),
3025 : FSNS( XML_w, XML_fontKey ), fontKeyStr,
3026 0 : FSEND );
3027 0 : ++m_nextFontId;
3028 : }
3029 :
3030 0 : void DocxAttributeOutput::NumberingDefinition( sal_uInt16 nId, const SwNumRule &rRule )
3031 : {
3032 : // nId is the same both for abstract numbering definition as well as the
3033 : // numbering definition itself
3034 : // TODO check that this is actually true & fix if not ;-)
3035 0 : OString aId( OString::valueOf( sal_Int32( nId ) ) );
3036 :
3037 : m_pSerializer->startElementNS( XML_w, XML_num,
3038 : FSNS( XML_w, XML_numId ), aId.getStr(),
3039 0 : FSEND );
3040 :
3041 : m_pSerializer->singleElementNS( XML_w, XML_abstractNumId,
3042 : FSNS( XML_w, XML_val ), aId.getStr(),
3043 0 : FSEND );
3044 :
3045 : #if OSL_DEBUG_LEVEL > 1
3046 : // TODO ww8 version writes this, anything to do about it here?
3047 : if ( rRule.IsContinusNum() )
3048 : OSL_TRACE( "TODO DocxAttributeOutput::NumberingDefinition()" );
3049 : #else
3050 : (void) rRule; // to quiet the warning...
3051 : #endif
3052 :
3053 0 : m_pSerializer->endElementNS( XML_w, XML_num );
3054 0 : }
3055 :
3056 0 : void DocxAttributeOutput::StartAbstractNumbering( sal_uInt16 nId )
3057 : {
3058 : m_pSerializer->startElementNS( XML_w, XML_abstractNum,
3059 : FSNS( XML_w, XML_abstractNumId ), OString::valueOf( sal_Int32( nId ) ).getStr(),
3060 0 : FSEND );
3061 0 : }
3062 :
3063 0 : void DocxAttributeOutput::EndAbstractNumbering()
3064 : {
3065 0 : m_pSerializer->endElementNS( XML_w, XML_abstractNum );
3066 0 : }
3067 :
3068 0 : void DocxAttributeOutput::NumberingLevel( sal_uInt8 nLevel,
3069 : sal_uInt16 nStart,
3070 : sal_uInt16 nNumberingType,
3071 : SvxAdjust eAdjust,
3072 : const sal_uInt8 * /*pNumLvlPos*/,
3073 : sal_uInt8 nFollow,
3074 : const wwFont *pFont,
3075 : const SfxItemSet *pOutSet,
3076 : sal_Int16 nIndentAt,
3077 : sal_Int16 nFirstLineIndex,
3078 : sal_Int16 nListTabPos,
3079 : const String &rNumberingString )
3080 : {
3081 : m_pSerializer->startElementNS( XML_w, XML_lvl,
3082 : FSNS( XML_w, XML_ilvl ), OString::valueOf( sal_Int32( nLevel ) ).getStr(),
3083 0 : FSEND );
3084 :
3085 : // start with the nStart value
3086 : m_pSerializer->singleElementNS( XML_w, XML_start,
3087 : FSNS( XML_w, XML_val ), OString::valueOf( sal_Int32( nStart ) ).getStr(),
3088 0 : FSEND );
3089 :
3090 : // format
3091 0 : OString aFmt( impl_NumberingType( nNumberingType ) );
3092 :
3093 0 : if ( !aFmt.isEmpty() )
3094 : m_pSerializer->singleElementNS( XML_w, XML_numFmt,
3095 : FSNS( XML_w, XML_val ), aFmt.getStr(),
3096 0 : FSEND );
3097 :
3098 : // suffix
3099 0 : const char *pSuffix = NULL;
3100 0 : switch ( nFollow )
3101 : {
3102 0 : case 1: pSuffix = "space"; break;
3103 0 : case 2: pSuffix = "nothing"; break;
3104 0 : default: /*pSuffix = "tab";*/ break;
3105 : }
3106 0 : if ( pSuffix )
3107 : m_pSerializer->singleElementNS( XML_w, XML_suff,
3108 : FSNS( XML_w, XML_val ), pSuffix,
3109 0 : FSEND );
3110 :
3111 : // text
3112 0 : OUString aText( rNumberingString );
3113 0 : OUStringBuffer aBuffer( aText.getLength() + WW8ListManager::nMaxLevel );
3114 :
3115 0 : const sal_Unicode *pPrev = aText.getStr();
3116 0 : const sal_Unicode *pIt = aText.getStr();
3117 0 : while ( pIt < aText.getStr() + aText.getLength() )
3118 : {
3119 : // convert the level values to %NUMBER form
3120 : // (we don't use pNumLvlPos at all)
3121 : // FIXME so far we support the ww8 limit of levels only
3122 0 : if ( *pIt < sal_Unicode( WW8ListManager::nMaxLevel ) )
3123 : {
3124 0 : aBuffer.append( pPrev, pIt - pPrev );
3125 0 : aBuffer.append( '%' );
3126 0 : aBuffer.append( OUString::valueOf( sal_Int32( *pIt ) + 1 ) );
3127 :
3128 0 : pPrev = pIt + 1;
3129 : }
3130 0 : ++pIt;
3131 : }
3132 0 : if ( pPrev < pIt )
3133 0 : aBuffer.append( pPrev, pIt - pPrev );
3134 :
3135 : m_pSerializer->singleElementNS( XML_w, XML_lvlText,
3136 : FSNS( XML_w, XML_val ), OUStringToOString( aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ).getStr(),
3137 0 : FSEND );
3138 :
3139 : // justification
3140 : const char *pJc;
3141 0 : bool ecmaDialect = ( m_rExport.GetFilter().getVersion() == oox::core::ECMA_DIALECT );
3142 0 : switch ( eAdjust )
3143 : {
3144 0 : case SVX_ADJUST_CENTER: pJc = "center"; break;
3145 0 : case SVX_ADJUST_RIGHT: pJc = !ecmaDialect ? "end" : "right"; break;
3146 0 : default: pJc = !ecmaDialect ? "start" : "left"; break;
3147 : }
3148 : m_pSerializer->singleElementNS( XML_w, XML_lvlJc,
3149 : FSNS( XML_w, XML_val ), pJc,
3150 0 : FSEND );
3151 :
3152 : // indentation
3153 0 : m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND );
3154 0 : if( nListTabPos != 0 )
3155 : {
3156 0 : m_pSerializer->startElementNS( XML_w, XML_tabs, FSEND );
3157 : m_pSerializer->singleElementNS( XML_w, XML_tab,
3158 : FSNS( XML_w, XML_val ), "num",
3159 : FSNS( XML_w, XML_pos ), OString::valueOf( static_cast<sal_Int32>(nListTabPos) ).getStr(),
3160 0 : FSEND );
3161 0 : m_pSerializer->endElementNS( XML_w, XML_tabs );
3162 : }
3163 :
3164 0 : sal_Int32 nToken = ecmaDialect ? XML_left : XML_start;
3165 : m_pSerializer->singleElementNS( XML_w, XML_ind,
3166 : FSNS( XML_w, nToken ), OString::valueOf( sal_Int32( nIndentAt ) ).getStr(),
3167 : FSNS( XML_w, XML_hanging ), OString::valueOf( sal_Int32( -nFirstLineIndex ) ).getStr(),
3168 0 : FSEND );
3169 0 : m_pSerializer->endElementNS( XML_w, XML_pPr );
3170 :
3171 : // font
3172 0 : if ( pOutSet )
3173 : {
3174 0 : m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
3175 :
3176 0 : if ( pFont )
3177 : {
3178 0 : GetExport().GetId( *pFont ); // ensure font info is written to fontTable.xml
3179 0 : OString aFamilyName( OUStringToOString( OUString( pFont->GetFamilyName() ), RTL_TEXTENCODING_UTF8 ) );
3180 : m_pSerializer->singleElementNS( XML_w, XML_rFonts,
3181 : FSNS( XML_w, XML_ascii ), aFamilyName.getStr(),
3182 : FSNS( XML_w, XML_hAnsi ), aFamilyName.getStr(),
3183 : FSNS( XML_w, XML_cs ), aFamilyName.getStr(),
3184 : FSNS( XML_w, XML_hint ), "default",
3185 0 : FSEND );
3186 : }
3187 0 : m_rExport.OutputItemSet( *pOutSet, false, true, i18n::ScriptType::LATIN, m_rExport.mbExportModeRTF );
3188 :
3189 0 : m_pSerializer->endElementNS( XML_w, XML_rPr );
3190 : }
3191 :
3192 : // TODO anything to do about nListTabPos?
3193 :
3194 0 : m_pSerializer->endElementNS( XML_w, XML_lvl );
3195 0 : }
3196 :
3197 0 : void DocxAttributeOutput::CharCaseMap( const SvxCaseMapItem& rCaseMap )
3198 : {
3199 0 : switch ( rCaseMap.GetValue() )
3200 : {
3201 : case SVX_CASEMAP_KAPITAELCHEN:
3202 0 : m_pSerializer->singleElementNS( XML_w, XML_smallCaps, FSEND );
3203 0 : break;
3204 : case SVX_CASEMAP_VERSALIEN:
3205 0 : m_pSerializer->singleElementNS( XML_w, XML_caps, FSEND );
3206 0 : break;
3207 : default: // Something that ooxml does not support
3208 0 : m_pSerializer->singleElementNS( XML_w, XML_smallCaps, FSNS( XML_w, XML_val ), "false", FSEND );
3209 0 : m_pSerializer->singleElementNS( XML_w, XML_caps, FSNS( XML_w, XML_val ), "false", FSEND );
3210 0 : break;
3211 : }
3212 0 : }
3213 :
3214 27 : void DocxAttributeOutput::CharColor( const SvxColorItem& rColor )
3215 : {
3216 27 : const Color aColor( rColor.GetValue() );
3217 27 : OString aColorString;
3218 :
3219 27 : aColorString = impl_ConvertColor( aColor );
3220 :
3221 : m_pSerializer->singleElementNS( XML_w, XML_color,
3222 27 : FSNS( XML_w, XML_val ), aColorString.getStr(), FSEND );
3223 27 : }
3224 :
3225 0 : void DocxAttributeOutput::CharContour( const SvxContourItem& rContour )
3226 : {
3227 0 : if ( rContour.GetValue() )
3228 0 : m_pSerializer->singleElementNS( XML_w, XML_outline, FSEND );
3229 : else
3230 0 : m_pSerializer->singleElementNS( XML_w, XML_outline, FSNS( XML_w, XML_val ), "false", FSEND );
3231 0 : }
3232 :
3233 0 : void DocxAttributeOutput::CharCrossedOut( const SvxCrossedOutItem& rCrossedOut )
3234 : {
3235 0 : switch ( rCrossedOut.GetStrikeout() )
3236 : {
3237 : case STRIKEOUT_DOUBLE:
3238 0 : m_pSerializer->singleElementNS( XML_w, XML_dstrike, FSEND );
3239 0 : break;
3240 : case STRIKEOUT_NONE:
3241 0 : m_pSerializer->singleElementNS( XML_w, XML_dstrike, FSNS( XML_w, XML_val ), "false", FSEND );
3242 0 : m_pSerializer->singleElementNS( XML_w, XML_strike, FSNS( XML_w, XML_val ), "false", FSEND );
3243 0 : break;
3244 : default:
3245 0 : m_pSerializer->singleElementNS( XML_w, XML_strike, FSEND );
3246 0 : break;
3247 : }
3248 0 : }
3249 :
3250 0 : void DocxAttributeOutput::CharEscapement( const SvxEscapementItem& rEscapement )
3251 : {
3252 0 : OString sIss;
3253 0 : short nEsc = rEscapement.GetEsc(), nProp = rEscapement.GetProp();
3254 0 : if ( !nEsc )
3255 : {
3256 0 : sIss = OString( "baseline" );
3257 0 : nEsc = 0;
3258 0 : nProp = 100;
3259 : }
3260 0 : else if ( DFLT_ESC_PROP == nProp )
3261 : {
3262 0 : if ( DFLT_ESC_SUB == nEsc || DFLT_ESC_AUTO_SUB == nEsc )
3263 0 : sIss = OString( "subscript" );
3264 0 : else if ( DFLT_ESC_SUPER == nEsc || DFLT_ESC_AUTO_SUPER == nEsc )
3265 0 : sIss = OString( "superscript" );
3266 : }
3267 :
3268 0 : if ( !sIss.isEmpty() )
3269 : m_pSerializer->singleElementNS( XML_w, XML_vertAlign,
3270 0 : FSNS( XML_w, XML_val ), sIss.getStr(), FSEND );
3271 :
3272 0 : if ( sIss.isEmpty() || sIss.match( OString( "baseline" ) ) )
3273 : {
3274 : long nHeight = ((SvxFontHeightItem&)m_rExport.GetItem(
3275 0 : RES_CHRATR_FONTSIZE )).GetHeight();
3276 0 : OString sPos = OString::valueOf( ( nHeight * nEsc + 500 ) / 1000 );
3277 : m_pSerializer->singleElementNS( XML_w, XML_position,
3278 0 : FSNS( XML_w, XML_val ), sPos.getStr( ), FSEND );
3279 :
3280 0 : if( 100 != nProp || sIss.match( OString( "baseline" ) ) )
3281 : {
3282 0 : OString sSize = OString::valueOf( ( nHeight * nProp + 500 ) / 1000 );
3283 : m_pSerializer->singleElementNS( XML_w, XML_sz,
3284 0 : FSNS( XML_w, XML_val ), sSize.getStr( ), FSEND );
3285 0 : }
3286 0 : }
3287 0 : }
3288 :
3289 117 : void DocxAttributeOutput::CharFont( const SvxFontItem& rFont)
3290 : {
3291 117 : if (!m_pFontsAttrList)
3292 117 : m_pFontsAttrList = m_pSerializer->createAttrList();
3293 117 : GetExport().GetId( rFont ); // ensure font info is written to fontTable.xml
3294 117 : OUString sFontName(rFont.GetFamilyName());
3295 117 : OString sFontNameUtf8 = OUStringToOString(sFontName, RTL_TEXTENCODING_UTF8);
3296 117 : m_pFontsAttrList->add(FSNS(XML_w, XML_ascii), sFontNameUtf8);
3297 117 : m_pFontsAttrList->add(FSNS(XML_w, XML_hAnsi), sFontNameUtf8);
3298 117 : }
3299 :
3300 162 : void DocxAttributeOutput::CharFontSize( const SvxFontHeightItem& rFontSize)
3301 : {
3302 162 : OString fontSize = OString::valueOf( sal_Int32( ( rFontSize.GetHeight() + 5 ) / 10 ) );
3303 :
3304 162 : switch ( rFontSize.Which() )
3305 : {
3306 : case RES_CHRATR_FONTSIZE:
3307 : case RES_CHRATR_CJK_FONTSIZE:
3308 81 : m_pSerializer->singleElementNS( XML_w, XML_sz, FSNS( XML_w, XML_val ), fontSize.getStr(), FSEND );
3309 81 : break;
3310 : case RES_CHRATR_CTL_FONTSIZE:
3311 81 : m_pSerializer->singleElementNS( XML_w, XML_szCs, FSNS( XML_w, XML_val ), fontSize.getStr(), FSEND );
3312 81 : break;
3313 162 : }
3314 162 : }
3315 :
3316 0 : void DocxAttributeOutput::CharKerning( const SvxKerningItem& rKerning )
3317 : {
3318 0 : OString aKerning = OString::valueOf( ( sal_Int32 ) rKerning.GetValue() );
3319 0 : m_pSerializer->singleElementNS( XML_w, XML_spacing, FSNS(XML_w, XML_val), aKerning.getStr(), FSEND );
3320 0 : }
3321 :
3322 111 : void DocxAttributeOutput::CharLanguage( const SvxLanguageItem& rLanguage )
3323 : {
3324 111 : if (!m_pCharLangAttrList)
3325 57 : m_pCharLangAttrList = m_pSerializer->createAttrList();
3326 :
3327 111 : ::com::sun::star::lang::Locale xLocale= LanguageTag( rLanguage.GetLanguage( ) ).getLocale();
3328 111 : OString sLanguage = OUStringToOString(xLocale.Language, RTL_TEXTENCODING_UTF8);
3329 111 : OString sCountry = OUStringToOString(xLocale.Country, RTL_TEXTENCODING_UTF8);
3330 :
3331 111 : OString aLanguageCode = sLanguage + "-" + sCountry;
3332 :
3333 111 : switch ( rLanguage.Which() )
3334 : {
3335 : case RES_CHRATR_LANGUAGE:
3336 57 : m_pCharLangAttrList->add(FSNS(XML_w, XML_val), aLanguageCode);
3337 57 : break;
3338 : case RES_CHRATR_CJK_LANGUAGE:
3339 27 : m_pCharLangAttrList->add(FSNS(XML_w, XML_eastAsia), aLanguageCode);
3340 27 : break;
3341 : case RES_CHRATR_CTL_LANGUAGE:
3342 27 : m_pCharLangAttrList->add(FSNS(XML_w, XML_bidi), aLanguageCode);
3343 27 : break;
3344 111 : }
3345 111 : }
3346 :
3347 24 : void DocxAttributeOutput::CharPosture( const SvxPostureItem& rPosture )
3348 : {
3349 24 : if ( rPosture.GetPosture() != ITALIC_NONE )
3350 24 : m_pSerializer->singleElementNS( XML_w, XML_i, FSEND );
3351 : else
3352 0 : m_pSerializer->singleElementNS( XML_w, XML_i, FSNS( XML_w, XML_val ), "false", FSEND );
3353 24 : }
3354 :
3355 0 : void DocxAttributeOutput::CharShadow( const SvxShadowedItem& rShadow )
3356 : {
3357 0 : if ( rShadow.GetValue() )
3358 0 : m_pSerializer->singleElementNS( XML_w, XML_shadow, FSEND );
3359 : else
3360 0 : m_pSerializer->singleElementNS( XML_w, XML_shadow, FSNS( XML_w, XML_val ), "false", FSEND );
3361 0 : }
3362 :
3363 3 : void DocxAttributeOutput::CharUnderline( const SvxUnderlineItem& rUnderline )
3364 : {
3365 : const char *pUnderline;
3366 :
3367 3 : switch ( rUnderline.GetLineStyle() )
3368 : {
3369 3 : case UNDERLINE_SINGLE: pUnderline = "single"; break;
3370 0 : case UNDERLINE_BOLD: pUnderline = "thick"; break;
3371 0 : case UNDERLINE_DOUBLE: pUnderline = "double"; break;
3372 0 : case UNDERLINE_DOTTED: pUnderline = "dotted"; break;
3373 0 : case UNDERLINE_DASH: pUnderline = "dash"; break;
3374 0 : case UNDERLINE_DASHDOT: pUnderline = "dotDash"; break;
3375 0 : case UNDERLINE_DASHDOTDOT: pUnderline = "dotDotDash"; break;
3376 0 : case UNDERLINE_WAVE: pUnderline = "wave"; break;
3377 0 : case UNDERLINE_BOLDDOTTED: pUnderline = "dottedHeavy"; break;
3378 0 : case UNDERLINE_BOLDDASH: pUnderline = "dashedHeavy"; break;
3379 0 : case UNDERLINE_LONGDASH: pUnderline = "dashLongHeavy"; break;
3380 0 : case UNDERLINE_BOLDLONGDASH: pUnderline = "dashLongHeavy"; break;
3381 0 : case UNDERLINE_BOLDDASHDOT: pUnderline = "dashDotHeavy"; break;
3382 0 : case UNDERLINE_BOLDDASHDOTDOT: pUnderline = "dashDotDotHeavy"; break;
3383 0 : case UNDERLINE_BOLDWAVE: pUnderline = "wavyHeavy"; break;
3384 0 : case UNDERLINE_DOUBLEWAVE: pUnderline = "wavyDouble"; break;
3385 : case UNDERLINE_NONE: // fall through
3386 0 : default: pUnderline = "none"; break;
3387 : }
3388 :
3389 3 : m_pSerializer->singleElementNS( XML_w, XML_u, FSNS( XML_w, XML_val ), pUnderline, FSEND );
3390 3 : }
3391 :
3392 2 : void DocxAttributeOutput::CharWeight( const SvxWeightItem& rWeight )
3393 : {
3394 2 : if ( rWeight.GetWeight() == WEIGHT_BOLD )
3395 2 : m_pSerializer->singleElementNS( XML_w, XML_b, FSEND );
3396 : else
3397 0 : m_pSerializer->singleElementNS( XML_w, XML_b, FSNS( XML_w, XML_val ), "false", FSEND );
3398 2 : }
3399 :
3400 24 : void DocxAttributeOutput::CharAutoKern( const SvxAutoKernItem& )
3401 : {
3402 : OSL_TRACE( "TODO DocxAttributeOutput::CharAutoKern()" );
3403 24 : }
3404 :
3405 0 : void DocxAttributeOutput::CharAnimatedText( const SvxBlinkItem& rBlink )
3406 : {
3407 0 : if ( rBlink.GetValue() )
3408 0 : m_pSerializer->singleElementNS(XML_w, XML_effect, FSNS( XML_w, XML_val ), "blinkBackground", FSEND );
3409 : else
3410 0 : m_pSerializer->singleElementNS(XML_w, XML_effect, FSNS( XML_w, XML_val ), "none", FSEND );
3411 0 : }
3412 :
3413 0 : void DocxAttributeOutput::CharBackground( const SvxBrushItem& rBrush )
3414 : {
3415 : m_pSerializer->singleElementNS( XML_w, XML_shd,
3416 0 : FSNS( XML_w, XML_fill ), impl_ConvertColor( rBrush.GetColor() ).getStr(),
3417 : FSNS( XML_w, XML_val ), "clear",
3418 0 : FSEND );
3419 0 : }
3420 :
3421 111 : void DocxAttributeOutput::CharFontCJK( const SvxFontItem& rFont )
3422 : {
3423 111 : if (!m_pFontsAttrList)
3424 0 : m_pFontsAttrList = m_pSerializer->createAttrList();
3425 111 : OUString sFontName(rFont.GetFamilyName());
3426 111 : OString sFontNameUtf8 = OUStringToOString(sFontName, RTL_TEXTENCODING_UTF8);
3427 111 : m_pFontsAttrList->add(FSNS(XML_w, XML_eastAsia), sFontNameUtf8);
3428 111 : }
3429 :
3430 0 : void DocxAttributeOutput::CharPostureCJK( const SvxPostureItem& rPosture )
3431 : {
3432 0 : if ( rPosture.GetPosture() != ITALIC_NONE )
3433 0 : m_pSerializer->singleElementNS( XML_w, XML_i, FSEND );
3434 : else
3435 0 : m_pSerializer->singleElementNS( XML_w, XML_i, FSNS( XML_w, XML_val ), "false", FSEND );
3436 0 : }
3437 :
3438 0 : void DocxAttributeOutput::CharWeightCJK( const SvxWeightItem& rWeight )
3439 : {
3440 0 : if ( rWeight.GetWeight() == WEIGHT_BOLD )
3441 0 : m_pSerializer->singleElementNS( XML_w, XML_b, FSEND );
3442 : else
3443 0 : m_pSerializer->singleElementNS( XML_w, XML_b, FSNS( XML_w, XML_val ), "false", FSEND );
3444 0 : }
3445 :
3446 121 : void DocxAttributeOutput::CharFontCTL( const SvxFontItem& rFont )
3447 : {
3448 121 : if (!m_pFontsAttrList)
3449 6 : m_pFontsAttrList = m_pSerializer->createAttrList();
3450 121 : OUString sFontName(rFont.GetFamilyName());
3451 121 : OString sFontNameUtf8 = OUStringToOString(sFontName, RTL_TEXTENCODING_UTF8);
3452 121 : m_pFontsAttrList->add(FSNS(XML_w, XML_cs), sFontNameUtf8);
3453 :
3454 121 : }
3455 :
3456 24 : void DocxAttributeOutput::CharPostureCTL( const SvxPostureItem& rPosture)
3457 : {
3458 24 : if ( rPosture.GetPosture() != ITALIC_NONE )
3459 24 : m_pSerializer->singleElementNS( XML_w, XML_iCs, FSEND );
3460 : else
3461 0 : m_pSerializer->singleElementNS( XML_w, XML_iCs, FSNS( XML_w, XML_val ), "false", FSEND );
3462 24 : }
3463 :
3464 2 : void DocxAttributeOutput::CharWeightCTL( const SvxWeightItem& rWeight )
3465 : {
3466 2 : if ( rWeight.GetWeight() == WEIGHT_BOLD )
3467 2 : m_pSerializer->singleElementNS( XML_w, XML_bCs, FSEND );
3468 : else
3469 0 : m_pSerializer->singleElementNS( XML_w, XML_bCs, FSNS( XML_w, XML_val ), "false", FSEND );
3470 2 : }
3471 :
3472 0 : void DocxAttributeOutput::CharRotate( const SvxCharRotateItem& rRotate)
3473 : {
3474 0 : if ( !rRotate.GetValue() )
3475 0 : return;
3476 :
3477 0 : if (!m_pEastAsianLayoutAttrList)
3478 0 : m_pEastAsianLayoutAttrList = m_pSerializer->createAttrList();
3479 0 : OString sTrue((sal_Char *)"true");
3480 0 : m_pEastAsianLayoutAttrList->add(FSNS(XML_w, XML_vert), sTrue);
3481 :
3482 0 : if (rRotate.IsFitToLine())
3483 0 : m_pEastAsianLayoutAttrList->add(FSNS(XML_w, XML_vertCompress), sTrue);
3484 : }
3485 :
3486 0 : void DocxAttributeOutput::CharEmphasisMark( const SvxEmphasisMarkItem& rEmphasisMark )
3487 : {
3488 : const char *pEmphasis;
3489 :
3490 0 : switch ( rEmphasisMark.GetValue() )
3491 : {
3492 0 : case EMPHASISMARK_NONE: pEmphasis = "none"; break;
3493 0 : case EMPHASISMARK_SIDE_DOTS: pEmphasis = "dot"; break;
3494 0 : case EMPHASISMARK_CIRCLE_ABOVE: pEmphasis = "circle"; break;
3495 0 : case EMPHASISMARK_DOTS_BELOW: pEmphasis = "underDot"; break;
3496 0 : default: pEmphasis = "comma"; break;
3497 : }
3498 :
3499 0 : m_pSerializer->singleElementNS( XML_w, XML_em, FSNS( XML_w, XML_val ), pEmphasis, FSEND );
3500 0 : }
3501 :
3502 0 : void DocxAttributeOutput::CharTwoLines( const SvxTwoLinesItem& rTwoLines )
3503 : {
3504 0 : if ( !rTwoLines.GetValue() )
3505 : return;
3506 :
3507 0 : if (!m_pEastAsianLayoutAttrList)
3508 0 : m_pEastAsianLayoutAttrList = m_pSerializer->createAttrList();
3509 0 : OString sTrue((sal_Char *)"true");
3510 0 : m_pEastAsianLayoutAttrList->add(FSNS(XML_w, XML_combine), sTrue);
3511 :
3512 0 : sal_Unicode cStart = rTwoLines.GetStartBracket();
3513 0 : sal_Unicode cEnd = rTwoLines.GetEndBracket();
3514 :
3515 0 : if (!cStart && !cEnd)
3516 : return;
3517 :
3518 0 : OString sBracket;
3519 0 : if ((cStart == '{') || (cEnd == '}'))
3520 0 : sBracket = (sal_Char *)"curly";
3521 0 : else if ((cStart == '<') || (cEnd == '>'))
3522 0 : sBracket = (sal_Char *)"angle";
3523 0 : else if ((cStart == '[') || (cEnd == ']'))
3524 0 : sBracket = (sal_Char *)"square";
3525 : else
3526 0 : sBracket = (sal_Char *)"round";
3527 0 : m_pEastAsianLayoutAttrList->add(FSNS(XML_w, XML_combineBrackets), sBracket);
3528 : }
3529 :
3530 0 : void DocxAttributeOutput::CharScaleWidth( const SvxCharScaleWidthItem& rScaleWidth )
3531 : {
3532 : m_pSerializer->singleElementNS( XML_w, XML_w,
3533 0 : FSNS( XML_w, XML_val ), rtl::OString::valueOf( sal_Int32( rScaleWidth.GetValue() ) ).getStr(), FSEND );
3534 0 : }
3535 :
3536 0 : void DocxAttributeOutput::CharRelief( const SvxCharReliefItem& rRelief )
3537 : {
3538 0 : switch ( rRelief.GetValue() )
3539 : {
3540 : case RELIEF_EMBOSSED:
3541 0 : m_pSerializer->singleElementNS( XML_w, XML_emboss, FSEND );
3542 0 : break;
3543 : case RELIEF_ENGRAVED:
3544 0 : m_pSerializer->singleElementNS( XML_w, XML_imprint, FSEND );
3545 0 : break;
3546 : default:
3547 0 : m_pSerializer->singleElementNS( XML_w, XML_emboss, FSNS( XML_w, XML_val ), "false", FSEND );
3548 0 : m_pSerializer->singleElementNS( XML_w, XML_imprint, FSNS( XML_w, XML_val ), "false", FSEND );
3549 0 : break;
3550 : }
3551 0 : }
3552 :
3553 0 : void DocxAttributeOutput::CharHidden( const SvxCharHiddenItem& rHidden )
3554 : {
3555 0 : if ( rHidden.GetValue() )
3556 0 : m_pSerializer->singleElementNS( XML_w, XML_vanish, FSEND );
3557 : else
3558 0 : m_pSerializer->singleElementNS( XML_w, XML_vanish, FSNS( XML_w, XML_val ), "false", FSEND );
3559 0 : }
3560 :
3561 3 : void DocxAttributeOutput::TextINetFormat( const SwFmtINetFmt& rLink )
3562 : {
3563 3 : const SwTxtINetFmt* pINetFmt = rLink.GetTxtINetFmt();
3564 3 : const SwCharFmt* pCharFmt = pINetFmt->GetCharFmt();
3565 :
3566 3 : OString aStyleId( "style" );
3567 3 : aStyleId += OString::valueOf( sal_Int32( m_rExport.GetId( *pCharFmt ) ) );
3568 :
3569 3 : m_pSerializer->singleElementNS( XML_w, XML_rStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND );
3570 3 : }
3571 :
3572 1 : void DocxAttributeOutput::TextCharFormat( const SwFmtCharFmt& rCharFmt )
3573 : {
3574 1 : OString aStyleId( "style" );
3575 1 : aStyleId += OString::valueOf( sal_Int32( m_rExport.GetId( *rCharFmt.GetCharFmt() ) ) );
3576 :
3577 1 : m_pSerializer->singleElementNS( XML_w, XML_rStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND );
3578 1 : }
3579 :
3580 0 : void DocxAttributeOutput::RefField( const SwField& rFld, const String& rRef )
3581 : {
3582 0 : sal_uInt16 nType = rFld.GetTyp( )->Which( );
3583 0 : if ( nType == RES_GETEXPFLD )
3584 : {
3585 0 : String sCmd = FieldString( ww::eREF );
3586 0 : sCmd.AppendAscii( "\"" );
3587 0 : sCmd += rRef;
3588 0 : sCmd.AppendAscii( "\" " );
3589 :
3590 0 : m_rExport.OutputField( &rFld, ww::eREF, sCmd );
3591 : }
3592 :
3593 : // There is nothing to do here for the set fields
3594 0 : }
3595 :
3596 0 : void DocxAttributeOutput::HiddenField( const SwField& /*rFld*/ )
3597 : {
3598 : OSL_TRACE( "TODO DocxAttributeOutput::HiddenField()" );
3599 0 : }
3600 :
3601 1 : void DocxAttributeOutput::PostitField( const SwField* pFld )
3602 : {
3603 : assert( dynamic_cast< const SwPostItField* >( pFld ));
3604 1 : m_postitFields.push_back( static_cast< const SwPostItField* >( pFld ));
3605 1 : }
3606 :
3607 109 : void DocxAttributeOutput::WritePostitFieldReference()
3608 : {
3609 219 : while( m_postitFieldsMaxId < m_postitFields.size())
3610 : {
3611 1 : OString idstr = OString::valueOf( sal_Int32( m_postitFieldsMaxId ));
3612 1 : m_pSerializer->singleElementNS( XML_w, XML_commentReference, FSNS( XML_w, XML_id ), idstr.getStr(), FSEND );
3613 1 : ++m_postitFieldsMaxId;
3614 1 : }
3615 109 : }
3616 :
3617 1 : void DocxAttributeOutput::WritePostitFieldStart()
3618 : {
3619 1 : m_bPostitStart = true;
3620 1 : }
3621 :
3622 1 : void DocxAttributeOutput::WritePostitFieldEnd()
3623 : {
3624 1 : m_bPostitEnd = true;
3625 1 : }
3626 :
3627 1 : void DocxAttributeOutput::WritePostitFields()
3628 : {
3629 4 : for( unsigned int i = 0;
3630 2 : i < m_postitFields.size();
3631 : ++i )
3632 : {
3633 1 : OString idstr = OString::valueOf( sal_Int32( i ));
3634 1 : const SwPostItField* f = m_postitFields[ i ];
3635 : m_pSerializer->startElementNS( XML_w, XML_comment, FSNS( XML_w, XML_id ), idstr.getStr(),
3636 1 : FSNS( XML_w, XML_author ), rtl::OUStringToOString( f->GetPar1(), RTL_TEXTENCODING_UTF8 ).getStr(),
3637 : FSNS( XML_w, XML_date ), msfilter::util::DateTimeToOString(f->GetDateTime()).getStr(),
3638 2 : FSNS( XML_w, XML_initials ), rtl::OUStringToOString( f->GetInitials(), RTL_TEXTENCODING_UTF8 ).getStr(), FSEND );
3639 : // Check for the text object existing, it seems that it can be NULL when saving a newly created
3640 : // comment without giving focus back to the main document. As GetTxt() is empty in that case as well,
3641 : // that is probably a bug in the Writer core.
3642 1 : if( f->GetTextObject() != NULL )
3643 1 : GetExport().WriteOutliner( *f->GetTextObject(), TXT_ATN );
3644 1 : m_pSerializer->endElementNS( XML_w, XML_comment );
3645 1 : }
3646 1 : }
3647 :
3648 0 : bool DocxAttributeOutput::DropdownField( const SwField* pFld )
3649 : {
3650 0 : bool bExpand = false;
3651 :
3652 0 : ww::eField eType = ww::eFORMDROPDOWN;
3653 0 : String sCmd = FieldString( eType );
3654 0 : GetExport( ).OutputField( pFld, eType, sCmd );
3655 :
3656 0 : return bExpand;
3657 : }
3658 :
3659 0 : void DocxAttributeOutput::SetField( const SwField& rFld, ww::eField eType, const String& rCmd )
3660 : {
3661 : // field bookmarks are handled in the EndRun method
3662 0 : GetExport().OutputField(&rFld, eType, rCmd );
3663 0 : }
3664 :
3665 0 : void DocxAttributeOutput::WriteExpand( const SwField* pFld )
3666 : {
3667 : // Will be written in the next End Run
3668 0 : String sCmd;
3669 0 : m_rExport.OutputField( pFld, ww::eUNKNOWN, sCmd );
3670 0 : }
3671 :
3672 2 : void DocxAttributeOutput::WriteField_Impl( const SwField* pFld, ww::eField eType, const String& rFldCmd, sal_uInt8 nMode )
3673 : {
3674 2 : struct FieldInfos infos;
3675 2 : infos.pField = pFld;
3676 2 : infos.sCmd = rFldCmd;
3677 2 : infos.eType = eType;
3678 2 : infos.bClose = WRITEFIELD_CLOSE & nMode;
3679 2 : infos.bOpen = WRITEFIELD_START & nMode;
3680 2 : m_Fields.push_back( infos );
3681 :
3682 2 : if ( pFld )
3683 : {
3684 0 : sal_uInt16 nType = pFld->GetTyp( )->Which( );
3685 0 : sal_uInt16 nSubType = pFld->GetSubType();
3686 :
3687 : // TODO Any other field types here ?
3688 0 : if ( ( nType == RES_SETEXPFLD ) && ( nSubType & nsSwGetSetExpType::GSE_STRING ) )
3689 : {
3690 0 : const SwSetExpField *pSet = ( const SwSetExpField* )( pFld );
3691 0 : m_sFieldBkm = pSet->GetPar1( );
3692 : }
3693 0 : else if ( nType == RES_DROPDOWN )
3694 : {
3695 0 : const SwDropDownField* pDropDown = ( const SwDropDownField* )( pFld );
3696 0 : m_sFieldBkm = pDropDown->GetName( );
3697 : }
3698 2 : }
3699 2 : }
3700 :
3701 0 : void DocxAttributeOutput::WriteFormData_Impl( const ::sw::mark::IFieldmark& rFieldmark )
3702 : {
3703 0 : if ( !m_Fields.empty() )
3704 0 : m_Fields.begin()->pFieldmark = &rFieldmark;
3705 0 : }
3706 :
3707 194 : void DocxAttributeOutput::WriteBookmarks_Impl( std::vector< OUString >& rStarts,
3708 : std::vector< OUString >& rEnds )
3709 : {
3710 197 : for ( std::vector< OUString >::const_iterator it = rStarts.begin(), end = rStarts.end(); it != end; ++it )
3711 : {
3712 3 : OString rName = OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr( );
3713 3 : m_rMarksStart.push_back( rName );
3714 3 : }
3715 194 : rStarts.clear();
3716 :
3717 197 : for ( std::vector< OUString >::const_iterator it = rEnds.begin(), end = rEnds.end(); it != end; ++it )
3718 : {
3719 3 : OString rName = OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr( );
3720 3 : m_rMarksEnd.push_back( rName );
3721 3 : }
3722 194 : rEnds.clear();
3723 194 : }
3724 :
3725 0 : void DocxAttributeOutput::TextFootnote_Impl( const SwFmtFtn& rFootnote )
3726 : {
3727 0 : const SwEndNoteInfo& rInfo = rFootnote.IsEndNote()?
3728 0 : m_rExport.pDoc->GetEndNoteInfo(): m_rExport.pDoc->GetFtnInfo();
3729 :
3730 : // footnote/endnote run properties
3731 0 : const SwCharFmt* pCharFmt = rInfo.GetAnchorCharFmt( *m_rExport.pDoc );
3732 :
3733 0 : OString aStyleId( "style" );
3734 0 : aStyleId += OString::valueOf( sal_Int32( m_rExport.GetId( *pCharFmt ) ) );
3735 :
3736 0 : m_pSerializer->singleElementNS( XML_w, XML_rStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND );
3737 :
3738 : // remember the footnote/endnote to
3739 : // 1) write the footnoteReference/endnoteReference in EndRunProperties()
3740 : // 2) be able to dump them all to footnotes.xml/endnotes.xml
3741 0 : if ( !rFootnote.IsEndNote() )
3742 0 : m_pFootnotesList->add( rFootnote );
3743 : else
3744 0 : m_pEndnotesList->add( rFootnote );
3745 0 : }
3746 :
3747 110 : void DocxAttributeOutput::FootnoteEndnoteReference()
3748 : {
3749 : sal_Int32 nId;
3750 110 : const SwFmtFtn *pFootnote = m_pFootnotesList->getCurrent( nId );
3751 :
3752 : // both cannot be set at the same time - if they are, it's a bug
3753 110 : if ( !pFootnote )
3754 110 : pFootnote = m_pEndnotesList->getCurrent( nId );
3755 :
3756 110 : if ( !pFootnote )
3757 110 : return;
3758 :
3759 0 : sal_Int32 nToken = pFootnote->IsEndNote()? XML_endnoteReference: XML_footnoteReference;
3760 :
3761 : // write it
3762 0 : if ( pFootnote->GetNumStr().Len() == 0 )
3763 : {
3764 : // autonumbered
3765 : m_pSerializer->singleElementNS( XML_w, nToken,
3766 : FSNS( XML_w, XML_id ), ::rtl::OString::valueOf( nId ).getStr(),
3767 0 : FSEND );
3768 : }
3769 : else
3770 : {
3771 : // not autonumbered
3772 : m_pSerializer->singleElementNS( XML_w, nToken,
3773 : FSNS( XML_w, XML_customMarkFollows ), "1",
3774 : FSNS( XML_w, XML_id ), ::rtl::OString::valueOf( nId ).getStr(),
3775 0 : FSEND );
3776 :
3777 0 : RunText( pFootnote->GetNumStr() );
3778 : }
3779 : }
3780 :
3781 0 : void DocxAttributeOutput::FootnotesEndnotes( bool bFootnotes )
3782 : {
3783 0 : const FootnotesVector& rVector = bFootnotes? m_pFootnotesList->getVector(): m_pEndnotesList->getVector();
3784 :
3785 0 : sal_Int32 nBody = bFootnotes? XML_footnotes: XML_endnotes;
3786 0 : sal_Int32 nItem = bFootnotes? XML_footnote: XML_endnote;
3787 :
3788 : m_pSerializer->startElementNS( XML_w, nBody,
3789 : FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
3790 : FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
3791 0 : FSEND );
3792 :
3793 0 : sal_Int32 nIndex = 0;
3794 :
3795 : // separator
3796 : m_pSerializer->startElementNS( XML_w, nItem,
3797 : FSNS( XML_w, XML_id ), OString::valueOf( nIndex++ ).getStr(),
3798 : FSNS( XML_w, XML_type ), "separator",
3799 0 : FSEND );
3800 0 : m_pSerializer->startElementNS( XML_w, XML_p, FSEND );
3801 0 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
3802 0 : m_pSerializer->singleElementNS( XML_w, XML_separator, FSEND );
3803 0 : m_pSerializer->endElementNS( XML_w, XML_r );
3804 0 : m_pSerializer->endElementNS( XML_w, XML_p );
3805 0 : m_pSerializer->endElementNS( XML_w, nItem );
3806 :
3807 : // separator
3808 : m_pSerializer->startElementNS( XML_w, nItem,
3809 : FSNS( XML_w, XML_id ), OString::valueOf( nIndex++ ).getStr(),
3810 : FSNS( XML_w, XML_type ), "continuationSeparator",
3811 0 : FSEND );
3812 0 : m_pSerializer->startElementNS( XML_w, XML_p, FSEND );
3813 0 : m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
3814 0 : m_pSerializer->singleElementNS( XML_w, XML_continuationSeparator, FSEND );
3815 0 : m_pSerializer->endElementNS( XML_w, XML_r );
3816 0 : m_pSerializer->endElementNS( XML_w, XML_p );
3817 0 : m_pSerializer->endElementNS( XML_w, nItem );
3818 :
3819 : // if new special ones are added, update also WriteFootnoteEndnotePr()
3820 :
3821 : // footnotes/endnotes themselves
3822 0 : for ( FootnotesVector::const_iterator i = rVector.begin(); i != rVector.end(); ++i, ++nIndex )
3823 : {
3824 : m_pSerializer->startElementNS( XML_w, nItem,
3825 : FSNS( XML_w, XML_id ), OString::valueOf( nIndex ).getStr(),
3826 0 : FSEND );
3827 :
3828 0 : const SwNodeIndex* pIndex = (*i)->GetTxtFtn()->GetStartNode();
3829 : // tag required at the start of each footnote/endnote
3830 0 : m_footnoteEndnoteRefTag = bFootnotes ? XML_footnoteRef : XML_endnoteRef;
3831 :
3832 0 : m_rExport.WriteSpecialText( pIndex->GetIndex() + 1,
3833 0 : pIndex->GetNode().EndOfSectionIndex(),
3834 0 : bFootnotes? TXT_FTN: TXT_EDN );
3835 :
3836 0 : m_pSerializer->endElementNS( XML_w, nItem );
3837 : }
3838 :
3839 0 : m_pSerializer->endElementNS( XML_w, nBody );
3840 :
3841 0 : }
3842 :
3843 0 : void DocxAttributeOutput::WriteFootnoteEndnotePr( ::sax_fastparser::FSHelperPtr fs, int tag,
3844 : const SwEndNoteInfo& info, int listtag )
3845 : {
3846 0 : fs->startElementNS( XML_w, tag, FSEND );
3847 0 : const char* fmt = NULL;
3848 0 : switch( info.aFmt.GetNumberingType())
3849 : {
3850 : case SVX_NUM_CHARS_UPPER_LETTER_N: // fall through, map to upper letters
3851 : case SVX_NUM_CHARS_UPPER_LETTER:
3852 0 : fmt = "upperLetter";
3853 0 : break;
3854 : case SVX_NUM_CHARS_LOWER_LETTER_N: // fall through, map to lower letters
3855 : case SVX_NUM_CHARS_LOWER_LETTER:
3856 0 : fmt = "lowerLetter";
3857 0 : break;
3858 : case SVX_NUM_ROMAN_UPPER:
3859 0 : fmt = "upperRoman";
3860 0 : break;
3861 : case SVX_NUM_ROMAN_LOWER:
3862 0 : fmt = "lowerRoman";
3863 0 : break;
3864 : case SVX_NUM_ARABIC:
3865 0 : fmt = "decimal";
3866 0 : break;
3867 : case SVX_NUM_NUMBER_NONE:
3868 0 : fmt = "none";
3869 0 : break;
3870 : case SVX_NUM_CHAR_SPECIAL:
3871 0 : fmt = "bullet";
3872 0 : break;
3873 : case SVX_NUM_PAGEDESC:
3874 : case SVX_NUM_BITMAP:
3875 : default:
3876 0 : break; // no format
3877 : }
3878 0 : if( fmt != NULL )
3879 0 : fs->singleElementNS( XML_w, XML_numFmt, FSNS( XML_w, XML_val ), fmt, FSEND );
3880 0 : if( info.nFtnOffset != 0 )
3881 : fs->singleElementNS( XML_w, XML_numStart, FSNS( XML_w, XML_val ),
3882 0 : rtl::OString::valueOf( sal_Int32( info.nFtnOffset + 1 )).getStr(), FSEND );
3883 0 : if( listtag != 0 ) // we are writting to settings.xml, write also special footnote/endnote list
3884 : { // there are currently only two hardcoded ones ( see FootnotesEndnotes())
3885 0 : fs->singleElementNS( XML_w, listtag, FSNS( XML_w, XML_id ), "0", FSEND );
3886 0 : fs->singleElementNS( XML_w, listtag, FSNS( XML_w, XML_id ), "1", FSEND );
3887 : }
3888 0 : fs->endElementNS( XML_w, tag );
3889 0 : }
3890 :
3891 24 : void DocxAttributeOutput::SectFootnoteEndnotePr()
3892 : {
3893 24 : if( HasFootnotes())
3894 0 : WriteFootnoteEndnotePr( m_pSerializer, XML_footnotePr, m_rExport.pDoc->GetFtnInfo(), 0 );
3895 24 : if( HasEndnotes())
3896 0 : WriteFootnoteEndnotePr( m_pSerializer, XML_endnotePr, m_rExport.pDoc->GetEndNoteInfo(), 0 );
3897 24 : }
3898 :
3899 11 : void DocxAttributeOutput::ParaLineSpacing_Impl( short nSpace, short nMulti )
3900 : {
3901 11 : if ( !m_pParagraphSpacingAttrList )
3902 11 : m_pParagraphSpacingAttrList = m_pSerializer->createAttrList();
3903 :
3904 11 : if ( nSpace < 0 )
3905 : {
3906 0 : m_pParagraphSpacingAttrList->add( FSNS( XML_w, XML_lineRule ), "exact" );
3907 0 : m_pParagraphSpacingAttrList->add( FSNS( XML_w, XML_line ), OString::valueOf( sal_Int32( -nSpace ) ) );
3908 : }
3909 11 : else if( nMulti )
3910 : {
3911 6 : m_pParagraphSpacingAttrList->add( FSNS( XML_w, XML_lineRule ), "auto" );
3912 6 : m_pParagraphSpacingAttrList->add( FSNS( XML_w, XML_line ), OString::valueOf( sal_Int32( nSpace ) ) );
3913 : }
3914 5 : else if ( nSpace > 0 )
3915 : {
3916 5 : m_pParagraphSpacingAttrList->add( FSNS( XML_w, XML_lineRule ), "atLeast" );
3917 5 : m_pParagraphSpacingAttrList->add( FSNS( XML_w, XML_line ), OString::valueOf( sal_Int32( nSpace ) ) );
3918 : }
3919 : else
3920 0 : m_pParagraphSpacingAttrList->add( FSNS( XML_w, XML_lineRule ), "auto" );
3921 11 : }
3922 :
3923 0 : void DocxAttributeOutput::ParaAdjust( const SvxAdjustItem& rAdjust )
3924 : {
3925 : const char *pAdjustString;
3926 :
3927 0 : bool bEcma = GetExport().GetFilter().getVersion( ) == oox::core::ECMA_DIALECT;
3928 :
3929 0 : const SfxItemSet* pItems = GetExport().GetCurItemSet();
3930 0 : const SvxFrameDirectionItem* rFrameDir = static_cast< const SvxFrameDirectionItem* >( pItems->GetItem( RES_FRAMEDIR ) );
3931 :
3932 0 : short nDir = FRMDIR_ENVIRONMENT;
3933 0 : if( rFrameDir != NULL )
3934 0 : nDir = rFrameDir->GetValue();
3935 0 : if ( nDir == FRMDIR_ENVIRONMENT )
3936 0 : nDir = GetExport( ).GetDefaultFrameDirection( );
3937 0 : bool bRtl = ( nDir == FRMDIR_HORI_RIGHT_TOP );
3938 :
3939 0 : switch ( rAdjust.GetAdjust() )
3940 : {
3941 : case SVX_ADJUST_LEFT:
3942 0 : if ( bEcma )
3943 0 : pAdjustString = "left";
3944 0 : else if ( bRtl )
3945 0 : pAdjustString = "end";
3946 : else
3947 0 : pAdjustString = "start";
3948 0 : break;
3949 : case SVX_ADJUST_RIGHT:
3950 0 : if ( bEcma )
3951 0 : pAdjustString = "right";
3952 0 : else if ( bRtl )
3953 0 : pAdjustString = "start";
3954 : else
3955 0 : pAdjustString = "end";
3956 0 : break;
3957 : case SVX_ADJUST_BLOCKLINE:
3958 : case SVX_ADJUST_BLOCK:
3959 0 : pAdjustString = "both";
3960 0 : break;
3961 : case SVX_ADJUST_CENTER:
3962 0 : pAdjustString = "center";
3963 0 : break;
3964 : default:
3965 0 : return; // not supported attribute
3966 : }
3967 0 : m_pSerializer->singleElementNS( XML_w, XML_jc, FSNS( XML_w, XML_val ), pAdjustString, FSEND );
3968 : }
3969 :
3970 0 : void DocxAttributeOutput::ParaSplit( const SvxFmtSplitItem& rSplit )
3971 : {
3972 0 : if (rSplit.GetValue())
3973 0 : m_pSerializer->singleElementNS( XML_w, XML_keepLines, FSNS( XML_w, XML_val ), "false", FSEND );
3974 : else
3975 0 : m_pSerializer->singleElementNS( XML_w, XML_keepLines, FSEND );
3976 0 : }
3977 :
3978 25 : void DocxAttributeOutput::ParaWidows( const SvxWidowsItem& rWidows )
3979 : {
3980 25 : if (rWidows.GetValue())
3981 6 : m_pSerializer->singleElementNS( XML_w, XML_widowControl, FSEND );
3982 : else
3983 19 : m_pSerializer->singleElementNS( XML_w, XML_widowControl, FSNS( XML_w, XML_val ), "false", FSEND );
3984 25 : }
3985 :
3986 14 : static void impl_WriteTabElement( FSHelperPtr pSerializer,
3987 : const SvxTabStop& rTab, long nCurrentLeft )
3988 : {
3989 14 : FastAttributeList *pTabElementAttrList = pSerializer->createAttrList();
3990 :
3991 14 : switch (rTab.GetAdjustment())
3992 : {
3993 : case SVX_TAB_ADJUST_RIGHT:
3994 0 : pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"right") );
3995 0 : break;
3996 : case SVX_TAB_ADJUST_DECIMAL:
3997 0 : pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"decimal") );
3998 0 : break;
3999 : case SVX_TAB_ADJUST_CENTER:
4000 0 : pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"center") );
4001 0 : break;
4002 : case SVX_TAB_ADJUST_DEFAULT:
4003 : case SVX_TAB_ADJUST_LEFT:
4004 : default:
4005 14 : pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"left") );
4006 14 : break;
4007 : }
4008 :
4009 14 : pTabElementAttrList->add( FSNS( XML_w, XML_pos ), OString::valueOf( rTab.GetTabPos() + nCurrentLeft ) );
4010 :
4011 14 : sal_Unicode cFillChar = rTab.GetFill();
4012 :
4013 14 : if (sal_Unicode('.') == cFillChar )
4014 0 : pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "dot" ) );
4015 14 : else if ( sal_Unicode('-') == cFillChar )
4016 0 : pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "hyphen" ) );
4017 14 : else if ( sal_Unicode(0xB7) == cFillChar ) // middle dot
4018 0 : pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "middleDot" ) );
4019 14 : else if ( sal_Unicode('_') == cFillChar )
4020 0 : pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "underscore" ) );
4021 : else
4022 14 : pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "none" ) );
4023 :
4024 14 : pSerializer->singleElementNS( XML_w, XML_tab, pTabElementAttrList );
4025 14 : }
4026 :
4027 24 : void DocxAttributeOutput::ParaTabStop( const SvxTabStopItem& rTabStop )
4028 : {
4029 24 : const SfxPoolItem* pLR = m_rExport.HasItem( RES_LR_SPACE );
4030 24 : long nCurrentLeft = pLR ? ((const SvxLRSpaceItem*)pLR)->GetTxtLeft() : 0;
4031 :
4032 24 : sal_uInt16 nCount = rTabStop.Count();
4033 :
4034 : // <w:tabs> must contain at least one <w:tab>, so don't write it empty
4035 24 : if( nCount == 0 )
4036 0 : return;
4037 24 : if( nCount == 1 && rTabStop[ 0 ].GetAdjustment() == SVX_TAB_ADJUST_DEFAULT )
4038 : {
4039 10 : GetExport().setDefaultTabStop( rTabStop[ 0 ].GetTabPos());
4040 10 : return;
4041 : }
4042 :
4043 14 : m_pSerializer->startElementNS( XML_w, XML_tabs, FSEND );
4044 :
4045 28 : for (sal_uInt16 i = 0; i < nCount; i++ )
4046 : {
4047 14 : if( rTabStop[i].GetAdjustment() != SVX_TAB_ADJUST_DEFAULT )
4048 14 : impl_WriteTabElement( m_pSerializer, rTabStop[i], nCurrentLeft );
4049 : else
4050 0 : GetExport().setDefaultTabStop( rTabStop[i].GetTabPos());
4051 : }
4052 :
4053 14 : m_pSerializer->endElementNS( XML_w, XML_tabs );
4054 : }
4055 :
4056 24 : void DocxAttributeOutput::ParaHyphenZone( const SvxHyphenZoneItem& rHyphenZone )
4057 : {
4058 : m_pSerializer->singleElementNS( XML_w, XML_suppressAutoHyphens,
4059 24 : FSNS( XML_w, XML_val ), rHyphenZone.IsHyphen( ) ? "false" : "true" ,
4060 24 : FSEND );
4061 24 : }
4062 :
4063 0 : void DocxAttributeOutput::ParaNumRule_Impl( const SwTxtNode* /*pTxtNd*/, sal_Int32 nLvl, sal_Int32 nNumId )
4064 : {
4065 0 : if ( USHRT_MAX != nNumId && 0 != nNumId )
4066 : {
4067 0 : m_pSerializer->startElementNS( XML_w, XML_numPr, FSEND );
4068 0 : m_pSerializer->singleElementNS( XML_w, XML_ilvl, FSNS( XML_w, XML_val ), OString::valueOf( sal_Int32( nLvl )).getStr(), FSEND );
4069 0 : m_pSerializer->singleElementNS( XML_w, XML_numId, FSNS( XML_w, XML_val ), OString::valueOf( sal_Int32( nNumId )).getStr(), FSEND );
4070 0 : m_pSerializer->endElementNS( XML_w, XML_numPr );
4071 : }
4072 0 : }
4073 :
4074 10 : void DocxAttributeOutput::ParaScriptSpace( const SfxBoolItem& rScriptSpace )
4075 : {
4076 10 : sal_uInt16 nXmlElement = 0;
4077 :
4078 10 : switch ( rScriptSpace.Which( ) )
4079 : {
4080 : case RES_PARATR_SCRIPTSPACE:
4081 3 : nXmlElement = XML_autoSpaceDE;
4082 3 : break;
4083 : case RES_PARATR_HANGINGPUNCTUATION:
4084 4 : nXmlElement = XML_overflowPunct;
4085 4 : break;
4086 : case RES_PARATR_FORBIDDEN_RULES:
4087 3 : nXmlElement = XML_kinsoku;
4088 3 : break;
4089 : }
4090 :
4091 10 : if ( nXmlElement )
4092 : {
4093 : m_pSerializer->singleElementNS( XML_w, nXmlElement,
4094 10 : FSNS( XML_w, XML_val ), rScriptSpace.GetValue( ) ? "true": "false",
4095 10 : FSEND );
4096 : }
4097 10 : }
4098 :
4099 0 : void DocxAttributeOutput::ParaVerticalAlign( const SvxParaVertAlignItem& rAlign )
4100 : {
4101 : const char *pAlignString;
4102 :
4103 0 : switch ( rAlign.GetValue() )
4104 : {
4105 : case SvxParaVertAlignItem::BASELINE:
4106 0 : pAlignString = "baseline";
4107 0 : break;
4108 : case SvxParaVertAlignItem::TOP:
4109 0 : pAlignString = "top";
4110 0 : break;
4111 : case SvxParaVertAlignItem::CENTER:
4112 0 : pAlignString = "center";
4113 0 : break;
4114 : case SvxParaVertAlignItem::BOTTOM:
4115 0 : pAlignString = "bottom";
4116 0 : break;
4117 : case SvxParaVertAlignItem::AUTOMATIC:
4118 0 : pAlignString = "auto";
4119 0 : break;
4120 : default:
4121 0 : return; // not supported attribute
4122 : }
4123 0 : m_pSerializer->singleElementNS( XML_w, XML_textAlignment, FSNS( XML_w, XML_val ), pAlignString, FSEND );
4124 : }
4125 :
4126 0 : void DocxAttributeOutput::ParaSnapToGrid( const SvxParaGridItem& rGrid )
4127 : {
4128 : m_pSerializer->singleElementNS( XML_w, XML_snapToGrid,
4129 0 : FSNS( XML_w, XML_val ), rGrid.GetValue( ) ? "true": "false",
4130 0 : FSEND );
4131 0 : }
4132 :
4133 24 : void DocxAttributeOutput::FormatFrameSize( const SwFmtFrmSize& rSize )
4134 : {
4135 24 : if ( m_rExport.bOutFlyFrmAttrs )
4136 : {
4137 0 : if ( !m_pFlyAttrList )
4138 0 : m_pFlyAttrList = m_pSerializer->createAttrList( );
4139 :
4140 0 : if ( rSize.GetWidth() && rSize.GetWidthSizeType() == ATT_FIX_SIZE )
4141 : {
4142 0 : m_pFlyAttrList->add( FSNS( XML_w, XML_w ), OString::valueOf( rSize.GetWidth( ) ) );
4143 : }
4144 :
4145 0 : if ( rSize.GetHeight() )
4146 : {
4147 0 : OString sRule( "exact" );
4148 0 : if ( rSize.GetHeightSizeType() == ATT_MIN_SIZE )
4149 0 : sRule = OString( "atLeast" );
4150 0 : m_pFlyAttrList->add( FSNS( XML_w, XML_hRule ), sRule );
4151 0 : m_pFlyAttrList->add( FSNS( XML_w, XML_h ), OString::valueOf( rSize.GetHeight( ) ) );
4152 : }
4153 : }
4154 24 : else if ( m_rExport.bOutPageDescs )
4155 : {
4156 24 : FastAttributeList *attrList = m_pSerializer->createAttrList( );
4157 24 : if ( m_rExport.pAktPageDesc->GetLandscape( ) )
4158 0 : attrList->add( FSNS( XML_w, XML_orient ), "landscape" );
4159 :
4160 24 : attrList->add( FSNS( XML_w, XML_w ), OString::valueOf( rSize.GetWidth( ) ) );
4161 24 : attrList->add( FSNS( XML_w, XML_h ), OString::valueOf( rSize.GetHeight( ) ) );
4162 :
4163 24 : XFastAttributeListRef xAttrList( attrList );
4164 24 : attrList = NULL;
4165 :
4166 24 : m_pSerializer->singleElementNS( XML_w, XML_pgSz, xAttrList );
4167 : }
4168 24 : }
4169 :
4170 0 : void DocxAttributeOutput::FormatPaperBin( const SvxPaperBinItem& )
4171 : {
4172 : OSL_TRACE( "TODO DocxAttributeOutput::FormatPaperBin()" );
4173 0 : }
4174 :
4175 24 : void DocxAttributeOutput::FormatLRSpace( const SvxLRSpaceItem& rLRSpace )
4176 : {
4177 24 : bool bEcma = m_rExport.GetFilter().getVersion( ) == oox::core::ECMA_DIALECT;
4178 :
4179 24 : if ( m_rExport.bOutFlyFrmAttrs )
4180 : {
4181 0 : if ( !m_pFlyAttrList )
4182 0 : m_pFlyAttrList = m_pSerializer->createAttrList();
4183 :
4184 : m_pFlyAttrList->add( FSNS( XML_w, XML_hSpace ),
4185 : OString::valueOf(
4186 0 : sal_Int32( ( rLRSpace.GetLeft() + rLRSpace.GetRight() ) / 2 ) ) );
4187 : }
4188 24 : else if ( m_rExport.bOutPageDescs )
4189 : {
4190 24 : if ( !m_pSectionSpacingAttrList )
4191 24 : m_pSectionSpacingAttrList = m_pSerializer->createAttrList();
4192 :
4193 : sal_uInt16 nLDist, nRDist;
4194 24 : const SfxPoolItem* pItem = m_rExport.HasItem( RES_BOX );
4195 24 : if ( pItem )
4196 : {
4197 0 : nRDist = ((SvxBoxItem*)pItem)->CalcLineSpace( BOX_LINE_LEFT );
4198 0 : nLDist = ((SvxBoxItem*)pItem)->CalcLineSpace( BOX_LINE_RIGHT );
4199 : }
4200 : else
4201 24 : nLDist = nRDist = 0;
4202 24 : nLDist = nLDist + (sal_uInt16)rLRSpace.GetLeft();
4203 24 : nRDist = nRDist + (sal_uInt16)rLRSpace.GetRight();
4204 :
4205 24 : m_pSectionSpacingAttrList->add( FSNS( XML_w, XML_left ), OString::valueOf( sal_Int32( nLDist ) ) );
4206 24 : m_pSectionSpacingAttrList->add( FSNS( XML_w, XML_right ), OString::valueOf( sal_Int32( nRDist ) ) );
4207 : }
4208 : else
4209 : {
4210 0 : FastAttributeList *pLRSpaceAttrList = m_pSerializer->createAttrList();
4211 :
4212 0 : pLRSpaceAttrList->add( FSNS( XML_w, ( bEcma ? XML_left : XML_start ) ), OString::valueOf( (sal_Int32) rLRSpace.GetTxtLeft() ) );
4213 0 : pLRSpaceAttrList->add( FSNS( XML_w, ( bEcma ? XML_right : XML_end ) ), OString::valueOf( (sal_Int32) rLRSpace.GetRight() ) );
4214 :
4215 0 : sal_Int32 nFirstLineAdjustment = rLRSpace.GetTxtFirstLineOfst();
4216 0 : if (nFirstLineAdjustment > 0)
4217 0 : pLRSpaceAttrList->add( FSNS( XML_w, XML_firstLine ), OString::valueOf( nFirstLineAdjustment ) );
4218 : else
4219 0 : pLRSpaceAttrList->add( FSNS( XML_w, XML_hanging ), OString::valueOf( - nFirstLineAdjustment ) );
4220 0 : m_pSerializer->singleElementNS( XML_w, XML_ind, pLRSpaceAttrList );
4221 : }
4222 24 : }
4223 :
4224 106 : void DocxAttributeOutput::FormatULSpace( const SvxULSpaceItem& rULSpace )
4225 : {
4226 :
4227 106 : if ( m_rExport.bOutFlyFrmAttrs )
4228 : {
4229 0 : if ( !m_pFlyAttrList )
4230 0 : m_pFlyAttrList = m_pSerializer->createAttrList();
4231 :
4232 : m_pFlyAttrList->add( FSNS( XML_w, XML_vSpace ),
4233 : OString::valueOf(
4234 0 : sal_Int32( ( rULSpace.GetLower() + rULSpace.GetUpper() ) / 2 ) ) );
4235 : }
4236 106 : else if (m_rExport.bOutPageDescs )
4237 : {
4238 : OSL_ENSURE( m_rExport.GetCurItemSet(), "Impossible" );
4239 24 : if ( !m_rExport.GetCurItemSet() )
4240 106 : return;
4241 :
4242 24 : if ( !m_pSectionSpacingAttrList )
4243 0 : m_pSectionSpacingAttrList = m_pSerializer->createAttrList();
4244 :
4245 24 : HdFtDistanceGlue aDistances( *m_rExport.GetCurItemSet() );
4246 :
4247 24 : sal_Int32 nHeader = 0;
4248 24 : if ( aDistances.HasHeader() )
4249 0 : nHeader = sal_Int32( aDistances.dyaHdrTop );
4250 24 : m_pSectionSpacingAttrList->add( FSNS( XML_w, XML_header ), OString::valueOf( nHeader ) );
4251 :
4252 : // Page top
4253 : m_pSectionSpacingAttrList->add( FSNS( XML_w, XML_top ),
4254 24 : OString::valueOf( sal_Int32( aDistances.dyaTop ) ) );
4255 :
4256 24 : sal_Int32 nFooter = 0;
4257 24 : if ( aDistances.HasFooter() )
4258 0 : nFooter = sal_Int32( aDistances.dyaHdrBottom );
4259 24 : m_pSectionSpacingAttrList->add( FSNS( XML_w, XML_footer ), OString::valueOf( nFooter ) );
4260 :
4261 : // Page Bottom
4262 : m_pSectionSpacingAttrList->add( FSNS( XML_w, XML_bottom ),
4263 24 : OString::valueOf( sal_Int32( aDistances.dyaBottom ) ) );
4264 :
4265 : // FIXME Page Gutter is not handled ATM, setting to 0 as it's mandatory for OOXML
4266 : m_pSectionSpacingAttrList->add( FSNS( XML_w, XML_gutter ),
4267 24 : OString::valueOf( sal_Int32( 0 ) ) );
4268 :
4269 : }
4270 : else
4271 : {
4272 82 : if ( !m_pParagraphSpacingAttrList )
4273 72 : m_pParagraphSpacingAttrList = m_pSerializer->createAttrList();
4274 : m_pParagraphSpacingAttrList->add( FSNS( XML_w, XML_before ),
4275 82 : OString::valueOf( (sal_Int32)rULSpace.GetUpper() ) );
4276 : m_pParagraphSpacingAttrList->add( FSNS( XML_w, XML_after ),
4277 82 : OString::valueOf( (sal_Int32)rULSpace.GetLower() ) );
4278 82 : if (rULSpace.GetContext())
4279 0 : m_pSerializer->singleElementNS( XML_w, XML_contextualSpacing, FSEND );
4280 : else
4281 82 : m_pSerializer->singleElementNS( XML_w, XML_contextualSpacing, FSNS( XML_w, XML_val ), "false", FSEND );
4282 : }
4283 : }
4284 :
4285 0 : void DocxAttributeOutput::FormatSurround( const SwFmtSurround& rSurround )
4286 : {
4287 0 : if ( m_rExport.bOutFlyFrmAttrs )
4288 : {
4289 0 : if ( !m_pFlyAttrList )
4290 0 : m_pFlyAttrList = m_pSerializer->createAttrList();
4291 :
4292 0 : OString sWrap( "auto" );
4293 0 : switch ( rSurround.GetSurround( ) )
4294 : {
4295 : case SURROUND_NONE:
4296 0 : sWrap = OString( "none" );
4297 0 : break;
4298 : case SURROUND_THROUGHT:
4299 0 : sWrap = OString( "through" );
4300 0 : break;
4301 : case SURROUND_IDEAL:
4302 : case SURROUND_PARALLEL:
4303 : case SURROUND_LEFT:
4304 : case SURROUND_RIGHT:
4305 : default:
4306 0 : sWrap = OString( "around" );
4307 : }
4308 :
4309 0 : m_pFlyAttrList->add( FSNS( XML_w, XML_wrap ), sWrap );
4310 : }
4311 0 : }
4312 :
4313 0 : void DocxAttributeOutput::FormatVertOrientation( const SwFmtVertOrient& rFlyVert )
4314 : {
4315 0 : if ( m_rExport.bOutFlyFrmAttrs )
4316 : {
4317 0 : if ( !m_pFlyAttrList )
4318 0 : m_pFlyAttrList = m_pSerializer->createAttrList();
4319 :
4320 0 : OString sAlign;
4321 0 : switch( rFlyVert.GetVertOrient() )
4322 : {
4323 : case text::VertOrientation::NONE:
4324 0 : break;
4325 : case text::VertOrientation::CENTER:
4326 : case text::VertOrientation::LINE_CENTER:
4327 0 : sAlign = OString( "center" );
4328 0 : break;
4329 : case text::VertOrientation::BOTTOM:
4330 : case text::VertOrientation::LINE_BOTTOM:
4331 0 : sAlign = OString( "bottom" );
4332 0 : break;
4333 : case text::VertOrientation::TOP:
4334 : case text::VertOrientation::LINE_TOP:
4335 : default:
4336 0 : sAlign = OString( "top" );
4337 0 : break;
4338 : }
4339 :
4340 0 : if ( !sAlign.isEmpty() )
4341 0 : m_pFlyAttrList->add( FSNS( XML_w, XML_yAlign ), sAlign );
4342 : else
4343 : m_pFlyAttrList->add( FSNS( XML_w, XML_y ),
4344 0 : OString::valueOf( sal_Int32( rFlyVert.GetPos() ) ) );
4345 :
4346 0 : OString sVAnchor( "page" );
4347 0 : switch ( rFlyVert.GetRelationOrient( ) )
4348 : {
4349 : case text::RelOrientation::CHAR:
4350 : case text::RelOrientation::PRINT_AREA:
4351 : case text::RelOrientation::TEXT_LINE:
4352 0 : sVAnchor = OString( "column" );
4353 0 : break;
4354 : case text::RelOrientation::FRAME:
4355 : case text::RelOrientation::PAGE_LEFT:
4356 : case text::RelOrientation::PAGE_RIGHT:
4357 : case text::RelOrientation::FRAME_LEFT:
4358 : case text::RelOrientation::FRAME_RIGHT:
4359 0 : sVAnchor = OString( "margin" );
4360 0 : break;
4361 : case text::RelOrientation::PAGE_FRAME:
4362 : case text::RelOrientation::PAGE_PRINT_AREA:
4363 : default:
4364 0 : break;
4365 : }
4366 :
4367 0 : m_pFlyAttrList->add( FSNS( XML_w, XML_vAnchor ), sVAnchor );
4368 : }
4369 0 : }
4370 :
4371 0 : void DocxAttributeOutput::FormatHorizOrientation( const SwFmtHoriOrient& rFlyHori )
4372 : {
4373 0 : if ( m_rExport.bOutFlyFrmAttrs )
4374 : {
4375 0 : if ( !m_pFlyAttrList )
4376 0 : m_pFlyAttrList = m_pSerializer->createAttrList();
4377 :
4378 0 : OString sAlign;
4379 0 : switch( rFlyHori.GetHoriOrient() )
4380 : {
4381 : case text::HoriOrientation::NONE:
4382 0 : break;
4383 : case text::HoriOrientation::LEFT:
4384 0 : sAlign = OString( rFlyHori.IsPosToggle( ) ? "inside" : "left" );
4385 0 : break;
4386 : case text::HoriOrientation::RIGHT:
4387 0 : sAlign = OString( rFlyHori.IsPosToggle( ) ? "outside" : "right" );
4388 0 : break;
4389 : case text::HoriOrientation::CENTER:
4390 : case text::HoriOrientation::FULL: // FULL only for tables
4391 : default:
4392 0 : sAlign = OString( "center" );
4393 0 : break;
4394 : }
4395 :
4396 0 : if ( !sAlign.isEmpty() )
4397 0 : m_pFlyAttrList->add( FSNS( XML_w, XML_xAlign ), sAlign );
4398 : else
4399 : m_pFlyAttrList->add( FSNS( XML_w, XML_x ),
4400 0 : OString::valueOf( sal_Int32( rFlyHori.GetPos() ) ) );
4401 :
4402 0 : OString sHAnchor( "page" );
4403 0 : switch ( rFlyHori.GetRelationOrient( ) )
4404 : {
4405 : case text::RelOrientation::CHAR:
4406 : case text::RelOrientation::PRINT_AREA:
4407 0 : sHAnchor = OString( "text" );
4408 0 : break;
4409 : case text::RelOrientation::FRAME:
4410 : case text::RelOrientation::PAGE_LEFT:
4411 : case text::RelOrientation::PAGE_RIGHT:
4412 : case text::RelOrientation::FRAME_LEFT:
4413 : case text::RelOrientation::FRAME_RIGHT:
4414 0 : sHAnchor = OString( "margin" );
4415 0 : break;
4416 : case text::RelOrientation::PAGE_FRAME:
4417 : case text::RelOrientation::PAGE_PRINT_AREA:
4418 : default:
4419 0 : break;
4420 : }
4421 :
4422 0 : m_pFlyAttrList->add( FSNS( XML_w, XML_hAnchor ), sHAnchor );
4423 : }
4424 0 : }
4425 :
4426 0 : void DocxAttributeOutput::FormatAnchor( const SwFmtAnchor& )
4427 : {
4428 : // Fly frames: anchors here aren't matching the anchors in docx
4429 0 : }
4430 :
4431 0 : void DocxAttributeOutput::FormatBackground( const SvxBrushItem& rBrush )
4432 : {
4433 0 : if ( !m_rExport.bOutPageDescs )
4434 : {
4435 0 : OString sColor = impl_ConvertColor( rBrush.GetColor( ) );
4436 : m_pSerializer->singleElementNS( XML_w, XML_shd,
4437 : FSNS( XML_w, XML_fill ), sColor.getStr( ),
4438 : FSNS( XML_w, XML_val ), "clear",
4439 0 : FSEND );
4440 : }
4441 0 : }
4442 :
4443 0 : void DocxAttributeOutput::FormatBox( const SvxBoxItem& rBox )
4444 : {
4445 :
4446 0 : if ( !m_bOpenedSectPr )
4447 : {
4448 : // Normally open the borders tag for paragraphs
4449 0 : m_pSerializer->startElementNS( XML_w, XML_pBdr, FSEND );
4450 : }
4451 :
4452 0 : impl_pageBorders( m_pSerializer, rBox, false, false );
4453 :
4454 0 : if ( m_bOpenedSectPr )
4455 : {
4456 : // Special handling for pgBorder
4457 0 : m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND );
4458 0 : m_pSerializer->mergeTopMarks( );
4459 : }
4460 : else
4461 : {
4462 : // Normally close the borders tag for paragraphs
4463 0 : m_pSerializer->endElementNS( XML_w, XML_pBdr );
4464 : }
4465 0 : }
4466 :
4467 0 : void DocxAttributeOutput::FormatColumns_Impl( sal_uInt16 nCols, const SwFmtCol& rCol, bool bEven, SwTwips nPageSize )
4468 : {
4469 : // Get the columns attributes
4470 0 : FastAttributeList *pColsAttrList = m_pSerializer->createAttrList();
4471 :
4472 : pColsAttrList->add( FSNS( XML_w, XML_num ),
4473 0 : OString::valueOf( sal_Int32( nCols ) ). getStr( ) );
4474 :
4475 0 : const char* pEquals = "false";
4476 0 : if ( bEven )
4477 : {
4478 0 : sal_uInt16 nWidth = rCol.GetGutterWidth( true );
4479 : pColsAttrList->add( FSNS( XML_w, XML_space ),
4480 0 : OString::valueOf( sal_Int32( nWidth ) ).getStr( ) );
4481 :
4482 0 : pEquals = "true";
4483 : }
4484 :
4485 0 : pColsAttrList->add( FSNS( XML_w, XML_equalWidth ), pEquals );
4486 :
4487 0 : bool bHasSep = COLADJ_NONE == rCol.GetLineAdj( );
4488 0 : pColsAttrList->add( FSNS( XML_w, XML_sep ), bHasSep ? "true" : "false" );
4489 :
4490 : // Write the element
4491 0 : m_pSerializer->startElementNS( XML_w, XML_cols, pColsAttrList );
4492 :
4493 : // Write the columns width if non-equals
4494 0 : const SwColumns & rColumns = rCol.GetColumns( );
4495 0 : if ( !bEven )
4496 : {
4497 0 : for ( sal_uInt16 n = 0; n < nCols; ++n )
4498 : {
4499 0 : FastAttributeList *pColAttrList = m_pSerializer->createAttrList();
4500 0 : sal_uInt16 nWidth = rCol.CalcPrtColWidth( n, ( sal_uInt16 ) nPageSize );
4501 : pColAttrList->add( FSNS( XML_w, XML_w ),
4502 0 : OString::valueOf( sal_Int32( nWidth ) ).getStr( ) );
4503 :
4504 0 : if ( n + 1 != nCols )
4505 : {
4506 0 : sal_uInt16 nSpacing = rColumns[n].GetRight( ) + rColumns[n + 1].GetLeft( );
4507 : pColAttrList->add( FSNS( XML_w, XML_space ),
4508 0 : OString::valueOf( sal_Int32( nSpacing ) ).getStr( ) );
4509 : }
4510 :
4511 0 : m_pSerializer->singleElementNS( XML_w, XML_col, pColAttrList );
4512 : }
4513 : }
4514 :
4515 0 : m_pSerializer->endElementNS( XML_w, XML_cols );
4516 0 : }
4517 :
4518 24 : void DocxAttributeOutput::FormatKeep( const SvxFmtKeepItem& )
4519 : {
4520 24 : m_pSerializer->singleElementNS( XML_w, XML_keepNext, FSEND );
4521 24 : }
4522 :
4523 20 : void DocxAttributeOutput::FormatTextGrid( const SwTextGridItem& rGrid )
4524 : {
4525 20 : FastAttributeList *pGridAttrList = m_pSerializer->createAttrList();
4526 :
4527 20 : OString sGridType;
4528 20 : switch ( rGrid.GetGridType( ) )
4529 : {
4530 : default:
4531 : case GRID_NONE:
4532 20 : sGridType = OString( "default" );
4533 20 : break;
4534 : case GRID_LINES_ONLY:
4535 0 : sGridType = OString( "lines" );
4536 0 : break;
4537 : case GRID_LINES_CHARS:
4538 0 : if ( rGrid.IsSnapToChars( ) )
4539 0 : sGridType = OString( "snapToChars" );
4540 : else
4541 0 : sGridType = OString( "linesAndChars" );
4542 0 : break;
4543 : }
4544 20 : pGridAttrList->add( FSNS( XML_w, XML_type ), sGridType.getStr( ) );
4545 :
4546 20 : sal_uInt16 nHeight = rGrid.GetBaseHeight() + rGrid.GetRubyHeight();
4547 : pGridAttrList->add( FSNS( XML_w, XML_linePitch ),
4548 20 : OString::valueOf( sal_Int32( nHeight ) ).getStr( ) );
4549 :
4550 : pGridAttrList->add( FSNS( XML_w, XML_charSpace ),
4551 20 : OString::valueOf( sal_Int32( GridCharacterPitch( rGrid ) ) ).getStr( ) );
4552 :
4553 20 : m_pSerializer->singleElementNS( XML_w, XML_docGrid, pGridAttrList );
4554 20 : }
4555 :
4556 48 : void DocxAttributeOutput::FormatLineNumbering( const SwFmtLineNumber& rNumbering )
4557 : {
4558 48 : if ( !rNumbering.IsCount( ) )
4559 48 : m_pSerializer->singleElementNS( XML_w, XML_suppressLineNumbers, FSEND );
4560 48 : }
4561 :
4562 48 : void DocxAttributeOutput::FormatFrameDirection( const SvxFrameDirectionItem& rDirection )
4563 : {
4564 48 : OString sTextFlow;
4565 48 : bool bBiDi = false;
4566 48 : short nDir = rDirection.GetValue();
4567 :
4568 48 : if ( nDir == FRMDIR_ENVIRONMENT )
4569 3 : nDir = GetExport( ).GetDefaultFrameDirection( );
4570 :
4571 48 : switch ( nDir )
4572 : {
4573 : default:
4574 : case FRMDIR_HORI_LEFT_TOP:
4575 48 : sTextFlow = OString( "lrTb" );
4576 48 : break;
4577 : case FRMDIR_HORI_RIGHT_TOP:
4578 0 : sTextFlow = OString( "lrTb" );
4579 0 : bBiDi = true;
4580 0 : break;
4581 : case FRMDIR_VERT_TOP_LEFT: // many things but not this one
4582 : case FRMDIR_VERT_TOP_RIGHT:
4583 0 : sTextFlow = OString( "tbRl" );
4584 0 : break;
4585 : }
4586 :
4587 48 : if ( m_rExport.bOutPageDescs )
4588 : {
4589 : m_pSerializer->singleElementNS( XML_w, XML_textDirection,
4590 : FSNS( XML_w, XML_val ), sTextFlow.getStr( ),
4591 24 : FSEND );
4592 24 : if ( bBiDi )
4593 0 : m_pSerializer->singleElementNS( XML_w, XML_bidi, FSEND );
4594 : }
4595 24 : else if ( !m_rExport.bOutFlyFrmAttrs )
4596 : {
4597 24 : if ( bBiDi )
4598 0 : m_pSerializer->singleElementNS( XML_w, XML_bidi, FSEND );
4599 48 : }
4600 48 : }
4601 :
4602 24 : DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, FSHelperPtr pSerializer, oox::drawingml::DrawingML* pDrawingML )
4603 : : m_rExport( rExport ),
4604 : m_pSerializer( pSerializer ),
4605 : m_rDrawingML( *pDrawingML ),
4606 : m_pFontsAttrList( NULL ),
4607 : m_pEastAsianLayoutAttrList( NULL ),
4608 : m_pCharLangAttrList( NULL ),
4609 : m_pSectionSpacingAttrList( NULL ),
4610 : m_pParagraphSpacingAttrList( NULL ),
4611 : m_pHyperlinkAttrList( NULL ),
4612 : m_pFlyAttrList( NULL ),
4613 0 : m_pFootnotesList( new ::docx::FootnotesList() ),
4614 0 : m_pEndnotesList( new ::docx::FootnotesList() ),
4615 : m_footnoteEndnoteRefTag( 0 ),
4616 : m_pSectionInfo( NULL ),
4617 : m_pRedlineData( NULL ),
4618 : m_nRedlineId( 0 ),
4619 : m_bOpenedSectPr( false ),
4620 : m_sFieldBkm( ),
4621 : m_nNextMarkId( 0 ),
4622 : m_bPostitStart(false),
4623 : m_bPostitEnd(false),
4624 : m_pTableWrt( NULL ),
4625 : m_bTableCellOpen( false ),
4626 : m_nTableDepth( 0 ),
4627 : m_bParagraphOpened( false ),
4628 : m_nColBreakStatus( COLBRK_NONE ),
4629 : m_pParentFrame( NULL ),
4630 : m_closeHyperlinkInThisRun( false ),
4631 : m_closeHyperlinkInPreviousRun( false ),
4632 : m_startedHyperlink( false ),
4633 : m_postponedGraphic( NULL ),
4634 : m_postponedMath( NULL ),
4635 : m_postitFieldsMaxId( 0 ),
4636 : m_anchorId( 0 ),
4637 24 : m_nextFontId( 1 )
4638 : {
4639 24 : }
4640 :
4641 72 : DocxAttributeOutput::~DocxAttributeOutput()
4642 : {
4643 24 : delete m_pFontsAttrList, m_pFontsAttrList = NULL;
4644 24 : delete m_pEastAsianLayoutAttrList, m_pEastAsianLayoutAttrList = NULL;
4645 24 : delete m_pCharLangAttrList, m_pCharLangAttrList = NULL;
4646 24 : delete m_pSectionSpacingAttrList, m_pSectionSpacingAttrList = NULL;
4647 24 : delete m_pParagraphSpacingAttrList, m_pParagraphSpacingAttrList = NULL;
4648 24 : delete m_pHyperlinkAttrList, m_pHyperlinkAttrList = NULL;
4649 24 : delete m_pFlyAttrList, m_pFlyAttrList = NULL;
4650 :
4651 24 : delete m_pFootnotesList, m_pFootnotesList = NULL;
4652 24 : delete m_pEndnotesList, m_pEndnotesList = NULL;
4653 :
4654 24 : delete m_pTableWrt, m_pTableWrt = NULL;
4655 24 : delete m_pParentFrame;
4656 48 : }
4657 :
4658 563 : DocxExport& DocxAttributeOutput::GetExport()
4659 : {
4660 563 : return m_rExport;
4661 : }
4662 :
4663 72 : bool DocxAttributeOutput::HasFootnotes() const
4664 : {
4665 72 : return !m_pFootnotesList->isEmpty();
4666 : }
4667 :
4668 72 : bool DocxAttributeOutput::HasEndnotes() const
4669 : {
4670 72 : return !m_pEndnotesList->isEmpty();
4671 : }
4672 :
4673 24 : bool DocxAttributeOutput::HasPostitFields() const
4674 : {
4675 24 : return !m_postitFields.empty();
4676 18 : }
4677 :
4678 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|