Update ooo320-m1
[ooovba.git] / sw / source / filter / ww8 / docxattributeoutput.cxx
blob44a5c329a50eecceb83ef94cc01e6762f1596226
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile$
10 * $Revision$
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "docxattributeoutput.hxx"
32 #include "docxexport.hxx"
33 #include "docxfootnotes.hxx"
34 #include "writerwordglue.hxx"
35 #include "wrtww8.hxx"
36 #include "ww8par.hxx"
38 #include <oox/core/tokens.hxx>
39 #include <oox/export/drawingml.hxx>
40 #include <oox/export/utils.hxx>
41 #include <oox/export/vmlexport.hxx>
43 #include <i18npool/mslangid.hxx>
45 #include <hintids.hxx>
47 #include <svtools/poolitem.hxx>
49 #include <svx/fontitem.hxx>
50 #include <svx/tstpitem.hxx>
51 #include <svx/adjitem.hxx>
52 #include <svx/spltitem.hxx>
53 #include <svx/widwitem.hxx>
54 #include <svx/lspcitem.hxx>
55 #include <svx/keepitem.hxx>
56 #include <svx/shaditem.hxx>
57 #include <svx/brshitem.hxx>
58 #include <svx/postitem.hxx>
59 #include <svx/wghtitem.hxx>
60 #include <svx/kernitem.hxx>
61 #include <svx/crsditem.hxx>
62 #include <svx/cmapitem.hxx>
63 #include <svx/wrlmitem.hxx>
64 #include <svx/udlnitem.hxx>
65 #include <svx/langitem.hxx>
66 #include <svx/escpitem.hxx>
67 #include <svx/fhgtitem.hxx>
68 #include <svx/colritem.hxx>
69 #include <svx/hyznitem.hxx>
70 #include <svx/brkitem.hxx>
71 #include <svx/lrspitem.hxx>
72 #include <svx/ulspitem.hxx>
73 #include <svx/boxitem.hxx>
74 #include <svx/cntritem.hxx>
75 #include <svx/shdditem.hxx>
76 #include <svx/akrnitem.hxx>
77 #include <svx/pbinitem.hxx>
78 #include <svx/emphitem.hxx>
79 #include <svx/twolinesitem.hxx>
80 #include <svx/charscaleitem.hxx>
81 #include <svx/charrotateitem.hxx>
82 #include <svx/charreliefitem.hxx>
83 #include <svx/paravertalignitem.hxx>
84 #include <svx/pgrditem.hxx>
85 #include <svx/frmdiritem.hxx>
86 #include <svx/blnkitem.hxx>
87 #include <svx/charhiddenitem.hxx>
88 #include <svx/svdmodel.hxx>
89 #include <svx/svdobj.hxx>
91 #include <docufld.hxx>
92 #include <flddropdown.hxx>
93 #include <format.hxx>
94 #include <fmtclds.hxx>
95 #include <fmtinfmt.hxx>
96 #include <fmtfld.hxx>
97 #include <fmtfsize.hxx>
98 #include <fmtftn.hxx>
99 #include <fmtrowsplt.hxx>
100 #include <fmtline.hxx>
101 #include <frmfmt.hxx>
102 #include <frmatr.hxx>
103 #include <ftninfo.hxx>
104 #include <htmltbl.hxx>
105 #include <ndgrf.hxx>
106 #include <ndtxt.hxx>
107 #include <node.hxx>
108 #include <pagedesc.hxx>
109 #include <paratr.hxx>
110 #include <swmodule.hxx>
111 #include <swtable.hxx>
112 #include <txtftn.hxx>
113 #include <txtinet.hxx>
114 #include <numrule.hxx>
116 #include <rtl/strbuf.hxx>
117 #include <rtl/ustrbuf.hxx>
118 #include <rtl/ustring.hxx>
120 #include <tools/color.hxx>
122 #include <com/sun/star/i18n/ScriptType.hdl>
124 #if OSL_DEBUG_LEVEL > 0
125 #include <stdio.h>
126 #endif
128 using rtl::OString;
129 using rtl::OStringBuffer;
130 using rtl::OUString;
131 using rtl::OUStringBuffer;
132 using rtl::OUStringToOString;
134 using namespace docx;
135 using namespace sax_fastparser;
136 using namespace nsSwDocInfoSubType;
137 using namespace nsFieldFlags;
138 using namespace sw::util;
140 void DocxAttributeOutput::RTLAndCJKState( bool bIsRTL, sal_uInt16 /*nScript*/ )
142 if (bIsRTL)
143 m_pSerializer->singleElementNS( XML_w, XML_rtl, FSNS( XML_w, XML_val ), "true", FSEND );
146 void DocxAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo )
148 if ( m_nColBreakStatus == COLBRK_POSTPONE )
149 m_nColBreakStatus = COLBRK_WRITE;
151 // Output table/table row/table cell starts if needed
152 if ( pTextNodeInfo.get() )
154 sal_uInt32 nRow = pTextNodeInfo->getRow();
155 sal_uInt32 nCell = pTextNodeInfo->getCell();
157 // New cell/row?
158 if ( m_nTableDepth > 0 && !m_bTableCellOpen )
160 ww8::WW8TableNodeInfoInner::Pointer_t pDeepInner( pTextNodeInfo->getInnerForDepth( m_nTableDepth ) );
161 if ( pDeepInner->getCell() == 0 )
162 StartTableRow( pDeepInner );
164 StartTableCell( pDeepInner );
167 if ( nRow == 0 && nCell == 0 )
169 // Do we have to start the table?
170 // [If we are at the rigth depth already, it means that we
171 // continue the table cell]
172 sal_uInt32 nCurrentDepth = pTextNodeInfo->getDepth();
174 if ( nCurrentDepth > m_nTableDepth )
176 // Start all the tables that begin here
177 for ( sal_uInt32 nDepth = m_nTableDepth + 1; nDepth <= pTextNodeInfo->getDepth(); ++nDepth )
179 ww8::WW8TableNodeInfoInner::Pointer_t pInner( pTextNodeInfo->getInnerForDepth( nDepth ) );
181 StartTable( pInner );
182 StartTableRow( pInner );
183 StartTableCell( pInner );
186 m_nTableDepth = nCurrentDepth;
191 m_pSerializer->startElementNS( XML_w, XML_p, FSEND );
193 // postpone the output of the run (we get it before the paragraph
194 // properties, but must write it after them)
195 m_pSerializer->mark();
197 // no section break in this paragraph yet; can be set in SectionBreak()
198 m_pSectionInfo = NULL;
200 m_bParagraphOpened = true;
203 void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner )
205 // write the paragraph properties + the run, already in the correct order
206 m_pSerializer->mergeTopMarks();
207 m_pSerializer->endElementNS( XML_w, XML_p );
209 // Check for end of cell, rows, tables here
210 FinishTableRowCell( pTextNodeInfoInner );
212 m_bParagraphOpened = false;
215 void DocxAttributeOutput::FinishTableRowCell( ww8::WW8TableNodeInfoInner::Pointer_t pInner, bool bForceEmptyParagraph )
217 if ( pInner.get() )
219 // Where are we in the table
220 sal_uInt32 nRow = pInner->getRow( );
222 const SwTable *pTable = pInner->getTable( );
223 const SwTableLines& rLines = pTable->GetTabLines( );
224 USHORT nLinesCount = rLines.Count( );
226 if ( pInner->isEndOfCell() )
228 if ( bForceEmptyParagraph )
229 m_pSerializer->singleElementNS( XML_w, XML_p, FSEND );
231 EndTableCell();
234 // This is a line end
235 if ( pInner->isEndOfLine() )
236 EndTableRow();
238 // This is the end of the table
239 if ( pInner->isEndOfLine( ) && ( nRow + 1 ) == nLinesCount )
240 EndTable();
244 void DocxAttributeOutput::EmptyParagraph()
246 m_pSerializer->singleElementNS( XML_w, XML_p, FSEND );
249 void DocxAttributeOutput::StartParagraphProperties( const SwTxtNode& rNode )
251 // output page/section breaks
252 // Writer can have them at the beginning of a paragraph, or at the end, but
253 // in docx, we have to output them in the paragraph properties of the last
254 // paragraph in a section. To get it right, we have to switch to the next
255 // paragraph, and detect the section breaks there.
256 SwNodeIndex aNextIndex( rNode, 1 );
257 if ( aNextIndex.GetNode().IsTxtNode() )
259 const SwTxtNode* pTxtNode = static_cast< SwTxtNode* >( &aNextIndex.GetNode() );
260 m_rExport.OutputSectionBreaks( pTxtNode->GetpSwAttrSet(), *pTxtNode );
262 else if ( aNextIndex.GetNode().IsTableNode() )
264 const SwTableNode* pTableNode = static_cast< SwTableNode* >( &aNextIndex.GetNode() );
265 const SwFrmFmt *pFmt = pTableNode->GetTable().GetFrmFmt();
266 m_rExport.OutputSectionBreaks( &(pFmt->GetAttrSet()), *pTableNode );
269 // postpone the output so that we can later [in EndParagraphProperties()]
270 // prepend the properties before the run
271 m_pSerializer->mark();
273 m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND );
275 // and output the section break now (if it appeared)
276 if ( m_pSectionInfo )
278 m_rExport.SectionProperties( *m_pSectionInfo );
279 m_pSectionInfo = NULL;
282 InitCollectedParagraphProperties();
285 void DocxAttributeOutput::InitCollectedParagraphProperties()
287 m_pSpacingAttrList = NULL;
290 void DocxAttributeOutput::WriteCollectedParagraphProperties()
292 if ( m_pSpacingAttrList )
294 XFastAttributeListRef xAttrList( m_pSpacingAttrList );
295 m_pSpacingAttrList = NULL;
297 m_pSerializer->singleElementNS( XML_w, XML_spacing, xAttrList );
301 void DocxAttributeOutput::EndParagraphProperties()
303 WriteCollectedParagraphProperties();
305 m_pSerializer->endElementNS( XML_w, XML_pPr );
307 if ( m_nColBreakStatus == COLBRK_WRITE )
309 m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
310 m_pSerializer->singleElementNS( XML_w, XML_br,
311 FSNS( XML_w, XML_type ), "column", FSEND );
312 m_pSerializer->endElementNS( XML_w, XML_r );
314 m_nColBreakStatus = COLBRK_NONE;
317 // merge the properties _before_ the run (strictly speaking, just
318 // after the start of the paragraph)
319 m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND );
322 void DocxAttributeOutput::StartRun( const SwRedlineData* pRedlineData )
324 // if there is some redlining in the document, output it
325 StartRedline( pRedlineData );
327 // postpone the output of the start of a run (there are elements that need
328 // to be written before the start of the run, but we learn which they are
329 // _inside_ of the run)
330 m_pSerializer->mark(); // let's call it "postponed run start"
332 // postpone the output of the text (we get it before the run properties,
333 // but must write it after them)
334 m_pSerializer->mark(); // let's call it "postponed text"
337 void DocxAttributeOutput::EndRun()
339 // Write field starts
340 for ( std::vector<FieldInfos>::iterator pIt = m_Fields.begin(); pIt != m_Fields.end(); ++pIt )
342 // Add the fields starts for all but hyperlinks and TOCs
343 if ( pIt->bOpen && pIt->pField )
345 StartField_Impl( *pIt );
347 // Remove the field from the stack if only the start has to be written
348 // Unknown fields sould be removed too
349 if ( !pIt->bClose || ( pIt->eType == ww::eUNKNOWN ) )
351 m_Fields.erase( pIt );
352 --pIt;
358 // write the run properties + the text, already in the correct order
359 m_pSerializer->mergeTopMarks(); // merges with "postponed text", see above
361 // level down, to be able to prepend the actual run start attribute (just
362 // before "postponed run start")
363 m_pSerializer->mark(); // let's call it "actual run start"
365 // prepend the actual run start
366 if ( m_pHyperlinkAttrList )
368 XFastAttributeListRef xAttrList ( m_pHyperlinkAttrList );
370 m_pSerializer->startElementNS( XML_w, XML_hyperlink, xAttrList );
373 // Write the hyperlink and toc fields starts
374 for ( std::vector<FieldInfos>::iterator pIt = m_Fields.begin(); pIt != m_Fields.end(); ++pIt )
376 // Add the fields starts for hyperlinks, TOCs and index marks
377 if ( pIt->bOpen )
379 StartField_Impl( *pIt, sal_True );
381 // Remove the field if no end needs to be written
382 if ( !pIt->bClose ) {
383 m_Fields.erase( pIt );
384 --pIt;
389 DoWriteBookmarks( );
391 m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
392 m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND ); // merges with "postponed run start", see above
394 // write the run start + the run content
395 m_pSerializer->mergeTopMarks(); // merges the "actual run start"
397 // append the actual run end
398 m_pSerializer->endElementNS( XML_w, XML_r );
400 if ( m_pHyperlinkAttrList )
402 m_pSerializer->endElementNS( XML_w, XML_hyperlink );
403 m_pHyperlinkAttrList = NULL;
406 while ( m_Fields.begin() != m_Fields.end() )
408 EndField_Impl( m_Fields.front( ) );
409 m_Fields.erase( m_Fields.begin( ) );
412 // if there is some redlining in the document, output it
413 EndRedline();
416 void DocxAttributeOutput::DoWriteBookmarks()
418 // Write the start bookmarks
419 for ( std::vector< OString >::const_iterator it = m_rMarksStart.begin(), end = m_rMarksStart.end();
420 it < end; ++it )
422 const OString& rName = *it;
424 // Output the bookmark
425 USHORT nId = m_nNextMarkId++;
426 m_rOpenedMarksIds[rName] = nId;
427 m_pSerializer->singleElementNS( XML_w, XML_bookmarkStart,
428 FSNS( XML_w, XML_id ), OString::valueOf( sal_Int32( nId ) ).getStr( ),
429 FSNS( XML_w, XML_name ), rName.getStr(),
430 FSEND );
432 m_rMarksStart.clear();
434 // export the end bookmarks
435 for ( std::vector< OString >::const_iterator it = m_rMarksEnd.begin(), end = m_rMarksEnd.end();
436 it < end; ++it )
438 const OString& rName = *it;
440 // Get the id of the bookmark
441 std::map< OString, USHORT >::iterator pPos = m_rOpenedMarksIds.find( rName );
442 if ( pPos != m_rOpenedMarksIds.end( ) )
444 USHORT nId = ( *pPos ).second;
445 m_pSerializer->singleElementNS( XML_w, XML_bookmarkEnd,
446 FSNS( XML_w, XML_id ), OString::valueOf( sal_Int32( nId ) ).getStr( ),
447 FSEND );
448 m_rOpenedMarksIds.erase( rName );
451 m_rMarksEnd.clear();
454 void DocxAttributeOutput::StartField_Impl( FieldInfos& rInfos, sal_Bool bWriteRun )
456 if ( rInfos.pField && rInfos.eType == ww::eUNKNOWN )
458 // Expand unsupported fields
459 RunText( rInfos.pField->Expand( ) );
461 else if ( rInfos.eType != ww::eNONE ) // HYPERLINK fields are just commands
463 if ( bWriteRun )
464 m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
466 if ( rInfos.eType == ww::eFORMDROPDOWN )
468 m_pSerializer->startElementNS( XML_w, XML_fldChar,
469 FSNS( XML_w, XML_fldCharType ), "begin",
470 FSEND );
472 const SwDropDownField& rFld2 = *(SwDropDownField*)rInfos.pField;
473 uno::Sequence<rtl::OUString> aItems =
474 rFld2.GetItemSequence();
475 GetExport().DoComboBox(rFld2.GetName(),
476 rFld2.GetHelp(),
477 rFld2.GetToolTip(),
478 rFld2.GetSelectedItem(), aItems);
480 m_pSerializer->endElementNS( XML_w, XML_fldChar );
482 if ( bWriteRun )
483 m_pSerializer->endElementNS( XML_w, XML_r );
486 else
488 // Write the field start
489 m_pSerializer->singleElementNS( XML_w, XML_fldChar,
490 FSNS( XML_w, XML_fldCharType ), "begin",
491 FSEND );
493 if ( bWriteRun )
494 m_pSerializer->endElementNS( XML_w, XML_r );
496 // The hyperlinks fields can't be expanded: the value is
497 // normally in the text run
498 if ( !rInfos.pField )
499 CmdField_Impl( rInfos );
504 void DocxAttributeOutput::DoWriteCmd( String& rCmd )
506 // Write the Field command
507 m_pSerializer->startElementNS( XML_w, XML_instrText, FSEND );
508 m_pSerializer->writeEscaped( OUString( rCmd ) );
509 m_pSerializer->endElementNS( XML_w, XML_instrText );
513 void DocxAttributeOutput::CmdField_Impl( FieldInfos& rInfos )
515 m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
516 xub_StrLen nNbToken = rInfos.sCmd.GetTokenCount( '\t' );
518 for ( xub_StrLen i = 0; i < nNbToken; i++ )
520 String sToken = rInfos.sCmd.GetToken( i, '\t' );
521 // Write the Field command
522 DoWriteCmd( sToken );
524 // Replace tabs by </instrText><tab/><instrText>
525 if ( i < ( nNbToken - 1 ) )
526 RunText( String::CreateFromAscii( "\t" ) );
529 m_pSerializer->endElementNS( XML_w, XML_r );
532 // Write the Field separator
533 m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
534 m_pSerializer->singleElementNS( XML_w, XML_fldChar,
535 FSNS( XML_w, XML_fldCharType ), "separate",
536 FSEND );
537 m_pSerializer->endElementNS( XML_w, XML_r );
540 void DocxAttributeOutput::EndField_Impl( FieldInfos& rInfos )
542 // The command has to be written before for the hyperlinks
543 if ( rInfos.pField )
545 CmdField_Impl( rInfos );
548 // Write the bookmark start if any
549 OUString aBkmName( m_sFieldBkm );
550 if ( aBkmName.getLength( ) > 0 )
552 m_pSerializer->singleElementNS( XML_w, XML_bookmarkStart,
553 FSNS( XML_w, XML_id ), OString::valueOf( sal_Int32( m_nNextMarkId ) ).getStr( ),
554 FSNS( XML_w, XML_name ), OUStringToOString( aBkmName, RTL_TEXTENCODING_UTF8 ).getStr( ),
555 FSEND );
558 if (rInfos.pField ) // For hyperlinks and TOX
560 // Write the Field latest value
561 m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
563 // Find another way for hyperlinks
564 RunText( rInfos.pField->Expand( ) );
565 m_pSerializer->endElementNS( XML_w, XML_r );
568 // Write the bookmark end if any
569 if ( aBkmName.getLength( ) > 0 )
571 m_pSerializer->singleElementNS( XML_w, XML_bookmarkEnd,
572 FSNS( XML_w, XML_id ), OString::valueOf( sal_Int32( m_nNextMarkId ) ).getStr( ),
573 FSEND );
575 m_nNextMarkId++;
578 // Write the Field end
579 m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
580 m_pSerializer->singleElementNS( XML_w, XML_fldChar,
581 FSNS( XML_w, XML_fldCharType ), "end",
582 FSEND );
583 m_pSerializer->endElementNS( XML_w, XML_r );
586 // Write the ref field if a bookmark had to be set and the field
587 // should be visible
588 if ( rInfos.pField )
590 USHORT nSubType = rInfos.pField->GetSubType( );
591 bool bIsSetField = rInfos.pField->GetTyp( )->Which( ) == RES_SETEXPFLD;
592 bool bShowRef = ( !bIsSetField || ( nSubType & nsSwExtendedSubType::SUB_INVISIBLE ) ) ? false : true;
594 if ( ( m_sFieldBkm.Len( ) > 0 ) && bShowRef )
596 // Write the field beginning
597 m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
598 m_pSerializer->singleElementNS( XML_w, XML_fldChar,
599 FSNS( XML_w, XML_fldCharType ), "begin",
600 FSEND );
601 m_pSerializer->endElementNS( XML_w, XML_r );
603 rInfos.sCmd = FieldString( ww::eREF );
604 rInfos.sCmd.APPEND_CONST_ASC( "\"" );
605 rInfos.sCmd += m_sFieldBkm;
606 rInfos.sCmd.APPEND_CONST_ASC( "\" " );
608 // Clean the field bookmark data to avoid infinite loop
609 m_sFieldBkm = String( );
611 // Write the end of the field
612 EndField_Impl( rInfos );
617 void DocxAttributeOutput::StartRunProperties()
619 // postpone the output so that we can later [in EndRunProperties()]
620 // prepend the properties before the text
621 m_pSerializer->mark();
623 m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
625 InitCollectedRunProperties();
628 void DocxAttributeOutput::InitCollectedRunProperties()
630 m_pFontsAttrList = NULL;
631 m_pEastAsianLayoutAttrList = NULL;
632 m_pCharLangAttrList = NULL;
635 void DocxAttributeOutput::WriteCollectedRunProperties()
637 // Write all differed properties
638 if ( m_pFontsAttrList )
640 XFastAttributeListRef xAttrList( m_pFontsAttrList );
641 m_pFontsAttrList = NULL;
643 m_pSerializer->singleElementNS( XML_w, XML_rFonts, xAttrList );
646 if ( m_pEastAsianLayoutAttrList )
648 XFastAttributeListRef xAttrList( m_pEastAsianLayoutAttrList );
649 m_pEastAsianLayoutAttrList = NULL;
651 m_pSerializer->singleElementNS( XML_w, XML_eastAsianLayout, xAttrList );
654 if ( m_pCharLangAttrList )
656 XFastAttributeListRef xAttrList( m_pCharLangAttrList );
657 m_pCharLangAttrList = NULL;
659 m_pSerializer->singleElementNS( XML_w, XML_lang, xAttrList );
663 void DocxAttributeOutput::EndRunProperties( const SwRedlineData* /*pRedlineData*/ )
665 WriteCollectedRunProperties();
667 m_pSerializer->endElementNS( XML_w, XML_rPr );
669 // write footnotes/endnotes if we have any
670 FootnoteEndnoteReference();
672 // merge the properties _before_ the run text (strictly speaking, just
673 // after the start of the run)
674 m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND );
677 /** Output sal_Unicode* as a run text (<t>the text</t>).
679 When bMove is true, update rBegin to point _after_ the end of the text +
680 1, meaning that it skips one character after the text. This is to make
681 the switch in DocxAttributeOutput::RunText() nicer ;-)
683 static void impl_WriteRunText( FSHelperPtr pSerializer, sal_Int32 nTextToken,
684 const sal_Unicode* &rBegin, const sal_Unicode* pEnd, bool bMove = true )
686 const sal_Unicode *pBegin = rBegin;
688 // skip one character after the end
689 if ( bMove )
690 rBegin = pEnd + 1;
692 if ( pBegin >= pEnd )
693 return; // we want to write at least one character
695 // we have to add 'preserve' when starting/ending with space
696 if ( *pBegin == sal_Unicode( ' ' ) || *( pEnd - 1 ) == sal_Unicode( ' ' ) )
698 pSerializer->startElementNS( XML_w, nTextToken, FSNS( XML_xml, XML_space ), "preserve", FSEND );
700 else
701 pSerializer->startElementNS( XML_w, nTextToken, FSEND );
703 pSerializer->writeEscaped( OUString( pBegin, pEnd - pBegin ) );
705 pSerializer->endElementNS( XML_w, nTextToken );
708 void DocxAttributeOutput::RunText( const String& rText, rtl_TextEncoding /*eCharSet*/ )
710 OUString aText( rText );
712 // one text can be split into more <w:t>blah</w:t>'s by line breaks etc.
713 const sal_Unicode *pBegin = aText.getStr();
714 const sal_Unicode *pEnd = pBegin + aText.getLength();
716 // the text run is usually XML_t, with the exception of the deleted text
717 sal_Int32 nTextToken = XML_t;
718 if ( m_pRedlineData && m_pRedlineData->GetType() == nsRedlineType_t::REDLINE_DELETE )
719 nTextToken = XML_delText;
721 for ( const sal_Unicode *pIt = pBegin; pIt < pEnd; ++pIt )
723 switch ( *pIt )
725 case 0x09: // tab
726 impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt );
727 m_pSerializer->singleElementNS( XML_w, XML_tab, FSEND );
728 break;
729 case 0x0b: // line break
730 impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt );
731 m_pSerializer->singleElementNS( XML_w, XML_br, FSEND );
732 break;
733 default:
734 if ( *pIt < 0x0020 ) // filter out the control codes
736 impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt );
737 #if OSL_DEBUG_LEVEL > 0
738 fprintf( stderr, "Ignored control code %x in a text run.", *pIt );
739 #endif
741 break;
745 impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pEnd, false );
748 void DocxAttributeOutput::RawText( const String& /*rText*/, bool /*bForceUnicode*/, rtl_TextEncoding /*eCharSet*/ )
750 #if OSL_DEBUG_LEVEL > 0
751 fprintf( stderr, "TODO DocxAttributeOutput::RawText( const String& rText, bool bForceUnicode, rtl_TextEncoding eCharSet )\n" );
752 #endif
755 void DocxAttributeOutput::StartRuby( const SwTxtNode& /*rNode*/, const SwFmtRuby& /*rRuby*/ )
757 #if OSL_DEBUG_LEVEL > 0
758 fprintf( stderr, "TODO DocxAttributeOutput::StartRuby( const SwTxtNode& rNode, const SwFmtRuby& rRuby )\n" );
759 #endif
762 void DocxAttributeOutput::EndRuby()
764 #if OSL_DEBUG_LEVEL > 0
765 fprintf( stderr, "TODO DocxAttributeOutput::EndRuby()\n" );
766 #endif
769 bool DocxAttributeOutput::AnalyzeURL( const String& rUrl, const String& rTarget, String* pLinkURL, String* pMark )
771 bool bBookMarkOnly = AttributeOutputBase::AnalyzeURL( rUrl, rTarget, pLinkURL, pMark );
773 String sURL = *pLinkURL;
774 String sMark = *pMark;
776 bool bOutputField = sMark.Len();
778 if ( bOutputField )
780 if ( bBookMarkOnly )
781 sURL = FieldString( ww::eHYPERLINK );
782 else
784 String sFld( FieldString( ww::eHYPERLINK ) );
785 sFld.APPEND_CONST_ASC( "\"" );
786 sURL.Insert( sFld, 0 );
787 sURL += '\"';
790 if ( sMark.Len() )
791 ( ( sURL.APPEND_CONST_ASC( " \\l \"" ) ) += sMark ) += '\"';
793 if ( rTarget.Len() )
794 ( sURL.APPEND_CONST_ASC( " \\n " ) ) += rTarget;
797 *pLinkURL = sURL;
798 *pMark = sMark;
800 return bBookMarkOnly;
803 bool DocxAttributeOutput::StartURL( const String& rUrl, const String& rTarget )
805 String sMark;
806 String sUrl;
808 bool bBookmarkOnly = AnalyzeURL( rUrl, rTarget, &sUrl, &sMark );
810 if ( sMark.Len() && !bBookmarkOnly )
812 m_rExport.OutputField( NULL, ww::eHYPERLINK, sUrl );
814 else
816 // Output a hyperlink XML element
818 m_pHyperlinkAttrList = m_pSerializer->createAttrList();
819 if ( !bBookmarkOnly )
821 OUString osUrl( sUrl );
823 ::rtl::OString sId = m_rExport.AddRelation(
824 S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" ),
825 osUrl, S("External") );
826 m_pHyperlinkAttrList->add( FSNS( XML_r, XML_id), sId.getStr());
828 else
829 m_pHyperlinkAttrList->add( FSNS( XML_w, XML_anchor ),
830 OUStringToOString( OUString( sMark ), RTL_TEXTENCODING_UTF8 ).getStr( ) );
832 OUString sTarget( rTarget );
833 if ( sTarget.getLength( ) > 0 )
835 OString soTarget = OUStringToOString( sTarget, RTL_TEXTENCODING_UTF8 );
836 m_pHyperlinkAttrList->add(FSNS( XML_w, XML_tgtFrame ), soTarget.getStr());
840 return true;
843 bool DocxAttributeOutput::EndURL()
845 return true;
848 void DocxAttributeOutput::FieldVanish( const String& rTxt, ww::eField eType )
850 WriteField_Impl( NULL, eType, rTxt, WRITEFIELD_ALL );
853 void DocxAttributeOutput::Redline( const SwRedlineData* /*pRedline*/ )
855 #if OSL_DEBUG_LEVEL > 0
856 fprintf( stderr, "TODO DocxAttributeOutput::Redline( const SwRedlineData* pRedline )\n" );
857 #endif
860 /// Append the number as 2-digit when less than 10.
861 static void impl_AppendTwoDigits( OStringBuffer &rBuffer, sal_Int32 nNum )
863 if ( nNum < 0 || nNum > 99 )
865 rBuffer.append( "00" );
866 return;
869 if ( nNum < 10 )
870 rBuffer.append( '0' );
872 rBuffer.append( nNum );
875 /** Convert DateTime to xsd::dateTime string.
877 I guess there must be an implementation of this somewhere in OOo, but I failed
878 to find it, unfortunately :-(
880 static OString impl_DateTimeToOString( const DateTime& rDateTime )
882 DateTime aInUTC( rDateTime );
883 aInUTC.ConvertToUTC();
885 OStringBuffer aBuffer( 25 );
886 aBuffer.append( sal_Int32( aInUTC.GetYear() ) );
887 aBuffer.append( '-' );
889 impl_AppendTwoDigits( aBuffer, aInUTC.GetMonth() );
890 aBuffer.append( '-' );
892 impl_AppendTwoDigits( aBuffer, aInUTC.GetDay() );
893 aBuffer.append( 'T' );
895 impl_AppendTwoDigits( aBuffer, aInUTC.GetHour() );
896 aBuffer.append( ':' );
898 impl_AppendTwoDigits( aBuffer, aInUTC.GetMin() );
899 aBuffer.append( ':' );
901 impl_AppendTwoDigits( aBuffer, aInUTC.GetSec() );
902 aBuffer.append( 'Z' ); // we are in UTC
904 return aBuffer.makeStringAndClear();
907 void DocxAttributeOutput::StartRedline( const SwRedlineData* pRedlineData )
909 m_pRedlineData = pRedlineData;
911 if ( !m_pRedlineData )
912 return;
914 // FIXME check if it's necessary to travel over the Next()'s in pRedlineData
916 OString aId( OString::valueOf( m_nRedlineId++ ) );
918 const String &rAuthor( SW_MOD()->GetRedlineAuthor( pRedlineData->GetAuthor() ) );
919 OString aAuthor( OUStringToOString( rAuthor, RTL_TEXTENCODING_UTF8 ) );
921 OString aDate( impl_DateTimeToOString( pRedlineData->GetTimeStamp() ) );
923 switch ( pRedlineData->GetType() )
925 case nsRedlineType_t::REDLINE_INSERT:
926 m_pSerializer->startElementNS( XML_w, XML_ins,
927 FSNS( XML_w, XML_id ), aId.getStr(),
928 FSNS( XML_w, XML_author ), aAuthor.getStr(),
929 FSNS( XML_w, XML_date ), aDate.getStr(),
930 FSEND );
931 break;
933 case nsRedlineType_t::REDLINE_DELETE:
934 m_pSerializer->startElementNS( XML_w, XML_del,
935 FSNS( XML_w, XML_id ), aId.getStr(),
936 FSNS( XML_w, XML_author ), aAuthor.getStr(),
937 FSNS( XML_w, XML_date ), aDate.getStr(),
938 FSEND );
939 break;
941 case nsRedlineType_t::REDLINE_FORMAT:
942 #if OSL_DEBUG_LEVEL > 0
943 fprintf( stderr, "TODO DocxAttributeOutput::StartRedline()\n" );
944 #endif
945 default:
946 break;
950 void DocxAttributeOutput::EndRedline()
952 if ( !m_pRedlineData )
953 return;
955 switch ( m_pRedlineData->GetType() )
957 case nsRedlineType_t::REDLINE_INSERT:
958 m_pSerializer->endElementNS( XML_w, XML_ins );
959 break;
961 case nsRedlineType_t::REDLINE_DELETE:
962 m_pSerializer->endElementNS( XML_w, XML_del );
963 break;
965 case nsRedlineType_t::REDLINE_FORMAT:
966 #if OSL_DEBUG_LEVEL > 0
967 fprintf( stderr, "TODO DocxAttributeOutput::EndRedline()\n" );
968 #endif
969 break;
970 default:
971 break;
974 m_pRedlineData = NULL;
977 void DocxAttributeOutput::FormatDrop( const SwTxtNode& /*rNode*/, const SwFmtDrop& /*rSwFmtDrop*/, USHORT /*nStyle*/, ww8::WW8TableNodeInfo::Pointer_t /*pTextNodeInfo*/, ww8::WW8TableNodeInfoInner::Pointer_t )
979 #if OSL_DEBUG_LEVEL > 0
980 fprintf( stderr, "TODO DocxAttributeOutput::FormatDrop( const SwTxtNode& rNode, const SwFmtDrop& rSwFmtDrop, USHORT nStyle )\n" );
981 #endif
984 void DocxAttributeOutput::ParagraphStyle( USHORT nStyle )
986 OString aStyleId( "style" );
987 aStyleId += OString::valueOf( sal_Int32( nStyle ) );
989 m_pSerializer->singleElementNS( XML_w, XML_pStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND );
992 #if 0
993 void DocxAttributeOutput::InTable()
995 #if OSL_DEBUG_LEVEL > 0
996 fprintf( stderr, "TODO DocxAttributeOutput::InTable()\n" );
997 #endif
1001 void DocxAttributeOutput::TableRowProperties( bool /*bHeader*/, long /*nCellHeight*/, bool /*bCannotSplit*/, bool /*bRightToLeft*/ )
1003 #if OSL_DEBUG_LEVEL > 0
1004 fprintf( stderr, "TODO DocxAttributeOutput::TableRowProperties()\n" );
1005 #endif
1007 #endif
1009 static OString impl_ConvertColor( const Color &rColor )
1011 OString color( "auto" );
1012 if ( rColor.GetColor() != COL_AUTO )
1014 const char pHexDigits[] = "0123456789ABCDEF";
1015 char pBuffer[] = "000000";
1017 pBuffer[0] = pHexDigits[ ( rColor.GetRed() >> 4 ) & 0x0F ];
1018 pBuffer[1] = pHexDigits[ rColor.GetRed() & 0x0F ];
1019 pBuffer[2] = pHexDigits[ ( rColor.GetGreen() >> 4 ) & 0x0F ];
1020 pBuffer[3] = pHexDigits[ rColor.GetGreen() & 0x0F ];
1021 pBuffer[4] = pHexDigits[ ( rColor.GetBlue() >> 4 ) & 0x0F ];
1022 pBuffer[5] = pHexDigits[ rColor.GetBlue() & 0x0F ];
1024 color = OString( pBuffer );
1026 return color;
1029 static void impl_borderLine( FSHelperPtr pSerializer, sal_Int32 elementToken, const SvxBorderLine* pBorderLine, USHORT nDist )
1031 FastAttributeList* pAttr = pSerializer->createAttrList();
1033 USHORT inW = pBorderLine->GetInWidth();
1034 USHORT outW = pBorderLine->GetOutWidth();
1035 USHORT nWidth = inW + outW;
1037 // Compute val attribute value
1038 // Can be one of:
1039 // single, double,
1040 // basicWideOutline, basicWideInline
1041 // OOXml also supports those types of borders, but we'll try to play with the first ones.
1042 // thickThinMediumGap, thickThinLargeGap, thickThinSmallGap
1043 // thinThickLargeGap, thinThickMediumGap, thinThickSmallGap
1044 const char* pVal = "single";
1045 if ( pBorderLine->isDouble() )
1047 if ( inW == outW )
1048 pVal = ( sal_Char* )"double";
1049 else if ( inW > outW )
1051 pVal = ( sal_Char* )"thinThickMediumGap";
1053 else if ( inW < outW )
1055 pVal = ( sal_Char* )"thickThinMediumGap";
1059 pAttr->add( FSNS( XML_w, XML_val ), OString( pVal ) );
1061 // Compute the sz attribute
1063 // The unit is the 8th of point
1064 nWidth = sal_Int32( nWidth / 2.5 );
1065 USHORT nMinWidth = 2;
1066 USHORT nMaxWidth = 96;
1068 if ( nWidth > nMaxWidth )
1069 nWidth = nMaxWidth;
1070 else if ( nWidth < nMinWidth )
1071 nWidth = nMinWidth;
1073 pAttr->add( FSNS( XML_w, XML_sz ), OString::valueOf( sal_Int32( nWidth ) ) );
1075 // Get the distance (in pt)
1076 pAttr->add( FSNS( XML_w, XML_space ), OString::valueOf( sal_Int32( nDist / 20 ) ) );
1078 // Get the color code as an RRGGBB hex value
1079 OString sColor( impl_ConvertColor( pBorderLine->GetColor( ) ) );
1080 pAttr->add( FSNS( XML_w, XML_color ), sColor );
1082 XFastAttributeListRef xAttrs( pAttr );
1083 pSerializer->singleElementNS( XML_w, elementToken, xAttrs );
1086 static void impl_pageBorders( FSHelperPtr pSerializer, const SvxBoxItem& rBox )
1088 static const USHORT aBorders[] =
1090 BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
1093 static const USHORT aXmlElements[] =
1095 XML_top, XML_left, XML_bottom, XML_right
1097 const USHORT* pBrd = aBorders;
1098 for( int i = 0; i < 4; ++i, ++pBrd )
1100 const SvxBorderLine* pLn = rBox.GetLine( *pBrd );
1101 if ( pLn )
1102 impl_borderLine( pSerializer, aXmlElements[i], pLn, 0 );
1106 void DocxAttributeOutput::TableCellProperties( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1108 m_pSerializer->startElementNS( XML_w, XML_tcPr, FSEND );
1110 const SwTableBox *pTblBox = pTableTextNodeInfoInner->getTableBox( );
1112 // The cell borders
1113 m_pSerializer->startElementNS( XML_w, XML_tcBorders, FSEND );
1114 SwFrmFmt *pFmt = pTblBox->GetFrmFmt( );
1115 impl_pageBorders( m_pSerializer, pFmt->GetBox( ) );
1116 m_pSerializer->endElementNS( XML_w, XML_tcBorders );
1118 // Vertical merges
1119 long vSpan = pTblBox->getRowSpan( );
1120 if ( vSpan > 1 )
1122 m_pSerializer->singleElementNS( XML_w, XML_vMerge,
1123 FSNS( XML_w, XML_val ), "restart",
1124 FSEND );
1126 else if ( vSpan < 0 )
1128 m_pSerializer->singleElementNS( XML_w, XML_vMerge,
1129 FSNS( XML_w, XML_val ), "continue",
1130 FSEND );
1133 // Horizontal spans
1134 const SwWriteTableRows& aRows = m_pTableWrt->GetRows( );
1135 SwWriteTableRow *pRow = aRows[ pTableTextNodeInfoInner->getRow( ) ];
1136 SwWriteTableCell *pCell = pRow->GetCells( )[ pTableTextNodeInfoInner->getCell( ) ];
1138 USHORT nColSpan = pCell->GetColSpan();
1139 if ( nColSpan > 1 )
1140 m_pSerializer->singleElementNS( XML_w, XML_gridSpan,
1141 FSNS( XML_w, XML_val ), OString::valueOf( sal_Int32( nColSpan ) ).getStr(),
1142 FSEND );
1144 TableBackgrounds( pTableTextNodeInfoInner );
1146 // Cell prefered width
1147 SwTwips nWidth = GetGridCols( pTableTextNodeInfoInner )[ pTableTextNodeInfoInner->getCell() ];
1148 m_pSerializer->singleElementNS( XML_w, XML_tcW,
1149 FSNS( XML_w, XML_w ), OString::valueOf( sal_Int32( nWidth ) ).getStr( ),
1150 FSNS( XML_w, XML_type ), "dxa",
1151 FSEND );
1153 // Cell margins
1154 m_pSerializer->startElementNS( XML_w, XML_tcMar, FSEND );
1155 const SvxBoxItem& rBox = pFmt->GetBox( );
1156 static const USHORT aBorders[] =
1158 BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
1161 static const USHORT aXmlElements[] =
1163 XML_top, XML_left, XML_bottom, XML_right
1165 const USHORT* pBrd = aBorders;
1166 for( int i = 0; i < 4; ++i, ++pBrd )
1168 sal_Int32 nDist = sal_Int32( rBox.GetDistance( *pBrd ) );
1169 m_pSerializer->singleElementNS( XML_w, aXmlElements[i],
1170 FSNS( XML_w, XML_w ), OString::valueOf( nDist ).getStr( ),
1171 FSNS( XML_w, XML_type ), "dxa",
1172 FSEND );
1175 m_pSerializer->endElementNS( XML_w, XML_tcMar );
1177 TableVerticalCell( pTableTextNodeInfoInner );
1179 m_pSerializer->endElementNS( XML_w, XML_tcPr );
1182 void DocxAttributeOutput::InitTableHelper( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1184 sal_uInt32 nPageSize = 0;
1185 bool bRelBoxSize = false;
1187 // Create the SwWriteTable instance to use col spans (and maybe other infos)
1188 GetTablePageSize( pTableTextNodeInfoInner, nPageSize, bRelBoxSize );
1190 const SwTable* pTable = pTableTextNodeInfoInner->getTable( );
1191 const SwFrmFmt *pFmt = pTable->GetFrmFmt( );
1192 SwTwips nTblSz = pFmt->GetFrmSize( ).GetWidth( );
1194 const SwHTMLTableLayout *pLayout = pTable->GetHTMLTableLayout();
1195 if( pLayout && pLayout->IsExportable() )
1196 m_pTableWrt = new SwWriteTable( pLayout );
1197 else
1198 m_pTableWrt = new SwWriteTable( pTable->GetTabLines(), (USHORT)nPageSize,
1199 (USHORT)nTblSz, false);
1202 void DocxAttributeOutput::StartTable( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1204 m_pSerializer->startElementNS( XML_w, XML_tbl, FSEND );
1206 InitTableHelper( pTableTextNodeInfoInner );
1207 TableDefinition( pTableTextNodeInfoInner );
1210 void DocxAttributeOutput::EndTable()
1212 m_pSerializer->endElementNS( XML_w, XML_tbl );
1214 if ( m_nTableDepth > 0 )
1215 --m_nTableDepth;
1217 // We closed the table; if it is a nested table, the cell that contains it
1218 // still continues
1219 m_bTableCellOpen = true;
1221 // Cleans the table helper
1222 delete m_pTableWrt, m_pTableWrt = NULL;
1225 void DocxAttributeOutput::StartTableRow( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1227 m_pSerializer->startElementNS( XML_w, XML_tr, FSEND );
1229 // Output the row properties
1230 m_pSerializer->startElementNS( XML_w, XML_trPr, FSEND );
1232 // Header row: tblHeader
1233 const SwTable *pTable = pTableTextNodeInfoInner->getTable( );
1234 if ( pTable->GetRowsToRepeat( ) > pTableTextNodeInfoInner->getRow( ) )
1235 m_pSerializer->singleElementNS( XML_w, XML_tblHeader,
1236 FSNS( XML_w, XML_val ), "true",
1237 FSEND );
1239 TableHeight( pTableTextNodeInfoInner );
1240 TableCanSplit( pTableTextNodeInfoInner );
1242 m_pSerializer->endElementNS( XML_w, XML_trPr );
1245 void DocxAttributeOutput::EndTableRow( )
1247 m_pSerializer->endElementNS( XML_w, XML_tr );
1251 void DocxAttributeOutput::StartTableCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1253 if ( !m_pTableWrt )
1254 InitTableHelper( pTableTextNodeInfoInner );
1256 m_pSerializer->startElementNS( XML_w, XML_tc, FSEND );
1258 // Write the cell properties here
1259 TableCellProperties( pTableTextNodeInfoInner );
1261 m_bTableCellOpen = true;
1264 void DocxAttributeOutput::EndTableCell( )
1266 m_pSerializer->endElementNS( XML_w, XML_tc );
1268 m_bTableCellOpen = false;
1271 void DocxAttributeOutput::TableInfoCell( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
1275 void DocxAttributeOutput::TableInfoRow( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfo*/ )
1279 void DocxAttributeOutput::TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1281 // Write the table properties
1282 m_pSerializer->startElementNS( XML_w, XML_tblPr, FSEND );
1284 sal_uInt32 nPageSize = 0;
1285 bool bRelBoxSize = false;
1287 // Create the SwWriteTable instance to use col spans (and maybe other infos)
1288 GetTablePageSize( pTableTextNodeInfoInner, nPageSize, bRelBoxSize );
1290 // Output the table prefered width
1291 if ( nPageSize != 0 )
1292 m_pSerializer->singleElementNS( XML_w, XML_tblW,
1293 FSNS( XML_w, XML_w ), OString::valueOf( sal_Int32( nPageSize ) ).getStr( ),
1294 FSNS( XML_w, XML_type ), "dxa",
1295 FSEND );
1297 // Output the table borders
1298 TableDefaultBorders( pTableTextNodeInfoInner );
1299 TableBidi( pTableTextNodeInfoInner );
1301 // Output the table alignement
1302 const SwTable *pTable = pTableTextNodeInfoInner->getTable();
1303 SwFrmFmt *pTblFmt = pTable->GetFrmFmt( );
1304 const char* pJcVal;
1305 sal_Int32 nIndent = 0;
1306 switch ( pTblFmt->GetHoriOrient( ).GetHoriOrient( ) )
1308 case text::HoriOrientation::CENTER:
1309 pJcVal = "center";
1310 break;
1311 case text::HoriOrientation::RIGHT:
1312 pJcVal = "right";
1313 break;
1314 default:
1315 case text::HoriOrientation::NONE:
1316 case text::HoriOrientation::LEFT_AND_WIDTH:
1318 pJcVal = "left";
1319 nIndent = sal_Int32( pTblFmt->GetLRSpace( ).GetLeft( ) );
1320 break;
1323 m_pSerializer->singleElementNS( XML_w, XML_jc,
1324 FSNS( XML_w, XML_val ), pJcVal,
1325 FSEND );
1327 // Table indent
1328 if ( nIndent != 0 )
1329 m_pSerializer->singleElementNS( XML_w, XML_tblInd,
1330 FSNS( XML_w, XML_w ), OString::valueOf( nIndent ).getStr( ),
1331 FSNS( XML_w, XML_type ), "dxa",
1332 FSEND );
1334 m_pSerializer->endElementNS( XML_w, XML_tblPr );
1337 // Write the table grid infos
1338 m_pSerializer->startElementNS( XML_w, XML_tblGrid, FSEND );
1340 std::vector<SwTwips> gridCols = GetGridCols( pTableTextNodeInfoInner );
1341 for ( std::vector<SwTwips>::const_iterator it = gridCols.begin(); it != gridCols.end(); ++it )
1342 m_pSerializer->singleElementNS( XML_w, XML_gridCol,
1343 FSNS( XML_w, XML_w ), OString::valueOf( sal_Int32( *it ) ).getStr( ),
1344 FSEND );
1346 m_pSerializer->endElementNS( XML_w, XML_tblGrid );
1349 void DocxAttributeOutput::TableDefaultBorders( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1351 const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
1352 const SwFrmFmt * pFrmFmt = pTabBox->GetFrmFmt();
1354 // the defaults of the table are taken from the top-left cell
1355 m_pSerializer->startElementNS( XML_w, XML_tblBorders, FSEND );
1356 impl_pageBorders( m_pSerializer, pFrmFmt->GetBox( ) );
1357 m_pSerializer->endElementNS( XML_w, XML_tblBorders );
1360 void DocxAttributeOutput::TableBackgrounds( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1362 const SwTableBox *pTblBox = pTableTextNodeInfoInner->getTableBox( );
1363 const SwFrmFmt *pFmt = pTblBox->GetFrmFmt( );
1364 const SfxPoolItem *pI = NULL;
1366 Color aColor;
1367 if ( SFX_ITEM_ON == pFmt->GetAttrSet().GetItemState( RES_BACKGROUND, false, &pI ) )
1368 aColor = dynamic_cast<const SvxBrushItem *>(pI)->GetColor();
1369 else
1370 aColor = COL_AUTO;
1372 OString sColor = impl_ConvertColor( aColor );
1373 m_pSerializer->singleElementNS( XML_w, XML_shd,
1374 FSNS( XML_w, XML_fill ), sColor.getStr( ),
1375 FSEND );
1378 void DocxAttributeOutput::TableHeight( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1380 const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
1381 const SwTableLine * pTabLine = pTabBox->GetUpper();
1382 const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();
1384 const SwFmtFrmSize& rLSz = pLineFmt->GetFrmSize();
1385 if ( ATT_VAR_SIZE != rLSz.GetHeightSizeType() && rLSz.GetHeight() )
1387 sal_Int32 nHeight = rLSz.GetHeight();
1388 const char *pRule = NULL;
1390 switch ( rLSz.GetHeightSizeType() )
1392 case ATT_FIX_SIZE: pRule = "exact"; break;
1393 case ATT_MIN_SIZE: pRule = "atLeast"; break;
1394 default: break;
1397 if ( pRule )
1398 m_pSerializer->singleElementNS( XML_w, XML_trHeight,
1399 FSNS( XML_w, XML_val ), OString::valueOf( nHeight ).getStr( ),
1400 FSNS( XML_w, XML_hRule ), pRule,
1401 FSEND );
1405 void DocxAttributeOutput::TableCanSplit( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1407 const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
1408 const SwTableLine * pTabLine = pTabBox->GetUpper();
1409 const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();
1411 const SwFmtRowSplit& rSplittable = pLineFmt->GetRowSplit( );
1412 const char* pCantSplit = ( !rSplittable.GetValue( ) ) ? "on" : "off";
1414 m_pSerializer->singleElementNS( XML_w, XML_cantSplit,
1415 FSNS( XML_w, XML_val ), pCantSplit,
1416 FSEND );
1419 void DocxAttributeOutput::TableBidi( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1421 const SwTable * pTable = pTableTextNodeInfoInner->getTable();
1422 const SwFrmFmt * pFrmFmt = pTable->GetFrmFmt();
1424 if ( m_rExport.TrueFrameDirection( *pFrmFmt ) == FRMDIR_HORI_RIGHT_TOP )
1426 m_pSerializer->singleElementNS( XML_w, XML_bidiVisual,
1427 FSNS( XML_w, XML_val ), "on",
1428 FSEND );
1432 void DocxAttributeOutput::TableVerticalCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
1434 const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
1435 const SwFrmFmt *pFrmFmt = pTabBox->GetFrmFmt( );
1437 if ( FRMDIR_VERT_TOP_RIGHT == m_rExport.TrueFrameDirection( *pFrmFmt ) )
1438 m_pSerializer->singleElementNS( XML_w, XML_textDirection,
1439 FSNS( XML_w, XML_val ), "tbRl",
1440 FSEND );
1443 void DocxAttributeOutput::TableNodeInfo( ww8::WW8TableNodeInfo::Pointer_t /*pNodeInfo*/ )
1445 #if OSL_DEBUG_LEVEL > 0
1446 fprintf( stderr, "TODO: DocxAttributeOutput::TableNodeInfo( ww8::WW8TableNodeInfo::Pointer_t pNodeInfo )\n" );
1447 #endif
1450 void DocxAttributeOutput::TableNodeInfoInner( ww8::WW8TableNodeInfoInner::Pointer_t pNodeInfoInner )
1452 // This is called when the nested table ends in a cell, and there's no
1453 // paragraph benhind that; so we must check for the ends of cell, rows,
1454 // tables
1455 // ['true' to write an empty paragraph, MS Word insists on that]
1456 FinishTableRowCell( pNodeInfoInner, true );
1459 void DocxAttributeOutput::TableOrientation( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
1461 #if OSL_DEBUG_LEVEL > 0
1462 fprintf( stderr, "TODO: DocxAttributeOutput::TableOrientation( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )\n" );
1463 #endif
1466 void DocxAttributeOutput::TableRowEnd( sal_uInt32 /*nDepth*/ )
1468 #if OSL_DEBUG_LEVEL > 0
1469 fprintf( stderr, "TODO: DocxAttributeOutput::TableRowEnd( sal_uInt32 nDepth = 1 )\n" );
1470 #endif
1473 void DocxAttributeOutput::StartStyles()
1475 m_pSerializer->startElementNS( XML_w, XML_styles,
1476 FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
1477 FSEND );
1480 void DocxAttributeOutput::EndStyles( USHORT /*nNumberOfStyles*/ )
1482 m_pSerializer->endElementNS( XML_w, XML_styles );
1485 void DocxAttributeOutput::DefaultStyle( USHORT nStyle )
1487 // are these the values of enum ww::sti (see ../inc/wwstyles.hxx)?
1488 #if OSL_DEBUG_LEVEL > 0
1489 fprintf( stderr, "TODO DocxAttributeOutput::DefaultStyle( USHORT nStyle )- %d\n", nStyle );
1490 #else
1491 (void) nStyle; // to quiet the warning
1492 #endif
1495 void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode& rGrfNode, const Size& rSize )
1497 #if OSL_DEBUG_LEVEL > 0
1498 fprintf( stderr, "TODO DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode& rGrfNode, const Size& rSize ) - some stuff still missing\n" );
1499 #endif
1500 // create the relation ID
1501 OString aRelId;
1502 sal_Int32 nImageType;
1503 if ( rGrfNode.IsLinkedFile() )
1505 // linked image, just create the relation
1506 String aFileName;
1507 rGrfNode.GetFileFilterNms( &aFileName, 0 );
1509 // TODO Convert the file name to relative for better interoperability
1511 aRelId = m_rExport.AddRelation(
1512 S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" ),
1513 OUString( aFileName ),
1514 S( "External" ) );
1516 nImageType = XML_link;
1518 else
1520 // inline, we also have to write the image itself
1521 Graphic& rGraphic = const_cast< Graphic& >( rGrfNode.GetGrf() );
1523 m_rDrawingML.SetFS( m_pSerializer ); // to be sure that we write to the right stream
1524 OUString aImageId = m_rDrawingML.WriteImage( rGraphic );
1526 aRelId = OUStringToOString( aImageId, RTL_TEXTENCODING_UTF8 );
1528 nImageType = XML_embed;
1531 if ( aRelId.getLength() == 0 )
1532 return;
1534 m_pSerializer->startElementNS( XML_w, XML_drawing,
1535 FSEND );
1536 m_pSerializer->startElementNS( XML_wp, XML_inline,
1537 XML_distT, "0", XML_distB, "0", XML_distL, "0", XML_distR, "0",
1538 FSEND );
1540 // extent of the image
1541 OString aWidth( OString::valueOf( TwipsToEMU( rSize.Width() ) ) );
1542 OString aHeight( OString::valueOf( TwipsToEMU( rSize.Height() ) ) );
1543 m_pSerializer->singleElementNS( XML_wp, XML_extent,
1544 XML_cx, aWidth.getStr(),
1545 XML_cy, aHeight.getStr(),
1546 FSEND );
1547 // TODO - the right effectExtent, extent including the effect
1548 m_pSerializer->singleElementNS( XML_wp, XML_effectExtent,
1549 XML_l, "0", XML_t, "0", XML_r, "0", XML_b, "0",
1550 FSEND );
1552 // picture description
1553 // TODO the right image description
1554 m_pSerializer->startElementNS( XML_wp, XML_docPr,
1555 XML_id, "1",
1556 XML_name, "Picture",
1557 XML_descr, "A description...",
1558 FSEND );
1559 // TODO hyperlink
1560 // m_pSerializer->singleElementNS( XML_a, XML_hlinkClick,
1561 // FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
1562 // FSNS( XML_r, XML_id ), "rId4",
1563 // FSEND );
1564 m_pSerializer->endElementNS( XML_wp, XML_docPr );
1566 m_pSerializer->startElementNS( XML_wp, XML_cNvGraphicFramePr,
1567 FSEND );
1568 // TODO change aspect?
1569 m_pSerializer->singleElementNS( XML_a, XML_graphicFrameLocks,
1570 FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
1571 XML_noChangeAspect, "1",
1572 FSEND );
1573 m_pSerializer->endElementNS( XML_wp, XML_cNvGraphicFramePr );
1575 m_pSerializer->startElementNS( XML_a, XML_graphic,
1576 FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
1577 FSEND );
1578 m_pSerializer->startElementNS( XML_a, XML_graphicData,
1579 XML_uri, "http://schemas.openxmlformats.org/drawingml/2006/picture",
1580 FSEND );
1582 m_pSerializer->startElementNS( XML_pic, XML_pic,
1583 FSNS( XML_xmlns, XML_pic ), "http://schemas.openxmlformats.org/drawingml/2006/picture",
1584 FSEND );
1586 m_pSerializer->startElementNS( XML_pic, XML_nvPicPr,
1587 FSEND );
1588 // TODO the right image description
1589 m_pSerializer->startElementNS( XML_pic, XML_cNvPr,
1590 XML_id, "0",
1591 XML_name, "Picture",
1592 XML_descr, "A description...",
1593 FSEND );
1594 // TODO hyperlink
1595 // m_pSerializer->singleElementNS( XML_a, XML_hlinkClick,
1596 // FSNS( XML_r, XML_id ), "rId4",
1597 // FSEND );
1598 m_pSerializer->endElementNS( XML_pic, XML_cNvPr );
1600 m_pSerializer->startElementNS( XML_pic, XML_cNvPicPr,
1601 FSEND );
1602 // TODO change aspect?
1603 m_pSerializer->singleElementNS( XML_a, XML_picLocks,
1604 XML_noChangeAspect, "1", XML_noChangeArrowheads, "1",
1605 FSEND );
1606 m_pSerializer->endElementNS( XML_pic, XML_cNvPicPr );
1607 m_pSerializer->endElementNS( XML_pic, XML_nvPicPr );
1609 // the actual picture
1610 m_pSerializer->startElementNS( XML_pic, XML_blipFill,
1611 FSEND );
1612 m_pSerializer->singleElementNS( XML_a, XML_blip,
1613 FSNS( XML_r, nImageType ), aRelId.getStr(),
1614 FSEND );
1615 m_pSerializer->singleElementNS( XML_a, XML_srcRect,
1616 FSEND );
1617 m_pSerializer->startElementNS( XML_a, XML_stretch,
1618 FSEND );
1619 m_pSerializer->singleElementNS( XML_a, XML_fillRect,
1620 FSEND );
1621 m_pSerializer->endElementNS( XML_a, XML_stretch );
1622 m_pSerializer->endElementNS( XML_pic, XML_blipFill );
1624 // TODO setup the right values below
1625 m_pSerializer->startElementNS( XML_pic, XML_spPr,
1626 XML_bwMode, "auto",
1627 FSEND );
1628 m_pSerializer->startElementNS( XML_a, XML_xfrm,
1629 FSEND );
1630 m_pSerializer->singleElementNS( XML_a, XML_off,
1631 XML_x, "0", XML_y, "0",
1632 FSEND );
1633 m_pSerializer->singleElementNS( XML_a, XML_ext,
1634 XML_cx, aWidth.getStr(),
1635 XML_cy, aHeight.getStr(),
1636 FSEND );
1637 m_pSerializer->endElementNS( XML_a, XML_xfrm );
1638 m_pSerializer->startElementNS( XML_a, XML_prstGeom,
1639 XML_prst, "rect",
1640 FSEND );
1641 m_pSerializer->singleElementNS( XML_a, XML_avLst,
1642 FSEND );
1643 m_pSerializer->endElementNS( XML_a, XML_prstGeom );
1644 m_pSerializer->singleElementNS( XML_a, XML_noFill,
1645 FSEND );
1646 m_pSerializer->startElementNS( XML_a, XML_ln,
1647 XML_w, "9525",
1648 FSEND );
1649 m_pSerializer->singleElementNS( XML_a, XML_noFill,
1650 FSEND );
1651 m_pSerializer->singleElementNS( XML_a, XML_miter,
1652 XML_lim, "800000",
1653 FSEND );
1654 m_pSerializer->singleElementNS( XML_a, XML_headEnd,
1655 FSEND );
1656 m_pSerializer->singleElementNS( XML_a, XML_tailEnd,
1657 FSEND );
1658 m_pSerializer->endElementNS( XML_a, XML_ln );
1659 m_pSerializer->endElementNS( XML_pic, XML_spPr );
1661 m_pSerializer->endElementNS( XML_pic, XML_pic );
1663 m_pSerializer->endElementNS( XML_a, XML_graphicData );
1664 m_pSerializer->endElementNS( XML_a, XML_graphic );
1665 m_pSerializer->endElementNS( XML_wp, XML_inline );
1667 m_pSerializer->endElementNS( XML_w, XML_drawing );
1670 void DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame &rFrame, const Point& /*rNdTopLeft*/ )
1672 m_pSerializer->mark();
1674 switch ( rFrame.GetWriterType() )
1676 case sw::Frame::eGraphic:
1678 const SwNode *pNode = rFrame.GetContent();
1679 const SwGrfNode *pGrfNode = pNode ? pNode->GetGrfNode() : 0;
1680 if ( pGrfNode )
1681 FlyFrameGraphic( *pGrfNode, rFrame.GetLayoutSize() );
1683 break;
1684 case sw::Frame::eDrawing:
1686 const SdrObject* pSdrObj = rFrame.GetFrmFmt().FindRealSdrObject();
1687 if ( pSdrObj )
1689 bool bSwapInPage = false;
1690 if ( !pSdrObj->GetPage() )
1692 if ( SdrModel* pModel = m_rExport.pDoc->GetDrawModel() )
1694 if ( SdrPage *pPage = pModel->GetPage( 0 ) )
1696 bSwapInPage = true;
1697 const_cast< SdrObject* >( pSdrObj )->SetPage( pPage );
1702 m_pSerializer->startElementNS( XML_w, XML_pict,
1703 FSEND );
1705 m_rExport.VMLExporter().AddSdrObject( *pSdrObj );
1707 m_pSerializer->endElementNS( XML_w, XML_pict );
1709 if ( bSwapInPage )
1710 const_cast< SdrObject* >( pSdrObj )->SetPage( 0 );
1713 break;
1714 default:
1715 #if OSL_DEBUG_LEVEL > 0
1716 fprintf( stderr, "TODO DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame& rFrame, const Point& rNdTopLeft ) - frame type '%s'\n",
1717 rFrame.GetWriterType() == sw::Frame::eTxtBox? "eTxtBox":
1718 ( rFrame.GetWriterType() == sw::Frame::eOle? "eOle":
1719 ( rFrame.GetWriterType() == sw::Frame::eFormControl? "eFormControl": "???" ) ) );
1720 #endif
1721 break;
1724 m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_POSTPONE );
1727 void DocxAttributeOutput::StartStyle( const String& rName, bool bPapFmt,
1728 USHORT nBase, USHORT nNext, USHORT /*nWwId*/, USHORT nId )
1730 OString aStyle( "style" );
1732 m_pSerializer->startElementNS( XML_w, XML_style,
1733 FSNS( XML_w, XML_type ), bPapFmt? "paragraph": "character", // FIXME is this correct?
1734 FSNS( XML_w, XML_styleId ), ( aStyle + OString::valueOf( sal_Int32( nId ) ) ).getStr(),
1735 FSEND );
1737 m_pSerializer->singleElementNS( XML_w, XML_name,
1738 FSNS( XML_w, XML_val ), OUStringToOString( OUString( rName ), RTL_TEXTENCODING_UTF8 ).getStr(),
1739 FSEND );
1741 if ( nBase != 0x0FFF )
1743 m_pSerializer->singleElementNS( XML_w, XML_basedOn,
1744 FSNS( XML_w, XML_val ), ( aStyle + OString::valueOf( sal_Int32( nBase ) ) ).getStr(),
1745 FSEND );
1748 m_pSerializer->singleElementNS( XML_w, XML_next,
1749 FSNS( XML_w, XML_val ), ( aStyle + OString::valueOf( sal_Int32( nNext ) ) ).getStr(),
1750 FSEND );
1753 void DocxAttributeOutput::EndStyle()
1755 m_pSerializer->endElementNS( XML_w, XML_style );
1758 void DocxAttributeOutput::StartStyleProperties( bool bParProp, USHORT /*nStyle*/ )
1760 if ( bParProp )
1762 m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND );
1763 InitCollectedParagraphProperties();
1765 else
1767 m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
1768 InitCollectedRunProperties();
1772 void DocxAttributeOutput::EndStyleProperties( bool bParProp )
1774 if ( bParProp )
1776 WriteCollectedParagraphProperties();
1777 m_pSerializer->endElementNS( XML_w, XML_pPr );
1779 else
1781 WriteCollectedRunProperties();
1782 m_pSerializer->endElementNS( XML_w, XML_rPr );
1786 void DocxAttributeOutput::OutlineNumbering( BYTE nLvl, const SwNumFmt& /*rNFmt*/, const SwFmt& /*rFmt*/ )
1788 if ( nLvl >= WW8ListManager::nMaxLevel )
1789 nLvl = WW8ListManager::nMaxLevel - 1;
1791 m_pSerializer->singleElementNS( XML_w, XML_outlineLvl,
1792 FSNS( XML_w, XML_val ), OString::valueOf( sal_Int32( nLvl ) ).getStr( ),
1793 FSEND );
1796 void DocxAttributeOutput::PageBreakBefore( bool bBreak )
1798 if ( bBreak )
1799 m_pSerializer->singleElementNS( XML_w, XML_pageBreakBefore, FSEND );
1800 else
1801 m_pSerializer->singleElementNS( XML_w, XML_pageBreakBefore,
1802 FSNS( XML_w, XML_val ), "off",
1803 FSEND );
1806 void DocxAttributeOutput::SectionBreak( BYTE nC, const WW8_SepInfo* pSectionInfo )
1808 switch ( nC )
1810 case msword::ColumnBreak:
1811 // The column break should be output in the next paragraph...
1812 m_nColBreakStatus = COLBRK_POSTPONE;
1813 break;
1814 case msword::PageBreak:
1815 if ( pSectionInfo )
1817 if ( !m_bParagraphOpened )
1819 // Create a dummy paragraph if needed
1820 m_pSerializer->startElementNS( XML_w, XML_p, FSEND );
1821 m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND );
1823 m_rExport.SectionProperties( *pSectionInfo );
1825 m_pSerializer->endElementNS( XML_w, XML_pPr );
1826 m_pSerializer->endElementNS( XML_w, XML_p );
1828 else
1830 // postpone the output of this; it has to be done inside the
1831 // paragraph properties, so remember it until then
1832 m_pSectionInfo = pSectionInfo;
1835 else
1837 m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
1838 m_pSerializer->singleElementNS( XML_w, XML_br,
1839 FSNS( XML_w, XML_type ), "page", FSEND );
1840 m_pSerializer->endElementNS( XML_w, XML_r );
1842 break;
1843 default:
1844 #if OSL_DEBUG_LEVEL > 0
1845 fprintf( stderr, "Unknown section break to write: %d\n", nC );
1846 #endif
1847 break;
1851 void DocxAttributeOutput::StartSection()
1853 m_pSerializer->startElementNS( XML_w, XML_sectPr, FSEND );
1854 m_bOpenedSectPr = true;
1857 void DocxAttributeOutput::EndSection()
1859 // Write the section properties
1860 if ( m_pSpacingAttrList )
1862 XFastAttributeListRef xAttrList( m_pSpacingAttrList );
1863 m_pSpacingAttrList = NULL;
1865 m_pSerializer->singleElementNS( XML_w, XML_pgMar, xAttrList );
1868 m_pSerializer->endElementNS( XML_w, XML_sectPr );
1869 m_bOpenedSectPr = false;
1872 void DocxAttributeOutput::SectionFormProtection( bool bProtected )
1874 if ( bProtected )
1875 m_pSerializer->singleElementNS( XML_w, XML_formProt, FSEND );
1876 else
1877 m_pSerializer->singleElementNS( XML_w, XML_formProt,
1878 FSNS( XML_w, XML_val ), "off", FSEND );
1881 void DocxAttributeOutput::SectionLineNumbering( ULONG /*nRestartNo*/, const SwLineNumberInfo& /*rLnNumInfo*/ )
1883 // see 2.6.8 lnNumType (Line Numbering Settings)
1884 #if OSL_DEBUG_LEVEL > 0
1885 fprintf( stderr, "TODO DocxAttributeOutput::SectionLineNumbering()\n" );
1886 #endif
1889 void DocxAttributeOutput::SectionTitlePage()
1891 m_pSerializer->singleElementNS( XML_w, XML_titlePg, FSEND );
1894 void DocxAttributeOutput::SectionPageBorders( const SwFrmFmt* pFmt, const SwFrmFmt* /*pFirstPageFmt*/ )
1896 // Output the margins
1899 const SvxBoxItem& rBox = pFmt->GetBox( );
1901 const SvxBorderLine* pBottom = rBox.GetBottom( );
1902 const SvxBorderLine* pTop = rBox.GetTop( );
1903 const SvxBorderLine* pLeft = rBox.GetLeft( );
1904 const SvxBorderLine* pRight = rBox.GetRight( );
1906 if ( pBottom || pTop || pLeft || pRight )
1908 // All distances are relative to the text margins
1909 m_pSerializer->startElementNS( XML_w, XML_pgBorders,
1910 FSNS( XML_w, XML_display ), "allPages",
1911 FSNS( XML_w, XML_offsetFrom ), "text",
1912 FSEND );
1914 m_pSerializer->mark();
1916 m_pSerializer->endElementNS( XML_w, XML_pgBorders );
1917 m_pSerializer->mark();
1921 void DocxAttributeOutput::SectionBiDi( bool bBiDi )
1923 if ( bBiDi )
1924 m_pSerializer->singleElementNS( XML_w, XML_bidi, FSEND );
1927 static OString impl_NumberingType( USHORT nNumberingType )
1929 OString aType;
1931 switch ( nNumberingType )
1933 case SVX_NUM_CHARS_UPPER_LETTER:
1934 case SVX_NUM_CHARS_UPPER_LETTER_N: aType = "upperLetter"; break;
1935 case SVX_NUM_CHARS_LOWER_LETTER:
1936 case SVX_NUM_CHARS_LOWER_LETTER_N: aType = "lowerLetter"; break;
1937 case SVX_NUM_ROMAN_UPPER: aType = "upperRoman"; break;
1938 case SVX_NUM_ROMAN_LOWER: aType = "lowerRoman"; break;
1940 case SVX_NUM_ARABIC: aType = "decimal"; break;
1942 case SVX_NUM_BITMAP:
1943 case SVX_NUM_CHAR_SPECIAL: aType = "bullet"; break;
1945 default: aType = "none"; break;
1948 return aType;
1951 void DocxAttributeOutput::SectionPageNumbering( USHORT nNumType, USHORT nPageRestartNumber )
1953 // FIXME Not called properly with page styles like "First Page"
1955 FastAttributeList* pAttr = m_pSerializer->createAttrList();
1957 // 0 means no restart: then don't output that attribute if 0
1958 if ( nPageRestartNumber > 0 )
1959 pAttr->add( FSNS( XML_w, XML_start ), OString::valueOf( sal_Int32( nPageRestartNumber ) ) );
1961 // nNumType corresponds to w:fmt. See WW8Export::GetNumId() for more precisions
1962 OString aFmt( impl_NumberingType( nNumType ) );
1963 if ( aFmt.getLength() )
1964 pAttr->add( FSNS( XML_w, XML_fmt ), aFmt.getStr() );
1966 XFastAttributeListRef xAttrs( pAttr );
1967 m_pSerializer->singleElementNS( XML_w, XML_pgNumType, xAttrs );
1969 // see 2.6.12 pgNumType (Page Numbering Settings)
1970 #if OSL_DEBUG_LEVEL > 0
1971 fprintf( stderr, "TODO DocxAttributeOutput::SectionPageNumbering()\n" );
1972 #endif
1975 void DocxAttributeOutput::SectionType( BYTE nBreakCode )
1977 /* break code: 0 No break, 1 New column
1978 2 New page, 3 Even page, 4 Odd page
1980 const char* pType = NULL;
1981 switch ( nBreakCode )
1983 case 1: pType = "nextColumn"; break;
1984 case 2: pType = "nextPage"; break;
1985 case 3: pType = "evenPage"; break;
1986 case 4: pType = "oddPage"; break;
1987 default: pType = "continuous"; break;
1990 if ( pType )
1991 m_pSerializer->singleElementNS( XML_w, XML_type,
1992 FSNS( XML_w, XML_val ), pType,
1993 FSEND );
1996 void DocxAttributeOutput::StartFont( const String& rFamilyName ) const
1998 m_pSerializer->startElementNS( XML_w, XML_font,
1999 FSNS( XML_w, XML_name ), OUStringToOString( OUString( rFamilyName ), RTL_TEXTENCODING_UTF8 ).getStr(),
2000 FSEND );
2003 void DocxAttributeOutput::EndFont() const
2005 m_pSerializer->endElementNS( XML_w, XML_font );
2008 void DocxAttributeOutput::FontAlternateName( const String& rName ) const
2010 m_pSerializer->singleElementNS( XML_w, XML_altName,
2011 FSNS( XML_w, XML_val ), OUStringToOString( OUString( rName ), RTL_TEXTENCODING_UTF8 ).getStr(),
2012 FSEND );
2015 void DocxAttributeOutput::FontCharset( sal_uInt8 nCharSet ) const
2017 OString aCharSet( OString::valueOf( sal_Int32( nCharSet ), 16 ) );
2018 if ( aCharSet.getLength() == 1 )
2019 aCharSet = OString( "0" ) + aCharSet;
2021 m_pSerializer->singleElementNS( XML_w, XML_charset,
2022 FSNS( XML_w, XML_val ), aCharSet.getStr(),
2023 FSEND );
2026 void DocxAttributeOutput::FontFamilyType( FontFamily eFamily ) const
2028 const char *pFamily = NULL;
2029 switch ( eFamily )
2031 case FAMILY_ROMAN: pFamily = "roman"; break;
2032 case FAMILY_SWISS: pFamily = "swiss"; break;
2033 case FAMILY_MODERN: pFamily = "modern"; break;
2034 case FAMILY_SCRIPT: pFamily = "script"; break;
2035 case FAMILY_DECORATIVE: pFamily = "decorative"; break;
2036 default: pFamily = "auto"; break; // no font family
2039 if ( pFamily )
2040 m_pSerializer->singleElementNS( XML_w, XML_family,
2041 FSNS( XML_w, XML_val ), pFamily,
2042 FSEND );
2045 void DocxAttributeOutput::FontPitchType( FontPitch ePitch ) const
2047 const char *pPitch = NULL;
2048 switch ( ePitch )
2050 case PITCH_VARIABLE: pPitch = "variable"; break;
2051 case PITCH_FIXED: pPitch = "fixed"; break;
2052 default: pPitch = "default"; break; // no info about the pitch
2055 if ( pPitch )
2056 m_pSerializer->singleElementNS( XML_w, XML_pitch,
2057 FSNS( XML_w, XML_val ), pPitch,
2058 FSEND );
2061 void DocxAttributeOutput::NumberingDefinition( USHORT nId, const SwNumRule &rRule )
2063 // nId is the same both for abstract numbering definition as well as the
2064 // numbering definition itself
2065 // TODO check that this is actually true & fix if not ;-)
2066 OString aId( OString::valueOf( sal_Int32( nId ) ) );
2068 m_pSerializer->startElementNS( XML_w, XML_num,
2069 FSNS( XML_w, XML_numId ), aId.getStr(),
2070 FSEND );
2072 m_pSerializer->singleElementNS( XML_w, XML_abstractNumId,
2073 FSNS( XML_w, XML_val ), aId.getStr(),
2074 FSEND );
2076 #if OSL_DEBUG_LEVEL > 0
2077 // TODO ww8 version writes this, anything to do about it here?
2078 if ( rRule.IsContinusNum() )
2079 fprintf( stderr, "TODO DocxAttributeOutput::NumberingDefinition()\n" );
2080 #else
2081 (void) rRule; // to quiet the warning...
2082 #endif
2084 m_pSerializer->endElementNS( XML_w, XML_num );
2087 void DocxAttributeOutput::StartAbstractNumbering( USHORT nId )
2089 m_pSerializer->startElementNS( XML_w, XML_abstractNum,
2090 FSNS( XML_w, XML_abstractNumId ), OString::valueOf( sal_Int32( nId ) ).getStr(),
2091 FSEND );
2094 void DocxAttributeOutput::EndAbstractNumbering()
2096 m_pSerializer->endElementNS( XML_w, XML_abstractNum );
2099 void DocxAttributeOutput::NumberingLevel( BYTE nLevel,
2100 USHORT nStart,
2101 USHORT nNumberingType,
2102 SvxAdjust eAdjust,
2103 const BYTE * /*pNumLvlPos*/,
2104 BYTE nFollow,
2105 const wwFont *pFont,
2106 const SfxItemSet *pOutSet,
2107 sal_Int16 nIndentAt,
2108 sal_Int16 nFirstLineIndex,
2109 sal_Int16 /*nListTabPos*/,
2110 const String &rNumberingString )
2112 m_pSerializer->startElementNS( XML_w, XML_lvl,
2113 FSNS( XML_w, XML_ilvl ), OString::valueOf( sal_Int32( nLevel ) ).getStr(),
2114 FSEND );
2116 // start with the nStart value
2117 m_pSerializer->singleElementNS( XML_w, XML_start,
2118 FSNS( XML_w, XML_val ), OString::valueOf( sal_Int32( nStart ) ).getStr(),
2119 FSEND );
2121 // format
2122 OString aFmt( impl_NumberingType( nNumberingType ) );
2124 if ( aFmt.getLength() )
2125 m_pSerializer->singleElementNS( XML_w, XML_numFmt,
2126 FSNS( XML_w, XML_val ), aFmt.getStr(),
2127 FSEND );
2129 // justification
2130 const char *pJc;
2131 switch ( eAdjust )
2133 case SVX_ADJUST_CENTER: pJc = "center"; break;
2134 case SVX_ADJUST_RIGHT: pJc = "right"; break;
2135 default: pJc = "left"; break;
2137 m_pSerializer->singleElementNS( XML_w, XML_lvlJc,
2138 FSNS( XML_w, XML_val ), pJc,
2139 FSEND );
2141 // suffix
2142 const char *pSuffix = NULL;
2143 switch ( nFollow )
2145 case 1: pSuffix = "space"; break;
2146 case 2: pSuffix = "nothing"; break;
2147 default: /*pSuffix = "tab";*/ break;
2149 if ( pSuffix )
2150 m_pSerializer->singleElementNS( XML_w, XML_suff,
2151 FSNS( XML_w, XML_val ), pSuffix,
2152 FSEND );
2154 // text
2155 OUString aText( rNumberingString );
2156 OUStringBuffer aBuffer( aText.getLength() + WW8ListManager::nMaxLevel );
2158 const sal_Unicode *pPrev = aText.getStr();
2159 const sal_Unicode *pIt = aText.getStr();
2160 while ( pIt < aText.getStr() + aText.getLength() )
2162 // convert the level values to %NUMBER form
2163 // (we don't use pNumLvlPos at all)
2164 // FIXME so far we support the ww8 limit of levels only
2165 if ( *pIt < sal_Unicode( WW8ListManager::nMaxLevel ) )
2167 aBuffer.append( pPrev, pIt - pPrev );
2168 aBuffer.appendAscii( "%" );
2169 aBuffer.append( OUString::valueOf( sal_Int32( *pIt ) + 1 ) );
2171 pPrev = pIt + 1;
2173 ++pIt;
2175 if ( pPrev < pIt )
2176 aBuffer.append( pPrev, pIt - pPrev );
2178 m_pSerializer->singleElementNS( XML_w, XML_lvlText,
2179 FSNS( XML_w, XML_val ), OUStringToOString( aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ).getStr(),
2180 FSEND );
2182 // indentation
2183 m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND );
2184 m_pSerializer->singleElementNS( XML_w, XML_ind,
2185 FSNS( XML_w, XML_left ), OString::valueOf( sal_Int32( nIndentAt ) ).getStr(),
2186 FSNS( XML_w, XML_hanging ), OString::valueOf( sal_Int32( -nFirstLineIndex ) ).getStr(),
2187 FSEND );
2188 m_pSerializer->endElementNS( XML_w, XML_pPr );
2190 // font
2191 if ( pOutSet )
2193 m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
2195 if ( pFont )
2197 OString aFamilyName( OUStringToOString( OUString( pFont->GetFamilyName() ), RTL_TEXTENCODING_UTF8 ) );
2198 m_pSerializer->singleElementNS( XML_w, XML_rFonts,
2199 FSNS( XML_w, XML_ascii ), aFamilyName.getStr(),
2200 FSNS( XML_w, XML_hAnsi ), aFamilyName.getStr(),
2201 FSNS( XML_w, XML_cs ), aFamilyName.getStr(),
2202 FSNS( XML_w, XML_hint ), "default",
2203 FSEND );
2205 m_rExport.OutputItemSet( *pOutSet, false, true, i18n::ScriptType::LATIN );
2207 m_pSerializer->endElementNS( XML_w, XML_rPr );
2210 // TODO anything to do about nListTabPos?
2212 m_pSerializer->endElementNS( XML_w, XML_lvl );
2215 void DocxAttributeOutput::CharCaseMap( const SvxCaseMapItem& rCaseMap )
2217 switch ( rCaseMap.GetValue() )
2219 case SVX_CASEMAP_KAPITAELCHEN:
2220 m_pSerializer->singleElementNS( XML_w, XML_smallCaps, FSEND );
2221 break;
2222 case SVX_CASEMAP_VERSALIEN:
2223 m_pSerializer->singleElementNS( XML_w, XML_caps, FSEND );
2224 break;
2225 default: // Something that ooxml does not support
2226 m_pSerializer->singleElementNS( XML_w, XML_smallCaps, FSNS( XML_w, XML_val ), "off", FSEND );
2227 m_pSerializer->singleElementNS( XML_w, XML_caps, FSNS( XML_w, XML_val ), "off", FSEND );
2228 break;
2232 void DocxAttributeOutput::CharColor( const SvxColorItem& rColor )
2234 const Color aColor( rColor.GetValue() );
2235 OString aColorString;
2237 aColorString = impl_ConvertColor( aColor );
2239 m_pSerializer->singleElementNS( XML_w, XML_color,
2240 FSNS( XML_w, XML_val ), aColorString.getStr(), FSEND );
2243 void DocxAttributeOutput::CharContour( const SvxContourItem& rContour )
2245 if ( rContour.GetValue() )
2246 m_pSerializer->singleElementNS( XML_w, XML_outline, FSEND );
2247 else
2248 m_pSerializer->singleElementNS( XML_w, XML_outline, FSNS( XML_w, XML_val ), "off", FSEND );
2251 void DocxAttributeOutput::CharCrossedOut( const SvxCrossedOutItem& rCrossedOut )
2253 switch ( rCrossedOut.GetStrikeout() )
2255 case STRIKEOUT_DOUBLE:
2256 m_pSerializer->singleElementNS( XML_w, XML_dstrike, FSEND );
2257 break;
2258 case STRIKEOUT_NONE:
2259 m_pSerializer->singleElementNS( XML_w, XML_dstrike, FSNS( XML_w, XML_val ), "off", FSEND );
2260 m_pSerializer->singleElementNS( XML_w, XML_strike, FSNS( XML_w, XML_val ), "off", FSEND );
2261 break;
2262 default:
2263 m_pSerializer->singleElementNS( XML_w, XML_strike, FSEND );
2264 break;
2268 void DocxAttributeOutput::CharEscapement( const SvxEscapementItem& /*rEscapement*/ )
2270 #if OSL_DEBUG_LEVEL > 0
2271 fprintf( stderr, "TODO DocxAttributeOutput::CharEscapement()\n" );
2272 #endif
2275 void DocxAttributeOutput::CharFont( const SvxFontItem& rFont)
2277 if (!m_pFontsAttrList)
2278 m_pFontsAttrList = m_pSerializer->createAttrList();
2279 OUString sFontName(rFont.GetFamilyName());
2280 OString sFontNameUtf8 = OUStringToOString(sFontName, RTL_TEXTENCODING_UTF8);
2281 m_pFontsAttrList->add(FSNS(XML_w, XML_ascii), sFontNameUtf8);
2282 m_pFontsAttrList->add(FSNS(XML_w, XML_hAnsi), sFontNameUtf8);
2285 void DocxAttributeOutput::CharFontSize( const SvxFontHeightItem& rFontSize)
2287 OString fontSize = OString::valueOf( sal_Int32( ( rFontSize.GetHeight() + 5 ) / 10 ) );
2289 switch ( rFontSize.Which() )
2291 case RES_CHRATR_FONTSIZE:
2292 case RES_CHRATR_CJK_FONTSIZE:
2293 m_pSerializer->singleElementNS( XML_w, XML_sz, FSNS( XML_w, XML_val ), fontSize.getStr(), FSEND );
2294 break;
2295 case RES_CHRATR_CTL_FONTSIZE:
2296 m_pSerializer->singleElementNS( XML_w, XML_szCs, FSNS( XML_w, XML_val ), fontSize.getStr(), FSEND );
2297 break;
2301 void DocxAttributeOutput::CharKerning( const SvxKerningItem& rKerning )
2303 OString aKerning = OString::valueOf( ( sal_Int32 ) rKerning.GetValue() );
2304 m_pSerializer->singleElementNS( XML_w, XML_kern, FSNS(XML_w, XML_val), aKerning.getStr(), FSEND );
2307 void DocxAttributeOutput::CharLanguage( const SvxLanguageItem& rLanguage )
2309 if (!m_pCharLangAttrList)
2310 m_pCharLangAttrList = m_pSerializer->createAttrList();
2312 ::com::sun::star::lang::Locale xLocale= MsLangId::convertLanguageToLocale( rLanguage.GetLanguage( ) );
2313 OString sLanguage = OUStringToOString(xLocale.Language, RTL_TEXTENCODING_UTF8);
2314 OString sCountry = OUStringToOString(xLocale.Country, RTL_TEXTENCODING_UTF8);
2316 OString aLanguageCode = sLanguage + "-" + sCountry;
2318 switch ( rLanguage.Which() )
2320 case RES_CHRATR_LANGUAGE:
2321 m_pCharLangAttrList->add(FSNS(XML_w, XML_val), aLanguageCode);
2322 break;
2323 case RES_CHRATR_CJK_LANGUAGE:
2324 m_pCharLangAttrList->add(FSNS(XML_w, XML_eastAsia), aLanguageCode);
2325 break;
2326 case RES_CHRATR_CTL_LANGUAGE:
2327 m_pCharLangAttrList->add(FSNS(XML_w, XML_bidi), aLanguageCode);
2328 break;
2332 void DocxAttributeOutput::CharPosture( const SvxPostureItem& rPosture )
2334 if ( rPosture.GetPosture() != ITALIC_NONE )
2335 m_pSerializer->singleElementNS( XML_w, XML_i, FSEND );
2336 else
2337 m_pSerializer->singleElementNS( XML_w, XML_i, FSNS( XML_w, XML_val ), "off", FSEND );
2340 void DocxAttributeOutput::CharShadow( const SvxShadowedItem& rShadow )
2342 if ( rShadow.GetValue() )
2343 m_pSerializer->singleElementNS( XML_w, XML_shadow, FSEND );
2344 else
2345 m_pSerializer->singleElementNS( XML_w, XML_shadow, FSNS( XML_w, XML_val ), "off", FSEND );
2348 void DocxAttributeOutput::CharUnderline( const SvxUnderlineItem& rUnderline )
2350 const char *pUnderline;
2352 switch ( rUnderline.GetLineStyle() )
2354 case UNDERLINE_SINGLE: pUnderline = "single"; break;
2355 case UNDERLINE_BOLD: pUnderline = "thick"; break;
2356 case UNDERLINE_DOUBLE: pUnderline = "double"; break;
2357 case UNDERLINE_DOTTED: pUnderline = "dotted"; break;
2358 case UNDERLINE_DASH: pUnderline = "dash"; break;
2359 case UNDERLINE_DASHDOT: pUnderline = "dotDash"; break;
2360 case UNDERLINE_DASHDOTDOT: pUnderline = "dotDotDash"; break;
2361 case UNDERLINE_WAVE: pUnderline = "wave"; break;
2362 case UNDERLINE_BOLDDOTTED: pUnderline = "dottedHeavy"; break;
2363 case UNDERLINE_BOLDDASH: pUnderline = "dashedHeavy"; break;
2364 case UNDERLINE_LONGDASH: pUnderline = "dashLongHeavy"; break;
2365 case UNDERLINE_BOLDLONGDASH: pUnderline = "dashLongHeavy"; break;
2366 case UNDERLINE_BOLDDASHDOT: pUnderline = "dashDotHeavy"; break;
2367 case UNDERLINE_BOLDDASHDOTDOT: pUnderline = "dashDotDotHeavy"; break;
2368 case UNDERLINE_BOLDWAVE: pUnderline = "wavyHeavy"; break;
2369 case UNDERLINE_DOUBLEWAVE: pUnderline = "wavyDouble"; break;
2370 case UNDERLINE_NONE: // fall through
2371 default: pUnderline = "none"; break;
2374 m_pSerializer->singleElementNS( XML_w, XML_u, FSNS( XML_w, XML_val ), pUnderline, FSEND );
2377 void DocxAttributeOutput::CharWeight( const SvxWeightItem& rWeight )
2379 if ( rWeight.GetWeight() == WEIGHT_BOLD )
2380 m_pSerializer->singleElementNS( XML_w, XML_b, FSEND );
2381 else
2382 m_pSerializer->singleElementNS( XML_w, XML_b, FSNS( XML_w, XML_val ), "off", FSEND );
2385 void DocxAttributeOutput::CharAutoKern( const SvxAutoKernItem& )
2387 #if OSL_DEBUG_LEVEL > 0
2388 fprintf( stderr, "TODO DocxAttributeOutput::CharAutoKern()\n" );
2389 #endif
2392 void DocxAttributeOutput::CharAnimatedText( const SvxBlinkItem& rBlink )
2394 if ( rBlink.GetValue() )
2395 m_pSerializer->singleElementNS(XML_w, XML_effect, FSNS( XML_w, XML_val ), "blinkBackground", FSEND );
2396 else
2397 m_pSerializer->singleElementNS(XML_w, XML_effect, FSNS( XML_w, XML_val ), "none", FSEND );
2400 void DocxAttributeOutput::CharBackground( const SvxBrushItem& rBrush )
2402 m_pSerializer->singleElementNS( XML_w, XML_shd,
2403 FSNS( XML_w, XML_fill ), impl_ConvertColor( rBrush.GetColor() ).getStr(), FSEND );
2406 void DocxAttributeOutput::CharFontCJK( const SvxFontItem& rFont )
2408 if (!m_pFontsAttrList)
2409 m_pFontsAttrList = m_pSerializer->createAttrList();
2410 OUString sFontName(rFont.GetFamilyName());
2411 OString sFontNameUtf8 = OUStringToOString(sFontName, RTL_TEXTENCODING_UTF8);
2412 m_pFontsAttrList->add(FSNS(XML_w, XML_eastAsia), sFontNameUtf8);
2415 void DocxAttributeOutput::CharPostureCJK( const SvxPostureItem& rPosture )
2417 if ( rPosture.GetPosture() != ITALIC_NONE )
2418 m_pSerializer->singleElementNS( XML_w, XML_i, FSEND );
2419 else
2420 m_pSerializer->singleElementNS( XML_w, XML_i, FSNS( XML_w, XML_val ), "off", FSEND );
2423 void DocxAttributeOutput::CharWeightCJK( const SvxWeightItem& rWeight )
2425 if ( rWeight.GetWeight() == WEIGHT_BOLD )
2426 m_pSerializer->singleElementNS( XML_w, XML_b, FSEND );
2427 else
2428 m_pSerializer->singleElementNS( XML_w, XML_b, FSNS( XML_w, XML_val ), "off", FSEND );
2431 void DocxAttributeOutput::CharFontCTL( const SvxFontItem& rFont )
2433 if (!m_pFontsAttrList)
2434 m_pFontsAttrList = m_pSerializer->createAttrList();
2435 OUString sFontName(rFont.GetFamilyName());
2436 OString sFontNameUtf8 = OUStringToOString(sFontName, RTL_TEXTENCODING_UTF8);
2437 m_pFontsAttrList->add(FSNS(XML_w, XML_cs), sFontNameUtf8);
2441 void DocxAttributeOutput::CharPostureCTL( const SvxPostureItem& rPosture)
2443 if ( rPosture.GetPosture() != ITALIC_NONE )
2444 m_pSerializer->singleElementNS( XML_w, XML_iCs, FSEND );
2445 else
2446 m_pSerializer->singleElementNS( XML_w, XML_iCs, FSNS( XML_w, XML_val ), "off", FSEND );
2449 void DocxAttributeOutput::CharWeightCTL( const SvxWeightItem& rWeight )
2451 if ( rWeight.GetWeight() == WEIGHT_BOLD )
2452 m_pSerializer->singleElementNS( XML_w, XML_bCs, FSEND );
2453 else
2454 m_pSerializer->singleElementNS( XML_w, XML_bCs, FSNS( XML_w, XML_val ), "off", FSEND );
2457 void DocxAttributeOutput::CharRotate( const SvxCharRotateItem& rRotate)
2459 if ( !rRotate.GetValue() )
2460 return;
2462 if (!m_pEastAsianLayoutAttrList)
2463 m_pEastAsianLayoutAttrList = m_pSerializer->createAttrList();
2464 OString sTrue((sal_Char *)"true");
2465 m_pEastAsianLayoutAttrList->add(FSNS(XML_w, XML_vert), sTrue);
2467 if (rRotate.IsFitToLine())
2468 m_pEastAsianLayoutAttrList->add(FSNS(XML_w, XML_vertCompress), sTrue);
2471 void DocxAttributeOutput::CharEmphasisMark( const SvxEmphasisMarkItem& rEmphasisMark )
2473 const char *pEmphasis;
2475 switch ( rEmphasisMark.GetValue() )
2477 case EMPHASISMARK_NONE: pEmphasis = "none"; break;
2478 case EMPHASISMARK_SIDE_DOTS: pEmphasis = "dot"; break;
2479 case EMPHASISMARK_CIRCLE_ABOVE: pEmphasis = "circle"; break;
2480 case EMPHASISMARK_DOTS_BELOW: pEmphasis = "underDot"; break;
2481 default: pEmphasis = "comma"; break;
2484 m_pSerializer->singleElementNS( XML_w, XML_em, FSNS( XML_w, XML_val ), pEmphasis, FSEND );
2487 void DocxAttributeOutput::CharTwoLines( const SvxTwoLinesItem& rTwoLines )
2489 if ( !rTwoLines.GetValue() )
2490 return;
2492 if (!m_pEastAsianLayoutAttrList)
2493 m_pEastAsianLayoutAttrList = m_pSerializer->createAttrList();
2494 OString sTrue((sal_Char *)"true");
2495 m_pEastAsianLayoutAttrList->add(FSNS(XML_w, XML_combine), sTrue);
2497 sal_Unicode cStart = rTwoLines.GetStartBracket();
2498 sal_Unicode cEnd = rTwoLines.GetEndBracket();
2500 if (!cStart && !cEnd)
2501 return;
2503 OString sBracket;
2504 if ((cStart == '{') || (cEnd == '}'))
2505 sBracket = (sal_Char *)"curly";
2506 else if ((cStart == '<') || (cEnd == '>'))
2507 sBracket = (sal_Char *)"angle";
2508 else if ((cStart == '[') || (cEnd == ']'))
2509 sBracket = (sal_Char *)"square";
2510 else
2511 sBracket = (sal_Char *)"round";
2512 m_pEastAsianLayoutAttrList->add(FSNS(XML_w, XML_combineBrackets), sBracket);
2515 void DocxAttributeOutput::CharScaleWidth( const SvxCharScaleWidthItem& rScaleWidth )
2517 m_pSerializer->singleElementNS( XML_w, XML_w,
2518 FSNS( XML_w, XML_val ), rtl::OString::valueOf( sal_Int32( rScaleWidth.GetValue() ) ).getStr(), FSEND );
2521 void DocxAttributeOutput::CharRelief( const SvxCharReliefItem& rRelief )
2523 switch ( rRelief.GetValue() )
2525 case RELIEF_EMBOSSED:
2526 m_pSerializer->singleElementNS( XML_w, XML_emboss, FSEND );
2527 break;
2528 case RELIEF_ENGRAVED:
2529 m_pSerializer->singleElementNS( XML_w, XML_imprint, FSEND );
2530 break;
2531 default:
2532 m_pSerializer->singleElementNS( XML_w, XML_emboss, FSNS( XML_w, XML_val ), "off", FSEND );
2533 m_pSerializer->singleElementNS( XML_w, XML_imprint, FSNS( XML_w, XML_val ), "off", FSEND );
2534 break;
2538 void DocxAttributeOutput::CharHidden( const SvxCharHiddenItem& rHidden )
2540 if ( rHidden.GetValue() )
2541 m_pSerializer->singleElementNS( XML_w, XML_vanish, FSEND );
2542 else
2543 m_pSerializer->singleElementNS( XML_w, XML_vanish, FSNS( XML_w, XML_val ), "off", FSEND );
2546 void DocxAttributeOutput::TextINetFormat( const SwFmtINetFmt& rLink )
2548 const SwTxtINetFmt* pINetFmt = rLink.GetTxtINetFmt();
2549 const SwCharFmt* pCharFmt = pINetFmt->GetCharFmt();
2551 OString aStyleId( "style" );
2552 aStyleId += OString::valueOf( sal_Int32( m_rExport.GetId( *pCharFmt ) ) );
2554 m_pSerializer->singleElementNS( XML_w, XML_rStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND );
2557 void DocxAttributeOutput::TextCharFormat( const SwFmtCharFmt& )
2559 #if OSL_DEBUG_LEVEL > 0
2560 fprintf( stderr, "TODO DocxAttributeOutput::TextCharFormat()\n" );
2561 #endif
2564 void DocxAttributeOutput::RefField( const SwField& rFld, const String& rRef )
2566 USHORT nType = rFld.GetTyp( )->Which( );
2567 if ( nType == RES_GETEXPFLD )
2569 String sCmd = FieldString( ww::eREF );
2570 sCmd.APPEND_CONST_ASC( "\"" );
2571 sCmd += rRef;
2572 sCmd.APPEND_CONST_ASC( "\" " );
2574 m_rExport.OutputField( &rFld, ww::eREF, sCmd );
2577 // There is nothing to do here for the set fields
2580 void DocxAttributeOutput::HiddenField( const SwField& /*rFld*/ )
2582 #if OSL_DEBUG_LEVEL > 0
2583 fprintf( stderr, "TODO DocxAttributeOutput::HiddenField()\n" );
2584 #endif
2587 void DocxAttributeOutput::PostitField( const SwField* /* pFld*/ )
2589 #if OSL_DEBUG_LEVEL > 0
2590 fprintf( stderr, "TODO DocxAttributeOutput::PostitField()\n" );
2591 #endif
2594 bool DocxAttributeOutput::DropdownField( const SwField* pFld )
2596 bool bExpand = false;
2598 ww::eField eType = ww::eFORMDROPDOWN;
2599 String sCmd = FieldString( eType );
2600 GetExport( ).OutputField( pFld, eType, sCmd );
2602 return bExpand;
2605 void DocxAttributeOutput::SetField( const SwField& rFld, ww::eField eType, const String& rCmd )
2607 // field bookmarks are handled in the EndRun method
2608 GetExport().OutputField(&rFld, eType, rCmd );
2611 void DocxAttributeOutput::WriteExpand( const SwField* pFld )
2613 // Will be written in the next End Run
2614 String sCmd;
2615 m_rExport.OutputField( pFld, ww::eUNKNOWN, sCmd );
2618 void DocxAttributeOutput::WriteField_Impl( const SwField* pFld, ww::eField eType, const String& rFldCmd, BYTE nMode )
2620 struct FieldInfos infos;
2621 infos.pField = pFld;
2622 infos.sCmd = rFldCmd;
2623 infos.eType = eType;
2624 infos.bClose = WRITEFIELD_CLOSE & nMode;
2625 infos.bOpen = WRITEFIELD_START & nMode;
2627 m_Fields.push_back( infos );
2629 if ( pFld )
2631 USHORT nType = pFld->GetTyp( )->Which( );
2632 USHORT nSubType = pFld->GetSubType();
2634 // TODO Any other field types here ?
2635 if ( ( nType == RES_SETEXPFLD ) && ( nSubType & nsSwGetSetExpType::GSE_STRING ) )
2637 const SwSetExpField *pSet = ( const SwSetExpField* )( pFld );
2638 m_sFieldBkm = pSet->GetPar1( );
2640 else if ( nType == RES_DROPDOWN )
2642 const SwDropDownField* pDropDown = ( const SwDropDownField* )( pFld );
2643 m_sFieldBkm = pDropDown->GetName( );
2648 void DocxAttributeOutput::WriteBookmarks_Impl( std::vector< OUString >& rStarts,
2649 std::vector< OUString >& rEnds )
2651 for ( std::vector< OUString >::const_iterator it = rStarts.begin(), end = rStarts.end(); it < end; ++it )
2653 OString rName = OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr( );
2654 m_rMarksStart.push_back( rName );
2656 rStarts.clear();
2658 for ( std::vector< OUString >::const_iterator it = rEnds.begin(), end = rEnds.end(); it < end; ++it )
2660 OString rName = OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr( );
2661 m_rMarksEnd.push_back( rName );
2663 rEnds.clear();
2666 void DocxAttributeOutput::TextFootnote_Impl( const SwFmtFtn& rFootnote )
2668 const SwEndNoteInfo& rInfo = rFootnote.IsEndNote()?
2669 m_rExport.pDoc->GetEndNoteInfo(): m_rExport.pDoc->GetFtnInfo();
2671 // footnote/endnote run properties
2672 const SwCharFmt* pCharFmt = rInfo.GetAnchorCharFmt( *m_rExport.pDoc );
2674 OString aStyleId( "style" );
2675 aStyleId += OString::valueOf( sal_Int32( m_rExport.GetId( *pCharFmt ) ) );
2677 m_pSerializer->singleElementNS( XML_w, XML_rStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND );
2679 // remember the footnote/endnote to
2680 // 1) write the footnoteReference/endnoteReference in EndRunProperties()
2681 // 2) be able to dump them all to footnotes.xml/endnotes.xml
2682 if ( !rFootnote.IsEndNote() )
2683 m_pFootnotesList->add( rFootnote );
2684 else
2685 m_pEndnotesList->add( rFootnote );
2688 void DocxAttributeOutput::FootnoteEndnoteReference()
2690 sal_Int32 nId;
2691 const SwFmtFtn *pFootnote = m_pFootnotesList->getCurrent( nId );
2693 // both cannot be set at the same time - if they are, it's a bug
2694 if ( !pFootnote )
2695 pFootnote = m_pEndnotesList->getCurrent( nId );
2697 if ( !pFootnote )
2698 return;
2700 sal_Int32 nToken = pFootnote->IsEndNote()? XML_endnoteReference: XML_footnoteReference;
2702 // write it
2703 if ( pFootnote->GetNumStr().Len() == 0 )
2705 // autonumbered
2706 m_pSerializer->singleElementNS( XML_w, nToken,
2707 FSNS( XML_w, XML_id ), ::rtl::OString::valueOf( nId ).getStr(),
2708 FSEND );
2710 else
2712 // not autonumbered
2713 m_pSerializer->singleElementNS( XML_w, nToken,
2714 FSNS( XML_w, XML_customMarkFollows ), "1",
2715 FSNS( XML_w, XML_id ), ::rtl::OString::valueOf( nId ).getStr(),
2716 FSEND );
2718 RunText( pFootnote->GetNumStr() );
2722 void DocxAttributeOutput::FootnotesEndnotes( bool bFootnotes )
2724 const FootnotesVector& rVector = bFootnotes? m_pFootnotesList->getVector(): m_pEndnotesList->getVector();
2726 sal_Int32 nBody = bFootnotes? XML_footnotes: XML_endnotes;
2727 sal_Int32 nItem = bFootnotes? XML_footnote: XML_endnote;
2729 m_pSerializer->startElementNS( XML_w, nBody,
2730 FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
2731 FSEND );
2733 sal_Int32 nIndex = 0;
2735 // separator
2736 m_pSerializer->startElementNS( XML_w, nItem,
2737 FSNS( XML_w, XML_id ), OString::valueOf( nIndex++ ).getStr(),
2738 FSNS( XML_w, XML_type ), "separator",
2739 FSEND );
2740 m_pSerializer->startElementNS( XML_w, XML_p, FSEND );
2741 m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
2742 m_pSerializer->singleElementNS( XML_w, XML_separator, FSEND );
2743 m_pSerializer->endElementNS( XML_w, XML_r );
2744 m_pSerializer->endElementNS( XML_w, XML_p );
2745 m_pSerializer->endElementNS( XML_w, nItem );
2747 // separator
2748 m_pSerializer->startElementNS( XML_w, nItem,
2749 FSNS( XML_w, XML_id ), OString::valueOf( nIndex++ ).getStr(),
2750 FSNS( XML_w, XML_type ), "continuationSeparator",
2751 FSEND );
2752 m_pSerializer->startElementNS( XML_w, XML_p, FSEND );
2753 m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
2754 m_pSerializer->singleElementNS( XML_w, XML_continuationSeparator, FSEND );
2755 m_pSerializer->endElementNS( XML_w, XML_r );
2756 m_pSerializer->endElementNS( XML_w, XML_p );
2757 m_pSerializer->endElementNS( XML_w, nItem );
2759 // footnotes/endnotes themselves
2760 for ( FootnotesVector::const_iterator i = rVector.begin(); i != rVector.end(); ++i, ++nIndex )
2762 m_pSerializer->startElementNS( XML_w, nItem,
2763 FSNS( XML_w, XML_id ), OString::valueOf( nIndex ).getStr(),
2764 FSEND );
2766 const SwNodeIndex* pIndex = (*i)->GetTxtFtn()->GetStartNode();
2768 m_rExport.WriteSpecialText( pIndex->GetIndex() + 1,
2769 pIndex->GetNode().EndOfSectionIndex(),
2770 bFootnotes? TXT_FTN: TXT_EDN );
2772 m_pSerializer->endElementNS( XML_w, nItem );
2775 m_pSerializer->endElementNS( XML_w, nBody );
2779 void DocxAttributeOutput::ParaLineSpacing_Impl( short nSpace, short /*nMulti*/ )
2781 if ( !m_pSpacingAttrList )
2782 m_pSpacingAttrList = m_pSerializer->createAttrList();
2784 if ( nSpace < 0 )
2786 m_pSpacingAttrList->add( FSNS( XML_w, XML_lineRule ), "exact" );
2787 m_pSpacingAttrList->add( FSNS( XML_w, XML_line ), OString::valueOf( sal_Int32( -nSpace ) ) );
2789 else if ( nSpace > 0 )
2791 m_pSpacingAttrList->add( FSNS( XML_w, XML_lineRule ), "atLeast" );
2792 m_pSpacingAttrList->add( FSNS( XML_w, XML_line ), OString::valueOf( sal_Int32( nSpace ) ) );
2794 else
2795 m_pSpacingAttrList->add( FSNS( XML_w, XML_lineRule ), "auto" );
2798 void DocxAttributeOutput::ParaAdjust( const SvxAdjustItem& rAdjust )
2800 const char *pAdjustString;
2802 switch ( rAdjust.GetAdjust() )
2804 case SVX_ADJUST_LEFT:
2805 pAdjustString = "left";
2806 break;
2807 case SVX_ADJUST_RIGHT:
2808 pAdjustString = "right";
2809 break;
2810 case SVX_ADJUST_BLOCKLINE:
2811 case SVX_ADJUST_BLOCK:
2812 pAdjustString = "both";
2813 break;
2814 case SVX_ADJUST_CENTER:
2815 pAdjustString = "center";
2816 break;
2817 default:
2818 return; // not supported attribute
2820 m_pSerializer->singleElementNS( XML_w, XML_jc, FSNS( XML_w, XML_val ), pAdjustString, FSEND );
2823 void DocxAttributeOutput::ParaSplit( const SvxFmtSplitItem& rSplit )
2825 if (rSplit.GetValue())
2826 m_pSerializer->singleElementNS( XML_w, XML_keepLines, FSNS( XML_w, XML_val ), "off", FSEND );
2827 else
2828 m_pSerializer->singleElementNS( XML_w, XML_keepLines, FSEND );
2831 void DocxAttributeOutput::ParaWidows( const SvxWidowsItem& rWidows )
2833 if (rWidows.GetValue())
2834 m_pSerializer->singleElementNS( XML_w, XML_widowControl, FSEND );
2835 else
2836 m_pSerializer->singleElementNS( XML_w, XML_widowControl, FSNS( XML_w, XML_val ), "off", FSEND );
2839 static void impl_WriteTabElement( FSHelperPtr pSerializer,
2840 const SvxTabStop& rTab, long nCurrentLeft )
2842 FastAttributeList *pTabElementAttrList = pSerializer->createAttrList();
2844 switch (rTab.GetAdjustment())
2846 case SVX_TAB_ADJUST_RIGHT:
2847 pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"right") );
2848 break;
2849 case SVX_TAB_ADJUST_DECIMAL:
2850 pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"decimal") );
2851 break;
2852 case SVX_TAB_ADJUST_CENTER:
2853 pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"center") );
2854 break;
2855 case SVX_TAB_ADJUST_DEFAULT:
2856 case SVX_TAB_ADJUST_LEFT:
2857 default:
2858 pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"left") );
2859 break;
2862 pTabElementAttrList->add( FSNS( XML_w, XML_pos ), OString::valueOf( rTab.GetTabPos() + nCurrentLeft ) );
2864 sal_Unicode cFillChar = rTab.GetFill();
2866 if (sal_Unicode('.') == cFillChar )
2867 pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "dot" ) );
2868 else if ( sal_Unicode('-') == cFillChar )
2869 pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "hyphen" ) );
2870 else if ( sal_Unicode(0xB7) == cFillChar ) // middle dot
2871 pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "middleDot" ) );
2872 else if ( sal_Unicode('_') == cFillChar )
2873 pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "underscore" ) );
2874 else
2875 pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "none" ) );
2877 pSerializer->singleElementNS( XML_w, XML_tab, pTabElementAttrList );
2880 void DocxAttributeOutput::ParaTabStop( const SvxTabStopItem& rTabStop )
2882 const SfxPoolItem* pLR = m_rExport.HasItem( RES_LR_SPACE );
2883 long nCurrentLeft = pLR ? ((const SvxLRSpaceItem*)pLR)->GetTxtLeft() : 0;
2885 m_pSerializer->startElementNS( XML_w, XML_tabs, FSEND );
2887 sal_uInt16 nCount = rTabStop.Count();
2888 for (sal_uInt16 i = 0; i < nCount; i++ )
2889 impl_WriteTabElement( m_pSerializer, rTabStop[i], nCurrentLeft );
2891 m_pSerializer->endElementNS( XML_w, XML_tabs );
2894 void DocxAttributeOutput::ParaHyphenZone( const SvxHyphenZoneItem& rHyphenZone )
2896 m_pSerializer->singleElementNS( XML_w, XML_suppressAutoHyphens,
2897 FSNS( XML_w, XML_val ), rHyphenZone.IsHyphen( ) ? "false" : "true" ,
2898 FSEND );
2901 void DocxAttributeOutput::ParaNumRule_Impl( const SwTxtNode* /*pTxtNd*/, sal_Int32 nLvl, sal_Int32 nNumId )
2903 if ( USHRT_MAX != nNumId && 0 != nNumId )
2905 m_pSerializer->startElementNS( XML_w, XML_numPr, FSEND );
2906 m_pSerializer->singleElementNS( XML_w, XML_ilvl, FSNS( XML_w, XML_val ), OString::valueOf( sal_Int32( nLvl )).getStr(), FSEND );
2907 m_pSerializer->singleElementNS( XML_w, XML_numId, FSNS( XML_w, XML_val ), OString::valueOf( sal_Int32( nNumId )).getStr(), FSEND );
2908 m_pSerializer->endElementNS( XML_w, XML_numPr );
2912 void DocxAttributeOutput::ParaScriptSpace( const SfxBoolItem& rScriptSpace )
2914 USHORT nXmlElement = 0;
2916 switch ( rScriptSpace.Which( ) )
2918 case RES_PARATR_SCRIPTSPACE:
2919 nXmlElement = XML_autoSpaceDE;
2920 break;
2921 case RES_PARATR_HANGINGPUNCTUATION:
2922 nXmlElement = XML_overflowPunct;
2923 break;
2924 case RES_PARATR_FORBIDDEN_RULES:
2925 nXmlElement = XML_kinsoku;
2926 break;
2929 if ( nXmlElement )
2931 m_pSerializer->singleElementNS( XML_w, nXmlElement,
2932 FSNS( XML_w, XML_val ), rScriptSpace.GetValue( ) ? "true": "false",
2933 FSEND );
2937 void DocxAttributeOutput::ParaVerticalAlign( const SvxParaVertAlignItem& rAlign )
2939 const char *pAlignString;
2941 switch ( rAlign.GetValue() )
2943 case SvxParaVertAlignItem::BASELINE:
2944 pAlignString = "baseline";
2945 break;
2946 case SvxParaVertAlignItem::TOP:
2947 pAlignString = "top";
2948 break;
2949 case SvxParaVertAlignItem::CENTER:
2950 pAlignString = "center";
2951 break;
2952 case SvxParaVertAlignItem::BOTTOM:
2953 pAlignString = "bottom";
2954 break;
2955 case SvxParaVertAlignItem::AUTOMATIC:
2956 pAlignString = "auto";
2957 break;
2958 default:
2959 return; // not supported attribute
2961 m_pSerializer->singleElementNS( XML_w, XML_textAlignment, FSNS( XML_w, XML_val ), pAlignString, FSEND );
2964 void DocxAttributeOutput::ParaSnapToGrid( const SvxParaGridItem& rGrid )
2966 m_pSerializer->singleElementNS( XML_w, XML_snapToGrid,
2967 FSNS( XML_w, XML_val ), rGrid.GetValue( ) ? "true": "false",
2968 FSEND );
2971 void DocxAttributeOutput::FormatFrameSize( const SwFmtFrmSize& rSize )
2973 if ( m_rExport.bOutFlyFrmAttrs )
2975 #if OSL_DEBUG_LEVEL > 0
2976 fprintf( stderr, "TODO DocxAttributeOutput::FormatFrameSize() - Fly frames\n" );
2977 #endif
2979 else if ( m_rExport.bOutPageDescs )
2981 FastAttributeList *attrList = m_pSerializer->createAttrList( );
2982 if ( m_rExport.pAktPageDesc->GetLandscape( ) )
2983 attrList->add( FSNS( XML_w, XML_orient ), "landscape" );
2986 attrList->add( FSNS( XML_w, XML_w ), OString::valueOf( rSize.GetWidth( ) ) );
2987 attrList->add( FSNS( XML_w, XML_h ), OString::valueOf( rSize.GetHeight( ) ) );
2989 XFastAttributeListRef xAttrList( attrList );
2990 attrList = NULL;
2992 m_pSerializer->singleElementNS( XML_w, XML_pgSz, xAttrList );
2996 void DocxAttributeOutput::FormatPaperBin( const SvxPaperBinItem& )
2998 #if OSL_DEBUG_LEVEL > 0
2999 fprintf( stderr, "TODO DocxAttributeOutput::FormatPaperBin()\n" );
3000 #endif
3003 void DocxAttributeOutput::FormatLRSpace( const SvxLRSpaceItem& rLRSpace )
3005 if ( m_rExport.bOutFlyFrmAttrs )
3007 #if OSL_DEBUG_LEVEL > 0
3008 fprintf( stderr, "DocxAttributeOutput::FormatLRSpace() - Fly frames\n" );
3009 #endif
3011 else if ( m_rExport.bOutPageDescs )
3013 if ( !m_pSpacingAttrList )
3014 m_pSpacingAttrList = m_pSerializer->createAttrList();
3017 USHORT nLDist, nRDist;
3018 const SfxPoolItem* pItem = m_rExport.HasItem( RES_BOX );
3019 if ( pItem )
3021 nRDist = ((SvxBoxItem*)pItem)->CalcLineSpace( BOX_LINE_LEFT );
3022 nLDist = ((SvxBoxItem*)pItem)->CalcLineSpace( BOX_LINE_RIGHT );
3024 else
3025 nLDist = nRDist = 0;
3026 nLDist = nLDist + (USHORT)rLRSpace.GetLeft();
3027 nRDist = nRDist + (USHORT)rLRSpace.GetRight();
3029 m_pSpacingAttrList->add( FSNS( XML_w, XML_left ), OString::valueOf( sal_Int32( nLDist ) ) );
3030 m_pSpacingAttrList->add( FSNS( XML_w, XML_right ), OString::valueOf( sal_Int32( nRDist ) ) );
3032 else
3034 FastAttributeList *pLRSpaceAttrList = m_pSerializer->createAttrList();
3036 pLRSpaceAttrList->add( FSNS( XML_w, XML_left ), OString::valueOf( (sal_Int32) rLRSpace.GetTxtLeft() ) );
3037 pLRSpaceAttrList->add( FSNS( XML_w, XML_right ), OString::valueOf( (sal_Int32) rLRSpace.GetRight() ) );
3039 sal_Int32 nFirstLineAdjustment = rLRSpace.GetTxtFirstLineOfst();
3040 if (nFirstLineAdjustment > 0)
3041 pLRSpaceAttrList->add( FSNS( XML_w, XML_firstLine ), OString::valueOf( nFirstLineAdjustment ) );
3042 else
3043 pLRSpaceAttrList->add( FSNS( XML_w, XML_hanging ), OString::valueOf( - nFirstLineAdjustment ) );
3044 m_pSerializer->singleElementNS( XML_w, XML_ind, pLRSpaceAttrList );
3048 void DocxAttributeOutput::FormatULSpace( const SvxULSpaceItem& rULSpace )
3050 if (!m_pSpacingAttrList)
3051 m_pSpacingAttrList = m_pSerializer->createAttrList();
3053 if ( m_rExport.bOutFlyFrmAttrs )
3056 else if (m_rExport.bOutPageDescs )
3058 ASSERT( m_rExport.GetCurItemSet(), "Impossible" );
3059 if ( !m_rExport.GetCurItemSet() )
3060 return;
3062 HdFtDistanceGlue aDistances( *m_rExport.GetCurItemSet() );
3064 if ( aDistances.HasHeader() )
3066 // Header top
3067 m_pSpacingAttrList->add( FSNS( XML_w, XML_header ),
3068 OString::valueOf( sal_Int32( aDistances.dyaHdrTop ) ) );
3071 // Page top
3072 m_pSpacingAttrList->add( FSNS( XML_w, XML_top ),
3073 OString::valueOf( sal_Int32( aDistances.dyaTop ) ) );
3075 if ( aDistances.HasFooter() )
3077 // Footer bottom
3078 m_pSpacingAttrList->add( FSNS( XML_w, XML_footer ),
3079 OString::valueOf( sal_Int32( aDistances.dyaHdrBottom ) ) );
3082 // Page Bottom
3083 m_pSpacingAttrList->add( FSNS( XML_w, XML_bottom ),
3084 OString::valueOf( sal_Int32( aDistances.dyaBottom ) ) );
3087 else
3089 m_pSpacingAttrList->add( FSNS( XML_w, XML_before ),
3090 OString::valueOf( (sal_Int32)rULSpace.GetUpper() ) );
3091 m_pSpacingAttrList->add( FSNS( XML_w, XML_after ),
3092 OString::valueOf( (sal_Int32)rULSpace.GetLower() ) );
3096 void DocxAttributeOutput::FormatSurround( const SwFmtSurround& )
3098 #if OSL_DEBUG_LEVEL > 0
3099 fprintf( stderr, "TODO DocxAttributeOutput::FormatSurround()\n" );
3100 #endif
3103 void DocxAttributeOutput::FormatVertOrientation( const SwFmtVertOrient& )
3105 #if OSL_DEBUG_LEVEL > 0
3106 fprintf( stderr, "TODO DocxAttributeOutput::FormatVertOrientation()\n" );
3107 #endif
3110 void DocxAttributeOutput::FormatHorizOrientation( const SwFmtHoriOrient& )
3112 #if OSL_DEBUG_LEVEL > 0
3113 fprintf( stderr, "TODO DocxAttributeOutput::FormatHorizOrientation()\n" );
3114 #endif
3117 void DocxAttributeOutput::FormatAnchor( const SwFmtAnchor& )
3119 #if OSL_DEBUG_LEVEL > 0
3120 fprintf( stderr, "TODO DocxAttributeOutput::FormatAnchor()\n" );
3121 #endif
3124 void DocxAttributeOutput::FormatBackground( const SvxBrushItem& rBrush )
3126 if ( !m_rExport.bOutPageDescs )
3128 OString sColor = impl_ConvertColor( rBrush.GetColor( ) );
3129 m_pSerializer->singleElementNS( XML_w, XML_shd,
3130 FSNS( XML_w, XML_fill ), sColor.getStr( ),
3131 FSEND );
3134 #if OSL_DEBUG_LEVEL > 0
3135 fprintf( stderr, "TODO DocxAttributeOutput::FormatBackground()\n" );
3136 #endif
3139 void DocxAttributeOutput::FormatBox( const SvxBoxItem& rBox )
3142 if ( !m_bOpenedSectPr )
3144 // Normally open the borders tag for paragraphs
3145 m_pSerializer->startElementNS( XML_w, XML_pBdr, FSEND );
3148 impl_pageBorders( m_pSerializer, rBox );
3150 if ( m_bOpenedSectPr )
3152 // Special handling for pgBorder
3153 m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND );
3154 m_pSerializer->mergeTopMarks( );
3156 else
3158 // Normally close the borders tag for paragraphs
3159 m_pSerializer->endElementNS( XML_w, XML_pBdr );
3163 void DocxAttributeOutput::FormatColumns_Impl( USHORT nCols, const SwFmtCol& rCol, bool bEven, SwTwips nPageSize )
3165 // Get the columns attributes
3166 FastAttributeList *pColsAttrList = m_pSerializer->createAttrList();
3168 pColsAttrList->add( FSNS( XML_w, XML_num ),
3169 OString::valueOf( sal_Int32( nCols ) ). getStr( ) );
3171 const char* pEquals = "false";
3172 if ( bEven )
3174 USHORT nWidth = rCol.GetGutterWidth( true );
3175 pColsAttrList->add( FSNS( XML_w, XML_space ),
3176 OString::valueOf( sal_Int32( nWidth ) ).getStr( ) );
3178 pEquals = "true";
3181 pColsAttrList->add( FSNS( XML_w, XML_equalWidth ), pEquals );
3183 bool bHasSep = COLADJ_NONE == rCol.GetLineAdj( );
3184 pColsAttrList->add( FSNS( XML_w, XML_sep ), bHasSep ? "true" : "false" );
3186 // Write the element
3187 m_pSerializer->startElementNS( XML_w, XML_cols, pColsAttrList );
3189 // Write the columns width if non-equals
3190 const SwColumns & rColumns = rCol.GetColumns( );
3191 if ( !bEven )
3193 for ( USHORT n = 0; n < nCols; ++n )
3195 FastAttributeList *pColAttrList = m_pSerializer->createAttrList();
3196 USHORT nWidth = rCol.CalcPrtColWidth( n, ( USHORT ) nPageSize );
3197 pColAttrList->add( FSNS( XML_w, XML_w ),
3198 OString::valueOf( sal_Int32( nWidth ) ).getStr( ) );
3200 if ( n + 1 != nCols )
3202 USHORT nSpacing = rColumns[n]->GetRight( ) + rColumns[n + 1]->GetLeft( );
3203 pColAttrList->add( FSNS( XML_w, XML_space ),
3204 OString::valueOf( sal_Int32( nSpacing ) ).getStr( ) );
3207 m_pSerializer->singleElementNS( XML_w, XML_col, pColAttrList );
3211 m_pSerializer->endElementNS( XML_w, XML_cols );
3214 void DocxAttributeOutput::FormatKeep( const SvxFmtKeepItem& )
3216 m_pSerializer->singleElementNS( XML_w, XML_keepNext, FSEND );
3219 void DocxAttributeOutput::FormatTextGrid( const SwTextGridItem& )
3221 #if OSL_DEBUG_LEVEL > 0
3222 fprintf( stderr, "TODO DocxAttributeOutput::FormatTextGrid()\n" );
3223 #endif
3226 void DocxAttributeOutput::FormatLineNumbering( const SwFmtLineNumber& rNumbering )
3228 if ( !rNumbering.IsCount( ) )
3229 m_pSerializer->singleElementNS( XML_w, XML_suppressLineNumbers, FSEND );
3232 void DocxAttributeOutput::FormatFrameDirection( const SvxFrameDirectionItem& rDirection )
3234 OString sTextFlow;
3235 bool bBiDi = false;
3236 short nDir = rDirection.GetValue();
3238 if ( nDir == FRMDIR_ENVIRONMENT )
3239 nDir = GetExport( ).GetDefaultFrameDirection( );
3241 switch ( nDir )
3243 default:
3244 case FRMDIR_HORI_LEFT_TOP:
3245 sTextFlow = OString( "lrTb" );
3246 break;
3247 case FRMDIR_HORI_RIGHT_TOP:
3248 sTextFlow = OString( "lrTb" );
3249 bBiDi = true;
3250 break;
3251 case FRMDIR_VERT_TOP_LEFT: // many things but not this one
3252 case FRMDIR_VERT_TOP_RIGHT:
3253 sTextFlow = OString( "tbRl" );
3254 break;
3257 if ( m_rExport.bOutPageDescs )
3259 m_pSerializer->singleElementNS( XML_w, XML_textDirection,
3260 FSNS( XML_w, XML_val ), sTextFlow.getStr( ),
3261 FSEND );
3262 if ( bBiDi )
3263 m_pSerializer->singleElementNS( XML_w, XML_bidi, FSEND );
3265 else if ( !m_rExport.bOutFlyFrmAttrs )
3267 if ( bBiDi )
3268 m_pSerializer->singleElementNS( XML_w, XML_bidi, FSEND );
3272 DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, FSHelperPtr pSerializer, oox::drawingml::DrawingML* pDrawingML )
3273 : m_rExport( rExport ),
3274 m_pSerializer( pSerializer ),
3275 m_rDrawingML( *pDrawingML ),
3276 m_pFontsAttrList( NULL ),
3277 m_pEastAsianLayoutAttrList( NULL ),
3278 m_pCharLangAttrList( NULL ),
3279 m_pSpacingAttrList( NULL ),
3280 m_pHyperlinkAttrList( NULL ),
3281 m_pFootnotesList( new ::docx::FootnotesList() ),
3282 m_pEndnotesList( new ::docx::FootnotesList() ),
3283 m_pSectionInfo( NULL ),
3284 m_pRedlineData( NULL ),
3285 m_nRedlineId( 0 ),
3286 m_bOpenedSectPr( false ),
3287 m_sFieldBkm( ),
3288 m_nNextMarkId( 0 ),
3289 m_pTableWrt( NULL ),
3290 m_bTableCellOpen( false ),
3291 m_nTableDepth( 0 ),
3292 m_bParagraphOpened( false ),
3293 m_nColBreakStatus( COLBRK_NONE )
3297 DocxAttributeOutput::~DocxAttributeOutput()
3299 delete m_pFontsAttrList, m_pFontsAttrList = NULL;
3300 delete m_pEastAsianLayoutAttrList, m_pEastAsianLayoutAttrList = NULL;
3301 delete m_pCharLangAttrList, m_pCharLangAttrList = NULL;
3302 delete m_pSpacingAttrList, m_pSpacingAttrList = NULL;
3303 delete m_pHyperlinkAttrList, m_pHyperlinkAttrList = NULL;
3305 delete m_pFootnotesList, m_pFootnotesList = NULL;
3306 delete m_pEndnotesList, m_pEndnotesList = NULL;
3308 delete m_pTableWrt, m_pTableWrt = NULL;
3311 MSWordExportBase& DocxAttributeOutput::GetExport()
3313 return m_rExport;
3316 bool DocxAttributeOutput::HasFootnotes()
3318 return !m_pFootnotesList->isEmpty();
3321 bool DocxAttributeOutput::HasEndnotes()
3323 return !m_pEndnotesList->isEmpty();