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 <comphelper/string.hxx>
22 #include <editeng/eeitem.hxx>
24 #include <rtl/tencinfo.h>
26 #include <vcl/svapp.hxx>
27 #include <svx/algitem.hxx>
28 #include <editeng/boxitem.hxx>
29 #include <editeng/brushitem.hxx>
30 #include <editeng/colritem.hxx>
31 #include <editeng/fhgtitem.hxx>
32 #include <editeng/fontitem.hxx>
33 #include <editeng/postitem.hxx>
34 #include <editeng/udlnitem.hxx>
35 #include <editeng/wghtitem.hxx>
36 #include <editeng/justifyitem.hxx>
37 #include <svx/xoutbmp.hxx>
38 #include <editeng/editeng.hxx>
39 #include <svtools/htmlcfg.hxx>
40 #include <sfx2/docfile.hxx>
41 #include <sfx2/frmhtmlw.hxx>
42 #include <sfx2/objsh.hxx>
43 #include <svl/stritem.hxx>
44 #include <svl/urihelper.hxx>
45 #include <svl/zforlist.hxx>
46 #include <svtools/htmlkywd.hxx>
47 #include <svtools/htmlout.hxx>
48 #include <svtools/parhtml.hxx>
49 #include <vcl/outdev.hxx>
52 #include "htmlexp.hxx"
55 #include "document.hxx"
57 #include "patattr.hxx"
58 #include "stlpool.hxx"
59 #include "scresid.hxx"
60 #include "formulacell.hxx"
61 #include "cellform.hxx"
62 #include "docoptio.hxx"
63 #include "editutil.hxx"
65 #include "cellvalue.hxx"
67 #include <editeng/flditem.hxx>
68 #include <editeng/borderline.hxx>
69 #include <unotools/syslocale.hxx>
71 // Without sc.hrc: error C2679: binary '=' : no operator defined which takes a
72 // right-hand operand of type 'const class String (__stdcall *)(class ScResId)'
74 // const String aStrTable( ScResId( SCSTR_TABLE ) ); aStrOut = aStrTable;
77 #include "globstr.hrc"
79 #include <com/sun/star/uno/Reference.h>
80 #include <com/sun/star/document/XDocumentProperties.hpp>
81 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
82 #include <rtl/strbuf.hxx>
84 using ::editeng::SvxBorderLine
;
85 using namespace ::com::sun::star
;
87 const static sal_Char sMyBegComment
[] = "<!-- ";
88 const static sal_Char sMyEndComment
[] = " -->";
89 const static sal_Char sFontFamily
[] = "font-family:";
90 const static sal_Char sFontSize
[] = "font-size:";
92 const sal_uInt16
ScHTMLExport::nDefaultFontSize
[SC_HTML_FONTSIZES
] =
94 HTMLFONTSZ1_DFLT
, HTMLFONTSZ2_DFLT
, HTMLFONTSZ3_DFLT
, HTMLFONTSZ4_DFLT
,
95 HTMLFONTSZ5_DFLT
, HTMLFONTSZ6_DFLT
, HTMLFONTSZ7_DFLT
98 sal_uInt16
ScHTMLExport::nFontSize
[SC_HTML_FONTSIZES
] = { 0 };
100 const char* ScHTMLExport::pFontSizeCss
[SC_HTML_FONTSIZES
] =
102 "xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large"
105 const sal_uInt16
ScHTMLExport::nCellSpacing
= 0;
106 const sal_Char
ScHTMLExport::sIndentSource
[nIndentMax
+1] =
107 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
109 // Macros for HTML export
111 #define TAG_ON( tag ) HTMLOutFuncs::Out_AsciiTag( rStrm, tag )
112 #define TAG_OFF( tag ) HTMLOutFuncs::Out_AsciiTag( rStrm, tag, false )
113 #define OUT_STR( str ) HTMLOutFuncs::Out_String( rStrm, str, eDestEnc, &aNonConvertibleChars )
114 #define OUT_LF() rStrm.WriteCharPtr( SAL_NEWLINE_STRING ).WriteCharPtr( GetIndentStr() )
115 #define TAG_ON_LF( tag ) (TAG_ON( tag ).WriteCharPtr( SAL_NEWLINE_STRING ).WriteCharPtr( GetIndentStr() ))
116 #define TAG_OFF_LF( tag ) (TAG_OFF( tag ).WriteCharPtr( SAL_NEWLINE_STRING ).WriteCharPtr( GetIndentStr() ))
117 #define OUT_HR() TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_horzrule )
118 #define OUT_COMMENT( comment ) (rStrm.WriteCharPtr( sMyBegComment ), OUT_STR( comment ) \
119 .WriteCharPtr( sMyEndComment ).WriteCharPtr( SAL_NEWLINE_STRING ) \
120 .WriteCharPtr( GetIndentStr() ))
122 #define OUT_SP_CSTR_ASS( s ) rStrm.WriteChar( ' ').WriteCharPtr( s ).WriteChar( '=' )
124 #define GLOBSTR(id) ScGlobal::GetRscString( id )
126 FltError
ScFormatFilterPluginImpl::ScExportHTML( SvStream
& rStrm
, const OUString
& rBaseURL
, ScDocument
* pDoc
,
127 const ScRange
& rRange
, const rtl_TextEncoding
/*eNach*/, bool bAll
,
128 const OUString
& rStreamPath
, OUString
& rNonConvertibleChars
, const OUString
& rFilterOptions
)
130 ScHTMLExport
aEx( rStrm
, rBaseURL
, pDoc
, rRange
, bAll
, rStreamPath
, rFilterOptions
);
131 FltError nErr
= aEx
.Write();
132 rNonConvertibleChars
= aEx
.GetNonConvertibleChars();
136 static OString
lcl_getColGroupString(sal_Int32 nSpan
, sal_Int32 nWidth
)
138 OStringBuffer
aByteStr(OOO_STRING_SVTOOLS_HTML_colgroup
);
139 aByteStr
.append(' ');
142 aByteStr
.append(OOO_STRING_SVTOOLS_HTML_O_span
);
143 aByteStr
.append("=\"");
144 aByteStr
.append(nSpan
);
145 aByteStr
.append("\" ");
147 aByteStr
.append(OOO_STRING_SVTOOLS_HTML_O_width
);
148 aByteStr
.append("=\"");
149 aByteStr
.append(nWidth
);
150 aByteStr
.append('"');
151 return aByteStr
.makeStringAndClear();
154 static void lcl_AddStamp( OUString
& rStr
, const OUString
& rName
,
155 const ::com::sun::star::util::DateTime
& rDateTime
,
156 const LocaleDataWrapper
& rLoc
)
158 Date
aD(rDateTime
.Day
, rDateTime
.Month
, rDateTime
.Year
);
159 tools::Time
aT(rDateTime
.Hours
, rDateTime
.Minutes
, rDateTime
.Seconds
,
160 rDateTime
.NanoSeconds
);
161 DateTime
aDateTime(aD
,aT
);
163 OUString aStrDate
= rLoc
.getDate( aDateTime
);
164 OUString aStrTime
= rLoc
.getTime( aDateTime
);
166 rStr
+= GLOBSTR( STR_BY
) + " ";
167 if (!rName
.isEmpty())
171 rStr
+= " " + GLOBSTR( STR_ON
) + " ";
172 if (!aStrDate
.isEmpty())
177 if (!aStrTime
.isEmpty())
183 static OString
lcl_makeHTMLColorTriplet(const Color
& rColor
)
185 OStringBuffer
aStr( "\"#" );
186 // <font COLOR="#00FF40">hello</font>
189 p
+= sprintf( p
, "%02X", rColor
.GetRed() );
190 p
+= sprintf( p
, "%02X", rColor
.GetGreen() );
191 p
+= sprintf( p
, "%02X", rColor
.GetBlue() );
194 return aStr
.makeStringAndClear();
197 ScHTMLExport::ScHTMLExport( SvStream
& rStrmP
, const OUString
& rBaseURL
, ScDocument
* pDocP
,
198 const ScRange
& rRangeP
, bool bAllP
,
199 const OUString
& rStreamPathP
, const OUString
& rFilterOptions
) :
200 ScExportBase( rStrmP
, pDocP
, rRangeP
),
201 aBaseURL( rBaseURL
),
202 aStreamPath( rStreamPathP
),
203 aFilterOptions( rFilterOptions
),
204 pAppWin( Application::GetDefaultDevice() ),
208 bTabHasGraphics( false ),
209 bTabAlignedLeft( false ),
210 bCalcAsShown( pDocP
->GetDocOptions().IsCalcAsShown() ),
211 bTableDataWidth( true ),
212 bTableDataHeight( true ),
213 mbSkipImages ( false ),
214 mbSkipHeaderFooter( false )
216 strcpy( sIndent
, sIndentSource
);
219 // set HTML configuration
220 SvxHtmlOptions
& rHtmlOptions
= SvxHtmlOptions::Get();
221 eDestEnc
= (pDoc
->IsClipOrUndo() ? RTL_TEXTENCODING_UTF8
: rHtmlOptions
.GetTextEncoding());
222 bCopyLocalFileToINet
= rHtmlOptions
.IsSaveGraphicsLocal();
224 if (rFilterOptions
== "SkipImages")
228 else if (rFilterOptions
== "SkipHeaderFooter")
230 mbSkipHeaderFooter
= true;
233 for ( sal_uInt16 j
=0; j
< SC_HTML_FONTSIZES
; j
++ )
235 sal_uInt16 nSize
= rHtmlOptions
.GetFontSize( j
);
236 // remember in Twips, like our SvxFontHeightItem
238 nFontSize
[j
] = nSize
* 20;
240 nFontSize
[j
] = nDefaultFontSize
[j
] * 20;
243 const SCTAB nCount
= pDoc
->GetTableCount();
244 for ( SCTAB nTab
= 0; nTab
< nCount
; nTab
++ )
246 if ( !IsEmptyTable( nTab
) )
250 // Content-Id for Mail export?
251 SfxObjectShell
* pDocSh
= pDoc
->GetDocumentShell();
254 const SfxPoolItem
* pItem
= pDocSh
->GetItem( SID_ORIGURL
);
257 aCId
= static_cast<const SfxStringItem
*>(pItem
)->GetValue();
258 OSL_ENSURE( !aCId
.isEmpty(), "CID without length!" );
263 ScHTMLExport::~ScHTMLExport()
268 sal_uInt16
ScHTMLExport::GetFontSizeNumber( sal_uInt16 nHeight
)
270 sal_uInt16 nSize
= 1;
271 for ( sal_uInt16 j
=SC_HTML_FONTSIZES
-1; j
>0; j
-- )
273 if( nHeight
> (nFontSize
[j
] + nFontSize
[j
-1]) / 2 )
274 { // The one next to it
282 const char* ScHTMLExport::GetFontSizeCss( sal_uInt16 nHeight
)
284 sal_uInt16 nSize
= GetFontSizeNumber( nHeight
);
285 return pFontSizeCss
[ nSize
-1 ];
288 sal_uInt16
ScHTMLExport::ToPixel( sal_uInt16 nVal
)
292 nVal
= (sal_uInt16
)pAppWin
->LogicToPixel(
293 Size( nVal
, nVal
), MapMode( MAP_TWIP
) ).Width();
294 if( !nVal
) // If there's a Twip there should also be a Pixel
300 Size
ScHTMLExport::MMToPixel( const Size
& rSize
)
303 aSize
= pAppWin
->LogicToPixel( rSize
, MapMode( MAP_100TH_MM
) );
304 // If there's something there should also be a Pixel
305 if ( !aSize
.Width() && rSize
.Width() )
307 if ( !aSize
.Height() && rSize
.Height() )
312 sal_uLong
ScHTMLExport::Write()
314 if (!mbSkipHeaderFooter
)
316 rStrm
.WriteChar( '<' ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_doctype
).WriteChar( ' ' ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_doctype40
).WriteChar( '>' )
317 .WriteCharPtr( SAL_NEWLINE_STRING
).WriteCharPtr( SAL_NEWLINE_STRING
);
318 TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_html
);
324 if (!mbSkipHeaderFooter
)
325 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_html
);
327 return rStrm
.GetError();
330 void ScHTMLExport::WriteHeader()
332 IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_head
);
334 if ( pDoc
->IsClipOrUndo() )
335 { // no real DocInfo available, but some META information like charset needed
336 SfxFrameHTMLWriter::Out_DocInfo( rStrm
, aBaseURL
, NULL
, sIndent
, eDestEnc
, &aNonConvertibleChars
);
340 using namespace ::com::sun::star
;
341 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS(
342 pDoc
->GetDocumentShell()->GetModel(), uno::UNO_QUERY_THROW
);
343 uno::Reference
<document::XDocumentProperties
> xDocProps
344 = xDPS
->getDocumentProperties();
345 SfxFrameHTMLWriter::Out_DocInfo( rStrm
, aBaseURL
, xDocProps
,
346 sIndent
, eDestEnc
, &aNonConvertibleChars
);
349 if (!xDocProps
->getPrintedBy().isEmpty())
351 OUT_COMMENT( GLOBSTR( STR_DOC_INFO
) );
352 OUString aStrOut
= ( GLOBSTR( STR_DOC_PRINTED
) ) + ": ";
353 lcl_AddStamp( aStrOut
, xDocProps
->getPrintedBy(),
354 xDocProps
->getPrintDate(), *ScGlobal::pLocaleData
);
355 OUT_COMMENT( aStrOut
);
362 PageDefaults( bAll
? 0 : aRange
.aStart
.Tab() );
364 rStrm
.WriteCharPtr( "<" ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_style
).WriteCharPtr( " " ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_O_type
).WriteCharPtr( "=\"text/css\">" );
367 rStrm
.WriteCharPtr( OOO_STRING_SVTOOLS_HTML_body
).WriteCharPtr( "," ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_division
).WriteCharPtr( "," ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_table
).WriteCharPtr( "," )
368 .WriteCharPtr( OOO_STRING_SVTOOLS_HTML_thead
).WriteCharPtr( "," ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_tbody
).WriteCharPtr( "," ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_tfoot
).WriteCharPtr( "," )
369 .WriteCharPtr( OOO_STRING_SVTOOLS_HTML_tablerow
).WriteCharPtr( "," ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_tableheader
).WriteCharPtr( "," )
370 .WriteCharPtr( OOO_STRING_SVTOOLS_HTML_tabledata
).WriteCharPtr( "," ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_parabreak
).WriteCharPtr( " { " ).WriteCharPtr( sFontFamily
);
371 sal_Int32 nFonts
= comphelper::string::getTokenCount(aHTMLStyle
.aFontFamilyName
, ';');
374 rStrm
.WriteChar( '\"' );
375 OUT_STR( aHTMLStyle
.aFontFamilyName
);
376 rStrm
.WriteChar( '\"' );
379 { // Fontlist, VCL: Semicolon as separator
380 // CSS1: Comma as separator and every single font name quoted
381 const OUString
& rList
= aHTMLStyle
.aFontFamilyName
;
382 for ( sal_Int32 j
= 0, nPos
= 0; j
< (sal_Int32
) nFonts
; j
++ )
384 rStrm
.WriteChar( '\"' );
385 OUT_STR( rList
.getToken( 0, ';', nPos
) );
386 rStrm
.WriteChar( '\"' );
388 rStrm
.WriteCharPtr( ", " );
391 rStrm
.WriteCharPtr( "; " ).WriteCharPtr( sFontSize
)
392 .WriteCharPtr( GetFontSizeCss( ( sal_uInt16
) aHTMLStyle
.nFontHeight
) ).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( ScGlobal::GetRscString( 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 .WriteCharPtr( OString::number(nTab
).getStr() )
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
= NULL
;
435 OSL_ENSURE( pStylePool
, "StylePool not found! :-(" );
437 // remember defaults for compare in WriteCell
438 if ( !aHTMLStyle
.bInitialized
)
440 pStylePool
->SetSearchMask( SFX_STYLE_FAMILY_PARA
, SFXSTYLEBIT_ALL
);
441 pStyleSheet
= pStylePool
->Find(
442 ScGlobal::GetRscString(STR_STYLENAME_STANDARD
),
443 SFX_STYLE_FAMILY_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( SFX_STYLE_FAMILY_PAGE
, SFXSTYLEBIT_ALL
);
464 pStyleSheet
= pStylePool
->Find( pDoc
->GetPageStyle( nTab
), SFX_STYLE_FAMILY_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
= static_cast<const SvxBrushItem
*>(&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 table::BorderLineStyle::SOLID
:
500 aOut
.append("solid");
502 case table::BorderLineStyle::DOTTED
:
503 aOut
.append("dotted");
505 case table::BorderLineStyle::DASHED
:
506 case table::BorderLineStyle::DASH_DOT
:
507 case table::BorderLineStyle::DASH_DOT_DOT
:
508 aOut
.append("dashed");
510 case table::BorderLineStyle::DOUBLE
:
511 case table::BorderLineStyle::DOUBLE_THIN
:
512 case table::BorderLineStyle::THINTHICK_SMALLGAP
:
513 case table::BorderLineStyle::THINTHICK_MEDIUMGAP
:
514 case table::BorderLineStyle::THINTHICK_LARGEGAP
:
515 case table::BorderLineStyle::THICKTHIN_SMALLGAP
:
516 case table::BorderLineStyle::THICKTHIN_MEDIUMGAP
:
517 case table::BorderLineStyle::THICKTHIN_LARGEGAP
:
518 aOut
.append("double");
520 case table::BorderLineStyle::EMBOSSED
:
521 aOut
.append("ridge");
523 case table::BorderLineStyle::ENGRAVED
:
524 aOut
.append("groove");
526 case table::BorderLineStyle::OUTSET
:
527 aOut
.append("outset");
529 case table::BorderLineStyle::INSET
:
530 aOut
.append("inset");
533 aOut
.append("hidden");
539 snprintf( hex
, 7, "%06x", static_cast< unsigned int >( 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
= static_cast<const SvxBrushItem
*>(&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 sal_uInt16 nErr
= XOutBitmap::WriteGraphic( *pGrf
, aGrfNm
,
576 "JPG", XOUTBMP_USE_NATIVE_IF_POSSIBLE
);
577 if( !nErr
) // Contains errors, as we have nothing to output
579 aGrfNm
= URIHelper::SmartRel2Abs(
580 INetURLObject(aBaseURL
),
581 aGrfNm
, URIHelper::GetMaybeFileHdl(), true, false);
583 MakeCIdURL( aGrfNm
);
591 if( bCopyLocalFileToINet
|| HasCId() )
593 CopyLocalFileToINet( aGrfNm
, aStreamPath
);
595 MakeCIdURL( aGrfNm
);
598 aGrfNm
= URIHelper::SmartRel2Abs(
599 INetURLObject(aBaseURL
),
600 aGrfNm
, URIHelper::GetMaybeFileHdl(), true, false);
603 if( !aLink
.isEmpty() )
605 rStrm
.WriteChar( ' ' ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_O_background
).WriteCharPtr( "=\"" );
606 OUT_STR( URIHelper::simpleNormalizedMakeRelative(
608 aLink
) ).WriteChar( '\"' );
612 if ( !aHTMLStyle
.aBackgroundColor
.GetTransparency() )
613 { // A transparent background color should always result in default
614 // background of the browser. Also, HTMLOutFuncs::Out_Color() writes
615 // black #000000 for COL_AUTO which is the same as white #ffffff with
616 // transparency set to 0xff, our default background.
617 OUT_SP_CSTR_ASS( OOO_STRING_SVTOOLS_HTML_O_bgcolor
);
618 HTMLOutFuncs::Out_Color( rStrm
, aHTMLStyle
.aBackgroundColor
);
621 rStrm
.WriteChar( '>' ); OUT_LF();
629 if (!mbSkipHeaderFooter
)
630 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_body
);
633 void ScHTMLExport::WriteTables()
635 const SCTAB nTabCount
= pDoc
->GetTableCount();
636 const OUString
aStrTable( ScResId( SCSTR_TABLE
) );
645 SCCOL nStartColFix
= 0;
646 SCROW nStartRowFix
= 0;
647 SCCOL nEndColFix
= 0;
648 SCROW nEndRowFix
= 0;
649 ScDrawLayer
* pDrawLayer
= pDoc
->GetDrawLayer();
653 nEndTab
= nTabCount
- 1;
657 nStartCol
= nStartColFix
= aRange
.aStart
.Col();
658 nStartRow
= nStartRowFix
= aRange
.aStart
.Row();
659 nStartTab
= aRange
.aStart
.Tab();
660 nEndCol
= nEndColFix
= aRange
.aEnd
.Col();
661 nEndRow
= nEndRowFix
= aRange
.aEnd
.Row();
662 nEndTab
= aRange
.aEnd
.Tab();
664 SCTAB nTableStrNum
= 1;
665 for ( SCTAB nTab
=nStartTab
; nTab
<=nEndTab
; nTab
++ )
667 if ( !pDoc
->IsVisible( nTab
) )
672 if ( !GetDataArea( nTab
, nStartCol
, nStartRow
, nEndCol
, nEndRow
) )
675 if ( nUsedTables
> 1 )
677 aStrOut
= aStrTable
+ " " + OUString::number( nTableStrNum
++ ) + ": ";
682 rStrm
.WriteCharPtr( "<A NAME=\"table" )
683 .WriteCharPtr( OString::number(nTab
).getStr() )
684 .WriteCharPtr( "\">" );
685 TAG_ON( OOO_STRING_SVTOOLS_HTML_head1
);
687 TAG_ON( OOO_STRING_SVTOOLS_HTML_emphasis
);
689 pDoc
->GetName( nTab
, aStr
);
692 TAG_OFF( OOO_STRING_SVTOOLS_HTML_emphasis
);
693 TAG_OFF( OOO_STRING_SVTOOLS_HTML_head1
);
694 rStrm
.WriteCharPtr( "</A>" ); OUT_LF();
699 nStartCol
= nStartColFix
;
700 nStartRow
= nStartRowFix
;
701 nEndCol
= nEndColFix
;
702 nEndRow
= nEndRowFix
;
703 if ( !TrimDataArea( nTab
, nStartCol
, nStartRow
, nEndCol
, nEndRow
) )
708 OStringBuffer
aByteStrOut(OOO_STRING_SVTOOLS_HTML_table
);
710 bTabHasGraphics
= bTabAlignedLeft
= false;
711 if ( bAll
&& pDrawLayer
)
712 PrepareGraphics( pDrawLayer
, nTab
, nStartCol
, nStartRow
,
716 if ( bTabAlignedLeft
)
718 aByteStrOut
.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_align
).
720 append(OOO_STRING_SVTOOLS_HTML_AL_left
).append('"');
722 // ALIGN=LEFT allow text and graphics to flow around
724 aByteStrOut
.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_cellspacing
).
726 append(static_cast<sal_Int32
>(nCellSpacing
)).append('"');
728 // BORDER=0, we do the styling of the cells in <TD>
729 aByteStrOut
.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_border
).
731 IncIndent(1); TAG_ON_LF( aByteStrOut
.makeStringAndClear().getStr() );
733 // --- <COLGROUP> ----
735 SCCOL nCol
= nStartCol
;
736 sal_Int32 nWidth
= 0;
738 while( nCol
<= nEndCol
)
740 if( pDoc
->ColHidden(nCol
, nTab
) )
746 if( nWidth
!= ToPixel( pDoc
->GetColWidth( nCol
, nTab
) ) )
750 TAG_ON(lcl_getColGroupString(nSpan
, nWidth
).getStr());
751 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_colgroup
);
753 nWidth
= ToPixel( pDoc
->GetColWidth( nCol
, nTab
) );
762 TAG_ON(lcl_getColGroupString(nSpan
, nWidth
).getStr());
763 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_colgroup
);
767 // <TBODY> // Re-enable only when THEAD and TFOOT are exported
768 // IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_tbody );
769 // At least old (3.x, 4.x?) Netscape doesn't follow <TABLE COLS=n> and
770 // <COL WIDTH=x> specified, but needs a width at every column.
771 bTableDataWidth
= true; // widths in first row
772 bool bHasHiddenRows
= pDoc
->HasHiddenRows(nStartRow
, nEndRow
, nTab
);
773 for ( SCROW nRow
=nStartRow
; nRow
<=nEndRow
; nRow
++ )
775 if ( bHasHiddenRows
&& pDoc
->RowHidden(nRow
, nTab
) )
777 nRow
= pDoc
->FirstVisibleRow(nRow
+1, nEndRow
, nTab
);
782 IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_tablerow
);
783 bTableDataHeight
= true; // height at every first cell of each row
784 for ( SCCOL nCol2
=nStartCol
; nCol2
<=nEndCol
; nCol2
++ )
786 if ( pDoc
->ColHidden(nCol2
, nTab
) )
789 if ( nCol2
== nEndCol
)
791 WriteCell( nCol2
, nRow
, nTab
);
792 bTableDataHeight
= false;
794 bTableDataWidth
= false; // widths only in first row
796 if ( nRow
== nEndRow
)
798 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tablerow
);
800 // TODO: Uncomment later
801 // IncIndent(-1); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tbody );
803 IncIndent(-1); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_table
);
805 if ( bTabHasGraphics
&& !mbSkipImages
)
807 // the rest that is not in a cell
808 size_t ListSize
= aGraphList
.size();
809 for ( size_t i
= 0; i
< ListSize
; ++i
)
811 ScHTMLGraphEntry
* pE
= &aGraphList
[ i
];
813 WriteGraphEntry( pE
);
816 if ( bTabAlignedLeft
)
818 // clear <TABLE ALIGN=LEFT> with <BR CLEAR=LEFT>
819 aByteStrOut
.append(OOO_STRING_SVTOOLS_HTML_linebreak
);
820 aByteStrOut
.append(' ').
821 append(OOO_STRING_SVTOOLS_HTML_O_clear
).append('=').
822 append(OOO_STRING_SVTOOLS_HTML_AL_left
);
823 TAG_ON_LF( aByteStrOut
.makeStringAndClear().getStr() );
828 OUT_COMMENT( OUString("**************************************************************************") );
832 void ScHTMLExport::WriteCell( SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
834 const ScPatternAttr
* pAttr
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
835 const SfxItemSet
* pCondItemSet
= pDoc
->GetCondResult( nCol
, nRow
, nTab
);
837 const ScMergeFlagAttr
& rMergeFlagAttr
= static_cast<const ScMergeFlagAttr
&>( pAttr
->GetItem( ATTR_MERGE_FLAG
, pCondItemSet
) );
838 if ( rMergeFlagAttr
.IsOverlapped() )
841 ScAddress
aPos( nCol
, nRow
, nTab
);
842 ScHTMLGraphEntry
* pGraphEntry
= NULL
;
843 if ( bTabHasGraphics
&& !mbSkipImages
)
845 size_t ListSize
= aGraphList
.size();
846 for ( size_t i
= 0; i
< ListSize
; ++i
)
848 ScHTMLGraphEntry
* pE
= &aGraphList
[ i
];
849 if ( pE
->bInCell
&& pE
->aRange
.In( aPos
) )
851 if ( pE
->aRange
.aStart
== aPos
)
857 return ; // Is a Col/RowSpan, Overlapped
862 ScRefCellValue aCell
;
863 aCell
.assign(*pDoc
, aPos
);
865 sal_uLong nFormat
= pAttr
->GetNumberFormat( pFormatter
);
866 bool bValueData
= aCell
.hasNumeric();
867 SvtScriptType nScriptType
= SvtScriptType::NONE
;
868 if (!aCell
.isEmpty())
869 nScriptType
= pDoc
->GetScriptType(nCol
, nRow
, nTab
);
871 if ( nScriptType
== SvtScriptType::NONE
)
872 nScriptType
= aHTMLStyle
.nDefaultScriptType
;
874 OStringBuffer
aStrTD(OOO_STRING_SVTOOLS_HTML_tabledata
);
876 // border of the cells
877 const SvxBoxItem
* pBorder
= static_cast<const SvxBoxItem
*>( pDoc
->GetAttr( nCol
, nRow
, nTab
, ATTR_BORDER
) );
878 if ( pBorder
&& (pBorder
->GetTop() || pBorder
->GetBottom() || pBorder
->GetLeft() || pBorder
->GetRight()) )
880 aStrTD
.append(' ').append(OOO_STRING_SVTOOLS_HTML_style
).
883 bool bInsertSemicolon
= false;
884 aStrTD
.append(BorderToStyle("top", pBorder
->GetTop(),
886 aStrTD
.append(BorderToStyle("bottom", pBorder
->GetBottom(),
888 aStrTD
.append(BorderToStyle("left", pBorder
->GetLeft(),
890 aStrTD
.append(BorderToStyle("right", pBorder
->GetRight(),
896 const sal_Char
* pChar
;
897 sal_uInt16 nHeightPixel
;
899 const ScMergeAttr
& rMergeAttr
= static_cast<const ScMergeAttr
&>( pAttr
->GetItem( ATTR_MERGE
, pCondItemSet
) );
900 if ( pGraphEntry
|| rMergeAttr
.IsMerged() )
906 nC
= std::max( SCCOL(pGraphEntry
->aRange
.aEnd
.Col() - nCol
+ 1),
907 SCCOL(rMergeAttr
.GetColMerge()) );
909 nC
= rMergeAttr
.GetColMerge();
912 aStrTD
.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_colspan
).
913 append('=').append(static_cast<sal_Int32
>(nC
));
915 for ( jC
=nCol
, v
=0; jC
<nC
; jC
++ )
916 v
+= pDoc
->GetColWidth( jC
, nTab
);
920 nR
= std::max( SCROW(pGraphEntry
->aRange
.aEnd
.Row() - nRow
+ 1),
921 SCROW(rMergeAttr
.GetRowMerge()) );
923 nR
= rMergeAttr
.GetRowMerge();
926 aStrTD
.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_rowspan
).
927 append('=').append(static_cast<sal_Int32
>(nR
));
929 v
= pDoc
->GetRowHeight( nRow
, nR
-1, nTab
);
930 nHeightPixel
= ToPixel( static_cast< sal_uInt16
>( v
) );
933 nHeightPixel
= ToPixel( pDoc
->GetRowHeight( nRow
, nTab
) );
936 nHeightPixel
= ToPixel( pDoc
->GetRowHeight( nRow
, nTab
) );
938 if ( bTableDataHeight
)
940 aStrTD
.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_height
).
942 append(static_cast<sal_Int32
>(nHeightPixel
)).append('"');
945 const SvxFontItem
& rFontItem
= static_cast<const SvxFontItem
&>( pAttr
->GetItem(
946 ScGlobal::GetScriptedWhichID( nScriptType
, ATTR_FONT
),
949 const SvxFontHeightItem
& rFontHeightItem
= static_cast<const SvxFontHeightItem
&>(
950 pAttr
->GetItem( ScGlobal::GetScriptedWhichID( nScriptType
,
951 ATTR_FONT_HEIGHT
), pCondItemSet
) );
953 const SvxWeightItem
& rWeightItem
= static_cast<const SvxWeightItem
&>( pAttr
->GetItem(
954 ScGlobal::GetScriptedWhichID( nScriptType
, ATTR_FONT_WEIGHT
),
957 const SvxPostureItem
& rPostureItem
= static_cast<const SvxPostureItem
&>(
958 pAttr
->GetItem( ScGlobal::GetScriptedWhichID( nScriptType
,
959 ATTR_FONT_POSTURE
), pCondItemSet
) );
961 const SvxUnderlineItem
& rUnderlineItem
= static_cast<const SvxUnderlineItem
&>(
962 pAttr
->GetItem( ATTR_FONT_UNDERLINE
, pCondItemSet
) );
964 const SvxColorItem
& rColorItem
= static_cast<const SvxColorItem
&>( pAttr
->GetItem(
965 ATTR_FONT_COLOR
, pCondItemSet
) );
967 const SvxHorJustifyItem
& rHorJustifyItem
= static_cast<const SvxHorJustifyItem
&>(
968 pAttr
->GetItem( ATTR_HOR_JUSTIFY
, pCondItemSet
) );
970 const SvxVerJustifyItem
& rVerJustifyItem
= static_cast<const SvxVerJustifyItem
&>(
971 pAttr
->GetItem( ATTR_VER_JUSTIFY
, pCondItemSet
) );
973 const SvxBrushItem
& rBrushItem
= static_cast<const SvxBrushItem
&>( pAttr
->GetItem(
974 ATTR_BACKGROUND
, pCondItemSet
) );
977 if ( rBrushItem
.GetColor().GetTransparency() == 255 )
978 aBgColor
= aHTMLStyle
.aBackgroundColor
; // No unwanted background color
980 aBgColor
= rBrushItem
.GetColor();
982 bool bBold
= ( WEIGHT_BOLD
<= rWeightItem
.GetWeight() );
983 bool bItalic
= ( ITALIC_NONE
!= rPostureItem
.GetPosture() );
984 bool bUnderline
= ( UNDERLINE_NONE
!= rUnderlineItem
.GetLineStyle() );
985 bool bSetFontColor
= ( COL_AUTO
!= rColorItem
.GetValue().GetColor() ); // 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( (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 SVX_HOR_JUSTIFY_STANDARD
:
1005 pChar
= (bValueData
? OOO_STRING_SVTOOLS_HTML_AL_right
: OOO_STRING_SVTOOLS_HTML_AL_left
);
1007 case SVX_HOR_JUSTIFY_CENTER
: pChar
= OOO_STRING_SVTOOLS_HTML_AL_center
; break;
1008 case SVX_HOR_JUSTIFY_BLOCK
: pChar
= OOO_STRING_SVTOOLS_HTML_AL_justify
; break;
1009 case SVX_HOR_JUSTIFY_RIGHT
: pChar
= OOO_STRING_SVTOOLS_HTML_AL_right
; break;
1010 case SVX_HOR_JUSTIFY_LEFT
:
1011 case SVX_HOR_JUSTIFY_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 SVX_VER_JUSTIFY_TOP
: pChar
= OOO_STRING_SVTOOLS_HTML_VA_top
; break;
1021 case SVX_VER_JUSTIFY_CENTER
: pChar
= OOO_STRING_SVTOOLS_HTML_VA_middle
; break;
1022 case SVX_VER_JUSTIFY_BOTTOM
: pChar
= OOO_STRING_SVTOOLS_HTML_VA_bottom
; break;
1023 case SVX_VER_JUSTIFY_STANDARD
:
1024 default: pChar
= NULL
;
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 if ( bBold
) TAG_ON( OOO_STRING_SVTOOLS_HTML_bold
);
1063 if ( bItalic
) TAG_ON( OOO_STRING_SVTOOLS_HTML_italic
);
1064 if ( bUnderline
) TAG_ON( OOO_STRING_SVTOOLS_HTML_underline
);
1068 OStringBuffer
aStr(OOO_STRING_SVTOOLS_HTML_font
);
1071 aStr
.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_face
).
1073 sal_Int32 nFonts
= comphelper::string::getTokenCount(rFontItem
.GetFamilyName(), ';');
1076 OString aTmpStr
= HTMLOutFuncs::ConvertStringToHTML(
1077 rFontItem
.GetFamilyName(), eDestEnc
, &aNonConvertibleChars
);
1078 aStr
.append(aTmpStr
);
1081 { // Font list, VCL: Semicolon as separator, HTML: Comma
1082 const OUString
& rList
= rFontItem
.GetFamilyName();
1083 for ( sal_Int32 j
= 0, nPos
= 0; j
< (sal_Int32
)nFonts
; j
++ )
1085 OString aTmpStr
= HTMLOutFuncs::ConvertStringToHTML(
1086 rList
.getToken( 0, ';', nPos
), eDestEnc
,
1087 &aNonConvertibleChars
);
1088 aStr
.append(aTmpStr
);
1095 if ( nSetFontSizeNumber
)
1097 aStr
.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_size
).
1098 append('=').append(static_cast<sal_Int32
>(nSetFontSizeNumber
));
1100 if ( bSetFontColor
)
1102 Color aColor
= rColorItem
.GetValue();
1104 // always export automatic text color as black
1105 if ( aColor
.GetColor() == COL_AUTO
)
1106 aColor
.SetColor( COL_BLACK
);
1108 aStr
.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_color
).
1109 append('=').append(lcl_makeHTMLColorTriplet(aColor
));
1111 TAG_ON(aStr
.makeStringAndClear().getStr());
1115 bool bFieldText
= false;
1118 switch (aCell
.meType
)
1120 case CELLTYPE_EDIT
:
1121 bFieldText
= WriteFieldText(aCell
.mpEditText
);
1126 ScCellFormat::GetString(aCell
, nFormat
, aStrOut
, &pColor
, *pFormatter
, pDoc
);
1131 if ( aStrOut
.isEmpty() )
1133 TAG_ON( OOO_STRING_SVTOOLS_HTML_linebreak
); // No completely empty line
1137 OUString aStr
= aStrOut
;
1138 sal_Int32 nPos
= aStr
.indexOf( '\n' );
1145 sal_Int32 nStartPos
= 0;
1148 OUString aSingleLine
= aStr
.copy( nStartPos
, nPos
- nStartPos
);
1149 OUT_STR( aSingleLine
);
1150 TAG_ON( OOO_STRING_SVTOOLS_HTML_linebreak
);
1151 nStartPos
= nPos
+ 1;
1153 while( ( nPos
= aStr
.indexOf( '\n', nStartPos
) ) != -1 );
1154 OUString aSingleLine
= aStr
.copy( nStartPos
, aStr
.getLength() - nStartPos
);
1155 OUT_STR( aSingleLine
);
1160 WriteGraphEntry( pGraphEntry
);
1162 if ( bSetFont
) TAG_OFF( OOO_STRING_SVTOOLS_HTML_font
);
1163 if ( bUnderline
) TAG_OFF( OOO_STRING_SVTOOLS_HTML_underline
);
1164 if ( bItalic
) TAG_OFF( OOO_STRING_SVTOOLS_HTML_italic
);
1165 if ( bBold
) TAG_OFF( OOO_STRING_SVTOOLS_HTML_bold
);
1167 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tabledata
);
1170 bool ScHTMLExport::WriteFieldText( const EditTextObject
* pData
)
1172 bool bFields
= false;
1173 // text and anchor of URL fields, Doc-Engine is a ScFieldEditEngine
1174 EditEngine
& rEngine
= pDoc
->GetEditEngine();
1175 rEngine
.SetText( *pData
);
1176 sal_Int32 nParas
= rEngine
.GetParagraphCount();
1179 ESelection
aSel( 0, 0, nParas
-1, rEngine
.GetTextLen( nParas
-1 ) );
1180 SfxItemSet
aSet( rEngine
.GetAttribs( aSel
) );
1181 SfxItemState eFieldState
= aSet
.GetItemState( EE_FEATURE_FIELD
, false );
1182 if ( eFieldState
== SfxItemState::DONTCARE
|| eFieldState
== SfxItemState::SET
)
1187 bool bOldUpdateMode
= rEngine
.GetUpdateMode();
1188 rEngine
.SetUpdateMode( true ); // no portions if not formatted
1189 for ( sal_Int32 nPar
=0; nPar
< nParas
; nPar
++ )
1192 TAG_ON( OOO_STRING_SVTOOLS_HTML_linebreak
);
1193 std::vector
<sal_Int32
> aPortions
;
1194 rEngine
.GetPortions( nPar
, aPortions
);
1195 sal_Int32 nStart
= 0;
1196 for ( std::vector
<sal_Int32
>::const_iterator
it(aPortions
.begin()); it
!= aPortions
.end(); ++it
)
1198 sal_Int32 nEnd
= *it
;
1199 ESelection
aSel( nPar
, nStart
, nPar
, nEnd
);
1201 // fields are single characters
1202 if ( nEnd
== nStart
+1 )
1204 const SfxPoolItem
* pItem
;
1205 SfxItemSet aSet
= rEngine
.GetAttribs( aSel
);
1206 if ( aSet
.GetItemState( EE_FEATURE_FIELD
, false, &pItem
) == SfxItemState::SET
)
1208 const SvxFieldData
* pField
= static_cast<const SvxFieldItem
*>(pItem
)->GetField();
1209 if ( pField
&& pField
->ISA(SvxURLField
) )
1212 const SvxURLField
* pURLField
= static_cast<const SvxURLField
*>(pField
);
1213 // String aFieldText = rEngine.GetText( aSel );
1214 rStrm
.WriteChar( '<' ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_anchor
).WriteChar( ' ' ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_O_href
).WriteCharPtr( "=\"" );
1215 OUT_STR( pURLField
->GetURL() );
1216 rStrm
.WriteCharPtr( "\">" );
1217 OUT_STR( pURLField
->GetRepresentation() );
1218 rStrm
.WriteCharPtr( "</" ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_anchor
).WriteChar( '>' );
1223 OUT_STR( rEngine
.GetText( aSel
) );
1227 rEngine
.SetUpdateMode( bOldUpdateMode
);
1232 bool ScHTMLExport::CopyLocalFileToINet( OUString
& rFileNm
,
1233 const OUString
& rTargetNm
, bool bFileToFile
)
1236 INetURLObject aFileUrl
, aTargetUrl
;
1237 aFileUrl
.SetSmartURL( rFileNm
);
1238 aTargetUrl
.SetSmartURL( rTargetNm
);
1239 if( INetProtocol::File
== aFileUrl
.GetProtocol() &&
1240 ( (bFileToFile
&& INetProtocol::File
== aTargetUrl
.GetProtocol()) ||
1241 (!bFileToFile
&& INetProtocol::File
!= aTargetUrl
.GetProtocol() &&
1242 INetProtocol::Ftp
<= aTargetUrl
.GetProtocol() &&
1243 INetProtocol::Javascript
>= aTargetUrl
.GetProtocol()) ) )
1247 // Did we already move the file?
1248 std::map
<OUString
, OUString
>::iterator it
= pFileNameMap
->find( rFileNm
);
1249 if( it
!= pFileNameMap
->end() )
1251 rFileNm
= it
->second
;
1257 pFileNameMap
.reset( new std::map
<OUString
, OUString
>() );
1260 SvFileStream
aTmp( aFileUrl
.PathToFileName(), StreamMode::READ
);
1262 OUString aSrc
= rFileNm
;
1263 OUString aDest
= aTargetUrl
.GetPartBeforeLastName();
1264 aDest
+= aFileUrl
.GetName();
1268 INetURLObject
aCpyURL( aDest
);
1269 SvFileStream
aCpy( aCpyURL
.PathToFileName(), StreamMode::WRITE
);
1270 aCpy
.WriteStream( aTmp
);
1273 bRet
= SVSTREAM_OK
== aCpy
.GetError();
1277 SfxMedium
aMedium( aDest
, StreamMode::WRITE
| StreamMode::SHARE_DENYNONE
);
1280 SvFileStream
aCpy( aMedium
.GetPhysicalName(), StreamMode::WRITE
);
1281 aCpy
.WriteStream( aTmp
);
1288 bRet
= 0 == aMedium
.GetError();
1293 pFileNameMap
->insert( std::make_pair( aSrc
, aDest
) );
1301 void ScHTMLExport::MakeCIdURL( OUString
& rURL
)
1303 if( aCId
.isEmpty() )
1306 INetURLObject
aURLObj( rURL
);
1307 if( INetProtocol::File
!= aURLObj
.GetProtocol() )
1310 OUString
aLastName( aURLObj
.GetLastName().toAsciiLowerCase() );
1311 OSL_ENSURE( !aLastName
.isEmpty(), "filename without length!" );
1313 rURL
= "cid:" + aLastName
+ "." + aCId
;
1316 void ScHTMLExport::IncIndent( short nVal
)
1318 sIndent
[nIndent
] = '\t';
1319 nIndent
= nIndent
+ nVal
;
1322 else if ( nIndent
> nIndentMax
)
1323 nIndent
= nIndentMax
;
1324 sIndent
[nIndent
] = 0;
1327 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */