update dev300-m58
[ooovba.git] / sc / source / filter / html / htmlexp.cxx
blob9698b9d6d9f90499c5edfc084bc6cd3f0f430e6c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: htmlexp.cxx,v $
10 * $Revision: 1.38.144.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 // INCLUDE ---------------------------------------------------------------
38 #include "scitems.hxx"
39 #include <svx/eeitem.hxx>
41 #define _SVSTDARR_STRINGSSORTDTOR
42 #include <rtl/tencinfo.h>
44 #include <vcl/svapp.hxx>
45 #include <svx/algitem.hxx>
46 #include <svx/boxitem.hxx>
47 #include <svx/brshitem.hxx>
48 #include <svx/colritem.hxx>
49 #include <svx/fhgtitem.hxx>
50 #include <svx/fontitem.hxx>
51 #include <svx/postitem.hxx>
52 #include <svx/udlnitem.hxx>
53 #include <svx/wghtitem.hxx>
54 #include <svx/xoutbmp.hxx>
55 #include <svx/editeng.hxx>
56 #include <svx/htmlcfg.hxx>
57 #include <sfx2/docfile.hxx>
58 #include <sfx2/frmhtmlw.hxx>
59 #include <sfx2/objsh.hxx>
60 #include <svtools/stritem.hxx>
61 #include <svtools/urihelper.hxx>
62 #ifndef _SVSTDARR_USHORTS
63 #define _SVSTDARR_USHORTS
64 #endif
65 #include <svtools/svstdarr.hxx>
66 #include <svtools/zforlist.hxx>
67 #include <svtools/htmlkywd.hxx>
68 #include <svtools/htmlout.hxx>
69 #include <svtools/parhtml.hxx>
70 #include <vcl/outdev.hxx>
71 #include <stdio.h>
73 #include "htmlexp.hxx"
74 #include "filter.hxx"
75 #include "global.hxx"
76 #include "document.hxx"
77 #include "scitems.hxx"
78 #include "attrib.hxx"
79 #include "patattr.hxx"
80 #include "stlpool.hxx"
81 #include "scresid.hxx"
82 #include "cell.hxx"
83 #include "cellform.hxx"
84 #include "docoptio.hxx"
85 #include "editutil.hxx"
86 #include "ftools.hxx"
89 #include <svx/flditem.hxx>
90 #include <svx/borderline.hxx>
91 #include <svtools/syslocale.hxx>
94 // ohne sc.hrc: error C2679: binary '=' : no operator defined which takes a
95 // right-hand operand of type 'const class String (__stdcall *)(class ScResId)'
96 // bei
97 // const String aStrTable( ScResId( SCSTR_TABLE ) ); aStrOut = aStrTable;
98 // ?!???
99 #include "sc.hrc"
100 #include "globstr.hrc"
102 #include <com/sun/star/uno/Reference.h>
103 #include <com/sun/star/document/XDocumentProperties.hpp>
104 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
107 //========================================================================
109 const static sal_Char __FAR_DATA sMyBegComment[] = "<!-- ";
110 const static sal_Char __FAR_DATA sMyEndComment[] = " -->";
111 const static sal_Char __FAR_DATA sFontFamily[] = "font-family:";
112 const static sal_Char __FAR_DATA sFontSize[] = "font-size:";
114 const USHORT __FAR_DATA ScHTMLExport::nDefaultFontSize[SC_HTML_FONTSIZES] =
116 HTMLFONTSZ1_DFLT, HTMLFONTSZ2_DFLT, HTMLFONTSZ3_DFLT, HTMLFONTSZ4_DFLT,
117 HTMLFONTSZ5_DFLT, HTMLFONTSZ6_DFLT, HTMLFONTSZ7_DFLT
120 USHORT ScHTMLExport::nFontSize[SC_HTML_FONTSIZES] = { 0 };
122 const char* __FAR_DATA ScHTMLExport::pFontSizeCss[SC_HTML_FONTSIZES] =
124 "xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large"
127 const USHORT ScHTMLExport::nCellSpacing = 0;
128 const sal_Char __FAR_DATA ScHTMLExport::sIndentSource[nIndentMax+1] =
129 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
131 //========================================================================
132 // Makros fuer HTML-Export
133 //========================================================================
134 #define OUT_PROLOGUE() (rStrm << sHTML30_Prologue << ScExportBase::sNewLine \
135 << ScExportBase::sNewLine)
136 #define TAG_ON( tag ) HTMLOutFuncs::Out_AsciiTag( rStrm, tag )
137 #define TAG_OFF( tag ) HTMLOutFuncs::Out_AsciiTag( rStrm, tag, FALSE )
138 #define OUT_STR( str ) HTMLOutFuncs::Out_String( rStrm, str, eDestEnc, &aNonConvertibleChars )
139 #define OUT_STR_NO_CONV( str ) HTMLOutFuncs::Out_String( rStrm, str, eDestEnc )
140 #define OUT_LF() rStrm << ScExportBase::sNewLine << GetIndentStr()
141 #define lcl_OUT_LF() rStrm << ScExportBase::sNewLine
142 #define TAG_ON_LF( tag ) (TAG_ON( tag ) << ScExportBase::sNewLine << GetIndentStr())
143 #define TAG_OFF_LF( tag ) (TAG_OFF( tag ) << ScExportBase::sNewLine << GetIndentStr())
144 #define OUT_HR() TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_horzrule )
145 #define OUT_COMMENT( comment ) (rStrm << sMyBegComment, OUT_STR( comment ) \
146 << sMyEndComment << ScExportBase::sNewLine \
147 << GetIndentStr())
148 #define lcl_OUT_COMMENT( comment ) (rStrm << sMyBegComment, OUT_STR_NO_CONV( comment ) \
149 << sMyEndComment << ScExportBase::sNewLine)
151 #define OUT_SP_CSTR_ASS( s ) rStrm << ' ' << s << '='
152 #define APPEND_SPACE( s ) s.AppendAscii(" ")
154 extern BOOL bOderSo;
156 #define GLOBSTR(id) ScGlobal::GetRscString( id )
160 //========================================================================
162 FltError ScFormatFilterPluginImpl::ScExportHTML( SvStream& rStrm, const String& rBaseURL, ScDocument* pDoc,
163 const ScRange& rRange, const CharSet /*eNach*/, BOOL bAll,
164 const String& rStreamPath, String& rNonConvertibleChars )
166 ScHTMLExport aEx( rStrm, rBaseURL, pDoc, rRange, bAll, rStreamPath );
167 FltError nErr = aEx.Write();
168 rNonConvertibleChars = aEx.GetNonConvertibleChars();
169 return nErr;
173 void lcl_AddStamp( String& rStr, const String& rName,
174 const ::com::sun::star::util::DateTime& rDateTime,
175 const LocaleDataWrapper& rLoc )
177 Date aD(rDateTime.Day, rDateTime.Month, rDateTime.Year);
178 Time aT(rDateTime.Hours, rDateTime.Minutes, rDateTime.Seconds,
179 rDateTime.HundredthSeconds);
180 DateTime aDateTime(aD,aT);
182 String aStrDate = rLoc.getDate( aDateTime );
183 String aStrTime = rLoc.getTime( aDateTime );
185 rStr += GLOBSTR( STR_BY );
186 APPEND_SPACE( rStr );
187 if (rName.Len())
188 rStr += rName;
189 else
190 rStr.AppendAscii( "???" );
191 APPEND_SPACE( rStr );
192 rStr += GLOBSTR( STR_ON );
193 APPEND_SPACE( rStr );
194 if (aStrDate.Len())
195 rStr += aStrDate;
196 else
197 rStr.AppendAscii( "???" );
198 rStr.AppendAscii( ", " );
199 if (aStrTime.Len())
200 rStr += aStrTime;
201 else
202 rStr.AppendAscii( "???" );
206 void lcl_AppendHTMLColorTripel( ByteString& rStr, const Color& rColor )
208 // <font COLOR="#00FF40">hallo</font>
209 sal_Char buf[64];
210 sal_Char* p = buf;
212 rStr += "\"#";
213 p += sprintf( p, "%02X", rColor.GetRed() ); // #100211# - checked
214 p += sprintf( p, "%02X", rColor.GetGreen() ); // #100211# - checked
215 p += sprintf( p, "%02X", rColor.GetBlue() ); // #100211# - checked
216 rStr += buf;
217 rStr += '\"';
221 /*void lcl_TagOn( String& rResult, const String& rTag, const String* pStrOpt )
223 rResult = '<';
224 rResult += rTag;
225 if ( pStrOpt )
227 rResult += ' ';
228 rResult += *pStrOpt;
230 rResult += '>';
234 /*void lcl_TagOff( String& rResult, const String& rTag )
236 rResult = '<'; rResult += rTag; rResult += '>';
240 bool SC_DLLPUBLIC ScGetWriteTeamInfo();
242 void lcl_WriteTeamInfo( SvStream& rStrm, rtl_TextEncoding eDestEnc )
244 if ( !ScGetWriteTeamInfo() ) return;
245 lcl_OUT_LF();
246 lcl_OUT_COMMENT( CREATE_STRING( "Sascha Ballach " ) );
247 lcl_OUT_COMMENT( CREATE_STRING( "Michael Daeumling (aka Bitsau) " ) );
248 lcl_OUT_COMMENT( CREATE_STRING( "Michael Hagen " ) );
249 lcl_OUT_COMMENT( CREATE_STRING( "Roland Jakobs " ) );
250 lcl_OUT_COMMENT( CREATE_STRING( "Andreas Krebs " ) );
251 lcl_OUT_COMMENT( CREATE_STRING( "John Marmion " ) );
252 lcl_OUT_COMMENT( CREATE_STRING( "Niklas Nebel " ) );
253 lcl_OUT_COMMENT( CREATE_STRING( "Jacques Nietsch " ) );
254 lcl_OUT_COMMENT( CREATE_STRING( "Marcus Olk " ) );
255 lcl_OUT_COMMENT( CREATE_STRING( "Eike Rathke " ) );
256 lcl_OUT_COMMENT( CREATE_STRING( "Daniel Rentz " ) );
257 lcl_OUT_COMMENT( CREATE_STRING( "Stephan Templin " ) );
258 lcl_OUT_COMMENT( CREATE_STRING( "Gunnar Timm " ) );
259 lcl_OUT_COMMENT( CREATE_STRING( "*** Man kann nicht ALLES haben! ***" ) );
260 lcl_OUT_LF();
264 //////////////////////////////////////////////////////////////////////////////
266 ScHTMLExport::ScHTMLExport( SvStream& rStrmP, const String& rBaseURL, ScDocument* pDocP,
267 const ScRange& rRangeP,
268 BOOL bAllP, const String& rStreamPathP ) :
269 ScExportBase( rStrmP, pDocP, rRangeP ),
270 aBaseURL( rBaseURL ),
271 aStreamPath( rStreamPathP ),
272 pAppWin( Application::GetDefaultDevice() ),
273 pSrcArr( NULL ),
274 pDestArr( NULL ),
275 nUsedTables( 0 ),
276 nIndent( 0 ),
277 bAll( bAllP ),
278 bTabHasGraphics( FALSE ),
279 bCalcAsShown( pDocP->GetDocOptions().IsCalcAsShown() ),
280 bTableDataWidth( TRUE ),
281 bTableDataHeight( TRUE )
283 strcpy( sIndent, sIndentSource ); // #100211# - checked
284 sIndent[0] = 0;
286 // set HTML configuration
287 SvxHtmlOptions* pHtmlOptions = SvxHtmlOptions::Get();
288 eDestEnc = (pDoc->IsClipOrUndo() ? RTL_TEXTENCODING_UTF8 : pHtmlOptions->GetTextEncoding());
289 bCopyLocalFileToINet = pHtmlOptions->IsSaveGraphicsLocal();
290 for ( USHORT j=0; j < SC_HTML_FONTSIZES; j++ )
292 USHORT nSize = pHtmlOptions->GetFontSize( j );
293 // remember in Twips, like our SvxFontHeightItem
294 if ( nSize )
295 nFontSize[j] = nSize * 20;
296 else
297 nFontSize[j] = nDefaultFontSize[j] * 20;
300 const SCTAB nCount = pDoc->GetTableCount();
301 for ( SCTAB nTab = 0; nTab < nCount; nTab++ )
303 if ( !IsEmptyTable( nTab ) )
304 nUsedTables++;
307 // Content-Id fuer Mail-Export?
308 SfxObjectShell* pDocSh = pDoc->GetDocumentShell();
309 if ( pDocSh )
311 const SfxPoolItem* pItem = pDocSh->GetItem( SID_ORIGURL );
312 if( pItem )
314 aCId = ((const SfxStringItem *)pItem)->GetValue();
315 DBG_ASSERT( aCId.Len(), "CID ohne Laenge!" );
321 ScHTMLExport::~ScHTMLExport()
323 for ( ScHTMLGraphEntry* pE = aGraphList.First(); pE; pE = aGraphList.Next() )
324 delete pE;
325 delete pSrcArr;
326 delete pDestArr;
330 USHORT ScHTMLExport::GetFontSizeNumber( USHORT nHeight )
332 USHORT nSize = 1;
333 for ( USHORT j=SC_HTML_FONTSIZES-1; j>0; j-- )
335 if( nHeight > (nFontSize[j] + nFontSize[j-1]) / 2 )
336 { // der naechstgelegene
337 nSize = j+1;
338 break;
341 return nSize;
344 const char* ScHTMLExport::GetFontSizeCss( USHORT nHeight )
346 USHORT nSize = GetFontSizeNumber( nHeight );
347 return pFontSizeCss[ nSize-1 ];
351 USHORT ScHTMLExport::ToPixel( USHORT nVal )
353 if( nVal )
355 nVal = (USHORT)pAppWin->LogicToPixel(
356 Size( nVal, nVal ), MapMode( MAP_TWIP ) ).Width();
357 if( !nVal ) // wo ein Twip ist sollte auch ein Pixel sein
358 nVal = 1;
360 return nVal;
364 Size ScHTMLExport::MMToPixel( const Size& rSize )
366 Size aSize( rSize );
367 aSize = pAppWin->LogicToPixel( rSize, MapMode( MAP_100TH_MM ) );
368 // wo etwas ist sollte auch ein Pixel sein
369 if ( !aSize.Width() && rSize.Width() )
370 aSize.Width() = 1;
371 if ( !aSize.Height() && rSize.Height() )
372 aSize.Height() = 1;
373 return aSize;
377 ULONG ScHTMLExport::Write()
379 rStrm << '<' << OOO_STRING_SVTOOLS_HTML_doctype << ' ' << OOO_STRING_SVTOOLS_HTML_doctype32 << '>'
380 << sNewLine << sNewLine;
381 TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_html );
382 WriteHeader();
383 OUT_LF();
384 WriteBody();
385 OUT_LF();
386 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_html );
388 return rStrm.GetError();
392 void ScHTMLExport::WriteHeader()
394 IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_head );
396 if ( pDoc->IsClipOrUndo() )
397 { // no real DocInfo available, but some META information like charset needed
398 SfxFrameHTMLWriter::Out_DocInfo( rStrm, aBaseURL, NULL, sIndent, eDestEnc, &aNonConvertibleChars );
400 else
402 using namespace ::com::sun::star;
403 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
404 pDoc->GetDocumentShell()->GetModel(), uno::UNO_QUERY_THROW);
405 uno::Reference<document::XDocumentProperties> xDocProps
406 = xDPS->getDocumentProperties();
407 SfxFrameHTMLWriter::Out_DocInfo( rStrm, aBaseURL, xDocProps,
408 sIndent, eDestEnc, &aNonConvertibleChars );
409 OUT_LF();
411 //----------------------------------------------------------
412 if (!xDocProps->getPrintedBy().equalsAscii(""))
414 OUT_COMMENT( GLOBSTR( STR_DOC_INFO ) );
415 String aStrOut( GLOBSTR( STR_DOC_PRINTED ) );
416 aStrOut.AppendAscii( ": " );
417 lcl_AddStamp( aStrOut, xDocProps->getPrintedBy(),
418 xDocProps->getPrintDate(), *ScGlobal::pLocaleData );
419 OUT_COMMENT( aStrOut );
421 //----------------------------------------------------------
423 lcl_WriteTeamInfo( rStrm, eDestEnc );
425 OUT_LF();
427 // CSS1 StyleSheet
428 PageDefaults( bAll ? 0 : aRange.aStart.Tab() );
429 IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_style );
430 rStrm << sMyBegComment; OUT_LF();
431 rStrm << OOO_STRING_SVTOOLS_HTML_body << "," << OOO_STRING_SVTOOLS_HTML_division << "," << OOO_STRING_SVTOOLS_HTML_table << ","
432 << OOO_STRING_SVTOOLS_HTML_thead << "," << OOO_STRING_SVTOOLS_HTML_tbody << "," << OOO_STRING_SVTOOLS_HTML_tfoot << ","
433 << OOO_STRING_SVTOOLS_HTML_tablerow << "," << OOO_STRING_SVTOOLS_HTML_tableheader << ","
434 << OOO_STRING_SVTOOLS_HTML_tabledata << "," << OOO_STRING_SVTOOLS_HTML_parabreak << " { " << sFontFamily;
435 xub_StrLen nFonts = aHTMLStyle.aFontFamilyName.GetTokenCount( ';' );
436 if ( nFonts == 1 )
438 rStrm << '\"';
439 OUT_STR( aHTMLStyle.aFontFamilyName );
440 rStrm << '\"';
442 else
443 { // Fontliste, VCL: Semikolon als Separator,
444 // CSS1: Komma als Separator und jeder einzelne Fontname quoted
445 const String& rList = aHTMLStyle.aFontFamilyName;
446 for ( xub_StrLen j = 0, nPos = 0; j < nFonts; j++ )
448 rStrm << '\"';
449 OUT_STR( rList.GetToken( 0, ';', nPos ) );
450 rStrm << '\"';
451 if ( j < nFonts-1 )
452 rStrm << ", ";
455 rStrm << "; " << sFontSize
456 << GetFontSizeCss( ( USHORT ) aHTMLStyle.nFontHeight ) << " }";
457 OUT_LF();
458 rStrm << sMyEndComment;
459 IncIndent(-1); OUT_LF(); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_style );
461 IncIndent(-1); OUT_LF(); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_head );
465 void ScHTMLExport::WriteOverview()
467 if ( nUsedTables > 1 )
469 IncIndent(1);
470 OUT_HR();
471 IncIndent(1); TAG_ON( OOO_STRING_SVTOOLS_HTML_parabreak ); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_center );
472 TAG_ON( OOO_STRING_SVTOOLS_HTML_head1 );
473 OUT_STR( ScGlobal::GetRscString( STR_OVERVIEW ) );
474 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_head1 );
476 String aStr;
478 const SCTAB nCount = pDoc->GetTableCount();
479 for ( SCTAB nTab = 0; nTab < nCount; nTab++ )
481 if ( !IsEmptyTable( nTab ) )
483 pDoc->GetName( nTab, aStr );
484 rStrm << "<A HREF=\"#table"
485 << ByteString::CreateFromInt32( nTab ).GetBuffer()
486 << "\">";
487 OUT_STR( aStr );
488 rStrm << "</A>";
489 TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_linebreak );
493 IncIndent(-1); OUT_LF();
494 IncIndent(-1); TAG_OFF( OOO_STRING_SVTOOLS_HTML_center ); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_parabreak );
499 const SfxItemSet& ScHTMLExport::PageDefaults( SCTAB nTab )
501 SfxStyleSheetBasePool* pStylePool = pDoc->GetStyleSheetPool();
502 SfxStyleSheetBase* pStyleSheet = NULL;
503 DBG_ASSERT( pStylePool, "StylePool not found! :-(" );
505 // remember defaults for compare in WriteCell
506 if ( !aHTMLStyle.bInitialized )
508 pStylePool->SetSearchMask( SFX_STYLE_FAMILY_PARA, SFXSTYLEBIT_ALL );
509 pStyleSheet = pStylePool->Find(
510 ScGlobal::GetRscString(STR_STYLENAME_STANDARD),
511 SFX_STYLE_FAMILY_PARA );
512 DBG_ASSERT( pStyleSheet, "ParaStyle not found! :-(" );
513 if (!pStyleSheet)
514 pStyleSheet = pStylePool->First();
515 const SfxItemSet& rSetPara = pStyleSheet->GetItemSet();
517 aHTMLStyle.nDefaultScriptType = ScGlobal::GetDefaultScriptType();
518 aHTMLStyle.aFontFamilyName = ((const SvxFontItem&)(rSetPara.Get(
519 ScGlobal::GetScriptedWhichID(
520 aHTMLStyle.nDefaultScriptType, ATTR_FONT
521 )))).GetFamilyName();
522 aHTMLStyle.nFontHeight = ((const SvxFontHeightItem&)(rSetPara.Get(
523 ScGlobal::GetScriptedWhichID(
524 aHTMLStyle.nDefaultScriptType, ATTR_FONT_HEIGHT
525 )))).GetHeight();
526 aHTMLStyle.nFontSizeNumber = GetFontSizeNumber( static_cast< USHORT >( aHTMLStyle.nFontHeight ) );
529 // Page style sheet printer settings, e.g. for background graphics.
530 // There's only one background graphic in HTML!
531 pStylePool->SetSearchMask( SFX_STYLE_FAMILY_PAGE, SFXSTYLEBIT_ALL );
532 pStyleSheet = pStylePool->Find( pDoc->GetPageStyle( nTab ), SFX_STYLE_FAMILY_PAGE );
533 DBG_ASSERT( pStyleSheet, "PageStyle not found! :-(" );
534 if (!pStyleSheet)
535 pStyleSheet = pStylePool->First();
536 const SfxItemSet& rSet = pStyleSheet->GetItemSet();
537 if ( !aHTMLStyle.bInitialized )
539 const SvxBrushItem* pBrushItem = (const SvxBrushItem*)&rSet.Get( ATTR_BACKGROUND );
540 aHTMLStyle.aBackgroundColor = pBrushItem->GetColor();
541 aHTMLStyle.bInitialized = TRUE;
543 return rSet;
547 void ScHTMLExport::BorderToStyle( ByteString& rOut, const char* pBorderName,
548 const SvxBorderLine* pLine, bool& bInsertSemicolon )
550 if ( pLine )
552 if ( bInsertSemicolon )
553 rOut += "; ";
555 // which border
556 ((rOut += "border-") += pBorderName) += ": ";
558 // thickness
559 int nWidth = pLine->GetOutWidth();
560 int nPxWidth = ( nWidth > 0 )? std::max( int( nWidth / TWIPS_PER_PIXEL ), 1 ): 0;
561 (rOut += ByteString::CreateFromInt32( nPxWidth )) += "px solid #";
563 // color
564 char hex[7];
565 snprintf( hex, 7, "%06x", static_cast< unsigned int >( pLine->GetColor().GetRGBColor() ) );
566 hex[6] = 0;
568 rOut += hex;
570 bInsertSemicolon = true;
574 void ScHTMLExport::WriteBody()
576 const SfxItemSet& rSet = PageDefaults( bAll ? 0 : aRange.aStart.Tab() );
577 const SvxBrushItem* pBrushItem = (const SvxBrushItem*)&rSet.Get( ATTR_BACKGROUND );
579 // default Textfarbe schwarz
580 rStrm << '<' << OOO_STRING_SVTOOLS_HTML_body << ' ' << OOO_STRING_SVTOOLS_HTML_O_text << "=\"#000000\"";
582 if ( bAll && GPOS_NONE != pBrushItem->GetGraphicPos() )
584 const String* pLink = pBrushItem->GetGraphicLink();
585 String aGrfNm;
587 // embeddete Grafik -> via WriteGraphic schreiben
588 if( !pLink )
590 const Graphic* pGrf = pBrushItem->GetGraphic();
591 if( pGrf )
593 // Grafik als (JPG-)File speichern
594 aGrfNm = aStreamPath;
595 USHORT nErr = XOutBitmap::WriteGraphic( *pGrf, aGrfNm,
596 CREATE_STRING( "JPG" ), XOUTBMP_USE_NATIVE_IF_POSSIBLE );
597 if( !nErr ) // fehlerhaft, da ist nichts auszugeben
599 aGrfNm = URIHelper::SmartRel2Abs(
600 INetURLObject(aBaseURL),
601 aGrfNm, URIHelper::GetMaybeFileHdl(), true, false);
602 if ( HasCId() )
603 MakeCIdURL( aGrfNm );
604 pLink = &aGrfNm;
608 else
610 aGrfNm = *pLink;
611 if( bCopyLocalFileToINet || HasCId() )
613 CopyLocalFileToINet( aGrfNm, aStreamPath );
614 if ( HasCId() )
615 MakeCIdURL( aGrfNm );
617 else
618 aGrfNm = URIHelper::SmartRel2Abs(
619 INetURLObject(aBaseURL),
620 aGrfNm, URIHelper::GetMaybeFileHdl(), true, false);
621 pLink = &aGrfNm;
623 if( pLink )
625 rStrm << ' ' << OOO_STRING_SVTOOLS_HTML_O_background << "=\"";
626 OUT_STR( URIHelper::simpleNormalizedMakeRelative(
627 aBaseURL,
628 *pLink ) ) << '\"';
631 if ( !aHTMLStyle.aBackgroundColor.GetTransparency() )
632 { // A transparent background color should always result in default
633 // background of the browser. Also, HTMLOutFuncs::Out_Color() writes
634 // black #000000 for COL_AUTO which is the same as white #ffffff with
635 // transparency set to 0xff, our default background.
636 OUT_SP_CSTR_ASS( OOO_STRING_SVTOOLS_HTML_O_bgcolor );
637 HTMLOutFuncs::Out_Color( rStrm, aHTMLStyle.aBackgroundColor );
640 rStrm << '>'; OUT_LF();
642 if ( bAll )
643 WriteOverview();
645 WriteTables();
647 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_body );
651 void ScHTMLExport::WriteTables()
653 const SCTAB nTabCount = pDoc->GetTableCount();
654 const String aStrTable( ScResId( SCSTR_TABLE ) );
655 String aStr;
656 String aStrOut;
657 SCCOL nStartCol;
658 SCROW nStartRow;
659 SCTAB nStartTab;
660 SCCOL nEndCol;
661 SCROW nEndRow;
662 SCTAB nEndTab;
663 SCCOL nStartColFix = 0;
664 SCROW nStartRowFix = 0;
665 SCCOL nEndColFix = 0;
666 SCROW nEndRowFix = 0;
667 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
668 if ( bAll )
670 nStartTab = 0;
671 nEndTab = nTabCount - 1;
673 else
675 nStartCol = nStartColFix = aRange.aStart.Col();
676 nStartRow = nStartRowFix = aRange.aStart.Row();
677 nStartTab = aRange.aStart.Tab();
678 nEndCol = nEndColFix = aRange.aEnd.Col();
679 nEndRow = nEndRowFix = aRange.aEnd.Row();
680 nEndTab = aRange.aEnd.Tab();
682 SCTAB nTableStrNum = 1;
683 for ( SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++ )
685 if ( !pDoc->IsVisible( nTab ) )
686 continue; // for
688 if ( bAll )
690 if ( !GetDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow ) )
691 continue; // for
693 if ( nUsedTables > 1 )
695 aStrOut = aStrTable;
696 aStrOut.AppendAscii( " " );
697 aStrOut += String::CreateFromInt32( nTableStrNum++ );
698 aStrOut.AppendAscii( ": " );
700 OUT_HR();
702 // Anker festlegen:
703 rStrm << "<A NAME=\"table"
704 << ByteString::CreateFromInt32( nTab ).GetBuffer()
705 << "\">";
706 TAG_ON( OOO_STRING_SVTOOLS_HTML_head1 );
707 OUT_STR( aStrOut );
708 TAG_ON( OOO_STRING_SVTOOLS_HTML_emphasis );
710 pDoc->GetName( nTab, aStr );
711 OUT_STR( aStr );
713 TAG_OFF( OOO_STRING_SVTOOLS_HTML_emphasis );
714 TAG_OFF( OOO_STRING_SVTOOLS_HTML_head1 );
715 rStrm << "</A>"; OUT_LF();
718 else
720 nStartCol = nStartColFix;
721 nStartRow = nStartRowFix;
722 nEndCol = nEndColFix;
723 nEndRow = nEndRowFix;
724 if ( !TrimDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow ) )
725 continue; // for
728 // <TABLE ...>
729 ByteString aByteStrOut = OOO_STRING_SVTOOLS_HTML_table;
730 // aStrOut = OOO_STRING_SVTOOLS_HTML_table;
732 // FRAME=VOID, we do the styling of the cells in <TD>
733 (((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_frame) += '=') += OOO_STRING_SVTOOLS_HTML_TF_void;
735 bTabHasGraphics = bTabAlignedLeft = FALSE;
736 if ( bAll && pDrawLayer )
737 PrepareGraphics( pDrawLayer, nTab, nStartCol, nStartRow,
738 nEndCol, nEndRow );
740 // more <TABLE ...>
741 if ( bTabAlignedLeft )
742 (((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_align) += '=') += OOO_STRING_SVTOOLS_HTML_AL_left;
743 // ALIGN=LEFT allow text and graphics to flow around
744 // CELLSPACING
745 (((aByteStrOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_cellspacing ) += '=') +=
746 ByteString::CreateFromInt32( nCellSpacing );
747 // COLS=n
748 SCCOL nColCnt = 0;
749 SCCOL nCol;
750 for ( nCol=nStartCol; nCol<=nEndCol; nCol++ )
752 if ( !pDoc->ColHidden(nCol, nTab) )
753 ++nColCnt;
755 (((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_cols) += '=') += ByteString::CreateFromInt32( nColCnt );
757 // RULES=NONE, we do the styling of the cells in <TD>
758 (((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_rules) += '=') += OOO_STRING_SVTOOLS_HTML_TR_none;
760 // BORDER=0, we do the styling of the cells in <TD>
761 ((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_border) += "=0";
762 IncIndent(1); TAG_ON_LF( aByteStrOut.GetBuffer() );
764 // <COLGROUP>
765 TAG_ON( OOO_STRING_SVTOOLS_HTML_colgroup );
766 // <COL WIDTH=x> as pre-info for long tables
767 ByteString aByteStr = OOO_STRING_SVTOOLS_HTML_col;
768 aByteStr += ' ';
769 aByteStr += OOO_STRING_SVTOOLS_HTML_O_width;
770 aByteStr += '=';
771 for ( nCol=nStartCol; nCol<=nEndCol; nCol++ )
773 if ( pDoc->ColHidden(nCol, nTab) )
774 continue; // for
776 aByteStrOut = aByteStr;
777 aByteStrOut += ByteString::CreateFromInt32(
778 ToPixel( pDoc->GetColWidth( nCol, nTab ) ) );
779 TAG_ON( aByteStrOut.GetBuffer() );
781 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_colgroup );
783 // <TBODY>
784 IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_tbody );
785 // At least old (3.x, 4.x?) Netscape doesn't follow <TABLE COLS=n> and
786 // <COL WIDTH=x> specified, but needs a width at every column.
787 bTableDataWidth = TRUE; // widths in first row
788 bool bHasHiddenRows = pDoc->HasHiddenRows(nStartRow, nEndRow, nTab);
789 for ( SCROW nRow=nStartRow; nRow<=nEndRow; nRow++ )
791 if ( bHasHiddenRows && pDoc->RowHidden(nRow, nTab) )
793 nRow = pDoc->FirstVisibleRow(nRow+1, nEndRow, nTab);
794 --nRow;
795 continue; // for
798 IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_tablerow );
799 bTableDataHeight = TRUE; // height at every first cell of each row
800 for ( SCCOL nCol2=nStartCol; nCol2<=nEndCol; nCol2++ )
802 if ( pDoc->ColHidden(nCol2, nTab) )
803 continue; // for
805 if ( nCol2 == nEndCol )
806 IncIndent(-1);
807 WriteCell( nCol2, nRow, nTab );
808 bTableDataHeight = FALSE;
810 bTableDataWidth = FALSE; // widths only in first row
812 if ( nRow == nEndRow )
813 IncIndent(-1);
814 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tablerow );
816 IncIndent(-1); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tbody );
818 IncIndent(-1); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_table );
820 if ( bTabHasGraphics )
822 // the rest that is not in a cell
823 for ( ScHTMLGraphEntry* pE = aGraphList.First(); pE; pE = aGraphList.Next() )
825 if ( !pE->bWritten )
826 WriteGraphEntry( pE );
827 delete pE;
829 aGraphList.Clear();
830 if ( bTabAlignedLeft )
831 { // clear <TABLE ALIGN=LEFT> with <BR CLEAR=LEFT>
832 aByteStrOut = OOO_STRING_SVTOOLS_HTML_linebreak;
833 (((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_clear) += '=') += OOO_STRING_SVTOOLS_HTML_AL_left;
834 TAG_ON_LF( aByteStrOut.GetBuffer() );
838 if ( bAll )
839 OUT_COMMENT( CREATE_STRING( "**************************************************************************" ) );
844 void ScHTMLExport::WriteCell( SCCOL nCol, SCROW nRow, SCTAB nTab )
846 const ScPatternAttr* pAttr = pDoc->GetPattern( nCol, nRow, nTab );
847 const SfxItemSet* pCondItemSet = pDoc->GetCondResult( nCol, nRow, nTab );
849 const ScMergeFlagAttr& rMergeFlagAttr = (const ScMergeFlagAttr&) pAttr->GetItem( ATTR_MERGE_FLAG, pCondItemSet );
850 if ( rMergeFlagAttr.IsOverlapped() )
851 return ;
853 ScAddress aPos( nCol, nRow, nTab );
854 ScHTMLGraphEntry* pGraphEntry = NULL;
855 if ( bTabHasGraphics )
857 for ( pGraphEntry = aGraphList.First(); pGraphEntry;
858 pGraphEntry = aGraphList.Next() )
860 if ( pGraphEntry->bInCell && pGraphEntry->aRange.In( aPos ) )
862 if ( pGraphEntry->aRange.aStart == aPos )
863 break; // for
864 else
865 return ; // ist ein Col/RowSpan, Overlapped
870 ScBaseCell* pCell = pDoc->GetCell( aPos );
871 ULONG nFormat = pAttr->GetNumberFormat( pFormatter );
872 BOOL bValueData;
873 BYTE nScriptType;
874 if ( pCell )
876 bValueData = pCell->HasValueData();
877 nScriptType = pDoc->GetScriptType( nCol, nRow, nTab, pCell );
879 else
881 bValueData = FALSE;
882 nScriptType = 0;
884 if ( nScriptType == 0 )
885 nScriptType = aHTMLStyle.nDefaultScriptType;
888 ByteString aStrTD = OOO_STRING_SVTOOLS_HTML_tabledata;
890 // border of the cells
891 SvxBoxItem* pBorder = (SvxBoxItem*) pDoc->GetAttr( nCol, nRow, nTab, ATTR_BORDER );
892 if ( pBorder && (pBorder->GetTop() || pBorder->GetBottom() || pBorder->GetLeft() || pBorder->GetRight()) )
894 ((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_style) += "=\"";
896 bool bInsertSemicolon = false;
897 BorderToStyle( aStrTD, "top", pBorder->GetTop(), bInsertSemicolon );
898 BorderToStyle( aStrTD, "bottom", pBorder->GetBottom(), bInsertSemicolon );
899 BorderToStyle( aStrTD, "left", pBorder->GetLeft(), bInsertSemicolon );
900 BorderToStyle( aStrTD, "right", pBorder->GetRight(), bInsertSemicolon );
902 aStrTD += '"';
905 const sal_Char* pChar;
906 USHORT nWidthPixel;
907 USHORT nHeightPixel;
909 const ScMergeAttr& rMergeAttr = (const ScMergeAttr&) pAttr->GetItem( ATTR_MERGE, pCondItemSet );
910 if ( pGraphEntry || rMergeAttr.IsMerged() )
912 SCCOL nC, jC;
913 SCROW nR;
914 ULONG v;
915 if ( pGraphEntry )
916 nC = Max( SCCOL(pGraphEntry->aRange.aEnd.Col() - nCol + 1),
917 SCCOL(rMergeAttr.GetColMerge()) );
918 else
919 nC = rMergeAttr.GetColMerge();
920 if ( nC > 1 )
922 (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_colspan) += '=') += ByteString::CreateFromInt32( nC );
923 nC = nC + nCol;
924 for ( jC=nCol, v=0; jC<nC; jC++ )
925 v += pDoc->GetColWidth( jC, nTab );
926 nWidthPixel = ToPixel( static_cast< USHORT >( v ) );
928 else
929 nWidthPixel = ToPixel( pDoc->GetColWidth( nCol, nTab ) );
931 if ( pGraphEntry )
932 nR = Max( SCROW(pGraphEntry->aRange.aEnd.Row() - nRow + 1),
933 SCROW(rMergeAttr.GetRowMerge()) );
934 else
935 nR = rMergeAttr.GetRowMerge();
936 if ( nR > 1 )
938 (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_rowspan) += '=') += ByteString::CreateFromInt32( nR );
939 nR += nRow;
940 v = pDoc->GetRowHeight( nRow, nR-1, nTab );
941 nHeightPixel = ToPixel( static_cast< USHORT >( v ) );
943 else
944 nHeightPixel = ToPixel( pDoc->GetRowHeight( nRow, nTab ) );
946 else
948 nWidthPixel = ToPixel( pDoc->GetColWidth( nCol, nTab ) );
949 nHeightPixel = ToPixel( pDoc->GetRowHeight( nRow, nTab ) );
952 if ( bTableDataWidth )
953 (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_width) += '=') += ByteString::CreateFromInt32( nWidthPixel );
954 if ( bTableDataHeight )
955 (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_height) += '=') += ByteString::CreateFromInt32( nHeightPixel );
957 const SvxFontItem& rFontItem = (const SvxFontItem&) pAttr->GetItem(
958 ScGlobal::GetScriptedWhichID( nScriptType, ATTR_FONT),
959 pCondItemSet);
961 const SvxFontHeightItem& rFontHeightItem = (const SvxFontHeightItem&)
962 pAttr->GetItem( ScGlobal::GetScriptedWhichID( nScriptType,
963 ATTR_FONT_HEIGHT), pCondItemSet);
965 const SvxWeightItem& rWeightItem = (const SvxWeightItem&) pAttr->GetItem(
966 ScGlobal::GetScriptedWhichID( nScriptType, ATTR_FONT_WEIGHT),
967 pCondItemSet);
969 const SvxPostureItem& rPostureItem = (const SvxPostureItem&)
970 pAttr->GetItem( ScGlobal::GetScriptedWhichID( nScriptType,
971 ATTR_FONT_POSTURE), pCondItemSet);
973 const SvxUnderlineItem& rUnderlineItem = (const SvxUnderlineItem&)
974 pAttr->GetItem( ATTR_FONT_UNDERLINE, pCondItemSet );
976 const SvxColorItem& rColorItem = (const SvxColorItem&) pAttr->GetItem(
977 ATTR_FONT_COLOR, pCondItemSet );
979 const SvxHorJustifyItem& rHorJustifyItem = (const SvxHorJustifyItem&)
980 pAttr->GetItem( ATTR_HOR_JUSTIFY, pCondItemSet );
982 const SvxVerJustifyItem& rVerJustifyItem = (const SvxVerJustifyItem&)
983 pAttr->GetItem( ATTR_VER_JUSTIFY, pCondItemSet );
985 const SvxBrushItem& rBrushItem = (const SvxBrushItem&) pAttr->GetItem(
986 ATTR_BACKGROUND, pCondItemSet );
988 Color aBgColor;
989 if ( rBrushItem.GetColor().GetTransparency() == 255 )
990 aBgColor = aHTMLStyle.aBackgroundColor; // #55121# keine ungewollte Hintergrundfarbe
991 else
992 aBgColor = rBrushItem.GetColor();
994 BOOL bBold = ( WEIGHT_BOLD <= rWeightItem.GetWeight() );
995 BOOL bItalic = ( ITALIC_NONE != rPostureItem.GetPosture() );
996 BOOL bUnderline = ( UNDERLINE_NONE != rUnderlineItem.GetLineStyle() );
997 BOOL bSetFontColor = ( COL_AUTO != rColorItem.GetValue().GetColor() ); // #97650# default is AUTO now
998 #if 0
999 // keine StyleSheet-Fontangaben: hart fuer jede Zelle
1000 BOOL bSetFontName = TRUE;
1001 USHORT nSetFontSizeNumber = GetFontSizeNumber( (USHORT)rFontHeightItem.GetHeight() );
1002 #else
1003 BOOL bSetFontName = ( aHTMLStyle.aFontFamilyName != rFontItem.GetFamilyName() );
1004 USHORT nSetFontSizeNumber = 0;
1005 UINT32 nFontHeight = rFontHeightItem.GetHeight();
1006 if ( nFontHeight != aHTMLStyle.nFontHeight )
1008 nSetFontSizeNumber = GetFontSizeNumber( (USHORT) nFontHeight );
1009 if ( nSetFontSizeNumber == aHTMLStyle.nFontSizeNumber )
1010 nSetFontSizeNumber = 0; // no difference, don't set
1012 #endif
1013 BOOL bSetFont = (bSetFontColor || bSetFontName || nSetFontSizeNumber);
1015 //! TODO: we could entirely use CSS1 here instead, but that would exclude
1016 //! Netscape 3.0 and Netscape 4.x without JavaScript enabled.
1017 //! Do we want that?
1019 switch( rHorJustifyItem.GetValue() )
1021 case SVX_HOR_JUSTIFY_STANDARD:
1022 pChar = (bValueData ? OOO_STRING_SVTOOLS_HTML_AL_right : OOO_STRING_SVTOOLS_HTML_AL_left);
1023 break;
1024 case SVX_HOR_JUSTIFY_CENTER: pChar = OOO_STRING_SVTOOLS_HTML_AL_center; break;
1025 case SVX_HOR_JUSTIFY_BLOCK: pChar = OOO_STRING_SVTOOLS_HTML_AL_justify; break;
1026 case SVX_HOR_JUSTIFY_RIGHT: pChar = OOO_STRING_SVTOOLS_HTML_AL_right; break;
1027 case SVX_HOR_JUSTIFY_LEFT:
1028 case SVX_HOR_JUSTIFY_REPEAT:
1029 default: pChar = OOO_STRING_SVTOOLS_HTML_AL_left; break;
1032 (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_align) += '=') += pChar;
1034 switch( rVerJustifyItem.GetValue() )
1036 case SVX_VER_JUSTIFY_TOP: pChar = OOO_STRING_SVTOOLS_HTML_VA_top; break;
1037 case SVX_VER_JUSTIFY_CENTER: pChar = OOO_STRING_SVTOOLS_HTML_VA_middle; break;
1038 case SVX_VER_JUSTIFY_BOTTOM: pChar = OOO_STRING_SVTOOLS_HTML_VA_bottom; break;
1039 case SVX_VER_JUSTIFY_STANDARD:
1040 default: pChar = NULL;
1042 if ( pChar )
1043 (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_valign) += '=') += pChar;
1045 if ( aHTMLStyle.aBackgroundColor != aBgColor )
1047 ((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_bgcolor) += '=';
1048 lcl_AppendHTMLColorTripel( aStrTD, aBgColor );
1051 double fVal = 0.0;
1052 if ( bValueData )
1054 if ( pCell )
1056 switch ( pCell->GetCellType() )
1058 case CELLTYPE_VALUE:
1059 fVal = ((ScValueCell*)pCell)->GetValue();
1060 if ( bCalcAsShown && fVal != 0.0 )
1061 fVal = pDoc->RoundValueAsShown( fVal, nFormat );
1062 break;
1063 case CELLTYPE_FORMULA:
1064 fVal = ((ScFormulaCell*)pCell)->GetValue();
1065 if ( (nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 )
1066 nFormat = ScGlobal::GetStandardFormat( fVal, *pFormatter,
1067 nFormat, ((ScFormulaCell*)pCell)->GetFormatType() );
1068 break;
1069 default:
1070 DBG_ERRORFILE( "value data with unsupported cell type" );
1074 HTMLOutFuncs::CreateTableDataOptionsValNum( aStrTD, bValueData, fVal,
1075 nFormat, *pFormatter, eDestEnc, &aNonConvertibleChars );
1077 TAG_ON( aStrTD.GetBuffer() );
1079 if ( bBold ) TAG_ON( OOO_STRING_SVTOOLS_HTML_bold );
1080 if ( bItalic ) TAG_ON( OOO_STRING_SVTOOLS_HTML_italic );
1081 if ( bUnderline ) TAG_ON( OOO_STRING_SVTOOLS_HTML_underline );
1084 if ( bSetFont )
1086 ByteString aStr = OOO_STRING_SVTOOLS_HTML_font;
1087 if ( bSetFontName )
1089 ((aStr += ' ') += OOO_STRING_SVTOOLS_HTML_O_face) += "=\"";
1090 xub_StrLen nFonts = rFontItem.GetFamilyName().GetTokenCount( ';' );
1091 if ( nFonts == 1 )
1093 ByteString aTmpStr;
1094 HTMLOutFuncs::ConvertStringToHTML( rFontItem.GetFamilyName(),
1095 aTmpStr, eDestEnc, &aNonConvertibleChars );
1096 aStr += aTmpStr;
1098 else
1099 { // Fontliste, VCL: Semikolon als Separator, HTML: Komma
1100 const String& rList = rFontItem.GetFamilyName();
1101 for ( xub_StrLen j = 0, nPos = 0; j < nFonts; j++ )
1103 ByteString aTmpStr;
1104 HTMLOutFuncs::ConvertStringToHTML(
1105 rList.GetToken( 0, ';', nPos ), aTmpStr, eDestEnc,
1106 &aNonConvertibleChars );
1107 aStr += aTmpStr;
1108 if ( j < nFonts-1 )
1109 aStr += ',';
1112 aStr += '\"';
1114 if ( nSetFontSizeNumber )
1116 (((aStr += ' ') += OOO_STRING_SVTOOLS_HTML_O_size) += '=')
1117 += ByteString::CreateFromInt32( nSetFontSizeNumber );
1119 if ( bSetFontColor )
1121 Color aColor = rColorItem.GetValue();
1123 // always export automatic text color as black
1124 if ( aColor.GetColor() == COL_AUTO )
1125 aColor.SetColor( COL_BLACK );
1127 ((aStr += ' ') += OOO_STRING_SVTOOLS_HTML_O_color) += '=';
1128 lcl_AppendHTMLColorTripel( aStr, aColor );
1130 TAG_ON( aStr.GetBuffer() );
1133 String aStrOut;
1134 BOOL bFieldText = FALSE;
1135 if ( pCell )
1136 { // cell content
1137 Color* pColor;
1138 switch ( pCell->GetCellType() )
1140 case CELLTYPE_NOTE :
1141 // nothing
1142 break;
1143 case CELLTYPE_EDIT :
1144 bFieldText = WriteFieldText( (const ScEditCell*) pCell );
1145 if ( bFieldText )
1146 break;
1147 //! else: fallthru
1148 default:
1149 ScCellFormat::GetString( pCell, nFormat, aStrOut, &pColor, *pFormatter );
1152 if ( !bFieldText )
1154 if ( !aStrOut.Len() )
1156 TAG_ON( OOO_STRING_SVTOOLS_HTML_linebreak ); // #42573# keine komplett leere Zelle
1158 else
1160 xub_StrLen nPos = aStrOut.Search( _LF );
1161 if ( nPos == STRING_NOTFOUND )
1163 OUT_STR( aStrOut );
1165 else
1167 xub_StrLen nStartPos = 0;
1170 String aSingleLine( aStrOut, nStartPos, nPos - nStartPos );
1171 OUT_STR( aSingleLine );
1172 TAG_ON( OOO_STRING_SVTOOLS_HTML_linebreak );
1173 nStartPos = nPos + 1;
1175 while( ( nPos = aStrOut.Search( _LF, nStartPos ) ) != STRING_NOTFOUND );
1176 String aSingleLine( aStrOut, nStartPos, aStrOut.Len() - nStartPos );
1177 OUT_STR( aSingleLine );
1181 if ( pGraphEntry )
1182 WriteGraphEntry( pGraphEntry );
1184 if ( bSetFont ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_font );
1185 if ( bUnderline ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_underline );
1186 if ( bItalic ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_italic );
1187 if ( bBold ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_bold );
1189 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tabledata );
1193 BOOL ScHTMLExport::WriteFieldText( const ScEditCell* pCell )
1195 BOOL bFields = FALSE;
1196 const EditTextObject* pData;
1197 pCell->GetData( pData );
1198 // text and anchor of URL fields, Doc-Engine is a ScFieldEditEngine
1199 EditEngine& rEngine = pDoc->GetEditEngine();
1200 rEngine.SetText( *pData );
1201 USHORT nParas = rEngine.GetParagraphCount();
1202 if ( nParas )
1204 ESelection aSel( 0, 0, nParas-1, rEngine.GetTextLen( nParas-1 ) );
1205 SfxItemSet aSet( rEngine.GetAttribs( aSel ) );
1206 SfxItemState eFieldState = aSet.GetItemState( EE_FEATURE_FIELD, FALSE );
1207 if ( eFieldState == SFX_ITEM_DONTCARE || eFieldState == SFX_ITEM_SET )
1208 bFields = TRUE;
1210 if ( bFields )
1212 BOOL bOldUpdateMode = rEngine.GetUpdateMode();
1213 rEngine.SetUpdateMode( TRUE ); // no portions if not formatted
1214 for ( USHORT nPar=0; nPar < nParas; nPar++ )
1216 if ( nPar > 0 )
1217 TAG_ON( OOO_STRING_SVTOOLS_HTML_linebreak );
1218 SvUShorts aPortions;
1219 rEngine.GetPortions( nPar, aPortions );
1220 USHORT nCnt = aPortions.Count();
1221 USHORT nStart = 0;
1222 for ( USHORT nPos = 0; nPos < nCnt; nPos++ )
1224 USHORT nEnd = aPortions.GetObject( nPos );
1225 ESelection aSel( nPar, nStart, nPar, nEnd );
1226 BOOL bUrl = FALSE;
1227 // fields are single characters
1228 if ( nEnd == nStart+1 )
1230 const SfxPoolItem* pItem;
1231 SfxItemSet aSet = rEngine.GetAttribs( aSel );
1232 if ( aSet.GetItemState( EE_FEATURE_FIELD, FALSE, &pItem ) == SFX_ITEM_ON )
1234 const SvxFieldData* pField = ((const SvxFieldItem*)pItem)->GetField();
1235 if ( pField && pField->ISA(SvxURLField) )
1237 bUrl = TRUE;
1238 const SvxURLField* pURLField = (const SvxURLField*)pField;
1239 // String aFieldText = rEngine.GetText( aSel );
1240 rStrm << '<' << OOO_STRING_SVTOOLS_HTML_anchor << ' ' << OOO_STRING_SVTOOLS_HTML_O_href << "=\"";
1241 OUT_STR( pURLField->GetURL() );
1242 rStrm << "\">";
1243 OUT_STR( pURLField->GetRepresentation() );
1244 rStrm << "</" << OOO_STRING_SVTOOLS_HTML_anchor << '>';
1248 if ( !bUrl )
1249 OUT_STR( rEngine.GetText( aSel ) );
1250 nStart = nEnd;
1253 rEngine.SetUpdateMode( bOldUpdateMode );
1255 return bFields;
1259 BOOL ScHTMLExport::CopyLocalFileToINet( String& rFileNm,
1260 const String& rTargetNm, BOOL bFileToFile )
1262 BOOL bRet = FALSE;
1263 INetURLObject aFileUrl, aTargetUrl;
1264 aFileUrl.SetSmartURL( rFileNm );
1265 aTargetUrl.SetSmartURL( rTargetNm );
1266 if( INET_PROT_FILE == aFileUrl.GetProtocol() &&
1267 ( (bFileToFile && INET_PROT_FILE == aTargetUrl.GetProtocol()) ||
1268 (!bFileToFile && INET_PROT_FILE != aTargetUrl.GetProtocol() &&
1269 INET_PROT_FTP <= aTargetUrl.GetProtocol() &&
1270 INET_PROT_NEWS >= aTargetUrl.GetProtocol()) ) )
1272 if( pSrcArr )
1274 // wurde die Datei schon verschoben
1275 USHORT nPos;
1276 if( pSrcArr->Seek_Entry( &rFileNm, &nPos ))
1278 rFileNm = *(*pDestArr)[ nPos ];
1279 return TRUE;
1282 else
1284 pSrcArr = new SvStringsSortDtor( 4, 4 );
1285 pDestArr = new SvStringsSortDtor( 4, 4 );
1288 String* pSrc = new String( rFileNm );
1289 SvFileStream aTmp( aFileUrl.PathToFileName(), STREAM_READ );
1291 String* pDest = new String( aTargetUrl.GetPartBeforeLastName() );
1292 *pDest += String(aFileUrl.GetName());
1294 if( bFileToFile )
1296 INetURLObject aCpyURL( *pDest );
1297 SvFileStream aCpy( aCpyURL.PathToFileName(), STREAM_WRITE );
1298 aCpy << aTmp;
1300 aCpy.Close();
1301 bRet = SVSTREAM_OK == aCpy.GetError();
1303 else
1305 SfxMedium aMedium( *pDest, STREAM_WRITE | STREAM_SHARE_DENYNONE,
1306 FALSE );
1308 // temp. File anlegen
1309 // aMedium.DownLoad();
1312 SvFileStream aCpy( aMedium.GetPhysicalName(), STREAM_WRITE );
1313 aCpy << aTmp;
1316 // uebertragen
1317 aMedium.Close();
1318 aMedium.Commit();
1320 bRet = 0 == aMedium.GetError();
1323 if( bRet )
1325 pSrcArr->Insert( pSrc );
1326 pDestArr->Insert( pDest );
1327 rFileNm = *pDest;
1329 else
1331 delete pSrc;
1332 delete pDest;
1336 return bRet;
1340 void ScHTMLExport::MakeCIdURL( String& rURL )
1342 if( !aCId.Len() )
1343 return;
1345 INetURLObject aURLObj( rURL );
1346 if( INET_PROT_FILE != aURLObj.GetProtocol() )
1347 return;
1349 String aLastName( aURLObj.GetLastName() );
1350 DBG_ASSERT( aLastName.Len(), "Dateiname ohne Laenge!" );
1351 aLastName.ToLowerAscii();
1353 rURL.AssignAscii( "cid:" );
1354 rURL += aLastName;
1355 rURL.AppendAscii( "." );
1356 rURL += aCId;
1360 void ScHTMLExport::IncIndent( short nVal )
1362 sIndent[nIndent] = '\t';
1363 nIndent = nIndent + nVal;
1364 if ( nIndent < 0 )
1365 nIndent = 0;
1366 else if ( nIndent > nIndentMax )
1367 nIndent = nIndentMax;
1368 sIndent[nIndent] = 0;