LCOV - code coverage report
Current view: top level - libreoffice/sw/source/filter/ww8 - docxattributeoutput.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 1167 2255 51.8 %
Date: 2012-12-27 Functions: 123 200 61.5 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10