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