1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <scitems.hxx>
21 #include <editeng/eeitem.hxx>
23 #include <vcl/svapp.hxx>
24 #include <editeng/boxitem.hxx>
25 #include <editeng/brushitem.hxx>
26 #include <editeng/colritem.hxx>
27 #include <editeng/crossedoutitem.hxx>
28 #include <editeng/fhgtitem.hxx>
29 #include <editeng/fontitem.hxx>
30 #include <editeng/postitem.hxx>
31 #include <editeng/udlnitem.hxx>
32 #include <editeng/wghtitem.hxx>
33 #include <editeng/justifyitem.hxx>
34 #include <svx/xoutbmp.hxx>
35 #include <editeng/editeng.hxx>
36 #include <svtools/htmlcfg.hxx>
37 #include <sfx2/docfile.hxx>
38 #include <sfx2/frmhtmlw.hxx>
39 #include <sfx2/objsh.hxx>
40 #include <svl/urihelper.hxx>
41 #include <svtools/htmlkywd.hxx>
42 #include <svtools/htmlout.hxx>
43 #include <svtools/parhtml.hxx>
44 #include <vcl/outdev.hxx>
46 #include <osl/diagnose.h>
48 #include <htmlexp.hxx>
51 #include <document.hxx>
53 #include <patattr.hxx>
54 #include <stlpool.hxx>
55 #include <scresid.hxx>
56 #include <formulacell.hxx>
57 #include <cellform.hxx>
58 #include <docoptio.hxx>
59 #include <editutil.hxx>
61 #include <cellvalue.hxx>
62 #include <mtvelements.hxx>
64 #include <editeng/flditem.hxx>
65 #include <editeng/borderline.hxx>
67 // Without strings.hrc: error C2679: binary '=' : no operator defined which takes a
68 // right-hand operand of type 'const class String (__stdcall *)(class ScResId)'
70 // const String aStrTable( ScResId( SCSTR_TABLE ) ); aStrOut = aStrTable;
72 #include <strings.hrc>
73 #include <globstr.hrc>
75 #include <com/sun/star/uno/Reference.h>
76 #include <com/sun/star/document/XDocumentProperties.hpp>
77 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
78 #include <rtl/strbuf.hxx>
80 using ::editeng::SvxBorderLine
;
81 using namespace ::com::sun::star
;
83 const static sal_Char sMyBegComment
[] = "<!-- ";
84 const static sal_Char sMyEndComment
[] = " -->";
85 const static sal_Char sDisplay
[] = "display:";
86 const static sal_Char sBorder
[] = "border:";
87 const static sal_Char sBackground
[] = "background:";
89 const sal_uInt16
ScHTMLExport::nDefaultFontSize
[SC_HTML_FONTSIZES
] =
91 HTMLFONTSZ1_DFLT
, HTMLFONTSZ2_DFLT
, HTMLFONTSZ3_DFLT
, HTMLFONTSZ4_DFLT
,
92 HTMLFONTSZ5_DFLT
, HTMLFONTSZ6_DFLT
, HTMLFONTSZ7_DFLT
95 sal_uInt16
ScHTMLExport::nFontSize
[SC_HTML_FONTSIZES
] = { 0 };
97 const char* ScHTMLExport::pFontSizeCss
[SC_HTML_FONTSIZES
] =
99 "xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large"
102 const sal_uInt16
ScHTMLExport::nCellSpacing
= 0;
103 const sal_Char
ScHTMLExport::sIndentSource
[nIndentMax
+1] =
104 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
106 // Macros for HTML export
108 #define TAG_ON( tag ) HTMLOutFuncs::Out_AsciiTag( rStrm, tag )
109 #define TAG_OFF( tag ) HTMLOutFuncs::Out_AsciiTag( rStrm, tag, false )
110 #define OUT_STR( str ) HTMLOutFuncs::Out_String( rStrm, str, eDestEnc, &aNonConvertibleChars )
111 #define OUT_LF() rStrm.WriteCharPtr( SAL_NEWLINE_STRING ).WriteCharPtr( GetIndentStr() )
112 #define TAG_ON_LF( tag ) (TAG_ON( tag ).WriteCharPtr( SAL_NEWLINE_STRING ).WriteCharPtr( GetIndentStr() ))
113 #define TAG_OFF_LF( tag ) (TAG_OFF( tag ).WriteCharPtr( SAL_NEWLINE_STRING ).WriteCharPtr( GetIndentStr() ))
114 #define OUT_HR() TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_horzrule )
115 #define OUT_COMMENT( comment ) (rStrm.WriteCharPtr( sMyBegComment ), OUT_STR( comment ) \
116 .WriteCharPtr( sMyEndComment ).WriteCharPtr( SAL_NEWLINE_STRING ) \
117 .WriteCharPtr( GetIndentStr() ))
119 #define OUT_SP_CSTR_ASS( s ) rStrm.WriteChar( ' ').WriteCharPtr( s ).WriteChar( '=' )
121 #define GLOBSTR(id) ScResId( id )
123 void ScFormatFilterPluginImpl::ScExportHTML( SvStream
& rStrm
, const OUString
& rBaseURL
, ScDocument
* pDoc
,
124 const ScRange
& rRange
, const rtl_TextEncoding
/*eNach*/, bool bAll
,
125 const OUString
& rStreamPath
, OUString
& rNonConvertibleChars
, const OUString
& rFilterOptions
)
127 ScHTMLExport
aEx( rStrm
, rBaseURL
, pDoc
, rRange
, bAll
, rStreamPath
, rFilterOptions
);
129 rNonConvertibleChars
= aEx
.GetNonConvertibleChars();
132 static OString
lcl_getColGroupString(sal_Int32 nSpan
, sal_Int32 nWidth
)
134 OStringBuffer
aByteStr(OOO_STRING_SVTOOLS_HTML_colgroup
);
135 aByteStr
.append(' ');
138 aByteStr
.append(OOO_STRING_SVTOOLS_HTML_O_span
);
139 aByteStr
.append("=\"");
140 aByteStr
.append(nSpan
);
141 aByteStr
.append("\" ");
143 aByteStr
.append(OOO_STRING_SVTOOLS_HTML_O_width
);
144 aByteStr
.append("=\"");
145 aByteStr
.append(nWidth
);
146 aByteStr
.append('"');
147 return aByteStr
.makeStringAndClear();
150 static void lcl_AddStamp( OUString
& rStr
, const OUString
& rName
,
151 const css::util::DateTime
& rDateTime
,
152 const LocaleDataWrapper
& rLoc
)
154 Date
aD(rDateTime
.Day
, rDateTime
.Month
, rDateTime
.Year
);
155 tools::Time
aT(rDateTime
.Hours
, rDateTime
.Minutes
, rDateTime
.Seconds
,
156 rDateTime
.NanoSeconds
);
157 DateTime
aDateTime(aD
,aT
);
159 OUString aStrDate
= rLoc
.getDate( aDateTime
);
160 OUString aStrTime
= rLoc
.getTime( aDateTime
);
162 rStr
+= GLOBSTR( STR_BY
) + " ";
163 if (!rName
.isEmpty())
167 rStr
+= " " + GLOBSTR( STR_ON
) + " ";
168 if (!aStrDate
.isEmpty())
173 if (!aStrTime
.isEmpty())
179 static OString
lcl_makeHTMLColorTriplet(const Color
& rColor
)
183 // <font COLOR="#00FF40">hello</font>
184 snprintf( buf
, 24, "\"#%02X%02X%02X\"", rColor
.GetRed(), rColor
.GetGreen(), rColor
.GetBlue() );
189 ScHTMLExport::ScHTMLExport( SvStream
& rStrmP
, const OUString
& rBaseURL
, ScDocument
* pDocP
,
190 const ScRange
& rRangeP
, bool bAllP
,
191 const OUString
& rStreamPathP
, const OUString
& rFilterOptions
) :
192 ScExportBase( rStrmP
, pDocP
, rRangeP
),
193 aBaseURL( rBaseURL
),
194 aStreamPath( rStreamPathP
),
195 pAppWin( Application::GetDefaultDevice() ),
199 bTabHasGraphics( false ),
200 bTabAlignedLeft( false ),
201 bCalcAsShown( pDocP
->GetDocOptions().IsCalcAsShown() ),
202 bTableDataHeight( true ),
203 mbSkipImages ( false ),
204 mbSkipHeaderFooter( false )
206 strcpy( sIndent
, sIndentSource
);
209 // set HTML configuration
210 SvxHtmlOptions
& rHtmlOptions
= SvxHtmlOptions::Get();
211 eDestEnc
= (pDoc
->IsClipOrUndo() ? RTL_TEXTENCODING_UTF8
: rHtmlOptions
.GetTextEncoding());
212 bCopyLocalFileToINet
= rHtmlOptions
.IsSaveGraphicsLocal();
214 if (rFilterOptions
== "SkipImages")
218 else if (rFilterOptions
== "SkipHeaderFooter")
220 mbSkipHeaderFooter
= true;
223 for ( sal_uInt16 j
=0; j
< SC_HTML_FONTSIZES
; j
++ )
225 sal_uInt16 nSize
= rHtmlOptions
.GetFontSize( j
);
226 // remember in Twips, like our SvxFontHeightItem
228 nFontSize
[j
] = nSize
* 20;
230 nFontSize
[j
] = nDefaultFontSize
[j
] * 20;
233 const SCTAB nCount
= pDoc
->GetTableCount();
234 for ( SCTAB nTab
= 0; nTab
< nCount
; nTab
++ )
236 if ( !IsEmptyTable( nTab
) )
241 ScHTMLExport::~ScHTMLExport()
246 sal_uInt16
ScHTMLExport::GetFontSizeNumber( sal_uInt16 nHeight
)
248 sal_uInt16 nSize
= 1;
249 for ( sal_uInt16 j
=SC_HTML_FONTSIZES
-1; j
>0; j
-- )
251 if( nHeight
> (nFontSize
[j
] + nFontSize
[j
-1]) / 2 )
252 { // The one next to it
260 const char* ScHTMLExport::GetFontSizeCss( sal_uInt16 nHeight
)
262 sal_uInt16 nSize
= GetFontSizeNumber( nHeight
);
263 return pFontSizeCss
[ nSize
-1 ];
266 sal_uInt16
ScHTMLExport::ToPixel( sal_uInt16 nVal
)
270 nVal
= static_cast<sal_uInt16
>(pAppWin
->LogicToPixel(
271 Size( nVal
, nVal
), MapMode( MapUnit::MapTwip
) ).Width());
272 if( !nVal
) // If there's a Twip there should also be a Pixel
278 Size
ScHTMLExport::MMToPixel( const Size
& rSize
)
280 Size aSize
= pAppWin
->LogicToPixel( rSize
, MapMode( MapUnit::Map100thMM
) );
281 // If there's something there should also be a Pixel
282 if ( !aSize
.Width() && rSize
.Width() )
284 if ( !aSize
.Height() && rSize
.Height() )
285 aSize
.setHeight( 1 );
289 void ScHTMLExport::Write()
291 if (!mbSkipHeaderFooter
)
293 rStrm
.WriteChar( '<' ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_doctype
).WriteChar( ' ' ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_doctype40
).WriteChar( '>' )
294 .WriteCharPtr( SAL_NEWLINE_STRING
).WriteCharPtr( SAL_NEWLINE_STRING
);
295 TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_html
);
301 if (!mbSkipHeaderFooter
)
302 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_html
);
305 void ScHTMLExport::WriteHeader()
307 IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_head
);
309 if ( pDoc
->IsClipOrUndo() )
310 { // no real DocInfo available, but some META information like charset needed
311 SfxFrameHTMLWriter::Out_DocInfo( rStrm
, aBaseURL
, nullptr, sIndent
, eDestEnc
, &aNonConvertibleChars
);
315 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS(
316 pDoc
->GetDocumentShell()->GetModel(), uno::UNO_QUERY_THROW
);
317 uno::Reference
<document::XDocumentProperties
> xDocProps
318 = xDPS
->getDocumentProperties();
319 SfxFrameHTMLWriter::Out_DocInfo( rStrm
, aBaseURL
, xDocProps
,
320 sIndent
, eDestEnc
, &aNonConvertibleChars
);
323 if (!xDocProps
->getPrintedBy().isEmpty())
325 OUT_COMMENT( GLOBSTR( STR_DOC_INFO
) );
326 OUString aStrOut
= GLOBSTR( STR_DOC_PRINTED
) + ": ";
327 lcl_AddStamp( aStrOut
, xDocProps
->getPrintedBy(),
328 xDocProps
->getPrintDate(), *ScGlobal::pLocaleData
);
329 OUT_COMMENT( aStrOut
);
336 PageDefaults( bAll
? 0 : aRange
.aStart
.Tab() );
338 rStrm
.WriteCharPtr( "<" ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_style
).WriteCharPtr( " " ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_O_type
).WriteCharPtr( "=\"text/css\">" );
341 rStrm
.WriteCharPtr( OOO_STRING_SVTOOLS_HTML_body
).WriteCharPtr( "," ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_division
).WriteCharPtr( "," ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_table
).WriteCharPtr( "," )
342 .WriteCharPtr( OOO_STRING_SVTOOLS_HTML_thead
).WriteCharPtr( "," ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_tbody
).WriteCharPtr( "," ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_tfoot
).WriteCharPtr( "," )
343 .WriteCharPtr( OOO_STRING_SVTOOLS_HTML_tablerow
).WriteCharPtr( "," ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_tableheader
).WriteCharPtr( "," )
344 .WriteCharPtr( OOO_STRING_SVTOOLS_HTML_tabledata
).WriteCharPtr( "," ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_parabreak
)
345 .WriteCharPtr( " { " ).WriteCharPtr( "font-family:" );
346 if (!aHTMLStyle
.aFontFamilyName
.isEmpty())
348 const OUString
& rList
= aHTMLStyle
.aFontFamilyName
;
349 for(sal_Int32 nPos
{0};;)
351 rStrm
.WriteChar( '\"' );
352 OUT_STR( rList
.getToken( 0, ';', nPos
) );
353 rStrm
.WriteChar( '\"' );
356 rStrm
.WriteCharPtr( ", " );
359 rStrm
.WriteCharPtr( "; " ).WriteCharPtr( "font-size:" )
360 .WriteCharPtr( GetFontSizeCss( static_cast<sal_uInt16
>(aHTMLStyle
.nFontHeight
) ) ).WriteCharPtr( " }" );
364 // write the style for the comments to make them stand out from normal cell content
365 // this is done through only showing the cell contents when the custom indicator is hovered
366 rStrm
.WriteCharPtr( OOO_STRING_SVTOOLS_HTML_anchor
).WriteCharPtr(".comment-indicator:hover")
367 .WriteCharPtr(" + ").WriteCharPtr( OOO_STRING_SVTOOLS_HTML_comment2
).WriteCharPtr(" { ")
368 .WriteCharPtr(sBackground
).WriteCharPtr("#ffd").WriteCharPtr("; ")
369 .WriteCharPtr("position:").WriteCharPtr("absolute").WriteCharPtr("; ")
370 .WriteCharPtr(sDisplay
).WriteCharPtr("block").WriteCharPtr("; ")
371 .WriteCharPtr(sBorder
).WriteCharPtr("1px solid black").WriteCharPtr("; ")
372 .WriteCharPtr("padding:").WriteCharPtr("0.5em").WriteCharPtr("; ")
373 .WriteCharPtr(" } ");
377 rStrm
.WriteCharPtr( OOO_STRING_SVTOOLS_HTML_anchor
).WriteCharPtr(".comment-indicator")
379 .WriteCharPtr(sBackground
).WriteCharPtr("red").WriteCharPtr("; ")
380 .WriteCharPtr(sDisplay
).WriteCharPtr("inline-block").WriteCharPtr("; ")
381 .WriteCharPtr(sBorder
).WriteCharPtr("1px solid black").WriteCharPtr("; ")
382 .WriteCharPtr("width:").WriteCharPtr("0.5em").WriteCharPtr("; ")
383 .WriteCharPtr("height:").WriteCharPtr("0.5em").WriteCharPtr("; ")
384 .WriteCharPtr(" } ");
388 rStrm
.WriteCharPtr( OOO_STRING_SVTOOLS_HTML_comment2
).WriteCharPtr(" { ")
389 .WriteCharPtr(sDisplay
).WriteCharPtr("none").WriteCharPtr("; ")
390 .WriteCharPtr(" } ");
393 IncIndent(-1); OUT_LF(); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_style
);
395 IncIndent(-1); OUT_LF(); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_head
);
398 void ScHTMLExport::WriteOverview()
400 if ( nUsedTables
> 1 )
404 IncIndent(1); TAG_ON( OOO_STRING_SVTOOLS_HTML_parabreak
); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_center
);
405 TAG_ON( OOO_STRING_SVTOOLS_HTML_head1
);
406 OUT_STR( ScResId( STR_OVERVIEW
) );
407 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_head1
);
411 const SCTAB nCount
= pDoc
->GetTableCount();
412 for ( SCTAB nTab
= 0; nTab
< nCount
; nTab
++ )
414 if ( !IsEmptyTable( nTab
) )
416 pDoc
->GetName( nTab
, aStr
);
417 rStrm
.WriteCharPtr( "<A HREF=\"#table" )
418 .WriteOString( OString::number(nTab
) )
419 .WriteCharPtr( "\">" );
421 rStrm
.WriteCharPtr( "</A>" );
422 TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_linebreak
);
426 IncIndent(-1); OUT_LF();
427 IncIndent(-1); TAG_OFF( OOO_STRING_SVTOOLS_HTML_center
); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_parabreak
);
431 const SfxItemSet
& ScHTMLExport::PageDefaults( SCTAB nTab
)
433 SfxStyleSheetBasePool
* pStylePool
= pDoc
->GetStyleSheetPool();
434 SfxStyleSheetBase
* pStyleSheet
= nullptr;
435 OSL_ENSURE( pStylePool
, "StylePool not found! :-(" );
437 // remember defaults for compare in WriteCell
438 if ( !aHTMLStyle
.bInitialized
)
440 pStylePool
->SetSearchMask( SfxStyleFamily::Para
);
441 pStyleSheet
= pStylePool
->Find(
442 ScResId(STR_STYLENAME_STANDARD
),
443 SfxStyleFamily::Para
);
444 OSL_ENSURE( pStyleSheet
, "ParaStyle not found! :-(" );
446 pStyleSheet
= pStylePool
->First();
447 const SfxItemSet
& rSetPara
= pStyleSheet
->GetItemSet();
449 aHTMLStyle
.nDefaultScriptType
= ScGlobal::GetDefaultScriptType();
450 aHTMLStyle
.aFontFamilyName
= static_cast<const SvxFontItem
&>((rSetPara
.Get(
451 ScGlobal::GetScriptedWhichID(
452 aHTMLStyle
.nDefaultScriptType
, ATTR_FONT
453 )))).GetFamilyName();
454 aHTMLStyle
.nFontHeight
= static_cast<const SvxFontHeightItem
&>((rSetPara
.Get(
455 ScGlobal::GetScriptedWhichID(
456 aHTMLStyle
.nDefaultScriptType
, ATTR_FONT_HEIGHT
458 aHTMLStyle
.nFontSizeNumber
= GetFontSizeNumber( static_cast< sal_uInt16
>( aHTMLStyle
.nFontHeight
) );
461 // Page style sheet printer settings, e.g. for background graphics.
462 // There's only one background graphic in HTML!
463 pStylePool
->SetSearchMask( SfxStyleFamily::Page
);
464 pStyleSheet
= pStylePool
->Find( pDoc
->GetPageStyle( nTab
), SfxStyleFamily::Page
);
465 OSL_ENSURE( pStyleSheet
, "PageStyle not found! :-(" );
467 pStyleSheet
= pStylePool
->First();
468 const SfxItemSet
& rSet
= pStyleSheet
->GetItemSet();
469 if ( !aHTMLStyle
.bInitialized
)
471 const SvxBrushItem
* pBrushItem
= &rSet
.Get( ATTR_BACKGROUND
);
472 aHTMLStyle
.aBackgroundColor
= pBrushItem
->GetColor();
473 aHTMLStyle
.bInitialized
= true;
478 OString
ScHTMLExport::BorderToStyle(const char* pBorderName
,
479 const SvxBorderLine
* pLine
, bool& bInsertSemicolon
)
485 if ( bInsertSemicolon
)
489 aOut
.append("border-").append(pBorderName
).append(": ");
492 int nWidth
= pLine
->GetWidth();
493 int nPxWidth
= (nWidth
> 0) ?
494 std::max(int(nWidth
/ TWIPS_PER_PIXEL
), 1) : 0;
495 aOut
.append(static_cast<sal_Int32
>(nPxWidth
)).
497 switch (pLine
->GetBorderLineStyle())
499 case SvxBorderLineStyle::SOLID
:
500 aOut
.append("solid");
502 case SvxBorderLineStyle::DOTTED
:
503 aOut
.append("dotted");
505 case SvxBorderLineStyle::DASHED
:
506 case SvxBorderLineStyle::DASH_DOT
:
507 case SvxBorderLineStyle::DASH_DOT_DOT
:
508 aOut
.append("dashed");
510 case SvxBorderLineStyle::DOUBLE
:
511 case SvxBorderLineStyle::DOUBLE_THIN
:
512 case SvxBorderLineStyle::THINTHICK_SMALLGAP
:
513 case SvxBorderLineStyle::THINTHICK_MEDIUMGAP
:
514 case SvxBorderLineStyle::THINTHICK_LARGEGAP
:
515 case SvxBorderLineStyle::THICKTHIN_SMALLGAP
:
516 case SvxBorderLineStyle::THICKTHIN_MEDIUMGAP
:
517 case SvxBorderLineStyle::THICKTHIN_LARGEGAP
:
518 aOut
.append("double");
520 case SvxBorderLineStyle::EMBOSSED
:
521 aOut
.append("ridge");
523 case SvxBorderLineStyle::ENGRAVED
:
524 aOut
.append("groove");
526 case SvxBorderLineStyle::OUTSET
:
527 aOut
.append("outset");
529 case SvxBorderLineStyle::INSET
:
530 aOut
.append("inset");
533 aOut
.append("hidden");
539 snprintf( hex
, 7, "%06" SAL_PRIxUINT32
, static_cast<sal_uInt32
>( pLine
->GetColor().GetRGBColor() ) );
544 bInsertSemicolon
= true;
547 return aOut
.makeStringAndClear();
550 void ScHTMLExport::WriteBody()
552 const SfxItemSet
& rSet
= PageDefaults( bAll
? 0 : aRange
.aStart
.Tab() );
553 const SvxBrushItem
* pBrushItem
= &rSet
.Get( ATTR_BACKGROUND
);
555 // default text color black
556 if (!mbSkipHeaderFooter
)
558 rStrm
.WriteChar( '<' ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_body
);
562 if ( bAll
&& GPOS_NONE
!= pBrushItem
->GetGraphicPos() )
564 OUString aLink
= pBrushItem
->GetGraphicLink();
567 // Embedded graphic -> write using WriteGraphic
568 if( aLink
.isEmpty() )
570 const Graphic
* pGrf
= pBrushItem
->GetGraphic();
573 // Save graphic as (JPG) file
574 aGrfNm
= aStreamPath
;
575 ErrCode nErr
= XOutBitmap::WriteGraphic( *pGrf
, aGrfNm
,
576 "JPG", XOutFlags::UseNativeIfPossible
);
577 if( !nErr
) // Contains errors, as we have nothing to output
579 aGrfNm
= URIHelper::SmartRel2Abs(
580 INetURLObject(aBaseURL
),
581 aGrfNm
, URIHelper::GetMaybeFileHdl());
589 if( bCopyLocalFileToINet
)
591 CopyLocalFileToINet( aGrfNm
, aStreamPath
);
594 aGrfNm
= URIHelper::SmartRel2Abs(
595 INetURLObject(aBaseURL
),
596 aGrfNm
, URIHelper::GetMaybeFileHdl());
599 if( !aLink
.isEmpty() )
601 rStrm
.WriteChar( ' ' ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_O_background
).WriteCharPtr( "=\"" );
602 OUT_STR( URIHelper::simpleNormalizedMakeRelative(
604 aLink
) ).WriteChar( '\"' );
608 if ( !aHTMLStyle
.aBackgroundColor
.GetTransparency() )
609 { // A transparent background color should always result in default
610 // background of the browser. Also, HTMLOutFuncs::Out_Color() writes
611 // black #000000 for COL_AUTO which is the same as white #ffffff with
612 // transparency set to 0xff, our default background.
613 OUT_SP_CSTR_ASS( OOO_STRING_SVTOOLS_HTML_O_bgcolor
);
614 HTMLOutFuncs::Out_Color( rStrm
, aHTMLStyle
.aBackgroundColor
);
617 rStrm
.WriteChar( '>' ); OUT_LF();
625 if (!mbSkipHeaderFooter
)
626 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_body
);
629 void ScHTMLExport::WriteTables()
631 const SCTAB nTabCount
= pDoc
->GetTableCount();
632 const OUString
aStrTable( ScResId( SCSTR_TABLE
) );
641 SCCOL nStartColFix
= 0;
642 SCROW nStartRowFix
= 0;
643 SCCOL nEndColFix
= 0;
644 SCROW nEndRowFix
= 0;
645 ScDrawLayer
* pDrawLayer
= pDoc
->GetDrawLayer();
649 nEndTab
= nTabCount
- 1;
653 nStartCol
= nStartColFix
= aRange
.aStart
.Col();
654 nStartRow
= nStartRowFix
= aRange
.aStart
.Row();
655 nStartTab
= aRange
.aStart
.Tab();
656 nEndCol
= nEndColFix
= aRange
.aEnd
.Col();
657 nEndRow
= nEndRowFix
= aRange
.aEnd
.Row();
658 nEndTab
= aRange
.aEnd
.Tab();
660 SCTAB nTableStrNum
= 1;
661 for ( SCTAB nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++ )
663 if ( !pDoc
->IsVisible( nTab
) )
668 if ( !GetDataArea( nTab
, nStartCol
, nStartRow
, nEndCol
, nEndRow
) )
671 if ( nUsedTables
> 1 )
673 aStrOut
= aStrTable
+ " " + OUString::number( nTableStrNum
++ ) + ": ";
678 rStrm
.WriteCharPtr( "<A NAME=\"table" )
679 .WriteOString( OString::number(nTab
) )
680 .WriteCharPtr( "\">" );
681 TAG_ON( OOO_STRING_SVTOOLS_HTML_head1
);
683 TAG_ON( OOO_STRING_SVTOOLS_HTML_emphasis
);
685 pDoc
->GetName( nTab
, aStr
);
688 TAG_OFF( OOO_STRING_SVTOOLS_HTML_emphasis
);
689 TAG_OFF( OOO_STRING_SVTOOLS_HTML_head1
);
690 rStrm
.WriteCharPtr( "</A>" ); OUT_LF();
695 nStartCol
= nStartColFix
;
696 nStartRow
= nStartRowFix
;
697 nEndCol
= nEndColFix
;
698 nEndRow
= nEndRowFix
;
699 if ( !TrimDataArea( nTab
, nStartCol
, nStartRow
, nEndCol
, nEndRow
) )
704 OStringBuffer
aByteStrOut(OOO_STRING_SVTOOLS_HTML_table
);
706 bTabHasGraphics
= bTabAlignedLeft
= false;
707 if ( bAll
&& pDrawLayer
)
708 PrepareGraphics( pDrawLayer
, nTab
, nStartCol
, nStartRow
,
712 if ( bTabAlignedLeft
)
714 aByteStrOut
.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_align
).
716 append(OOO_STRING_SVTOOLS_HTML_AL_left
).append('"');
718 // ALIGN=LEFT allow text and graphics to flow around
720 aByteStrOut
.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_cellspacing
).
722 append(static_cast<sal_Int32
>(nCellSpacing
)).append('"');
724 // BORDER=0, we do the styling of the cells in <TD>
725 aByteStrOut
.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_border
).
727 IncIndent(1); TAG_ON_LF( aByteStrOut
.makeStringAndClear().getStr() );
729 // --- <COLGROUP> ----
731 SCCOL nCol
= nStartCol
;
732 sal_Int32 nWidth
= 0;
734 while( nCol
<= nEndCol
)
736 if( pDoc
->ColHidden(nCol
, nTab
) )
742 if( nWidth
!= ToPixel( pDoc
->GetColWidth( nCol
, nTab
) ) )
746 TAG_ON(lcl_getColGroupString(nSpan
, nWidth
).getStr());
747 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_colgroup
);
749 nWidth
= ToPixel( pDoc
->GetColWidth( nCol
, nTab
) );
758 TAG_ON(lcl_getColGroupString(nSpan
, nWidth
).getStr());
759 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_colgroup
);
763 // <TBODY> // Re-enable only when THEAD and TFOOT are exported
764 // IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_tbody );
765 // At least old (3.x, 4.x?) Netscape doesn't follow <TABLE COLS=n> and
766 // <COL WIDTH=x> specified, but needs a width at every column.
767 bool bHasHiddenRows
= pDoc
->HasHiddenRows(nStartRow
, nEndRow
, nTab
);
768 // We need to cache sc::ColumnBlockPosition per each column.
769 std::vector
< sc::ColumnBlockPosition
> blockPos( nEndCol
- nStartCol
+ 1 );
770 for( SCCOL i
= nStartCol
; i
<= nEndCol
; ++i
)
771 pDoc
->InitColumnBlockPosition( blockPos
[ i
- nStartCol
], nTab
, i
);
772 for ( SCROW nRow
=nStartRow
; nRow
<=nEndRow
; nRow
++ )
774 if ( bHasHiddenRows
&& pDoc
->RowHidden(nRow
, nTab
) )
776 nRow
= pDoc
->FirstVisibleRow(nRow
+1, nEndRow
, nTab
);
781 IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_tablerow
);
782 bTableDataHeight
= true; // height at every first cell of each row
783 for ( SCCOL nCol2
=nStartCol
; nCol2
<=nEndCol
; nCol2
++ )
785 if ( pDoc
->ColHidden(nCol2
, nTab
) )
788 if ( nCol2
== nEndCol
)
790 WriteCell( blockPos
[ nCol2
- nStartCol
], nCol2
, nRow
, nTab
);
791 bTableDataHeight
= false;
794 if ( nRow
== nEndRow
)
796 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tablerow
);
798 // TODO: Uncomment later
799 // IncIndent(-1); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tbody );
801 IncIndent(-1); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_table
);
803 if ( bTabHasGraphics
&& !mbSkipImages
)
805 // the rest that is not in a cell
806 size_t ListSize
= aGraphList
.size();
807 for ( size_t i
= 0; i
< ListSize
; ++i
)
809 ScHTMLGraphEntry
* pE
= &aGraphList
[ i
];
811 WriteGraphEntry( pE
);
814 if ( bTabAlignedLeft
)
816 // clear <TABLE ALIGN=LEFT> with <BR CLEAR=LEFT>
817 aByteStrOut
.append(OOO_STRING_SVTOOLS_HTML_linebreak
);
818 aByteStrOut
.append(' ').
819 append(OOO_STRING_SVTOOLS_HTML_O_clear
).append('=').
820 append(OOO_STRING_SVTOOLS_HTML_AL_left
);
821 TAG_ON_LF( aByteStrOut
.makeStringAndClear().getStr() );
826 OUT_COMMENT( "**************************************************************************" );
830 void ScHTMLExport::WriteCell( sc::ColumnBlockPosition
& rBlockPos
, SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
832 ScAddress
aPos( nCol
, nRow
, nTab
);
833 ScRefCellValue
aCell(*pDoc
, aPos
, rBlockPos
);
834 const ScPatternAttr
* pAttr
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
835 const SfxItemSet
* pCondItemSet
= pDoc
->GetCondResult( nCol
, nRow
, nTab
, &aCell
);
837 const ScMergeFlagAttr
& rMergeFlagAttr
= pAttr
->GetItem( ATTR_MERGE_FLAG
, pCondItemSet
);
838 if ( rMergeFlagAttr
.IsOverlapped() )
841 ScHTMLGraphEntry
* pGraphEntry
= nullptr;
842 if ( bTabHasGraphics
&& !mbSkipImages
)
844 size_t ListSize
= aGraphList
.size();
845 for ( size_t i
= 0; i
< ListSize
; ++i
)
847 ScHTMLGraphEntry
* pE
= &aGraphList
[ i
];
848 if ( pE
->bInCell
&& pE
->aRange
.In( aPos
) )
850 if ( pE
->aRange
.aStart
== aPos
)
856 return ; // Is a Col/RowSpan, Overlapped
861 sal_uInt32 nFormat
= pAttr
->GetNumberFormat( pFormatter
);
862 bool bValueData
= aCell
.hasNumeric();
863 SvtScriptType nScriptType
= SvtScriptType::NONE
;
864 if (!aCell
.isEmpty())
865 nScriptType
= pDoc
->GetScriptType(nCol
, nRow
, nTab
, &aCell
);
867 if ( nScriptType
== SvtScriptType::NONE
)
868 nScriptType
= aHTMLStyle
.nDefaultScriptType
;
870 OStringBuffer
aStrTD(OOO_STRING_SVTOOLS_HTML_tabledata
);
872 // border of the cells
873 const SvxBoxItem
* pBorder
= pDoc
->GetAttr( nCol
, nRow
, nTab
, ATTR_BORDER
);
874 if ( pBorder
&& (pBorder
->GetTop() || pBorder
->GetBottom() || pBorder
->GetLeft() || pBorder
->GetRight()) )
876 aStrTD
.append(' ').append(OOO_STRING_SVTOOLS_HTML_style
).
879 bool bInsertSemicolon
= false;
880 aStrTD
.append(BorderToStyle("top", pBorder
->GetTop(),
882 aStrTD
.append(BorderToStyle("bottom", pBorder
->GetBottom(),
884 aStrTD
.append(BorderToStyle("left", pBorder
->GetLeft(),
886 aStrTD
.append(BorderToStyle("right", pBorder
->GetRight(),
892 const sal_Char
* pChar
;
893 sal_uInt16 nHeightPixel
;
895 const ScMergeAttr
& rMergeAttr
= pAttr
->GetItem( ATTR_MERGE
, pCondItemSet
);
896 if ( pGraphEntry
|| rMergeAttr
.IsMerged() )
902 nC
= std::max( SCCOL(pGraphEntry
->aRange
.aEnd
.Col() - nCol
+ 1),
903 rMergeAttr
.GetColMerge() );
905 nC
= rMergeAttr
.GetColMerge();
908 aStrTD
.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_colspan
).
909 append('=').append(static_cast<sal_Int32
>(nC
));
911 for ( jC
=nCol
, v
=0; jC
<nC
; jC
++ )
912 v
+= pDoc
->GetColWidth( jC
, nTab
);
916 nR
= std::max( SCROW(pGraphEntry
->aRange
.aEnd
.Row() - nRow
+ 1),
917 rMergeAttr
.GetRowMerge() );
919 nR
= rMergeAttr
.GetRowMerge();
922 aStrTD
.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_rowspan
).
923 append('=').append(static_cast<sal_Int32
>(nR
));
925 v
= pDoc
->GetRowHeight( nRow
, nR
-1, nTab
);
926 nHeightPixel
= ToPixel( static_cast< sal_uInt16
>( v
) );
929 nHeightPixel
= ToPixel( pDoc
->GetRowHeight( nRow
, nTab
) );
932 nHeightPixel
= ToPixel( pDoc
->GetRowHeight( nRow
, nTab
) );
934 if ( bTableDataHeight
)
936 aStrTD
.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_height
).
938 append(static_cast<sal_Int32
>(nHeightPixel
)).append('"');
941 const SvxFontItem
& rFontItem
= static_cast<const SvxFontItem
&>( pAttr
->GetItem(
942 ScGlobal::GetScriptedWhichID( nScriptType
, ATTR_FONT
),
945 const SvxFontHeightItem
& rFontHeightItem
= static_cast<const SvxFontHeightItem
&>(
946 pAttr
->GetItem( ScGlobal::GetScriptedWhichID( nScriptType
,
947 ATTR_FONT_HEIGHT
), pCondItemSet
) );
949 const SvxWeightItem
& rWeightItem
= static_cast<const SvxWeightItem
&>( pAttr
->GetItem(
950 ScGlobal::GetScriptedWhichID( nScriptType
, ATTR_FONT_WEIGHT
),
953 const SvxPostureItem
& rPostureItem
= static_cast<const SvxPostureItem
&>(
954 pAttr
->GetItem( ScGlobal::GetScriptedWhichID( nScriptType
,
955 ATTR_FONT_POSTURE
), pCondItemSet
) );
957 const SvxUnderlineItem
& rUnderlineItem
=
958 pAttr
->GetItem( ATTR_FONT_UNDERLINE
, pCondItemSet
);
960 const SvxCrossedOutItem
& rCrossedOutItem
=
961 pAttr
->GetItem( ATTR_FONT_CROSSEDOUT
, pCondItemSet
);
963 const SvxColorItem
& rColorItem
= pAttr
->GetItem(
964 ATTR_FONT_COLOR
, pCondItemSet
);
966 const SvxHorJustifyItem
& rHorJustifyItem
=
967 pAttr
->GetItem( ATTR_HOR_JUSTIFY
, pCondItemSet
);
969 const SvxVerJustifyItem
& rVerJustifyItem
=
970 pAttr
->GetItem( ATTR_VER_JUSTIFY
, pCondItemSet
);
972 const SvxBrushItem
& rBrushItem
= pAttr
->GetItem(
973 ATTR_BACKGROUND
, pCondItemSet
);
976 if ( rBrushItem
.GetColor().GetTransparency() == 255 )
977 aBgColor
= aHTMLStyle
.aBackgroundColor
; // No unwanted background color
979 aBgColor
= rBrushItem
.GetColor();
981 bool bBold
= ( WEIGHT_BOLD
<= rWeightItem
.GetWeight() );
982 bool bItalic
= ( ITALIC_NONE
!= rPostureItem
.GetPosture() );
983 bool bUnderline
= ( LINESTYLE_NONE
!= rUnderlineItem
.GetLineStyle() );
984 bool bCrossedOut
= ( STRIKEOUT_SINGLE
<= rCrossedOutItem
.GetStrikeout() );
985 bool bSetFontColor
= ( COL_AUTO
!= rColorItem
.GetValue() ); // default is AUTO now
986 bool bSetFontName
= ( aHTMLStyle
.aFontFamilyName
!= rFontItem
.GetFamilyName() );
987 sal_uInt16 nSetFontSizeNumber
= 0;
988 sal_uInt32 nFontHeight
= rFontHeightItem
.GetHeight();
989 if ( nFontHeight
!= aHTMLStyle
.nFontHeight
)
991 nSetFontSizeNumber
= GetFontSizeNumber( static_cast<sal_uInt16
>(nFontHeight
) );
992 if ( nSetFontSizeNumber
== aHTMLStyle
.nFontSizeNumber
)
993 nSetFontSizeNumber
= 0; // no difference, don't set
996 bool bSetFont
= (bSetFontColor
|| bSetFontName
|| nSetFontSizeNumber
);
998 //! TODO: we could entirely use CSS1 here instead, but that would exclude
999 //! Netscape 3.0 and Netscape 4.x without JavaScript enabled.
1000 //! Do we want that?
1002 switch( rHorJustifyItem
.GetValue() )
1004 case SvxCellHorJustify::Standard
:
1005 pChar
= (bValueData
? OOO_STRING_SVTOOLS_HTML_AL_right
: OOO_STRING_SVTOOLS_HTML_AL_left
);
1007 case SvxCellHorJustify::Center
: pChar
= OOO_STRING_SVTOOLS_HTML_AL_center
; break;
1008 case SvxCellHorJustify::Block
: pChar
= OOO_STRING_SVTOOLS_HTML_AL_justify
; break;
1009 case SvxCellHorJustify::Right
: pChar
= OOO_STRING_SVTOOLS_HTML_AL_right
; break;
1010 case SvxCellHorJustify::Left
:
1011 case SvxCellHorJustify::Repeat
:
1012 default: pChar
= OOO_STRING_SVTOOLS_HTML_AL_left
; break;
1015 aStrTD
.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_align
).
1016 append("=\"").append(pChar
).append('"');
1018 switch( rVerJustifyItem
.GetValue() )
1020 case SvxCellVerJustify::Top
: pChar
= OOO_STRING_SVTOOLS_HTML_VA_top
; break;
1021 case SvxCellVerJustify::Center
: pChar
= OOO_STRING_SVTOOLS_HTML_VA_middle
; break;
1022 case SvxCellVerJustify::Bottom
: pChar
= OOO_STRING_SVTOOLS_HTML_VA_bottom
; break;
1023 case SvxCellVerJustify::Standard
:
1024 default: pChar
= nullptr;
1028 aStrTD
.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_valign
).
1029 append('=').append(pChar
);
1032 if ( aHTMLStyle
.aBackgroundColor
!= aBgColor
)
1034 aStrTD
.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_bgcolor
).
1036 aStrTD
.append(lcl_makeHTMLColorTriplet(aBgColor
));
1042 switch (aCell
.meType
)
1044 case CELLTYPE_VALUE
:
1045 fVal
= aCell
.mfValue
;
1046 if ( bCalcAsShown
&& fVal
!= 0.0 )
1047 fVal
= pDoc
->RoundValueAsShown( fVal
, nFormat
);
1049 case CELLTYPE_FORMULA
:
1050 fVal
= aCell
.mpFormula
->GetValue();
1053 OSL_FAIL( "value data with unsupported cell type" );
1057 aStrTD
.append(HTMLOutFuncs::CreateTableDataOptionsValNum(bValueData
, fVal
,
1058 nFormat
, *pFormatter
, eDestEnc
, &aNonConvertibleChars
));
1060 TAG_ON(aStrTD
.makeStringAndClear().getStr());
1062 //write the note for this as the first thing in the tag
1063 ScPostIt
* pNote
= pDoc
->HasNote(aPos
) ? pDoc
->GetNote(aPos
) : nullptr;
1066 //create the comment indicator
1067 OString aStr
= OOO_STRING_SVTOOLS_HTML_anchor
" "
1068 OOO_STRING_SVTOOLS_HTML_O_class
"=\"comment-indicator\"";
1069 TAG_ON(aStr
.getStr());
1070 TAG_OFF(OOO_STRING_SVTOOLS_HTML_anchor
);
1073 //create the element holding the contents
1074 //this is a bit naive, since it doesn't separate
1075 //lines into html breaklines yet
1076 TAG_ON(OOO_STRING_SVTOOLS_HTML_comment2
);
1077 OUT_STR( pNote
->GetText() );
1078 TAG_OFF(OOO_STRING_SVTOOLS_HTML_comment2
);
1082 if ( bBold
) TAG_ON( OOO_STRING_SVTOOLS_HTML_bold
);
1083 if ( bItalic
) TAG_ON( OOO_STRING_SVTOOLS_HTML_italic
);
1084 if ( bUnderline
) TAG_ON( OOO_STRING_SVTOOLS_HTML_underline
);
1085 if ( bCrossedOut
) TAG_ON( OOO_STRING_SVTOOLS_HTML_strikethrough
);
1089 OStringBuffer
aStr(OOO_STRING_SVTOOLS_HTML_font
);
1092 aStr
.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_face
).
1095 if (!rFontItem
.GetFamilyName().isEmpty())
1097 const OUString
& rList
= rFontItem
.GetFamilyName();
1098 for (sal_Int32 nPos
{0};;)
1100 OString aTmpStr
= HTMLOutFuncs::ConvertStringToHTML(
1101 rList
.getToken( 0, ';', nPos
), eDestEnc
,
1102 &aNonConvertibleChars
);
1103 aStr
.append(aTmpStr
);
1112 if ( nSetFontSizeNumber
)
1114 aStr
.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_size
).
1115 append('=').append(static_cast<sal_Int32
>(nSetFontSizeNumber
));
1117 if ( bSetFontColor
)
1119 Color aColor
= rColorItem
.GetValue();
1121 // always export automatic text color as black
1122 if ( aColor
== COL_AUTO
)
1125 aStr
.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_color
).
1126 append('=').append(lcl_makeHTMLColorTriplet(aColor
));
1128 TAG_ON(aStr
.makeStringAndClear().getStr());
1132 bool bFieldText
= false;
1135 switch (aCell
.meType
)
1137 case CELLTYPE_EDIT
:
1138 bFieldText
= WriteFieldText(aCell
.mpEditText
);
1143 ScCellFormat::GetString(aCell
, nFormat
, aStrOut
, &pColor
, *pFormatter
, pDoc
);
1148 if ( aStrOut
.isEmpty() )
1150 TAG_ON( OOO_STRING_SVTOOLS_HTML_linebreak
); // No completely empty line
1154 sal_Int32 nPos
= aStrOut
.indexOf( '\n' );
1161 sal_Int32 nStartPos
= 0;
1164 OUString aSingleLine
= aStrOut
.copy( nStartPos
, nPos
- nStartPos
);
1165 OUT_STR( aSingleLine
);
1166 TAG_ON( OOO_STRING_SVTOOLS_HTML_linebreak
);
1167 nStartPos
= nPos
+ 1;
1169 while( ( nPos
= aStrOut
.indexOf( '\n', nStartPos
) ) != -1 );
1170 OUString aSingleLine
= aStrOut
.copy( nStartPos
);
1171 OUT_STR( aSingleLine
);
1176 WriteGraphEntry( pGraphEntry
);
1178 if ( bSetFont
) TAG_OFF( OOO_STRING_SVTOOLS_HTML_font
);
1179 if ( bCrossedOut
) TAG_OFF( OOO_STRING_SVTOOLS_HTML_strikethrough
);
1180 if ( bUnderline
) TAG_OFF( OOO_STRING_SVTOOLS_HTML_underline
);
1181 if ( bItalic
) TAG_OFF( OOO_STRING_SVTOOLS_HTML_italic
);
1182 if ( bBold
) TAG_OFF( OOO_STRING_SVTOOLS_HTML_bold
);
1184 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tabledata
);
1187 bool ScHTMLExport::WriteFieldText( const EditTextObject
* pData
)
1189 bool bFields
= false;
1190 // text and anchor of URL fields, Doc-Engine is a ScFieldEditEngine
1191 EditEngine
& rEngine
= pDoc
->GetEditEngine();
1192 rEngine
.SetText( *pData
);
1193 sal_Int32 nParas
= rEngine
.GetParagraphCount();
1196 ESelection
aSel( 0, 0, nParas
-1, rEngine
.GetTextLen( nParas
-1 ) );
1197 SfxItemSet
aSet( rEngine
.GetAttribs( aSel
) );
1198 SfxItemState eFieldState
= aSet
.GetItemState( EE_FEATURE_FIELD
, false );
1199 if ( eFieldState
== SfxItemState::DONTCARE
|| eFieldState
== SfxItemState::SET
)
1204 bool bOldUpdateMode
= rEngine
.GetUpdateMode();
1205 rEngine
.SetUpdateMode( true ); // no portions if not formatted
1206 for ( sal_Int32 nPar
=0; nPar
< nParas
; nPar
++ )
1209 TAG_ON( OOO_STRING_SVTOOLS_HTML_linebreak
);
1210 std::vector
<sal_Int32
> aPortions
;
1211 rEngine
.GetPortions( nPar
, aPortions
);
1212 sal_Int32 nStart
= 0;
1213 for ( const sal_Int32 nEnd
: aPortions
)
1215 ESelection
aSel( nPar
, nStart
, nPar
, nEnd
);
1217 // fields are single characters
1218 if ( nEnd
== nStart
+1 )
1220 const SfxPoolItem
* pItem
;
1221 SfxItemSet aSet
= rEngine
.GetAttribs( aSel
);
1222 if ( aSet
.GetItemState( EE_FEATURE_FIELD
, false, &pItem
) == SfxItemState::SET
)
1224 const SvxFieldData
* pField
= static_cast<const SvxFieldItem
*>(pItem
)->GetField();
1225 if (const SvxURLField
* pURLField
= dynamic_cast<const SvxURLField
*>(pField
))
1228 rStrm
.WriteChar( '<' ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_anchor
).WriteChar( ' ' ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_O_href
).WriteCharPtr( "=\"" );
1229 OUT_STR( pURLField
->GetURL() );
1230 rStrm
.WriteCharPtr( "\">" );
1231 OUT_STR( pURLField
->GetRepresentation() );
1232 rStrm
.WriteCharPtr( "</" ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_anchor
).WriteChar( '>' );
1237 OUT_STR( rEngine
.GetText( aSel
) );
1241 rEngine
.SetUpdateMode( bOldUpdateMode
);
1246 void ScHTMLExport::CopyLocalFileToINet( OUString
& rFileNm
,
1247 const OUString
& rTargetNm
)
1249 INetURLObject aFileUrl
, aTargetUrl
;
1250 aFileUrl
.SetSmartURL( rFileNm
);
1251 aTargetUrl
.SetSmartURL( rTargetNm
);
1252 if( INetProtocol::File
== aFileUrl
.GetProtocol() &&
1253 ( INetProtocol::File
!= aTargetUrl
.GetProtocol() &&
1254 INetProtocol::Ftp
<= aTargetUrl
.GetProtocol() &&
1255 INetProtocol::Javascript
>= aTargetUrl
.GetProtocol()) )
1259 // Did we already move the file?
1260 std::map
<OUString
, OUString
>::iterator it
= pFileNameMap
->find( rFileNm
);
1261 if( it
!= pFileNameMap
->end() )
1263 rFileNm
= it
->second
;
1269 pFileNameMap
.reset( new std::map
<OUString
, OUString
> );
1273 SvFileStream
aTmp( aFileUrl
.PathToFileName(), StreamMode::READ
);
1275 OUString aSrc
= rFileNm
;
1276 OUString aDest
= aTargetUrl
.GetPartBeforeLastName() + aFileUrl
.GetLastName();
1278 SfxMedium
aMedium( aDest
, StreamMode::WRITE
| StreamMode::SHARE_DENYNONE
);
1281 SvFileStream
aCpy( aMedium
.GetPhysicalName(), StreamMode::WRITE
);
1282 aCpy
.WriteStream( aTmp
);
1289 bRet
= ERRCODE_NONE
== aMedium
.GetError();
1293 pFileNameMap
->insert( std::make_pair( aSrc
, aDest
) );
1299 void ScHTMLExport::IncIndent( short nVal
)
1301 sIndent
[nIndent
] = '\t';
1302 nIndent
= nIndent
+ nVal
;
1305 else if ( nIndent
> nIndentMax
)
1306 nIndent
= nIndentMax
;
1307 sIndent
[nIndent
] = 0;
1310 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */