summaryrefslogtreecommitdiff
path: root/sc/source/filter/html/htmlexp.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/filter/html/htmlexp.cxx')
-rw-r--r--sc/source/filter/html/htmlexp.cxx1343
1 files changed, 1343 insertions, 0 deletions
diff --git a/sc/source/filter/html/htmlexp.cxx b/sc/source/filter/html/htmlexp.cxx
new file mode 100644
index 000000000000..0ab97170621e
--- /dev/null
+++ b/sc/source/filter/html/htmlexp.cxx
@@ -0,0 +1,1343 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#define _SVSTDARR_STRINGSSORTDTOR
+#include <rtl/tencinfo.h>
+
+#include <vcl/svapp.hxx>
+#include <svx/algitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <svx/xoutbmp.hxx>
+#include <editeng/editeng.hxx>
+#include <svtools/htmlcfg.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/frmhtmlw.hxx>
+#include <sfx2/objsh.hxx>
+#include <svl/stritem.hxx>
+#include <svl/urihelper.hxx>
+#ifndef _SVSTDARR_USHORTS
+#define _SVSTDARR_USHORTS
+#endif
+#include <svl/svstdarr.hxx>
+#include <svl/zforlist.hxx>
+#include <svtools/htmlkywd.hxx>
+#include <svtools/htmlout.hxx>
+#include <svtools/parhtml.hxx>
+#include <vcl/outdev.hxx>
+#include <stdio.h>
+
+#include "htmlexp.hxx"
+#include "filter.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "scitems.hxx"
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "stlpool.hxx"
+#include "scresid.hxx"
+#include "cell.hxx"
+#include "cellform.hxx"
+#include "docoptio.hxx"
+#include "editutil.hxx"
+#include "ftools.hxx"
+
+
+#include <editeng/flditem.hxx>
+#include <editeng/borderline.hxx>
+#include <unotools/syslocale.hxx>
+
+
+// ohne sc.hrc: error C2679: binary '=' : no operator defined which takes a
+// right-hand operand of type 'const class String (__stdcall *)(class ScResId)'
+// bei
+// const String aStrTable( ScResId( SCSTR_TABLE ) ); aStrOut = aStrTable;
+// ?!???
+#include "sc.hrc"
+#include "globstr.hrc"
+
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+
+
+//========================================================================
+
+const static sal_Char __FAR_DATA sMyBegComment[] = "<!-- ";
+const static sal_Char __FAR_DATA sMyEndComment[] = " -->";
+const static sal_Char __FAR_DATA sFontFamily[] = "font-family:";
+const static sal_Char __FAR_DATA sFontSize[] = "font-size:";
+
+const USHORT __FAR_DATA ScHTMLExport::nDefaultFontSize[SC_HTML_FONTSIZES] =
+{
+ HTMLFONTSZ1_DFLT, HTMLFONTSZ2_DFLT, HTMLFONTSZ3_DFLT, HTMLFONTSZ4_DFLT,
+ HTMLFONTSZ5_DFLT, HTMLFONTSZ6_DFLT, HTMLFONTSZ7_DFLT
+};
+
+USHORT ScHTMLExport::nFontSize[SC_HTML_FONTSIZES] = { 0 };
+
+const char* __FAR_DATA ScHTMLExport::pFontSizeCss[SC_HTML_FONTSIZES] =
+{
+ "xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large"
+};
+
+const USHORT ScHTMLExport::nCellSpacing = 0;
+const sal_Char __FAR_DATA ScHTMLExport::sIndentSource[nIndentMax+1] =
+ "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
+
+//========================================================================
+// Makros fuer HTML-Export
+//========================================================================
+#define OUT_PROLOGUE() (rStrm << sHTML30_Prologue << ScExportBase::sNewLine \
+ << ScExportBase::sNewLine)
+#define TAG_ON( tag ) HTMLOutFuncs::Out_AsciiTag( rStrm, tag )
+#define TAG_OFF( tag ) HTMLOutFuncs::Out_AsciiTag( rStrm, tag, FALSE )
+#define OUT_STR( str ) HTMLOutFuncs::Out_String( rStrm, str, eDestEnc, &aNonConvertibleChars )
+#define OUT_STR_NO_CONV( str ) HTMLOutFuncs::Out_String( rStrm, str, eDestEnc )
+#define OUT_LF() rStrm << ScExportBase::sNewLine << GetIndentStr()
+#define lcl_OUT_LF() rStrm << ScExportBase::sNewLine
+#define TAG_ON_LF( tag ) (TAG_ON( tag ) << ScExportBase::sNewLine << GetIndentStr())
+#define TAG_OFF_LF( tag ) (TAG_OFF( tag ) << ScExportBase::sNewLine << GetIndentStr())
+#define OUT_HR() TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_horzrule )
+#define OUT_COMMENT( comment ) (rStrm << sMyBegComment, OUT_STR( comment ) \
+ << sMyEndComment << ScExportBase::sNewLine \
+ << GetIndentStr())
+#define lcl_OUT_COMMENT( comment ) (rStrm << sMyBegComment, OUT_STR_NO_CONV( comment ) \
+ << sMyEndComment << ScExportBase::sNewLine)
+
+#define OUT_SP_CSTR_ASS( s ) rStrm << ' ' << s << '='
+#define APPEND_SPACE( s ) s.AppendAscii(" ")
+
+#define GLOBSTR(id) ScGlobal::GetRscString( id )
+
+
+
+//========================================================================
+
+FltError ScFormatFilterPluginImpl::ScExportHTML( SvStream& rStrm, const String& rBaseURL, ScDocument* pDoc,
+ const ScRange& rRange, const CharSet /*eNach*/, BOOL bAll,
+ const String& rStreamPath, String& rNonConvertibleChars )
+{
+ ScHTMLExport aEx( rStrm, rBaseURL, pDoc, rRange, bAll, rStreamPath );
+ FltError nErr = aEx.Write();
+ rNonConvertibleChars = aEx.GetNonConvertibleChars();
+ return nErr;
+}
+
+
+void lcl_AddStamp( String& rStr, const String& rName,
+ const ::com::sun::star::util::DateTime& rDateTime,
+ const LocaleDataWrapper& rLoc )
+{
+ Date aD(rDateTime.Day, rDateTime.Month, rDateTime.Year);
+ Time aT(rDateTime.Hours, rDateTime.Minutes, rDateTime.Seconds,
+ rDateTime.HundredthSeconds);
+ DateTime aDateTime(aD,aT);
+
+ String aStrDate = rLoc.getDate( aDateTime );
+ String aStrTime = rLoc.getTime( aDateTime );
+
+ rStr += GLOBSTR( STR_BY );
+ APPEND_SPACE( rStr );
+ if (rName.Len())
+ rStr += rName;
+ else
+ rStr.AppendAscii( "???" );
+ APPEND_SPACE( rStr );
+ rStr += GLOBSTR( STR_ON );
+ APPEND_SPACE( rStr );
+ if (aStrDate.Len())
+ rStr += aStrDate;
+ else
+ rStr.AppendAscii( "???" );
+ rStr.AppendAscii( ", " );
+ if (aStrTime.Len())
+ rStr += aStrTime;
+ else
+ rStr.AppendAscii( "???" );
+}
+
+
+void lcl_AppendHTMLColorTripel( ByteString& rStr, const Color& rColor )
+{
+ // <font COLOR="#00FF40">hallo</font>
+ sal_Char buf[64];
+ sal_Char* p = buf;
+
+ rStr += "\"#";
+ p += sprintf( p, "%02X", rColor.GetRed() ); // #100211# - checked
+ p += sprintf( p, "%02X", rColor.GetGreen() ); // #100211# - checked
+ p += sprintf( p, "%02X", rColor.GetBlue() ); // #100211# - checked
+ rStr += buf;
+ rStr += '\"';
+}
+
+
+/*void lcl_TagOn( String& rResult, const String& rTag, const String* pStrOpt )
+{
+ rResult = '<';
+ rResult += rTag;
+ if ( pStrOpt )
+ {
+ rResult += ' ';
+ rResult += *pStrOpt;
+ }
+ rResult += '>';
+}
+*/
+
+/*void lcl_TagOff( String& rResult, const String& rTag )
+{
+ rResult = '<'; rResult += rTag; rResult += '>';
+}
+*/
+
+//////////////////////////////////////////////////////////////////////////////
+
+ScHTMLExport::ScHTMLExport( SvStream& rStrmP, const String& rBaseURL, ScDocument* pDocP,
+ const ScRange& rRangeP,
+ BOOL bAllP, const String& rStreamPathP ) :
+ ScExportBase( rStrmP, pDocP, rRangeP ),
+ aBaseURL( rBaseURL ),
+ aStreamPath( rStreamPathP ),
+ pAppWin( Application::GetDefaultDevice() ),
+ pSrcArr( NULL ),
+ pDestArr( NULL ),
+ nUsedTables( 0 ),
+ nIndent( 0 ),
+ bAll( bAllP ),
+ bTabHasGraphics( FALSE ),
+ bCalcAsShown( pDocP->GetDocOptions().IsCalcAsShown() ),
+ bTableDataWidth( TRUE ),
+ bTableDataHeight( TRUE )
+{
+ strcpy( sIndent, sIndentSource ); // #100211# - checked
+ sIndent[0] = 0;
+
+ // set HTML configuration
+ SvxHtmlOptions* pHtmlOptions = SvxHtmlOptions::Get();
+ eDestEnc = (pDoc->IsClipOrUndo() ? RTL_TEXTENCODING_UTF8 : pHtmlOptions->GetTextEncoding());
+ bCopyLocalFileToINet = pHtmlOptions->IsSaveGraphicsLocal();
+ for ( USHORT j=0; j < SC_HTML_FONTSIZES; j++ )
+ {
+ USHORT nSize = pHtmlOptions->GetFontSize( j );
+ // remember in Twips, like our SvxFontHeightItem
+ if ( nSize )
+ nFontSize[j] = nSize * 20;
+ else
+ nFontSize[j] = nDefaultFontSize[j] * 20;
+ }
+
+ const SCTAB nCount = pDoc->GetTableCount();
+ for ( SCTAB nTab = 0; nTab < nCount; nTab++ )
+ {
+ if ( !IsEmptyTable( nTab ) )
+ nUsedTables++;
+ }
+
+ // Content-Id fuer Mail-Export?
+ SfxObjectShell* pDocSh = pDoc->GetDocumentShell();
+ if ( pDocSh )
+ {
+ const SfxPoolItem* pItem = pDocSh->GetItem( SID_ORIGURL );
+ if( pItem )
+ {
+ aCId = ((const SfxStringItem *)pItem)->GetValue();
+ DBG_ASSERT( aCId.Len(), "CID ohne Laenge!" );
+ }
+ }
+}
+
+
+ScHTMLExport::~ScHTMLExport()
+{
+ for ( ScHTMLGraphEntry* pE = aGraphList.First(); pE; pE = aGraphList.Next() )
+ delete pE;
+ delete pSrcArr;
+ delete pDestArr;
+}
+
+
+USHORT ScHTMLExport::GetFontSizeNumber( USHORT nHeight )
+{
+ USHORT nSize = 1;
+ for ( USHORT j=SC_HTML_FONTSIZES-1; j>0; j-- )
+ {
+ if( nHeight > (nFontSize[j] + nFontSize[j-1]) / 2 )
+ { // der naechstgelegene
+ nSize = j+1;
+ break;
+ }
+ }
+ return nSize;
+}
+
+const char* ScHTMLExport::GetFontSizeCss( USHORT nHeight )
+{
+ USHORT nSize = GetFontSizeNumber( nHeight );
+ return pFontSizeCss[ nSize-1 ];
+}
+
+
+USHORT ScHTMLExport::ToPixel( USHORT nVal )
+{
+ if( nVal )
+ {
+ nVal = (USHORT)pAppWin->LogicToPixel(
+ Size( nVal, nVal ), MapMode( MAP_TWIP ) ).Width();
+ if( !nVal ) // wo ein Twip ist sollte auch ein Pixel sein
+ nVal = 1;
+ }
+ return nVal;
+}
+
+
+Size ScHTMLExport::MMToPixel( const Size& rSize )
+{
+ Size aSize( rSize );
+ aSize = pAppWin->LogicToPixel( rSize, MapMode( MAP_100TH_MM ) );
+ // wo etwas ist sollte auch ein Pixel sein
+ if ( !aSize.Width() && rSize.Width() )
+ aSize.Width() = 1;
+ if ( !aSize.Height() && rSize.Height() )
+ aSize.Height() = 1;
+ return aSize;
+}
+
+
+ULONG ScHTMLExport::Write()
+{
+ rStrm << '<' << OOO_STRING_SVTOOLS_HTML_doctype << ' ' << OOO_STRING_SVTOOLS_HTML_doctype32 << '>'
+ << sNewLine << sNewLine;
+ TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_html );
+ WriteHeader();
+ OUT_LF();
+ WriteBody();
+ OUT_LF();
+ TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_html );
+
+ return rStrm.GetError();
+}
+
+
+void ScHTMLExport::WriteHeader()
+{
+ IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_head );
+
+ if ( pDoc->IsClipOrUndo() )
+ { // no real DocInfo available, but some META information like charset needed
+ SfxFrameHTMLWriter::Out_DocInfo( rStrm, aBaseURL, NULL, sIndent, eDestEnc, &aNonConvertibleChars );
+ }
+ else
+ {
+ using namespace ::com::sun::star;
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ pDoc->GetDocumentShell()->GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> xDocProps
+ = xDPS->getDocumentProperties();
+ SfxFrameHTMLWriter::Out_DocInfo( rStrm, aBaseURL, xDocProps,
+ sIndent, eDestEnc, &aNonConvertibleChars );
+ OUT_LF();
+
+ //----------------------------------------------------------
+ if (!xDocProps->getPrintedBy().equalsAscii(""))
+ {
+ OUT_COMMENT( GLOBSTR( STR_DOC_INFO ) );
+ String aStrOut( GLOBSTR( STR_DOC_PRINTED ) );
+ aStrOut.AppendAscii( ": " );
+ lcl_AddStamp( aStrOut, xDocProps->getPrintedBy(),
+ xDocProps->getPrintDate(), *ScGlobal::pLocaleData );
+ OUT_COMMENT( aStrOut );
+ }
+ //----------------------------------------------------------
+ }
+ OUT_LF();
+
+ // CSS1 StyleSheet
+ PageDefaults( bAll ? 0 : aRange.aStart.Tab() );
+ IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_style );
+ rStrm << sMyBegComment; OUT_LF();
+ rStrm << OOO_STRING_SVTOOLS_HTML_body << "," << OOO_STRING_SVTOOLS_HTML_division << "," << OOO_STRING_SVTOOLS_HTML_table << ","
+ << OOO_STRING_SVTOOLS_HTML_thead << "," << OOO_STRING_SVTOOLS_HTML_tbody << "," << OOO_STRING_SVTOOLS_HTML_tfoot << ","
+ << OOO_STRING_SVTOOLS_HTML_tablerow << "," << OOO_STRING_SVTOOLS_HTML_tableheader << ","
+ << OOO_STRING_SVTOOLS_HTML_tabledata << "," << OOO_STRING_SVTOOLS_HTML_parabreak << " { " << sFontFamily;
+ xub_StrLen nFonts = aHTMLStyle.aFontFamilyName.GetTokenCount( ';' );
+ if ( nFonts == 1 )
+ {
+ rStrm << '\"';
+ OUT_STR( aHTMLStyle.aFontFamilyName );
+ rStrm << '\"';
+ }
+ else
+ { // Fontliste, VCL: Semikolon als Separator,
+ // CSS1: Komma als Separator und jeder einzelne Fontname quoted
+ const String& rList = aHTMLStyle.aFontFamilyName;
+ for ( xub_StrLen j = 0, nPos = 0; j < nFonts; j++ )
+ {
+ rStrm << '\"';
+ OUT_STR( rList.GetToken( 0, ';', nPos ) );
+ rStrm << '\"';
+ if ( j < nFonts-1 )
+ rStrm << ", ";
+ }
+ }
+ rStrm << "; " << sFontSize
+ << GetFontSizeCss( ( USHORT ) aHTMLStyle.nFontHeight ) << " }";
+ OUT_LF();
+ rStrm << sMyEndComment;
+ IncIndent(-1); OUT_LF(); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_style );
+
+ IncIndent(-1); OUT_LF(); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_head );
+}
+
+
+void ScHTMLExport::WriteOverview()
+{
+ if ( nUsedTables > 1 )
+ {
+ IncIndent(1);
+ OUT_HR();
+ IncIndent(1); TAG_ON( OOO_STRING_SVTOOLS_HTML_parabreak ); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_center );
+ TAG_ON( OOO_STRING_SVTOOLS_HTML_head1 );
+ OUT_STR( ScGlobal::GetRscString( STR_OVERVIEW ) );
+ TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_head1 );
+
+ String aStr;
+
+ const SCTAB nCount = pDoc->GetTableCount();
+ for ( SCTAB nTab = 0; nTab < nCount; nTab++ )
+ {
+ if ( !IsEmptyTable( nTab ) )
+ {
+ pDoc->GetName( nTab, aStr );
+ rStrm << "<A HREF=\"#table"
+ << ByteString::CreateFromInt32( nTab ).GetBuffer()
+ << "\">";
+ OUT_STR( aStr );
+ rStrm << "</A>";
+ TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_linebreak );
+ }
+ }
+
+ IncIndent(-1); OUT_LF();
+ IncIndent(-1); TAG_OFF( OOO_STRING_SVTOOLS_HTML_center ); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_parabreak );
+ }
+}
+
+
+const SfxItemSet& ScHTMLExport::PageDefaults( SCTAB nTab )
+{
+ SfxStyleSheetBasePool* pStylePool = pDoc->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = NULL;
+ DBG_ASSERT( pStylePool, "StylePool not found! :-(" );
+
+ // remember defaults for compare in WriteCell
+ if ( !aHTMLStyle.bInitialized )
+ {
+ pStylePool->SetSearchMask( SFX_STYLE_FAMILY_PARA, SFXSTYLEBIT_ALL );
+ pStyleSheet = pStylePool->Find(
+ ScGlobal::GetRscString(STR_STYLENAME_STANDARD),
+ SFX_STYLE_FAMILY_PARA );
+ DBG_ASSERT( pStyleSheet, "ParaStyle not found! :-(" );
+ if (!pStyleSheet)
+ pStyleSheet = pStylePool->First();
+ const SfxItemSet& rSetPara = pStyleSheet->GetItemSet();
+
+ aHTMLStyle.nDefaultScriptType = ScGlobal::GetDefaultScriptType();
+ aHTMLStyle.aFontFamilyName = ((const SvxFontItem&)(rSetPara.Get(
+ ScGlobal::GetScriptedWhichID(
+ aHTMLStyle.nDefaultScriptType, ATTR_FONT
+ )))).GetFamilyName();
+ aHTMLStyle.nFontHeight = ((const SvxFontHeightItem&)(rSetPara.Get(
+ ScGlobal::GetScriptedWhichID(
+ aHTMLStyle.nDefaultScriptType, ATTR_FONT_HEIGHT
+ )))).GetHeight();
+ aHTMLStyle.nFontSizeNumber = GetFontSizeNumber( static_cast< USHORT >( aHTMLStyle.nFontHeight ) );
+ }
+
+ // Page style sheet printer settings, e.g. for background graphics.
+ // There's only one background graphic in HTML!
+ pStylePool->SetSearchMask( SFX_STYLE_FAMILY_PAGE, SFXSTYLEBIT_ALL );
+ pStyleSheet = pStylePool->Find( pDoc->GetPageStyle( nTab ), SFX_STYLE_FAMILY_PAGE );
+ DBG_ASSERT( pStyleSheet, "PageStyle not found! :-(" );
+ if (!pStyleSheet)
+ pStyleSheet = pStylePool->First();
+ const SfxItemSet& rSet = pStyleSheet->GetItemSet();
+ if ( !aHTMLStyle.bInitialized )
+ {
+ const SvxBrushItem* pBrushItem = (const SvxBrushItem*)&rSet.Get( ATTR_BACKGROUND );
+ aHTMLStyle.aBackgroundColor = pBrushItem->GetColor();
+ aHTMLStyle.bInitialized = TRUE;
+ }
+ return rSet;
+}
+
+
+void ScHTMLExport::BorderToStyle( ByteString& rOut, const char* pBorderName,
+ const SvxBorderLine* pLine, bool& bInsertSemicolon )
+{
+ if ( pLine )
+ {
+ if ( bInsertSemicolon )
+ rOut += "; ";
+
+ // which border
+ ((rOut += "border-") += pBorderName) += ": ";
+
+ // thickness
+ int nWidth = pLine->GetOutWidth();
+ int nPxWidth = ( nWidth > 0 )? std::max( int( nWidth / TWIPS_PER_PIXEL ), 1 ): 0;
+ (rOut += ByteString::CreateFromInt32( nPxWidth )) += "px solid #";
+
+ // color
+ char hex[7];
+ snprintf( hex, 7, "%06x", static_cast< unsigned int >( pLine->GetColor().GetRGBColor() ) );
+ hex[6] = 0;
+
+ rOut += hex;
+
+ bInsertSemicolon = true;
+ }
+}
+
+void ScHTMLExport::WriteBody()
+{
+ const SfxItemSet& rSet = PageDefaults( bAll ? 0 : aRange.aStart.Tab() );
+ const SvxBrushItem* pBrushItem = (const SvxBrushItem*)&rSet.Get( ATTR_BACKGROUND );
+
+ // default Textfarbe schwarz
+ rStrm << '<' << OOO_STRING_SVTOOLS_HTML_body << ' ' << OOO_STRING_SVTOOLS_HTML_O_text << "=\"#000000\"";
+
+ if ( bAll && GPOS_NONE != pBrushItem->GetGraphicPos() )
+ {
+ const String* pLink = pBrushItem->GetGraphicLink();
+ String aGrfNm;
+
+ // embeddete Grafik -> via WriteGraphic schreiben
+ if( !pLink )
+ {
+ const Graphic* pGrf = pBrushItem->GetGraphic();
+ if( pGrf )
+ {
+ // Grafik als (JPG-)File speichern
+ aGrfNm = aStreamPath;
+ USHORT nErr = XOutBitmap::WriteGraphic( *pGrf, aGrfNm,
+ CREATE_STRING( "JPG" ), XOUTBMP_USE_NATIVE_IF_POSSIBLE );
+ if( !nErr ) // fehlerhaft, da ist nichts auszugeben
+ {
+ aGrfNm = URIHelper::SmartRel2Abs(
+ INetURLObject(aBaseURL),
+ aGrfNm, URIHelper::GetMaybeFileHdl(), true, false);
+ if ( HasCId() )
+ MakeCIdURL( aGrfNm );
+ pLink = &aGrfNm;
+ }
+ }
+ }
+ else
+ {
+ aGrfNm = *pLink;
+ if( bCopyLocalFileToINet || HasCId() )
+ {
+ CopyLocalFileToINet( aGrfNm, aStreamPath );
+ if ( HasCId() )
+ MakeCIdURL( aGrfNm );
+ }
+ else
+ aGrfNm = URIHelper::SmartRel2Abs(
+ INetURLObject(aBaseURL),
+ aGrfNm, URIHelper::GetMaybeFileHdl(), true, false);
+ pLink = &aGrfNm;
+ }
+ if( pLink )
+ {
+ rStrm << ' ' << OOO_STRING_SVTOOLS_HTML_O_background << "=\"";
+ OUT_STR( URIHelper::simpleNormalizedMakeRelative(
+ aBaseURL,
+ *pLink ) ) << '\"';
+ }
+ }
+ if ( !aHTMLStyle.aBackgroundColor.GetTransparency() )
+ { // A transparent background color should always result in default
+ // background of the browser. Also, HTMLOutFuncs::Out_Color() writes
+ // black #000000 for COL_AUTO which is the same as white #ffffff with
+ // transparency set to 0xff, our default background.
+ OUT_SP_CSTR_ASS( OOO_STRING_SVTOOLS_HTML_O_bgcolor );
+ HTMLOutFuncs::Out_Color( rStrm, aHTMLStyle.aBackgroundColor );
+ }
+
+ rStrm << '>'; OUT_LF();
+
+ if ( bAll )
+ WriteOverview();
+
+ WriteTables();
+
+ TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_body );
+}
+
+
+void ScHTMLExport::WriteTables()
+{
+ const SCTAB nTabCount = pDoc->GetTableCount();
+ const String aStrTable( ScResId( SCSTR_TABLE ) );
+ String aStr;
+ String aStrOut;
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCTAB nStartTab;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ SCTAB nEndTab;
+ SCCOL nStartColFix = 0;
+ SCROW nStartRowFix = 0;
+ SCCOL nEndColFix = 0;
+ SCROW nEndRowFix = 0;
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+ if ( bAll )
+ {
+ nStartTab = 0;
+ nEndTab = nTabCount - 1;
+ }
+ else
+ {
+ nStartCol = nStartColFix = aRange.aStart.Col();
+ nStartRow = nStartRowFix = aRange.aStart.Row();
+ nStartTab = aRange.aStart.Tab();
+ nEndCol = nEndColFix = aRange.aEnd.Col();
+ nEndRow = nEndRowFix = aRange.aEnd.Row();
+ nEndTab = aRange.aEnd.Tab();
+ }
+ SCTAB nTableStrNum = 1;
+ for ( SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++ )
+ {
+ if ( !pDoc->IsVisible( nTab ) )
+ continue; // for
+
+ if ( bAll )
+ {
+ if ( !GetDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow ) )
+ continue; // for
+
+ if ( nUsedTables > 1 )
+ {
+ aStrOut = aStrTable;
+ aStrOut.AppendAscii( " " );
+ aStrOut += String::CreateFromInt32( nTableStrNum++ );
+ aStrOut.AppendAscii( ": " );
+
+ OUT_HR();
+
+ // Anker festlegen:
+ rStrm << "<A NAME=\"table"
+ << ByteString::CreateFromInt32( nTab ).GetBuffer()
+ << "\">";
+ TAG_ON( OOO_STRING_SVTOOLS_HTML_head1 );
+ OUT_STR( aStrOut );
+ TAG_ON( OOO_STRING_SVTOOLS_HTML_emphasis );
+
+ pDoc->GetName( nTab, aStr );
+ OUT_STR( aStr );
+
+ TAG_OFF( OOO_STRING_SVTOOLS_HTML_emphasis );
+ TAG_OFF( OOO_STRING_SVTOOLS_HTML_head1 );
+ rStrm << "</A>"; OUT_LF();
+ }
+ }
+ else
+ {
+ nStartCol = nStartColFix;
+ nStartRow = nStartRowFix;
+ nEndCol = nEndColFix;
+ nEndRow = nEndRowFix;
+ if ( !TrimDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow ) )
+ continue; // for
+ }
+
+ // <TABLE ...>
+ ByteString aByteStrOut = OOO_STRING_SVTOOLS_HTML_table;
+// aStrOut = OOO_STRING_SVTOOLS_HTML_table;
+
+ // FRAME=VOID, we do the styling of the cells in <TD>
+ (((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_frame) += '=') += OOO_STRING_SVTOOLS_HTML_TF_void;
+
+ bTabHasGraphics = bTabAlignedLeft = FALSE;
+ if ( bAll && pDrawLayer )
+ PrepareGraphics( pDrawLayer, nTab, nStartCol, nStartRow,
+ nEndCol, nEndRow );
+
+ // more <TABLE ...>
+ if ( bTabAlignedLeft )
+ (((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_align) += '=') += OOO_STRING_SVTOOLS_HTML_AL_left;
+ // ALIGN=LEFT allow text and graphics to flow around
+ // CELLSPACING
+ (((aByteStrOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_cellspacing ) += '=') +=
+ ByteString::CreateFromInt32( nCellSpacing );
+ // COLS=n
+ SCCOL nColCnt = 0;
+ SCCOL nCol;
+ for ( nCol=nStartCol; nCol<=nEndCol; nCol++ )
+ {
+ if ( !(pDoc->GetColFlags( nCol, nTab ) & CR_HIDDEN) )
+ ++nColCnt;
+ }
+ (((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_cols) += '=') += ByteString::CreateFromInt32( nColCnt );
+
+ // RULES=NONE, we do the styling of the cells in <TD>
+ (((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_rules) += '=') += OOO_STRING_SVTOOLS_HTML_TR_none;
+
+ // BORDER=0, we do the styling of the cells in <TD>
+ ((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_border) += "=0";
+ IncIndent(1); TAG_ON_LF( aByteStrOut.GetBuffer() );
+
+ // <COLGROUP>
+ TAG_ON( OOO_STRING_SVTOOLS_HTML_colgroup );
+ // <COL WIDTH=x> as pre-info for long tables
+ ByteString aByteStr = OOO_STRING_SVTOOLS_HTML_col;
+ aByteStr += ' ';
+ aByteStr += OOO_STRING_SVTOOLS_HTML_O_width;
+ aByteStr += '=';
+ for ( nCol=nStartCol; nCol<=nEndCol; nCol++ )
+ {
+ if ( pDoc->GetColFlags( nCol, nTab ) & CR_HIDDEN )
+ continue; // for
+
+ aByteStrOut = aByteStr;
+ aByteStrOut += ByteString::CreateFromInt32(
+ ToPixel( pDoc->GetColWidth( nCol, nTab ) ) );
+ TAG_ON( aByteStrOut.GetBuffer() );
+ }
+ TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_colgroup );
+
+ // <TBODY>
+ IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_tbody );
+ // At least old (3.x, 4.x?) Netscape doesn't follow <TABLE COLS=n> and
+ // <COL WIDTH=x> specified, but needs a width at every column.
+ bTableDataWidth = TRUE; // widths in first row
+ bool bHasHiddenRows = pDoc->GetRowFlagsArray( nTab).HasCondition(
+ nStartRow, nEndRow, CR_HIDDEN, CR_HIDDEN);
+ for ( SCROW nRow=nStartRow; nRow<=nEndRow; nRow++ )
+ {
+ if ( bHasHiddenRows && (pDoc->GetRowFlags( nRow, nTab ) & CR_HIDDEN) )
+ {
+ nRow = pDoc->GetRowFlagsArray( nTab).GetFirstForCondition(
+ nRow+1, nEndRow, CR_HIDDEN, 0);
+ --nRow;
+ continue; // for
+ }
+
+ IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_tablerow );
+ bTableDataHeight = TRUE; // height at every first cell of each row
+ for ( SCCOL nCol2=nStartCol; nCol2<=nEndCol; nCol2++ )
+ {
+ if ( pDoc->GetColFlags( nCol2, nTab ) & CR_HIDDEN )
+ continue; // for
+
+ if ( nCol2 == nEndCol )
+ IncIndent(-1);
+ WriteCell( nCol2, nRow, nTab );
+ bTableDataHeight = FALSE;
+ }
+ bTableDataWidth = FALSE; // widths only in first row
+
+ if ( nRow == nEndRow )
+ IncIndent(-1);
+ TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tablerow );
+ }
+ IncIndent(-1); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tbody );
+
+ IncIndent(-1); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_table );
+
+ if ( bTabHasGraphics )
+ {
+ // the rest that is not in a cell
+ for ( ScHTMLGraphEntry* pE = aGraphList.First(); pE; pE = aGraphList.Next() )
+ {
+ if ( !pE->bWritten )
+ WriteGraphEntry( pE );
+ delete pE;
+ }
+ aGraphList.Clear();
+ if ( bTabAlignedLeft )
+ { // clear <TABLE ALIGN=LEFT> with <BR CLEAR=LEFT>
+ aByteStrOut = OOO_STRING_SVTOOLS_HTML_linebreak;
+ (((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_clear) += '=') += OOO_STRING_SVTOOLS_HTML_AL_left;
+ TAG_ON_LF( aByteStrOut.GetBuffer() );
+ }
+ }
+
+ if ( bAll )
+ OUT_COMMENT( CREATE_STRING( "**************************************************************************" ) );
+ }
+}
+
+
+void ScHTMLExport::WriteCell( SCCOL nCol, SCROW nRow, SCTAB nTab )
+{
+ const ScPatternAttr* pAttr = pDoc->GetPattern( nCol, nRow, nTab );
+ const SfxItemSet* pCondItemSet = pDoc->GetCondResult( nCol, nRow, nTab );
+
+ const ScMergeFlagAttr& rMergeFlagAttr = (const ScMergeFlagAttr&) pAttr->GetItem( ATTR_MERGE_FLAG, pCondItemSet );
+ if ( rMergeFlagAttr.IsOverlapped() )
+ return ;
+
+ ScAddress aPos( nCol, nRow, nTab );
+ ScHTMLGraphEntry* pGraphEntry = NULL;
+ if ( bTabHasGraphics )
+ {
+ for ( pGraphEntry = aGraphList.First(); pGraphEntry;
+ pGraphEntry = aGraphList.Next() )
+ {
+ if ( pGraphEntry->bInCell && pGraphEntry->aRange.In( aPos ) )
+ {
+ if ( pGraphEntry->aRange.aStart == aPos )
+ break; // for
+ else
+ return ; // ist ein Col/RowSpan, Overlapped
+ }
+ }
+ }
+
+ ScBaseCell* pCell = pDoc->GetCell( aPos );
+ ULONG nFormat = pAttr->GetNumberFormat( pFormatter );
+ BOOL bValueData;
+ BYTE nScriptType;
+ if ( pCell )
+ {
+ bValueData = pCell->HasValueData();
+ nScriptType = pDoc->GetScriptType( nCol, nRow, nTab, pCell );
+ }
+ else
+ {
+ bValueData = FALSE;
+ nScriptType = 0;
+ }
+ if ( nScriptType == 0 )
+ nScriptType = aHTMLStyle.nDefaultScriptType;
+
+
+ ByteString aStrTD = OOO_STRING_SVTOOLS_HTML_tabledata;
+
+ // border of the cells
+ SvxBoxItem* pBorder = (SvxBoxItem*) pDoc->GetAttr( nCol, nRow, nTab, ATTR_BORDER );
+ if ( pBorder && (pBorder->GetTop() || pBorder->GetBottom() || pBorder->GetLeft() || pBorder->GetRight()) )
+ {
+ ((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_style) += "=\"";
+
+ bool bInsertSemicolon = false;
+ BorderToStyle( aStrTD, "top", pBorder->GetTop(), bInsertSemicolon );
+ BorderToStyle( aStrTD, "bottom", pBorder->GetBottom(), bInsertSemicolon );
+ BorderToStyle( aStrTD, "left", pBorder->GetLeft(), bInsertSemicolon );
+ BorderToStyle( aStrTD, "right", pBorder->GetRight(), bInsertSemicolon );
+
+ aStrTD += '"';
+ }
+
+ const sal_Char* pChar;
+ USHORT nWidthPixel;
+ USHORT nHeightPixel;
+
+ const ScMergeAttr& rMergeAttr = (const ScMergeAttr&) pAttr->GetItem( ATTR_MERGE, pCondItemSet );
+ if ( pGraphEntry || rMergeAttr.IsMerged() )
+ {
+ SCCOL nC, jC;
+ SCROW nR;
+ ULONG v;
+ if ( pGraphEntry )
+ nC = Max( SCCOL(pGraphEntry->aRange.aEnd.Col() - nCol + 1),
+ SCCOL(rMergeAttr.GetColMerge()) );
+ else
+ nC = rMergeAttr.GetColMerge();
+ if ( nC > 1 )
+ {
+ (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_colspan) += '=') += ByteString::CreateFromInt32( nC );
+ nC = nC + nCol;
+ for ( jC=nCol, v=0; jC<nC; jC++ )
+ v += pDoc->GetColWidth( jC, nTab );
+ nWidthPixel = ToPixel( static_cast< USHORT >( v ) );
+ }
+ else
+ nWidthPixel = ToPixel( pDoc->GetColWidth( nCol, nTab ) );
+
+ if ( pGraphEntry )
+ nR = Max( SCROW(pGraphEntry->aRange.aEnd.Row() - nRow + 1),
+ SCROW(rMergeAttr.GetRowMerge()) );
+ else
+ nR = rMergeAttr.GetRowMerge();
+ if ( nR > 1 )
+ {
+ (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_rowspan) += '=') += ByteString::CreateFromInt32( nR );
+ nR += nRow;
+ v = pDoc->GetRowHeight( nRow, nR-1, nTab );
+ nHeightPixel = ToPixel( static_cast< USHORT >( v ) );
+ }
+ else
+ nHeightPixel = ToPixel( pDoc->GetRowHeight( nRow, nTab ) );
+ }
+ else
+ {
+ nWidthPixel = ToPixel( pDoc->GetColWidth( nCol, nTab ) );
+ nHeightPixel = ToPixel( pDoc->GetRowHeight( nRow, nTab ) );
+ }
+
+ if ( bTableDataWidth )
+ (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_width) += '=') += ByteString::CreateFromInt32( nWidthPixel );
+ if ( bTableDataHeight )
+ (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_height) += '=') += ByteString::CreateFromInt32( nHeightPixel );
+
+ const SvxFontItem& rFontItem = (const SvxFontItem&) pAttr->GetItem(
+ ScGlobal::GetScriptedWhichID( nScriptType, ATTR_FONT),
+ pCondItemSet);
+
+ const SvxFontHeightItem& rFontHeightItem = (const SvxFontHeightItem&)
+ pAttr->GetItem( ScGlobal::GetScriptedWhichID( nScriptType,
+ ATTR_FONT_HEIGHT), pCondItemSet);
+
+ const SvxWeightItem& rWeightItem = (const SvxWeightItem&) pAttr->GetItem(
+ ScGlobal::GetScriptedWhichID( nScriptType, ATTR_FONT_WEIGHT),
+ pCondItemSet);
+
+ const SvxPostureItem& rPostureItem = (const SvxPostureItem&)
+ pAttr->GetItem( ScGlobal::GetScriptedWhichID( nScriptType,
+ ATTR_FONT_POSTURE), pCondItemSet);
+
+ const SvxUnderlineItem& rUnderlineItem = (const SvxUnderlineItem&)
+ pAttr->GetItem( ATTR_FONT_UNDERLINE, pCondItemSet );
+
+ const SvxColorItem& rColorItem = (const SvxColorItem&) pAttr->GetItem(
+ ATTR_FONT_COLOR, pCondItemSet );
+
+ const SvxHorJustifyItem& rHorJustifyItem = (const SvxHorJustifyItem&)
+ pAttr->GetItem( ATTR_HOR_JUSTIFY, pCondItemSet );
+
+ const SvxVerJustifyItem& rVerJustifyItem = (const SvxVerJustifyItem&)
+ pAttr->GetItem( ATTR_VER_JUSTIFY, pCondItemSet );
+
+ const SvxBrushItem& rBrushItem = (const SvxBrushItem&) pAttr->GetItem(
+ ATTR_BACKGROUND, pCondItemSet );
+
+ Color aBgColor;
+ if ( rBrushItem.GetColor().GetTransparency() == 255 )
+ aBgColor = aHTMLStyle.aBackgroundColor; // #55121# keine ungewollte Hintergrundfarbe
+ else
+ aBgColor = rBrushItem.GetColor();
+
+ BOOL bBold = ( WEIGHT_BOLD <= rWeightItem.GetWeight() );
+ BOOL bItalic = ( ITALIC_NONE != rPostureItem.GetPosture() );
+ BOOL bUnderline = ( UNDERLINE_NONE != rUnderlineItem.GetLineStyle() );
+ BOOL bSetFontColor = ( COL_AUTO != rColorItem.GetValue().GetColor() ); // #97650# default is AUTO now
+#if 0
+// keine StyleSheet-Fontangaben: hart fuer jede Zelle
+ BOOL bSetFontName = TRUE;
+ USHORT nSetFontSizeNumber = GetFontSizeNumber( (USHORT)rFontHeightItem.GetHeight() );
+#else
+ BOOL bSetFontName = ( aHTMLStyle.aFontFamilyName != rFontItem.GetFamilyName() );
+ USHORT nSetFontSizeNumber = 0;
+ UINT32 nFontHeight = rFontHeightItem.GetHeight();
+ if ( nFontHeight != aHTMLStyle.nFontHeight )
+ {
+ nSetFontSizeNumber = GetFontSizeNumber( (USHORT) nFontHeight );
+ if ( nSetFontSizeNumber == aHTMLStyle.nFontSizeNumber )
+ nSetFontSizeNumber = 0; // no difference, don't set
+ }
+#endif
+ BOOL bSetFont = (bSetFontColor || bSetFontName || nSetFontSizeNumber);
+
+ //! TODO: we could entirely use CSS1 here instead, but that would exclude
+ //! Netscape 3.0 and Netscape 4.x without JavaScript enabled.
+ //! Do we want that?
+
+ switch( rHorJustifyItem.GetValue() )
+ {
+ case SVX_HOR_JUSTIFY_STANDARD:
+ pChar = (bValueData ? OOO_STRING_SVTOOLS_HTML_AL_right : OOO_STRING_SVTOOLS_HTML_AL_left);
+ break;
+ case SVX_HOR_JUSTIFY_CENTER: pChar = OOO_STRING_SVTOOLS_HTML_AL_center; break;
+ case SVX_HOR_JUSTIFY_BLOCK: pChar = OOO_STRING_SVTOOLS_HTML_AL_justify; break;
+ case SVX_HOR_JUSTIFY_RIGHT: pChar = OOO_STRING_SVTOOLS_HTML_AL_right; break;
+ case SVX_HOR_JUSTIFY_LEFT:
+ case SVX_HOR_JUSTIFY_REPEAT:
+ default: pChar = OOO_STRING_SVTOOLS_HTML_AL_left; break;
+ }
+
+ (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_align) += '=') += pChar;
+
+ switch( rVerJustifyItem.GetValue() )
+ {
+ case SVX_VER_JUSTIFY_TOP: pChar = OOO_STRING_SVTOOLS_HTML_VA_top; break;
+ case SVX_VER_JUSTIFY_CENTER: pChar = OOO_STRING_SVTOOLS_HTML_VA_middle; break;
+ case SVX_VER_JUSTIFY_BOTTOM: pChar = OOO_STRING_SVTOOLS_HTML_VA_bottom; break;
+ case SVX_VER_JUSTIFY_STANDARD:
+ default: pChar = NULL;
+ }
+ if ( pChar )
+ (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_valign) += '=') += pChar;
+
+ if ( aHTMLStyle.aBackgroundColor != aBgColor )
+ {
+ ((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_bgcolor) += '=';
+ lcl_AppendHTMLColorTripel( aStrTD, aBgColor );
+ }
+
+ double fVal = 0.0;
+ if ( bValueData )
+ {
+ if ( pCell )
+ {
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_VALUE:
+ fVal = ((ScValueCell*)pCell)->GetValue();
+ if ( bCalcAsShown && fVal != 0.0 )
+ fVal = pDoc->RoundValueAsShown( fVal, nFormat );
+ break;
+ case CELLTYPE_FORMULA:
+ fVal = ((ScFormulaCell*)pCell)->GetValue();
+ if ( (nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 )
+ nFormat = ScGlobal::GetStandardFormat( fVal, *pFormatter,
+ nFormat, ((ScFormulaCell*)pCell)->GetFormatType() );
+ break;
+ default:
+ DBG_ERRORFILE( "value data with unsupported cell type" );
+ }
+ }
+ }
+ HTMLOutFuncs::CreateTableDataOptionsValNum( aStrTD, bValueData, fVal,
+ nFormat, *pFormatter, eDestEnc, &aNonConvertibleChars );
+
+ TAG_ON( aStrTD.GetBuffer() );
+
+ if ( bBold ) TAG_ON( OOO_STRING_SVTOOLS_HTML_bold );
+ if ( bItalic ) TAG_ON( OOO_STRING_SVTOOLS_HTML_italic );
+ if ( bUnderline ) TAG_ON( OOO_STRING_SVTOOLS_HTML_underline );
+
+
+ if ( bSetFont )
+ {
+ ByteString aStr = OOO_STRING_SVTOOLS_HTML_font;
+ if ( bSetFontName )
+ {
+ ((aStr += ' ') += OOO_STRING_SVTOOLS_HTML_O_face) += "=\"";
+ xub_StrLen nFonts = rFontItem.GetFamilyName().GetTokenCount( ';' );
+ if ( nFonts == 1 )
+ {
+ ByteString aTmpStr;
+ HTMLOutFuncs::ConvertStringToHTML( rFontItem.GetFamilyName(),
+ aTmpStr, eDestEnc, &aNonConvertibleChars );
+ aStr += aTmpStr;
+ }
+ else
+ { // Fontliste, VCL: Semikolon als Separator, HTML: Komma
+ const String& rList = rFontItem.GetFamilyName();
+ for ( xub_StrLen j = 0, nPos = 0; j < nFonts; j++ )
+ {
+ ByteString aTmpStr;
+ HTMLOutFuncs::ConvertStringToHTML(
+ rList.GetToken( 0, ';', nPos ), aTmpStr, eDestEnc,
+ &aNonConvertibleChars );
+ aStr += aTmpStr;
+ if ( j < nFonts-1 )
+ aStr += ',';
+ }
+ }
+ aStr += '\"';
+ }
+ if ( nSetFontSizeNumber )
+ {
+ (((aStr += ' ') += OOO_STRING_SVTOOLS_HTML_O_size) += '=')
+ += ByteString::CreateFromInt32( nSetFontSizeNumber );
+ }
+ if ( bSetFontColor )
+ {
+ Color aColor = rColorItem.GetValue();
+
+ // always export automatic text color as black
+ if ( aColor.GetColor() == COL_AUTO )
+ aColor.SetColor( COL_BLACK );
+
+ ((aStr += ' ') += OOO_STRING_SVTOOLS_HTML_O_color) += '=';
+ lcl_AppendHTMLColorTripel( aStr, aColor );
+ }
+ TAG_ON( aStr.GetBuffer() );
+ }
+
+ String aStrOut;
+ BOOL bFieldText = FALSE;
+ if ( pCell )
+ { // cell content
+ Color* pColor;
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_NOTE :
+ // nothing
+ break;
+ case CELLTYPE_EDIT :
+ bFieldText = WriteFieldText( (const ScEditCell*) pCell );
+ if ( bFieldText )
+ break;
+ //! else: fallthru
+ default:
+ ScCellFormat::GetString( pCell, nFormat, aStrOut, &pColor, *pFormatter );
+ }
+ }
+ if ( !bFieldText )
+ {
+ if ( !aStrOut.Len() )
+ {
+ TAG_ON( OOO_STRING_SVTOOLS_HTML_linebreak ); // #42573# keine komplett leere Zelle
+ }
+ else
+ {
+ xub_StrLen nPos = aStrOut.Search( _LF );
+ if ( nPos == STRING_NOTFOUND )
+ {
+ OUT_STR( aStrOut );
+ }
+ else
+ {
+ xub_StrLen nStartPos = 0;
+ do
+ {
+ String aSingleLine( aStrOut, nStartPos, nPos - nStartPos );
+ OUT_STR( aSingleLine );
+ TAG_ON( OOO_STRING_SVTOOLS_HTML_linebreak );
+ nStartPos = nPos + 1;
+ }
+ while( ( nPos = aStrOut.Search( _LF, nStartPos ) ) != STRING_NOTFOUND );
+ String aSingleLine( aStrOut, nStartPos, aStrOut.Len() - nStartPos );
+ OUT_STR( aSingleLine );
+ }
+ }
+ }
+ if ( pGraphEntry )
+ WriteGraphEntry( pGraphEntry );
+
+ if ( bSetFont ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_font );
+ if ( bUnderline ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_underline );
+ if ( bItalic ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_italic );
+ if ( bBold ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_bold );
+
+ TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tabledata );
+}
+
+
+BOOL ScHTMLExport::WriteFieldText( const ScEditCell* pCell )
+{
+ BOOL bFields = FALSE;
+ const EditTextObject* pData;
+ pCell->GetData( pData );
+ // text and anchor of URL fields, Doc-Engine is a ScFieldEditEngine
+ EditEngine& rEngine = pDoc->GetEditEngine();
+ rEngine.SetText( *pData );
+ USHORT nParas = rEngine.GetParagraphCount();
+ if ( nParas )
+ {
+ ESelection aSel( 0, 0, nParas-1, rEngine.GetTextLen( nParas-1 ) );
+ SfxItemSet aSet( rEngine.GetAttribs( aSel ) );
+ SfxItemState eFieldState = aSet.GetItemState( EE_FEATURE_FIELD, FALSE );
+ if ( eFieldState == SFX_ITEM_DONTCARE || eFieldState == SFX_ITEM_SET )
+ bFields = TRUE;
+ }
+ if ( bFields )
+ {
+ BOOL bOldUpdateMode = rEngine.GetUpdateMode();
+ rEngine.SetUpdateMode( TRUE ); // no portions if not formatted
+ for ( USHORT nPar=0; nPar < nParas; nPar++ )
+ {
+ if ( nPar > 0 )
+ TAG_ON( OOO_STRING_SVTOOLS_HTML_linebreak );
+ SvUShorts aPortions;
+ rEngine.GetPortions( nPar, aPortions );
+ USHORT nCnt = aPortions.Count();
+ USHORT nStart = 0;
+ for ( USHORT nPos = 0; nPos < nCnt; nPos++ )
+ {
+ USHORT nEnd = aPortions.GetObject( nPos );
+ ESelection aSel( nPar, nStart, nPar, nEnd );
+ BOOL bUrl = FALSE;
+ // fields are single characters
+ if ( nEnd == nStart+1 )
+ {
+ const SfxPoolItem* pItem;
+ SfxItemSet aSet = rEngine.GetAttribs( aSel );
+ if ( aSet.GetItemState( EE_FEATURE_FIELD, FALSE, &pItem ) == SFX_ITEM_ON )
+ {
+ const SvxFieldData* pField = ((const SvxFieldItem*)pItem)->GetField();
+ if ( pField && pField->ISA(SvxURLField) )
+ {
+ bUrl = TRUE;
+ const SvxURLField* pURLField = (const SvxURLField*)pField;
+// String aFieldText = rEngine.GetText( aSel );
+ rStrm << '<' << OOO_STRING_SVTOOLS_HTML_anchor << ' ' << OOO_STRING_SVTOOLS_HTML_O_href << "=\"";
+ OUT_STR( pURLField->GetURL() );
+ rStrm << "\">";
+ OUT_STR( pURLField->GetRepresentation() );
+ rStrm << "</" << OOO_STRING_SVTOOLS_HTML_anchor << '>';
+ }
+ }
+ }
+ if ( !bUrl )
+ OUT_STR( rEngine.GetText( aSel ) );
+ nStart = nEnd;
+ }
+ }
+ rEngine.SetUpdateMode( bOldUpdateMode );
+ }
+ return bFields;
+}
+
+
+BOOL ScHTMLExport::CopyLocalFileToINet( String& rFileNm,
+ const String& rTargetNm, BOOL bFileToFile )
+{
+ BOOL bRet = FALSE;
+ INetURLObject aFileUrl, aTargetUrl;
+ aFileUrl.SetSmartURL( rFileNm );
+ aTargetUrl.SetSmartURL( rTargetNm );
+ if( INET_PROT_FILE == aFileUrl.GetProtocol() &&
+ ( (bFileToFile && INET_PROT_FILE == aTargetUrl.GetProtocol()) ||
+ (!bFileToFile && INET_PROT_FILE != aTargetUrl.GetProtocol() &&
+ INET_PROT_FTP <= aTargetUrl.GetProtocol() &&
+ INET_PROT_NEWS >= aTargetUrl.GetProtocol()) ) )
+ {
+ if( pSrcArr )
+ {
+ // wurde die Datei schon verschoben
+ USHORT nPos;
+ if( pSrcArr->Seek_Entry( &rFileNm, &nPos ))
+ {
+ rFileNm = *(*pDestArr)[ nPos ];
+ return TRUE;
+ }
+ }
+ else
+ {
+ pSrcArr = new SvStringsSortDtor( 4, 4 );
+ pDestArr = new SvStringsSortDtor( 4, 4 );
+ }
+
+ String* pSrc = new String( rFileNm );
+ SvFileStream aTmp( aFileUrl.PathToFileName(), STREAM_READ );
+
+ String* pDest = new String( aTargetUrl.GetPartBeforeLastName() );
+ *pDest += String(aFileUrl.GetName());
+
+ if( bFileToFile )
+ {
+ INetURLObject aCpyURL( *pDest );
+ SvFileStream aCpy( aCpyURL.PathToFileName(), STREAM_WRITE );
+ aCpy << aTmp;
+
+ aCpy.Close();
+ bRet = SVSTREAM_OK == aCpy.GetError();
+ }
+ else
+ {
+ SfxMedium aMedium( *pDest, STREAM_WRITE | STREAM_SHARE_DENYNONE,
+ FALSE );
+
+ // temp. File anlegen
+ // aMedium.DownLoad();
+
+ {
+ SvFileStream aCpy( aMedium.GetPhysicalName(), STREAM_WRITE );
+ aCpy << aTmp;
+ }
+
+ // uebertragen
+ aMedium.Close();
+ aMedium.Commit();
+
+ bRet = 0 == aMedium.GetError();
+ }
+
+ if( bRet )
+ {
+ pSrcArr->Insert( pSrc );
+ pDestArr->Insert( pDest );
+ rFileNm = *pDest;
+ }
+ else
+ {
+ delete pSrc;
+ delete pDest;
+ }
+ }
+
+ return bRet;
+}
+
+
+void ScHTMLExport::MakeCIdURL( String& rURL )
+{
+ if( !aCId.Len() )
+ return;
+
+ INetURLObject aURLObj( rURL );
+ if( INET_PROT_FILE != aURLObj.GetProtocol() )
+ return;
+
+ String aLastName( aURLObj.GetLastName() );
+ DBG_ASSERT( aLastName.Len(), "Dateiname ohne Laenge!" );
+ aLastName.ToLowerAscii();
+
+ rURL.AssignAscii( "cid:" );
+ rURL += aLastName;
+ rURL.AppendAscii( "." );
+ rURL += aCId;
+}
+
+
+void ScHTMLExport::IncIndent( short nVal )
+{
+ sIndent[nIndent] = '\t';
+ nIndent = nIndent + nVal;
+ if ( nIndent < 0 )
+ nIndent = 0;
+ else if ( nIndent > nIndentMax )
+ nIndent = nIndentMax;
+ sIndent[nIndent] = 0;
+}
+
+
+