LCOV - code coverage report
Current view: top level - sw/source/filter/ww8 - docxattributeoutput.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 3111 3614 86.1 %
Date: 2014-04-11 Functions: 222 246 90.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 "docxhelper.hxx"
      22             : #include "docxsdrexport.hxx"
      23             : #include "docxexportfilter.hxx"
      24             : #include "docxfootnotes.hxx"
      25             : #include "writerwordglue.hxx"
      26             : #include "ww8par.hxx"
      27             : #include "fmtcntnt.hxx"
      28             : #include "fmtftn.hxx"
      29             : #include "fchrfmt.hxx"
      30             : #include "tgrditem.hxx"
      31             : #include "fmtruby.hxx"
      32             : #include "breakit.hxx"
      33             : #include "redline.hxx"
      34             : #include "unocoll.hxx"
      35             : #include "unoframe.hxx"
      36             : #include "wrtww8.hxx"
      37             : 
      38             : #include "wrtww8.hxx"
      39             : 
      40             : #include <comphelper/string.hxx>
      41             : #include <oox/token/tokens.hxx>
      42             : #include <oox/export/utils.hxx>
      43             : #include <oox/mathml/export.hxx>
      44             : #include <oox/drawingml/drawingmltypes.hxx>
      45             : 
      46             : #include <editeng/autokernitem.hxx>
      47             : #include <editeng/unoprnms.hxx>
      48             : #include <editeng/fontitem.hxx>
      49             : #include <editeng/tstpitem.hxx>
      50             : #include <editeng/spltitem.hxx>
      51             : #include <editeng/widwitem.hxx>
      52             : #include <editeng/shaditem.hxx>
      53             : #include <editeng/brushitem.hxx>
      54             : #include <editeng/postitem.hxx>
      55             : #include <editeng/wghtitem.hxx>
      56             : #include <editeng/kernitem.hxx>
      57             : #include <editeng/crossedoutitem.hxx>
      58             : #include <editeng/cmapitem.hxx>
      59             : #include <editeng/udlnitem.hxx>
      60             : #include <editeng/langitem.hxx>
      61             : #include <editeng/lspcitem.hxx>
      62             : #include <editeng/escapementitem.hxx>
      63             : #include <editeng/fhgtitem.hxx>
      64             : #include <editeng/colritem.hxx>
      65             : #include <editeng/hyphenzoneitem.hxx>
      66             : #include <editeng/ulspitem.hxx>
      67             : #include <editeng/boxitem.hxx>
      68             : #include <editeng/contouritem.hxx>
      69             : #include <editeng/shdditem.hxx>
      70             : #include <editeng/emphasismarkitem.hxx>
      71             : #include <editeng/twolinesitem.hxx>
      72             : #include <editeng/charscaleitem.hxx>
      73             : #include <editeng/charrotateitem.hxx>
      74             : #include <editeng/charreliefitem.hxx>
      75             : #include <editeng/paravertalignitem.hxx>
      76             : #include <editeng/pgrditem.hxx>
      77             : #include <editeng/frmdiritem.hxx>
      78             : #include <editeng/blinkitem.hxx>
      79             : #include <editeng/charhiddenitem.hxx>
      80             : #include <editeng/editobj.hxx>
      81             : #include <svx/xfillit0.hxx>
      82             : #include <svx/xflgrit.hxx>
      83             : #include <svx/fmglob.hxx>
      84             : #include <svx/svdouno.hxx>
      85             : #include <svl/grabbagitem.hxx>
      86             : #include <sfx2/sfxbasemodel.hxx>
      87             : #include <tools/datetimeutils.hxx>
      88             : #include <svl/whiter.hxx>
      89             : 
      90             : #include <docufld.hxx>
      91             : #include <flddropdown.hxx>
      92             : #include <fmtclds.hxx>
      93             : #include <fmtinfmt.hxx>
      94             : #include <fmtrowsplt.hxx>
      95             : #include <fmtline.hxx>
      96             : #include <ftninfo.hxx>
      97             : #include <htmltbl.hxx>
      98             : #include <lineinfo.hxx>
      99             : #include <ndgrf.hxx>
     100             : #include <ndole.hxx>
     101             : #include <ndtxt.hxx>
     102             : #include <pagedesc.hxx>
     103             : #include <paratr.hxx>
     104             : #include <charatr.hxx>
     105             : #include <swmodule.hxx>
     106             : #include <swtable.hxx>
     107             : #include <txtftn.hxx>
     108             : #include <txtinet.hxx>
     109             : #include <fmtautofmt.hxx>
     110             : #include <docsh.hxx>
     111             : #include <docary.hxx>
     112             : 
     113             : #include <osl/file.hxx>
     114             : #include <vcl/embeddedfontshelper.hxx>
     115             : #include <svtools/miscopt.hxx>
     116             : 
     117             : #include <com/sun/star/i18n/ScriptType.hpp>
     118             : #include <com/sun/star/chart2/XChartDocument.hpp>
     119             : #include <com/sun/star/drawing/ShadingPattern.hpp>
     120             : #include <com/sun/star/text/GraphicCrop.hpp>
     121             : 
     122             : #include <algorithm>
     123             : 
     124             : #if OSL_DEBUG_LEVEL > 1
     125             : #include <stdio.h>
     126             : #endif
     127             : 
     128             : using ::editeng::SvxBorderLine;
     129             : 
     130             : using namespace oox;
     131             : using namespace docx;
     132             : using namespace sax_fastparser;
     133             : using namespace nsSwDocInfoSubType;
     134             : using namespace nsFieldFlags;
     135             : using namespace sw::util;
     136             : using namespace ::com::sun::star;
     137             : using namespace ::com::sun::star::drawing;
     138             : 
     139           1 : class FFDataWriterHelper
     140             : {
     141             :     ::sax_fastparser::FSHelperPtr m_pSerializer;
     142           1 :     void writeCommonStart( const OUString& rName )
     143             :     {
     144           1 :         m_pSerializer->startElementNS( XML_w, XML_ffData, FSEND );
     145             :         m_pSerializer->singleElementNS( XML_w, XML_name,
     146             :             FSNS( XML_w, XML_val ), OUStringToOString( rName, RTL_TEXTENCODING_UTF8 ).getStr(),
     147           1 :             FSEND );
     148           1 :         m_pSerializer->singleElementNS( XML_w, XML_enabled, FSEND );
     149             :         m_pSerializer->singleElementNS( XML_w, XML_calcOnExit,
     150             :             FSNS( XML_w, XML_val ),
     151           1 :             "0", FSEND );
     152           1 :     }
     153           1 :     void writeFinish()
     154             :     {
     155           1 :         m_pSerializer->endElementNS( XML_w, XML_ffData );
     156           1 :     }
     157             : public:
     158           1 :     FFDataWriterHelper( const ::sax_fastparser::FSHelperPtr pSerializer ) : m_pSerializer( pSerializer ){}
     159           1 :     void WriteFormCheckbox( const OUString& rName, const OUString& rDefault, bool bChecked )
     160             :     {
     161           1 :        writeCommonStart( rName );
     162             :        // Checkbox specific bits
     163           1 :        m_pSerializer->startElementNS( XML_w, XML_checkBox, FSEND );
     164             :        // currently hardcoding autosize
     165             :        // #TODO check if this defaulted
     166           1 :        m_pSerializer->startElementNS( XML_w, XML_sizeAuto, FSEND );
     167           1 :        m_pSerializer->endElementNS( XML_w, XML_sizeAuto );
     168           1 :        if ( !rDefault.isEmpty() )
     169             :        {
     170             :            m_pSerializer->singleElementNS( XML_w, XML_default,
     171             :                FSNS( XML_w, XML_val ),
     172           0 :                    OUStringToOString( rDefault, RTL_TEXTENCODING_UTF8 ).getStr(), FSEND );
     173             :        }
     174           1 :        if ( bChecked )
     175           0 :             m_pSerializer->singleElementNS( XML_w, XML_checked, FSEND );
     176           1 :         m_pSerializer->endElementNS( XML_w, XML_checkBox );
     177           1 :        writeFinish();
     178           1 :     }
     179           0 :     void WriteFormText(  const OUString& rName, const OUString& rDefault )
     180             :     {
     181           0 :        writeCommonStart( rName );
     182           0 :        if ( !rDefault.isEmpty() )
     183             :        {
     184           0 :            m_pSerializer->startElementNS( XML_w, XML_textInput, FSEND );
     185             :            m_pSerializer->singleElementNS( XML_w, XML_default,
     186             :                FSNS( XML_w, XML_val ),
     187           0 :                OUStringToOString( rDefault, RTL_TEXTENCODING_UTF8 ).getStr(), FSEND );
     188           0 :            m_pSerializer->endElementNS( XML_w, XML_textInput );
     189             :        }
     190           0 :        writeFinish();
     191           0 :     }
     192             : };
     193             : 
     194             : class FieldMarkParamsHelper
     195             : {
     196             :     const sw::mark::IFieldmark& mrFieldmark;
     197             :     public:
     198           1 :     FieldMarkParamsHelper( const sw::mark::IFieldmark& rFieldmark ) : mrFieldmark( rFieldmark ) {}
     199           0 :     OUString getName() { return mrFieldmark.GetName(); }
     200             :     template < typename T >
     201           1 :     bool extractParam( const OUString& rKey, T& rResult )
     202             :     {
     203           1 :         bool bResult = false;
     204           1 :         if ( mrFieldmark.GetParameters() )
     205             :         {
     206           1 :             sw::mark::IFieldmark::parameter_map_t::const_iterator it = mrFieldmark.GetParameters()->find( rKey );
     207           1 :             if ( it != mrFieldmark.GetParameters()->end() )
     208           0 :                 bResult = ( it->second >>= rResult );
     209             :         }
     210           1 :         return bResult;
     211             :     }
     212             : };
     213        6489 : void DocxAttributeOutput::RTLAndCJKState( bool bIsRTL, sal_uInt16 /*nScript*/ )
     214             : {
     215        6489 :     if (bIsRTL)
     216          23 :         m_pSerializer->singleElementNS( XML_w, XML_rtl, FSNS( XML_w, XML_val ), "true", FSEND );
     217        6489 : }
     218             : 
     219        5393 : void DocxAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo )
     220             : {
     221        5393 :     if ( m_nColBreakStatus == COLBRK_POSTPONE )
     222           2 :         m_nColBreakStatus = COLBRK_WRITE;
     223             : 
     224             :     // Output table/table row/table cell starts if needed
     225        5393 :     if ( pTextNodeInfo.get() )
     226             :     {
     227        1602 :         sal_uInt32 nRow = pTextNodeInfo->getRow();
     228        1602 :         sal_uInt32 nCell = pTextNodeInfo->getCell();
     229             : 
     230             :         // New cell/row?
     231        1602 :         if ( m_tableReference->m_nTableDepth > 0 && !m_tableReference->m_bTableCellOpen )
     232             :         {
     233        1295 :             ww8::WW8TableNodeInfoInner::Pointer_t pDeepInner( pTextNodeInfo->getInnerForDepth( m_tableReference->m_nTableDepth ) );
     234        1295 :             if ( pDeepInner->getCell() == 0 )
     235         421 :                 StartTableRow( pDeepInner );
     236             : 
     237        1295 :             StartTableCell( pDeepInner );
     238             :         }
     239             : 
     240        1602 :         if ( nRow == 0 && nCell == 0 )
     241             :         {
     242             :             // Do we have to start the table?
     243             :             // [If we are at the right depth already, it means that we
     244             :             // continue the table cell]
     245         175 :             sal_uInt32 nCurrentDepth = pTextNodeInfo->getDepth();
     246             : 
     247         175 :             if ( nCurrentDepth > m_tableReference->m_nTableDepth )
     248             :             {
     249             :                 // Start all the tables that begin here
     250         186 :                 for ( sal_uInt32 nDepth = m_tableReference->m_nTableDepth + 1; nDepth <= pTextNodeInfo->getDepth(); ++nDepth )
     251             :                 {
     252          99 :                     ww8::WW8TableNodeInfoInner::Pointer_t pInner( pTextNodeInfo->getInnerForDepth( nDepth ) );
     253             : 
     254          99 :                     if (m_tableReference->m_pOldTablepInner && m_tableReference->m_pOldTablepInner->getTable() == pInner->getTable() && nCurrentDepth > 1 &&  nDepth != 1)
     255             :                     {
     256           5 :                        m_tableReference->m_pOldTablepInner = pInner;
     257           5 :                        break;
     258             :                     }
     259             :                     else
     260             :                     {
     261          94 :                     StartTable( pInner );
     262          94 :                     StartTableRow( pInner );
     263          94 :                     StartTableCell( pInner );
     264          94 :                     m_tableReference->m_pOldTablepInner = pInner;
     265             :                     }
     266          94 :                 }
     267             : 
     268          92 :                 m_tableReference->m_nTableDepth = nCurrentDepth;
     269             :             }
     270             :         }
     271             :     }
     272             : 
     273             :     // this mark is used to be able to enclose the paragraph inside a sdr tag.
     274             :     // We will only know if we have to do that later.
     275        5393 :     m_pSerializer->mark();
     276             : 
     277        5393 :     m_pSerializer->startElementNS( XML_w, XML_p, FSEND );
     278             : 
     279             :     // postpone the output of the run (we get it before the paragraph
     280             :     // properties, but must write it after them)
     281        5393 :     m_pSerializer->mark();
     282             : 
     283             :     // no section break in this paragraph yet; can be set in SectionBreak()
     284        5393 :     m_pSectionInfo.reset();
     285             : 
     286        5393 :     m_bParagraphOpened = true;
     287        5393 :     m_bIsFirstParagraph = false;
     288        5393 : }
     289             : 
     290        5393 : void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner )
     291             : {
     292             :     // write the paragraph properties + the run, already in the correct order
     293        5393 :     m_pSerializer->mergeTopMarks();
     294             : 
     295             :     // Write the anchored frame if any
     296             :     // Word can't handle nested text boxes, so write them on the same level.
     297        5393 :     ++m_nTextFrameLevel;
     298        5393 :     if( m_nTextFrameLevel == 1 )
     299             :     {
     300        4751 :         for (size_t nIndex = 0; nIndex < m_aFramesOfParagraph.size(); ++nIndex)
     301             :         {
     302         115 :             sw::Frame aFrame = m_aFramesOfParagraph[nIndex];
     303         115 :             m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
     304             : 
     305         115 :             m_pSerializer->startElementNS(XML_mc, XML_AlternateContent, FSEND);
     306             :             m_pSerializer->startElementNS(XML_mc, XML_Choice,
     307             :                     XML_Requires, "wps",
     308         115 :                     FSEND);
     309             :             /**
     310             :                This is to avoid AltenateContent within another AlternateContent.
     311             :                So when Choice is Open, only write the DML Drawing instead of both DML
     312             :                and VML Drawing in another AlternateContent.
     313             :             **/
     314         115 :             SetAlternateContentChoiceOpen( true );
     315             :             /** FDO#71834 :
     316             :                We should probably be renaming the function
     317             :                switchHeaderFooter to something like SaveRetrieveTableReference.
     318             :                Save the table reference attributes before calling WriteDMLTextFrame,
     319             :                otherwise the StartParagraph function will use the previous existing
     320             :                table reference attributes since the variable is being shared.
     321             :             */
     322         115 :             switchHeaderFooter(true,1);
     323             :             /** Save the table info's before writing the shape
     324             :                 as there might be a new table that might get
     325             :                 spawned from within the VML & DML block and alter
     326             :                 the contents.
     327             :             */
     328         230 :             ww8::WW8TableInfo::Pointer_t pOldTableInfo = m_rExport.mpTableInfo;
     329             :             //Reset the table infos after saving.
     330         115 :             m_rExport.mpTableInfo = ww8::WW8TableInfo::Pointer_t(new ww8::WW8TableInfo());
     331             : 
     332         115 :             m_rExport.SdrExporter().writeDMLTextFrame(&aFrame, m_anchorId++);
     333         115 :             m_pSerializer->endElementNS(XML_mc, XML_Choice);
     334         115 :             SetAlternateContentChoiceOpen( false );
     335             : 
     336             :             // Reset table infos, otherwise the depth of the cells will be incorrect,
     337             :             // in case the text frame had table(s) and we try to export the
     338             :             // same table second time.
     339         115 :             m_rExport.mpTableInfo = ww8::WW8TableInfo::Pointer_t(new ww8::WW8TableInfo());
     340             :             //reset the tableReference.
     341         115 :             switchHeaderFooter(false,0);
     342             : 
     343         115 :             m_pSerializer->startElementNS(XML_mc, XML_Fallback, FSEND);
     344         115 :             m_rExport.SdrExporter().writeVMLTextFrame(&aFrame);
     345             :             /* FDO#71834 :Restore the data here after having written the Shape
     346             :                for further processing.
     347             :             */
     348         115 :             switchHeaderFooter(false,-1);
     349         115 :             m_rExport.mpTableInfo = pOldTableInfo;
     350             : 
     351         115 :             m_pSerializer->endElementNS(XML_mc, XML_Fallback);
     352         115 :             m_pSerializer->endElementNS(XML_mc, XML_AlternateContent);
     353             : 
     354         115 :             m_pSerializer->endElementNS( XML_w, XML_r );
     355         115 :         }
     356             : 
     357        4636 :         m_aFramesOfParagraph.clear();
     358             :     }
     359             : 
     360        5393 :     --m_nTextFrameLevel;
     361             : 
     362             :     /* If m_nHyperLinkCount > 0 that means hyperlink tag is not yet colsed.
     363             :      * This is due to nested hyperlink tags. So close it before end of paragraph.
     364             :      */
     365        5393 :     if(m_nHyperLinkCount > 0)
     366             :     {
     367           2 :         for(sal_Int32 nHyperLinkToClose = 0; nHyperLinkToClose < m_nHyperLinkCount; ++nHyperLinkToClose)
     368           1 :             m_pSerializer->endElementNS( XML_w, XML_hyperlink );
     369           1 :         m_nHyperLinkCount = 0;
     370             :     }
     371             : 
     372        5393 :     m_pSerializer->endElementNS( XML_w, XML_p );
     373             : 
     374        5393 :     WriteSdtBlock( m_nParagraphSdtPrToken, m_pParagraphSdtPrTokenChildren, m_pParagraphSdtPrDataBindingAttrs );
     375        5393 :     m_pSerializer->mergeTopMarks();
     376             : 
     377             :     // Check for end of cell, rows, tables here
     378        5393 :     FinishTableRowCell( pTextNodeInfoInner );
     379             : 
     380        5393 :     m_bParagraphOpened = false;
     381             : 
     382        5393 : }
     383             : 
     384       11887 : void DocxAttributeOutput::WriteSdtBlock( sal_Int32& nSdtPrToken, ::sax_fastparser::FastAttributeList* &pSdtPrTokenChildren, ::sax_fastparser::FastAttributeList* &pSdtPrDataBindingAttrs )
     385             : {
     386       11887 :     if( nSdtPrToken > 0 || pSdtPrDataBindingAttrs )
     387             :     {
     388             :         // sdt start mark
     389          55 :         m_pSerializer->mark();
     390             : 
     391          55 :         m_pSerializer->startElementNS( XML_w, XML_sdt, FSEND );
     392             : 
     393             :         // output sdt properties
     394          55 :         m_pSerializer->startElementNS( XML_w, XML_sdtPr, FSEND );
     395             : 
     396          55 :         if( nSdtPrToken > 0 && pSdtPrTokenChildren )
     397             :         {
     398          30 :             m_pSerializer->startElement( nSdtPrToken, FSEND );
     399             : 
     400          30 :             uno::Sequence<xml::FastAttribute> aChildren = pSdtPrTokenChildren->getFastAttributes();
     401         101 :             for( sal_Int32 i=0; i < aChildren.getLength(); ++i )
     402          71 :                 m_pSerializer->singleElement( aChildren[i].Token,
     403             :                                               FSNS(XML_w, XML_val),
     404          71 :                                               rtl::OUStringToOString( aChildren[i].Value, RTL_TEXTENCODING_UTF8 ).getStr(),
     405         142 :                                               FSEND );
     406             : 
     407          30 :             m_pSerializer->endElement( nSdtPrToken );
     408             :         }
     409          25 :         else if( nSdtPrToken == FSNS( XML_w, XML_id ) )
     410             :             //Word won't open a document with an empty id tag, we fill it with a random number
     411             :             m_pSerializer->singleElement( nSdtPrToken,
     412             :                                           FSNS(XML_w, XML_val), OString::number( rand() ),
     413           8 :                                           FSEND );
     414          17 :         else if( nSdtPrToken > 0 )
     415          17 :             m_pSerializer->singleElement( nSdtPrToken, FSEND );
     416             : 
     417          55 :         if( pSdtPrDataBindingAttrs )
     418             :         {
     419          11 :             XFastAttributeListRef xAttrList( pSdtPrDataBindingAttrs );
     420          11 :             m_pSerializer->singleElementNS( XML_w, XML_dataBinding, xAttrList );
     421             :         }
     422             : 
     423          55 :         m_pSerializer->endElementNS( XML_w, XML_sdtPr );
     424             : 
     425             :         // sdt contents start tag
     426          55 :         m_pSerializer->startElementNS( XML_w, XML_sdtContent, FSEND );
     427             : 
     428             :         // prepend the tags since the sdt start mark before the paragraph
     429          55 :         m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND );
     430             : 
     431             :         // write the ending tags after the paragraph
     432          55 :         m_pSerializer->endElementNS( XML_w, XML_sdtContent );
     433          55 :         m_pSerializer->endElementNS( XML_w, XML_sdt );
     434             : 
     435             :         // clear sdt status
     436          55 :         nSdtPrToken = 0;
     437          55 :         delete pSdtPrTokenChildren; pSdtPrTokenChildren = NULL;
     438          55 :         if( pSdtPrDataBindingAttrs )
     439             :         {
     440             :             // do not delete yet; it's in xAttrList inside the parser
     441          11 :             pSdtPrDataBindingAttrs = NULL;
     442             :         }
     443             :     }
     444       11887 : }
     445             : 
     446        8379 : void DocxAttributeOutput::FinishTableRowCell( ww8::WW8TableNodeInfoInner::Pointer_t pInner, bool bForceEmptyParagraph )
     447             : {
     448        8379 :     if ( pInner.get() )
     449             :     {
     450             :         // Where are we in the table
     451        4588 :         sal_uInt32 nRow = pInner->getRow( );
     452             : 
     453        4588 :         const SwTable *pTable = pInner->getTable( );
     454        4588 :         const SwTableLines& rLines = pTable->GetTabLines( );
     455        4588 :         sal_uInt16 nLinesCount = rLines.size( );
     456             :         // HACK
     457             :         // msoffice seems to have an internal limitation of 63 columns for tables
     458             :         // and refuses to load .docx with more, even though the spec seems to allow that;
     459             :         // so simply if there are more columns, don't close the last one msoffice will handle
     460             :         // and merge the contents of the remaining ones into it (since we don't close the cell
     461             :         // here, following ones will not be opened)
     462        4588 :         bool limitWorkaround = ( pInner->getCell() >= 62 && !pInner->isEndOfLine());
     463             : 
     464        4588 :         if ( pInner->isEndOfCell() && !limitWorkaround )
     465             :         {
     466        1389 :             if ( bForceEmptyParagraph )
     467           0 :                 m_pSerializer->singleElementNS( XML_w, XML_p, FSEND );
     468             : 
     469        1389 :             EndTableCell();
     470             :         }
     471             : 
     472             :         // This is a line end
     473        4588 :         if ( pInner->isEndOfLine() )
     474         515 :             EndTableRow();
     475             : 
     476             :         // This is the end of the table
     477        4588 :         if ( pInner->isEndOfLine( ) && ( nRow + 1 ) == nLinesCount )
     478          94 :             EndTable();
     479             :     }
     480        8379 : }
     481             : 
     482           0 : void DocxAttributeOutput::EmptyParagraph()
     483             : {
     484           0 :     m_pSerializer->singleElementNS( XML_w, XML_p, FSEND );
     485           0 : }
     486             : 
     487        5189 : void DocxAttributeOutput::SectionBreaks(const SwTxtNode& rNode)
     488             : {
     489             :     // output page/section breaks
     490             :     // Writer can have them at the beginning of a paragraph, or at the end, but
     491             :     // in docx, we have to output them in the paragraph properties of the last
     492             :     // paragraph in a section.  To get it right, we have to switch to the next
     493             :     // paragraph, and detect the section breaks there.
     494        5189 :     SwNodeIndex aNextIndex( rNode, 1 );
     495        5189 :     if ( aNextIndex.GetNode().IsTxtNode() )
     496             :     {
     497        3084 :         const SwTxtNode* pTxtNode = static_cast< SwTxtNode* >( &aNextIndex.GetNode() );
     498        3084 :         m_rExport.OutputSectionBreaks( pTxtNode->GetpSwAttrSet(), *pTxtNode, m_tableReference->m_bTableCellOpen, pTxtNode->GetTxt().isEmpty() );
     499             :     }
     500        2105 :     else if ( aNextIndex.GetNode().IsTableNode() )
     501             :     {
     502          26 :         const SwTableNode* pTableNode = static_cast< SwTableNode* >( &aNextIndex.GetNode() );
     503          26 :         const SwFrmFmt *pFmt = pTableNode->GetTable().GetFrmFmt();
     504          26 :         m_rExport.OutputSectionBreaks( &(pFmt->GetAttrSet()), *pTableNode );
     505        5189 :     }
     506        5189 : }
     507             : 
     508        5388 : void DocxAttributeOutput::StartParagraphProperties()
     509             : {
     510        5388 :     m_pSerializer->mark( );
     511             : 
     512        5388 :     m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND );
     513             : 
     514             :     // and output the section break now (if it appeared)
     515        5388 :     if ( m_pSectionInfo && (!m_setFootnote))
     516             :     {
     517          13 :         m_rExport.SectionProperties( *m_pSectionInfo );
     518          13 :         m_pSectionInfo.reset();
     519             :     }
     520             : 
     521        5388 :     InitCollectedParagraphProperties();
     522        5388 : }
     523             : 
     524        9028 : void DocxAttributeOutput::InitCollectedParagraphProperties()
     525             : {
     526        9028 :     m_pParagraphSpacingAttrList = NULL;
     527             : 
     528             :     // Write the elements in the spec order
     529             :     static const sal_Int32 aOrder[] =
     530             :     {
     531             :         FSNS( XML_w, XML_pStyle ),
     532             :         FSNS( XML_w, XML_keepNext ),
     533             :         FSNS( XML_w, XML_keepLines ),
     534             :         FSNS( XML_w, XML_pageBreakBefore ),
     535             :         FSNS( XML_w, XML_framePr ),
     536             :         FSNS( XML_w, XML_widowControl ),
     537             :         FSNS( XML_w, XML_numPr ),
     538             :         FSNS( XML_w, XML_suppressLineNumbers ),
     539             :         FSNS( XML_w, XML_pBdr ),
     540             :         FSNS( XML_w, XML_shd ),
     541             :         FSNS( XML_w, XML_tabs ),
     542             :         FSNS( XML_w, XML_suppressAutoHyphens ),
     543             :         FSNS( XML_w, XML_kinsoku ),
     544             :         FSNS( XML_w, XML_wordWrap ),
     545             :         FSNS( XML_w, XML_overflowPunct ),
     546             :         FSNS( XML_w, XML_topLinePunct ),
     547             :         FSNS( XML_w, XML_autoSpaceDE ),
     548             :         FSNS( XML_w, XML_autoSpaceDN ),
     549             :         FSNS( XML_w, XML_bidi ),
     550             :         FSNS( XML_w, XML_adjustRightInd ),
     551             :         FSNS( XML_w, XML_snapToGrid ),
     552             :         FSNS( XML_w, XML_spacing ),
     553             :         FSNS( XML_w, XML_ind ),
     554             :         FSNS( XML_w, XML_contextualSpacing ),
     555             :         FSNS( XML_w, XML_mirrorIndents ),
     556             :         FSNS( XML_w, XML_suppressOverlap ),
     557             :         FSNS( XML_w, XML_jc ),
     558             :         FSNS( XML_w, XML_textDirection ),
     559             :         FSNS( XML_w, XML_textAlignment ),
     560             :         FSNS( XML_w, XML_textboxTightWrap ),
     561             :         FSNS( XML_w, XML_outlineLvl ),
     562             :         FSNS( XML_w, XML_divId ),
     563             :         FSNS( XML_w, XML_cnfStyle ),
     564             :         FSNS( XML_w, XML_rPr ),
     565             :         FSNS( XML_w, XML_sectPr ),
     566             :         FSNS( XML_w, XML_pPrChange )
     567             :     };
     568             : 
     569             :     // postpone the output so that we can later [in EndParagraphProperties()]
     570             :     // prepend the properties before the run
     571        9028 :     sal_Int32 len = sizeof ( aOrder ) / sizeof( sal_Int32 );
     572        9028 :     uno::Sequence< sal_Int32 > aSeqOrder( len );
     573      334036 :     for ( sal_Int32 i = 0; i < len; i++ )
     574      325008 :         aSeqOrder[i] = aOrder[i];
     575             : 
     576        9028 :     m_pSerializer->mark( aSeqOrder );
     577        9028 : }
     578             : 
     579        9028 : void DocxAttributeOutput::WriteCollectedParagraphProperties()
     580             : {
     581        9028 :     if ( m_rExport.SdrExporter().getFlyAttrList() )
     582             :     {
     583           0 :         XFastAttributeListRef xAttrList( m_rExport.SdrExporter().getFlyAttrList() );
     584           0 :         m_rExport.SdrExporter().setFlyAttrList(NULL);
     585             : 
     586           0 :         m_pSerializer->singleElementNS( XML_w, XML_framePr, xAttrList );
     587             :     }
     588             : 
     589        9028 :     if ( m_pParagraphSpacingAttrList )
     590             :     {
     591        4070 :         XFastAttributeListRef xAttrList( m_pParagraphSpacingAttrList );
     592        4070 :         m_pParagraphSpacingAttrList = NULL;
     593             : 
     594        4070 :         m_pSerializer->singleElementNS( XML_w, XML_spacing, xAttrList );
     595             :     }
     596             : 
     597        9028 :     if ( m_pBackgroundAttrList )
     598             :     {
     599          24 :         XFastAttributeListRef xAttrList( m_pBackgroundAttrList );
     600          24 :         m_pBackgroundAttrList = NULL;
     601             : 
     602          24 :         m_pSerializer->singleElementNS( XML_w, XML_shd, xAttrList );
     603             :     }
     604        9028 : }
     605             : 
     606        5388 : void DocxAttributeOutput::EndParagraphProperties( const SfxItemSet* pParagraphMarkerProperties, const SwRedlineData* pRedlineData, const SwRedlineData* pRedlineParagraphMarkerDeleted, const SwRedlineData* pRedlineParagraphMarkerInserted)
     607             : {
     608             :     // Call the 'Redline' function. This will add redline (change-tracking) information that regards to paragraph properties.
     609             :     // This includes changes like 'Bold', 'Underline', 'Strikethrough' etc.
     610        5388 :     Redline( pRedlineData );
     611             : 
     612        5388 :     WriteCollectedParagraphProperties();
     613             : 
     614             :     // Merge the marks for the ordered elements
     615        5388 :     m_pSerializer->mergeTopMarks( );
     616             : 
     617             :     // Write 'Paragraph Mark' properties
     618        5388 :     if ( pRedlineParagraphMarkerDeleted || pRedlineParagraphMarkerInserted || pParagraphMarkerProperties)
     619             :     {
     620        3751 :         m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
     621             : 
     622        3751 :         if(pParagraphMarkerProperties)
     623             :         {
     624             :             // The 'm_pFontsAttrList', 'm_pEastAsianLayoutAttrList', 'm_pCharLangAttrList' are used to hold information
     625             :             // that should be collected by different properties in the core, and are all flushed together
     626             :             // to the DOCX when the function 'WriteCollectedRunProperties' gets called.
     627             :             // So we need to store the current status of these lists, so that we can revert back to them when
     628             :             // we are done exporting the redline attributes.
     629        3751 :             ::sax_fastparser::FastAttributeList *pFontsAttrList_Original           = m_pFontsAttrList;
     630        3751 :             ::sax_fastparser::FastAttributeList *pEastAsianLayoutAttrList_Original = m_pEastAsianLayoutAttrList;
     631        3751 :             ::sax_fastparser::FastAttributeList *pCharLangAttrList_Original        = m_pCharLangAttrList;
     632        3751 :             m_pFontsAttrList           = NULL;
     633        3751 :             m_pEastAsianLayoutAttrList = NULL;
     634        3751 :             m_pCharLangAttrList        = NULL;
     635             : 
     636        3751 :             SfxWhichIter aIter( *pParagraphMarkerProperties );
     637        3751 :             sal_uInt16 nWhichId = aIter.FirstWhich();
     638        3751 :             const SfxPoolItem* pItem = 0;
     639      287880 :             while( nWhichId )
     640             :             {
     641      280378 :                 if( SFX_ITEM_SET == pParagraphMarkerProperties->GetItemState( nWhichId, true, &pItem ))
     642             :                 {
     643             :                     SAL_INFO( "sw.ww8", "nWhichId " << nWhichId);
     644       30652 :                     if (isCHRATR( nWhichId ))
     645       16866 :                         OutputItem( *pItem );
     646             :                 }
     647      280378 :                 nWhichId = aIter.NextWhich();
     648             :             }
     649             : 
     650             :             // Write the collected run properties that are stored in 'm_pFontsAttrList', 'm_pEastAsianLayoutAttrList', 'm_pCharLangAttrList'
     651        3751 :             WriteCollectedRunProperties();
     652             : 
     653             :             // Revert back the original values that were stored in 'm_pFontsAttrList', 'm_pEastAsianLayoutAttrList', 'm_pCharLangAttrList'
     654        3751 :             m_pFontsAttrList           = pFontsAttrList_Original;
     655        3751 :             m_pEastAsianLayoutAttrList = pEastAsianLayoutAttrList_Original;
     656        3751 :             m_pCharLangAttrList        = pCharLangAttrList_Original;
     657             :         }
     658        3751 :         if ( pRedlineParagraphMarkerDeleted )
     659             :         {
     660           1 :             StartRedline( pRedlineParagraphMarkerDeleted );
     661           1 :             EndRedline( pRedlineParagraphMarkerDeleted );
     662             :         }
     663        3751 :         if ( pRedlineParagraphMarkerInserted )
     664             :         {
     665           1 :             StartRedline( pRedlineParagraphMarkerInserted );
     666           1 :             EndRedline( pRedlineParagraphMarkerInserted );
     667             :         }
     668             : 
     669        3751 :         m_pSerializer->endElementNS( XML_w, XML_rPr );
     670             :     }
     671             : 
     672        5388 :     m_pSerializer->endElementNS( XML_w, XML_pPr );
     673             : 
     674        5388 :     if ( m_nColBreakStatus == COLBRK_WRITE )
     675             :     {
     676           2 :         m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
     677             :         m_pSerializer->singleElementNS( XML_w, XML_br,
     678           2 :                 FSNS( XML_w, XML_type ), "column", FSEND );
     679           2 :         m_pSerializer->endElementNS( XML_w, XML_r );
     680             : 
     681           2 :         m_nColBreakStatus = COLBRK_NONE;
     682             :     }
     683             : 
     684             :     // merge the properties _before_ the run (strictly speaking, just
     685             :     // after the start of the paragraph)
     686        5388 :     m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND );
     687        5388 : }
     688             : 
     689        6494 : void DocxAttributeOutput::StartRun( const SwRedlineData* pRedlineData, bool /*bSingleEmptyRun*/ )
     690             : {
     691             :     // Don't start redline data here, possibly there is a hyperlink later, and
     692             :     // that has to be started first.
     693        6494 :     m_pRedlineData = pRedlineData;
     694             : 
     695             :     // this mark is used to be able to enclose the run inside a sdr tag.
     696        6494 :     m_pSerializer->mark();
     697             : 
     698             :     // postpone the output of the start of a run (there are elements that need
     699             :     // to be written before the start of the run, but we learn which they are
     700             :     // _inside_ of the run)
     701        6494 :     m_pSerializer->mark(); // let's call it "postponed run start"
     702             : 
     703             :     // postpone the output of the text (we get it before the run properties,
     704             :     // but must write it after them)
     705        6494 :     m_pSerializer->mark(); // let's call it "postponed text"
     706        6494 : }
     707             : 
     708        6494 : void DocxAttributeOutput::EndRun()
     709             : {
     710             :     // Write field starts
     711       13267 :     for ( std::vector<FieldInfos>::iterator pIt = m_Fields.begin(); pIt != m_Fields.end(); )
     712             :     {
     713             :         // Add the fields starts for all but hyperlinks and TOCs
     714         279 :         if ( pIt->bOpen && pIt->pField )
     715             :         {
     716          80 :             StartField_Impl( *pIt );
     717             : 
     718             :             // Remove the field from the stack if only the start has to be written
     719             :             // Unknown fields sould be removed too
     720          80 :             if ( !pIt->bClose || ( pIt->eType == ww::eUNKNOWN ) )
     721             :             {
     722           1 :                 if (pIt->pField)
     723           1 :                     delete pIt->pField;
     724           1 :                 pIt = m_Fields.erase( pIt );
     725           1 :                 continue;
     726             :             }
     727             :         }
     728         278 :         ++pIt;
     729             :     }
     730             : 
     731             :     // write the run properties + the text, already in the correct order
     732        6494 :     m_pSerializer->mergeTopMarks(); // merges with "postponed text", see above
     733             : 
     734             :     // level down, to be able to prepend the actual run start attribute (just
     735             :     // before "postponed run start")
     736        6494 :     m_pSerializer->mark(); // let's call it "actual run start"
     737             : 
     738        6494 :     if ( m_closeHyperlinkInPreviousRun )
     739             :     {
     740         169 :         if ( m_startedHyperlink )
     741             :         {
     742         160 :             for ( int i = 0; i < m_nFieldsInHyperlink; i++ )
     743             :             {
     744             :                 // If fields begin before hyperlink then
     745             :                 // it should end before hyperlink close
     746           1 :                 EndField_Impl( m_Fields.back( ) );
     747           1 :                 if (m_Fields.back().pField)
     748           0 :                     delete m_Fields.back().pField;
     749             :             }
     750         159 :             m_pSerializer->endElementNS( XML_w, XML_hyperlink );
     751         159 :             m_startedHyperlink = false;
     752         159 :             m_nHyperLinkCount--;
     753             :         }
     754         169 :         m_closeHyperlinkInPreviousRun = false;
     755             :     }
     756             : 
     757             :     // Write the hyperlink and toc fields starts
     758       13266 :     for ( std::vector<FieldInfos>::iterator pIt = m_Fields.begin(); pIt != m_Fields.end(); )
     759             :     {
     760             :         // Add the fields starts for hyperlinks, TOCs and index marks
     761         278 :         if ( pIt->bOpen && !pIt->pField )
     762             :         {
     763         106 :             StartField_Impl( *pIt, true );
     764             : 
     765             :             // Remove the field if no end needs to be written
     766         106 :             if ( !pIt->bClose ) {
     767          49 :                 if (pIt->pField)
     768           0 :                     delete pIt->pField;
     769          49 :                 pIt = m_Fields.erase( pIt );
     770          49 :                 continue;
     771             :             }
     772             :         }
     773         229 :         ++pIt;
     774             :     }
     775             : 
     776             :     // Start the hyperlink after the fields separators or we would generate invalid file
     777        6494 :     if ( m_pHyperlinkAttrList )
     778             :     {
     779         287 :         XFastAttributeListRef xAttrList ( m_pHyperlinkAttrList );
     780             : 
     781         287 :         m_pSerializer->startElementNS( XML_w, XML_hyperlink, xAttrList );
     782         287 :         m_pHyperlinkAttrList = NULL;
     783         287 :         m_startedHyperlink = true;
     784         287 :         m_nHyperLinkCount++;
     785         287 :         m_nFieldsInHyperlink = 0;
     786             :     }
     787             : 
     788             :     // if there is some redlining in the document, output it
     789        6494 :     StartRedline( m_pRedlineData );
     790             : 
     791        6494 :     DoWriteBookmarks( );
     792        6494 :     DoWriteAnnotationMarks( );
     793             : 
     794        6494 :     if( m_closeHyperlinkInThisRun && m_startedHyperlink && m_hyperLinkAnchor != "" && m_hyperLinkAnchor.startsWith("_Toc"))
     795             :         {
     796          86 :             OUString sToken;
     797          86 :             m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
     798          86 :             m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
     799          86 :             m_pSerializer->singleElementNS( XML_w, XML_webHidden, FSEND );
     800          86 :             m_pSerializer->endElementNS( XML_w, XML_rPr );
     801             :             m_pSerializer->startElementNS( XML_w, XML_fldChar,
     802             :                     FSNS( XML_w, XML_fldCharType ), "begin",
     803          86 :                     FSEND );
     804          86 :             m_pSerializer->endElementNS( XML_w, XML_fldChar );
     805          86 :             m_pSerializer->endElementNS( XML_w, XML_r );
     806             : 
     807             : 
     808          86 :             m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
     809          86 :             m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
     810          86 :             m_pSerializer->singleElementNS( XML_w, XML_webHidden, FSEND );
     811          86 :             m_pSerializer->endElementNS( XML_w, XML_rPr );
     812          86 :             sToken = "PAGEREF " + m_hyperLinkAnchor + " \\h"; // '\h' Creates a hyperlink to the bookmarked paragraph.
     813          86 :             DoWriteCmd( sToken );
     814          86 :             m_pSerializer->endElementNS( XML_w, XML_r );
     815             : 
     816             :             // Write the Field separator
     817          86 :             m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
     818          86 :             m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
     819          86 :             m_pSerializer->singleElementNS( XML_w, XML_webHidden, FSEND );
     820          86 :             m_pSerializer->endElementNS( XML_w, XML_rPr );
     821             :             m_pSerializer->singleElementNS( XML_w, XML_fldChar,
     822             :                     FSNS( XML_w, XML_fldCharType ), "separate",
     823          86 :                     FSEND );
     824          86 :             m_pSerializer->endElementNS( XML_w, XML_r );
     825             :         }
     826             : 
     827        6494 :     m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
     828        6494 :     if(GetExport().bTabInTOC && m_pHyperlinkAttrList)
     829             :     {
     830           0 :         RunText(OUString("\t")) ;
     831             :     }
     832        6494 :     m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND ); // merges with "postponed run start", see above
     833             : 
     834             :     // write the run start + the run content
     835        6494 :     m_pSerializer->mergeTopMarks(); // merges the "actual run start"
     836             :     // append the actual run end
     837        6494 :     m_pSerializer->endElementNS( XML_w, XML_r );
     838             : 
     839             :     // enclose in a sdt block, if necessary
     840        6494 :     WriteSdtBlock( m_nRunSdtPrToken, m_pRunSdtPrTokenChildren, m_pRunSdtPrDataBindingAttrs );
     841        6494 :     m_pSerializer->mergeTopMarks();
     842             : 
     843        6494 :     WritePostponedMath();
     844             : 
     845        6496 :     for (std::vector<const SdrObject*>::iterator it = m_aPostponedFormControls.begin(); it != m_aPostponedFormControls.end(); ++it)
     846           2 :         WritePostponedFormControl(*it);
     847        6494 :     m_aPostponedFormControls.clear();
     848             : 
     849        6494 :     WritePendingPlaceholder();
     850             : 
     851             :     // if there is some redlining in the document, output it
     852        6494 :     EndRedline( m_pRedlineData );
     853             : 
     854        6494 :     m_pRedlineData = NULL;
     855             : 
     856        6494 :     if ( m_closeHyperlinkInThisRun )
     857             :     {
     858         299 :         if ( m_startedHyperlink )
     859             :         {
     860         127 :             if( m_endPageRef )
     861             :             {
     862             :                 // Hyperlink is started and fldchar "end" needs to be written for PAGEREF
     863          86 :                 m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
     864          86 :                 m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
     865          86 :                 m_pSerializer->singleElementNS( XML_w, XML_webHidden, FSEND );
     866          86 :                 m_pSerializer->endElementNS( XML_w, XML_rPr );
     867             :                 m_pSerializer->singleElementNS( XML_w, XML_fldChar,
     868             :                         FSNS( XML_w, XML_fldCharType ), "end",
     869          86 :                         FSEND );
     870          86 :                 m_pSerializer->endElementNS( XML_w, XML_r );
     871          86 :                 m_endPageRef = false;
     872          86 :                 m_hyperLinkAnchor = "";
     873             :             }
     874             : 
     875         127 :             m_pSerializer->endElementNS( XML_w, XML_hyperlink );
     876         127 :             m_startedHyperlink = false;
     877         127 :             m_nHyperLinkCount--;
     878             :         }
     879         299 :         m_closeHyperlinkInThisRun = false;
     880             :     }
     881             : 
     882        6494 :     if(!m_startedHyperlink)
     883       12694 :         while ( m_Fields.begin() != m_Fields.end() )
     884             :         {
     885         210 :             EndField_Impl( m_Fields.front( ) );
     886         210 :             if (m_Fields.front().pField)
     887          79 :                 delete m_Fields.front().pField;
     888         210 :             m_Fields.erase( m_Fields.begin( ) );
     889             :         }
     890        6494 : }
     891             : 
     892        6494 : void DocxAttributeOutput::DoWriteBookmarks()
     893             : {
     894             :     // Write the start bookmarks
     895        7275 :     for ( std::vector< OString >::const_iterator it = m_rBookmarksStart.begin(), end = m_rBookmarksStart.end();
     896             :           it != end; ++it )
     897             :     {
     898         781 :         const OString& rName = *it;
     899             : 
     900             :         // Output the bookmark
     901         781 :         sal_uInt16 nId = m_nNextBookmarkId++;
     902         781 :         m_rOpenedBookmarksIds[rName] = nId;
     903             :         m_pSerializer->singleElementNS( XML_w, XML_bookmarkStart,
     904             :             FSNS( XML_w, XML_id ), OString::number( nId ).getStr(  ),
     905             :             FSNS( XML_w, XML_name ), rName.getStr(),
     906         781 :             FSEND );
     907         781 :         m_sLastOpenedBookmark = rName;
     908             :     }
     909        6494 :     m_rBookmarksStart.clear();
     910             : 
     911             :     // export the end bookmarks
     912        7259 :     for ( std::vector< OString >::const_iterator it = m_rBookmarksEnd.begin(), end = m_rBookmarksEnd.end();
     913             :           it != end; ++it )
     914             :     {
     915         765 :         const OString& rName = *it;
     916             : 
     917             :         // Get the id of the bookmark
     918         765 :         std::map< OString, sal_uInt16 >::iterator pPos = m_rOpenedBookmarksIds.find( rName );
     919         765 :         if ( pPos != m_rOpenedBookmarksIds.end(  ) )
     920             :         {
     921         613 :             sal_uInt16 nId = ( *pPos ).second;
     922             :             m_pSerializer->singleElementNS( XML_w, XML_bookmarkEnd,
     923             :                 FSNS( XML_w, XML_id ), OString::number( nId ).getStr(  ),
     924         613 :                 FSEND );
     925         613 :             m_rOpenedBookmarksIds.erase( rName );
     926             :         }
     927             :     }
     928        6494 :     m_rBookmarksEnd.clear();
     929        6494 : }
     930             : 
     931        6494 : void DocxAttributeOutput::DoWriteAnnotationMarks()
     932             : {
     933             :     // Write the start annotation marks
     934        6500 :     for ( std::vector< OString >::const_iterator it = m_rAnnotationMarksStart.begin(), end = m_rAnnotationMarksStart.end();
     935             :           it != end; ++it )
     936             :     {
     937           6 :         const OString& rName = *it;
     938             : 
     939             :         // Output the annotation mark
     940             :         /* Ensure that the existing Annotation Marks are not overwritten
     941             :            as it causes discrepancy when DocxAttributeOutput::PostitField
     942             :            refers to this map & while mapping comment id's in document.xml &
     943             :            comment.xml.
     944             :         */
     945           6 :         if ( m_rOpenedAnnotationMarksIds.end() == m_rOpenedAnnotationMarksIds.find( rName ) )
     946             :         {
     947           4 :             sal_uInt16 nId = m_nNextAnnotationMarkId++;
     948           4 :             m_rOpenedAnnotationMarksIds[rName] = nId;
     949             :             m_pSerializer->singleElementNS( XML_w, XML_commentRangeStart,
     950             :                 FSNS( XML_w, XML_id ), OString::number( nId ).getStr(  ),
     951           4 :                 FSEND );
     952           4 :             m_sLastOpenedAnnotationMark = rName;
     953             :         }
     954             :     }
     955        6494 :     m_rAnnotationMarksStart.clear();
     956             : 
     957             :     // export the end annotation marks
     958        6498 :     for ( std::vector< OString >::const_iterator it = m_rAnnotationMarksEnd.begin(), end = m_rAnnotationMarksEnd.end();
     959             :           it != end; ++it )
     960             :     {
     961           4 :         const OString& rName = *it;
     962             : 
     963             :         // Get the id of the annotation mark
     964           4 :         std::map< OString, sal_uInt16 >::iterator pPos = m_rOpenedAnnotationMarksIds.find( rName );
     965           4 :         if ( pPos != m_rOpenedAnnotationMarksIds.end(  ) )
     966             :         {
     967           4 :             sal_uInt16 nId = ( *pPos ).second;
     968             :             m_pSerializer->singleElementNS( XML_w, XML_commentRangeEnd,
     969             :                 FSNS( XML_w, XML_id ), OString::number( nId ).getStr(  ),
     970           4 :                 FSEND );
     971           4 :             m_rOpenedAnnotationMarksIds.erase( rName );
     972             : 
     973           4 :             m_pSerializer->startElementNS(XML_w, XML_r, FSEND);
     974             :             m_pSerializer->singleElementNS( XML_w, XML_commentReference, FSNS( XML_w, XML_id ),
     975             :                                             OString::number( nId ).getStr(),
     976           4 :                                             FSEND );
     977           4 :             m_pSerializer->endElementNS(XML_w, XML_r);
     978             :         }
     979             :     }
     980        6494 :     m_rAnnotationMarksEnd.clear();
     981        6494 : }
     982             : 
     983           1 : void DocxAttributeOutput::WriteFFData(  const FieldInfos& rInfos )
     984             : {
     985           1 :     const ::sw::mark::IFieldmark& rFieldmark = *rInfos.pFieldmark;
     986           1 :     if ( rInfos.eType == ww::eFORMDROPDOWN )
     987             :     {
     988           0 :         uno::Sequence< OUString> vListEntries;
     989           0 :         OUString sName, sHelp, sToolTip, sSelected;
     990             : 
     991           0 :         FieldMarkParamsHelper params( rFieldmark );
     992           0 :         params.extractParam( ODF_FORMDROPDOWN_LISTENTRY, vListEntries );
     993           0 :         sName = params.getName();
     994           0 :         sal_Int32 nSelectedIndex = 0;
     995             : 
     996           0 :         if ( params.extractParam( ODF_FORMDROPDOWN_RESULT, nSelectedIndex ) )
     997             :         {
     998           0 :             if (nSelectedIndex < vListEntries.getLength() )
     999           0 :                 sSelected = vListEntries[ nSelectedIndex ];
    1000             :         }
    1001             : 
    1002           0 :         GetExport().DoComboBox( sName, sHelp, sToolTip, sSelected, vListEntries );
    1003             :     }
    1004           1 :     else if ( rInfos.eType == ww::eFORMCHECKBOX )
    1005             :     {
    1006           1 :         OUString sName;
    1007           1 :         bool bChecked = false;
    1008             : 
    1009           1 :         FieldMarkParamsHelper params( rFieldmark );
    1010           1 :         params.extractParam( ODF_FORMCHECKBOX_NAME, sName );
    1011             : 
    1012           1 :         const sw::mark::ICheckboxFieldmark* pCheckboxFm = dynamic_cast<const sw::mark::ICheckboxFieldmark*>(&rFieldmark);
    1013           1 :         if ( pCheckboxFm && pCheckboxFm->IsChecked() )
    1014           0 :             bChecked = true;
    1015             : 
    1016           2 :         FFDataWriterHelper ffdataOut( m_pSerializer );
    1017           2 :         ffdataOut.WriteFormCheckbox( sName, OUString(), bChecked );
    1018             :     }
    1019           0 :     else if ( rInfos.eType == ww::eFORMTEXT )
    1020             :     {
    1021           0 :         FieldMarkParamsHelper params( rFieldmark );
    1022           0 :         FFDataWriterHelper ffdataOut( m_pSerializer );
    1023           0 :         ffdataOut.WriteFormText( params.getName(), OUString() );
    1024             :     }
    1025           1 : }
    1026             : 
    1027         186 : void DocxAttributeOutput::StartField_Impl( FieldInfos& rInfos, bool bWriteRun )
    1028             : {
    1029         186 :     if ( m_startedHyperlink )
    1030           1 :         ++m_nFieldsInHyperlink;
    1031         186 :     if ( rInfos.pField && rInfos.eType == ww::eUNKNOWN )
    1032             :     {
    1033             :         // Expand unsupported fields
    1034           1 :         RunText( rInfos.pField->GetFieldName() );
    1035             :     }
    1036         185 :     else if ( rInfos.eType != ww::eNONE ) // HYPERLINK fields are just commands
    1037             :     {
    1038         185 :         if ( bWriteRun )
    1039         106 :             m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
    1040             : 
    1041         185 :         if ( rInfos.eType == ww::eFORMDROPDOWN )
    1042             :         {
    1043             :                 m_pSerializer->startElementNS( XML_w, XML_fldChar,
    1044             :                     FSNS( XML_w, XML_fldCharType ), "begin",
    1045           0 :                     FSEND );
    1046           0 :                 if ( rInfos.pFieldmark && !rInfos.pField )
    1047           0 :                     WriteFFData(  rInfos );
    1048           0 :                 if ( rInfos.pField )
    1049             :                 {
    1050           0 :                     const SwDropDownField& rFld2 = *(SwDropDownField*)rInfos.pField;
    1051             :                     uno::Sequence<OUString> aItems =
    1052           0 :                         rFld2.GetItemSequence();
    1053           0 :                     GetExport().DoComboBox(rFld2.GetName(),
    1054             :                                rFld2.GetHelp(),
    1055             :                                rFld2.GetToolTip(),
    1056           0 :                                rFld2.GetSelectedItem(), aItems);
    1057             :                 }
    1058           0 :                 m_pSerializer->endElementNS( XML_w, XML_fldChar );
    1059             : 
    1060           0 :                 if ( bWriteRun )
    1061           0 :                     m_pSerializer->endElementNS( XML_w, XML_r );
    1062           0 :                 if ( !rInfos.pField )
    1063           0 :                     CmdField_Impl( rInfos );
    1064             : 
    1065             :         }
    1066             :         else
    1067             :         {
    1068             :             // Write the field start
    1069             :             m_pSerializer->startElementNS( XML_w, XML_fldChar,
    1070             :                 FSNS( XML_w, XML_fldCharType ), "begin",
    1071         185 :                 FSEND );
    1072             : 
    1073         185 :             if ( rInfos.pFieldmark )
    1074           1 :                 WriteFFData(  rInfos );
    1075             : 
    1076         185 :             m_pSerializer->endElementNS( XML_w, XML_fldChar );
    1077             : 
    1078         185 :             if ( bWriteRun )
    1079         106 :                 m_pSerializer->endElementNS( XML_w, XML_r );
    1080             : 
    1081             :             // The hyperlinks fields can't be expanded: the value is
    1082             :             // normally in the text run
    1083         185 :             if ( !rInfos.pField )
    1084         106 :                 CmdField_Impl( rInfos );
    1085             :         }
    1086             :     }
    1087         186 : }
    1088             : 
    1089         277 : void DocxAttributeOutput::DoWriteCmd( const OUString& rCmd )
    1090             : {
    1091         277 :     OUString sCmd = rCmd.trim();
    1092         277 :     if (sCmd.startsWith("SEQ"))
    1093             :     {
    1094           9 :         OUString sSeqName = msfilter::util::findQuotedText(sCmd, "SEQ ", '\\').trim();
    1095           9 :         m_aSeqBookmarksNames[sSeqName].push_back(m_sLastOpenedBookmark);
    1096             :     }
    1097             :     // Write the Field command
    1098         277 :     m_pSerializer->startElementNS( XML_w, XML_instrText, FSEND );
    1099         277 :     m_pSerializer->writeEscaped( rCmd );
    1100         277 :     m_pSerializer->endElementNS( XML_w, XML_instrText );
    1101             : 
    1102         277 : }
    1103             : 
    1104         185 : void DocxAttributeOutput::CmdField_Impl( FieldInfos& rInfos )
    1105             : {
    1106         185 :     m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
    1107         185 :     sal_Int32 nNbToken = comphelper::string::getTokenCount(rInfos.sCmd, '\t');
    1108             : 
    1109         376 :     for ( sal_Int32 i = 0; i < nNbToken; i++ )
    1110             :     {
    1111         191 :         OUString sToken = rInfos.sCmd.getToken( i, '\t' );
    1112         191 :         if ( rInfos.eType ==  ww::eCREATEDATE
    1113         191 :           || rInfos.eType ==  ww::eSAVEDATE
    1114         191 :           || rInfos.eType ==  ww::ePRINTDATE
    1115         191 :           || rInfos.eType ==  ww::eDATE
    1116         187 :           || rInfos.eType ==  ww::eTIME )
    1117             :         {
    1118           4 :            sToken = sToken.replaceAll("NNNN", "dddd");
    1119           4 :            sToken = sToken.replaceAll("NN", "ddd");
    1120             :         }
    1121             : 
    1122             :         // Write the Field command
    1123         191 :         DoWriteCmd( sToken );
    1124             : 
    1125             :         // Replace tabs by </instrText><tab/><instrText>
    1126         191 :         if ( i < ( nNbToken - 1 ) )
    1127           6 :             RunText( OUString( "\t" ) );
    1128         191 :     }
    1129             : 
    1130         185 :     m_pSerializer->endElementNS( XML_w, XML_r );
    1131             : 
    1132             :     // Write the Field separator
    1133         185 :     m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
    1134             :     m_pSerializer->singleElementNS( XML_w, XML_fldChar,
    1135             :           FSNS( XML_w, XML_fldCharType ), "separate",
    1136         185 :           FSEND );
    1137         185 :     m_pSerializer->endElementNS( XML_w, XML_r );
    1138         185 : }
    1139             : 
    1140         211 : void DocxAttributeOutput::EndField_Impl( FieldInfos& rInfos )
    1141             : {
    1142             :     // The command has to be written before for the hyperlinks
    1143         211 :     if ( rInfos.pField )
    1144             :     {
    1145          79 :         CmdField_Impl( rInfos );
    1146             :     }
    1147             : 
    1148             :     // Write the bookmark start if any
    1149         211 :     OUString aBkmName( m_sFieldBkm );
    1150         211 :     if ( !aBkmName.isEmpty() )
    1151             :     {
    1152             :         m_pSerializer->singleElementNS( XML_w, XML_bookmarkStart,
    1153             :                FSNS( XML_w, XML_id ), OString::number( m_nNextBookmarkId ).getStr( ),
    1154             :                FSNS( XML_w, XML_name ), OUStringToOString( aBkmName, RTL_TEXTENCODING_UTF8 ).getStr( ),
    1155           0 :                FSEND );
    1156             :     }
    1157             : 
    1158         211 :     if (rInfos.pField ) // For hyperlinks and TOX
    1159             :     {
    1160             :         // Write the Field latest value
    1161          79 :         m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
    1162          79 :         OUString sExpand;
    1163          79 :         if(rInfos.eType == ww::eCITATION)
    1164             :         {
    1165           6 :             sExpand = rInfos.pField->ExpandField( false , AUTH_FIELD_TITLE);
    1166             :         }
    1167             :         else
    1168             :         {
    1169          73 :             sExpand = rInfos.pField->ExpandField( true );
    1170             :         }
    1171             :         // newlines embedded in fields are 0x0B in MSO and 0x0A for us
    1172          79 :         RunText(sExpand.replace(0x0A, 0x0B));
    1173             : 
    1174          79 :         m_pSerializer->endElementNS( XML_w, XML_r );
    1175             :     }
    1176             : 
    1177             :     // Write the bookmark end if any
    1178         211 :     if ( !aBkmName.isEmpty() )
    1179             :     {
    1180             :         m_pSerializer->singleElementNS( XML_w, XML_bookmarkEnd,
    1181             :                FSNS( XML_w, XML_id ), OString::number( m_nNextBookmarkId ).getStr( ),
    1182           0 :                FSEND );
    1183             : 
    1184           0 :         m_nNextBookmarkId++;
    1185             :     }
    1186             : 
    1187             :     // Write the Field end
    1188         211 :     if ( rInfos.bClose  )
    1189             :     {
    1190         186 :         m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
    1191             :         m_pSerializer->singleElementNS( XML_w, XML_fldChar,
    1192             :               FSNS( XML_w, XML_fldCharType ), "end",
    1193         186 :               FSEND );
    1194         186 :         m_pSerializer->endElementNS( XML_w, XML_r );
    1195             :     }
    1196             :     // Write the ref field if a bookmark had to be set and the field
    1197             :     // should be visible
    1198         211 :     if ( rInfos.pField )
    1199             :     {
    1200          79 :         sal_uInt16 nSubType = rInfos.pField->GetSubType( );
    1201          79 :         bool bIsSetField = rInfos.pField->GetTyp( )->Which( ) == RES_SETEXPFLD;
    1202          79 :         bool bShowRef = ( !bIsSetField || ( nSubType & nsSwExtendedSubType::SUB_INVISIBLE ) ) ? false : true;
    1203             : 
    1204          79 :         if ( ( !m_sFieldBkm.isEmpty() ) && bShowRef )
    1205             :         {
    1206             :             // Write the field beginning
    1207           0 :             m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
    1208             :             m_pSerializer->singleElementNS( XML_w, XML_fldChar,
    1209             :                 FSNS( XML_w, XML_fldCharType ), "begin",
    1210           0 :                 FSEND );
    1211           0 :             m_pSerializer->endElementNS( XML_w, XML_r );
    1212             : 
    1213           0 :             rInfos.sCmd = FieldString( ww::eREF );
    1214           0 :             rInfos.sCmd += "\"";
    1215           0 :             rInfos.sCmd += m_sFieldBkm;
    1216           0 :             rInfos.sCmd += "\" ";
    1217             : 
    1218             :             // Clean the field bookmark data to avoid infinite loop
    1219           0 :             m_sFieldBkm = OUString( );
    1220             : 
    1221             :             // Write the end of the field
    1222           0 :             EndField_Impl( rInfos );
    1223             :         }
    1224         211 :     }
    1225         211 : }
    1226             : 
    1227        6494 : void DocxAttributeOutput::StartRunProperties()
    1228             : {
    1229             :     // postpone the output so that we can later [in EndRunProperties()]
    1230             :     // prepend the properties before the text
    1231        6494 :     m_pSerializer->mark();
    1232             : 
    1233        6494 :     m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
    1234             : 
    1235        6494 :     if(GetExport().bHideTabLeaderAndPageNumbers && m_pHyperlinkAttrList )
    1236             :     {
    1237          83 :         m_pSerializer->singleElementNS( XML_w, XML_webHidden, FSEND );
    1238             :     }
    1239        6494 :     InitCollectedRunProperties();
    1240             : 
    1241             :     OSL_ASSERT( m_postponedGraphic == NULL );
    1242        6494 :     m_postponedGraphic = new std::list< PostponedGraphic >;
    1243             : 
    1244             :     OSL_ASSERT( m_postponedDiagram == NULL );
    1245        6494 :     m_postponedDiagram = new std::list< PostponedDiagram >;
    1246             : 
    1247             :     OSL_ASSERT( m_postponedVMLDrawing == NULL );
    1248        6494 :     m_postponedVMLDrawing = new std::list< PostponedDrawing >;
    1249             : 
    1250             :     assert(!m_postponedDMLDrawing);
    1251        6494 :     m_postponedDMLDrawing = new std::list< PostponedDrawing >;
    1252             : 
    1253             :     assert( !m_postponedOLE );
    1254        6494 :     m_postponedOLE = new std::list< PostponedOLE >;
    1255        6494 : }
    1256             : 
    1257       11491 : void DocxAttributeOutput::InitCollectedRunProperties()
    1258             : {
    1259       11491 :     m_pFontsAttrList = NULL;
    1260       11491 :     m_pEastAsianLayoutAttrList = NULL;
    1261       11491 :     m_pCharLangAttrList = NULL;
    1262             : 
    1263             :     // Write the elements in the spec order
    1264             :     static const sal_Int32 aOrder[] =
    1265             :     {
    1266             :         FSNS( XML_w, XML_rStyle ),
    1267             :         FSNS( XML_w, XML_rFonts ),
    1268             :         FSNS( XML_w, XML_b ),
    1269             :         FSNS( XML_w, XML_bCs ),
    1270             :         FSNS( XML_w, XML_i ),
    1271             :         FSNS( XML_w, XML_iCs ),
    1272             :         FSNS( XML_w, XML_caps ),
    1273             :         FSNS( XML_w, XML_smallCaps ),
    1274             :         FSNS( XML_w, XML_strike ),
    1275             :         FSNS( XML_w, XML_dstrike ),
    1276             :         FSNS( XML_w, XML_outline ),
    1277             :         FSNS( XML_w, XML_shadow ),
    1278             :         FSNS( XML_w, XML_emboss ),
    1279             :         FSNS( XML_w, XML_imprint ),
    1280             :         FSNS( XML_w, XML_noProof ),
    1281             :         FSNS( XML_w, XML_snapToGrid ),
    1282             :         FSNS( XML_w, XML_vanish ),
    1283             :         FSNS( XML_w, XML_webHidden ),
    1284             :         FSNS( XML_w, XML_color ),
    1285             :         FSNS( XML_w, XML_spacing ),
    1286             :         FSNS( XML_w, XML_w ),
    1287             :         FSNS( XML_w, XML_kern ),
    1288             :         FSNS( XML_w, XML_position ),
    1289             :         FSNS( XML_w, XML_sz ),
    1290             :         FSNS( XML_w, XML_szCs ),
    1291             :         FSNS( XML_w, XML_highlight ),
    1292             :         FSNS( XML_w, XML_u ),
    1293             :         FSNS( XML_w, XML_effect ),
    1294             :         FSNS( XML_w, XML_bdr ),
    1295             :         FSNS( XML_w, XML_shd ),
    1296             :         FSNS( XML_w, XML_fitText ),
    1297             :         FSNS( XML_w, XML_vertAlign ),
    1298             :         FSNS( XML_w, XML_rtl ),
    1299             :         FSNS( XML_w, XML_cs ),
    1300             :         FSNS( XML_w, XML_em ),
    1301             :         FSNS( XML_w, XML_lang ),
    1302             :         FSNS( XML_w, XML_eastAsianLayout ),
    1303             :         FSNS( XML_w, XML_specVanish ),
    1304             :         FSNS( XML_w, XML_oMath ),
    1305             :         FSNS( XML_w, XML_rPrChange ),
    1306             :         FSNS( XML_w14, XML_glow ),
    1307             :         FSNS( XML_w14, XML_shadow ),
    1308             :         FSNS( XML_w14, XML_reflection ),
    1309             :         FSNS( XML_w14, XML_textOutline ),
    1310             :         FSNS( XML_w14, XML_textFill ),
    1311             :         FSNS( XML_w14, XML_scene3d ),
    1312             :         FSNS( XML_w14, XML_props3d ),
    1313             :         FSNS( XML_w14, XML_ligatures ),
    1314             :         FSNS( XML_w14, XML_numForm ),
    1315             :         FSNS( XML_w14, XML_numSpacing ),
    1316             :         FSNS( XML_w14, XML_stylisticSets ),
    1317             :         FSNS( XML_w14, XML_cntxtAlts ),
    1318             :     };
    1319             : 
    1320             :     // postpone the output so that we can later [in EndParagraphProperties()]
    1321             :     // prepend the properties before the run
    1322       11491 :     sal_Int32 len = sizeof ( aOrder ) / sizeof( sal_Int32 );
    1323       11491 :     uno::Sequence< sal_Int32 > aSeqOrder( len );
    1324      609023 :     for ( sal_Int32 i = 0; i < len; i++ )
    1325      597532 :         aSeqOrder[i] = aOrder[i];
    1326             : 
    1327       11491 :     m_pSerializer->mark( aSeqOrder );
    1328             : 
    1329       11491 : }
    1330             : 
    1331             : namespace
    1332             : {
    1333             : 
    1334         902 : struct NameToId
    1335             : {
    1336             :     OUString  maName;
    1337             :     sal_Int32 maId;
    1338             : };
    1339             : 
    1340          22 : const NameToId constNameToIdMapping[] =
    1341             : {
    1342             :     { OUString("glow"),         FSNS( XML_w14, XML_glow ) },
    1343             :     { OUString("shadow"),       FSNS( XML_w14, XML_shadow ) },
    1344             :     { OUString("reflection"),   FSNS( XML_w14, XML_reflection ) },
    1345             :     { OUString("textOutline"),  FSNS( XML_w14, XML_textOutline ) },
    1346             :     { OUString("textFill"),     FSNS( XML_w14, XML_textFill ) },
    1347             :     { OUString("scene3d"),      FSNS( XML_w14, XML_scene3d ) },
    1348             :     { OUString("props3d"),      FSNS( XML_w14, XML_props3d ) },
    1349             :     { OUString("ligatures"),    FSNS( XML_w14, XML_ligatures ) },
    1350             :     { OUString("numForm"),      FSNS( XML_w14, XML_numForm ) },
    1351             :     { OUString("numSpacing"),   FSNS( XML_w14, XML_numSpacing ) },
    1352             :     { OUString("stylisticSets"),FSNS( XML_w14, XML_stylisticSets ) },
    1353             :     { OUString("cntxtAlts"),    FSNS( XML_w14, XML_cntxtAlts ) },
    1354             : 
    1355             :     { OUString("val"),          FSNS( XML_w14, XML_val ) },
    1356             :     { OUString("rad"),          FSNS( XML_w14, XML_rad ) },
    1357             :     { OUString("blurRad"),      FSNS( XML_w14, XML_blurRad ) },
    1358             :     { OUString("stA"),          FSNS( XML_w14, XML_stA ) },
    1359             :     { OUString("stPos"),        FSNS( XML_w14, XML_stPos ) },
    1360             :     { OUString("endA"),         FSNS( XML_w14, XML_endA ) },
    1361             :     { OUString("endPos"),       FSNS( XML_w14, XML_endPos ) },
    1362             :     { OUString("dist"),         FSNS( XML_w14, XML_dist ) },
    1363             :     { OUString("dir"),          FSNS( XML_w14, XML_dir ) },
    1364             :     { OUString("fadeDir"),      FSNS( XML_w14, XML_fadeDir ) },
    1365             :     { OUString("sx"),           FSNS( XML_w14, XML_sx ) },
    1366             :     { OUString("sy"),           FSNS( XML_w14, XML_sy ) },
    1367             :     { OUString("kx"),           FSNS( XML_w14, XML_kx ) },
    1368             :     { OUString("ky"),           FSNS( XML_w14, XML_ky ) },
    1369             :     { OUString("algn"),         FSNS( XML_w14, XML_algn ) },
    1370             :     { OUString("w"),            FSNS( XML_w14, XML_w ) },
    1371             :     { OUString("cap"),          FSNS( XML_w14, XML_cap ) },
    1372             :     { OUString("cmpd"),         FSNS( XML_w14, XML_cmpd ) },
    1373             :     { OUString("pos"),          FSNS( XML_w14, XML_pos ) },
    1374             :     { OUString("ang"),          FSNS( XML_w14, XML_ang ) },
    1375             :     { OUString("scaled"),       FSNS( XML_w14, XML_scaled ) },
    1376             :     { OUString("path"),         FSNS( XML_w14, XML_path ) },
    1377             :     { OUString("l"),            FSNS( XML_w14, XML_l ) },
    1378             :     { OUString("t"),            FSNS( XML_w14, XML_t ) },
    1379             :     { OUString("r"),            FSNS( XML_w14, XML_r ) },
    1380             :     { OUString("b"),            FSNS( XML_w14, XML_b ) },
    1381             :     { OUString("lim"),          FSNS( XML_w14, XML_lim ) },
    1382             :     { OUString("prst"),         FSNS( XML_w14, XML_prst ) },
    1383             :     { OUString("rig"),          FSNS( XML_w14, XML_rig ) },
    1384             :     { OUString("lat"),          FSNS( XML_w14, XML_lat ) },
    1385             :     { OUString("lon"),          FSNS( XML_w14, XML_lon ) },
    1386             :     { OUString("rev"),          FSNS( XML_w14, XML_rev ) },
    1387             :     { OUString("h"),            FSNS( XML_w14, XML_h ) },
    1388             :     { OUString("extrusionH"),   FSNS( XML_w14, XML_extrusionH ) },
    1389             :     { OUString("contourW"),     FSNS( XML_w14, XML_contourW ) },
    1390             :     { OUString("prstMaterial"), FSNS( XML_w14, XML_prstMaterial ) },
    1391             :     { OUString("id"),           FSNS( XML_w14, XML_id ) },
    1392             : 
    1393             :     { OUString("schemeClr"),    FSNS( XML_w14, XML_schemeClr ) },
    1394             :     { OUString("srgbClr"),      FSNS( XML_w14, XML_srgbClr ) },
    1395             :     { OUString("tint"),         FSNS( XML_w14, XML_tint ) },
    1396             :     { OUString("shade"),        FSNS( XML_w14, XML_shade ) },
    1397             :     { OUString("alpha"),        FSNS( XML_w14, XML_alpha ) },
    1398             :     { OUString("hueMod"),       FSNS( XML_w14, XML_hueMod ) },
    1399             :     { OUString("sat"),          FSNS( XML_w14, XML_sat ) },
    1400             :     { OUString("satOff"),       FSNS( XML_w14, XML_satOff ) },
    1401             :     { OUString("satMod"),       FSNS( XML_w14, XML_satMod ) },
    1402             :     { OUString("lum"),          FSNS( XML_w14, XML_lum ) },
    1403             :     { OUString("lumOff"),       FSNS( XML_w14, XML_lumOff ) },
    1404             :     { OUString("lumMod"),       FSNS( XML_w14, XML_lumMod ) },
    1405             :     { OUString("noFill"),       FSNS( XML_w14, XML_noFill ) },
    1406             :     { OUString("solidFill"),    FSNS( XML_w14, XML_solidFill ) },
    1407             :     { OUString("gradFill"),     FSNS( XML_w14, XML_gradFill ) },
    1408             :     { OUString("gsLst"),        FSNS( XML_w14, XML_gsLst ) },
    1409             :     { OUString("gs"),           FSNS( XML_w14, XML_gs ) },
    1410             :     { OUString("pos"),          FSNS( XML_w14, XML_pos ) },
    1411             :     { OUString("lin"),          FSNS( XML_w14, XML_lin ) },
    1412             :     { OUString("path"),         FSNS( XML_w14, XML_path ) },
    1413             :     { OUString("fillToRect"),   FSNS( XML_w14, XML_fillToRect ) },
    1414             :     { OUString("prstDash"),     FSNS( XML_w14, XML_prstDash ) },
    1415             :     { OUString("round"),        FSNS( XML_w14, XML_round ) },
    1416             :     { OUString("bevel"),        FSNS( XML_w14, XML_bevel ) },
    1417             :     { OUString("miter"),        FSNS( XML_w14, XML_miter ) },
    1418             :     { OUString("camera"),       FSNS( XML_w14, XML_camera ) },
    1419             :     { OUString("lightRig"),     FSNS( XML_w14, XML_lightRig ) },
    1420             :     { OUString("rot"),          FSNS( XML_w14, XML_rot ) },
    1421             :     { OUString("bevelT"),       FSNS( XML_w14, XML_bevelT ) },
    1422             :     { OUString("bevelB"),       FSNS( XML_w14, XML_bevelB ) },
    1423             :     { OUString("extrusionClr"), FSNS( XML_w14, XML_extrusionClr ) },
    1424             :     { OUString("contourClr"),   FSNS( XML_w14, XML_contourClr ) },
    1425             :     { OUString("styleSet"),     FSNS( XML_w14, XML_styleSet ) },
    1426             : 
    1427          11 : };
    1428             : 
    1429        1079 : boost::optional<sal_Int32> lclGetElementIdForName(const OUString& rName)
    1430             : {
    1431        1079 :     sal_Int32 aLength = sizeof (constNameToIdMapping) / sizeof(NameToId);
    1432       50207 :     for (sal_Int32 i=0; i < aLength; ++i)
    1433             :     {
    1434       49932 :         if (rName == constNameToIdMapping[i].maName)
    1435             :         {
    1436         804 :             return constNameToIdMapping[i].maId;
    1437             :         }
    1438             :     }
    1439         275 :     return boost::optional<sal_Int32>();
    1440             : }
    1441             : 
    1442         343 : void lclProcessRecursiveGrabBag(sal_Int32 aElementId, const css::uno::Sequence<css::beans::PropertyValue>& rElements, sax_fastparser::FSHelperPtr pSerializer)
    1443             : {
    1444         343 :     css::uno::Sequence<css::beans::PropertyValue> aAttributes;
    1445         343 :     FastAttributeList* pAttributes = pSerializer->createAttrList();
    1446             : 
    1447         879 :     for (sal_Int32 j=0; j < rElements.getLength(); ++j)
    1448             :     {
    1449         536 :         if (rElements[j].Name == "attributes")
    1450             :         {
    1451         275 :             rElements[j].Value >>= aAttributes;
    1452             :         }
    1453             :     }
    1454             : 
    1455         804 :     for (sal_Int32 j=0; j < aAttributes.getLength(); ++j)
    1456             :     {
    1457         461 :         uno::Any aAny = aAttributes[j].Value;
    1458         922 :         OString aValue;
    1459             : 
    1460         461 :         if(aAny.getValueType() == getCppuType<sal_Int32>())
    1461             :         {
    1462         266 :             aValue = OString::number(aAny.get<sal_Int32>());
    1463             :         }
    1464         195 :         else if(aAny.getValueType() == getCppuType<OUString>())
    1465             :         {
    1466         195 :             aValue =  OUStringToOString(aAny.get<OUString>(), RTL_TEXTENCODING_ASCII_US);
    1467             :         }
    1468             : 
    1469         922 :         boost::optional<sal_Int32> aSubElementId = lclGetElementIdForName(aAttributes[j].Name);
    1470         461 :         if(aSubElementId)
    1471         461 :             pAttributes->add(*aSubElementId, aValue.getStr());
    1472         461 :     }
    1473             : 
    1474         686 :     XFastAttributeListRef xAttributesList( pAttributes );
    1475             : 
    1476         343 :     pSerializer->startElement(aElementId, xAttributesList);
    1477             : 
    1478         879 :     for (sal_Int32 j=0; j < rElements.getLength(); ++j)
    1479             :     {
    1480         536 :         css::uno::Sequence<css::beans::PropertyValue> aSumElements;
    1481             : 
    1482        1072 :         boost::optional<sal_Int32> aSubElementId = lclGetElementIdForName(rElements[j].Name);
    1483         536 :         if(aSubElementId)
    1484             :         {
    1485         261 :             rElements[j].Value >>= aSumElements;
    1486         261 :             lclProcessRecursiveGrabBag(*aSubElementId, aSumElements, pSerializer);
    1487             :         }
    1488         536 :     }
    1489             : 
    1490         686 :     pSerializer->endElement(aElementId);
    1491         343 : }
    1492             : 
    1493             : }
    1494             : 
    1495       15441 : void DocxAttributeOutput::WriteCollectedRunProperties()
    1496             : {
    1497             :     // Write all differed properties
    1498       15441 :     if ( m_pFontsAttrList )
    1499             :     {
    1500        7023 :         XFastAttributeListRef xAttrList( m_pFontsAttrList );
    1501        7023 :         m_pFontsAttrList = NULL;
    1502             : 
    1503        7023 :         m_pSerializer->singleElementNS( XML_w, XML_rFonts, xAttrList );
    1504             :     }
    1505             : 
    1506       15441 :     if ( m_pColorAttrList )
    1507             :     {
    1508        4347 :         XFastAttributeListRef xAttrList( m_pColorAttrList );
    1509        4347 :         m_pColorAttrList = NULL;
    1510             : 
    1511        4347 :         m_pSerializer->singleElementNS( XML_w, XML_color, xAttrList );
    1512             :     }
    1513             : 
    1514       15441 :     if ( m_pEastAsianLayoutAttrList )
    1515             :     {
    1516           0 :         XFastAttributeListRef xAttrList( m_pEastAsianLayoutAttrList );
    1517           0 :         m_pEastAsianLayoutAttrList = NULL;
    1518             : 
    1519           0 :         m_pSerializer->singleElementNS( XML_w, XML_eastAsianLayout, xAttrList );
    1520             :     }
    1521             : 
    1522       15441 :     if ( m_pCharLangAttrList )
    1523             :     {
    1524        3160 :         XFastAttributeListRef xAttrList( m_pCharLangAttrList );
    1525        3160 :         m_pCharLangAttrList = NULL;
    1526             : 
    1527        3160 :         m_pSerializer->singleElementNS( XML_w, XML_lang, xAttrList );
    1528             :     }
    1529             : 
    1530       15441 :     if (m_aTextEffectsGrabBag.getLength() > 0)
    1531             :     {
    1532         123 :         for (sal_Int32 i=0; i < m_aTextEffectsGrabBag.getLength(); ++i)
    1533             :         {
    1534          82 :             boost::optional<sal_Int32> aElementId = lclGetElementIdForName(m_aTextEffectsGrabBag[i].Name);
    1535          82 :             if(aElementId)
    1536             :             {
    1537          82 :                 uno::Sequence<beans::PropertyValue> aGrabBagSeq;
    1538          82 :                 m_aTextEffectsGrabBag[i].Value >>= aGrabBagSeq;
    1539          82 :                 lclProcessRecursiveGrabBag(*aElementId, aGrabBagSeq, m_pSerializer);
    1540             :             }
    1541          82 :         }
    1542          41 :         m_aTextEffectsGrabBag.realloc(0);
    1543             :     }
    1544       15441 : }
    1545             : 
    1546        6494 : void DocxAttributeOutput::EndRunProperties( const SwRedlineData* pRedlineData )
    1547             : {
    1548             :     // Call the 'Redline' function. This will add redline (change-tracking) information that regards to run properties.
    1549             :     // This includes changes like 'Bold', 'Underline', 'Strikethrough' etc.
    1550        6494 :     Redline( pRedlineData );
    1551             : 
    1552        6494 :     WriteCollectedRunProperties();
    1553             : 
    1554             :     // Merge the marks for the ordered elements
    1555        6494 :     m_pSerializer->mergeTopMarks();
    1556             : 
    1557        6494 :     m_pSerializer->endElementNS( XML_w, XML_rPr );
    1558             : 
    1559             :     // write footnotes/endnotes if we have any
    1560        6494 :     FootnoteEndnoteReference();
    1561             : 
    1562        6494 :     WritePostponedGraphic();
    1563             : 
    1564        6494 :     WritePostponedDiagram();
    1565             :     //We need to write w:drawing tag after the w:rPr.
    1566        6494 :     WritePostponedChart();
    1567             : 
    1568             :     //We need to write w:pict tag after the w:rPr.
    1569        6494 :     WritePostponedVMLDrawing();
    1570        6494 :     WritePostponedDMLDrawing();
    1571             : 
    1572        6494 :     WritePostponedOLE();
    1573             : 
    1574             :     // merge the properties _before_ the run text (strictly speaking, just
    1575             :     // after the start of the run)
    1576        6494 :     m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND );
    1577        6494 : }
    1578             : 
    1579        6494 : void DocxAttributeOutput::WritePostponedGraphic()
    1580             : {
    1581       19617 :     for( std::list< PostponedGraphic >::const_iterator it = m_postponedGraphic->begin();
    1582       13078 :          it != m_postponedGraphic->end();
    1583             :          ++it )
    1584          45 :         FlyFrameGraphic( it->grfNode, it->size, it->mOLEFrmFmt, it->mOLENode, it->pSdrObj );
    1585        6494 :     delete m_postponedGraphic;
    1586        6494 :     m_postponedGraphic = NULL;
    1587        6494 : }
    1588             : 
    1589        6494 : void DocxAttributeOutput::WritePostponedDiagram()
    1590             : {
    1591       19488 :     for( std::list< PostponedDiagram >::const_iterator it = m_postponedDiagram->begin();
    1592       12992 :          it != m_postponedDiagram->end();
    1593             :          ++it )
    1594           2 :         m_rExport.SdrExporter().writeDiagram( it->object, *(it->frame), m_anchorId++ );
    1595        6494 :     delete m_postponedDiagram;
    1596        6494 :     m_postponedDiagram = NULL;
    1597        6494 : }
    1598             : 
    1599          19 : void DocxAttributeOutput::FootnoteEndnoteRefTag()
    1600             : {
    1601          19 :     if( m_footnoteEndnoteRefTag == 0 )
    1602          33 :         return;
    1603           5 :     m_pSerializer->singleElementNS( XML_w, m_footnoteEndnoteRefTag, FSEND );
    1604           5 :     m_footnoteEndnoteRefTag = 0;
    1605             : }
    1606             : 
    1607             : /** Output sal_Unicode* as a run text (<t>the text</t>).
    1608             : 
    1609             :     When bMove is true, update rBegin to point _after_ the end of the text +
    1610             :     1, meaning that it skips one character after the text.  This is to make
    1611             :     the switch in DocxAttributeOutput::RunText() nicer ;-)
    1612             :  */
    1613        6048 : static void impl_WriteRunText( FSHelperPtr pSerializer, sal_Int32 nTextToken,
    1614             :         const sal_Unicode* &rBegin, const sal_Unicode* pEnd, bool bMove = true )
    1615             : {
    1616        6048 :     const sal_Unicode *pBegin = rBegin;
    1617             : 
    1618             :     // skip one character after the end
    1619        6048 :     if ( bMove )
    1620        1424 :         rBegin = pEnd + 1;
    1621             : 
    1622        6048 :     if ( pBegin >= pEnd )
    1623        6980 :         return; // we want to write at least one character
    1624             : 
    1625             :     // we have to add 'preserve' when starting/ending with space
    1626        5116 :     if ( *pBegin == ' ' || *( pEnd - 1 ) == ' ' )
    1627             :     {
    1628        1267 :         pSerializer->startElementNS( XML_w, nTextToken, FSNS( XML_xml, XML_space ), "preserve", FSEND );
    1629             :     }
    1630             :     else
    1631        3849 :         pSerializer->startElementNS( XML_w, nTextToken, FSEND );
    1632             : 
    1633        5116 :     pSerializer->writeEscaped( OUString( pBegin, pEnd - pBegin ) );
    1634             : 
    1635        5116 :     pSerializer->endElementNS( XML_w, nTextToken );
    1636             : }
    1637             : 
    1638        4624 : void DocxAttributeOutput::RunText( const OUString& rText, rtl_TextEncoding /*eCharSet*/ )
    1639             : {
    1640        4624 :     if( m_closeHyperlinkInThisRun )
    1641             :     {
    1642         169 :         m_closeHyperlinkInPreviousRun = true;
    1643             :     }
    1644             : 
    1645             :     // one text can be split into more <w:t>blah</w:t>'s by line breaks etc.
    1646        4624 :     const sal_Unicode *pBegin = rText.getStr();
    1647        4624 :     const sal_Unicode *pEnd = pBegin + rText.getLength();
    1648             : 
    1649             :     // the text run is usually XML_t, with the exception of the deleted text
    1650        4624 :     sal_Int32 nTextToken = XML_t;
    1651        4624 :     if ( m_pRedlineData && m_pRedlineData->GetType() == nsRedlineType_t::REDLINE_DELETE )
    1652           4 :         nTextToken = XML_delText;
    1653             : 
    1654      181602 :     for ( const sal_Unicode *pIt = pBegin; pIt < pEnd; ++pIt )
    1655             :     {
    1656      176978 :         switch ( *pIt )
    1657             :         {
    1658             :             case 0x09: // tab
    1659        1378 :                 impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt );
    1660        1378 :                 m_pSerializer->singleElementNS( XML_w, XML_tab, FSEND );
    1661        1378 :                 break;
    1662             :             case 0x0b: // line break
    1663          19 :                 impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt );
    1664          19 :                 m_pSerializer->singleElementNS( XML_w, XML_br, FSEND );
    1665          19 :                 break;
    1666             :             case 0x1E: //non-breaking hyphen
    1667           1 :                 impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt );
    1668           1 :                 m_pSerializer->singleElementNS( XML_w, XML_noBreakHyphen, FSEND );
    1669           1 :                 break;
    1670             :             case 0x1F: //soft (on demand) hyphen
    1671          20 :                 impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt );
    1672          20 :                 m_pSerializer->singleElementNS( XML_w, XML_softHyphen, FSEND );
    1673          20 :                 break;
    1674             :             default:
    1675      175560 :                 if ( *pIt < 0x0020 ) // filter out the control codes
    1676             :                 {
    1677           6 :                     impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt );
    1678             :                     OSL_TRACE( "Ignored control code %x in a text run.", *pIt );
    1679             :                 }
    1680      175560 :                 break;
    1681             :         }
    1682             :     }
    1683             : 
    1684        4624 :     impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pEnd, false );
    1685        4624 : }
    1686             : 
    1687           0 : void DocxAttributeOutput::RawText( const OUString& /*rText*/, bool /*bForceUnicode*/, rtl_TextEncoding /*eCharSet*/ )
    1688             : {
    1689             :     OSL_TRACE("TODO DocxAttributeOutput::RawText( const String& rText, bool bForceUnicode, rtl_TextEncoding eCharSet )" );
    1690           0 : }
    1691             : 
    1692           0 : void DocxAttributeOutput::StartRuby( const SwTxtNode& rNode, sal_Int32 nPos, const SwFmtRuby& rRuby )
    1693             : {
    1694             :     OSL_TRACE("TODO DocxAttributeOutput::StartRuby( const SwTxtNode& rNode, const SwFmtRuby& rRuby )" );
    1695           0 :     m_pSerializer->startElementNS( XML_w, XML_ruby, FSEND );
    1696           0 :     m_pSerializer->startElementNS( XML_w, XML_rubyPr, FSEND );
    1697             :     // hps
    1698             :     // hpsBaseText
    1699             :     // hpsRaise
    1700             :     // lid
    1701             :     lang::Locale aLocale( SwBreakIt::Get()->GetLocale(
    1702           0 :                 rNode.GetLang( nPos ) ) );
    1703           0 :     OUString sLang( LanguageTag::convertToBcp47( aLocale) );
    1704             :     m_pSerializer->singleElementNS( XML_w, XML_lid,
    1705             :             FSNS( XML_w, XML_val ),
    1706           0 :             OUStringToOString( sLang, RTL_TEXTENCODING_UTF8 ).getStr( ), FSEND );
    1707             : 
    1708           0 :     OString sAlign ( "center" );
    1709           0 :     switch ( rRuby.GetAdjustment( ) )
    1710             :     {
    1711             :         case 0:
    1712           0 :             sAlign = OString( "left" );
    1713           0 :             break;
    1714             :         case 1:
    1715             :             // Defaults to center
    1716           0 :             break;
    1717             :         case 2:
    1718           0 :             sAlign = OString( "right" );
    1719           0 :             break;
    1720             :         case 3:
    1721           0 :             sAlign = OString( "distributeLetter" );
    1722           0 :             break;
    1723             :         case 4:
    1724           0 :             sAlign = OString( "distributeSpace" );
    1725           0 :             break;
    1726             :         default:
    1727           0 :             break;
    1728             :     }
    1729             :     m_pSerializer->singleElementNS( XML_w, XML_rubyAlign,
    1730           0 :             FSNS( XML_w, XML_val ), sAlign.getStr(), FSEND );
    1731           0 :     m_pSerializer->endElementNS( XML_w, XML_rubyPr );
    1732             : 
    1733           0 :     m_pSerializer->startElementNS( XML_w, XML_rt, FSEND );
    1734           0 :     StartRun( NULL );
    1735           0 :     StartRunProperties( );
    1736           0 :     SwWW8AttrIter aAttrIt( m_rExport, rNode );
    1737           0 :     aAttrIt.OutAttr( nPos, true );
    1738             : 
    1739           0 :     sal_uInt16 nStyle = m_rExport.GetId( *rRuby.GetTxtRuby()->GetCharFmt() );
    1740           0 :     OString aStyleId(m_rExport.pStyles->GetStyleId(nStyle));
    1741             :     m_pSerializer->singleElementNS( XML_w, XML_rStyle,
    1742           0 :             FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND );
    1743             : 
    1744           0 :     EndRunProperties( NULL );
    1745           0 :     RunText( rRuby.GetText( ) );
    1746           0 :     EndRun( );
    1747           0 :     m_pSerializer->endElementNS( XML_w, XML_rt );
    1748             : 
    1749           0 :     m_pSerializer->startElementNS( XML_w, XML_rubyBase, FSEND );
    1750           0 :     StartRun( NULL );
    1751           0 : }
    1752             : 
    1753           0 : void DocxAttributeOutput::EndRuby()
    1754             : {
    1755             :     OSL_TRACE( "TODO DocxAttributeOutput::EndRuby()" );
    1756           0 :     EndRun( );
    1757           0 :     m_pSerializer->endElementNS( XML_w, XML_rubyBase );
    1758           0 :     m_pSerializer->endElementNS( XML_w, XML_ruby );
    1759           0 : }
    1760             : 
    1761         302 : bool DocxAttributeOutput::AnalyzeURL( const OUString& rUrl, const OUString& rTarget, OUString* pLinkURL, OUString* pMark )
    1762             : {
    1763         302 :     bool bBookMarkOnly = AttributeOutputBase::AnalyzeURL( rUrl, rTarget, pLinkURL, pMark );
    1764             : 
    1765         302 :     if ( !pMark->isEmpty() )
    1766             :     {
    1767         103 :         OUString sURL = *pLinkURL;
    1768             : 
    1769         103 :         if ( bBookMarkOnly )
    1770          88 :             sURL = FieldString( ww::eHYPERLINK );
    1771             :         else
    1772          15 :             sURL = FieldString( ww::eHYPERLINK ) + "\"" + sURL + "\"";
    1773             : 
    1774         103 :         sURL += " \\l \"" + *pMark + "\"";
    1775             : 
    1776         103 :         if ( !rTarget.isEmpty() )
    1777           0 :             sURL += " \\n " + rTarget;
    1778             : 
    1779         103 :         *pLinkURL = sURL;
    1780             :     }
    1781             : 
    1782         302 :     return bBookMarkOnly;
    1783             : }
    1784             : 
    1785         302 : bool DocxAttributeOutput::StartURL( const OUString& rUrl, const OUString& rTarget )
    1786             : {
    1787         302 :     OUString sMark;
    1788         604 :     OUString sUrl;
    1789             : 
    1790         302 :     bool bBookmarkOnly = AnalyzeURL( rUrl, rTarget, &sUrl, &sMark );
    1791             : 
    1792         302 :     m_hyperLinkAnchor = sMark;
    1793             : 
    1794         302 :     if ( !sMark.isEmpty() && !bBookmarkOnly )
    1795             :     {
    1796          15 :         m_rExport.OutputField( NULL, ww::eHYPERLINK, sUrl );
    1797             :     }
    1798             :     else
    1799             :     {
    1800             :         // Output a hyperlink XML element
    1801         287 :         m_pHyperlinkAttrList = m_pSerializer->createAttrList();
    1802             : 
    1803         287 :         if ( !bBookmarkOnly )
    1804             :         {
    1805         199 :             OString sId = OUStringToOString( GetExport().GetFilter().addRelation( m_pSerializer->getOutputStream(),
    1806             :                         "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
    1807         398 :                         sUrl, true ), RTL_TEXTENCODING_UTF8 );
    1808             : 
    1809         199 :             m_pHyperlinkAttrList->add( FSNS( XML_r, XML_id), sId.getStr());
    1810             :         }
    1811             :         else
    1812             :         {
    1813             :             // Is this a link to a sequence? Then try to replace that with a
    1814             :             // normal bookmark, as Word won't understand our special
    1815             :             // <seqname>!<index>|sequence syntax.
    1816          88 :             if (sMark.endsWith("|sequence"))
    1817             :             {
    1818           2 :                 sal_Int32 nPos = sMark.indexOf('!');
    1819           2 :                 if (nPos != -1)
    1820             :                 {
    1821             :                     // Extract <seqname>, the field instruction text has the name quoted.
    1822           2 :                     OUString aSequenceName = sMark.copy(0, nPos);
    1823             :                     // Extract <index>.
    1824           2 :                     sal_uInt32 nIndex = sMark.copy(nPos + 1, sMark.getLength() - nPos - sizeof("|sequence")).toInt32();
    1825           2 :                     std::map<OUString, std::vector<OString> >::iterator it = m_aSeqBookmarksNames.find(aSequenceName);
    1826           2 :                     if (it != m_aSeqBookmarksNames.end())
    1827             :                     {
    1828           2 :                         std::vector<OString>& rNames = it->second;
    1829           2 :                         if (rNames.size() > nIndex)
    1830             :                             // We know the bookmark name for this sequence and this index, do the replacement.
    1831           2 :                             sMark = OStringToOUString(rNames[nIndex], RTL_TEXTENCODING_UTF8);
    1832           2 :                     }
    1833             :                 }
    1834             :             }
    1835             :             m_pHyperlinkAttrList->add( FSNS( XML_w, XML_anchor ),
    1836          88 :                     OUStringToOString( sMark, RTL_TEXTENCODING_UTF8 ).getStr( ) );
    1837             :         }
    1838             : 
    1839         287 :         OUString sTarget( rTarget );
    1840         287 :         if ( !sTarget.isEmpty() )
    1841             :         {
    1842           0 :             OString soTarget = OUStringToOString( sTarget, RTL_TEXTENCODING_UTF8 );
    1843           0 :             m_pHyperlinkAttrList->add(FSNS( XML_w, XML_tgtFrame ), soTarget.getStr());
    1844         287 :         }
    1845             :     }
    1846             : 
    1847         604 :     return true;
    1848             : }
    1849             : 
    1850         302 : bool DocxAttributeOutput::EndURL()
    1851             : {
    1852         302 :     m_closeHyperlinkInThisRun = true;
    1853         302 :     if(m_hyperLinkAnchor != "" && m_hyperLinkAnchor.startsWith("_Toc"))
    1854             :     {
    1855          86 :         m_endPageRef = true;
    1856             :     }
    1857         302 :     return true;
    1858             : }
    1859             : 
    1860          42 : void DocxAttributeOutput::FieldVanish( const OUString& rTxt, ww::eField eType )
    1861             : {
    1862          42 :     WriteField_Impl( NULL, eType, rTxt, WRITEFIELD_ALL );
    1863          42 : }
    1864             : 
    1865             : // The difference between 'Redline' and 'StartRedline'+'EndRedline' is that:
    1866             : // 'Redline' is used for tracked changes of formatting information of a run like Bold, Underline. (the '<w:rPrChange>' is inside the 'run' node)
    1867             : // 'StartRedline' is used to output tracked changes of run insertion and deletion (the run is inside the '<w:ins>' node)
    1868       11885 : void DocxAttributeOutput::Redline( const SwRedlineData* pRedlineData)
    1869             : {
    1870       11885 :     if ( !pRedlineData )
    1871       23759 :         return;
    1872             : 
    1873          11 :     OString aId( OString::number( pRedlineData->GetSeqNo() ) );
    1874          22 :     const OUString &rAuthor( SW_MOD()->GetRedlineAuthor( pRedlineData->GetAuthor() ) );
    1875          22 :     OString aAuthor( OUStringToOString( rAuthor, RTL_TEXTENCODING_UTF8 ) );
    1876          22 :     OString aDate( DateTimeToOString( pRedlineData->GetTimeStamp() ) );
    1877             : 
    1878          11 :     switch( pRedlineData->GetType() )
    1879             :     {
    1880             :     case nsRedlineType_t::REDLINE_INSERT:
    1881           4 :         break;
    1882             : 
    1883             :     case nsRedlineType_t::REDLINE_DELETE:
    1884           4 :         break;
    1885             : 
    1886             :     case nsRedlineType_t::REDLINE_FORMAT:
    1887             :         m_pSerializer->startElementNS( XML_w, XML_rPrChange,
    1888             :                 FSNS( XML_w, XML_id ), aId.getStr(),
    1889             :                 FSNS( XML_w, XML_author ), aAuthor.getStr(),
    1890             :                 FSNS( XML_w, XML_date ), aDate.getStr(),
    1891           2 :                 FSEND );
    1892             : 
    1893             :         // Check if there is any extra data stored in the redline object
    1894           2 :         if (pRedlineData->GetExtraData())
    1895             :         {
    1896           0 :             const SwRedlineExtraData* pExtraData = pRedlineData->GetExtraData();
    1897           0 :             const SwRedlineExtraData_FormattingChanges* pFormattingChanges = dynamic_cast<const SwRedlineExtraData_FormattingChanges*>(pExtraData);
    1898             : 
    1899             :             // Check if the extra data is of type 'formatting changes'
    1900           0 :             if (pFormattingChanges)
    1901             :             {
    1902             :                 // Get the item set that holds all the changes properties
    1903           0 :                 const SfxItemSet *pChangesSet = pFormattingChanges->GetItemSet();
    1904           0 :                 if (pChangesSet)
    1905             :                 {
    1906           0 :                     m_pSerializer->mark();
    1907             : 
    1908           0 :                     m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
    1909             : 
    1910             :                     // The 'm_pFontsAttrList', 'm_pEastAsianLayoutAttrList', 'm_pCharLangAttrList' are used to hold information
    1911             :                     // that should be collected by different properties in the core, and are all flushed together
    1912             :                     // to the DOCX when the function 'WriteCollectedRunProperties' gets called.
    1913             :                     // So we need to store the current status of these lists, so that we can revert back to them when
    1914             :                     // we are done exporting the redline attributes.
    1915           0 :                     ::sax_fastparser::FastAttributeList *pFontsAttrList_Original           = m_pFontsAttrList;
    1916           0 :                     ::sax_fastparser::FastAttributeList *pEastAsianLayoutAttrList_Original = m_pEastAsianLayoutAttrList;
    1917           0 :                     ::sax_fastparser::FastAttributeList *pCharLangAttrList_Original        = m_pCharLangAttrList;
    1918           0 :                     m_pFontsAttrList           = NULL;
    1919           0 :                     m_pEastAsianLayoutAttrList = NULL;
    1920           0 :                     m_pCharLangAttrList        = NULL;
    1921             : 
    1922             :                     // Output the redline item set
    1923           0 :                     m_rExport.OutputItemSet( *pChangesSet, false, true, i18n::ScriptType::LATIN, m_rExport.mbExportModeRTF );
    1924             : 
    1925             :                     // Write the collected run properties that are stored in 'm_pFontsAttrList', 'm_pEastAsianLayoutAttrList', 'm_pCharLangAttrList'
    1926           0 :                     WriteCollectedRunProperties();
    1927             : 
    1928             :                     // Revert back the original values that were stored in 'm_pFontsAttrList', 'm_pEastAsianLayoutAttrList', 'm_pCharLangAttrList'
    1929           0 :                     m_pFontsAttrList           = pFontsAttrList_Original;
    1930           0 :                     m_pEastAsianLayoutAttrList = pEastAsianLayoutAttrList_Original;
    1931           0 :                     m_pCharLangAttrList        = pCharLangAttrList_Original;
    1932             : 
    1933           0 :                     m_pSerializer->endElementNS( XML_w, XML_rPr );
    1934             : 
    1935           0 :                     m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND );
    1936             :                 }
    1937             :             }
    1938             :         }
    1939           2 :         m_pSerializer->endElementNS( XML_w, XML_rPrChange );
    1940           2 :         break;
    1941             : 
    1942             :     case nsRedlineType_t::REDLINE_PARAGRAPH_FORMAT:
    1943             :         m_pSerializer->startElementNS( XML_w, XML_pPrChange,
    1944             :                 FSNS( XML_w, XML_id ), aId.getStr(),
    1945             :                 FSNS( XML_w, XML_author ), aAuthor.getStr(),
    1946             :                 FSNS( XML_w, XML_date ), aDate.getStr(),
    1947           1 :                 FSEND );
    1948             : 
    1949             :         // Check if there is any extra data stored in the redline object
    1950           1 :         if (pRedlineData->GetExtraData())
    1951             :         {
    1952           0 :             const SwRedlineExtraData* pExtraData = pRedlineData->GetExtraData();
    1953           0 :             const SwRedlineExtraData_FormattingChanges* pFormattingChanges = dynamic_cast<const SwRedlineExtraData_FormattingChanges*>(pExtraData);
    1954             : 
    1955             :             // Check if the extra data is of type 'formatting changes'
    1956           0 :             if (pFormattingChanges)
    1957             :             {
    1958             :                 // Get the item set that holds all the changes properties
    1959           0 :                 const SfxItemSet *pChangesSet = pFormattingChanges->GetItemSet();
    1960           0 :                 if (pChangesSet)
    1961             :                 {
    1962           0 :                     m_pSerializer->mark();
    1963             : 
    1964           0 :                     m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND );
    1965             : 
    1966             :                     // The 'm_rExport.SdrExporter().getFlyAttrList()', 'm_pParagraphSpacingAttrList' are used to hold information
    1967             :                     // that should be collected by different properties in the core, and are all flushed together
    1968             :                     // to the DOCX when the function 'WriteCollectedParagraphProperties' gets called.
    1969             :                     // So we need to store the current status of these lists, so that we can revert back to them when
    1970             :                     // we are done exporting the redline attributes.
    1971           0 :                     ::sax_fastparser::FastAttributeList *pFlyAttrList_Original              = m_rExport.SdrExporter().getFlyAttrList();
    1972           0 :                     ::sax_fastparser::FastAttributeList *pParagraphSpacingAttrList_Original = m_pParagraphSpacingAttrList;
    1973           0 :                     m_rExport.SdrExporter().setFlyAttrList(NULL);
    1974           0 :                     m_pParagraphSpacingAttrList = NULL;
    1975             : 
    1976             :                     // Output the redline item set
    1977           0 :                     m_rExport.OutputItemSet( *pChangesSet, true, false, i18n::ScriptType::LATIN, m_rExport.mbExportModeRTF );
    1978             : 
    1979             :                     // Write the collected paragraph properties that are stored in 'm_rExport.SdrExporter().getFlyAttrList()', 'm_pParagraphSpacingAttrList'
    1980           0 :                     WriteCollectedParagraphProperties();
    1981             : 
    1982             :                     // Revert back the original values that were stored in 'm_rExport.SdrExporter().getFlyAttrList()', 'm_pParagraphSpacingAttrList'
    1983           0 :                     m_rExport.SdrExporter().setFlyAttrList(pFlyAttrList_Original);
    1984           0 :                     m_pParagraphSpacingAttrList = pParagraphSpacingAttrList_Original;
    1985             : 
    1986           0 :                     m_pSerializer->endElementNS( XML_w, XML_pPr );
    1987             : 
    1988           0 :                     m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND );
    1989             :                 }
    1990             :             }
    1991             :         }
    1992           1 :         m_pSerializer->endElementNS( XML_w, XML_pPrChange );
    1993           1 :         break;
    1994             : 
    1995             :     default:
    1996             :         SAL_WARN("sw.ww8", "Unhandled redline type for export " << pRedlineData->GetType());
    1997           0 :         break;
    1998          11 :     }
    1999             : }
    2000             : 
    2001             : // The difference between 'Redline' and 'StartRedline'+'EndRedline' is that:
    2002             : // 'Redline' is used for tracked changes of formatting information of a run like Bold, Underline. (the '<w:rPrChange>' is inside the 'run' node)
    2003             : // 'StartRedline' is used to output tracked changes of run insertion and deletion (the run is inside the '<w:ins>' node)
    2004        6496 : void DocxAttributeOutput::StartRedline( const SwRedlineData * pRedlineData )
    2005             : {
    2006        6496 :     if ( !pRedlineData )
    2007       12980 :         return;
    2008             : 
    2009             :     // FIXME check if it's necessary to travel over the Next()'s in pRedlineData
    2010             : 
    2011          12 :     OString aId( OString::number( m_nRedlineId++ ) );
    2012             : 
    2013          24 :     const OUString &rAuthor( SW_MOD()->GetRedlineAuthor( pRedlineData->GetAuthor() ) );
    2014          24 :     OString aAuthor( OUStringToOString( rAuthor, RTL_TEXTENCODING_UTF8 ) );
    2015             : 
    2016          24 :     OString aDate( DateTimeToOString( pRedlineData->GetTimeStamp() ) );
    2017             : 
    2018          12 :     switch ( pRedlineData->GetType() )
    2019             :     {
    2020             :         case nsRedlineType_t::REDLINE_INSERT:
    2021             :             m_pSerializer->startElementNS( XML_w, XML_ins,
    2022             :                     FSNS( XML_w, XML_id ), aId.getStr(),
    2023             :                     FSNS( XML_w, XML_author ), aAuthor.getStr(),
    2024             :                     FSNS( XML_w, XML_date ), aDate.getStr(),
    2025           5 :                     FSEND );
    2026           5 :             break;
    2027             : 
    2028             :         case nsRedlineType_t::REDLINE_DELETE:
    2029             :             m_pSerializer->startElementNS( XML_w, XML_del,
    2030             :                     FSNS( XML_w, XML_id ), aId.getStr(),
    2031             :                     FSNS( XML_w, XML_author ), aAuthor.getStr(),
    2032             :                     FSNS( XML_w, XML_date ), aDate.getStr(),
    2033           5 :                     FSEND );
    2034           5 :             break;
    2035             : 
    2036             :         case nsRedlineType_t::REDLINE_FORMAT:
    2037             :             OSL_TRACE( "TODO DocxAttributeOutput::StartRedline()" );
    2038             :         default:
    2039           2 :             break;
    2040          12 :     }
    2041             : }
    2042             : 
    2043        6496 : void DocxAttributeOutput::EndRedline( const SwRedlineData * pRedlineData )
    2044             : {
    2045        6496 :     if ( !pRedlineData )
    2046       12980 :         return;
    2047             : 
    2048          12 :     switch ( pRedlineData->GetType() )
    2049             :     {
    2050             :         case nsRedlineType_t::REDLINE_INSERT:
    2051           5 :             m_pSerializer->endElementNS( XML_w, XML_ins );
    2052           5 :             break;
    2053             : 
    2054             :         case nsRedlineType_t::REDLINE_DELETE:
    2055           5 :             m_pSerializer->endElementNS( XML_w, XML_del );
    2056           5 :             break;
    2057             : 
    2058             :         case nsRedlineType_t::REDLINE_FORMAT:
    2059             :             OSL_TRACE( "TODO DocxAttributeOutput::EndRedline()" );
    2060           2 :             break;
    2061             :         default:
    2062           0 :             break;
    2063             :     }
    2064             : }
    2065             : 
    2066           0 : void DocxAttributeOutput::FormatDrop( const SwTxtNode& /*rNode*/, const SwFmtDrop& /*rSwFmtDrop*/, sal_uInt16 /*nStyle*/, ww8::WW8TableNodeInfo::Pointer_t /*pTextNodeInfo*/, ww8::WW8TableNodeInfoInner::Pointer_t )
    2067             : {
    2068             :     OSL_TRACE( "TODO DocxAttributeOutput::FormatDrop( const SwTxtNode& rNode, const SwFmtDrop& rSwFmtDrop, sal_uInt16 nStyle )" );
    2069           0 : }
    2070             : 
    2071        5189 : void DocxAttributeOutput::ParagraphStyle( sal_uInt16 nStyle )
    2072             : {
    2073        5189 :     OString aStyleId(m_rExport.pStyles->GetStyleId(nStyle));
    2074             : 
    2075        5189 :     m_pSerializer->singleElementNS( XML_w, XML_pStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND );
    2076        5189 : }
    2077             : 
    2078        9184 : static void impl_borderLine( FSHelperPtr pSerializer, sal_Int32 elementToken, const SvxBorderLine* pBorderLine, sal_uInt16 nDist,
    2079             :                              bool bWriteShadow = false, const table::BorderLine2* rStyleProps = NULL )
    2080             : {
    2081        9184 :     FastAttributeList* pAttr = pSerializer->createAttrList();
    2082             : 
    2083             :     // Compute val attribute value
    2084             :     // Can be one of:
    2085             :     //      single, double,
    2086             :     //      basicWideOutline, basicWideInline
    2087             :     // OOXml also supports those types of borders, but we'll try to play with the first ones.
    2088             :     //      thickThinMediumGap, thickThinLargeGap, thickThinSmallGap
    2089             :     //      thinThickLargeGap, thinThickMediumGap, thinThickSmallGap
    2090        9184 :     const char* pVal = "nil";
    2091        9184 :     if ( pBorderLine && !pBorderLine->isEmpty( ) )
    2092             :     {
    2093        6185 :         switch (pBorderLine->GetBorderLineStyle())
    2094             :         {
    2095             :             case table::BorderLineStyle::SOLID:
    2096        6112 :                 pVal = ( sal_Char* )"single";
    2097        6112 :                 break;
    2098             :             case table::BorderLineStyle::DOTTED:
    2099           0 :                 pVal = ( sal_Char* )"dotted";
    2100           0 :                 break;
    2101             :             case table::BorderLineStyle::DASHED:
    2102           8 :                 pVal = ( sal_Char* )"dashed";
    2103           8 :                 break;
    2104             :             case table::BorderLineStyle::DOUBLE:
    2105           5 :                 pVal = ( sal_Char* )"double";
    2106           5 :                 break;
    2107             :             case table::BorderLineStyle::THINTHICK_SMALLGAP:
    2108           5 :                 pVal = ( sal_Char* )"thinThickSmallGap";
    2109           5 :                 break;
    2110             :             case table::BorderLineStyle::THINTHICK_MEDIUMGAP:
    2111           0 :                 pVal = ( sal_Char* )"thinThickMediumGap";
    2112           0 :                 break;
    2113             :             case table::BorderLineStyle::THINTHICK_LARGEGAP:
    2114           0 :                 pVal = ( sal_Char* )"thinThickLargeGap";
    2115           0 :                 break;
    2116             :             case table::BorderLineStyle::THICKTHIN_SMALLGAP:
    2117           5 :                 pVal = ( sal_Char* )"thickThinSmallGap";
    2118           5 :                 break;
    2119             :             case table::BorderLineStyle::THICKTHIN_MEDIUMGAP:
    2120           0 :                 pVal = ( sal_Char* )"thickThinMediumGap";
    2121           0 :                 break;
    2122             :             case table::BorderLineStyle::THICKTHIN_LARGEGAP:
    2123          30 :                 pVal = ( sal_Char* )"thickThinLargeGap";
    2124          30 :                 break;
    2125             :             case table::BorderLineStyle::EMBOSSED:
    2126           0 :                 pVal = ( sal_Char* )"threeDEmboss";
    2127           0 :                 break;
    2128             :             case table::BorderLineStyle::ENGRAVED:
    2129           0 :                 pVal = ( sal_Char* )"threeDEngrave";
    2130           0 :                 break;
    2131             :             case table::BorderLineStyle::OUTSET:
    2132           0 :                 pVal = ( sal_Char* )"outset";
    2133           0 :                 break;
    2134             :             case table::BorderLineStyle::INSET:
    2135           0 :                 pVal = ( sal_Char* )"inset";
    2136           0 :                 break;
    2137             :             case table::BorderLineStyle::FINE_DASHED:
    2138          20 :                 pVal = ( sal_Char* )"dashSmallGap";
    2139          20 :                 break;
    2140             :             case table::BorderLineStyle::NONE:
    2141             :             default:
    2142           0 :                 break;
    2143             :         }
    2144             :     }
    2145        2999 :     else if( rStyleProps == NULL )
    2146             :         // no line, and no line set by the style either:
    2147             :         // there is no need to write the property
    2148        9350 :         return;
    2149             : 
    2150             :     // compare the properties with the theme properties before writing them:
    2151             :     // if they are equal, it means that they were style-defined and there is
    2152             :     // no need to write them.
    2153       23309 :     if( rStyleProps != NULL && pBorderLine && !pBorderLine->isEmpty() &&
    2154       11678 :             pBorderLine->GetBorderLineStyle() == rStyleProps->LineStyle &&
    2155       28328 :             pBorderLine->GetColor() == rStyleProps->Color &&
    2156        3886 :             (sal_uInt32) pBorderLine->GetWidth() == MM100_TO_TWIP_UNSIGNED( rStyleProps->LineWidth ) )
    2157        3766 :         return;
    2158             : 
    2159        2626 :     pAttr->add( FSNS( XML_w, XML_val ), OString( pVal ) );
    2160             : 
    2161        2626 :     if ( pBorderLine && !pBorderLine->isEmpty() )
    2162             :     {
    2163             :         // Compute the sz attribute
    2164             : 
    2165             :         double const fConverted( ::editeng::ConvertBorderWidthToWord(
    2166        2419 :                 pBorderLine->GetBorderLineStyle(), pBorderLine->GetWidth()));
    2167             :         // The unit is the 8th of point
    2168        2419 :         sal_Int32 nWidth = sal_Int32( fConverted / 2.5 );
    2169        2419 :         sal_uInt16 nMinWidth = 2;
    2170        2419 :         sal_uInt16 nMaxWidth = 96;
    2171             : 
    2172        2419 :         if ( nWidth > nMaxWidth )
    2173           0 :             nWidth = nMaxWidth;
    2174        2419 :         else if ( nWidth < nMinWidth )
    2175          12 :             nWidth = nMinWidth;
    2176             : 
    2177        2419 :         pAttr->add( FSNS( XML_w, XML_sz ), OString::number( nWidth ) );
    2178             : 
    2179             :         // Get the distance (in pt)
    2180        2419 :         pAttr->add( FSNS( XML_w, XML_space ), OString::number( nDist / 20 ) );
    2181             : 
    2182             :         // Get the color code as an RRGGBB hex value
    2183        2419 :         OString sColor( msfilter::util::ConvertColor( pBorderLine->GetColor( ) ) );
    2184        2419 :         pAttr->add( FSNS( XML_w, XML_color ), sColor );
    2185             :     }
    2186             : 
    2187        2626 :     if (bWriteShadow)
    2188             :     {
    2189             :         // Set the shadow value
    2190          18 :         pAttr->add( FSNS( XML_w, XML_shadow ), "1" );
    2191             :     }
    2192             : 
    2193        2626 :     XFastAttributeListRef xAttrs( pAttr );
    2194        2626 :     pSerializer->singleElementNS( XML_w, elementToken, xAttrs );
    2195             : }
    2196             : 
    2197          94 : static OutputBorderOptions lcl_getTableDefaultBorderOptions(bool bEcma)
    2198             : {
    2199          94 :     OutputBorderOptions rOptions;
    2200             : 
    2201          94 :     rOptions.tag = XML_tblBorders;
    2202          94 :     rOptions.bUseStartEnd = !bEcma;
    2203          94 :     rOptions.bWriteTag = true;
    2204          94 :     rOptions.bWriteInsideHV = true;
    2205          94 :     rOptions.bWriteDistance = false;
    2206          94 :     rOptions.aShadowLocation = SVX_SHADOW_NONE;
    2207          94 :     rOptions.bCheckDistanceSize = false;
    2208             : 
    2209          94 :     return rOptions;
    2210             : }
    2211             : 
    2212        1389 : static OutputBorderOptions lcl_getTableCellBorderOptions(bool bEcma)
    2213             : {
    2214        1389 :     OutputBorderOptions rOptions;
    2215             : 
    2216        1389 :     rOptions.tag = XML_tcBorders;
    2217        1389 :     rOptions.bUseStartEnd = !bEcma;
    2218        1389 :     rOptions.bWriteTag = true;
    2219        1389 :     rOptions.bWriteInsideHV = true;
    2220        1389 :     rOptions.bWriteDistance = false;
    2221        1389 :     rOptions.aShadowLocation = SVX_SHADOW_NONE;
    2222        1389 :     rOptions.bCheckDistanceSize = false;
    2223             : 
    2224        1389 :     return rOptions;
    2225             : }
    2226             : 
    2227          74 : static OutputBorderOptions lcl_getBoxBorderOptions()
    2228             : {
    2229          74 :     OutputBorderOptions rOptions;
    2230             : 
    2231          74 :     rOptions.tag = XML_pBdr;
    2232          74 :     rOptions.bUseStartEnd = false;
    2233          74 :     rOptions.bWriteTag = false;
    2234          74 :     rOptions.bWriteInsideHV = false;
    2235          74 :     rOptions.bWriteDistance = true;
    2236          74 :     rOptions.aShadowLocation = SVX_SHADOW_NONE;
    2237          74 :     rOptions.bCheckDistanceSize = false;
    2238             : 
    2239          74 :     return rOptions;
    2240             : }
    2241             : 
    2242           8 : static bool boxHasLineLargerThan31(const SvxBoxItem& rBox)
    2243             : {
    2244             :     return  (
    2245          12 :                 ( rBox.GetDistance( BOX_LINE_TOP ) / 20 ) > 31 ||
    2246           4 :                 ( rBox.GetDistance( BOX_LINE_LEFT ) / 20 ) > 31 ||
    2247           8 :                 ( rBox.GetDistance( BOX_LINE_BOTTOM ) / 20 ) > 31 ||
    2248           0 :                 ( rBox.GetDistance( BOX_LINE_RIGHT ) / 20 ) > 31
    2249           8 :             );
    2250             : }
    2251             : 
    2252        1553 : static void impl_borders( FSHelperPtr pSerializer, const SvxBoxItem& rBox, const OutputBorderOptions& rOptions, PageMargins* pageMargins,
    2253             :                           std::map<sal_uInt16, css::table::BorderLine2> &rTableStyleConf )
    2254             : {
    2255             :     static const sal_uInt16 aBorders[] =
    2256             :     {
    2257             :         BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
    2258             :     };
    2259             : 
    2260             :     const sal_Int32 aXmlElements[] =
    2261             :     {
    2262             :         XML_top,
    2263             :         rOptions.bUseStartEnd ? XML_start : XML_left,
    2264             :         XML_bottom,
    2265             :         rOptions.bUseStartEnd ? XML_end : XML_right
    2266        1553 :     };
    2267        1553 :     bool tagWritten = false;
    2268        1553 :     const sal_uInt16* pBrd = aBorders;
    2269             : 
    2270        1553 :     bool bExportDistanceFromPageEdge = false;
    2271        1553 :     if ( rOptions.bCheckDistanceSize == true && boxHasLineLargerThan31(rBox) == true )
    2272             :     {
    2273             :         // The distance is larger than '31'. This cannot be exported as 'distance from text'.
    2274             :         // Instead - it should be exported as 'distance from page edge'.
    2275             :         // This is based on http://wiki.openoffice.org/wiki/Writer/MSInteroperability/PageBorder
    2276             :         // Specifically 'export case #2'
    2277           4 :         bExportDistanceFromPageEdge = true;
    2278             :     }
    2279             : 
    2280        1553 :     bool bWriteInsideH = false;
    2281        1553 :     bool bWriteInsideV = false;
    2282        7765 :     for( int i = 0; i < 4; ++i, ++pBrd )
    2283             :     {
    2284        6212 :         const SvxBorderLine* pLn = rBox.GetLine( *pBrd );
    2285        6212 :         const table::BorderLine2 *aStyleProps = NULL;
    2286        6212 :         if( rTableStyleConf.find( *pBrd ) != rTableStyleConf.end() )
    2287        2742 :             aStyleProps = &rTableStyleConf[ *pBrd ];
    2288             : 
    2289        6212 :         if (!tagWritten && rOptions.bWriteTag)
    2290             :         {
    2291        1483 :             pSerializer->startElementNS( XML_w, rOptions.tag, FSEND );
    2292        1483 :             tagWritten = true;
    2293             :         }
    2294             : 
    2295        6212 :         bool bWriteShadow = false;
    2296        6212 :         if (rOptions.aShadowLocation == SVX_SHADOW_NONE)
    2297             :         {
    2298             :             // The border has no shadow
    2299             :         }
    2300          16 :         else if (rOptions.aShadowLocation == SVX_SHADOW_BOTTOMRIGHT)
    2301             :         {
    2302             :             // Special case of 'Bottom-Right' shadow:
    2303             :             // If the shadow location is 'Bottom-Right' - then turn on the shadow
    2304             :             // for ALL the sides. This is because in Word - if you select a shadow
    2305             :             // for a border - it turn on the shadow for ALL the sides (but shows only
    2306             :             // the bottom-right one).
    2307             :             // This is so that no information will be lost if passed through LibreOffice
    2308          16 :             bWriteShadow = true;
    2309             :         }
    2310             :         else
    2311             :         {
    2312             :             // If there is a shadow, and it's not the regular 'Bottom-Right',
    2313             :             // then write only the 'shadowed' sides of the border
    2314           0 :             if  (
    2315           0 :                     ( ( rOptions.aShadowLocation == SVX_SHADOW_TOPLEFT     || rOptions.aShadowLocation == SVX_SHADOW_TOPRIGHT      )    &&  *pBrd == BOX_LINE_TOP   )  ||
    2316           0 :                     ( ( rOptions.aShadowLocation == SVX_SHADOW_TOPLEFT     || rOptions.aShadowLocation == SVX_SHADOW_BOTTOMLEFT    )    &&  *pBrd == BOX_LINE_LEFT  )  ||
    2317           0 :                     ( ( rOptions.aShadowLocation == SVX_SHADOW_BOTTOMLEFT  || rOptions.aShadowLocation == SVX_SHADOW_BOTTOMRIGHT   )    &&  *pBrd == BOX_LINE_BOTTOM)  ||
    2318           0 :                     ( ( rOptions.aShadowLocation == SVX_SHADOW_TOPRIGHT    || rOptions.aShadowLocation == SVX_SHADOW_BOTTOMRIGHT   )    &&  *pBrd == BOX_LINE_RIGHT )
    2319             :                 )
    2320             :             {
    2321           0 :                 bWriteShadow = true;
    2322             :             }
    2323             :         }
    2324             : 
    2325        6212 :         sal_uInt16 nDist = 0;
    2326        6212 :         if (rOptions.bWriteDistance)
    2327             :         {
    2328         280 :             if (bExportDistanceFromPageEdge)
    2329             :             {
    2330             :                 // Export 'Distance from Page Edge'
    2331          16 :                 if ( *pBrd == BOX_LINE_TOP)
    2332           4 :                     nDist = pageMargins->nPageMarginTop - rBox.GetDistance( *pBrd );
    2333          12 :                 else if ( *pBrd == BOX_LINE_LEFT)
    2334           4 :                     nDist = pageMargins->nPageMarginLeft - rBox.GetDistance( *pBrd );
    2335           8 :                 else if ( *pBrd == BOX_LINE_BOTTOM)
    2336           4 :                     nDist = pageMargins->nPageMarginBottom - rBox.GetDistance( *pBrd );
    2337           4 :                 else if ( *pBrd == BOX_LINE_RIGHT)
    2338           4 :                     nDist = pageMargins->nPageMarginRight - rBox.GetDistance( *pBrd );
    2339             :             }
    2340             :             else
    2341             :             {
    2342             :                 // Export 'Distance from text'
    2343         264 :                 nDist = rBox.GetDistance( *pBrd );
    2344             :             }
    2345             :         }
    2346             : 
    2347        6212 :         impl_borderLine( pSerializer, aXmlElements[i], pLn, nDist, bWriteShadow, aStyleProps );
    2348             : 
    2349             :         // When exporting default borders, we need to export these 2 attr
    2350        6212 :         if ( rOptions.bWriteInsideHV) {
    2351        5932 :             if ( i == 2 )
    2352        1483 :                 bWriteInsideH = true;
    2353        4449 :             else if ( i == 3 )
    2354        1483 :                 bWriteInsideV = true;
    2355             :         }
    2356             :     }
    2357        1553 :     if (bWriteInsideH)
    2358             :     {
    2359        1483 :         const table::BorderLine2 *aStyleProps = NULL;
    2360        1483 :         if( rTableStyleConf.find( BOX_LINE_BOTTOM ) != rTableStyleConf.end() )
    2361         689 :             aStyleProps = &rTableStyleConf[ BOX_LINE_BOTTOM ];
    2362        1483 :         impl_borderLine( pSerializer, XML_insideH, rBox.GetLine(BOX_LINE_BOTTOM), 0, false, aStyleProps );
    2363             :     }
    2364        1553 :     if (bWriteInsideV)
    2365             :     {
    2366        1483 :         const table::BorderLine2 *aStyleProps = NULL;
    2367        1483 :         if( rTableStyleConf.find( BOX_LINE_RIGHT ) != rTableStyleConf.end() )
    2368         682 :             aStyleProps = &rTableStyleConf[ BOX_LINE_RIGHT ];
    2369        1483 :         impl_borderLine( pSerializer, XML_insideV, rBox.GetLine(BOX_LINE_RIGHT), 0, false, aStyleProps );
    2370             :     }
    2371        1553 :     if (tagWritten && rOptions.bWriteTag) {
    2372        1483 :         pSerializer->endElementNS( XML_w, rOptions.tag );
    2373             :     }
    2374        1553 : }
    2375             : 
    2376        1483 : static void impl_cellMargins( FSHelperPtr pSerializer, const SvxBoxItem& rBox, sal_Int32 tag, bool bUseStartEnd = false, const SvxBoxItem* pDefaultMargins = 0)
    2377             : {
    2378             :     static const sal_uInt16 aBorders[] =
    2379             :     {
    2380             :         BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
    2381             :     };
    2382             : 
    2383             :     const sal_Int32 aXmlElements[] =
    2384             :     {
    2385             :         XML_top,
    2386             :         bUseStartEnd ? XML_start : XML_left,
    2387             :         XML_bottom,
    2388             :         bUseStartEnd ? XML_end : XML_right
    2389        1483 :     };
    2390        1483 :     bool tagWritten = false;
    2391        1483 :     const sal_uInt16* pBrd = aBorders;
    2392        7415 :     for( int i = 0; i < 4; ++i, ++pBrd )
    2393             :     {
    2394        5932 :         sal_Int32 nDist = sal_Int32( rBox.GetDistance( *pBrd ) );
    2395             : 
    2396        5932 :         if ( aBorders[i] == BOX_LINE_LEFT ) {
    2397             :             // Office's cell margin is measured from the right of the border.
    2398             :             // While LO's cell spacing is measured from the center of the border.
    2399             :             // So we add half left-border width to tblIndent value
    2400        1483 :             const SvxBorderLine* pLn = rBox.GetLine( *pBrd );
    2401        1483 :             if (pLn)
    2402         964 :                 nDist -= pLn->GetWidth() * 0.5;
    2403             :         }
    2404             : 
    2405        5932 :         if (pDefaultMargins)
    2406             :         {
    2407             :             // Skip output if cell margin == table default margin
    2408        5556 :             if (sal_Int32( pDefaultMargins->GetDistance( *pBrd ) ) == nDist)
    2409        4438 :                 continue;
    2410             :         }
    2411             : 
    2412        1494 :         if (!tagWritten) {
    2413        1187 :             pSerializer->startElementNS( XML_w, tag, FSEND );
    2414        1187 :             tagWritten = true;
    2415             :         }
    2416        1494 :         pSerializer->singleElementNS( XML_w, aXmlElements[i],
    2417             :                FSNS( XML_w, XML_w ), OString::number( nDist ).getStr( ),
    2418             :                FSNS( XML_w, XML_type ), "dxa",
    2419        2988 :                FSEND );
    2420             :     }
    2421        1483 :     if (tagWritten) {
    2422        1187 :         pSerializer->endElementNS( XML_w, tag );
    2423             :     }
    2424        1483 : }
    2425             : 
    2426        1389 : void DocxAttributeOutput::TableCellProperties( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2427             : {
    2428        1389 :     m_pSerializer->startElementNS( XML_w, XML_tcPr, FSEND );
    2429             : 
    2430        1389 :     const SwTableBox *pTblBox = pTableTextNodeInfoInner->getTableBox( );
    2431             : 
    2432        1389 :     bool bEcma = GetExport().GetFilter().getVersion( ) == oox::core::ECMA_DIALECT;
    2433             : 
    2434             :     // Output any table cell redlines if there are any attached to this specific cell
    2435        1389 :     TableCellRedline( pTableTextNodeInfoInner );
    2436             : 
    2437             :     // Cell preferred width
    2438        1389 :     SwTwips nWidth = GetGridCols( pTableTextNodeInfoInner )->at( pTableTextNodeInfoInner->getCell() );
    2439        1389 :     if ( pTableTextNodeInfoInner->getCell() )
    2440         874 :         nWidth = nWidth - GetGridCols( pTableTextNodeInfoInner )->at( pTableTextNodeInfoInner->getCell() - 1 );
    2441             :     m_pSerializer->singleElementNS( XML_w, XML_tcW,
    2442             :            FSNS( XML_w, XML_w ), OString::number( nWidth ).getStr( ),
    2443             :            FSNS( XML_w, XML_type ), "dxa",
    2444        1389 :            FSEND );
    2445             : 
    2446             :     // Horizontal spans
    2447        1389 :     const SwWriteTableRows& aRows = m_pTableWrt->GetRows( );
    2448        1389 :     SwWriteTableRow *pRow = aRows[ pTableTextNodeInfoInner->getRow( ) ];
    2449        1389 :     sal_uInt32 nCell = pTableTextNodeInfoInner->getCell();
    2450        1389 :     const SwWriteTableCells *tableCells =  &pRow->GetCells();
    2451        1389 :     if (nCell < tableCells->size() )
    2452             :     {
    2453        1389 :         const SwWriteTableCell *pCell = &pRow->GetCells( )[ pTableTextNodeInfoInner->getCell( ) ];
    2454             : 
    2455        1389 :         sal_uInt16 nColSpan = pCell->GetColSpan();
    2456        1389 :         if ( nColSpan > 1 )
    2457             :             m_pSerializer->singleElementNS( XML_w, XML_gridSpan,
    2458             :                     FSNS( XML_w, XML_val ), OString::number( nColSpan ).getStr(),
    2459         189 :                     FSEND );
    2460             :     }
    2461             : 
    2462             :     // Vertical merges
    2463        1389 :     long vSpan = pTblBox->getRowSpan( );
    2464        1389 :     if ( vSpan > 1 )
    2465             :     {
    2466             :         m_pSerializer->singleElementNS( XML_w, XML_vMerge,
    2467             :                 FSNS( XML_w, XML_val ), "restart",
    2468          12 :                 FSEND );
    2469             :     }
    2470        1377 :     else if ( vSpan < 0 )
    2471             :     {
    2472             :         m_pSerializer->singleElementNS( XML_w, XML_vMerge,
    2473             :                 FSNS( XML_w, XML_val ), "continue",
    2474          12 :                 FSEND );
    2475             :     }
    2476             : 
    2477        1389 :     const SvxBoxItem& rBox = pTblBox->GetFrmFmt( )->GetBox( );
    2478        1389 :     const SvxBoxItem& rDefaultBox = (*tableFirstCells.rbegin())->getTableBox( )->GetFrmFmt( )->GetBox( );
    2479             :     {
    2480             :         // The cell borders
    2481        1389 :         impl_borders( m_pSerializer, rBox, lcl_getTableCellBorderOptions(bEcma), NULL, m_aTableStyleConf );
    2482             :     }
    2483             : 
    2484        1389 :     TableBackgrounds( pTableTextNodeInfoInner );
    2485             : 
    2486             :     {
    2487             :         // Cell margins
    2488        1389 :         impl_cellMargins( m_pSerializer, rBox, XML_tcMar, !bEcma, &rDefaultBox );
    2489             :     }
    2490             : 
    2491        1389 :     TableVerticalCell( pTableTextNodeInfoInner );
    2492             : 
    2493        1389 :     m_pSerializer->endElementNS( XML_w, XML_tcPr );
    2494        1389 : }
    2495             : 
    2496          98 : void DocxAttributeOutput::InitTableHelper( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2497             : {
    2498          98 :     sal_uInt32 nPageSize = 0;
    2499          98 :     bool bRelBoxSize = false;
    2500             : 
    2501             :     // Create the SwWriteTable instance to use col spans (and maybe other infos)
    2502          98 :     GetTablePageSize( pTableTextNodeInfoInner.get(), nPageSize, bRelBoxSize );
    2503             : 
    2504          98 :     const SwTable* pTable = pTableTextNodeInfoInner->getTable( );
    2505          98 :     const SwFrmFmt *pFmt = pTable->GetFrmFmt( );
    2506          98 :     SwTwips nTblSz = pFmt->GetFrmSize( ).GetWidth( );
    2507             : 
    2508          98 :     const SwHTMLTableLayout *pLayout = pTable->GetHTMLTableLayout();
    2509          98 :     if( pLayout && pLayout->IsExportable() )
    2510           0 :         m_pTableWrt = new SwWriteTable( pLayout );
    2511             :     else
    2512             :         m_pTableWrt = new SwWriteTable( pTable->GetTabLines(), (sal_uInt16)nPageSize,
    2513          98 :                 (sal_uInt16)nTblSz, false);
    2514          98 : }
    2515             : 
    2516             : /**
    2517             :  * As we are exporting Header and footer in between when we are exporting document.xml.
    2518             :  * In this case we are facing issue in table export for header and footer. Because
    2519             :  * flags for table is getting shared in both export.
    2520             :  * So we are switching between flags in between exporting "document.xml" and Header & footer
    2521             :  * export.
    2522             :  */
    2523         799 : void DocxAttributeOutput::switchHeaderFooter(bool isHeaderFooter, sal_Int32 index)
    2524             : {
    2525         799 :     if( isHeaderFooter && index == 1)
    2526             :     {
    2527         191 :         m_oldTableReference->m_bTableCellOpen = m_tableReference->m_bTableCellOpen;
    2528         191 :         m_oldTableReference->m_nTableDepth = m_tableReference->m_nTableDepth;
    2529         191 :         m_oldTableReference->m_pOldTablepInner = m_tableReference->m_pOldTablepInner;
    2530         191 :         m_tableReference->m_bTableCellOpen = false;
    2531         191 :         m_tableReference->m_nTableDepth = 0;
    2532         191 :         m_pSectionInfo.reset();
    2533             :     }
    2534         608 :     else if( index == -1)
    2535             :     {
    2536         413 :        if (m_oldTableReference->m_pOldTablepInner)
    2537             :        {
    2538          25 :            *m_tableReference = *m_oldTableReference;
    2539             : 
    2540             :             //Reset the oldReference, after copying it back to the original.
    2541          25 :             m_oldTableReference->m_bTableCellOpen = false ;
    2542          25 :             m_oldTableReference->m_nTableDepth = 0;
    2543             :        }
    2544             : 
    2545             :     }
    2546             :     else
    2547             :     {
    2548         195 :         m_tableReference->m_bTableCellOpen = false;
    2549         195 :         m_tableReference->m_nTableDepth = 0;
    2550             :     }
    2551         799 : }
    2552             : 
    2553          94 : void DocxAttributeOutput::StartTable( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2554             : {
    2555          94 :     m_pSerializer->startElementNS( XML_w, XML_tbl, FSEND );
    2556             : 
    2557          94 :     tableFirstCells.push_back(pTableTextNodeInfoInner);
    2558             : 
    2559          94 :     InitTableHelper( pTableTextNodeInfoInner );
    2560          94 :     TableDefinition( pTableTextNodeInfoInner );
    2561          94 : }
    2562             : 
    2563          94 : void DocxAttributeOutput::EndTable()
    2564             : {
    2565          94 :     m_pSerializer->endElementNS( XML_w, XML_tbl );
    2566             : 
    2567          94 :     if ( m_tableReference->m_nTableDepth > 0 )
    2568          94 :         --m_tableReference->m_nTableDepth;
    2569             : 
    2570          94 :     tableFirstCells.pop_back();
    2571             : 
    2572             :     // We closed the table; if it is a nested table, the cell that contains it
    2573             :     // still continues
    2574             :     // set to true only if we were in a nested table, not otherwise.
    2575          94 :     if( 0 != tableFirstCells.size() )
    2576          10 :         m_tableReference->m_bTableCellOpen = true;
    2577             : 
    2578             :     // Cleans the table helper
    2579          94 :     delete m_pTableWrt, m_pTableWrt = NULL;
    2580             : 
    2581          94 :     m_aTableStyleConf.clear();
    2582          94 : }
    2583             : 
    2584         515 : void DocxAttributeOutput::StartTableRow( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2585             : {
    2586         515 :     m_pSerializer->startElementNS( XML_w, XML_tr, FSEND );
    2587             : 
    2588             :     // Output the row properties
    2589         515 :     m_pSerializer->startElementNS( XML_w, XML_trPr, FSEND );
    2590             : 
    2591             :     // Header row: tblHeader
    2592         515 :     const SwTable *pTable = pTableTextNodeInfoInner->getTable( );
    2593         515 :     if ( pTable->GetRowsToRepeat( ) > pTableTextNodeInfoInner->getRow( ) )
    2594             :         m_pSerializer->singleElementNS( XML_w, XML_tblHeader,
    2595             :                FSNS( XML_w, XML_val ), "true",
    2596           2 :                FSEND );
    2597             : 
    2598         515 :     TableRowRedline( pTableTextNodeInfoInner );
    2599         515 :     TableHeight( pTableTextNodeInfoInner );
    2600         515 :     TableCanSplit( pTableTextNodeInfoInner );
    2601             : 
    2602         515 :     m_pSerializer->endElementNS( XML_w, XML_trPr );
    2603         515 : }
    2604             : 
    2605         515 : void DocxAttributeOutput::EndTableRow( )
    2606             : {
    2607         515 :     m_pSerializer->endElementNS( XML_w, XML_tr );
    2608         515 : }
    2609             : 
    2610        1389 : void DocxAttributeOutput::StartTableCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2611             : {
    2612        1389 :     if ( !m_pTableWrt )
    2613           4 :         InitTableHelper( pTableTextNodeInfoInner );
    2614             : 
    2615        1389 :     m_pSerializer->startElementNS( XML_w, XML_tc, FSEND );
    2616             : 
    2617             :     // Write the cell properties here
    2618        1389 :     TableCellProperties( pTableTextNodeInfoInner );
    2619             : 
    2620        1389 :     m_tableReference->m_bTableCellOpen = true;
    2621        1389 : }
    2622             : 
    2623        1389 : void DocxAttributeOutput::EndTableCell( )
    2624             : {
    2625        1389 :     m_pSerializer->endElementNS( XML_w, XML_tc );
    2626             : 
    2627        1389 :     m_bBtLr = false;
    2628        1389 :     m_tableReference->m_bTableCellOpen = false;
    2629        1389 : }
    2630             : 
    2631        1602 : void DocxAttributeOutput::TableInfoCell( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
    2632             : {
    2633        1602 : }
    2634             : 
    2635           0 : void DocxAttributeOutput::TableInfoRow( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfo*/ )
    2636             : {
    2637           0 : }
    2638             : 
    2639          94 : void DocxAttributeOutput::TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2640             : {
    2641          94 :     bool bEcma = GetExport().GetFilter().getVersion( ) == oox::core::ECMA_DIALECT;
    2642             : 
    2643             :     // Write the table properties
    2644          94 :     m_pSerializer->startElementNS( XML_w, XML_tblPr, FSEND );
    2645             : 
    2646             :     static const sal_Int32 aOrder[] =
    2647             :     {
    2648             :         FSNS( XML_w, XML_tblStyle ),
    2649             :         FSNS( XML_w, XML_tblpPr ),
    2650             :         FSNS( XML_w, XML_tblOverlap ),
    2651             :         FSNS( XML_w, XML_bidiVisual ),
    2652             :         FSNS( XML_w, XML_tblStyleRowBandSize ),
    2653             :         FSNS( XML_w, XML_tblStyleColBandSize ),
    2654             :         FSNS( XML_w, XML_tblW ),
    2655             :         FSNS( XML_w, XML_jc ),
    2656             :         FSNS( XML_w, XML_tblCellSpacing ),
    2657             :         FSNS( XML_w, XML_tblInd ),
    2658             :         FSNS( XML_w, XML_tblBorders ),
    2659             :         FSNS( XML_w, XML_shd ),
    2660             :         FSNS( XML_w, XML_tblLayout ),
    2661             :         FSNS( XML_w, XML_tblCellMar ),
    2662             :         FSNS( XML_w, XML_tblLook ),
    2663             :         FSNS( XML_w, XML_tblPrChange )
    2664             :     };
    2665             : 
    2666             :     // postpone the output so that we can later []
    2667             :     // prepend the properties before the run
    2668          94 :     sal_Int32 len = sizeof ( aOrder ) / sizeof( sal_Int32 );
    2669          94 :     uno::Sequence< sal_Int32 > aSeqOrder( len );
    2670        1598 :     for ( sal_Int32 i = 0; i < len; i++ )
    2671        1504 :         aSeqOrder[i] = aOrder[i];
    2672             : 
    2673          94 :     m_pSerializer->mark( aSeqOrder );
    2674             : 
    2675          94 :     sal_uInt32 nPageSize = 0;
    2676          94 :     const char* widthType = "dxa";
    2677          94 :     bool bRelBoxSize = false;
    2678             : 
    2679             :     // If actual width of table is relative it shoud export is as "auto".
    2680          94 :     const SwTable *pTable = pTableTextNodeInfoInner->getTable();
    2681          94 :     SwFrmFmt *pTblFmt = pTable->GetFrmFmt( );
    2682         188 :     uno::Reference<beans::XPropertySet> xPropertySet(SwXTextTables::GetObject(const_cast<SwFrmFmt&>(*pTable->GetFrmFmt( ))),uno::UNO_QUERY);
    2683          94 :     bool isWidthRelative = false;
    2684          94 :     xPropertySet->getPropertyValue("IsWidthRelative") >>= isWidthRelative;
    2685             : 
    2686          94 :     if(isWidthRelative)
    2687             :     {
    2688           9 :         nPageSize = 0;
    2689           9 :         widthType = "auto";
    2690             :     }
    2691             :     else
    2692             :     {
    2693             :         // Create the SwWriteTable instance to use col spans (and maybe other infos)
    2694          85 :         GetTablePageSize( pTableTextNodeInfoInner.get(), nPageSize, bRelBoxSize );
    2695          85 :         if(nPageSize == 0)
    2696          84 :             widthType = "auto";
    2697             :     }
    2698             : 
    2699             :     // Output the table preferred width
    2700             :     m_pSerializer->singleElementNS( XML_w, XML_tblW,
    2701             :             FSNS( XML_w, XML_w ), OString::number( nPageSize ).getStr( ),
    2702             :             FSNS( XML_w, XML_type ), widthType,
    2703          94 :             FSEND );
    2704             : 
    2705             :     // Look for the table style property in the table grab bag
    2706             :     std::map<OUString, com::sun::star::uno::Any> aGrabBag =
    2707         188 :             sw::util::HasItem<SfxGrabBagItem>( pTblFmt->GetAttrSet(), RES_FRMATR_GRABBAG )->GetGrabBag();
    2708             : 
    2709             :     // Extract properties from grab bag
    2710          94 :     std::map<OUString, com::sun::star::uno::Any>::iterator aGrabBagElement;
    2711         265 :     for( aGrabBagElement = aGrabBag.begin(); aGrabBagElement != aGrabBag.end(); ++aGrabBagElement )
    2712             :     {
    2713         171 :         if( aGrabBagElement->first == "TableStyleName")
    2714             :         {
    2715          37 :             OString sStyleName = OUStringToOString( aGrabBagElement->second.get<OUString>(), RTL_TEXTENCODING_UTF8 );
    2716             :             m_pSerializer->singleElementNS( XML_w, XML_tblStyle,
    2717             :                     FSNS( XML_w, XML_val ), sStyleName.getStr(),
    2718          37 :                     FSEND );
    2719             :         }
    2720         134 :         else if( aGrabBagElement->first == "TableStyleTopBorder" )
    2721          34 :             m_aTableStyleConf[ BOX_LINE_TOP ] = aGrabBagElement->second.get<table::BorderLine2>();
    2722         100 :         else if( aGrabBagElement->first == "TableStyleBottomBorder" )
    2723          34 :             m_aTableStyleConf[ BOX_LINE_BOTTOM ] = aGrabBagElement->second.get<table::BorderLine2>();
    2724          66 :         else if( aGrabBagElement->first == "TableStyleLeftBorder" )
    2725          33 :             m_aTableStyleConf[ BOX_LINE_LEFT ] = aGrabBagElement->second.get<table::BorderLine2>();
    2726          33 :         else if( aGrabBagElement->first == "TableStyleRightBorder" )
    2727          33 :             m_aTableStyleConf[ BOX_LINE_RIGHT ] = aGrabBagElement->second.get<table::BorderLine2>();
    2728             :     }
    2729             : 
    2730             :     // Output the table alignement
    2731             :     const char* pJcVal;
    2732          94 :     sal_Int32 nIndent = 0;
    2733          94 :     switch ( pTblFmt->GetHoriOrient( ).GetHoriOrient( ) )
    2734             :     {
    2735             :         case text::HoriOrientation::CENTER:
    2736          11 :             pJcVal = "center";
    2737          11 :             break;
    2738             :         case text::HoriOrientation::RIGHT:
    2739           0 :             if ( bEcma )
    2740           0 :                 pJcVal = "right";
    2741             :             else
    2742           0 :                 pJcVal = "end";
    2743           0 :             break;
    2744             :         default:
    2745             :         case text::HoriOrientation::NONE:
    2746             :         case text::HoriOrientation::LEFT_AND_WIDTH:
    2747             :         {
    2748          83 :             if ( bEcma )
    2749           0 :                 pJcVal = "left";
    2750             :             else
    2751          83 :                 pJcVal = "start";
    2752          83 :             nIndent = sal_Int32( pTblFmt->GetLRSpace( ).GetLeft( ) );
    2753             :             // Table indentation has different meaning in Word, depending if the table is nested or not.
    2754             :             // If nested, tblInd is added to parent table's left spacing and defines left edge position
    2755             :             // If not nested, text position of left-most cell must be at absolute X = tblInd
    2756             :             // so, table_spacing + table_spacing_to_content = tblInd
    2757          83 :             if (m_tableReference->m_nTableDepth == 0)
    2758             :             {
    2759          81 :                 const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
    2760          81 :                 const SwFrmFmt * pFrmFmt = pTabBox->GetFrmFmt();
    2761          81 :                 nIndent += sal_Int32( pFrmFmt->GetBox( ).GetDistance( BOX_LINE_LEFT ) );
    2762             :             }
    2763          83 :             break;
    2764             :         }
    2765             :     }
    2766             :     m_pSerializer->singleElementNS( XML_w, XML_jc,
    2767             :             FSNS( XML_w, XML_val ), pJcVal,
    2768          94 :             FSEND );
    2769             : 
    2770             :     // Output the table borders
    2771          94 :     TableDefaultBorders( pTableTextNodeInfoInner );
    2772             : 
    2773             :     // Output the default cell margins
    2774          94 :     TableDefaultCellMargins( pTableTextNodeInfoInner );
    2775             : 
    2776          94 :     TableBidi( pTableTextNodeInfoInner );
    2777             : 
    2778             :     // Table indent (need to get written even if == 0)
    2779             :     m_pSerializer->singleElementNS( XML_w, XML_tblInd,
    2780             :             FSNS( XML_w, XML_w ), OString::number( nIndent ).getStr( ),
    2781             :             FSNS( XML_w, XML_type ), "dxa",
    2782          94 :             FSEND );
    2783             : 
    2784             :     // Merge the marks for the ordered elements
    2785          94 :     m_pSerializer->mergeTopMarks( );
    2786             : 
    2787          94 :     m_pSerializer->endElementNS( XML_w, XML_tblPr );
    2788             : 
    2789             :     // Write the table grid infos
    2790          94 :     m_pSerializer->startElementNS( XML_w, XML_tblGrid, FSEND );
    2791          94 :     sal_Int32 nPrv = 0;
    2792          94 :     ww8::WidthsPtr pColumnWidths = GetColumnWidths( pTableTextNodeInfoInner );
    2793         386 :     for ( ww8::Widths::const_iterator it = pColumnWidths->begin(); it != pColumnWidths->end(); ++it )
    2794             :     {
    2795         292 :         sal_Int32 nWidth  =  sal_Int32( *it ) - nPrv;
    2796             :         m_pSerializer->singleElementNS( XML_w, XML_gridCol,
    2797             :                FSNS( XML_w, XML_w ), OString::number( nWidth ).getStr( ),
    2798         292 :                FSEND );
    2799         292 :         nPrv = sal_Int32( *it );
    2800             :     }
    2801             : 
    2802         188 :     m_pSerializer->endElementNS( XML_w, XML_tblGrid );
    2803          94 : }
    2804             : 
    2805          94 : void DocxAttributeOutput::TableDefaultBorders( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2806             : {
    2807          94 :     const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
    2808          94 :     const SwFrmFmt * pFrmFmt = pTabBox->GetFrmFmt();
    2809             : 
    2810          94 :     bool bEcma = GetExport().GetFilter().getVersion( ) == oox::core::ECMA_DIALECT;
    2811             : 
    2812             :     // the defaults of the table are taken from the top-left cell
    2813          94 :     impl_borders( m_pSerializer, pFrmFmt->GetBox( ), lcl_getTableDefaultBorderOptions(bEcma), NULL, m_aTableStyleConf );
    2814          94 : }
    2815             : 
    2816          94 : void DocxAttributeOutput::TableDefaultCellMargins( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2817             : {
    2818          94 :     const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
    2819          94 :     const SwFrmFmt * pFrmFmt = pTabBox->GetFrmFmt();
    2820          94 :     const SvxBoxItem& rBox = pFrmFmt->GetBox( );
    2821          94 :     const bool bEcma = GetExport().GetFilter().getVersion( ) == oox::core::ECMA_DIALECT;
    2822             : 
    2823          94 :     impl_cellMargins(m_pSerializer, rBox, XML_tblCellMar, !bEcma);
    2824          94 : }
    2825             : 
    2826        1389 : void DocxAttributeOutput::TableBackgrounds( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2827             : {
    2828        1389 :     const SwTableBox *pTblBox = pTableTextNodeInfoInner->getTableBox( );
    2829        1389 :     const SwFrmFmt *pFmt = pTblBox->GetFrmFmt( );
    2830             : 
    2831        1389 :     const SvxBrushItem *aColorProp = sw::util::HasItem<SvxBrushItem>( pFmt->GetAttrSet(), RES_BACKGROUND );
    2832        1389 :     Color aColor = aColorProp ? aColorProp->GetColor() : COL_AUTO;
    2833        1389 :     OString sColor = msfilter::util::ConvertColor( aColor );
    2834             : 
    2835             :     std::map<OUString, com::sun::star::uno::Any> aGrabBag =
    2836        2778 :             sw::util::HasItem<SfxGrabBagItem>( pFmt->GetAttrSet(), RES_FRMATR_GRABBAG )->GetGrabBag();
    2837             : 
    2838        2778 :     OString sOriginalColor;
    2839        1389 :     std::map<OUString, com::sun::star::uno::Any>::iterator aGrabBagElement = aGrabBag.find("fill");
    2840        1389 :     if( aGrabBagElement != aGrabBag.end() )
    2841         172 :         sOriginalColor = OUStringToOString( aGrabBagElement->second.get<OUString>(), RTL_TEXTENCODING_UTF8 );
    2842             : 
    2843        1389 :     if ( sOriginalColor != sColor )
    2844             :     {
    2845             :         // color changed by the user, or no grab bag: write sColor
    2846             :         m_pSerializer->singleElementNS( XML_w, XML_shd,
    2847             :                 FSNS( XML_w, XML_fill ), sColor.getStr( ),
    2848             :                 FSNS( XML_w, XML_val ), "clear",
    2849        1267 :                 FSEND );
    2850             :     }
    2851             :     else
    2852             :     {
    2853         122 :         ::sax_fastparser::FastAttributeList* aAttrList = NULL;
    2854         122 :         AddToAttrList( aAttrList, FSNS( XML_w, XML_fill ), sColor.getStr() );
    2855             : 
    2856         539 :         for( aGrabBagElement = aGrabBag.begin(); aGrabBagElement != aGrabBag.end(); ++aGrabBagElement )
    2857             :         {
    2858         417 :             OString sValue = OUStringToOString( aGrabBagElement->second.get<OUString>(), RTL_TEXTENCODING_UTF8 );
    2859         417 :             if( aGrabBagElement->first == "themeFill")
    2860          32 :                 AddToAttrList( aAttrList, FSNS( XML_w, XML_themeFill ), sValue.getStr() );
    2861         385 :             else if( aGrabBagElement->first == "themeFillTint")
    2862           7 :                 AddToAttrList( aAttrList, FSNS( XML_w, XML_themeFillTint ), sValue.getStr() );
    2863         378 :             else if( aGrabBagElement->first == "themeFillShade")
    2864          24 :                 AddToAttrList( aAttrList, FSNS( XML_w, XML_themeFillShade ), sValue.getStr() );
    2865         354 :             else if( aGrabBagElement->first == "color")
    2866         110 :                 AddToAttrList( aAttrList, FSNS( XML_w, XML_color ), sValue.getStr() );
    2867         244 :             else if( aGrabBagElement->first == "val")
    2868         122 :                 AddToAttrList( aAttrList, FSNS( XML_w, XML_val ), sValue.getStr() );
    2869         417 :         }
    2870             :         m_pSerializer->singleElementNS( XML_w, XML_shd,
    2871         122 :                 XFastAttributeListRef( aAttrList ) );
    2872        1389 :     }
    2873        1389 : }
    2874             : 
    2875         515 : void DocxAttributeOutput::TableRowRedline( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2876             : {
    2877         515 :     const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
    2878         515 :     const SwTableLine * pTabLine = pTabBox->GetUpper();
    2879             : 
    2880             :     // search next Redline
    2881         515 :     const SwExtraRedlineTbl& aExtraRedlineTbl = m_rExport.pDoc->GetExtraRedlineTbl();
    2882         527 :     for(sal_uInt16 nCurRedlinePos = 0; nCurRedlinePos < aExtraRedlineTbl.GetSize(); ++nCurRedlinePos )
    2883             :     {
    2884          12 :         SwExtraRedline* pExtraRedline = aExtraRedlineTbl.GetRedline(nCurRedlinePos);
    2885          12 :         const SwTableRowRedline* pTableRowRedline = dynamic_cast<const SwTableRowRedline*>(pExtraRedline);
    2886          12 :         const SwTableLine *pRedTabLine = pTableRowRedline ? &pTableRowRedline->GetTableLine() : NULL;
    2887          12 :         if (pRedTabLine == pTabLine)
    2888             :         {
    2889             :             // Redline for this table row
    2890           2 :             const SwRedlineData& aRedlineData = pTableRowRedline->GetRedlineData();
    2891           2 :             sal_uInt16 nRedlineType = aRedlineData.GetType();
    2892           2 :             switch (nRedlineType)
    2893             :             {
    2894             :                 case nsRedlineType_t::REDLINE_TABLE_ROW_INSERT:
    2895             :                 case nsRedlineType_t::REDLINE_TABLE_ROW_DELETE:
    2896             :                 {
    2897           2 :                     OString aId( OString::number( m_nRedlineId++ ) );
    2898           4 :                     const OUString &rAuthor( SW_MOD()->GetRedlineAuthor( aRedlineData.GetAuthor() ) );
    2899           4 :                     OString aAuthor( OUStringToOString( rAuthor, RTL_TEXTENCODING_UTF8 ) );
    2900             : 
    2901           4 :                     OString aDate( DateTimeToOString( aRedlineData.GetTimeStamp() ) );
    2902             : 
    2903           2 :                     if (nRedlineType == nsRedlineType_t::REDLINE_TABLE_ROW_INSERT)
    2904             :                         m_pSerializer->singleElementNS( XML_w, XML_ins,
    2905             :                             FSNS( XML_w, XML_id ), aId.getStr(),
    2906             :                             FSNS( XML_w, XML_author ), aAuthor.getStr(),
    2907             :                             FSNS( XML_w, XML_date ), aDate.getStr(),
    2908           1 :                             FSEND );
    2909           1 :                     else if (nRedlineType == nsRedlineType_t::REDLINE_TABLE_ROW_DELETE)
    2910             :                         m_pSerializer->singleElementNS( XML_w, XML_del,
    2911             :                             FSNS( XML_w, XML_id ), aId.getStr(),
    2912             :                             FSNS( XML_w, XML_author ), aAuthor.getStr(),
    2913             :                             FSNS( XML_w, XML_date ), aDate.getStr(),
    2914           3 :                             FSEND );
    2915             :                 }
    2916           2 :                 break;
    2917             :             };
    2918             :         }
    2919             :     }
    2920         515 : }
    2921             : 
    2922        1389 : void DocxAttributeOutput::TableCellRedline( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2923             : {
    2924        1389 :     const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
    2925             : 
    2926             :     // search next Redline
    2927        1389 :     const SwExtraRedlineTbl& aExtraRedlineTbl = m_rExport.pDoc->GetExtraRedlineTbl();
    2928        1413 :     for(sal_uInt16 nCurRedlinePos = 0; nCurRedlinePos < aExtraRedlineTbl.GetSize(); ++nCurRedlinePos )
    2929             :     {
    2930          24 :         SwExtraRedline* pExtraRedline = aExtraRedlineTbl.GetRedline(nCurRedlinePos);
    2931          24 :         const SwTableCellRedline* pTableCellRedline = dynamic_cast<const SwTableCellRedline*>(pExtraRedline);
    2932          24 :         const SwTableBox *pRedTabBox = pTableCellRedline ? &pTableCellRedline->GetTableBox() : NULL;
    2933          24 :         if (pRedTabBox == pTabBox)
    2934             :         {
    2935             :             // Redline for this table cell
    2936           2 :             const SwRedlineData& aRedlineData = pTableCellRedline->GetRedlineData();
    2937           2 :             sal_uInt16 nRedlineType = aRedlineData.GetType();
    2938           2 :             switch (nRedlineType)
    2939             :             {
    2940             :                 case nsRedlineType_t::REDLINE_TABLE_CELL_INSERT:
    2941             :                 case nsRedlineType_t::REDLINE_TABLE_CELL_DELETE:
    2942             :                 {
    2943           2 :                     OString aId( OString::number( m_nRedlineId++ ) );
    2944           4 :                     const OUString &rAuthor( SW_MOD()->GetRedlineAuthor( aRedlineData.GetAuthor() ) );
    2945           4 :                     OString aAuthor( OUStringToOString( rAuthor, RTL_TEXTENCODING_UTF8 ) );
    2946             : 
    2947           4 :                     OString aDate( DateTimeToOString( aRedlineData.GetTimeStamp() ) );
    2948             : 
    2949           2 :                     if (nRedlineType == nsRedlineType_t::REDLINE_TABLE_CELL_INSERT)
    2950             :                         m_pSerializer->singleElementNS( XML_w, XML_cellIns,
    2951             :                             FSNS( XML_w, XML_id ), aId.getStr(),
    2952             :                             FSNS( XML_w, XML_author ), aAuthor.getStr(),
    2953             :                             FSNS( XML_w, XML_date ), aDate.getStr(),
    2954           1 :                             FSEND );
    2955           1 :                     else if (nRedlineType == nsRedlineType_t::REDLINE_TABLE_CELL_DELETE)
    2956             :                         m_pSerializer->singleElementNS( XML_w, XML_cellDel,
    2957             :                             FSNS( XML_w, XML_id ), aId.getStr(),
    2958             :                             FSNS( XML_w, XML_author ), aAuthor.getStr(),
    2959             :                             FSNS( XML_w, XML_date ), aDate.getStr(),
    2960           3 :                             FSEND );
    2961             :                 }
    2962           2 :                 break;
    2963             :             };
    2964             :         }
    2965             :     }
    2966        1389 : }
    2967             : 
    2968         515 : void DocxAttributeOutput::TableHeight( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2969             : {
    2970         515 :     const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
    2971         515 :     const SwTableLine * pTabLine = pTabBox->GetUpper();
    2972         515 :     const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();
    2973             : 
    2974         515 :     const SwFmtFrmSize& rLSz = pLineFmt->GetFrmSize();
    2975         515 :     if ( ATT_VAR_SIZE != rLSz.GetHeightSizeType() && rLSz.GetHeight() )
    2976             :     {
    2977         260 :         sal_Int32 nHeight = rLSz.GetHeight();
    2978         260 :         const char *pRule = NULL;
    2979             : 
    2980         260 :         switch ( rLSz.GetHeightSizeType() )
    2981             :         {
    2982           0 :             case ATT_FIX_SIZE: pRule = "exact"; break;
    2983         260 :             case ATT_MIN_SIZE: pRule = "atLeast"; break;
    2984           0 :             default:           break;
    2985             :         }
    2986             : 
    2987         260 :         if ( pRule )
    2988             :             m_pSerializer->singleElementNS( XML_w, XML_trHeight,
    2989             :                     FSNS( XML_w, XML_val ), OString::number( nHeight ).getStr( ),
    2990             :                     FSNS( XML_w, XML_hRule ), pRule,
    2991         260 :                     FSEND );
    2992             :     }
    2993         515 : }
    2994             : 
    2995         515 : void DocxAttributeOutput::TableCanSplit( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2996             : {
    2997         515 :     const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
    2998         515 :     const SwTableLine * pTabLine = pTabBox->GetUpper();
    2999         515 :     const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();
    3000             : 
    3001         515 :     const SwFmtRowSplit& rSplittable = pLineFmt->GetRowSplit( );
    3002         515 :     const char* pCantSplit = ( !rSplittable.GetValue( ) ) ? "true" : "false";
    3003             :     // if rSplittable is true then no need to write <w:cantSplit w:val="false"/>
    3004             :     // as default row prop is allow row to break across page.
    3005         515 :     if( !rSplittable.GetValue( ) )
    3006             :     m_pSerializer->singleElementNS( XML_w, XML_cantSplit,
    3007             :            FSNS( XML_w, XML_val ), pCantSplit,
    3008          17 :            FSEND );
    3009         515 : }
    3010             : 
    3011          94 : void DocxAttributeOutput::TableBidi( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    3012             : {
    3013          94 :     const SwTable * pTable = pTableTextNodeInfoInner->getTable();
    3014          94 :     const SwFrmFmt * pFrmFmt = pTable->GetFrmFmt();
    3015             : 
    3016          94 :     if ( m_rExport.TrueFrameDirection( *pFrmFmt ) == FRMDIR_HORI_RIGHT_TOP )
    3017             :     {
    3018             :         m_pSerializer->singleElementNS( XML_w, XML_bidiVisual,
    3019             :                 FSNS( XML_w, XML_val ), "true",
    3020           0 :                 FSEND );
    3021             :     }
    3022          94 : }
    3023             : 
    3024        1389 : void DocxAttributeOutput::TableVerticalCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    3025             : {
    3026        1389 :     const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
    3027        1389 :     const SwFrmFmt *pFrmFmt = pTabBox->GetFrmFmt( );
    3028             : 
    3029        1389 :     if ( FRMDIR_VERT_TOP_RIGHT == m_rExport.TrueFrameDirection( *pFrmFmt ) )
    3030             :         m_pSerializer->singleElementNS( XML_w, XML_textDirection,
    3031             :                FSNS( XML_w, XML_val ), "tbRl",
    3032           0 :                FSEND );
    3033        1389 :     else if ( FRMDIR_HORI_LEFT_TOP == m_rExport.TrueFrameDirection( *pFrmFmt ) )
    3034             :     {
    3035             :         // Undo the text direction mangling done by the btLr handler in writerfilter::dmapper::DomainMapperTableManager::sprm()
    3036        1351 :         SwPaM aPam(*pTabBox->GetSttNd(), 0);
    3037        1351 :         aPam.GetPoint()->nNode++;
    3038        1351 :         if (aPam.GetPoint()->nNode.GetNode().IsTxtNode())
    3039             :         {
    3040        1346 :             const SwTxtNode& rTxtNode = (const SwTxtNode&)aPam.GetPoint()->nNode.GetNode();
    3041        1346 :             if( const SwAttrSet* pAttrSet = rTxtNode.GetpSwAttrSet())
    3042             :             {
    3043        1288 :                 const SvxCharRotateItem& rCharRotate = pAttrSet->GetCharRotate();
    3044        1288 :                 if (rCharRotate.GetValue() == 900)
    3045             :                 {
    3046           1 :                     m_pSerializer->singleElementNS( XML_w, XML_textDirection, FSNS( XML_w, XML_val ), "btLr", FSEND );
    3047           1 :                     m_bBtLr = true;
    3048             :                 }
    3049             :             }
    3050        1351 :         }
    3051             :     }
    3052             : 
    3053        1389 :     const SwWriteTableRows& aRows = m_pTableWrt->GetRows( );
    3054        1389 :     SwWriteTableRow *pRow = aRows[ pTableTextNodeInfoInner->getRow( ) ];
    3055        1389 :     sal_uInt32 nCell = pTableTextNodeInfoInner->getCell();
    3056        1389 :     const SwWriteTableCells *tableCells =  &pRow->GetCells();
    3057        1389 :     if (nCell < tableCells->size() )
    3058             :     {
    3059        1389 :         const SwWriteTableCell *pCell = &pRow->GetCells( )[ pTableTextNodeInfoInner->getCell( ) ];
    3060        1389 :         switch( pCell->GetVertOri())
    3061             :         {
    3062             :         case text::VertOrientation::TOP:
    3063         972 :             break;
    3064             :         case text::VertOrientation::CENTER:
    3065             :             m_pSerializer->singleElementNS( XML_w, XML_vAlign,
    3066         197 :             FSNS( XML_w, XML_val ), "center", FSEND );
    3067         197 :             break;
    3068             :         case text::VertOrientation::BOTTOM:
    3069             :             m_pSerializer->singleElementNS( XML_w, XML_vAlign,
    3070         220 :                     FSNS( XML_w, XML_val ), "bottom", FSEND );
    3071         220 :             break;
    3072             :         }
    3073             :     }
    3074        1389 : }
    3075             : 
    3076           0 : void DocxAttributeOutput::TableNodeInfo( ww8::WW8TableNodeInfo::Pointer_t /*pNodeInfo*/ )
    3077             : {
    3078             :     OSL_TRACE( "TODO: DocxAttributeOutput::TableNodeInfo( ww8::WW8TableNodeInfo::Pointer_t pNodeInfo )" );
    3079           0 : }
    3080             : 
    3081        2986 : void DocxAttributeOutput::TableNodeInfoInner( ww8::WW8TableNodeInfoInner::Pointer_t pNodeInfoInner )
    3082             : {
    3083             :     // This is called when the nested table ends in a cell, and there's no
    3084             :     // paragraph benhind that; so we must check for the ends of cell, rows,
    3085             :     // tables
    3086             :     // ['true' to write an empty paragraph, MS Word insists on that]
    3087        2986 :     FinishTableRowCell( pNodeInfoInner, true );
    3088        2986 : }
    3089             : 
    3090           0 : void DocxAttributeOutput::TableOrientation( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
    3091             : {
    3092             :     OSL_TRACE( "TODO: DocxAttributeOutput::TableOrientation( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )" );
    3093           0 : }
    3094             : 
    3095           0 : void DocxAttributeOutput::TableSpacing( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
    3096             : {
    3097             : #if OSL_DEBUG_LEVEL > 1
    3098             :     fprintf( stderr, "TODO: DocxAttributeOutput::TableSpacing( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )\n" );
    3099             : #endif
    3100           0 : }
    3101             : 
    3102           0 : void DocxAttributeOutput::TableRowEnd( sal_uInt32 /*nDepth*/ )
    3103             : {
    3104             :     OSL_TRACE( "TODO: DocxAttributeOutput::TableRowEnd( sal_uInt32 nDepth = 1 )" );
    3105           0 : }
    3106             : 
    3107         272 : void DocxAttributeOutput::StartStyles()
    3108             : {
    3109             :     m_pSerializer->startElementNS( XML_w, XML_styles,
    3110             :             FSNS( XML_xmlns, XML_w ),   "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
    3111             :             FSNS( XML_xmlns, XML_w14 ), "http://schemas.microsoft.com/office/word/2010/wordml",
    3112             :             FSNS( XML_xmlns, XML_mc ),  "http://schemas.openxmlformats.org/markup-compatibility/2006",
    3113             :             FSNS( XML_mc, XML_Ignorable ), "w14",
    3114         272 :             FSEND );
    3115             : 
    3116         272 :     DocDefaults();
    3117         272 :     LatentStyles();
    3118         272 : }
    3119             : 
    3120      149246 : sal_Int32 DocxStringGetToken(DocxStringTokenMap const * pMap, const OUString& rName)
    3121             : {
    3122      149246 :     OString sName = OUStringToOString(rName, RTL_TEXTENCODING_UTF8);
    3123      610093 :     while (pMap->pToken)
    3124             :     {
    3125      460616 :         if (sName == pMap->pToken)
    3126      149015 :             return pMap->nToken;
    3127      311601 :         ++pMap;
    3128             :     }
    3129         231 :     return 0;
    3130             : }
    3131             : 
    3132             : DocxStringTokenMap const aDefaultTokens[] = {
    3133             :     {"defQFormat", XML_defQFormat},
    3134             :     {"defUnhideWhenUsed", XML_defUnhideWhenUsed},
    3135             :     {"defSemiHidden", XML_defSemiHidden},
    3136             :     {"count", XML_count},
    3137             :     {"defUIPriority", XML_defUIPriority},
    3138             :     {"defLockedState", XML_defLockedState},
    3139             :     {0, 0}
    3140             : };
    3141             : 
    3142             : DocxStringTokenMap const aExceptionTokens[] = {
    3143             :     {"name", XML_name},
    3144             :     {"locked", XML_locked},
    3145             :     {"uiPriority", XML_uiPriority},
    3146             :     {"semiHidden", XML_semiHidden},
    3147             :     {"unhideWhenUsed", XML_unhideWhenUsed},
    3148             :     {"qFormat", XML_qFormat},
    3149             :     {0, 0}
    3150             : };
    3151             : 
    3152         272 : void DocxAttributeOutput::LatentStyles()
    3153             : {
    3154             :     // Do we have latent styles available?
    3155         272 :     uno::Reference<beans::XPropertySet> xPropertySet(m_rExport.pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW);
    3156         503 :     uno::Sequence<beans::PropertyValue> aInteropGrabBag;
    3157         272 :     xPropertySet->getPropertyValue("InteropGrabBag") >>= aInteropGrabBag;
    3158         503 :     uno::Sequence<beans::PropertyValue> aLatentStyles;
    3159        2816 :     for (sal_Int32 i = 0; i < aInteropGrabBag.getLength(); ++i)
    3160             :     {
    3161        2775 :         if (aInteropGrabBag[i].Name == "latentStyles")
    3162             :         {
    3163         231 :             aInteropGrabBag[i].Value >>= aLatentStyles;
    3164         231 :             break;
    3165             :         }
    3166             :     }
    3167         272 :     if (!aLatentStyles.getLength())
    3168         313 :         return;
    3169             : 
    3170             :     // Extract default attributes first.
    3171         231 :     sax_fastparser::FastAttributeList* pAttributeList = m_pSerializer->createAttrList();
    3172         462 :     uno::Sequence<beans::PropertyValue> aLsdExceptions;
    3173        1848 :     for (sal_Int32 i = 0; i < aLatentStyles.getLength(); ++i)
    3174             :     {
    3175        1617 :         if (sal_Int32 nToken = DocxStringGetToken(aDefaultTokens, aLatentStyles[i].Name))
    3176        1386 :             pAttributeList->add(FSNS(XML_w, nToken), OUStringToOString(aLatentStyles[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8));
    3177         231 :         else if (aLatentStyles[i].Name == "lsdExceptions")
    3178         231 :             aLatentStyles[i].Value >>= aLsdExceptions;
    3179             :     }
    3180             : 
    3181         462 :     XFastAttributeListRef xAttributeList(pAttributeList);
    3182         231 :     m_pSerializer->startElementNS(XML_w, XML_latentStyles, xAttributeList);
    3183         231 :     pAttributeList = 0;
    3184             : 
    3185             :     // Then handle the exceptions.
    3186       44397 :     for (sal_Int32 i = 0; i < aLsdExceptions.getLength(); ++i)
    3187             :     {
    3188       44166 :         pAttributeList = m_pSerializer->createAttrList();
    3189             : 
    3190       44166 :         uno::Sequence<beans::PropertyValue> aAttributes;
    3191       44166 :         aLsdExceptions[i].Value >>= aAttributes;
    3192      184934 :         for (sal_Int32 j = 0; j < aAttributes.getLength(); ++j)
    3193      140768 :             if (sal_Int32 nToken = DocxStringGetToken(aExceptionTokens, aAttributes[j].Name))
    3194      140768 :                 pAttributeList->add(FSNS(XML_w, nToken), OUStringToOString(aAttributes[j].Value.get<OUString>(), RTL_TEXTENCODING_UTF8));
    3195             : 
    3196       44166 :         xAttributeList = pAttributeList;
    3197       44166 :         m_pSerializer->singleElementNS(XML_w, XML_lsdException, xAttributeList);
    3198       44166 :         pAttributeList = 0;
    3199       44166 :     }
    3200             : 
    3201         462 :     m_pSerializer->endElementNS(XML_w, XML_latentStyles);
    3202             : }
    3203             : 
    3204             : /// Should the font size we have written out as a default one?
    3205         272 : bool lcl_isDefaultFontSize(const SvxFontHeightItem& rFontHeight, SwDoc* pDoc)
    3206             : {
    3207         272 :     bool bRet = rFontHeight.GetHeight() != 200; // see StyleSheetTable_Impl::StyleSheetTable_Impl() where we set this default
    3208             :     // Additionally, if the default para style has the same font size, then don't write it here.
    3209         272 :     SwTxtFmtColl* pDefaultStyle = pDoc->GetTxtCollFromPool(RES_POOLCOLL_STANDARD);
    3210         272 :     if (pDefaultStyle)
    3211             :     {
    3212         272 :         const SfxPoolItem* pItem = 0;
    3213         272 :         if (pDefaultStyle->GetAttrSet().HasItem(RES_CHRATR_FONTSIZE, &pItem))
    3214          62 :             return static_cast<const SvxFontHeightItem*>(pItem)->GetHeight() != rFontHeight.GetHeight();
    3215             :     }
    3216         210 :     return bRet;
    3217             : }
    3218             : 
    3219       17408 : void DocxAttributeOutput::OutputDefaultItem(const SfxPoolItem& rHt)
    3220             : {
    3221       17408 :     bool bMustWrite = true;
    3222       17408 :     switch (rHt.Which())
    3223             :     {
    3224             :         case RES_CHRATR_CASEMAP:
    3225         272 :             bMustWrite = static_cast< const SvxCaseMapItem& >(rHt).GetCaseMap() != SVX_CASEMAP_NOT_MAPPED;
    3226         272 :             break;
    3227             :         case RES_CHRATR_COLOR:
    3228         272 :             bMustWrite = static_cast< const SvxColorItem& >(rHt).GetValue().GetColor() != COL_AUTO;
    3229         272 :             break;
    3230             :         case RES_CHRATR_CONTOUR:
    3231         272 :             bMustWrite = static_cast< const SvxContourItem& >(rHt).GetValue();
    3232         272 :             break;
    3233             :         case RES_CHRATR_CROSSEDOUT:
    3234         272 :             bMustWrite = static_cast< const SvxCrossedOutItem& >(rHt).GetStrikeout() != STRIKEOUT_NONE;
    3235         272 :             break;
    3236             :         case RES_CHRATR_ESCAPEMENT:
    3237         272 :             bMustWrite = static_cast< const SvxEscapementItem& >(rHt).GetEscapement() != SVX_ESCAPEMENT_OFF;
    3238         272 :             break;
    3239             :         case RES_CHRATR_FONT:
    3240         272 :             bMustWrite = true;
    3241         272 :             break;
    3242             :         case RES_CHRATR_FONTSIZE:
    3243         272 :             bMustWrite = lcl_isDefaultFontSize(static_cast< const SvxFontHeightItem& >(rHt), m_rExport.pDoc);
    3244         272 :             break;
    3245             :         case RES_CHRATR_KERNING:
    3246         272 :             bMustWrite = static_cast< const SvxKerningItem& >(rHt).GetValue() != 0;
    3247         272 :             break;
    3248             :         case RES_CHRATR_LANGUAGE:
    3249         272 :             bMustWrite = true;
    3250         272 :             break;
    3251             :         case RES_CHRATR_POSTURE:
    3252         272 :             bMustWrite = static_cast< const SvxPostureItem& >(rHt).GetPosture() != ITALIC_NONE;
    3253         272 :             break;
    3254             :         case RES_CHRATR_SHADOWED:
    3255         272 :             bMustWrite = static_cast< const SvxShadowedItem& >(rHt).GetValue();
    3256         272 :             break;
    3257             :         case RES_CHRATR_UNDERLINE:
    3258         272 :             bMustWrite = static_cast< const SvxUnderlineItem& >(rHt).GetLineStyle() != UNDERLINE_NONE;
    3259         272 :             break;
    3260             :         case RES_CHRATR_WEIGHT:
    3261         272 :             bMustWrite = static_cast< const SvxWeightItem& >(rHt).GetWeight() != WEIGHT_NORMAL;
    3262         272 :             break;
    3263             :         case RES_CHRATR_AUTOKERN:
    3264         272 :             bMustWrite = static_cast< const SvxAutoKernItem& >(rHt).GetValue();
    3265         272 :             break;
    3266             :         case RES_CHRATR_BLINK:
    3267         272 :             bMustWrite = static_cast< const SvxBlinkItem& >(rHt).GetValue();
    3268         272 :             break;
    3269             :         case RES_CHRATR_BACKGROUND:
    3270             :             {
    3271         272 :                 const SvxBrushItem& rBrushItem = static_cast< const SvxBrushItem& >(rHt);
    3272        1360 :                 bMustWrite = (rBrushItem.GetColor() != COL_AUTO ||
    3273         816 :                               rBrushItem.GetShadingValue() != sal_uInt32(ShadingPattern::CLEAR) ||
    3274        2176 :                               rBrushItem.GetGraphic() != NULL ||
    3275         816 :                               rBrushItem.GetGraphicObject() != NULL);
    3276             :             }
    3277         272 :             break;
    3278             : 
    3279             :         case RES_CHRATR_CJK_FONT:
    3280         272 :             bMustWrite = true;
    3281         272 :             break;
    3282             :         case RES_CHRATR_CJK_FONTSIZE:
    3283         272 :             bMustWrite = false; // we have written it already as RES_CHRATR_FONTSIZE
    3284         272 :             break;
    3285             :         case RES_CHRATR_CJK_LANGUAGE:
    3286         272 :             bMustWrite = true;
    3287         272 :             break;
    3288             :         case RES_CHRATR_CJK_POSTURE:
    3289         272 :             bMustWrite = false; // we have written it already as RES_CHRATR_POSTURE
    3290         272 :             break;
    3291             :         case RES_CHRATR_CJK_WEIGHT:
    3292         272 :             bMustWrite = false; // we have written it already as RES_CHRATR_WEIGHT
    3293         272 :             break;
    3294             : 
    3295             :         case RES_CHRATR_CTL_FONT:
    3296         272 :             bMustWrite = true;
    3297         272 :             break;
    3298             :         case RES_CHRATR_CTL_FONTSIZE:
    3299         272 :             bMustWrite = static_cast< const SvxFontHeightItem& >(rHt).GetHeight() != 200; // see StyleSheetTable_Impl::StyleSheetTable_Impl() where we set this default
    3300         272 :             break;
    3301             :         case RES_CHRATR_CTL_LANGUAGE:
    3302         272 :             bMustWrite = true;
    3303         272 :             break;
    3304             :         case RES_CHRATR_CTL_POSTURE:
    3305         272 :             bMustWrite = static_cast< const SvxPostureItem& >(rHt).GetPosture() != ITALIC_NONE;
    3306         272 :             break;
    3307             :         case RES_CHRATR_CTL_WEIGHT:
    3308         272 :             bMustWrite = static_cast< const SvxWeightItem& >(rHt).GetWeight() != WEIGHT_NORMAL;
    3309         272 :             break;
    3310             : 
    3311             :         case RES_CHRATR_ROTATE:
    3312         272 :             bMustWrite = static_cast< const SvxCharRotateItem& >(rHt).GetValue() != 0;
    3313         272 :             break;
    3314             :         case RES_CHRATR_EMPHASIS_MARK:
    3315         272 :             bMustWrite = static_cast< const SvxEmphasisMarkItem& >(rHt).GetValue() != EMPHASISMARK_NONE;
    3316         272 :             break;
    3317             :         case RES_CHRATR_TWO_LINES:
    3318         272 :             bMustWrite = static_cast< const SvxTwoLinesItem& >(rHt).GetValue();
    3319         272 :             break;
    3320             :         case RES_CHRATR_SCALEW:
    3321         272 :             bMustWrite = static_cast< const SvxCharScaleWidthItem& >(rHt).GetValue() != 100;
    3322         272 :             break;
    3323             :         case RES_CHRATR_RELIEF:
    3324         272 :             bMustWrite = static_cast< const SvxCharReliefItem& >(rHt).GetValue() != RELIEF_NONE;
    3325         272 :             break;
    3326             :         case RES_CHRATR_HIDDEN:
    3327         272 :             bMustWrite = static_cast< const SvxCharHiddenItem& >(rHt).GetValue();
    3328         272 :             break;
    3329             :         case RES_CHRATR_BOX:
    3330             :             {
    3331         272 :                 const SvxBoxItem& rBoxItem = static_cast< const SvxBoxItem& >(rHt);
    3332         816 :                 bMustWrite = rBoxItem.GetTop() || rBoxItem.GetLeft() ||
    3333        1088 :                              rBoxItem.GetBottom() || rBoxItem.GetRight() ||
    3334         544 :                              rBoxItem.GetDistance();
    3335             :             }
    3336         272 :             break;
    3337             :         case RES_CHRATR_HIGHLIGHT:
    3338             :             {
    3339         272 :                 const SvxBrushItem& rBrushItem = static_cast< const SvxBrushItem& >(rHt);
    3340        1360 :                 bMustWrite = (rBrushItem.GetColor() != COL_AUTO ||
    3341         816 :                               rBrushItem.GetShadingValue() != sal_uInt32(ShadingPattern::CLEAR) ||
    3342        2176 :                               rBrushItem.GetGraphic() != NULL ||
    3343         816 :                               rBrushItem.GetGraphicObject() != NULL);
    3344             :             }
    3345         272 :             break;
    3346             : 
    3347             :         case RES_PARATR_LINESPACING:
    3348         272 :             bMustWrite = static_cast< const SvxLineSpacingItem& >(rHt).GetInterLineSpaceRule() != SVX_INTER_LINE_SPACE_OFF;
    3349         272 :             break;
    3350             :         case RES_PARATR_ADJUST:
    3351         272 :             bMustWrite = static_cast< const SvxAdjustItem& >(rHt).GetAdjust() != SVX_ADJUST_LEFT;
    3352         272 :             break;
    3353             :         case RES_PARATR_SPLIT:
    3354         272 :             bMustWrite = !static_cast< const SvxFmtSplitItem& >(rHt).GetValue();
    3355         272 :             break;
    3356             :         case RES_PARATR_WIDOWS:
    3357         272 :             bMustWrite = static_cast< const SvxWidowsItem& >(rHt).GetValue();
    3358         272 :             break;
    3359             :         case RES_PARATR_TABSTOP:
    3360         272 :             bMustWrite = static_cast< const SvxTabStopItem& >(rHt).Count() != 0;
    3361         272 :             break;
    3362             :         case RES_PARATR_HYPHENZONE:
    3363         272 :             bMustWrite = static_cast< const SvxHyphenZoneItem& >(rHt).IsHyphen();
    3364         272 :             break;
    3365             :         case RES_PARATR_NUMRULE:
    3366         272 :             bMustWrite = !static_cast< const SwNumRuleItem& >(rHt).GetValue().isEmpty();
    3367         272 :             break;
    3368             :         case RES_PARATR_SCRIPTSPACE:
    3369         272 :             bMustWrite = !static_cast< const SfxBoolItem& >(rHt).GetValue();
    3370         272 :             break;
    3371             :         case RES_PARATR_HANGINGPUNCTUATION:
    3372         272 :             bMustWrite = !static_cast< const SfxBoolItem& >(rHt).GetValue();
    3373         272 :             break;
    3374             :         case RES_PARATR_FORBIDDEN_RULES:
    3375         272 :             bMustWrite = !static_cast< const SfxBoolItem& >(rHt).GetValue();
    3376         272 :             break;
    3377             :         case RES_PARATR_VERTALIGN:
    3378         272 :             bMustWrite = static_cast< const SvxParaVertAlignItem& >(rHt).GetValue() != SvxParaVertAlignItem::AUTOMATIC;
    3379         272 :             break;
    3380             :         case RES_PARATR_SNAPTOGRID:
    3381         272 :             bMustWrite = !static_cast< const SvxParaGridItem& >(rHt).GetValue();
    3382         272 :             break;
    3383             :         case RES_CHRATR_GRABBAG:
    3384         272 :             bMustWrite = true;
    3385         272 :             break;
    3386             : 
    3387             :         default:
    3388             :             SAL_INFO("sw.ww8", "Unhandled SfxPoolItem with id " << rHt.Which() );
    3389        4624 :             break;
    3390             :     }
    3391             : 
    3392       17408 :     if (bMustWrite)
    3393        7714 :         OutputItem(rHt);
    3394       17408 : }
    3395             : 
    3396         272 : void DocxAttributeOutput::DocDefaults( )
    3397             : {
    3398             :     // Write the '<w:docDefaults>' section here
    3399         272 :     m_pSerializer->startElementNS(XML_w, XML_docDefaults, FSEND);
    3400             : 
    3401             :     // Output the default run properties
    3402         272 :     m_pSerializer->startElementNS(XML_w, XML_rPrDefault, FSEND);
    3403             : 
    3404         272 :     StartStyleProperties(false, 0);
    3405             : 
    3406       12512 :     for (int i = int(RES_CHRATR_BEGIN); i < int(RES_CHRATR_END); ++i)
    3407       12240 :         OutputDefaultItem(m_rExport.pDoc->GetDefault(i));
    3408             : 
    3409         272 :     EndStyleProperties(false);
    3410             : 
    3411         272 :     m_pSerializer->endElementNS(XML_w, XML_rPrDefault);
    3412             : 
    3413             :     // Output the default paragraph properties
    3414         272 :     m_pSerializer->startElementNS(XML_w, XML_pPrDefault, FSEND);
    3415             : 
    3416         272 :     StartStyleProperties(true, 0);
    3417             : 
    3418        5440 :     for (int i = int(RES_PARATR_BEGIN); i < int(RES_PARATR_END); ++i)
    3419        5168 :         OutputDefaultItem(m_rExport.pDoc->GetDefault(i));
    3420             : 
    3421         272 :     EndStyleProperties(true);
    3422             : 
    3423         272 :     m_pSerializer->endElementNS(XML_w, XML_pPrDefault);
    3424             : 
    3425         272 :     m_pSerializer->endElementNS(XML_w, XML_docDefaults);
    3426         272 : }
    3427             : 
    3428         272 : void DocxAttributeOutput::EndStyles( sal_uInt16 nNumberOfStyles )
    3429             : {
    3430             :     // HACK
    3431             :     // Ms Office seems to have an internal limitation of 4091 styles
    3432             :     // and refuses to load .docx with more, even though the spec seems to allow that;
    3433             :     // so simply if there are more styles, don't export those
    3434         272 :     sal_uInt16 nCountStylesToWrite = MSWORD_MAX_STYLES_LIMIT - nNumberOfStyles;
    3435         272 :     m_pTableStyleExport->TableStyles(nCountStylesToWrite);
    3436         272 :     m_pSerializer->endElementNS( XML_w, XML_styles );
    3437         272 : }
    3438             : 
    3439        3561 : void DocxAttributeOutput::DefaultStyle( sal_uInt16 nStyle )
    3440             : {
    3441             :     // are these the values of enum ww::sti (see ../inc/wwstyles.hxx)?
    3442             : #if OSL_DEBUG_LEVEL > 1
    3443             :     OSL_TRACE( "TODO DocxAttributeOutput::DefaultStyle( sal_uInt16 nStyle )- %d", nStyle );
    3444             : #else
    3445             :     (void) nStyle; // to quiet the warning
    3446             : #endif
    3447        3561 : }
    3448             : 
    3449             : /* Writes <a:srcRect> tag back to document.xml if a file conatins a cropped image.
    3450             : *  NOTE : Tested on images of type JPEG,EMF/WMF,BMP, PNG and GIF.
    3451             : */
    3452          45 : void DocxAttributeOutput::WriteSrcRect(const SdrObject* pSdrObj )
    3453             : {
    3454          45 :     uno::Reference< drawing::XShape > xShape( ((SdrObject*)pSdrObj)->getUnoShape(), uno::UNO_QUERY );
    3455          90 :     uno::Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
    3456             : 
    3457          90 :     OUString sUrl;
    3458          45 :     xPropSet->getPropertyValue("GraphicURL") >>= sUrl;
    3459          45 :     Size aOriginalSize( GraphicObject::CreateGraphicObjectFromURL( sUrl ).GetPrefSize() );
    3460             : 
    3461          45 :     ::com::sun::star::text::GraphicCrop aGraphicCropStruct;
    3462          45 :     xPropSet->getPropertyValue( "GraphicCrop" ) >>= aGraphicCropStruct;
    3463             : 
    3464          90 :     const MapMode aMap100mm( MAP_100TH_MM );
    3465          45 :     const MapMode& mapMode = GraphicObject::CreateGraphicObjectFromURL( sUrl ).GetPrefMapMode();
    3466          45 :     if( mapMode.GetMapUnit() == MAP_PIXEL )
    3467             :     {
    3468          25 :         aOriginalSize = Application::GetDefaultDevice()->PixelToLogic(aOriginalSize, aMap100mm );
    3469             :     }
    3470             : 
    3471          45 :     if ( (0 != aGraphicCropStruct.Left) || (0 != aGraphicCropStruct.Top) || (0 != aGraphicCropStruct.Right) || (0 != aGraphicCropStruct.Bottom) )
    3472             :     {
    3473           4 :         double  widthMultiplier  = 100000.0/aOriginalSize.Width();
    3474           4 :         double  heightMultiplier = 100000.0/aOriginalSize.Height();
    3475             : 
    3476           4 :         double left   = aGraphicCropStruct.Left * widthMultiplier;
    3477           4 :         double right  = aGraphicCropStruct.Right * widthMultiplier;
    3478           4 :         double top    = aGraphicCropStruct.Top * heightMultiplier;
    3479           4 :         double bottom = aGraphicCropStruct.Bottom * heightMultiplier;
    3480             : 
    3481             :         m_pSerializer->singleElementNS( XML_a, XML_srcRect,
    3482             :              XML_l, I32S(left),
    3483             :              XML_t, I32S(top),
    3484             :              XML_r, I32S(right),
    3485             :              XML_b, I32S(bottom),
    3486           4 :              FSEND );
    3487          45 :     }
    3488          45 : }
    3489             : 
    3490          48 : void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size& rSize, const SwFlyFrmFmt* pOLEFrmFmt, SwOLENode* pOLENode, const SdrObject* pSdrObj )
    3491             : {
    3492             :     OSL_TRACE( "TODO DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size& rSize, const SwFlyFrmFmt* pOLEFrmFmt, SwOLENode* pOLENode, const SdrObject* pSdrObj  ) - some stuff still missing" );
    3493             :     // detect mis-use of the API
    3494             :     assert(pGrfNode || (pOLEFrmFmt && pOLENode));
    3495          48 :     const SwFrmFmt* pFrmFmt = pGrfNode ? pGrfNode->GetFlyFmt() : pOLEFrmFmt;
    3496             :     // create the relation ID
    3497          48 :     OString aRelId;
    3498             :     sal_Int32 nImageType;
    3499          48 :     if ( pGrfNode && pGrfNode->IsLinkedFile() )
    3500             :     {
    3501             :         // linked image, just create the relation
    3502           0 :         OUString aFileName;
    3503           0 :         pGrfNode->GetFileFilterNms( &aFileName, 0 );
    3504             : 
    3505             :         // TODO Convert the file name to relative for better interoperability
    3506             : 
    3507           0 :         aRelId = m_rExport.AddRelation(
    3508             :                     "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
    3509           0 :                     aFileName );
    3510             : 
    3511           0 :         nImageType = XML_link;
    3512             :     }
    3513             :     else
    3514             :     {
    3515             :         // inline, we also have to write the image itself
    3516          48 :         const Graphic* pGraphic = 0;
    3517          48 :         if (pGrfNode)
    3518          47 :             pGraphic = &const_cast< Graphic& >( pGrfNode->GetGrf() );
    3519             :         else
    3520           1 :             pGraphic = pOLENode->GetGraphic();
    3521             : 
    3522          48 :         if (m_aRelIdCache.find(pGraphic) != m_aRelIdCache.end())
    3523             :             // We already have a RelId for this Graphic.
    3524           9 :             aRelId = m_aRelIdCache[pGraphic];
    3525             :         else
    3526             :         {
    3527             :             // Not in cache, then need to write it.
    3528          39 :             m_rDrawingML.SetFS( m_pSerializer ); // to be sure that we write to the right stream
    3529          39 :             OUString aImageId = m_rDrawingML.WriteImage( *pGraphic );
    3530             : 
    3531          39 :             aRelId = OUStringToOString( aImageId, RTL_TEXTENCODING_UTF8 );
    3532          39 :             m_aRelIdCache[pGraphic] = aRelId;
    3533             :         }
    3534             : 
    3535          48 :         nImageType = XML_embed;
    3536             :     }
    3537             : 
    3538          48 :     m_rExport.SdrExporter().startDMLAnchorInline(pFrmFmt, rSize);
    3539             : 
    3540             :     // picture description (used for pic:cNvPr later too)
    3541          48 :     ::sax_fastparser::FastAttributeList* docPrattrList = m_pSerializer->createAttrList();
    3542          48 :     docPrattrList->add( XML_id, OString::number( m_anchorId++).getStr());
    3543          48 :     docPrattrList->add( XML_name, "Picture" );
    3544          48 :     docPrattrList->add( XML_descr, OUStringToOString( pGrfNode ? pGrfNode->GetDescription() : pOLEFrmFmt->GetObjDescription(), RTL_TEXTENCODING_UTF8 ).getStr());
    3545          48 :     if( GetExport().GetFilter().getVersion( ) != oox::core::ECMA_DIALECT )
    3546          48 :         docPrattrList->add( XML_title, OUStringToOString( pGrfNode ? pGrfNode->GetTitle() : pOLEFrmFmt->GetObjTitle(), RTL_TEXTENCODING_UTF8 ).getStr());
    3547          96 :     XFastAttributeListRef docPrAttrListRef( docPrattrList );
    3548          48 :     m_pSerializer->startElementNS( XML_wp, XML_docPr, docPrAttrListRef );
    3549             :     // TODO hyperlink
    3550             :     // m_pSerializer->singleElementNS( XML_a, XML_hlinkClick,
    3551             :     //         FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
    3552             :     //         FSNS( XML_r, XML_id ), "rId4",
    3553             :     //         FSEND );
    3554          48 :     m_pSerializer->endElementNS( XML_wp, XML_docPr );
    3555             : 
    3556             :     m_pSerializer->startElementNS( XML_wp, XML_cNvGraphicFramePr,
    3557          48 :             FSEND );
    3558             :     // TODO change aspect?
    3559             :     m_pSerializer->singleElementNS( XML_a, XML_graphicFrameLocks,
    3560             :             FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
    3561             :             XML_noChangeAspect, "1",
    3562          48 :             FSEND );
    3563          48 :     m_pSerializer->endElementNS( XML_wp, XML_cNvGraphicFramePr );
    3564             : 
    3565             :     m_pSerializer->startElementNS( XML_a, XML_graphic,
    3566             :             FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
    3567          48 :             FSEND );
    3568             :     m_pSerializer->startElementNS( XML_a, XML_graphicData,
    3569             :             XML_uri, "http://schemas.openxmlformats.org/drawingml/2006/picture",
    3570          48 :             FSEND );
    3571             : 
    3572             :     m_pSerializer->startElementNS( XML_pic, XML_pic,
    3573             :             FSNS( XML_xmlns, XML_pic ), "http://schemas.openxmlformats.org/drawingml/2006/picture",
    3574          48 :             FSEND );
    3575             : 
    3576             :     m_pSerializer->startElementNS( XML_pic, XML_nvPicPr,
    3577          48 :             FSEND );
    3578             :     // It seems pic:cNvpr and wp:docPr are pretty much the same thing with the same attributes
    3579          48 :     m_pSerializer->startElementNS( XML_pic, XML_cNvPr, docPrAttrListRef );
    3580             : 
    3581             :     // TODO hyperlink
    3582             :     // m_pSerializer->singleElementNS( XML_a, XML_hlinkClick,
    3583             :     //     FSNS( XML_r, XML_id ), "rId4",
    3584             :     //     FSEND );
    3585          48 :     m_pSerializer->endElementNS( XML_pic, XML_cNvPr );
    3586             : 
    3587             :     m_pSerializer->startElementNS( XML_pic, XML_cNvPicPr,
    3588          48 :             FSEND );
    3589             :     // TODO change aspect?
    3590             :     m_pSerializer->singleElementNS( XML_a, XML_picLocks,
    3591             :             XML_noChangeAspect, "1", XML_noChangeArrowheads, "1",
    3592          48 :             FSEND );
    3593          48 :     m_pSerializer->endElementNS( XML_pic, XML_cNvPicPr );
    3594          48 :     m_pSerializer->endElementNS( XML_pic, XML_nvPicPr );
    3595             : 
    3596             :     // the actual picture
    3597             :     m_pSerializer->startElementNS( XML_pic, XML_blipFill,
    3598          48 :             FSEND );
    3599             : 
    3600             : /* At this point we are certain that, WriteImage returns empty RelId
    3601             :    for unhandled graphic type. Therefore we write the picture description
    3602             :    and not the relation( coz there ain't any), so that the user knows
    3603             :    there is a image/graphic in the doc but it is broken instead of
    3604             :    completely discarding it.
    3605             : */
    3606          48 :     if ( aRelId.isEmpty() )
    3607             :         m_pSerializer->singleElementNS( XML_a, XML_blip,
    3608           1 :             FSEND );
    3609             :     else
    3610             :         m_pSerializer->singleElementNS( XML_a, XML_blip,
    3611             :             FSNS( XML_r, nImageType ), aRelId.getStr(),
    3612          47 :             FSEND );
    3613             : 
    3614          48 :     if (pSdrObj){
    3615          45 :         WriteSrcRect(pSdrObj);
    3616             :     }
    3617             : 
    3618             :     m_pSerializer->startElementNS( XML_a, XML_stretch,
    3619          48 :             FSEND );
    3620             :     m_pSerializer->singleElementNS( XML_a, XML_fillRect,
    3621          48 :             FSEND );
    3622          48 :     m_pSerializer->endElementNS( XML_a, XML_stretch );
    3623          48 :     m_pSerializer->endElementNS( XML_pic, XML_blipFill );
    3624             : 
    3625             :     // TODO setup the right values below
    3626             :     m_pSerializer->startElementNS( XML_pic, XML_spPr,
    3627             :             XML_bwMode, "auto",
    3628          48 :             FSEND );
    3629             :     m_pSerializer->startElementNS( XML_a, XML_xfrm,
    3630          48 :             FSEND );
    3631             :     m_pSerializer->singleElementNS( XML_a, XML_off,
    3632             :             XML_x, "0", XML_y, "0",
    3633          48 :             FSEND );
    3634          96 :     OString aWidth( OString::number( TwipsToEMU( rSize.Width() ) ) );
    3635          96 :     OString aHeight( OString::number( TwipsToEMU( rSize.Height() ) ) );
    3636             :     m_pSerializer->singleElementNS( XML_a, XML_ext,
    3637             :             XML_cx, aWidth.getStr(),
    3638             :             XML_cy, aHeight.getStr(),
    3639          48 :             FSEND );
    3640          48 :     m_pSerializer->endElementNS( XML_a, XML_xfrm );
    3641             :     m_pSerializer->startElementNS( XML_a, XML_prstGeom,
    3642             :             XML_prst, "rect",
    3643          48 :             FSEND );
    3644             :     m_pSerializer->singleElementNS( XML_a, XML_avLst,
    3645          48 :             FSEND );
    3646          48 :     m_pSerializer->endElementNS( XML_a, XML_prstGeom );
    3647             :     m_pSerializer->singleElementNS( XML_a, XML_noFill,
    3648          48 :             FSEND );
    3649             :     m_pSerializer->startElementNS( XML_a, XML_ln,
    3650             :             XML_w, "9525",
    3651          48 :             FSEND );
    3652             :     m_pSerializer->singleElementNS( XML_a, XML_noFill,
    3653          48 :             FSEND );
    3654             :     m_pSerializer->singleElementNS( XML_a, XML_miter,
    3655             :             XML_lim, "800000",
    3656          48 :             FSEND );
    3657             :     m_pSerializer->singleElementNS( XML_a, XML_headEnd,
    3658          48 :             FSEND );
    3659             :     m_pSerializer->singleElementNS( XML_a, XML_tailEnd,
    3660          48 :             FSEND );
    3661          48 :     m_pSerializer->endElementNS( XML_a, XML_ln );
    3662             : 
    3663          48 :     m_rExport.SdrExporter().writeDMLEffectLst(*pFrmFmt);
    3664             : 
    3665          48 :     m_pSerializer->endElementNS( XML_pic, XML_spPr );
    3666             : 
    3667          48 :     m_pSerializer->endElementNS( XML_pic, XML_pic );
    3668             : 
    3669          48 :     m_pSerializer->endElementNS( XML_a, XML_graphicData );
    3670          48 :     m_pSerializer->endElementNS( XML_a, XML_graphic );
    3671          96 :     m_rExport.SdrExporter().endDMLAnchorInline(pFrmFmt);
    3672          48 : }
    3673             : 
    3674          96 : void DocxAttributeOutput::WriteOLE2Obj( const SdrObject* pSdrObj, SwOLENode& rOLENode, const Size& rSize, const SwFlyFrmFmt* pFlyFrmFmt )
    3675             : {
    3676          96 :     if( WriteOLEChart( pSdrObj, rSize ))
    3677          20 :         return;
    3678          76 :     if( WriteOLEMath( pSdrObj, rOLENode, rSize ))
    3679          69 :         return;
    3680           7 :     if( PostponeOLE( pSdrObj, rOLENode, rSize, pFlyFrmFmt ))
    3681           7 :         return;
    3682             :     // Then we fall back to just export the object as a graphic.
    3683           0 :     if( m_postponedGraphic == NULL )
    3684           0 :         FlyFrameGraphic( 0, rSize, pFlyFrmFmt, &rOLENode );
    3685             :     else
    3686             :         // w:drawing should not be inside w:rPr, so write it out later
    3687           0 :         m_postponedGraphic->push_back( PostponedGraphic( 0, rSize, pFlyFrmFmt, &rOLENode, 0 ) );
    3688             : }
    3689             : 
    3690          96 : bool DocxAttributeOutput::WriteOLEChart( const SdrObject* pSdrObj, const Size& rSize )
    3691             : {
    3692          96 :     uno::Reference< chart2::XChartDocument > xChartDoc;
    3693         192 :     uno::Reference< drawing::XShape > xShape( ((SdrObject*)pSdrObj)->getUnoShape(), uno::UNO_QUERY );
    3694          96 :     if( xShape.is() )
    3695             :     {
    3696          96 :         uno::Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
    3697          96 :         if( xPropSet.is() )
    3698          96 :             xChartDoc.set( xPropSet->getPropertyValue( "Model" ), uno::UNO_QUERY );
    3699             :     }
    3700             : 
    3701          96 :     if( xChartDoc.is() )
    3702             :     {
    3703          20 :         m_postponedChart = pSdrObj;
    3704          20 :         m_postponedChartSize = rSize;
    3705          20 :         return true;
    3706             :     }
    3707         172 :     return false;
    3708             : }
    3709             : 
    3710             : /*
    3711             :  * Write chart hierarchy in w:drawing after end element of w:rPr tag.
    3712             :  */
    3713        6494 : void DocxAttributeOutput::WritePostponedChart()
    3714             : {
    3715        6494 :        if(m_postponedChart == NULL)
    3716        6474 :                 return;
    3717          20 :        uno::Reference< chart2::XChartDocument > xChartDoc;
    3718          40 :        uno::Reference< drawing::XShape > xShape( ((SdrObject*)m_postponedChart)->getUnoShape(), uno::UNO_QUERY );
    3719          20 :        if( xShape.is() )
    3720             :        {
    3721          20 :             uno::Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
    3722          20 :             if( xPropSet.is() )
    3723          20 :                 xChartDoc.set( xPropSet->getPropertyValue( "Model" ), uno::UNO_QUERY );
    3724             :        }
    3725             : 
    3726          20 :        if( xChartDoc.is() )
    3727             :        {
    3728             :         OSL_TRACE("DocxAttributeOutput::WriteOLE2Obj: export chart ");
    3729             :         m_pSerializer->startElementNS( XML_w, XML_drawing,
    3730          20 :             FSEND );
    3731             :         m_pSerializer->startElementNS( XML_wp, XML_inline,
    3732             :             XML_distT, "0", XML_distB, "0", XML_distL, "0", XML_distR, "0",
    3733          20 :             FSEND );
    3734             : 
    3735          20 :         OString aWidth( OString::number( TwipsToEMU( m_postponedChartSize.Width() ) ) );
    3736          40 :         OString aHeight( OString::number( TwipsToEMU( m_postponedChartSize.Height() ) ) );
    3737             :         m_pSerializer->singleElementNS( XML_wp, XML_extent,
    3738             :             XML_cx, aWidth.getStr(),
    3739             :             XML_cy, aHeight.getStr(),
    3740          20 :             FSEND );
    3741             :         // TODO - the right effectExtent, extent including the effect
    3742             :         m_pSerializer->singleElementNS( XML_wp, XML_effectExtent,
    3743             :             XML_l, "0", XML_t, "0", XML_r, "0", XML_b, "0",
    3744          20 :             FSEND );
    3745             : 
    3746          40 :         OUString sName("Object 1");
    3747          40 :         uno::Reference< container::XNamed > xNamed( xShape, uno::UNO_QUERY );
    3748          20 :         if( xNamed.is() )
    3749          20 :             sName = xNamed->getName();
    3750             : 
    3751             :         /* If there is a scenario where a chart is followed by a shape
    3752             :            which is being exported as an alternate content then, the
    3753             :            docPr Id is being repeated, ECMA 20.4.2.5 says that the
    3754             :            docPr Id should be unique, ensuring the same here.
    3755             :         */
    3756             :         m_pSerializer->singleElementNS( XML_wp, XML_docPr,
    3757             :             XML_id, I32S( m_anchorId++ ),
    3758             :             XML_name, USS( sName ),
    3759          20 :             FSEND );
    3760             : 
    3761             :         m_pSerializer->singleElementNS( XML_wp, XML_cNvGraphicFramePr,
    3762          20 :             FSEND );
    3763             : 
    3764             :         m_pSerializer->startElementNS( XML_a, XML_graphic,
    3765             :             FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
    3766          20 :             FSEND );
    3767             : 
    3768             :         m_pSerializer->startElementNS( XML_a, XML_graphicData,
    3769             :             XML_uri, "http://schemas.openxmlformats.org/drawingml/2006/chart",
    3770          20 :             FSEND );
    3771             : 
    3772          40 :         OString aRelId;
    3773             :         static sal_Int32 nChartCount = 0;
    3774          20 :         nChartCount++;
    3775          40 :         uno::Reference< frame::XModel > xModel( xChartDoc, uno::UNO_QUERY );
    3776          20 :         aRelId = m_rExport.OutputChart( xModel, nChartCount, m_pSerializer );
    3777             : 
    3778             :         m_pSerializer->singleElementNS( XML_c, XML_chart,
    3779             :             FSNS( XML_xmlns, XML_c ), "http://schemas.openxmlformats.org/drawingml/2006/chart",
    3780             :             FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
    3781             :             FSNS( XML_r, XML_id ), aRelId.getStr(),
    3782          20 :             FSEND );
    3783             : 
    3784          20 :         m_pSerializer->endElementNS( XML_a, XML_graphicData );
    3785          20 :         m_pSerializer->endElementNS( XML_a, XML_graphic );
    3786          20 :         m_pSerializer->endElementNS( XML_wp, XML_inline );
    3787          40 :         m_pSerializer->endElementNS( XML_w, XML_drawing );
    3788             : 
    3789             :     }
    3790          20 :         m_postponedChart = NULL;
    3791          40 :     return;
    3792             : }
    3793             : 
    3794          76 : bool DocxAttributeOutput::WriteOLEMath( const SdrObject*, const SwOLENode& rOLENode, const Size& )
    3795             : {
    3796          76 :     uno::Reference < embed::XEmbeddedObject > xObj(const_cast<SwOLENode&>(rOLENode).GetOLEObj().GetOleRef());
    3797         152 :     SvGlobalName aObjName(xObj->getClassID());
    3798             : 
    3799          76 :     if( !SotExchange::IsMath(aObjName) )
    3800           7 :         return false;
    3801             :     assert( m_postponedMath == NULL ); // make it a list if there can be more inside one run
    3802          69 :     m_postponedMath = &rOLENode;
    3803         145 :     return true;
    3804             : }
    3805             : 
    3806        6494 : void DocxAttributeOutput::WritePostponedMath()
    3807             : {
    3808        6494 :     if( m_postponedMath == NULL )
    3809       12919 :         return;
    3810          69 :     uno::Reference < embed::XEmbeddedObject > xObj(const_cast<SwOLENode*>(m_postponedMath)->GetOLEObj().GetOleRef());
    3811         138 :     uno::Reference< uno::XInterface > xInterface( xObj->getComponent(), uno::UNO_QUERY );
    3812             : // gcc4.4 (and 4.3 and possibly older) have a problem with dynamic_cast directly to the target class,
    3813             : // so help it with an intermediate cast. I'm not sure what exactly the problem is, seems to be unrelated
    3814             : // to RTLD_GLOBAL, so most probably a gcc bug.
    3815          69 :     oox::FormulaExportBase* formulaexport = dynamic_cast<oox::FormulaExportBase*>(dynamic_cast<SfxBaseModel*>(xInterface.get()));
    3816             :     assert( formulaexport != NULL );
    3817          69 :     if (formulaexport)
    3818          69 :         formulaexport->writeFormulaOoxml( m_pSerializer, GetExport().GetFilter().getVersion());
    3819         138 :     m_postponedMath = NULL;
    3820             : }
    3821             : 
    3822           2 : void DocxAttributeOutput::WritePostponedFormControl(const SdrObject* pObject)
    3823             : {
    3824           2 :     if (pObject && pObject->GetObjInventor() == FmFormInventor)
    3825             :     {
    3826           2 :         if (SdrUnoObj *pFormObj = PTR_CAST(SdrUnoObj,pObject))
    3827             :         {
    3828           2 :             uno::Reference<awt::XControlModel> xControlModel = pFormObj->GetUnoControlModel();
    3829           4 :             uno::Reference<lang::XServiceInfo> xInfo(xControlModel, uno::UNO_QUERY);
    3830           2 :             if (xInfo->supportsService("com.sun.star.form.component.DateField"))
    3831             :             {
    3832             :                 // gather component properties
    3833             : 
    3834           1 :                 Date aOriginalDate(Date::EMPTY);
    3835           2 :                 OUString sOriginalContent, sDateFormat;
    3836           2 :                 OUString sLocale("en-US");
    3837           2 :                 uno::Sequence<beans::PropertyValue> aGrabBag;
    3838           2 :                 uno::Reference<beans::XPropertySet> xShapePropertySet(pFormObj->getUnoShape(), uno::UNO_QUERY);
    3839           1 :                 if (xShapePropertySet->getPropertyValue(UNO_NAME_MISC_OBJ_INTEROPGRABBAG) >>= aGrabBag)
    3840             :                 {
    3841           5 :                     for (sal_Int32 i=0; i < aGrabBag.getLength(); ++i)
    3842             :                     {
    3843           4 :                         if (aGrabBag[i].Name == "DateFormat")
    3844           1 :                             aGrabBag[i].Value >>= sDateFormat;
    3845           3 :                         else if (aGrabBag[i].Name == "Locale")
    3846           1 :                             aGrabBag[i].Value >>= sLocale;
    3847           2 :                         else if (aGrabBag[i].Name == "OriginalContent")
    3848           1 :                             aGrabBag[i].Value >>= sOriginalContent;
    3849           1 :                         else if (aGrabBag[i].Name == "OriginalDate")
    3850             :                         {
    3851           1 :                             css::util::Date aUNODate;
    3852           1 :                             aGrabBag[i].Value >>= aUNODate;
    3853           1 :                             aOriginalDate.SetDay(aUNODate.Day);
    3854           1 :                             aOriginalDate.SetMonth(aUNODate.Month);
    3855           1 :                             aOriginalDate.SetYear(aUNODate.Year);
    3856             :                         }
    3857             :                     }
    3858             :                 }
    3859           2 :                 uno::Reference<beans::XPropertySet> xPropertySet(xControlModel, uno::UNO_QUERY);
    3860             : 
    3861           2 :                 OString sDate;
    3862           2 :                 OUString aContentText;
    3863           1 :                 bool bHasDate = false;
    3864           1 :                 css::util::Date aUNODate;
    3865           1 :                 if (xPropertySet->getPropertyValue("Date") >>= aUNODate)
    3866             :                 {
    3867           1 :                     bHasDate = true;
    3868           1 :                     Date aDate(aUNODate.Day, aUNODate.Month, aUNODate.Year);
    3869           1 :                     sDate = DateToOString(aDate);
    3870             : 
    3871           1 :                     if (aOriginalDate == aDate)
    3872             :                     {
    3873           1 :                         aContentText = sOriginalContent;
    3874             :                         // sDateFormat was extracted from the grab bag
    3875             :                     }
    3876             :                     else
    3877             :                     {
    3878           0 :                         aContentText = OUString::createFromAscii(DateToDDMMYYYYOString(aDate).getStr());
    3879           0 :                         sDateFormat = "dd/MM/yyyy";
    3880             :                     }
    3881             :                 }
    3882             :                 else
    3883           0 :                     aContentText = xPropertySet->getPropertyValue("HelpText").get<OUString>();
    3884             : 
    3885             :                 // output component
    3886             : 
    3887           1 :                 m_pSerializer->startElementNS(XML_w, XML_sdt, FSEND);
    3888           1 :                 m_pSerializer->startElementNS(XML_w, XML_sdtPr, FSEND);
    3889             : 
    3890           1 :                 if (bHasDate)
    3891             :                     m_pSerializer->startElementNS(XML_w, XML_date,
    3892             :                                                   FSNS( XML_w, XML_fullDate ), sDate.getStr(),
    3893           1 :                                                   FSEND);
    3894             :                 else
    3895           0 :                     m_pSerializer->startElementNS(XML_w, XML_date, FSEND);
    3896             : 
    3897             :                 m_pSerializer->singleElementNS(XML_w, XML_dateFormat,
    3898             :                                                FSNS(XML_w, XML_val),
    3899             :                                                rtl::OUStringToOString( sDateFormat, RTL_TEXTENCODING_UTF8 ).getStr(),
    3900           1 :                                                FSEND);
    3901             :                 m_pSerializer->singleElementNS(XML_w, XML_lid,
    3902             :                                                FSNS(XML_w, XML_val),
    3903             :                                                rtl::OUStringToOString( sLocale, RTL_TEXTENCODING_UTF8 ).getStr(),
    3904           1 :                                                FSEND);
    3905             :                 m_pSerializer->singleElementNS(XML_w, XML_storeMappedDataAs,
    3906             :                                                FSNS(XML_w, XML_val), "dateTime",
    3907           1 :                                                FSEND);
    3908             :                 m_pSerializer->singleElementNS(XML_w, XML_calendar,
    3909             :                                                FSNS(XML_w, XML_val), "gregorian",
    3910           1 :                                                FSEND);
    3911             : 
    3912           1 :                 m_pSerializer->endElementNS(XML_w, XML_date);
    3913           1 :                 m_pSerializer->endElementNS(XML_w, XML_sdtPr);
    3914             : 
    3915           1 :                 m_pSerializer->startElementNS(XML_w, XML_sdtContent, FSEND);
    3916           1 :                 m_pSerializer->startElementNS(XML_w, XML_r, FSEND);
    3917           1 :                 RunText(aContentText);
    3918           1 :                 m_pSerializer->endElementNS(XML_w, XML_r);
    3919           1 :                 m_pSerializer->endElementNS(XML_w, XML_sdtContent);
    3920             : 
    3921           2 :                 m_pSerializer->endElementNS(XML_w, XML_sdt);
    3922             :             }
    3923           1 :             else if (xInfo->supportsService("com.sun.star.form.component.ComboBox"))
    3924             :             {
    3925             :                 // gather component properties
    3926             : 
    3927           1 :                 uno::Reference<beans::XPropertySet> xPropertySet(xControlModel, uno::UNO_QUERY);
    3928           2 :                 OUString sText = xPropertySet->getPropertyValue("Text").get<OUString>();
    3929           2 :                 uno::Sequence<OUString> aItems = xPropertySet->getPropertyValue("StringItemList").get< uno::Sequence<OUString> >();
    3930             : 
    3931             :                 // output component
    3932             : 
    3933           1 :                 m_pSerializer->startElementNS(XML_w, XML_sdt, FSEND);
    3934           1 :                 m_pSerializer->startElementNS(XML_w, XML_sdtPr, FSEND);
    3935             : 
    3936           1 :                 m_pSerializer->startElementNS(XML_w, XML_dropDownList, FSEND);
    3937             : 
    3938           3 :                 for (sal_Int32 i=0; i < aItems.getLength(); ++i)
    3939             :                 {
    3940             :                     m_pSerializer->singleElementNS(XML_w, XML_listItem,
    3941             :                                                    FSNS(XML_w, XML_displayText),
    3942           2 :                                                    rtl::OUStringToOString( aItems[i], RTL_TEXTENCODING_UTF8 ).getStr(),
    3943             :                                                    FSNS(XML_w, XML_value),
    3944           2 :                                                    rtl::OUStringToOString( aItems[i], RTL_TEXTENCODING_UTF8 ).getStr(),
    3945           4 :                                                    FSEND);
    3946             :                 }
    3947             : 
    3948           1 :                 m_pSerializer->endElementNS(XML_w, XML_dropDownList);
    3949           1 :                 m_pSerializer->endElementNS(XML_w, XML_sdtPr);
    3950             : 
    3951           1 :                 m_pSerializer->startElementNS(XML_w, XML_sdtContent, FSEND);
    3952           1 :                 m_pSerializer->startElementNS(XML_w, XML_r, FSEND);
    3953           1 :                 RunText(sText);
    3954           1 :                 m_pSerializer->endElementNS(XML_w, XML_r);
    3955           1 :                 m_pSerializer->endElementNS(XML_w, XML_sdtContent);
    3956             : 
    3957           2 :                 m_pSerializer->endElementNS(XML_w, XML_sdt);
    3958           2 :             }
    3959             :         }
    3960             :     }
    3961           2 : }
    3962             : 
    3963           7 : bool DocxAttributeOutput::PostponeOLE( const SdrObject*, SwOLENode& rNode, const Size& rSize, const SwFlyFrmFmt* pFlyFrmFmt )
    3964             : {
    3965           7 :     if( m_postponedOLE == NULL )
    3966             :         //cannot be postponed, try to write now
    3967           1 :         WriteOLE( rNode, rSize, pFlyFrmFmt );
    3968             :     else
    3969           6 :         m_postponedOLE->push_back( PostponedOLE( &rNode, rSize, pFlyFrmFmt ) );
    3970           7 :     return true;
    3971             : }
    3972             : 
    3973             : /*
    3974             :  * Write w:object hierarchy for embedded objects after end element of w:rPr tag.
    3975             :  */
    3976        6494 : void DocxAttributeOutput::WritePostponedOLE()
    3977             : {
    3978        6494 :     if( m_postponedOLE == NULL )
    3979        6494 :         return;
    3980             : 
    3981             :     SAL_INFO( "sw.ww8", OSL_THIS_FUNC );
    3982             : 
    3983       19500 :     for( std::list< PostponedOLE >::iterator it = m_postponedOLE->begin();
    3984       13000 :          it != m_postponedOLE->end();
    3985             :          ++it )
    3986             :     {
    3987           6 :         WriteOLE( *it->object, it->size, it->frame );
    3988             :     }
    3989             : 
    3990             :     // clear list of postponed objects
    3991        6494 :     delete m_postponedOLE;
    3992        6494 :     m_postponedOLE = NULL;
    3993             : }
    3994             : 
    3995           7 : void DocxAttributeOutput::WriteOLE( SwOLENode& rNode, const Size& rSize, const SwFlyFrmFmt* rFlyFrmFmt )
    3996             : {
    3997             :     // get interoperability information about embedded objects
    3998           7 :     uno::Reference< beans::XPropertySet > xPropSet( m_rExport.pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
    3999          13 :     OUString pName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
    4000          13 :     uno::Sequence< beans::PropertyValue > aGrabBag, aObjectsInteropList;
    4001           7 :     xPropSet->getPropertyValue( pName ) >>= aGrabBag;
    4002          13 :     for( sal_Int32 i=0; i < aGrabBag.getLength(); ++i )
    4003          12 :         if ( aGrabBag[i].Name == "EmbeddedObjects" )
    4004             :         {
    4005           6 :             aGrabBag[i].Value >>= aObjectsInteropList;
    4006           6 :             break;
    4007             :         }
    4008             : 
    4009           7 :     SwOLEObj& aObject = rNode.GetOLEObj();
    4010          13 :     uno::Reference < embed::XEmbeddedObject > xObj( aObject.GetOleRef() );
    4011           7 :     comphelper::EmbeddedObjectContainer* aContainer = aObject.GetObject().GetContainer();
    4012          13 :     OUString sObjectName = aContainer->GetEmbeddedObjectName( xObj );
    4013             : 
    4014             :     // set some attributes according to the type of the embedded object
    4015          13 :     OUString sProgID, sMediaType, sRelationType;
    4016          10 :     for( sal_Int32 i=0; i < aObjectsInteropList.getLength(); ++i )
    4017           8 :         if ( aObjectsInteropList[i].Name == sObjectName )
    4018             :         {
    4019           5 :             aObjectsInteropList[i].Value >>= sProgID;
    4020           5 :             break;
    4021             :         }
    4022           7 :     if( sProgID.startsWith("Excel.Sheet") )
    4023             :     {
    4024           2 :         sMediaType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
    4025           2 :         sRelationType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package";
    4026             :     }
    4027           5 :     else if( sProgID.startsWith("PowerPoint.Show") )
    4028             :     {
    4029           0 :         sMediaType = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
    4030           0 :         sRelationType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package";
    4031             :     }
    4032             :     else
    4033             :     {
    4034           5 :         sMediaType = "application/vnd.openxmlformats-officedocument.oleObject";
    4035           5 :         sRelationType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject";
    4036             :     }
    4037             : 
    4038             :     // write embedded file
    4039          13 :     OString sId = m_rExport.WriteOLEObject( aObject, sMediaType, sRelationType );
    4040             : 
    4041           7 :     if( sId.isEmpty() )
    4042             :     {
    4043             :         // the embedded file could not be saved
    4044             :         // fallback: save as an image
    4045           1 :         FlyFrameGraphic( 0, rSize, rFlyFrmFmt, &rNode );
    4046           8 :         return;
    4047             :     }
    4048             : 
    4049             :     // write preview image
    4050           6 :     const Graphic* pGraphic = rNode.GetGraphic();
    4051           6 :     m_rDrawingML.SetFS(m_pSerializer);
    4052          12 :     OUString sImageId = m_rDrawingML.WriteImage( *pGraphic );
    4053             : 
    4054           6 :     m_pSerializer->startElementNS( XML_w, XML_object, FSEND );
    4055             : 
    4056          12 :     OStringBuffer sShapeStyle, sShapeId;
    4057           6 :     sShapeStyle.append( "width:" ).append( double( rSize.Width() ) / 20 )
    4058          12 :                         .append( "pt;height:" ).append( double( rSize.Height() ) / 20 )
    4059           6 :                         .append( "pt" ); //from VMLExport::AddRectangleDimensions(), it does: value/20
    4060           6 :     sShapeId.append( "ole_" ).append( sId );
    4061             : 
    4062             :     // shape definition
    4063             :     m_pSerializer->startElementNS( XML_v, XML_shape,
    4064             :                                    XML_id, sShapeId.getStr(),
    4065             :                                    XML_style, sShapeStyle.getStr(),
    4066             :                                    FSNS( XML_o, XML_ole ), "", //compulsory, even if it's empty
    4067           6 :                                    FSEND );
    4068             : 
    4069             :     // shape filled with the preview image
    4070             :     m_pSerializer->singleElementNS( XML_v, XML_imagedata,
    4071             :                                     FSNS( XML_r, XML_id ), OUStringToOString( sImageId, RTL_TEXTENCODING_UTF8 ).getStr(),
    4072             :                                     FSNS( XML_o, XML_title ), "",
    4073           6 :                                     FSEND );
    4074             : 
    4075           6 :     m_pSerializer->endElementNS( XML_v, XML_shape );
    4076             : 
    4077             :     // OLE object definition
    4078             :     m_pSerializer->singleElementNS( XML_o, XML_OLEObject,
    4079             :                                     XML_Type, "Embed",
    4080          12 :                                     XML_ProgID, OUStringToOString( sProgID, RTL_TEXTENCODING_UTF8 ).getStr(),
    4081           6 :                                     XML_ShapeID, sShapeId.getStr(),
    4082             :                                     XML_DrawAspect, "Content",
    4083          12 :                                     XML_ObjectID, "_" + OString::number( rand() ),
    4084           6 :                                     FSNS( XML_r, XML_id ), sId.getStr(),
    4085          36 :                                     FSEND );
    4086             : 
    4087          12 :     m_pSerializer->endElementNS( XML_w, XML_object );
    4088             : }
    4089             : 
    4090             : /*
    4091             :  * Write w:pict hierarchy  end element of w:rPr tag.
    4092             :  */
    4093        6494 : void DocxAttributeOutput::WritePostponedVMLDrawing()
    4094             : {
    4095        6494 :     if(m_postponedVMLDrawing == NULL)
    4096        6494 :         return;
    4097             : 
    4098       19482 :     for( std::list< PostponedDrawing >::iterator it = m_postponedVMLDrawing->begin();
    4099       12988 :          it != m_postponedVMLDrawing->end();
    4100             :          ++it )
    4101             :     {
    4102           0 :         m_rExport.SdrExporter().writeVMLDrawing(it->object, *(it->frame), *(it->point));
    4103             :     }
    4104        6494 :     delete m_postponedVMLDrawing;
    4105        6494 :     m_postponedVMLDrawing = NULL;
    4106             : }
    4107             : 
    4108        6494 : void DocxAttributeOutput::WritePostponedDMLDrawing()
    4109             : {
    4110        6494 :     if(m_postponedDMLDrawing == NULL)
    4111        6494 :         return;
    4112             : 
    4113       19629 :     for( std::list< PostponedDrawing >::iterator it = m_postponedDMLDrawing->begin();
    4114       13086 :          it != m_postponedDMLDrawing->end();
    4115             :          ++it )
    4116             :     {
    4117          49 :         if ( IsAlternateContentChoiceOpen() )
    4118           1 :             m_rExport.SdrExporter().writeDMLDrawing(it->object, (it->frame), m_anchorId++);
    4119             :         else
    4120          48 :             m_rExport.SdrExporter().writeDMLAndVMLDrawing(it->object, *(it->frame), *(it->point), m_anchorId++);
    4121             :     }
    4122        6494 :     delete m_postponedDMLDrawing;
    4123        6494 :     m_postponedDMLDrawing = NULL;
    4124             : }
    4125             : 
    4126         430 : void DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame &rFrame, const Point& rNdTopLeft )
    4127             : {
    4128         430 :     m_pSerializer->mark();
    4129             : 
    4130         430 :     switch ( rFrame.GetWriterType() )
    4131             :     {
    4132             :         case sw::Frame::eGraphic:
    4133             :             {
    4134          47 :                 const SdrObject* pSdrObj = rFrame.GetFrmFmt().FindRealSdrObject();
    4135          47 :                 const SwNode *pNode = rFrame.GetContent();
    4136          47 :                 const SwGrfNode *pGrfNode = pNode ? pNode->GetGrfNode() : 0;
    4137          47 :                 if ( pGrfNode )
    4138             :                 {
    4139          47 :                     if( m_postponedGraphic == NULL )
    4140           2 :                         FlyFrameGraphic( pGrfNode, rFrame.GetLayoutSize(), 0, 0, pSdrObj);
    4141             :                     else // we are writing out attributes, but w:drawing should not be inside w:rPr,
    4142             :                     {    // so write it out later
    4143          45 :                         m_postponedGraphic->push_back( PostponedGraphic( pGrfNode, rFrame.GetLayoutSize(), 0, 0, pSdrObj));
    4144             :                     }
    4145             :                 }
    4146             :             }
    4147          47 :             break;
    4148             :         case sw::Frame::eDrawing:
    4149             :             {
    4150         167 :                 const SdrObject* pSdrObj = rFrame.GetFrmFmt().FindRealSdrObject();
    4151         167 :                 if ( pSdrObj )
    4152             :                 {
    4153         167 :                     if ( IsDiagram( pSdrObj ) )
    4154             :                     {
    4155           3 :                         if ( m_postponedDiagram == NULL )
    4156           1 :                             m_rExport.SdrExporter().writeDiagram( pSdrObj, rFrame.GetFrmFmt(), m_anchorId++);
    4157             :                         else // we are writing out attributes, but w:drawing should not be inside w:rPr,
    4158             :                         {    // so write it out later
    4159           2 :                             m_postponedDiagram->push_back( PostponedDiagram( pSdrObj, &(rFrame.GetFrmFmt()) ));
    4160             :                         }
    4161             :                     }
    4162             :                     else
    4163             :                     {
    4164         164 :                         if ( m_postponedDMLDrawing == NULL )
    4165             :                         {
    4166         115 :                             if ( IsAlternateContentChoiceOpen() )
    4167           1 :                                 m_rExport.SdrExporter().writeDMLDrawing( pSdrObj, &rFrame.GetFrmFmt(), m_anchorId++);
    4168             :                             else
    4169         114 :                                 m_rExport.SdrExporter().writeDMLAndVMLDrawing( pSdrObj, rFrame.GetFrmFmt(), rNdTopLeft, m_anchorId++);
    4170             :                         }
    4171             :                         else
    4172             :                             // we are writing out attributes, but w:drawing should not be inside w:rPr, so write it out later
    4173          49 :                             m_postponedDMLDrawing->push_back(PostponedDrawing(pSdrObj, &(rFrame.GetFrmFmt()), &rNdTopLeft));
    4174             :                     }
    4175             :                 }
    4176             :             }
    4177         167 :             break;
    4178             :         case sw::Frame::eTxtBox:
    4179             :             {
    4180             :                 // The frame output is postponed to the end of the anchor paragraph
    4181         117 :                 bool bDuplicate = false;
    4182         117 :                 const OUString& rName = rFrame.GetFrmFmt().GetName();
    4183         117 :                 unsigned nSize = m_aFramesOfParagraph.size();
    4184        1069 :                 for( unsigned nIndex = 0; nIndex < nSize; ++nIndex )
    4185             :                 {
    4186         952 :                     const OUString& rNameExisting = m_aFramesOfParagraph[nIndex].GetFrmFmt().GetName();
    4187             : 
    4188         952 :                     if (!rName.isEmpty() && !rNameExisting.isEmpty())
    4189             :                     {
    4190         948 :                         if (rName == rNameExisting)
    4191           2 :                             bDuplicate = true;
    4192             :                     }
    4193         952 :                 }
    4194             : 
    4195         117 :                 if( !bDuplicate )
    4196         115 :                     m_aFramesOfParagraph.push_back(sw::Frame(rFrame));
    4197             :             }
    4198         117 :             break;
    4199             :         case sw::Frame::eOle:
    4200             :             {
    4201          97 :                 const SwFrmFmt &rFrmFmt = rFrame.GetFrmFmt();
    4202          97 :                 const SdrObject *pSdrObj = rFrmFmt.FindRealSdrObject();
    4203          97 :                 if ( pSdrObj )
    4204             :                 {
    4205          96 :                     SwNodeIndex aIdx(*rFrmFmt.GetCntnt().GetCntntIdx(), 1);
    4206          96 :                     SwOLENode& rOLENd = *aIdx.GetNode().GetOLENode();
    4207          96 :                     WriteOLE2Obj( pSdrObj, rOLENd, rFrame.GetLayoutSize(), dynamic_cast<const SwFlyFrmFmt*>( &rFrmFmt ));
    4208             :                 }
    4209             :             }
    4210          97 :             break;
    4211             :         case sw::Frame::eFormControl:
    4212             :             {
    4213           2 :                 const SdrObject* pObject = rFrame.GetFrmFmt().FindRealSdrObject();
    4214           2 :                 m_aPostponedFormControls.push_back(pObject);
    4215             :             }
    4216           2 :             break;
    4217             :         default:
    4218             :             OSL_TRACE( "TODO DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame& rFrame, const Point& rNdTopLeft ) - frame type '%s'\n",
    4219             :                     rFrame.GetWriterType() == sw::Frame::eTxtBox? "eTxtBox":
    4220             :                     ( rFrame.GetWriterType() == sw::Frame::eOle? "eOle": "???" ) );
    4221           0 :             break;
    4222             :     }
    4223             : 
    4224         430 :     m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_POSTPONE );
    4225         430 : }
    4226             : 
    4227         167 : bool DocxAttributeOutput::IsDiagram( const SdrObject* sdrObject )
    4228             : {
    4229         167 :     uno::Reference< drawing::XShape > xShape( ((SdrObject*)sdrObject)->getUnoShape(), uno::UNO_QUERY );
    4230         167 :     if ( !xShape.is() )
    4231           0 :         return false;
    4232             : 
    4233         334 :     uno::Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
    4234         167 :     if ( !xPropSet.is() )
    4235           0 :         return false;
    4236             : 
    4237             :     // if the shape doesn't have the InteropGrabBag property, it's not a diagram
    4238         334 :     uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
    4239         334 :     OUString pName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
    4240         167 :     if ( !xPropSetInfo->hasPropertyByName( pName ) )
    4241           1 :         return false;
    4242             : 
    4243         332 :     uno::Sequence< beans::PropertyValue > propList;
    4244         166 :     xPropSet->getPropertyValue( pName ) >>= propList;
    4245         438 :     for ( sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp )
    4246             :     {
    4247             :         // if we find any of the diagram components, it's a diagram
    4248         275 :         OUString propName = propList[nProp].Name;
    4249        1100 :         if ( propName == "OOXData" || propName == "OOXLayout" || propName == "OOXStyle" ||
    4250         822 :              propName == "OOXColor" || propName == "OOXDrawing")
    4251           3 :             return true;
    4252         272 :     }
    4253         330 :     return false;
    4254             : }
    4255             : 
    4256         184 : void DocxAttributeOutput::WriteOutliner(const OutlinerParaObject& rParaObj)
    4257             : {
    4258         184 :     const EditTextObject& rEditObj = rParaObj.GetTextObject();
    4259         184 :     MSWord_SdrAttrIter aAttrIter( m_rExport, rEditObj, TXT_HFTXTBOX );
    4260             : 
    4261         184 :     sal_Int32 nPara = rEditObj.GetParagraphCount();
    4262             : 
    4263         184 :     m_pSerializer->startElementNS( XML_w, XML_txbxContent, FSEND );
    4264         383 :     for (sal_Int32 n = 0; n < nPara; ++n)
    4265             :     {
    4266         199 :         if( n )
    4267          15 :             aAttrIter.NextPara( n );
    4268             : 
    4269         199 :         OUString aStr( rEditObj.GetText( n ));
    4270         199 :         sal_Int32 nAktPos = 0;
    4271         199 :         sal_Int32 nEnd = aStr.getLength();
    4272             : 
    4273         199 :         StartParagraph(ww8::WW8TableNodeInfo::Pointer_t());
    4274             : 
    4275             :         // Write paragraph properties.
    4276         199 :         StartParagraphProperties();
    4277         199 :         aAttrIter.OutParaAttr(false);
    4278         199 :         EndParagraphProperties(0, 0, 0, 0);
    4279             : 
    4280         199 :         do {
    4281         199 :             const sal_Int32 nNextAttr = std::min(aAttrIter.WhereNext(), nEnd);
    4282             : 
    4283         199 :             m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
    4284             : 
    4285             :             // Write run properties.
    4286         199 :             m_pSerializer->startElementNS(XML_w, XML_rPr, FSEND);
    4287         199 :             aAttrIter.OutAttr(nAktPos);
    4288         199 :             WriteCollectedRunProperties();
    4289         199 :             m_pSerializer->endElementNS(XML_w, XML_rPr);
    4290             : 
    4291         199 :             bool bTxtAtr = aAttrIter.IsTxtAttr( nAktPos );
    4292         199 :             if( !bTxtAtr )
    4293             :             {
    4294         199 :                 OUString aOut( aStr.copy( nAktPos, nNextAttr - nAktPos ) );
    4295         199 :                 RunText(aOut);
    4296             :             }
    4297             : 
    4298         199 :             m_pSerializer->endElementNS( XML_w, XML_r );
    4299             : 
    4300         199 :             nAktPos = nNextAttr;
    4301         199 :             aAttrIter.NextPos();
    4302             :         }
    4303         199 :         while( nAktPos < nEnd );
    4304             :         // Word can't handle nested text boxes, so write them on the same level.
    4305         199 :         ++m_nTextFrameLevel;
    4306         199 :         EndParagraph(ww8::WW8TableNodeInfoInner::Pointer_t());
    4307         199 :         --m_nTextFrameLevel;
    4308         199 :     }
    4309         184 :     m_pSerializer->endElementNS( XML_w, XML_txbxContent );
    4310         184 : }
    4311             : 
    4312          24 : oox::drawingml::DrawingML& DocxAttributeOutput::GetDrawingML()
    4313             : {
    4314          24 :     return m_rDrawingML;
    4315             : }
    4316             : 
    4317        8980 : void DocxAttributeOutput::StartStyle( const OUString& rName, StyleType eType,
    4318             :         sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 /*nWwId*/, sal_uInt16 nId, bool bAutoUpdate )
    4319             : {
    4320        8980 :     bool bQFormat = false, bUnhideWhenUsed = false, bSemiHidden = false, bLocked = false, bDefault = false, bCustomStyle = false;
    4321       17960 :     OUString aLink, aRsid, aUiPriority;
    4322        8980 :     FastAttributeList* pStyleAttributeList = m_pSerializer->createAttrList();
    4323       17960 :     uno::Any aAny;
    4324        8980 :     if (eType == STYLE_TYPE_PARA || eType == STYLE_TYPE_CHAR)
    4325             :     {
    4326        4725 :         const SwFmt* pFmt = m_rExport.pStyles->GetSwFmt(nId);
    4327        4725 :         pFmt->GetGrabBagItem(aAny);
    4328             :     }
    4329             :     else
    4330             :     {
    4331        4255 :         const SwNumRule* pRule = m_rExport.pStyles->GetSwNumRule(nId);
    4332        4255 :         pRule->GetGrabBagItem(aAny);
    4333             :     }
    4334       17960 :     const uno::Sequence<beans::PropertyValue>& rGrabBag = aAny.get< uno::Sequence<beans::PropertyValue> >();
    4335             : 
    4336       39312 :     for (sal_Int32 i = 0; i < rGrabBag.getLength(); ++i)
    4337             :     {
    4338       30332 :         if (rGrabBag[i].Name == "uiPriority")
    4339        5702 :             aUiPriority = rGrabBag[i].Value.get<OUString>();
    4340       24630 :         else if (rGrabBag[i].Name == "qFormat")
    4341         712 :             bQFormat = true;
    4342       23918 :         else if (rGrabBag[i].Name == "link")
    4343        1250 :             aLink = rGrabBag[i].Value.get<OUString>();
    4344       22668 :         else if (rGrabBag[i].Name == "rsid")
    4345        6542 :             aRsid = rGrabBag[i].Value.get<OUString>();
    4346       16126 :         else if (rGrabBag[i].Name == "unhideWhenUsed")
    4347        4977 :             bUnhideWhenUsed = true;
    4348       11149 :         else if (rGrabBag[i].Name == "semiHidden")
    4349        4998 :             bSemiHidden = true;
    4350        6151 :         else if (rGrabBag[i].Name == "locked")
    4351         124 :             bLocked = true;
    4352        6027 :         else if (rGrabBag[i].Name == "default")
    4353         696 :             bDefault = rGrabBag[i].Value.get<sal_Bool>();
    4354        5331 :         else if (rGrabBag[i].Name == "customStyle")
    4355        5331 :             bCustomStyle = rGrabBag[i].Value.get<sal_Bool>();
    4356             :         else
    4357             :             SAL_WARN("sw.ww8", "Unhandled style property: " << rGrabBag[i].Name);
    4358             :     }
    4359             : 
    4360        8980 :     const char* pType = 0;
    4361        8980 :     switch (eType)
    4362             :     {
    4363        3368 :         case STYLE_TYPE_PARA: pType = "paragraph"; break;
    4364        1357 :         case STYLE_TYPE_CHAR: pType = "character"; break;
    4365        4255 :         case STYLE_TYPE_LIST: pType = "numbering"; break;
    4366             :     }
    4367        8980 :     pStyleAttributeList->add(FSNS( XML_w, XML_type ), pType);
    4368        8980 :     pStyleAttributeList->add(FSNS( XML_w, XML_styleId ), m_rExport.pStyles->GetStyleId(nId).getStr());
    4369        8980 :     if (bDefault)
    4370         696 :         pStyleAttributeList->add(FSNS(XML_w, XML_default), "1");
    4371        8980 :     if (bCustomStyle)
    4372        5331 :         pStyleAttributeList->add(FSNS(XML_w, XML_customStyle), "1");
    4373        8980 :     XFastAttributeListRef xStyleAttributeList(pStyleAttributeList);
    4374        8980 :     m_pSerializer->startElementNS( XML_w, XML_style, xStyleAttributeList);
    4375             : 
    4376             :     m_pSerializer->singleElementNS( XML_w, XML_name,
    4377             :             FSNS( XML_w, XML_val ), OUStringToOString( OUString( rName ), RTL_TEXTENCODING_UTF8 ).getStr(),
    4378        8980 :             FSEND );
    4379             : 
    4380        8980 :     if ( nBase != 0x0FFF && eType != STYLE_TYPE_LIST)
    4381             :     {
    4382             :         m_pSerializer->singleElementNS( XML_w, XML_basedOn,
    4383             :                 FSNS( XML_w, XML_val ), m_rExport.pStyles->GetStyleId(nBase).getStr(),
    4384        3776 :                 FSEND );
    4385             :     }
    4386             : 
    4387        8980 :     if ( nNext != nId && eType != STYLE_TYPE_LIST)
    4388             :     {
    4389             :         m_pSerializer->singleElementNS( XML_w, XML_next,
    4390             :                 FSNS( XML_w, XML_val ), m_rExport.pStyles->GetStyleId(nNext).getStr(),
    4391         882 :                 FSEND );
    4392             :     }
    4393             : 
    4394        8980 :     if (!aLink.isEmpty())
    4395             :         m_pSerializer->singleElementNS(XML_w, XML_link,
    4396             :                 FSNS(XML_w, XML_val), OUStringToOString(aLink, RTL_TEXTENCODING_UTF8).getStr(),
    4397        1250 :                 FSEND);
    4398             : 
    4399        8980 :     if ( bAutoUpdate )
    4400         204 :         m_pSerializer->singleElementNS( XML_w, XML_autoRedefine, FSEND );
    4401             : 
    4402        8980 :     if (!aUiPriority.isEmpty())
    4403             :         m_pSerializer->singleElementNS(XML_w, XML_uiPriority,
    4404             :                 FSNS(XML_w, XML_val), OUStringToOString(aUiPriority, RTL_TEXTENCODING_UTF8).getStr(),
    4405        5702 :                 FSEND);
    4406        8980 :     if (bSemiHidden)
    4407        4998 :         m_pSerializer->singleElementNS(XML_w, XML_semiHidden, FSEND);
    4408        8980 :     if (bUnhideWhenUsed)
    4409        4977 :         m_pSerializer->singleElementNS(XML_w, XML_unhideWhenUsed, FSEND);
    4410        8980 :     if (bQFormat)
    4411         712 :         m_pSerializer->singleElementNS(XML_w, XML_qFormat, FSEND);
    4412        8980 :     if (bLocked)
    4413         124 :         m_pSerializer->singleElementNS(XML_w, XML_locked, FSEND);
    4414        8980 :     if (!aRsid.isEmpty())
    4415             :         m_pSerializer->singleElementNS(XML_w, XML_rsid,
    4416             :                 FSNS(XML_w, XML_val), OUStringToOString(aRsid, RTL_TEXTENCODING_UTF8).getStr(),
    4417       15522 :                 FSEND);
    4418        8980 : }
    4419             : 
    4420        8980 : void DocxAttributeOutput::EndStyle()
    4421             : {
    4422        8980 :     m_pSerializer->endElementNS( XML_w, XML_style );
    4423        8980 : }
    4424             : 
    4425        8637 : void DocxAttributeOutput::StartStyleProperties( bool bParProp, sal_uInt16 /*nStyle*/ )
    4426             : {
    4427        8637 :     if ( bParProp )
    4428             :     {
    4429        3640 :         m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND );
    4430        3640 :         InitCollectedParagraphProperties();
    4431             :     }
    4432             :     else
    4433             :     {
    4434        4997 :         m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
    4435        4997 :         InitCollectedRunProperties();
    4436             :     }
    4437        8637 : }
    4438             : 
    4439        8637 : void DocxAttributeOutput::EndStyleProperties( bool bParProp )
    4440             : {
    4441        8637 :     if ( bParProp )
    4442             :     {
    4443        3640 :         WriteCollectedParagraphProperties();
    4444             : 
    4445             :         // Merge the marks for the ordered elements
    4446        3640 :         m_pSerializer->mergeTopMarks( );
    4447             : 
    4448        3640 :         m_pSerializer->endElementNS( XML_w, XML_pPr );
    4449             :     }
    4450             :     else
    4451             :     {
    4452        4997 :         WriteCollectedRunProperties();
    4453             : 
    4454             :         // Merge the marks for the ordered elements
    4455        4997 :         m_pSerializer->mergeTopMarks();
    4456             : 
    4457        4997 :         m_pSerializer->endElementNS( XML_w, XML_rPr );
    4458             :     }
    4459        8637 : }
    4460             : 
    4461         374 : void lcl_OutlineLevel(sax_fastparser::FSHelperPtr pSerializer, sal_uInt16 nLevel)
    4462             : {
    4463         374 :     if (nLevel >= WW8ListManager::nMaxLevel)
    4464           0 :         nLevel = WW8ListManager::nMaxLevel - 1;
    4465             : 
    4466             :     pSerializer->singleElementNS(XML_w, XML_outlineLvl,
    4467             :             FSNS(XML_w, XML_val), OString::number(nLevel).getStr(),
    4468         374 :             FSEND);
    4469         374 : }
    4470             : 
    4471          31 : void DocxAttributeOutput::OutlineNumbering( sal_uInt8 nLvl, const SwNumFmt& /*rNFmt*/, const SwFmt& /*rFmt*/ )
    4472             : {
    4473          31 :     lcl_OutlineLevel(m_pSerializer, nLvl);
    4474          31 : }
    4475             : 
    4476        2435 : void DocxAttributeOutput::ParaOutlineLevel(const SfxUInt16Item& rItem)
    4477             : {
    4478        2435 :     if (rItem.GetValue() > 0)
    4479         343 :         lcl_OutlineLevel(m_pSerializer, rItem.GetValue() - 1);
    4480        2435 : }
    4481             : 
    4482           4 : void DocxAttributeOutput::PageBreakBefore( bool bBreak )
    4483             : {
    4484           4 :     if ( bBreak )
    4485           4 :         m_pSerializer->singleElementNS( XML_w, XML_pageBreakBefore, FSEND );
    4486             :     else
    4487             :         m_pSerializer->singleElementNS( XML_w, XML_pageBreakBefore,
    4488             :                 FSNS( XML_w, XML_val ), "false",
    4489           0 :                 FSEND );
    4490           4 : }
    4491             : 
    4492         108 : void DocxAttributeOutput::SectionBreak( sal_uInt8 nC, const WW8_SepInfo* pSectionInfo )
    4493             : {
    4494         108 :     switch ( nC )
    4495             :     {
    4496             :         case msword::ColumnBreak:
    4497             :             // The column break should be output in the next paragraph...
    4498           2 :             m_nColBreakStatus = COLBRK_POSTPONE;
    4499           2 :             break;
    4500             :         case msword::PageBreak:
    4501         106 :             if ( pSectionInfo )
    4502             :             {
    4503             :                 // don't add section properties if this will be the first
    4504             :                 // paragraph in the document
    4505          34 :                 if ( !m_bParagraphOpened && !m_bIsFirstParagraph)
    4506             :                 {
    4507             :                     // Create a dummy paragraph if needed
    4508          13 :                     m_pSerializer->startElementNS( XML_w, XML_p, FSEND );
    4509          13 :                     m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND );
    4510             : 
    4511          13 :                     m_rExport.SectionProperties( *pSectionInfo );
    4512             : 
    4513          13 :                     m_pSerializer->endElementNS( XML_w, XML_pPr );
    4514          13 :                     m_pSerializer->endElementNS( XML_w, XML_p );
    4515             :                 }
    4516             :                 else
    4517             :                 {
    4518             :                     // postpone the output of this; it has to be done inside the
    4519             :                     // paragraph properties, so remember it until then
    4520          21 :                     m_pSectionInfo.reset( new WW8_SepInfo( *pSectionInfo ));
    4521             :                 }
    4522             :             }
    4523             :             else
    4524             :             {
    4525          72 :                 m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
    4526             :                 m_pSerializer->singleElementNS( XML_w, XML_br,
    4527          72 :                         FSNS( XML_w, XML_type ), "page", FSEND );
    4528          72 :                 m_pSerializer->endElementNS( XML_w, XML_r );
    4529             :             }
    4530         106 :             break;
    4531             :         default:
    4532             :             OSL_TRACE( "Unknown section break to write: %d", nC );
    4533           0 :             break;
    4534             :     }
    4535         108 : }
    4536             : 
    4537         298 : void DocxAttributeOutput::StartSection()
    4538             : {
    4539         298 :     m_pSerializer->startElementNS( XML_w, XML_sectPr, FSEND );
    4540         298 :     m_bOpenedSectPr = true;
    4541             : 
    4542             :     // Write the elements in the spec order
    4543             :     static const sal_Int32 aOrder[] =
    4544             :     {
    4545             :         FSNS( XML_w, XML_headerReference ),
    4546             :         FSNS( XML_w, XML_footerReference ),
    4547             :         FSNS( XML_w, XML_footnotePr ),
    4548             :         FSNS( XML_w, XML_endnotePr ),
    4549             :         FSNS( XML_w, XML_type ),
    4550             :         FSNS( XML_w, XML_pgSz ),
    4551             :         FSNS( XML_w, XML_pgMar ),
    4552             :         FSNS( XML_w, XML_paperSrc ),
    4553             :         FSNS( XML_w, XML_pgBorders ),
    4554             :         FSNS( XML_w, XML_lnNumType ),
    4555             :         FSNS( XML_w, XML_pgNumType ),
    4556             :         FSNS( XML_w, XML_cols ),
    4557             :         FSNS( XML_w, XML_formProt ),
    4558             :         FSNS( XML_w, XML_vAlign ),
    4559             :         FSNS( XML_w, XML_noEndnote ),
    4560             :         FSNS( XML_w, XML_titlePg ),
    4561             :         FSNS( XML_w, XML_textDirection ),
    4562             :         FSNS( XML_w, XML_bidi ),
    4563             :         FSNS( XML_w, XML_rtlGutter ),
    4564             :         FSNS( XML_w, XML_docGrid ),
    4565             :         FSNS( XML_w, XML_printerSettings ),
    4566             :         FSNS( XML_w, XML_sectPrChange )
    4567             :     };
    4568             : 
    4569             :     // postpone the output so that we can later [in EndParagraphProperties()]
    4570             :     // prepend the properties before the run
    4571         298 :     sal_Int32 len = sizeof ( aOrder ) / sizeof( sal_Int32 );
    4572         298 :     uno::Sequence< sal_Int32 > aSeqOrder( len );
    4573        6854 :     for ( sal_Int32 i = 0; i < len; i++ )
    4574        6556 :         aSeqOrder[i] = aOrder[i];
    4575             : 
    4576         298 :     m_pSerializer->mark( aSeqOrder );
    4577         298 : }
    4578             : 
    4579         298 : void DocxAttributeOutput::EndSection()
    4580             : {
    4581             :     // Write the section properties
    4582         298 :     if ( m_pSectionSpacingAttrList )
    4583             :     {
    4584         298 :         XFastAttributeListRef xAttrList( m_pSectionSpacingAttrList );
    4585         298 :         m_pSectionSpacingAttrList = NULL;
    4586             : 
    4587         298 :         m_pSerializer->singleElementNS( XML_w, XML_pgMar, xAttrList );
    4588             :     }
    4589             : 
    4590             :     // Order the elements
    4591         298 :     m_pSerializer->mergeTopMarks( );
    4592             : 
    4593         298 :     m_pSerializer->endElementNS( XML_w, XML_sectPr );
    4594         298 :     m_bOpenedSectPr = false;
    4595         298 : }
    4596             : 
    4597         298 : void DocxAttributeOutput::SectionFormProtection( bool bProtected )
    4598             : {
    4599         298 :     if ( bProtected )
    4600           0 :         m_pSerializer->singleElementNS( XML_w, XML_formProt, FSEND );
    4601             :     else
    4602             :         m_pSerializer->singleElementNS( XML_w, XML_formProt,
    4603         298 :                 FSNS( XML_w, XML_val ), "false", FSEND );
    4604         298 : }
    4605             : 
    4606           1 : void DocxAttributeOutput::SectionLineNumbering( sal_uLong nRestartNo, const SwLineNumberInfo& rLnNumInfo )
    4607             : {
    4608           1 :     FastAttributeList* pAttr = m_pSerializer->createAttrList();
    4609           1 :     pAttr->add( FSNS( XML_w, XML_countBy ), OString::number(rLnNumInfo.GetCountBy()).getStr());
    4610           1 :     pAttr->add( FSNS( XML_w, XML_restart ), rLnNumInfo.IsRestartEachPage() ? "newPage" : "continuous" );
    4611           1 :     if( rLnNumInfo.GetPosFromLeft())
    4612           0 :         pAttr->add( FSNS( XML_w, XML_distance ), OString::number(rLnNumInfo.GetPosFromLeft()).getStr());
    4613           1 :     if( nRestartNo )
    4614           1 :         pAttr->add( FSNS( XML_w, XML_start ), OString::number( nRestartNo).getStr());
    4615           1 :     XFastAttributeListRef xAttrs( pAttr );
    4616           1 :     m_pSerializer->singleElementNS( XML_w, XML_lnNumType, xAttrs );
    4617           1 : }
    4618             : 
    4619          28 : void DocxAttributeOutput::SectionTitlePage()
    4620             : {
    4621          28 :     m_pSerializer->singleElementNS( XML_w, XML_titlePg, FSEND );
    4622          28 : }
    4623             : 
    4624         283 : void DocxAttributeOutput::SectionPageBorders( const SwFrmFmt* pFmt, const SwFrmFmt* /*pFirstPageFmt*/ )
    4625             : {
    4626             :     // Output the margins
    4627             : 
    4628         283 :     const SvxBoxItem& rBox = pFmt->GetBox( );
    4629             : 
    4630         283 :     const SvxBorderLine* pLeft = rBox.GetLeft( );
    4631         283 :     const SvxBorderLine* pTop = rBox.GetTop( );
    4632         283 :     const SvxBorderLine* pRight = rBox.GetRight( );
    4633         283 :     const SvxBorderLine* pBottom = rBox.GetBottom( );
    4634             : 
    4635         283 :     if ( pBottom || pTop || pLeft || pRight )
    4636             :     {
    4637           4 :         bool bExportDistanceFromPageEdge = false;
    4638           4 :         if ( boxHasLineLargerThan31(rBox) == true )
    4639             :         {
    4640             :             // The distance is larger than '31'. This cannot be exported as 'distance from text'.
    4641             :             // Instead - it should be exported as 'distance from page edge'.
    4642             :             // This is based on http://wiki.openoffice.org/wiki/Writer/MSInteroperability/PageBorder
    4643             :             // Specifically 'export case #2'
    4644           4 :             bExportDistanceFromPageEdge = true;
    4645             :         }
    4646             : 
    4647             :         // All distances are relative to the text margins
    4648             :         m_pSerializer->startElementNS( XML_w, XML_pgBorders,
    4649             :                FSNS( XML_w, XML_display ), "allPages",
    4650             :                FSNS( XML_w, XML_offsetFrom ), bExportDistanceFromPageEdge ? "page" : "text",
    4651           4 :                FSEND );
    4652             : 
    4653           4 :         OutputBorderOptions aOutputBorderOptions = lcl_getBoxBorderOptions();
    4654             : 
    4655             :         // Check if the distance is larger than 31 points
    4656           4 :         aOutputBorderOptions.bCheckDistanceSize = true;
    4657             : 
    4658             :         // Check if there is a shadow item
    4659           4 :         const SfxPoolItem* pItem = GetExport().HasItem( RES_SHADOW );
    4660           4 :         if ( pItem )
    4661             :         {
    4662           2 :             const SvxShadowItem* pShadowItem = (const SvxShadowItem*)pItem;
    4663           2 :             aOutputBorderOptions.aShadowLocation = pShadowItem->GetLocation();
    4664             :         }
    4665             : 
    4666           4 :         std::map<sal_uInt16, css::table::BorderLine2> aEmptyMap; // empty styles map
    4667             :         impl_borders( m_pSerializer, rBox, aOutputBorderOptions, &m_pageMargins,
    4668           4 :                       aEmptyMap );
    4669             : 
    4670           4 :         m_pSerializer->endElementNS( XML_w, XML_pgBorders );
    4671             :     }
    4672         283 : }
    4673             : 
    4674          15 : void DocxAttributeOutput::SectionBiDi( bool bBiDi )
    4675             : {
    4676          15 :     if ( bBiDi )
    4677           0 :         m_pSerializer->singleElementNS( XML_w, XML_bidi, FSEND );
    4678          15 : }
    4679             : 
    4680        1372 : static OString impl_NumberingType( sal_uInt16 nNumberingType )
    4681             : {
    4682        1372 :     OString aType;
    4683             : 
    4684        1372 :     switch ( nNumberingType )
    4685             :     {
    4686             :         case SVX_NUM_CHARS_UPPER_LETTER:
    4687           3 :         case SVX_NUM_CHARS_UPPER_LETTER_N:  aType = "upperLetter"; break;
    4688             :         case SVX_NUM_CHARS_LOWER_LETTER:
    4689          58 :         case SVX_NUM_CHARS_LOWER_LETTER_N:  aType = "lowerLetter"; break;
    4690           2 :         case SVX_NUM_ROMAN_UPPER:           aType = "upperRoman";  break;
    4691          52 :         case SVX_NUM_ROMAN_LOWER:           aType = "lowerRoman";  break;
    4692             : 
    4693         733 :         case SVX_NUM_ARABIC:                aType = "decimal";     break;
    4694             : 
    4695             :         case SVX_NUM_BITMAP:
    4696         296 :         case SVX_NUM_CHAR_SPECIAL:          aType = "bullet";      break;
    4697           1 :         case style::NumberingType::CHARS_HEBREW: aType = "hebrew1"; break;
    4698             : 
    4699         227 :         default:                            aType = "none";        break;
    4700             :     }
    4701             : 
    4702        1372 :     return aType;
    4703             : }
    4704             : 
    4705         283 : void DocxAttributeOutput::SectionPageNumbering( sal_uInt16 nNumType, ::boost::optional<sal_uInt16> oPageRestartNumber )
    4706             : {
    4707             :     // FIXME Not called properly with page styles like "First Page"
    4708             : 
    4709         283 :     FastAttributeList* pAttr = m_pSerializer->createAttrList();
    4710             : 
    4711             :     // boost::none means no restart: then don't output that attribute if it is negative
    4712         283 :     if ( oPageRestartNumber )
    4713          19 :        pAttr->add( FSNS( XML_w, XML_start ), OString::number( oPageRestartNumber.get() ) );
    4714             : 
    4715             :     // nNumType corresponds to w:fmt. See WW8Export::GetNumId() for more precisions
    4716         283 :     OString aFmt( impl_NumberingType( nNumType ) );
    4717         283 :     if ( !aFmt.isEmpty() )
    4718         283 :         pAttr->add( FSNS( XML_w, XML_fmt ), aFmt.getStr() );
    4719             : 
    4720         566 :     XFastAttributeListRef xAttrs( pAttr );
    4721         283 :     m_pSerializer->singleElementNS( XML_w, XML_pgNumType, xAttrs );
    4722             : 
    4723             :     // see 2.6.12 pgNumType (Page Numbering Settings)
    4724         283 :     OSL_TRACE( "TODO DocxAttributeOutput::SectionPageNumbering()" );
    4725         283 : }
    4726             : 
    4727         298 : void DocxAttributeOutput::SectionType( sal_uInt8 nBreakCode )
    4728             : {
    4729             :     /*  break code:   0 No break, 1 New column
    4730             :         2 New page, 3 Even page, 4 Odd page
    4731             :         */
    4732         298 :     const char* pType = NULL;
    4733         298 :     switch ( nBreakCode )
    4734             :     {
    4735           0 :         case 1:  pType = "nextColumn"; break;
    4736         275 :         case 2:  pType = "nextPage";   break;
    4737           0 :         case 3:  pType = "evenPage";   break;
    4738           0 :         case 4:  pType = "oddPage";    break;
    4739          23 :         default: pType = "continuous"; break;
    4740             :     }
    4741             : 
    4742         298 :     if ( pType )
    4743             :         m_pSerializer->singleElementNS( XML_w, XML_type,
    4744             :                 FSNS( XML_w, XML_val ), pType,
    4745         298 :                 FSEND );
    4746         298 : }
    4747             : 
    4748        2026 : void DocxAttributeOutput::StartFont( const OUString& rFamilyName ) const
    4749             : {
    4750             :     m_pSerializer->startElementNS( XML_w, XML_font,
    4751             :             FSNS( XML_w, XML_name ), OUStringToOString( rFamilyName, RTL_TEXTENCODING_UTF8 ).getStr(),
    4752        2026 :             FSEND );
    4753        2026 : }
    4754             : 
    4755        2026 : void DocxAttributeOutput::EndFont() const
    4756             : {
    4757        2026 :     m_pSerializer->endElementNS( XML_w, XML_font );
    4758        2026 : }
    4759             : 
    4760         542 : void DocxAttributeOutput::FontAlternateName( const OUString& rName ) const
    4761             : {
    4762             :     m_pSerializer->singleElementNS( XML_w, XML_altName,
    4763             :             FSNS( XML_w, XML_val ), OUStringToOString( rName, RTL_TEXTENCODING_UTF8 ).getStr(),
    4764         542 :             FSEND );
    4765         542 : }
    4766             : 
    4767        2026 : void DocxAttributeOutput::FontCharset( sal_uInt8 nCharSet, rtl_TextEncoding nEncoding ) const
    4768             : {
    4769        2026 :     FastAttributeList* pAttr = m_pSerializer->createAttrList();
    4770             : 
    4771        2026 :     OString aCharSet( OString::number( nCharSet, 16 ) );
    4772        2026 :     if ( aCharSet.getLength() == 1 )
    4773        2026 :         aCharSet = OString( "0" ) + aCharSet;
    4774        2026 :     pAttr->add( FSNS( XML_w, XML_val ), aCharSet.getStr());
    4775             : 
    4776        2026 :     if( GetExport().GetFilter().getVersion( ) != oox::core::ECMA_DIALECT )
    4777             :     {
    4778        2026 :         if( const char* charset = rtl_getMimeCharsetFromTextEncoding( nEncoding ))
    4779        1698 :             pAttr->add( FSNS( XML_w, XML_characterSet ), charset );
    4780             :     }
    4781             : 
    4782        2026 :     m_pSerializer->singleElementNS( XML_w, XML_charset, XFastAttributeListRef( pAttr ));
    4783        2026 : }
    4784             : 
    4785        2026 : void DocxAttributeOutput::FontFamilyType( FontFamily eFamily ) const
    4786             : {
    4787        2026 :     const char *pFamily = NULL;
    4788        2026 :     switch ( eFamily )
    4789             :     {
    4790        1415 :         case FAMILY_ROMAN:      pFamily = "roman"; break;
    4791         552 :         case FAMILY_SWISS:      pFamily = "swiss"; break;
    4792          17 :         case FAMILY_MODERN:     pFamily = "modern"; break;
    4793           0 :         case FAMILY_SCRIPT:     pFamily = "script"; break;
    4794           0 :         case FAMILY_DECORATIVE: pFamily = "decorative"; break;
    4795          42 :         default:                pFamily = "auto"; break; // no font family
    4796             :     }
    4797             : 
    4798        2026 :     if ( pFamily )
    4799             :         m_pSerializer->singleElementNS( XML_w, XML_family,
    4800             :                 FSNS( XML_w, XML_val ), pFamily,
    4801        2026 :                 FSEND );
    4802        2026 : }
    4803             : 
    4804        2026 : void DocxAttributeOutput::FontPitchType( FontPitch ePitch ) const
    4805             : {
    4806        2026 :     const char *pPitch = NULL;
    4807        2026 :     switch ( ePitch )
    4808             :     {
    4809        1960 :         case PITCH_VARIABLE: pPitch = "variable"; break;
    4810          16 :         case PITCH_FIXED:    pPitch = "fixed"; break;
    4811          50 :         default:             pPitch = "default"; break; // no info about the pitch
    4812             :     }
    4813             : 
    4814        2026 :     if ( pPitch )
    4815             :         m_pSerializer->singleElementNS( XML_w, XML_pitch,
    4816             :                 FSNS( XML_w, XML_val ), pPitch,
    4817        2026 :                 FSEND );
    4818        2026 : }
    4819             : 
    4820        2026 : void DocxAttributeOutput::EmbedFont( const OUString& name, FontFamily family, FontPitch pitch, rtl_TextEncoding encoding )
    4821             : {
    4822        2026 :     if( !m_rExport.pDoc->get( IDocumentSettingAccess::EMBED_FONTS ))
    4823        4052 :         return; // no font embedding with this document
    4824           0 :     EmbedFontStyle( name, XML_embedRegular, family, ITALIC_NONE, WEIGHT_NORMAL, pitch, encoding );
    4825           0 :     EmbedFontStyle( name, XML_embedBold, family, ITALIC_NONE, WEIGHT_BOLD, pitch, encoding );
    4826           0 :     EmbedFontStyle( name, XML_embedItalic, family, ITALIC_NORMAL, WEIGHT_NORMAL, pitch, encoding );
    4827           0 :     EmbedFontStyle( name, XML_embedBoldItalic, family, ITALIC_NORMAL, WEIGHT_BOLD, pitch, encoding );
    4828             : }
    4829             : 
    4830           0 : static inline char toHexChar( int value )
    4831             : {
    4832           0 :     return value >= 10 ? value + 'A' - 10 : value + '0';
    4833             : }
    4834             : 
    4835           0 : void DocxAttributeOutput::EmbedFontStyle( const OUString& name, int tag, FontFamily family, FontItalic italic,
    4836             :     FontWeight weight, FontPitch pitch, rtl_TextEncoding encoding )
    4837             : {
    4838             :     // Embed font if at least viewing is allowed (in which case the opening app must check
    4839             :     // the font license rights too and open either read-only or not use the font for editing).
    4840             :     OUString fontUrl = EmbeddedFontsHelper::fontFileUrl( name, family, italic, weight, pitch, encoding,
    4841           0 :         EmbeddedFontsHelper::ViewingAllowed );
    4842           0 :     if( fontUrl.isEmpty())
    4843           0 :         return;
    4844             :     // TODO IDocumentSettingAccess::EMBED_SYSTEM_FONTS
    4845           0 :     if( !fontFilesMap.count( fontUrl ))
    4846             :     {
    4847           0 :         osl::File file( fontUrl );
    4848           0 :         if( file.open( osl_File_OpenFlag_Read ) != osl::File::E_None )
    4849           0 :             return;
    4850           0 :         uno::Reference< com::sun::star::io::XOutputStream > xOutStream = m_rExport.GetFilter().openFragmentStream(
    4851           0 :             OUString( "word/fonts/font" ) + OUString::number(m_nextFontId) + ".odttf",
    4852           0 :             "application/vnd.openxmlformats-officedocument.obfuscatedFont" );
    4853             :         // Not much point in trying hard with the obfuscation key, whoever reads the spec can read the font anyway,
    4854             :         // so just alter the first and last part of the key.
    4855           0 :         char fontKeyStr[] = "{00014A78-CABC-4EF0-12AC-5CD89AEFDE00}";
    4856             :         sal_uInt8 fontKey[ 16 ] = { 0, 0xDE, 0xEF, 0x9A, 0xD8, 0x5C, 0xAC, 0x12, 0xF0, 0x4E,
    4857           0 :             0xBC, 0xCA, 0x78, 0x4A, 0x01, 0 };
    4858           0 :         fontKey[ 0 ] = fontKey[ 15 ] = m_nextFontId % 256;
    4859           0 :         fontKeyStr[ 1 ] = fontKeyStr[ 35 ] = toHexChar(( m_nextFontId % 256 ) / 16 );
    4860           0 :         fontKeyStr[ 2 ] = fontKeyStr[ 36 ] = toHexChar(( m_nextFontId % 256 ) % 16 );
    4861             :         char buffer[ 4096 ];
    4862             :         sal_uInt64 readSize;
    4863           0 :         file.read( buffer, 32, readSize );
    4864           0 :         if( readSize < 32 )
    4865             :         {
    4866             :             SAL_WARN( "sw.ww8", "Font file size too small (" << fontUrl << ")" );
    4867           0 :             xOutStream->closeOutput();
    4868           0 :             return;
    4869             :         }
    4870           0 :         for( int i = 0;
    4871             :              i < 16;
    4872             :              ++i )
    4873             :         {
    4874           0 :             buffer[ i ] ^= fontKey[ i ];
    4875           0 :             buffer[ i + 16 ] ^= fontKey[ i ];
    4876             :         }
    4877           0 :         xOutStream->writeBytes( uno::Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( buffer ), 32 ));
    4878             :         for(;;)
    4879             :         {
    4880             :             sal_Bool eof;
    4881           0 :             if( file.isEndOfFile( &eof ) != osl::File::E_None )
    4882             :             {
    4883             :                 SAL_WARN( "sw.ww8", "Error reading font file " << fontUrl );
    4884           0 :                 xOutStream->closeOutput();
    4885           0 :                 return;
    4886             :             }
    4887           0 :             if( eof )
    4888           0 :                 break;
    4889           0 :             if( file.read( buffer, 4096, readSize ) != osl::File::E_None )
    4890             :             {
    4891             :                 SAL_WARN( "sw.ww8", "Error reading font file " << fontUrl );
    4892           0 :                 xOutStream->closeOutput();
    4893           0 :                 return;
    4894             :             }
    4895           0 :             if( readSize == 0 )
    4896           0 :                 break;
    4897           0 :             xOutStream->writeBytes( uno::Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( buffer ), readSize ));
    4898           0 :         }
    4899           0 :         xOutStream->closeOutput();
    4900           0 :         OString relId = OUStringToOString( GetExport().GetFilter().addRelation( m_pSerializer->getOutputStream(),
    4901             :             "http://schemas.openxmlformats.org/officeDocument/2006/relationships/font",
    4902           0 :             OUString( "fonts/font" ) + OUString::number( m_nextFontId ) + ".odttf" ), RTL_TEXTENCODING_UTF8 );
    4903           0 :         EmbeddedFontRef ref;
    4904           0 :         ref.relId = relId;
    4905           0 :         ref.fontKey = fontKeyStr;
    4906           0 :         fontFilesMap[ fontUrl ] = ref;
    4907           0 :         ++m_nextFontId;
    4908             :     }
    4909             :     m_pSerializer->singleElementNS( XML_w, tag,
    4910           0 :         FSNS( XML_r, XML_id ), fontFilesMap[ fontUrl ].relId,
    4911           0 :         FSNS( XML_w, XML_fontKey ), fontFilesMap[ fontUrl ].fontKey,
    4912           0 :         FSEND );
    4913             : }
    4914             : 
    4915          31 : OString DocxAttributeOutput::TransHighlightColor( const Color& rColor )
    4916             : {
    4917          31 :     switch (rColor.GetColor())
    4918             :     {
    4919           3 :         case 0x000000: return OString("black"); break;
    4920           1 :         case 0x0000ff: return OString("blue"); break;
    4921           1 :         case 0x00ffff: return OString("cyan"); break;
    4922           1 :         case 0x00ff00: return OString("green"); break;
    4923           1 :         case 0xff00ff: return OString("magenta"); break;
    4924           1 :         case 0xff0000: return OString("red"); break;
    4925          13 :         case 0xffff00: return OString("yellow"); break;
    4926           1 :         case 0xffffff: return OString("white"); break;
    4927           1 :         case 0x000080: return OString("darkBlue"); break;
    4928           1 :         case 0x008080: return OString("darkCyan"); break;
    4929           1 :         case 0x008000: return OString("darkGreen"); break;
    4930           1 :         case 0x800080: return OString("darkMagenta"); break;
    4931           1 :         case 0x800000: return OString("darkRed"); break;
    4932           1 :         case 0x808000: return OString("darkYellow"); break;
    4933           1 :         case 0x808080: return OString("darkGray"); break;
    4934           2 :         case 0xC0C0C0: return OString("lightGray"); break;
    4935           0 :         default: return OString(); break;
    4936             :     }
    4937             : }
    4938             : 
    4939         121 : void DocxAttributeOutput::NumberingDefinition( sal_uInt16 nId, const SwNumRule &rRule )
    4940             : {
    4941             :     // nId is the same both for abstract numbering definition as well as the
    4942             :     // numbering definition itself
    4943             :     // TODO check that this is actually true & fix if not ;-)
    4944         121 :     OString aId( OString::number( nId ) );
    4945             : 
    4946             :     m_pSerializer->startElementNS( XML_w, XML_num,
    4947             :             FSNS( XML_w, XML_numId ), aId.getStr(),
    4948         121 :             FSEND );
    4949             : 
    4950             :     m_pSerializer->singleElementNS( XML_w, XML_abstractNumId,
    4951             :             FSNS( XML_w, XML_val ), aId.getStr(),
    4952         121 :             FSEND );
    4953             : 
    4954             : #if OSL_DEBUG_LEVEL > 1
    4955             :     // TODO ww8 version writes this, anything to do about it here?
    4956             :     if ( rRule.IsContinusNum() )
    4957             :         OSL_TRACE( "TODO DocxAttributeOutput::NumberingDefinition()" );
    4958             : #else
    4959             :     (void) rRule; // to quiet the warning...
    4960             : #endif
    4961             : 
    4962         121 :     m_pSerializer->endElementNS( XML_w, XML_num );
    4963         121 : }
    4964             : 
    4965         121 : void DocxAttributeOutput::StartAbstractNumbering( sal_uInt16 nId )
    4966             : {
    4967             :     m_pSerializer->startElementNS( XML_w, XML_abstractNum,
    4968             :             FSNS( XML_w, XML_abstractNumId ), OString::number( nId ).getStr(),
    4969         121 :             FSEND );
    4970         121 : }
    4971             : 
    4972         121 : void DocxAttributeOutput::EndAbstractNumbering()
    4973             : {
    4974         121 :     m_pSerializer->endElementNS( XML_w, XML_abstractNum );
    4975         121 : }
    4976             : 
    4977        1089 : void DocxAttributeOutput::NumberingLevel( sal_uInt8 nLevel,
    4978             :         sal_uInt16 nStart,
    4979             :         sal_uInt16 nNumberingType,
    4980             :         SvxAdjust eAdjust,
    4981             :         const sal_uInt8 * /*pNumLvlPos*/,
    4982             :         sal_uInt8 nFollow,
    4983             :         const wwFont *pFont,
    4984             :         const SfxItemSet *pOutSet,
    4985             :         sal_Int16 nIndentAt,
    4986             :         sal_Int16 nFirstLineIndex,
    4987             :         sal_Int16 nListTabPos,
    4988             :         const OUString &rNumberingString,
    4989             :         const SvxBrushItem* pBrush)
    4990             : {
    4991             :     m_pSerializer->startElementNS( XML_w, XML_lvl,
    4992             :             FSNS( XML_w, XML_ilvl ), OString::number( nLevel ).getStr(),
    4993        1089 :             FSEND );
    4994             : 
    4995             :     // start with the nStart value. Do not write w:start if Numbered Lists
    4996             :     // starts from zero.As it's an optional parameter.
    4997             :     // refer ECMA 376 Second edition Part-1
    4998        1089 :     if(!(0 == nLevel && 0 == nStart))
    4999             :     {
    5000             :         m_pSerializer->singleElementNS( XML_w, XML_start,
    5001             :                 FSNS( XML_w, XML_val ), OString::number( nStart ).getStr(),
    5002        1089 :                 FSEND );
    5003             :     }
    5004             : 
    5005             :     // format
    5006        1089 :     OString aFmt( impl_NumberingType( nNumberingType ) );
    5007             : 
    5008        1089 :     if ( !aFmt.isEmpty() )
    5009             :         m_pSerializer->singleElementNS( XML_w, XML_numFmt,
    5010             :                 FSNS( XML_w, XML_val ), aFmt.getStr(),
    5011        1089 :                 FSEND );
    5012             : 
    5013             :     // suffix
    5014        1089 :     const char *pSuffix = NULL;
    5015        1089 :     switch ( nFollow )
    5016             :     {
    5017           0 :         case 1:  pSuffix = "space";   break;
    5018         227 :         case 2:  pSuffix = "nothing"; break;
    5019         862 :         default: /*pSuffix = "tab";*/ break;
    5020             :     }
    5021        1089 :     if ( pSuffix )
    5022             :         m_pSerializer->singleElementNS( XML_w, XML_suff,
    5023             :                 FSNS( XML_w, XML_val ), pSuffix,
    5024         227 :                 FSEND );
    5025             : 
    5026             :     // text
    5027        1089 :     OUString aText( rNumberingString );
    5028        2178 :     OUStringBuffer aBuffer( aText.getLength() + WW8ListManager::nMaxLevel );
    5029             : 
    5030        1089 :     const sal_Unicode *pPrev = aText.getStr();
    5031        1089 :     const sal_Unicode *pIt = aText.getStr();
    5032        4318 :     while ( pIt < aText.getStr() + aText.getLength() )
    5033             :     {
    5034             :         // convert the level values to %NUMBER form
    5035             :         // (we don't use pNumLvlPos at all)
    5036             :         // FIXME so far we support the ww8 limit of levels only
    5037        2140 :         if ( *pIt < sal_Unicode( WW8ListManager::nMaxLevel ) )
    5038             :         {
    5039         972 :             aBuffer.append( pPrev, pIt - pPrev );
    5040         972 :             aBuffer.append( '%' );
    5041         972 :             aBuffer.append( OUString::number( sal_Int32( *pIt ) + 1 ) );
    5042             : 
    5043         972 :             pPrev = pIt + 1;
    5044             :         }
    5045        2140 :         ++pIt;
    5046             :     }
    5047        1089 :     if ( pPrev < pIt )
    5048         741 :         aBuffer.append( pPrev, pIt - pPrev );
    5049             : 
    5050             :     // If bullet char is empty, set lvlText as empty
    5051        1089 :     if ( aText.equals ( OUString(sal_Unicode(0)) ) && nNumberingType == SVX_NUM_CHAR_SPECIAL )
    5052             :     {
    5053           1 :         m_pSerializer->singleElementNS( XML_w, XML_lvlText, FSNS( XML_w, XML_val ), "", FSEND );
    5054             :     }
    5055             :     else
    5056             :     {
    5057        1088 :         m_pSerializer->singleElementNS( XML_w, XML_lvlText,FSNS( XML_w, XML_val ), OUStringToOString( aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ).getStr(), FSEND );
    5058             :     }
    5059             : 
    5060             :     // bullet
    5061        1089 :     if (nNumberingType == SVX_NUM_BITMAP && pBrush)
    5062             :     {
    5063           3 :         int nIndex = m_rExport.GetGrfIndex(*pBrush);
    5064           3 :         if (nIndex != -1)
    5065             :         {
    5066             :             m_pSerializer->singleElementNS(XML_w, XML_lvlPicBulletId,
    5067             :                     FSNS(XML_w, XML_val), OString::number(nIndex).getStr(),
    5068           2 :                     FSEND);
    5069             :         }
    5070             :     }
    5071             : 
    5072             :     // justification
    5073             :     const char *pJc;
    5074        1089 :     bool ecmaDialect = ( m_rExport.GetFilter().getVersion() == oox::core::ECMA_DIALECT );
    5075        1089 :     switch ( eAdjust )
    5076             :     {
    5077           0 :         case SVX_ADJUST_CENTER: pJc = "center"; break;
    5078          46 :         case SVX_ADJUST_RIGHT:  pJc = !ecmaDialect ? "end" : "right";  break;
    5079        1043 :         default:                pJc = !ecmaDialect ? "start" : "left";   break;
    5080             :     }
    5081             :     m_pSerializer->singleElementNS( XML_w, XML_lvlJc,
    5082             :             FSNS( XML_w, XML_val ), pJc,
    5083        1089 :             FSEND );
    5084             : 
    5085             :     // indentation
    5086        1089 :     m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND );
    5087        1089 :     if( nListTabPos != 0 )
    5088             :     {
    5089         658 :         m_pSerializer->startElementNS( XML_w, XML_tabs, FSEND );
    5090             :         m_pSerializer->singleElementNS( XML_w, XML_tab,
    5091             :                 FSNS( XML_w, XML_val ), "num",
    5092             :                 FSNS( XML_w, XML_pos ), OString::number( nListTabPos ).getStr(),
    5093         658 :                 FSEND );
    5094         658 :         m_pSerializer->endElementNS( XML_w, XML_tabs );
    5095             :     }
    5096             : 
    5097        1089 :     sal_Int32 nToken = ecmaDialect ? XML_left : XML_start;
    5098             :     m_pSerializer->singleElementNS( XML_w, XML_ind,
    5099             :             FSNS( XML_w, nToken ), OString::number( nIndentAt ).getStr(),
    5100             :             FSNS( XML_w, XML_hanging ), OString::number( -nFirstLineIndex ).getStr(),
    5101        1089 :             FSEND );
    5102        1089 :     m_pSerializer->endElementNS( XML_w, XML_pPr );
    5103             : 
    5104             :     // font
    5105        1089 :     if ( pOutSet )
    5106             :     {
    5107         335 :         m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
    5108             : 
    5109         335 :         if ( pFont )
    5110             :         {
    5111         296 :             GetExport().GetId( *pFont ); // ensure font info is written to fontTable.xml
    5112         296 :             OString aFamilyName( OUStringToOString( OUString( pFont->GetFamilyName() ), RTL_TEXTENCODING_UTF8 ) );
    5113             :             m_pSerializer->singleElementNS( XML_w, XML_rFonts,
    5114             :                     FSNS( XML_w, XML_ascii ), aFamilyName.getStr(),
    5115             :                     FSNS( XML_w, XML_hAnsi ), aFamilyName.getStr(),
    5116             :                     FSNS( XML_w, XML_cs ), aFamilyName.getStr(),
    5117             :                     FSNS( XML_w, XML_hint ), "default",
    5118         296 :                     FSEND );
    5119             :         }
    5120         335 :         m_rExport.OutputItemSet( *pOutSet, false, true, i18n::ScriptType::LATIN, m_rExport.mbExportModeRTF );
    5121             : 
    5122         335 :         m_pSerializer->endElementNS( XML_w, XML_rPr );
    5123             :     }
    5124             : 
    5125             :     // TODO anything to do about nListTabPos?
    5126             : 
    5127        2178 :     m_pSerializer->endElementNS( XML_w, XML_lvl );
    5128        1089 : }
    5129             : 
    5130          86 : void DocxAttributeOutput::CharCaseMap( const SvxCaseMapItem& rCaseMap )
    5131             : {
    5132          86 :     switch ( rCaseMap.GetValue() )
    5133             :     {
    5134             :         case SVX_CASEMAP_KAPITAELCHEN:
    5135          16 :             m_pSerializer->singleElementNS( XML_w, XML_smallCaps, FSEND );
    5136          16 :             break;
    5137             :         case SVX_CASEMAP_VERSALIEN:
    5138          45 :             m_pSerializer->singleElementNS( XML_w, XML_caps, FSEND );
    5139          45 :             break;
    5140             :         default: // Something that ooxml does not support
    5141          25 :             m_pSerializer->singleElementNS( XML_w, XML_smallCaps, FSNS( XML_w, XML_val ), "false", FSEND );
    5142          25 :             m_pSerializer->singleElementNS( XML_w, XML_caps, FSNS( XML_w, XML_val ), "false", FSEND );
    5143          25 :             break;
    5144             :     }
    5145          86 : }
    5146             : 
    5147        4360 : void DocxAttributeOutput::CharColor( const SvxColorItem& rColor )
    5148             : {
    5149        4360 :     const Color aColor( rColor.GetValue() );
    5150        4360 :     OString aColorString;
    5151             : 
    5152        4360 :     aColorString = msfilter::util::ConvertColor( aColor );
    5153             : 
    5154        4360 :     AddToAttrList( m_pColorAttrList, FSNS( XML_w, XML_val ), aColorString.getStr() );
    5155        4360 : }
    5156             : 
    5157           4 : void DocxAttributeOutput::CharContour( const SvxContourItem& rContour )
    5158             : {
    5159           4 :     if ( rContour.GetValue() )
    5160           0 :         m_pSerializer->singleElementNS( XML_w, XML_outline, FSEND );
    5161             :     else
    5162           4 :         m_pSerializer->singleElementNS( XML_w, XML_outline, FSNS( XML_w, XML_val ), "false", FSEND );
    5163           4 : }
    5164             : 
    5165          36 : void DocxAttributeOutput::CharCrossedOut( const SvxCrossedOutItem& rCrossedOut )
    5166             : {
    5167          36 :     switch ( rCrossedOut.GetStrikeout() )
    5168             :     {
    5169             :         case STRIKEOUT_DOUBLE:
    5170           0 :             m_pSerializer->singleElementNS( XML_w, XML_dstrike, FSEND );
    5171           0 :             break;
    5172             :         case STRIKEOUT_NONE:
    5173          31 :             m_pSerializer->singleElementNS( XML_w, XML_dstrike, FSNS( XML_w, XML_val ), "false", FSEND );
    5174          31 :             m_pSerializer->singleElementNS( XML_w, XML_strike, FSNS( XML_w, XML_val ), "false", FSEND );
    5175          31 :             break;
    5176             :         default:
    5177           5 :             m_pSerializer->singleElementNS( XML_w, XML_strike, FSEND );
    5178           5 :             break;
    5179             :     }
    5180          36 : }
    5181             : 
    5182         125 : void DocxAttributeOutput::CharEscapement( const SvxEscapementItem& rEscapement )
    5183             : {
    5184         125 :     OString sIss;
    5185         125 :     short nEsc = rEscapement.GetEsc(), nProp = rEscapement.GetProp();
    5186         125 :     if ( !nEsc )
    5187             :     {
    5188          27 :         sIss = OString( "baseline" );
    5189          27 :         nEsc = 0;
    5190          27 :         nProp = 100;
    5191             :     }
    5192          98 :     else if ( DFLT_ESC_PROP == nProp )
    5193             :     {
    5194          98 :         if ( DFLT_ESC_SUB == nEsc || DFLT_ESC_AUTO_SUB == nEsc )
    5195          10 :             sIss = OString( "subscript" );
    5196          88 :         else if ( DFLT_ESC_SUPER == nEsc || DFLT_ESC_AUTO_SUPER == nEsc )
    5197          88 :             sIss = OString( "superscript" );
    5198             :     }
    5199             : 
    5200         125 :     if ( !sIss.isEmpty() )
    5201             :         m_pSerializer->singleElementNS( XML_w, XML_vertAlign,
    5202         125 :            FSNS( XML_w, XML_val ), sIss.getStr(), FSEND );
    5203             : 
    5204         125 :     const SvxFontHeightItem& rItem = static_cast<const SvxFontHeightItem&>(m_rExport.GetItem(RES_CHRATR_FONTSIZE));
    5205         125 :     if (&rItem != NULL && (sIss.isEmpty() || sIss.match(OString("baseline"))))
    5206             :     {
    5207          27 :         long nHeight = rItem.GetHeight();
    5208          27 :         OString sPos = OString::number( ( nHeight * nEsc + 500 ) / 1000 );
    5209             :         m_pSerializer->singleElementNS( XML_w, XML_position,
    5210          27 :                 FSNS( XML_w, XML_val ), sPos.getStr( ), FSEND );
    5211             : 
    5212          27 :         if( 100 != nProp || sIss.match( OString( "baseline" ) ) )
    5213             :         {
    5214          27 :             OString sSize = OString::number( ( nHeight * nProp + 500 ) / 1000 );
    5215             :                 m_pSerializer->singleElementNS( XML_w, XML_sz,
    5216          27 :                     FSNS( XML_w, XML_val ), sSize.getStr( ), FSEND );
    5217          27 :         }
    5218         125 :     }
    5219         125 : }
    5220             : 
    5221        5706 : void DocxAttributeOutput::CharFont( const SvxFontItem& rFont)
    5222             : {
    5223        5706 :     GetExport().GetId( rFont ); // ensure font info is written to fontTable.xml
    5224        5706 :     OUString sFontName(rFont.GetFamilyName());
    5225       11412 :     OString sFontNameUtf8 = OUStringToOString(sFontName, RTL_TEXTENCODING_UTF8);
    5226             :     AddToAttrList( m_pFontsAttrList, 2,
    5227             :             FSNS( XML_w, XML_ascii ), sFontNameUtf8.getStr(),
    5228       11412 :             FSNS( XML_w, XML_hAnsi ), sFontNameUtf8.getStr() );
    5229        5706 : }
    5230             : 
    5231       13823 : void DocxAttributeOutput::CharFontSize( const SvxFontHeightItem& rFontSize)
    5232             : {
    5233       13823 :     OString fontSize = OString::number( ( rFontSize.GetHeight() + 5 ) / 10 );
    5234             : 
    5235       13823 :     switch ( rFontSize.Which() )
    5236             :     {
    5237             :         case RES_CHRATR_FONTSIZE:
    5238             :         case RES_CHRATR_CJK_FONTSIZE:
    5239        7996 :             m_pSerializer->singleElementNS( XML_w, XML_sz, FSNS( XML_w, XML_val ), fontSize.getStr(), FSEND );
    5240        7996 :             break;
    5241             :         case RES_CHRATR_CTL_FONTSIZE:
    5242        5827 :             m_pSerializer->singleElementNS( XML_w, XML_szCs, FSNS( XML_w, XML_val ), fontSize.getStr(), FSEND );
    5243        5827 :             break;
    5244       13823 :     }
    5245       13823 : }
    5246             : 
    5247         177 : void DocxAttributeOutput::CharKerning( const SvxKerningItem& rKerning )
    5248             : {
    5249         177 :     OString aKerning = OString::number(  rKerning.GetValue() );
    5250         177 :     m_pSerializer->singleElementNS( XML_w, XML_spacing, FSNS(XML_w, XML_val), aKerning.getStr(), FSEND );
    5251         177 : }
    5252             : 
    5253        6175 : void DocxAttributeOutput::CharLanguage( const SvxLanguageItem& rLanguage )
    5254             : {
    5255             :     OString aLanguageCode( OUStringToOString(
    5256       12350 :                 LanguageTag( rLanguage.GetLanguage()).getBcp47(),
    5257        6175 :                 RTL_TEXTENCODING_UTF8));
    5258             : 
    5259        6175 :     switch ( rLanguage.Which() )
    5260             :     {
    5261             :         case RES_CHRATR_LANGUAGE:
    5262        2519 :             AddToAttrList( m_pCharLangAttrList, FSNS( XML_w, XML_val ), aLanguageCode.getStr() );
    5263        2519 :             break;
    5264             :         case RES_CHRATR_CJK_LANGUAGE:
    5265        1350 :             AddToAttrList( m_pCharLangAttrList, FSNS( XML_w, XML_eastAsia ), aLanguageCode.getStr() );
    5266        1350 :             break;
    5267             :         case RES_CHRATR_CTL_LANGUAGE:
    5268        2306 :             AddToAttrList( m_pCharLangAttrList, FSNS( XML_w, XML_bidi ), aLanguageCode.getStr() );
    5269        2306 :             break;
    5270        6175 :     }
    5271        6175 : }
    5272             : 
    5273        1080 : void DocxAttributeOutput::CharPosture( const SvxPostureItem& rPosture )
    5274             : {
    5275        1080 :     if ( rPosture.GetPosture() != ITALIC_NONE )
    5276         981 :         m_pSerializer->singleElementNS( XML_w, XML_i, FSEND );
    5277             :     else
    5278          99 :         m_pSerializer->singleElementNS( XML_w, XML_i, FSNS( XML_w, XML_val ), "false", FSEND );
    5279        1080 : }
    5280             : 
    5281           1 : void DocxAttributeOutput::CharShadow( const SvxShadowedItem& rShadow )
    5282             : {
    5283           1 :     if ( rShadow.GetValue() )
    5284           0 :         m_pSerializer->singleElementNS( XML_w, XML_shadow, FSEND );
    5285             :     else
    5286           1 :         m_pSerializer->singleElementNS( XML_w, XML_shadow, FSNS( XML_w, XML_val ), "false", FSEND );
    5287           1 : }
    5288             : 
    5289         245 : void DocxAttributeOutput::CharUnderline( const SvxUnderlineItem& rUnderline )
    5290             : {
    5291             :     const char *pUnderlineValue;
    5292             : 
    5293         245 :     switch ( rUnderline.GetLineStyle() )
    5294             :     {
    5295         186 :         case UNDERLINE_SINGLE:         pUnderlineValue = "single";          break;
    5296           1 :         case UNDERLINE_BOLD:           pUnderlineValue = "thick";           break;
    5297           2 :         case UNDERLINE_DOUBLE:         pUnderlineValue = "double";          break;
    5298           0 :         case UNDERLINE_DOTTED:         pUnderlineValue = "dotted";          break;
    5299           0 :         case UNDERLINE_DASH:           pUnderlineValue = "dash";            break;
    5300           0 :         case UNDERLINE_DASHDOT:        pUnderlineValue = "dotDash";         break;
    5301           0 :         case UNDERLINE_DASHDOTDOT:     pUnderlineValue = "dotDotDash";      break;
    5302           0 :         case UNDERLINE_WAVE:           pUnderlineValue = "wave";            break;
    5303           0 :         case UNDERLINE_BOLDDOTTED:     pUnderlineValue = "dottedHeavy";     break;
    5304           0 :         case UNDERLINE_BOLDDASH:       pUnderlineValue = "dashedHeavy";     break;
    5305           0 :         case UNDERLINE_LONGDASH:       pUnderlineValue = "dashLongHeavy";   break;
    5306           0 :         case UNDERLINE_BOLDLONGDASH:   pUnderlineValue = "dashLongHeavy";   break;
    5307           0 :         case UNDERLINE_BOLDDASHDOT:    pUnderlineValue = "dashDotHeavy";    break;
    5308           0 :         case UNDERLINE_BOLDDASHDOTDOT: pUnderlineValue = "dashDotDotHeavy"; break;
    5309           0 :         case UNDERLINE_BOLDWAVE:       pUnderlineValue = "wavyHeavy";       break;
    5310           0 :         case UNDERLINE_DOUBLEWAVE:     pUnderlineValue = "wavyDouble";      break;
    5311             :         case UNDERLINE_NONE:           // fall through
    5312          56 :         default:                       pUnderlineValue = "none";            break;
    5313             :     }
    5314             : 
    5315         245 :     Color aUnderlineColor = rUnderline.GetColor();
    5316         245 :     bool  bUnderlineHasColor = aUnderlineColor.GetTransparency() == 0;
    5317         245 :     if (bUnderlineHasColor)
    5318             :     {
    5319             :         // Underline has a color
    5320             :         m_pSerializer->singleElementNS( XML_w, XML_u,
    5321             :                                         FSNS( XML_w, XML_val ), pUnderlineValue,
    5322             :                                         FSNS( XML_w, XML_color ), msfilter::util::ConvertColor( aUnderlineColor ).getStr(),
    5323          23 :                                     FSEND );
    5324             :     }
    5325             :     else
    5326             :     {
    5327             :         // Underline has no color
    5328         222 :         m_pSerializer->singleElementNS( XML_w, XML_u, FSNS( XML_w, XML_val ), pUnderlineValue, FSEND );
    5329             :     }
    5330         245 : }
    5331             : 
    5332        3202 : void DocxAttributeOutput::CharWeight( const SvxWeightItem& rWeight )
    5333             : {
    5334        3202 :     if ( rWeight.GetWeight() == WEIGHT_BOLD )
    5335        3066 :         m_pSerializer->singleElementNS( XML_w, XML_b, FSEND );
    5336             :     else
    5337         136 :         m_pSerializer->singleElementNS( XML_w, XML_b, FSNS( XML_w, XML_val ), "false", FSEND );
    5338        3202 : }
    5339             : 
    5340        1149 : void DocxAttributeOutput::CharAutoKern( const SvxAutoKernItem& )
    5341             : {
    5342             :     OSL_TRACE( "TODO DocxAttributeOutput::CharAutoKern()" );
    5343        1149 : }
    5344             : 
    5345           6 : void DocxAttributeOutput::CharAnimatedText( const SvxBlinkItem& rBlink )
    5346             : {
    5347           6 :     if ( rBlink.GetValue() )
    5348           0 :         m_pSerializer->singleElementNS(XML_w, XML_effect, FSNS( XML_w, XML_val ), "blinkBackground", FSEND );
    5349             :     else
    5350           6 :         m_pSerializer->singleElementNS(XML_w, XML_effect, FSNS( XML_w, XML_val ), "none", FSEND );
    5351           6 : }
    5352             : 
    5353             : #define MSWORD_CH_SHADING_FILL "FFFFFF" // The attribute w:fill of w:shd, for MS-Word's character shading,
    5354             : #define MSWORD_CH_SHADING_COLOR "auto" // The attribute w:color of w:shd, for MS-Word's character shading,
    5355             : #define MSWORD_CH_SHADING_VAL "pct15" // The attribute w:value of w:shd, for MS-Word's character shading,
    5356             : 
    5357          43 : void DocxAttributeOutput::CharBackground( const SvxBrushItem& rBrush )
    5358             : {
    5359             :     // Check if the brush shading pattern is 'PCT15'. If so - write it back to the DOCX
    5360          43 :     if (rBrush.GetShadingValue() == +ShadingPattern::PCT15)
    5361             :     {
    5362             :         m_pSerializer->singleElementNS( XML_w, XML_shd,
    5363             :             FSNS( XML_w, XML_val ), MSWORD_CH_SHADING_VAL,
    5364             :             FSNS( XML_w, XML_color ), MSWORD_CH_SHADING_COLOR,
    5365             :             FSNS( XML_w, XML_fill ), MSWORD_CH_SHADING_FILL,
    5366           1 :             FSEND );
    5367             :     }
    5368             :     else
    5369             :     {
    5370             :         m_pSerializer->singleElementNS( XML_w, XML_shd,
    5371          42 :             FSNS( XML_w, XML_fill ), msfilter::util::ConvertColor( rBrush.GetColor() ).getStr(),
    5372             :             FSNS( XML_w, XML_val ), "clear",
    5373          42 :             FSEND );
    5374             :     }
    5375          43 : }
    5376             : 
    5377        2640 : void DocxAttributeOutput::CharFontCJK( const SvxFontItem& rFont )
    5378             : {
    5379        2640 :     OUString sFontName(rFont.GetFamilyName());
    5380        5280 :     OString sFontNameUtf8 = OUStringToOString(sFontName, RTL_TEXTENCODING_UTF8);
    5381        5280 :     AddToAttrList( m_pFontsAttrList, FSNS( XML_w, XML_eastAsia ), sFontNameUtf8.getStr() );
    5382        2640 : }
    5383             : 
    5384         240 : void DocxAttributeOutput::CharPostureCJK( const SvxPostureItem& rPosture )
    5385             : {
    5386         240 :     if ( rPosture.GetPosture() != ITALIC_NONE )
    5387         214 :         m_pSerializer->singleElementNS( XML_w, XML_i, FSEND );
    5388             :     else
    5389          26 :         m_pSerializer->singleElementNS( XML_w, XML_i, FSNS( XML_w, XML_val ), "false", FSEND );
    5390         240 : }
    5391             : 
    5392        1184 : void DocxAttributeOutput::CharWeightCJK( const SvxWeightItem& rWeight )
    5393             : {
    5394        1184 :     if ( rWeight.GetWeight() == WEIGHT_BOLD )
    5395        1122 :         m_pSerializer->singleElementNS( XML_w, XML_b, FSEND );
    5396             :     else
    5397          62 :         m_pSerializer->singleElementNS( XML_w, XML_b, FSNS( XML_w, XML_val ), "false", FSEND );
    5398        1184 : }
    5399             : 
    5400        5395 : void DocxAttributeOutput::CharFontCTL( const SvxFontItem& rFont )
    5401             : {
    5402        5395 :     OUString sFontName(rFont.GetFamilyName());
    5403       10790 :     OString sFontNameUtf8 = OUStringToOString(sFontName, RTL_TEXTENCODING_UTF8);
    5404       10790 :     AddToAttrList( m_pFontsAttrList, FSNS( XML_w, XML_cs ), sFontNameUtf8.getStr() );
    5405             : 
    5406        5395 : }
    5407             : 
    5408         567 : void DocxAttributeOutput::CharPostureCTL( const SvxPostureItem& rPosture)
    5409             : {
    5410         567 :     if ( rPosture.GetPosture() != ITALIC_NONE )
    5411         543 :         m_pSerializer->singleElementNS( XML_w, XML_iCs, FSEND );
    5412             :     else
    5413          24 :         m_pSerializer->singleElementNS( XML_w, XML_iCs, FSNS( XML_w, XML_val ), "false", FSEND );
    5414         567 : }
    5415             : 
    5416        1136 : void DocxAttributeOutput::CharWeightCTL( const SvxWeightItem& rWeight )
    5417             : {
    5418        1136 :     if ( rWeight.GetWeight() == WEIGHT_BOLD )
    5419        1103 :         m_pSerializer->singleElementNS( XML_w, XML_bCs, FSEND );
    5420             :     else
    5421          33 :         m_pSerializer->singleElementNS( XML_w, XML_bCs, FSNS( XML_w, XML_val ), "false", FSEND );
    5422        1136 : }
    5423             : 
    5424         272 : void DocxAttributeOutput::CharBidiRTL( const SfxPoolItem& )
    5425             : {
    5426         272 : }
    5427             : 
    5428         296 : void DocxAttributeOutput::CharIdctHint( const SfxPoolItem& )
    5429             : {
    5430         296 : }
    5431             : 
    5432           3 : void DocxAttributeOutput::CharRotate( const SvxCharRotateItem& rRotate)
    5433             : {
    5434             :     // Not rorated or we the rotation already handled?
    5435           3 :     if ( !rRotate.GetValue() || m_bBtLr || m_rExport.SdrExporter().getFrameBtLr())
    5436           6 :         return;
    5437             : 
    5438           0 :     AddToAttrList( m_pEastAsianLayoutAttrList, FSNS( XML_w, XML_vert ), "true" );
    5439             : 
    5440           0 :     if (rRotate.IsFitToLine())
    5441           0 :         AddToAttrList( m_pEastAsianLayoutAttrList, FSNS( XML_w, XML_vertCompress ), "true" );
    5442             : }
    5443             : 
    5444           1 : void DocxAttributeOutput::CharEmphasisMark( const SvxEmphasisMarkItem& rEmphasisMark )
    5445             : {
    5446             :     const char *pEmphasis;
    5447             : 
    5448           1 :     switch ( rEmphasisMark.GetValue() )
    5449             :     {
    5450           1 :         case EMPHASISMARK_NONE:         pEmphasis = "none";     break;
    5451           0 :         case EMPHASISMARK_SIDE_DOTS:    pEmphasis = "dot";      break;
    5452           0 :         case EMPHASISMARK_CIRCLE_ABOVE: pEmphasis = "circle";   break;
    5453           0 :         case EMPHASISMARK_DOTS_BELOW:   pEmphasis = "underDot"; break;
    5454           0 :         default:                        pEmphasis = "comma";    break;
    5455             :     }
    5456             : 
    5457           1 :     m_pSerializer->singleElementNS( XML_w, XML_em, FSNS( XML_w, XML_val ), pEmphasis, FSEND );
    5458           1 : }
    5459             : 
    5460           0 : void DocxAttributeOutput::CharTwoLines( const SvxTwoLinesItem& rTwoLines )
    5461             : {
    5462           0 :     if ( !rTwoLines.GetValue() )
    5463           0 :         return;
    5464             : 
    5465           0 :     AddToAttrList( m_pEastAsianLayoutAttrList, FSNS( XML_w, XML_combine ), "true" );
    5466             : 
    5467           0 :     sal_Unicode cStart = rTwoLines.GetStartBracket();
    5468           0 :     sal_Unicode cEnd = rTwoLines.GetEndBracket();
    5469             : 
    5470           0 :     if (!cStart && !cEnd)
    5471           0 :         return;
    5472             : 
    5473           0 :     OString sBracket;
    5474           0 :     if ((cStart == '{') || (cEnd == '}'))
    5475           0 :         sBracket = (sal_Char *)"curly";
    5476           0 :     else if ((cStart == '<') || (cEnd == '>'))
    5477           0 :         sBracket = (sal_Char *)"angle";
    5478           0 :     else if ((cStart == '[') || (cEnd == ']'))
    5479           0 :         sBracket = (sal_Char *)"square";
    5480             :     else
    5481           0 :         sBracket = (sal_Char *)"round";
    5482           0 :     AddToAttrList( m_pEastAsianLayoutAttrList, FSNS( XML_w, XML_combineBrackets ), sBracket.getStr() );
    5483             : }
    5484             : 
    5485           3 : void DocxAttributeOutput::CharScaleWidth( const SvxCharScaleWidthItem& rScaleWidth )
    5486             : {
    5487             :     m_pSerializer->singleElementNS( XML_w, XML_w,
    5488           3 :             FSNS( XML_w, XML_val ), OString::number( rScaleWidth.GetValue() ).getStr(), FSEND );
    5489           3 : }
    5490             : 
    5491           3 : void DocxAttributeOutput::CharRelief( const SvxCharReliefItem& rRelief )
    5492             : {
    5493           3 :     switch ( rRelief.GetValue() )
    5494             :     {
    5495             :         case RELIEF_EMBOSSED:
    5496           0 :             m_pSerializer->singleElementNS( XML_w, XML_emboss, FSEND );
    5497           0 :             break;
    5498             :         case RELIEF_ENGRAVED:
    5499           0 :             m_pSerializer->singleElementNS( XML_w, XML_imprint, FSEND );
    5500           0 :             break;
    5501             :         default:
    5502           3 :             m_pSerializer->singleElementNS( XML_w, XML_emboss, FSNS( XML_w, XML_val ), "false", FSEND );
    5503           3 :             m_pSerializer->singleElementNS( XML_w, XML_imprint, FSNS( XML_w, XML_val ), "false", FSEND );
    5504           3 :             break;
    5505             :     }
    5506           3 : }
    5507             : 
    5508         109 : void DocxAttributeOutput::CharHidden( const SvxCharHiddenItem& rHidden )
    5509             : {
    5510         109 :     if ( rHidden.GetValue() )
    5511          22 :         m_pSerializer->singleElementNS( XML_w, XML_vanish, FSEND );
    5512             :     else
    5513          87 :         m_pSerializer->singleElementNS( XML_w, XML_vanish, FSNS( XML_w, XML_val ), "false", FSEND );
    5514         109 : }
    5515             : 
    5516           6 : void DocxAttributeOutput::CharBorder(
    5517             :     const SvxBorderLine* pAllBorder, const sal_uInt16 nDist, const bool bShadow )
    5518             : {
    5519           6 :     impl_borderLine( m_pSerializer, XML_bdr, pAllBorder, nDist, bShadow );
    5520           6 : }
    5521             : 
    5522          31 : void DocxAttributeOutput::CharHighlight( const SvxBrushItem& rHighlight )
    5523             : {
    5524          31 :     const OString sColor = TransHighlightColor( rHighlight.GetColor() );
    5525          31 :     if ( !sColor.isEmpty() )
    5526             :     {
    5527             :         m_pSerializer->singleElementNS( XML_w, XML_highlight,
    5528          31 :             FSNS( XML_w, XML_val ), sColor.getStr(), FSEND );
    5529          31 :     }
    5530          31 : }
    5531             : 
    5532         385 : void DocxAttributeOutput::TextINetFormat( const SwFmtINetFmt& rLink )
    5533             : {
    5534         385 :     const SwTxtINetFmt* pINetFmt = rLink.GetTxtINetFmt();
    5535         385 :     const SwCharFmt* pCharFmt = pINetFmt->GetCharFmt();
    5536             : 
    5537         385 :     OString aStyleId(m_rExport.pStyles->GetStyleId(m_rExport.GetId(*pCharFmt)));
    5538             : 
    5539         385 :     m_pSerializer->singleElementNS( XML_w, XML_rStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND );
    5540         385 : }
    5541             : 
    5542          51 : void DocxAttributeOutput::TextCharFormat( const SwFmtCharFmt& rCharFmt )
    5543             : {
    5544          51 :     OString aStyleId(m_rExport.pStyles->GetStyleId(m_rExport.GetId(*rCharFmt.GetCharFmt())));
    5545             : 
    5546          51 :     m_pSerializer->singleElementNS( XML_w, XML_rStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND );
    5547          51 : }
    5548             : 
    5549           0 : void DocxAttributeOutput::RefField( const SwField&  rFld, const OUString& rRef )
    5550             : {
    5551           0 :     sal_uInt16 nType = rFld.GetTyp( )->Which( );
    5552           0 :     if ( nType == RES_GETEXPFLD )
    5553             :     {
    5554           0 :         OUString sCmd = FieldString( ww::eREF );
    5555           0 :         sCmd += "\"" + rRef + "\" ";
    5556             : 
    5557           0 :         m_rExport.OutputField( &rFld, ww::eREF, sCmd );
    5558             :     }
    5559             : 
    5560             :     // There is nothing to do here for the set fields
    5561           0 : }
    5562             : 
    5563           0 : void DocxAttributeOutput::HiddenField( const SwField& /*rFld*/ )
    5564             : {
    5565             :     OSL_TRACE( "TODO DocxAttributeOutput::HiddenField()" );
    5566           0 : }
    5567             : 
    5568           5 : void DocxAttributeOutput::PostitField( const SwField* pFld )
    5569             : {
    5570             :     assert( dynamic_cast< const SwPostItField* >( pFld ));
    5571           5 :     const SwPostItField* pPostItFld = static_cast<const SwPostItField*>(pFld);
    5572           5 :     OString aName = OUStringToOString(pPostItFld->GetName(), RTL_TEXTENCODING_UTF8);
    5573           5 :     sal_Int32 nId = 0;
    5574           5 :     std::map< OString, sal_uInt16 >::iterator it = m_rOpenedAnnotationMarksIds.find(aName);
    5575           5 :     if (it != m_rOpenedAnnotationMarksIds.end())
    5576             :         // If the postit field has an annotation mark associated, we already have an id.
    5577           4 :         nId = it->second;
    5578             :     else
    5579             :         // Otherwise get a new one.
    5580           1 :         nId = m_nNextAnnotationMarkId++;
    5581           5 :     m_postitFields.push_back(std::make_pair(pPostItFld, nId));
    5582           5 : }
    5583             : 
    5584        6489 : void DocxAttributeOutput::WritePostitFieldReference()
    5585             : {
    5586       12983 :     while( m_postitFieldsMaxId < m_postitFields.size())
    5587             :     {
    5588           5 :         OString idstr = OString::number(m_postitFields[m_postitFieldsMaxId].second);
    5589             : 
    5590             :         // In case this file is inside annotation marks, we want to write the
    5591             :         // comment reference after the annotation mark is closed, not here.
    5592          10 :         OString idname = OUStringToOString(m_postitFields[m_postitFieldsMaxId].first->GetName(), RTL_TEXTENCODING_UTF8);
    5593           5 :         std::map< OString, sal_uInt16 >::iterator it = m_rOpenedAnnotationMarksIds.find( idname );
    5594           5 :         if ( it == m_rOpenedAnnotationMarksIds.end(  ) )
    5595           1 :             m_pSerializer->singleElementNS( XML_w, XML_commentReference, FSNS( XML_w, XML_id ), idstr.getStr(), FSEND );
    5596           5 :         ++m_postitFieldsMaxId;
    5597           5 :     }
    5598        6489 : }
    5599             : 
    5600           3 : void DocxAttributeOutput::WritePostitFields()
    5601             : {
    5602          16 :     for( unsigned int i = 0;
    5603           8 :          i < m_postitFields.size();
    5604             :          ++i )
    5605             :     {
    5606           5 :         OString idstr = OString::number( m_postitFields[ i ].second);
    5607           5 :         const SwPostItField* f = m_postitFields[ i ].first;
    5608             :         m_pSerializer->startElementNS( XML_w, XML_comment, FSNS( XML_w, XML_id ), idstr.getStr(),
    5609           5 :             FSNS( XML_w, XML_author ), OUStringToOString( f->GetPar1(), RTL_TEXTENCODING_UTF8 ).getStr(),
    5610             :             FSNS( XML_w, XML_date ), DateTimeToOString(f->GetDateTime()).getStr(),
    5611          10 :             FSNS( XML_w, XML_initials ), OUStringToOString( f->GetInitials(), RTL_TEXTENCODING_UTF8 ).getStr(), FSEND );
    5612             :         // Check for the text object existing, it seems that it can be NULL when saving a newly created
    5613             :         // comment without giving focus back to the main document. As GetTxt() is empty in that case as well,
    5614             :         // that is probably a bug in the Writer core.
    5615           5 :         if( f->GetTextObject() != NULL )
    5616           5 :             GetExport().WriteOutliner( *f->GetTextObject(), TXT_ATN );
    5617           5 :         m_pSerializer->endElementNS( XML_w, XML_comment );
    5618           5 :     }
    5619           3 : }
    5620             : 
    5621           0 : bool DocxAttributeOutput::DropdownField( const SwField* pFld )
    5622             : {
    5623           0 :     bool bExpand = false;
    5624             : 
    5625           0 :     ww::eField eType = ww::eFORMDROPDOWN;
    5626           0 :     OUString sCmd = FieldString( eType  );
    5627           0 :     GetExport( ).OutputField( pFld, eType, sCmd );
    5628             : 
    5629           0 :     return bExpand;
    5630             : }
    5631             : 
    5632           0 : bool DocxAttributeOutput::PlaceholderField( const SwField* pFld )
    5633             : {
    5634             :     assert( pendingPlaceholder == NULL );
    5635           0 :     pendingPlaceholder = pFld;
    5636           0 :     return false; // do not expand
    5637             : }
    5638             : 
    5639        6494 : void DocxAttributeOutput::WritePendingPlaceholder()
    5640             : {
    5641        6494 :     if( pendingPlaceholder == NULL )
    5642       12988 :         return;
    5643           0 :     const SwField* pFld = pendingPlaceholder;
    5644           0 :     pendingPlaceholder = NULL;
    5645           0 :     m_pSerializer->startElementNS( XML_w, XML_sdt, FSEND );
    5646           0 :     m_pSerializer->startElementNS( XML_w, XML_sdtPr, FSEND );
    5647           0 :     if( !pFld->GetPar2().isEmpty())
    5648             :         m_pSerializer->singleElementNS( XML_w, XML_alias,
    5649           0 :             FSNS( XML_w, XML_val ), OUStringToOString( pFld->GetPar2(), RTL_TEXTENCODING_UTF8 ), FSEND );
    5650           0 :     m_pSerializer->singleElementNS( XML_w, XML_temporary, FSEND );
    5651           0 :     m_pSerializer->singleElementNS( XML_w, XML_showingPlcHdr, FSEND );
    5652           0 :     m_pSerializer->singleElementNS( XML_w, XML_text, FSEND );
    5653           0 :     m_pSerializer->endElementNS( XML_w, XML_sdtPr );
    5654           0 :     m_pSerializer->startElementNS( XML_w, XML_sdtContent, FSEND );
    5655           0 :     m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
    5656           0 :     RunText( pFld->GetPar1());
    5657           0 :     m_pSerializer->endElementNS( XML_w, XML_r );
    5658           0 :     m_pSerializer->endElementNS( XML_w, XML_sdtContent );
    5659           0 :     m_pSerializer->endElementNS( XML_w, XML_sdt );
    5660             : }
    5661             : 
    5662           0 : void DocxAttributeOutput::SetField( const SwField& rFld, ww::eField eType, const OUString& rCmd )
    5663             : {
    5664             :     // field bookmarks are handled in the EndRun method
    5665           0 :     GetExport().OutputField(&rFld, eType, rCmd );
    5666           0 : }
    5667             : 
    5668           1 : void DocxAttributeOutput::WriteExpand( const SwField* pFld )
    5669             : {
    5670             :     // Will be written in the next End Run
    5671           1 :     OUString sCmd;
    5672           1 :     m_rExport.OutputField( pFld, ww::eUNKNOWN, sCmd );
    5673           1 : }
    5674             : 
    5675         260 : void DocxAttributeOutput::WriteField_Impl( const SwField* pFld, ww::eField eType, const OUString& rFldCmd, sal_uInt8 nMode )
    5676             : {
    5677         260 :     struct FieldInfos infos;
    5678         260 :     if (pFld)
    5679          80 :         infos.pField = pFld->CopyField();
    5680         260 :     infos.sCmd = rFldCmd;
    5681         260 :     infos.eType = eType;
    5682         260 :     infos.bClose = WRITEFIELD_CLOSE & nMode;
    5683         260 :     infos.bOpen = WRITEFIELD_START & nMode;
    5684         260 :     m_Fields.push_back( infos );
    5685             : 
    5686         260 :     if ( pFld )
    5687             :     {
    5688          80 :         sal_uInt16 nType = pFld->GetTyp( )->Which( );
    5689          80 :         sal_uInt16 nSubType = pFld->GetSubType();
    5690             : 
    5691             :         // TODO Any other field types here ?
    5692          80 :         if ( ( nType == RES_SETEXPFLD ) && ( nSubType & nsSwGetSetExpType::GSE_STRING ) )
    5693             :         {
    5694           0 :             const SwSetExpField *pSet = ( const SwSetExpField* )( pFld );
    5695           0 :             m_sFieldBkm = pSet->GetPar1( );
    5696             :         }
    5697          80 :         else if ( nType == RES_DROPDOWN )
    5698             :         {
    5699           0 :             const SwDropDownField* pDropDown = ( const SwDropDownField* )( pFld );
    5700           0 :             m_sFieldBkm = pDropDown->GetName( );
    5701             :         }
    5702         260 :     }
    5703         260 : }
    5704             : 
    5705           1 : void DocxAttributeOutput::WriteFormData_Impl( const ::sw::mark::IFieldmark& rFieldmark )
    5706             : {
    5707           1 :     if ( !m_Fields.empty() )
    5708           1 :         m_Fields.begin()->pFieldmark = &rFieldmark;
    5709           1 : }
    5710             : 
    5711       11680 : void DocxAttributeOutput::WriteBookmarks_Impl( std::vector< OUString >& rStarts,
    5712             :         std::vector< OUString >& rEnds )
    5713             : {
    5714       12461 :     for ( std::vector< OUString >::const_iterator it = rStarts.begin(), end = rStarts.end(); it != end; ++it )
    5715             :     {
    5716         781 :         OString rName = OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr( );
    5717         781 :         m_rBookmarksStart.push_back( rName );
    5718         781 :     }
    5719       11680 :     rStarts.clear();
    5720             : 
    5721       12445 :     for ( std::vector< OUString >::const_iterator it = rEnds.begin(), end = rEnds.end(); it != end; ++it )
    5722             :     {
    5723         765 :         OString rName = OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr( );
    5724         765 :         m_rBookmarksEnd.push_back( rName );
    5725         765 :     }
    5726       11680 :     rEnds.clear();
    5727       11680 : }
    5728             : 
    5729       11678 : void DocxAttributeOutput::WriteAnnotationMarks_Impl( std::vector< OUString >& rStarts,
    5730             :         std::vector< OUString >& rEnds )
    5731             : {
    5732       11684 :     for ( std::vector< OUString >::const_iterator it = rStarts.begin(), end = rStarts.end(); it != end; ++it )
    5733             :     {
    5734           6 :         OString rName = OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr( );
    5735           6 :         m_rAnnotationMarksStart.push_back( rName );
    5736           6 :     }
    5737       11678 :     rStarts.clear();
    5738             : 
    5739       11682 :     for ( std::vector< OUString >::const_iterator it = rEnds.begin(), end = rEnds.end(); it != end; ++it )
    5740             :     {
    5741           4 :         OString rName = OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr( );
    5742           4 :         m_rAnnotationMarksEnd.push_back( rName );
    5743           4 :     }
    5744       11678 :     rEnds.clear();
    5745       11678 : }
    5746             : 
    5747           5 : void DocxAttributeOutput::TextFootnote_Impl( const SwFmtFtn& rFootnote )
    5748             : {
    5749           5 :     const SwEndNoteInfo& rInfo = rFootnote.IsEndNote()?
    5750           5 :         m_rExport.pDoc->GetEndNoteInfo(): m_rExport.pDoc->GetFtnInfo();
    5751             : 
    5752             :     // footnote/endnote run properties
    5753           5 :     const SwCharFmt* pCharFmt = rInfo.GetAnchorCharFmt( *m_rExport.pDoc );
    5754             : 
    5755           5 :     OString aStyleId(m_rExport.pStyles->GetStyleId(m_rExport.GetId(*pCharFmt)));
    5756             : 
    5757           5 :     m_pSerializer->singleElementNS( XML_w, XML_rStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND );
    5758             : 
    5759             :     // remember the footnote/endnote to
    5760             :     // 1) write the footnoteReference/endnoteReference in EndRunProperties()
    5761             :     // 2) be able to dump them all to footnotes.xml/endnotes.xml
    5762           5 :     if ( !rFootnote.IsEndNote() )
    5763           3 :         m_pFootnotesList->add( rFootnote );
    5764             :     else
    5765           2 :         m_pEndnotesList->add( rFootnote );
    5766           5 : }
    5767             : 
    5768        6494 : void DocxAttributeOutput::FootnoteEndnoteReference()
    5769             : {
    5770             :     sal_Int32 nId;
    5771        6494 :     const SwFmtFtn *pFootnote = m_pFootnotesList->getCurrent( nId );
    5772             : 
    5773             :     // both cannot be set at the same time - if they are, it's a bug
    5774        6494 :     if ( !pFootnote )
    5775        6491 :         pFootnote = m_pEndnotesList->getCurrent( nId );
    5776             : 
    5777        6494 :     if ( !pFootnote )
    5778       12983 :         return;
    5779             : 
    5780           5 :     sal_Int32 nToken = pFootnote->IsEndNote()? XML_endnoteReference: XML_footnoteReference;
    5781             : 
    5782             :     // write it
    5783           5 :     if ( pFootnote->GetNumStr().isEmpty() )
    5784             :     {
    5785             :         // autonumbered
    5786             :         m_pSerializer->singleElementNS( XML_w, nToken,
    5787             :                 FSNS( XML_w, XML_id ), OString::number( nId ).getStr(),
    5788           5 :                 FSEND );
    5789             :     }
    5790             :     else
    5791             :     {
    5792             :         // not autonumbered
    5793             :         m_pSerializer->singleElementNS( XML_w, nToken,
    5794             :                 FSNS( XML_w, XML_customMarkFollows ), "1",
    5795             :                 FSNS( XML_w, XML_id ), OString::number( nId ).getStr(),
    5796           0 :                 FSEND );
    5797             : 
    5798           0 :         RunText( pFootnote->GetNumStr() );
    5799             :     }
    5800             : }
    5801             : 
    5802           3 : void DocxAttributeOutput::FootnotesEndnotes( bool bFootnotes )
    5803             : {
    5804           3 :     m_setFootnote = true;
    5805           3 :     const FootnotesVector& rVector = bFootnotes? m_pFootnotesList->getVector(): m_pEndnotesList->getVector();
    5806             : 
    5807           3 :     sal_Int32 nBody = bFootnotes? XML_footnotes: XML_endnotes;
    5808           3 :     sal_Int32 nItem = bFootnotes? XML_footnote:  XML_endnote;
    5809             : 
    5810             :     m_pSerializer->startElementNS( XML_w, nBody,
    5811             :             FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
    5812             :             FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
    5813           3 :             FSEND );
    5814             : 
    5815           3 :     sal_Int32 nIndex = 0;
    5816             : 
    5817             :     // separator
    5818             :     m_pSerializer->startElementNS( XML_w, nItem,
    5819             :             FSNS( XML_w, XML_id ), OString::number( nIndex++ ).getStr(),
    5820             :             FSNS( XML_w, XML_type ), "separator",
    5821           3 :             FSEND );
    5822           3 :     m_pSerializer->startElementNS( XML_w, XML_p, FSEND );
    5823           3 :     m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
    5824             : 
    5825           3 :     bool bSeparator = true;
    5826           3 :     if (bFootnotes)
    5827             :     {
    5828           2 :         const SwPageFtnInfo& rFtnInfo = m_rExport.pDoc->GetPageDesc(0).GetFtnInfo();
    5829             :         // Request a separator only in case the width is larger than zero.
    5830           2 :         bSeparator = double(rFtnInfo.GetWidth()) > 0;
    5831             :     }
    5832             : 
    5833           3 :     if (bSeparator)
    5834           2 :         m_pSerializer->singleElementNS( XML_w, XML_separator, FSEND );
    5835           3 :     m_pSerializer->endElementNS( XML_w, XML_r );
    5836           3 :     m_pSerializer->endElementNS( XML_w, XML_p );
    5837           3 :     m_pSerializer->endElementNS( XML_w, nItem );
    5838             : 
    5839             :     // separator
    5840             :     m_pSerializer->startElementNS( XML_w, nItem,
    5841             :             FSNS( XML_w, XML_id ), OString::number( nIndex++ ).getStr(),
    5842             :             FSNS( XML_w, XML_type ), "continuationSeparator",
    5843           3 :             FSEND );
    5844           3 :     m_pSerializer->startElementNS( XML_w, XML_p, FSEND );
    5845           3 :     m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
    5846           3 :     m_pSerializer->singleElementNS( XML_w, XML_continuationSeparator, FSEND );
    5847           3 :     m_pSerializer->endElementNS( XML_w, XML_r );
    5848           3 :     m_pSerializer->endElementNS( XML_w, XML_p );
    5849           3 :     m_pSerializer->endElementNS( XML_w, nItem );
    5850             : 
    5851             :     // if new special ones are added, update also WriteFootnoteEndnotePr()
    5852             : 
    5853             :     // footnotes/endnotes themselves
    5854           8 :     for ( FootnotesVector::const_iterator i = rVector.begin(); i != rVector.end(); ++i, ++nIndex )
    5855             :     {
    5856             :         m_pSerializer->startElementNS( XML_w, nItem,
    5857             :                 FSNS( XML_w, XML_id ), OString::number( nIndex ).getStr(),
    5858           5 :                 FSEND );
    5859             : 
    5860           5 :         const SwNodeIndex* pIndex = (*i)->GetTxtFtn()->GetStartNode();
    5861             :         // tag required at the start of each footnote/endnote
    5862           5 :         m_footnoteEndnoteRefTag = bFootnotes ? XML_footnoteRef : XML_endnoteRef;
    5863             : 
    5864           5 :         m_rExport.WriteSpecialText( pIndex->GetIndex() + 1,
    5865           5 :                 pIndex->GetNode().EndOfSectionIndex(),
    5866          15 :                 bFootnotes? TXT_FTN: TXT_EDN );
    5867             : 
    5868           5 :         m_pSerializer->endElementNS( XML_w, nItem );
    5869             :     }
    5870             : 
    5871           3 :     m_pSerializer->endElementNS( XML_w, nBody );
    5872             : 
    5873           3 : }
    5874             : 
    5875           6 : void DocxAttributeOutput::WriteFootnoteEndnotePr( ::sax_fastparser::FSHelperPtr fs, int tag,
    5876             :     const SwEndNoteInfo& info, int listtag )
    5877             : {
    5878           6 :     fs->startElementNS( XML_w, tag, FSEND );
    5879           6 :     const char* fmt = NULL;
    5880           6 :     switch( info.aFmt.GetNumberingType())
    5881             :     {
    5882             :         case SVX_NUM_CHARS_UPPER_LETTER_N: // fall through, map to upper letters
    5883             :         case SVX_NUM_CHARS_UPPER_LETTER:
    5884           0 :             fmt = "upperLetter";
    5885           0 :             break;
    5886             :         case SVX_NUM_CHARS_LOWER_LETTER_N: // fall through, map to lower letters
    5887             :         case SVX_NUM_CHARS_LOWER_LETTER:
    5888           0 :             fmt = "lowerLetter";
    5889           0 :             break;
    5890             :         case SVX_NUM_ROMAN_UPPER:
    5891           0 :             fmt = "upperRoman";
    5892           0 :             break;
    5893             :         case SVX_NUM_ROMAN_LOWER:
    5894           2 :             fmt = "lowerRoman";
    5895           2 :             break;
    5896             :         case SVX_NUM_ARABIC:
    5897           4 :             fmt = "decimal";
    5898           4 :             break;
    5899             :         case SVX_NUM_NUMBER_NONE:
    5900           0 :             fmt = "none";
    5901           0 :             break;
    5902             :         case SVX_NUM_CHAR_SPECIAL:
    5903           0 :             fmt = "bullet";
    5904           0 :             break;
    5905             :         case SVX_NUM_PAGEDESC:
    5906             :         case SVX_NUM_BITMAP:
    5907             :         default:
    5908           0 :             break; // no format
    5909             :     }
    5910           6 :     if( fmt != NULL )
    5911           6 :         fs->singleElementNS( XML_w, XML_numFmt, FSNS( XML_w, XML_val ), fmt, FSEND );
    5912           6 :     if( info.nFtnOffset != 0 )
    5913             :         fs->singleElementNS( XML_w, XML_numStart, FSNS( XML_w, XML_val ),
    5914           0 :             OString::number( info.nFtnOffset + 1).getStr(), FSEND );
    5915           6 :     if( listtag != 0 ) // we are writing to settings.xml, write also special footnote/endnote list
    5916             :     { // there are currently only two hardcoded ones ( see FootnotesEndnotes())
    5917           3 :         fs->singleElementNS( XML_w, listtag, FSNS( XML_w, XML_id ), "0", FSEND );
    5918           3 :         fs->singleElementNS( XML_w, listtag, FSNS( XML_w, XML_id ), "1", FSEND );
    5919             :     }
    5920           6 :     fs->endElementNS( XML_w, tag );
    5921           6 : }
    5922             : 
    5923         298 : void DocxAttributeOutput::SectFootnoteEndnotePr()
    5924             : {
    5925         298 :     if( HasFootnotes())
    5926           2 :         WriteFootnoteEndnotePr( m_pSerializer, XML_footnotePr, m_rExport.pDoc->GetFtnInfo(), 0 );
    5927         298 :     if( HasEndnotes())
    5928           1 :         WriteFootnoteEndnotePr( m_pSerializer, XML_endnotePr, m_rExport.pDoc->GetEndNoteInfo(), 0 );
    5929         298 : }
    5930             : 
    5931        1593 : void DocxAttributeOutput::ParaLineSpacing_Impl( short nSpace, short nMulti )
    5932             : {
    5933        1593 :     if ( nSpace < 0 )
    5934             :     {
    5935             :         AddToAttrList( m_pParagraphSpacingAttrList, 2,
    5936             :                 FSNS( XML_w, XML_lineRule ), "exact",
    5937          75 :                 FSNS( XML_w, XML_line ), OString::number( -nSpace ).getStr() );
    5938             :     }
    5939        1518 :     else if( nMulti )
    5940             :     {
    5941             :         AddToAttrList( m_pParagraphSpacingAttrList, 2,
    5942             :                 FSNS( XML_w, XML_lineRule ), "auto",
    5943        1256 :                 FSNS( XML_w, XML_line ), OString::number( nSpace ).getStr() );
    5944             :     }
    5945         262 :     else if ( nSpace > 0 )
    5946             :     {
    5947             :         AddToAttrList( m_pParagraphSpacingAttrList, 2,
    5948             :                 FSNS( XML_w, XML_lineRule ), "atLeast",
    5949         262 :                 FSNS( XML_w, XML_line ), OString::number( nSpace ).getStr() );
    5950             :     }
    5951             :     else
    5952           0 :         AddToAttrList( m_pParagraphSpacingAttrList, FSNS( XML_w, XML_lineRule ), "auto" );
    5953        1593 : }
    5954             : 
    5955        2214 : void DocxAttributeOutput::ParaAdjust( const SvxAdjustItem& rAdjust )
    5956             : {
    5957             :     const char *pAdjustString;
    5958             : 
    5959        2214 :     bool bEcma = GetExport().GetFilter().getVersion( ) == oox::core::ECMA_DIALECT;
    5960             : 
    5961        2214 :     const SfxItemSet* pItems = GetExport().GetCurItemSet();
    5962             :     const SvxFrameDirectionItem* rFrameDir = pItems?
    5963        2214 :         static_cast< const SvxFrameDirectionItem* >( pItems->GetItem( RES_FRAMEDIR ) ): NULL;
    5964             : 
    5965        2214 :     short nDir = FRMDIR_ENVIRONMENT;
    5966        2214 :     if( rFrameDir != NULL )
    5967        2147 :         nDir = rFrameDir->GetValue();
    5968        2214 :     if ( nDir == FRMDIR_ENVIRONMENT )
    5969          81 :         nDir = GetExport( ).GetDefaultFrameDirection( );
    5970        2214 :     bool bRtl = ( nDir == FRMDIR_HORI_RIGHT_TOP );
    5971             : 
    5972        2214 :     switch ( rAdjust.GetAdjust() )
    5973             :     {
    5974             :         case SVX_ADJUST_LEFT:
    5975         534 :             if ( bEcma )
    5976             :             {
    5977           0 :                 if ( bRtl )
    5978           0 :                     pAdjustString = "right";
    5979             :                 else
    5980           0 :                     pAdjustString = "left";
    5981             :             }
    5982         534 :             else if ( bRtl )
    5983           1 :                 pAdjustString = "end";
    5984             :             else
    5985         533 :                 pAdjustString = "start";
    5986         534 :             break;
    5987             :         case SVX_ADJUST_RIGHT:
    5988         315 :             if ( bEcma )
    5989             :             {
    5990           0 :                 if ( bRtl )
    5991           0 :                     pAdjustString = "left";
    5992             :                 else
    5993           0 :                     pAdjustString = "right";
    5994             :             }
    5995         315 :             else if ( bRtl )
    5996           3 :                 pAdjustString = "start";
    5997             :             else
    5998         312 :                 pAdjustString = "end";
    5999         315 :             break;
    6000             :         case SVX_ADJUST_BLOCKLINE:
    6001             :         case SVX_ADJUST_BLOCK:
    6002         605 :             pAdjustString = "both";
    6003         605 :             break;
    6004             :         case SVX_ADJUST_CENTER:
    6005         760 :             pAdjustString = "center";
    6006         760 :             break;
    6007             :         default:
    6008        2214 :             return; // not supported attribute
    6009             :     }
    6010        2214 :     m_pSerializer->singleElementNS( XML_w, XML_jc, FSNS( XML_w, XML_val ), pAdjustString, FSEND );
    6011             : }
    6012             : 
    6013         112 : void DocxAttributeOutput::ParaSplit( const SvxFmtSplitItem& rSplit )
    6014             : {
    6015         112 :     if (rSplit.GetValue())
    6016           2 :         m_pSerializer->singleElementNS( XML_w, XML_keepLines, FSNS( XML_w, XML_val ), "false", FSEND );
    6017             :     else
    6018         110 :         m_pSerializer->singleElementNS( XML_w, XML_keepLines, FSEND );
    6019         112 : }
    6020             : 
    6021        1190 : void DocxAttributeOutput::ParaWidows( const SvxWidowsItem& rWidows )
    6022             : {
    6023        1190 :     if (rWidows.GetValue())
    6024         398 :         m_pSerializer->singleElementNS( XML_w, XML_widowControl, FSEND );
    6025             :     else
    6026         792 :         m_pSerializer->singleElementNS( XML_w, XML_widowControl, FSNS( XML_w, XML_val ), "false", FSEND );
    6027        1190 : }
    6028             : 
    6029        1248 : static void impl_WriteTabElement( FSHelperPtr pSerializer,
    6030             :                                   const SvxTabStop& rTab, long /* nCurrentLeft */ )
    6031             : {
    6032        1248 :     FastAttributeList *pTabElementAttrList = pSerializer->createAttrList();
    6033             : 
    6034        1248 :     switch (rTab.GetAdjustment())
    6035             :     {
    6036             :     case SVX_TAB_ADJUST_RIGHT:
    6037         416 :         pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"right") );
    6038         416 :         break;
    6039             :     case SVX_TAB_ADJUST_DECIMAL:
    6040           1 :         pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"decimal") );
    6041           1 :         break;
    6042             :     case SVX_TAB_ADJUST_CENTER:
    6043         185 :         pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"center") );
    6044         185 :         break;
    6045             :     case SVX_TAB_ADJUST_DEFAULT:
    6046             :     case SVX_TAB_ADJUST_LEFT:
    6047             :     default:
    6048         646 :         pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"left") );
    6049         646 :         break;
    6050             :     }
    6051             : 
    6052             :     // Because GetTabPos already includes indent, we don't need to add nCurrentLeft (CurrentLeft is indentation information)
    6053             :     //pTabElementAttrList->add( FSNS( XML_w, XML_pos ), OString::valueOf( rTab.GetTabPos() + nCurrentLeft ) );
    6054        1248 :     pTabElementAttrList->add( FSNS( XML_w, XML_pos ), OString::number( rTab.GetTabPos()                ) );
    6055             : 
    6056        1248 :     sal_Unicode cFillChar = rTab.GetFill();
    6057             : 
    6058        1248 :     if ('.' == cFillChar )
    6059         157 :         pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "dot" ) );
    6060        1091 :     else if ( '-' == cFillChar )
    6061           0 :         pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "hyphen" ) );
    6062        1091 :     else if ( sal_Unicode(0xB7) == cFillChar ) // middle dot
    6063           0 :         pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "middleDot" ) );
    6064        1091 :     else if ( '_' == cFillChar )
    6065           0 :         pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "underscore" ) );
    6066             :     else
    6067        1091 :         pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "none" ) );
    6068             : 
    6069        1248 :     pSerializer->singleElementNS( XML_w, XML_tab, pTabElementAttrList );
    6070        1248 : }
    6071             : 
    6072        1360 : void DocxAttributeOutput::ParaTabStop( const SvxTabStopItem& rTabStop )
    6073             : {
    6074        1360 :     const SfxPoolItem* pLR = m_rExport.HasItem( RES_LR_SPACE );
    6075        1360 :     long nCurrentLeft = pLR ? ((const SvxLRSpaceItem*)pLR)->GetTxtLeft() : 0;
    6076             : 
    6077        1360 :     sal_uInt16 nCount = rTabStop.Count();
    6078             : 
    6079             :     // <w:tabs> must contain at least one <w:tab>, so don't write it empty
    6080        1360 :     if( nCount == 0 )
    6081           8 :         return;
    6082        1352 :     if( nCount == 1 && rTabStop[ 0 ].GetAdjustment() == SVX_TAB_ADJUST_DEFAULT )
    6083             :     {
    6084         668 :         GetExport().setDefaultTabStop( rTabStop[ 0 ].GetTabPos());
    6085         668 :         return;
    6086             :     }
    6087             : 
    6088         684 :     m_pSerializer->startElementNS( XML_w, XML_tabs, FSEND );
    6089             : 
    6090        1932 :     for (sal_uInt16 i = 0; i < nCount; i++ )
    6091             :     {
    6092        1248 :         if( rTabStop[i].GetAdjustment() != SVX_TAB_ADJUST_DEFAULT )
    6093        1248 :             impl_WriteTabElement( m_pSerializer, rTabStop[i], nCurrentLeft );
    6094             :         else
    6095           0 :             GetExport().setDefaultTabStop( rTabStop[i].GetTabPos());
    6096             :     }
    6097             : 
    6098         684 :     m_pSerializer->endElementNS( XML_w, XML_tabs );
    6099             : }
    6100             : 
    6101         475 : void DocxAttributeOutput::ParaHyphenZone( const SvxHyphenZoneItem& rHyphenZone )
    6102             : {
    6103             :     m_pSerializer->singleElementNS( XML_w, XML_suppressAutoHyphens,
    6104         475 :             FSNS( XML_w, XML_val ), rHyphenZone.IsHyphen( ) ? "false" : "true" ,
    6105         475 :             FSEND );
    6106         475 : }
    6107             : 
    6108         419 : void DocxAttributeOutput::ParaNumRule_Impl( const SwTxtNode* /*pTxtNd*/, sal_Int32 nLvl, sal_Int32 nNumId )
    6109             : {
    6110         419 :     if ( USHRT_MAX != nNumId && 0 != nNumId )
    6111             :     {
    6112         401 :         m_pSerializer->startElementNS( XML_w, XML_numPr, FSEND );
    6113         401 :         m_pSerializer->singleElementNS( XML_w, XML_ilvl, FSNS( XML_w, XML_val ), OString::number( nLvl).getStr(), FSEND );
    6114         401 :         m_pSerializer->singleElementNS( XML_w, XML_numId, FSNS( XML_w, XML_val ), OString::number( nNumId).getStr(), FSEND );
    6115         401 :         m_pSerializer->endElementNS( XML_w, XML_numPr );
    6116             :     }
    6117         419 : }
    6118             : 
    6119          18 : void DocxAttributeOutput::ParaScriptSpace( const SfxBoolItem& rScriptSpace )
    6120             : {
    6121             :     m_pSerializer->singleElementNS( XML_w, XML_autoSpaceDE,
    6122          18 :            FSNS( XML_w, XML_val ), rScriptSpace.GetValue( ) ? "true": "false",
    6123          18 :            FSEND );
    6124          18 : }
    6125             : 
    6126          68 : void DocxAttributeOutput::ParaHangingPunctuation( const SfxBoolItem& rItem )
    6127             : {
    6128             :     m_pSerializer->singleElementNS( XML_w, XML_overflowPunct,
    6129          68 :            FSNS( XML_w, XML_val ), rItem.GetValue( ) ? "true": "false",
    6130          68 :            FSEND );
    6131          68 : }
    6132             : 
    6133          18 : void DocxAttributeOutput::ParaForbiddenRules( const SfxBoolItem& rItem )
    6134             : {
    6135             :     m_pSerializer->singleElementNS( XML_w, XML_kinsoku,
    6136          18 :            FSNS( XML_w, XML_val ), rItem.GetValue( ) ? "true": "false",
    6137          18 :            FSEND );
    6138          18 : }
    6139             : 
    6140          33 : void DocxAttributeOutput::ParaVerticalAlign( const SvxParaVertAlignItem& rAlign )
    6141             : {
    6142             :     const char *pAlignString;
    6143             : 
    6144          33 :     switch ( rAlign.GetValue() )
    6145             :     {
    6146             :         case SvxParaVertAlignItem::BASELINE:
    6147          33 :             pAlignString = "baseline";
    6148          33 :             break;
    6149             :         case SvxParaVertAlignItem::TOP:
    6150           0 :             pAlignString = "top";
    6151           0 :             break;
    6152             :         case SvxParaVertAlignItem::CENTER:
    6153           0 :             pAlignString = "center";
    6154           0 :             break;
    6155             :         case SvxParaVertAlignItem::BOTTOM:
    6156           0 :             pAlignString = "bottom";
    6157           0 :             break;
    6158             :         case SvxParaVertAlignItem::AUTOMATIC:
    6159           0 :             pAlignString = "auto";
    6160           0 :             break;
    6161             :         default:
    6162          33 :             return; // not supported attribute
    6163             :     }
    6164          33 :     m_pSerializer->singleElementNS( XML_w, XML_textAlignment, FSNS( XML_w, XML_val ), pAlignString, FSEND );
    6165             : }
    6166             : 
    6167           0 : void DocxAttributeOutput::ParaSnapToGrid( const SvxParaGridItem& rGrid )
    6168             : {
    6169             :     m_pSerializer->singleElementNS( XML_w, XML_snapToGrid,
    6170           0 :             FSNS( XML_w, XML_val ), rGrid.GetValue( ) ? "true": "false",
    6171           0 :             FSEND );
    6172           0 : }
    6173             : 
    6174         528 : void DocxAttributeOutput::FormatFrameSize( const SwFmtFrmSize& rSize )
    6175             : {
    6176         528 :     if (m_rExport.SdrExporter().getTextFrameSyntax() && m_rExport.SdrExporter().getFlyFrameSize())
    6177             :     {
    6178         115 :         const Size* pSize = m_rExport.SdrExporter().getFlyFrameSize();
    6179         115 :         m_rExport.SdrExporter().getTextFrameStyle().append(";width:").append(double(pSize->Width()) / 20);
    6180         115 :         m_rExport.SdrExporter().getTextFrameStyle().append("pt;height:").append(double(pSize->Height()) / 20).append("pt");
    6181             :     }
    6182         413 :     else if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
    6183             :     {
    6184             :     }
    6185         298 :     else if ( m_rExport.bOutFlyFrmAttrs )
    6186             :     {
    6187           0 :         if ( rSize.GetWidth() && rSize.GetWidthSizeType() == ATT_FIX_SIZE )
    6188           0 :             AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(),
    6189           0 :                     FSNS( XML_w, XML_w ), OString::number( rSize.GetWidth( ) ).getStr() );
    6190             : 
    6191           0 :         if ( rSize.GetHeight() )
    6192             :         {
    6193           0 :             OString sRule( "exact" );
    6194           0 :             if ( rSize.GetHeightSizeType() == ATT_MIN_SIZE )
    6195           0 :                 sRule = OString( "atLeast" );
    6196           0 :             AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), 2,
    6197             :                     FSNS( XML_w, XML_hRule ), sRule.getStr(),
    6198           0 :                     FSNS( XML_w, XML_h ), OString::number( rSize.GetHeight( ) ).getStr() );
    6199             :         }
    6200             :     }
    6201         298 :     else if ( m_rExport.bOutPageDescs )
    6202             :     {
    6203         298 :         FastAttributeList *attrList = m_pSerializer->createAttrList( );
    6204         298 :         if ( m_rExport.pAktPageDesc->GetLandscape( ) )
    6205           8 :             attrList->add( FSNS( XML_w, XML_orient ), "landscape" );
    6206             : 
    6207         298 :         attrList->add( FSNS( XML_w, XML_w ), OString::number( rSize.GetWidth( ) ) );
    6208         298 :         attrList->add( FSNS( XML_w, XML_h ), OString::number( rSize.GetHeight( ) ) );
    6209             : 
    6210         298 :         XFastAttributeListRef xAttrList( attrList );
    6211         298 :         attrList = NULL;
    6212             : 
    6213         298 :         m_pSerializer->singleElementNS( XML_w, XML_pgSz, xAttrList );
    6214             :     }
    6215         528 : }
    6216             : 
    6217           0 : void DocxAttributeOutput::FormatPaperBin( const SvxPaperBinItem& )
    6218             : {
    6219             :     OSL_TRACE( "TODO DocxAttributeOutput::FormatPaperBin()" );
    6220           0 : }
    6221             : 
    6222        1936 : void DocxAttributeOutput::FormatLRSpace( const SvxLRSpaceItem& rLRSpace )
    6223             : {
    6224        1936 :     bool bEcma = m_rExport.GetFilter().getVersion( ) == oox::core::ECMA_DIALECT;
    6225             : 
    6226        1936 :     if (m_rExport.SdrExporter().getTextFrameSyntax())
    6227             :     {
    6228         115 :         m_rExport.SdrExporter().getTextFrameStyle().append(";mso-wrap-distance-left:").append(double(rLRSpace.GetLeft()) / 20).append("pt");
    6229         115 :         m_rExport.SdrExporter().getTextFrameStyle().append(";mso-wrap-distance-right:").append(double(rLRSpace.GetRight()) / 20).append("pt");
    6230             :     }
    6231        1821 :     else if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
    6232             :     {
    6233             :     }
    6234        1706 :     else if ( m_rExport.bOutFlyFrmAttrs )
    6235             :     {
    6236           0 :         AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), FSNS( XML_w, XML_hSpace ),
    6237             :                 OString::number(
    6238           0 :                     ( rLRSpace.GetLeft() + rLRSpace.GetRight() ) / 2 ).getStr() );
    6239             :     }
    6240        1706 :     else if ( m_rExport.bOutPageDescs )
    6241             :     {
    6242         298 :         m_pageMargins.nPageMarginLeft = 0;
    6243         298 :         m_pageMargins.nPageMarginRight = 0;
    6244             : 
    6245         298 :         const SfxPoolItem* pItem = m_rExport.HasItem( RES_BOX );
    6246         298 :         if ( pItem )
    6247             :         {
    6248           4 :             m_pageMargins.nPageMarginRight = ((SvxBoxItem*)pItem)->CalcLineSpace( BOX_LINE_LEFT );
    6249           4 :             m_pageMargins.nPageMarginLeft = ((SvxBoxItem*)pItem)->CalcLineSpace( BOX_LINE_RIGHT );
    6250             :         }
    6251             :         else
    6252         294 :             m_pageMargins.nPageMarginLeft = m_pageMargins.nPageMarginRight = 0;
    6253             : 
    6254         298 :         m_pageMargins.nPageMarginLeft = m_pageMargins.nPageMarginLeft + (sal_uInt16)rLRSpace.GetLeft();
    6255         298 :         m_pageMargins.nPageMarginRight = m_pageMargins.nPageMarginRight + (sal_uInt16)rLRSpace.GetRight();
    6256             : 
    6257             :         AddToAttrList( m_pSectionSpacingAttrList, 2,
    6258             :                 FSNS( XML_w, XML_left ), OString::number( m_pageMargins.nPageMarginLeft ).getStr(),
    6259         298 :                 FSNS( XML_w, XML_right ), OString::number( m_pageMargins.nPageMarginRight ).getStr() );
    6260             :     }
    6261             :     else
    6262             :     {
    6263        1408 :         FastAttributeList *pLRSpaceAttrList = m_pSerializer->createAttrList();
    6264        1408 :         if((0 != rLRSpace.GetTxtLeft()) || ((0 == rLRSpace.GetTxtLeft()) && rLRSpace.IsExplicitZeroMarginValLeft()))
    6265             :         {
    6266         807 :             pLRSpaceAttrList->add( FSNS( XML_w, ( bEcma ? XML_left : XML_start ) ), OString::number(  rLRSpace.GetTxtLeft() ) );
    6267             :         }
    6268        1408 :         if((0 != rLRSpace.GetRight()) || ((0 == rLRSpace.GetRight()) && rLRSpace.IsExplicitZeroMarginValRight()))
    6269             :         {
    6270         668 :             pLRSpaceAttrList->add( FSNS( XML_w, ( bEcma ? XML_right : XML_end ) ), OString::number(  rLRSpace.GetRight() ) );
    6271             :         }
    6272        1408 :         sal_Int32 nFirstLineAdjustment = rLRSpace.GetTxtFirstLineOfst();
    6273        1408 :         if (nFirstLineAdjustment > 0)
    6274          74 :             pLRSpaceAttrList->add( FSNS( XML_w, XML_firstLine ), OString::number( nFirstLineAdjustment ) );
    6275             :         else
    6276        1334 :             pLRSpaceAttrList->add( FSNS( XML_w, XML_hanging ), OString::number( - nFirstLineAdjustment ) );
    6277        1408 :         m_pSerializer->singleElementNS( XML_w, XML_ind, pLRSpaceAttrList );
    6278             :     }
    6279        1936 : }
    6280             : 
    6281        4183 : void DocxAttributeOutput::FormatULSpace( const SvxULSpaceItem& rULSpace )
    6282             : {
    6283             : 
    6284        4183 :     if (m_rExport.SdrExporter().getTextFrameSyntax())
    6285             :     {
    6286         114 :         m_rExport.SdrExporter().getTextFrameStyle().append(";mso-wrap-distance-top:").append(double(rULSpace.GetUpper()) / 20).append("pt");
    6287         114 :         m_rExport.SdrExporter().getTextFrameStyle().append(";mso-wrap-distance-bottom:").append(double(rULSpace.GetLower()) / 20).append("pt");
    6288             :     }
    6289        4069 :     else if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
    6290             :     {
    6291             :     }
    6292        3955 :     else if ( m_rExport.bOutFlyFrmAttrs )
    6293             :     {
    6294           0 :         AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), FSNS( XML_w, XML_vSpace ),
    6295             :                 OString::number(
    6296           0 :                     ( rULSpace.GetLower() + rULSpace.GetUpper() ) / 2 ).getStr() );
    6297             :     }
    6298        3955 :     else if (m_rExport.bOutPageDescs )
    6299             :     {
    6300             :         OSL_ENSURE( m_rExport.GetCurItemSet(), "Impossible" );
    6301         298 :         if ( !m_rExport.GetCurItemSet() )
    6302        4183 :             return;
    6303             : 
    6304         298 :         HdFtDistanceGlue aDistances( *m_rExport.GetCurItemSet() );
    6305             : 
    6306         298 :         sal_Int32 nHeader = 0;
    6307         298 :         if ( aDistances.HasHeader() )
    6308          56 :             nHeader = sal_Int32( aDistances.dyaHdrTop );
    6309             : 
    6310             :         // Page top
    6311         298 :         m_pageMargins.nPageMarginTop = aDistances.dyaTop;
    6312             : 
    6313         298 :         sal_Int32 nFooter = 0;
    6314         298 :         if ( aDistances.HasFooter() )
    6315          68 :             nFooter = sal_Int32( aDistances.dyaHdrBottom );
    6316             : 
    6317             :         // Page Bottom
    6318         298 :         m_pageMargins.nPageMarginBottom = aDistances.dyaBottom;
    6319             : 
    6320             :         AddToAttrList( m_pSectionSpacingAttrList, 5,
    6321             :                 FSNS( XML_w, XML_header ), OString::number( nHeader ).getStr(),
    6322             :                 FSNS( XML_w, XML_top ), OString::number( m_pageMargins.nPageMarginTop ).getStr(),
    6323             :                 FSNS( XML_w, XML_footer ), OString::number( nFooter ).getStr(),
    6324             :                 FSNS( XML_w, XML_bottom ), OString::number( m_pageMargins.nPageMarginBottom ).getStr(),
    6325             :                 // FIXME Page Gutter is not handled ATM, setting to 0 as it's mandatory for OOXML
    6326         298 :                 FSNS( XML_w, XML_gutter ), "0" );
    6327             :     }
    6328             :     else
    6329             :     {
    6330             :         SAL_INFO("sw.ww8", "DocxAttributeOutput::FormatULSpace: setting spacing" << rULSpace.GetUpper() );
    6331             :         // check if before auto spacing was set during import and spacing we get from actual object is same
    6332             :         // that we set in import. If yes just write beforeAutoSpacing tag.
    6333        3657 :         if (m_bParaBeforeAutoSpacing && m_nParaBeforeSpacing == rULSpace.GetUpper())
    6334             :         {
    6335             :             AddToAttrList( m_pParagraphSpacingAttrList,
    6336          57 :                     FSNS( XML_w, XML_beforeAutospacing ), "1" );
    6337             :         }
    6338             :         else
    6339             :         {
    6340             :             AddToAttrList( m_pParagraphSpacingAttrList,
    6341        3600 :                     FSNS( XML_w, XML_before ), OString::number( rULSpace.GetUpper() ).getStr() );
    6342             :         }
    6343        3657 :         m_bParaBeforeAutoSpacing = false;
    6344             :         // check if after auto spacing was set during import and spacing we get from actual object is same
    6345             :         // that we set in import. If yes just write afterAutoSpacing tag.
    6346        3657 :         if (m_bParaAfterAutoSpacing && m_nParaAfterSpacing == rULSpace.GetLower())
    6347             :         {
    6348             :             AddToAttrList( m_pParagraphSpacingAttrList,
    6349          57 :                     FSNS( XML_w, XML_afterAutospacing ), "1" );
    6350             :         }
    6351             :         else
    6352             :         {
    6353             :             AddToAttrList( m_pParagraphSpacingAttrList,
    6354        3600 :                     FSNS( XML_w, XML_after ), OString::number( rULSpace.GetLower()).getStr() );
    6355             :         }
    6356        3657 :         m_bParaAfterAutoSpacing = false;
    6357             : 
    6358        3657 :         if (rULSpace.GetContext())
    6359         251 :             m_pSerializer->singleElementNS( XML_w, XML_contextualSpacing, FSEND );
    6360             :     }
    6361             : }
    6362             : 
    6363         230 : void DocxAttributeOutput::FormatSurround( const SwFmtSurround& rSurround )
    6364             : {
    6365         230 :     if (m_rExport.SdrExporter().getTextFrameSyntax())
    6366             :     {
    6367         230 :         OString sType, sSide;
    6368         115 :         switch (rSurround.GetSurround())
    6369             :         {
    6370             :             case SURROUND_NONE:
    6371           0 :                 sType = "topAndBottom";
    6372           0 :                 break;
    6373             :             case SURROUND_PARALLEL:
    6374          26 :                 sType = "square";
    6375          26 :                 break;
    6376             :             case SURROUND_IDEAL:
    6377           8 :                 sType = "square";
    6378           8 :                 sSide = "largest";
    6379           8 :                 break;
    6380             :             case SURROUND_LEFT:
    6381           0 :                 sType = "square";
    6382           0 :                 sSide = "left";
    6383           0 :                 break;
    6384             :             case SURROUND_RIGHT:
    6385           0 :                 sType = "square";
    6386           0 :                 sSide = "right";
    6387           0 :                 break;
    6388             :             case SURROUND_THROUGHT:
    6389             :                 /* empty type and side means throught */
    6390             :             default:
    6391          81 :                 break;
    6392             :         }
    6393         115 :         if (!sType.isEmpty() || !sSide.isEmpty())
    6394             :         {
    6395          34 :             m_rExport.SdrExporter().setFlyWrapAttrList(m_pSerializer->createAttrList());
    6396          34 :             if (!sType.isEmpty())
    6397          34 :                 m_rExport.SdrExporter().getFlyWrapAttrList()->add(XML_type, sType);
    6398          34 :             if (!sSide.isEmpty())
    6399           8 :                 m_rExport.SdrExporter().getFlyWrapAttrList()->add(XML_side, sSide);
    6400         115 :         }
    6401             :     }
    6402         115 :     else if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
    6403             :     {
    6404             :     }
    6405           0 :     else if ( m_rExport.bOutFlyFrmAttrs )
    6406             :     {
    6407           0 :         OString sWrap( "auto" );
    6408           0 :         switch ( rSurround.GetSurround( ) )
    6409             :         {
    6410             :             case SURROUND_NONE:
    6411           0 :                 sWrap = OString( "none" );
    6412           0 :                 break;
    6413             :             case SURROUND_THROUGHT:
    6414           0 :                 sWrap = OString( "through" );
    6415           0 :                 break;
    6416             :             case SURROUND_IDEAL:
    6417             :             case SURROUND_PARALLEL:
    6418             :             case SURROUND_LEFT:
    6419             :             case SURROUND_RIGHT:
    6420             :             default:
    6421           0 :                 sWrap = OString( "around" );
    6422             :         }
    6423             : 
    6424           0 :         AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), FSNS( XML_w, XML_wrap ), sWrap.getStr() );
    6425             :     }
    6426         230 : }
    6427             : 
    6428         230 : void DocxAttributeOutput::FormatVertOrientation( const SwFmtVertOrient& rFlyVert )
    6429             : {
    6430         230 :     if (m_rExport.SdrExporter().getTextFrameSyntax())
    6431             :     {
    6432         115 :         m_rExport.SdrExporter().getTextFrameStyle().append(";margin-top:").append(double(rFlyVert.GetPos()) / 20).append("pt");
    6433             :     }
    6434         115 :     else if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
    6435             :     {
    6436             :     }
    6437           0 :     else if ( m_rExport.bOutFlyFrmAttrs )
    6438             :     {
    6439           0 :         OString sAlign;
    6440           0 :         switch( rFlyVert.GetVertOrient() )
    6441             :         {
    6442             :             case text::VertOrientation::NONE:
    6443           0 :                 break;
    6444             :             case text::VertOrientation::CENTER:
    6445             :             case text::VertOrientation::LINE_CENTER:
    6446           0 :                 sAlign = OString( "center" );
    6447           0 :                 break;
    6448             :             case text::VertOrientation::BOTTOM:
    6449             :             case text::VertOrientation::LINE_BOTTOM:
    6450           0 :                 sAlign = OString( "bottom" );
    6451           0 :                 break;
    6452             :             case text::VertOrientation::TOP:
    6453             :             case text::VertOrientation::LINE_TOP:
    6454             :             default:
    6455           0 :                 sAlign = OString( "top" );
    6456           0 :                 break;
    6457             :         }
    6458             : 
    6459           0 :         if ( !sAlign.isEmpty() )
    6460           0 :             AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), FSNS( XML_w, XML_yAlign ), sAlign.getStr() );
    6461             :         else
    6462           0 :             AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), FSNS( XML_w, XML_y ),
    6463           0 :                 OString::number( rFlyVert.GetPos() ).getStr() );
    6464             : 
    6465           0 :         OString sVAnchor( "page" );
    6466           0 :         switch ( rFlyVert.GetRelationOrient( ) )
    6467             :         {
    6468             :             case text::RelOrientation::CHAR:
    6469             :             case text::RelOrientation::PRINT_AREA:
    6470             :             case text::RelOrientation::TEXT_LINE:
    6471           0 :                 sVAnchor = OString( "column" );
    6472           0 :                 break;
    6473             :             case text::RelOrientation::FRAME:
    6474             :             case text::RelOrientation::PAGE_LEFT:
    6475             :             case text::RelOrientation::PAGE_RIGHT:
    6476             :             case text::RelOrientation::FRAME_LEFT:
    6477             :             case text::RelOrientation::FRAME_RIGHT:
    6478           0 :                 sVAnchor = OString( "margin" );
    6479           0 :                 break;
    6480             :             case text::RelOrientation::PAGE_FRAME:
    6481             :             case text::RelOrientation::PAGE_PRINT_AREA:
    6482             :             default:
    6483           0 :                 break;
    6484             :         }
    6485             : 
    6486           0 :         AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), FSNS( XML_w, XML_vAnchor ), sVAnchor.getStr() );
    6487             :     }
    6488         230 : }
    6489             : 
    6490         230 : void DocxAttributeOutput::FormatHorizOrientation( const SwFmtHoriOrient& rFlyHori )
    6491             : {
    6492         230 :     if (m_rExport.SdrExporter().getTextFrameSyntax())
    6493             :     {
    6494         115 :         m_rExport.SdrExporter().getTextFrameStyle().append(";margin-left:").append(double(rFlyHori.GetPos()) / 20).append("pt");
    6495             :     }
    6496         115 :     else if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
    6497             :     {
    6498             :     }
    6499           0 :     else if ( m_rExport.bOutFlyFrmAttrs )
    6500             :     {
    6501           0 :         OString sAlign;
    6502           0 :         switch( rFlyHori.GetHoriOrient() )
    6503             :         {
    6504             :             case text::HoriOrientation::NONE:
    6505           0 :                 break;
    6506             :             case text::HoriOrientation::LEFT:
    6507           0 :                 sAlign = OString( rFlyHori.IsPosToggle( ) ? "inside" : "left" );
    6508           0 :                 break;
    6509             :             case text::HoriOrientation::RIGHT:
    6510           0 :                 sAlign = OString( rFlyHori.IsPosToggle( ) ? "outside" : "right" );
    6511           0 :                 break;
    6512             :             case text::HoriOrientation::CENTER:
    6513             :             case text::HoriOrientation::FULL: // FULL only for tables
    6514             :             default:
    6515           0 :                 sAlign = OString( "center" );
    6516           0 :                 break;
    6517             :         }
    6518             : 
    6519           0 :         if ( !sAlign.isEmpty() )
    6520           0 :             AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), FSNS( XML_w, XML_xAlign ), sAlign.getStr() );
    6521             :         else
    6522           0 :             AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), FSNS( XML_w, XML_x ),
    6523           0 :                 OString::number( rFlyHori.GetPos() ).getStr() );
    6524             : 
    6525           0 :         OString sHAnchor( "page" );
    6526           0 :         switch ( rFlyHori.GetRelationOrient( ) )
    6527             :         {
    6528             :             case text::RelOrientation::CHAR:
    6529             :             case text::RelOrientation::PRINT_AREA:
    6530           0 :                 sHAnchor = OString( "text" );
    6531           0 :                 break;
    6532             :             case text::RelOrientation::FRAME:
    6533             :             case text::RelOrientation::PAGE_LEFT:
    6534             :             case text::RelOrientation::PAGE_RIGHT:
    6535             :             case text::RelOrientation::FRAME_LEFT:
    6536             :             case text::RelOrientation::FRAME_RIGHT:
    6537           0 :                 sHAnchor = OString( "margin" );
    6538           0 :                 break;
    6539             :             case text::RelOrientation::PAGE_FRAME:
    6540             :             case text::RelOrientation::PAGE_PRINT_AREA:
    6541             :             default:
    6542           0 :                 break;
    6543             :         }
    6544             : 
    6545           0 :         AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), FSNS( XML_w, XML_hAnchor ), sHAnchor.getStr() );
    6546             :     }
    6547         230 : }
    6548             : 
    6549         230 : void DocxAttributeOutput::FormatAnchor( const SwFmtAnchor& )
    6550             : {
    6551             :     // Fly frames: anchors here aren't matching the anchors in docx
    6552         230 : }
    6553             : 
    6554         191 : boost::optional<sal_Int32> lcl_getDmlAlpha(const SvxBrushItem& rBrush)
    6555             : {
    6556         191 :     boost::optional<sal_Int32> oRet;
    6557         191 :     sal_Int32 nTransparency = rBrush.GetColor().GetTransparency();
    6558         191 :     if (nTransparency)
    6559             :     {
    6560             :         // Convert transparency to percent
    6561          21 :         sal_Int8 nTransparencyPercent = SvxBrushItem::TransparencyToPercent(nTransparency);
    6562             : 
    6563             :         // Calculate alpha value
    6564             :         // Consider oox/source/drawingml/color.cxx : getTransparency() function.
    6565          21 :         sal_Int32 nAlpha = (::oox::drawingml::MAX_PERCENT - ( ::oox::drawingml::PER_PERCENT * nTransparencyPercent ) );
    6566          21 :         oRet = nAlpha;
    6567             :     }
    6568         191 :     return oRet;
    6569             : }
    6570             : 
    6571         191 : void DocxAttributeOutput::FormatBackground( const SvxBrushItem& rBrush )
    6572             : {
    6573         191 :     OString sColor = msfilter::util::ConvertColor( rBrush.GetColor().GetRGBColor() );
    6574         382 :     boost::optional<sal_Int32> oAlpha = lcl_getDmlAlpha(rBrush);
    6575         191 :     if (m_rExport.SdrExporter().getTextFrameSyntax())
    6576             :     {
    6577             :         // Handle 'Opacity'
    6578          81 :         if (oAlpha)
    6579             :         {
    6580             :             // Calculate opacity value
    6581             :             // Consider oox/source/vml/vmlformatting.cxx : decodeColor() function.
    6582          10 :             double fOpacity = (double)(*oAlpha) * 65535 / ::oox::drawingml::MAX_PERCENT;
    6583          10 :             OUString sOpacity = OUString::number(fOpacity) + "f";
    6584             : 
    6585          10 :             AddToAttrList( m_rExport.SdrExporter().getFlyFillAttrList(), XML_opacity, OUStringToOString(sOpacity, RTL_TEXTENCODING_UTF8).getStr() );
    6586             :         }
    6587             : 
    6588          81 :         sColor = "#" + sColor;
    6589          81 :         AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), XML_fillcolor, sColor.getStr() );
    6590             :     }
    6591         110 :     else if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
    6592             :     {
    6593          81 :         bool bImageBackground = false;
    6594          81 :         const SfxPoolItem* pItem = GetExport().HasItem(XATTR_FILLSTYLE);
    6595          81 :         if (pItem)
    6596             :         {
    6597          81 :             const XFillStyleItem* pFillStyle = static_cast<const XFillStyleItem*>(pItem);
    6598          81 :             if(pFillStyle->GetValue() == XFILL_BITMAP)
    6599             :             {
    6600           0 :                 bImageBackground = true;
    6601             :             }
    6602             :         }
    6603          81 :         if (!bImageBackground)
    6604             :         {
    6605          81 :             m_pSerializer->startElementNS(XML_a, XML_solidFill, FSEND);
    6606             :             m_pSerializer->startElementNS(XML_a, XML_srgbClr,
    6607             :                                           XML_val, sColor,
    6608          81 :                                           FSEND);
    6609          81 :             if (oAlpha)
    6610             :                 m_pSerializer->singleElementNS(XML_a, XML_alpha,
    6611          10 :                                               XML_val, OString::number(*oAlpha),
    6612          10 :                                               FSEND);
    6613          81 :             m_pSerializer->endElementNS(XML_a, XML_srgbClr);
    6614          81 :             m_pSerializer->endElementNS(XML_a, XML_solidFill);
    6615             :         }
    6616             :     }
    6617          29 :     else if ( !m_rExport.bOutPageDescs )
    6618             :     {
    6619          24 :         if( !m_pBackgroundAttrList )
    6620          16 :             m_pBackgroundAttrList = m_pSerializer->createAttrList();
    6621             : 
    6622             :         // compare fill color with the original fill color
    6623             :         OString sOriginalFill = rtl::OUStringToOString(
    6624          24 :                 m_pBackgroundAttrList->getOptionalValue( FSNS( XML_w, XML_fill ) ), RTL_TEXTENCODING_UTF8 );
    6625          24 :         if( sOriginalFill.isEmpty() )
    6626             :         {
    6627          16 :             m_pBackgroundAttrList->add( FSNS( XML_w, XML_fill ), sColor.getStr() );
    6628             :         }
    6629           8 :         else if ( sOriginalFill != sColor )
    6630             :         {
    6631             :             // fill was modified during edition, theme fill attribute must be dropped
    6632           0 :             delete m_pBackgroundAttrList;
    6633           0 :             m_pBackgroundAttrList = m_pSerializer->createAttrList();
    6634           0 :             m_pBackgroundAttrList->add( FSNS( XML_w, XML_fill ), sColor.getStr() );
    6635             :         }
    6636          24 :         m_pBackgroundAttrList->add( FSNS( XML_w, XML_val ), "clear" );
    6637         191 :     }
    6638         191 : }
    6639             : 
    6640         643 : void DocxAttributeOutput::FormatFillStyle( const XFillStyleItem& rFillStyle )
    6641             : {
    6642         643 :     if (!m_bIgnoreNextFill)
    6643         528 :         m_oFillStyle.reset(rFillStyle.GetValue());
    6644             :     else
    6645         115 :         m_bIgnoreNextFill = false;
    6646         643 : }
    6647             : 
    6648          33 : void DocxAttributeOutput::FormatFillGradient( const XFillGradientItem& rFillGradient )
    6649             : {
    6650          33 :     if (m_oFillStyle && *m_oFillStyle == XFILL_GRADIENT && !m_rExport.SdrExporter().getDMLTextFrameSyntax())
    6651             :     {
    6652          11 :         AddToAttrList( m_rExport.SdrExporter().getFlyFillAttrList(), XML_type, "gradient" );
    6653             : 
    6654          11 :         const XGradient& rGradient = rFillGradient.GetGradientValue();
    6655          11 :         OString sStartColor = msfilter::util::ConvertColor(rGradient.GetStartColor());
    6656          22 :         OString sEndColor = msfilter::util::ConvertColor(rGradient.GetEndColor());
    6657             : 
    6658             :         // Calculate the angle that was originally in the imported DOCX file
    6659             :         // (reverse calculate the angle that was converted in the file
    6660             :         //     /oox/source/vml/vmlformatting.cxx :: FillModel::pushToPropMap
    6661             :         // and also in
    6662             :         //     /oox/source/drawingml/fillproperties.cxx :: FillProperties::pushToPropMap
    6663          11 :         sal_Int32 nReverseAngle = 4500 - rGradient.GetAngle();
    6664          11 :         nReverseAngle = nReverseAngle / 10;
    6665          11 :         nReverseAngle = (270 - nReverseAngle) % 360;
    6666          11 :         if (nReverseAngle != 0)
    6667           8 :             AddToAttrList( m_rExport.SdrExporter().getFlyFillAttrList(),
    6668          16 :                     XML_angle, OString::number( nReverseAngle ).getStr() );
    6669             : 
    6670          22 :         OString sColor1 = sStartColor;
    6671          22 :         OString sColor2 = sEndColor;
    6672             : 
    6673          11 :         switch (rGradient.GetGradientStyle())
    6674             :         {
    6675             :             case XGRAD_AXIAL:
    6676           3 :                 AddToAttrList( m_rExport.SdrExporter().getFlyFillAttrList(), XML_focus, "50%" );
    6677             :                 // If it is an 'axial' gradient - swap the colors
    6678             :                 // (because in the import process they were imported swapped)
    6679           3 :                 sColor1 = sEndColor;
    6680           3 :                 sColor2 = sStartColor;
    6681           3 :                 break;
    6682           8 :             case XGRAD_LINEAR: break;
    6683           0 :             case XGRAD_RADIAL: break;
    6684           0 :             case XGRAD_ELLIPTICAL: break;
    6685           0 :             case XGRAD_SQUARE: break;
    6686           0 :             case XGRAD_RECT: break;
    6687             :         }
    6688             : 
    6689          11 :         sColor1 = "#" + sColor1;
    6690          11 :         sColor2 = "#" + sColor2;
    6691          11 :         AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), XML_fillcolor, sColor1.getStr() );
    6692          22 :         AddToAttrList( m_rExport.SdrExporter().getFlyFillAttrList(), XML_color2, sColor2.getStr() );
    6693             :     }
    6694          22 :     else if (m_oFillStyle && *m_oFillStyle == XFILL_GRADIENT && m_rExport.SdrExporter().getDMLTextFrameSyntax())
    6695             :     {
    6696          11 :         uno::Reference<beans::XPropertySet> xPropertySet = SwXFrames::GetObject(const_cast<SwFrmFmt&>(m_rExport.mpParentFrame->GetFrmFmt()), FLYCNTTYPE_FRM);
    6697          11 :         m_rDrawingML.SetFS(m_pSerializer);
    6698          11 :         m_rDrawingML.WriteGradientFill(xPropertySet);
    6699             :     }
    6700          33 :     m_oFillStyle.reset();
    6701          33 : }
    6702             : 
    6703         300 : void DocxAttributeOutput::FormatBox( const SvxBoxItem& rBox )
    6704             : {
    6705         300 :     if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
    6706             :     {
    6707             :         // <a:gradFill> should be before <a:ln>.
    6708         115 :         const SfxPoolItem* pItem = GetExport().HasItem(XATTR_FILLSTYLE);
    6709         115 :         if (pItem)
    6710             :         {
    6711         115 :             const XFillStyleItem* pFillStyle = static_cast<const XFillStyleItem*>(pItem);
    6712         115 :             FormatFillStyle(*pFillStyle);
    6713         115 :             if (m_oFillStyle && *m_oFillStyle == XFILL_BITMAP)
    6714             :             {
    6715           1 :                 const SdrObject* pSdrObj = m_rExport.mpParentFrame->GetFrmFmt().FindRealSdrObject();
    6716           1 :                 if (pSdrObj)
    6717             :                 {
    6718           1 :                     uno::Reference< drawing::XShape > xShape( ((SdrObject*)pSdrObj)->getUnoShape(), uno::UNO_QUERY );
    6719           2 :                     uno::Reference< beans::XPropertySet > xPropertySet( xShape, uno::UNO_QUERY );
    6720           1 :                     m_rDrawingML.SetFS(m_pSerializer);
    6721           2 :                     m_rDrawingML.WriteBlipFill( xPropertySet, "BackGraphicURL" );
    6722             :                 }
    6723             :             }
    6724             :         }
    6725             : 
    6726         115 :         pItem = GetExport().HasItem(XATTR_FILLGRADIENT);
    6727         115 :         if (pItem)
    6728             :         {
    6729          11 :             const XFillGradientItem* pFillGradient = static_cast<const XFillGradientItem*>(pItem);
    6730          11 :             FormatFillGradient(*pFillGradient);
    6731             :         }
    6732         115 :         m_bIgnoreNextFill = true;
    6733             :     }
    6734         300 :     if (m_rExport.SdrExporter().getTextFrameSyntax() || m_rExport.SdrExporter().getDMLTextFrameSyntax())
    6735             :     {
    6736         230 :         const SvxBorderLine* pLeft = rBox.GetLeft( );
    6737         230 :         const SvxBorderLine* pTop = rBox.GetTop( );
    6738         230 :         const SvxBorderLine* pRight = rBox.GetRight( );
    6739         230 :         const SvxBorderLine* pBottom = rBox.GetBottom( );
    6740             : 
    6741         626 :         if (pLeft && pRight && pTop && pBottom &&
    6742         626 :                 *pLeft == *pRight && *pLeft == *pTop && *pLeft == *pBottom)
    6743             :         {
    6744             :             // Check border style
    6745         198 :             editeng::SvxBorderStyle eBorderStyle = pTop->GetBorderLineStyle();
    6746         198 :             if (eBorderStyle == table::BorderLineStyle::NONE)
    6747             :             {
    6748          24 :                 if (m_rExport.SdrExporter().getTextFrameSyntax())
    6749             :                 {
    6750          12 :                     AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), 2,
    6751          12 :                             XML_stroked, "f", XML_strokeweight, "0pt" );
    6752             :                 }
    6753             :             }
    6754             :             else
    6755             :             {
    6756         174 :                 OString sColor(msfilter::util::ConvertColor(pTop->GetColor()));
    6757         174 :                 double const fConverted(editeng::ConvertBorderWidthToWord(pTop->GetBorderLineStyle(), pTop->GetWidth()));
    6758             : 
    6759         174 :                 if (m_rExport.SdrExporter().getTextFrameSyntax())
    6760             :                 {
    6761          87 :                     sColor = "#" + sColor;
    6762          87 :                     sal_Int32 nWidth = sal_Int32(fConverted / 20);
    6763          87 :                     OString sWidth = OString::number(nWidth) + "pt";
    6764          87 :                     AddToAttrList( m_rExport.SdrExporter().getFlyAttrList(), 2,
    6765             :                             XML_strokecolor, sColor.getStr(),
    6766         174 :                             XML_strokeweight, sWidth.getStr() );
    6767          87 :                     if( LineStyle_DASH == pTop->GetBorderLineStyle() ) // Line Style is Dash type
    6768           5 :                         AddToAttrList( m_rExport.SdrExporter().getDashLineStyle(),
    6769           5 :                             XML_dashstyle, "dash" );
    6770             :                 }
    6771             :                 else
    6772             :                 {
    6773          87 :                     OString sWidth(OString::number(TwipsToEMU(fConverted)));
    6774             :                     m_pSerializer->startElementNS(XML_a, XML_ln,
    6775             :                             XML_w, sWidth.getStr(),
    6776          87 :                             FSEND);
    6777          87 :                     m_pSerializer->startElementNS(XML_a, XML_solidFill, FSEND);
    6778             :                     m_pSerializer->singleElementNS(XML_a, XML_srgbClr,
    6779             :                             XML_val, sColor,
    6780          87 :                             FSEND);
    6781          87 :                     m_pSerializer->endElementNS(XML_a, XML_solidFill);
    6782          87 :                     if( LineStyle_DASH == pTop->GetBorderLineStyle() ) // Line Style is Dash type
    6783           5 :                         m_pSerializer->singleElementNS(XML_a, XML_prstDash, XML_val, "dash", FSEND);
    6784          87 :                     m_pSerializer->endElementNS(XML_a, XML_ln);
    6785         174 :                 }
    6786             :             }
    6787             :         }
    6788             : 
    6789         230 :         if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
    6790             :         {
    6791         115 :             m_rExport.SdrExporter().getBodyPrAttrList()->add(XML_lIns, OString::number(TwipsToEMU(rBox.GetDistance(BOX_LINE_LEFT))));
    6792         115 :             m_rExport.SdrExporter().getBodyPrAttrList()->add(XML_tIns, OString::number(TwipsToEMU(rBox.GetDistance(BOX_LINE_TOP))));
    6793         115 :             m_rExport.SdrExporter().getBodyPrAttrList()->add(XML_rIns, OString::number(TwipsToEMU(rBox.GetDistance(BOX_LINE_RIGHT))));
    6794         115 :             m_rExport.SdrExporter().getBodyPrAttrList()->add(XML_bIns, OString::number(TwipsToEMU(rBox.GetDistance(BOX_LINE_BOTTOM))));
    6795         115 :             return;
    6796             :         }
    6797             : 
    6798             :         // v:textbox's inset attribute: inner margin values for textbox text - write only non-default values
    6799         115 :         double fDistanceLeftTwips = double(rBox.GetDistance(BOX_LINE_LEFT));
    6800         115 :         double fDistanceTopTwips = double(rBox.GetDistance(BOX_LINE_TOP));
    6801         115 :         double fDistanceRightTwips = double(rBox.GetDistance(BOX_LINE_RIGHT));
    6802         115 :         double fDistanceBottomTwips = double(rBox.GetDistance(BOX_LINE_BOTTOM));
    6803             : 
    6804             :         // Convert 'TWIPS' to 'INCH' (because in Word the default values are in Inches)
    6805         115 :         double fDistanceLeftInch = fDistanceLeftTwips / 1440;
    6806         115 :         double fDistanceTopInch = fDistanceTopTwips / 1440;
    6807         115 :         double fDistanceRightInch = fDistanceRightTwips / 1440;
    6808         115 :         double fDistanceBottomInch = fDistanceBottomTwips / 1440;
    6809             : 
    6810             :         // This code will write ONLY the non-default values. The values are in 'left','top','right','bottom' order.
    6811             :         // so 'bottom' is checked if it is default and if it is non-default - all the values will be written
    6812             :         // otherwise - 'right' is checked if it is default and if it is non-default - all the values except for 'bottom' will be written
    6813             :         // and so on.
    6814         115 :         OStringBuffer aInset;
    6815         115 :         if(!aInset.isEmpty() || fDistanceBottomInch != double(0.05))
    6816          59 :             aInset.insert(0, "," + OString::number(fDistanceBottomInch) + "in");
    6817             : 
    6818         115 :         if(!aInset.isEmpty() || fDistanceRightInch != double(0.1))
    6819          60 :             aInset.insert(0, "," + OString::number(fDistanceRightInch) + "in");
    6820             : 
    6821         115 :         if(!aInset.isEmpty() || fDistanceTopInch != double(0.05))
    6822          60 :             aInset.insert(0, "," + OString::number(fDistanceTopInch) + "in");
    6823             : 
    6824         115 :         if(!aInset.isEmpty() || fDistanceLeftInch != double(0.1))
    6825          61 :             aInset.insert(0, OString::number(fDistanceLeftInch) + "in");
    6826             : 
    6827         115 :         if (!aInset.isEmpty())
    6828          61 :             m_rExport.SdrExporter().getTextboxAttrList()->add(XML_inset, aInset.makeStringAndClear());
    6829             : 
    6830         115 :         return;
    6831             :     }
    6832             : 
    6833          70 :     OutputBorderOptions aOutputBorderOptions = lcl_getBoxBorderOptions();
    6834             :     // Check if there is a shadow item
    6835          70 :     const SfxPoolItem* pItem = GetExport().HasItem( RES_SHADOW );
    6836          70 :     if ( pItem )
    6837             :     {
    6838           4 :         const SvxShadowItem* pShadowItem = (const SvxShadowItem*)pItem;
    6839           4 :         aOutputBorderOptions.aShadowLocation = pShadowItem->GetLocation();
    6840             :     }
    6841             : 
    6842          70 :     if ( !m_bOpenedSectPr || GetWritingHeaderFooter())
    6843             :     {
    6844             :         // Not inside a section
    6845             : 
    6846             :         // Open the paragraph's borders tag
    6847          66 :         m_pSerializer->startElementNS( XML_w, XML_pBdr, FSEND );
    6848             : 
    6849          66 :         std::map<sal_uInt16, css::table::BorderLine2> aEmptyMap; // empty styles map
    6850             :         impl_borders( m_pSerializer, rBox, aOutputBorderOptions, &m_pageMargins,
    6851          66 :                       aEmptyMap );
    6852             : 
    6853             :         // Close the paragraph's borders tag
    6854          66 :         m_pSerializer->endElementNS( XML_w, XML_pBdr );
    6855             :     }
    6856             : }
    6857             : 
    6858           9 : void DocxAttributeOutput::FormatColumns_Impl( sal_uInt16 nCols, const SwFmtCol& rCol, bool bEven, SwTwips nPageSize )
    6859             : {
    6860             :     // Get the columns attributes
    6861           9 :     FastAttributeList *pColsAttrList = m_pSerializer->createAttrList();
    6862             : 
    6863             :     pColsAttrList->add( FSNS( XML_w, XML_num ),
    6864           9 :             OString::number( nCols ). getStr( ) );
    6865             : 
    6866           9 :     const char* pEquals = "false";
    6867           9 :     if ( bEven )
    6868             :     {
    6869           6 :         sal_uInt16 nWidth = rCol.GetGutterWidth( true );
    6870             :         pColsAttrList->add( FSNS( XML_w, XML_space ),
    6871           6 :                OString::number( nWidth ).getStr( ) );
    6872             : 
    6873           6 :         pEquals = "true";
    6874             :     }
    6875             : 
    6876           9 :     pColsAttrList->add( FSNS( XML_w, XML_equalWidth ), pEquals );
    6877             : 
    6878           9 :     bool bHasSep = (COLADJ_NONE != rCol.GetLineAdj());
    6879             : 
    6880           9 :     pColsAttrList->add( FSNS( XML_w, XML_sep ), bHasSep ? "true" : "false" );
    6881             : 
    6882             :     // Write the element
    6883           9 :     m_pSerializer->startElementNS( XML_w, XML_cols, pColsAttrList );
    6884             : 
    6885             :     // Write the columns width if non-equals
    6886           9 :     const SwColumns & rColumns = rCol.GetColumns(  );
    6887           9 :     if ( !bEven )
    6888             :     {
    6889          13 :         for ( sal_uInt16 n = 0; n < nCols; ++n )
    6890             :         {
    6891          10 :             FastAttributeList *pColAttrList = m_pSerializer->createAttrList();
    6892          10 :             sal_uInt16 nWidth = rCol.CalcPrtColWidth( n, ( sal_uInt16 ) nPageSize );
    6893             :             pColAttrList->add( FSNS( XML_w, XML_w ),
    6894          10 :                     OString::number( nWidth ).getStr( ) );
    6895             : 
    6896          10 :             if ( n + 1 != nCols )
    6897             :             {
    6898           7 :                 sal_uInt16 nSpacing = rColumns[n].GetRight( ) + rColumns[n + 1].GetLeft( );
    6899             :                 pColAttrList->add( FSNS( XML_w, XML_space ),
    6900           7 :                     OString::number( nSpacing ).getStr( ) );
    6901             :             }
    6902             : 
    6903          10 :             m_pSerializer->singleElementNS( XML_w, XML_col, pColAttrList );
    6904             :         }
    6905             :     }
    6906             : 
    6907           9 :     m_pSerializer->endElementNS( XML_w, XML_cols );
    6908           9 : }
    6909             : 
    6910         545 : void DocxAttributeOutput::FormatKeep( const SvxFmtKeepItem& )
    6911             : {
    6912         545 :     m_pSerializer->singleElementNS( XML_w, XML_keepNext, FSEND );
    6913         545 : }
    6914             : 
    6915         282 : void DocxAttributeOutput::FormatTextGrid( const SwTextGridItem& rGrid )
    6916             : {
    6917         282 :     FastAttributeList *pGridAttrList = m_pSerializer->createAttrList();
    6918             : 
    6919         282 :     OString sGridType;
    6920         282 :     switch ( rGrid.GetGridType( ) )
    6921             :     {
    6922             :         default:
    6923             :         case GRID_NONE:
    6924         282 :             sGridType = OString( "default" );
    6925         282 :             break;
    6926             :         case GRID_LINES_ONLY:
    6927           0 :             sGridType = OString( "lines" );
    6928           0 :             break;
    6929             :         case GRID_LINES_CHARS:
    6930           0 :             if ( rGrid.IsSnapToChars( ) )
    6931           0 :                 sGridType = OString( "snapToChars" );
    6932             :             else
    6933           0 :                 sGridType = OString( "linesAndChars" );
    6934           0 :             break;
    6935             :     }
    6936         282 :     pGridAttrList->add( FSNS( XML_w, XML_type ), sGridType.getStr( ) );
    6937             : 
    6938         282 :     sal_uInt16 nHeight = rGrid.GetBaseHeight() + rGrid.GetRubyHeight();
    6939             :     pGridAttrList->add( FSNS( XML_w, XML_linePitch ),
    6940         282 :             OString::number( nHeight ).getStr( ) );
    6941             : 
    6942             :     pGridAttrList->add( FSNS( XML_w, XML_charSpace ),
    6943         282 :             OString::number( GridCharacterPitch( rGrid ) ).getStr( ) );
    6944             : 
    6945         282 :     m_pSerializer->singleElementNS( XML_w, XML_docGrid, pGridAttrList );
    6946         282 : }
    6947             : 
    6948         562 : void DocxAttributeOutput::FormatLineNumbering( const SwFmtLineNumber& rNumbering )
    6949             : {
    6950         562 :     if ( !rNumbering.IsCount( ) )
    6951         559 :         m_pSerializer->singleElementNS( XML_w, XML_suppressLineNumbers, FSEND );
    6952         562 : }
    6953             : 
    6954         787 : void DocxAttributeOutput::FormatFrameDirection( const SvxFrameDirectionItem& rDirection )
    6955             : {
    6956         787 :     OString sTextFlow;
    6957         787 :     bool bBiDi = false;
    6958         787 :     short nDir = rDirection.GetValue();
    6959             : 
    6960         787 :     if ( nDir == FRMDIR_ENVIRONMENT )
    6961          15 :         nDir = GetExport( ).GetDefaultFrameDirection( );
    6962             : 
    6963         787 :     switch ( nDir )
    6964             :     {
    6965             :         default:
    6966             :         case FRMDIR_HORI_LEFT_TOP:
    6967         779 :             sTextFlow = OString( "lrTb" );
    6968         779 :             break;
    6969             :         case FRMDIR_HORI_RIGHT_TOP:
    6970           8 :             sTextFlow = OString( "lrTb" );
    6971           8 :             bBiDi = true;
    6972           8 :             break;
    6973             :         case FRMDIR_VERT_TOP_LEFT: // many things but not this one
    6974             :         case FRMDIR_VERT_TOP_RIGHT:
    6975           0 :             sTextFlow = OString( "tbRl" );
    6976           0 :             break;
    6977             :     }
    6978             : 
    6979         787 :     if ( m_rExport.bOutPageDescs )
    6980             :     {
    6981             :         m_pSerializer->singleElementNS( XML_w, XML_textDirection,
    6982             :                FSNS( XML_w, XML_val ), sTextFlow.getStr( ),
    6983         298 :                FSEND );
    6984         298 :         if ( bBiDi )
    6985           4 :             m_pSerializer->singleElementNS( XML_w, XML_bidi, FSEND );
    6986             :     }
    6987         489 :     else if ( !m_rExport.bOutFlyFrmAttrs )
    6988             :     {
    6989         489 :         if ( bBiDi )
    6990           4 :             m_pSerializer->singleElementNS( XML_w, XML_bidi, FSNS( XML_w, XML_val ), "1", FSEND );
    6991             :         else
    6992         485 :             m_pSerializer->singleElementNS( XML_w, XML_bidi, FSNS( XML_w, XML_val ), "0", FSEND );
    6993         787 :     }
    6994         787 : }
    6995             : 
    6996         374 : void DocxAttributeOutput::ParaGrabBag(const SfxGrabBagItem& rItem)
    6997             : {
    6998         374 :     const std::map<OUString, com::sun::star::uno::Any>& rMap = rItem.GetGrabBag();
    6999         532 :     for (std::map<OUString, com::sun::star::uno::Any>::const_iterator i = rMap.begin(); i != rMap.end(); ++i)
    7000             :     {
    7001         158 :         if (i->first == "MirrorIndents")
    7002           1 :             m_pSerializer->singleElementNS(XML_w, XML_mirrorIndents, FSEND);
    7003         157 :         else if (i->first == "ParaTopMarginBeforeAutoSpacing")
    7004             :         {
    7005          57 :             m_bParaBeforeAutoSpacing = true;
    7006             :             // get fixed value which was set during import
    7007          57 :             i->second >>= m_nParaBeforeSpacing;
    7008          57 :             m_nParaBeforeSpacing = MM100_TO_TWIP(m_nParaBeforeSpacing);
    7009             :             SAL_INFO("sw.ww8", "DocxAttributeOutput::ParaGrabBag: property =" << i->first << " : m_nParaBeforeSpacing= " << m_nParaBeforeSpacing);
    7010             :         }
    7011         100 :         else if (i->first == "ParaBottomMarginAfterAutoSpacing")
    7012             :         {
    7013          57 :             m_bParaAfterAutoSpacing = true;
    7014             :             // get fixed value which was set during import
    7015          57 :             i->second >>= m_nParaAfterSpacing;
    7016          57 :             m_nParaAfterSpacing = MM100_TO_TWIP(m_nParaAfterSpacing);
    7017             :             SAL_INFO("sw.ww8", "DocxAttributeOutput::ParaGrabBag: property =" << i->first << " : m_nParaBeforeSpacing= " << m_nParaAfterSpacing);
    7018             :         }
    7019          43 :         else if (i->first == "CharThemeFill")
    7020             :         {
    7021           8 :             uno::Sequence<beans::PropertyValue> aGrabBagSeq;
    7022           8 :             i->second >>= aGrabBagSeq;
    7023          16 :             OUString sThemeFill, sOriginalFill;
    7024          33 :             for (sal_Int32 j=0; j < aGrabBagSeq.getLength(); ++j)
    7025             :             {
    7026          25 :                 if (aGrabBagSeq[j].Name == "themeFill")
    7027           1 :                     aGrabBagSeq[j].Value >>= sThemeFill;
    7028          24 :                 else if (aGrabBagSeq[j].Name == "fill")
    7029           8 :                     aGrabBagSeq[j].Value >>= sOriginalFill;
    7030             :             }
    7031             :             AddToAttrList(m_pBackgroundAttrList, 2,
    7032             :                     FSNS(XML_w, XML_themeFill), OUStringToOString(sThemeFill, RTL_TEXTENCODING_UTF8).getStr(),
    7033          16 :                     FSNS(XML_w, XML_fill), OUStringToOString(sOriginalFill, RTL_TEXTENCODING_UTF8).getStr());
    7034             :         }
    7035          35 :         else if (i->first == "SdtPr")
    7036             :         {
    7037             :             uno::Sequence<beans::PropertyValue> aGrabBagSdt =
    7038          35 :                     i->second.get< uno::Sequence<beans::PropertyValue> >();
    7039         115 :             for (sal_Int32 k=0; k < aGrabBagSdt.getLength(); ++k)
    7040             :             {
    7041          80 :                 beans::PropertyValue aPropertyValue = aGrabBagSdt[k];
    7042         126 :                 if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartObj" ||
    7043          46 :                         aPropertyValue.Name == "ooxml:CT_SdtPr_docPartList")
    7044             :                 {
    7045          34 :                     if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartObj")
    7046          34 :                         m_nParagraphSdtPrToken = FSNS( XML_w, XML_docPartObj );
    7047           0 :                     else if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartList")
    7048           0 :                         m_nParagraphSdtPrToken = FSNS( XML_w, XML_docPartList );
    7049             : 
    7050          34 :                     uno::Sequence<beans::PropertyValue> aGrabBag;
    7051          34 :                     aPropertyValue.Value >>= aGrabBag;
    7052         102 :                     for (sal_Int32 j=0; j < aGrabBag.getLength(); ++j)
    7053             :                     {
    7054          68 :                         OUString sValue = aGrabBag[j].Value.get<OUString>();
    7055          68 :                         if (aGrabBag[j].Name == "ooxml:CT_SdtDocPart_docPartGallery")
    7056             :                             AddToAttrList( m_pParagraphSdtPrTokenChildren,
    7057             :                                            FSNS( XML_w, XML_docPartGallery ),
    7058          34 :                                            rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
    7059          34 :                         else if (aGrabBag[j].Name == "ooxml:CT_SdtDocPart_docPartCategory")
    7060             :                             AddToAttrList( m_pParagraphSdtPrTokenChildren,
    7061             :                                            FSNS( XML_w, XML_docPartCategory ),
    7062           0 :                                            rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
    7063          34 :                         else if (aGrabBag[j].Name == "ooxml:CT_SdtDocPart_docPartUnique")
    7064          34 :                             AddToAttrList( m_pParagraphSdtPrTokenChildren, FSNS( XML_w, XML_docPartUnique ), "" );
    7065         102 :                     }
    7066             :                 }
    7067          46 :                 else if (aPropertyValue.Name == "ooxml:CT_SdtPr_equation")
    7068           0 :                     m_nParagraphSdtPrToken = FSNS( XML_w, XML_equation );
    7069          46 :                 else if (aPropertyValue.Name == "ooxml:CT_SdtPr_picture")
    7070           1 :                     m_nParagraphSdtPrToken = FSNS( XML_w, XML_picture );
    7071          45 :                 else if (aPropertyValue.Name == "ooxml:CT_SdtPr_citation")
    7072           4 :                     m_nParagraphSdtPrToken = FSNS( XML_w, XML_citation );
    7073          41 :                 else if (aPropertyValue.Name == "ooxml:CT_SdtPr_group")
    7074           1 :                     m_nParagraphSdtPrToken = FSNS( XML_w, XML_group );
    7075         115 :             }
    7076             :         }
    7077             :         else
    7078             :             SAL_INFO("sw.ww8", "DocxAttributeOutput::ParaGrabBag: unhandled grab bag property " << i->first );
    7079             :     }
    7080         374 : }
    7081             : 
    7082        4775 : void DocxAttributeOutput::CharGrabBag( const SfxGrabBagItem& rItem )
    7083             : {
    7084        4775 :     const std::map< OUString, com::sun::star::uno::Any >& rMap = rItem.GetGrabBag();
    7085             : 
    7086             :     // get original values of theme-derived properties to check if they have changed during the edition
    7087        4775 :     sal_Bool bWriteCSTheme = sal_True;
    7088        4775 :     sal_Bool bWriteAsciiTheme = sal_True;
    7089        4775 :     sal_Bool bWriteEastAsiaTheme = sal_True;
    7090        4775 :     sal_Bool bWriteThemeFontColor = sal_True;
    7091        4775 :     OUString sOriginalValue;
    7092       16207 :     for ( std::map< OUString, com::sun::star::uno::Any >::const_iterator i = rMap.begin(); i != rMap.end(); ++i )
    7093             :     {
    7094       11432 :         if ( m_pFontsAttrList && i->first == "CharThemeFontNameCs" )
    7095             :         {
    7096         864 :             if ( i->second >>= sOriginalValue )
    7097             :                 bWriteCSTheme =
    7098         864 :                         ( m_pFontsAttrList->getOptionalValue( FSNS( XML_w, XML_cs ) ) == sOriginalValue );
    7099             :         }
    7100       10568 :         else if ( m_pFontsAttrList && i->first == "CharThemeFontNameAscii" )
    7101             :         {
    7102         887 :             if ( i->second >>= sOriginalValue )
    7103             :                 bWriteAsciiTheme =
    7104         887 :                         ( m_pFontsAttrList->getOptionalValue( FSNS( XML_w, XML_ascii ) ) == sOriginalValue );
    7105             :         }
    7106        9681 :         else if ( m_pFontsAttrList && i->first == "CharThemeFontNameEastAsia" )
    7107             :         {
    7108        1087 :             if ( i->second >>= sOriginalValue )
    7109             :                 bWriteEastAsiaTheme =
    7110        1087 :                         ( m_pFontsAttrList->getOptionalValue( FSNS( XML_w, XML_eastAsia ) ) == sOriginalValue );
    7111             :         }
    7112        8594 :         else if ( m_pColorAttrList && i->first == "CharThemeOriginalColor" )
    7113             :         {
    7114        3801 :             if ( i->second >>= sOriginalValue )
    7115             :                 bWriteThemeFontColor =
    7116        3801 :                         ( m_pColorAttrList->getOptionalValue( FSNS( XML_w, XML_val ) ) == sOriginalValue );
    7117             :         }
    7118             :     }
    7119             : 
    7120             :     // save theme attributes back to the run properties
    7121        9550 :     OUString str;
    7122       16207 :     for ( std::map< OUString, com::sun::star::uno::Any >::const_iterator i = rMap.begin(); i != rMap.end(); ++i )
    7123             :     {
    7124       11432 :         if ( i->first == "CharThemeNameAscii" && bWriteAsciiTheme )
    7125             :         {
    7126         859 :             i->second >>= str;
    7127             :             AddToAttrList( m_pFontsAttrList, FSNS( XML_w, XML_asciiTheme ),
    7128         859 :                     OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
    7129             :         }
    7130       10573 :         else if ( i->first == "CharThemeNameCs" && bWriteCSTheme )
    7131             :         {
    7132         851 :             i->second >>= str;
    7133             :             AddToAttrList( m_pFontsAttrList, FSNS( XML_w, XML_cstheme ),
    7134         851 :                     OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
    7135             :         }
    7136        9722 :         else if ( i->first == "CharThemeNameEastAsia" && bWriteEastAsiaTheme )
    7137             :         {
    7138        1074 :             i->second >>= str;
    7139             :             AddToAttrList( m_pFontsAttrList, FSNS( XML_w, XML_eastAsiaTheme ),
    7140        1074 :                     OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
    7141             :         }
    7142        8648 :         else if ( i->first == "CharThemeNameHAnsi" && bWriteAsciiTheme )
    7143             :         // this is not a mistake: in LibO we don't directly support the hAnsi family
    7144             :         // of attributes so we save the same value from ascii attributes instead
    7145             :         {
    7146         857 :             i->second >>= str;
    7147             :             AddToAttrList( m_pFontsAttrList, FSNS( XML_w, XML_hAnsiTheme ),
    7148         857 :                     OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
    7149             :         }
    7150        7791 :         else if ( i->first == "CharThemeColor" && bWriteThemeFontColor )
    7151             :         {
    7152         616 :             i->second >>= str;
    7153             :             AddToAttrList( m_pColorAttrList, FSNS( XML_w, XML_themeColor ),
    7154         616 :                     OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
    7155             :         }
    7156        7175 :         else if ( i->first == "CharThemeColorShade" )
    7157             :         {
    7158         254 :             i->second >>= str;
    7159             :             AddToAttrList( m_pColorAttrList, FSNS( XML_w, XML_themeShade ),
    7160         254 :                     OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
    7161             :         }
    7162        6921 :         else if ( i->first == "CharThemeColorTint" )
    7163             :         {
    7164          88 :             i->second >>= str;
    7165             :             AddToAttrList( m_pColorAttrList, FSNS( XML_w, XML_themeTint ),
    7166          88 :                     OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
    7167             :         }
    7168       19634 :         else if( i->first == "CharThemeFontNameCs"   ||
    7169       11047 :                 i->first == "CharThemeFontNameAscii" ||
    7170       15903 :                 i->first == "CharThemeFontNameEastAsia" ||
    7171        3991 :                 i->first == "CharThemeOriginalColor" )
    7172             :         {
    7173             :             // just skip these, they were processed before
    7174             :         }
    7175         564 :         else if(i->first == "CharGlowTextEffect" ||
    7176         362 :                 i->first == "CharShadowTextEffect" ||
    7177         350 :                 i->first == "CharReflectionTextEffect" ||
    7178         333 :                 i->first == "CharTextOutlineTextEffect" ||
    7179         313 :                 i->first == "CharTextFillTextEffect" ||
    7180         304 :                 i->first == "CharScene3DTextEffect" ||
    7181         298 :                 i->first == "CharProps3DTextEffect" ||
    7182         285 :                 i->first == "CharLigaturesTextEffect" ||
    7183         272 :                 i->first == "CharNumFormTextEffect" ||
    7184         260 :                 i->first == "CharNumSpacingTextEffect" ||
    7185         431 :                 i->first == "CharStylisticSetsTextEffect" ||
    7186         114 :                 i->first == "CharCntxtAltsTextEffect")
    7187             :         {
    7188          82 :             beans::PropertyValue aPropertyValue;
    7189          82 :             i->second >>= aPropertyValue;
    7190          82 :             sal_Int32 aLength = m_aTextEffectsGrabBag.getLength();
    7191          82 :             m_aTextEffectsGrabBag.realloc(m_aTextEffectsGrabBag.getLength() + 1);
    7192          82 :             m_aTextEffectsGrabBag[aLength] = aPropertyValue;
    7193             :         }
    7194         108 :         else if (i->first == "SdtPr")
    7195             :         {
    7196             :             uno::Sequence<beans::PropertyValue> aGrabBagSdt =
    7197          20 :                     i->second.get< uno::Sequence<beans::PropertyValue> >();
    7198          63 :             for (sal_Int32 k=0; k < aGrabBagSdt.getLength(); ++k)
    7199             :             {
    7200          43 :                 beans::PropertyValue aPropertyValue = aGrabBagSdt[k];
    7201          43 :                 if (aPropertyValue.Name == "ooxml:CT_SdtPr_checkbox")
    7202             :                 {
    7203           1 :                     m_nRunSdtPrToken = FSNS( XML_w14, XML_checkbox );
    7204           1 :                     uno::Sequence<beans::PropertyValue> aGrabBag;
    7205           1 :                     aPropertyValue.Value >>= aGrabBag;
    7206           4 :                     for (sal_Int32 j=0; j < aGrabBag.getLength(); ++j)
    7207             :                     {
    7208           3 :                         OUString sValue = aGrabBag[j].Value.get<OUString>();
    7209           3 :                         if (aGrabBag[j].Name == "ooxml:CT_SdtCheckbox_checked")
    7210             :                             AddToAttrList( m_pRunSdtPrTokenChildren,
    7211             :                                            FSNS( XML_w14, XML_checked ),
    7212           1 :                                            rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
    7213           2 :                         else if (aGrabBag[j].Name == "ooxml:CT_SdtCheckbox_checkedState")
    7214             :                             AddToAttrList( m_pRunSdtPrTokenChildren,
    7215             :                                            FSNS( XML_w14, XML_checkedState ),
    7216           1 :                                            rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
    7217           1 :                         else if (aGrabBag[j].Name == "ooxml:CT_SdtCheckbox_uncheckedState")
    7218             :                             AddToAttrList( m_pRunSdtPrTokenChildren,
    7219             :                                            FSNS( XML_w14, XML_uncheckedState ),
    7220           1 :                                            rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
    7221           4 :                     }
    7222             :                 }
    7223          42 :                 else if (aPropertyValue.Name == "ooxml:CT_SdtPr_dataBinding")
    7224             :                 {
    7225          11 :                     uno::Sequence<beans::PropertyValue> aGrabBag;
    7226          11 :                     aPropertyValue.Value >>= aGrabBag;
    7227          44 :                     for (sal_Int32 j=0; j < aGrabBag.getLength(); ++j)
    7228             :                     {
    7229          33 :                         OUString sValue = aGrabBag[j].Value.get<OUString>();
    7230          33 :                         if (aGrabBag[j].Name == "ooxml:CT_DataBinding_prefixMappings")
    7231             :                             AddToAttrList( m_pRunSdtPrDataBindingAttrs,
    7232             :                                            FSNS( XML_w, XML_prefixMappings ),
    7233          11 :                                            rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
    7234          22 :                         else if (aGrabBag[j].Name == "ooxml:CT_DataBinding_xpath")
    7235             :                             AddToAttrList( m_pRunSdtPrDataBindingAttrs,
    7236             :                                            FSNS( XML_w, XML_xpath ),
    7237          11 :                                            rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
    7238          11 :                         else if (aGrabBag[j].Name == "ooxml:CT_DataBinding_storeItemID")
    7239             :                             AddToAttrList( m_pRunSdtPrDataBindingAttrs,
    7240             :                                            FSNS( XML_w, XML_storeItemID ),
    7241          11 :                                            rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
    7242          44 :                     }
    7243             :                 }
    7244          31 :                 else if (aPropertyValue.Name == "ooxml:CT_SdtPr_text")
    7245          11 :                     m_nRunSdtPrToken = FSNS( XML_w, XML_text );
    7246          20 :                 else if (aPropertyValue.Name == "ooxml:CT_SdtPr_id" && m_nRunSdtPrToken == 0)
    7247             :                     // only write id token as a marker if no other exist
    7248          20 :                     m_nRunSdtPrToken = FSNS( XML_w, XML_id );
    7249          63 :             }
    7250             :         }
    7251             :         else
    7252             :             SAL_INFO("sw.ww8", "DocxAttributeOutput::CharGrabBag: unhandled grab bag property " << i->first);
    7253        4775 :     }
    7254        4775 : }
    7255             : 
    7256         272 : DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, FSHelperPtr pSerializer, oox::drawingml::DrawingML* pDrawingML )
    7257             :     : m_rExport( rExport ),
    7258             :       m_pSerializer( pSerializer ),
    7259             :       m_rDrawingML( *pDrawingML ),
    7260             :       m_pFontsAttrList( NULL ),
    7261             :       m_pEastAsianLayoutAttrList( NULL ),
    7262             :       m_pCharLangAttrList( NULL ),
    7263             :       m_pSectionSpacingAttrList( NULL ),
    7264             :       m_pParagraphSpacingAttrList( NULL ),
    7265             :       m_pHyperlinkAttrList( NULL ),
    7266             :       m_pColorAttrList( NULL ),
    7267             :       m_pBackgroundAttrList( NULL ),
    7268             :       m_endPageRef( false ),
    7269           0 :       m_pFootnotesList( new ::docx::FootnotesList() ),
    7270           0 :       m_pEndnotesList( new ::docx::FootnotesList() ),
    7271             :       m_footnoteEndnoteRefTag( 0 ),
    7272             :       m_pSectionInfo( NULL ),
    7273             :       m_pRedlineData( NULL ),
    7274             :       m_nRedlineId( 0 ),
    7275             :       m_bOpenedSectPr( false ),
    7276             :       m_bWritingHeaderFooter( false ),
    7277             :       m_sFieldBkm( ),
    7278             :       m_nNextBookmarkId( 0 ),
    7279             :       m_nNextAnnotationMarkId( 0 ),
    7280             :       m_pTableWrt( NULL ),
    7281             :       m_bParagraphOpened( false ),
    7282             :       m_bIsFirstParagraph( true ),
    7283             :       m_bAlternateContentChoiceOpen( false ),
    7284             :       m_nColBreakStatus( COLBRK_NONE ),
    7285             :       m_nTextFrameLevel( 0 ),
    7286             :       m_closeHyperlinkInThisRun( false ),
    7287             :       m_closeHyperlinkInPreviousRun( false ),
    7288             :       m_startedHyperlink( false ),
    7289             :       m_nHyperLinkCount(0),
    7290             :       m_nFieldsInHyperlink( 0 ),
    7291             :       m_postponedGraphic( NULL ),
    7292             :       m_postponedDiagram( NULL ),
    7293             :       m_postponedVMLDrawing(NULL),
    7294             :       m_postponedDMLDrawing(NULL),
    7295             :       m_postponedOLE( NULL ),
    7296             :       m_postponedMath( NULL ),
    7297             :       m_postponedChart( NULL ),
    7298             :       pendingPlaceholder( NULL ),
    7299             :       m_postitFieldsMaxId( 0 ),
    7300             :       m_anchorId( 1 ),
    7301             :       m_nextFontId( 1 ),
    7302             :       m_tableReference(new TableReference()),
    7303             :       m_oldTableReference(new TableReference()),
    7304             :       m_bIgnoreNextFill(false),
    7305             :       m_bBtLr(false),
    7306         272 :       m_pTableStyleExport(new DocxTableStyleExport(rExport.pDoc, pSerializer)),
    7307             :       m_bParaBeforeAutoSpacing(false),
    7308             :       m_bParaAfterAutoSpacing(false),
    7309             :       m_nParaBeforeSpacing(0),
    7310             :       m_nParaAfterSpacing(0),
    7311             :       m_setFootnote(false)
    7312             :     , m_nParagraphSdtPrToken(0)
    7313             :     , m_pParagraphSdtPrTokenChildren(NULL)
    7314             :     , m_pParagraphSdtPrDataBindingAttrs(NULL)
    7315             :     , m_nRunSdtPrToken(0)
    7316             :     , m_pRunSdtPrTokenChildren(NULL)
    7317         544 :     , m_pRunSdtPrDataBindingAttrs(NULL)
    7318             : {
    7319         272 : }
    7320             : 
    7321         816 : DocxAttributeOutput::~DocxAttributeOutput()
    7322             : {
    7323         272 :     delete m_pFontsAttrList, m_pFontsAttrList = NULL;
    7324         272 :     delete m_pEastAsianLayoutAttrList, m_pEastAsianLayoutAttrList = NULL;
    7325         272 :     delete m_pCharLangAttrList, m_pCharLangAttrList = NULL;
    7326         272 :     delete m_pSectionSpacingAttrList, m_pSectionSpacingAttrList = NULL;
    7327         272 :     delete m_pParagraphSpacingAttrList, m_pParagraphSpacingAttrList = NULL;
    7328         272 :     delete m_pHyperlinkAttrList, m_pHyperlinkAttrList = NULL;
    7329         272 :     delete m_pColorAttrList, m_pColorAttrList = NULL;
    7330         272 :     delete m_pBackgroundAttrList, m_pBackgroundAttrList = NULL;
    7331             : 
    7332         272 :     delete m_pFootnotesList, m_pFootnotesList = NULL;
    7333         272 :     delete m_pEndnotesList, m_pEndnotesList = NULL;
    7334             : 
    7335         272 :     delete m_pTableWrt, m_pTableWrt = NULL;
    7336         272 :     delete m_pParagraphSdtPrTokenChildren; m_pParagraphSdtPrTokenChildren = NULL;
    7337         272 :     delete m_pParagraphSdtPrDataBindingAttrs; m_pParagraphSdtPrDataBindingAttrs = NULL;
    7338         272 :     delete m_pRunSdtPrTokenChildren; m_pRunSdtPrTokenChildren = NULL;
    7339         272 :     delete m_pRunSdtPrDataBindingAttrs; m_pRunSdtPrDataBindingAttrs = NULL;
    7340         544 : }
    7341             : 
    7342       43519 : DocxExport& DocxAttributeOutput::GetExport()
    7343             : {
    7344       43519 :     return m_rExport;
    7345             : }
    7346             : 
    7347        1468 : void DocxAttributeOutput::SetSerializer( ::sax_fastparser::FSHelperPtr pSerializer )
    7348             : {
    7349        1468 :     m_pSerializer = pSerializer;
    7350        1468 :     m_pTableStyleExport->SetSerializer(pSerializer);
    7351        1468 : }
    7352             : 
    7353         842 : bool DocxAttributeOutput::HasFootnotes() const
    7354             : {
    7355         842 :     return !m_pFootnotesList->isEmpty();
    7356             : }
    7357             : 
    7358         842 : bool DocxAttributeOutput::HasEndnotes() const
    7359             : {
    7360         842 :     return !m_pEndnotesList->isEmpty();
    7361             : }
    7362             : 
    7363         272 : bool DocxAttributeOutput::HasPostitFields() const
    7364             : {
    7365         272 :     return !m_postitFields.empty();
    7366             : }
    7367             : 
    7368           3 : void DocxAttributeOutput::BulletDefinition(int nId, const Graphic& rGraphic, Size aSize)
    7369             : {
    7370             :     m_pSerializer->startElementNS(XML_w, XML_numPicBullet,
    7371             :             FSNS(XML_w, XML_numPicBulletId), OString::number(nId).getStr(),
    7372           3 :             FSEND);
    7373             : 
    7374           3 :     OStringBuffer aStyle;
    7375             :     // Size is in twips, we need it in points.
    7376           3 :     aStyle.append("width:").append(double(aSize.Width()) / 20);
    7377           3 :     aStyle.append("pt;height:").append(double(aSize.Height()) / 20).append("pt");
    7378           3 :     m_pSerializer->startElementNS( XML_w, XML_pict, FSEND);
    7379             :     m_pSerializer->startElementNS( XML_v, XML_shape,
    7380             :             XML_style, aStyle.getStr(),
    7381             :             FSNS(XML_o, XML_bullet), "t",
    7382           3 :             FSEND);
    7383             : 
    7384           3 :     m_rDrawingML.SetFS(m_pSerializer);
    7385           6 :     OUString aRelId = m_rDrawingML.WriteImage(rGraphic);
    7386             :     m_pSerializer->singleElementNS( XML_v, XML_imagedata,
    7387             :             FSNS(XML_r, XML_id), OUStringToOString(aRelId, RTL_TEXTENCODING_UTF8),
    7388             :             FSNS(XML_o, XML_title), "",
    7389           3 :             FSEND);
    7390             : 
    7391           3 :     m_pSerializer->endElementNS(XML_v, XML_shape);
    7392           3 :     m_pSerializer->endElementNS(XML_w, XML_pict);
    7393             : 
    7394           6 :     m_pSerializer->endElementNS(XML_w, XML_numPicBullet);
    7395           3 : }
    7396             : 
    7397       31144 : void DocxAttributeOutput::AddToAttrList( ::sax_fastparser::FastAttributeList* &pAttrList, sal_Int32 nAttrName, const sal_Char* sAttrValue )
    7398             : {
    7399       31144 :     AddToAttrList( pAttrList, 1, nAttrName, sAttrValue );
    7400       31144 : }
    7401             : 
    7402       39146 : void DocxAttributeOutput::AddToAttrList( ::sax_fastparser::FastAttributeList* &pAttrList, sal_Int32 nAttrs, ... )
    7403             : {
    7404       39146 :     if( !pAttrList )
    7405       19115 :         pAttrList = m_pSerializer->createAttrList();
    7406             : 
    7407             :     va_list args;
    7408       39146 :     va_start( args, nAttrs );
    7409       87188 :     for( sal_Int32 i = 0; i<nAttrs; i++)
    7410             :     {
    7411       48042 :         sal_Int32 nName = va_arg( args, sal_Int32 );
    7412       48042 :         const char* pValue = va_arg( args, const char* );
    7413       48042 :         if( pValue )
    7414       48042 :             pAttrList->add( nName, pValue );
    7415             :     }
    7416       39146 :     va_end( args );
    7417       39179 : }
    7418             : 
    7419             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10