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 .
21 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
22 #include <com/sun/star/drawing/GraphicExportFilter.hpp>
23 #include <com/sun/star/frame/XModel.hpp>
24 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
26 #include <sal/log.hxx>
27 #include <rtl/tencinfo.h>
28 #include <comphelper/processfactory.hxx>
29 #include <o3tl/safeint.hxx>
30 #include <osl/file.hxx>
31 #include <unotools/pathoptions.hxx>
32 #include <unotools/ucbstreamhelper.hxx>
33 #include <com/sun/star/frame/XStorable.hpp>
34 #include <sfx2/frmhtmlw.hxx>
35 #include <sfx2/progress.hxx>
36 #include <vcl/svapp.hxx>
37 #include <vcl/weld.hxx>
38 #include <svx/svditer.hxx>
39 #include <vcl/imaprect.hxx>
40 #include <vcl/imapcirc.hxx>
41 #include <vcl/imappoly.hxx>
42 #include <editeng/eeitem.hxx>
43 #include <editeng/outlobj.hxx>
44 #include <editeng/editobj.hxx>
45 #include <svx/svdopath.hxx>
46 #include <svtools/htmlout.hxx>
47 #include <svtools/colorcfg.hxx>
48 #include <editeng/colritem.hxx>
49 #include <editeng/editeng.hxx>
50 #include <editeng/wghtitem.hxx>
51 #include <editeng/udlnitem.hxx>
52 #include <editeng/postitem.hxx>
53 #include <editeng/crossedoutitem.hxx>
54 #include <editeng/flditem.hxx>
55 #include <svl/style.hxx>
56 #include <editeng/frmdiritem.hxx>
57 #include <svx/svdoutl.hxx>
58 #include <svx/svdogrp.hxx>
59 #include <svx/svdotable.hxx>
60 #include <svx/ImageMapInfo.hxx>
61 #include <tools/urlobj.hxx>
62 #include <svtools/sfxecode.hxx>
63 #include <basegfx/polygon/b2dpolygon.hxx>
64 #include <tools/debug.hxx>
65 #include <tools/diagnose_ex.h>
67 #include <drawdoc.hxx>
68 #include <DrawDocShell.hxx>
69 #include "htmlpublishmode.hxx"
70 #include <Outliner.hxx>
72 #include <strings.hrc>
73 #include <strings.hxx>
74 #include <anminfo.hxx>
75 #include <sdresid.hxx>
76 #include "buttonset.hxx"
78 using namespace ::com::sun::star
;
79 using namespace ::com::sun::star::uno
;
80 using namespace ::com::sun::star::beans
;
81 using namespace ::com::sun::star::frame
;
82 using namespace ::com::sun::star::lang
;
83 using namespace ::com::sun::star::document
;
85 using namespace sdr::table
;
87 // get parameter from Itemset
88 #define RESTOHTML( res ) StringToHTMLString(SdResId(res))
90 const char * const pButtonNames
[] =
106 #define BTN_FIRST_0 0
107 #define BTN_FIRST_1 1
121 // Helper class for the simple creation of files local/remote
125 std::unique_ptr
<SvStream
> pOStm
;
133 ErrCode
createStream( const OUString
& rUrl
, SvStream
*& rpStr
);
134 void createFileName( const OUString
& rUrl
, OUString
& rFileName
);
140 // Helper class for the embedding of text attributes into the html output
156 explicit HtmlState( Color aDefColor
);
158 OUString
SetWeight( bool bWeight
);
159 OUString
SetItalic( bool bItalic
);
160 OUString
SetUnderline( bool bUnderline
);
161 OUString
SetColor( Color aColor
);
162 OUString
SetStrikeout( bool bStrike
);
163 OUString
SetLink( const OUString
& aLink
, const OUString
& aTarget
);
167 // close all still open tags
168 OUString
HtmlState::Flush()
170 OUString aStr
= SetWeight(false)
172 + SetUnderline(false)
173 + SetStrikeout(false)
174 + SetColor(maDefColor
)
180 // c'tor with default color for the page
181 HtmlState::HtmlState( Color aDefColor
)
188 maDefColor(aDefColor
)
192 // enables/disables bold print
193 OUString
HtmlState::SetWeight( bool bWeight
)
197 if(bWeight
&& !mbWeight
)
199 else if(!bWeight
&& mbWeight
)
206 // enables/disables italic
208 OUString
HtmlState::SetItalic( bool bItalic
)
212 if(bItalic
&& !mbItalic
)
214 else if(!bItalic
&& mbItalic
)
221 // enables/disables underlines
223 OUString
HtmlState::SetUnderline( bool bUnderline
)
227 if(bUnderline
&& !mbUnderline
)
229 else if(!bUnderline
&& mbUnderline
)
232 mbUnderline
= bUnderline
;
236 // enables/disables strike through
237 OUString
HtmlState::SetStrikeout( bool bStrike
)
241 if(bStrike
&& !mbStrike
)
243 else if(!bStrike
&& mbStrike
)
250 // Sets the specified text color
251 OUString
HtmlState::SetColor( Color aColor
)
255 if(mbColor
&& aColor
== maColor
)
264 if(aColor
!= maDefColor
)
267 aStr
+= "<font color=\"" + HtmlExport::ColorToHTMLString(aColor
) + "\">";
274 // enables/disables a hyperlink
275 OUString
HtmlState::SetLink( const OUString
& aLink
, const OUString
& aTarget
)
279 if(mbLink
&&maLink
== aLink
&&maTarget
==aTarget
)
288 if (!aLink
.isEmpty())
290 aStr
+= "<a href=\"" + aLink
;
291 if (!aTarget
.isEmpty())
293 aStr
+= "\" target=\"" + aTarget
;
306 OUString
getParagraphStyle( SdrOutliner
* pOutliner
, sal_Int32 nPara
)
308 SfxItemSet
aParaSet( pOutliner
->GetParaAttribs( nPara
) );
312 if( aParaSet
.GetItem
<SvxFrameDirectionItem
>( EE_PARA_WRITINGDIR
)->GetValue() == SvxFrameDirection::Horizontal_RL_TB
)
315 sStyle
= "direction: rtl;";
319 // This is the default so don't write it out
320 // sStyle += "direction: ltr;";
325 void lclAppendStyle(OUStringBuffer
& aBuffer
, const OUString
& aTag
, const OUString
& aStyle
)
327 if (aStyle
.isEmpty())
328 aBuffer
.append("<").append(aTag
).append(">");
330 aBuffer
.append("<").append(aTag
).append(" style=\"").append(aStyle
).append("\">");
333 } // anonymous namespace
335 constexpr OUStringLiteral
gaHTMLHeader(
336 u
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n"
337 " \"http://www.w3.org/TR/html4/transitional.dtd\">\r\n"
338 "<html>\r\n<head>\r\n" );
340 constexpr OUStringLiteral gaHTMLExtension
= u
"" STR_HTMLEXP_DEFAULT_EXTENSION
;
342 // constructor for the html export helper classes
343 HtmlExport::HtmlExport(
344 const OUString
& aPath
,
345 const Sequence
< PropertyValue
>& rParams
,
346 SdDrawDocument
* pExpDoc
,
347 sd::DrawDocShell
* pDocShell
)
350 mpDocSh( pDocShell
),
352 meMode( PUBLISH_SINGLE_DOCUMENT
),
353 mbContentsPage(false),
355 mnWidthPixel( PUB_MEDRES_WIDTH
),
356 meFormat( FORMAT_JPG
),
361 mbHiddenSlides(true),
363 maTextColor(COL_BLACK
),
364 maBackColor(COL_WHITE
),
367 meScript( SCRIPT_ASP
),
368 mpButtonSet( new ButtonSet() )
370 bool bChange
= mpDoc
->IsChanged();
372 maIndexUrl
+= gaHTMLExtension
;
374 InitExportParameters( rParams
);
382 case PUBLISH_WEBCAST
:
388 case PUBLISH_SINGLE_DOCUMENT
:
389 ExportSingleDocument();
393 mpDoc
->SetChanged(bChange
);
396 HtmlExport::~HtmlExport()
400 // get common export parameters from item set
401 void HtmlExport::InitExportParameters( const Sequence
< PropertyValue
>& rParams
)
403 mbImpress
= mpDoc
->GetDocumentType() == DocumentType::Impress
;
406 for( const PropertyValue
& rParam
: rParams
)
408 if ( rParam
.Name
== "PublishMode" )
411 rParam
.Value
>>= temp
;
412 meMode
= static_cast<HtmlPublishMode
>(temp
);
414 else if ( rParam
.Name
== "IndexURL" )
416 rParam
.Value
>>= aStr
;
419 else if ( rParam
.Name
== "Format" )
422 rParam
.Value
>>= temp
;
423 meFormat
= static_cast<PublishingFormat
>(temp
);
425 else if ( rParam
.Name
== "Compression" )
427 rParam
.Value
>>= aStr
;
428 OUString
aTmp( aStr
);
431 aTmp
= aTmp
.replaceFirst("%", "");
432 mnCompression
= static_cast<sal_Int16
>(aTmp
.toInt32());
435 else if ( rParam
.Name
== "Width" )
438 rParam
.Value
>>= temp
;
439 mnWidthPixel
= static_cast<sal_uInt16
>(temp
);
441 else if ( rParam
.Name
== "UseButtonSet" )
444 rParam
.Value
>>= temp
;
445 mnButtonThema
= static_cast<sal_Int16
>(temp
);
447 else if ( rParam
.Name
== "IsExportNotes" )
452 rParam
.Value
>>= temp
;
456 else if ( rParam
.Name
== "IsExportContentsPage" )
459 rParam
.Value
>>= temp
;
460 mbContentsPage
= temp
;
462 else if ( rParam
.Name
== "Author" )
464 rParam
.Value
>>= aStr
;
467 else if ( rParam
.Name
== "EMail" )
469 rParam
.Value
>>= aStr
;
472 else if ( rParam
.Name
== "HomepageURL" )
474 rParam
.Value
>>= aStr
;
477 else if ( rParam
.Name
== "UserText" )
479 rParam
.Value
>>= aStr
;
482 else if ( rParam
.Name
== "EnableDownload" )
485 rParam
.Value
>>= temp
;
488 else if ( rParam
.Name
== "SlideSound" )
491 rParam
.Value
>>= temp
;
494 else if ( rParam
.Name
== "HiddenSlides" )
497 rParam
.Value
>>= temp
;
498 mbHiddenSlides
= temp
;
500 else if ( rParam
.Name
== "BackColor" )
503 rParam
.Value
>>= temp
;
504 maBackColor
= Color(temp
);
507 else if ( rParam
.Name
== "TextColor" )
510 rParam
.Value
>>= temp
;
511 maTextColor
= Color(temp
);
514 else if ( rParam
.Name
== "LinkColor" )
517 rParam
.Value
>>= temp
;
518 maLinkColor
= Color(temp
);
521 else if ( rParam
.Name
== "VLinkColor" )
524 rParam
.Value
>>= temp
;
525 maVLinkColor
= Color(temp
);
528 else if ( rParam
.Name
== "ALinkColor" )
531 rParam
.Value
>>= temp
;
532 maALinkColor
= Color(temp
);
535 else if ( rParam
.Name
== "IsUseDocumentColors" )
538 rParam
.Value
>>= temp
;
541 else if ( rParam
.Name
== "KioskSlideDuration" )
544 rParam
.Value
>>= temp
;
545 mfSlideDuration
= temp
;
548 else if ( rParam
.Name
== "KioskEndless" )
551 rParam
.Value
>>= temp
;
554 else if ( rParam
.Name
== "WebCastCGIURL" )
556 rParam
.Value
>>= aStr
;
559 else if ( rParam
.Name
== "WebCastTargetURL" )
561 rParam
.Value
>>= aStr
;
564 else if ( rParam
.Name
== "WebCastScriptLanguage" )
566 rParam
.Value
>>= aStr
;
569 meScript
= SCRIPT_ASP
;
573 meScript
= SCRIPT_PERL
;
578 OSL_FAIL("Unknown property for html export detected!");
582 if( meMode
== PUBLISH_KIOSK
)
584 mbContentsPage
= false;
589 // calculate image sizes
590 SdPage
* pPage
= mpDoc
->GetSdPage(0, PageKind::Standard
);
591 Size
aTmpSize( pPage
->GetSize() );
592 double dRatio
=static_cast<double>(aTmpSize
.Width())/aTmpSize
.Height();
594 mnHeightPixel
= static_cast<sal_uInt16
>(mnWidthPixel
/dRatio
);
596 // we come up with a destination...
598 INetURLObject
aINetURLObj( maPath
);
599 DBG_ASSERT( aINetURLObj
.GetProtocol() != INetProtocol::NotValid
, "invalid URL" );
601 maExportPath
= aINetURLObj
.GetPartBeforeLastName(); // with trailing '/'
602 maIndex
= aINetURLObj
.GetLastName();
604 mnSdPageCount
= mpDoc
->GetSdPageCount( PageKind::Standard
);
605 for( sal_uInt16 nPage
= 0; nPage
< mnSdPageCount
; nPage
++ )
607 pPage
= mpDoc
->GetSdPage( nPage
, PageKind::Standard
);
609 if( mbHiddenSlides
|| !pPage
->IsExcluded() )
611 maPages
.push_back( pPage
);
612 maNotesPages
.push_back( mpDoc
->GetSdPage( nPage
, PageKind::Notes
) );
615 mnSdPageCount
= maPages
.size();
617 mbFrames
= meMode
== PUBLISH_FRAMES
;
619 maDocFileName
= maIndex
;
622 void HtmlExport::ExportSingleDocument()
624 SdrOutliner
* pOutliner
= mpDoc
->GetInternalOutliner();
626 maPageNames
.resize(mnSdPageCount
);
629 InitProgress(mnSdPageCount
);
631 OUStringBuffer
aStr(gaHTMLHeader
);
632 aStr
.append(DocumentMetadata());
634 aStr
.append("</head>\r\n");
635 aStr
.append(CreateBodyTag());
637 for(sal_uInt16 nSdPage
= 0; nSdPage
< mnSdPageCount
; ++nSdPage
)
639 SdPage
* pPage
= maPages
[nSdPage
];
640 maPageNames
[nSdPage
] = pPage
->GetName();
644 SetDocColors( pPage
);
648 OUString
sTitleText(CreateTextForTitle(pOutliner
, pPage
, pPage
->GetPageBackgroundColor()));
651 if (nSdPage
!= 0) // First page - no need for a page brake here
652 sStyle
+= "page-break-before:always; ";
653 sStyle
+= getParagraphStyle(pOutliner
, 0);
655 lclAppendStyle(aStr
, "h1", sStyle
);
657 aStr
.append(sTitleText
);
658 aStr
.append("</h1>\r\n");
660 // write outline text
661 aStr
.append(CreateTextForPage( pOutliner
, pPage
, true, pPage
->GetPageBackgroundColor() ));
666 SdPage
* pNotesPage
= maNotesPages
[ nSdPage
];
667 OUString
aNotesStr( CreateTextForNotesPage( pOutliner
, pNotesPage
, maBackColor
) );
669 if (!aNotesStr
.isEmpty())
671 aStr
.append("<br>\r\n<h3>");
672 aStr
.append(RESTOHTML(STR_HTMLEXP_NOTES
));
673 aStr
.append(":</h3>\r\n");
675 aStr
.append(aNotesStr
);
680 mpProgress
->SetState(++mnPagesWritten
);
685 aStr
.append("</body>\r\n</html>");
687 WriteHtml(maDocFileName
, false, aStr
.makeStringAndClear());
693 // exports the (in the c'tor specified impress document) to html
694 void HtmlExport::ExportHtml()
698 if( maTextColor
== COL_AUTO
)
700 if( !maBackColor
.IsDark() )
701 maTextColor
= COL_BLACK
;
704 else if( mbDocColors
)
706 // default colors for the color schema 'From Document'
708 maFirstPageColor
= maBackColor
;
711 // get name for downloadable presentation if needed
714 // fade out separator search and extension
715 sal_Int32 nSepPos
= maDocFileName
.indexOf('.');
717 maDocFileName
= maDocFileName
.copy(0, nSepPos
);
719 maDocFileName
+= ".odp";
722 sal_uInt16 nProgrCount
= mnSdPageCount
;
723 nProgrCount
+= mbImpress
?mnSdPageCount
:0;
724 nProgrCount
+= mbContentsPage
?1:0;
725 nProgrCount
+= (mbFrames
&& mbNotes
)?mnSdPageCount
:0;
726 nProgrCount
+= mbFrames
? 8 : 0;
727 InitProgress( nProgrCount
);
729 mpDocSh
->SetWaitCursor( true );
731 // Exceptions are cool...
735 // this is not a true while
738 if( checkForExistingFiles() )
741 if( !CreateImagesForPresPages() )
744 if( mbContentsPage
&&
745 !CreateImagesForPresPages( true ) )
748 if( !CreateHtmlForPresPages() )
752 if( !CreateHtmlTextForPresPages() )
757 if( !CreateFrames() )
760 if( !CreateOutlinePages() )
763 if( !CreateNavBarFrames() )
766 if( mbNotes
&& mbImpress
)
767 if( !CreateNotesPages() )
773 if( !CreateContentPage() )
778 mpDocSh
->SetWaitCursor( false );
787 // if we get to this point the export was
788 // canceled by the user after an error
789 mpDocSh
->SetWaitCursor( false );
793 void HtmlExport::SetDocColors( SdPage
* pPage
)
795 if( pPage
== nullptr )
796 pPage
= mpDoc
->GetSdPage(0, PageKind::Standard
);
798 svtools::ColorConfig aConfig
;
799 maVLinkColor
= aConfig
.GetColorValue(svtools::LINKSVISITED
).nColor
;
800 maALinkColor
= aConfig
.GetColorValue(svtools::LINKS
).nColor
;
801 maLinkColor
= aConfig
.GetColorValue(svtools::LINKS
).nColor
;
802 maTextColor
= COL_BLACK
;
804 SfxStyleSheet
* pSheet
= nullptr;
806 if( mpDoc
->GetDocumentType() == DocumentType::Impress
)
808 // default text color from the outline template of the first page
809 pSheet
= pPage
->GetStyleSheetForPresObj(PresObjKind::Outline
);
810 if(pSheet
== nullptr)
811 pSheet
= pPage
->GetStyleSheetForPresObj(PresObjKind::Text
);
812 if(pSheet
== nullptr)
813 pSheet
= pPage
->GetStyleSheetForPresObj(PresObjKind::Title
);
816 if(pSheet
== nullptr)
817 pSheet
= mpDoc
->GetDefaultStyleSheet();
821 SfxItemSet
& rSet
= pSheet
->GetItemSet();
822 if(rSet
.GetItemState(EE_CHAR_COLOR
) == SfxItemState::SET
)
823 maTextColor
= rSet
.GetItem
<SvxColorItem
>(EE_CHAR_COLOR
)->GetValue();
826 // default background from the background of the master page of the first page
827 maBackColor
= pPage
->GetPageBackgroundColor();
829 if( maTextColor
== COL_AUTO
)
831 if( !maBackColor
.IsDark() )
832 maTextColor
= COL_BLACK
;
836 void HtmlExport::InitProgress( sal_uInt16 nProgrCount
)
838 mpProgress
.reset(new SfxProgress( mpDocSh
, SdResId(STR_CREATE_PAGES
), nProgrCount
));
841 void HtmlExport::ResetProgress()
846 void HtmlExport::ExportKiosk()
849 InitProgress( 2*mnSdPageCount
);
852 if( !checkForExistingFiles() )
854 if( CreateImagesForPresPages() )
855 CreateHtmlForPresPages();
861 // Export Document with WebCast (TM) Technology
862 void HtmlExport::ExportWebCast()
865 InitProgress( mnSdPageCount
+ 9 );
867 mpDocSh
->SetWaitCursor( true );
871 if (maCGIPath
.isEmpty())
874 if (!maCGIPath
.endsWith("/"))
877 if( meScript
== SCRIPT_ASP
)
883 if (maURLPath
.isEmpty())
886 if (!maURLPath
.endsWith("/"))
890 // this is not a true while
893 if( checkForExistingFiles() )
896 if(!CreateImagesForPresPages())
899 if( meScript
== SCRIPT_ASP
)
901 if(!CreateASPScripts())
906 if(!CreatePERLScripts())
910 if(!CreateImageFileList())
913 if(!CreateImageNumberFile())
919 mpDocSh
->SetWaitCursor( false );
923 // Save the presentation as a downloadable file in the dest directory
924 bool HtmlExport::SavePresentation()
926 meEC
.SetContext( STR_HTMLEXP_ERROR_CREATE_FILE
, maDocFileName
);
928 OUString
aURL(maExportPath
+ maDocFileName
);
930 mpDocSh
->EnableSetModified();
934 uno::Reference
< frame::XStorable
> xStorable( mpDoc
->getUnoModel(), uno::UNO_QUERY
);
937 uno::Sequence
< beans::PropertyValue
> aProperties( 2 );
938 aProperties
[ 0 ].Name
= "Overwrite";
939 aProperties
[ 0 ].Value
<<= true;
940 aProperties
[ 1 ].Name
= "FilterName";
941 aProperties
[ 1 ].Value
<<= OUString("impress8");
942 xStorable
->storeToURL( aURL
, aProperties
);
944 mpDocSh
->EnableSetModified( false );
953 mpDocSh
->EnableSetModified( false );
958 // create image files
959 bool HtmlExport::CreateImagesForPresPages( bool bThumbnail
)
963 Reference
< XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
965 Reference
< drawing::XGraphicExportFilter
> xGraphicExporter
= drawing::GraphicExportFilter::create( xContext
);
967 Sequence
< PropertyValue
> aFilterData(((meFormat
==FORMAT_JPG
)&&(mnCompression
!= -1))? 3 : 2);
968 aFilterData
[0].Name
= "PixelWidth";
969 aFilterData
[0].Value
<<= static_cast<sal_Int32
>(bThumbnail
? PUB_THUMBNAIL_WIDTH
: mnWidthPixel
);
970 aFilterData
[1].Name
= "PixelHeight";
971 aFilterData
[1].Value
<<= static_cast<sal_Int32
>(bThumbnail
? PUB_THUMBNAIL_HEIGHT
: mnHeightPixel
);
972 if((meFormat
==FORMAT_JPG
)&&(mnCompression
!= -1))
974 aFilterData
[2].Name
= "Quality";
975 aFilterData
[2].Value
<<= static_cast<sal_Int32
>(mnCompression
);
978 Sequence
< PropertyValue
> aDescriptor( 3 );
979 aDescriptor
[0].Name
= "URL";
980 aDescriptor
[1].Name
= "FilterName";
982 if( meFormat
== FORMAT_PNG
)
984 else if( meFormat
== FORMAT_GIF
)
989 aDescriptor
[1].Value
<<= sFormat
;
990 aDescriptor
[2].Name
= "FilterData";
991 aDescriptor
[2].Value
<<= aFilterData
;
993 for (sal_uInt16 nSdPage
= 0; nSdPage
< mnSdPageCount
; nSdPage
++)
995 SdPage
* pPage
= maPages
[ nSdPage
];
997 OUString
aFull(maExportPath
);
999 aFull
+= maThumbnailFiles
[nSdPage
];
1001 aFull
+= maImageFiles
[nSdPage
];
1003 aDescriptor
[0].Value
<<= aFull
;
1005 Reference
< XComponent
> xPage( pPage
->getUnoPage(), UNO_QUERY
);
1006 xGraphicExporter
->setSourceDocument( xPage
);
1007 xGraphicExporter
->filter( aDescriptor
);
1010 mpProgress
->SetState(++mnPagesWritten
);
1021 // get SdrTextObject with layout text of this page
1022 SdrTextObj
* HtmlExport::GetLayoutTextObject(SdrPage
const * pPage
)
1024 const size_t nObjectCount
= pPage
->GetObjCount();
1025 SdrTextObj
* pResult
= nullptr;
1027 for (size_t nObject
= 0; nObject
< nObjectCount
; ++nObject
)
1029 SdrObject
* pObject
= pPage
->GetObj(nObject
);
1030 if (pObject
->GetObjInventor() == SdrInventor::Default
&&
1031 pObject
->GetObjIdentifier() == OBJ_OUTLINETEXT
)
1033 pResult
= static_cast<SdrTextObj
*>(pObject
);
1040 // create HTML text version of impress pages
1041 OUString
HtmlExport::CreateMetaCharset()
1044 const char *pCharSet
= rtl_getBestMimeCharsetFromTextEncoding( RTL_TEXTENCODING_UTF8
);
1047 aStr
= " <meta HTTP-EQUIV=CONTENT-TYPE CONTENT=\"text/html; charset=" +
1048 OUString::createFromAscii(pCharSet
) + "\">\r\n";
1053 OUString
HtmlExport::DocumentMetadata() const
1055 SvMemoryStream aStream
;
1057 uno::Reference
<document::XDocumentProperties
> xDocProps
;
1060 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS(
1061 mpDocSh
->GetModel(), uno::UNO_QUERY_THROW
);
1062 xDocProps
.set(xDPS
->getDocumentProperties());
1065 OUString aNonConvertableCharacters
;
1067 SfxFrameHTMLWriter::Out_DocInfo(aStream
, maDocFileName
, xDocProps
,
1068 " ", RTL_TEXTENCODING_UTF8
,
1069 &aNonConvertableCharacters
);
1071 const sal_uInt64 nLen
= aStream
.GetSize();
1072 OSL_ENSURE(nLen
< o3tl::make_unsigned(SAL_MAX_INT32
), "Stream can't fit in OString");
1073 OString
aData(static_cast<const char*>(aStream
.GetData()), static_cast<sal_Int32
>(nLen
));
1075 return OStringToOUString(aData
, RTL_TEXTENCODING_UTF8
);
1078 bool HtmlExport::CreateHtmlTextForPresPages()
1082 SdrOutliner
* pOutliner
= mpDoc
->GetInternalOutliner();
1084 for(sal_uInt16 nSdPage
= 0; nSdPage
< mnSdPageCount
&& bOk
; nSdPage
++)
1086 SdPage
* pPage
= maPages
[ nSdPage
];
1090 SetDocColors( pPage
);
1094 OUStringBuffer
aStr(gaHTMLHeader
);
1095 aStr
.append(CreateMetaCharset());
1096 aStr
.append(" <title>");
1097 aStr
.append(StringToHTMLString(maPageNames
[nSdPage
]));
1098 aStr
.append("</title>\r\n");
1099 aStr
.append("</head>\r\n");
1100 aStr
.append(CreateBodyTag());
1103 aStr
.append(CreateNavBar(nSdPage
, true));
1106 OUString
sTitleText( CreateTextForTitle(pOutliner
,pPage
, pPage
->GetPageBackgroundColor()) );
1107 lclAppendStyle(aStr
, "h1", getParagraphStyle(pOutliner
, 0));
1108 aStr
.append(sTitleText
);
1109 aStr
.append("</h1>\r\n");
1111 // write outline text
1112 aStr
.append(CreateTextForPage( pOutliner
, pPage
, true, pPage
->GetPageBackgroundColor() ));
1117 SdPage
* pNotesPage
= maNotesPages
[ nSdPage
];
1118 OUString
aNotesStr( CreateTextForNotesPage( pOutliner
, pNotesPage
, maBackColor
) );
1120 if (!aNotesStr
.isEmpty())
1122 aStr
.append("<br>\r\n<h3>");
1123 aStr
.append(RESTOHTML(STR_HTMLEXP_NOTES
));
1124 aStr
.append(":</h3>\r\n");
1126 aStr
.append(aNotesStr
);
1131 aStr
.append("</body>\r\n</html>");
1133 bOk
= WriteHtml(maTextFiles
[nSdPage
], false, aStr
.makeStringAndClear());
1136 mpProgress
->SetState(++mnPagesWritten
);
1145 /** exports the given html data into a non unicode file in the current export path with
1146 the given filename */
1147 bool HtmlExport::WriteHtml( const OUString
& rFileName
, bool bAddExtension
, const OUString
& rHtmlData
)
1149 ErrCode nErr
= ERRCODE_NONE
;
1151 OUString
aFileName( rFileName
);
1153 aFileName
+= gaHTMLExtension
;
1155 meEC
.SetContext( STR_HTMLEXP_ERROR_CREATE_FILE
, rFileName
);
1158 OUString
aFull(maExportPath
+ aFileName
);
1159 nErr
= aFile
.createStream(aFull
, pStr
);
1160 if(nErr
== ERRCODE_NONE
)
1162 OString
aStr(OUStringToOString(rHtmlData
, RTL_TEXTENCODING_UTF8
));
1163 pStr
->WriteOString( aStr
);
1167 if( nErr
!= ERRCODE_NONE
)
1168 ErrorHandler::HandleError(nErr
);
1170 return nErr
== ERRCODE_NONE
;
1173 /** creates an outliner text for the title objects of a page
1175 OUString
HtmlExport::CreateTextForTitle( SdrOutliner
* pOutliner
, SdPage
* pPage
, const Color
& rBackgroundColor
)
1177 SdrTextObj
* pTO
= static_cast<SdrTextObj
*>(pPage
->GetPresObj(PresObjKind::Title
));
1179 pTO
= GetLayoutTextObject(pPage
);
1181 if (pTO
&& !pTO
->IsEmptyPresObj())
1183 OutlinerParaObject
* pOPO
= pTO
->GetOutlinerParaObject();
1184 if(pOPO
&& pOutliner
->GetParagraphCount() != 0)
1187 pOutliner
->SetText(*pOPO
);
1188 return ParagraphToHTMLString(pOutliner
,0, rBackgroundColor
);
1195 // creates an outliner text for a page
1196 OUString
HtmlExport::CreateTextForPage(SdrOutliner
* pOutliner
, SdPage
const * pPage
,
1197 bool bHeadLine
, const Color
& rBackgroundColor
)
1199 OUStringBuffer aStr
;
1201 for (size_t i
= 0; i
<pPage
->GetObjCount(); ++i
)
1203 SdrObject
* pObject
= pPage
->GetObj(i
);
1204 PresObjKind eKind
= pPage
->GetPresObjKind(pObject
);
1208 case PresObjKind::NONE
:
1210 if (pObject
->GetObjIdentifier() == OBJ_GRUP
)
1212 SdrObjGroup
* pObjectGroup
= static_cast<SdrObjGroup
*>(pObject
);
1213 WriteObjectGroup(aStr
, pObjectGroup
, pOutliner
, rBackgroundColor
, false);
1215 else if (pObject
->GetObjIdentifier() == OBJ_TABLE
)
1217 SdrTableObj
* pTableObject
= static_cast<SdrTableObj
*>(pObject
);
1218 WriteTable(aStr
, pTableObject
, pOutliner
, rBackgroundColor
);
1222 if (pObject
->GetOutlinerParaObject())
1224 WriteOutlinerParagraph(aStr
, pOutliner
, pObject
->GetOutlinerParaObject(), rBackgroundColor
, false);
1230 case PresObjKind::Table
:
1232 SdrTableObj
* pTableObject
= static_cast<SdrTableObj
*>(pObject
);
1233 WriteTable(aStr
, pTableObject
, pOutliner
, rBackgroundColor
);
1237 case PresObjKind::Text
:
1238 case PresObjKind::Outline
:
1240 SdrTextObj
* pTextObject
= static_cast<SdrTextObj
*>(pObject
);
1241 if (pTextObject
->IsEmptyPresObj())
1243 WriteOutlinerParagraph(aStr
, pOutliner
, pTextObject
->GetOutlinerParaObject(), rBackgroundColor
, bHeadLine
);
1251 return aStr
.makeStringAndClear();
1254 void HtmlExport::WriteTable(OUStringBuffer
& aStr
, SdrTableObj
const * pTableObject
, SdrOutliner
* pOutliner
, const Color
& rBackgroundColor
)
1256 CellPos aStart
, aEnd
;
1258 aStart
= SdrTableObj::getFirstCell();
1259 aEnd
= pTableObject
->getLastCell();
1261 sal_Int32 nColCount
= pTableObject
->getColumnCount();
1262 aStr
.append("<table>\r\n");
1263 for (sal_Int32 nRow
= aStart
.mnRow
; nRow
<= aEnd
.mnRow
; nRow
++)
1265 aStr
.append(" <tr>\r\n");
1266 for (sal_Int32 nCol
= aStart
.mnCol
; nCol
<= aEnd
.mnCol
; nCol
++)
1268 aStr
.append(" <td>\r\n");
1269 sal_Int32 nCellIndex
= nRow
* nColCount
+ nCol
;
1270 SdrText
* pText
= pTableObject
->getText(nCellIndex
);
1272 if (pText
== nullptr)
1274 WriteOutlinerParagraph(aStr
, pOutliner
, pText
->GetOutlinerParaObject(), rBackgroundColor
, false);
1275 aStr
.append(" </td>\r\n");
1277 aStr
.append(" </tr>\r\n");
1279 aStr
.append("</table>\r\n");
1282 void HtmlExport::WriteObjectGroup(OUStringBuffer
& aStr
, SdrObjGroup
const * pObjectGroup
, SdrOutliner
* pOutliner
,
1283 const Color
& rBackgroundColor
, bool bHeadLine
)
1285 SdrObjListIter
aGroupIterator(pObjectGroup
->GetSubList(), SdrIterMode::DeepNoGroups
);
1286 while (aGroupIterator
.IsMore())
1288 SdrObject
* pCurrentObject
= aGroupIterator
.Next();
1289 if (pCurrentObject
->GetObjIdentifier() == OBJ_GRUP
)
1291 SdrObjGroup
* pCurrentGroupObject
= static_cast<SdrObjGroup
*>(pCurrentObject
);
1292 WriteObjectGroup(aStr
, pCurrentGroupObject
, pOutliner
, rBackgroundColor
, bHeadLine
);
1296 OutlinerParaObject
* pOutlinerParagraphObject
= pCurrentObject
->GetOutlinerParaObject();
1297 if (pOutlinerParagraphObject
!= nullptr)
1299 WriteOutlinerParagraph(aStr
, pOutliner
, pOutlinerParagraphObject
, rBackgroundColor
, bHeadLine
);
1305 void HtmlExport::WriteOutlinerParagraph(OUStringBuffer
& aStr
, SdrOutliner
* pOutliner
,
1306 OutlinerParaObject
const * pOutlinerParagraphObject
,
1307 const Color
& rBackgroundColor
, bool bHeadLine
)
1309 if (pOutlinerParagraphObject
== nullptr)
1312 pOutliner
->SetText(*pOutlinerParagraphObject
);
1314 sal_Int32 nCount
= pOutliner
->GetParagraphCount();
1317 sal_Int16 nCurrentDepth
= -1;
1319 for (sal_Int32 nIndex
= 0; nIndex
< nCount
; nIndex
++)
1321 Paragraph
* pParagraph
= pOutliner
->GetParagraph(nIndex
);
1322 if(pParagraph
== nullptr)
1325 const sal_Int16 nDepth
= static_cast<sal_uInt16
>(pOutliner
->GetDepth(nIndex
));
1326 OUString aParaText
= ParagraphToHTMLString(pOutliner
, nIndex
, rBackgroundColor
);
1328 if (aParaText
.isEmpty())
1333 OUString aTag
= bHeadLine
? OUString("h2") : OUString("p");
1334 lclAppendStyle(aStr
, aTag
, getParagraphStyle(pOutliner
, nIndex
));
1336 aStr
.append(aParaText
);
1337 aStr
.append("</").append(aTag
).append(">\r\n");
1341 while(nCurrentDepth
< nDepth
)
1343 aStr
.append("<ul>\r\n");
1346 while(nCurrentDepth
> nDepth
)
1348 aStr
.append("</ul>\r\n");
1351 lclAppendStyle(aStr
, "li", getParagraphStyle(pOutliner
, nIndex
));
1352 aStr
.append(aParaText
);
1353 aStr
.append("</li>\r\n");
1356 while(nCurrentDepth
>= 0)
1358 aStr
.append("</ul>\r\n");
1364 // creates an outliner text for a note page
1365 OUString
HtmlExport::CreateTextForNotesPage( SdrOutliner
* pOutliner
,
1367 const Color
& rBackgroundColor
)
1369 OUStringBuffer aStr
;
1371 SdrTextObj
* pTO
= static_cast<SdrTextObj
*>(pPage
->GetPresObj(PresObjKind::Notes
));
1373 if (pTO
&& !pTO
->IsEmptyPresObj())
1375 OutlinerParaObject
* pOPO
= pTO
->GetOutlinerParaObject();
1379 pOutliner
->SetText( *pOPO
);
1381 sal_Int32 nCount
= pOutliner
->GetParagraphCount();
1382 for (sal_Int32 nPara
= 0; nPara
< nCount
; nPara
++)
1384 lclAppendStyle(aStr
, "p", getParagraphStyle(pOutliner
, nPara
));
1385 aStr
.append(ParagraphToHTMLString(pOutliner
, nPara
, rBackgroundColor
));
1386 aStr
.append("</p>\r\n");
1391 return aStr
.makeStringAndClear();
1394 // converts a paragraph of the outliner to html
1395 OUString
HtmlExport::ParagraphToHTMLString( SdrOutliner
const * pOutliner
, sal_Int32 nPara
, const Color
& rBackgroundColor
)
1397 OUStringBuffer aStr
;
1399 if(nullptr == pOutliner
)
1403 EditEngine
& rEditEngine
= *const_cast<EditEngine
*>(&pOutliner
->GetEditEngine());
1404 bool bOldUpdateMode
= rEditEngine
.GetUpdateMode();
1405 rEditEngine
.SetUpdateMode(true);
1407 Paragraph
* pPara
= pOutliner
->GetParagraph(nPara
);
1408 if(nullptr == pPara
)
1411 HtmlState
aState( (mbUserAttr
|| mbDocColors
) ? maTextColor
: COL_BLACK
);
1412 std::vector
<sal_Int32
> aPortionList
;
1413 rEditEngine
.GetPortions( nPara
, aPortionList
);
1415 sal_Int32 nPos1
= 0;
1416 for( sal_Int32 nPos2
: aPortionList
)
1418 ESelection
aSelection( nPara
, nPos1
, nPara
, nPos2
);
1420 SfxItemSet
aSet( rEditEngine
.GetAttribs( aSelection
) );
1422 OUString
aPortion(StringToHTMLString(rEditEngine
.GetText( aSelection
)));
1424 aStr
.append(TextAttribToHTMLString( &aSet
, &aState
, rBackgroundColor
));
1425 aStr
.append(aPortion
);
1429 aStr
.append(aState
.Flush());
1430 rEditEngine
.SetUpdateMode(bOldUpdateMode
);
1432 return aStr
.makeStringAndClear();
1435 // Depending on the attributes of the specified set and the specified
1436 // HtmlState, it creates the needed html tags in order to get the
1438 OUString
HtmlExport::TextAttribToHTMLString( SfxItemSet
const * pSet
, HtmlState
* pState
, const Color
& rBackgroundColor
)
1440 OUStringBuffer aStr
;
1445 OUString aLink
, aTarget
;
1446 if ( pSet
->GetItemState( EE_FEATURE_FIELD
) == SfxItemState::SET
)
1448 const SvxFieldItem
* pItem
= pSet
->GetItem
<SvxFieldItem
>( EE_FEATURE_FIELD
);
1451 const SvxURLField
* pURL
= dynamic_cast<const SvxURLField
*>( pItem
->GetField() );
1454 aLink
= pURL
->GetURL();
1455 aTarget
= pURL
->GetTargetFrame();
1463 if ( pSet
->GetItemState( EE_CHAR_WEIGHT
) == SfxItemState::SET
)
1465 bTemp
= pSet
->Get( EE_CHAR_WEIGHT
).GetWeight() == WEIGHT_BOLD
;
1466 aTemp
= pState
->SetWeight( bTemp
);
1468 aStr
.insert(0, aTemp
);
1473 if ( pSet
->GetItemState( EE_CHAR_UNDERLINE
) == SfxItemState::SET
)
1475 bTemp
= pSet
->Get( EE_CHAR_UNDERLINE
).GetLineStyle() != LINESTYLE_NONE
;
1476 aTemp
= pState
->SetUnderline( bTemp
);
1478 aStr
.insert(0, aTemp
);
1483 if ( pSet
->GetItemState( EE_CHAR_STRIKEOUT
) == SfxItemState::SET
)
1485 bTemp
= pSet
->Get( EE_CHAR_STRIKEOUT
).GetStrikeout() != STRIKEOUT_NONE
;
1486 aTemp
= pState
->SetStrikeout( bTemp
);
1488 aStr
.insert(0, aTemp
);
1493 if ( pSet
->GetItemState( EE_CHAR_ITALIC
) == SfxItemState::SET
)
1495 bTemp
= pSet
->Get( EE_CHAR_ITALIC
).GetPosture() != ITALIC_NONE
;
1496 aTemp
= pState
->SetItalic( bTemp
);
1498 aStr
.insert(0, aTemp
);
1505 if ( pSet
->GetItemState( EE_CHAR_COLOR
) == SfxItemState::SET
)
1507 Color aTextColor
= pSet
->Get( EE_CHAR_COLOR
).GetValue();
1508 if( aTextColor
== COL_AUTO
)
1510 if( !rBackgroundColor
.IsDark() )
1511 aTextColor
= COL_BLACK
;
1513 aStr
.append(pState
->SetColor( aTextColor
));
1517 if (!aLink
.isEmpty())
1518 aStr
.insert(0, pState
->SetLink(aLink
, aTarget
));
1520 aStr
.append(pState
->SetLink(aLink
, aTarget
));
1522 return aStr
.makeStringAndClear();
1525 // create HTML wrapper for picture files
1526 bool HtmlExport::CreateHtmlForPresPages()
1530 std::vector
<SdrObject
*> aClickableObjects
;
1532 for(sal_uInt16 nSdPage
= 0; nSdPage
< mnSdPageCount
&& bOk
; nSdPage
++)
1534 // find clickable objects (also on the master page) and put it in the
1535 // list. This in reverse order character order since in html the first
1536 // area is taken in the case they overlap.
1537 SdPage
* pPage
= maPages
[ nSdPage
];
1541 SetDocColors( pPage
);
1544 bool bMasterDone
= false;
1546 while (!bMasterDone
)
1548 // sal_True = backwards
1549 SdrObjListIter
aIter(pPage
, SdrIterMode::DeepWithGroups
, true);
1551 SdrObject
* pObject
= aIter
.Next();
1554 SdAnimationInfo
* pInfo
= SdDrawDocument::GetAnimationInfo(pObject
);
1555 SvxIMapInfo
* pIMapInfo
= SvxIMapInfo::GetIMapInfo(pObject
);
1558 (pInfo
->meClickAction
== presentation::ClickAction_BOOKMARK
||
1559 pInfo
->meClickAction
== presentation::ClickAction_DOCUMENT
||
1560 pInfo
->meClickAction
== presentation::ClickAction_PREVPAGE
||
1561 pInfo
->meClickAction
== presentation::ClickAction_NEXTPAGE
||
1562 pInfo
->meClickAction
== presentation::ClickAction_FIRSTPAGE
||
1563 pInfo
->meClickAction
== presentation::ClickAction_LASTPAGE
)) ||
1566 aClickableObjects
.push_back(pObject
);
1569 pObject
= aIter
.Next();
1571 // now to the master page or finishing
1572 if (!pPage
->IsMasterPage())
1573 pPage
= static_cast<SdPage
*>(&(pPage
->TRG_GetMasterPage()));
1579 OUStringBuffer
aStr(gaHTMLHeader
);
1580 aStr
.append(CreateMetaCharset());
1581 aStr
.append(" <title>" ).append( StringToHTMLString(maPageNames
[nSdPage
]) ).append("</title>\r\n");
1583 // insert timing information
1584 pPage
= maPages
[ nSdPage
];
1585 if( meMode
== PUBLISH_KIOSK
)
1588 bool bEndless
= false;
1591 if( pPage
->GetPresChange() != PresChange::Manual
)
1593 fSecs
= pPage
->GetTime();
1594 bEndless
= mpDoc
->getPresentationSettings().mbEndless
;
1599 fSecs
= mfSlideDuration
;
1600 bEndless
= mbEndless
;
1605 if( nSdPage
< (mnSdPageCount
-1) || bEndless
)
1607 aStr
.append("<meta http-equiv=\"refresh\" content=\"");
1608 aStr
.append(OUString::number(fSecs
));
1609 aStr
.append("; URL=");
1611 int nPage
= nSdPage
+ 1;
1612 if( nPage
== mnSdPageCount
)
1615 aStr
.append(maHTMLFiles
[nPage
]);
1617 aStr
.append("\">\r\n");
1622 aStr
.append("</head>\r\n");
1625 aStr
.append(CreateBodyTag());
1627 if( mbSlideSound
&& pPage
->IsSoundOn() )
1628 aStr
.append(InsertSound(pPage
->GetSoundFile()));
1632 aStr
.append(CreateNavBar(nSdPage
, false));
1634 aStr
.append("<center>");
1635 aStr
.append("<img src=\"");
1636 aStr
.append(maImageFiles
[nSdPage
]);
1637 aStr
.append("\" alt=\"\"");
1639 if (!aClickableObjects
.empty())
1640 aStr
.append(" USEMAP=\"#map0\"");
1642 aStr
.append("></center>\r\n");
1645 if(mbNotes
&& !mbFrames
)
1647 SdrOutliner
* pOutliner
= mpDoc
->GetInternalOutliner();
1648 SdPage
* pNotesPage
= maNotesPages
[ nSdPage
];
1649 OUString
aNotesStr( CreateTextForNotesPage( pOutliner
, pNotesPage
, maBackColor
) );
1652 if (!aNotesStr
.isEmpty())
1654 aStr
.append("<h3>");
1655 aStr
.append(RESTOHTML(STR_HTMLEXP_NOTES
));
1656 aStr
.append(":</h3><br>\r\n\r\n<p>");
1658 aStr
.append(aNotesStr
);
1659 aStr
.append("\r\n</p>\r\n");
1663 // create Imagemap if necessary
1664 if (!aClickableObjects
.empty())
1666 aStr
.append("<map name=\"map0\">\r\n");
1668 for (SdrObject
* pObject
: aClickableObjects
)
1670 SdAnimationInfo
* pInfo
= SdDrawDocument::GetAnimationInfo(pObject
);
1671 SvxIMapInfo
* pIMapInfo
= SvxIMapInfo::GetIMapInfo(pObject
);
1673 ::tools::Rectangle
aRect(pObject
->GetCurrentBoundRect());
1674 Point
aLogPos(aRect
.TopLeft());
1675 bool bIsSquare
= aRect
.GetWidth() == aRect
.GetHeight();
1677 sal_uLong nPageWidth
= pPage
->GetSize().Width() - pPage
->GetLeftBorder() -
1678 pPage
->GetRightBorder();
1680 // BoundRect is relative to the physical page origin, not the
1681 // origin of ordinates
1682 aRect
.Move(-pPage
->GetLeftBorder(), -pPage
->GetUpperBorder());
1684 double fLogicToPixel
= static_cast<double>(mnWidthPixel
) / nPageWidth
;
1685 aRect
.SetLeft( static_cast<tools::Long
>(aRect
.Left() * fLogicToPixel
) );
1686 aRect
.SetTop( static_cast<tools::Long
>(aRect
.Top() * fLogicToPixel
) );
1687 aRect
.SetRight( static_cast<tools::Long
>(aRect
.Right() * fLogicToPixel
) );
1688 aRect
.SetBottom( static_cast<tools::Long
>(aRect
.Bottom() * fLogicToPixel
) );
1689 tools::Long nRadius
= aRect
.GetWidth() / 2;
1692 insert areas into Imagemap of the object, if the object has
1697 const ImageMap
& rIMap
= pIMapInfo
->GetImageMap();
1698 sal_uInt16 nAreaCount
= rIMap
.GetIMapObjectCount();
1699 for (sal_uInt16 nArea
= 0; nArea
< nAreaCount
; nArea
++)
1701 IMapObject
* pArea
= rIMap
.GetIMapObject(nArea
);
1702 IMapObjectType nType
= pArea
->GetType();
1703 OUString
aURL( pArea
->GetURL() );
1705 // if necessary, convert page and object names into the
1706 // corresponding names of the html file
1708 sal_uInt16 nPgNum
= mpDoc
->GetPageByName( aURL
, bIsMasterPage
);
1710 if (nPgNum
== SDRPAGE_NOTFOUND
)
1712 // is the bookmark an object?
1713 SdrObject
* pObj
= mpDoc
->GetObj( aURL
);
1715 nPgNum
= pObj
->getSdrPageFromSdrObject()->GetPageNum();
1717 if (nPgNum
!= SDRPAGE_NOTFOUND
)
1719 nPgNum
= (nPgNum
- 1) / 2; // SdrPageNum --> SdPageNum
1720 aURL
= CreatePageURL(nPgNum
);
1725 case IMapObjectType::Rectangle
:
1727 ::tools::Rectangle
aArea(static_cast<IMapRectangleObject
*>(pArea
)->
1728 GetRectangle(false));
1730 // conversion into pixel coordinates
1731 aArea
.Move(aLogPos
.X() - pPage
->GetLeftBorder(),
1732 aLogPos
.Y() - pPage
->GetUpperBorder());
1733 aArea
.SetLeft( static_cast<tools::Long
>(aArea
.Left() * fLogicToPixel
) );
1734 aArea
.SetTop( static_cast<tools::Long
>(aArea
.Top() * fLogicToPixel
) );
1735 aArea
.SetRight( static_cast<tools::Long
>(aArea
.Right() * fLogicToPixel
) );
1736 aArea
.SetBottom( static_cast<tools::Long
>(aArea
.Bottom() * fLogicToPixel
) );
1738 aStr
.append(CreateHTMLRectArea(aArea
, aURL
));
1742 case IMapObjectType::Circle
:
1744 Point
aCenter(static_cast<IMapCircleObject
*>(pArea
)->
1746 aCenter
+= Point(aLogPos
.X() - pPage
->GetLeftBorder(),
1747 aLogPos
.Y() - pPage
->GetUpperBorder());
1748 aCenter
.setX( static_cast<tools::Long
>(aCenter
.X() * fLogicToPixel
) );
1749 aCenter
.setY( static_cast<tools::Long
>(aCenter
.Y() * fLogicToPixel
) );
1751 sal_uLong nCircleRadius
= static_cast<IMapCircleObject
*>(pArea
)->
1753 nCircleRadius
= static_cast<sal_uLong
>(nCircleRadius
* fLogicToPixel
);
1754 aStr
.append(CreateHTMLCircleArea(nCircleRadius
,
1755 aCenter
.X(), aCenter
.Y(),
1760 case IMapObjectType::Polygon
:
1762 tools::Polygon
aArea(static_cast<IMapPolygonObject
*>(pArea
)->GetPolygon(false));
1763 aStr
.append(CreateHTMLPolygonArea(::basegfx::B2DPolyPolygon(aArea
.getB2DPolygon()),
1764 Size(aLogPos
.X() - pPage
->GetLeftBorder(),
1765 aLogPos
.Y() - pPage
->GetUpperBorder()),
1766 fLogicToPixel
, aURL
));
1772 SAL_INFO("sd", "unknown IMapObjectType");
1780 if there is a presentation::ClickAction, determine bookmark
1781 and create area for the whole object
1786 presentation::ClickAction eClickAction
= pInfo
->meClickAction
;
1788 switch( eClickAction
)
1790 case presentation::ClickAction_BOOKMARK
:
1793 sal_uInt16 nPgNum
= mpDoc
->GetPageByName( pInfo
->GetBookmark(), bIsMasterPage
);
1795 if( nPgNum
== SDRPAGE_NOTFOUND
)
1797 // is the bookmark an object?
1798 SdrObject
* pObj
= mpDoc
->GetObj(pInfo
->GetBookmark());
1800 nPgNum
= pObj
->getSdrPageFromSdrObject()->GetPageNum();
1803 if( SDRPAGE_NOTFOUND
!= nPgNum
)
1804 aHRef
= CreatePageURL(( nPgNum
- 1 ) / 2 );
1808 case presentation::ClickAction_DOCUMENT
:
1809 aHRef
= pInfo
->GetBookmark();
1812 case presentation::ClickAction_PREVPAGE
:
1819 nPage
= nSdPage
- 1;
1821 aHRef
= CreatePageURL( static_cast<sal_uInt16
>(nPage
));
1825 case presentation::ClickAction_NEXTPAGE
:
1828 if (nSdPage
== mnSdPageCount
- 1)
1829 nPage
= mnSdPageCount
- 1;
1831 nPage
= nSdPage
+ 1;
1833 aHRef
= CreatePageURL( static_cast<sal_uInt16
>(nPage
));
1837 case presentation::ClickAction_FIRSTPAGE
:
1838 aHRef
= CreatePageURL(0);
1841 case presentation::ClickAction_LASTPAGE
:
1842 aHRef
= CreatePageURL(mnSdPageCount
- 1);
1849 // and now the areas
1850 if (!aHRef
.isEmpty())
1853 if (pObject
->GetObjInventor() == SdrInventor::Default
&&
1854 pObject
->GetObjIdentifier() == OBJ_CIRC
&&
1857 aStr
.append(CreateHTMLCircleArea(aRect
.GetWidth() / 2,
1858 aRect
.Left() + nRadius
,
1859 aRect
.Top() + nRadius
,
1863 else if (pObject
->GetObjInventor() == SdrInventor::Default
&&
1864 (pObject
->GetObjIdentifier() == OBJ_PATHLINE
||
1865 pObject
->GetObjIdentifier() == OBJ_PLIN
||
1866 pObject
->GetObjIdentifier() == OBJ_POLY
))
1868 aStr
.append(CreateHTMLPolygonArea(static_cast<SdrPathObj
*>(pObject
)->GetPathPoly(), Size(-pPage
->GetLeftBorder(), -pPage
->GetUpperBorder()), fLogicToPixel
, aHRef
));
1870 // something completely different: use the BoundRect
1873 aStr
.append(CreateHTMLRectArea(aRect
, aHRef
));
1880 aStr
.append("</map>\r\n");
1882 aClickableObjects
.clear();
1884 aStr
.append("</body>\r\n</html>");
1886 bOk
= WriteHtml(maHTMLFiles
[nSdPage
], false, aStr
.makeStringAndClear());
1889 mpProgress
->SetState(++mnPagesWritten
);
1895 // create overview pages
1896 bool HtmlExport::CreateContentPage()
1902 OUStringBuffer
aStr(gaHTMLHeader
);
1903 aStr
.append(CreateMetaCharset());
1904 aStr
.append(" <title>");
1905 aStr
.append(StringToHTMLString(maPageNames
[0]));
1906 aStr
.append("</title>\r\n</head>\r\n");
1907 aStr
.append(CreateBodyTag());
1910 aStr
.append("<center>\r\n");
1914 aStr
.append("<h1>");
1915 aStr
.append(getDocumentTitle());
1916 aStr
.append("</h1><br>\r\n");
1919 aStr
.append("<h2>");
1921 // Solaris compiler bug workaround
1923 aStr
.append(CreateLink(maFramePage
,
1924 RESTOHTML(STR_HTMLEXP_CLICKSTART
)));
1926 aStr
.append(CreateLink(StringToHTMLString(maHTMLFiles
[0]),
1927 RESTOHTML(STR_HTMLEXP_CLICKSTART
)));
1929 aStr
.append("</h2>\r\n</center>\r\n");
1931 aStr
.append("<center><table width=\"90%\"><tr>\r\n");
1934 aStr
.append("<td valign=\"top\" align=\"left\" width=\"25%\">\r\n");
1935 aStr
.append("<h3>");
1936 aStr
.append(RESTOHTML(STR_HTMLEXP_CONTENTS
));
1937 aStr
.append("</h3>");
1939 for(sal_uInt16 nSdPage
= 0; nSdPage
< mnSdPageCount
; nSdPage
++)
1941 OUString aPageName
= maPageNames
[nSdPage
];
1942 aStr
.append("<div align=\"left\">");
1944 aStr
.append(StringToHTMLString(aPageName
));
1946 aStr
.append(CreateLink(maHTMLFiles
[nSdPage
], aPageName
));
1947 aStr
.append("</div>\r\n");
1949 aStr
.append("</td>\r\n");
1951 // document information
1952 aStr
.append("<td valign=\"top\" align=\"left\" width=\"75%\">\r\n");
1954 if (!maAuthor
.isEmpty())
1956 aStr
.append("<p><strong>");
1957 aStr
.append(RESTOHTML(STR_HTMLEXP_AUTHOR
));
1958 aStr
.append(":</strong> ");
1959 aStr
.append(StringToHTMLString(maAuthor
));
1960 aStr
.append("</p>\r\n");
1963 if (!maEMail
.isEmpty())
1965 aStr
.append("<p><strong>");
1966 aStr
.append(RESTOHTML(STR_HTMLEXP_EMAIL
));
1967 aStr
.append(":</strong> <a href=\"mailto:");
1968 aStr
.append(maEMail
);
1970 aStr
.append(StringToHTMLString(maEMail
));
1971 aStr
.append("</a></p>\r\n");
1974 if (!maHomePage
.isEmpty())
1976 aStr
.append("<p><strong>");
1977 aStr
.append(RESTOHTML(STR_HTMLEXP_HOMEPAGE
));
1978 aStr
.append(":</strong> <a href=\"");
1979 aStr
.append(maHomePage
);
1981 aStr
.append(StringToHTMLString(maHomePage
));
1982 aStr
.append("</a> </p>\r\n");
1985 if (!maInfo
.isEmpty())
1987 aStr
.append("<p><strong>");
1988 aStr
.append(RESTOHTML(STR_HTMLEXP_INFO
));
1989 aStr
.append(":</strong><br>\r\n");
1990 aStr
.append(StringToHTMLString(maInfo
));
1991 aStr
.append("</p>\r\n");
1996 aStr
.append("<p><a href=\"");
1997 aStr
.append(maDocFileName
);
1999 aStr
.append(RESTOHTML(STR_HTMLEXP_DOWNLOAD
));
2000 aStr
.append("</a></p>\r\n");
2003 for(sal_uInt16 nSdPage
= 0; nSdPage
< mnSdPageCount
; nSdPage
++)
2007 maThumbnailFiles
[nSdPage
] +
2008 "\" width=\"256\" height=\"192\" alt=\"" +
2009 StringToHTMLString(maPageNames
[nSdPage
]) +
2012 aStr
.append(CreateLink(maHTMLFiles
[nSdPage
], aText
));
2013 aStr
.append("\r\n");
2016 aStr
.append("</td></tr></table></center>\r\n");
2018 aStr
.append("</body>\r\n</html>");
2020 bool bOk
= WriteHtml(maIndex
, false, aStr
.makeStringAndClear());
2023 mpProgress
->SetState(++mnPagesWritten
);
2028 // create note pages (for frames)
2030 bool HtmlExport::CreateNotesPages()
2034 SdrOutliner
* pOutliner
= mpDoc
->GetInternalOutliner();
2035 for( sal_uInt16 nSdPage
= 0; bOk
&& nSdPage
< mnSdPageCount
; nSdPage
++ )
2037 SdPage
* pPage
= maNotesPages
[nSdPage
];
2039 SetDocColors( pPage
);
2042 OUStringBuffer
aStr(gaHTMLHeader
);
2043 aStr
.append(CreateMetaCharset());
2044 aStr
.append(" <title>");
2045 aStr
.append(StringToHTMLString(maPageNames
[0]));
2046 aStr
.append("</title>\r\n</head>\r\n");
2047 aStr
.append(CreateBodyTag());
2050 aStr
.append(CreateTextForNotesPage( pOutliner
, pPage
, maBackColor
));
2052 aStr
.append("</body>\r\n</html>");
2054 OUString
aFileName("note" + OUString::number(nSdPage
));
2055 bOk
= WriteHtml(aFileName
, true, aStr
.makeStringAndClear());
2058 mpProgress
->SetState(++mnPagesWritten
);
2066 // create outline pages (for frames)
2068 bool HtmlExport::CreateOutlinePages()
2077 // page 0 will be the closed outline, page 1 the opened
2078 for (sal_Int32 nPage
= 0; nPage
< (mbImpress
?2:1) && bOk
; ++nPage
)
2081 OUStringBuffer
aStr(gaHTMLHeader
);
2082 aStr
.append(CreateMetaCharset());
2083 aStr
.append(" <title>");
2084 aStr
.append(StringToHTMLString(maPageNames
[0]));
2085 aStr
.append("</title>\r\n</head>\r\n");
2086 aStr
.append(CreateBodyTag());
2088 SdrOutliner
* pOutliner
= mpDoc
->GetInternalOutliner();
2089 for(sal_uInt16 nSdPage
= 0; nSdPage
< mnSdPageCount
; nSdPage
++)
2091 SdPage
* pPage
= maPages
[ nSdPage
];
2093 aStr
.append("<div align=\"left\">");
2094 OUString
aLink("JavaScript:parent.NavigateAbs(" +
2095 OUString::number(nSdPage
) + ")");
2097 OUString aTitle
= CreateTextForTitle(pOutliner
, pPage
, maBackColor
);
2098 if (aTitle
.isEmpty())
2099 aTitle
= maPageNames
[nSdPage
];
2101 lclAppendStyle(aStr
, "p", getParagraphStyle(pOutliner
, 0));
2102 aStr
.append(CreateLink(aLink
, aTitle
));
2103 aStr
.append("</p>");
2107 aStr
.append(CreateTextForPage( pOutliner
, pPage
, false, maBackColor
));
2109 aStr
.append("</div>\r\n");
2113 aStr
.append("</body>\r\n</html>");
2115 OUString
aFileName("outline" + OUString::number(nPage
));
2116 bOk
= WriteHtml(aFileName
, true, aStr
.makeStringAndClear());
2119 mpProgress
->SetState(++mnPagesWritten
);
2126 void HtmlExport::CreateFileNames()
2128 // create lists with new file names
2129 maHTMLFiles
.resize(mnSdPageCount
);
2130 maImageFiles
.resize(mnSdPageCount
);
2131 maThumbnailFiles
.resize(mnSdPageCount
);
2132 maPageNames
.resize(mnSdPageCount
);
2133 maTextFiles
.resize(mnSdPageCount
);
2135 mbHeader
= false; // headline on overview page?
2137 for (sal_uInt16 nSdPage
= 0; nSdPage
< mnSdPageCount
; nSdPage
++)
2139 OUString aHTMLFileName
;
2140 if(nSdPage
== 0 && !mbContentsPage
&& !mbFrames
)
2141 aHTMLFileName
= maIndex
;
2144 aHTMLFileName
= "img" + OUString::number(nSdPage
) + gaHTMLExtension
;
2147 maHTMLFiles
[nSdPage
] = aHTMLFileName
;
2149 OUString aImageFileName
= "img" + OUString::number(nSdPage
);
2150 if( meFormat
==FORMAT_GIF
)
2151 aImageFileName
+= ".gif";
2152 else if( meFormat
==FORMAT_JPG
)
2153 aImageFileName
+= ".jpg";
2155 aImageFileName
+= ".png";
2157 maImageFiles
[nSdPage
] = aImageFileName
;
2159 OUString aThumbnailFileName
= "thumb" + OUString::number(nSdPage
);
2160 if( meFormat
!=FORMAT_JPG
)
2161 aThumbnailFileName
+= ".png";
2163 aThumbnailFileName
+= ".jpg";
2165 maThumbnailFiles
[nSdPage
] = aThumbnailFileName
;
2167 maTextFiles
[nSdPage
] = "text" + OUString::number(nSdPage
) + gaHTMLExtension
;
2169 SdPage
* pSdPage
= maPages
[ nSdPage
];
2171 // get slide title from page name
2172 maPageNames
[nSdPage
] = pSdPage
->GetName();
2175 if(!mbContentsPage
&& mbFrames
)
2176 maFramePage
= maIndex
;
2179 maFramePage
= "siframes" + gaHTMLExtension
;
2183 OUString
const & HtmlExport::getDocumentTitle()
2185 // check for a title object in this page, if it's the first
2186 // title it becomes this documents title for the content
2192 // if there is a non-empty title object, use their first passage
2194 SdPage
* pSdPage
= mpDoc
->GetSdPage(0, PageKind::Standard
);
2195 SdrObject
* pTitleObj
= pSdPage
->GetPresObj(PresObjKind::Title
);
2196 if (pTitleObj
&& !pTitleObj
->IsEmptyPresObj())
2198 OutlinerParaObject
* pParaObject
= pTitleObj
->GetOutlinerParaObject();
2201 const EditTextObject
& rEditTextObject
=
2202 pParaObject
->GetTextObject();
2203 OUString
aTest(rEditTextObject
.GetText(0));
2204 if (!aTest
.isEmpty())
2209 mDocTitle
= mDocTitle
.replace(0xff, ' ');
2212 if (mDocTitle
.isEmpty())
2214 mDocTitle
= maDocFileName
;
2215 sal_Int32 nDot
= mDocTitle
.indexOf('.');
2217 mDocTitle
= mDocTitle
.copy(0, nDot
);
2225 const char JS_NavigateAbs
[] =
2226 "function NavigateAbs( nPage )\r\n"
2228 " frames[\"show\"].location.href = \"img\" + nPage + \".$EXT\";\r\n"
2229 " //frames[\"notes\"].location.href = \"note\" + nPage + \".$EXT\";\r\n"
2230 " nCurrentPage = nPage;\r\n"
2231 " if(nCurrentPage==0)\r\n"
2233 " frames[\"navbar1\"].location.href = \"navbar0.$EXT\";\r\n"
2235 " else if(nCurrentPage==nPageCount-1)\r\n"
2237 " frames[\"navbar1\"].location.href = \"navbar2.$EXT\";\r\n"
2241 " frames[\"navbar1\"].location.href = \"navbar1.$EXT\";\r\n"
2245 const char JS_NavigateRel
[] =
2246 "function NavigateRel( nDelta )\r\n"
2248 " var nPage = parseInt(nCurrentPage) + parseInt(nDelta);\r\n"
2249 " if( (nPage >= 0) && (nPage < nPageCount) )\r\n"
2251 " NavigateAbs( nPage );\r\n"
2255 const char JS_ExpandOutline
[] =
2256 "function ExpandOutline()\r\n"
2258 " frames[\"navbar2\"].location.href = \"navbar4.$EXT\";\r\n"
2259 " frames[\"outline\"].location.href = \"outline1.$EXT\";\r\n"
2262 const char JS_CollapseOutline
[] =
2263 "function CollapseOutline()\r\n"
2265 " frames[\"navbar2\"].location.href = \"navbar3.$EXT\";\r\n"
2266 " frames[\"outline\"].location.href = \"outline0.$EXT\";\r\n"
2269 // create page with the frames
2271 bool HtmlExport::CreateFrames()
2274 OUStringBuffer
aStr(
2275 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\"\r\n"
2276 " \"http://www.w3.org/TR/html4/frameset.dtd\">\r\n"
2277 "<html>\r\n<head>\r\n");
2279 aStr
.append(CreateMetaCharset());
2280 aStr
.append(" <title>");
2281 aStr
.append(StringToHTMLString(maPageNames
[0]));
2282 aStr
.append("</title>\r\n");
2284 aStr
.append("<script type=\"text/javascript\">\r\n<!--\r\n");
2286 aStr
.append("var nCurrentPage = 0;\r\nvar nPageCount = ");
2287 aStr
.append(OUString::number(mnSdPageCount
));
2288 aStr
.append(";\r\n\r\n");
2290 OUString aFunction
= JS_NavigateAbs
;
2294 aFunction
= aFunction
.replaceAll("//", "");
2297 // substitute HTML file extension
2298 OUString
aPlaceHolder(".$EXT");
2299 aFunction
= aFunction
.replaceAll(aPlaceHolder
, gaHTMLExtension
);
2300 aStr
.append(aFunction
);
2302 aTmp
= JS_NavigateRel
;
2303 aTmp
= aTmp
.replaceAll(aPlaceHolder
, gaHTMLExtension
);
2308 aTmp
= JS_ExpandOutline
;
2309 aTmp
= aTmp
.replaceAll(aPlaceHolder
, gaHTMLExtension
);
2312 aTmp
= JS_CollapseOutline
;
2313 aTmp
= aTmp
.replaceAll(aPlaceHolder
, gaHTMLExtension
);
2316 aStr
.append("// -->\r\n</script>\r\n");
2318 aStr
.append("</head>\r\n");
2320 aStr
.append("<frameset cols=\"*,");
2321 aStr
.append(OUString::number((mnWidthPixel
+ 16)));
2322 aStr
.append("\">\r\n");
2325 aStr
.append(" <frameset rows=\"42,*\">\r\n");
2326 aStr
.append(" <frame src=\"navbar3");
2327 aStr
.append(gaHTMLExtension
);
2328 aStr
.append("\" name=\"navbar2\" marginwidth=\"4\" marginheight=\"4\" scrolling=\"no\">\r\n");
2330 aStr
.append(" <frame src=\"outline0");
2331 aStr
.append(gaHTMLExtension
);
2332 aStr
.append("\" name=\"outline\">\r\n");
2334 aStr
.append(" </frameset>\r\n");
2338 aStr
.append(" <frameset rows=\"42,");
2339 aStr
.append(OUString::number(static_cast<int>(static_cast<double>(mnWidthPixel
) * 0.75) + 16));
2340 aStr
.append(",*\">\r\n");
2343 aStr
.append(" <frameset rows=\"42,*\">\r\n");
2345 aStr
.append(" <frame src=\"navbar0");
2346 aStr
.append(gaHTMLExtension
);
2347 aStr
.append("\" name=\"navbar1\" marginwidth=\"4\" marginheight=\"4\" scrolling=\"no\">\r\n");
2349 aStr
.append(" <frame src=\"");
2350 aStr
.append(maHTMLFiles
[0]);
2351 aStr
.append("\" name=\"show\" marginwidth=\"4\" marginheight=\"4\">\r\n");
2355 aStr
.append(" <frame src=\"note0");
2356 aStr
.append(gaHTMLExtension
);
2357 aStr
.append("\" name=\"notes\">\r\n");
2359 aStr
.append(" </frameset>\r\n");
2361 aStr
.append("<noframes>\r\n");
2362 aStr
.append(CreateBodyTag());
2363 aStr
.append(RESTOHTML(STR_HTMLEXP_NOFRAMES
));
2364 aStr
.append("\r\n</noframes>\r\n</frameset>\r\n</html>");
2366 bool bOk
= WriteHtml(maFramePage
, false, aStr
.makeStringAndClear());
2369 mpProgress
->SetState(++mnPagesWritten
);
2374 // create button bar for standard
2375 // we create the following html files
2376 // navbar0.htm navigation bar graphic for the first page
2377 // navbar1.htm navigation bar graphic for the second until second last page
2378 // navbar2.htm navigation bar graphic for the last page
2379 // navbar3.htm navigation outline closed
2380 // navbar4.htm navigation outline open
2381 bool HtmlExport::CreateNavBarFrames()
2389 maBackColor
= maFirstPageColor
;
2392 for( int nFile
= 0; nFile
< 3 && bOk
; nFile
++ )
2394 OUStringBuffer
aStr(gaHTMLHeader
);
2395 aStr
.append(CreateMetaCharset());
2396 aStr
.append(" <title>");
2397 aStr
.append(StringToHTMLString(maPageNames
[0]));
2398 aStr
.append("</title>\r\n</head>\r\n");
2399 aStr
.append(CreateBodyTag());
2400 aStr
.append("<center>\r\n");
2403 aButton
= SdResId(STR_HTMLEXP_FIRSTPAGE
);
2404 if(mnButtonThema
!= -1)
2405 aButton
= CreateImage(GetButtonName(nFile
== 0 || mnSdPageCount
== 1 ? BTN_FIRST_0
: BTN_FIRST_1
),
2408 if(nFile
!= 0 && mnSdPageCount
> 1)
2409 aButton
= CreateLink("JavaScript:parent.NavigateAbs(0)", aButton
);
2411 aStr
.append(aButton
);
2412 aStr
.append("\r\n");
2414 // to the previous page
2415 aButton
= SdResId(STR_PUBLISH_BACK
);
2416 if(mnButtonThema
!= -1)
2417 aButton
= CreateImage(GetButtonName(nFile
== 0 || mnSdPageCount
== 1?
2418 BTN_PREV_0
:BTN_PREV_1
),
2421 if(nFile
!= 0 && mnSdPageCount
> 1)
2422 aButton
= CreateLink("JavaScript:parent.NavigateRel(-1)", aButton
);
2424 aStr
.append(aButton
);
2425 aStr
.append("\r\n");
2428 aButton
= SdResId(STR_PUBLISH_NEXT
);
2429 if(mnButtonThema
!= -1)
2430 aButton
= CreateImage(GetButtonName(nFile
==2 || mnSdPageCount
== 1?
2431 BTN_NEXT_0
:BTN_NEXT_1
),
2434 if(nFile
!= 2 && mnSdPageCount
> 1)
2435 aButton
= CreateLink("JavaScript:parent.NavigateRel(1)", aButton
);
2437 aStr
.append(aButton
);
2438 aStr
.append("\r\n");
2441 aButton
= SdResId(STR_HTMLEXP_LASTPAGE
);
2442 if(mnButtonThema
!= -1)
2443 aButton
= CreateImage(GetButtonName(nFile
==2 || mnSdPageCount
== 1?
2444 BTN_LAST_0
:BTN_LAST_1
),
2447 if(nFile
!= 2 && mnSdPageCount
> 1)
2449 OUString
aLink("JavaScript:parent.NavigateAbs(" +
2450 OUString::number(mnSdPageCount
-1) + ")");
2452 aButton
= CreateLink(aLink
, aButton
);
2455 aStr
.append(aButton
);
2456 aStr
.append("\r\n");
2461 aButton
= SdResId(STR_PUBLISH_OUTLINE
);
2462 if(mnButtonThema
!= -1)
2463 aButton
= CreateImage(GetButtonName(BTN_INDEX
), aButton
);
2466 aStr
.append(CreateLink(maIndex
, aButton
, "_top"));
2467 aStr
.append("\r\n");
2473 aButton
= SdResId(STR_HTMLEXP_SETTEXT
);
2474 if(mnButtonThema
!= -1)
2475 aButton
= CreateImage(GetButtonName(BTN_TEXT
), aButton
);
2477 OUString
aText0("text0" + gaHTMLExtension
);
2478 aStr
.append(CreateLink(aText0
, aButton
, "_top"));
2479 aStr
.append("\r\n");
2483 aStr
.append("</center>\r\n");
2484 aStr
.append("</body>\r\n</html>");
2486 OUString
aFileName("navbar" + OUString::number(nFile
));
2488 bOk
= WriteHtml(aFileName
, true, aStr
.makeStringAndClear());
2491 mpProgress
->SetState(++mnPagesWritten
);
2494 // the navigation bar outliner closed...
2497 OUStringBuffer
aStr(gaHTMLHeader
);
2498 aStr
.append(CreateMetaCharset());
2499 aStr
.append(" <title>");
2500 aStr
.append(StringToHTMLString(maPageNames
[0]));
2501 aStr
.append("</title>\r\n</head>\r\n");
2502 aStr
.append(CreateBodyTag());
2504 aButton
= SdResId(STR_HTMLEXP_OUTLINE
);
2505 if(mnButtonThema
!= -1)
2506 aButton
= CreateImage(GetButtonName(BTN_MORE
), aButton
);
2508 aStr
.append(CreateLink("JavaScript:parent.ExpandOutline()", aButton
));
2509 aStr
.append("</body>\r\n</html>");
2511 bOk
= WriteHtml("navbar3", true, aStr
.makeStringAndClear());
2514 mpProgress
->SetState(++mnPagesWritten
);
2517 // ... and the outliner open
2520 OUStringBuffer
aStr(gaHTMLHeader
);
2521 aStr
.append(CreateMetaCharset());
2522 aStr
.append(" <title>");
2523 aStr
.append(StringToHTMLString(maPageNames
[0]));
2524 aStr
.append("</title>\r\n</head>\r\n");
2525 aStr
.append(CreateBodyTag());
2527 aButton
= SdResId(STR_HTMLEXP_NOOUTLINE
);
2528 if(mnButtonThema
!= -1)
2529 aButton
= CreateImage(GetButtonName(BTN_LESS
), aButton
);
2531 aStr
.append(CreateLink("JavaScript:parent.CollapseOutline()", aButton
));
2532 aStr
.append("</body>\r\n</html>");
2534 bOk
= WriteHtml("navbar4", true, aStr
.makeStringAndClear());
2537 mpProgress
->SetState(++mnPagesWritten
);
2544 // create button bar for standard
2545 OUString
HtmlExport::CreateNavBar( sal_uInt16 nSdPage
, bool bIsText
) const
2547 // prepare button bar
2548 OUString
aStrNavFirst(SdResId(STR_HTMLEXP_FIRSTPAGE
));
2549 OUString
aStrNavPrev(SdResId(STR_PUBLISH_BACK
));
2550 OUString
aStrNavNext(SdResId(STR_PUBLISH_NEXT
));
2551 OUString
aStrNavLast(SdResId(STR_HTMLEXP_LASTPAGE
));
2552 OUString
aStrNavContent(SdResId(STR_PUBLISH_OUTLINE
));
2553 OUString aStrNavText
;
2556 aStrNavText
= SdResId(STR_HTMLEXP_SETGRAPHIC
);
2560 aStrNavText
= SdResId(STR_HTMLEXP_SETTEXT
);
2563 if(!bIsText
&& mnButtonThema
!= -1)
2565 if(nSdPage
<1 || mnSdPageCount
== 1)
2567 aStrNavFirst
= CreateImage(GetButtonName(BTN_FIRST_0
), aStrNavFirst
);
2568 aStrNavPrev
= CreateImage(GetButtonName(BTN_PREV_0
), aStrNavPrev
);
2572 aStrNavFirst
= CreateImage(GetButtonName(BTN_FIRST_1
), aStrNavFirst
);
2573 aStrNavPrev
= CreateImage(GetButtonName(BTN_PREV_1
), aStrNavPrev
);
2576 if(nSdPage
== mnSdPageCount
-1 || mnSdPageCount
== 1)
2578 aStrNavNext
= CreateImage(GetButtonName(BTN_NEXT_0
), aStrNavNext
);
2579 aStrNavLast
= CreateImage(GetButtonName(BTN_LAST_0
), aStrNavLast
);
2583 aStrNavNext
= CreateImage(GetButtonName(BTN_NEXT_1
), aStrNavNext
);
2584 aStrNavLast
= CreateImage(GetButtonName(BTN_LAST_1
), aStrNavLast
);
2587 aStrNavContent
= CreateImage(GetButtonName(BTN_INDEX
), aStrNavContent
);
2588 aStrNavText
= CreateImage(GetButtonName(BTN_TEXT
), aStrNavText
);
2591 OUStringBuffer
aStr("<center>\r\n"); //<table><tr>\r\n");
2595 aStr
.append(CreateLink( bIsText
? maTextFiles
[0] : maHTMLFiles
[0],aStrNavFirst
));
2597 aStr
.append(aStrNavFirst
);
2602 aStr
.append(CreateLink( bIsText
? maTextFiles
[nSdPage
-1]
2603 : maHTMLFiles
[nSdPage
-1], aStrNavPrev
));
2605 aStr
.append(aStrNavPrev
);
2609 if(nSdPage
< mnSdPageCount
-1)
2610 aStr
.append(CreateLink( bIsText
? maTextFiles
[nSdPage
+1]
2611 : maHTMLFiles
[nSdPage
+1], aStrNavNext
));
2613 aStr
.append(aStrNavNext
);
2617 if(nSdPage
< mnSdPageCount
-1)
2618 aStr
.append(CreateLink( bIsText
? maTextFiles
[mnSdPageCount
-1]
2619 : maHTMLFiles
[mnSdPageCount
-1],
2622 aStr
.append(aStrNavLast
);
2628 aStr
.append(CreateLink(maIndex
, aStrNavContent
));
2635 aStr
.append(CreateLink( bIsText
? (mbFrames
? maFramePage
: maHTMLFiles
[nSdPage
])
2636 : maTextFiles
[nSdPage
], aStrNavText
));
2640 aStr
.append("</center><br>\r\n");
2642 return aStr
.makeStringAndClear();
2645 // export navigation graphics from button set
2646 void HtmlExport::CreateBitmaps()
2648 if(mnButtonThema
== -1 || !mpButtonSet
)
2651 for( int nButton
= 0; nButton
!= SAL_N_ELEMENTS(pButtonNames
); nButton
++ )
2653 if(!mbFrames
&& (nButton
== BTN_MORE
|| nButton
== BTN_LESS
))
2656 if(!mbImpress
&& (nButton
== BTN_TEXT
|| nButton
== BTN_MORE
|| nButton
== BTN_LESS
))
2659 OUString aFull
= maExportPath
+ GetButtonName(nButton
);
2660 mpButtonSet
->exportButton( mnButtonThema
, aFull
, GetButtonName(nButton
) );
2664 // creates the <body> tag, including the specified color attributes
2665 OUString
HtmlExport::CreateBodyTag() const
2667 OUStringBuffer
aStr( "<body" );
2669 if( mbUserAttr
|| mbDocColors
)
2671 Color
aTextColor( maTextColor
);
2672 if( (aTextColor
== COL_AUTO
) && (!maBackColor
.IsDark()) )
2673 aTextColor
= COL_BLACK
;
2675 aStr
.append(" text=\"");
2676 aStr
.append(ColorToHTMLString( aTextColor
));
2677 aStr
.append("\" bgcolor=\"");
2678 aStr
.append(ColorToHTMLString( maBackColor
));
2679 aStr
.append("\" link=\"");
2680 aStr
.append(ColorToHTMLString( maLinkColor
));
2681 aStr
.append("\" vlink=\"");
2682 aStr
.append(ColorToHTMLString( maVLinkColor
));
2683 aStr
.append("\" alink=\"");
2684 aStr
.append(ColorToHTMLString( maALinkColor
));
2688 aStr
.append(">\r\n");
2690 return aStr
.makeStringAndClear();
2693 // creates a hyperlink
2694 OUString
HtmlExport::CreateLink( const OUString
& aLink
,
2695 const OUString
& aText
,
2696 const OUString
& aTarget
)
2698 OUStringBuffer
aStr( "<a href=\"" );
2700 if (!aTarget
.isEmpty())
2702 aStr
.append("\" target=\"");
2703 aStr
.append(aTarget
);
2707 aStr
.append("</a>");
2709 return aStr
.makeStringAndClear();
2712 // creates an image tag
2713 OUString
HtmlExport::CreateImage( const OUString
& aImage
, const OUString
& aAltText
)
2715 OUStringBuffer
aStr( "<img src=\"");
2716 aStr
.append(aImage
);
2717 aStr
.append("\" border=0");
2719 if (!aAltText
.isEmpty())
2721 aStr
.append(" alt=\"");
2722 aStr
.append(aAltText
);
2727 // Agerskov: HTML 4.01 has to have an alt attribute even if it is an empty string
2728 aStr
.append(" alt=\"\"");
2733 return aStr
.makeStringAndClear();
2736 // create area for a circle; we expect pixel coordinates
2737 OUString
HtmlExport::ColorToHTMLString( Color aColor
)
2739 static const char hex
[] = "0123456789ABCDEF";
2740 OUStringBuffer
aStr( "#xxxxxx" );
2741 aStr
[1] = hex
[(aColor
.GetRed() >> 4) & 0xf];
2742 aStr
[2] = hex
[aColor
.GetRed() & 0xf];
2743 aStr
[3] = hex
[(aColor
.GetGreen() >> 4) & 0xf];
2744 aStr
[4] = hex
[aColor
.GetGreen() & 0xf];
2745 aStr
[5] = hex
[(aColor
.GetBlue() >> 4) & 0xf];
2746 aStr
[6] = hex
[aColor
.GetBlue() & 0xf];
2748 return aStr
.makeStringAndClear();
2751 // create area for a circle; we expect pixel coordinates
2752 OUString
HtmlExport::CreateHTMLCircleArea( sal_uLong nRadius
,
2755 const OUString
& rHRef
)
2758 "<area shape=\"circle\" alt=\"\" coords=\"" +
2759 OUString::number(nCenterX
) + "," +
2760 OUString::number(nCenterY
) + "," +
2761 OUString::number(nRadius
) +
2762 "\" href=\"" + rHRef
+ "\">\n");
2767 // create area for a polygon; we expect pixel coordinates
2768 OUString
HtmlExport::CreateHTMLPolygonArea( const ::basegfx::B2DPolyPolygon
& rPolyPolygon
,
2769 Size aShift
, double fFactor
, const OUString
& rHRef
)
2771 OUStringBuffer aStr
;
2772 const sal_uInt32
nNoOfPolygons(rPolyPolygon
.count());
2774 for ( sal_uInt32 nXPoly
= 0; nXPoly
< nNoOfPolygons
; nXPoly
++ )
2776 const ::basegfx::B2DPolygon
& aPolygon
= rPolyPolygon
.getB2DPolygon(nXPoly
);
2777 const sal_uInt32
nNoOfPoints(aPolygon
.count());
2779 aStr
.append("<area shape=\"polygon\" alt=\"\" coords=\"");
2781 for ( sal_uInt32 nPoint
= 0; nPoint
< nNoOfPoints
; nPoint
++ )
2783 const ::basegfx::B2DPoint
aB2DPoint(aPolygon
.getB2DPoint(nPoint
));
2784 Point
aPnt(FRound(aB2DPoint
.getX()), FRound(aB2DPoint
.getY()));
2785 // coordinates are relative to the physical page origin, not the
2786 // origin of ordinates
2787 aPnt
.Move(aShift
.Width(), aShift
.Height());
2789 aPnt
.setX( static_cast<tools::Long
>(aPnt
.X() * fFactor
) );
2790 aPnt
.setY( static_cast<tools::Long
>(aPnt
.Y() * fFactor
) );
2791 aStr
.append(OUString::number(aPnt
.X())).append(",").append(OUString::number(aPnt
.Y()));
2793 if (nPoint
< nNoOfPoints
- 1)
2796 aStr
.append("\" href=\"").append(rHRef
).append("\">\n");
2799 return aStr
.makeStringAndClear();
2802 // create area for a rectangle; we expect pixel coordinates
2803 OUString
HtmlExport::CreateHTMLRectArea( const ::tools::Rectangle
& rRect
,
2804 const OUString
& rHRef
)
2807 "<area shape=\"rect\" alt=\"\" coords=\"" +
2808 OUString::number(rRect
.Left()) + "," +
2809 OUString::number(rRect
.Top()) + "," +
2810 OUString::number(rRect
.Right()) + "," +
2811 OUString::number(rRect
.Bottom()) +
2812 "\" href=\"" + rHRef
+ "\">\n");
2817 // escapes a string for html
2818 OUString
HtmlExport::StringToHTMLString( const OUString
& rString
)
2820 SvMemoryStream aMemStm
;
2821 HTMLOutFuncs::Out_String( aMemStm
, rString
, RTL_TEXTENCODING_UTF8
);
2822 aMemStm
.WriteChar( char(0) );
2823 sal_Int32 nLength
= strlen(static_cast<char const *>(aMemStm
.GetData()));
2824 return OUString( static_cast<char const *>(aMemStm
.GetData()), nLength
, RTL_TEXTENCODING_UTF8
);
2827 // creates a URL for a specific page
2828 OUString
HtmlExport::CreatePageURL( sal_uInt16 nPgNum
)
2832 return OUString("JavaScript:parent.NavigateAbs(" +
2833 OUString::number(nPgNum
) + ")");
2836 return maHTMLFiles
[nPgNum
];
2839 bool HtmlExport::CopyScript( const OUString
& rPath
, const OUString
& rSource
, const OUString
& rDest
, bool bUnix
/* = false */ )
2841 INetURLObject
aURL( SvtPathOptions().GetConfigPath() );
2842 OUStringBuffer aScriptBuf
;
2844 aURL
.Append( "webcast" );
2845 aURL
.Append( rSource
);
2847 meEC
.SetContext( STR_HTMLEXP_ERROR_OPEN_FILE
, rSource
);
2849 ErrCode nErr
= ERRCODE_NONE
;
2850 std::unique_ptr
<SvStream
> pIStm
= ::utl::UcbStreamHelper::CreateStream( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), StreamMode::READ
);
2856 while( pIStm
->ReadLine( aLine
) )
2858 aScriptBuf
.appendAscii( aLine
.getStr() );
2861 aScriptBuf
.append("\n");
2865 aScriptBuf
.append("\r\n");
2869 nErr
= pIStm
->GetError();
2873 if( nErr
!= ERRCODE_NONE
)
2875 ErrorHandler::HandleError( nErr
);
2876 return static_cast<bool>(nErr
);
2879 OUString
aScript(aScriptBuf
.makeStringAndClear());
2880 aScript
= aScript
.replaceAll("$$1", getDocumentTitle());
2881 aScript
= aScript
.replaceAll("$$2", RESTOHTML(STR_WEBVIEW_SAVE
));
2882 aScript
= aScript
.replaceAll("$$3", maCGIPath
);
2883 aScript
= aScript
.replaceAll("$$4", OUString::number(mnWidthPixel
));
2884 aScript
= aScript
.replaceAll("$$5", OUString::number(mnHeightPixel
));
2886 OUString
aDest(rPath
+ rDest
);
2888 meEC
.SetContext( STR_HTMLEXP_ERROR_CREATE_FILE
, rDest
);
2889 // write script file
2893 nErr
= aFile
.createStream(aDest
, pStr
);
2894 if(nErr
== ERRCODE_NONE
)
2896 OString
aStr(OUStringToOString(aScript
, RTL_TEXTENCODING_UTF8
));
2897 pStr
->WriteOString( aStr
);
2903 mpProgress
->SetState(++mnPagesWritten
);
2905 if( nErr
!= ERRCODE_NONE
)
2906 ErrorHandler::HandleError( nErr
);
2908 return nErr
== ERRCODE_NONE
;
2911 static const char * ASP_Scripts
[] = { "common.inc", "webcast.asp", "show.asp", "savepic.asp", "poll.asp", "editpic.asp" };
2913 /** creates and saves the ASP scripts for WebShow */
2914 bool HtmlExport::CreateASPScripts()
2916 for(const char * p
: ASP_Scripts
)
2918 OUString aScript
= OUString::createFromAscii(p
);
2920 if(!CopyScript(maExportPath
, aScript
, aScript
))
2924 return CopyScript(maExportPath
, "edit.asp", maIndex
);
2927 static const char *PERL_Scripts
[] = { "webcast.pl", "common.pl", "editpic.pl", "poll.pl", "savepic.pl", "show.pl" };
2929 // creates and saves the PERL scripts for WebShow
2930 bool HtmlExport::CreatePERLScripts()
2932 for(const char * p
: PERL_Scripts
)
2934 OUString aScript
= OUString::createFromAscii(p
);
2936 if(!CopyScript(maExportPath
, aScript
, aScript
, true))
2940 if (!CopyScript(maExportPath
, "edit.pl", maIndex
, true))
2943 if (!CopyScript(maExportPath
, "index.pl", maIndexUrl
, true))
2949 // creates a list with names of the saved images
2950 bool HtmlExport::CreateImageFileList()
2952 OUStringBuffer aStr
;
2953 for( sal_uInt16 nSdPage
= 0; nSdPage
< mnSdPageCount
; nSdPage
++)
2955 aStr
.append(OUString::number(nSdPage
+ 1));
2957 aStr
.append(maURLPath
);
2958 aStr
.append(maImageFiles
[nSdPage
]);
2959 aStr
.append("\r\n");
2962 bool bOk
= WriteHtml("picture.txt", false, aStr
.makeStringAndClear());
2965 mpProgress
->SetState(++mnPagesWritten
);
2970 // creates a file with the actual page number
2971 bool HtmlExport::CreateImageNumberFile()
2973 OUString
aFileName("currpic.txt");
2974 OUString
aFull(maExportPath
+ aFileName
);
2976 meEC
.SetContext( STR_HTMLEXP_ERROR_CREATE_FILE
, aFileName
);
2979 ErrCode nErr
= aFile
.createStream(aFull
, pStr
);
2980 if(nErr
== ERRCODE_NONE
)
2982 pStr
->WriteCharPtr( "1" );
2987 mpProgress
->SetState(++mnPagesWritten
);
2989 if( nErr
!= ERRCODE_NONE
)
2990 ErrorHandler::HandleError( nErr
);
2992 return nErr
== ERRCODE_NONE
;
2995 OUString
HtmlExport::InsertSound( const OUString
& rSoundFile
)
2997 if (rSoundFile
.isEmpty())
3000 INetURLObject
aURL( rSoundFile
);
3001 OUString aSoundFileName
= aURL
.getName();
3003 DBG_ASSERT( aURL
.GetProtocol() != INetProtocol::NotValid
, "invalid URL" );
3005 OUString
aStr("<embed src=\"" + aSoundFileName
+
3006 "\" hidden=\"true\" autostart=\"true\">");
3008 CopyFile(rSoundFile
, maExportPath
+ aSoundFileName
);
3013 bool HtmlExport::CopyFile( const OUString
& rSourceFile
, const OUString
& rDestFile
)
3015 meEC
.SetContext( STR_HTMLEXP_ERROR_COPY_FILE
, rSourceFile
, rDestFile
);
3016 osl::FileBase::RC Error
= osl::File::copy( rSourceFile
, rDestFile
);
3018 if( Error
!= osl::FileBase::E_None
)
3020 ErrorHandler::HandleError(ErrCode(Error
));
3029 bool HtmlExport::checkFileExists( Reference
< css::ucb::XSimpleFileAccess3
> const & xFileAccess
, OUString
const & aFileName
)
3033 OUString url
= maExportPath
+ aFileName
;
3034 return xFileAccess
->exists( url
);
3036 catch( css::uno::Exception
& )
3038 TOOLS_WARN_EXCEPTION( "sd", "sd::HtmlExport::checkFileExists()" );
3044 bool HtmlExport::checkForExistingFiles()
3046 bool bFound
= false;
3050 Reference
< XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
3051 uno::Reference
<ucb::XSimpleFileAccess3
> xFA(ucb::SimpleFileAccess::create(xContext
));
3054 for( nSdPage
= 0; !bFound
&& (nSdPage
< mnSdPageCount
); nSdPage
++)
3056 if( checkFileExists( xFA
, maImageFiles
[nSdPage
] ) ||
3057 checkFileExists( xFA
, maHTMLFiles
[nSdPage
] ) ||
3058 checkFileExists( xFA
, maThumbnailFiles
[nSdPage
] ) ||
3059 checkFileExists( xFA
, maPageNames
[nSdPage
] ) ||
3060 checkFileExists( xFA
, maTextFiles
[nSdPage
] ) )
3066 if( !bFound
&& mbDownload
)
3067 bFound
= checkFileExists( xFA
, maDocFileName
);
3069 if( !bFound
&& mbFrames
)
3070 bFound
= checkFileExists( xFA
, maFramePage
);
3074 OUString aSystemPath
;
3075 osl::FileBase::getSystemPathFromFileURL( maExportPath
, aSystemPath
);
3076 OUString
aMsg(SdResId(STR_OVERWRITE_WARNING
));
3077 aMsg
= aMsg
.replaceFirst( "%FILENAME", aSystemPath
);
3079 std::unique_ptr
<weld::MessageDialog
> xWarn(Application::CreateMessageDialog(nullptr,
3080 VclMessageType::Warning
, VclButtonsType::YesNo
,
3082 xWarn
->set_default_response(RET_YES
);
3083 bFound
= (RET_NO
== xWarn
->run());
3088 TOOLS_WARN_EXCEPTION( "sd", "sd::HtmlExport::checkForExistingFiles()" );
3095 OUString
HtmlExport::GetButtonName( int nButton
)
3097 return OUString::createFromAscii(pButtonNames
[nButton
]);
3100 EasyFile::EasyFile() : bOpen(false)
3104 EasyFile::~EasyFile()
3110 ErrCode
EasyFile::createStream( const OUString
& rUrl
, SvStream
* &rpStr
)
3116 createFileName( rUrl
, aFileName
);
3118 ErrCode nErr
= ERRCODE_NONE
;
3119 pOStm
= ::utl::UcbStreamHelper::CreateStream( aFileName
, StreamMode::WRITE
| StreamMode::TRUNC
);
3123 nErr
= pOStm
->GetError();
3127 nErr
= ERRCODE_SFX_CANTCREATECONTENT
;
3130 if( nErr
!= ERRCODE_NONE
)
3136 rpStr
= pOStm
.get();
3141 void EasyFile::createFileName( const OUString
& rURL
, OUString
& rFileName
)
3146 INetURLObject
aURL( rURL
);
3148 if( aURL
.GetProtocol() == INetProtocol::NotValid
)
3151 osl::FileBase::getFileURLFromSystemPath( rURL
, aURLStr
);
3152 aURL
= INetURLObject( aURLStr
);
3154 DBG_ASSERT( aURL
.GetProtocol() != INetProtocol::NotValid
, "invalid URL" );
3155 rFileName
= aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
3158 void EasyFile::close()
3164 // This class helps reporting errors during file i/o
3165 HtmlErrorContext::HtmlErrorContext()
3166 : ErrorContext(nullptr)
3171 bool HtmlErrorContext::GetString( ErrCode
, OUString
& rCtxStr
)
3173 DBG_ASSERT(mpResId
, "No error context set");
3177 rCtxStr
= SdResId(mpResId
);
3179 rCtxStr
= rCtxStr
.replaceAll( "$(URL1)", maURL1
);
3180 rCtxStr
= rCtxStr
.replaceAll( "$(URL2)", maURL2
);
3185 void HtmlErrorContext::SetContext(const char* pResId
, const OUString
& rURL
)
3192 void HtmlErrorContext::SetContext(const char* pResId
, const OUString
& rURL1
, const OUString
& rURL2
)
3199 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */