merged tag ooo/OOO330_m14
[LibreOffice.git] / sc / source / filter / html / htmlexp.cxx
blobb4d764dc74a775e99b09097ecbb49193c92a1dde
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
33 // INCLUDE ---------------------------------------------------------------
35 #include "scitems.hxx"
36 #include <editeng/eeitem.hxx>
38 #define _SVSTDARR_STRINGSSORTDTOR
39 #include <rtl/tencinfo.h>
41 #include <vcl/svapp.hxx>
42 #include <svx/algitem.hxx>
43 #include <editeng/boxitem.hxx>
44 #include <editeng/brshitem.hxx>
45 #include <editeng/colritem.hxx>
46 #include <editeng/fhgtitem.hxx>
47 #include <editeng/fontitem.hxx>
48 #include <editeng/postitem.hxx>
49 #include <editeng/udlnitem.hxx>
50 #include <editeng/wghtitem.hxx>
51 #include <svx/xoutbmp.hxx>
52 #include <editeng/editeng.hxx>
53 #include <svtools/htmlcfg.hxx>
54 #include <sfx2/docfile.hxx>
55 #include <sfx2/frmhtmlw.hxx>
56 #include <sfx2/objsh.hxx>
57 #include <svl/stritem.hxx>
58 #include <svl/urihelper.hxx>
59 #ifndef _SVSTDARR_USHORTS
60 #define _SVSTDARR_USHORTS
61 #endif
62 #include <svl/svstdarr.hxx>
63 #include <svl/zforlist.hxx>
64 #include <svtools/htmlkywd.hxx>
65 #include <svtools/htmlout.hxx>
66 #include <svtools/parhtml.hxx>
67 #include <vcl/outdev.hxx>
68 #include <stdio.h>
70 #include "htmlexp.hxx"
71 #include "filter.hxx"
72 #include "global.hxx"
73 #include "document.hxx"
74 #include "scitems.hxx"
75 #include "attrib.hxx"
76 #include "patattr.hxx"
77 #include "stlpool.hxx"
78 #include "scresid.hxx"
79 #include "cell.hxx"
80 #include "cellform.hxx"
81 #include "docoptio.hxx"
82 #include "editutil.hxx"
83 #include "ftools.hxx"
86 #include <editeng/flditem.hxx>
87 #include <editeng/borderline.hxx>
88 #include <unotools/syslocale.hxx>
91 // ohne sc.hrc: error C2679: binary '=' : no operator defined which takes a
92 // right-hand operand of type 'const class String (__stdcall *)(class ScResId)'
93 // bei
94 // const String aStrTable( ScResId( SCSTR_TABLE ) ); aStrOut = aStrTable;
95 // ?!???
96 #include "sc.hrc"
97 #include "globstr.hrc"
99 #include <com/sun/star/uno/Reference.h>
100 #include <com/sun/star/document/XDocumentProperties.hpp>
101 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
104 //========================================================================
106 const static sal_Char __FAR_DATA sMyBegComment[] = "<!-- ";
107 const static sal_Char __FAR_DATA sMyEndComment[] = " -->";
108 const static sal_Char __FAR_DATA sFontFamily[] = "font-family:";
109 const static sal_Char __FAR_DATA sFontSize[] = "font-size:";
111 const USHORT __FAR_DATA ScHTMLExport::nDefaultFontSize[SC_HTML_FONTSIZES] =
113 HTMLFONTSZ1_DFLT, HTMLFONTSZ2_DFLT, HTMLFONTSZ3_DFLT, HTMLFONTSZ4_DFLT,
114 HTMLFONTSZ5_DFLT, HTMLFONTSZ6_DFLT, HTMLFONTSZ7_DFLT
117 USHORT ScHTMLExport::nFontSize[SC_HTML_FONTSIZES] = { 0 };
119 const char* __FAR_DATA ScHTMLExport::pFontSizeCss[SC_HTML_FONTSIZES] =
121 "xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large"
124 const USHORT ScHTMLExport::nCellSpacing = 0;
125 const sal_Char __FAR_DATA ScHTMLExport::sIndentSource[nIndentMax+1] =
126 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
128 //========================================================================
129 // Makros fuer HTML-Export
130 //========================================================================
131 #define OUT_PROLOGUE() (rStrm << sHTML30_Prologue << ScExportBase::sNewLine \
132 << ScExportBase::sNewLine)
133 #define TAG_ON( tag ) HTMLOutFuncs::Out_AsciiTag( rStrm, tag )
134 #define TAG_OFF( tag ) HTMLOutFuncs::Out_AsciiTag( rStrm, tag, FALSE )
135 #define OUT_STR( str ) HTMLOutFuncs::Out_String( rStrm, str, eDestEnc, &aNonConvertibleChars )
136 #define OUT_STR_NO_CONV( str ) HTMLOutFuncs::Out_String( rStrm, str, eDestEnc )
137 #define OUT_LF() rStrm << ScExportBase::sNewLine << GetIndentStr()
138 #define lcl_OUT_LF() rStrm << ScExportBase::sNewLine
139 #define TAG_ON_LF( tag ) (TAG_ON( tag ) << ScExportBase::sNewLine << GetIndentStr())
140 #define TAG_OFF_LF( tag ) (TAG_OFF( tag ) << ScExportBase::sNewLine << GetIndentStr())
141 #define OUT_HR() TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_horzrule )
142 #define OUT_COMMENT( comment ) (rStrm << sMyBegComment, OUT_STR( comment ) \
143 << sMyEndComment << ScExportBase::sNewLine \
144 << GetIndentStr())
145 #define lcl_OUT_COMMENT( comment ) (rStrm << sMyBegComment, OUT_STR_NO_CONV( comment ) \
146 << sMyEndComment << ScExportBase::sNewLine)
148 #define OUT_SP_CSTR_ASS( s ) rStrm << ' ' << s << '='
149 #define APPEND_SPACE( s ) s.AppendAscii(" ")
151 #define GLOBSTR(id) ScGlobal::GetRscString( id )
155 //========================================================================
157 FltError ScFormatFilterPluginImpl::ScExportHTML( SvStream& rStrm, const String& rBaseURL, ScDocument* pDoc,
158 const ScRange& rRange, const CharSet /*eNach*/, BOOL bAll,
159 const String& rStreamPath, String& rNonConvertibleChars )
161 ScHTMLExport aEx( rStrm, rBaseURL, pDoc, rRange, bAll, rStreamPath );
162 FltError nErr = aEx.Write();
163 rNonConvertibleChars = aEx.GetNonConvertibleChars();
164 return nErr;
168 void lcl_AddStamp( String& rStr, const String& rName,
169 const ::com::sun::star::util::DateTime& rDateTime,
170 const LocaleDataWrapper& rLoc )
172 Date aD(rDateTime.Day, rDateTime.Month, rDateTime.Year);
173 Time aT(rDateTime.Hours, rDateTime.Minutes, rDateTime.Seconds,
174 rDateTime.HundredthSeconds);
175 DateTime aDateTime(aD,aT);
177 String aStrDate = rLoc.getDate( aDateTime );
178 String aStrTime = rLoc.getTime( aDateTime );
180 rStr += GLOBSTR( STR_BY );
181 APPEND_SPACE( rStr );
182 if (rName.Len())
183 rStr += rName;
184 else
185 rStr.AppendAscii( "???" );
186 APPEND_SPACE( rStr );
187 rStr += GLOBSTR( STR_ON );
188 APPEND_SPACE( rStr );
189 if (aStrDate.Len())
190 rStr += aStrDate;
191 else
192 rStr.AppendAscii( "???" );
193 rStr.AppendAscii( ", " );
194 if (aStrTime.Len())
195 rStr += aStrTime;
196 else
197 rStr.AppendAscii( "???" );
201 void lcl_AppendHTMLColorTripel( ByteString& rStr, const Color& rColor )
203 // <font COLOR="#00FF40">hallo</font>
204 sal_Char buf[64];
205 sal_Char* p = buf;
207 rStr += "\"#";
208 p += sprintf( p, "%02X", rColor.GetRed() ); // #100211# - checked
209 p += sprintf( p, "%02X", rColor.GetGreen() ); // #100211# - checked
210 p += sprintf( p, "%02X", rColor.GetBlue() ); // #100211# - checked
211 rStr += buf;
212 rStr += '\"';
216 /*void lcl_TagOn( String& rResult, const String& rTag, const String* pStrOpt )
218 rResult = '<';
219 rResult += rTag;
220 if ( pStrOpt )
222 rResult += ' ';
223 rResult += *pStrOpt;
225 rResult += '>';
229 /*void lcl_TagOff( String& rResult, const String& rTag )
231 rResult = '<'; rResult += rTag; rResult += '>';
235 //////////////////////////////////////////////////////////////////////////////
237 ScHTMLExport::ScHTMLExport( SvStream& rStrmP, const String& rBaseURL, ScDocument* pDocP,
238 const ScRange& rRangeP,
239 BOOL bAllP, const String& rStreamPathP ) :
240 ScExportBase( rStrmP, pDocP, rRangeP ),
241 aBaseURL( rBaseURL ),
242 aStreamPath( rStreamPathP ),
243 pAppWin( Application::GetDefaultDevice() ),
244 pSrcArr( NULL ),
245 pDestArr( NULL ),
246 nUsedTables( 0 ),
247 nIndent( 0 ),
248 bAll( bAllP ),
249 bTabHasGraphics( FALSE ),
250 bCalcAsShown( pDocP->GetDocOptions().IsCalcAsShown() ),
251 bTableDataWidth( TRUE ),
252 bTableDataHeight( TRUE )
254 strcpy( sIndent, sIndentSource ); // #100211# - checked
255 sIndent[0] = 0;
257 // set HTML configuration
258 SvxHtmlOptions* pHtmlOptions = SvxHtmlOptions::Get();
259 eDestEnc = (pDoc->IsClipOrUndo() ? RTL_TEXTENCODING_UTF8 : pHtmlOptions->GetTextEncoding());
260 bCopyLocalFileToINet = pHtmlOptions->IsSaveGraphicsLocal();
261 for ( USHORT j=0; j < SC_HTML_FONTSIZES; j++ )
263 USHORT nSize = pHtmlOptions->GetFontSize( j );
264 // remember in Twips, like our SvxFontHeightItem
265 if ( nSize )
266 nFontSize[j] = nSize * 20;
267 else
268 nFontSize[j] = nDefaultFontSize[j] * 20;
271 const SCTAB nCount = pDoc->GetTableCount();
272 for ( SCTAB nTab = 0; nTab < nCount; nTab++ )
274 if ( !IsEmptyTable( nTab ) )
275 nUsedTables++;
278 // Content-Id fuer Mail-Export?
279 SfxObjectShell* pDocSh = pDoc->GetDocumentShell();
280 if ( pDocSh )
282 const SfxPoolItem* pItem = pDocSh->GetItem( SID_ORIGURL );
283 if( pItem )
285 aCId = ((const SfxStringItem *)pItem)->GetValue();
286 DBG_ASSERT( aCId.Len(), "CID ohne Laenge!" );
292 ScHTMLExport::~ScHTMLExport()
294 for ( ScHTMLGraphEntry* pE = aGraphList.First(); pE; pE = aGraphList.Next() )
295 delete pE;
296 delete pSrcArr;
297 delete pDestArr;
301 USHORT ScHTMLExport::GetFontSizeNumber( USHORT nHeight )
303 USHORT nSize = 1;
304 for ( USHORT j=SC_HTML_FONTSIZES-1; j>0; j-- )
306 if( nHeight > (nFontSize[j] + nFontSize[j-1]) / 2 )
307 { // der naechstgelegene
308 nSize = j+1;
309 break;
312 return nSize;
315 const char* ScHTMLExport::GetFontSizeCss( USHORT nHeight )
317 USHORT nSize = GetFontSizeNumber( nHeight );
318 return pFontSizeCss[ nSize-1 ];
322 USHORT ScHTMLExport::ToPixel( USHORT nVal )
324 if( nVal )
326 nVal = (USHORT)pAppWin->LogicToPixel(
327 Size( nVal, nVal ), MapMode( MAP_TWIP ) ).Width();
328 if( !nVal ) // wo ein Twip ist sollte auch ein Pixel sein
329 nVal = 1;
331 return nVal;
335 Size ScHTMLExport::MMToPixel( const Size& rSize )
337 Size aSize( rSize );
338 aSize = pAppWin->LogicToPixel( rSize, MapMode( MAP_100TH_MM ) );
339 // wo etwas ist sollte auch ein Pixel sein
340 if ( !aSize.Width() && rSize.Width() )
341 aSize.Width() = 1;
342 if ( !aSize.Height() && rSize.Height() )
343 aSize.Height() = 1;
344 return aSize;
348 ULONG ScHTMLExport::Write()
350 rStrm << '<' << OOO_STRING_SVTOOLS_HTML_doctype << ' ' << OOO_STRING_SVTOOLS_HTML_doctype32 << '>'
351 << sNewLine << sNewLine;
352 TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_html );
353 WriteHeader();
354 OUT_LF();
355 WriteBody();
356 OUT_LF();
357 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_html );
359 return rStrm.GetError();
363 void ScHTMLExport::WriteHeader()
365 IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_head );
367 if ( pDoc->IsClipOrUndo() )
368 { // no real DocInfo available, but some META information like charset needed
369 SfxFrameHTMLWriter::Out_DocInfo( rStrm, aBaseURL, NULL, sIndent, eDestEnc, &aNonConvertibleChars );
371 else
373 using namespace ::com::sun::star;
374 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
375 pDoc->GetDocumentShell()->GetModel(), uno::UNO_QUERY_THROW);
376 uno::Reference<document::XDocumentProperties> xDocProps
377 = xDPS->getDocumentProperties();
378 SfxFrameHTMLWriter::Out_DocInfo( rStrm, aBaseURL, xDocProps,
379 sIndent, eDestEnc, &aNonConvertibleChars );
380 OUT_LF();
382 //----------------------------------------------------------
383 if (!xDocProps->getPrintedBy().equalsAscii(""))
385 OUT_COMMENT( GLOBSTR( STR_DOC_INFO ) );
386 String aStrOut( GLOBSTR( STR_DOC_PRINTED ) );
387 aStrOut.AppendAscii( ": " );
388 lcl_AddStamp( aStrOut, xDocProps->getPrintedBy(),
389 xDocProps->getPrintDate(), *ScGlobal::pLocaleData );
390 OUT_COMMENT( aStrOut );
392 //----------------------------------------------------------
394 OUT_LF();
396 // CSS1 StyleSheet
397 PageDefaults( bAll ? 0 : aRange.aStart.Tab() );
398 IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_style );
399 rStrm << sMyBegComment; OUT_LF();
400 rStrm << OOO_STRING_SVTOOLS_HTML_body << "," << OOO_STRING_SVTOOLS_HTML_division << "," << OOO_STRING_SVTOOLS_HTML_table << ","
401 << OOO_STRING_SVTOOLS_HTML_thead << "," << OOO_STRING_SVTOOLS_HTML_tbody << "," << OOO_STRING_SVTOOLS_HTML_tfoot << ","
402 << OOO_STRING_SVTOOLS_HTML_tablerow << "," << OOO_STRING_SVTOOLS_HTML_tableheader << ","
403 << OOO_STRING_SVTOOLS_HTML_tabledata << "," << OOO_STRING_SVTOOLS_HTML_parabreak << " { " << sFontFamily;
404 xub_StrLen nFonts = aHTMLStyle.aFontFamilyName.GetTokenCount( ';' );
405 if ( nFonts == 1 )
407 rStrm << '\"';
408 OUT_STR( aHTMLStyle.aFontFamilyName );
409 rStrm << '\"';
411 else
412 { // Fontliste, VCL: Semikolon als Separator,
413 // CSS1: Komma als Separator und jeder einzelne Fontname quoted
414 const String& rList = aHTMLStyle.aFontFamilyName;
415 for ( xub_StrLen j = 0, nPos = 0; j < nFonts; j++ )
417 rStrm << '\"';
418 OUT_STR( rList.GetToken( 0, ';', nPos ) );
419 rStrm << '\"';
420 if ( j < nFonts-1 )
421 rStrm << ", ";
424 rStrm << "; " << sFontSize
425 << GetFontSizeCss( ( USHORT ) aHTMLStyle.nFontHeight ) << " }";
426 OUT_LF();
427 rStrm << sMyEndComment;
428 IncIndent(-1); OUT_LF(); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_style );
430 IncIndent(-1); OUT_LF(); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_head );
434 void ScHTMLExport::WriteOverview()
436 if ( nUsedTables > 1 )
438 IncIndent(1);
439 OUT_HR();
440 IncIndent(1); TAG_ON( OOO_STRING_SVTOOLS_HTML_parabreak ); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_center );
441 TAG_ON( OOO_STRING_SVTOOLS_HTML_head1 );
442 OUT_STR( ScGlobal::GetRscString( STR_OVERVIEW ) );
443 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_head1 );
445 String aStr;
447 const SCTAB nCount = pDoc->GetTableCount();
448 for ( SCTAB nTab = 0; nTab < nCount; nTab++ )
450 if ( !IsEmptyTable( nTab ) )
452 pDoc->GetName( nTab, aStr );
453 rStrm << "<A HREF=\"#table"
454 << ByteString::CreateFromInt32( nTab ).GetBuffer()
455 << "\">";
456 OUT_STR( aStr );
457 rStrm << "</A>";
458 TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_linebreak );
462 IncIndent(-1); OUT_LF();
463 IncIndent(-1); TAG_OFF( OOO_STRING_SVTOOLS_HTML_center ); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_parabreak );
468 const SfxItemSet& ScHTMLExport::PageDefaults( SCTAB nTab )
470 SfxStyleSheetBasePool* pStylePool = pDoc->GetStyleSheetPool();
471 SfxStyleSheetBase* pStyleSheet = NULL;
472 DBG_ASSERT( pStylePool, "StylePool not found! :-(" );
474 // remember defaults for compare in WriteCell
475 if ( !aHTMLStyle.bInitialized )
477 pStylePool->SetSearchMask( SFX_STYLE_FAMILY_PARA, SFXSTYLEBIT_ALL );
478 pStyleSheet = pStylePool->Find(
479 ScGlobal::GetRscString(STR_STYLENAME_STANDARD),
480 SFX_STYLE_FAMILY_PARA );
481 DBG_ASSERT( pStyleSheet, "ParaStyle not found! :-(" );
482 if (!pStyleSheet)
483 pStyleSheet = pStylePool->First();
484 const SfxItemSet& rSetPara = pStyleSheet->GetItemSet();
486 aHTMLStyle.nDefaultScriptType = ScGlobal::GetDefaultScriptType();
487 aHTMLStyle.aFontFamilyName = ((const SvxFontItem&)(rSetPara.Get(
488 ScGlobal::GetScriptedWhichID(
489 aHTMLStyle.nDefaultScriptType, ATTR_FONT
490 )))).GetFamilyName();
491 aHTMLStyle.nFontHeight = ((const SvxFontHeightItem&)(rSetPara.Get(
492 ScGlobal::GetScriptedWhichID(
493 aHTMLStyle.nDefaultScriptType, ATTR_FONT_HEIGHT
494 )))).GetHeight();
495 aHTMLStyle.nFontSizeNumber = GetFontSizeNumber( static_cast< USHORT >( aHTMLStyle.nFontHeight ) );
498 // Page style sheet printer settings, e.g. for background graphics.
499 // There's only one background graphic in HTML!
500 pStylePool->SetSearchMask( SFX_STYLE_FAMILY_PAGE, SFXSTYLEBIT_ALL );
501 pStyleSheet = pStylePool->Find( pDoc->GetPageStyle( nTab ), SFX_STYLE_FAMILY_PAGE );
502 DBG_ASSERT( pStyleSheet, "PageStyle not found! :-(" );
503 if (!pStyleSheet)
504 pStyleSheet = pStylePool->First();
505 const SfxItemSet& rSet = pStyleSheet->GetItemSet();
506 if ( !aHTMLStyle.bInitialized )
508 const SvxBrushItem* pBrushItem = (const SvxBrushItem*)&rSet.Get( ATTR_BACKGROUND );
509 aHTMLStyle.aBackgroundColor = pBrushItem->GetColor();
510 aHTMLStyle.bInitialized = TRUE;
512 return rSet;
516 void ScHTMLExport::BorderToStyle( ByteString& rOut, const char* pBorderName,
517 const SvxBorderLine* pLine, bool& bInsertSemicolon )
519 if ( pLine )
521 if ( bInsertSemicolon )
522 rOut += "; ";
524 // which border
525 ((rOut += "border-") += pBorderName) += ": ";
527 // thickness
528 int nWidth = pLine->GetOutWidth();
529 int nPxWidth = ( nWidth > 0 )? std::max( int( nWidth / TWIPS_PER_PIXEL ), 1 ): 0;
530 (rOut += ByteString::CreateFromInt32( nPxWidth )) += "px solid #";
532 // color
533 char hex[7];
534 snprintf( hex, 7, "%06x", static_cast< unsigned int >( pLine->GetColor().GetRGBColor() ) );
535 hex[6] = 0;
537 rOut += hex;
539 bInsertSemicolon = true;
543 void ScHTMLExport::WriteBody()
545 const SfxItemSet& rSet = PageDefaults( bAll ? 0 : aRange.aStart.Tab() );
546 const SvxBrushItem* pBrushItem = (const SvxBrushItem*)&rSet.Get( ATTR_BACKGROUND );
548 // default Textfarbe schwarz
549 rStrm << '<' << OOO_STRING_SVTOOLS_HTML_body << ' ' << OOO_STRING_SVTOOLS_HTML_O_text << "=\"#000000\"";
551 if ( bAll && GPOS_NONE != pBrushItem->GetGraphicPos() )
553 const String* pLink = pBrushItem->GetGraphicLink();
554 String aGrfNm;
556 // embeddete Grafik -> via WriteGraphic schreiben
557 if( !pLink )
559 const Graphic* pGrf = pBrushItem->GetGraphic();
560 if( pGrf )
562 // Grafik als (JPG-)File speichern
563 aGrfNm = aStreamPath;
564 USHORT nErr = XOutBitmap::WriteGraphic( *pGrf, aGrfNm,
565 CREATE_STRING( "JPG" ), XOUTBMP_USE_NATIVE_IF_POSSIBLE );
566 if( !nErr ) // fehlerhaft, da ist nichts auszugeben
568 aGrfNm = URIHelper::SmartRel2Abs(
569 INetURLObject(aBaseURL),
570 aGrfNm, URIHelper::GetMaybeFileHdl(), true, false);
571 if ( HasCId() )
572 MakeCIdURL( aGrfNm );
573 pLink = &aGrfNm;
577 else
579 aGrfNm = *pLink;
580 if( bCopyLocalFileToINet || HasCId() )
582 CopyLocalFileToINet( aGrfNm, aStreamPath );
583 if ( HasCId() )
584 MakeCIdURL( aGrfNm );
586 else
587 aGrfNm = URIHelper::SmartRel2Abs(
588 INetURLObject(aBaseURL),
589 aGrfNm, URIHelper::GetMaybeFileHdl(), true, false);
590 pLink = &aGrfNm;
592 if( pLink )
594 rStrm << ' ' << OOO_STRING_SVTOOLS_HTML_O_background << "=\"";
595 OUT_STR( URIHelper::simpleNormalizedMakeRelative(
596 aBaseURL,
597 *pLink ) ) << '\"';
600 if ( !aHTMLStyle.aBackgroundColor.GetTransparency() )
601 { // A transparent background color should always result in default
602 // background of the browser. Also, HTMLOutFuncs::Out_Color() writes
603 // black #000000 for COL_AUTO which is the same as white #ffffff with
604 // transparency set to 0xff, our default background.
605 OUT_SP_CSTR_ASS( OOO_STRING_SVTOOLS_HTML_O_bgcolor );
606 HTMLOutFuncs::Out_Color( rStrm, aHTMLStyle.aBackgroundColor );
609 rStrm << '>'; OUT_LF();
611 if ( bAll )
612 WriteOverview();
614 WriteTables();
616 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_body );
620 void ScHTMLExport::WriteTables()
622 const SCTAB nTabCount = pDoc->GetTableCount();
623 const String aStrTable( ScResId( SCSTR_TABLE ) );
624 String aStr;
625 String aStrOut;
626 SCCOL nStartCol;
627 SCROW nStartRow;
628 SCTAB nStartTab;
629 SCCOL nEndCol;
630 SCROW nEndRow;
631 SCTAB nEndTab;
632 SCCOL nStartColFix = 0;
633 SCROW nStartRowFix = 0;
634 SCCOL nEndColFix = 0;
635 SCROW nEndRowFix = 0;
636 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
637 if ( bAll )
639 nStartTab = 0;
640 nEndTab = nTabCount - 1;
642 else
644 nStartCol = nStartColFix = aRange.aStart.Col();
645 nStartRow = nStartRowFix = aRange.aStart.Row();
646 nStartTab = aRange.aStart.Tab();
647 nEndCol = nEndColFix = aRange.aEnd.Col();
648 nEndRow = nEndRowFix = aRange.aEnd.Row();
649 nEndTab = aRange.aEnd.Tab();
651 SCTAB nTableStrNum = 1;
652 for ( SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++ )
654 if ( !pDoc->IsVisible( nTab ) )
655 continue; // for
657 if ( bAll )
659 if ( !GetDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow ) )
660 continue; // for
662 if ( nUsedTables > 1 )
664 aStrOut = aStrTable;
665 aStrOut.AppendAscii( " " );
666 aStrOut += String::CreateFromInt32( nTableStrNum++ );
667 aStrOut.AppendAscii( ": " );
669 OUT_HR();
671 // Anker festlegen:
672 rStrm << "<A NAME=\"table"
673 << ByteString::CreateFromInt32( nTab ).GetBuffer()
674 << "\">";
675 TAG_ON( OOO_STRING_SVTOOLS_HTML_head1 );
676 OUT_STR( aStrOut );
677 TAG_ON( OOO_STRING_SVTOOLS_HTML_emphasis );
679 pDoc->GetName( nTab, aStr );
680 OUT_STR( aStr );
682 TAG_OFF( OOO_STRING_SVTOOLS_HTML_emphasis );
683 TAG_OFF( OOO_STRING_SVTOOLS_HTML_head1 );
684 rStrm << "</A>"; OUT_LF();
687 else
689 nStartCol = nStartColFix;
690 nStartRow = nStartRowFix;
691 nEndCol = nEndColFix;
692 nEndRow = nEndRowFix;
693 if ( !TrimDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow ) )
694 continue; // for
697 // <TABLE ...>
698 ByteString aByteStrOut = OOO_STRING_SVTOOLS_HTML_table;
699 // aStrOut = OOO_STRING_SVTOOLS_HTML_table;
701 // FRAME=VOID, we do the styling of the cells in <TD>
702 (((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_frame) += '=') += OOO_STRING_SVTOOLS_HTML_TF_void;
704 bTabHasGraphics = bTabAlignedLeft = FALSE;
705 if ( bAll && pDrawLayer )
706 PrepareGraphics( pDrawLayer, nTab, nStartCol, nStartRow,
707 nEndCol, nEndRow );
709 // more <TABLE ...>
710 if ( bTabAlignedLeft )
711 (((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_align) += '=') += OOO_STRING_SVTOOLS_HTML_AL_left;
712 // ALIGN=LEFT allow text and graphics to flow around
713 // CELLSPACING
714 (((aByteStrOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_cellspacing ) += '=') +=
715 ByteString::CreateFromInt32( nCellSpacing );
716 // COLS=n
717 SCCOL nColCnt = 0;
718 SCCOL nCol;
719 for ( nCol=nStartCol; nCol<=nEndCol; nCol++ )
721 if ( !pDoc->ColHidden(nCol, nTab) )
722 ++nColCnt;
724 (((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_cols) += '=') += ByteString::CreateFromInt32( nColCnt );
726 // RULES=NONE, we do the styling of the cells in <TD>
727 (((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_rules) += '=') += OOO_STRING_SVTOOLS_HTML_TR_none;
729 // BORDER=0, we do the styling of the cells in <TD>
730 ((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_border) += "=0";
731 IncIndent(1); TAG_ON_LF( aByteStrOut.GetBuffer() );
733 // <COLGROUP>
734 TAG_ON( OOO_STRING_SVTOOLS_HTML_colgroup );
735 // <COL WIDTH=x> as pre-info for long tables
736 ByteString aByteStr = OOO_STRING_SVTOOLS_HTML_col;
737 aByteStr += ' ';
738 aByteStr += OOO_STRING_SVTOOLS_HTML_O_width;
739 aByteStr += '=';
740 for ( nCol=nStartCol; nCol<=nEndCol; nCol++ )
742 if ( pDoc->ColHidden(nCol, nTab) )
743 continue; // for
745 aByteStrOut = aByteStr;
746 aByteStrOut += ByteString::CreateFromInt32(
747 ToPixel( pDoc->GetColWidth( nCol, nTab ) ) );
748 TAG_ON( aByteStrOut.GetBuffer() );
750 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_colgroup );
752 // <TBODY>
753 IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_tbody );
754 // At least old (3.x, 4.x?) Netscape doesn't follow <TABLE COLS=n> and
755 // <COL WIDTH=x> specified, but needs a width at every column.
756 bTableDataWidth = TRUE; // widths in first row
757 bool bHasHiddenRows = pDoc->HasHiddenRows(nStartRow, nEndRow, nTab);
758 for ( SCROW nRow=nStartRow; nRow<=nEndRow; nRow++ )
760 if ( bHasHiddenRows && pDoc->RowHidden(nRow, nTab) )
762 nRow = pDoc->FirstVisibleRow(nRow+1, nEndRow, nTab);
763 --nRow;
764 continue; // for
767 IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_tablerow );
768 bTableDataHeight = TRUE; // height at every first cell of each row
769 for ( SCCOL nCol2=nStartCol; nCol2<=nEndCol; nCol2++ )
771 if ( pDoc->ColHidden(nCol2, nTab) )
772 continue; // for
774 if ( nCol2 == nEndCol )
775 IncIndent(-1);
776 WriteCell( nCol2, nRow, nTab );
777 bTableDataHeight = FALSE;
779 bTableDataWidth = FALSE; // widths only in first row
781 if ( nRow == nEndRow )
782 IncIndent(-1);
783 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tablerow );
785 IncIndent(-1); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tbody );
787 IncIndent(-1); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_table );
789 if ( bTabHasGraphics )
791 // the rest that is not in a cell
792 for ( ScHTMLGraphEntry* pE = aGraphList.First(); pE; pE = aGraphList.Next() )
794 if ( !pE->bWritten )
795 WriteGraphEntry( pE );
796 delete pE;
798 aGraphList.Clear();
799 if ( bTabAlignedLeft )
800 { // clear <TABLE ALIGN=LEFT> with <BR CLEAR=LEFT>
801 aByteStrOut = OOO_STRING_SVTOOLS_HTML_linebreak;
802 (((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_clear) += '=') += OOO_STRING_SVTOOLS_HTML_AL_left;
803 TAG_ON_LF( aByteStrOut.GetBuffer() );
807 if ( bAll )
808 OUT_COMMENT( CREATE_STRING( "**************************************************************************" ) );
813 void ScHTMLExport::WriteCell( SCCOL nCol, SCROW nRow, SCTAB nTab )
815 const ScPatternAttr* pAttr = pDoc->GetPattern( nCol, nRow, nTab );
816 const SfxItemSet* pCondItemSet = pDoc->GetCondResult( nCol, nRow, nTab );
818 const ScMergeFlagAttr& rMergeFlagAttr = (const ScMergeFlagAttr&) pAttr->GetItem( ATTR_MERGE_FLAG, pCondItemSet );
819 if ( rMergeFlagAttr.IsOverlapped() )
820 return ;
822 ScAddress aPos( nCol, nRow, nTab );
823 ScHTMLGraphEntry* pGraphEntry = NULL;
824 if ( bTabHasGraphics )
826 for ( pGraphEntry = aGraphList.First(); pGraphEntry;
827 pGraphEntry = aGraphList.Next() )
829 if ( pGraphEntry->bInCell && pGraphEntry->aRange.In( aPos ) )
831 if ( pGraphEntry->aRange.aStart == aPos )
832 break; // for
833 else
834 return ; // ist ein Col/RowSpan, Overlapped
839 ScBaseCell* pCell = pDoc->GetCell( aPos );
840 ULONG nFormat = pAttr->GetNumberFormat( pFormatter );
841 BOOL bValueData;
842 BYTE nScriptType;
843 if ( pCell )
845 bValueData = pCell->HasValueData();
846 nScriptType = pDoc->GetScriptType( nCol, nRow, nTab, pCell );
848 else
850 bValueData = FALSE;
851 nScriptType = 0;
853 if ( nScriptType == 0 )
854 nScriptType = aHTMLStyle.nDefaultScriptType;
857 ByteString aStrTD = OOO_STRING_SVTOOLS_HTML_tabledata;
859 // border of the cells
860 SvxBoxItem* pBorder = (SvxBoxItem*) pDoc->GetAttr( nCol, nRow, nTab, ATTR_BORDER );
861 if ( pBorder && (pBorder->GetTop() || pBorder->GetBottom() || pBorder->GetLeft() || pBorder->GetRight()) )
863 ((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_style) += "=\"";
865 bool bInsertSemicolon = false;
866 BorderToStyle( aStrTD, "top", pBorder->GetTop(), bInsertSemicolon );
867 BorderToStyle( aStrTD, "bottom", pBorder->GetBottom(), bInsertSemicolon );
868 BorderToStyle( aStrTD, "left", pBorder->GetLeft(), bInsertSemicolon );
869 BorderToStyle( aStrTD, "right", pBorder->GetRight(), bInsertSemicolon );
871 aStrTD += '"';
874 const sal_Char* pChar;
875 USHORT nWidthPixel;
876 USHORT nHeightPixel;
878 const ScMergeAttr& rMergeAttr = (const ScMergeAttr&) pAttr->GetItem( ATTR_MERGE, pCondItemSet );
879 if ( pGraphEntry || rMergeAttr.IsMerged() )
881 SCCOL nC, jC;
882 SCROW nR;
883 ULONG v;
884 if ( pGraphEntry )
885 nC = Max( SCCOL(pGraphEntry->aRange.aEnd.Col() - nCol + 1),
886 SCCOL(rMergeAttr.GetColMerge()) );
887 else
888 nC = rMergeAttr.GetColMerge();
889 if ( nC > 1 )
891 (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_colspan) += '=') += ByteString::CreateFromInt32( nC );
892 nC = nC + nCol;
893 for ( jC=nCol, v=0; jC<nC; jC++ )
894 v += pDoc->GetColWidth( jC, nTab );
895 nWidthPixel = ToPixel( static_cast< USHORT >( v ) );
897 else
898 nWidthPixel = ToPixel( pDoc->GetColWidth( nCol, nTab ) );
900 if ( pGraphEntry )
901 nR = Max( SCROW(pGraphEntry->aRange.aEnd.Row() - nRow + 1),
902 SCROW(rMergeAttr.GetRowMerge()) );
903 else
904 nR = rMergeAttr.GetRowMerge();
905 if ( nR > 1 )
907 (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_rowspan) += '=') += ByteString::CreateFromInt32( nR );
908 nR += nRow;
909 v = pDoc->GetRowHeight( nRow, nR-1, nTab );
910 nHeightPixel = ToPixel( static_cast< USHORT >( v ) );
912 else
913 nHeightPixel = ToPixel( pDoc->GetRowHeight( nRow, nTab ) );
915 else
917 nWidthPixel = ToPixel( pDoc->GetColWidth( nCol, nTab ) );
918 nHeightPixel = ToPixel( pDoc->GetRowHeight( nRow, nTab ) );
921 if ( bTableDataWidth )
922 (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_width) += '=') += ByteString::CreateFromInt32( nWidthPixel );
923 if ( bTableDataHeight )
924 (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_height) += '=') += ByteString::CreateFromInt32( nHeightPixel );
926 const SvxFontItem& rFontItem = (const SvxFontItem&) pAttr->GetItem(
927 ScGlobal::GetScriptedWhichID( nScriptType, ATTR_FONT),
928 pCondItemSet);
930 const SvxFontHeightItem& rFontHeightItem = (const SvxFontHeightItem&)
931 pAttr->GetItem( ScGlobal::GetScriptedWhichID( nScriptType,
932 ATTR_FONT_HEIGHT), pCondItemSet);
934 const SvxWeightItem& rWeightItem = (const SvxWeightItem&) pAttr->GetItem(
935 ScGlobal::GetScriptedWhichID( nScriptType, ATTR_FONT_WEIGHT),
936 pCondItemSet);
938 const SvxPostureItem& rPostureItem = (const SvxPostureItem&)
939 pAttr->GetItem( ScGlobal::GetScriptedWhichID( nScriptType,
940 ATTR_FONT_POSTURE), pCondItemSet);
942 const SvxUnderlineItem& rUnderlineItem = (const SvxUnderlineItem&)
943 pAttr->GetItem( ATTR_FONT_UNDERLINE, pCondItemSet );
945 const SvxColorItem& rColorItem = (const SvxColorItem&) pAttr->GetItem(
946 ATTR_FONT_COLOR, pCondItemSet );
948 const SvxHorJustifyItem& rHorJustifyItem = (const SvxHorJustifyItem&)
949 pAttr->GetItem( ATTR_HOR_JUSTIFY, pCondItemSet );
951 const SvxVerJustifyItem& rVerJustifyItem = (const SvxVerJustifyItem&)
952 pAttr->GetItem( ATTR_VER_JUSTIFY, pCondItemSet );
954 const SvxBrushItem& rBrushItem = (const SvxBrushItem&) pAttr->GetItem(
955 ATTR_BACKGROUND, pCondItemSet );
957 Color aBgColor;
958 if ( rBrushItem.GetColor().GetTransparency() == 255 )
959 aBgColor = aHTMLStyle.aBackgroundColor; // #55121# keine ungewollte Hintergrundfarbe
960 else
961 aBgColor = rBrushItem.GetColor();
963 BOOL bBold = ( WEIGHT_BOLD <= rWeightItem.GetWeight() );
964 BOOL bItalic = ( ITALIC_NONE != rPostureItem.GetPosture() );
965 BOOL bUnderline = ( UNDERLINE_NONE != rUnderlineItem.GetLineStyle() );
966 BOOL bSetFontColor = ( COL_AUTO != rColorItem.GetValue().GetColor() ); // #97650# default is AUTO now
967 #if 0
968 // keine StyleSheet-Fontangaben: hart fuer jede Zelle
969 BOOL bSetFontName = TRUE;
970 USHORT nSetFontSizeNumber = GetFontSizeNumber( (USHORT)rFontHeightItem.GetHeight() );
971 #else
972 BOOL bSetFontName = ( aHTMLStyle.aFontFamilyName != rFontItem.GetFamilyName() );
973 USHORT nSetFontSizeNumber = 0;
974 UINT32 nFontHeight = rFontHeightItem.GetHeight();
975 if ( nFontHeight != aHTMLStyle.nFontHeight )
977 nSetFontSizeNumber = GetFontSizeNumber( (USHORT) nFontHeight );
978 if ( nSetFontSizeNumber == aHTMLStyle.nFontSizeNumber )
979 nSetFontSizeNumber = 0; // no difference, don't set
981 #endif
982 BOOL bSetFont = (bSetFontColor || bSetFontName || nSetFontSizeNumber);
984 //! TODO: we could entirely use CSS1 here instead, but that would exclude
985 //! Netscape 3.0 and Netscape 4.x without JavaScript enabled.
986 //! Do we want that?
988 switch( rHorJustifyItem.GetValue() )
990 case SVX_HOR_JUSTIFY_STANDARD:
991 pChar = (bValueData ? OOO_STRING_SVTOOLS_HTML_AL_right : OOO_STRING_SVTOOLS_HTML_AL_left);
992 break;
993 case SVX_HOR_JUSTIFY_CENTER: pChar = OOO_STRING_SVTOOLS_HTML_AL_center; break;
994 case SVX_HOR_JUSTIFY_BLOCK: pChar = OOO_STRING_SVTOOLS_HTML_AL_justify; break;
995 case SVX_HOR_JUSTIFY_RIGHT: pChar = OOO_STRING_SVTOOLS_HTML_AL_right; break;
996 case SVX_HOR_JUSTIFY_LEFT:
997 case SVX_HOR_JUSTIFY_REPEAT:
998 default: pChar = OOO_STRING_SVTOOLS_HTML_AL_left; break;
1001 (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_align) += '=') += pChar;
1003 switch( rVerJustifyItem.GetValue() )
1005 case SVX_VER_JUSTIFY_TOP: pChar = OOO_STRING_SVTOOLS_HTML_VA_top; break;
1006 case SVX_VER_JUSTIFY_CENTER: pChar = OOO_STRING_SVTOOLS_HTML_VA_middle; break;
1007 case SVX_VER_JUSTIFY_BOTTOM: pChar = OOO_STRING_SVTOOLS_HTML_VA_bottom; break;
1008 case SVX_VER_JUSTIFY_STANDARD:
1009 default: pChar = NULL;
1011 if ( pChar )
1012 (((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_valign) += '=') += pChar;
1014 if ( aHTMLStyle.aBackgroundColor != aBgColor )
1016 ((aStrTD += ' ') += OOO_STRING_SVTOOLS_HTML_O_bgcolor) += '=';
1017 lcl_AppendHTMLColorTripel( aStrTD, aBgColor );
1020 double fVal = 0.0;
1021 if ( bValueData )
1023 if ( pCell )
1025 switch ( pCell->GetCellType() )
1027 case CELLTYPE_VALUE:
1028 fVal = ((ScValueCell*)pCell)->GetValue();
1029 if ( bCalcAsShown && fVal != 0.0 )
1030 fVal = pDoc->RoundValueAsShown( fVal, nFormat );
1031 break;
1032 case CELLTYPE_FORMULA:
1033 fVal = ((ScFormulaCell*)pCell)->GetValue();
1034 if ( (nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 )
1035 nFormat = ScGlobal::GetStandardFormat( fVal, *pFormatter,
1036 nFormat, ((ScFormulaCell*)pCell)->GetFormatType() );
1037 break;
1038 default:
1039 DBG_ERRORFILE( "value data with unsupported cell type" );
1043 HTMLOutFuncs::CreateTableDataOptionsValNum( aStrTD, bValueData, fVal,
1044 nFormat, *pFormatter, eDestEnc, &aNonConvertibleChars );
1046 TAG_ON( aStrTD.GetBuffer() );
1048 if ( bBold ) TAG_ON( OOO_STRING_SVTOOLS_HTML_bold );
1049 if ( bItalic ) TAG_ON( OOO_STRING_SVTOOLS_HTML_italic );
1050 if ( bUnderline ) TAG_ON( OOO_STRING_SVTOOLS_HTML_underline );
1053 if ( bSetFont )
1055 ByteString aStr = OOO_STRING_SVTOOLS_HTML_font;
1056 if ( bSetFontName )
1058 ((aStr += ' ') += OOO_STRING_SVTOOLS_HTML_O_face) += "=\"";
1059 xub_StrLen nFonts = rFontItem.GetFamilyName().GetTokenCount( ';' );
1060 if ( nFonts == 1 )
1062 ByteString aTmpStr;
1063 HTMLOutFuncs::ConvertStringToHTML( rFontItem.GetFamilyName(),
1064 aTmpStr, eDestEnc, &aNonConvertibleChars );
1065 aStr += aTmpStr;
1067 else
1068 { // Fontliste, VCL: Semikolon als Separator, HTML: Komma
1069 const String& rList = rFontItem.GetFamilyName();
1070 for ( xub_StrLen j = 0, nPos = 0; j < nFonts; j++ )
1072 ByteString aTmpStr;
1073 HTMLOutFuncs::ConvertStringToHTML(
1074 rList.GetToken( 0, ';', nPos ), aTmpStr, eDestEnc,
1075 &aNonConvertibleChars );
1076 aStr += aTmpStr;
1077 if ( j < nFonts-1 )
1078 aStr += ',';
1081 aStr += '\"';
1083 if ( nSetFontSizeNumber )
1085 (((aStr += ' ') += OOO_STRING_SVTOOLS_HTML_O_size) += '=')
1086 += ByteString::CreateFromInt32( nSetFontSizeNumber );
1088 if ( bSetFontColor )
1090 Color aColor = rColorItem.GetValue();
1092 // always export automatic text color as black
1093 if ( aColor.GetColor() == COL_AUTO )
1094 aColor.SetColor( COL_BLACK );
1096 ((aStr += ' ') += OOO_STRING_SVTOOLS_HTML_O_color) += '=';
1097 lcl_AppendHTMLColorTripel( aStr, aColor );
1099 TAG_ON( aStr.GetBuffer() );
1102 String aStrOut;
1103 BOOL bFieldText = FALSE;
1104 if ( pCell )
1105 { // cell content
1106 Color* pColor;
1107 switch ( pCell->GetCellType() )
1109 case CELLTYPE_NOTE :
1110 // nothing
1111 break;
1112 case CELLTYPE_EDIT :
1113 bFieldText = WriteFieldText( (const ScEditCell*) pCell );
1114 if ( bFieldText )
1115 break;
1116 //! else: fallthru
1117 default:
1118 ScCellFormat::GetString( pCell, nFormat, aStrOut, &pColor, *pFormatter );
1121 if ( !bFieldText )
1123 if ( !aStrOut.Len() )
1125 TAG_ON( OOO_STRING_SVTOOLS_HTML_linebreak ); // #42573# keine komplett leere Zelle
1127 else
1129 xub_StrLen nPos = aStrOut.Search( _LF );
1130 if ( nPos == STRING_NOTFOUND )
1132 OUT_STR( aStrOut );
1134 else
1136 xub_StrLen nStartPos = 0;
1139 String aSingleLine( aStrOut, nStartPos, nPos - nStartPos );
1140 OUT_STR( aSingleLine );
1141 TAG_ON( OOO_STRING_SVTOOLS_HTML_linebreak );
1142 nStartPos = nPos + 1;
1144 while( ( nPos = aStrOut.Search( _LF, nStartPos ) ) != STRING_NOTFOUND );
1145 String aSingleLine( aStrOut, nStartPos, aStrOut.Len() - nStartPos );
1146 OUT_STR( aSingleLine );
1150 if ( pGraphEntry )
1151 WriteGraphEntry( pGraphEntry );
1153 if ( bSetFont ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_font );
1154 if ( bUnderline ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_underline );
1155 if ( bItalic ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_italic );
1156 if ( bBold ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_bold );
1158 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tabledata );
1162 BOOL ScHTMLExport::WriteFieldText( const ScEditCell* pCell )
1164 BOOL bFields = FALSE;
1165 const EditTextObject* pData;
1166 pCell->GetData( pData );
1167 // text and anchor of URL fields, Doc-Engine is a ScFieldEditEngine
1168 EditEngine& rEngine = pDoc->GetEditEngine();
1169 rEngine.SetText( *pData );
1170 USHORT nParas = rEngine.GetParagraphCount();
1171 if ( nParas )
1173 ESelection aSel( 0, 0, nParas-1, rEngine.GetTextLen( nParas-1 ) );
1174 SfxItemSet aSet( rEngine.GetAttribs( aSel ) );
1175 SfxItemState eFieldState = aSet.GetItemState( EE_FEATURE_FIELD, FALSE );
1176 if ( eFieldState == SFX_ITEM_DONTCARE || eFieldState == SFX_ITEM_SET )
1177 bFields = TRUE;
1179 if ( bFields )
1181 BOOL bOldUpdateMode = rEngine.GetUpdateMode();
1182 rEngine.SetUpdateMode( TRUE ); // no portions if not formatted
1183 for ( USHORT nPar=0; nPar < nParas; nPar++ )
1185 if ( nPar > 0 )
1186 TAG_ON( OOO_STRING_SVTOOLS_HTML_linebreak );
1187 SvUShorts aPortions;
1188 rEngine.GetPortions( nPar, aPortions );
1189 USHORT nCnt = aPortions.Count();
1190 USHORT nStart = 0;
1191 for ( USHORT nPos = 0; nPos < nCnt; nPos++ )
1193 USHORT nEnd = aPortions.GetObject( nPos );
1194 ESelection aSel( nPar, nStart, nPar, nEnd );
1195 BOOL bUrl = FALSE;
1196 // fields are single characters
1197 if ( nEnd == nStart+1 )
1199 const SfxPoolItem* pItem;
1200 SfxItemSet aSet = rEngine.GetAttribs( aSel );
1201 if ( aSet.GetItemState( EE_FEATURE_FIELD, FALSE, &pItem ) == SFX_ITEM_ON )
1203 const SvxFieldData* pField = ((const SvxFieldItem*)pItem)->GetField();
1204 if ( pField && pField->ISA(SvxURLField) )
1206 bUrl = TRUE;
1207 const SvxURLField* pURLField = (const SvxURLField*)pField;
1208 // String aFieldText = rEngine.GetText( aSel );
1209 rStrm << '<' << OOO_STRING_SVTOOLS_HTML_anchor << ' ' << OOO_STRING_SVTOOLS_HTML_O_href << "=\"";
1210 OUT_STR( pURLField->GetURL() );
1211 rStrm << "\">";
1212 OUT_STR( pURLField->GetRepresentation() );
1213 rStrm << "</" << OOO_STRING_SVTOOLS_HTML_anchor << '>';
1217 if ( !bUrl )
1218 OUT_STR( rEngine.GetText( aSel ) );
1219 nStart = nEnd;
1222 rEngine.SetUpdateMode( bOldUpdateMode );
1224 return bFields;
1228 BOOL ScHTMLExport::CopyLocalFileToINet( String& rFileNm,
1229 const String& rTargetNm, BOOL bFileToFile )
1231 BOOL bRet = FALSE;
1232 INetURLObject aFileUrl, aTargetUrl;
1233 aFileUrl.SetSmartURL( rFileNm );
1234 aTargetUrl.SetSmartURL( rTargetNm );
1235 if( INET_PROT_FILE == aFileUrl.GetProtocol() &&
1236 ( (bFileToFile && INET_PROT_FILE == aTargetUrl.GetProtocol()) ||
1237 (!bFileToFile && INET_PROT_FILE != aTargetUrl.GetProtocol() &&
1238 INET_PROT_FTP <= aTargetUrl.GetProtocol() &&
1239 INET_PROT_NEWS >= aTargetUrl.GetProtocol()) ) )
1241 if( pSrcArr )
1243 // wurde die Datei schon verschoben
1244 USHORT nPos;
1245 if( pSrcArr->Seek_Entry( &rFileNm, &nPos ))
1247 rFileNm = *(*pDestArr)[ nPos ];
1248 return TRUE;
1251 else
1253 pSrcArr = new SvStringsSortDtor( 4, 4 );
1254 pDestArr = new SvStringsSortDtor( 4, 4 );
1257 String* pSrc = new String( rFileNm );
1258 SvFileStream aTmp( aFileUrl.PathToFileName(), STREAM_READ );
1260 String* pDest = new String( aTargetUrl.GetPartBeforeLastName() );
1261 *pDest += String(aFileUrl.GetName());
1263 if( bFileToFile )
1265 INetURLObject aCpyURL( *pDest );
1266 SvFileStream aCpy( aCpyURL.PathToFileName(), STREAM_WRITE );
1267 aCpy << aTmp;
1269 aCpy.Close();
1270 bRet = SVSTREAM_OK == aCpy.GetError();
1272 else
1274 SfxMedium aMedium( *pDest, STREAM_WRITE | STREAM_SHARE_DENYNONE,
1275 FALSE );
1277 // temp. File anlegen
1278 // aMedium.DownLoad();
1281 SvFileStream aCpy( aMedium.GetPhysicalName(), STREAM_WRITE );
1282 aCpy << aTmp;
1285 // uebertragen
1286 aMedium.Close();
1287 aMedium.Commit();
1289 bRet = 0 == aMedium.GetError();
1292 if( bRet )
1294 pSrcArr->Insert( pSrc );
1295 pDestArr->Insert( pDest );
1296 rFileNm = *pDest;
1298 else
1300 delete pSrc;
1301 delete pDest;
1305 return bRet;
1309 void ScHTMLExport::MakeCIdURL( String& rURL )
1311 if( !aCId.Len() )
1312 return;
1314 INetURLObject aURLObj( rURL );
1315 if( INET_PROT_FILE != aURLObj.GetProtocol() )
1316 return;
1318 String aLastName( aURLObj.GetLastName() );
1319 DBG_ASSERT( aLastName.Len(), "Dateiname ohne Laenge!" );
1320 aLastName.ToLowerAscii();
1322 rURL.AssignAscii( "cid:" );
1323 rURL += aLastName;
1324 rURL.AppendAscii( "." );
1325 rURL += aCId;
1329 void ScHTMLExport::IncIndent( short nVal )
1331 sIndent[nIndent] = '\t';
1332 nIndent = nIndent + nVal;
1333 if ( nIndent < 0 )
1334 nIndent = 0;
1335 else if ( nIndent > nIndentMax )
1336 nIndent = nIndentMax;
1337 sIndent[nIndent] = 0;