LCOV - code coverage report
Current view: top level - sw/source/filter/html - wrthtml.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 497 733 67.8 %
Date: 2014-11-03 Functions: 30 37 81.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <stdlib.h>
      21             : #include <hintids.hxx>
      22             : #include <comphelper/string.hxx>
      23             : #include <svl/urihelper.hxx>
      24             : #include <rtl/tencinfo.h>
      25             : #include <vcl/wrkwin.hxx>
      26             : #include <sfx2/linkmgr.hxx>
      27             : 
      28             : #include <svtools/htmlcfg.hxx>
      29             : #include <vcl/svapp.hxx>
      30             : #include <i18nlangtag/languagetag.hxx>
      31             : #include <sfx2/frmhtmlw.hxx>
      32             : #include <svx/xoutbmp.hxx>
      33             : #include <sfx2/htmlmode.hxx>
      34             : #include <editeng/lrspitem.hxx>
      35             : #include <editeng/colritem.hxx>
      36             : #include <editeng/brushitem.hxx>
      37             : #include <editeng/fontitem.hxx>
      38             : #include <editeng/scripttypeitem.hxx>
      39             : #include <editeng/langitem.hxx>
      40             : #include <svl/stritem.hxx>
      41             : #include <editeng/frmdiritem.hxx>
      42             : 
      43             : #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
      44             : #include <com/sun/star/document/XDocumentProperties.hpp>
      45             : #include <com/sun/star/form/XFormsSupplier.hpp>
      46             : #include <com/sun/star/form/XForm.hpp>
      47             : #include <com/sun/star/form/XImageProducerSupplier.hpp>
      48             : #include <com/sun/star/form/XFormController.hpp>
      49             : #include <com/sun/star/container/XContainer.hpp>
      50             : #include <com/sun/star/container/XIndexContainer.hpp>
      51             : #include <com/sun/star/container/XSet.hpp>
      52             : #include <fmthdft.hxx>
      53             : #include <fmtfld.hxx>
      54             : #include <fmtpdsc.hxx>
      55             : #include <txatbase.hxx>
      56             : #include <frmatr.hxx>
      57             : #include <charfmt.hxx>
      58             : #include <docary.hxx>
      59             : #include <pam.hxx>
      60             : #include <doc.hxx>
      61             : #include <ndtxt.hxx>
      62             : #include <mdiexp.hxx>
      63             : #include <fltini.hxx>
      64             : #include <viewopt.hxx>
      65             : #include <IMark.hxx>
      66             : #include <poolfmt.hxx>
      67             : #include <pagedesc.hxx>
      68             : #include <section.hxx>
      69             : #include <swtable.hxx>
      70             : #include <fldbas.hxx>
      71             : #include <fmtclds.hxx>
      72             : #include <docsh.hxx>
      73             : #include <wrthtml.hxx>
      74             : #include <htmlnum.hxx>
      75             : #include <htmlfly.hxx>
      76             : #include <swmodule.hxx>
      77             : #include <statstr.hrc>
      78             : #include <swerror.h>
      79             : #include <rtl/strbuf.hxx>
      80             : #include <IDocumentSettingAccess.hxx>
      81             : #include <IDocumentStylePoolAccess.hxx>
      82             : #include <xmloff/odffields.hxx>
      83             : 
      84             : #define MAX_INDENT_LEVEL 20
      85             : 
      86             : using namespace css;
      87             : 
      88             : static sal_Char sIndentTabs[MAX_INDENT_LEVEL+2] =
      89             :     "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
      90             : 
      91          24 : SwHTMLWriter::SwHTMLWriter( const OUString& rBaseURL )
      92             :     : pHTMLPosFlyFrms(NULL)
      93          24 :     , pNumRuleInfo(new SwHTMLNumRuleInfo)
      94             :     , pNextNumRuleInfo(NULL)
      95             :     , nHTMLMode(0)
      96             :     , eCSS1Unit(FUNIT_NONE)
      97             :     , pFootEndNotes(NULL)
      98             :     , pxFormComps(NULL)
      99             :     , pTemplate(NULL)
     100             :     , pDfltColor(NULL)
     101             :     , pStartNdIdx(NULL)
     102             :     , pCurrPageDesc(NULL)
     103             :     , pFmtFtn(NULL)
     104             :     , nWarn(0)
     105             :     , nLastLFPos(0)
     106             :     , nLastParaToken(0)
     107             :     , nBkmkTabPos(-1)
     108             :     , nImgMapCnt(1)
     109             :     , nFormCntrlCnt(0)
     110             :     , nEndNote(0)
     111             :     , nFootNote(0)
     112             :     , nLeftMargin(0)
     113             :     , nDfltLeftMargin(0)
     114             :     , nDfltRightMargin(0)
     115             :     , nFirstLineIndent(0)
     116             :     , nDfltFirstLineIndent(0)
     117             :     , nDfltTopMargin(0)
     118             :     , nDfltBottomMargin(0)
     119             :     , nIndentLvl(0)
     120             :     , nWhishLineLen(0)
     121             :     , nDefListLvl(0)
     122             :     , nDefListMargin(0)
     123             :     , nHeaderFooterSpace(0)
     124             :     , nTxtAttrsToIgnore(0)
     125             :     , nExportMode(0)
     126             :     , nCSS1OutMode(0)
     127             :     , nCSS1Script(CSS1_OUTMODE_WESTERN)
     128             :     , nDirection(FRMDIR_HORI_LEFT_TOP)
     129             :     , eDestEnc(RTL_TEXTENCODING_MS_1252)
     130             :     , eLang(LANGUAGE_DONTKNOW)
     131             :     , bCfgOutStyles( false )
     132             :     , bCfgPreferStyles( false )
     133             :     , bCfgFormFeed( false )
     134             :     , bCfgStarBasic( false )
     135             :     , bCfgCpyLinkedGrfs( false )
     136             :     , bFirstLine(true)
     137             :     , bTagOn( false )
     138             :     , bTxtAttr( false )
     139             :     , bOutOpts( false )
     140             :     , bOutTable( false )
     141             :     , bOutHeader( false )
     142             :     , bOutFooter( false )
     143             :     , bOutFlyFrame( false )
     144             :     , bFirstCSS1Rule( false )
     145             :     , bFirstCSS1Property( false )
     146             :     , bPoolCollTextModified( false )
     147             :     , bCSS1IgnoreFirstPageDesc( false )
     148             :     , bNoAlign( false )
     149             :     , bClearLeft( false )
     150             :     , bClearRight( false )
     151             :     , bLFPossible( false )
     152             :     , bPreserveForm( false )
     153             :     , bCfgNetscape4( false )
     154             :     , mbSkipImages(false)
     155          48 :     , mbSkipHeaderFooter(false)
     156             : {
     157          24 :     SetBaseURL(rBaseURL);
     158          24 : }
     159             : 
     160          72 : SwHTMLWriter::~SwHTMLWriter()
     161             : {
     162          24 :     delete pNumRuleInfo;
     163          48 : }
     164             : 
     165          24 : void SwHTMLWriter::SetupFilterOptions(SfxMedium& rMedium)
     166             : {
     167          24 :     const SfxItemSet* pSet = rMedium.GetItemSet();
     168          24 :     if (pSet == NULL)
     169          16 :         return;
     170             : 
     171             :     const SfxPoolItem* pItem;
     172          24 :     if (pSet->GetItemState( SID_FILE_FILTEROPTIONS, true, &pItem ) != SfxItemState::SET)
     173          16 :         return;
     174             : 
     175             : 
     176           8 :     OUString sFilterOptions = ((const SfxStringItem*)pItem)->GetValue();
     177           8 :     if (sFilterOptions == "SkipImages")
     178             :     {
     179           6 :         mbSkipImages = true;
     180             :     }
     181           2 :     else if (sFilterOptions == "SkipHeaderFooter")
     182             :     {
     183           2 :         mbSkipHeaderFooter = true;
     184           8 :     }
     185             : }
     186             : 
     187          24 : sal_uLong SwHTMLWriter::WriteStream()
     188             : {
     189          24 :     SvxHtmlOptions& rHtmlOptions = SvxHtmlOptions::Get();
     190             : 
     191             :     // font heights 1-7
     192          24 :     aFontHeights[0] = rHtmlOptions.GetFontSize( 0 ) * 20;
     193          24 :     aFontHeights[1] = rHtmlOptions.GetFontSize( 1 ) * 20;
     194          24 :     aFontHeights[2] = rHtmlOptions.GetFontSize( 2 ) * 20;
     195          24 :     aFontHeights[3] = rHtmlOptions.GetFontSize( 3 ) * 20;
     196          24 :     aFontHeights[4] = rHtmlOptions.GetFontSize( 4 ) * 20;
     197          24 :     aFontHeights[5] = rHtmlOptions.GetFontSize( 5 ) * 20;
     198          24 :     aFontHeights[6] = rHtmlOptions.GetFontSize( 6 ) * 20;
     199             : 
     200             :     // ueberhaupt Styles ausgeben
     201             :     // (dann auch obere und untere Absatz-Abstaende)
     202          24 :     nExportMode = rHtmlOptions.GetExportMode();
     203          24 :     nHTMLMode = GetHtmlMode(0);
     204             : 
     205          24 :     if( HTML_CFG_WRITER == nExportMode || HTML_CFG_NS40 == nExportMode )
     206          24 :         nHTMLMode |= HTMLMODE_BLOCK_SPACER;
     207             : 
     208          24 :     if( HTML_CFG_WRITER == nExportMode || HTML_CFG_MSIE == nExportMode )
     209           0 :         nHTMLMode |= (HTMLMODE_FLOAT_FRAME | HTMLMODE_LSPACE_IN_NUMBUL);
     210             : 
     211          24 :     if( HTML_CFG_MSIE == nExportMode )
     212           0 :         nHTMLMode |= HTMLMODE_NBSP_IN_TABLES;
     213             : 
     214          24 :     if( HTML_CFG_WRITER == nExportMode || HTML_CFG_NS40 == nExportMode || HTML_CFG_MSIE == nExportMode )
     215          24 :         nHTMLMode |= HTMLMODE_ABS_POS_FLY | HTMLMODE_ABS_POS_DRAW;
     216             : 
     217          24 :     if( HTML_CFG_WRITER == nExportMode )
     218           0 :         nHTMLMode |= HTMLMODE_FLY_MARGINS;
     219             : 
     220          24 :     if( HTML_CFG_NS40 == nExportMode )
     221          24 :         nHTMLMode |= HTMLMODE_BORDER_NONE;
     222             : 
     223          24 :     nHTMLMode |= HTMLMODE_FONT_GENERIC;
     224             : 
     225          24 :     if( HTML_CFG_NS40==nExportMode )
     226          24 :         nHTMLMode |= HTMLMODE_NO_CONTROL_CENTERING;
     227             : 
     228          24 :     bCfgOutStyles = IsHTMLMode(HTMLMODE_SOME_STYLES | HTMLMODE_FULL_STYLES);
     229          24 :     bCfgNetscape4 = (HTML_CFG_NS40 == nExportMode);
     230             : 
     231          24 :     if( IsHTMLMode(HTMLMODE_SOME_STYLES | HTMLMODE_FULL_STYLES) )
     232          24 :         nHTMLMode |= HTMLMODE_PRINT_EXT;
     233             : 
     234          24 :     const sal_Char *pHelpHack = getenv( "HelpEx" );
     235          24 :     if( pHelpHack )
     236             :     {
     237           0 :         OString aTmp(pHelpHack);
     238           0 :         if (aTmp.equalsIgnoreAsciiCase("Hilfe"))
     239           0 :             nHTMLMode |= HTMLMODE_NO_BR_AT_PAREND;
     240             :     }
     241             : 
     242          24 :     eCSS1Unit = (FieldUnit)SW_MOD()->GetMetric( pDoc->getIDocumentSettingAccess().get(IDocumentSettingAccess::HTML_MODE) );
     243             : 
     244          24 :     bool bWriteUTF8 = bWriteClipboardDoc;
     245          24 :     eDestEnc = bWriteUTF8 ? RTL_TEXTENCODING_UTF8 : rHtmlOptions.GetTextEncoding();
     246          24 :     const sal_Char *pCharSet = rtl_getBestMimeCharsetFromTextEncoding( eDestEnc );
     247          24 :     eDestEnc = rtl_getTextEncodingFromMimeCharset( pCharSet );
     248             : 
     249             :     // Nur noch fuer den MS-IE ziehen wir den Export von Styles vor.
     250          24 :     bCfgPreferStyles = HTML_CFG_MSIE == nExportMode;
     251             : 
     252          24 :     bCfgStarBasic = rHtmlOptions.IsStarBasic();
     253             : 
     254          24 :     bCfgFormFeed = !IsHTMLMode(HTMLMODE_PRINT_EXT);
     255          24 :     bCfgCpyLinkedGrfs = rHtmlOptions.IsSaveGraphicsLocal();
     256             : 
     257             :     // die HTML-Vorlage holen
     258          24 :     bool bOldHTMLMode = false;
     259          24 :     sal_uInt16 nOldTxtFmtCollCnt = 0, nOldCharFmtCnt = 0;
     260             : 
     261             :     OSL_ENSURE( !pTemplate, "Wo kommt denn die HTML-Vorlage hier her?" );
     262          24 :     pTemplate = ((HTMLReader*)ReadHTML)->GetTemplateDoc();
     263          24 :     if( pTemplate )
     264             :     {
     265          24 :         pTemplate->acquire();
     266          24 :         bOldHTMLMode = pTemplate->getIDocumentSettingAccess().get(IDocumentSettingAccess::HTML_MODE);
     267          24 :         pTemplate->getIDocumentSettingAccess().set(IDocumentSettingAccess::HTML_MODE, true);
     268             : 
     269          24 :         nOldTxtFmtCollCnt = pTemplate->GetTxtFmtColls()->size();
     270          24 :         nOldCharFmtCnt = pTemplate->GetCharFmts()->size();
     271             :     }
     272             : 
     273          24 :     if( bShowProgress )
     274          24 :         ::StartProgress( STR_STATSTR_W4WWRITE, 0, pDoc->GetNodes().Count(),
     275          48 :                          pDoc->GetDocShell());
     276             : 
     277          24 :     pDfltColor = 0;
     278          24 :     pFootEndNotes = 0;
     279          24 :     pFmtFtn = 0;
     280          24 :     bOutTable = bOutHeader = bOutFooter = bOutFlyFrame = false;
     281          24 :     pxFormComps = 0;
     282          24 :     nFormCntrlCnt = 0;
     283          24 :     bPreserveForm = false;
     284          24 :     bClearLeft = bClearRight = false;
     285          24 :     bLFPossible = false;
     286             : 
     287          24 :     nLeftMargin = nDfltLeftMargin = nDfltRightMargin = 0;
     288          24 :     nDfltTopMargin = nDfltBottomMargin = 0;
     289          24 :     nFirstLineIndent = nDfltFirstLineIndent = 0;
     290          24 :     bPoolCollTextModified = false;
     291          24 :     bFirstCSS1Property = bFirstCSS1Rule = false;
     292          24 :     bCSS1IgnoreFirstPageDesc = false;
     293          24 :     nIndentLvl = 0;
     294          24 :     nWhishLineLen = 70;
     295          24 :     nLastLFPos = 0;
     296          24 :     nDefListLvl = 0;
     297          24 :     nDefListMargin = ((pTemplate && !bCfgOutStyles) ? pTemplate : pDoc)
     298          24 :         ->getIDocumentStylePoolAccess().GetTxtCollFromPool( RES_POOLCOLL_HTML_DD, false )
     299          24 :         ->GetLRSpace().GetTxtLeft();
     300          24 :     nHeaderFooterSpace = 0;
     301          24 :     nTxtAttrsToIgnore = 0;
     302          24 :     nCSS1OutMode = 0;
     303          24 :     sal_uInt16 nScript = SvtLanguageOptions::GetScriptTypeOfLanguage( GetAppLanguage() );
     304          24 :     switch( nScript )
     305             :     {
     306             :     case SCRIPTTYPE_ASIAN:
     307           0 :         nCSS1Script = CSS1_OUTMODE_CJK;
     308           0 :         break;
     309             :     case SCRIPTTYPE_COMPLEX:
     310           0 :         nCSS1Script = CSS1_OUTMODE_CTL;
     311           0 :         break;
     312             :     default:
     313          24 :         nCSS1Script = CSS1_OUTMODE_WESTERN;
     314          24 :         break;
     315             :     }
     316             :     eLang = ((const SvxLanguageItem&)pDoc
     317          24 :             ->GetDefault(GetLangWhichIdFromScript(nCSS1Script))).GetLanguage();
     318             : 
     319          24 :     nFootNote = nEndNote = 0;
     320             : 
     321          24 :     nWarn = 0;
     322          24 :     GetNumInfo().Clear();
     323          24 :     pNextNumRuleInfo = 0;
     324             : 
     325          24 :     OString aStartTags;
     326             : 
     327             :     // Tabellen und Bereiche am Doc.-Anfang beachten
     328             :     {
     329          24 :         SwTableNode * pTNd = pCurPam->GetNode().FindTableNode();
     330          24 :         if( pTNd && bWriteAll )
     331             :         {
     332             :             // mit dem Tabellen-Node anfangen !!
     333           2 :             pCurPam->GetPoint()->nNode = *pTNd;
     334             : 
     335           2 :             if( bWriteOnlyFirstTable )
     336           0 :                 pCurPam->GetMark()->nNode = *pTNd->EndOfSectionNode();
     337             :         }
     338             : 
     339             :         // erster Node (der einen Seitenumbruch enthalten darf)
     340          24 :         pStartNdIdx = new SwNodeIndex( pCurPam->GetPoint()->nNode );
     341             : 
     342          24 :         SwSectionNode * pSNd = pCurPam->GetNode().FindSectionNode();
     343          48 :         while( pSNd )
     344             :         {
     345           0 :             if( bWriteAll )
     346             :             {
     347             :                 // mit dem Section-Node anfangen !!
     348           0 :                 pCurPam->GetPoint()->nNode = *pSNd;
     349             :             }
     350             :             else
     351             :             {
     352             :                 OSL_ENSURE( FILE_LINK_SECTION != pSNd->GetSection().GetType(),
     353             :                         "Export gelinkter Bereiche am Dok-Anfang ist nicht implemntiert" );
     354             : 
     355             :                 // nur das Tag fuer die Section merken
     356             :                 OString aName = HTMLOutFuncs::ConvertStringToHTML(
     357           0 :                     pSNd->GetSection().GetSectionName(), eDestEnc,
     358           0 :                     &aNonConvertableCharacters );
     359             : 
     360           0 :                 OStringBuffer sOut;
     361           0 :                 sOut.append('<').append(OOO_STRING_SVTOOLS_HTML_division)
     362           0 :                     .append(' ').append(OOO_STRING_SVTOOLS_HTML_O_id)
     363           0 :                     .append("=\"").append(aName).append('\"').append('>')
     364           0 :                     .append(aStartTags);
     365           0 :                 aStartTags = sOut.makeStringAndClear();
     366             :             }
     367             :             // FindSectionNode() an einem SectionNode liefert den selben!
     368           0 :             pSNd = pSNd->StartOfSectionNode()->FindSectionNode();
     369             :         }
     370             :     }
     371             : 
     372             :     // Tabelle fuer die freifliegenden Rahmen erzeugen, aber nur wenn
     373             :     // das gesamte Dokument geschrieben wird
     374          24 :     pHTMLPosFlyFrms = 0;
     375          24 :     CollectFlyFrms();
     376          24 :     nLastParaToken = 0;
     377          24 :     GetControls();
     378          24 :     CollectLinkTargets();
     379             : 
     380          24 :     sal_uInt16 nHeaderAttrs = 0;
     381          24 :     pCurrPageDesc = MakeHeader( nHeaderAttrs );
     382             : 
     383          24 :     bLFPossible = true;
     384             : 
     385             :     // Formulare, die nur HiddenControls enthalten ausgeben.
     386          24 :     OutHiddenForms();
     387             : 
     388          24 :     if( !aStartTags.isEmpty() )
     389           0 :         Strm().WriteCharPtr( aStartTags.getStr() );
     390             : 
     391             :     const SfxPoolItem *pItem;
     392          24 :     const SfxItemSet& rPageItemSet = pCurrPageDesc->GetMaster().GetAttrSet();
     393          96 :     if( !bWriteClipboardDoc && pDoc->GetDocShell() &&
     394          46 :          (!pDoc->getIDocumentSettingAccess().get(IDocumentSettingAccess::HTML_MODE) &&
     395          66 :           !pDoc->getIDocumentSettingAccess().get(IDocumentSettingAccess::BROWSE_MODE)) &&
     396          20 :         SfxItemState::SET == rPageItemSet.GetItemState( RES_HEADER, true, &pItem) )
     397             :     {
     398             :         const SwFrmFmt *pHeaderFmt =
     399          20 :             ((const SwFmtHeader *)pItem)->GetHeaderFmt();
     400          20 :         if( pHeaderFmt )
     401           0 :             OutHTML_HeaderFooter( *this, *pHeaderFmt, true );
     402             :     }
     403             : 
     404          24 :     nTxtAttrsToIgnore = nHeaderAttrs;
     405          24 :     Out_SwDoc( pOrigPam );
     406          24 :     nTxtAttrsToIgnore = 0;
     407             : 
     408          24 :     if( pxFormComps && pxFormComps->is() )
     409           0 :         OutForm( false, *pxFormComps );
     410             : 
     411          24 :     if( pFootEndNotes )
     412           0 :         OutFootEndNotes();
     413             : 
     414          96 :     if( !bWriteClipboardDoc && pDoc->GetDocShell() &&
     415          90 :         (!pDoc->getIDocumentSettingAccess().get(IDocumentSettingAccess::HTML_MODE) && !pDoc->getIDocumentSettingAccess().get(IDocumentSettingAccess::BROWSE_MODE))  &&
     416          20 :         SfxItemState::SET == rPageItemSet.GetItemState( RES_FOOTER, true, &pItem) )
     417             :     {
     418             :         const SwFrmFmt *pFooterFmt =
     419          20 :             ((const SwFmtFooter *)pItem)->GetFooterFmt();
     420          20 :         if( pFooterFmt )
     421           2 :             OutHTML_HeaderFooter( *this, *pFooterFmt, false );
     422             :     }
     423             : 
     424          24 :     if( bLFPossible )
     425          24 :         OutNewLine();
     426          24 :     if (!mbSkipHeaderFooter)
     427             :     {
     428          22 :         HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_body, false );
     429          22 :         OutNewLine();
     430          22 :         HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_html, false );
     431             :     }
     432             : 
     433             :     // loesche die Tabelle mit den freifliegenden Rahmen
     434             :     sal_uInt16 i;
     435             :     OSL_ENSURE( !pHTMLPosFlyFrms, "Wurden nicht alle Rahmen ausgegeben" );
     436          24 :     if( pHTMLPosFlyFrms )
     437             :     {
     438           0 :         pHTMLPosFlyFrms->DeleteAndDestroyAll();
     439           0 :         delete pHTMLPosFlyFrms;
     440           0 :         pHTMLPosFlyFrms = 0;
     441             :     }
     442             : 
     443          24 :     aHTMLControls.DeleteAndDestroyAll();
     444             : 
     445          24 :     if( !aChrFmtInfos.empty() )
     446           0 :         aChrFmtInfos.clear();
     447             : 
     448          24 :     if( !aTxtCollInfos.empty() )
     449          24 :         aTxtCollInfos.clear();
     450             : 
     451          24 :     if(!aImgMapNames.empty())
     452           2 :         aImgMapNames.clear();
     453             : 
     454          24 :     aImplicitMarks.clear();
     455             : 
     456          24 :     aOutlineMarks.clear();
     457             : 
     458          24 :     aOutlineMarkPoss.clear();
     459             : 
     460          24 :     aNumRuleNames.clear();
     461             : 
     462          24 :     aScriptParaStyles.clear();
     463          24 :     aScriptTextStyles.clear();
     464             : 
     465          24 :     delete pDfltColor;
     466          24 :     pDfltColor = 0;
     467             : 
     468          24 :     delete pStartNdIdx;
     469          24 :     pStartNdIdx = 0;
     470             : 
     471          24 :     delete pxFormComps;
     472          24 :     pxFormComps = 0;
     473             : 
     474             :     OSL_ENSURE( !pFootEndNotes,
     475             :             "SwHTMLWriter::Write: Ftns nicht durch OutFootEndNotes geloescht" );
     476             : 
     477          24 :     pCurrPageDesc = 0;
     478             : 
     479          24 :     ClearNextNumInfo();
     480             : 
     481         264 :     for( i=0; i<MAXLEVEL; i++ )
     482         240 :         aBulletGrfs[i] = "";
     483             : 
     484          24 :     aNonConvertableCharacters = "";
     485             : 
     486          24 :     if( bShowProgress )
     487          24 :         ::EndProgress( pDoc->GetDocShell() );
     488             : 
     489          24 :     if( pTemplate )
     490             :     {
     491             :         // Waehrend des Exports angelegte Zeichen- und Abastzvorlagen
     492             :         // loeschen
     493          24 :         sal_uInt16 nTxtFmtCollCnt = pTemplate->GetTxtFmtColls()->size();
     494          48 :         while( nTxtFmtCollCnt > nOldTxtFmtCollCnt )
     495           0 :             pTemplate->DelTxtFmtColl( --nTxtFmtCollCnt );
     496             :         OSL_ENSURE( pTemplate->GetTxtFmtColls()->size() == nOldTxtFmtCollCnt,
     497             :                 "falsche Anzahl TxtFmtColls geloescht" );
     498             : 
     499          24 :         sal_uInt16 nCharFmtCnt = pTemplate->GetCharFmts()->size();
     500         124 :         while( nCharFmtCnt > nOldCharFmtCnt )
     501          76 :             pTemplate->DelCharFmt( --nCharFmtCnt );
     502             :         OSL_ENSURE( pTemplate->GetCharFmts()->size() == nOldCharFmtCnt,
     503             :                 "falsche Anzahl CharFmts geloescht" );
     504             : 
     505             :         // HTML-Modus wieder restaurieren
     506          24 :         pTemplate->getIDocumentSettingAccess().set(IDocumentSettingAccess::HTML_MODE, bOldHTMLMode);
     507             : 
     508          24 :         if( 0 == pTemplate->release() )
     509           0 :             delete pTemplate;
     510             : 
     511          24 :         pTemplate = 0;
     512             :     }
     513             : 
     514          24 :     return nWarn;
     515             : }
     516             : 
     517           0 : static const SwFmtCol *lcl_html_GetFmtCol( const SwSection& rSection,
     518             :                                        const SwSectionFmt& rFmt )
     519             : {
     520           0 :     const SwFmtCol *pCol = 0;
     521             : 
     522             :     const SfxPoolItem* pItem;
     523           0 :     if( FILE_LINK_SECTION != rSection.GetType() &&
     524           0 :         SfxItemState::SET == rFmt.GetAttrSet().GetItemState(RES_COL,false,&pItem) &&
     525           0 :         ((const SwFmtCol *)pItem)->GetNumCols() > 1 )
     526             :     {
     527           0 :         pCol = (const SwFmtCol *)pItem;
     528             :     }
     529             : 
     530           0 :     return pCol;
     531             : }
     532             : 
     533           0 : static bool lcl_html_IsMultiColStart( const SwHTMLWriter& rHTMLWrt, sal_uLong nIndex )
     534             : {
     535           0 :     bool bRet = false;
     536             :     const SwSectionNode *pSectNd =
     537           0 :         rHTMLWrt.pDoc->GetNodes()[nIndex]->GetSectionNode();
     538           0 :     if( pSectNd )
     539             :     {
     540           0 :         const SwSection& rSection = pSectNd->GetSection();
     541           0 :         const SwSectionFmt *pFmt = rSection.GetFmt();
     542           0 :         if( pFmt && lcl_html_GetFmtCol( rSection, *pFmt ) )
     543           0 :             bRet = true;
     544             :     }
     545             : 
     546           0 :     return bRet;
     547             : }
     548             : 
     549           0 : static bool lcl_html_IsMultiColEnd( const SwHTMLWriter& rHTMLWrt, sal_uLong nIndex )
     550             : {
     551           0 :     bool bRet = false;
     552           0 :     const SwEndNode *pEndNd = rHTMLWrt.pDoc->GetNodes()[nIndex]->GetEndNode();
     553           0 :     if( pEndNd )
     554             :         bRet = lcl_html_IsMultiColStart( rHTMLWrt,
     555           0 :                                          pEndNd->StartOfSectionIndex() );
     556             : 
     557           0 :     return bRet;
     558             : }
     559             : 
     560           0 : static void lcl_html_OutSectionStartTag( SwHTMLWriter& rHTMLWrt,
     561             :                                      const SwSection& rSection,
     562             :                                      const SwSectionFmt& rFmt,
     563             :                                   const SwFmtCol *pCol,
     564             :                                   bool bContinued=false )
     565             : {
     566             :     OSL_ENSURE( pCol || !bContinued, "Continuation of DIV" );
     567             : 
     568           0 :     if( rHTMLWrt.bLFPossible )
     569           0 :         rHTMLWrt.OutNewLine();
     570             : 
     571           0 :     OStringBuffer sOut;
     572           0 :     sOut.append('<').append(OOO_STRING_SVTOOLS_HTML_division);
     573             : 
     574           0 :     const OUString& rName = rSection.GetSectionName();
     575           0 :     if( !rName.isEmpty() && !bContinued )
     576             :     {
     577           0 :         sOut.append(" " + OString(OOO_STRING_SVTOOLS_HTML_O_id) + "=\"");
     578           0 :         rHTMLWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
     579           0 :         HTMLOutFuncs::Out_String( rHTMLWrt.Strm(), rName, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
     580           0 :         sOut.append('\"');
     581             :     }
     582             : 
     583           0 :     sal_uInt16 nDir = rHTMLWrt.GetHTMLDirection( rFmt.GetAttrSet() );
     584           0 :     rHTMLWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
     585           0 :     rHTMLWrt.OutDirection( nDir );
     586             : 
     587           0 :     if( FILE_LINK_SECTION == rSection.GetType() )
     588             :     {
     589           0 :         sOut.append(" " + OString(OOO_STRING_SVTOOLS_HTML_O_href) + "=\"");
     590           0 :         rHTMLWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
     591             : 
     592           0 :         const OUString& aFName = rSection.GetLinkFileName();
     593           0 :         OUString aURL( aFName.getToken(0,sfx2::cTokenSeparator) );
     594           0 :         OUString aFilter( aFName.getToken(1,sfx2::cTokenSeparator) );
     595           0 :         OUString aSection( aFName.getToken(2,sfx2::cTokenSeparator) );
     596             : 
     597           0 :         OUString aEncURL( URIHelper::simpleNormalizedMakeRelative(rHTMLWrt.GetBaseURL(), aURL ) );
     598           0 :         sal_Unicode cDelim = 255U;
     599           0 :         bool bURLContainsDelim = (-1 != aEncURL.indexOf( cDelim ) );
     600             : 
     601           0 :         HTMLOutFuncs::Out_String( rHTMLWrt.Strm(), aEncURL,
     602             :                                   rHTMLWrt.eDestEnc,
     603           0 :                                   &rHTMLWrt.aNonConvertableCharacters );
     604           0 :         const sal_Char* pDelim = "&#255;";
     605           0 :         if( !aFilter.isEmpty() || !aSection.isEmpty() || bURLContainsDelim )
     606           0 :             rHTMLWrt.Strm().WriteCharPtr( pDelim );
     607           0 :         if( !aFilter.isEmpty() )
     608           0 :             HTMLOutFuncs::Out_String( rHTMLWrt.Strm(), aFilter, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
     609           0 :         if( !aSection.isEmpty() || bURLContainsDelim  )
     610           0 :                 rHTMLWrt.Strm().WriteCharPtr( pDelim );
     611           0 :         if( !aSection.isEmpty() )
     612             :         {
     613           0 :             sal_Int32 nPos = aSection.indexOf( '%' );
     614           0 :             while( nPos != -1 )
     615             :             {
     616           0 :                 aSection = aSection.replaceAt(nPos, 1, "%25");
     617           0 :                 nPos = aSection.indexOf( '%', nPos+3 );
     618             :             }
     619           0 :             nPos = aSection.indexOf( cDelim );
     620           0 :             while( nPos != -1 )
     621             :             {
     622           0 :                 aSection = aSection.replaceAt(nPos, 1, "%FF" );
     623           0 :                 nPos = aSection.indexOf( cDelim, nPos+3 );
     624             :             }
     625           0 :             HTMLOutFuncs::Out_String( rHTMLWrt.Strm(), aSection,
     626           0 :                                       rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
     627             :         }
     628           0 :         sOut.append('\"');
     629             :     }
     630           0 :     else if( pCol )
     631             :     {
     632             :         // minumum gutter width
     633           0 :         sal_uInt16 nGutter = pCol->GetGutterWidth( true );
     634           0 :         if( nGutter!=USHRT_MAX )
     635             :         {
     636           0 :             if( nGutter && Application::GetDefaultDevice() )
     637             :             {
     638             :                 nGutter = (sal_uInt16)Application::GetDefaultDevice()
     639           0 :                                 ->LogicToPixel( Size(nGutter, 0), MapMode(MAP_TWIP) ).Width();
     640             :             }
     641           0 :             sOut.append(" " + OString(OOO_STRING_SVTOOLS_HTML_O_gutter) + "=\"" + OString::number(nGutter) + "\"");
     642             :         }
     643             :     }
     644             : 
     645           0 :     rHTMLWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
     646           0 :     if( rHTMLWrt.IsHTMLMode( rHTMLWrt.bCfgOutStyles ? HTMLMODE_ON : 0 ) )
     647           0 :         rHTMLWrt.OutCSS1_SectionFmtOptions( rFmt, pCol );
     648             : 
     649           0 :     rHTMLWrt.Strm().WriteChar( '>' );
     650             : 
     651           0 :     rHTMLWrt.bLFPossible = true;
     652           0 :     if( !rName.isEmpty() && !bContinued )
     653           0 :         rHTMLWrt.OutImplicitMark( rName, "region" );
     654             : 
     655           0 :     rHTMLWrt.IncIndentLevel();
     656           0 : }
     657             : 
     658           0 : static void lcl_html_OutSectionEndTag( SwHTMLWriter& rHTMLWrt )
     659             : {
     660           0 :     rHTMLWrt.DecIndentLevel();
     661           0 :     if( rHTMLWrt.bLFPossible )
     662           0 :         rHTMLWrt.OutNewLine();
     663           0 :     HTMLOutFuncs::Out_AsciiTag( rHTMLWrt.Strm(), OOO_STRING_SVTOOLS_HTML_division, false );
     664           0 :     rHTMLWrt.bLFPossible = true;
     665           0 : }
     666             : 
     667           0 : static Writer& OutHTML_Section( Writer& rWrt, const SwSectionNode& rSectNd )
     668             : {
     669           0 :     SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
     670             : 
     671             :     // End <PRE> and any <DL>, because a definition list's level may
     672             :     // change inside the section.
     673           0 :     rHTMLWrt.ChangeParaToken( 0 );
     674           0 :     rHTMLWrt.OutAndSetDefList( 0 );
     675             : 
     676           0 :     const SwSection& rSection = rSectNd.GetSection();
     677           0 :     const SwSectionFmt *pFmt = rSection.GetFmt();
     678             :     OSL_ENSURE( pFmt, "Section without a format?" );
     679             : 
     680           0 :     bool bStartTag = true;
     681           0 :     bool bEndTag = true;
     682           0 :     const SwSectionFmt *pSurrFmt = 0;
     683           0 :     const SwSectionNode *pSurrSectNd = 0;
     684           0 :     const SwSection *pSurrSection = 0;
     685           0 :     const SwFmtCol *pSurrCol = 0;
     686             : 
     687           0 :     sal_uInt32 nSectSttIdx = rSectNd.GetIndex();
     688           0 :     sal_uInt32 nSectEndIdx = rSectNd.EndOfSectionIndex();
     689           0 :     const SwFmtCol *pCol = lcl_html_GetFmtCol( rSection, *pFmt );
     690           0 :     if( pCol )
     691             :     {
     692             :         // If the next node is a columned section node, too, don't export
     693             :         // an empty section.
     694           0 :         if( lcl_html_IsMultiColStart( rHTMLWrt, nSectSttIdx+1 ) )
     695           0 :             bStartTag = false;
     696             : 
     697             :         // The same applies if the section end with another columned section.
     698           0 :         if( lcl_html_IsMultiColEnd( rHTMLWrt, nSectEndIdx-1 ) )
     699           0 :             bEndTag = false;
     700             : 
     701             :         //.is there a columned section around this one?
     702           0 :         const SwStartNode *pSttNd = rSectNd.StartOfSectionNode();
     703           0 :         if( pSttNd )
     704             :         {
     705           0 :             pSurrSectNd = pSttNd->FindSectionNode();
     706           0 :             if( pSurrSectNd )
     707             :             {
     708           0 :                 const SwStartNode *pBoxSttNd = pSttNd->FindTableBoxStartNode();
     709           0 :                 if( !pBoxSttNd ||
     710           0 :                     pBoxSttNd->GetIndex() < pSurrSectNd->GetIndex() )
     711             :                 {
     712           0 :                     pSurrSection = &pSurrSectNd->GetSection();
     713           0 :                     pSurrFmt = pSurrSection->GetFmt();
     714           0 :                     if( pSurrFmt )
     715             :                         pSurrCol = lcl_html_GetFmtCol( *pSurrSection,
     716           0 :                                                        *pSurrFmt );
     717             :                 }
     718             :             }
     719             :         }
     720             :     }
     721             : 
     722             :     // The surrounding section must be closed before the current one is
     723             :     // opended, except that it start immediately before the current one or
     724             :     // another end immediately before the current one
     725           0 :     if( pSurrCol && nSectSttIdx - pSurrSectNd->GetIndex() > 1 &&
     726           0 :         !lcl_html_IsMultiColEnd( rHTMLWrt, nSectSttIdx-1 ) )
     727           0 :         lcl_html_OutSectionEndTag( rHTMLWrt );
     728             : 
     729           0 :     if( bStartTag )
     730           0 :         lcl_html_OutSectionStartTag( rHTMLWrt, rSection, *pFmt, pCol );
     731             : 
     732             :     {
     733             :         HTMLSaveData aSaveData( rHTMLWrt,
     734           0 :             rHTMLWrt.pCurPam->GetPoint()->nNode.GetIndex()+1,
     735             :             rSectNd.EndOfSectionIndex(),
     736           0 :             false, pFmt );
     737           0 :         rHTMLWrt.Out_SwDoc( rHTMLWrt.pCurPam );
     738             :     }
     739             : 
     740           0 :     rHTMLWrt.pCurPam->GetPoint()->nNode = *rSectNd.EndOfSectionNode();
     741             : 
     742           0 :     if( bEndTag )
     743           0 :         lcl_html_OutSectionEndTag( rHTMLWrt );
     744             : 
     745             :     // The surrounding section must be started again, except that it ends
     746             :     // immeditaly behind the current one.
     747           0 :     if( pSurrCol &&
     748           0 :         pSurrSectNd->EndOfSectionIndex() - nSectEndIdx > 1 &&
     749           0 :         !lcl_html_IsMultiColStart( rHTMLWrt, nSectEndIdx+1 ) )
     750             :         lcl_html_OutSectionStartTag( rHTMLWrt, *pSurrSection, *pSurrFmt,
     751           0 :                                      pSurrCol, true );
     752             : 
     753           0 :     return rWrt;
     754             : }
     755             : 
     756         546 : void SwHTMLWriter::Out_SwDoc( SwPaM* pPam )
     757             : {
     758         546 :     bool bSaveWriteAll = bWriteAll;     // sichern
     759             : 
     760             :     // suche die naechste text::Bookmark-Position aus der text::Bookmark-Tabelle
     761         546 :     nBkmkTabPos = bWriteAll ? FindPos_Bkmk( *pCurPam->GetPoint() ) : -1;
     762             : 
     763             :     // gebe alle Bereiche des Pams in das HTML-File aus.
     764         546 :     do {
     765         546 :         bWriteAll = bSaveWriteAll;
     766         546 :         bFirstLine = true;
     767             : 
     768             :         // suche den ersten am Pam-auszugebenen FlyFrame
     769             :         // fehlt noch:
     770             : 
     771        3328 :         while( pCurPam->GetPoint()->nNode.GetIndex() < pCurPam->GetMark()->nNode.GetIndex() ||
     772        1614 :               (pCurPam->GetPoint()->nNode.GetIndex() == pCurPam->GetMark()->nNode.GetIndex() &&
     773         546 :                pCurPam->GetPoint()->nContent.GetIndex() <= pCurPam->GetMark()->nContent.GetIndex()) )
     774             :         {
     775         596 :             SwNode&  rNd = pCurPam->GetNode();
     776             : 
     777             :             OSL_ENSURE( !(rNd.IsGrfNode() || rNd.IsOLENode()),
     778             :                     "Grf- oder OLE-Node hier unerwartet" );
     779         596 :             if( rNd.IsTxtNode() )
     780             :             {
     781         570 :                 SwTxtNode* pTxtNd = rNd.GetTxtNode();
     782             : 
     783         570 :                 if( !bFirstLine )
     784          26 :                     pCurPam->GetPoint()->nContent.Assign( pTxtNd, 0 );
     785             : 
     786         570 :                 OutHTML_SwTxtNode( *this, *pTxtNd );
     787             :             }
     788          26 :             else if( rNd.IsTableNode() )
     789             :             {
     790           2 :                 OutHTML_SwTblNode( *this, *rNd.GetTableNode(), 0 );
     791           2 :                 nBkmkTabPos = bWriteAll ? FindPos_Bkmk( *pCurPam->GetPoint() ) : -1;
     792             :             }
     793          24 :             else if( rNd.IsSectionNode() )
     794             :             {
     795           0 :                 OutHTML_Section( *this, *rNd.GetSectionNode() );
     796           0 :                 nBkmkTabPos = bWriteAll ? FindPos_Bkmk( *pCurPam->GetPoint() ) : -1;
     797             :             }
     798          24 :             else if( &rNd == &pDoc->GetNodes().GetEndOfContent() )
     799          24 :                 break;
     800             : 
     801         572 :             pCurPam->GetPoint()->nNode++;   // Bewegen
     802         572 :             sal_uInt32 nPos = pCurPam->GetPoint()->nNode.GetIndex();
     803             : 
     804         572 :             if( bShowProgress )
     805         572 :                 ::SetProgressState( nPos, pDoc->GetDocShell() );   // Wie weit ?
     806             : 
     807             :             /* sollen nur die Selectierten Bereiche gesichert werden, so
     808             :              * duerfen nur die vollstaendigen Nodes gespeichert werde,
     809             :              * d.H. der 1. und n. Node teilweise, der 2. bis n-1. Node
     810             :              * vollstaendig. (vollstaendig heisst mit allen Formaten! )
     811             :              */
     812         572 :             bWriteAll = bSaveWriteAll ||
     813         572 :                         nPos != pCurPam->GetMark()->nNode.GetIndex();
     814         572 :             bFirstLine = false;
     815         572 :             bOutFooter = false; // Nach einem Node keine Fusszeile mehr
     816             :         }
     817             : 
     818         546 :         ChangeParaToken( 0 ); // MIB 8.7.97: Machen wir jetzt hier und nicht
     819             :                               // beim Aufrufer
     820         546 :         OutAndSetDefList( 0 );
     821             : 
     822         546 :     } while( CopyNextPam( &pPam ) );        // bis alle PaM's bearbeitet
     823             : 
     824         546 :     bWriteAll = bSaveWriteAll;          // wieder auf alten Wert zurueck
     825         546 : }
     826             : 
     827             : // schreibe die StyleTabelle, algemeine Angaben,Header/Footer/Footnotes
     828          66 : static void OutBodyColor( const sal_Char* pTag, const SwFmt *pFmt,
     829             :                           SwHTMLWriter& rHWrt )
     830             : {
     831          66 :     const SwFmt *pRefFmt = 0;
     832             : 
     833          66 :     if( rHWrt.pTemplate )
     834          66 :         pRefFmt = SwHTMLWriter::GetTemplateFmt( pFmt->GetPoolFmtId(),
     835         132 :                                                 &rHWrt.pTemplate->getIDocumentStylePoolAccess() );
     836             : 
     837          66 :     const SvxColorItem *pColorItem = 0;
     838             : 
     839          66 :     const SfxItemSet& rItemSet = pFmt->GetAttrSet();
     840          66 :     const SfxPoolItem *pRefItem = 0, *pItem = 0;
     841             :     bool bItemSet = SfxItemState::SET == rItemSet.GetItemState( RES_CHRATR_COLOR,
     842          66 :                                                            true, &pItem);
     843         132 :     bool bRefItemSet = pRefFmt &&
     844          66 :         SfxItemState::SET == pRefFmt->GetAttrSet().GetItemState( RES_CHRATR_COLOR,
     845         132 :                                                             true, &pRefItem);
     846          66 :     if( bItemSet )
     847             :     {
     848             :         // wenn das Item nur in der Vorlage des aktuellen Doks gesetzt
     849             :         // ist oder einen anderen Wert hat, als in der HTML-Vorlage,
     850             :         // wird es gesetzt
     851          52 :         const SvxColorItem *pCItem = (const SvxColorItem*)pItem;
     852             : 
     853          52 :         if( !bRefItemSet )
     854             :         {
     855           8 :             pColorItem = pCItem;
     856             :         }
     857             :         else
     858             :         {
     859          44 :             Color aColor( pCItem->GetValue() );
     860          44 :             if( COL_AUTO == aColor.GetColor() )
     861           0 :                 aColor.SetColor( COL_BLACK );
     862             : 
     863          44 :             Color aRefColor( ((const SvxColorItem*)pRefItem)->GetValue() );
     864          44 :             if( COL_AUTO == aRefColor.GetColor() )
     865           0 :                 aRefColor.SetColor( COL_BLACK );
     866             : 
     867          44 :             if( !aColor.IsRGBEqual( aRefColor ) )
     868           4 :                 pColorItem = pCItem;
     869             :         }
     870             :     }
     871          14 :     else if( bRefItemSet )
     872             :     {
     873             :         // Das Item war in der HTML-Vorlage noch gesetzt, also geben wir
     874             :         // das Default aus
     875           0 :         pColorItem = (const SvxColorItem*)&rItemSet.GetPool()
     876           0 :                                         ->GetDefaultItem( RES_CHRATR_COLOR );
     877             :     }
     878             : 
     879          66 :     if( pColorItem )
     880             :     {
     881          12 :         OStringBuffer sOut;
     882          12 :         sOut.append(" " + OString(pTag) + "=");
     883          12 :         rHWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
     884          12 :         Color aColor( pColorItem->GetValue() );
     885          12 :         if( COL_AUTO == aColor.GetColor() )
     886           4 :             aColor.SetColor( COL_BLACK );
     887          12 :         HTMLOutFuncs::Out_Color( rHWrt.Strm(), aColor, rHWrt.eDestEnc );
     888          12 :         if( RES_POOLCOLL_STANDARD==pFmt->GetPoolFmtId() )
     889           8 :             rHWrt.pDfltColor = new Color( aColor );
     890             :     }
     891          66 : }
     892             : 
     893          22 : sal_uInt16 SwHTMLWriter::OutHeaderAttrs()
     894             : {
     895          22 :     sal_uLong nIdx = pCurPam->GetPoint()->nNode.GetIndex();
     896          22 :     sal_uLong nEndIdx = pCurPam->GetMark()->nNode.GetIndex();
     897             : 
     898          22 :     SwTxtNode *pTxtNd = 0;
     899          74 :     while( nIdx<=nEndIdx &&
     900          26 :         0==(pTxtNd=pDoc->GetNodes()[nIdx]->GetTxtNode()) )
     901           4 :         nIdx++;
     902             : 
     903             :     OSL_ENSURE( pTxtNd, "Kein Text-Node gefunden" );
     904          22 :     if( !pTxtNd || !pTxtNd->HasHints() )
     905          14 :         return 0;
     906             : 
     907           8 :     sal_uInt16 nAttrs = 0;
     908           8 :     const size_t nCntAttr = pTxtNd->GetSwpHints().Count();
     909           8 :     sal_Int32 nOldPos = 0;
     910          20 :     for( size_t i=0; i<nCntAttr; ++i )
     911             :     {
     912          14 :         const SwTxtAttr *pHt = pTxtNd->GetSwpHints()[i];
     913          14 :         if( !pHt->End() )
     914             :         {
     915           2 :             sal_Int32 nPos = pHt->GetStart();
     916           4 :             if( nPos-nOldPos > 1
     917           4 :                 || ( pHt->Which() != RES_TXTATR_FIELD
     918           0 :                      && pHt->Which() != RES_TXTATR_ANNOTATION ) )
     919           2 :                 break;
     920             : 
     921             :             const sal_uInt16 nFldWhich =
     922           0 :                 ((const SwFmtFld&)pHt->GetAttr()).GetField()->GetTyp()->Which();
     923           0 :             if( RES_POSTITFLD!=nFldWhich &&
     924             :                 RES_SCRIPTFLD!=nFldWhich )
     925           0 :                 break;
     926             : 
     927           0 :             OutNewLine();
     928           0 :             OutHTML_SwFmtFld( *this, pHt->GetAttr() );
     929           0 :             nOldPos = nPos;
     930             :             OSL_ENSURE( nAttrs<SAL_MAX_UINT16, "Too many attributes" );
     931           0 :             nAttrs++;
     932             :         }
     933             :     }
     934             : 
     935           8 :     return nAttrs;
     936             : }
     937             : 
     938          24 : const SwPageDesc *SwHTMLWriter::MakeHeader( sal_uInt16 &rHeaderAttrs )
     939             : {
     940          24 :     OStringBuffer sOut;
     941          24 :     if (!mbSkipHeaderFooter)
     942             :     {
     943          22 :         sOut.append(OString(OOO_STRING_SVTOOLS_HTML_doctype) + " " + OString(OOO_STRING_SVTOOLS_HTML_doctype40));
     944          22 :         HTMLOutFuncs::Out_AsciiTag( Strm(), sOut.makeStringAndClear().getStr() );
     945             : 
     946             :         // baue den Vorspann
     947          22 :         OutNewLine();
     948          22 :         HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_html );
     949             : 
     950          22 :         OutNewLine();
     951          22 :         HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_head );
     952             : 
     953          22 :         IncIndentLevel();   // Inhalt von <HEAD> einruecken
     954             : 
     955             :         // DokumentInfo
     956          22 :         OString sIndent = GetIndentString();
     957             : 
     958          44 :         uno::Reference<document::XDocumentProperties> xDocProps;
     959          22 :         SwDocShell *pDocShell(pDoc->GetDocShell());
     960          22 :         if (pDocShell)
     961             :         {
     962             :             uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
     963          22 :                                                                        pDocShell->GetModel(), uno::UNO_QUERY_THROW);
     964          22 :             xDocProps.set(xDPS->getDocumentProperties());
     965             :         }
     966             : 
     967             :         // xDocProps may be null here (when copying)
     968          22 :         SfxFrameHTMLWriter::Out_DocInfo( Strm(), GetBaseURL(), xDocProps,
     969             :                                          sIndent.getStr(), eDestEnc,
     970          44 :                                          &aNonConvertableCharacters );
     971             : 
     972             :         // Kommentare und Meta-Tags des ersten Absatzes
     973          22 :         rHeaderAttrs = OutHeaderAttrs();
     974             : 
     975          44 :         OutFootEndNoteInfo();
     976             :     }
     977             : 
     978          24 :     const SwPageDesc *pPageDesc = 0;
     979             : 
     980             :     // In Nicht-HTML-Dokumenten wird die erste gesetzte Seitenvorlage
     981             :     // exportiert und wenn keine gesetzt ist die Standard-Vorlage
     982          24 :     sal_uLong nNodeIdx = pCurPam->GetPoint()->nNode.GetIndex();
     983             : 
     984          48 :     while( nNodeIdx < pDoc->GetNodes().Count() )
     985             :     {
     986          24 :         SwNode *pNd = pDoc->GetNodes()[ nNodeIdx ];
     987          24 :         if( pNd->IsCntntNode() )
     988             :         {
     989             :             pPageDesc = ((const SwFmtPageDesc &)pNd->GetCntntNode()
     990          22 :                 ->GetAttr(RES_PAGEDESC)).GetPageDesc();
     991          22 :             break;
     992             :         }
     993           2 :         else if( pNd->IsTableNode() )
     994             :         {
     995           2 :             pPageDesc = pNd->GetTableNode()->GetTable().GetFrmFmt()
     996           2 :                            ->GetPageDesc().GetPageDesc();
     997           2 :             break;
     998             :         }
     999             : 
    1000           0 :         nNodeIdx++;
    1001             :     }
    1002             : 
    1003          24 :     if( !pPageDesc )
    1004           6 :         pPageDesc = &pDoc->GetPageDesc( 0 );
    1005             : 
    1006          24 :     if (!mbSkipHeaderFooter)
    1007             :     {
    1008             :         // und nun ... das Style-Sheet!!!
    1009          22 :         if( bCfgOutStyles )
    1010             :         {
    1011          22 :             OutStyleSheet( *pPageDesc );
    1012             :         }
    1013             : 
    1014             :         // und nun ... das BASIC und JavaScript!
    1015          22 :         if( pDoc->GetDocShell() )   // nur mit DocShell ist Basic moeglich
    1016          22 :             OutBasic();
    1017             : 
    1018          22 :         DecIndentLevel();   // Inhalt von <HEAD> einruecken
    1019          22 :         OutNewLine();
    1020          22 :         HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_head, false );
    1021             : 
    1022             :         // der Body wird nicht eingerueckt, weil sonst alles eingerueckt waere!
    1023          22 :         OutNewLine();
    1024          22 :         sOut.append("<" + OString(OOO_STRING_SVTOOLS_HTML_body));
    1025          22 :         Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
    1026             : 
    1027             :         // language
    1028          22 :         OutLanguage( eLang );
    1029             : 
    1030             :         // Textfarbe ausgeben, wenn sie an der Standard-Vorlage gesetzt ist
    1031             :         // und sich geaendert hat.
    1032             :         OutBodyColor( OOO_STRING_SVTOOLS_HTML_O_text,
    1033          22 :                       pDoc->getIDocumentStylePoolAccess().GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false ),
    1034          22 :                       *this );
    1035             : 
    1036             :         // Farben fuer (un)besuchte Links
    1037             :         OutBodyColor( OOO_STRING_SVTOOLS_HTML_O_link,
    1038          22 :                       pDoc->getIDocumentStylePoolAccess().GetCharFmtFromPool( RES_POOLCHR_INET_NORMAL ),
    1039          22 :                       *this );
    1040             :         OutBodyColor( OOO_STRING_SVTOOLS_HTML_O_vlink,
    1041          22 :                       pDoc->getIDocumentStylePoolAccess().GetCharFmtFromPool( RES_POOLCHR_INET_VISIT ),
    1042          22 :                       *this );
    1043             : 
    1044          22 :         const SfxItemSet& rItemSet = pPageDesc->GetMaster().GetAttrSet();
    1045             : 
    1046          22 :         OutBackground( rItemSet, true );
    1047             : 
    1048          22 :         nDirection = GetHTMLDirection( rItemSet );
    1049          22 :         OutDirection( nDirection );
    1050             : 
    1051          22 :         if( bCfgOutStyles )
    1052          22 :             OutCSS1_BodyTagStyleOpt( *this, rItemSet );
    1053             : 
    1054             :         // Events anhaengen
    1055          22 :         if( pDoc->GetDocShell() )   // nur mit DocShell ist Basic moeglich
    1056          22 :             OutBasicBodyEvents();
    1057             : 
    1058          22 :         Strm().WriteChar( '>' );
    1059             :     }
    1060             : 
    1061          24 :     return pPageDesc;
    1062             : }
    1063             : 
    1064           8 : void SwHTMLWriter::OutAnchor( const OUString& rName )
    1065             : {
    1066           8 :     OStringBuffer sOut;
    1067           8 :     sOut.append("<" + OString(OOO_STRING_SVTOOLS_HTML_anchor) + " " + OString(OOO_STRING_SVTOOLS_HTML_O_name) + "=\"");
    1068           8 :     Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
    1069           8 :     HTMLOutFuncs::Out_String( Strm(), rName, eDestEnc, &aNonConvertableCharacters ).WriteCharPtr( "\">" );
    1070           8 :     HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_anchor, false );
    1071           8 : }
    1072             : 
    1073         570 : void SwHTMLWriter::OutBookmarks()
    1074             : {
    1075             :     // hole das aktuelle Bookmark
    1076         570 :     const ::sw::mark::IMark* pBookmark = NULL;
    1077         570 :     IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
    1078         570 :     if(nBkmkTabPos != -1)
    1079          12 :         pBookmark = (pMarkAccess->getAllMarksBegin() + nBkmkTabPos)->get();
    1080             :     // Ausgabe aller Bookmarks in diesem Absatz. Die Content-Position
    1081             :     // wird vorerst nicht beruecksichtigt!
    1082         570 :     sal_uInt32 nNode = pCurPam->GetPoint()->nNode.GetIndex();
    1083        1734 :     while( nBkmkTabPos != -1
    1084         582 :            && pBookmark->GetMarkPos().nNode.GetIndex() == nNode )
    1085             :     {
    1086             :         // Der Bereich derBookmark wird erstam ignoriert, da er von uns
    1087             :         // auch nicht eingelesen wird.
    1088             : 
    1089             :         // erst die SWG spezifischen Daten:
    1090          12 :         if ( dynamic_cast< const ::sw::mark::IBookmark* >(pBookmark) && !pBookmark->GetName().isEmpty() )
    1091             :         {
    1092           8 :             OutAnchor( pBookmark->GetName() );
    1093             :         }
    1094             : 
    1095          12 :         if( ++nBkmkTabPos >= pMarkAccess->getAllMarksCount() )
    1096           2 :             nBkmkTabPos = -1;
    1097             :         else
    1098          10 :             pBookmark = (pMarkAccess->getAllMarksBegin() + nBkmkTabPos)->get();
    1099             :     }
    1100             : 
    1101             :     sal_uInt32 nPos;
    1102         570 :     for( nPos = 0; nPos < aOutlineMarkPoss.size() &&
    1103           0 :                    aOutlineMarkPoss[nPos] < nNode; nPos++ )
    1104             :         ;
    1105             : 
    1106        1140 :     while( nPos < aOutlineMarkPoss.size() && aOutlineMarkPoss[nPos] == nNode )
    1107             :     {
    1108           0 :         OUString sMark( aOutlineMarks[nPos] );
    1109           0 :         OutAnchor( sMark.replace('?', '_') ); // '?' causes problems in IE/Netscape 5
    1110           0 :         aOutlineMarkPoss.erase( aOutlineMarkPoss.begin()+nPos );
    1111           0 :         aOutlineMarks.erase( aOutlineMarks.begin() + nPos );
    1112           0 :     }
    1113         570 : }
    1114             : 
    1115           4 : void SwHTMLWriter::OutPointFieldmarks( const SwPosition& rPos )
    1116             : {
    1117             :     // "point" fieldmarks that occupy single character space, as opposed to
    1118             :     // range fieldmarks that are associated with start and end points.
    1119             : 
    1120           4 :     const IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
    1121           4 :     if (!pMarkAccess)
    1122           0 :         return;
    1123             : 
    1124           4 :     const sw::mark::IFieldmark* pMark = pMarkAccess->getFieldmarkFor(rPos);
    1125           4 :     if (!pMark)
    1126           0 :         return;
    1127             : 
    1128           4 :     if (pMark->GetFieldname() == ODF_FORMCHECKBOX)
    1129             :     {
    1130             :         const sw::mark::ICheckboxFieldmark* pCheckBox =
    1131           4 :             dynamic_cast<const sw::mark::ICheckboxFieldmark*>(pMark);
    1132             : 
    1133           4 :         if (pCheckBox)
    1134             :         {
    1135           4 :             OString aOut("<");
    1136           4 :             aOut += OOO_STRING_SVTOOLS_HTML_input;
    1137           4 :             aOut += " ";
    1138           4 :             aOut += OOO_STRING_SVTOOLS_HTML_O_type;
    1139           4 :             aOut += "=\"";
    1140           4 :             aOut += OOO_STRING_SVTOOLS_HTML_IT_checkbox;
    1141           4 :             aOut += "\"";
    1142             : 
    1143           4 :             if (pCheckBox->IsChecked())
    1144             :             {
    1145           2 :                 aOut += " ";
    1146           2 :                 aOut += OOO_STRING_SVTOOLS_HTML_O_checked;
    1147           2 :                 aOut += "=\"";
    1148           2 :                 aOut += OOO_STRING_SVTOOLS_HTML_O_checked;
    1149           2 :                 aOut += "\"";
    1150             :             }
    1151             : 
    1152           4 :             aOut += "/>";
    1153           4 :             Strm().WriteCharPtr(aOut.getStr());
    1154             :         }
    1155             :     }
    1156             : 
    1157             :     // TODO : Handle other single-point fieldmark types here (if any).
    1158             : }
    1159             : 
    1160           8 : void SwHTMLWriter::OutImplicitMark( const OUString& rMark,
    1161             :                                     const sal_Char *pMarkType )
    1162             : {
    1163           8 :     if( !rMark.isEmpty() && !aImplicitMarks.empty() )
    1164             :     {
    1165           0 :         OUString sMark( rMark );
    1166           0 :         sMark + OUString(cMarkSeparator) + OUString::createFromAscii(pMarkType);
    1167           0 :         if( 0 != aImplicitMarks.erase( sMark ) )
    1168             :         {
    1169           0 :             OutAnchor(sMark.replace('?', '_')); // '?' causes problems in IE/Netscape 5
    1170           0 :         }
    1171             :     }
    1172           8 : }
    1173             : 
    1174           4 : OUString SwHTMLWriter::convertHyperlinkHRefValue(const OUString& rURL)
    1175             : {
    1176           4 :     OUString sURL(rURL);
    1177           4 :     sal_Int32 nPos = sURL.lastIndexOf(cMarkSeparator);
    1178           4 :     if (nPos != -1)
    1179             :     {
    1180           0 :         OUString sCompare(comphelper::string::remove(sURL.copy(nPos + 1), ' '));
    1181           0 :         if (!sCompare.isEmpty())
    1182             :         {
    1183           0 :             sCompare = sCompare.toAsciiLowerCase();
    1184           0 :             if( sCompare == "region"  || sCompare == "frame"   ||
    1185           0 :                 sCompare == "graphic" || sCompare == "ole"     ||
    1186           0 :                 sCompare == "table"   || sCompare == "outline" ||
    1187           0 :                 sCompare == "text" )
    1188             :             {
    1189           0 :                 sURL = sURL.replace( '?', '_' );   // '?' causes problems in IE/Netscape 5
    1190             :             }
    1191           0 :         }
    1192             :     }
    1193           4 :     return URIHelper::simpleNormalizedMakeRelative(GetBaseURL(), sURL);
    1194             : }
    1195             : 
    1196           0 : void SwHTMLWriter::OutHyperlinkHRefValue( const OUString& rURL )
    1197             : {
    1198           0 :     OUString sURL = convertHyperlinkHRefValue(rURL);
    1199           0 :     HTMLOutFuncs::Out_String( Strm(), sURL, eDestEnc, &aNonConvertableCharacters );
    1200           0 : }
    1201             : 
    1202         522 : void SwHTMLWriter::OutBackground( const SvxBrushItem *pBrushItem, bool bGraphic )
    1203             : {
    1204         522 :     const Color &rBackColor = pBrushItem->GetColor();
    1205             :     /// check, if background color is not "no fill"/"auto fill", instead of
    1206             :     /// only checking, if transparency is not set.
    1207         522 :     if( rBackColor.GetColor() != COL_TRANSPARENT )
    1208             :     {
    1209         522 :         OStringBuffer sOut;
    1210         522 :         sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_bgcolor).append('=');
    1211         522 :         Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
    1212         522 :         HTMLOutFuncs::Out_Color( Strm(), rBackColor, eDestEnc);
    1213             :     }
    1214             : 
    1215         522 :     if( !bGraphic )
    1216        1044 :         return;
    1217             : 
    1218           0 :     OUString aGraphicInBase64;
    1219           0 :     const Graphic* pGrf = pBrushItem->GetGraphic();
    1220           0 :     if( pGrf )
    1221             :     {
    1222           0 :         sal_uLong nErr = XOutBitmap::GraphicToBase64(*pGrf, aGraphicInBase64);
    1223           0 :         if( nErr )
    1224             :         {
    1225           0 :             nWarn = WARN_SWG_POOR_LOAD | WARN_SW_WRITE_BASE;
    1226             :         }
    1227           0 :         Strm().WriteCharPtr( " " OOO_STRING_SVTOOLS_HTML_O_background "=\"" );
    1228           0 :         Strm().WriteCharPtr( OOO_STRING_SVTOOLS_HTML_O_data ":" );
    1229           0 :         HTMLOutFuncs::Out_String( Strm(), aGraphicInBase64, eDestEnc, &aNonConvertableCharacters ).WriteChar( '\"' );
    1230           0 :     }
    1231             : }
    1232             : 
    1233          24 : void SwHTMLWriter::OutBackground( const SfxItemSet& rItemSet, bool bGraphic )
    1234             : {
    1235             :     const SfxPoolItem* pItem;
    1236          24 :     if( SfxItemState::SET == rItemSet.GetItemState( RES_BACKGROUND, false,
    1237          24 :                                                &pItem ))
    1238             :     {
    1239           2 :         OutBackground( ((const SvxBrushItem*)pItem), bGraphic );
    1240             :     }
    1241          24 : }
    1242             : 
    1243         622 : sal_uInt16 SwHTMLWriter::GetLangWhichIdFromScript( sal_uInt16 nScript )
    1244             : {
    1245             :     sal_uInt16 nWhichId;
    1246         622 :     switch( nScript )
    1247             :     {
    1248             :     case CSS1_OUTMODE_CJK:
    1249           0 :         nWhichId = RES_CHRATR_CJK_LANGUAGE;
    1250           0 :         break;
    1251             :     case CSS1_OUTMODE_CTL:
    1252           0 :         nWhichId = RES_CHRATR_CJK_LANGUAGE;
    1253           0 :         break;
    1254             :     default:
    1255         622 :         nWhichId = RES_CHRATR_LANGUAGE;
    1256         622 :         break;
    1257             :     }
    1258         622 :     return nWhichId;
    1259             : }
    1260             : 
    1261         550 : void SwHTMLWriter::OutLanguage( LanguageType nLang )
    1262             : {
    1263         550 :     if( LANGUAGE_DONTKNOW != nLang )
    1264             :     {
    1265         550 :         OStringBuffer sOut;
    1266         550 :         sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_lang)
    1267         550 :             .append("=\"");
    1268         550 :         Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
    1269         550 :         HTMLOutFuncs::Out_String( Strm(), LanguageTag::convertToBcp47(nLang),
    1270        1100 :                                   eDestEnc, &aNonConvertableCharacters ).WriteChar( '"' );
    1271             :     }
    1272         550 : }
    1273             : 
    1274          24 : sal_uInt16 SwHTMLWriter::GetHTMLDirection( const SfxItemSet& rItemSet ) const
    1275             : {
    1276             :     return GetHTMLDirection(
    1277          24 :         static_cast < const SvxFrameDirectionItem& >( rItemSet.Get( RES_FRAMEDIR ) )
    1278          24 :             .GetValue() );
    1279             : }
    1280             : 
    1281         594 : sal_uInt16 SwHTMLWriter::GetHTMLDirection( sal_uInt16 nDir ) const
    1282             : {
    1283         594 :     switch( nDir )
    1284             :     {
    1285             :     case FRMDIR_VERT_TOP_LEFT:
    1286           0 :         nDir = FRMDIR_HORI_LEFT_TOP;
    1287           0 :         break;
    1288             :     case FRMDIR_VERT_TOP_RIGHT:
    1289           0 :         nDir = FRMDIR_HORI_RIGHT_TOP;
    1290           0 :         break;
    1291             :     case FRMDIR_ENVIRONMENT:
    1292          12 :         nDir = nDirection;
    1293             :     }
    1294             : 
    1295         594 :     return nDir;
    1296             : }
    1297             : 
    1298          22 : void SwHTMLWriter::OutDirection( sal_uInt16 nDir )
    1299             : {
    1300          22 :     OString sConverted = convertDirection(nDir);
    1301          22 :     if (!sConverted.isEmpty())
    1302             :     {
    1303          22 :         OStringBuffer sOut;
    1304          22 :         sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_dir)
    1305          22 :             .append("=\"").append(sConverted).append('\"');
    1306          22 :         Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
    1307          22 :     }
    1308          22 : }
    1309             : 
    1310          22 : OString SwHTMLWriter::convertDirection(sal_uInt16 nDir)
    1311             : {
    1312          22 :     OString sConverted;
    1313          22 :     switch (nDir)
    1314             :     {
    1315             :     case FRMDIR_HORI_LEFT_TOP:
    1316             :     case FRMDIR_VERT_TOP_LEFT:
    1317          22 :         sConverted = "ltr";
    1318          22 :         break;
    1319             :     case FRMDIR_HORI_RIGHT_TOP:
    1320             :     case FRMDIR_VERT_TOP_RIGHT:
    1321           0 :         sConverted = "rtl";
    1322           0 :         break;
    1323             :     }
    1324          22 :     return sConverted;
    1325             : }
    1326             : 
    1327          26 : OString SwHTMLWriter::GetIndentString(sal_uInt16 nIncLvl)
    1328             : {
    1329          26 :     OString sRet;
    1330             : 
    1331             :     // etwas umstaendlich, aber wir haben nur einen Indent-String!
    1332          26 :     sal_uInt16 nLevel = nIndentLvl + nIncLvl;
    1333             : 
    1334          26 :     if( nLevel && nLevel <= MAX_INDENT_LEVEL)
    1335             :     {
    1336          24 :         sIndentTabs[nLevel] = 0;
    1337          24 :         sRet = sIndentTabs;
    1338          24 :         sIndentTabs[nLevel] = '\t';
    1339             :     }
    1340             : 
    1341          26 :     return sRet;
    1342             : }
    1343             : 
    1344        2664 : void SwHTMLWriter::OutNewLine( bool bCheck )
    1345             : {
    1346        2664 :     if( !bCheck || (Strm().Tell()-nLastLFPos) > nIndentLvl )
    1347             :     {
    1348        2664 :         Strm().WriteCharPtr( SAL_NEWLINE_STRING );
    1349        2664 :         nLastLFPos = Strm().Tell();
    1350             :     }
    1351             : 
    1352        2664 :     if( nIndentLvl && nIndentLvl <= MAX_INDENT_LEVEL)
    1353             :     {
    1354        2446 :         sIndentTabs[nIndentLvl] = 0;
    1355        2446 :         Strm().WriteCharPtr( sIndentTabs );
    1356        2446 :         sIndentTabs[nIndentLvl] = '\t';
    1357             :     }
    1358        2664 : }
    1359             : 
    1360          10 : sal_uInt16 SwHTMLWriter::GetHTMLFontSize( sal_uInt32 nHeight ) const
    1361             : {
    1362          10 :     sal_uInt16 nSize = 1;
    1363          40 :     for( sal_uInt16 i=6; i>0; i-- )
    1364             :     {
    1365          40 :         if( nHeight > (aFontHeights[i] + aFontHeights[i-1])/2 )
    1366             :         {
    1367          10 :             nSize = i+1;
    1368          10 :             break;
    1369             :         }
    1370             :     }
    1371             : 
    1372          10 :     return nSize;
    1373             : }
    1374             : 
    1375             : // Struktur speichert die aktuellen Daten des Writers zwischen, um
    1376             : // einen anderen Dokument-Teil auszugeben, wie z.B. Header/Footer
    1377         522 : HTMLSaveData::HTMLSaveData(SwHTMLWriter& rWriter, sal_uLong nStt,
    1378             :                            sal_uLong nEnd, bool bSaveNum,
    1379             :                            const SwFrmFmt *pFrmFmt)
    1380             :     : rWrt(rWriter)
    1381             :     , pOldPam(rWrt.pCurPam)
    1382         522 :     , pOldEnd(rWrt.GetEndPaM())
    1383             :     , pOldNumRuleInfo(0)
    1384             :     , pOldNextNumRuleInfo(0)
    1385             :     , nOldDefListLvl(rWrt.nDefListLvl)
    1386             :     , nOldDirection(rWrt.nDirection)
    1387             :     , bOldOutHeader(rWrt.bOutHeader)
    1388             :     , bOldOutFooter(rWrt.bOutFooter)
    1389             :     , bOldOutFlyFrame(rWrt.bOutFlyFrame)
    1390        1044 :     , pOldFlyFmt(NULL)
    1391             : {
    1392         522 :     bOldWriteAll = rWrt.bWriteAll;
    1393             : 
    1394         522 :     rWrt.pCurPam = Writer::NewSwPaM( *rWrt.pDoc, nStt, nEnd );
    1395             : 
    1396             :     // Tabelle in Sonderbereichen erkennen
    1397         522 :     if( nStt != rWrt.pCurPam->GetMark()->nNode.GetIndex() )
    1398             :     {
    1399           0 :         const SwNode *pNd = rWrt.pDoc->GetNodes()[ nStt ];
    1400           0 :         if( pNd->IsTableNode() || pNd->IsSectionNode() )
    1401           0 :             rWrt.pCurPam->GetMark()->nNode = nStt;
    1402             :     }
    1403             : 
    1404         522 :     rWrt.SetEndPaM( rWrt.pCurPam );
    1405         522 :     rWrt.pCurPam->Exchange( );
    1406         522 :     rWrt.bWriteAll = true;
    1407         522 :     rWrt.nDefListLvl = 0;
    1408         522 :     rWrt.bOutHeader = rWrt.bOutFooter = false;
    1409             : 
    1410             :     // Ggf. die aktuelle Numerierungs-Info merken, damit sie wieder
    1411             :     // neu aufgenommen werden kann. Nur dann belibt auch die Numerierungs-
    1412             :     // Info des nachsten Absatz gueltig.
    1413         522 :     if( bSaveNum )
    1414             :     {
    1415         522 :         pOldNumRuleInfo = new SwHTMLNumRuleInfo( rWrt.GetNumInfo() );
    1416         522 :         pOldNextNumRuleInfo = rWrt.GetNextNumInfo();
    1417         522 :         rWrt.SetNextNumInfo( 0 );
    1418             :     }
    1419             :     else
    1420             :     {
    1421           0 :         rWrt.ClearNextNumInfo();
    1422             :     }
    1423             : 
    1424             :     // Die Numerierung wird in jedem Fall unterbrochen.
    1425         522 :     rWrt.GetNumInfo().Clear();
    1426             : 
    1427         522 :     if( pFrmFmt )
    1428           0 :         rWrt.nDirection = rWrt.GetHTMLDirection( pFrmFmt->GetAttrSet() );
    1429         522 : }
    1430             : 
    1431         522 : HTMLSaveData::~HTMLSaveData()
    1432             : {
    1433         522 :     delete rWrt.pCurPam;                    // Pam wieder loeschen
    1434             : 
    1435         522 :     rWrt.pCurPam = pOldPam;
    1436         522 :     rWrt.SetEndPaM( pOldEnd );
    1437         522 :     rWrt.bWriteAll = bOldWriteAll;
    1438         522 :     rWrt.nBkmkTabPos = bOldWriteAll ? rWrt.FindPos_Bkmk( *pOldPam->GetPoint() ) : -1;
    1439         522 :     rWrt.nLastParaToken = 0;
    1440         522 :     rWrt.nDefListLvl = nOldDefListLvl;
    1441         522 :     rWrt.nDirection = nOldDirection;
    1442         522 :     rWrt.bOutHeader = bOldOutHeader;
    1443         522 :     rWrt.bOutFooter = bOldOutFooter;
    1444         522 :     rWrt.bOutFlyFrame = bOldOutFlyFrame;
    1445             : 
    1446             :     // Ggf. die Numerierung von vor der Section fortsetzen. Die Numerierung
    1447             :     // des naecshten Absatz wird in jedem Fall ungueltig.
    1448         522 :     if( pOldNumRuleInfo )
    1449             :     {
    1450         522 :         rWrt.GetNumInfo().Set( *pOldNumRuleInfo );
    1451         522 :         delete pOldNumRuleInfo;
    1452         522 :         rWrt.SetNextNumInfo( pOldNextNumRuleInfo );
    1453             :     }
    1454             :     else
    1455             :     {
    1456           0 :         rWrt.GetNumInfo().Clear();
    1457           0 :         rWrt.ClearNextNumInfo();
    1458             :     }
    1459         522 : }
    1460             : 
    1461          24 : void GetHTMLWriter( const OUString&, const OUString& rBaseURL, WriterRef& xRet )
    1462             : {
    1463          24 :     xRet = new SwHTMLWriter( rBaseURL );
    1464         294 : }
    1465             : 
    1466             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10