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/ucb/SimpleFileAccess.hpp>
25 #include <sal/log.hxx>
26 #include <rtl/tencinfo.h>
27 #include <comphelper/processfactory.hxx>
28 #include <osl/file.hxx>
29 #include <unotools/pathoptions.hxx>
30 #include <unotools/ucbstreamhelper.hxx>
31 #include <com/sun/star/frame/XStorable.hpp>
32 #include <sfx2/frmhtmlw.hxx>
33 #include <sfx2/progress.hxx>
34 #include <vcl/svapp.hxx>
35 #include <vcl/weld.hxx>
36 #include <svx/svditer.hxx>
37 #include <vcl/imaprect.hxx>
38 #include <vcl/imapcirc.hxx>
39 #include <vcl/imappoly.hxx>
40 #include <editeng/eeitem.hxx>
41 #include <editeng/outlobj.hxx>
42 #include <editeng/editobj.hxx>
43 #include <svx/svdopath.hxx>
44 #include <svtools/htmlout.hxx>
45 #include <svtools/colorcfg.hxx>
46 #include <editeng/colritem.hxx>
47 #include <editeng/editeng.hxx>
48 #include <editeng/wghtitem.hxx>
49 #include <editeng/udlnitem.hxx>
50 #include <editeng/postitem.hxx>
51 #include <editeng/crossedoutitem.hxx>
52 #include <editeng/flditem.hxx>
53 #include <svl/style.hxx>
54 #include <editeng/frmdiritem.hxx>
55 #include <svx/svdoutl.hxx>
56 #include <svx/svdogrp.hxx>
57 #include <svx/svdotable.hxx>
58 #include <tools/urlobj.hxx>
59 #include <svtools/sfxecode.hxx>
60 #include <comphelper/anytostring.hxx>
61 #include <cppuhelper/exc_hlp.hxx>
62 #include <basegfx/polygon/b2dpolygon.hxx>
63 #include <tools/debug.hxx>
64 #include <tools/diagnose_ex.h>
66 #include <drawdoc.hxx>
67 #include <DrawDocShell.hxx>
68 #include "htmlpublishmode.hxx"
69 #include <Outliner.hxx>
71 #include <strings.hrc>
72 #include <strings.hxx>
73 #include <anminfo.hxx>
74 #include <imapinfo.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
119 // Helper class for the simple creation of files local/remote
123 std::unique_ptr
<SvStream
> pOStm
;
131 ErrCode
createStream( const OUString
& rUrl
, SvStream
*& rpStr
);
132 void createFileName( const OUString
& rUrl
, OUString
& rFileName
);
136 // Helper class for the embedding of text attributes into the html output
152 explicit HtmlState( Color aDefColor
);
154 OUString
SetWeight( bool bWeight
);
155 OUString
SetItalic( bool bItalic
);
156 OUString
SetUnderline( bool bUnderline
);
157 OUString
SetColor( Color aColor
);
158 OUString
SetStrikeout( bool bStrike
);
159 OUString
SetLink( const OUString
& aLink
, const OUString
& aTarget
);
163 // close all still open tags
164 OUString
HtmlState::Flush()
166 OUString aStr
= SetWeight(false)
168 + SetUnderline(false)
169 + SetStrikeout(false)
170 + SetColor(maDefColor
)
176 // c'tor with default color for the page
177 HtmlState::HtmlState( Color aDefColor
)
185 maDefColor
= aDefColor
;
188 // enables/disables bold print
189 OUString
HtmlState::SetWeight( bool bWeight
)
193 if(bWeight
&& !mbWeight
)
195 else if(!bWeight
&& mbWeight
)
202 // enables/disables italic
204 OUString
HtmlState::SetItalic( bool bItalic
)
208 if(bItalic
&& !mbItalic
)
210 else if(!bItalic
&& mbItalic
)
217 // enables/disables underlines
219 OUString
HtmlState::SetUnderline( bool bUnderline
)
223 if(bUnderline
&& !mbUnderline
)
225 else if(!bUnderline
&& mbUnderline
)
228 mbUnderline
= bUnderline
;
232 // enables/disables strike through
233 OUString
HtmlState::SetStrikeout( bool bStrike
)
237 if(bStrike
&& !mbStrike
)
239 else if(!bStrike
&& mbStrike
)
246 // Sets the specified text color
247 OUString
HtmlState::SetColor( Color aColor
)
251 if(mbColor
&& aColor
== maColor
)
260 if(aColor
!= maDefColor
)
263 aStr
+= "<font color=\"" + HtmlExport::ColorToHTMLString(aColor
) + "\">";
270 // enables/disables a hyperlink
271 OUString
HtmlState::SetLink( const OUString
& aLink
, const OUString
& aTarget
)
275 if(mbLink
&&maLink
== aLink
&&maTarget
==aTarget
)
284 if (!aLink
.isEmpty())
286 aStr
+= "<a href=\"" + aLink
;
287 if (!aTarget
.isEmpty())
289 aStr
+= "\" target=\"" + aTarget
;
302 OUString
getParagraphStyle( SdrOutliner
* pOutliner
, sal_Int32 nPara
)
304 SfxItemSet
aParaSet( pOutliner
->GetParaAttribs( nPara
) );
308 if( aParaSet
.GetItem
<SvxFrameDirectionItem
>( EE_PARA_WRITINGDIR
)->GetValue() == SvxFrameDirection::Horizontal_RL_TB
)
311 sStyle
= "direction: rtl;";
315 // This is the default so don't write it out
316 // sStyle += "direction: ltr;";
321 void lclAppendStyle(OUStringBuffer
& aBuffer
, const OUString
& aTag
, const OUString
& aStyle
)
323 if (aStyle
.isEmpty())
324 aBuffer
.append("<").append(aTag
).append(">");
326 aBuffer
.append("<").append(aTag
).append(" style=\"").append(aStyle
).append("\">");
329 } // anonymous namespace
331 static constexpr OUStringLiteral
gaHTMLHeader(
332 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n"
333 " \"http://www.w3.org/TR/html4/transitional.dtd\">\r\n"
334 "<html>\r\n<head>\r\n" );
336 static constexpr OUStringLiteral gaHTMLExtension
= STR_HTMLEXP_DEFAULT_EXTENSION
;
338 // constructor for the html export helper classes
339 HtmlExport::HtmlExport(
340 const OUString
& aPath
,
341 const Sequence
< PropertyValue
>& rParams
,
342 SdDrawDocument
* pExpDoc
,
343 sd::DrawDocShell
* pDocShell
)
346 mpDocSh( pDocShell
),
348 meMode( PUBLISH_SINGLE_DOCUMENT
),
349 mbContentsPage(false),
351 mnWidthPixel( PUB_MEDRES_WIDTH
),
352 meFormat( FORMAT_JPG
),
357 mbHiddenSlides(true),
359 maTextColor(COL_BLACK
),
360 maBackColor(COL_WHITE
),
363 meScript( SCRIPT_ASP
),
364 mpButtonSet( new ButtonSet() )
366 bool bChange
= mpDoc
->IsChanged();
368 maIndexUrl
+= gaHTMLExtension
;
370 InitExportParameters( rParams
);
378 case PUBLISH_WEBCAST
:
384 case PUBLISH_SINGLE_DOCUMENT
:
385 ExportSingleDocument();
389 mpDoc
->SetChanged(bChange
);
392 HtmlExport::~HtmlExport()
396 // get common export parameters from item set
397 void HtmlExport::InitExportParameters( const Sequence
< PropertyValue
>& rParams
)
399 mbImpress
= mpDoc
->GetDocumentType() == DocumentType::Impress
;
401 sal_Int32 nArgs
= rParams
.getLength();
402 const PropertyValue
* pParams
= rParams
.getConstArray();
406 if ( pParams
->Name
== "PublishMode" )
409 pParams
->Value
>>= temp
;
410 meMode
= static_cast<HtmlPublishMode
>(temp
);
412 else if ( pParams
->Name
== "IndexURL" )
414 pParams
->Value
>>= aStr
;
417 else if ( pParams
->Name
== "Format" )
420 pParams
->Value
>>= temp
;
421 meFormat
= static_cast<PublishingFormat
>(temp
);
423 else if ( pParams
->Name
== "Compression" )
425 pParams
->Value
>>= aStr
;
426 OUString
aTmp( aStr
);
429 aTmp
= aTmp
.replaceFirst("%", "");
430 mnCompression
= static_cast<sal_Int16
>(aTmp
.toInt32());
433 else if ( pParams
->Name
== "Width" )
436 pParams
->Value
>>= temp
;
437 mnWidthPixel
= static_cast<sal_uInt16
>(temp
);
439 else if ( pParams
->Name
== "UseButtonSet" )
442 pParams
->Value
>>= temp
;
443 mnButtonThema
= static_cast<sal_Int16
>(temp
);
445 else if ( pParams
->Name
== "IsExportNotes" )
450 pParams
->Value
>>= temp
;
454 else if ( pParams
->Name
== "IsExportContentsPage" )
457 pParams
->Value
>>= temp
;
458 mbContentsPage
= temp
;
460 else if ( pParams
->Name
== "Author" )
462 pParams
->Value
>>= aStr
;
465 else if ( pParams
->Name
== "EMail" )
467 pParams
->Value
>>= aStr
;
470 else if ( pParams
->Name
== "HomepageURL" )
472 pParams
->Value
>>= aStr
;
475 else if ( pParams
->Name
== "UserText" )
477 pParams
->Value
>>= aStr
;
480 else if ( pParams
->Name
== "EnableDownload" )
483 pParams
->Value
>>= temp
;
486 else if ( pParams
->Name
== "SlideSound" )
489 pParams
->Value
>>= temp
;
492 else if ( pParams
->Name
== "HiddenSlides" )
495 pParams
->Value
>>= temp
;
496 mbHiddenSlides
= temp
;
498 else if ( pParams
->Name
== "BackColor" )
501 pParams
->Value
>>= temp
;
502 maBackColor
= Color(temp
);
505 else if ( pParams
->Name
== "TextColor" )
508 pParams
->Value
>>= temp
;
509 maTextColor
= Color(temp
);
512 else if ( pParams
->Name
== "LinkColor" )
515 pParams
->Value
>>= temp
;
516 maLinkColor
= Color(temp
);
519 else if ( pParams
->Name
== "VLinkColor" )
522 pParams
->Value
>>= temp
;
523 maVLinkColor
= Color(temp
);
526 else if ( pParams
->Name
== "ALinkColor" )
529 pParams
->Value
>>= temp
;
530 maALinkColor
= Color(temp
);
533 else if ( pParams
->Name
== "IsUseDocumentColors" )
536 pParams
->Value
>>= temp
;
539 else if ( pParams
->Name
== "KioskSlideDuration" )
542 pParams
->Value
>>= temp
;
543 mfSlideDuration
= temp
;
546 else if ( pParams
->Name
== "KioskEndless" )
549 pParams
->Value
>>= temp
;
552 else if ( pParams
->Name
== "WebCastCGIURL" )
554 pParams
->Value
>>= aStr
;
557 else if ( pParams
->Name
== "WebCastTargetURL" )
559 pParams
->Value
>>= aStr
;
562 else if ( pParams
->Name
== "WebCastScriptLanguage" )
564 pParams
->Value
>>= aStr
;
567 meScript
= SCRIPT_ASP
;
571 meScript
= SCRIPT_PERL
;
576 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(PRESOBJ_OUTLINE
);
810 if(pSheet
== nullptr)
811 pSheet
= pPage
->GetStyleSheetForPresObj(PRESOBJ_TEXT
);
812 if(pSheet
== nullptr)
813 pSheet
= pPage
->GetStyleSheetForPresObj(PRESOBJ_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 sal_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
< static_cast<sal_uInt64
>(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
,
1163 RTL_TEXTENCODING_UTF8
));
1164 pStr
->WriteCharPtr( aStr
.getStr() );
1168 if( nErr
!= ERRCODE_NONE
)
1169 ErrorHandler::HandleError(nErr
);
1171 return nErr
== ERRCODE_NONE
;
1174 /** creates a outliner text for the title objects of a page
1176 OUString
HtmlExport::CreateTextForTitle( SdrOutliner
* pOutliner
, SdPage
* pPage
, const Color
& rBackgroundColor
)
1178 SdrTextObj
* pTO
= static_cast<SdrTextObj
*>(pPage
->GetPresObj(PRESOBJ_TITLE
));
1180 pTO
= GetLayoutTextObject(pPage
);
1182 if (pTO
&& !pTO
->IsEmptyPresObj())
1184 OutlinerParaObject
* pOPO
= pTO
->GetOutlinerParaObject();
1185 if(pOPO
&& pOutliner
->GetParagraphCount() != 0)
1188 pOutliner
->SetText(*pOPO
);
1189 return ParagraphToHTMLString(pOutliner
,0, rBackgroundColor
);
1196 // creates a outliner text for a page
1197 OUString
HtmlExport::CreateTextForPage(SdrOutliner
* pOutliner
, SdPage
const * pPage
,
1198 bool bHeadLine
, const Color
& rBackgroundColor
)
1200 OUStringBuffer aStr
;
1202 for (size_t i
= 0; i
<pPage
->GetObjCount(); ++i
)
1204 SdrObject
* pObject
= pPage
->GetObj(i
);
1205 PresObjKind eKind
= pPage
->GetPresObjKind(pObject
);
1211 if (pObject
->GetObjIdentifier() == OBJ_GRUP
)
1213 SdrObjGroup
* pObjectGroup
= static_cast<SdrObjGroup
*>(pObject
);
1214 WriteObjectGroup(aStr
, pObjectGroup
, pOutliner
, rBackgroundColor
, false);
1216 else if (pObject
->GetObjIdentifier() == OBJ_TABLE
)
1218 SdrTableObj
* pTableObject
= static_cast<SdrTableObj
*>(pObject
);
1219 WriteTable(aStr
, pTableObject
, pOutliner
, rBackgroundColor
);
1223 if (pObject
->GetOutlinerParaObject())
1225 WriteOutlinerParagraph(aStr
, pOutliner
, pObject
->GetOutlinerParaObject(), rBackgroundColor
, false);
1233 SdrTableObj
* pTableObject
= static_cast<SdrTableObj
*>(pObject
);
1234 WriteTable(aStr
, pTableObject
, pOutliner
, rBackgroundColor
);
1239 case PRESOBJ_OUTLINE
:
1241 SdrTextObj
* pTextObject
= static_cast<SdrTextObj
*>(pObject
);
1242 if (pTextObject
->IsEmptyPresObj())
1244 WriteOutlinerParagraph(aStr
, pOutliner
, pTextObject
->GetOutlinerParaObject(), rBackgroundColor
, bHeadLine
);
1252 return aStr
.makeStringAndClear();
1255 void HtmlExport::WriteTable(OUStringBuffer
& aStr
, SdrTableObj
const * pTableObject
, SdrOutliner
* pOutliner
, const Color
& rBackgroundColor
)
1257 CellPos aStart
, aEnd
;
1259 aStart
= SdrTableObj::getFirstCell();
1260 aEnd
= pTableObject
->getLastCell();
1262 sal_Int32 nColCount
= pTableObject
->getColumnCount();
1263 aStr
.append("<table>\r\n");
1264 for (sal_Int32 nRow
= aStart
.mnRow
; nRow
<= aEnd
.mnRow
; nRow
++)
1266 aStr
.append(" <tr>\r\n");
1267 for (sal_Int32 nCol
= aStart
.mnCol
; nCol
<= aEnd
.mnCol
; nCol
++)
1269 aStr
.append(" <td>\r\n");
1270 sal_Int32 nCellIndex
= nRow
* nColCount
+ nCol
;
1271 SdrText
* pText
= pTableObject
->getText(nCellIndex
);
1273 if (pText
== nullptr)
1275 WriteOutlinerParagraph(aStr
, pOutliner
, pText
->GetOutlinerParaObject(), rBackgroundColor
, false);
1276 aStr
.append(" </td>\r\n");
1278 aStr
.append(" </tr>\r\n");
1280 aStr
.append("</table>\r\n");
1283 void HtmlExport::WriteObjectGroup(OUStringBuffer
& aStr
, SdrObjGroup
const * pObjectGroup
, SdrOutliner
* pOutliner
,
1284 const Color
& rBackgroundColor
, bool bHeadLine
)
1286 SdrObjListIter
aGroupIterator(pObjectGroup
->GetSubList(), SdrIterMode::DeepNoGroups
);
1287 while (aGroupIterator
.IsMore())
1289 SdrObject
* pCurrentObject
= aGroupIterator
.Next();
1290 if (pCurrentObject
->GetObjIdentifier() == OBJ_GRUP
)
1292 SdrObjGroup
* pCurrentGroupObject
= static_cast<SdrObjGroup
*>(pCurrentObject
);
1293 WriteObjectGroup(aStr
, pCurrentGroupObject
, pOutliner
, rBackgroundColor
, bHeadLine
);
1297 OutlinerParaObject
* pOutlinerParagraphObject
= pCurrentObject
->GetOutlinerParaObject();
1298 if (pOutlinerParagraphObject
!= nullptr)
1300 WriteOutlinerParagraph(aStr
, pOutliner
, pOutlinerParagraphObject
, rBackgroundColor
, bHeadLine
);
1306 void HtmlExport::WriteOutlinerParagraph(OUStringBuffer
& aStr
, SdrOutliner
* pOutliner
,
1307 OutlinerParaObject
const * pOutlinerParagraphObject
,
1308 const Color
& rBackgroundColor
, bool bHeadLine
)
1310 if (pOutlinerParagraphObject
== nullptr)
1313 pOutliner
->SetText(*pOutlinerParagraphObject
);
1315 sal_Int32 nCount
= pOutliner
->GetParagraphCount();
1318 sal_Int16 nCurrentDepth
= -1;
1320 for (sal_Int32 nIndex
= 0; nIndex
< nCount
; nIndex
++)
1322 Paragraph
* pParagraph
= pOutliner
->GetParagraph(nIndex
);
1323 if(pParagraph
== nullptr)
1326 const sal_Int16 nDepth
= static_cast<sal_uInt16
>(pOutliner
->GetDepth(nIndex
));
1327 OUString aParaText
= ParagraphToHTMLString(pOutliner
, nIndex
, rBackgroundColor
);
1329 if (aParaText
.isEmpty())
1334 OUString aTag
= bHeadLine
? OUString("h2") : OUString("p");
1335 lclAppendStyle(aStr
, aTag
, getParagraphStyle(pOutliner
, nIndex
));
1337 aStr
.append(aParaText
);
1338 aStr
.append("</").append(aTag
).append(">\r\n");
1342 while(nCurrentDepth
< nDepth
)
1344 aStr
.append("<ul>\r\n");
1347 while(nCurrentDepth
> nDepth
)
1349 aStr
.append("</ul>\r\n");
1352 lclAppendStyle(aStr
, "li", getParagraphStyle(pOutliner
, nIndex
));
1353 aStr
.append(aParaText
);
1354 aStr
.append("</li>\r\n");
1357 while(nCurrentDepth
>= 0)
1359 aStr
.append("</ul>\r\n");
1365 // creates a outliner text for a note page
1366 OUString
HtmlExport::CreateTextForNotesPage( SdrOutliner
* pOutliner
,
1368 const Color
& rBackgroundColor
)
1370 OUStringBuffer aStr
;
1372 SdrTextObj
* pTO
= static_cast<SdrTextObj
*>(pPage
->GetPresObj(PRESOBJ_NOTES
));
1374 if (pTO
&& !pTO
->IsEmptyPresObj())
1376 OutlinerParaObject
* pOPO
= pTO
->GetOutlinerParaObject();
1380 pOutliner
->SetText( *pOPO
);
1382 sal_Int32 nCount
= pOutliner
->GetParagraphCount();
1383 for (sal_Int32 nPara
= 0; nPara
< nCount
; nPara
++)
1385 lclAppendStyle(aStr
, "p", getParagraphStyle(pOutliner
, nPara
));
1386 aStr
.append(ParagraphToHTMLString(pOutliner
, nPara
, rBackgroundColor
));
1387 aStr
.append("</p>\r\n");
1392 return aStr
.makeStringAndClear();
1395 // converts a paragraph of the outliner to html
1396 OUString
HtmlExport::ParagraphToHTMLString( SdrOutliner
const * pOutliner
, sal_Int32 nPara
, const Color
& rBackgroundColor
)
1398 OUStringBuffer aStr
;
1400 if(nullptr == pOutliner
)
1404 EditEngine
& rEditEngine
= *const_cast<EditEngine
*>(&pOutliner
->GetEditEngine());
1405 bool bOldUpdateMode
= rEditEngine
.GetUpdateMode();
1406 rEditEngine
.SetUpdateMode(true);
1408 Paragraph
* pPara
= pOutliner
->GetParagraph(nPara
);
1409 if(nullptr == pPara
)
1412 HtmlState
aState( (mbUserAttr
|| mbDocColors
) ? maTextColor
: COL_BLACK
);
1413 std::vector
<sal_Int32
> aPortionList
;
1414 rEditEngine
.GetPortions( nPara
, aPortionList
);
1416 sal_Int32 nPos1
= 0;
1417 for( sal_Int32 nPos2
: aPortionList
)
1419 ESelection
aSelection( nPara
, nPos1
, nPara
, nPos2
);
1421 SfxItemSet
aSet( rEditEngine
.GetAttribs( aSelection
) );
1423 OUString
aPortion(StringToHTMLString(rEditEngine
.GetText( aSelection
)));
1425 aStr
.append(TextAttribToHTMLString( &aSet
, &aState
, rBackgroundColor
));
1426 aStr
.append(aPortion
);
1430 aStr
.append(aState
.Flush());
1431 rEditEngine
.SetUpdateMode(bOldUpdateMode
);
1433 return aStr
.makeStringAndClear();
1436 // Depending on the attributes of the specified set and the specified
1437 // HtmlState, it creates the needed html tags in order to get the
1439 OUString
HtmlExport::TextAttribToHTMLString( SfxItemSet
const * pSet
, HtmlState
* pState
, const Color
& rBackgroundColor
)
1441 OUStringBuffer aStr
;
1446 OUString aLink
, aTarget
;
1447 if ( pSet
->GetItemState( EE_FEATURE_FIELD
) == SfxItemState::SET
)
1449 const SvxFieldItem
* pItem
= pSet
->GetItem
<SvxFieldItem
>( EE_FEATURE_FIELD
);
1452 const SvxURLField
* pURL
= dynamic_cast<const SvxURLField
*>( pItem
->GetField() );
1455 aLink
= pURL
->GetURL();
1456 aTarget
= pURL
->GetTargetFrame();
1464 if ( pSet
->GetItemState( EE_CHAR_WEIGHT
) == SfxItemState::SET
)
1466 bTemp
= pSet
->Get( EE_CHAR_WEIGHT
).GetWeight() == WEIGHT_BOLD
;
1467 aTemp
= pState
->SetWeight( bTemp
);
1469 aStr
.insert(0, aTemp
);
1474 if ( pSet
->GetItemState( EE_CHAR_UNDERLINE
) == SfxItemState::SET
)
1476 bTemp
= pSet
->Get( EE_CHAR_UNDERLINE
).GetLineStyle() != LINESTYLE_NONE
;
1477 aTemp
= pState
->SetUnderline( bTemp
);
1479 aStr
.insert(0, aTemp
);
1484 if ( pSet
->GetItemState( EE_CHAR_STRIKEOUT
) == SfxItemState::SET
)
1486 bTemp
= pSet
->Get( EE_CHAR_STRIKEOUT
).GetStrikeout() != STRIKEOUT_NONE
;
1487 aTemp
= pState
->SetStrikeout( bTemp
);
1489 aStr
.insert(0, aTemp
);
1494 if ( pSet
->GetItemState( EE_CHAR_ITALIC
) == SfxItemState::SET
)
1496 bTemp
= pSet
->Get( EE_CHAR_ITALIC
).GetPosture() != ITALIC_NONE
;
1497 aTemp
= pState
->SetItalic( bTemp
);
1499 aStr
.insert(0, aTemp
);
1506 if ( pSet
->GetItemState( EE_CHAR_COLOR
) == SfxItemState::SET
)
1508 Color aTextColor
= pSet
->Get( EE_CHAR_COLOR
).GetValue();
1509 if( aTextColor
== COL_AUTO
)
1511 if( !rBackgroundColor
.IsDark() )
1512 aTextColor
= COL_BLACK
;
1514 aStr
.append(pState
->SetColor( aTextColor
));
1518 if (!aLink
.isEmpty())
1519 aStr
.insert(0, pState
->SetLink(aLink
, aTarget
));
1521 aStr
.append(pState
->SetLink(aLink
, aTarget
));
1523 return aStr
.makeStringAndClear();
1526 // create HTML wrapper for picture files
1527 bool HtmlExport::CreateHtmlForPresPages()
1531 std::vector
<SdrObject
*> aClickableObjects
;
1533 for(sal_uInt16 nSdPage
= 0; nSdPage
< mnSdPageCount
&& bOk
; nSdPage
++)
1535 // find clickable objects (also on the master page) and put it in the
1536 // list. This in reverse order character order since in html the first
1537 // area is taken in the case they overlap.
1538 SdPage
* pPage
= maPages
[ nSdPage
];
1542 SetDocColors( pPage
);
1545 bool bMasterDone
= false;
1547 while (!bMasterDone
)
1549 // sal_True = backwards
1550 SdrObjListIter
aIter(pPage
, SdrIterMode::DeepWithGroups
, true);
1552 SdrObject
* pObject
= aIter
.Next();
1555 SdAnimationInfo
* pInfo
= SdDrawDocument::GetAnimationInfo(pObject
);
1556 SdIMapInfo
* pIMapInfo
= SdDrawDocument::GetIMapInfo(pObject
);
1559 (pInfo
->meClickAction
== presentation::ClickAction_BOOKMARK
||
1560 pInfo
->meClickAction
== presentation::ClickAction_DOCUMENT
||
1561 pInfo
->meClickAction
== presentation::ClickAction_PREVPAGE
||
1562 pInfo
->meClickAction
== presentation::ClickAction_NEXTPAGE
||
1563 pInfo
->meClickAction
== presentation::ClickAction_FIRSTPAGE
||
1564 pInfo
->meClickAction
== presentation::ClickAction_LASTPAGE
)) ||
1567 aClickableObjects
.push_back(pObject
);
1570 pObject
= aIter
.Next();
1572 // now to the master page or finishing
1573 if (!pPage
->IsMasterPage())
1574 pPage
= static_cast<SdPage
*>(&(pPage
->TRG_GetMasterPage()));
1580 OUStringBuffer
aStr(gaHTMLHeader
);
1581 aStr
.append(CreateMetaCharset());
1582 aStr
.append(" <title>" ).append( StringToHTMLString(maPageNames
[nSdPage
]) ).append("</title>\r\n");
1584 // insert timing information
1585 pPage
= maPages
[ nSdPage
];
1586 if( meMode
== PUBLISH_KIOSK
)
1589 bool bEndless
= false;
1592 if( pPage
->GetPresChange() != PRESCHANGE_MANUAL
)
1594 fSecs
= pPage
->GetTime();
1595 bEndless
= mpDoc
->getPresentationSettings().mbEndless
;
1600 fSecs
= mfSlideDuration
;
1601 bEndless
= mbEndless
;
1606 if( nSdPage
< (mnSdPageCount
-1) || bEndless
)
1608 aStr
.append("<meta http-equiv=\"refresh\" content=\"");
1609 aStr
.append(OUString::number(fSecs
));
1610 aStr
.append("; URL=");
1612 int nPage
= nSdPage
+ 1;
1613 if( nPage
== mnSdPageCount
)
1616 aStr
.append(maHTMLFiles
[nPage
]);
1618 aStr
.append("\">\r\n");
1623 aStr
.append("</head>\r\n");
1626 aStr
.append(CreateBodyTag());
1628 if( mbSlideSound
&& pPage
->IsSoundOn() )
1629 aStr
.append(InsertSound(pPage
->GetSoundFile()));
1633 aStr
.append(CreateNavBar(nSdPage
, false));
1635 aStr
.append("<center>");
1636 aStr
.append("<img src=\"");
1637 aStr
.append(maImageFiles
[nSdPage
]);
1638 aStr
.append("\" alt=\"\"");
1640 if (!aClickableObjects
.empty())
1641 aStr
.append(" USEMAP=\"#map0\"");
1643 aStr
.append("></center>\r\n");
1646 if(mbNotes
&& !mbFrames
)
1648 SdrOutliner
* pOutliner
= mpDoc
->GetInternalOutliner();
1649 SdPage
* pNotesPage
= maNotesPages
[ nSdPage
];
1650 OUString
aNotesStr( CreateTextForNotesPage( pOutliner
, pNotesPage
, maBackColor
) );
1653 if (!aNotesStr
.isEmpty())
1655 aStr
.append("<h3>");
1656 aStr
.append(RESTOHTML(STR_HTMLEXP_NOTES
));
1657 aStr
.append(":</h3><br>\r\n\r\n<p>");
1659 aStr
.append(aNotesStr
);
1660 aStr
.append("\r\n</p>\r\n");
1664 // create Imagemap if necessary
1665 if (!aClickableObjects
.empty())
1667 aStr
.append("<map name=\"map0\">\r\n");
1669 for (SdrObject
* pObject
: aClickableObjects
)
1671 SdAnimationInfo
* pInfo
= SdDrawDocument::GetAnimationInfo(pObject
);
1672 SdIMapInfo
* pIMapInfo
= SdDrawDocument::GetIMapInfo(pObject
);
1674 ::tools::Rectangle
aRect(pObject
->GetCurrentBoundRect());
1675 Point
aLogPos(aRect
.TopLeft());
1676 bool bIsSquare
= aRect
.GetWidth() == aRect
.GetHeight();
1678 sal_uLong nPageWidth
= pPage
->GetSize().Width() - pPage
->GetLeftBorder() -
1679 pPage
->GetRightBorder();
1681 // BoundRect is relative to the physical page origin, not the
1682 // origin of ordinates
1683 aRect
.Move(-pPage
->GetLeftBorder(), -pPage
->GetUpperBorder());
1685 double fLogicToPixel
= static_cast<double>(mnWidthPixel
) / nPageWidth
;
1686 aRect
.SetLeft( static_cast<long>(aRect
.Left() * fLogicToPixel
) );
1687 aRect
.SetTop( static_cast<long>(aRect
.Top() * fLogicToPixel
) );
1688 aRect
.SetRight( static_cast<long>(aRect
.Right() * fLogicToPixel
) );
1689 aRect
.SetBottom( static_cast<long>(aRect
.Bottom() * fLogicToPixel
) );
1690 long nRadius
= aRect
.GetWidth() / 2;
1693 insert areas into Imagemap of the object, if the object has
1698 const ImageMap
& rIMap
= pIMapInfo
->GetImageMap();
1699 sal_uInt16 nAreaCount
= rIMap
.GetIMapObjectCount();
1700 for (sal_uInt16 nArea
= 0; nArea
< nAreaCount
; nArea
++)
1702 IMapObject
* pArea
= rIMap
.GetIMapObject(nArea
);
1703 sal_uInt16 nType
= pArea
->GetType();
1704 OUString
aURL( pArea
->GetURL() );
1706 // if necessary, convert page and object names into the
1707 // corresponding names of the html file
1709 sal_uInt16 nPgNum
= mpDoc
->GetPageByName( aURL
, bIsMasterPage
);
1710 SdrObject
* pObj
= nullptr;
1712 if (nPgNum
== SDRPAGE_NOTFOUND
)
1714 // is the bookmark a object?
1715 pObj
= mpDoc
->GetObj( aURL
);
1717 nPgNum
= pObj
->getSdrPageFromSdrObject()->GetPageNum();
1719 if (nPgNum
!= SDRPAGE_NOTFOUND
)
1721 nPgNum
= (nPgNum
- 1) / 2; // SdrPageNum --> SdPageNum
1722 aURL
= CreatePageURL(nPgNum
);
1727 case IMAP_OBJ_RECTANGLE
:
1729 ::tools::Rectangle
aArea(static_cast<IMapRectangleObject
*>(pArea
)->
1730 GetRectangle(false));
1732 // conversion into pixel coordinates
1733 aArea
.Move(aLogPos
.X() - pPage
->GetLeftBorder(),
1734 aLogPos
.Y() - pPage
->GetUpperBorder());
1735 aArea
.SetLeft( static_cast<long>(aArea
.Left() * fLogicToPixel
) );
1736 aArea
.SetTop( static_cast<long>(aArea
.Top() * fLogicToPixel
) );
1737 aArea
.SetRight( static_cast<long>(aArea
.Right() * fLogicToPixel
) );
1738 aArea
.SetBottom( static_cast<long>(aArea
.Bottom() * fLogicToPixel
) );
1740 aStr
.append(CreateHTMLRectArea(aArea
, aURL
));
1744 case IMAP_OBJ_CIRCLE
:
1746 Point
aCenter(static_cast<IMapCircleObject
*>(pArea
)->
1748 aCenter
+= Point(aLogPos
.X() - pPage
->GetLeftBorder(),
1749 aLogPos
.Y() - pPage
->GetUpperBorder());
1750 aCenter
.setX( static_cast<long>(aCenter
.X() * fLogicToPixel
) );
1751 aCenter
.setY( static_cast<long>(aCenter
.Y() * fLogicToPixel
) );
1753 sal_uLong nCircleRadius
= static_cast<IMapCircleObject
*>(pArea
)->
1755 nCircleRadius
= static_cast<sal_uLong
>(nCircleRadius
* fLogicToPixel
);
1756 aStr
.append(CreateHTMLCircleArea(nCircleRadius
,
1757 aCenter
.X(), aCenter
.Y(),
1762 case IMAP_OBJ_POLYGON
:
1764 tools::Polygon
aArea(static_cast<IMapPolygonObject
*>(pArea
)->GetPolygon(false));
1765 aStr
.append(CreateHTMLPolygonArea(::basegfx::B2DPolyPolygon(aArea
.getB2DPolygon()),
1766 Size(aLogPos
.X() - pPage
->GetLeftBorder(),
1767 aLogPos
.Y() - pPage
->GetUpperBorder()),
1768 fLogicToPixel
, aURL
));
1774 SAL_INFO("sd", "unknown IMAP_OBJ_type");
1782 if there is a presentation::ClickAction, determine bookmark
1783 and create area for the whole object
1788 presentation::ClickAction eClickAction
= pInfo
->meClickAction
;
1790 switch( eClickAction
)
1792 case presentation::ClickAction_BOOKMARK
:
1795 sal_uInt16 nPgNum
= mpDoc
->GetPageByName( pInfo
->GetBookmark(), bIsMasterPage
);
1796 SdrObject
* pObj
= nullptr;
1798 if( nPgNum
== SDRPAGE_NOTFOUND
)
1800 // is the bookmark a object?
1801 pObj
= mpDoc
->GetObj(pInfo
->GetBookmark());
1803 nPgNum
= pObj
->getSdrPageFromSdrObject()->GetPageNum();
1806 if( SDRPAGE_NOTFOUND
!= nPgNum
)
1807 aHRef
= CreatePageURL(( nPgNum
- 1 ) / 2 );
1811 case presentation::ClickAction_DOCUMENT
:
1812 aHRef
= pInfo
->GetBookmark();
1815 case presentation::ClickAction_PREVPAGE
:
1822 nPage
= nSdPage
- 1;
1824 aHRef
= CreatePageURL( static_cast<sal_uInt16
>(nPage
));
1828 case presentation::ClickAction_NEXTPAGE
:
1831 if (nSdPage
== mnSdPageCount
- 1)
1832 nPage
= mnSdPageCount
- 1;
1834 nPage
= nSdPage
+ 1;
1836 aHRef
= CreatePageURL( static_cast<sal_uInt16
>(nPage
));
1840 case presentation::ClickAction_FIRSTPAGE
:
1841 aHRef
= CreatePageURL(0);
1844 case presentation::ClickAction_LASTPAGE
:
1845 aHRef
= CreatePageURL(mnSdPageCount
- 1);
1852 // and now the areas
1853 if (!aHRef
.isEmpty())
1856 if (pObject
->GetObjInventor() == SdrInventor::Default
&&
1857 pObject
->GetObjIdentifier() == OBJ_CIRC
&&
1860 aStr
.append(CreateHTMLCircleArea(aRect
.GetWidth() / 2,
1861 aRect
.Left() + nRadius
,
1862 aRect
.Top() + nRadius
,
1866 else if (pObject
->GetObjInventor() == SdrInventor::Default
&&
1867 (pObject
->GetObjIdentifier() == OBJ_PATHLINE
||
1868 pObject
->GetObjIdentifier() == OBJ_PLIN
||
1869 pObject
->GetObjIdentifier() == OBJ_POLY
))
1871 aStr
.append(CreateHTMLPolygonArea(static_cast<SdrPathObj
*>(pObject
)->GetPathPoly(), Size(-pPage
->GetLeftBorder(), -pPage
->GetUpperBorder()), fLogicToPixel
, aHRef
));
1873 // something completely different: use the BoundRect
1876 aStr
.append(CreateHTMLRectArea(aRect
, aHRef
));
1883 aStr
.append("</map>\r\n");
1885 aClickableObjects
.clear();
1887 aStr
.append("</body>\r\n</html>");
1889 bOk
= WriteHtml(maHTMLFiles
[nSdPage
], false, aStr
.makeStringAndClear());
1892 mpProgress
->SetState(++mnPagesWritten
);
1898 // create overview pages
1899 bool HtmlExport::CreateContentPage()
1905 OUStringBuffer
aStr(gaHTMLHeader
);
1906 aStr
.append(CreateMetaCharset());
1907 aStr
.append(" <title>");
1908 aStr
.append(StringToHTMLString(maPageNames
[0]));
1909 aStr
.append("</title>\r\n</head>\r\n");
1910 aStr
.append(CreateBodyTag());
1913 aStr
.append("<center>\r\n");
1917 aStr
.append("<h1>");
1918 aStr
.append(getDocumentTitle());
1919 aStr
.append("</h1><br>\r\n");
1922 aStr
.append("<h2>");
1924 // Solaris compiler bug workaround
1926 aStr
.append(CreateLink(maFramePage
,
1927 RESTOHTML(STR_HTMLEXP_CLICKSTART
)));
1929 aStr
.append(CreateLink(StringToHTMLString(maHTMLFiles
[0]),
1930 RESTOHTML(STR_HTMLEXP_CLICKSTART
)));
1932 aStr
.append("</h2>\r\n</center>\r\n");
1934 aStr
.append("<center><table width=\"90%\"><tr>\r\n");
1937 aStr
.append("<td valign=\"top\" align=\"left\" width=\"25%\">\r\n");
1938 aStr
.append("<h3>");
1939 aStr
.append(RESTOHTML(STR_HTMLEXP_CONTENTS
));
1940 aStr
.append("</h3>");
1942 for(sal_uInt16 nSdPage
= 0; nSdPage
< mnSdPageCount
; nSdPage
++)
1944 OUString aPageName
= maPageNames
[nSdPage
];
1945 aStr
.append("<div align=\"left\">");
1947 aStr
.append(StringToHTMLString(aPageName
));
1949 aStr
.append(CreateLink(maHTMLFiles
[nSdPage
], aPageName
));
1950 aStr
.append("</div>\r\n");
1952 aStr
.append("</td>\r\n");
1954 // document information
1955 aStr
.append("<td valign=\"top\" align=\"left\" width=\"75%\">\r\n");
1957 if (!maAuthor
.isEmpty())
1959 aStr
.append("<p><strong>");
1960 aStr
.append(RESTOHTML(STR_HTMLEXP_AUTHOR
));
1961 aStr
.append(":</strong> ");
1962 aStr
.append(StringToHTMLString(maAuthor
));
1963 aStr
.append("</p>\r\n");
1966 if (!maEMail
.isEmpty())
1968 aStr
.append("<p><strong>");
1969 aStr
.append(RESTOHTML(STR_HTMLEXP_EMAIL
));
1970 aStr
.append(":</strong> <a href=\"mailto:");
1971 aStr
.append(maEMail
);
1973 aStr
.append(StringToHTMLString(maEMail
));
1974 aStr
.append("</a></p>\r\n");
1977 if (!maHomePage
.isEmpty())
1979 aStr
.append("<p><strong>");
1980 aStr
.append(RESTOHTML(STR_HTMLEXP_HOMEPAGE
));
1981 aStr
.append(":</strong> <a href=\"");
1982 aStr
.append(maHomePage
);
1984 aStr
.append(StringToHTMLString(maHomePage
));
1985 aStr
.append("</a> </p>\r\n");
1988 if (!maInfo
.isEmpty())
1990 aStr
.append("<p><strong>");
1991 aStr
.append(RESTOHTML(STR_HTMLEXP_INFO
));
1992 aStr
.append(":</strong><br>\r\n");
1993 aStr
.append(StringToHTMLString(maInfo
));
1994 aStr
.append("</p>\r\n");
1999 aStr
.append("<p><a href=\"");
2000 aStr
.append(maDocFileName
);
2002 aStr
.append(RESTOHTML(STR_HTMLEXP_DOWNLOAD
));
2003 aStr
.append("</a></p>\r\n");
2006 for(sal_uInt16 nSdPage
= 0; nSdPage
< mnSdPageCount
; nSdPage
++)
2010 maThumbnailFiles
[nSdPage
] +
2011 "\" width=\"256\" height=\"192\" alt=\"" +
2012 StringToHTMLString(maPageNames
[nSdPage
]) +
2015 aStr
.append(CreateLink(maHTMLFiles
[nSdPage
], aText
));
2016 aStr
.append("\r\n");
2019 aStr
.append("</td></tr></table></center>\r\n");
2021 aStr
.append("</body>\r\n</html>");
2023 bool bOk
= WriteHtml(maIndex
, false, aStr
.makeStringAndClear());
2026 mpProgress
->SetState(++mnPagesWritten
);
2031 // create note pages (for frames)
2033 bool HtmlExport::CreateNotesPages()
2037 SdrOutliner
* pOutliner
= mpDoc
->GetInternalOutliner();
2038 for( sal_uInt16 nSdPage
= 0; bOk
&& nSdPage
< mnSdPageCount
; nSdPage
++ )
2040 SdPage
* pPage
= maNotesPages
[nSdPage
];
2042 SetDocColors( pPage
);
2045 OUStringBuffer
aStr(gaHTMLHeader
);
2046 aStr
.append(CreateMetaCharset());
2047 aStr
.append(" <title>");
2048 aStr
.append(StringToHTMLString(maPageNames
[0]));
2049 aStr
.append("</title>\r\n</head>\r\n");
2050 aStr
.append(CreateBodyTag());
2053 aStr
.append(CreateTextForNotesPage( pOutliner
, pPage
, maBackColor
));
2055 aStr
.append("</body>\r\n</html>");
2057 OUString
aFileName("note" + OUString::number(nSdPage
));
2058 bOk
= WriteHtml(aFileName
, true, aStr
.makeStringAndClear());
2061 mpProgress
->SetState(++mnPagesWritten
);
2069 // create outline pages (for frames)
2071 bool HtmlExport::CreateOutlinePages()
2080 // page 0 will be the closed outline, page 1 the opened
2081 for (sal_Int32 nPage
= 0; nPage
< (mbImpress
?2:1) && bOk
; ++nPage
)
2084 OUStringBuffer
aStr(gaHTMLHeader
);
2085 aStr
.append(CreateMetaCharset());
2086 aStr
.append(" <title>");
2087 aStr
.append(StringToHTMLString(maPageNames
[0]));
2088 aStr
.append("</title>\r\n</head>\r\n");
2089 aStr
.append(CreateBodyTag());
2091 SdrOutliner
* pOutliner
= mpDoc
->GetInternalOutliner();
2092 for(sal_uInt16 nSdPage
= 0; nSdPage
< mnSdPageCount
; nSdPage
++)
2094 SdPage
* pPage
= maPages
[ nSdPage
];
2096 aStr
.append("<div align=\"left\">");
2097 OUString
aLink("JavaScript:parent.NavigateAbs(" +
2098 OUString::number(nSdPage
) + ")");
2100 OUString aTitle
= CreateTextForTitle(pOutliner
, pPage
, maBackColor
);
2101 if (aTitle
.isEmpty())
2102 aTitle
= maPageNames
[nSdPage
];
2104 lclAppendStyle(aStr
, "p", getParagraphStyle(pOutliner
, 0));
2105 aStr
.append(CreateLink(aLink
, aTitle
));
2106 aStr
.append("</p>");
2110 aStr
.append(CreateTextForPage( pOutliner
, pPage
, false, maBackColor
));
2112 aStr
.append("</div>\r\n");
2116 aStr
.append("</body>\r\n</html>");
2118 OUString
aFileName("outline" + OUString::number(nPage
));
2119 bOk
= WriteHtml(aFileName
, true, aStr
.makeStringAndClear());
2122 mpProgress
->SetState(++mnPagesWritten
);
2129 void HtmlExport::CreateFileNames()
2131 // create lists with new file names
2132 maHTMLFiles
.resize(mnSdPageCount
);
2133 maImageFiles
.resize(mnSdPageCount
);
2134 maThumbnailFiles
.resize(mnSdPageCount
);
2135 maPageNames
.resize(mnSdPageCount
);
2136 maTextFiles
.resize(mnSdPageCount
);
2138 mbHeader
= false; // headline on overview page?
2140 for (sal_uInt16 nSdPage
= 0; nSdPage
< mnSdPageCount
; nSdPage
++)
2142 OUString aHTMLFileName
;
2143 if(nSdPage
== 0 && !mbContentsPage
&& !mbFrames
)
2144 aHTMLFileName
= maIndex
;
2147 aHTMLFileName
= "img" + OUString::number(nSdPage
) + gaHTMLExtension
;
2150 maHTMLFiles
[nSdPage
] = aHTMLFileName
;
2152 OUString aImageFileName
= "img" + OUString::number(nSdPage
);
2153 if( meFormat
==FORMAT_GIF
)
2154 aImageFileName
+= ".gif";
2155 else if( meFormat
==FORMAT_JPG
)
2156 aImageFileName
+= ".jpg";
2158 aImageFileName
+= ".png";
2160 maImageFiles
[nSdPage
] = aImageFileName
;
2162 OUString aThumbnailFileName
= "thumb" + OUString::number(nSdPage
);
2163 if( meFormat
!=FORMAT_JPG
)
2164 aThumbnailFileName
+= ".png";
2166 aThumbnailFileName
+= ".jpg";
2168 maThumbnailFiles
[nSdPage
] = aThumbnailFileName
;
2170 maTextFiles
[nSdPage
] = "text" + OUString::number(nSdPage
) + gaHTMLExtension
;
2172 SdPage
* pSdPage
= maPages
[ nSdPage
];
2174 // get slide title from page name
2175 maPageNames
[nSdPage
] = pSdPage
->GetName();
2178 if(!mbContentsPage
&& mbFrames
)
2179 maFramePage
= maIndex
;
2182 maFramePage
= "siframes" + gaHTMLExtension
;
2186 OUString
const & HtmlExport::getDocumentTitle()
2188 // check for a title object in this page, if it's the first
2189 // title it becomes this documents title for the content
2195 // if there is a non-empty title object, use their first passage
2197 SdPage
* pSdPage
= mpDoc
->GetSdPage(0, PageKind::Standard
);
2198 SdrObject
* pTitleObj
= pSdPage
->GetPresObj(PRESOBJ_TITLE
);
2199 if (pTitleObj
&& !pTitleObj
->IsEmptyPresObj())
2201 OutlinerParaObject
* pParaObject
= pTitleObj
->GetOutlinerParaObject();
2204 const EditTextObject
& rEditTextObject
=
2205 pParaObject
->GetTextObject();
2206 OUString
aTest(rEditTextObject
.GetText(0));
2207 if (!aTest
.isEmpty())
2212 mDocTitle
= mDocTitle
.replace(0xff, ' ');
2215 if (mDocTitle
.isEmpty())
2217 mDocTitle
= maDocFileName
;
2218 sal_Int32 nDot
= mDocTitle
.indexOf('.');
2220 mDocTitle
= mDocTitle
.copy(0, nDot
);
2228 static const char JS_NavigateAbs
[] =
2229 "function NavigateAbs( nPage )\r\n"
2231 " frames[\"show\"].location.href = \"img\" + nPage + \".$EXT\";\r\n"
2232 " //frames[\"notes\"].location.href = \"note\" + nPage + \".$EXT\";\r\n"
2233 " nCurrentPage = nPage;\r\n"
2234 " if(nCurrentPage==0)\r\n"
2236 " frames[\"navbar1\"].location.href = \"navbar0.$EXT\";\r\n"
2238 " else if(nCurrentPage==nPageCount-1)\r\n"
2240 " frames[\"navbar1\"].location.href = \"navbar2.$EXT\";\r\n"
2244 " frames[\"navbar1\"].location.href = \"navbar1.$EXT\";\r\n"
2248 static const char JS_NavigateRel
[] =
2249 "function NavigateRel( nDelta )\r\n"
2251 " var nPage = parseInt(nCurrentPage) + parseInt(nDelta);\r\n"
2252 " if( (nPage >= 0) && (nPage < nPageCount) )\r\n"
2254 " NavigateAbs( nPage );\r\n"
2258 static const char JS_ExpandOutline
[] =
2259 "function ExpandOutline()\r\n"
2261 " frames[\"navbar2\"].location.href = \"navbar4.$EXT\";\r\n"
2262 " frames[\"outline\"].location.href = \"outline1.$EXT\";\r\n"
2265 static const char JS_CollapseOutline
[] =
2266 "function CollapseOutline()\r\n"
2268 " frames[\"navbar2\"].location.href = \"navbar3.$EXT\";\r\n"
2269 " frames[\"outline\"].location.href = \"outline0.$EXT\";\r\n"
2272 // create page with the frames
2274 bool HtmlExport::CreateFrames()
2277 OUStringBuffer
aStr(
2278 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\"\r\n"
2279 " \"http://www.w3.org/TR/html4/frameset.dtd\">\r\n"
2280 "<html>\r\n<head>\r\n");
2282 aStr
.append(CreateMetaCharset());
2283 aStr
.append(" <title>");
2284 aStr
.append(StringToHTMLString(maPageNames
[0]));
2285 aStr
.append("</title>\r\n");
2287 aStr
.append("<script type=\"text/javascript\">\r\n<!--\r\n");
2289 aStr
.append("var nCurrentPage = 0;\r\nvar nPageCount = ");
2290 aStr
.append(OUString::number(mnSdPageCount
));
2291 aStr
.append(";\r\n\r\n");
2293 OUString aFunction
= JS_NavigateAbs
;
2297 aFunction
= aFunction
.replaceAll("//", "");
2300 // substitute HTML file extension
2301 OUString
aPlaceHolder(".$EXT");
2302 aFunction
= aFunction
.replaceAll(aPlaceHolder
, gaHTMLExtension
);
2303 aStr
.append(aFunction
);
2305 aTmp
= JS_NavigateRel
;
2306 aTmp
= aTmp
.replaceAll(aPlaceHolder
, gaHTMLExtension
);
2311 aTmp
= JS_ExpandOutline
;
2312 aTmp
= aTmp
.replaceAll(aPlaceHolder
, gaHTMLExtension
);
2315 aTmp
= JS_CollapseOutline
;
2316 aTmp
= aTmp
.replaceAll(aPlaceHolder
, gaHTMLExtension
);
2319 aStr
.append("// -->\r\n</script>\r\n");
2321 aStr
.append("</head>\r\n");
2323 aStr
.append("<frameset cols=\"*,");
2324 aStr
.append(OUString::number((mnWidthPixel
+ 16)));
2325 aStr
.append("\">\r\n");
2328 aStr
.append(" <frameset rows=\"42,*\">\r\n");
2329 aStr
.append(" <frame src=\"navbar3");
2330 aStr
.append(gaHTMLExtension
);
2331 aStr
.append("\" name=\"navbar2\" marginwidth=\"4\" marginheight=\"4\" scrolling=\"no\">\r\n");
2333 aStr
.append(" <frame src=\"outline0");
2334 aStr
.append(gaHTMLExtension
);
2335 aStr
.append("\" name=\"outline\">\r\n");
2337 aStr
.append(" </frameset>\r\n");
2341 aStr
.append(" <frameset rows=\"42,");
2342 aStr
.append(OUString::number(static_cast<int>(static_cast<double>(mnWidthPixel
) * 0.75) + 16));
2343 aStr
.append(",*\">\r\n");
2346 aStr
.append(" <frameset rows=\"42,*\">\r\n");
2348 aStr
.append(" <frame src=\"navbar0");
2349 aStr
.append(gaHTMLExtension
);
2350 aStr
.append("\" name=\"navbar1\" marginwidth=\"4\" marginheight=\"4\" scrolling=\"no\">\r\n");
2352 aStr
.append(" <frame src=\"");
2353 aStr
.append(maHTMLFiles
[0]);
2354 aStr
.append("\" name=\"show\" marginwidth=\"4\" marginheight=\"4\">\r\n");
2358 aStr
.append(" <frame src=\"note0");
2359 aStr
.append(gaHTMLExtension
);
2360 aStr
.append("\" name=\"notes\">\r\n");
2362 aStr
.append(" </frameset>\r\n");
2364 aStr
.append("<noframes>\r\n");
2365 aStr
.append(CreateBodyTag());
2366 aStr
.append(RESTOHTML(STR_HTMLEXP_NOFRAMES
));
2367 aStr
.append("\r\n</noframes>\r\n</frameset>\r\n</html>");
2369 bool bOk
= WriteHtml(maFramePage
, false, aStr
.makeStringAndClear());
2372 mpProgress
->SetState(++mnPagesWritten
);
2377 // create button bar for standard
2378 // we create the following html files
2379 // navbar0.htm navigation bar graphic for the first page
2380 // navbar1.htm navigation bar graphic for the second until second last page
2381 // navbar2.htm navigation bar graphic for the last page
2382 // navbar3.htm navigation outline closed
2383 // navbar4.htm navigation outline open
2384 bool HtmlExport::CreateNavBarFrames()
2392 maBackColor
= maFirstPageColor
;
2395 for( int nFile
= 0; nFile
< 3 && bOk
; nFile
++ )
2397 OUStringBuffer
aStr(gaHTMLHeader
);
2398 aStr
.append(CreateMetaCharset());
2399 aStr
.append(" <title>");
2400 aStr
.append(StringToHTMLString(maPageNames
[0]));
2401 aStr
.append("</title>\r\n</head>\r\n");
2402 aStr
.append(CreateBodyTag());
2403 aStr
.append("<center>\r\n");
2406 aButton
= SdResId(STR_HTMLEXP_FIRSTPAGE
);
2407 if(mnButtonThema
!= -1)
2408 aButton
= CreateImage(GetButtonName(nFile
== 0 || mnSdPageCount
== 1 ? BTN_FIRST_0
: BTN_FIRST_1
),
2411 if(nFile
!= 0 && mnSdPageCount
> 1)
2412 aButton
= CreateLink("JavaScript:parent.NavigateAbs(0)", aButton
);
2414 aStr
.append(aButton
);
2415 aStr
.append("\r\n");
2417 // to the previous page
2418 aButton
= SdResId(STR_PUBLISH_BACK
);
2419 if(mnButtonThema
!= -1)
2420 aButton
= CreateImage(GetButtonName(nFile
== 0 || mnSdPageCount
== 1?
2421 BTN_PREV_0
:BTN_PREV_1
),
2424 if(nFile
!= 0 && mnSdPageCount
> 1)
2425 aButton
= CreateLink("JavaScript:parent.NavigateRel(-1)", aButton
);
2427 aStr
.append(aButton
);
2428 aStr
.append("\r\n");
2431 aButton
= SdResId(STR_PUBLISH_NEXT
);
2432 if(mnButtonThema
!= -1)
2433 aButton
= CreateImage(GetButtonName(nFile
==2 || mnSdPageCount
== 1?
2434 BTN_NEXT_0
:BTN_NEXT_1
),
2437 if(nFile
!= 2 && mnSdPageCount
> 1)
2438 aButton
= CreateLink("JavaScript:parent.NavigateRel(1)", aButton
);
2440 aStr
.append(aButton
);
2441 aStr
.append("\r\n");
2444 aButton
= SdResId(STR_HTMLEXP_LASTPAGE
);
2445 if(mnButtonThema
!= -1)
2446 aButton
= CreateImage(GetButtonName(nFile
==2 || mnSdPageCount
== 1?
2447 BTN_LAST_0
:BTN_LAST_1
),
2450 if(nFile
!= 2 && mnSdPageCount
> 1)
2452 OUString
aLink("JavaScript:parent.NavigateAbs(" +
2453 OUString::number(mnSdPageCount
-1) + ")");
2455 aButton
= CreateLink(aLink
, aButton
);
2458 aStr
.append(aButton
);
2459 aStr
.append("\r\n");
2464 aButton
= SdResId(STR_PUBLISH_OUTLINE
);
2465 if(mnButtonThema
!= -1)
2466 aButton
= CreateImage(GetButtonName(BTN_INDEX
), aButton
);
2469 aStr
.append(CreateLink(maIndex
, aButton
, "_top"));
2470 aStr
.append("\r\n");
2476 aButton
= SdResId(STR_HTMLEXP_SETTEXT
);
2477 if(mnButtonThema
!= -1)
2478 aButton
= CreateImage(GetButtonName(BTN_TEXT
), aButton
);
2480 OUString
aText0("text0" + gaHTMLExtension
);
2481 aStr
.append(CreateLink(aText0
, aButton
, "_top"));
2482 aStr
.append("\r\n");
2486 aStr
.append("</center>\r\n");
2487 aStr
.append("</body>\r\n</html>");
2489 OUString
aFileName("navbar" + OUString::number(nFile
));
2491 bOk
= WriteHtml(aFileName
, true, aStr
.makeStringAndClear());
2494 mpProgress
->SetState(++mnPagesWritten
);
2497 // the navigation bar outliner closed...
2500 OUStringBuffer
aStr(gaHTMLHeader
);
2501 aStr
.append(CreateMetaCharset());
2502 aStr
.append(" <title>");
2503 aStr
.append(StringToHTMLString(maPageNames
[0]));
2504 aStr
.append("</title>\r\n</head>\r\n");
2505 aStr
.append(CreateBodyTag());
2507 aButton
= SdResId(STR_HTMLEXP_OUTLINE
);
2508 if(mnButtonThema
!= -1)
2509 aButton
= CreateImage(GetButtonName(BTN_MORE
), aButton
);
2511 aStr
.append(CreateLink("JavaScript:parent.ExpandOutline()", aButton
));
2512 aStr
.append("</body>\r\n</html>");
2514 bOk
= WriteHtml("navbar3", true, aStr
.makeStringAndClear());
2517 mpProgress
->SetState(++mnPagesWritten
);
2520 // ... and the outliner open
2523 OUStringBuffer
aStr(gaHTMLHeader
);
2524 aStr
.append(CreateMetaCharset());
2525 aStr
.append(" <title>");
2526 aStr
.append(StringToHTMLString(maPageNames
[0]));
2527 aStr
.append("</title>\r\n</head>\r\n");
2528 aStr
.append(CreateBodyTag());
2530 aButton
= SdResId(STR_HTMLEXP_NOOUTLINE
);
2531 if(mnButtonThema
!= -1)
2532 aButton
= CreateImage(GetButtonName(BTN_LESS
), aButton
);
2534 aStr
.append(CreateLink("JavaScript:parent.CollapseOutline()", aButton
));
2535 aStr
.append("</body>\r\n</html>");
2537 bOk
= WriteHtml("navbar4", true, aStr
.makeStringAndClear());
2540 mpProgress
->SetState(++mnPagesWritten
);
2547 // create button bar for standard
2548 OUString
HtmlExport::CreateNavBar( sal_uInt16 nSdPage
, bool bIsText
) const
2550 // prepare button bar
2551 OUString
aStrNavFirst(SdResId(STR_HTMLEXP_FIRSTPAGE
));
2552 OUString
aStrNavPrev(SdResId(STR_PUBLISH_BACK
));
2553 OUString
aStrNavNext(SdResId(STR_PUBLISH_NEXT
));
2554 OUString
aStrNavLast(SdResId(STR_HTMLEXP_LASTPAGE
));
2555 OUString
aStrNavContent(SdResId(STR_PUBLISH_OUTLINE
));
2556 OUString aStrNavText
;
2559 aStrNavText
= SdResId(STR_HTMLEXP_SETGRAPHIC
);
2563 aStrNavText
= SdResId(STR_HTMLEXP_SETTEXT
);
2566 if(!bIsText
&& mnButtonThema
!= -1)
2568 if(nSdPage
<1 || mnSdPageCount
== 1)
2570 aStrNavFirst
= CreateImage(GetButtonName(BTN_FIRST_0
), aStrNavFirst
);
2571 aStrNavPrev
= CreateImage(GetButtonName(BTN_PREV_0
), aStrNavPrev
);
2575 aStrNavFirst
= CreateImage(GetButtonName(BTN_FIRST_1
), aStrNavFirst
);
2576 aStrNavPrev
= CreateImage(GetButtonName(BTN_PREV_1
), aStrNavPrev
);
2579 if(nSdPage
== mnSdPageCount
-1 || mnSdPageCount
== 1)
2581 aStrNavNext
= CreateImage(GetButtonName(BTN_NEXT_0
), aStrNavNext
);
2582 aStrNavLast
= CreateImage(GetButtonName(BTN_LAST_0
), aStrNavLast
);
2586 aStrNavNext
= CreateImage(GetButtonName(BTN_NEXT_1
), aStrNavNext
);
2587 aStrNavLast
= CreateImage(GetButtonName(BTN_LAST_1
), aStrNavLast
);
2590 aStrNavContent
= CreateImage(GetButtonName(BTN_INDEX
), aStrNavContent
);
2591 aStrNavText
= CreateImage(GetButtonName(BTN_TEXT
), aStrNavText
);
2594 OUStringBuffer
aStr("<center>\r\n"); //<table><tr>\r\n");
2598 aStr
.append(CreateLink( bIsText
? maTextFiles
[0] : maHTMLFiles
[0],aStrNavFirst
));
2600 aStr
.append(aStrNavFirst
);
2605 aStr
.append(CreateLink( bIsText
? maTextFiles
[nSdPage
-1]
2606 : maHTMLFiles
[nSdPage
-1], aStrNavPrev
));
2608 aStr
.append(aStrNavPrev
);
2612 if(nSdPage
< mnSdPageCount
-1)
2613 aStr
.append(CreateLink( bIsText
? maTextFiles
[nSdPage
+1]
2614 : maHTMLFiles
[nSdPage
+1], aStrNavNext
));
2616 aStr
.append(aStrNavNext
);
2620 if(nSdPage
< mnSdPageCount
-1)
2621 aStr
.append(CreateLink( bIsText
? maTextFiles
[mnSdPageCount
-1]
2622 : maHTMLFiles
[mnSdPageCount
-1],
2625 aStr
.append(aStrNavLast
);
2631 aStr
.append(CreateLink(maIndex
, aStrNavContent
));
2638 aStr
.append(CreateLink( bIsText
? (mbFrames
? maFramePage
: maHTMLFiles
[nSdPage
])
2639 : maTextFiles
[nSdPage
], aStrNavText
));
2643 aStr
.append("</center><br>\r\n");
2645 return aStr
.makeStringAndClear();
2648 // export navigation graphics from button set
2649 void HtmlExport::CreateBitmaps()
2651 if(mnButtonThema
== -1 || !mpButtonSet
.get())
2654 for( int nButton
= 0; nButton
!= SAL_N_ELEMENTS(pButtonNames
); nButton
++ )
2656 if(!mbFrames
&& (nButton
== BTN_MORE
|| nButton
== BTN_LESS
))
2659 if(!mbImpress
&& (nButton
== BTN_TEXT
|| nButton
== BTN_MORE
|| nButton
== BTN_LESS
))
2662 OUString
aFull(maExportPath
);
2663 aFull
+= GetButtonName(nButton
);
2664 mpButtonSet
->exportButton( mnButtonThema
, aFull
, GetButtonName(nButton
) );
2668 // creates the <body> tag, including the specified color attributes
2669 OUString
HtmlExport::CreateBodyTag() const
2671 OUStringBuffer
aStr( "<body" );
2673 if( mbUserAttr
|| mbDocColors
)
2675 Color
aTextColor( maTextColor
);
2676 if( (aTextColor
== COL_AUTO
) && (!maBackColor
.IsDark()) )
2677 aTextColor
= COL_BLACK
;
2679 aStr
.append(" text=\"");
2680 aStr
.append(ColorToHTMLString( aTextColor
));
2681 aStr
.append("\" bgcolor=\"");
2682 aStr
.append(ColorToHTMLString( maBackColor
));
2683 aStr
.append("\" link=\"");
2684 aStr
.append(ColorToHTMLString( maLinkColor
));
2685 aStr
.append("\" vlink=\"");
2686 aStr
.append(ColorToHTMLString( maVLinkColor
));
2687 aStr
.append("\" alink=\"");
2688 aStr
.append(ColorToHTMLString( maALinkColor
));
2692 aStr
.append(">\r\n");
2694 return aStr
.makeStringAndClear();
2697 // creates a hyperlink
2698 OUString
HtmlExport::CreateLink( const OUString
& aLink
,
2699 const OUString
& aText
,
2700 const OUString
& aTarget
)
2702 OUStringBuffer
aStr( "<a href=\"" );
2704 if (!aTarget
.isEmpty())
2706 aStr
.append("\" target=\"");
2707 aStr
.append(aTarget
);
2711 aStr
.append("</a>");
2713 return aStr
.makeStringAndClear();
2716 // creates a image tag
2717 OUString
HtmlExport::CreateImage( const OUString
& aImage
, const OUString
& aAltText
)
2719 OUStringBuffer
aStr( "<img src=\"");
2720 aStr
.append(aImage
);
2721 aStr
.append("\" border=0");
2723 if (!aAltText
.isEmpty())
2725 aStr
.append(" alt=\"");
2726 aStr
.append(aAltText
);
2731 // Agerskov: HTML 4.01 has to have an alt attribute even if it is an empty string
2732 aStr
.append(" alt=\"\"");
2737 return aStr
.makeStringAndClear();
2740 // create area for a circle; we expect pixel coordinates
2741 OUString
HtmlExport::ColorToHTMLString( Color aColor
)
2743 static const char hex
[] = "0123456789ABCDEF";
2744 OUStringBuffer
aStr( "#xxxxxx" );
2745 aStr
[1] = hex
[(aColor
.GetRed() >> 4) & 0xf];
2746 aStr
[2] = hex
[aColor
.GetRed() & 0xf];
2747 aStr
[3] = hex
[(aColor
.GetGreen() >> 4) & 0xf];
2748 aStr
[4] = hex
[aColor
.GetGreen() & 0xf];
2749 aStr
[5] = hex
[(aColor
.GetBlue() >> 4) & 0xf];
2750 aStr
[6] = hex
[aColor
.GetBlue() & 0xf];
2752 return aStr
.makeStringAndClear();
2755 // create area for a circle; we expect pixel coordinates
2756 OUString
HtmlExport::CreateHTMLCircleArea( sal_uLong nRadius
,
2759 const OUString
& rHRef
)
2762 "<area shape=\"circle\" alt=\"\" coords=\"" +
2763 OUString::number(nCenterX
) + "," +
2764 OUString::number(nCenterY
) + "," +
2765 OUString::number(nRadius
) +
2766 "\" href=\"" + rHRef
+ "\">\n");
2771 // create area for a polygon; we expect pixel coordinates
2772 OUString
HtmlExport::CreateHTMLPolygonArea( const ::basegfx::B2DPolyPolygon
& rPolyPolygon
,
2773 Size aShift
, double fFactor
, const OUString
& rHRef
)
2775 OUStringBuffer aStr
;
2776 const sal_uInt32
nNoOfPolygons(rPolyPolygon
.count());
2778 for ( sal_uInt32 nXPoly
= 0; nXPoly
< nNoOfPolygons
; nXPoly
++ )
2780 const ::basegfx::B2DPolygon
& aPolygon
= rPolyPolygon
.getB2DPolygon(nXPoly
);
2781 const sal_uInt32
nNoOfPoints(aPolygon
.count());
2783 aStr
.append("<area shape=\"polygon\" alt=\"\" coords=\"");
2785 for ( sal_uInt32 nPoint
= 0; nPoint
< nNoOfPoints
; nPoint
++ )
2787 const ::basegfx::B2DPoint
aB2DPoint(aPolygon
.getB2DPoint(nPoint
));
2788 Point
aPnt(FRound(aB2DPoint
.getX()), FRound(aB2DPoint
.getY()));
2789 // coordinates are relative to the physical page origin, not the
2790 // origin of ordinates
2791 aPnt
.Move(aShift
.Width(), aShift
.Height());
2793 aPnt
.setX( static_cast<long>(aPnt
.X() * fFactor
) );
2794 aPnt
.setY( static_cast<long>(aPnt
.Y() * fFactor
) );
2795 aStr
.append(OUString::number(aPnt
.X())).append(",").append(OUString::number(aPnt
.Y()));
2797 if (nPoint
< nNoOfPoints
- 1)
2800 aStr
.append("\" href=\"").append(rHRef
).append("\">\n");
2803 return aStr
.makeStringAndClear();
2806 // create area for a rectangle; we expect pixel coordinates
2807 OUString
HtmlExport::CreateHTMLRectArea( const ::tools::Rectangle
& rRect
,
2808 const OUString
& rHRef
)
2811 "<area shape=\"rect\" alt=\"\" coords=\"" +
2812 OUString::number(rRect
.Left()) + "," +
2813 OUString::number(rRect
.Top()) + "," +
2814 OUString::number(rRect
.Right()) + "," +
2815 OUString::number(rRect
.Bottom()) +
2816 "\" href=\"" + rHRef
+ "\">\n");
2821 // escapes a string for html
2822 OUString
HtmlExport::StringToHTMLString( const OUString
& rString
)
2824 SvMemoryStream aMemStm
;
2825 HTMLOutFuncs::Out_String( aMemStm
, rString
, RTL_TEXTENCODING_UTF8
);
2826 aMemStm
.WriteChar( char(0) );
2827 sal_Int32 nLength
= strlen(static_cast<char const *>(aMemStm
.GetData()));
2828 return OUString( static_cast<char const *>(aMemStm
.GetData()), nLength
, RTL_TEXTENCODING_UTF8
);
2831 // creates a url for a specific page
2832 OUString
HtmlExport::CreatePageURL( sal_uInt16 nPgNum
)
2836 return OUString("JavaScript:parent.NavigateAbs(" +
2837 OUString::number(nPgNum
) + ")");
2840 return maHTMLFiles
[nPgNum
];
2843 bool HtmlExport::CopyScript( const OUString
& rPath
, const OUString
& rSource
, const OUString
& rDest
, bool bUnix
/* = false */ )
2845 INetURLObject
aURL( SvtPathOptions().GetConfigPath() );
2846 OUStringBuffer aScriptBuf
;
2848 aURL
.Append( "webcast" );
2849 aURL
.Append( rSource
);
2851 meEC
.SetContext( STR_HTMLEXP_ERROR_OPEN_FILE
, rSource
);
2853 ErrCode nErr
= ERRCODE_NONE
;
2854 std::unique_ptr
<SvStream
> pIStm
= ::utl::UcbStreamHelper::CreateStream( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), StreamMode::READ
);
2860 while( pIStm
->ReadLine( aLine
) )
2862 aScriptBuf
.appendAscii( aLine
.getStr() );
2865 aScriptBuf
.append("\n");
2869 aScriptBuf
.append("\r\n");
2873 nErr
= pIStm
->GetError();
2877 if( nErr
!= ERRCODE_NONE
)
2879 ErrorHandler::HandleError( nErr
);
2880 return static_cast<bool>(nErr
);
2883 OUString
aScript(aScriptBuf
.makeStringAndClear());
2884 aScript
= aScript
.replaceAll("$$1", getDocumentTitle());
2885 aScript
= aScript
.replaceAll("$$2", RESTOHTML(STR_WEBVIEW_SAVE
));
2886 aScript
= aScript
.replaceAll("$$3", maCGIPath
);
2887 aScript
= aScript
.replaceAll("$$4", OUString::number(mnWidthPixel
));
2888 aScript
= aScript
.replaceAll("$$5", OUString::number(mnHeightPixel
));
2890 OUString
aDest(rPath
+ rDest
);
2892 meEC
.SetContext( STR_HTMLEXP_ERROR_CREATE_FILE
, rDest
);
2893 // write script file
2897 nErr
= aFile
.createStream(aDest
, pStr
);
2898 if(nErr
== ERRCODE_NONE
)
2900 OString
aStr(OUStringToOString(aScript
,
2901 RTL_TEXTENCODING_UTF8
));
2902 pStr
->WriteCharPtr( aStr
.getStr() );
2908 mpProgress
->SetState(++mnPagesWritten
);
2910 if( nErr
!= ERRCODE_NONE
)
2911 ErrorHandler::HandleError( nErr
);
2913 return nErr
== ERRCODE_NONE
;
2916 static const char * ASP_Scripts
[] = { "common.inc", "webcast.asp", "show.asp", "savepic.asp", "poll.asp", "editpic.asp" };
2918 /** creates and saves the ASP scripts for WebShow */
2919 bool HtmlExport::CreateASPScripts()
2921 for(const char * p
: ASP_Scripts
)
2923 OUString aScript
= OUString::createFromAscii(p
);
2925 if(!CopyScript(maExportPath
, aScript
, aScript
))
2929 return CopyScript(maExportPath
, "edit.asp", maIndex
);
2932 static const char *PERL_Scripts
[] = { "webcast.pl", "common.pl", "editpic.pl", "poll.pl", "savepic.pl", "show.pl" };
2934 // creates and saves the PERL scripts for WebShow
2935 bool HtmlExport::CreatePERLScripts()
2937 for(const char * p
: PERL_Scripts
)
2939 OUString aScript
= OUString::createFromAscii(p
);
2941 if(!CopyScript(maExportPath
, aScript
, aScript
, true))
2945 if (!CopyScript(maExportPath
, "edit.pl", maIndex
, true))
2948 if (!CopyScript(maExportPath
, "index.pl", maIndexUrl
, true))
2954 // creates a list with names of the saved images
2955 bool HtmlExport::CreateImageFileList()
2957 OUStringBuffer aStr
;
2958 for( sal_uInt16 nSdPage
= 0; nSdPage
< mnSdPageCount
; nSdPage
++)
2960 aStr
.append(OUString::number(nSdPage
+ 1));
2962 aStr
.append(maURLPath
);
2963 aStr
.append(maImageFiles
[nSdPage
]);
2964 aStr
.append("\r\n");
2967 bool bOk
= WriteHtml("picture.txt", false, aStr
.makeStringAndClear());
2970 mpProgress
->SetState(++mnPagesWritten
);
2975 // creates a file with the actual page number
2976 bool HtmlExport::CreateImageNumberFile()
2978 OUString
aFileName("currpic.txt");
2979 OUString
aFull(maExportPath
+ aFileName
);
2981 meEC
.SetContext( STR_HTMLEXP_ERROR_CREATE_FILE
, aFileName
);
2984 ErrCode nErr
= aFile
.createStream(aFull
, pStr
);
2985 if(nErr
== ERRCODE_NONE
)
2987 pStr
->WriteCharPtr( "1" );
2992 mpProgress
->SetState(++mnPagesWritten
);
2994 if( nErr
!= ERRCODE_NONE
)
2995 ErrorHandler::HandleError( nErr
);
2997 return nErr
== ERRCODE_NONE
;
3000 OUString
HtmlExport::InsertSound( const OUString
& rSoundFile
)
3002 if (rSoundFile
.isEmpty())
3005 INetURLObject
aURL( rSoundFile
);
3006 OUString aSoundFileName
= aURL
.getName();
3008 DBG_ASSERT( aURL
.GetProtocol() != INetProtocol::NotValid
, "invalid URL" );
3010 OUString
aStr("<embed src=\"" + aSoundFileName
+
3011 "\" hidden=\"true\" autostart=\"true\">");
3013 CopyFile(rSoundFile
, maExportPath
+ aSoundFileName
);
3018 bool HtmlExport::CopyFile( const OUString
& rSourceFile
, const OUString
& rDestFile
)
3020 meEC
.SetContext( STR_HTMLEXP_ERROR_COPY_FILE
, rSourceFile
, rDestFile
);
3021 osl::FileBase::RC Error
= osl::File::copy( rSourceFile
, rDestFile
);
3023 if( Error
!= osl::FileBase::E_None
)
3025 ErrorHandler::HandleError(ErrCode(Error
));
3034 bool HtmlExport::checkFileExists( Reference
< css::ucb::XSimpleFileAccess3
> const & xFileAccess
, OUString
const & aFileName
)
3038 OUString
url( maExportPath
);
3040 return xFileAccess
->exists( url
);
3042 catch( css::uno::Exception
& )
3044 SAL_WARN( "sd", "sd::HtmlExport::checkFileExists(), exception caught: "
3045 << exceptionToString( cppu::getCaughtException() ) );
3051 bool HtmlExport::checkForExistingFiles()
3053 bool bFound
= false;
3057 Reference
< XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
3058 uno::Reference
<ucb::XSimpleFileAccess3
> xFA(ucb::SimpleFileAccess::create(xContext
));
3061 for( nSdPage
= 0; !bFound
&& (nSdPage
< mnSdPageCount
); nSdPage
++)
3063 if( checkFileExists( xFA
, maImageFiles
[nSdPage
] ) ||
3064 checkFileExists( xFA
, maHTMLFiles
[nSdPage
] ) ||
3065 checkFileExists( xFA
, maThumbnailFiles
[nSdPage
] ) ||
3066 checkFileExists( xFA
, maPageNames
[nSdPage
] ) ||
3067 checkFileExists( xFA
, maTextFiles
[nSdPage
] ) )
3073 if( !bFound
&& mbDownload
)
3074 bFound
= checkFileExists( xFA
, maDocFileName
);
3076 if( !bFound
&& mbFrames
)
3077 bFound
= checkFileExists( xFA
, maFramePage
);
3081 OUString aSystemPath
;
3082 osl::FileBase::getSystemPathFromFileURL( maExportPath
, aSystemPath
);
3083 OUString
aMsg(SdResId(STR_OVERWRITE_WARNING
));
3084 aMsg
= aMsg
.replaceFirst( "%FILENAME", aSystemPath
);
3086 std::unique_ptr
<weld::MessageDialog
> xWarn(Application::CreateMessageDialog(nullptr,
3087 VclMessageType::Warning
, VclButtonsType::YesNo
,
3089 xWarn
->set_default_response(RET_YES
);
3090 bFound
= (RET_NO
== xWarn
->run());
3095 SAL_WARN( "sd", "sd::HtmlExport::checkForExistingFiles(), exception caught: "
3096 << exceptionToString( cppu::getCaughtException() ) );
3103 OUString
HtmlExport::GetButtonName( int nButton
)
3105 return OUString::createFromAscii(pButtonNames
[nButton
]);
3108 EasyFile::EasyFile()
3114 EasyFile::~EasyFile()
3120 ErrCode
EasyFile::createStream( const OUString
& rUrl
, SvStream
* &rpStr
)
3126 createFileName( rUrl
, aFileName
);
3128 ErrCode nErr
= ERRCODE_NONE
;
3129 pOStm
= ::utl::UcbStreamHelper::CreateStream( aFileName
, StreamMode::WRITE
| StreamMode::TRUNC
);
3133 nErr
= pOStm
->GetError();
3137 nErr
= ERRCODE_SFX_CANTCREATECONTENT
;
3140 if( nErr
!= ERRCODE_NONE
)
3146 rpStr
= pOStm
.get();
3151 void EasyFile::createFileName( const OUString
& rURL
, OUString
& rFileName
)
3156 INetURLObject
aURL( rURL
);
3158 if( aURL
.GetProtocol() == INetProtocol::NotValid
)
3161 osl::FileBase::getFileURLFromSystemPath( rURL
, aURLStr
);
3162 aURL
= INetURLObject( aURLStr
);
3164 DBG_ASSERT( aURL
.GetProtocol() != INetProtocol::NotValid
, "invalid URL" );
3165 rFileName
= aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
3168 void EasyFile::close()
3174 // This class helps reporting errors during file i/o
3175 HtmlErrorContext::HtmlErrorContext()
3176 : ErrorContext(nullptr)
3181 bool HtmlErrorContext::GetString( ErrCode
, OUString
& rCtxStr
)
3183 DBG_ASSERT(mpResId
, "No error context set");
3187 rCtxStr
= SdResId(mpResId
);
3189 rCtxStr
= rCtxStr
.replaceAll( "$(URL1)", maURL1
);
3190 rCtxStr
= rCtxStr
.replaceAll( "$(URL2)", maURL2
);
3195 void HtmlErrorContext::SetContext(const char* pResId
, const OUString
& rURL
)
3202 void HtmlErrorContext::SetContext(const char* pResId
, const OUString
& rURL1
, const OUString
& rURL2
)
3209 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */