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

Generated by: LCOV version 1.10