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

Generated by: LCOV version 1.11