LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sw/source/filter/ww8 - wrtw8nds.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 740 1354 54.7 %
Date: 2013-07-09 Functions: 47 61 77.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include <vector>
      22             : #include <list>
      23             : #include <utility>
      24             : #include <algorithm>
      25             : #include <functional>
      26             : #include <iostream>
      27             : 
      28             : #include <hintids.hxx>
      29             : #include <comphelper/string.hxx>
      30             : #include <tools/urlobj.hxx>
      31             : #include <editeng/boxitem.hxx>
      32             : #include <editeng/cmapitem.hxx>
      33             : #include <editeng/langitem.hxx>
      34             : #include <editeng/svxfont.hxx>
      35             : #include <editeng/lrspitem.hxx>
      36             : #include <editeng/brushitem.hxx>
      37             : #include <editeng/fontitem.hxx>
      38             : #include <editeng/keepitem.hxx>
      39             : #include <editeng/fhgtitem.hxx>
      40             : #include <editeng/ulspitem.hxx>
      41             : #include <editeng/formatbreakitem.hxx>
      42             : #include <editeng/frmdiritem.hxx>
      43             : #include <editeng/tstpitem.hxx>
      44             : #include "svl/urihelper.hxx"
      45             : #include <svl/whiter.hxx>
      46             : #include <fmtpdsc.hxx>
      47             : #include <fmtfsize.hxx>
      48             : #include <fmtornt.hxx>
      49             : #include <fmtlsplt.hxx>
      50             : #include <fmtflcnt.hxx>
      51             : #include <fmtanchr.hxx>
      52             : #include <fmtcntnt.hxx>
      53             : #include <frmatr.hxx>
      54             : #include <paratr.hxx>
      55             : #include <txatbase.hxx>
      56             : #include <fmtinfmt.hxx>
      57             : #include <fmtrfmrk.hxx>
      58             : #include <fchrfmt.hxx>
      59             : #include <fmtautofmt.hxx>
      60             : #include <charfmt.hxx>
      61             : #include <tox.hxx>
      62             : #include <ndtxt.hxx>
      63             : #include <pam.hxx>
      64             : #include <doc.hxx>
      65             : #include <docary.hxx>
      66             : #include <swtable.hxx>
      67             : #include <swtblfmt.hxx>
      68             : #include <section.hxx>
      69             : #include <pagedesc.hxx>
      70             : #include <swrect.hxx>
      71             : #include <reffld.hxx>
      72             : #include <redline.hxx>
      73             : #include <wrtswtbl.hxx>
      74             : #include <htmltbl.hxx>
      75             : #include <txttxmrk.hxx>
      76             : #include <fmtline.hxx>
      77             : #include <fmtruby.hxx>
      78             : #include <breakit.hxx>
      79             : #include <txtatr.hxx>
      80             : #include <fmtsrnd.hxx>
      81             : #include <fmtrowsplt.hxx>
      82             : #include <com/sun/star/i18n/ScriptType.hpp>
      83             : #include <com/sun/star/i18n/WordType.hpp>
      84             : 
      85             : #include <doctok/sprmids.hxx>
      86             : 
      87             : #include "writerhelper.hxx"
      88             : #include "writerwordglue.hxx"
      89             : #include <numrule.hxx>
      90             : #include "wrtww8.hxx"
      91             : #include "ww8par.hxx"
      92             : #include <IMark.hxx>
      93             : #include "ww8attributeoutput.hxx"
      94             : 
      95             : #include <ndgrf.hxx>
      96             : #include <ndole.hxx>
      97             : 
      98             : #include <cstdio>
      99             : 
     100             : using namespace ::com::sun::star;
     101             : using namespace ::com::sun::star::i18n;
     102             : using namespace sw::util;
     103             : using namespace sw::types;
     104             : using namespace sw::mark;
     105             : using namespace nsFieldFlags;
     106             : 
     107           2 : static String lcl_getFieldCode( const IFieldmark* pFieldmark ) {
     108             :     OSL_ENSURE(pFieldmark!=NULL, "where is my fieldmark???");
     109             : 
     110           2 :     if ( !pFieldmark) {
     111           0 :         return String();
     112           2 :     } else if ( pFieldmark->GetFieldname( ) == ODF_FORMTEXT ) {
     113           0 :         return OUString(" FORMTEXT ");
     114           2 :     } else if ( pFieldmark->GetFieldname( ) == ODF_FORMDROPDOWN ) {
     115           0 :         return OUString(" FORMDROPDOWN ");
     116           2 :     } else if ( pFieldmark->GetFieldname( ) == ODF_FORMCHECKBOX ) {
     117           0 :         return OUString(" FORMCHECKBOX ");
     118           2 :     } else if ( pFieldmark->GetFieldname( ) == ODF_TOC ) {
     119           0 :         return OUString(" TOC ");
     120           2 :     } else if ( pFieldmark->GetFieldname( ) == ODF_HYPERLINK ) {
     121           0 :         return OUString(" HYPERLINK ");
     122           2 :     } else if ( pFieldmark->GetFieldname( ) == ODF_PAGEREF ) {
     123           0 :         return OUString(" PAGEREF ");
     124             :     } else {
     125           2 :         return pFieldmark->GetFieldname();
     126             :     }
     127             : }
     128             : 
     129           4 : static ww::eField lcl_getFieldId( const IFieldmark* pFieldmark ) {
     130             :     OSL_ENSURE(pFieldmark!=NULL, "where is my fieldmark???");
     131           4 :     if ( !pFieldmark ) {
     132           0 :         return ww::eUNKNOWN;
     133           4 :     } else if ( pFieldmark->GetFieldname( ) == ODF_FORMTEXT ) {
     134           0 :         return ww::eFORMTEXT;
     135           4 :     } else if ( pFieldmark->GetFieldname( ) == ODF_FORMDROPDOWN ) {
     136           0 :         return ww::eFORMDROPDOWN;
     137           4 :     } else if ( pFieldmark->GetFieldname( ) == ODF_FORMCHECKBOX ) {
     138           0 :         return ww::eFORMCHECKBOX;
     139           4 :     } else if ( pFieldmark->GetFieldname( ) == ODF_TOC ) {
     140           0 :         return ww::eTOC;
     141           4 :     } else if ( pFieldmark->GetFieldname( ) == ODF_HYPERLINK ) {
     142           0 :         return ww::eHYPERLINK;
     143           4 :     } else if ( pFieldmark->GetFieldname( ) == ODF_PAGEREF ) {
     144           0 :         return ww::ePAGEREF;
     145             :     } else {
     146           4 :         return ww::eUNKNOWN;
     147             :     }
     148             : }
     149             : 
     150         623 : MSWordAttrIter::MSWordAttrIter( MSWordExportBase& rExport )
     151         623 :     : pOld( rExport.pChpIter ), m_rExport( rExport )
     152             : {
     153         623 :     m_rExport.pChpIter = this;
     154         623 : }
     155             : 
     156         623 : MSWordAttrIter::~MSWordAttrIter()
     157             : {
     158         623 :     m_rExport.pChpIter = pOld;
     159         623 : }
     160             : 
     161             : class sortswflys :
     162             :     public std::binary_function<const sw::Frame&, const sw::Frame&, bool>
     163             : {
     164             : public:
     165           4 :     bool operator()(const sw::Frame &rOne, const sw::Frame &rTwo) const
     166             :     {
     167           4 :         return rOne.GetPosition() < rTwo.GetPosition();
     168             :     }
     169             : };
     170             : 
     171        1347 : void SwWW8AttrIter::IterToCurrent()
     172             : {
     173             :     OSL_ENSURE(maCharRuns.begin() != maCharRuns.end(), "Impossible");
     174        1347 :     mnScript = maCharRunIter->mnScript;
     175        1347 :     meChrSet = maCharRunIter->meCharSet;
     176        1347 :     mbCharIsRTL = maCharRunIter->mbRTL;
     177        1347 : }
     178             : 
     179         622 : SwWW8AttrIter::SwWW8AttrIter(MSWordExportBase& rWr, const SwTxtNode& rTxtNd) :
     180             :     MSWordAttrIter(rWr),
     181             :     rNd(rTxtNd),
     182         622 :     maCharRuns(GetPseudoCharRuns(rTxtNd, 0, !rWr.SupportsUnicode())),
     183             :     pCurRedline(0),
     184             :     nAktSwPos(0),
     185             :     nCurRedlinePos(USHRT_MAX),
     186        1244 :     mrSwFmtDrop(rTxtNd.GetSwAttrSet().GetDrop())
     187             : {
     188             : 
     189         622 :     SwPosition aPos(rTxtNd);
     190         622 :     if (FRMDIR_HORI_RIGHT_TOP == rWr.pDoc->GetTextDirection(aPos))
     191           2 :         mbParaIsRTL = true;
     192             :     else
     193         620 :         mbParaIsRTL = false;
     194             : 
     195         622 :     maCharRunIter = maCharRuns.begin();
     196         622 :     IterToCurrent();
     197             : 
     198             :     /*
     199             :      #i2916#
     200             :      Get list of any graphics which may be anchored from this paragraph.
     201             :     */
     202         622 :     maFlyFrms = GetFramesInNode(rWr.maFrames, rNd);
     203         622 :     std::sort(maFlyFrms.begin(), maFlyFrms.end(), sortswflys());
     204             : 
     205             :     /*
     206             :      #i18480#
     207             :      If we are inside a frame then anything anchored inside this frame can
     208             :      only be supported by word anchored inline ("as character"), so force
     209             :      this in the supportable case.
     210             :     */
     211         622 :     if (rWr.SupportsUnicode() && rWr.bInWriteEscher)
     212             :     {
     213             :         std::for_each(maFlyFrms.begin(), maFlyFrms.end(),
     214          14 :             std::mem_fun_ref(&sw::Frame::ForceTreatAsInline));
     215             :     }
     216             : 
     217         622 :     maFlyIter = maFlyFrms.begin();
     218             : 
     219         622 :     if ( !m_rExport.pDoc->GetRedlineTbl().empty() )
     220             :     {
     221          10 :         SwPosition aPosition( rNd, SwIndex( (SwTxtNode*)&rNd ) );
     222          10 :         pCurRedline = m_rExport.pDoc->GetRedline( aPosition, &nCurRedlinePos );
     223             :     }
     224             : 
     225         622 :     nAktSwPos = SearchNext(1);
     226         622 : }
     227             : 
     228        2694 : xub_StrLen lcl_getMinPos( xub_StrLen pos1, xub_StrLen pos2 )
     229             : {
     230        2694 :     xub_StrLen min = STRING_NOTFOUND;
     231        2694 :     if ( pos1 == STRING_NOTFOUND && pos2 != STRING_NOTFOUND )
     232           0 :         min = pos2;
     233        2694 :     else if ( pos2 == STRING_NOTFOUND && pos1 != STRING_NOTFOUND )
     234           6 :         min = pos1;
     235        2688 :     else if ( pos1 != STRING_NOTFOUND && pos2 != STRING_NOTFOUND )
     236             :     {
     237           2 :         if ( pos1 < pos2 )
     238           0 :             min = pos1;
     239             :         else
     240           2 :             min = pos2;
     241             :     }
     242             : 
     243        2694 :     return min;
     244             : }
     245             : 
     246        1347 : xub_StrLen SwWW8AttrIter::SearchNext( xub_StrLen nStartPos )
     247             : {
     248             :     xub_StrLen nPos;
     249        1347 :     xub_StrLen nMinPos = STRING_MAXLEN;
     250        1347 :     xub_StrLen i=0;
     251             : 
     252        1347 :     const String aTxt = rNd.GetTxt();
     253        1347 :     xub_StrLen fieldEndPos = aTxt.Search(CH_TXT_ATR_FIELDEND, nStartPos);
     254        1347 :     xub_StrLen fieldStartPos = aTxt.Search(CH_TXT_ATR_FIELDSTART, nStartPos);
     255        1347 :     xub_StrLen formElementPos = aTxt.Search(CH_TXT_ATR_FORMELEMENT, nStartPos);
     256             : 
     257        1347 :     xub_StrLen pos = lcl_getMinPos( fieldEndPos, fieldStartPos );
     258        1347 :     pos = lcl_getMinPos( pos, formElementPos );
     259             : 
     260        1347 :     if (pos!=STRING_NOTFOUND)
     261           4 :         nMinPos=pos;
     262             : 
     263             :     // first the redline, then the attributes
     264        1347 :     if( pCurRedline )
     265             :     {
     266           7 :         const SwPosition* pEnd = pCurRedline->End();
     267           7 :         if (pEnd->nNode == rNd && ((i = pEnd->nContent.GetIndex()) >= nStartPos) && i < nMinPos )
     268           1 :                 nMinPos = i;
     269             :     }
     270             : 
     271        1347 :     if ( nCurRedlinePos < m_rExport.pDoc->GetRedlineTbl().size() )
     272             :     {
     273             :         // nCurRedlinePos point to the next redline
     274          19 :         nPos = nCurRedlinePos;
     275          19 :         if( pCurRedline )
     276           7 :             ++nPos;
     277             : 
     278          28 :         for ( ; nPos < m_rExport.pDoc->GetRedlineTbl().size(); ++nPos )
     279             :         {
     280          19 :             const SwRedline* pRedl = m_rExport.pDoc->GetRedlineTbl()[ nPos ];
     281             : 
     282          19 :             const SwPosition* pStt = pRedl->Start();
     283          19 :             const SwPosition* pEnd = pStt == pRedl->GetPoint()
     284          19 :                                         ? pRedl->GetMark()
     285          38 :                                         : pRedl->GetPoint();
     286             : 
     287          19 :             if( pStt->nNode == rNd )
     288             :             {
     289           9 :                 if( ( i = pStt->nContent.GetIndex() ) >= nStartPos &&
     290             :                     i < nMinPos )
     291           4 :                     nMinPos = i;
     292             :             }
     293             :             else
     294          10 :                 break;
     295             : 
     296          33 :             if( pEnd->nNode == rNd &&
     297          30 :                 ( i = pEnd->nContent.GetIndex() ) < nMinPos &&
     298             :                 i >= nStartPos )
     299           3 :                     nMinPos = i;
     300             :         }
     301             :     }
     302             : 
     303             : 
     304        1347 :     if (mrSwFmtDrop.GetWholeWord() && nStartPos <= rNd.GetDropLen(0))
     305           0 :         nMinPos = rNd.GetDropLen(0);
     306        1347 :     else if(nStartPos <= mrSwFmtDrop.GetChars())
     307           0 :         nMinPos = mrSwFmtDrop.GetChars();
     308             : 
     309        1347 :     if(const SwpHints* pTxtAttrs = rNd.GetpSwpHints())
     310             :     {
     311             : 
     312             : // can be optimized if we consider that the TxtAttrs are sorted by start position.
     313             : // but then we'd have to save 2 indices
     314        1632 :         for( i = 0; i < pTxtAttrs->Count(); i++ )
     315             :         {
     316        1116 :             const SwTxtAttr* pHt = (*pTxtAttrs)[i];
     317        1116 :             nPos = *pHt->GetStart();    // first Attr characters
     318        1116 :             if( nPos >= nStartPos && nPos <= nMinPos )
     319         221 :                 nMinPos = nPos;
     320             : 
     321        1116 :             if( pHt->GetEnd() )         // Attr with end
     322             :             {
     323         830 :                 nPos = *pHt->GetEnd();      // last Attr character + 1
     324         830 :                 if( nPos >= nStartPos && nPos <= nMinPos )
     325         270 :                     nMinPos = nPos;
     326             :             }
     327        1116 :             if (pHt->HasDummyChar())
     328             :             {
     329             :                 // pos + 1 because of CH_TXTATR in Text
     330         286 :                 nPos = *pHt->GetStart() + 1;
     331         286 :                 if( nPos >= nStartPos && nPos <= nMinPos )
     332          81 :                     nMinPos = nPos;
     333             :             }
     334             :         }
     335             :     }
     336             : 
     337        1347 :     if (maCharRunIter != maCharRuns.end())
     338             :     {
     339         725 :         if (maCharRunIter->mnEndPos < nMinPos)
     340         423 :             nMinPos = maCharRunIter->mnEndPos;
     341         725 :         IterToCurrent();
     342             :     }
     343             : 
     344             :     /*
     345             :      #i2916#
     346             :      Check to see if there are any graphics anchored to characters in this
     347             :      paragraph's text. Set nMinPos to 1 past the placement for anchored to
     348             :      character because anchors in Word appear after the character they are
     349             :      anchored to.
     350             :     */
     351        1347 :     if (maFlyIter != maFlyFrms.end())
     352             :     {
     353          24 :         const SwPosition &rAnchor = maFlyIter->GetPosition();
     354             : 
     355          24 :         nPos = rAnchor.nContent.GetIndex();
     356          24 :         if (nPos >= nStartPos && nPos <= nMinPos)
     357           0 :             nMinPos = nPos;
     358             : 
     359          24 :         if (maFlyIter->GetFrmFmt().GetAnchor().GetAnchorId() == FLY_AT_CHAR)
     360             :         {
     361          11 :             ++nPos;
     362          11 :             if (nPos >= nStartPos && nPos <= nMinPos)
     363           5 :                 nMinPos = nPos;
     364             :         }
     365             :     }
     366             : 
     367             :     //nMinPos found and not going to change at this point
     368             : 
     369        1347 :     if (maCharRunIter != maCharRuns.end())
     370             :     {
     371         725 :         if (maCharRunIter->mnEndPos == nMinPos)
     372         622 :             ++maCharRunIter;
     373             :     }
     374             : 
     375        1347 :     return nMinPos;
     376             : }
     377             : 
     378           0 : static bool lcl_isFontsizeItem( const SfxPoolItem& rItem )
     379             : {
     380           0 :     return ( rItem.Which( ) == RES_CHRATR_FONTSIZE ||
     381           0 :             rItem.Which( ) == RES_CHRATR_CJK_FONTSIZE ||
     382           0 :             rItem.Which( ) == RES_CHRATR_CTL_FONTSIZE );
     383             : }
     384             : 
     385         727 : void SwWW8AttrIter::OutAttr( xub_StrLen nSwPos, bool bRuby )
     386             : {
     387         727 :     m_rExport.AttrOutput().RTLAndCJKState( IsCharRTL(), GetScript() );
     388             : 
     389             :     /*
     390             :      Depending on whether text is in CTL/CJK or Western, get the id of that
     391             :      script, the idea is that the font that is actually in use to render this
     392             :      range of text ends up in pFont
     393             :     */
     394         727 :     sal_uInt16 nFontId = GetWhichOfScript( RES_CHRATR_FONT, GetScript() );
     395             : 
     396             :     const SvxFontItem &rParentFont = ItemGet<SvxFontItem>(
     397         727 :         (const SwTxtFmtColl&)rNd.GetAnyFmtColl(), nFontId);
     398         727 :     const SvxFontItem *pFont = &rParentFont;
     399             : 
     400         727 :     SfxItemSet aExportSet(*rNd.GetSwAttrSet().GetPool(),
     401         727 :         RES_CHRATR_BEGIN, RES_TXTATR_END - 1);
     402             : 
     403             :     //The hard formatting properties that affect the entire paragraph
     404         727 :     if (rNd.HasSwAttrSet())
     405             :     {
     406         524 :         sal_Bool bDeep = sal_False;
     407             :         // only copy hard attributes - bDeep = false
     408         524 :         aExportSet.Set(rNd.GetSwAttrSet(), bDeep);
     409             :         // get the current font item. Use rNd.GetSwAttrSet instead of aExportSet:
     410         524 :         const SvxFontItem &rNdFont = ItemGet<SvxFontItem>(rNd.GetSwAttrSet(), nFontId);
     411         524 :         pFont = &rNdFont;
     412         524 :         aExportSet.ClearItem(nFontId);
     413             :     }
     414             : 
     415             :     //The additional hard formatting properties that affect this range in the
     416             :     //paragraph
     417        1454 :     sw::PoolItems aRangeItems;
     418         727 :     if (const SwpHints* pTxtAttrs = rNd.GetpSwpHints())
     419             :     {
     420         711 :         for (xub_StrLen i = 0; i < pTxtAttrs->Count(); ++i)
     421             :         {
     422         623 :             const SwTxtAttr* pHt = (*pTxtAttrs)[i];
     423         623 :             const xub_StrLen* pEnd = pHt->GetEnd();
     424             : 
     425         790 :             if (pEnd ? ( nSwPos >= *pHt->GetStart() && nSwPos < *pEnd)
     426         167 :                         : nSwPos == *pHt->GetStart() )
     427             :             {
     428         218 :                 sal_uInt16 nWhich = pHt->GetAttr().Which();
     429         218 :                 if (nWhich == RES_TXTATR_AUTOFMT)
     430             :                 {
     431         130 :                     const SwFmtAutoFmt& rAutoFmt = static_cast<const SwFmtAutoFmt&>(pHt->GetAttr());
     432         130 :                     const boost::shared_ptr<SfxItemSet> pSet = rAutoFmt.GetStyleHandle();
     433         260 :                     SfxWhichIter aIter( *pSet );
     434             :                     const SfxPoolItem* pItem;
     435         130 :                     sal_uInt16 nWhichId = aIter.FirstWhich();
     436        5720 :                     while( nWhichId )
     437             :                     {
     438        5460 :                         if( SFX_ITEM_SET == pSet->GetItemState( nWhichId, sal_False, &pItem ))
     439             :                         {
     440         485 :                             if (nWhichId == nFontId)
     441          42 :                                 pFont = &(item_cast<SvxFontItem>(*pItem));
     442             :                             else
     443         443 :                                 aRangeItems[nWhichId] = pItem;
     444             :                         }
     445        5460 :                         nWhichId = aIter.NextWhich();
     446         130 :                     }
     447             :                 }
     448             :                 else
     449          88 :                     aRangeItems[nWhich] = (&(pHt->GetAttr()));
     450             :             }
     451         405 :             else if (nSwPos < *pHt->GetStart())
     452         222 :                 break;
     453             :         }
     454             :     }
     455             : 
     456             :     /*
     457             :      For #i24291# we need to explictly remove any properties from the
     458             :      aExportSet which a SwCharFmt would override, we can't rely on word doing
     459             :      this for us like writer does
     460             :     */
     461             :     const SwFmtCharFmt *pCharFmtItem =
     462         727 :         HasItem< SwFmtCharFmt >( aRangeItems, RES_TXTATR_CHARFMT );
     463         727 :     if ( pCharFmtItem )
     464           2 :         ClearOverridesFromSet( *pCharFmtItem, aExportSet );
     465             : 
     466        1454 :     sw::PoolItems aExportItems;
     467         727 :     GetPoolItems( aExportSet, aExportItems, false );
     468             : 
     469         727 :     sw::cPoolItemIter aEnd = aRangeItems.end();
     470        1258 :     for ( sw::cPoolItemIter aI = aRangeItems.begin(); aI != aEnd; ++aI )
     471             :     {
     472         531 :         if ( !bRuby || !lcl_isFontsizeItem( *aI->second ) )
     473         531 :             aExportItems[aI->first] = aI->second;
     474             :     }
     475             : 
     476         727 :     if ( !aExportItems.empty() )
     477             :     {
     478         516 :         const SwModify* pOldMod = m_rExport.pOutFmtNode;
     479         516 :         m_rExport.pOutFmtNode = &rNd;
     480         516 :         m_rExport.m_aCurrentCharPropStarts.push( nSwPos );
     481             : 
     482         516 :         m_rExport.ExportPoolItemsToCHP( aExportItems, GetScript() );
     483             : 
     484             :         // HasTextItem only allowed in the above range
     485         516 :         m_rExport.m_aCurrentCharPropStarts.pop();
     486         516 :         m_rExport.pOutFmtNode = pOldMod;
     487             :     }
     488             : 
     489             :     OSL_ENSURE( pFont, "must be *some* font associated with this txtnode" );
     490         727 :     if ( pFont )
     491             :     {
     492         727 :         SvxFontItem aFont( *pFont );
     493             : 
     494             :         /*
     495             :          If we are a nonunicode aware format then we set the charset we want to
     496             :          use for export of this range. If necessary this will generate a pseudo
     497             :          font to use for this range.
     498             : 
     499             :          So now we are guaranteed to have a font with the correct charset set
     500             :          for WW6/95 which will match the script we have exported this range in,
     501             :          this makes older nonunicode aware versions of word display the correct
     502             :          characters.
     503             :         */
     504         727 :         if ( !m_rExport.SupportsUnicode() )
     505           0 :             aFont.SetCharSet( GetCharSet() );
     506             : 
     507         727 :         if ( rParentFont != aFont )
     508         269 :             m_rExport.AttrOutput().OutputItem( aFont );
     509         727 :     }
     510         727 : }
     511             : 
     512        1349 : void SwWW8AttrIter::OutFlys(xub_StrLen nSwPos)
     513             : {
     514             :     /*
     515             :      #i2916#
     516             :      May have an anchored graphic to be placed, loop through sorted array
     517             :      and output all at this position
     518             :     */
     519        2724 :     while ( maFlyIter != maFlyFrms.end() )
     520             :     {
     521          26 :         const SwPosition &rAnchor = maFlyIter->GetPosition();
     522          26 :         xub_StrLen nPos = rAnchor.nContent.GetIndex();
     523             : 
     524          26 :         if ( nPos != nSwPos )
     525           0 :             break;
     526             :         else
     527             :         {
     528          26 :             m_rExport.AttrOutput().OutputFlyFrame( *maFlyIter );
     529          26 :             ++maFlyIter;
     530             :         }
     531             :     }
     532        1349 : }
     533             : 
     534         727 : bool SwWW8AttrIter::IsTxtAttr( xub_StrLen nSwPos )
     535             : {
     536             :     // search for attrs with CH_TXTATR
     537         727 :     if (const SwpHints* pTxtAttrs = rNd.GetpSwpHints())
     538             :     {
     539         940 :         for (sal_uInt16 i = 0; i < pTxtAttrs->Count(); ++i)
     540             :         {
     541         711 :             const SwTxtAttr* pHt = (*pTxtAttrs)[i];
     542         711 :             if ( pHt->HasDummyChar() && (*pHt->GetStart() == nSwPos) )
     543          81 :                 return true;
     544             :         }
     545             :     }
     546             : 
     547         646 :     return false;
     548             : }
     549             : 
     550         727 : bool SwWW8AttrIter::IsDropCap( int nSwPos )
     551             : {
     552             :     // see if the current position falls on a DropCap
     553         727 :     int nDropChars = mrSwFmtDrop.GetChars();
     554         727 :     bool bWholeWord = mrSwFmtDrop.GetWholeWord();
     555         727 :     if (bWholeWord)
     556             :     {
     557           0 :         short nWordLen = rNd.GetDropLen(0);
     558           0 :         if(nSwPos == nWordLen && nSwPos != 0)
     559           0 :             return true;
     560             :     }
     561             :     else
     562             :     {
     563         727 :         if (nSwPos == nDropChars && nSwPos != 0)
     564           0 :             return true;
     565             :     }
     566         727 :     return false;
     567             : }
     568             : 
     569         622 : bool SwWW8AttrIter::RequiresImplicitBookmark()
     570             : {
     571         622 :     SwImplBookmarksIter bkmkIterEnd = m_rExport.maImplicitBookmarks.end();
     572         622 :     for ( SwImplBookmarksIter aIter = m_rExport.maImplicitBookmarks.begin(); aIter != bkmkIterEnd; ++aIter )
     573             :     {
     574           0 :         sal_uLong sample  = aIter->second;
     575             : 
     576           0 :         if ( sample == rNd.GetIndex() )
     577           0 :             return true;
     578             :     }
     579         622 :     return false;
     580             : }
     581             : 
     582             : //HasItem is for the summary of the double attributes: Underline and WordlineMode as TextItems.
     583             : // OutAttr () calls the output function, which can call HasItem() for other items at the attribute's start position.
     584             : // Only attributes with end can be queried.
     585             : // It searches with bDeep
     586         345 : const SfxPoolItem* SwWW8AttrIter::HasTextItem( sal_uInt16 nWhich ) const
     587             : {
     588         345 :     const SfxPoolItem* pRet = 0;
     589         345 :     const SwpHints* pTxtAttrs = rNd.GetpSwpHints();
     590             : 
     591         345 :     if (pTxtAttrs && !m_rExport.m_aCurrentCharPropStarts.empty())
     592             :     {
     593         243 :         xub_StrLen nTmpSwPos = m_rExport.m_aCurrentCharPropStarts.top();
     594         527 :         for (sal_uInt16 i = 0; i < pTxtAttrs->Count(); ++i)
     595             :         {
     596         495 :             const SwTxtAttr* pHt = (*pTxtAttrs)[i];
     597         495 :             const SfxPoolItem* pItem = &pHt->GetAttr();
     598         495 :             const xub_StrLen* pAtrEnd = 0;
     599         977 :             if( 0 != ( pAtrEnd = pHt->GetEnd() ) &&     // only Attr with an end
     600         482 :                 nWhich == pItem->Which() &&
     601         495 :                 nTmpSwPos >= *pHt->GetStart() && nTmpSwPos < *pAtrEnd )
     602             :             {
     603           0 :                 pRet = pItem;       // found it
     604           0 :                 break;
     605             :             }
     606         495 :             else if (nTmpSwPos < *pHt->GetStart())
     607         211 :                 break;              // nothing more to come
     608             :         }
     609             :     }
     610         345 :     return pRet;
     611             : }
     612             : 
     613           6 : void WW8Export::GetCurrentItems(ww::bytes &rItems) const
     614             : {
     615           6 :     rItems.insert(rItems.end(), pO->begin(), pO->end());
     616           6 : }
     617             : 
     618         328 : const SfxPoolItem& SwWW8AttrIter::GetItem(sal_uInt16 nWhich) const
     619             : {
     620         328 :     const SfxPoolItem* pRet = HasTextItem(nWhich);
     621         328 :     return pRet ? *pRet : rNd.SwCntntNode::GetAttr(nWhich);
     622             : }
     623             : 
     624           0 : void WW8AttributeOutput::StartRuby( const SwTxtNode& rNode, xub_StrLen /*nPos*/, const SwFmtRuby& rRuby )
     625             : {
     626           0 :     String aStr( FieldString( ww::eEQ ) );
     627           0 :     aStr.AppendAscii( "\\* jc" );
     628           0 :     sal_Int32 nJC = 0;
     629           0 :     sal_Char cDirective = 0;
     630           0 :     switch ( rRuby.GetAdjustment() )
     631             :     {
     632             :         case 0:
     633           0 :             nJC = 3;
     634           0 :             cDirective = 'l';
     635           0 :             break;
     636             :         case 1:
     637             :             //defaults to 0
     638           0 :             break;
     639             :         case 2:
     640           0 :             nJC = 4;
     641           0 :             cDirective = 'r';
     642           0 :             break;
     643             :         case 3:
     644           0 :             nJC = 1;
     645           0 :             cDirective = 'd';
     646           0 :             break;
     647             :         case 4:
     648           0 :             nJC = 2;
     649           0 :             cDirective = 'd';
     650           0 :             break;
     651             :         default:
     652             :             OSL_ENSURE( !this,"Unhandled Ruby justication code" );
     653           0 :             break;
     654             :     }
     655           0 :     aStr += OUString::number( nJC );
     656             : 
     657             :     /*
     658             :      MS needs to know the name and size of the font used in the ruby item,
     659             :      but we coud have written it in a mixture of asian and western
     660             :      scripts, and each of these can be a different font and size than the
     661             :      other, so we make a guess based upon the first character of the text,
     662             :      defaulting to asian.
     663             :      */
     664             :     sal_uInt16 nRubyScript;
     665           0 :     if( g_pBreakIt->GetBreakIter().is() )
     666           0 :         nRubyScript = g_pBreakIt->GetBreakIter()->getScriptType( rRuby.GetText(), 0);
     667             :     else
     668           0 :         nRubyScript = i18n::ScriptType::ASIAN;
     669             : 
     670           0 :     const SwTxtRuby* pRubyTxt = rRuby.GetTxtRuby();
     671           0 :     const SwCharFmt* pFmt = pRubyTxt ? pRubyTxt->GetCharFmt() : 0;
     672           0 :     String sFamilyName;
     673             :     long nHeight;
     674           0 :     if ( pFmt )
     675             :     {
     676             :         const SvxFontItem &rFont = ItemGet< SvxFontItem >( *pFmt,
     677           0 :                 GetWhichOfScript(RES_CHRATR_FONT,nRubyScript) );
     678           0 :         sFamilyName = rFont.GetFamilyName();
     679             : 
     680             :         const SvxFontHeightItem &rHeight = ItemGet< SvxFontHeightItem >( *pFmt,
     681           0 :                 GetWhichOfScript( RES_CHRATR_FONTSIZE, nRubyScript ) );
     682           0 :         nHeight = rHeight.GetHeight();
     683             :     }
     684             :     else
     685             :     {
     686             :         /*Get defaults if no formatting on ruby text*/
     687             : 
     688           0 :         const SfxItemPool *pPool = rNode.GetSwAttrSet().GetPool();
     689           0 :         pPool = pPool ? pPool : &m_rWW8Export.pDoc->GetAttrPool();
     690             : 
     691             :         const SvxFontItem &rFont  = DefaultItemGet< SvxFontItem >( *pPool,
     692           0 :                 GetWhichOfScript( RES_CHRATR_FONT,nRubyScript ) );
     693           0 :         sFamilyName = rFont.GetFamilyName();
     694             : 
     695             :         const SvxFontHeightItem &rHeight = DefaultItemGet< SvxFontHeightItem >
     696           0 :             ( *pPool, GetWhichOfScript( RES_CHRATR_FONTSIZE, nRubyScript ) );
     697           0 :         nHeight = rHeight.GetHeight();
     698             :     }
     699           0 :     nHeight = (nHeight + 5)/10;
     700             : 
     701           0 :     aStr.AppendAscii( " \\* \"Font:" );
     702           0 :     aStr.Append( sFamilyName );
     703           0 :     aStr.AppendAscii( "\" \\* hps" );
     704           0 :     aStr += OUString::number( nHeight );
     705           0 :     aStr.AppendAscii( " \\o" );
     706           0 :     if ( cDirective )
     707             :     {
     708           0 :         aStr.AppendAscii( "\\a" );
     709           0 :         aStr.Append( cDirective );
     710             :     }
     711           0 :     aStr.AppendAscii( "(\\s\\up " );
     712             : 
     713             : 
     714           0 :     if ( g_pBreakIt->GetBreakIter().is() )
     715           0 :         nRubyScript = g_pBreakIt->GetBreakIter()->getScriptType( rNode.GetTxt(),
     716           0 :                 *( pRubyTxt->GetStart() ) );
     717             :     else
     718           0 :         nRubyScript = i18n::ScriptType::ASIAN;
     719             : 
     720           0 :     const SwAttrSet& rSet = rNode.GetSwAttrSet();
     721             :     const SvxFontHeightItem &rHeightItem  =
     722             :         ( const SvxFontHeightItem& )rSet.Get(
     723           0 :                                              GetWhichOfScript( RES_CHRATR_FONTSIZE, nRubyScript ) );
     724           0 :     nHeight = (rHeightItem.GetHeight() + 10)/20-1;
     725           0 :     aStr += OUString::number(nHeight);
     726           0 :     aStr += '(';
     727           0 :     aStr += rRuby.GetText();
     728           0 :     aStr.AppendAscii( ")" );
     729             : 
     730             :     // The parameter separator depends on the FIB.lid
     731           0 :     if ( m_rWW8Export.pFib->getNumDecimalSep() == '.' )
     732           0 :         aStr.AppendAscii( "," );
     733             :     else
     734           0 :         aStr.AppendAscii( ";" );
     735             : 
     736             :     m_rWW8Export.OutputField( 0, ww::eEQ, aStr,
     737           0 :             WRITEFIELD_START | WRITEFIELD_CMD_START );
     738           0 : }
     739             : 
     740           0 : void WW8AttributeOutput::EndRuby()
     741             : {
     742           0 :     m_rWW8Export.WriteChar( ')' );
     743           0 :     m_rWW8Export.OutputField( 0, ww::eEQ, aEmptyStr, WRITEFIELD_END | WRITEFIELD_CLOSE );
     744           0 : }
     745             : 
     746             : /*#i15387# Better ideas welcome*/
     747           4 : String &TruncateBookmark( String &rRet )
     748             : {
     749           4 :     if ( rRet.Len() > 40 )
     750           0 :         rRet.Erase( 40 );
     751             :     OSL_ENSURE( rRet.Len() <= 40, "Word cannot have bookmarks longer than 40 chars" );
     752           4 :     return rRet;
     753             : }
     754             : 
     755           4 : bool AttributeOutputBase::AnalyzeURL( const String& rUrl, const String& /*rTarget*/, String* pLinkURL, String* pMark )
     756             : {
     757           4 :     bool bBookMarkOnly = false;
     758             : 
     759           4 :     INetURLObject aURL( rUrl );
     760           8 :     String sMark;
     761           8 :     String sURL;
     762             : 
     763           4 :     if ( rUrl.Len() > 1 && rUrl.GetChar(0) == INET_MARK_TOKEN )
     764             :     {
     765           0 :         sMark = BookmarkToWriter( rUrl.Copy(1) );
     766             : 
     767           0 :         xub_StrLen nPos = sMark.SearchBackward( cMarkSeparator );
     768             : 
     769           0 :         String sRefType(comphelper::string::remove(sMark.Copy(nPos+1), ' '));
     770             : 
     771             :         // #i21465# Only interested in outline references
     772           0 :         if ( sRefType.EqualsAscii( pMarkToOutline ) )
     773             :         {
     774           0 :             String sLink = sMark.Copy(0, nPos);
     775           0 :             SwImplBookmarksIter bkmkIterEnd = GetExport().maImplicitBookmarks.end();
     776           0 :             for ( SwImplBookmarksIter aIter = GetExport().maImplicitBookmarks.begin(); aIter != bkmkIterEnd; ++aIter )
     777             :             {
     778           0 :                 String bkmkName  = aIter->first;
     779             : 
     780           0 :                 if ( bkmkName == sLink )
     781             :                 {
     782           0 :                     sMark = String(  "_toc"  );
     783           0 :                     sMark += OUString::number( aIter->second );
     784             :                 }
     785           0 :             }
     786           0 :         }
     787             :     }
     788             :     else
     789             :     {
     790           4 :         sURL = aURL.GetURLNoMark( INetURLObject::DECODE_UNAMBIGUOUS );
     791           4 :         sMark = aURL.GetMark( INetURLObject::DECODE_UNAMBIGUOUS );
     792             : 
     793             :     }
     794             : 
     795           4 :     if ( sMark.Len() && !sURL.Len() )
     796           0 :         bBookMarkOnly = true;
     797             : 
     798             : 
     799             : 
     800           4 :     *pMark = sMark;
     801           4 :     *pLinkURL = sURL;
     802           8 :     return bBookMarkOnly;
     803             : }
     804             : 
     805           1 : bool WW8AttributeOutput::AnalyzeURL( const String& rUrl, const String& rTarget, String* pLinkURL, String* pMark )
     806             : {
     807           1 :     bool bBookMarkOnly = AttributeOutputBase::AnalyzeURL( rUrl, rTarget, pLinkURL, pMark );
     808             : 
     809           1 :     String sURL = *pLinkURL;
     810           2 :     String sMark = *pMark;
     811             : 
     812           1 :     if ( sURL.Len() )
     813           1 :         sURL = URIHelper::simpleNormalizedMakeRelative( m_rWW8Export.GetWriter().GetBaseURL(), sURL );
     814             : 
     815           1 :     if ( bBookMarkOnly )
     816           0 :         sURL = FieldString( ww::eHYPERLINK );
     817             :     else
     818             :     {
     819           1 :         String sFld( FieldString( ww::eHYPERLINK ) );
     820           1 :         sFld.AppendAscii( "\"" );
     821           1 :         sURL.Insert( sFld, 0 );
     822           1 :         sURL += '\"';
     823             :     }
     824             : 
     825           1 :     if ( sMark.Len() )
     826           0 :         ( ( sURL.AppendAscii( " \\l \"" ) ) += sMark ) += '\"';
     827             : 
     828           1 :     if ( rTarget.Len() )
     829           0 :         ( sURL.AppendAscii( " \\n " ) ) += rTarget;
     830             : 
     831           1 :     *pLinkURL = sURL;
     832           1 :     *pMark = sMark;
     833             : 
     834           2 :     return bBookMarkOnly;
     835             : }
     836             : 
     837           1 : bool WW8AttributeOutput::StartURL( const String &rUrl, const String &rTarget )
     838             : {
     839             :     // hyperlinks only in WW8
     840           1 :     if ( !m_rWW8Export.bWrtWW8 )
     841           0 :         return false;
     842             : 
     843           1 :     INetURLObject aURL( rUrl );
     844           2 :     String sURL;
     845           2 :     String sMark;
     846             : 
     847           1 :     bool bBookMarkOnly = AnalyzeURL( rUrl, rTarget, &sURL, &sMark );
     848             : 
     849             : 
     850           1 :     m_rWW8Export.OutputField( 0, ww::eHYPERLINK, sURL, WRITEFIELD_START | WRITEFIELD_CMD_START );
     851             : 
     852             :     // write the refence to the "picture" structure
     853           1 :     sal_uLong nDataStt = m_rWW8Export.pDataStrm->Tell();
     854           1 :     m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell() );
     855             : 
     856             :     // WinWord 2000 doesn't write this - so its a temp solution by W97 ?
     857           1 :     m_rWW8Export.WriteChar( 0x01 );
     858             : 
     859             :     static sal_uInt8 aArr1[] = {
     860             :         0x03, 0x6a, 0,0,0,0,    // sprmCPicLocation
     861             : 
     862             :         0x06, 0x08, 0x01,       // sprmCFData
     863             :         0x55, 0x08, 0x01,       // sprmCFSpec
     864             :         0x02, 0x08, 0x01        // sprmCFFldVanish
     865             :     };
     866           1 :     sal_uInt8* pDataAdr = aArr1 + 2;
     867           1 :     Set_UInt32( pDataAdr, nDataStt );
     868             : 
     869           1 :     m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), sizeof( aArr1 ), aArr1 );
     870             : 
     871           1 :     m_rWW8Export.OutputField( 0, ww::eHYPERLINK, sURL, WRITEFIELD_CMD_END );
     872             : 
     873             :     // now write the picture structur
     874           1 :     sURL = aURL.GetURLNoMark();
     875             : 
     876             :     // Compare the URL written by AnalyzeURL with the original one to see if
     877             :     // the output URL is absolute or relative.
     878           2 :     String sRelativeURL;
     879           1 :     if ( rUrl.Len() )
     880           1 :         sRelativeURL = URIHelper::simpleNormalizedMakeRelative( m_rWW8Export.GetWriter().GetBaseURL(), rUrl );
     881           1 :     bool bAbsolute = sRelativeURL.Equals( rUrl );
     882             : 
     883             :     static sal_uInt8 aURLData1[] = {
     884             :         0,0,0,0,        // len of struct
     885             :         0x44,0,         // the start of "next" data
     886             :         0,0,0,0,0,0,0,0,0,0,                // PIC-Structure!
     887             :         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    //  |
     888             :         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    //  |
     889             :         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    //  |
     890             :         0,0,0,0,                            // /
     891             :     };
     892             :     static sal_uInt8 MAGIC_A[] = {
     893             :         // start of "next" data
     894             :         0xD0,0xC9,0xEA,0x79,0xF9,0xBA,0xCE,0x11,
     895             :         0x8C,0x82,0x00,0xAA,0x00,0x4B,0xA9,0x0B
     896             :     };
     897             : 
     898           1 :     m_rWW8Export.pDataStrm->Write( aURLData1, sizeof( aURLData1 ) );
     899             :     /* Write HFD Structure */
     900           1 :     sal_uInt8 nAnchor = 0x00;
     901           1 :     if ( sMark.Len() )
     902           0 :         nAnchor = 0x08;
     903           1 :     m_rWW8Export.pDataStrm->Write( &nAnchor, 1 ); // HFDBits
     904           1 :     m_rWW8Export.pDataStrm->Write( MAGIC_A, sizeof(MAGIC_A) ); //clsid
     905             : 
     906             :     /* Write Hyperlink Object see [MS-OSHARED] spec*/
     907           1 :     SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, 0x00000002);
     908           1 :     sal_uInt32 nFlag = bBookMarkOnly ? 0 : 0x01;
     909           1 :     if ( bAbsolute )
     910           1 :         nFlag |= 0x02;
     911           1 :     if ( sMark.Len() )
     912           0 :         nFlag |= 0x08;
     913           1 :     SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, nFlag );
     914             : 
     915           1 :     INetProtocol eProto = aURL.GetProtocol();
     916           1 :     if ( eProto == INET_PROT_FILE || eProto == INET_PROT_SMB )
     917             :     {
     918             :         // version 1 (for a document)
     919             : 
     920             :         static sal_uInt8 MAGIC_C[] = {
     921             :             0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     922             :             0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
     923             :             0x00, 0x00
     924             :         };
     925             : 
     926             :         static sal_uInt8 MAGIC_D[] = {
     927             :             0xFF, 0xFF, 0xAD, 0xDE, 0x00, 0x00, 0x00, 0x00,
     928             :             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     929             :             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     930             :         };
     931             : 
     932             :         // save the links to files as relative
     933           0 :         sURL = URIHelper::simpleNormalizedMakeRelative( m_rWW8Export.GetWriter().GetBaseURL(), sURL );
     934           0 :         if ( eProto == INET_PROT_FILE && sURL.EqualsAscii( "/", 0, 1 ) )
     935           0 :             sURL = aURL.PathToFileName();
     936             : 
     937             :         // special case for the absolute windows names
     938             :         // (convert '/c:/foo/bar.doc' into 'c:\foo\bar.doc')
     939           0 :         sal_Unicode aDrive = ( sURL.Len() > 1 )? sURL.GetChar( 1 ): 0;
     940           0 :         if ( sURL.EqualsAscii( "/", 0, 1 ) &&
     941           0 :              ( ( aDrive >= 'A' && aDrive <= 'Z' ) || ( aDrive >= 'a' && aDrive <= 'z' ) ) &&
     942           0 :              sURL.EqualsAscii( ":", 2, 1 ) )
     943             :         {
     944           0 :             sURL.Erase( 0, 1 );
     945           0 :             sURL.SearchAndReplaceAll( '/', '\\' );
     946             :         }
     947             : 
     948             :         // n#261623 convert smb notation to '\\'
     949           0 :         const char pSmb[] = "smb://";
     950           0 :         if ( eProto == INET_PROT_SMB &&
     951           0 :              sURL.EqualsAscii( pSmb, 0, sizeof( pSmb ) - 1 ) )
     952             :         {
     953           0 :             sURL.Erase( 0, sizeof( pSmb ) - 3 );
     954           0 :             sURL.SearchAndReplaceAll( '/', '\\' );
     955             :         }
     956             : 
     957           0 :         m_rWW8Export.pDataStrm->Write( MAGIC_C, sizeof(MAGIC_C) );
     958           0 :         SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, sURL.Len()+1 );
     959             :         SwWW8Writer::WriteString8( *m_rWW8Export.pDataStrm, sURL, true,
     960           0 :                                     RTL_TEXTENCODING_MS_1252 );
     961           0 :         m_rWW8Export.pDataStrm->Write( MAGIC_D, sizeof( MAGIC_D ) );
     962             : 
     963           0 :         SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, 2*sURL.Len() + 6 );
     964           0 :         SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, 2*sURL.Len() );
     965           0 :         SwWW8Writer::WriteShort( *m_rWW8Export.pDataStrm, 3 );
     966           0 :         SwWW8Writer::WriteString16( *m_rWW8Export.pDataStrm, sURL, false );
     967             :     }
     968           1 :     else if ( eProto != INET_PROT_NOT_VALID )
     969             :     {
     970             :         // version 2 (simple url)
     971             :         // an write some data to the data stream, but dont ask
     972             :         // what the data mean, except for the URL.
     973             :         // The First piece is the WW8_PIC structure.
     974             :         static sal_uInt8 MAGIC_B[] = {
     975             :             0xE0,0xC9,0xEA,0x79,0xF9,0xBA,0xCE,0x11,
     976             :             0x8C,0x82,0x00,0xAA,0x00,0x4B,0xA9,0x0B
     977             :         };
     978             : 
     979           1 :         m_rWW8Export.pDataStrm->Write( MAGIC_B, sizeof(MAGIC_B) );
     980           1 :         SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, 2 * ( sURL.Len() + 1 ) );
     981           1 :         SwWW8Writer::WriteString16( *m_rWW8Export.pDataStrm, sURL, true );
     982             :     }
     983             : 
     984           1 :     if ( sMark.Len() )
     985             :     {
     986           0 :         SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, sMark.Len()+1 );
     987           0 :         SwWW8Writer::WriteString16( *m_rWW8Export.pDataStrm, sMark, true );
     988             :     }
     989             :     SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, nDataStt,
     990           1 :         m_rWW8Export.pDataStrm->Tell() - nDataStt );
     991             : 
     992           2 :     return true;
     993             : }
     994             : 
     995           1 : bool WW8AttributeOutput::EndURL()
     996             : {
     997             :     // hyperlinks only in WW8
     998           1 :     if ( !m_rWW8Export.bWrtWW8 )
     999           0 :         return false;
    1000             : 
    1001           1 :     m_rWW8Export.OutputField( 0, ww::eHYPERLINK, aEmptyStr, WRITEFIELD_CLOSE );
    1002             : 
    1003           1 :     return true;
    1004             : }
    1005             : 
    1006           4 : String BookmarkToWord(const String &rBookmark)
    1007             : {
    1008             :     String sRet(INetURLObject::encode(rBookmark,
    1009             :         INetURLObject::PART_REL_SEGMENT_EXTRA, '%',
    1010           4 :         INetURLObject::ENCODE_ALL, RTL_TEXTENCODING_ASCII_US));
    1011           4 :     return TruncateBookmark(sRet);
    1012             : }
    1013             : 
    1014           6 : String BookmarkToWriter(const String &rBookmark)
    1015             : {
    1016             :     return INetURLObject::decode(rBookmark, '%',
    1017           6 :         INetURLObject::DECODE_UNAMBIGUOUS, RTL_TEXTENCODING_ASCII_US);
    1018             : }
    1019             : 
    1020           0 : void SwWW8AttrIter::OutSwFmtRefMark(const SwFmtRefMark& rAttr, bool)
    1021             : {
    1022           0 :     if ( m_rExport.HasRefToObject( REF_SETREFATTR, &rAttr.GetRefName(), 0 ) )
    1023             :         m_rExport.AppendBookmark( m_rExport.GetBookmarkName( REF_SETREFATTR,
    1024           0 :                                             &rAttr.GetRefName(), 0 ));
    1025           0 : }
    1026             : 
    1027           0 : void WW8AttributeOutput::FieldVanish( const String& rTxt, ww::eField /*eType*/ )
    1028             : {
    1029           0 :     ww::bytes aItems;
    1030           0 :     m_rWW8Export.GetCurrentItems( aItems );
    1031             : 
    1032             :     // sprmCFFldVanish
    1033           0 :     if ( m_rWW8Export.bWrtWW8 )
    1034           0 :         SwWW8Writer::InsUInt16( aItems, NS_sprm::LN_CFFldVanish );
    1035             :     else
    1036           0 :         aItems.push_back( 67 );
    1037           0 :     aItems.push_back( 1 );
    1038             : 
    1039           0 :     sal_uInt16 nStt_sprmCFSpec = aItems.size();
    1040             : 
    1041             :     // sprmCFSpec --  fSpec-Attribut true
    1042           0 :     if ( m_rWW8Export.bWrtWW8 )
    1043           0 :         SwWW8Writer::InsUInt16( aItems, 0x855 );
    1044             :     else
    1045           0 :         aItems.push_back( 117 );
    1046           0 :     aItems.push_back( 1 );
    1047             : 
    1048           0 :     m_rWW8Export.WriteChar( '\x13' );
    1049           0 :     m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), aItems.size(),
    1050           0 :                                     aItems.data() );
    1051           0 :     m_rWW8Export.OutSwString( rTxt, 0, rTxt.Len(), m_rWW8Export.IsUnicode(),
    1052           0 :                         RTL_TEXTENCODING_MS_1252 );
    1053           0 :     m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), nStt_sprmCFSpec,
    1054           0 :                                     aItems.data() );
    1055           0 :     m_rWW8Export.WriteChar( '\x15' );
    1056           0 :     m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), aItems.size(),
    1057           0 :                                     aItems.data() );
    1058           0 : }
    1059             : 
    1060           0 : void AttributeOutputBase::TOXMark( const SwTxtNode& rNode, const SwTOXMark& rAttr )
    1061             : {
    1062             :     // its a field; so get the Text form the Node and build the field
    1063           0 :     String sTxt;
    1064           0 :     ww::eField eType = ww::eNONE;
    1065             : 
    1066           0 :     const SwTxtTOXMark& rTxtTOXMark = *rAttr.GetTxtTOXMark();
    1067           0 :     const xub_StrLen* pTxtEnd = rTxtTOXMark.GetEnd();
    1068           0 :     if ( pTxtEnd ) // has range?
    1069             :     {
    1070           0 :         sTxt = rNode.GetExpandTxt( *rTxtTOXMark.GetStart(),
    1071           0 :                                    *pTxtEnd - *rTxtTOXMark.GetStart() );
    1072             :     }
    1073             :     else
    1074           0 :         sTxt = rAttr.GetAlternativeText();
    1075             : 
    1076           0 :     switch ( rAttr.GetTOXType()->GetType() )
    1077             :     {
    1078             :         case TOX_INDEX:
    1079           0 :             eType = ww::eXE;
    1080           0 :             if ( rAttr.GetPrimaryKey().Len() )
    1081             :             {
    1082           0 :                 if ( rAttr.GetSecondaryKey().Len() )
    1083             :                 {
    1084           0 :                     sTxt.Insert( ':', 0 );
    1085           0 :                     sTxt.Insert( rAttr.GetSecondaryKey(), 0 );
    1086             :                 }
    1087             : 
    1088           0 :                 sTxt.Insert( ':', 0 );
    1089           0 :                 sTxt.Insert( rAttr.GetPrimaryKey(), 0 );
    1090             :             }
    1091           0 :             sTxt.InsertAscii( " XE \"", 0 );
    1092           0 :             sTxt.InsertAscii( "\" " );
    1093           0 :             break;
    1094             : 
    1095             :         case TOX_USER:
    1096           0 :             ( sTxt.AppendAscii( "\" \\f \"" ) )
    1097           0 :                 += (sal_Char)( 'A' + GetExport( ).GetId( *rAttr.GetTOXType() ) );
    1098             :             // fall through - no break;
    1099             :         case TOX_CONTENT:
    1100             :             {
    1101           0 :                 eType = ww::eTC;
    1102           0 :                 sTxt.InsertAscii( " TC \"", 0 );
    1103           0 :                 sal_uInt16 nLvl = rAttr.GetLevel();
    1104           0 :                 if (nLvl > WW8ListManager::nMaxLevel)
    1105           0 :                     nLvl = WW8ListManager::nMaxLevel;
    1106             : 
    1107           0 :                 ((sTxt.AppendAscii( "\" \\l " ))
    1108           0 :                  += OUString::number( nLvl )) += ' ';
    1109             :             }
    1110           0 :             break;
    1111             :         default:
    1112             :             OSL_ENSURE( !this, "Unhandled option for toc export" );
    1113           0 :             break;
    1114             :     }
    1115             : 
    1116           0 :     if ( sTxt.Len() )
    1117           0 :         FieldVanish( sTxt, eType );
    1118           0 : }
    1119             : 
    1120        1033 : int SwWW8AttrIter::OutAttrWithRange(xub_StrLen nPos)
    1121             : {
    1122        1033 :     int nRet = 0;
    1123        1033 :     if ( const SwpHints* pTxtAttrs = rNd.GetpSwpHints() )
    1124             :     {
    1125         517 :         m_rExport.m_aCurrentCharPropStarts.push( nPos );
    1126             :         const xub_StrLen* pEnd;
    1127        1634 :         for ( sal_uInt16 i = 0; i < pTxtAttrs->Count(); ++i )
    1128             :         {
    1129        1117 :             const SwTxtAttr* pHt = (*pTxtAttrs)[i];
    1130        1117 :             const SfxPoolItem* pItem = &pHt->GetAttr();
    1131        1117 :             switch ( pItem->Which() )
    1132             :             {
    1133             :                 case RES_TXTATR_INETFMT:
    1134          18 :                     if ( nPos == *pHt->GetStart() )
    1135             :                     {
    1136           5 :                         const SwFmtINetFmt *rINet = static_cast< const SwFmtINetFmt* >( pItem );
    1137           5 :                         if ( m_rExport.AttrOutput().StartURL( rINet->GetValue(), rINet->GetTargetFrame() ) )
    1138           5 :                             ++nRet;
    1139             :                     }
    1140          18 :                     if ( 0 != ( pEnd = pHt->GetEnd() ) && nPos == *pEnd )
    1141             :                     {
    1142           5 :                         if ( m_rExport.AttrOutput().EndURL() )
    1143           5 :                             --nRet;
    1144             :                     }
    1145          18 :                     break;
    1146             :                 case RES_TXTATR_REFMARK:
    1147           0 :                     if ( nPos == *pHt->GetStart() )
    1148             :                     {
    1149           0 :                         OutSwFmtRefMark( *static_cast< const SwFmtRefMark* >( pItem ), true );
    1150           0 :                         ++nRet;
    1151             :                     }
    1152           0 :                     if ( 0 != ( pEnd = pHt->GetEnd() ) && nPos == *pEnd )
    1153             :                     {
    1154           0 :                         OutSwFmtRefMark( *static_cast< const SwFmtRefMark* >( pItem ), false );
    1155           0 :                         --nRet;
    1156             :                     }
    1157           0 :                     break;
    1158             :                 case RES_TXTATR_TOXMARK:
    1159           0 :                     if ( nPos == *pHt->GetStart() )
    1160           0 :                         m_rExport.AttrOutput().TOXMark( rNd, *static_cast< const SwTOXMark* >( pItem ) );
    1161           0 :                     break;
    1162             :                 case RES_TXTATR_CJK_RUBY:
    1163           0 :                     if ( nPos == *pHt->GetStart() )
    1164             :                     {
    1165           0 :                         m_rExport.AttrOutput().StartRuby( rNd, nPos, *static_cast< const SwFmtRuby* >( pItem ) );
    1166           0 :                         ++nRet;
    1167             :                     }
    1168           0 :                     if ( 0 != ( pEnd = pHt->GetEnd() ) && nPos == *pEnd )
    1169             :                     {
    1170           0 :                         m_rExport.AttrOutput().EndRuby();
    1171           0 :                         --nRet;
    1172             :                     }
    1173           0 :                     break;
    1174             :             }
    1175             :         }
    1176         517 :         m_rExport.m_aCurrentCharPropStarts.pop(); // HasTextItem only allowed in the above range
    1177             :     }
    1178        1033 :     return nRet;
    1179             : }
    1180             : 
    1181         560 : bool SwWW8AttrIter::IsRedlineAtEnd( xub_StrLen nEnd ) const
    1182             : {
    1183         560 :     bool bRet = false;
    1184             :     // search next Redline
    1185        1120 :     for( sal_uInt16 nPos = nCurRedlinePos;
    1186         560 :         nPos < m_rExport.pDoc->GetRedlineTbl().size(); ++nPos )
    1187             :     {
    1188           6 :         const SwPosition* pEnd = m_rExport.pDoc->GetRedlineTbl()[ nPos ]->End();
    1189           6 :         if( pEnd->nNode == rNd )
    1190             :         {
    1191           1 :             if( pEnd->nContent.GetIndex() == nEnd )
    1192             :             {
    1193           1 :                 bRet = true;
    1194           1 :                 break;
    1195             :             }
    1196             :         }
    1197             :         else
    1198           5 :             break;
    1199             :     }
    1200         560 :     return bRet;
    1201             : }
    1202             : 
    1203         728 : const SwRedlineData* SwWW8AttrIter::GetRedline( xub_StrLen nPos )
    1204             : {
    1205         728 :     if( pCurRedline )
    1206             :     {
    1207           6 :         const SwPosition* pEnd = pCurRedline->End();
    1208          11 :         if( pEnd->nNode == rNd &&
    1209           5 :             pEnd->nContent.GetIndex() <= nPos )
    1210             :         {
    1211           4 :             pCurRedline = 0;
    1212           4 :             ++nCurRedlinePos;
    1213             :         }
    1214             :         else
    1215             :         {
    1216             :             // write data of current redline
    1217           2 :             return &( pCurRedline->GetRedlineData() );
    1218             :         }
    1219             :     }
    1220             : 
    1221         726 :     if( !pCurRedline )
    1222             :     {
    1223             :         // search next Redline
    1224         726 :         for( ; nCurRedlinePos < m_rExport.pDoc->GetRedlineTbl().size();
    1225             :                 ++nCurRedlinePos )
    1226             :         {
    1227          11 :             const SwRedline* pRedl = m_rExport.pDoc->GetRedlineTbl()[ nCurRedlinePos ];
    1228             : 
    1229          11 :             const SwPosition* pStt = pRedl->Start();
    1230          11 :             const SwPosition* pEnd = pStt == pRedl->GetPoint()
    1231          11 :                                         ? pRedl->GetMark()
    1232          22 :                                         : pRedl->GetPoint();
    1233             : 
    1234          11 :             if( pStt->nNode == rNd )
    1235             :             {
    1236           8 :                 if( pStt->nContent.GetIndex() >= nPos )
    1237             :                 {
    1238           8 :                     if( pStt->nContent.GetIndex() == nPos )
    1239             :                     {
    1240             :                         // write data of this redline
    1241           4 :                         pCurRedline = pRedl;
    1242           4 :                         return &( pCurRedline->GetRedlineData() );
    1243             :                     }
    1244           4 :                     break;
    1245             :                 }
    1246             :             }
    1247             :             else
    1248           3 :                 break;
    1249             : 
    1250           0 :             if( pEnd->nNode == rNd &&
    1251           0 :                 pEnd->nContent.GetIndex() < nPos )
    1252             :             {
    1253           0 :                 pCurRedline = pRedl;
    1254           0 :                 break;
    1255             :             }
    1256             :         }
    1257             :     }
    1258         722 :     return NULL;
    1259             : }
    1260             : 
    1261             : 
    1262          97 : short MSWordExportBase::GetCurrentPageDirection() const
    1263             : {
    1264             :     const SwFrmFmt &rFmt = pAktPageDesc
    1265          97 :                     ? pAktPageDesc->GetMaster()
    1266         194 :                     : pDoc->GetPageDesc( 0 ).GetMaster();
    1267          97 :     return rFmt.GetFrmDir().GetValue();
    1268             : }
    1269             : 
    1270           7 : short MSWordExportBase::GetDefaultFrameDirection( ) const
    1271             : {
    1272           7 :     short nDir = FRMDIR_ENVIRONMENT;
    1273             : 
    1274           7 :     if ( bOutPageDescs )
    1275           0 :         nDir = GetCurrentPageDirection(  );
    1276           7 :     else if ( pOutFmtNode )
    1277             :     {
    1278           7 :         if ( bOutFlyFrmAttrs ) //frame
    1279             :         {
    1280           0 :             nDir = TrueFrameDirection( *( const SwFrmFmt * ) pOutFmtNode );
    1281             :         }
    1282           7 :         else if ( pOutFmtNode->ISA( SwCntntNode ) )    //pagagraph
    1283             :         {
    1284           0 :             const SwCntntNode *pNd = ( const SwCntntNode * ) pOutFmtNode;
    1285           0 :             SwPosition aPos( *pNd );
    1286           0 :             nDir = pDoc->GetTextDirection( aPos );
    1287             :         }
    1288           7 :         else if ( pOutFmtNode->ISA( SwTxtFmtColl ) )
    1289           7 :             nDir = FRMDIR_HORI_LEFT_TOP;    //what else can we do :-(
    1290             :     }
    1291             : 
    1292           7 :     if ( nDir == FRMDIR_ENVIRONMENT )
    1293           0 :         nDir = FRMDIR_HORI_LEFT_TOP;        //Set something
    1294             : 
    1295           7 :     return nDir;
    1296             : }
    1297             : 
    1298         261 : short MSWordExportBase::TrueFrameDirection( const SwFrmFmt &rFlyFmt ) const
    1299             : {
    1300         261 :     const SwFrmFmt *pFlyFmt = &rFlyFmt;
    1301         261 :     const SvxFrameDirectionItem* pItem = 0;
    1302         783 :     while ( pFlyFmt )
    1303             :     {
    1304         261 :         pItem = &pFlyFmt->GetFrmDir();
    1305         261 :         if ( FRMDIR_ENVIRONMENT == pItem->GetValue() )
    1306             :         {
    1307          97 :             pItem = 0;
    1308          97 :             const SwFmtAnchor* pAnchor = &pFlyFmt->GetAnchor();
    1309         105 :             if ((FLY_AT_PAGE != pAnchor->GetAnchorId()) &&
    1310           8 :                 pAnchor->GetCntntAnchor() )
    1311             :             {
    1312           8 :                 pFlyFmt = pAnchor->GetCntntAnchor()->nNode.GetNode().GetFlyFmt();
    1313             :             }
    1314             :             else
    1315          89 :                 pFlyFmt = 0;
    1316             :         }
    1317             :         else
    1318         164 :             pFlyFmt = 0;
    1319             :     }
    1320             : 
    1321             :     short nRet;
    1322         261 :     if ( pItem )
    1323         164 :         nRet = pItem->GetValue();
    1324             :     else
    1325          97 :         nRet = GetCurrentPageDirection();
    1326             : 
    1327             :     OSL_ENSURE( nRet != FRMDIR_ENVIRONMENT, "leaving with environment direction" );
    1328         261 :     return nRet;
    1329             : }
    1330             : 
    1331           1 : const SvxBrushItem* WW8Export::GetCurrentPageBgBrush() const
    1332             : {
    1333             :     const SwFrmFmt  &rFmt = pAktPageDesc
    1334           1 :                     ? pAktPageDesc->GetMaster()
    1335           2 :                     : pDoc->GetPageDesc(0).GetMaster();
    1336             : 
    1337           1 :     const SfxPoolItem* pItem = 0;
    1338             :     //If not set, or "no fill", get real bg
    1339           1 :     SfxItemState eState = rFmt.GetItemState(RES_BACKGROUND, true, &pItem);
    1340             : 
    1341           1 :     const SvxBrushItem* pRet = (const SvxBrushItem*)pItem;
    1342           3 :     if (SFX_ITEM_SET != eState || (!pRet->GetGraphic() &&
    1343           1 :         pRet->GetColor() == COL_TRANSPARENT))
    1344             :     {
    1345           1 :         pRet = &(DefaultItemGet<SvxBrushItem>(*pDoc,RES_BACKGROUND));
    1346             :     }
    1347           1 :     return pRet;
    1348             : }
    1349             : 
    1350           2 : SvxBrushItem WW8Export::TrueFrameBgBrush(const SwFrmFmt &rFlyFmt) const
    1351             : {
    1352           2 :     const SwFrmFmt *pFlyFmt = &rFlyFmt;
    1353           2 :     const SvxBrushItem* pRet = 0;
    1354             : 
    1355           6 :     while (pFlyFmt)
    1356             :     {
    1357             :         //If not set, or "no fill", get real bg
    1358           2 :         const SfxPoolItem* pItem = 0;
    1359             :         SfxItemState eState =
    1360           2 :             pFlyFmt->GetItemState(RES_BACKGROUND, true, &pItem);
    1361           2 :         pRet = (const SvxBrushItem*)pItem;
    1362           7 :         if (SFX_ITEM_SET != eState || (!pRet->GetGraphic() &&
    1363           5 :             pRet->GetColor() == COL_TRANSPARENT))
    1364             :         {
    1365           1 :             pRet = 0;
    1366           1 :             const SwFmtAnchor* pAnchor = &pFlyFmt->GetAnchor();
    1367           2 :             if ((FLY_AT_PAGE != pAnchor->GetAnchorId()) &&
    1368           1 :                 pAnchor->GetCntntAnchor())
    1369             :             {
    1370             :                 pFlyFmt =
    1371           1 :                     pAnchor->GetCntntAnchor()->nNode.GetNode().GetFlyFmt();
    1372             :             }
    1373             :             else
    1374           0 :                 pFlyFmt = 0;
    1375             :         }
    1376             :         else
    1377           1 :             pFlyFmt = 0;
    1378             :     }
    1379             : 
    1380           2 :     if (!pRet)
    1381           1 :         pRet = GetCurrentPageBgBrush();
    1382             : 
    1383           2 :     const Color aTmpColor( COL_WHITE );
    1384           2 :     SvxBrushItem aRet( aTmpColor, RES_BACKGROUND );
    1385           2 :     if (pRet && (pRet->GetGraphic() ||( pRet->GetColor() != COL_TRANSPARENT)))
    1386           1 :         aRet = *pRet;
    1387             : 
    1388           2 :     return aRet;
    1389             : }
    1390             : 
    1391             : 
    1392             : /*
    1393             : Convert characters that need to be converted, the basic replacements and the
    1394             : ridicously complicated title case attribute mapping to hardcoded upper case
    1395             : because word doesn't have the feature
    1396             : */
    1397         330 : String SwWW8AttrIter::GetSnippet(const String &rStr, xub_StrLen nAktPos,
    1398             :     xub_StrLen nLen) const
    1399             : {
    1400         330 :     String aSnippet(rStr, nAktPos, nLen);
    1401         330 :     if (!nLen)
    1402           2 :         return aSnippet;
    1403             : 
    1404             :     // 0x0a     ( Hard Line Break ) -> 0x0b
    1405             :     // 0xad     ( soft hyphen )     -> 0x1f
    1406             :     // 0x2011   ( hard hyphen )     -> 0x1e
    1407         328 :     aSnippet.SearchAndReplaceAll(0x0A, 0x0B);
    1408         328 :     aSnippet.SearchAndReplaceAll(CHAR_HARDHYPHEN, 0x1e);
    1409         328 :     aSnippet.SearchAndReplaceAll(CHAR_SOFTHYPHEN, 0x1f);
    1410             : 
    1411         328 :     m_rExport.m_aCurrentCharPropStarts.push( nAktPos );
    1412         328 :     const SfxPoolItem &rItem = GetItem(RES_CHRATR_CASEMAP);
    1413             : 
    1414         328 :     if (SVX_CASEMAP_TITEL == ((const SvxCaseMapItem&)rItem).GetValue())
    1415             :     {
    1416           0 :         sal_uInt16 nScriptType = i18n::ScriptType::LATIN;
    1417           0 :         if (g_pBreakIt->GetBreakIter().is())
    1418           0 :             nScriptType = g_pBreakIt->GetBreakIter()->getScriptType(aSnippet, 0);
    1419             : 
    1420             :         LanguageType nLanguage;
    1421           0 :         switch (nScriptType)
    1422             :         {
    1423             :         case i18n::ScriptType::ASIAN:
    1424           0 :                 nLanguage = ((const SvxLanguageItem&)GetItem(RES_CHRATR_CJK_LANGUAGE)).GetLanguage();
    1425           0 :                 break;
    1426             :         case i18n::ScriptType::COMPLEX:
    1427           0 :                 nLanguage = ((const SvxLanguageItem&)GetItem(RES_CHRATR_CTL_LANGUAGE)).GetLanguage();
    1428           0 :                 break;
    1429             :         case i18n::ScriptType::LATIN:
    1430             :             default:
    1431           0 :                 nLanguage = ((const SvxLanguageItem&)GetItem(RES_CHRATR_LANGUAGE)).GetLanguage();
    1432           0 :                 break;
    1433             :         }
    1434             : 
    1435           0 :         SvxFont aFontHelper;
    1436           0 :         aFontHelper.SetCaseMap(SVX_CASEMAP_TITEL);
    1437           0 :         aFontHelper.SetLanguage(nLanguage);
    1438           0 :         aSnippet = aFontHelper.CalcCaseMap(aSnippet);
    1439             : 
    1440             :         //If we weren't at the begin of a word undo the case change.
    1441             :         //not done before doing the casemap because the sequence might start
    1442             :         //with whitespace
    1443           0 :         if (g_pBreakIt->GetBreakIter().is() && !g_pBreakIt->GetBreakIter()->isBeginWord(
    1444           0 :             rStr, nAktPos, g_pBreakIt->GetLocale(nLanguage),
    1445           0 :             i18n::WordType::ANYWORD_IGNOREWHITESPACES ) )
    1446             :         {
    1447           0 :             aSnippet.SetChar(0, rStr.GetChar(nAktPos));
    1448           0 :         }
    1449             :     }
    1450         328 :     m_rExport.m_aCurrentCharPropStarts.pop();
    1451             : 
    1452         328 :     return aSnippet;
    1453             : }
    1454             : 
    1455             : /** Delivers the right paragraph style
    1456             : 
    1457             :     Because of the different style handling for delete operations,
    1458             :     the track changes have to be analysed. A deletion, starting in paragraph A
    1459             :     with style A, ending in paragraph B with style B, needs a hack.
    1460             : */
    1461         620 : static SwTxtFmtColl& lcl_getFormatCollection( MSWordExportBase& rExport, const SwTxtNode* pTxtNode )
    1462             : {
    1463         620 :     sal_uInt16 nPos = 0;
    1464         620 :     sal_uInt16 nMax = rExport.pDoc->GetRedlineTbl().size();
    1465        1267 :     while( nPos < nMax )
    1466             :     {
    1467          27 :         const SwRedline* pRedl = rExport.pDoc->GetRedlineTbl()[ nPos++ ];
    1468          27 :         const SwPosition* pStt = pRedl->Start();
    1469          27 :         const SwPosition* pEnd = pStt == pRedl->GetPoint()
    1470          27 :                                     ? pRedl->GetMark()
    1471          54 :                                     : pRedl->GetPoint();
    1472             :         // Looking for deletions, which ends in current pTxtNode
    1473         121 :         if( nsRedlineType_t::REDLINE_DELETE == pRedl->GetRedlineData().GetType() &&
    1474         114 :             pEnd->nNode == *pTxtNode && pStt->nNode != *pTxtNode &&
    1475           3 :             pStt->nNode.GetNode().IsTxtNode() )
    1476             :         {
    1477           3 :             pTxtNode = pStt->nNode.GetNode().GetTxtNode();
    1478           3 :             nMax = nPos;
    1479           3 :             nPos = 0;
    1480             :         }
    1481             :     }
    1482         620 :     return static_cast<SwTxtFmtColl&>( pTxtNode->GetAnyFmtColl() );
    1483             : }
    1484             : 
    1485           0 : void WW8AttributeOutput::FormatDrop( const SwTxtNode& rNode, const SwFmtDrop &rSwFmtDrop, sal_uInt16 nStyle,
    1486             :         ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo, ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner )
    1487             : {
    1488           0 :     short nDropLines = rSwFmtDrop.GetLines();
    1489           0 :     short nDistance = rSwFmtDrop.GetDistance();
    1490             :     int rFontHeight, rDropHeight, rDropDescent;
    1491             : 
    1492             :     SVBT16 nSty;
    1493           0 :     ShortToSVBT16( nStyle, nSty );
    1494           0 :     m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), (sal_uInt8*)&nSty, (sal_uInt8*)&nSty+2 );     // Style #
    1495             : 
    1496           0 :     if ( m_rWW8Export.bWrtWW8 )
    1497             :     {
    1498           0 :         m_rWW8Export.InsUInt16( NS_sprm::LN_PPc );            // Alignment (sprmPPc)
    1499           0 :         m_rWW8Export.pO->push_back( 0x20 );
    1500             : 
    1501           0 :         m_rWW8Export.InsUInt16( NS_sprm::LN_PWr );            // Wrapping (sprmPWr)
    1502           0 :         m_rWW8Export.pO->push_back( 0x02 );
    1503             : 
    1504           0 :         m_rWW8Export.InsUInt16( NS_sprm::LN_PDcs );            // Dropcap (sprmPDcs)
    1505           0 :         int nDCS = ( nDropLines << 3 ) | 0x01;
    1506           0 :         m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( nDCS ) );
    1507             : 
    1508           0 :         m_rWW8Export.InsUInt16( NS_sprm::LN_PDxaFromText );            // Distance from text (sprmPDxaFromText)
    1509           0 :         m_rWW8Export.InsUInt16( nDistance );
    1510             : 
    1511           0 :         if ( rNode.GetDropSize( rFontHeight, rDropHeight, rDropDescent ) )
    1512             :         {
    1513           0 :             m_rWW8Export.InsUInt16( NS_sprm::LN_PDyaLine );            // Line spacing
    1514           0 :             m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( -rDropHeight ) );
    1515           0 :             m_rWW8Export.InsUInt16( 0 );
    1516             :         }
    1517             :     }
    1518             :     else
    1519             :     {
    1520           0 :         m_rWW8Export.pO->push_back( 29 );    // Alignment (sprmPPc)
    1521           0 :         m_rWW8Export.pO->push_back( 0x20 );
    1522             : 
    1523           0 :         m_rWW8Export.pO->push_back( 37 );    // Wrapping (sprmPWr)
    1524           0 :         m_rWW8Export.pO->push_back( 0x02 );
    1525             : 
    1526           0 :         m_rWW8Export.pO->push_back( 46 );    // Dropcap (sprmPDcs)
    1527           0 :         int nDCS = ( nDropLines << 3 ) | 0x01;
    1528           0 :         m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( nDCS ) );
    1529             : 
    1530           0 :         m_rWW8Export.pO->push_back( 49 );      // Distance from text (sprmPDxaFromText)
    1531           0 :         m_rWW8Export.InsUInt16( nDistance );
    1532             : 
    1533           0 :         if (rNode.GetDropSize(rFontHeight, rDropHeight, rDropDescent))
    1534             :         {
    1535           0 :             m_rWW8Export.pO->push_back( 20 );  // Line spacing
    1536           0 :             m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( -rDropHeight ) );
    1537           0 :             m_rWW8Export.InsUInt16( 0 );
    1538             :         }
    1539             :     }
    1540             : 
    1541           0 :     m_rWW8Export.WriteCR( pTextNodeInfoInner );
    1542             : 
    1543           0 :     if ( pTextNodeInfo.get() != NULL )
    1544             :     {
    1545             : #ifdef DBG_UTIL
    1546             :         SAL_INFO( "sw.ww8", pTextNodeInfo->toString());
    1547             : #endif
    1548           0 :         TableInfoCell( pTextNodeInfoInner );
    1549             :     }
    1550             : 
    1551           0 :     m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data() );
    1552           0 :     m_rWW8Export.pO->clear();
    1553             : 
    1554           0 :     if ( rNode.GetDropSize( rFontHeight, rDropHeight, rDropDescent ) )
    1555             :     {
    1556           0 :         if ( m_rWW8Export.bWrtWW8 )
    1557             :         {
    1558           0 :             const SwCharFmt *pSwCharFmt = rSwFmtDrop.GetCharFmt();
    1559           0 :             if ( pSwCharFmt )
    1560             :             {
    1561           0 :                 m_rWW8Export.InsUInt16( NS_sprm::LN_CIstd );
    1562           0 :                 m_rWW8Export.InsUInt16( m_rWW8Export.GetId( *pSwCharFmt ) );
    1563             :             }
    1564             : 
    1565           0 :             m_rWW8Export.InsUInt16( NS_sprm::LN_CHpsPos );            // Lower the chars
    1566           0 :             m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( -((nDropLines - 1)*rDropDescent) / 10 ) );
    1567             : 
    1568           0 :             m_rWW8Export.InsUInt16( NS_sprm::LN_CHps );            // Font Size
    1569           0 :             m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( rFontHeight / 10 ) );
    1570             :         }
    1571             :         else
    1572             :         {
    1573           0 :             const SwCharFmt *pSwCharFmt = rSwFmtDrop.GetCharFmt();
    1574           0 :             if ( pSwCharFmt )
    1575             :             {
    1576           0 :                 m_rWW8Export.InsUInt16( 80 );
    1577           0 :                 m_rWW8Export.InsUInt16( m_rWW8Export.GetId( *pSwCharFmt ) );
    1578             :             }
    1579             : 
    1580           0 :             m_rWW8Export.pO->push_back( 101 );      // Lower the chars
    1581           0 :             m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( -((nDropLines - 1)*rDropDescent) / 10 ) );
    1582             : 
    1583           0 :             m_rWW8Export.pO->push_back( 99 );      // Font Size
    1584           0 :             m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( rFontHeight / 10 ) );
    1585             :         }
    1586             :     }
    1587             : 
    1588           0 :     m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data() );
    1589           0 :     m_rWW8Export.pO->clear();
    1590           0 : }
    1591             : 
    1592         727 : xub_StrLen MSWordExportBase::GetNextPos( SwWW8AttrIter* aAttrIter, const SwTxtNode& rNode, xub_StrLen nAktPos  )
    1593             : {
    1594             :     // Get the bookmarks for the normal run
    1595         727 :     xub_StrLen nNextPos = aAttrIter->WhereNext();
    1596         727 :     xub_StrLen nNextBookmark = nNextPos;
    1597             : 
    1598         727 :     if( nNextBookmark > nAktPos ) //no need to search for bookmarks otherwise (checked in UpdatePosition())
    1599             :     {
    1600         411 :         GetSortedBookmarks( rNode, nAktPos, nNextBookmark - nAktPos );
    1601         411 :         NearestBookmark( nNextBookmark, nAktPos, false );
    1602             :     }
    1603         727 :     return std::min( nNextPos, nNextBookmark );
    1604             : }
    1605             : 
    1606         727 : void MSWordExportBase::UpdatePosition( SwWW8AttrIter* aAttrIter, xub_StrLen nAktPos, xub_StrLen /*nEnd*/ )
    1607             : {
    1608             :     xub_StrLen nNextPos;
    1609             : 
    1610             :     // go to next attribute if no bookmark is found or if the bookmark is behind the next attribute position
    1611             :     // It may happened that the WhereNext() wasn't used in the previous increment because there was a
    1612             :     // bookmark before it. Use that position before trying to find another one.
    1613         727 :     bool bNextBookmark = NearestBookmark( nNextPos, nAktPos, true );
    1614         727 :     if( nAktPos == aAttrIter->WhereNext() && ( !bNextBookmark || nNextPos > aAttrIter->WhereNext() ) )
    1615         725 :         aAttrIter->NextPos();
    1616         727 : }
    1617             : 
    1618        1138 : bool MSWordExportBase::GetBookmarks( const SwTxtNode& rNd, xub_StrLen nStt,
    1619             :                     xub_StrLen nEnd, IMarkVector& rArr )
    1620             : {
    1621        1138 :     IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
    1622        1138 :     sal_uLong nNd = rNd.GetIndex( );
    1623             : 
    1624        1138 :     const sal_Int32 nMarks = pMarkAccess->getMarksCount();
    1625        1505 :     for ( sal_Int32 i = 0; i < nMarks; i++ )
    1626             :     {
    1627         367 :         IMark* pMark = ( pMarkAccess->getMarksBegin() + i )->get();
    1628             : 
    1629             :         // Only keep the bookmarks starting or ending in this node
    1630         661 :         if ( pMark->GetMarkStart().nNode == nNd ||
    1631         294 :              pMark->GetMarkEnd().nNode == nNd )
    1632             :         {
    1633          73 :             xub_StrLen nBStart = pMark->GetMarkStart().nContent.GetIndex();
    1634          73 :             xub_StrLen nBEnd = pMark->GetMarkEnd().nContent.GetIndex();
    1635             : 
    1636             :             // Keep only the bookmars starting or ending in the snippet
    1637          73 :             bool bIsStartOk = ( pMark->GetMarkStart().nNode == nNd ) && ( nBStart >= nStt ) && ( nBStart <= nEnd );
    1638          73 :             bool bIsEndOk = ( pMark->GetMarkEnd().nNode == nNd ) && ( nBEnd >= nStt ) && ( nBEnd <= nEnd );
    1639             : 
    1640          73 :             IFieldmark* pFieldmark = dynamic_cast<IFieldmark*>(pMark);
    1641          73 :             if (pFieldmark && pFieldmark->GetFieldname() == ODF_COMMENTRANGE)
    1642          44 :                 continue;
    1643             : 
    1644          51 :             if ( bIsStartOk || bIsEndOk )
    1645          36 :                 rArr.push_back( pMark );
    1646             :         }
    1647             :     }
    1648        1138 :     return ( rArr.size() > 0 );
    1649             : }
    1650             : 
    1651             : class CompareMarksEnd : public std::binary_function < const IMark *, const IMark *, bool >
    1652             : {
    1653             : public:
    1654           2 :     inline bool operator() ( const IMark * pOneB, const IMark * pTwoB ) const
    1655             :     {
    1656           2 :         xub_StrLen nOEnd = pOneB->GetMarkEnd().nContent.GetIndex();
    1657           2 :         xub_StrLen nTEnd = pTwoB->GetMarkEnd().nContent.GetIndex();
    1658             : 
    1659           2 :         return nOEnd < nTEnd;
    1660             :     }
    1661             : };
    1662             : 
    1663        1138 : bool MSWordExportBase::NearestBookmark( xub_StrLen& rNearest, const xub_StrLen nAktPos, bool bNextPositionOnly )
    1664             : {
    1665        1138 :     bool bHasBookmark = false;
    1666             : 
    1667        1138 :     if ( !m_rSortedMarksStart.empty() )
    1668             :     {
    1669          13 :         IMark* pMarkStart = m_rSortedMarksStart.front();
    1670          13 :         xub_StrLen nNext = pMarkStart->GetMarkStart().nContent.GetIndex();
    1671          13 :         if( !bNextPositionOnly || (nNext > nAktPos ))
    1672             :         {
    1673           9 :             rNearest = nNext;
    1674           9 :             bHasBookmark = true;
    1675             :         }
    1676             :     }
    1677             : 
    1678        1138 :     if ( !m_rSortedMarksEnd.empty() )
    1679             :     {
    1680          17 :         IMark* pMarkEnd = m_rSortedMarksEnd[0];
    1681          17 :         xub_StrLen nNext = pMarkEnd->GetMarkEnd().nContent.GetIndex();
    1682          17 :         if( !bNextPositionOnly || nNext > nAktPos )
    1683             :         {
    1684          11 :             if ( !bHasBookmark )
    1685           2 :                 rNearest = nNext;
    1686             :             else
    1687           9 :                 rNearest = std::min( rNearest, nNext );
    1688          11 :             bHasBookmark = true;
    1689             :         }
    1690             :     }
    1691             : 
    1692        1138 :     return bHasBookmark;
    1693             : }
    1694             : 
    1695         411 : void MSWordExportBase::GetSortedBookmarks( const SwTxtNode& rNode, xub_StrLen nAktPos, xub_StrLen nLen )
    1696             : {
    1697         411 :     IMarkVector aMarksStart;
    1698         411 :     if ( GetBookmarks( rNode, nAktPos, nAktPos + nLen, aMarksStart ) )
    1699             :     {
    1700          12 :         IMarkVector aSortedEnd;
    1701          24 :         IMarkVector aSortedStart;
    1702          26 :         for ( IMarkVector::const_iterator it = aMarksStart.begin(), end = aMarksStart.end();
    1703             :               it != end; ++it )
    1704             :         {
    1705          14 :             IMark* pMark = (*it);
    1706             : 
    1707             :             // Remove the positions egals to the current pos
    1708          14 :             xub_StrLen nStart = pMark->GetMarkStart().nContent.GetIndex();
    1709          14 :             xub_StrLen nEnd = pMark->GetMarkEnd().nContent.GetIndex();
    1710             : 
    1711          14 :             if ( nStart > nAktPos && ( pMark->GetMarkStart().nNode == rNode.GetIndex()) )
    1712           4 :                 aSortedStart.push_back( pMark );
    1713             : 
    1714          14 :             if ( nEnd > nAktPos && nEnd <= ( nAktPos + nLen ) && (pMark->GetMarkEnd().nNode == rNode.GetIndex()) )
    1715           7 :                 aSortedEnd.push_back( pMark );
    1716             :         }
    1717             : 
    1718             :         // Sort the bookmarks by end position
    1719          12 :         std::sort( aSortedEnd.begin(), aSortedEnd.end(), CompareMarksEnd() );
    1720             : 
    1721          12 :         m_rSortedMarksStart.swap( aSortedStart );
    1722          24 :         m_rSortedMarksEnd.swap( aSortedEnd );
    1723             :     }
    1724             :     else
    1725             :     {
    1726         399 :         m_rSortedMarksStart.clear( );
    1727         399 :         m_rSortedMarksEnd.clear( );
    1728         411 :     }
    1729         411 : }
    1730             : 
    1731         622 : void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode )
    1732             : {
    1733             :     SAL_INFO( "sw.ww8", "<OutWW8_SwTxtNode>" );
    1734             : 
    1735         622 :     ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo( mpTableInfo->getTableNodeInfo( &rNode ) );
    1736             : 
    1737             :     //For i120928,identify the last node
    1738         622 :     bool bLastCR = false;
    1739         622 :     bool bExported = false;
    1740             :     {
    1741         622 :         SwNodeIndex aNextIdx(rNode,1);
    1742        1244 :         SwNodeIndex aLastIdx(rNode.GetNodes().GetEndOfContent());
    1743         622 :         if (aNextIdx == aLastIdx)
    1744         719 :             bLastCR = true;
    1745             :     }
    1746             : 
    1747         622 :     AttrOutput().StartParagraph( pTextNodeInfo );
    1748             : 
    1749         622 :     bool bFlyInTable = mpParentFrame && IsInTable();
    1750             : 
    1751         622 :     if ( !bFlyInTable )
    1752         620 :         nStyleBeforeFly = GetId( lcl_getFormatCollection( *this, &rNode ) );
    1753             : 
    1754             :     // nStyleBeforeFly may change when we recurse into another node, so we
    1755             :     // have to remember it in nStyle
    1756         622 :     sal_uInt16 nStyle = nStyleBeforeFly;
    1757             : 
    1758        1244 :     SwWW8AttrIter aAttrIter( *this, rNode );
    1759         622 :     rtl_TextEncoding eChrSet = aAttrIter.GetCharSet();
    1760             : 
    1761         622 :     if ( bStartTOX )
    1762             :     {
    1763             :         // ignore TOX header section
    1764           0 :         const SwSectionNode* pSectNd = rNode.FindSectionNode();
    1765           0 :         if ( pSectNd && TOX_CONTENT_SECTION == pSectNd->GetSection().GetType() )
    1766             :         {
    1767           0 :             AttrOutput().StartTOX( pSectNd->GetSection() );
    1768           0 :             m_aCurrentCharPropStarts.push( 0 );
    1769             :         }
    1770             :     }
    1771             : 
    1772         622 :     const SwSection* pTOXSect = 0;
    1773         622 :     if( bInWriteTOX )
    1774             :     {
    1775             :         // check for end of TOX
    1776           0 :         SwNodeIndex aIdx( rNode, 1 );
    1777           0 :         if( !aIdx.GetNode().IsTxtNode() )
    1778             :         {
    1779           0 :             const SwSectionNode* pTOXSectNd = rNode.FindSectionNode();
    1780           0 :             if ( pTOXSectNd )
    1781             :             {
    1782           0 :                 pTOXSect = &pTOXSectNd->GetSection();
    1783             : 
    1784           0 :                 const SwNode* pNxt = rNode.GetNodes().GoNext( &aIdx );
    1785           0 :                 if( pNxt && pNxt->FindSectionNode() == pTOXSectNd )
    1786           0 :                     pTOXSect = 0;
    1787             :             }
    1788           0 :         }
    1789             :     }
    1790             : 
    1791         622 :     if ( aAttrIter.RequiresImplicitBookmark() )
    1792             :     {
    1793           0 :         String sBkmkName = String(  "_toc"  );
    1794           0 :         sBkmkName += OUString::number( rNode.GetIndex() );
    1795           0 :         AppendWordBookmark( sBkmkName );
    1796             :     }
    1797             : 
    1798        1244 :     String aStr( rNode.GetTxt() );
    1799             : 
    1800         622 :     xub_StrLen nAktPos = 0;
    1801         622 :     xub_StrLen const nEnd = aStr.Len();
    1802         622 :     bool bRedlineAtEnd = false;
    1803         622 :     int nOpenAttrWithRange = 0;
    1804             : 
    1805        1244 :     ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner;
    1806         622 :     if ( pTextNodeInfo.get() != NULL )
    1807         276 :         pTextNodeInfoInner = pTextNodeInfo->getFirstInner();
    1808             : 
    1809         727 :     do {
    1810         727 :         const SwRedlineData* pRedlineData = aAttrIter.GetRedline( nAktPos );
    1811             : 
    1812         727 :         xub_StrLen nNextAttr = GetNextPos( &aAttrIter, rNode, nAktPos );
    1813             :         // Is this the only run in this paragraph and it's empty?
    1814         727 :         bool bSingleEmptyRun = nAktPos == 0 && nNextAttr == 0;
    1815         727 :         AttrOutput().StartRun( pRedlineData, bSingleEmptyRun );
    1816         727 :         if( nTxtTyp == TXT_FTN || nTxtTyp == TXT_EDN )
    1817           3 :             AttrOutput().FootnoteEndnoteRefTag();
    1818             : 
    1819         727 :         if( nNextAttr > nEnd )
    1820           0 :             nNextAttr = nEnd;
    1821             : 
    1822         727 :         aAttrIter.OutFlys( nAktPos );
    1823             :         // Append bookmarks in this range after flys, exclusive of final
    1824             :         // position of this range
    1825         727 :         AppendBookmarks( rNode, nAktPos, nNextAttr - nAktPos );
    1826         727 :         bool bTxtAtr = aAttrIter.IsTxtAttr( nAktPos );
    1827         727 :         nOpenAttrWithRange += aAttrIter.OutAttrWithRange(nAktPos);
    1828             : 
    1829         727 :         xub_StrLen nLen = nNextAttr - nAktPos;
    1830         727 :         if ( !bTxtAtr && nLen )
    1831             :         {
    1832         330 :             sal_Unicode ch = aStr.GetChar( nAktPos );
    1833         330 :             int ofs = ( ch == CH_TXT_ATR_FIELDSTART || ch == CH_TXT_ATR_FIELDEND || ch == CH_TXT_ATR_FORMELEMENT? 1: 0 );
    1834             : 
    1835         330 :             IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
    1836         330 :             if ( ch == CH_TXT_ATR_FIELDSTART )
    1837             :             {
    1838           2 :                 SwPosition aPosition( rNode, SwIndex( const_cast< SwTxtNode* >( &rNode ), nAktPos ) );
    1839           2 :                 ::sw::mark::IFieldmark const * const pFieldmark = pMarkAccess->getFieldmarkFor( aPosition );
    1840             :                 OSL_ENSURE( pFieldmark, "Looks like this doc is broken...; where is the Fieldmark for the FIELDSTART??" );
    1841             : 
    1842           2 :                 if ( pFieldmark && pFieldmark->GetFieldname() == ODF_FORMTEXT )
    1843           0 :                     AppendBookmark( pFieldmark->GetName(), false );
    1844           2 :                 ww::eField eFieldId = lcl_getFieldId( pFieldmark );
    1845           4 :                 String sCode = lcl_getFieldCode( pFieldmark );
    1846           2 :                 if ( pFieldmark && pFieldmark->GetFieldname() == ODF_UNHANDLED )
    1847             :                 {
    1848           0 :                     IFieldmark::parameter_map_t::const_iterator it = pFieldmark->GetParameters()->find( ODF_ID_PARAM );
    1849           0 :                     if ( it != pFieldmark->GetParameters()->end() )
    1850             :                     {
    1851           0 :                         OUString sFieldId;
    1852           0 :                         it->second >>= sFieldId;
    1853           0 :                         eFieldId = (ww::eField)sFieldId.toInt32();
    1854             :                     }
    1855             : 
    1856           0 :                     it = pFieldmark->GetParameters()->find( ODF_CODE_PARAM );
    1857           0 :                     if ( it != pFieldmark->GetParameters()->end() )
    1858             :                     {
    1859           0 :                         OUString sOUCode;
    1860           0 :                         it->second >>= sOUCode;
    1861           0 :                         sCode = sOUCode;
    1862             :                     }
    1863             :                 }
    1864             : 
    1865           2 :                 bool bCommentRange = pFieldmark && pFieldmark->GetFieldname() == ODF_COMMENTRANGE;
    1866           2 :                 if (bCommentRange)
    1867           2 :                     AttrOutput().WritePostitFieldStart();
    1868             :                 else
    1869           0 :                     OutputField( NULL, eFieldId, sCode, WRITEFIELD_START | WRITEFIELD_CMD_START );
    1870             : 
    1871           2 :                 if ( pFieldmark && pFieldmark->GetFieldname( ) == ODF_FORMTEXT )
    1872           0 :                     WriteFormData( *pFieldmark );
    1873           2 :                 else if ( pFieldmark && pFieldmark->GetFieldname( ) == ODF_HYPERLINK )
    1874           0 :                     WriteHyperlinkData( *pFieldmark );
    1875           2 :                 if (!bCommentRange)
    1876           0 :                     OutputField( NULL, lcl_getFieldId( pFieldmark ), String(), WRITEFIELD_CMD_END );
    1877             : 
    1878           2 :                 if ( pFieldmark && pFieldmark->GetFieldname() == ODF_UNHANDLED )
    1879             :                 {
    1880             :                     // Check for the presence of a linked OLE object
    1881           0 :                     IFieldmark::parameter_map_t::const_iterator it = pFieldmark->GetParameters()->find( ODF_OLE_PARAM );
    1882           0 :                     if ( it != pFieldmark->GetParameters()->end() )
    1883             :                     {
    1884           0 :                         OUString sOleId;
    1885           0 :                         uno::Any aValue = it->second;
    1886           0 :                         aValue >>= sOleId;
    1887           0 :                         if ( !sOleId.isEmpty() )
    1888           0 :                             OutputLinkedOLE( sOleId );
    1889             :                     }
    1890           2 :                 }
    1891             :             }
    1892         328 :             else if ( ch == CH_TXT_ATR_FIELDEND )
    1893             :             {
    1894           2 :                 SwPosition aPosition( rNode, SwIndex( const_cast< SwTxtNode* >( &rNode ), nAktPos ) );
    1895           2 :                 ::sw::mark::IFieldmark const * const pFieldmark = pMarkAccess->getFieldmarkFor( aPosition );
    1896             : 
    1897             :                 OSL_ENSURE( pFieldmark, "Looks like this doc is broken...; where is the Fieldmark for the FIELDEND??" );
    1898             : 
    1899           2 :                 ww::eField eFieldId = lcl_getFieldId( pFieldmark );
    1900           2 :                 if ( pFieldmark && pFieldmark->GetFieldname() == ODF_UNHANDLED )
    1901             :                 {
    1902           0 :                     IFieldmark::parameter_map_t::const_iterator it = pFieldmark->GetParameters()->find( ODF_ID_PARAM );
    1903           0 :                     if ( it != pFieldmark->GetParameters()->end() )
    1904             :                     {
    1905           0 :                         OUString sFieldId;
    1906           0 :                         it->second >>= sFieldId;
    1907           0 :                         eFieldId = (ww::eField)sFieldId.toInt32();
    1908             :                     }
    1909             :                 }
    1910             : 
    1911           2 :                 if (pFieldmark && pFieldmark->GetFieldname() == ODF_COMMENTRANGE)
    1912           2 :                     AttrOutput().WritePostitFieldEnd();
    1913             :                 else
    1914           0 :                     OutputField( NULL, eFieldId, String(), WRITEFIELD_CLOSE );
    1915             : 
    1916           2 :                 if ( pFieldmark && pFieldmark->GetFieldname() == ODF_FORMTEXT )
    1917           0 :                     AppendBookmark( pFieldmark->GetName(), false );
    1918             :             }
    1919         326 :             else if ( ch == CH_TXT_ATR_FORMELEMENT )
    1920             :             {
    1921           0 :                 SwPosition aPosition( rNode, SwIndex( const_cast< SwTxtNode* >( &rNode ), nAktPos ) );
    1922           0 :                 ::sw::mark::IFieldmark const * const pFieldmark = pMarkAccess->getFieldmarkFor( aPosition );
    1923             :                 OSL_ENSURE( pFieldmark, "Looks like this doc is broken...; where is the Fieldmark for the FIELDSTART??" );
    1924             : 
    1925           0 :                 bool isDropdownOrCheckbox = pFieldmark && (pFieldmark->GetFieldname( ) == ODF_FORMDROPDOWN ||
    1926           0 :                     pFieldmark->GetFieldname( ) == ODF_FORMCHECKBOX );
    1927             : 
    1928           0 :                 if ( isDropdownOrCheckbox )
    1929           0 :                     AppendBookmark( pFieldmark->GetName(), 0 );
    1930             :                 OutputField( NULL, lcl_getFieldId( pFieldmark ),
    1931             :                         lcl_getFieldCode( pFieldmark ),
    1932           0 :                         WRITEFIELD_START | WRITEFIELD_CMD_START );
    1933           0 :                 if ( isDropdownOrCheckbox )
    1934           0 :                     WriteFormData( *pFieldmark );
    1935           0 :                 OutputField( NULL, lcl_getFieldId( pFieldmark ), String(), WRITEFIELD_CLOSE );
    1936           0 :                 if ( isDropdownOrCheckbox )
    1937           0 :                     AppendBookmark( pFieldmark->GetName(), false );
    1938             :             }
    1939         330 :             nLen -= static_cast< sal_uInt16 >( ofs );
    1940             : 
    1941         330 :             String aSnippet( aAttrIter.GetSnippet( aStr, nAktPos + static_cast< sal_uInt16 >( ofs ), nLen ) );
    1942         330 :             if ( ( nTxtTyp == TXT_EDN || nTxtTyp == TXT_FTN ) && nAktPos == 0 && nLen > 0 )
    1943             :             {
    1944             :                 // Insert tab for aesthetic puposes #i24762#
    1945           2 :                 if ( aSnippet.GetChar( 0 ) != 0x09 )
    1946           2 :                     aSnippet.Insert( 0x09, 0 );
    1947             :             }
    1948         330 :             AttrOutput().RunText( aSnippet, eChrSet );
    1949             :         }
    1950             : 
    1951         727 :         if ( aAttrIter.IsDropCap( nNextAttr ) )
    1952           0 :             AttrOutput().FormatDrop( rNode, aAttrIter.GetSwFmtDrop(), nStyle, pTextNodeInfo, pTextNodeInfoInner );
    1953             : 
    1954         727 :         if (0 != nEnd)
    1955             :         {
    1956             :             // Output the character attributes
    1957             :             // #i51277# do this before writing flys at end of paragraph
    1958         411 :             AttrOutput().StartRunProperties();
    1959         411 :             aAttrIter.OutAttr( nAktPos );
    1960         411 :             AttrOutput().EndRunProperties( pRedlineData );
    1961             :         }
    1962             : 
    1963             :         // At the end of line, output the attributes until the CR.
    1964             :         // Exception: footnotes at the end of line
    1965         727 :         if ( nNextAttr == nEnd )
    1966             :         {
    1967             :             OSL_ENSURE( nOpenAttrWithRange >= 0, "odd to see this happening, expected >= 0" );
    1968         622 :             if ( !bTxtAtr && nOpenAttrWithRange <= 0 )
    1969             :             {
    1970         560 :                 if ( aAttrIter.IsRedlineAtEnd( nEnd ) )
    1971           1 :                     bRedlineAtEnd = true;
    1972             :                 else
    1973             :                 {
    1974             :                     // insert final graphic anchors if any before CR
    1975         559 :                     aAttrIter.OutFlys( nEnd );
    1976             :                     // insert final bookmarks if any before CR and after flys
    1977         559 :                     AppendBookmarks( rNode, nEnd, 1 );
    1978         559 :                     if ( pTOXSect )
    1979             :                     {
    1980           0 :                         m_aCurrentCharPropStarts.pop();
    1981           0 :                         AttrOutput().EndTOX( *pTOXSect );
    1982             :                     }
    1983             :                     //For i120928,the position of the bullet's graphic is at end of doc
    1984         559 :                     if (bLastCR && (!bExported))
    1985             :                     {
    1986          63 :                         ExportGrfBullet(rNode);
    1987          63 :                         bExported = true;
    1988             :                     }
    1989             : 
    1990         559 :                     WriteCR( pTextNodeInfoInner );
    1991             :                 }
    1992             :             }
    1993             :         }
    1994             : 
    1995         727 :         if (0 == nEnd)
    1996             :         {
    1997             :             // Output the character attributes
    1998             :             // do it after WriteCR for an empty paragraph (otherwise
    1999             :             // WW8_WrFkp::Append throws SPRMs away...)
    2000         316 :             AttrOutput().StartRunProperties();
    2001         316 :             aAttrIter.OutAttr( nAktPos );
    2002         316 :             AttrOutput().EndRunProperties( pRedlineData );
    2003             :         }
    2004             : 
    2005             :         // Exception: footnotes at the end of line
    2006         727 :         if ( nNextAttr == nEnd )
    2007             :         {
    2008             :             OSL_ENSURE(nOpenAttrWithRange >= 0,
    2009             :                 "odd to see this happening, expected >= 0");
    2010         622 :             bool bAttrWithRange = (nOpenAttrWithRange > 0);
    2011         622 :             if ( nAktPos != nEnd )
    2012             :             {
    2013         306 :                 nOpenAttrWithRange += aAttrIter.OutAttrWithRange(nEnd);
    2014             :                 OSL_ENSURE(nOpenAttrWithRange == 0,
    2015             :                     "odd to see this happening, expected 0");
    2016             :             }
    2017             : 
    2018         622 :             AttrOutput().OutputFKP();
    2019             : 
    2020         622 :             if ( bTxtAtr || bAttrWithRange || bRedlineAtEnd )
    2021             :             {
    2022             :                 // insert final graphic anchors if any before CR
    2023          63 :                 aAttrIter.OutFlys( nEnd );
    2024             :                 // insert final bookmarks if any before CR and after flys
    2025          63 :                 AppendBookmarks( rNode, nEnd, 1 );
    2026             :                 // #i120928 - position of the bullet's graphic is at end of doc
    2027          63 :                 if (bLastCR && (!bExported))
    2028             :                 {
    2029          34 :                     ExportGrfBullet(rNode);
    2030          34 :                     bExported = true;
    2031             :                 }
    2032             : 
    2033          63 :                 if ( pTOXSect )
    2034             :                 {
    2035           0 :                     m_aCurrentCharPropStarts.pop();
    2036           0 :                     AttrOutput().EndTOX( *pTOXSect );
    2037             :                 }
    2038             : 
    2039          63 :                 WriteCR( pTextNodeInfoInner );
    2040             : 
    2041          63 :                 if ( bRedlineAtEnd )
    2042             :                 {
    2043           1 :                     AttrOutput().Redline( aAttrIter.GetRedline( nEnd ) );
    2044           1 :                     AttrOutput().OutputFKP();
    2045             :                 }
    2046             :             }
    2047             :         }
    2048             : 
    2049         727 :         AttrOutput().WritePostitFieldReference();
    2050             : 
    2051         727 :         AttrOutput().EndRun();
    2052             : 
    2053         727 :         nAktPos = nNextAttr;
    2054         727 :         UpdatePosition( &aAttrIter, nAktPos, nEnd );
    2055         727 :         eChrSet = aAttrIter.GetCharSet();
    2056             :     }
    2057             :     while ( nAktPos < nEnd );
    2058             : 
    2059         622 :     AttrOutput().StartParagraphProperties( rNode );
    2060             : 
    2061         622 :     AttrOutput().ParagraphStyle( nStyle );
    2062             : 
    2063         622 :     if ( mpParentFrame && IsInTable() )    // Fly-Attrs
    2064           2 :         OutputFormat( mpParentFrame->GetFrmFmt(), false, false, true );
    2065             : 
    2066         622 :     if ( pTextNodeInfo.get() != NULL )
    2067             :     {
    2068             : #ifdef DBG_UTIL
    2069             :         SAL_INFO( "sw.ww8", pTextNodeInfo->toString());
    2070             : #endif
    2071             : 
    2072         276 :         AttrOutput().TableInfoCell( pTextNodeInfoInner );
    2073         276 :         if (pTextNodeInfoInner->isFirstInTable())
    2074             :         {
    2075          15 :             const SwTable * pTable = pTextNodeInfoInner->getTable();
    2076             : 
    2077          15 :             const SwTableFmt * pTabFmt = pTable->GetTableFmt();
    2078          15 :             if (pTabFmt != NULL)
    2079             :             {
    2080          15 :                 if (pTabFmt->GetBreak().GetBreak() == SVX_BREAK_PAGE_BEFORE)
    2081           0 :                     AttrOutput().PageBreakBefore(true);
    2082             :             }
    2083             :         }
    2084             :     }
    2085             : 
    2086         622 :     if ( !bFlyInTable )
    2087             :     {
    2088         620 :         SfxItemSet* pTmpSet = 0;
    2089         620 :         const sal_uInt8 nPrvNxtNd = rNode.HasPrevNextLayNode();
    2090             : 
    2091         620 :         if( (ND_HAS_PREV_LAYNODE|ND_HAS_NEXT_LAYNODE ) != nPrvNxtNd )
    2092             :         {
    2093             :             const SfxPoolItem* pItem;
    2094         746 :             if( SFX_ITEM_SET == rNode.GetSwAttrSet().GetItemState(
    2095         614 :                     RES_UL_SPACE, true, &pItem ) &&
    2096         319 :                 ( ( !( ND_HAS_PREV_LAYNODE & nPrvNxtNd ) &&
    2097         277 :                    ((SvxULSpaceItem*)pItem)->GetUpper()) ||
    2098         242 :                   ( !( ND_HAS_NEXT_LAYNODE & nPrvNxtNd ) &&
    2099         117 :                    ((SvxULSpaceItem*)pItem)->GetLower()) ))
    2100             :             {
    2101          74 :                 pTmpSet = new SfxItemSet( rNode.GetSwAttrSet() );
    2102          74 :                 SvxULSpaceItem aUL( *(SvxULSpaceItem*)pItem );
    2103             :                 // #i25901#- consider compatibility option
    2104          74 :                 if (!pDoc->get(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES))
    2105             :                 {
    2106           0 :                     if( !(ND_HAS_PREV_LAYNODE & nPrvNxtNd ))
    2107           0 :                         aUL.SetUpper( 0 );
    2108             :                 }
    2109             :                 // #i25901# - consider compatibility option
    2110          74 :                 if (!pDoc->get(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS))
    2111             :                 {
    2112           0 :                     if( !(ND_HAS_NEXT_LAYNODE & nPrvNxtNd ))
    2113           0 :                         aUL.SetLower( 0 );
    2114             :                 }
    2115          74 :                 pTmpSet->Put( aUL );
    2116             :             }
    2117             :         }
    2118             : 
    2119         620 :         bool bParaRTL = false;
    2120             :         const SvxFrameDirectionItem* pItem = (const SvxFrameDirectionItem*)
    2121         620 :             rNode.GetSwAttrSet().GetItem(RES_FRAMEDIR);
    2122         620 :         if ( aAttrIter.IsParaRTL())
    2123           2 :             bParaRTL = true;
    2124             : 
    2125         620 :         if( rNode.IsNumbered())
    2126             :         {
    2127          14 :             const SwNumRule* pRule = rNode.GetNumRule();
    2128          14 :             sal_uInt8 nLvl = static_cast< sal_uInt8 >( rNode.GetActualListLevel() );
    2129          14 :             const SwNumFmt* pFmt = pRule->GetNumFmt( nLvl );
    2130          14 :             if( !pFmt )
    2131           0 :                 pFmt = &pRule->Get( nLvl );
    2132             : 
    2133          14 :             if( !pTmpSet )
    2134          14 :                 pTmpSet = new SfxItemSet( rNode.GetSwAttrSet() );
    2135             : 
    2136          14 :             SvxLRSpaceItem aLR(ItemGet<SvxLRSpaceItem>(*pTmpSet, RES_LR_SPACE));
    2137             :             // #i86652#
    2138          14 :             if ( pFmt->GetPositionAndSpaceMode() ==
    2139             :                                     SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
    2140             :             {
    2141           0 :                 aLR.SetTxtLeft( aLR.GetTxtLeft() + pFmt->GetAbsLSpace() );
    2142             :             }
    2143             : 
    2144          14 :             if( rNode.IsNumbered() && rNode.IsCountedInList() )
    2145             :             {
    2146             :                 // #i86652#
    2147          14 :                 if ( pFmt->GetPositionAndSpaceMode() ==
    2148             :                                         SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
    2149             :                 {
    2150           0 :                     if (bParaRTL)
    2151           0 :                         aLR.SetTxtFirstLineOfstValue(pFmt->GetAbsLSpace() - pFmt->GetFirstLineOffset());
    2152             :                     else
    2153           0 :                         aLR.SetTxtFirstLineOfst(GetWordFirstLineOffset(*pFmt));
    2154             :                 }
    2155             : 
    2156             :                 // correct fix for issue i94187
    2157          14 :                 if (SFX_ITEM_SET !=
    2158          14 :                     pTmpSet->GetItemState(RES_PARATR_NUMRULE, false) )
    2159             :                 {
    2160             :                     // List style set via paragraph style - then put it into the itemset.
    2161             :                     // This is needed to get list level and list id exported for
    2162             :                     // the paragraph.
    2163           0 :                     pTmpSet->Put( SwNumRuleItem( pRule->GetName() ));
    2164             : 
    2165             :                     // Put indent values into the itemset in case that the list
    2166             :                     // style is applied via paragraph style and the list level
    2167             :                     // indent values are not applicable.
    2168           0 :                     if ( pFmt->GetPositionAndSpaceMode() ==
    2169           0 :                                             SvxNumberFormat::LABEL_ALIGNMENT &&
    2170           0 :                          !rNode.AreListLevelIndentsApplicable() )
    2171             :                     {
    2172           0 :                         pTmpSet->Put( aLR );
    2173             :                     }
    2174             :                 }
    2175             :             }
    2176             :             else
    2177           0 :                 pTmpSet->ClearItem(RES_PARATR_NUMRULE);
    2178             : 
    2179             :             // #i86652#
    2180          14 :             if ( pFmt->GetPositionAndSpaceMode() ==
    2181             :                                     SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
    2182             :             {
    2183           0 :                 pTmpSet->Put(aLR);
    2184             : 
    2185             :                 //#i21847#
    2186             :                 SvxTabStopItem aItem(
    2187           0 :                     ItemGet<SvxTabStopItem>(*pTmpSet, RES_PARATR_TABSTOP));
    2188           0 :                 SvxTabStop aTabStop(pFmt->GetAbsLSpace());
    2189           0 :                 aItem.Insert(aTabStop);
    2190           0 :                 pTmpSet->Put(aItem);
    2191             : 
    2192           0 :                 MSWordExportBase::CorrectTabStopInSet(*pTmpSet, pFmt->GetAbsLSpace());
    2193          14 :             }
    2194             :         }
    2195             : 
    2196             :         /*
    2197             :         If a given para is using the FRMDIR_ENVIRONMENT direction we
    2198             :         cannot export that, its its ltr then that's ok as thats word's
    2199             :         default. Otherwise we must add a RTL attribute to our export list
    2200             :         */
    2201             :         pItem = (const SvxFrameDirectionItem*)
    2202         620 :             rNode.GetSwAttrSet().GetItem(RES_FRAMEDIR);
    2203         620 :         if (
    2204         767 :             (!pItem || pItem->GetValue() == FRMDIR_ENVIRONMENT) &&
    2205         147 :             aAttrIter.IsParaRTL()
    2206             :            )
    2207             :         {
    2208           0 :             if ( !pTmpSet )
    2209           0 :                 pTmpSet = new SfxItemSet(rNode.GetSwAttrSet());
    2210             : 
    2211           0 :             pTmpSet->Put(SvxFrameDirectionItem(FRMDIR_HORI_RIGHT_TOP, RES_FRAMEDIR));
    2212             :         }
    2213             :         // move code for handling of numbered,
    2214             :         // but not counted paragraphs to this place. Otherwise, the paragraph
    2215             :         // isn't exported as numbered, but not counted, if no other attribute
    2216             :         // is found in <pTmpSet>
    2217             :         // #i44815# adjust numbering/indents for numbered paragraphs
    2218             :         //          without number (NO_NUMLEVEL)
    2219             :         // #i47013# need to check rNode.GetNumRule()!=NULL as well.
    2220         620 :         if ( ! rNode.IsCountedInList() && rNode.GetNumRule()!=NULL )
    2221             :         {
    2222             :             // WW8 does not know numbered paragraphs without number
    2223             :             // (NO_NUMLEVEL). In WW8AttributeOutput::ParaNumRule(), we will export
    2224             :             // the RES_PARATR_NUMRULE as list-id 0, which in WW8 means
    2225             :             // no numbering. Here, we will adjust the indents to match
    2226             :             // visually.
    2227             : 
    2228           0 :             if ( !pTmpSet )
    2229           0 :                 pTmpSet = new SfxItemSet(rNode.GetSwAttrSet());
    2230             : 
    2231             :             // create new LRSpace item, based on the current (if present)
    2232           0 :             const SfxPoolItem* pPoolItem = NULL;
    2233           0 :             pTmpSet->GetItemState(RES_LR_SPACE, sal_True, &pPoolItem);
    2234             :             SvxLRSpaceItem aLRSpace(
    2235           0 :                 ( pPoolItem == NULL )
    2236             :                     ? SvxLRSpaceItem(0, 0, 0, 0, RES_LR_SPACE)
    2237           0 :                     : *static_cast<const SvxLRSpaceItem*>( pPoolItem ) );
    2238             : 
    2239             :             // new left margin = old left + label space
    2240           0 :             const SwNumRule* pRule = rNode.GetNumRule();
    2241           0 :             const SwNumFmt& rNumFmt = pRule->Get( static_cast< sal_uInt16 >(rNode.GetActualListLevel()) );
    2242             :             // #i86652#
    2243           0 :             if ( rNumFmt.GetPositionAndSpaceMode() ==
    2244             :                                     SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
    2245             :             {
    2246           0 :                 aLRSpace.SetTxtLeft( aLRSpace.GetLeft() + rNumFmt.GetAbsLSpace() );
    2247             : 
    2248             :                 // new first line indent = 0
    2249             :                 // (first line indent is ignored for NO_NUMLEVEL)
    2250           0 :                 if (!bParaRTL)
    2251           0 :                     aLRSpace.SetTxtFirstLineOfst( 0 );
    2252             : 
    2253             :                 // put back the new item
    2254           0 :                 pTmpSet->Put( aLRSpace );
    2255             :             }
    2256             : 
    2257             :             // assure that numbering rule is in <pTmpSet>
    2258           0 :             if (SFX_ITEM_SET != pTmpSet->GetItemState(RES_PARATR_NUMRULE, false) )
    2259             :             {
    2260           0 :                 pTmpSet->Put( SwNumRuleItem( pRule->GetName() ));
    2261           0 :             }
    2262             :         }
    2263             : 
    2264             :         // #i75457#
    2265             :         // Export page break after attribute from paragraph style.
    2266             :         // If page break attribute at the text node exist, an existing page
    2267             :         // break after at the paragraph style hasn't got to be considered.
    2268        1069 :         if ( !rNode.GetpSwAttrSet() ||
    2269         449 :              SFX_ITEM_SET != rNode.GetpSwAttrSet()->GetItemState(RES_BREAK, false) )
    2270             :         {
    2271             :             const SvxFmtBreakItem* pBreakAtParaStyle =
    2272         606 :                 &(ItemGet<SvxFmtBreakItem>(rNode.GetSwAttrSet(), RES_BREAK));
    2273        1212 :             if ( pBreakAtParaStyle &&
    2274         606 :                  pBreakAtParaStyle->GetBreak() == SVX_BREAK_PAGE_AFTER )
    2275             :             {
    2276           0 :                 if ( !pTmpSet )
    2277             :                 {
    2278           0 :                     pTmpSet = new SfxItemSet(rNode.GetSwAttrSet());
    2279             :                 }
    2280           0 :                 pTmpSet->Put( *pBreakAtParaStyle );
    2281             :             }
    2282         606 :             else if( pTmpSet )
    2283             :             {   // Even a pagedesc item is set, the break item can be set 'NONE',
    2284             :                 // this has to be overruled.
    2285             :                 const SwFmtPageDesc& rPageDescAtParaStyle =
    2286          86 :                     ItemGet<SwFmtPageDesc>( rNode, RES_PAGEDESC );
    2287          86 :                 if( rPageDescAtParaStyle.KnowsPageDesc() )
    2288           6 :                     pTmpSet->ClearItem( RES_BREAK );
    2289             :             }
    2290             :         }
    2291             : 
    2292             :         // #i76520# Emulate non-splitting tables
    2293         620 :         if ( bOutTable )
    2294             :         {
    2295           0 :             const SwTableNode* pTableNode = rNode.FindTableNode();
    2296             : 
    2297           0 :             if ( pTableNode )
    2298             :             {
    2299           0 :                 const SwTable& rTable = pTableNode->GetTable();
    2300           0 :                 const SvxFmtKeepItem& rKeep = rTable.GetFrmFmt()->GetKeep();
    2301           0 :                 const bool bKeep = rKeep.GetValue();
    2302           0 :                 const bool bDontSplit = !bKeep ?
    2303           0 :                                         !rTable.GetFrmFmt()->GetLayoutSplit().GetValue() :
    2304           0 :                                         false;
    2305             : 
    2306           0 :                 if ( bKeep || bDontSplit )
    2307             :                 {
    2308             :                     // bKeep: set keep at first paragraphs in all lines
    2309             :                     // bDontSplit : set keep at first paragraphs in all lines except from last line
    2310             :                     // but only for non-complex tables
    2311           0 :                     const SwTableBox* pBox = rNode.GetTblBox();
    2312           0 :                     const SwTableLine* pLine = pBox ? pBox->GetUpper() : 0;
    2313             : 
    2314           0 :                     if ( pLine && !pLine->GetUpper() )
    2315             :                     {
    2316             :                         // check if box is first in that line:
    2317           0 :                         if ( 0 == pLine->GetTabBoxes().GetPos( pBox ) && pBox->GetSttNd() )
    2318             :                         {
    2319             :                             // check if paragraph is first in that line:
    2320           0 :                             if ( 1 == ( rNode.GetIndex() - pBox->GetSttNd()->GetIndex() ) )
    2321             :                             {
    2322           0 :                                 bool bSetAtPara = false;
    2323           0 :                                 if ( bKeep )
    2324           0 :                                     bSetAtPara = true;
    2325           0 :                                 else if ( bDontSplit )
    2326             :                                 {
    2327             :                                     // check if pLine isn't last line in table
    2328           0 :                                     if ( rTable.GetTabLines().size() - rTable.GetTabLines().GetPos( pLine ) != 1 )
    2329           0 :                                         bSetAtPara = true;
    2330             :                                 }
    2331             : 
    2332           0 :                                 if ( bSetAtPara )
    2333             :                                 {
    2334           0 :                                     if ( !pTmpSet )
    2335           0 :                                         pTmpSet = new SfxItemSet(rNode.GetSwAttrSet());
    2336             : 
    2337           0 :                                     const SvxFmtKeepItem aKeepItem( sal_True, RES_KEEP );
    2338           0 :                                     pTmpSet->Put( aKeepItem );
    2339             :                                 }
    2340             :                             }
    2341             :                         }
    2342             :                     }
    2343             :                 }
    2344             :             }
    2345             :         }
    2346             : 
    2347         620 :         const SfxItemSet* pNewSet = pTmpSet ? pTmpSet : rNode.GetpSwAttrSet();
    2348         620 :         if( pNewSet )
    2349             :         {                                               // Para-Attrs
    2350         455 :             pStyAttr = &rNode.GetAnyFmtColl().GetAttrSet();
    2351             : 
    2352         455 :             const SwModify* pOldMod = pOutFmtNode;
    2353         455 :             pOutFmtNode = &rNode;
    2354             : 
    2355             :             // Pap-Attrs, so script is not necessary
    2356         455 :             OutputItemSet( *pNewSet, true, false, i18n::ScriptType::LATIN, false);
    2357             : 
    2358         455 :             pStyAttr = 0;
    2359         455 :             pOutFmtNode = pOldMod;
    2360             : 
    2361         455 :             if( pNewSet != rNode.GetpSwAttrSet() )
    2362          88 :                 delete pNewSet;
    2363             :         }
    2364             :     }
    2365             : 
    2366         622 :     AttrOutput().EndParagraphProperties();
    2367             : 
    2368         622 :     AttrOutput().EndParagraph( pTextNodeInfoInner );
    2369             : 
    2370         622 :     SAL_INFO( "sw.ww8", "</OutWW8_SwTxtNode>" );
    2371         622 : }
    2372             : 
    2373           0 : void WW8AttributeOutput::TableNodeInfo( ww8::WW8TableNodeInfo::Pointer_t pNodeInfo )
    2374             : {
    2375             :     SVBT16 nSty;
    2376           0 :     ShortToSVBT16( GetExport().nStyleBeforeFly, nSty );
    2377             : 
    2378           0 :     ww8::WW8TableNodeInfo::Inners_t::const_iterator aIt( pNodeInfo->getInners().begin() );
    2379           0 :     ww8::WW8TableNodeInfo::Inners_t::const_iterator aItEnd( pNodeInfo->getInners().end() );
    2380             : 
    2381           0 :     while (aIt != aItEnd)
    2382             :     {
    2383           0 :         ww8::WW8TableNodeInfoInner::Pointer_t pInner = aIt->second;
    2384           0 :         if ( pInner->isEndOfCell() )
    2385             :         {
    2386           0 :             TableRowEnd( pInner->getDepth() );
    2387             : 
    2388           0 :             m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), (sal_uInt8*)&nSty, (sal_uInt8*)&nSty+2);     // Style #
    2389           0 :             TableInfoRow( pInner );
    2390           0 :             m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data());
    2391           0 :             m_rWW8Export.pO->clear();
    2392             :         }
    2393             : 
    2394           0 :         if ( pInner->isEndOfLine() )
    2395             :         {
    2396             :         }
    2397             : 
    2398           0 :         ++aIt;
    2399           0 :     }
    2400           0 : }
    2401             : 
    2402             : // Tables
    2403             : 
    2404           0 : void WW8AttributeOutput::EmptyParagraph()
    2405             : {
    2406           0 :     m_rWW8Export.WriteStringAsPara( aEmptyStr );
    2407           0 : }
    2408             : 
    2409           0 : bool MSWordExportBase::NoPageBreakSection( const SfxItemSet* pSet )
    2410             : {
    2411           0 :     bool bRet = false;
    2412             :     const SfxPoolItem* pI;
    2413           0 :     if( pSet)
    2414             :     {
    2415           0 :         bool bNoPageBreak = false;
    2416           0 :         if ( SFX_ITEM_ON != pSet->GetItemState(RES_PAGEDESC, true, &pI)
    2417           0 :             || 0 == ((SwFmtPageDesc*)pI)->GetPageDesc() )
    2418             :         {
    2419           0 :             bNoPageBreak = true;
    2420             :         }
    2421             : 
    2422           0 :         if (bNoPageBreak)
    2423             :         {
    2424           0 :             if (SFX_ITEM_ON != pSet->GetItemState(RES_BREAK, true, &pI))
    2425           0 :                 bNoPageBreak = true;
    2426             :             else
    2427             :             {
    2428           0 :                 SvxBreak eBreak = ((const SvxFmtBreakItem*)pI)->GetBreak();
    2429           0 :                 switch (eBreak)
    2430             :                 {
    2431             :                     case SVX_BREAK_PAGE_BEFORE:
    2432             :                     case SVX_BREAK_PAGE_AFTER:
    2433           0 :                         bNoPageBreak = false;
    2434           0 :                         break;
    2435             :                     default:
    2436           0 :                         break;
    2437             :                 }
    2438             :             }
    2439             :         }
    2440           0 :         bRet = bNoPageBreak;
    2441             :     }
    2442           0 :     return bRet;
    2443             : }
    2444             : 
    2445             : 
    2446           0 : void MSWordExportBase::OutputSectionNode( const SwSectionNode& rSectionNode )
    2447             : {
    2448           0 :     const SwSection& rSection = rSectionNode.GetSection();
    2449             : 
    2450           0 :     SwNodeIndex aIdx( rSectionNode, 1 );
    2451           0 :     const SwNode& rNd = aIdx.GetNode();
    2452           0 :     if ( !rNd.IsSectionNode() && !IsInTable() ) //No sections in table
    2453             :     {
    2454             :         // if the first Node inside the section has an own
    2455             :         // PageDesc or PageBreak attribut, then dont write
    2456             :         // here the section break
    2457           0 :         sal_uLong nRstLnNum = 0;
    2458             :         const SfxItemSet* pSet;
    2459           0 :         if ( rNd.IsTableNode() )
    2460           0 :             pSet = &rNd.GetTableNode()->GetTable().GetFrmFmt()->GetAttrSet();
    2461           0 :         else if ( rNd.IsCntntNode() )
    2462             :         {
    2463           0 :             pSet = &rNd.GetCntntNode()->GetSwAttrSet();
    2464             :             nRstLnNum = ((SwFmtLineNumber&)pSet->Get(
    2465           0 :                             RES_LINENUMBER )).GetStartValue();
    2466             :         }
    2467             :         else
    2468           0 :             pSet = 0;
    2469             : 
    2470           0 :         if ( pSet && NoPageBreakSection( pSet ) )
    2471           0 :             pSet = 0;
    2472             : 
    2473           0 :         if ( !pSet )
    2474             :         {
    2475             :             // new Section with no own PageDesc/-Break
    2476             :             //  -> write follow section break;
    2477           0 :             const SwSectionFmt& rFmt = *rSection.GetFmt();
    2478           0 :             ReplaceCr( msword::PageBreak ); // Indikator fuer Page/Section-Break
    2479             : 
    2480             :             // Get the page in use at the top of this section
    2481           0 :             SwNodeIndex aIdxTmp(rSectionNode, 1);
    2482             :             const SwPageDesc *pCurrent =
    2483           0 :                 SwPageDesc::GetPageDescOfNode(aIdxTmp.GetNode());
    2484           0 :             if (!pCurrent)
    2485           0 :                 pCurrent = pAktPageDesc;
    2486             : 
    2487           0 :             AppendSection( pCurrent, &rFmt, nRstLnNum );
    2488             :         }
    2489             :     }
    2490           0 :     if ( TOX_CONTENT_SECTION == rSection.GetType() )
    2491           0 :         bStartTOX = true;
    2492           0 : }
    2493             : 
    2494             : 
    2495           0 : void WW8Export::AppendSection( const SwPageDesc *pPageDesc, const SwSectionFmt* pFmt, sal_uLong nLnNum )
    2496             : {
    2497           0 :     pSepx->AppendSep(Fc2Cp(Strm().Tell()), pPageDesc, pFmt, nLnNum);
    2498           0 : }
    2499             : 
    2500             : // Flys
    2501             : 
    2502           0 : void WW8Export::OutWW6FlyFrmsInCntnt( const SwTxtNode& rNd )
    2503             : {
    2504             :     OSL_ENSURE(!bWrtWW8, "I shouldn't be needed for Word >=8");
    2505           0 :     if ( bWrtWW8 )
    2506           0 :         return;
    2507             : 
    2508           0 :     if (const SwpHints* pTxtAttrs = rNd.GetpSwpHints())
    2509             :     {
    2510           0 :         for( sal_uInt16 n=0; n < pTxtAttrs->Count(); ++n )
    2511             :         {
    2512           0 :             const SwTxtAttr* pAttr = (*pTxtAttrs)[ n ];
    2513           0 :             if( RES_TXTATR_FLYCNT == pAttr->Which() )
    2514             :             {
    2515             :                 // attribute bound to a character
    2516           0 :                 const SwFmtFlyCnt& rFlyCntnt = pAttr->GetFlyCnt();
    2517           0 :                 const SwFlyFrmFmt& rFlyFrmFmt = *(SwFlyFrmFmt*)rFlyCntnt.GetFrmFmt();
    2518           0 :                 const SwNodeIndex* pNodeIndex = rFlyFrmFmt.GetCntnt().GetCntntIdx();
    2519             : 
    2520           0 :                 if( pNodeIndex )
    2521             :                 {
    2522           0 :                     sal_uLong nStt = pNodeIndex->GetIndex()+1,
    2523           0 :                           nEnd = pNodeIndex->GetNode().EndOfSectionIndex();
    2524             : 
    2525           0 :                     if( (nStt < nEnd) && !pDoc->GetNodes()[ nStt ]->IsNoTxtNode() )
    2526             :                     {
    2527           0 :                         Point aOffset;
    2528             :                         // get rectangle (bounding box?) of Fly and paragraph
    2529           0 :                         SwRect aParentRect(rNd.FindLayoutRect(false, &aOffset)),
    2530           0 :                                aFlyRect(rFlyFrmFmt.FindLayoutRect(false, &aOffset ) );
    2531             : 
    2532           0 :                         aOffset = aFlyRect.Pos() - aParentRect.Pos();
    2533             : 
    2534             :                         // let PaM point to content of Fly-frame format
    2535           0 :                         SaveData( nStt, nEnd );
    2536             : 
    2537             :                         // is analysed in OutputFormat()
    2538           0 :                         pFlyOffset = &aOffset;
    2539           0 :                         eNewAnchorType = rFlyFrmFmt.GetAnchor().GetAnchorId();
    2540           0 :                         sw::Frame aFrm(rFlyFrmFmt, SwPosition(rNd));
    2541           0 :                         mpParentFrame = &aFrm;
    2542             :                         // Ok, write it out:
    2543           0 :                         WriteText();
    2544             : 
    2545           0 :                         RestoreData();
    2546             :                     }
    2547             :                 }
    2548             :             }
    2549             :         }
    2550             :     }
    2551             : }
    2552             : 
    2553           9 : void WW8AttributeOutput::OutputFlyFrame_Impl( const sw::Frame& rFmt, const Point& rNdTopLeft )
    2554             : {
    2555           9 :     const SwFrmFmt &rFrmFmt = rFmt.GetFrmFmt();
    2556           9 :     const SwFmtAnchor& rAnch = rFrmFmt.GetAnchor();
    2557             : 
    2558           9 :     bool bUseEscher = m_rWW8Export.bWrtWW8;
    2559             : 
    2560           9 :     if ( m_rWW8Export.bWrtWW8 && rFmt.IsInline() )
    2561             :     {
    2562           0 :         sw::Frame::WriterSource eType = rFmt.GetWriterType();
    2563           0 :         if ((eType == sw::Frame::eGraphic) || (eType == sw::Frame::eOle))
    2564           0 :             bUseEscher = false;
    2565             :         else
    2566           0 :             bUseEscher = true;
    2567             : 
    2568             :         /*
    2569             :          A special case for converting some inline form controls to form fields
    2570             :          when in winword 8+ mode
    2571             :         */
    2572           0 :         if ((bUseEscher == true) && (eType == sw::Frame::eFormControl))
    2573             :         {
    2574           0 :             if ( m_rWW8Export.MiserableFormFieldExportHack( rFrmFmt ) )
    2575           0 :                 return ;
    2576             :         }
    2577             :     }
    2578             : 
    2579           9 :     if (bUseEscher)
    2580             :     {
    2581             :         OSL_ENSURE( m_rWW8Export.bWrtWW8, "this has gone horribly wrong" );
    2582             :         // write as escher
    2583           9 :         m_rWW8Export.AppendFlyInFlys(rFmt, rNdTopLeft);
    2584             :     }
    2585             :     else
    2586             :     {
    2587           0 :         bool bDone = false;
    2588             : 
    2589             :         // Hole vom Node und vom letzten Node die Position in der Section
    2590           0 :         const SwNodeIndex* pNodeIndex = rFrmFmt.GetCntnt().GetCntntIdx();
    2591             : 
    2592           0 :         sal_uLong nStt = pNodeIndex ? pNodeIndex->GetIndex()+1                  : 0;
    2593           0 :         sal_uLong nEnd = pNodeIndex ? pNodeIndex->GetNode().EndOfSectionIndex() : 0;
    2594             : 
    2595           0 :         if( nStt >= nEnd )      // no range, hence no valid node
    2596           0 :             return;
    2597             : 
    2598           0 :         if ( !m_rWW8Export.IsInTable() && rFmt.IsInline() )
    2599             :         {
    2600             :             //Test to see if this textbox contains only a single graphic/ole
    2601           0 :             SwTxtNode* pParTxtNode = rAnch.GetCntntAnchor()->nNode.GetNode().GetTxtNode();
    2602           0 :             if ( pParTxtNode && !m_rWW8Export.pDoc->GetNodes()[ nStt ]->IsNoTxtNode() )
    2603           0 :                 bDone = true;
    2604             :         }
    2605           0 :         if( !bDone )
    2606             :         {
    2607             : 
    2608           0 :             m_rWW8Export.SaveData( nStt, nEnd );
    2609             : 
    2610           0 :             Point aOffset;
    2611           0 :             if ( m_rWW8Export.mpParentFrame )
    2612             :             {
    2613             :                 /* Munge flys in fly into absolutely positioned elements for word 6 */
    2614           0 :                 const SwTxtNode* pParTxtNode = rAnch.GetCntntAnchor()->nNode.GetNode().GetTxtNode();
    2615           0 :                 const SwRect aPageRect = pParTxtNode->FindPageFrmRect( sal_False, 0, sal_False );
    2616             : 
    2617           0 :                 aOffset = rFrmFmt.FindLayoutRect().Pos();
    2618           0 :                 aOffset -= aPageRect.Pos();
    2619             : 
    2620           0 :                 m_rWW8Export.pFlyOffset = &aOffset;
    2621           0 :                 m_rWW8Export.eNewAnchorType = FLY_AT_PAGE;
    2622             :             }
    2623             : 
    2624           0 :             m_rWW8Export.mpParentFrame = &rFmt;
    2625           0 :             if (
    2626           0 :                 m_rWW8Export.IsInTable() &&
    2627           0 :                  (FLY_AT_PAGE != rAnch.GetAnchorId()) &&
    2628           0 :                  !m_rWW8Export.pDoc->GetNodes()[ nStt ]->IsNoTxtNode()
    2629             :                )
    2630             :             {
    2631             :                 // note: set Flag  bOutTable again,
    2632             :                 // because we deliver the normal content of the table cell, and no border
    2633             :                 // ( Flag was deleted above in aSaveData() )
    2634           0 :                 m_rWW8Export.bOutTable = true;
    2635           0 :                 const String& rName = rFrmFmt.GetName();
    2636           0 :                 m_rWW8Export.StartCommentOutput(rName);
    2637           0 :                 m_rWW8Export.WriteText();
    2638           0 :                 m_rWW8Export.EndCommentOutput(rName);
    2639             :             }
    2640             :             else
    2641           0 :                 m_rWW8Export.WriteText();
    2642             : 
    2643           0 :             m_rWW8Export.RestoreData();
    2644             :         }
    2645             :     }
    2646             : }
    2647             : 
    2648          26 : void AttributeOutputBase::OutputFlyFrame( const sw::Frame& rFmt )
    2649             : {
    2650          26 :     if ( !rFmt.GetCntntNode() )
    2651          26 :         return;
    2652             : 
    2653          26 :     const SwCntntNode &rNode = *rFmt.GetCntntNode();
    2654          26 :     Point aNdPos, aPgPos;
    2655             :     Point* pLayPos;
    2656          26 :     bool bValidNdPos = false, bValidPgPos = false;
    2657             : 
    2658          26 :     if (FLY_AT_PAGE == rFmt.GetFrmFmt().GetAnchor().GetAnchorId())
    2659             :     {
    2660             :         // get the Layout Node-Position.
    2661           0 :         if ( !bValidPgPos )
    2662             :         {
    2663           0 :             aPgPos = rNode.FindPageFrmRect(false, &aPgPos).Pos();
    2664           0 :             bValidPgPos = true;
    2665             :         }
    2666           0 :         pLayPos = &aPgPos;
    2667             :     }
    2668             :     else
    2669             :     {
    2670             :         // get the Layout Node-Position.
    2671          26 :         if ( !bValidNdPos )
    2672             :         {
    2673          26 :             aNdPos = rNode.FindLayoutRect(false, &aNdPos).Pos();
    2674          26 :             bValidNdPos = true;
    2675             :         }
    2676          26 :         pLayPos = &aNdPos;
    2677             :     }
    2678             : 
    2679          26 :     OutputFlyFrame_Impl( rFmt, *pLayPos );
    2680             : }
    2681             : 
    2682             : // write data of any redline
    2683         324 : void WW8AttributeOutput::Redline( const SwRedlineData* pRedline )
    2684             : {
    2685         324 :     if ( !pRedline )
    2686         648 :         return;
    2687             : 
    2688           0 :     if ( pRedline->Next() )
    2689           0 :         Redline( pRedline->Next() );
    2690             : 
    2691             :     static sal_uInt16 aSprmIds[ 2 * 2 * 3 ] =
    2692             :     {
    2693             :         // Ids for insert
    2694             :             NS_sprm::LN_CFRMark, NS_sprm::LN_CIbstRMark, NS_sprm::LN_CDttmRMark,         // for WW8
    2695             :             0x0042, 0x0045, 0x0046,         // for WW6
    2696             :         // Ids for delete
    2697             :             NS_sprm::LN_CFRMarkDel, NS_sprm::LN_CIbstRMarkDel, NS_sprm::LN_CDttmRMarkDel,         // for WW8
    2698             :             0x0041, 0x0045, 0x0046          // for WW6
    2699             :     };
    2700             : 
    2701           0 :     const sal_uInt16* pSprmIds = 0;
    2702           0 :     switch( pRedline->GetType() )
    2703             :     {
    2704             :     case nsRedlineType_t::REDLINE_INSERT:
    2705           0 :         pSprmIds = aSprmIds;
    2706           0 :         break;
    2707             : 
    2708             :     case nsRedlineType_t::REDLINE_DELETE:
    2709           0 :         pSprmIds = aSprmIds + (2 * 3);
    2710           0 :         break;
    2711             : 
    2712             :     case nsRedlineType_t::REDLINE_FORMAT:
    2713           0 :         if( m_rWW8Export.bWrtWW8 )
    2714             :         {
    2715           0 :             m_rWW8Export.InsUInt16( NS_sprm::LN_CPropRMark );
    2716           0 :             m_rWW8Export.pO->push_back( 7 );       // len
    2717           0 :             m_rWW8Export.pO->push_back( 1 );
    2718           0 :             m_rWW8Export.InsUInt16( m_rWW8Export.AddRedlineAuthor( pRedline->GetAuthor() ) );
    2719           0 :             m_rWW8Export.InsUInt32( sw::ms::DateTime2DTTM( pRedline->GetTimeStamp() ));
    2720             :         }
    2721           0 :         break;
    2722             :     default:
    2723             :         OSL_ENSURE(!this, "Unhandled redline type for export");
    2724           0 :         break;
    2725             :     }
    2726             : 
    2727           0 :     if ( pSprmIds )
    2728             :     {
    2729           0 :         if ( !m_rWW8Export.bWrtWW8 )
    2730           0 :             pSprmIds += 3;
    2731             : 
    2732           0 :         if ( m_rWW8Export.bWrtWW8 )
    2733           0 :             m_rWW8Export.InsUInt16( pSprmIds[0] );
    2734             :         else
    2735           0 :             m_rWW8Export.pO->push_back( msword_cast<sal_uInt8>(pSprmIds[0]) );
    2736           0 :         m_rWW8Export.pO->push_back( 1 );
    2737             : 
    2738           0 :         if ( m_rWW8Export.bWrtWW8 )
    2739           0 :             m_rWW8Export.InsUInt16( pSprmIds[1] );
    2740             :         else
    2741           0 :             m_rWW8Export.pO->push_back( msword_cast<sal_uInt8>(pSprmIds[1]) );
    2742           0 :         m_rWW8Export.InsUInt16( m_rWW8Export.AddRedlineAuthor( pRedline->GetAuthor() ) );
    2743             : 
    2744           0 :         if ( m_rWW8Export.bWrtWW8 )
    2745           0 :             m_rWW8Export.InsUInt16( pSprmIds[2] );
    2746             :         else
    2747           0 :             m_rWW8Export.pO->push_back( msword_cast<sal_uInt8>(pSprmIds[2]) );
    2748           0 :         m_rWW8Export.InsUInt32( sw::ms::DateTime2DTTM( pRedline->GetTimeStamp() ));
    2749             :     }
    2750             : }
    2751             : 
    2752             : 
    2753         622 : void MSWordExportBase::OutputContentNode( const SwCntntNode& rNode )
    2754             : {
    2755         622 :     switch ( rNode.GetNodeType() )
    2756             :     {
    2757             :         case ND_TEXTNODE:
    2758             :         {
    2759         622 :             const SwTxtNode& rTextNode = *rNode.GetTxtNode();
    2760         622 :             if( !mbOutOutlineOnly || rTextNode.IsOutline() )
    2761         622 :                 OutputTextNode( rTextNode );
    2762             :         }
    2763         622 :         break;
    2764             :         case ND_GRFNODE:
    2765           0 :             OutputGrfNode( *rNode.GetGrfNode() );
    2766           0 :             break;
    2767             :         case ND_OLENODE:
    2768           0 :             OutputOLENode( *rNode.GetOLENode() );
    2769           0 :             break;
    2770             :         default:
    2771             :             OSL_TRACE("Unhandled node, type == %d", rNode.GetNodeType() );
    2772           0 :             break;
    2773             :     }
    2774         640 : }
    2775             : 
    2776             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10