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

Generated by: LCOV version 1.10