nss: upgrade to release 3.73
[LibreOffice.git] / sd / source / filter / html / htmlex.cxx
blob7b1efa7e14b5a0324137d2bed36723672d6cd5f4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "htmlex.hxx"
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>
71 #include <sdpage.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[] =
92 "first-inactive.png",
93 "first.png",
94 "left-inactive.png",
95 "left.png",
96 "right-inactive.png",
97 "right.png",
98 "last-inactive.png",
99 "last.png",
100 "home.png",
101 "text.png",
102 "expand.png",
103 "collapse.png",
106 #define BTN_FIRST_0 0
107 #define BTN_FIRST_1 1
108 #define BTN_PREV_0 2
109 #define BTN_PREV_1 3
110 #define BTN_NEXT_0 4
111 #define BTN_NEXT_1 5
112 #define BTN_LAST_0 6
113 #define BTN_LAST_1 7
114 #define BTN_INDEX 8
115 #define BTN_TEXT 9
116 #define BTN_MORE 10
117 #define BTN_LESS 11
119 namespace {
121 // Helper class for the simple creation of files local/remote
122 class EasyFile
124 private:
125 std::unique_ptr<SvStream> pOStm;
126 bool bOpen;
128 public:
130 EasyFile();
131 ~EasyFile();
133 ErrCode createStream( const OUString& rUrl, SvStream*& rpStr );
134 void createFileName( const OUString& rUrl, OUString& rFileName );
135 void close();
140 // Helper class for the embedding of text attributes into the html output
141 class HtmlState
143 private:
144 bool mbColor;
145 bool mbWeight;
146 bool mbItalic;
147 bool mbUnderline;
148 bool mbStrike;
149 bool mbLink;
150 Color maColor;
151 Color maDefColor;
152 OUString maLink;
153 OUString maTarget;
155 public:
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 );
164 OUString Flush();
167 // close all still open tags
168 OUString HtmlState::Flush()
170 OUString aStr = SetWeight(false)
171 + SetItalic(false)
172 + SetUnderline(false)
173 + SetStrikeout(false)
174 + SetColor(maDefColor)
175 + SetLink("","");
177 return aStr;
180 // c'tor with default color for the page
181 HtmlState::HtmlState( Color aDefColor )
182 : mbColor(false),
183 mbWeight(false),
184 mbItalic(false),
185 mbUnderline(false),
186 mbStrike(false),
187 mbLink(false),
188 maDefColor(aDefColor)
192 // enables/disables bold print
193 OUString HtmlState::SetWeight( bool bWeight )
195 OUString aStr;
197 if(bWeight && !mbWeight)
198 aStr = "<b>";
199 else if(!bWeight && mbWeight)
200 aStr = "</b>";
202 mbWeight = bWeight;
203 return aStr;
206 // enables/disables italic
208 OUString HtmlState::SetItalic( bool bItalic )
210 OUString aStr;
212 if(bItalic && !mbItalic)
213 aStr = "<i>";
214 else if(!bItalic && mbItalic)
215 aStr = "</i>";
217 mbItalic = bItalic;
218 return aStr;
221 // enables/disables underlines
223 OUString HtmlState::SetUnderline( bool bUnderline )
225 OUString aStr;
227 if(bUnderline && !mbUnderline)
228 aStr = "<u>";
229 else if(!bUnderline && mbUnderline)
230 aStr = "</u>";
232 mbUnderline = bUnderline;
233 return aStr;
236 // enables/disables strike through
237 OUString HtmlState::SetStrikeout( bool bStrike )
239 OUString aStr;
241 if(bStrike && !mbStrike)
242 aStr = "<strike>";
243 else if(!bStrike && mbStrike)
244 aStr = "</strike>";
246 mbStrike = bStrike;
247 return aStr;
250 // Sets the specified text color
251 OUString HtmlState::SetColor( Color aColor )
253 OUString aStr;
255 if(mbColor && aColor == maColor)
256 return aStr;
258 if(mbColor)
260 aStr = "</font>";
261 mbColor = false;
264 if(aColor != maDefColor)
266 maColor = aColor;
267 aStr += "<font color=\"" + HtmlExport::ColorToHTMLString(aColor) + "\">";
268 mbColor = true;
271 return aStr;
274 // enables/disables a hyperlink
275 OUString HtmlState::SetLink( const OUString& aLink, const OUString& aTarget )
277 OUString aStr;
279 if(mbLink&&maLink == aLink&&maTarget==aTarget)
280 return aStr;
282 if(mbLink)
284 aStr = "</a>";
285 mbLink = false;
288 if (!aLink.isEmpty())
290 aStr += "<a href=\"" + aLink;
291 if (!aTarget.isEmpty())
293 aStr += "\" target=\"" + aTarget;
295 aStr += "\">";
296 mbLink = true;
297 maLink = aLink;
298 maTarget = aTarget;
301 return aStr;
303 namespace
306 OUString getParagraphStyle( SdrOutliner* pOutliner, sal_Int32 nPara )
308 SfxItemSet aParaSet( pOutliner->GetParaAttribs( nPara ) );
310 OUString sStyle;
312 if( aParaSet.GetItem<SvxFrameDirectionItem>( EE_PARA_WRITINGDIR )->GetValue() == SvxFrameDirection::Horizontal_RL_TB )
315 sStyle = "direction: rtl;";
317 else
319 // This is the default so don't write it out
320 // sStyle += "direction: ltr;";
322 return sStyle;
325 void lclAppendStyle(OUStringBuffer& aBuffer, const OUString& aTag, const OUString& aStyle)
327 if (aStyle.isEmpty())
328 aBuffer.append("<").append(aTag).append(">");
329 else
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 )
348 : maPath( aPath ),
349 mpDoc(pExpDoc),
350 mpDocSh( pDocShell ),
351 meEC(),
352 meMode( PUBLISH_SINGLE_DOCUMENT ),
353 mbContentsPage(false),
354 mnButtonThema(-1),
355 mnWidthPixel( PUB_MEDRES_WIDTH ),
356 meFormat( FORMAT_JPG ),
357 mbNotes(false),
358 mnCompression( -1 ),
359 mbDownload( false ),
360 mbSlideSound(true),
361 mbHiddenSlides(true),
362 mbUserAttr(false),
363 maTextColor(COL_BLACK),
364 maBackColor(COL_WHITE),
365 mbDocColors(false),
366 maIndexUrl("index"),
367 meScript( SCRIPT_ASP ),
368 mpButtonSet( new ButtonSet() )
370 bool bChange = mpDoc->IsChanged();
372 maIndexUrl += gaHTMLExtension;
374 InitExportParameters( rParams );
376 switch( meMode )
378 case PUBLISH_HTML:
379 case PUBLISH_FRAMES:
380 ExportHtml();
381 break;
382 case PUBLISH_WEBCAST:
383 ExportWebCast();
384 break;
385 case PUBLISH_KIOSK:
386 ExportKiosk();
387 break;
388 case PUBLISH_SINGLE_DOCUMENT:
389 ExportSingleDocument();
390 break;
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;
405 OUString aStr;
406 for( const PropertyValue& rParam : rParams )
408 if ( rParam.Name == "PublishMode" )
410 sal_Int32 temp = 0;
411 rParam.Value >>= temp;
412 meMode = static_cast<HtmlPublishMode>(temp);
414 else if ( rParam.Name == "IndexURL" )
416 rParam.Value >>= aStr;
417 maIndexUrl = aStr;
419 else if ( rParam.Name == "Format" )
421 sal_Int32 temp = 0;
422 rParam.Value >>= temp;
423 meFormat = static_cast<PublishingFormat>(temp);
425 else if ( rParam.Name == "Compression" )
427 rParam.Value >>= aStr;
428 OUString aTmp( aStr );
429 if(!aTmp.isEmpty())
431 aTmp = aTmp.replaceFirst("%", "");
432 mnCompression = static_cast<sal_Int16>(aTmp.toInt32());
435 else if ( rParam.Name == "Width" )
437 sal_Int32 temp = 0;
438 rParam.Value >>= temp;
439 mnWidthPixel = static_cast<sal_uInt16>(temp);
441 else if ( rParam.Name == "UseButtonSet" )
443 sal_Int32 temp = 0;
444 rParam.Value >>= temp;
445 mnButtonThema = static_cast<sal_Int16>(temp);
447 else if ( rParam.Name == "IsExportNotes" )
449 if( mbImpress )
451 bool temp = false;
452 rParam.Value >>= temp;
453 mbNotes = temp;
456 else if ( rParam.Name == "IsExportContentsPage" )
458 bool temp = false;
459 rParam.Value >>= temp;
460 mbContentsPage = temp;
462 else if ( rParam.Name == "Author" )
464 rParam.Value >>= aStr;
465 maAuthor = aStr;
467 else if ( rParam.Name == "EMail" )
469 rParam.Value >>= aStr;
470 maEMail = aStr;
472 else if ( rParam.Name == "HomepageURL" )
474 rParam.Value >>= aStr;
475 maHomePage = aStr;
477 else if ( rParam.Name == "UserText" )
479 rParam.Value >>= aStr;
480 maInfo = aStr;
482 else if ( rParam.Name == "EnableDownload" )
484 bool temp = false;
485 rParam.Value >>= temp;
486 mbDownload = temp;
488 else if ( rParam.Name == "SlideSound" )
490 bool temp = true;
491 rParam.Value >>= temp;
492 mbSlideSound = temp;
494 else if ( rParam.Name == "HiddenSlides" )
496 bool temp = true;
497 rParam.Value >>= temp;
498 mbHiddenSlides = temp;
500 else if ( rParam.Name == "BackColor" )
502 sal_Int32 temp = 0;
503 rParam.Value >>= temp;
504 maBackColor = Color(temp);
505 mbUserAttr = true;
507 else if ( rParam.Name == "TextColor" )
509 sal_Int32 temp = 0;
510 rParam.Value >>= temp;
511 maTextColor = Color(temp);
512 mbUserAttr = true;
514 else if ( rParam.Name == "LinkColor" )
516 sal_Int32 temp = 0;
517 rParam.Value >>= temp;
518 maLinkColor = Color(temp);
519 mbUserAttr = true;
521 else if ( rParam.Name == "VLinkColor" )
523 sal_Int32 temp = 0;
524 rParam.Value >>= temp;
525 maVLinkColor = Color(temp);
526 mbUserAttr = true;
528 else if ( rParam.Name == "ALinkColor" )
530 sal_Int32 temp = 0;
531 rParam.Value >>= temp;
532 maALinkColor = Color(temp);
533 mbUserAttr = true;
535 else if ( rParam.Name == "IsUseDocumentColors" )
537 bool temp = false;
538 rParam.Value >>= temp;
539 mbDocColors = temp;
541 else if ( rParam.Name == "KioskSlideDuration" )
543 double temp = 0.0;
544 rParam.Value >>= temp;
545 mfSlideDuration = temp;
546 mbAutoSlide = true;
548 else if ( rParam.Name == "KioskEndless" )
550 bool temp = false;
551 rParam.Value >>= temp;
552 mbEndless = temp;
554 else if ( rParam.Name == "WebCastCGIURL" )
556 rParam.Value >>= aStr;
557 maCGIPath = aStr;
559 else if ( rParam.Name == "WebCastTargetURL" )
561 rParam.Value >>= aStr;
562 maURLPath = aStr;
564 else if ( rParam.Name == "WebCastScriptLanguage" )
566 rParam.Value >>= aStr;
567 if ( aStr == "asp" )
569 meScript = SCRIPT_ASP;
571 else
573 meScript = SCRIPT_PERL;
576 else
578 OSL_FAIL("Unknown property for html export detected!");
582 if( meMode == PUBLISH_KIOSK )
584 mbContentsPage = false;
585 mbNotes = 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);
628 mnPagesWritten = 0;
629 InitProgress(mnSdPageCount);
631 OUStringBuffer aStr(gaHTMLHeader);
632 aStr.append(DocumentMetadata());
633 aStr.append("\r\n");
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();
642 if( mbDocColors )
644 SetDocColors( pPage );
647 // page title
648 OUString sTitleText(CreateTextForTitle(pOutliner, pPage, pPage->GetPageBackgroundColor()));
649 OUString sStyle;
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() ));
663 // notes
664 if(mbNotes)
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);
679 if (mpProgress)
680 mpProgress->SetState(++mnPagesWritten);
684 // close page
685 aStr.append("</body>\r\n</html>");
687 WriteHtml(maDocFileName, false, aStr.makeStringAndClear());
689 pOutliner->Clear();
690 ResetProgress();
693 // exports the (in the c'tor specified impress document) to html
694 void HtmlExport::ExportHtml()
696 if(mbUserAttr)
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'
707 SetDocColors();
708 maFirstPageColor = maBackColor;
711 // get name for downloadable presentation if needed
712 if( mbDownload )
714 // fade out separator search and extension
715 sal_Int32 nSepPos = maDocFileName.indexOf('.');
716 if (nSepPos != -1)
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...
733 CreateFileNames();
735 // this is not a true while
736 while( true )
738 if( checkForExistingFiles() )
739 break;
741 if( !CreateImagesForPresPages() )
742 break;
744 if( mbContentsPage &&
745 !CreateImagesForPresPages( true ) )
746 break;
748 if( !CreateHtmlForPresPages() )
749 break;
751 if( mbImpress )
752 if( !CreateHtmlTextForPresPages() )
753 break;
755 if( mbFrames )
757 if( !CreateFrames() )
758 break;
760 if( !CreateOutlinePages() )
761 break;
763 if( !CreateNavBarFrames() )
764 break;
766 if( mbNotes && mbImpress )
767 if( !CreateNotesPages() )
768 break;
772 if( mbContentsPage )
773 if( !CreateContentPage() )
774 break;
776 CreateBitmaps();
778 mpDocSh->SetWaitCursor( false );
779 ResetProgress();
781 if( mbDownload )
782 SavePresentation();
784 return;
787 // if we get to this point the export was
788 // canceled by the user after an error
789 mpDocSh->SetWaitCursor( false );
790 ResetProgress();
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();
819 if(pSheet)
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()
843 mpProgress.reset();
846 void HtmlExport::ExportKiosk()
848 mnPagesWritten = 0;
849 InitProgress( 2*mnSdPageCount );
851 CreateFileNames();
852 if( !checkForExistingFiles() )
854 if( CreateImagesForPresPages() )
855 CreateHtmlForPresPages();
858 ResetProgress();
861 // Export Document with WebCast (TM) Technology
862 void HtmlExport::ExportWebCast()
864 mnPagesWritten = 0;
865 InitProgress( mnSdPageCount + 9 );
867 mpDocSh->SetWaitCursor( true );
869 CreateFileNames();
871 if (maCGIPath.isEmpty())
872 maCGIPath = ".";
874 if (!maCGIPath.endsWith("/"))
875 maCGIPath += "/";
877 if( meScript == SCRIPT_ASP )
879 maURLPath = "./";
881 else
883 if (maURLPath.isEmpty())
884 maURLPath = ".";
886 if (!maURLPath.endsWith("/"))
887 maURLPath += "/";
890 // this is not a true while
891 while(true)
893 if( checkForExistingFiles() )
894 break;
896 if(!CreateImagesForPresPages())
897 break;
899 if( meScript == SCRIPT_ASP )
901 if(!CreateASPScripts())
902 break;
904 else
906 if(!CreatePERLScripts())
907 break;
910 if(!CreateImageFileList())
911 break;
913 if(!CreateImageNumberFile())
914 break;
916 break;
919 mpDocSh->SetWaitCursor( false );
920 ResetProgress();
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 );
935 if( xStorable.is() )
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 );
946 return true;
949 catch( Exception& )
953 mpDocSh->EnableSetModified( false );
955 return 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";
981 OUString sFormat;
982 if( meFormat == FORMAT_PNG )
983 sFormat = "PNG";
984 else if( meFormat == FORMAT_GIF )
985 sFormat = "GIF";
986 else
987 sFormat = "JPG";
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);
998 if (bThumbnail)
999 aFull += maThumbnailFiles[nSdPage];
1000 else
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 );
1009 if (mpProgress)
1010 mpProgress->SetState(++mnPagesWritten);
1013 catch( Exception& )
1015 return false;
1018 return true;
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);
1034 break;
1037 return pResult;
1040 // create HTML text version of impress pages
1041 OUString HtmlExport::CreateMetaCharset()
1043 OUString aStr;
1044 const char *pCharSet = rtl_getBestMimeCharsetFromTextEncoding( RTL_TEXTENCODING_UTF8 );
1045 if ( pCharSet )
1047 aStr = " <meta HTTP-EQUIV=CONTENT-TYPE CONTENT=\"text/html; charset=" +
1048 OUString::createFromAscii(pCharSet) + "\">\r\n";
1050 return aStr;
1053 OUString HtmlExport::DocumentMetadata() const
1055 SvMemoryStream aStream;
1057 uno::Reference<document::XDocumentProperties> xDocProps;
1058 if (mpDocSh)
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()
1080 bool bOk = true;
1082 SdrOutliner* pOutliner = mpDoc->GetInternalOutliner();
1084 for(sal_uInt16 nSdPage = 0; nSdPage < mnSdPageCount && bOk; nSdPage++)
1086 SdPage* pPage = maPages[ nSdPage ];
1088 if( mbDocColors )
1090 SetDocColors( pPage );
1093 // HTML head
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());
1102 // navigation bar
1103 aStr.append(CreateNavBar(nSdPage, true));
1105 // page title
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() ));
1114 // notes
1115 if(mbNotes)
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);
1130 // close page
1131 aStr.append("</body>\r\n</html>");
1133 bOk = WriteHtml(maTextFiles[nSdPage], false, aStr.makeStringAndClear());
1135 if (mpProgress)
1136 mpProgress->SetState(++mnPagesWritten);
1140 pOutliner->Clear();
1142 return bOk;
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 );
1152 if( bAddExtension )
1153 aFileName += gaHTMLExtension;
1155 meEC.SetContext( STR_HTMLEXP_ERROR_CREATE_FILE, rFileName );
1156 EasyFile aFile;
1157 SvStream* pStr;
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 );
1164 aFile.close();
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));
1178 if(!pTO)
1179 pTO = GetLayoutTextObject(pPage);
1181 if (pTO && !pTO->IsEmptyPresObj())
1183 OutlinerParaObject* pOPO = pTO->GetOutlinerParaObject();
1184 if(pOPO && pOutliner->GetParagraphCount() != 0)
1186 pOutliner->Clear();
1187 pOutliner->SetText(*pOPO);
1188 return ParagraphToHTMLString(pOutliner,0, rBackgroundColor);
1192 return OUString();
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);
1206 switch (eKind)
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);
1220 else
1222 if (pObject->GetOutlinerParaObject())
1224 WriteOutlinerParagraph(aStr, pOutliner, pObject->GetOutlinerParaObject(), rBackgroundColor, false);
1228 break;
1230 case PresObjKind::Table:
1232 SdrTableObj* pTableObject = static_cast<SdrTableObj*>(pObject);
1233 WriteTable(aStr, pTableObject, pOutliner, rBackgroundColor);
1235 break;
1237 case PresObjKind::Text:
1238 case PresObjKind::Outline:
1240 SdrTextObj* pTextObject = static_cast<SdrTextObj*>(pObject);
1241 if (pTextObject->IsEmptyPresObj())
1242 continue;
1243 WriteOutlinerParagraph(aStr, pOutliner, pTextObject->GetOutlinerParaObject(), rBackgroundColor, bHeadLine);
1245 break;
1247 default:
1248 break;
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)
1273 continue;
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);
1294 else
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)
1310 return;
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)
1323 continue;
1325 const sal_Int16 nDepth = static_cast<sal_uInt16>(pOutliner->GetDepth(nIndex));
1326 OUString aParaText = ParagraphToHTMLString(pOutliner, nIndex, rBackgroundColor);
1328 if (aParaText.isEmpty())
1329 continue;
1331 if (nDepth < 0)
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");
1339 else
1341 while(nCurrentDepth < nDepth)
1343 aStr.append("<ul>\r\n");
1344 nCurrentDepth++;
1346 while(nCurrentDepth > nDepth)
1348 aStr.append("</ul>\r\n");
1349 nCurrentDepth--;
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");
1359 nCurrentDepth--;
1361 pOutliner->Clear();
1364 // creates an outliner text for a note page
1365 OUString HtmlExport::CreateTextForNotesPage( SdrOutliner* pOutliner,
1366 SdPage* pPage,
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();
1376 if (pOPO)
1378 pOutliner->Clear();
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)
1400 return OUString();
1402 // TODO: MALTE!!!
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)
1409 return OUString();
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);
1427 nPos1 = nPos2;
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
1437 // attributes
1438 OUString HtmlExport::TextAttribToHTMLString( SfxItemSet const * pSet, HtmlState* pState, const Color& rBackgroundColor )
1440 OUStringBuffer aStr;
1442 if(nullptr == pSet)
1443 return OUString();
1445 OUString aLink, aTarget;
1446 if ( pSet->GetItemState( EE_FEATURE_FIELD ) == SfxItemState::SET )
1448 const SvxFieldItem* pItem = pSet->GetItem<SvxFieldItem>( EE_FEATURE_FIELD );
1449 if(pItem)
1451 const SvxURLField* pURL = dynamic_cast<const SvxURLField*>( pItem->GetField() );
1452 if(pURL)
1454 aLink = pURL->GetURL();
1455 aTarget = pURL->GetTargetFrame();
1460 bool bTemp;
1461 OUString aTemp;
1463 if ( pSet->GetItemState( EE_CHAR_WEIGHT ) == SfxItemState::SET )
1465 bTemp = pSet->Get( EE_CHAR_WEIGHT ).GetWeight() == WEIGHT_BOLD;
1466 aTemp = pState->SetWeight( bTemp );
1467 if( bTemp )
1468 aStr.insert(0, aTemp);
1469 else
1470 aStr.append(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 );
1477 if( bTemp )
1478 aStr.insert(0, aTemp);
1479 else
1480 aStr.append(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 );
1487 if( bTemp )
1488 aStr.insert(0, aTemp);
1489 else
1490 aStr.append(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 );
1497 if( bTemp )
1498 aStr.insert(0, aTemp);
1499 else
1500 aStr.append(aTemp);
1503 if(mbDocColors)
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));
1519 else
1520 aStr.append(pState->SetLink(aLink, aTarget));
1522 return aStr.makeStringAndClear();
1525 // create HTML wrapper for picture files
1526 bool HtmlExport::CreateHtmlForPresPages()
1528 bool bOk = true;
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 ];
1539 if( mbDocColors )
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();
1552 while (pObject)
1554 SdAnimationInfo* pInfo = SdDrawDocument::GetAnimationInfo(pObject);
1555 SvxIMapInfo* pIMapInfo = SvxIMapInfo::GetIMapInfo(pObject);
1557 if ((pInfo &&
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)) ||
1564 pIMapInfo)
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()));
1574 else
1575 bMasterDone = true;
1578 // HTML Head
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 )
1587 double fSecs = 0;
1588 bool bEndless = false;
1589 if( !mbAutoSlide )
1591 if( pPage->GetPresChange() != PresChange::Manual )
1593 fSecs = pPage->GetTime();
1594 bEndless = mpDoc->getPresentationSettings().mbEndless;
1597 else
1599 fSecs = mfSlideDuration;
1600 bEndless = mbEndless;
1603 if( fSecs != 0 )
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 )
1613 nPage = 0;
1615 aStr.append(maHTMLFiles[nPage]);
1617 aStr.append("\">\r\n");
1622 aStr.append("</head>\r\n");
1624 // HTML Body
1625 aStr.append(CreateBodyTag());
1627 if( mbSlideSound && pPage->IsSoundOn() )
1628 aStr.append(InsertSound(pPage->GetSoundFile()));
1630 // navigation bar
1631 if(!mbFrames )
1632 aStr.append(CreateNavBar(nSdPage, false));
1633 // Image
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");
1644 // notes
1645 if(mbNotes && !mbFrames)
1647 SdrOutliner* pOutliner = mpDoc->GetInternalOutliner();
1648 SdPage* pNotesPage = maNotesPages[ nSdPage ];
1649 OUString aNotesStr( CreateTextForNotesPage( pOutliner, pNotesPage, maBackColor) );
1650 pOutliner->Clear();
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
1693 such an Imagemap
1695 if (pIMapInfo)
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
1707 bool bIsMasterPage;
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 );
1714 if (pObj)
1715 nPgNum = pObj->getSdrPageFromSdrObject()->GetPageNum();
1717 if (nPgNum != SDRPAGE_NOTFOUND)
1719 nPgNum = (nPgNum - 1) / 2; // SdrPageNum --> SdPageNum
1720 aURL = CreatePageURL(nPgNum);
1723 switch(nType)
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));
1740 break;
1742 case IMapObjectType::Circle:
1744 Point aCenter(static_cast<IMapCircleObject*>(pArea)->
1745 GetCenter(false));
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)->
1752 GetRadius(false);
1753 nCircleRadius = static_cast<sal_uLong>(nCircleRadius * fLogicToPixel);
1754 aStr.append(CreateHTMLCircleArea(nCircleRadius,
1755 aCenter.X(), aCenter.Y(),
1756 aURL));
1758 break;
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));
1768 break;
1770 default:
1772 SAL_INFO("sd", "unknown IMapObjectType");
1774 break;
1780 if there is a presentation::ClickAction, determine bookmark
1781 and create area for the whole object
1783 if( pInfo )
1785 OUString aHRef;
1786 presentation::ClickAction eClickAction = pInfo->meClickAction;
1788 switch( eClickAction )
1790 case presentation::ClickAction_BOOKMARK:
1792 bool bIsMasterPage;
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());
1799 if (pObj)
1800 nPgNum = pObj->getSdrPageFromSdrObject()->GetPageNum();
1803 if( SDRPAGE_NOTFOUND != nPgNum )
1804 aHRef = CreatePageURL(( nPgNum - 1 ) / 2 );
1806 break;
1808 case presentation::ClickAction_DOCUMENT:
1809 aHRef = pInfo->GetBookmark();
1810 break;
1812 case presentation::ClickAction_PREVPAGE:
1814 sal_uLong nPage;
1816 if (nSdPage == 0)
1817 nPage = 0;
1818 else
1819 nPage = nSdPage - 1;
1821 aHRef = CreatePageURL( static_cast<sal_uInt16>(nPage));
1823 break;
1825 case presentation::ClickAction_NEXTPAGE:
1827 sal_uLong nPage;
1828 if (nSdPage == mnSdPageCount - 1)
1829 nPage = mnSdPageCount - 1;
1830 else
1831 nPage = nSdPage + 1;
1833 aHRef = CreatePageURL( static_cast<sal_uInt16>(nPage));
1835 break;
1837 case presentation::ClickAction_FIRSTPAGE:
1838 aHRef = CreatePageURL(0);
1839 break;
1841 case presentation::ClickAction_LASTPAGE:
1842 aHRef = CreatePageURL(mnSdPageCount - 1);
1843 break;
1845 default:
1846 break;
1849 // and now the areas
1850 if (!aHRef.isEmpty())
1852 // a circle?
1853 if (pObject->GetObjInventor() == SdrInventor::Default &&
1854 pObject->GetObjIdentifier() == OBJ_CIRC &&
1855 bIsSquare )
1857 aStr.append(CreateHTMLCircleArea(aRect.GetWidth() / 2,
1858 aRect.Left() + nRadius,
1859 aRect.Top() + nRadius,
1860 aHRef));
1862 // a polygon?
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
1871 else
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());
1888 if (mpProgress)
1889 mpProgress->SetState(++mnPagesWritten);
1892 return bOk;
1895 // create overview pages
1896 bool HtmlExport::CreateContentPage()
1898 if( mbDocColors )
1899 SetDocColors();
1901 // html head
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());
1909 // page head
1910 aStr.append("<center>\r\n");
1912 if(mbHeader)
1914 aStr.append("<h1>");
1915 aStr.append(getDocumentTitle());
1916 aStr.append("</h1><br>\r\n");
1919 aStr.append("<h2>");
1921 // Solaris compiler bug workaround
1922 if( mbFrames )
1923 aStr.append(CreateLink(maFramePage,
1924 RESTOHTML(STR_HTMLEXP_CLICKSTART)));
1925 else
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");
1933 // table of content
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\">");
1943 if(mbFrames)
1944 aStr.append(StringToHTMLString(aPageName));
1945 else
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);
1969 aStr.append("\">");
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);
1980 aStr.append("\">");
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");
1994 if(mbDownload)
1996 aStr.append("<p><a href=\"");
1997 aStr.append(maDocFileName);
1998 aStr.append("\">");
1999 aStr.append(RESTOHTML(STR_HTMLEXP_DOWNLOAD));
2000 aStr.append("</a></p>\r\n");
2003 for(sal_uInt16 nSdPage = 0; nSdPage < mnSdPageCount; nSdPage++)
2005 OUString aText(
2006 "<img src=\"" +
2007 maThumbnailFiles[nSdPage] +
2008 "\" width=\"256\" height=\"192\" alt=\"" +
2009 StringToHTMLString(maPageNames[nSdPage]) +
2010 "\">");
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());
2022 if (mpProgress)
2023 mpProgress->SetState(++mnPagesWritten);
2025 return bOk;
2028 // create note pages (for frames)
2030 bool HtmlExport::CreateNotesPages()
2032 bool bOk = true;
2034 SdrOutliner* pOutliner = mpDoc->GetInternalOutliner();
2035 for( sal_uInt16 nSdPage = 0; bOk && nSdPage < mnSdPageCount; nSdPage++ )
2037 SdPage* pPage = maNotesPages[nSdPage];
2038 if( mbDocColors )
2039 SetDocColors( pPage );
2041 // Html head
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());
2049 if(pPage)
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());
2057 if (mpProgress)
2058 mpProgress->SetState(++mnPagesWritten);
2061 pOutliner->Clear();
2063 return bOk;
2066 // create outline pages (for frames)
2068 bool HtmlExport::CreateOutlinePages()
2070 bool bOk = true;
2072 if( mbDocColors )
2074 SetDocColors();
2077 // page 0 will be the closed outline, page 1 the opened
2078 for (sal_Int32 nPage = 0; nPage < (mbImpress?2:1) && bOk; ++nPage)
2080 // Html head
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>");
2105 if(nPage==1)
2107 aStr.append(CreateTextForPage( pOutliner, pPage, false, maBackColor ));
2109 aStr.append("</div>\r\n");
2111 pOutliner->Clear();
2113 aStr.append("</body>\r\n</html>");
2115 OUString aFileName("outline" + OUString::number(nPage));
2116 bOk = WriteHtml(aFileName, true, aStr.makeStringAndClear());
2118 if (mpProgress)
2119 mpProgress->SetState(++mnPagesWritten);
2122 return bOk;
2125 // set file name
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;
2142 else
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";
2154 else
2155 aImageFileName += ".png";
2157 maImageFiles[nSdPage] = aImageFileName;
2159 OUString aThumbnailFileName = "thumb" + OUString::number(nSdPage);
2160 if( meFormat!=FORMAT_JPG )
2161 aThumbnailFileName += ".png";
2162 else
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;
2177 else
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
2187 // page
2188 if( !mbHeader )
2190 if(mbImpress)
2192 // if there is a non-empty title object, use their first passage
2193 // as page title
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();
2199 if (pParaObject)
2201 const EditTextObject& rEditTextObject =
2202 pParaObject->GetTextObject();
2203 OUString aTest(rEditTextObject.GetText(0));
2204 if (!aTest.isEmpty())
2205 mDocTitle = aTest;
2209 mDocTitle = mDocTitle.replace(0xff, ' ');
2212 if (mDocTitle.isEmpty())
2214 mDocTitle = maDocFileName;
2215 sal_Int32 nDot = mDocTitle.indexOf('.');
2216 if (nDot > 0)
2217 mDocTitle = mDocTitle.copy(0, nDot);
2219 mbHeader = true;
2222 return mDocTitle;
2225 const char JS_NavigateAbs[] =
2226 "function NavigateAbs( nPage )\r\n"
2227 "{\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"
2232 " {\r\n"
2233 " frames[\"navbar1\"].location.href = \"navbar0.$EXT\";\r\n"
2234 " }\r\n"
2235 " else if(nCurrentPage==nPageCount-1)\r\n"
2236 " {\r\n"
2237 " frames[\"navbar1\"].location.href = \"navbar2.$EXT\";\r\n"
2238 " }\r\n"
2239 " else\r\n"
2240 " {\r\n"
2241 " frames[\"navbar1\"].location.href = \"navbar1.$EXT\";\r\n"
2242 " }\r\n"
2243 "}\r\n\r\n";
2245 const char JS_NavigateRel[] =
2246 "function NavigateRel( nDelta )\r\n"
2247 "{\r\n"
2248 " var nPage = parseInt(nCurrentPage) + parseInt(nDelta);\r\n"
2249 " if( (nPage >= 0) && (nPage < nPageCount) )\r\n"
2250 " {\r\n"
2251 " NavigateAbs( nPage );\r\n"
2252 " }\r\n"
2253 "}\r\n\r\n";
2255 const char JS_ExpandOutline[] =
2256 "function ExpandOutline()\r\n"
2257 "{\r\n"
2258 " frames[\"navbar2\"].location.href = \"navbar4.$EXT\";\r\n"
2259 " frames[\"outline\"].location.href = \"outline1.$EXT\";\r\n"
2260 "}\r\n\r\n";
2262 const char JS_CollapseOutline[] =
2263 "function CollapseOutline()\r\n"
2264 "{\r\n"
2265 " frames[\"navbar2\"].location.href = \"navbar3.$EXT\";\r\n"
2266 " frames[\"outline\"].location.href = \"outline0.$EXT\";\r\n"
2267 "}\r\n\r\n";
2269 // create page with the frames
2271 bool HtmlExport::CreateFrames()
2273 OUString aTmp;
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;
2292 if(mbNotes)
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);
2304 aStr.append(aTmp);
2306 if(mbImpress)
2308 aTmp = JS_ExpandOutline;
2309 aTmp = aTmp.replaceAll(aPlaceHolder, gaHTMLExtension);
2310 aStr.append(aTmp);
2312 aTmp = JS_CollapseOutline;
2313 aTmp = aTmp.replaceAll(aPlaceHolder, gaHTMLExtension);
2314 aStr.append(aTmp);
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");
2323 if(mbImpress)
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");
2333 if(mbImpress)
2334 aStr.append(" </frameset>\r\n");
2336 if(mbNotes)
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");
2342 else
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");
2353 if(mbNotes)
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());
2368 if (mpProgress)
2369 mpProgress->SetState(++mnPagesWritten);
2371 return bOk;
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()
2383 bool bOk = true;
2384 OUString aButton;
2386 if( mbDocColors )
2388 SetDocColors();
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");
2402 // first page
2403 aButton = SdResId(STR_HTMLEXP_FIRSTPAGE);
2404 if(mnButtonThema != -1)
2405 aButton = CreateImage(GetButtonName(nFile == 0 || mnSdPageCount == 1 ? BTN_FIRST_0 : BTN_FIRST_1),
2406 aButton);
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),
2419 aButton);
2421 if(nFile != 0 && mnSdPageCount > 1)
2422 aButton = CreateLink("JavaScript:parent.NavigateRel(-1)", aButton);
2424 aStr.append(aButton);
2425 aStr.append("\r\n");
2427 // to the next page
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),
2432 aButton);
2434 if(nFile != 2 && mnSdPageCount > 1)
2435 aButton = CreateLink("JavaScript:parent.NavigateRel(1)", aButton);
2437 aStr.append(aButton);
2438 aStr.append("\r\n");
2440 // to the last page
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),
2445 aButton);
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");
2458 // content
2459 if (mbContentsPage)
2461 aButton = SdResId(STR_PUBLISH_OUTLINE);
2462 if(mnButtonThema != -1)
2463 aButton = CreateImage(GetButtonName(BTN_INDEX), aButton);
2465 // to the overview
2466 aStr.append(CreateLink(maIndex, aButton, "_top"));
2467 aStr.append("\r\n");
2470 // text mode
2471 if(mbImpress)
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");
2482 // and finished...
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());
2490 if (mpProgress)
2491 mpProgress->SetState(++mnPagesWritten);
2494 // the navigation bar outliner closed...
2495 if(bOk)
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());
2513 if (mpProgress)
2514 mpProgress->SetState(++mnPagesWritten);
2517 // ... and the outliner open
2518 if( bOk )
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());
2536 if (mpProgress)
2537 mpProgress->SetState(++mnPagesWritten);
2541 return bOk;
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;
2554 if( bIsText )
2556 aStrNavText = SdResId(STR_HTMLEXP_SETGRAPHIC);
2558 else
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);
2570 else
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);
2581 else
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");
2593 // first page
2594 if(nSdPage > 0)
2595 aStr.append(CreateLink( bIsText ? maTextFiles[0] : maHTMLFiles[0],aStrNavFirst));
2596 else
2597 aStr.append(aStrNavFirst);
2598 aStr.append(' ');
2600 // to Previous page
2601 if(nSdPage > 0)
2602 aStr.append(CreateLink( bIsText ? maTextFiles[nSdPage-1]
2603 : maHTMLFiles[nSdPage-1], aStrNavPrev));
2604 else
2605 aStr.append(aStrNavPrev);
2606 aStr.append(' ');
2608 // to Next page
2609 if(nSdPage < mnSdPageCount-1)
2610 aStr.append(CreateLink( bIsText ? maTextFiles[nSdPage+1]
2611 : maHTMLFiles[nSdPage+1], aStrNavNext));
2612 else
2613 aStr.append(aStrNavNext);
2614 aStr.append(' ');
2616 // to Last page
2617 if(nSdPage < mnSdPageCount-1)
2618 aStr.append(CreateLink( bIsText ? maTextFiles[mnSdPageCount-1]
2619 : maHTMLFiles[mnSdPageCount-1],
2620 aStrNavLast));
2621 else
2622 aStr.append(aStrNavLast);
2623 aStr.append(' ');
2625 // to Index page
2626 if (mbContentsPage)
2628 aStr.append(CreateLink(maIndex, aStrNavContent));
2629 aStr.append(' ');
2632 // Text/Graphics
2633 if(mbImpress)
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)
2649 return;
2651 for( int nButton = 0; nButton != SAL_N_ELEMENTS(pButtonNames); nButton++ )
2653 if(!mbFrames && (nButton == BTN_MORE || nButton == BTN_LESS))
2654 continue;
2656 if(!mbImpress && (nButton == BTN_TEXT || nButton == BTN_MORE || nButton == BTN_LESS ))
2657 continue;
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 ));
2685 aStr.append("\"");
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=\"" );
2699 aStr.append(aLink);
2700 if (!aTarget.isEmpty())
2702 aStr.append("\" target=\"");
2703 aStr.append(aTarget);
2705 aStr.append("\">");
2706 aStr.append(aText);
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);
2723 aStr.append('"');
2725 else
2727 // Agerskov: HTML 4.01 has to have an alt attribute even if it is an empty string
2728 aStr.append(" alt=\"\"");
2731 aStr.append('>');
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,
2753 sal_uLong nCenterX,
2754 sal_uLong nCenterY,
2755 const OUString& rHRef )
2757 OUString aStr(
2758 "<area shape=\"circle\" alt=\"\" coords=\"" +
2759 OUString::number(nCenterX) + "," +
2760 OUString::number(nCenterY) + "," +
2761 OUString::number(nRadius) +
2762 "\" href=\"" + rHRef + "\">\n");
2764 return aStr;
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)
2794 aStr.append(',');
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 )
2806 OUString aStr(
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");
2814 return aStr;
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 )
2830 if(mbFrames)
2832 return OUString("JavaScript:parent.NavigateAbs(" +
2833 OUString::number(nPgNum) + ")");
2835 else
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 );
2852 if( pIStm )
2854 OString aLine;
2856 while( pIStm->ReadLine( aLine ) )
2858 aScriptBuf.appendAscii( aLine.getStr() );
2859 if( bUnix )
2861 aScriptBuf.append("\n");
2863 else
2865 aScriptBuf.append("\r\n");
2869 nErr = pIStm->GetError();
2870 pIStm.reset();
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
2891 EasyFile aFile;
2892 SvStream* pStr;
2893 nErr = aFile.createStream(aDest, pStr);
2894 if(nErr == ERRCODE_NONE)
2896 OString aStr(OUStringToOString(aScript, RTL_TEXTENCODING_UTF8));
2897 pStr->WriteOString( aStr );
2898 aFile.close();
2902 if (mpProgress)
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))
2921 return false;
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))
2937 return false;
2940 if (!CopyScript(maExportPath, "edit.pl", maIndex, true))
2941 return false;
2943 if (!CopyScript(maExportPath, "index.pl", maIndexUrl, true))
2944 return false;
2946 return 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));
2956 aStr.append(';');
2957 aStr.append(maURLPath);
2958 aStr.append(maImageFiles[nSdPage]);
2959 aStr.append("\r\n");
2962 bool bOk = WriteHtml("picture.txt", false, aStr.makeStringAndClear());
2964 if (mpProgress)
2965 mpProgress->SetState(++mnPagesWritten);
2967 return bOk;
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 );
2977 EasyFile aFile;
2978 SvStream* pStr;
2979 ErrCode nErr = aFile.createStream(aFull, pStr);
2980 if(nErr == ERRCODE_NONE)
2982 pStr->WriteCharPtr( "1" );
2983 aFile.close();
2986 if (mpProgress)
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())
2998 return rSoundFile;
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);
3010 return aStr;
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));
3021 return false;
3023 else
3025 return true;
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()" );
3041 return false;
3044 bool HtmlExport::checkForExistingFiles()
3046 bool bFound = false;
3050 Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
3051 uno::Reference<ucb::XSimpleFileAccess3> xFA(ucb::SimpleFileAccess::create(xContext));
3053 sal_uInt16 nSdPage;
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] ) )
3062 bFound = true;
3066 if( !bFound && mbDownload )
3067 bFound = checkFileExists( xFA, maDocFileName );
3069 if( !bFound && mbFrames )
3070 bFound = checkFileExists( xFA, maFramePage );
3072 if( bFound )
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,
3081 aMsg));
3082 xWarn->set_default_response(RET_YES);
3083 bFound = (RET_NO == xWarn->run());
3086 catch( Exception& )
3088 TOOLS_WARN_EXCEPTION( "sd", "sd::HtmlExport::checkForExistingFiles()" );
3089 bFound = false;
3092 return bFound;
3095 OUString HtmlExport::GetButtonName( int nButton )
3097 return OUString::createFromAscii(pButtonNames[nButton]);
3100 EasyFile::EasyFile() : bOpen(false)
3104 EasyFile::~EasyFile()
3106 if( bOpen )
3107 close();
3110 ErrCode EasyFile::createStream( const OUString& rUrl, SvStream* &rpStr )
3112 if(bOpen)
3113 close();
3115 OUString aFileName;
3116 createFileName( rUrl, aFileName );
3118 ErrCode nErr = ERRCODE_NONE;
3119 pOStm = ::utl::UcbStreamHelper::CreateStream( aFileName, StreamMode::WRITE | StreamMode::TRUNC );
3120 if( pOStm )
3122 bOpen = true;
3123 nErr = pOStm->GetError();
3125 else
3127 nErr = ERRCODE_SFX_CANTCREATECONTENT;
3130 if( nErr != ERRCODE_NONE )
3132 bOpen = false;
3133 pOStm.reset();
3136 rpStr = pOStm.get();
3138 return nErr;
3141 void EasyFile::createFileName( const OUString& rURL, OUString& rFileName )
3143 if( bOpen )
3144 close();
3146 INetURLObject aURL( rURL );
3148 if( aURL.GetProtocol() == INetProtocol::NotValid )
3150 OUString aURLStr;
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()
3160 pOStm.reset();
3161 bOpen = false;
3164 // This class helps reporting errors during file i/o
3165 HtmlErrorContext::HtmlErrorContext()
3166 : ErrorContext(nullptr)
3167 , mpResId(nullptr)
3171 bool HtmlErrorContext::GetString( ErrCode, OUString& rCtxStr )
3173 DBG_ASSERT(mpResId, "No error context set");
3174 if (!mpResId)
3175 return false;
3177 rCtxStr = SdResId(mpResId);
3179 rCtxStr = rCtxStr.replaceAll( "$(URL1)", maURL1 );
3180 rCtxStr = rCtxStr.replaceAll( "$(URL2)", maURL2 );
3182 return true;
3185 void HtmlErrorContext::SetContext(const char* pResId, const OUString& rURL)
3187 mpResId = pResId;
3188 maURL1 = rURL;
3189 maURL2.clear();
3192 void HtmlErrorContext::SetContext(const char* pResId, const OUString& rURL1, const OUString& rURL2 )
3194 mpResId = pResId;
3195 maURL1 = rURL1;
3196 maURL2 = rURL2;
3199 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */