bump product version to 5.0.4.1
[LibreOffice.git] / sd / source / filter / html / htmlex.cxx
blob1987b0589c11ee9b5acfdc9f836c2eece24d3e33
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/document/XExporter.hpp>
23 #include <com/sun/star/document/XFilter.hpp>
24 #include <com/sun/star/drawing/GraphicExportFilter.hpp>
25 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
27 #include <rtl/uri.hxx>
28 #include <comphelper/processfactory.hxx>
29 #include <osl/file.hxx>
30 #include <unotools/pathoptions.hxx>
31 #include <vcl/FilterConfigItem.hxx>
32 #include <unotools/ucbstreamhelper.hxx>
33 #include <unotools/localfilehelper.hxx>
34 #include <com/sun/star/frame/XStorable.hpp>
35 #include <sfx2/app.hxx>
36 #include <sfx2/dispatch.hxx>
37 #include <sfx2/docfile.hxx>
38 #include <sfx2/fcontnr.hxx>
39 #include <sfx2/frmhtmlw.hxx>
40 #include <sfx2/progress.hxx>
41 #include <vcl/wrkwin.hxx>
42 #include <svl/aeitem.hxx>
43 #include <svx/svditer.hxx>
44 #include <svtools/imaprect.hxx>
45 #include <svtools/imapcirc.hxx>
46 #include <svtools/imappoly.hxx>
47 #include <vcl/msgbox.hxx>
48 #include <editeng/outlobj.hxx>
49 #include <editeng/editobj.hxx>
50 #include <svx/svdopath.hxx>
51 #include <svx/xoutbmp.hxx>
52 #include <svtools/htmlout.hxx>
53 #include <vcl/cvtgrf.hxx>
54 #include <svtools/colorcfg.hxx>
55 #include <vcl/graphicfilter.hxx>
56 #include <editeng/colritem.hxx>
57 #include <editeng/editeng.hxx>
58 #include <editeng/wghtitem.hxx>
59 #include <editeng/udlnitem.hxx>
60 #include <editeng/postitem.hxx>
61 #include <editeng/crossedoutitem.hxx>
62 #include <editeng/flditem.hxx>
63 #include <svl/style.hxx>
64 #include <editeng/frmdiritem.hxx>
65 #include <svx/svdoutl.hxx>
66 #include <svx/svdogrp.hxx>
67 #include <svx/svdotable.hxx>
68 #include <tools/urlobj.hxx>
69 #include <vcl/bmpacc.hxx>
70 #include <svtools/sfxecode.hxx>
71 #include <com/sun/star/beans/PropertyState.hpp>
72 #include <tools/resmgr.hxx>
73 #include <comphelper/anytostring.hxx>
74 #include <cppuhelper/exc_hlp.hxx>
75 #include <basegfx/polygon/b2dpolygon.hxx>
77 #include "drawdoc.hxx"
78 #include "htmlpublishmode.hxx"
79 #include "Outliner.hxx"
80 #include "sdpage.hxx"
81 #include "sdattr.hxx"
82 #include "glob.hrc"
83 #include "anminfo.hxx"
84 #include "imapinfo.hxx"
85 #include "sdresid.hxx"
86 #include "buttonset.hxx"
88 using namespace ::com::sun::star;
89 using namespace ::com::sun::star::uno;
90 using namespace ::com::sun::star::beans;
91 using namespace ::com::sun::star::frame;
92 using namespace ::com::sun::star::lang;
93 using namespace ::com::sun::star::document;
95 using namespace sdr::table;
97 // get parameter from Itemset
98 #define RESTOHTML( res ) StringToHTMLString(SD_RESSTR(res))
100 const char *pButtonNames[] =
102 "first-inactive.png",
103 "first.png",
104 "left-inactive.png",
105 "left.png",
106 "right-inactive.png",
107 "right.png",
108 "last-inactive.png",
109 "last.png",
110 "home.png",
111 "text.png",
112 "expand.png",
113 "collapse.png",
116 #define BTN_FIRST_0 0
117 #define BTN_FIRST_1 1
118 #define BTN_PREV_0 2
119 #define BTN_PREV_1 3
120 #define BTN_NEXT_0 4
121 #define BTN_NEXT_1 5
122 #define BTN_LAST_0 6
123 #define BTN_LAST_1 7
124 #define BTN_INDEX 8
125 #define BTN_TEXT 9
126 #define BTN_MORE 10
127 #define BTN_LESS 11
129 // Helper class for the simple creation of files local/remote
130 class EasyFile
132 private:
133 SvStream* pOStm;
134 SfxMedium* pMedium;
135 bool bOpen;
137 public:
139 EasyFile();
140 ~EasyFile();
142 sal_uLong createStream( const OUString& rUrl, SvStream*& rpStr );
143 sal_uLong createFileName( const OUString& rUrl, OUString& rFileName );
144 sal_uLong close();
147 // Helper class for the embedding of text attributes into the html output
148 class HtmlState
150 private:
151 bool mbColor;
152 bool mbWeight;
153 bool mbItalic;
154 bool mbUnderline;
155 bool mbStrike;
156 bool mbLink;
157 Color maColor;
158 Color maDefColor;
159 OUString maLink;
160 OUString maTarget;
162 public:
163 HtmlState( Color aDefColor );
165 OUString SetWeight( bool bWeight );
166 OUString SetItalic( bool bItalic );
167 OUString SetUnderline( bool bUnderline );
168 OUString SetColor( Color aColor );
169 OUString SetStrikeout( bool bStrike );
170 OUString SetLink( const OUString& aLink, const OUString& aTarget );
171 OUString Flush();
174 // close all still open tags
175 OUString HtmlState::Flush()
177 OUString aStr;
179 aStr += SetWeight(false);
180 aStr += SetItalic(false);
181 aStr += SetUnderline(false);
182 aStr += SetStrikeout(false);
183 aStr += SetColor(maDefColor);
184 aStr += SetLink("","");
186 return aStr;
189 // c'tor with default color for the page
190 HtmlState::HtmlState( Color aDefColor )
192 mbColor = false;
193 mbWeight = false;
194 mbItalic = false;
195 mbUnderline = false;
196 mbLink = false;
197 mbStrike = false;
198 maDefColor = aDefColor;
201 // enables/disables bold print
202 OUString HtmlState::SetWeight( bool bWeight )
204 OUString aStr;
206 if(bWeight && !mbWeight)
207 aStr = "<b>";
208 else if(!bWeight && mbWeight)
209 aStr = "</b>";
211 mbWeight = bWeight;
212 return aStr;
215 // enables/disables italic
217 OUString HtmlState::SetItalic( bool bItalic )
219 OUString aStr;
221 if(bItalic && !mbItalic)
222 aStr = "<i>";
223 else if(!bItalic && mbItalic)
224 aStr = "</i>";
226 mbItalic = bItalic;
227 return aStr;
230 // enables/disables underlines
232 OUString HtmlState::SetUnderline( bool bUnderline )
234 OUString aStr;
236 if(bUnderline && !mbUnderline)
237 aStr = "<u>";
238 else if(!bUnderline && mbUnderline)
239 aStr = "</u>";
241 mbUnderline = bUnderline;
242 return aStr;
245 // enables/disables strike through
246 OUString HtmlState::SetStrikeout( bool bStrike )
248 OUString aStr;
250 if(bStrike && !mbStrike)
251 aStr = "<strike>";
252 else if(!bStrike && mbStrike)
253 aStr = "</strike>";
255 mbStrike = bStrike;
256 return aStr;
259 // Sets the specified text color
260 OUString HtmlState::SetColor( Color aColor )
262 OUString aStr;
264 if(mbColor && aColor == maColor)
265 return aStr;
267 if(mbColor)
269 aStr = "</font>";
270 mbColor = false;
273 if(aColor != maDefColor)
275 maColor = aColor;
276 aStr += "<font color=\"" + HtmlExport::ColorToHTMLString(aColor) + "\">";
277 mbColor = true;
280 return aStr;
283 // enables/disables a hyperlink
284 OUString HtmlState::SetLink( const OUString& aLink, const OUString& aTarget )
286 OUString aStr;
288 if(mbLink&&maLink == aLink&&maTarget==aTarget)
289 return aStr;
291 if(mbLink)
293 aStr = "</a>";
294 mbLink = false;
297 if (!aLink.isEmpty())
299 aStr += "<a href=\"" + aLink;
300 if (!aTarget.isEmpty())
302 aStr += "\" target=\"" + aTarget;
304 aStr += "\">";
305 mbLink = true;
306 maLink = aLink;
307 maTarget = aTarget;
310 return aStr;
312 namespace
315 OUString getParagraphStyle( SdrOutliner* pOutliner, sal_Int32 nPara )
317 SfxItemSet aParaSet( pOutliner->GetParaAttribs( nPara ) );
319 OUString sStyle;
321 if( static_cast<const SvxFrameDirectionItem*>(aParaSet.GetItem( EE_PARA_WRITINGDIR ))->GetValue() == FRMDIR_HORI_RIGHT_TOP )
324 sStyle = "direction: rtl;";
326 else
328 // This is the default so don't write it out
329 // sStyle += "direction: ltr;";
331 return sStyle;
334 void lclAppendStyle(OUStringBuffer& aBuffer, const OUString& aTag, const OUString& aStyle)
336 if (aStyle.isEmpty())
337 aBuffer.append("<" + aTag + ">");
338 else
339 aBuffer.append("<" + aTag + " style=\"" + aStyle + "\">");
342 } // anonymous namespace
344 // constructor for the html export helper classes
345 HtmlExport::HtmlExport(
346 const OUString& aPath,
347 const Sequence< PropertyValue >& rParams,
348 SdDrawDocument* pExpDoc,
349 sd::DrawDocShell* pDocShell )
350 : maPath( aPath ),
351 mpDoc(pExpDoc),
352 mpDocSh( pDocShell ),
353 meEC(NULL),
354 meMode( PUBLISH_SINGLE_DOCUMENT ),
355 mbContentsPage(false),
356 mnButtonThema(-1),
357 mnWidthPixel( PUB_MEDRES_WIDTH ),
358 meFormat( FORMAT_JPG ),
359 mbNotes(false),
360 mnCompression( -1 ),
361 mbDownload( false ),
362 mbSlideSound(true),
363 mbHiddenSlides(true),
364 mbUserAttr(false),
365 maTextColor(COL_BLACK),
366 maBackColor(COL_WHITE),
367 mbDocColors(false),
368 maHTMLExtension(SdResId(STR_HTMLEXP_DEFAULT_EXTENSION)),
369 maIndexUrl("index"),
370 meScript( SCRIPT_ASP ),
371 maHTMLHeader(
372 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n"
373 " \"http://www.w3.org/TR/html4/transitional.dtd\">\r\n"
374 "<html>\r\n<head>\r\n" ),
375 mpButtonSet( new ButtonSet() )
377 bool bChange = mpDoc->IsChanged();
379 maIndexUrl += maHTMLExtension;
381 InitExportParameters( rParams );
383 switch( meMode )
385 case PUBLISH_HTML:
386 case PUBLISH_FRAMES:
387 ExportHtml();
388 break;
389 case PUBLISH_WEBCAST:
390 ExportWebCast();
391 break;
392 case PUBLISH_KIOSK:
393 ExportKiosk();
394 break;
395 case PUBLISH_SINGLE_DOCUMENT:
396 ExportSingleDocument();
397 break;
400 mpDoc->SetChanged(bChange);
403 HtmlExport::~HtmlExport()
407 // get common export parameters from item set
408 void HtmlExport::InitExportParameters( const Sequence< PropertyValue >& rParams )
410 mbImpress = mpDoc->GetDocumentType() == DOCUMENT_TYPE_IMPRESS;
412 sal_Int32 nArgs = rParams.getLength();
413 const PropertyValue* pParams = rParams.getConstArray();
414 OUString aStr;
415 while( nArgs-- )
417 if ( pParams->Name == "PublishMode" )
419 sal_Int32 temp = 0;
420 pParams->Value >>= temp;
421 meMode = (HtmlPublishMode)temp;
423 else if ( pParams->Name == "IndexURL" )
425 pParams->Value >>= aStr;
426 maIndexUrl = aStr;
428 else if ( pParams->Name == "Format" )
430 sal_Int32 temp = 0;
431 pParams->Value >>= temp;
432 meFormat = (PublishingFormat)temp;
434 else if ( pParams->Name == "Compression" )
436 pParams->Value >>= aStr;
437 OUString aTmp( aStr );
438 if(!aTmp.isEmpty())
440 aTmp = aTmp.replaceFirst("%", "");
441 mnCompression = (sal_Int16)aTmp.toInt32();
444 else if ( pParams->Name == "Width" )
446 sal_Int32 temp = 0;
447 pParams->Value >>= temp;
448 mnWidthPixel = (sal_uInt16)temp;
450 else if ( pParams->Name == "UseButtonSet" )
452 sal_Int32 temp = 0;
453 pParams->Value >>= temp;
454 mnButtonThema = (sal_Int16)temp;
456 else if ( pParams->Name == "IsExportNotes" )
458 if( mbImpress )
460 bool temp = false;
461 pParams->Value >>= temp;
462 mbNotes = temp;
465 else if ( pParams->Name == "IsExportContentsPage" )
467 bool temp = false;
468 pParams->Value >>= temp;
469 mbContentsPage = temp;
471 else if ( pParams->Name == "Author" )
473 pParams->Value >>= aStr;
474 maAuthor = aStr;
476 else if ( pParams->Name == "EMail" )
478 pParams->Value >>= aStr;
479 maEMail = aStr;
481 else if ( pParams->Name == "HomepageURL" )
483 pParams->Value >>= aStr;
484 maHomePage = aStr;
486 else if ( pParams->Name == "UserText" )
488 pParams->Value >>= aStr;
489 maInfo = aStr;
491 else if ( pParams->Name == "EnableDownload" )
493 bool temp = false;
494 pParams->Value >>= temp;
495 mbDownload = temp;
497 else if ( pParams->Name == "SlideSound" )
499 bool temp = true;
500 pParams->Value >>= temp;
501 mbSlideSound = temp;
503 else if ( pParams->Name == "HiddenSlides" )
505 bool temp = true;
506 pParams->Value >>= temp;
507 mbHiddenSlides = temp;
509 else if ( pParams->Name == "BackColor" )
511 sal_Int32 temp = 0;
512 pParams->Value >>= temp;
513 maBackColor = temp;
514 mbUserAttr = true;
516 else if ( pParams->Name == "TextColor" )
518 sal_Int32 temp = 0;
519 pParams->Value >>= temp;
520 maTextColor = temp;
521 mbUserAttr = true;
523 else if ( pParams->Name == "LinkColor" )
525 sal_Int32 temp = 0;
526 pParams->Value >>= temp;
527 maLinkColor = temp;
528 mbUserAttr = true;
530 else if ( pParams->Name == "VLinkColor" )
532 sal_Int32 temp = 0;
533 pParams->Value >>= temp;
534 maVLinkColor = temp;
535 mbUserAttr = true;
537 else if ( pParams->Name == "ALinkColor" )
539 sal_Int32 temp = 0;
540 pParams->Value >>= temp;
541 maALinkColor = temp;
542 mbUserAttr = true;
544 else if ( pParams->Name == "IsUseDocumentColors" )
546 bool temp = false;
547 pParams->Value >>= temp;
548 mbDocColors = temp;
550 else if ( pParams->Name == "KioskSlideDuration" )
552 double temp = 0.0;
553 pParams->Value >>= temp;
554 mfSlideDuration = temp;
555 mbAutoSlide = true;
557 else if ( pParams->Name == "KioskEndless" )
559 bool temp = false;
560 pParams->Value >>= temp;
561 mbEndless = temp;
563 else if ( pParams->Name == "WebCastCGIURL" )
565 pParams->Value >>= aStr;
566 maCGIPath = aStr;
568 else if ( pParams->Name == "WebCastTargetURL" )
570 pParams->Value >>= aStr;
571 maURLPath = aStr;
573 else if ( pParams->Name == "WebCastScriptLanguage" )
575 pParams->Value >>= aStr;
576 if ( aStr == "asp" )
578 meScript = SCRIPT_ASP;
580 else
582 meScript = SCRIPT_PERL;
585 else
587 OSL_FAIL("Unknown property for html export detected!");
590 pParams++;
593 if( meMode == PUBLISH_KIOSK )
595 mbContentsPage = false;
596 mbNotes = false;
600 // calculate image sizes
601 SdPage* pPage = mpDoc->GetSdPage(0, PK_STANDARD);
602 Size aTmpSize( pPage->GetSize() );
603 double dRatio=((double)aTmpSize.Width())/aTmpSize.Height();
605 mnHeightPixel = (sal_uInt16)(mnWidthPixel/dRatio);
607 // we come up with a destination...
609 INetURLObject aINetURLObj( maPath );
610 DBG_ASSERT( aINetURLObj.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
612 maExportPath = aINetURLObj.GetPartBeforeLastName(); // with trailing '/'
613 maIndex = aINetURLObj.GetLastName();
615 mnSdPageCount = mpDoc->GetSdPageCount( PK_STANDARD );
616 for( sal_uInt16 nPage = 0; nPage < mnSdPageCount; nPage++ )
618 pPage = mpDoc->GetSdPage( nPage, PK_STANDARD );
620 if( mbHiddenSlides || !pPage->IsExcluded() )
622 maPages.push_back( pPage );
623 maNotesPages.push_back( mpDoc->GetSdPage( nPage, PK_NOTES ) );
626 mnSdPageCount = maPages.size();
628 mbFrames = meMode == PUBLISH_FRAMES;
630 maDocFileName = maIndex;
633 void HtmlExport::ExportSingleDocument()
635 SdrOutliner* pOutliner = mpDoc->GetInternalOutliner();
637 maPageNames.resize(mnSdPageCount);
639 mnPagesWritten = 0;
640 InitProgress(mnSdPageCount);
642 OUStringBuffer aStr(maHTMLHeader);
643 aStr.append(DocumentMetadata());
644 aStr.append("\r\n");
645 aStr.append("</head>\r\n");
646 aStr.append(CreateBodyTag());
648 for(sal_uInt16 nSdPage = 0; nSdPage < mnSdPageCount; ++nSdPage)
650 SdPage* pPage = maPages[nSdPage];
651 maPageNames[nSdPage] = pPage->GetName();
653 if( mbDocColors )
655 SetDocColors( pPage );
658 // page title
659 OUString sTitleText(CreateTextForTitle(pOutliner, pPage, pPage->GetPageBackgroundColor()));
660 OUString sStyle;
662 if (nSdPage != 0) // First page - no need for a page brake here
663 sStyle += "page-break-before:always; ";
664 sStyle += getParagraphStyle(pOutliner, 0);
666 lclAppendStyle(aStr, "h1", sStyle);
668 aStr.append(sTitleText);
669 aStr.append("</h1>\r\n");
671 // write outline text
672 aStr.append(CreateTextForPage( pOutliner, pPage, true, pPage->GetPageBackgroundColor() ));
674 // notes
675 if(mbNotes)
677 SdPage* pNotesPage = maNotesPages[ nSdPage ];
678 OUString aNotesStr( CreateTextForNotesPage( pOutliner, pNotesPage, true, maBackColor) );
680 if (!aNotesStr.isEmpty())
682 aStr.append("<br>\r\n<h3>");
683 aStr.append(RESTOHTML(STR_HTMLEXP_NOTES));
684 aStr.append(":</h3>\r\n");
686 aStr.append(aNotesStr);
690 if (mpProgress)
691 mpProgress->SetState(++mnPagesWritten);
695 // close page
696 aStr.append("</body>\r\n</html>");
698 WriteHtml(maDocFileName, false, aStr.makeStringAndClear());
700 pOutliner->Clear();
701 ResetProgress();
704 // exports the (in the c'tor specified impress document) to html
705 void HtmlExport::ExportHtml()
707 if(mbUserAttr)
709 if( maTextColor == COL_AUTO )
711 if( !maBackColor.IsDark() )
712 maTextColor = COL_BLACK;
715 else if( mbDocColors )
717 // default colors for the color schema 'From Document'
718 SetDocColors();
719 maFirstPageColor = maBackColor;
722 // get name for downloadable presentation if needed
723 if( mbDownload )
725 // fade out separator search and extension
726 sal_Int32 nSepPos = maDocFileName.indexOf('.');
727 if (nSepPos != -1)
728 maDocFileName = maDocFileName.copy(0, nSepPos);
730 maDocFileName += ".odp";
733 sal_uInt16 nProgrCount = mnSdPageCount;
734 nProgrCount += mbImpress?mnSdPageCount:0;
735 nProgrCount += mbContentsPage?1:0;
736 nProgrCount += (mbFrames && mbNotes)?mnSdPageCount:0;
737 nProgrCount += (mbFrames)?8:0;
738 InitProgress( nProgrCount );
740 mpDocSh->SetWaitCursor( true );
742 // Exceptions are cool...
744 CreateFileNames();
746 // this is not a true while
747 while( true )
749 if( checkForExistingFiles() )
750 break;
752 if( !CreateImagesForPresPages() )
753 break;
755 if( mbContentsPage &&
756 !CreateImagesForPresPages( true ) )
757 break;
759 if( !CreateHtmlForPresPages() )
760 break;
762 if( mbImpress )
763 if( !CreateHtmlTextForPresPages() )
764 break;
766 if( mbFrames )
768 if( !CreateFrames() )
769 break;
771 if( !CreateOutlinePages() )
772 break;
774 if( !CreateNavBarFrames() )
775 break;
777 if( mbNotes && mbImpress )
778 if( !CreateNotesPages() )
779 break;
783 if( mbContentsPage )
784 if( !CreateContentPage() )
785 break;
787 if( !CreateBitmaps() )
788 break;
790 mpDocSh->SetWaitCursor( false );
791 ResetProgress();
793 if( mbDownload )
794 SavePresentation();
796 return;
799 // if we get to this point the export was
800 // canceled by the user after an error
801 mpDocSh->SetWaitCursor( false );
802 ResetProgress();
805 void HtmlExport::SetDocColors( SdPage* pPage )
807 if( pPage == NULL )
808 pPage = mpDoc->GetSdPage(0, PK_STANDARD);
810 svtools::ColorConfig aConfig;
811 maVLinkColor = Color(aConfig.GetColorValue(svtools::LINKSVISITED).nColor);
812 maALinkColor = Color(aConfig.GetColorValue(svtools::LINKS).nColor);
813 maLinkColor = Color(aConfig.GetColorValue(svtools::LINKS).nColor);
814 maTextColor = Color(COL_BLACK);
816 SfxStyleSheet* pSheet = NULL;
818 if( mpDoc->GetDocumentType() == DOCUMENT_TYPE_IMPRESS )
820 // default text color from the outline template of the first page
821 pSheet = pPage->GetStyleSheetForPresObj(PRESOBJ_OUTLINE);
822 if(pSheet == NULL)
823 pSheet = pPage->GetStyleSheetForPresObj(PRESOBJ_TEXT);
824 if(pSheet == NULL)
825 pSheet = pPage->GetStyleSheetForPresObj(PRESOBJ_TITLE);
828 if(pSheet == NULL)
829 pSheet = mpDoc->GetDefaultStyleSheet();
831 if(pSheet)
833 SfxItemSet& rSet = pSheet->GetItemSet();
834 if(rSet.GetItemState(EE_CHAR_COLOR,true) == SfxItemState::SET)
835 maTextColor = static_cast<const SvxColorItem*>(rSet.GetItem(EE_CHAR_COLOR,true))->GetValue();
838 // default background from the background of the master page of the first page
839 maBackColor = pPage->GetPageBackgroundColor();
841 if( maTextColor == COL_AUTO )
843 if( !maBackColor.IsDark() )
844 maTextColor = COL_BLACK;
848 void HtmlExport::InitProgress( sal_uInt16 nProgrCount )
850 mpProgress = new SfxProgress( mpDocSh, SD_RESSTR(STR_CREATE_PAGES), nProgrCount );
853 void HtmlExport::ResetProgress()
855 delete mpProgress;
856 mpProgress = NULL;
859 void HtmlExport::ExportKiosk()
861 mnPagesWritten = 0;
862 InitProgress( 2*mnSdPageCount );
864 CreateFileNames();
865 if( !checkForExistingFiles() )
867 if( CreateImagesForPresPages() )
868 CreateHtmlForPresPages();
871 ResetProgress();
874 // Export Document with WebCast (TM) Technology
875 void HtmlExport::ExportWebCast()
877 mnPagesWritten = 0;
878 InitProgress( mnSdPageCount + 9 );
880 mpDocSh->SetWaitCursor( true );
882 CreateFileNames();
884 if (maCGIPath.isEmpty())
885 maCGIPath = ".";
887 if (!maCGIPath.endsWith("/"))
888 maCGIPath += "/";
890 if( meScript == SCRIPT_ASP )
892 maURLPath = "./";
894 else
896 if (maURLPath.isEmpty())
897 maURLPath = ".";
899 if (!maURLPath.endsWith("/"))
900 maURLPath += "/";
903 // this is not a true while
904 while(true)
906 if( checkForExistingFiles() )
907 break;
909 if(!CreateImagesForPresPages())
910 break;
912 if( meScript == SCRIPT_ASP )
914 if(!CreateASPScripts())
915 break;
917 else
919 if(!CreatePERLScripts())
920 break;
923 if(!CreateImageFileList())
924 break;
926 if(!CreateImageNumberFile())
927 break;
929 break;
932 mpDocSh->SetWaitCursor( false );
933 ResetProgress();
936 // Save the presentation as a downloadable file in the dest directory
937 bool HtmlExport::SavePresentation()
939 meEC.SetContext( STR_HTMLEXP_ERROR_CREATE_FILE, maDocFileName );
941 OUString aURL(maExportPath + maDocFileName);
943 mpDocSh->EnableSetModified( true );
947 uno::Reference< frame::XStorable > xStorable( mpDoc->getUnoModel(), uno::UNO_QUERY );
948 if( xStorable.is() )
950 uno::Sequence< beans::PropertyValue > aProperties( 2 );
951 aProperties[ 0 ].Name = "Overwrite";
952 aProperties[ 0 ].Value <<= true;
953 aProperties[ 1 ].Name = "FilterName";
954 aProperties[ 1 ].Value <<= OUString("impress8");
955 xStorable->storeToURL( aURL, aProperties );
957 mpDocSh->EnableSetModified( false );
959 return true;
962 catch( Exception& )
966 mpDocSh->EnableSetModified( false );
968 return false;
971 // create image files
972 bool HtmlExport::CreateImagesForPresPages( bool bThumbnail)
976 Reference < XComponentContext > xContext = ::comphelper::getProcessComponentContext();
978 Reference< drawing::XGraphicExportFilter > xGraphicExporter = drawing::GraphicExportFilter::create( xContext );
980 Sequence< PropertyValue > aFilterData(((meFormat==FORMAT_JPG)&&(mnCompression != -1))? 3 : 2);
981 aFilterData[0].Name = "PixelWidth";
982 aFilterData[0].Value <<= (sal_Int32)(bThumbnail ? PUB_THUMBNAIL_WIDTH : mnWidthPixel );
983 aFilterData[1].Name = "PixelHeight";
984 aFilterData[1].Value <<= (sal_Int32)(bThumbnail ? PUB_THUMBNAIL_HEIGHT : mnHeightPixel);
985 if((meFormat==FORMAT_JPG)&&(mnCompression != -1))
987 aFilterData[2].Name = "Quality";
988 aFilterData[2].Value <<= (sal_Int32)mnCompression;
991 Sequence< PropertyValue > aDescriptor( 3 );
992 aDescriptor[0].Name = "URL";
993 aDescriptor[1].Name = "FilterName";
994 OUString sFormat;
995 if( meFormat == FORMAT_PNG )
996 sFormat = "PNG";
997 else if( meFormat == FORMAT_GIF )
998 sFormat = "GIF";
999 else
1000 sFormat = "JPG";
1002 aDescriptor[1].Value <<= sFormat;
1003 aDescriptor[2].Name = "FilterData";
1004 aDescriptor[2].Value <<= aFilterData;
1006 for (sal_uInt16 nSdPage = 0; nSdPage < mnSdPageCount; nSdPage++)
1008 SdPage* pPage = maPages[ nSdPage ];
1010 OUString aFull(maExportPath);
1011 if (bThumbnail)
1012 aFull += maThumbnailFiles[nSdPage];
1013 else
1014 aFull += maImageFiles[nSdPage];
1016 aDescriptor[0].Value <<= aFull;
1018 Reference< XComponent > xPage( pPage->getUnoPage(), UNO_QUERY );
1019 xGraphicExporter->setSourceDocument( xPage );
1020 xGraphicExporter->filter( aDescriptor );
1022 if (mpProgress)
1023 mpProgress->SetState(++mnPagesWritten);
1026 catch( Exception& )
1028 return false;
1031 return true;
1034 // get SdrTextObject with layout text of this page
1035 SdrTextObj* HtmlExport::GetLayoutTextObject(SdrPage* pPage)
1037 const size_t nObjectCount = pPage->GetObjCount();
1038 SdrTextObj* pResult = NULL;
1040 for (size_t nObject = 0; nObject < nObjectCount; ++nObject)
1042 SdrObject* pObject = pPage->GetObj(nObject);
1043 if (pObject->GetObjInventor() == SdrInventor &&
1044 pObject->GetObjIdentifier() == OBJ_OUTLINETEXT)
1046 pResult = static_cast<SdrTextObj*>(pObject);
1047 break;
1050 return pResult;
1053 // create HTML text version of impress pages
1054 OUString HtmlExport::CreateMetaCharset()
1056 OUString aStr;
1057 const sal_Char *pCharSet = rtl_getBestMimeCharsetFromTextEncoding( RTL_TEXTENCODING_UTF8 );
1058 if ( pCharSet )
1060 aStr = " <meta HTTP-EQUIV=CONTENT-TYPE CONTENT=\"text/html; charset=" +
1061 OUString::createFromAscii(pCharSet) + "\">\r\n";
1063 return aStr;
1066 OUString HtmlExport::DocumentMetadata() const
1068 SvMemoryStream aStream;
1070 uno::Reference<document::XDocumentProperties> xDocProps;
1071 if (mpDocSh)
1073 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
1074 mpDocSh->GetModel(), uno::UNO_QUERY_THROW);
1075 xDocProps.set(xDPS->getDocumentProperties());
1078 OUString aNonConvertableCharacters;
1080 SfxFrameHTMLWriter::Out_DocInfo(aStream, maDocFileName, xDocProps,
1081 " ", RTL_TEXTENCODING_UTF8,
1082 &aNonConvertableCharacters);
1084 OString aData(static_cast<const char*>(aStream.GetData()), aStream.GetSize());
1086 return OStringToOUString(aData, RTL_TEXTENCODING_UTF8);
1089 bool HtmlExport::CreateHtmlTextForPresPages()
1091 bool bOk = true;
1093 SdrOutliner* pOutliner = mpDoc->GetInternalOutliner();
1095 for(sal_uInt16 nSdPage = 0; nSdPage < mnSdPageCount && bOk; nSdPage++)
1097 SdPage* pPage = maPages[ nSdPage ];
1099 if( mbDocColors )
1101 SetDocColors( pPage );
1104 // HTML head
1105 OUStringBuffer aStr(maHTMLHeader);
1106 aStr.append(CreateMetaCharset());
1107 aStr.append(" <title>");
1108 aStr.append(StringToHTMLString(maPageNames[nSdPage]));
1109 aStr.append("</title>\r\n");
1110 aStr.append("</head>\r\n");
1111 aStr.append(CreateBodyTag());
1113 // navigation bar
1114 aStr.append(CreateNavBar(nSdPage, true));
1116 // page title
1117 OUString sTitleText( CreateTextForTitle(pOutliner,pPage, pPage->GetPageBackgroundColor()) );
1118 lclAppendStyle(aStr, "h1", getParagraphStyle(pOutliner, 0));
1119 aStr.append(sTitleText);
1120 aStr.append("</h1>\r\n");
1122 // write outline text
1123 aStr.append(CreateTextForPage( pOutliner, pPage, true, pPage->GetPageBackgroundColor() ));
1125 // notes
1126 if(mbNotes)
1128 SdPage* pNotesPage = maNotesPages[ nSdPage ];
1129 OUString aNotesStr( CreateTextForNotesPage( pOutliner, pNotesPage, true, maBackColor) );
1131 if (!aNotesStr.isEmpty())
1133 aStr.append("<br>\r\n<h3>");
1134 aStr.append(RESTOHTML(STR_HTMLEXP_NOTES));
1135 aStr.append(":</h3>\r\n");
1137 aStr.append(aNotesStr);
1141 // close page
1142 aStr.append("</body>\r\n</html>");
1144 bOk = WriteHtml(maTextFiles[nSdPage], false, aStr.makeStringAndClear());
1146 if (mpProgress)
1147 mpProgress->SetState(++mnPagesWritten);
1151 pOutliner->Clear();
1153 return bOk;
1156 /** exports the given html data into a non unicode file in the current export path with
1157 the given filename */
1158 bool HtmlExport::WriteHtml( const OUString& rFileName, bool bAddExtension, const OUString& rHtmlData )
1160 sal_uLong nErr = 0;
1162 OUString aFileName( rFileName );
1163 if( bAddExtension )
1164 aFileName += maHTMLExtension;
1166 meEC.SetContext( STR_HTMLEXP_ERROR_CREATE_FILE, rFileName );
1167 EasyFile aFile;
1168 SvStream* pStr;
1169 OUString aFull(maExportPath + aFileName);
1170 nErr = aFile.createStream(aFull , pStr);
1171 if(nErr == 0)
1173 OString aStr(OUStringToOString(rHtmlData,
1174 RTL_TEXTENCODING_UTF8));
1175 pStr->WriteCharPtr( aStr.getStr() );
1176 nErr = aFile.close();
1179 if( nErr != 0 )
1180 ErrorHandler::HandleError(nErr);
1182 return nErr == 0;
1185 /** creates a outliner text for the title objects of a page
1187 OUString HtmlExport::CreateTextForTitle( SdrOutliner* pOutliner, SdPage* pPage, const Color& rBackgroundColor )
1189 SdrTextObj* pTO = static_cast<SdrTextObj*>(pPage->GetPresObj(PRESOBJ_TITLE));
1190 if(!pTO)
1191 pTO = GetLayoutTextObject(pPage);
1193 if (pTO && !pTO->IsEmptyPresObj())
1195 OutlinerParaObject* pOPO = pTO->GetOutlinerParaObject();
1196 if(pOPO && pOutliner->GetParagraphCount() != 0)
1198 pOutliner->Clear();
1199 pOutliner->SetText(*pOPO);
1200 return ParagraphToHTMLString(pOutliner,0, rBackgroundColor);
1204 return OUString();
1207 // creates a outliner text for a page
1208 OUString HtmlExport::CreateTextForPage(SdrOutliner* pOutliner, SdPage* pPage,
1209 bool bHeadLine, const Color& rBackgroundColor)
1211 OUStringBuffer aStr;
1213 for (size_t i = 0; i <pPage->GetObjCount(); ++i )
1215 SdrObject* pObject = pPage->GetObj(i);
1216 PresObjKind eKind = pPage->GetPresObjKind(pObject);
1218 switch (eKind)
1220 case PRESOBJ_NONE:
1222 if (pObject->GetObjIdentifier() == OBJ_GRUP)
1224 SdrObjGroup* pObjectGroup = static_cast<SdrObjGroup*>(pObject);
1225 WriteObjectGroup(aStr, pObjectGroup, pOutliner, rBackgroundColor, false);
1227 else if (pObject->GetObjIdentifier() == OBJ_TABLE)
1229 SdrTableObj* pTableObject = static_cast<SdrTableObj*>(pObject);
1230 WriteTable(aStr, pTableObject, pOutliner, rBackgroundColor);
1232 else
1234 if (pObject->GetOutlinerParaObject())
1236 WriteOutlinerParagraph(aStr, pOutliner, pObject->GetOutlinerParaObject(), rBackgroundColor, false);
1240 break;
1242 case PRESOBJ_TABLE:
1244 SdrTableObj* pTableObject = static_cast<SdrTableObj*>(pObject);
1245 WriteTable(aStr, pTableObject, pOutliner, rBackgroundColor);
1247 break;
1249 case PRESOBJ_TEXT:
1250 case PRESOBJ_OUTLINE:
1252 SdrTextObj* pTextObject = static_cast<SdrTextObj*>(pObject);
1253 if (pTextObject->IsEmptyPresObj())
1254 continue;
1255 WriteOutlinerParagraph(aStr, pOutliner, pTextObject->GetOutlinerParaObject(), rBackgroundColor, bHeadLine);
1257 break;
1259 default:
1260 break;
1263 return aStr.makeStringAndClear();
1266 void HtmlExport::WriteTable(OUStringBuffer& aStr, SdrTableObj* pTableObject, SdrOutliner* pOutliner, const Color& rBackgroundColor)
1268 CellPos aStart, aEnd;
1270 aStart = SdrTableObj::getFirstCell();
1271 aEnd = pTableObject->getLastCell();
1273 sal_Int32 nColCount = pTableObject->getColumnCount();
1274 aStr.append("<table>\r\n");
1275 for (sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++)
1277 aStr.append(" <tr>\r\n");
1278 for (sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++)
1280 aStr.append(" <td>\r\n");
1281 sal_Int32 nCellIndex = nRow * nColCount + nCol;
1282 SdrText* pText = pTableObject->getText(nCellIndex);
1284 if (pText == NULL)
1285 continue;
1286 WriteOutlinerParagraph(aStr, pOutliner, pText->GetOutlinerParaObject(), rBackgroundColor, false);
1287 aStr.append(" </td>\r\n");
1289 aStr.append(" </tr>\r\n");
1291 aStr.append("</table>\r\n");
1294 void HtmlExport::WriteObjectGroup(OUStringBuffer& aStr, SdrObjGroup* pObjectGroup, SdrOutliner* pOutliner,
1295 const Color& rBackgroundColor, bool bHeadLine)
1297 SdrObjListIter aGroupIterator(*pObjectGroup->GetSubList(), IM_DEEPNOGROUPS);
1298 while (aGroupIterator.IsMore())
1300 SdrObject* pCurrentObject = aGroupIterator.Next();
1301 if (pCurrentObject->GetObjIdentifier() == OBJ_GRUP)
1303 SdrObjGroup* pCurrentGroupObject = static_cast<SdrObjGroup*>(pCurrentObject);
1304 WriteObjectGroup(aStr, pCurrentGroupObject, pOutliner, rBackgroundColor, bHeadLine);
1306 else
1308 OutlinerParaObject* pOutlinerParagraphObject = pCurrentObject->GetOutlinerParaObject();
1309 if (pOutlinerParagraphObject != NULL)
1311 WriteOutlinerParagraph(aStr, pOutliner, pOutlinerParagraphObject, rBackgroundColor, bHeadLine);
1317 void HtmlExport::WriteOutlinerParagraph(OUStringBuffer& aStr, SdrOutliner* pOutliner,
1318 OutlinerParaObject* pOutlinerParagraphObject,
1319 const Color& rBackgroundColor, bool bHeadLine)
1321 if (pOutlinerParagraphObject == NULL)
1322 return;
1324 pOutliner->SetText(*pOutlinerParagraphObject);
1326 sal_Int32 nCount = pOutliner->GetParagraphCount();
1329 sal_Int16 nCurrentDepth = -1;
1331 for (sal_Int32 nIndex = 0; nIndex < nCount; nIndex++)
1333 Paragraph* pParagraph = pOutliner->GetParagraph(nIndex);
1334 if(pParagraph == NULL)
1335 continue;
1337 const sal_Int16 nDepth = (sal_uInt16) pOutliner->GetDepth(nIndex);
1338 OUString aParaText = ParagraphToHTMLString(pOutliner, nIndex, rBackgroundColor);
1340 if (aParaText.isEmpty())
1341 continue;
1343 if (nDepth < 0)
1345 OUString aTag = bHeadLine ? OUString("h2") : OUString("p");
1346 lclAppendStyle(aStr, aTag, getParagraphStyle(pOutliner, nIndex));
1348 aStr.append(aParaText);
1349 aStr.append("</" + aTag + ">\r\n");
1351 else
1353 while(nCurrentDepth < nDepth)
1355 aStr.append("<ul>\r\n");
1356 nCurrentDepth++;
1358 while(nCurrentDepth > nDepth)
1360 aStr.append("</ul>\r\n");
1361 nCurrentDepth--;
1363 lclAppendStyle(aStr, "li", getParagraphStyle(pOutliner, nIndex));
1364 aStr.append(aParaText);
1365 aStr.append("</li>\r\n");
1368 while(nCurrentDepth >= 0)
1370 aStr.append("</ul>\r\n");
1371 nCurrentDepth--;
1373 pOutliner->Clear();
1376 // creates a outliner text for a note page
1377 OUString HtmlExport::CreateTextForNotesPage( SdrOutliner* pOutliner,
1378 SdPage* pPage,
1379 bool,
1380 const Color& rBackgroundColor )
1382 OUStringBuffer aStr;
1384 SdrTextObj* pTO = static_cast<SdrTextObj*>(pPage->GetPresObj(PRESOBJ_NOTES));
1386 if (pTO && !pTO->IsEmptyPresObj())
1388 OutlinerParaObject* pOPO = pTO->GetOutlinerParaObject();
1389 if (pOPO)
1391 pOutliner->Clear();
1392 pOutliner->SetText( *pOPO );
1394 sal_Int32 nCount = pOutliner->GetParagraphCount();
1395 for (sal_Int32 nPara = 0; nPara < nCount; nPara++)
1397 lclAppendStyle(aStr, "p", getParagraphStyle(pOutliner, nPara));
1398 aStr.append(ParagraphToHTMLString(pOutliner, nPara, rBackgroundColor));
1399 aStr.append("</p>\r\n");
1404 return aStr.makeStringAndClear();
1407 // converts a paragraph of the outliner to html
1408 OUString HtmlExport::ParagraphToHTMLString( SdrOutliner* pOutliner, sal_Int32 nPara, const Color& rBackgroundColor )
1410 OUStringBuffer aStr;
1412 if(NULL == pOutliner)
1413 return OUString();
1415 // TODO: MALTE!!!
1416 EditEngine& rEditEngine = *const_cast<EditEngine*>(&pOutliner->GetEditEngine());
1417 bool bOldUpdateMode = rEditEngine.GetUpdateMode();
1418 rEditEngine.SetUpdateMode(true);
1420 Paragraph* pPara = pOutliner->GetParagraph(nPara);
1421 if(NULL == pPara)
1422 return OUString();
1424 HtmlState aState( (mbUserAttr || mbDocColors) ? maTextColor : Color(COL_BLACK) );
1425 std::vector<sal_Int32> aPortionList;
1426 rEditEngine.GetPortions( nPara, aPortionList );
1428 sal_Int32 nPos1 = 0;
1429 for( std::vector<sal_Int32>::const_iterator it( aPortionList.begin() ); it != aPortionList.end(); ++it )
1431 sal_Int32 nPos2 = *it;
1433 ESelection aSelection( nPara, nPos1, nPara, nPos2);
1435 SfxItemSet aSet( rEditEngine.GetAttribs( aSelection ) );
1437 OUString aPortion(StringToHTMLString(rEditEngine.GetText( aSelection )));
1439 aStr.append(TextAttribToHTMLString( &aSet, &aState, rBackgroundColor ));
1440 aStr.append(aPortion);
1442 nPos1 = nPos2;
1444 aStr.append(aState.Flush());
1445 rEditEngine.SetUpdateMode(bOldUpdateMode);
1447 return aStr.makeStringAndClear();
1450 // Depending on the attributes of the specified set and the specified
1451 // HtmlState, it creates the needed html tags in order to get the
1452 // attributes
1453 OUString HtmlExport::TextAttribToHTMLString( SfxItemSet* pSet, HtmlState* pState, const Color& rBackgroundColor )
1455 OUStringBuffer aStr;
1457 if(NULL == pSet)
1458 return OUString();
1460 OUString aLink, aTarget;
1461 if ( pSet->GetItemState( EE_FEATURE_FIELD ) == SfxItemState::SET )
1463 const SvxFieldItem* pItem = static_cast<const SvxFieldItem*>(pSet->GetItem( EE_FEATURE_FIELD ));
1464 if(pItem)
1466 const SvxURLField* pURL = PTR_CAST(SvxURLField, pItem->GetField());
1467 if(pURL)
1469 aLink = pURL->GetURL();
1470 aTarget = pURL->GetTargetFrame();
1475 bool bTemp;
1476 OUString aTemp;
1478 if ( pSet->GetItemState( EE_CHAR_WEIGHT ) == SfxItemState::SET )
1480 bTemp = static_cast<const SvxWeightItem&>(pSet->Get( EE_CHAR_WEIGHT )).GetWeight() == WEIGHT_BOLD;
1481 aTemp = pState->SetWeight( bTemp );
1482 if( bTemp )
1483 aStr.insert(0, aTemp);
1484 else
1485 aStr.append(aTemp);
1488 if ( pSet->GetItemState( EE_CHAR_UNDERLINE ) == SfxItemState::SET )
1490 bTemp = static_cast<const SvxUnderlineItem&>(pSet->Get( EE_CHAR_UNDERLINE )).GetLineStyle() != UNDERLINE_NONE;
1491 aTemp = pState->SetUnderline( bTemp );
1492 if( bTemp )
1493 aStr.insert(0, aTemp);
1494 else
1495 aStr.append(aTemp);
1498 if ( pSet->GetItemState( EE_CHAR_STRIKEOUT ) == SfxItemState::SET )
1500 bTemp = static_cast<const SvxCrossedOutItem&>(pSet->Get( EE_CHAR_STRIKEOUT )).GetStrikeout() != STRIKEOUT_NONE;
1501 aTemp = pState->SetStrikeout( bTemp );
1502 if( bTemp )
1503 aStr.insert(0, aTemp);
1504 else
1505 aStr.append(aTemp);
1508 if ( pSet->GetItemState( EE_CHAR_ITALIC ) == SfxItemState::SET )
1510 bTemp = static_cast<const SvxPostureItem&>(pSet->Get( EE_CHAR_ITALIC )).GetPosture() != ITALIC_NONE;
1511 aTemp = pState->SetItalic( bTemp );
1512 if( bTemp )
1513 aStr.insert(0, aTemp);
1514 else
1515 aStr.append(aTemp);
1518 if(mbDocColors)
1520 if ( pSet->GetItemState( EE_CHAR_COLOR ) == SfxItemState::SET )
1522 Color aTextColor = static_cast<const SvxColorItem&>(pSet->Get( EE_CHAR_COLOR )).GetValue();
1523 if( aTextColor == COL_AUTO )
1525 if( !rBackgroundColor.IsDark() )
1526 aTextColor = COL_BLACK;
1528 aStr.append(pState->SetColor( aTextColor ));
1532 if (!aLink.isEmpty())
1533 aStr.insert(0, pState->SetLink(aLink, aTarget));
1534 else
1535 aStr.append(pState->SetLink(aLink, aTarget));
1537 return aStr.makeStringAndClear();
1540 // create HTML wrapper for picture files
1541 bool HtmlExport::CreateHtmlForPresPages()
1543 bool bOk = true;
1545 std::vector<SdrObject*> aClickableObjects;
1547 for(sal_uInt16 nSdPage = 0; nSdPage < mnSdPageCount && bOk; nSdPage++)
1549 // find clickable objects (also on the master page) and put it in the
1550 // list. This in reverse order character order since in html the first
1551 // area is taken in the case they overlap.
1552 SdPage* pPage = maPages[ nSdPage ];
1554 if( mbDocColors )
1556 SetDocColors( pPage );
1559 bool bMasterDone = false;
1561 while (!bMasterDone)
1563 // sal_True = backwards
1564 SdrObjListIter aIter(*pPage, IM_DEEPWITHGROUPS, true);
1566 SdrObject* pObject = aIter.Next();
1567 while (pObject)
1569 SdAnimationInfo* pInfo = mpDoc->GetAnimationInfo(pObject);
1570 SdIMapInfo* pIMapInfo = mpDoc->GetIMapInfo(pObject);
1572 if ((pInfo &&
1573 (pInfo->meClickAction == presentation::ClickAction_BOOKMARK ||
1574 pInfo->meClickAction == presentation::ClickAction_DOCUMENT ||
1575 pInfo->meClickAction == presentation::ClickAction_PREVPAGE ||
1576 pInfo->meClickAction == presentation::ClickAction_NEXTPAGE ||
1577 pInfo->meClickAction == presentation::ClickAction_FIRSTPAGE ||
1578 pInfo->meClickAction == presentation::ClickAction_LASTPAGE)) ||
1579 pIMapInfo)
1581 aClickableObjects.push_back(pObject);
1584 pObject = aIter.Next();
1586 // now to the master page or finishing
1587 if (!pPage->IsMasterPage())
1588 pPage = static_cast<SdPage*>(&(pPage->TRG_GetMasterPage()));
1589 else
1590 bMasterDone = true;
1593 // HTML Head
1594 OUStringBuffer aStr(maHTMLHeader);
1595 aStr.append(CreateMetaCharset());
1596 aStr.append(" <title>" + StringToHTMLString(maPageNames[nSdPage]) + "</title>\r\n");
1598 // insert timing information
1599 pPage = maPages[ nSdPage ];
1600 if( meMode == PUBLISH_KIOSK )
1602 double fSecs = 0;
1603 bool bEndless = false;
1604 if( !mbAutoSlide )
1606 if( pPage->GetPresChange() != PRESCHANGE_MANUAL )
1608 fSecs = pPage->GetTime();
1609 bEndless = mpDoc->getPresentationSettings().mbEndless;
1612 else
1614 fSecs = mfSlideDuration;
1615 bEndless = mbEndless;
1618 if( fSecs != 0 )
1620 if( nSdPage < (mnSdPageCount-1) || bEndless )
1622 aStr.append("<meta http-equiv=\"refresh\" content=\"");
1623 aStr.append(OUString::number(fSecs));
1624 aStr.append("; URL=");
1626 int nPage = nSdPage + 1;
1627 if( nPage == mnSdPageCount )
1628 nPage = 0;
1630 aStr.append(maHTMLFiles[nPage]);
1632 aStr.append("\">\r\n");
1637 aStr.append("</head>\r\n");
1639 // HTML Body
1640 aStr.append(CreateBodyTag());
1642 if( mbSlideSound && pPage->IsSoundOn() )
1643 aStr.append(InsertSound(pPage->GetSoundFile()));
1645 // navigation bar
1646 if(!mbFrames )
1647 aStr.append(CreateNavBar(nSdPage, false));
1648 // Image
1649 aStr.append("<center>");
1650 aStr.append("<img src=\"");
1651 aStr.append(maImageFiles[nSdPage]);
1652 aStr.append("\" alt=\"\"");
1654 if (!aClickableObjects.empty())
1655 aStr.append(" USEMAP=\"#map0\"");
1657 aStr.append("></center>\r\n");
1659 // notes
1660 if(mbNotes && !mbFrames)
1662 SdrOutliner* pOutliner = mpDoc->GetInternalOutliner();
1663 SdPage* pNotesPage = maNotesPages[ nSdPage ];
1664 OUString aNotesStr( CreateTextForNotesPage( pOutliner, pNotesPage, true, maBackColor) );
1665 pOutliner->Clear();
1667 if (!aNotesStr.isEmpty())
1669 aStr.append("<h3>");
1670 aStr.append(RESTOHTML(STR_HTMLEXP_NOTES));
1671 aStr.append(":</h3><br>\r\n\r\n<p>");
1673 aStr.append(aNotesStr);
1674 aStr.append("\r\n</p>\r\n");
1678 // create Imagemap if necessary
1679 if (!aClickableObjects.empty())
1681 aStr.append("<map name=\"map0\">\r\n");
1683 for (sal_uInt32 nObject = 0, n = aClickableObjects.size(); nObject < n; nObject++)
1685 SdrObject* pObject = aClickableObjects[nObject];
1686 SdAnimationInfo* pInfo = mpDoc->GetAnimationInfo(pObject);
1687 SdIMapInfo* pIMapInfo = mpDoc->GetIMapInfo(pObject);
1689 Rectangle aRect(pObject->GetCurrentBoundRect());
1690 Point aLogPos(aRect.TopLeft());
1691 bool bIsSquare = aRect.GetWidth() == aRect.GetHeight();
1693 sal_uLong nPageWidth = pPage->GetSize().Width() - pPage->GetLftBorder() -
1694 pPage->GetRgtBorder();
1696 // BoundRect is relative to the physical page origin, not the
1697 // origin of ordinates
1698 aRect.Move(-pPage->GetLftBorder(), -pPage->GetUppBorder());
1700 double fLogicToPixel = ((double)mnWidthPixel) / nPageWidth;
1701 aRect.Left() = (long)(aRect.Left() * fLogicToPixel);
1702 aRect.Top() = (long)(aRect.Top() * fLogicToPixel);
1703 aRect.Right() = (long)(aRect.Right() * fLogicToPixel);
1704 aRect.Bottom() = (long)(aRect.Bottom() * fLogicToPixel);
1705 long nRadius = aRect.GetWidth() / 2;
1708 insert areas into Imagemap of the object, if the object has
1709 such a Imagemap
1711 if (pIMapInfo)
1713 const ImageMap& rIMap = pIMapInfo->GetImageMap();
1714 sal_uInt16 nAreaCount = rIMap.GetIMapObjectCount();
1715 for (sal_uInt16 nArea = 0; nArea < nAreaCount; nArea++)
1717 IMapObject* pArea = rIMap.GetIMapObject(nArea);
1718 sal_uInt16 nType = pArea->GetType();
1719 OUString aURL( pArea->GetURL() );
1721 // if necessary, convert page and object names into the
1722 // corresponding names of the html file
1723 bool bIsMasterPage;
1724 sal_uInt16 nPgNum = mpDoc->GetPageByName( aURL, bIsMasterPage );
1725 SdrObject* pObj = NULL;
1727 if (nPgNum == SDRPAGE_NOTFOUND)
1729 // is the bookmark a object?
1730 pObj = mpDoc->GetObj( aURL );
1731 if (pObj)
1732 nPgNum = pObj->GetPage()->GetPageNum();
1734 if (nPgNum != SDRPAGE_NOTFOUND)
1736 nPgNum = (nPgNum - 1) / 2; // SdrPageNum --> SdPageNum
1737 aURL = CreatePageURL(nPgNum);
1740 switch(nType)
1742 case IMAP_OBJ_RECTANGLE:
1744 Rectangle aArea(static_cast<IMapRectangleObject*>(pArea)->
1745 GetRectangle(false));
1747 // conversion into pixel coordinates
1748 aArea.Move(aLogPos.X() - pPage->GetLftBorder(),
1749 aLogPos.Y() - pPage->GetUppBorder());
1750 aArea.Left() = (long)(aArea.Left() * fLogicToPixel);
1751 aArea.Top() = (long)(aArea.Top() * fLogicToPixel);
1752 aArea.Right() = (long)(aArea.Right() * fLogicToPixel);
1753 aArea.Bottom() = (long)(aArea.Bottom() * fLogicToPixel);
1755 aStr.append(CreateHTMLRectArea(aArea, aURL));
1757 break;
1759 case IMAP_OBJ_CIRCLE:
1761 Point aCenter(static_cast<IMapCircleObject*>(pArea)->
1762 GetCenter(false));
1763 aCenter += Point(aLogPos.X() - pPage->GetLftBorder(),
1764 aLogPos.Y() - pPage->GetUppBorder());
1765 aCenter.X() = (long)(aCenter.X() * fLogicToPixel);
1766 aCenter.Y() = (long)(aCenter.Y() * fLogicToPixel);
1768 sal_uLong nCircleRadius = static_cast<IMapCircleObject*>(pArea)->
1769 GetRadius(false);
1770 nCircleRadius = (sal_uLong)(nCircleRadius * fLogicToPixel);
1771 aStr.append(CreateHTMLCircleArea(nCircleRadius,
1772 aCenter.X(), aCenter.Y(),
1773 aURL));
1775 break;
1777 case IMAP_OBJ_POLYGON:
1779 Polygon aArea(static_cast<IMapPolygonObject*>(pArea)->GetPolygon(false));
1780 aStr.append(CreateHTMLPolygonArea(::basegfx::B2DPolyPolygon(aArea.getB2DPolygon()), Size(aLogPos.X() - pPage->GetLftBorder(), aLogPos.Y() - pPage->GetUppBorder()), fLogicToPixel, aURL));
1782 break;
1784 default:
1786 DBG_WARNING("unknown IMAP_OBJ_type");
1788 break;
1794 if there is a presentation::ClickAction, determine bookmark
1795 and create area for the whole object
1797 if( pInfo )
1799 OUString aHRef;
1800 presentation::ClickAction eClickAction = pInfo->meClickAction;
1802 switch( eClickAction )
1804 case presentation::ClickAction_BOOKMARK:
1806 bool bIsMasterPage;
1807 sal_uInt16 nPgNum = mpDoc->GetPageByName( pInfo->GetBookmark(), bIsMasterPage );
1808 SdrObject* pObj = NULL;
1810 if( nPgNum == SDRPAGE_NOTFOUND )
1812 // is the bookmark a object?
1813 pObj = mpDoc->GetObj(pInfo->GetBookmark());
1814 if (pObj)
1815 nPgNum = pObj->GetPage()->GetPageNum();
1818 if( SDRPAGE_NOTFOUND != nPgNum )
1819 aHRef = CreatePageURL(( nPgNum - 1 ) / 2 );
1821 break;
1823 case presentation::ClickAction_DOCUMENT:
1824 aHRef = pInfo->GetBookmark();
1825 break;
1827 case presentation::ClickAction_PREVPAGE:
1829 sal_uLong nPage;
1831 if (nSdPage == 0)
1832 nPage = 0;
1833 else
1834 nPage = nSdPage - 1;
1836 aHRef = CreatePageURL( (sal_uInt16) nPage);
1838 break;
1840 case presentation::ClickAction_NEXTPAGE:
1842 sal_uLong nPage = nSdPage;
1843 if (nSdPage == mnSdPageCount - 1)
1844 nPage = mnSdPageCount - 1;
1845 else
1846 nPage = nSdPage + 1;
1848 aHRef = CreatePageURL( (sal_uInt16) nPage);
1850 break;
1852 case presentation::ClickAction_FIRSTPAGE:
1853 aHRef = CreatePageURL(0);
1854 break;
1856 case presentation::ClickAction_LASTPAGE:
1857 aHRef = CreatePageURL(mnSdPageCount - 1);
1858 break;
1860 default:
1861 break;
1864 // and now the areas
1865 if (!aHRef.isEmpty())
1867 // a circle?
1868 if (pObject->GetObjInventor() == SdrInventor &&
1869 pObject->GetObjIdentifier() == OBJ_CIRC &&
1870 bIsSquare )
1872 aStr.append(CreateHTMLCircleArea(aRect.GetWidth() / 2,
1873 aRect.Left() + nRadius,
1874 aRect.Top() + nRadius,
1875 aHRef));
1877 // a polygon?
1878 else if (pObject->GetObjInventor() == SdrInventor &&
1879 (pObject->GetObjIdentifier() == OBJ_PATHLINE ||
1880 pObject->GetObjIdentifier() == OBJ_PLIN ||
1881 pObject->GetObjIdentifier() == OBJ_POLY))
1883 aStr.append(CreateHTMLPolygonArea(static_cast<SdrPathObj*>(pObject)->GetPathPoly(), Size(-pPage->GetLftBorder(), -pPage->GetUppBorder()), fLogicToPixel, aHRef));
1885 // something completely different: use the BoundRect
1886 else
1888 aStr.append(CreateHTMLRectArea(aRect, aHRef));
1895 aStr.append("</map>\r\n");
1897 aClickableObjects.clear();
1899 aStr.append("</body>\r\n</html>");
1901 bOk = WriteHtml(maHTMLFiles[nSdPage], false, aStr.makeStringAndClear());
1903 if (mpProgress)
1904 mpProgress->SetState(++mnPagesWritten);
1907 return bOk;
1910 // create overview pages
1911 bool HtmlExport::CreateContentPage()
1913 if( mbDocColors )
1914 SetDocColors();
1916 // html head
1917 OUStringBuffer aStr(maHTMLHeader);
1918 aStr.append(CreateMetaCharset());
1919 aStr.append(" <title>");
1920 aStr.append(StringToHTMLString(maPageNames[0]));
1921 aStr.append("</title>\r\n</head>\r\n");
1922 aStr.append(CreateBodyTag());
1924 // page head
1925 aStr.append("<center>\r\n");
1927 if(mbHeader)
1929 aStr.append("<h1>");
1930 aStr.append(getDocumentTitle());
1931 aStr.append("</h1><br>\r\n");
1934 aStr.append("<h2>");
1936 // Solaris compiler bug workaround
1937 if( mbFrames )
1938 aStr.append(CreateLink(maFramePage,
1939 RESTOHTML(STR_HTMLEXP_CLICKSTART)));
1940 else
1941 aStr.append(CreateLink(StringToHTMLString(maHTMLFiles[0]),
1942 RESTOHTML(STR_HTMLEXP_CLICKSTART)));
1944 aStr.append("</h2>\r\n</center>\r\n");
1946 aStr.append("<center><table width=\"90%\"><tr>\r\n");
1948 // table of content
1949 aStr.append("<td valign=\"top\" align=\"left\" width=\"25%\">\r\n");
1950 aStr.append("<h3>");
1951 aStr.append(RESTOHTML(STR_HTMLEXP_CONTENTS));
1952 aStr.append("</h3>");
1954 for(sal_uInt16 nSdPage = 0; nSdPage < mnSdPageCount; nSdPage++)
1956 OUString aPageName = maPageNames[nSdPage];
1957 aStr.append("<div align=\"left\">");
1958 if(mbFrames)
1959 aStr.append(StringToHTMLString(aPageName));
1960 else
1961 aStr.append(CreateLink(maHTMLFiles[nSdPage], aPageName));
1962 aStr.append("</div>\r\n");
1964 aStr.append("</td>\r\n");
1966 // document information
1967 aStr.append("<td valign=\"top\" align=\"left\" width=\"75%\">\r\n");
1969 if (!maAuthor.isEmpty())
1971 aStr.append("<p><strong>");
1972 aStr.append(RESTOHTML(STR_HTMLEXP_AUTHOR));
1973 aStr.append(":</strong> ");
1974 aStr.append(StringToHTMLString(maAuthor));
1975 aStr.append("</p>\r\n");
1978 if (!maEMail.isEmpty())
1980 aStr.append("<p><strong>");
1981 aStr.append(RESTOHTML(STR_HTMLEXP_EMAIL));
1982 aStr.append(":</strong> <a href=\"mailto:");
1983 aStr.append(maEMail);
1984 aStr.append("\">");
1985 aStr.append(StringToHTMLString(maEMail));
1986 aStr.append("</a></p>\r\n");
1989 if (!maHomePage.isEmpty())
1991 aStr.append("<p><strong>");
1992 aStr.append(RESTOHTML(STR_HTMLEXP_HOMEPAGE));
1993 aStr.append(":</strong> <a href=\"");
1994 aStr.append(maHomePage);
1995 aStr.append("\">");
1996 aStr.append(StringToHTMLString(maHomePage));
1997 aStr.append("</a> </p>\r\n");
2000 if (!maInfo.isEmpty())
2002 aStr.append("<p><strong>");
2003 aStr.append(RESTOHTML(STR_HTMLEXP_INFO));
2004 aStr.append(":</strong><br>\r\n");
2005 aStr.append(StringToHTMLString(maInfo));
2006 aStr.append("</p>\r\n");
2009 if(mbDownload)
2011 aStr.append("<p><a href=\"");
2012 aStr.append(maDocFileName);
2013 aStr.append("\">");
2014 aStr.append(RESTOHTML(STR_HTMLEXP_DOWNLOAD));
2015 aStr.append("</a></p>\r\n");
2018 for(sal_uInt16 nSdPage = 0; nSdPage < mnSdPageCount; nSdPage++)
2020 OUString aText(
2021 "<img src=\"" +
2022 maThumbnailFiles[nSdPage] +
2023 "\" width=\"256\" height=\"192\" alt=\"" +
2024 StringToHTMLString(maPageNames[nSdPage]) +
2025 "\">");
2027 aStr.append(CreateLink(maHTMLFiles[nSdPage], aText));
2028 aStr.append("\r\n");
2031 aStr.append("</td></tr></table></center>\r\n");
2033 aStr.append("</body>\r\n</html>");
2035 bool bOk = WriteHtml(maIndex, false, aStr.makeStringAndClear());
2037 if (mpProgress)
2038 mpProgress->SetState(++mnPagesWritten);
2040 return bOk;
2043 // create note pages (for frames)
2045 bool HtmlExport::CreateNotesPages()
2047 bool bOk = true;
2049 SdrOutliner* pOutliner = mpDoc->GetInternalOutliner();
2050 for( sal_uInt16 nSdPage = 0; bOk && nSdPage < mnSdPageCount; nSdPage++ )
2052 SdPage* pPage = maNotesPages[nSdPage];
2053 if( mbDocColors )
2054 SetDocColors( pPage );
2056 // Html head
2057 OUStringBuffer aStr(maHTMLHeader);
2058 aStr.append(CreateMetaCharset());
2059 aStr.append(" <title>");
2060 aStr.append(StringToHTMLString(maPageNames[0]));
2061 aStr.append("</title>\r\n</head>\r\n");
2062 aStr.append(CreateBodyTag());
2064 if(pPage)
2065 aStr.append(CreateTextForNotesPage( pOutliner, pPage, true, maBackColor ));
2067 aStr.append("</body>\r\n</html>");
2069 OUString aFileName("note" + OUString::number(nSdPage));
2070 bOk = WriteHtml(aFileName, true, aStr.makeStringAndClear());
2072 if (mpProgress)
2073 mpProgress->SetState(++mnPagesWritten);
2076 pOutliner->Clear();
2078 return bOk;
2081 // create outline pages (for frames)
2083 bool HtmlExport::CreateOutlinePages()
2085 bool bOk = true;
2087 if( mbDocColors )
2089 SetDocColors();
2092 // page 0 will be the closed outline, page 1 the opened
2093 for (sal_Int32 nPage = 0; nPage < (mbImpress?2:1) && bOk; ++nPage)
2095 // Html head
2096 OUStringBuffer aStr(maHTMLHeader);
2097 aStr.append(CreateMetaCharset());
2098 aStr.append(" <title>");
2099 aStr.append(StringToHTMLString(maPageNames[0]));
2100 aStr.append("</title>\r\n</head>\r\n");
2101 aStr.append(CreateBodyTag());
2103 SdrOutliner* pOutliner = mpDoc->GetInternalOutliner();
2104 for(sal_uInt16 nSdPage = 0; nSdPage < mnSdPageCount; nSdPage++)
2106 SdPage* pPage = maPages[ nSdPage ];
2108 aStr.append("<div align=\"left\">");
2109 OUString aLink("JavaScript:parent.NavigateAbs(" +
2110 OUString::number(nSdPage) + ")");
2112 OUString aTitle = CreateTextForTitle(pOutliner, pPage, maBackColor);
2113 if (aTitle.isEmpty())
2114 aTitle = maPageNames[nSdPage];
2116 lclAppendStyle(aStr, "p", getParagraphStyle(pOutliner, 0));
2117 aStr.append(CreateLink(aLink, aTitle));
2118 aStr.append("</p>");
2120 if(nPage==1)
2122 aStr.append(CreateTextForPage( pOutliner, pPage, false, maBackColor ));
2124 aStr.append("</div>\r\n");
2126 pOutliner->Clear();
2128 aStr.append("</body>\r\n</html>");
2130 OUString aFileName("outline" + OUString::number(nPage));
2131 bOk = WriteHtml(aFileName, true, aStr.makeStringAndClear());
2133 if (mpProgress)
2134 mpProgress->SetState(++mnPagesWritten);
2137 return bOk;
2140 // set file name
2141 void HtmlExport::CreateFileNames()
2143 // create lists with new file names
2144 maHTMLFiles.resize(mnSdPageCount);
2145 maImageFiles.resize(mnSdPageCount);
2146 maThumbnailFiles.resize(mnSdPageCount);
2147 maPageNames.resize(mnSdPageCount);
2148 maTextFiles.resize(mnSdPageCount);
2150 mbHeader = false; // headline on overview page?
2152 for (sal_uInt16 nSdPage = 0; nSdPage < mnSdPageCount; nSdPage++)
2154 OUString aHTMLFileName;
2155 if(nSdPage == 0 && !mbContentsPage && !mbFrames )
2156 aHTMLFileName = maIndex;
2157 else
2159 aHTMLFileName = "img" + OUString::number(nSdPage) + maHTMLExtension;
2162 maHTMLFiles[nSdPage] = aHTMLFileName;
2164 OUString aImageFileName = "img" + OUString::number(nSdPage);
2165 if( meFormat==FORMAT_GIF )
2166 aImageFileName += ".gif";
2167 else if( meFormat==FORMAT_JPG )
2168 aImageFileName += ".jpg";
2169 else
2170 aImageFileName += ".png";
2172 maImageFiles[nSdPage] = aImageFileName;
2174 OUString aThumbnailFileName = "thumb" + OUString::number(nSdPage);
2175 if( meFormat!=FORMAT_JPG )
2176 aThumbnailFileName += ".png";
2177 else
2178 aThumbnailFileName += ".jpg";
2180 maThumbnailFiles[nSdPage] = aThumbnailFileName;
2182 maTextFiles[nSdPage] = "text" + OUString::number(nSdPage) + maHTMLExtension;
2184 SdPage* pSdPage = maPages[ nSdPage ];
2186 // get slide title from page name
2187 maPageNames[nSdPage] = pSdPage->GetName();
2190 if(!mbContentsPage && mbFrames)
2191 maFramePage = maIndex;
2192 else
2194 maFramePage = "siframes" + maHTMLExtension;
2198 OUString HtmlExport::getDocumentTitle()
2200 // check for a title object in this page, if its the first
2201 // title it becomes this documents title for the content
2202 // page
2203 if( !mbHeader )
2205 if(mbImpress)
2207 // if there is a non-empty title object, use their first passage
2208 // as page title
2209 SdPage* pSdPage = mpDoc->GetSdPage(0, PK_STANDARD);
2210 SdrObject* pTitleObj = pSdPage->GetPresObj(PRESOBJ_TITLE);
2211 if (pTitleObj && !pTitleObj->IsEmptyPresObj())
2213 OutlinerParaObject* pParaObject = pTitleObj->GetOutlinerParaObject();
2214 if (pParaObject)
2216 const EditTextObject& rEditTextObject =
2217 pParaObject->GetTextObject();
2218 OUString aTest(rEditTextObject.GetText(0));
2219 if (!aTest.isEmpty())
2220 mDocTitle = aTest;
2224 mDocTitle = mDocTitle.replace(0xff, ' ');
2227 if (mDocTitle.isEmpty())
2229 mDocTitle = maDocFileName;
2230 sal_Int32 nDot = mDocTitle.indexOf('.');
2231 if (nDot > 0)
2232 mDocTitle = mDocTitle.copy(0, nDot);
2234 mbHeader = true;
2237 return mDocTitle;
2240 static const char* JS_NavigateAbs =
2241 "function NavigateAbs( nPage )\r\n"
2242 "{\r\n"
2243 " frames[\"show\"].location.href = \"img\" + nPage + \".$EXT\";\r\n"
2244 " //frames[\"notes\"].location.href = \"note\" + nPage + \".$EXT\";\r\n"
2245 " nCurrentPage = nPage;\r\n"
2246 " if(nCurrentPage==0)\r\n"
2247 " {\r\n"
2248 " frames[\"navbar1\"].location.href = \"navbar0.$EXT\";\r\n"
2249 " }\r\n"
2250 " else if(nCurrentPage==nPageCount-1)\r\n"
2251 " {\r\n"
2252 " frames[\"navbar1\"].location.href = \"navbar2.$EXT\";\r\n"
2253 " }\r\n"
2254 " else\r\n"
2255 " {\r\n"
2256 " frames[\"navbar1\"].location.href = \"navbar1.$EXT\";\r\n"
2257 " }\r\n"
2258 "}\r\n\r\n";
2260 static const char* JS_NavigateRel =
2261 "function NavigateRel( nDelta )\r\n"
2262 "{\r\n"
2263 " var nPage = parseInt(nCurrentPage) + parseInt(nDelta);\r\n"
2264 " if( (nPage >= 0) && (nPage < nPageCount) )\r\n"
2265 " {\r\n"
2266 " NavigateAbs( nPage );\r\n"
2267 " }\r\n"
2268 "}\r\n\r\n";
2270 static const char* JS_ExpandOutline =
2271 "function ExpandOutline()\r\n"
2272 "{\r\n"
2273 " frames[\"navbar2\"].location.href = \"navbar4.$EXT\";\r\n"
2274 " frames[\"outline\"].location.href = \"outline1.$EXT\";\r\n"
2275 "}\r\n\r\n";
2277 static const char * JS_CollapseOutline =
2278 "function CollapseOutline()\r\n"
2279 "{\r\n"
2280 " frames[\"navbar2\"].location.href = \"navbar3.$EXT\";\r\n"
2281 " frames[\"outline\"].location.href = \"outline0.$EXT\";\r\n"
2282 "}\r\n\r\n";
2284 // create page with the frames
2286 bool HtmlExport::CreateFrames()
2288 OUString aTmp;
2289 OUStringBuffer aStr(
2290 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\"\r\n"
2291 " \"http://www.w3.org/TR/html4/frameset.dtd\">\r\n"
2292 "<html>\r\n<head>\r\n");
2294 aStr.append(CreateMetaCharset());
2295 aStr.append(" <title>");
2296 aStr.append(StringToHTMLString(maPageNames[0]));
2297 aStr.append("</title>\r\n");
2299 aStr.append("<script type=\"text/javascript\">\r\n<!--\r\n");
2301 aStr.append("var nCurrentPage = 0;\r\nvar nPageCount = ");
2302 aStr.append(OUString::number(mnSdPageCount));
2303 aStr.append(";\r\n\r\n");
2305 OUString aFunction = OUString::createFromAscii(JS_NavigateAbs);
2307 if(mbNotes)
2309 aFunction = aFunction.replaceAll("//", "");
2312 // substitute HTML file extension
2313 OUString aPlaceHolder(".$EXT");
2314 aFunction = aFunction.replaceAll(aPlaceHolder, maHTMLExtension);
2315 aStr.append(aFunction);
2317 aTmp = OUString::createFromAscii(JS_NavigateRel);
2318 aTmp = aTmp.replaceAll(aPlaceHolder, maHTMLExtension);
2319 aStr.append(aTmp);
2321 if(mbImpress)
2323 aTmp = OUString::createFromAscii(JS_ExpandOutline);
2324 aTmp = aTmp.replaceAll(aPlaceHolder, maHTMLExtension);
2325 aStr.append(aTmp);
2327 aTmp = OUString::createFromAscii(JS_CollapseOutline);
2328 aTmp = aTmp.replaceAll(aPlaceHolder, maHTMLExtension);
2329 aStr.append(aTmp);
2331 aStr.append("// -->\r\n</script>\r\n");
2333 aStr.append("</head>\r\n");
2335 aStr.append("<frameset cols=\"*,");
2336 aStr.append(OUString::number((mnWidthPixel + 16)));
2337 aStr.append("\">\r\n");
2338 if(mbImpress)
2340 aStr.append(" <frameset rows=\"42,*\">\r\n");
2341 aStr.append(" <frame src=\"navbar3");
2342 aStr.append(maHTMLExtension);
2343 aStr.append("\" name=\"navbar2\" marginwidth=\"4\" marginheight=\"4\" scrolling=\"no\">\r\n");
2345 aStr.append(" <frame src=\"outline0");
2346 aStr.append(maHTMLExtension);
2347 aStr.append("\" name=\"outline\">\r\n");
2348 if(mbImpress)
2349 aStr.append(" </frameset>\r\n");
2351 if(mbNotes)
2353 aStr.append(" <frameset rows=\"42,");
2354 aStr.append(OUString::number((int)((double)mnWidthPixel * 0.75) + 16));
2355 aStr.append(",*\">\r\n");
2357 else
2358 aStr.append(" <frameset rows=\"42,*\">\r\n");
2360 aStr.append(" <frame src=\"navbar0");
2361 aStr.append(maHTMLExtension);
2362 aStr.append("\" name=\"navbar1\" marginwidth=\"4\" marginheight=\"4\" scrolling=\"no\">\r\n");
2364 aStr.append(" <frame src=\"");
2365 aStr.append(maHTMLFiles[0]);
2366 aStr.append("\" name=\"show\" marginwidth=\"4\" marginheight=\"4\">\r\n");
2368 if(mbNotes)
2370 aStr.append(" <frame src=\"note0");
2371 aStr.append(maHTMLExtension);
2372 aStr.append("\" name=\"notes\">\r\n");
2374 aStr.append(" </frameset>\r\n");
2376 aStr.append("<noframes>\r\n");
2377 aStr.append(CreateBodyTag());
2378 aStr.append(RESTOHTML(STR_HTMLEXP_NOFRAMES));
2379 aStr.append("\r\n</noframes>\r\n</frameset>\r\n</html>");
2381 bool bOk = WriteHtml(maFramePage, false, aStr.makeStringAndClear());
2383 if (mpProgress)
2384 mpProgress->SetState(++mnPagesWritten);
2386 return bOk;
2389 // create button bar for standard
2390 // we create the following html files
2391 // navbar0.htm navigation bar graphic for the first page
2392 // navbar1.htm navigation bar graphic for the second until second last page
2393 // navbar2.htm navigation bar graphic for the last page
2394 // navbar3.htm navigation outline closed
2395 // navbar4.htm navigation outline open
2396 bool HtmlExport::CreateNavBarFrames()
2398 bool bOk = true;
2399 OUString aButton;
2401 if( mbDocColors )
2403 SetDocColors();
2404 maBackColor = maFirstPageColor;
2407 for( int nFile = 0; nFile < 3 && bOk; nFile++ )
2409 OUStringBuffer aStr(maHTMLHeader);
2410 aStr.append(CreateMetaCharset());
2411 aStr.append(" <title>");
2412 aStr.append(StringToHTMLString(maPageNames[0]));
2413 aStr.append("</title>\r\n</head>\r\n");
2414 aStr.append(CreateBodyTag());
2415 aStr.append("<center>\r\n");
2417 // first page
2418 aButton = SD_RESSTR(STR_HTMLEXP_FIRSTPAGE);
2419 if(mnButtonThema != -1)
2420 aButton = CreateImage(GetButtonName((nFile == 0 || mnSdPageCount == 1?
2421 BTN_FIRST_0:BTN_FIRST_1)), aButton);
2423 if(nFile != 0 && mnSdPageCount > 1)
2424 aButton = CreateLink("JavaScript:parent.NavigateAbs(0)", aButton);
2426 aStr.append(aButton);
2427 aStr.append("\r\n");
2429 // to the previous page
2430 aButton = SD_RESSTR(STR_PUBLISH_BACK);
2431 if(mnButtonThema != -1)
2432 aButton = CreateImage(GetButtonName((nFile == 0 || mnSdPageCount == 1?
2433 BTN_PREV_0:BTN_PREV_1)), aButton);
2435 if(nFile != 0 && mnSdPageCount > 1)
2436 aButton = CreateLink("JavaScript:parent.NavigateRel(-1)", aButton);
2438 aStr.append(aButton);
2439 aStr.append("\r\n");
2441 // to the next page
2442 aButton = SD_RESSTR(STR_PUBLISH_NEXT);
2443 if(mnButtonThema != -1)
2444 aButton = CreateImage(GetButtonName((nFile ==2 || mnSdPageCount == 1?
2445 BTN_NEXT_0:BTN_NEXT_1)), aButton);
2447 if(nFile != 2 && mnSdPageCount > 1)
2448 aButton = CreateLink("JavaScript:parent.NavigateRel(1)", aButton);
2450 aStr.append(aButton);
2451 aStr.append("\r\n");
2453 // to the last page
2454 aButton = SD_RESSTR(STR_HTMLEXP_LASTPAGE);
2455 if(mnButtonThema != -1)
2456 aButton = CreateImage(GetButtonName((nFile ==2 || mnSdPageCount == 1?
2457 BTN_LAST_0:BTN_LAST_1)), aButton);
2459 if(nFile != 2 && mnSdPageCount > 1)
2461 OUString aLink("JavaScript:parent.NavigateAbs(" +
2462 OUString::number(mnSdPageCount-1) + ")");
2464 aButton = CreateLink(aLink, aButton);
2467 aStr.append(aButton);
2468 aStr.append("\r\n");
2470 // content
2471 if (mbContentsPage)
2473 aButton = SD_RESSTR(STR_PUBLISH_OUTLINE);
2474 if(mnButtonThema != -1)
2475 aButton = CreateImage(GetButtonName(BTN_INDEX), aButton);
2477 // to the overview
2478 aStr.append(CreateLink(maIndex, aButton, "_top"));
2479 aStr.append("\r\n");
2482 // text mode
2483 if(mbImpress)
2485 aButton = SD_RESSTR(STR_HTMLEXP_SETTEXT);
2486 if(mnButtonThema != -1)
2487 aButton = CreateImage(GetButtonName(BTN_TEXT), aButton);
2489 OUString aText0("text0" + maHTMLExtension);
2490 aStr.append(CreateLink(aText0, aButton, "_top"));
2491 aStr.append("\r\n");
2494 // and finished...
2495 aStr.append("</center>\r\n");
2496 aStr.append("</body>\r\n</html>");
2498 OUString aFileName("navbar" + OUString::number(nFile));
2500 bOk = WriteHtml(aFileName, true, aStr.makeStringAndClear());
2502 if (mpProgress)
2503 mpProgress->SetState(++mnPagesWritten);
2506 // the navigation bar outliner closed...
2507 if(bOk)
2509 OUStringBuffer aStr(maHTMLHeader);
2510 aStr.append(CreateMetaCharset());
2511 aStr.append(" <title>");
2512 aStr.append(StringToHTMLString(maPageNames[0]));
2513 aStr.append("</title>\r\n</head>\r\n");
2514 aStr.append(CreateBodyTag());
2516 aButton = SD_RESSTR(STR_HTMLEXP_OUTLINE);
2517 if(mnButtonThema != -1)
2518 aButton = CreateImage(GetButtonName(BTN_MORE), aButton);
2520 aStr.append(CreateLink("JavaScript:parent.ExpandOutline()", aButton));
2521 aStr.append("</body>\r\n</html>");
2523 bOk = WriteHtml("navbar3", true, aStr.makeStringAndClear());
2525 if (mpProgress)
2526 mpProgress->SetState(++mnPagesWritten);
2529 // ... and the outliner open
2530 if( bOk )
2532 OUStringBuffer aStr(maHTMLHeader);
2533 aStr.append(CreateMetaCharset());
2534 aStr.append(" <title>");
2535 aStr.append(StringToHTMLString(maPageNames[0]));
2536 aStr.append("</title>\r\n</head>\r\n");
2537 aStr.append(CreateBodyTag());
2539 aButton = SD_RESSTR(STR_HTMLEXP_NOOUTLINE);
2540 if(mnButtonThema != -1)
2541 aButton = CreateImage(GetButtonName(BTN_LESS), aButton);
2543 aStr.append(CreateLink("JavaScript:parent.CollapseOutline()", aButton));
2544 aStr.append("</body>\r\n</html>");
2546 bOk = WriteHtml("navbar4", true, aStr.makeStringAndClear());
2548 if (mpProgress)
2549 mpProgress->SetState(++mnPagesWritten);
2553 return bOk;
2556 // create button bar for standard
2557 OUString HtmlExport::CreateNavBar( sal_uInt16 nSdPage, bool bIsText ) const
2559 // prepare button bar
2560 OUString aStrNavFirst(SD_RESSTR(STR_HTMLEXP_FIRSTPAGE));
2561 OUString aStrNavPrev(SD_RESSTR(STR_PUBLISH_BACK));
2562 OUString aStrNavNext(SD_RESSTR(STR_PUBLISH_NEXT));
2563 OUString aStrNavLast(SD_RESSTR(STR_HTMLEXP_LASTPAGE));
2564 OUString aStrNavContent(SD_RESSTR(STR_PUBLISH_OUTLINE));
2565 OUString aStrNavText;
2566 if( bIsText )
2568 aStrNavText = SD_RESSTR(STR_HTMLEXP_SETGRAPHIC);
2570 else
2572 aStrNavText = SD_RESSTR(STR_HTMLEXP_SETTEXT);
2575 if(!bIsText && mnButtonThema != -1)
2577 if(nSdPage<1 || mnSdPageCount == 1)
2579 aStrNavFirst = CreateImage(GetButtonName(BTN_FIRST_0), aStrNavFirst);
2580 aStrNavPrev = CreateImage(GetButtonName(BTN_PREV_0), aStrNavPrev);
2582 else
2584 aStrNavFirst = CreateImage(GetButtonName(BTN_FIRST_1), aStrNavFirst);
2585 aStrNavPrev = CreateImage(GetButtonName(BTN_PREV_1), aStrNavPrev);
2588 if(nSdPage == mnSdPageCount-1 || mnSdPageCount == 1)
2590 aStrNavNext = CreateImage(GetButtonName(BTN_NEXT_0), aStrNavNext);
2591 aStrNavLast = CreateImage(GetButtonName(BTN_LAST_0), aStrNavLast);
2593 else
2595 aStrNavNext = CreateImage(GetButtonName(BTN_NEXT_1), aStrNavNext);
2596 aStrNavLast = CreateImage(GetButtonName(BTN_LAST_1), aStrNavLast);
2599 aStrNavContent = CreateImage(GetButtonName(BTN_INDEX), aStrNavContent);
2600 aStrNavText = CreateImage(GetButtonName(BTN_TEXT), aStrNavText);
2603 OUStringBuffer aStr("<center>\r\n"); //<table><tr>\r\n");
2605 // first page
2606 if(nSdPage > 0)
2607 aStr.append(CreateLink( bIsText ? maTextFiles[0] : maHTMLFiles[0],aStrNavFirst));
2608 else
2609 aStr.append(aStrNavFirst);
2610 aStr.append(' ');
2612 // to Previous page
2613 if(nSdPage > 0)
2614 aStr.append(CreateLink( bIsText ? maTextFiles[nSdPage-1]
2615 : maHTMLFiles[nSdPage-1], aStrNavPrev));
2616 else
2617 aStr.append(aStrNavPrev);
2618 aStr.append(' ');
2620 // to Next page
2621 if(nSdPage < mnSdPageCount-1)
2622 aStr.append(CreateLink( bIsText ? maTextFiles[nSdPage+1]
2623 : maHTMLFiles[nSdPage+1], aStrNavNext));
2624 else
2625 aStr.append(aStrNavNext);
2626 aStr.append(' ');
2628 // to Last page
2629 if(nSdPage < mnSdPageCount-1)
2630 aStr.append(CreateLink( bIsText ? maTextFiles[mnSdPageCount-1]
2631 : maHTMLFiles[mnSdPageCount-1],
2632 aStrNavLast));
2633 else
2634 aStr.append(aStrNavLast);
2635 aStr.append(' ');
2637 // to Index page
2638 if (mbContentsPage)
2640 aStr.append(CreateLink(maIndex, aStrNavContent));
2641 aStr.append(' ');
2644 // Text/Graphics
2645 if(mbImpress)
2647 aStr.append(CreateLink( bIsText ? (mbFrames ? maFramePage : maHTMLFiles[nSdPage])
2648 : maTextFiles[nSdPage], aStrNavText));
2652 aStr.append("</center><br>\r\n");
2654 return aStr.makeStringAndClear();
2657 // export navigation graphics from button set
2658 bool HtmlExport::CreateBitmaps()
2660 if(mnButtonThema != -1 && mpButtonSet.get() )
2662 for( int nButton = 0; nButton != SAL_N_ELEMENTS(pButtonNames); nButton++ )
2664 if(!mbFrames && (nButton == BTN_MORE || nButton == BTN_LESS))
2665 continue;
2667 if(!mbImpress && (nButton == BTN_TEXT || nButton == BTN_MORE || nButton == BTN_LESS ))
2668 continue;
2670 OUString aFull(maExportPath);
2671 aFull += GetButtonName(nButton);
2672 mpButtonSet->exportButton( mnButtonThema, aFull, GetButtonName(nButton) );
2675 return true;
2678 // creates the <body> tag, including the specified color attributes
2679 OUString HtmlExport::CreateBodyTag() const
2681 OUStringBuffer aStr( "<body" );
2683 if( mbUserAttr || mbDocColors )
2685 Color aTextColor( maTextColor );
2686 if( (aTextColor == COL_AUTO) && (!maBackColor.IsDark()) )
2687 aTextColor = COL_BLACK;
2689 aStr.append(" text=\"");
2690 aStr.append(ColorToHTMLString( aTextColor ));
2691 aStr.append("\" bgcolor=\"");
2692 aStr.append(ColorToHTMLString( maBackColor ));
2693 aStr.append("\" link=\"");
2694 aStr.append(ColorToHTMLString( maLinkColor ));
2695 aStr.append("\" vlink=\"");
2696 aStr.append(ColorToHTMLString( maVLinkColor ));
2697 aStr.append("\" alink=\"");
2698 aStr.append(ColorToHTMLString( maALinkColor ));
2699 aStr.append("\"");
2702 aStr.append(">\r\n");
2704 return aStr.makeStringAndClear();
2707 // creates a hyperlink
2708 OUString HtmlExport::CreateLink( const OUString& aLink,
2709 const OUString& aText,
2710 const OUString& aTarget )
2712 OUStringBuffer aStr( "<a href=\"" );
2713 aStr.append(aLink);
2714 if (!aTarget.isEmpty())
2716 aStr.append("\" target=\"");
2717 aStr.append(aTarget);
2719 aStr.append("\">");
2720 aStr.append(aText);
2721 aStr.append("</a>");
2723 return aStr.makeStringAndClear();
2726 // creates a image tag
2727 OUString HtmlExport::CreateImage( const OUString& aImage, const OUString& aAltText,
2728 sal_Int16 nWidth,
2729 sal_Int16 nHeight )
2731 OUStringBuffer aStr( "<img src=\"");
2732 aStr.append(aImage);
2733 aStr.append("\" border=0");
2735 if (!aAltText.isEmpty())
2737 aStr.append(" alt=\"");
2738 aStr.append(aAltText);
2739 aStr.append('"');
2741 else
2743 // Agerskov: HTML 4.01 has to have an alt attribute even if it is an empty string
2744 aStr.append(" alt=\"\"");
2747 if(nWidth > -1)
2749 aStr.append(" width=" + OUString::number(nWidth));
2752 if(nHeight > -1)
2754 aStr.append(" height=" + OUString::number(nHeight));
2757 aStr.append('>');
2759 return aStr.makeStringAndClear();
2762 // create area for a circle; we expect pixel coordinates
2763 OUString HtmlExport::ColorToHTMLString( Color aColor )
2765 static const char hex[] = "0123456789ABCDEF";
2766 OUStringBuffer aStr( "#xxxxxx" );
2767 aStr[1] = hex[(aColor.GetRed() >> 4) & 0xf];
2768 aStr[2] = hex[aColor.GetRed() & 0xf];
2769 aStr[3] = hex[(aColor.GetGreen() >> 4) & 0xf];
2770 aStr[4] = hex[aColor.GetGreen() & 0xf];
2771 aStr[5] = hex[(aColor.GetBlue() >> 4) & 0xf];
2772 aStr[6] = hex[aColor.GetBlue() & 0xf];
2774 return aStr.makeStringAndClear();
2777 // create area for a circle; we expect pixel coordinates
2778 OUString HtmlExport::CreateHTMLCircleArea( sal_uLong nRadius,
2779 sal_uLong nCenterX,
2780 sal_uLong nCenterY,
2781 const OUString& rHRef )
2783 OUString aStr(
2784 "<area shape=\"circle\" alt=\"\" coords=\"" +
2785 OUString::number(nCenterX) + "," +
2786 OUString::number(nCenterY) + "," +
2787 OUString::number(nRadius) +
2788 "\" href=\"" + rHRef + "\">\n");
2790 return aStr;
2793 // create area for a polygon; we expect pixel coordinates
2794 OUString HtmlExport::CreateHTMLPolygonArea( const ::basegfx::B2DPolyPolygon& rPolyPolygon,
2795 Size aShift, double fFactor, const OUString& rHRef )
2797 OUStringBuffer aStr;
2798 const sal_uInt32 nNoOfPolygons(rPolyPolygon.count());
2800 for ( sal_uInt32 nXPoly = 0L; nXPoly < nNoOfPolygons; nXPoly++ )
2802 const ::basegfx::B2DPolygon& aPolygon = rPolyPolygon.getB2DPolygon(nXPoly);
2803 const sal_uInt32 nNoOfPoints(aPolygon.count());
2805 aStr.append("<area shape=\"polygon\" alt=\"\" coords=\"");
2807 for ( sal_uInt32 nPoint = 0L; nPoint < nNoOfPoints; nPoint++ )
2809 const ::basegfx::B2DPoint aB2DPoint(aPolygon.getB2DPoint(nPoint));
2810 Point aPnt(FRound(aB2DPoint.getX()), FRound(aB2DPoint.getY()));
2811 // coordinates are relative to the physical page origin, not the
2812 // origin of ordinates
2813 aPnt.Move(aShift.Width(), aShift.Height());
2815 aPnt.X() = (long)(aPnt.X() * fFactor);
2816 aPnt.Y() = (long)(aPnt.Y() * fFactor);
2817 aStr.append(OUString::number(aPnt.X()) + "," + OUString::number(aPnt.Y()));
2819 if (nPoint < nNoOfPoints - 1)
2820 aStr.append(',');
2822 aStr.append("\" href=\"" + rHRef + "\">\n");
2825 return aStr.makeStringAndClear();
2828 // create area for a rectangle; we expect pixel coordinates
2829 OUString HtmlExport::CreateHTMLRectArea( const Rectangle& rRect,
2830 const OUString& rHRef )
2832 OUString aStr(
2833 "<area shape=\"rect\" alt=\"\" coords=\"" +
2834 OUString::number(rRect.Left()) + "," +
2835 OUString::number(rRect.Top()) + "," +
2836 OUString::number(rRect.Right()) + "," +
2837 OUString::number(rRect.Bottom()) +
2838 "\" href=\"" + rHRef + "\">\n");
2840 return aStr;
2843 // escapes a string for html
2844 OUString HtmlExport::StringToHTMLString( const OUString& rString )
2846 SvMemoryStream aMemStm;
2847 HTMLOutFuncs::Out_String( aMemStm, rString, RTL_TEXTENCODING_UTF8 );
2848 aMemStm.WriteChar( (char) 0 );
2849 sal_Int32 nLength = strlen(static_cast<char const *>(aMemStm.GetData()));
2850 return OUString( static_cast<char const *>(aMemStm.GetData()), nLength, RTL_TEXTENCODING_UTF8 );
2853 // creates a url for a specific page
2854 OUString HtmlExport::CreatePageURL( sal_uInt16 nPgNum )
2856 if(mbFrames)
2858 return OUString("JavaScript:parent.NavigateAbs(" +
2859 OUString::number(nPgNum) + ")");
2861 else
2862 return maHTMLFiles[nPgNum];
2865 bool HtmlExport::CopyScript( const OUString& rPath, const OUString& rSource, const OUString& rDest, bool bUnix /* = false */ )
2867 INetURLObject aURL( SvtPathOptions().GetConfigPath() );
2868 OUStringBuffer aScriptBuf;
2870 aURL.Append( OUString("webcast") );
2871 aURL.Append( rSource );
2873 meEC.SetContext( STR_HTMLEXP_ERROR_OPEN_FILE, rSource );
2875 sal_uLong nErr = 0;
2876 SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::NO_DECODE ), StreamMode::READ );
2878 if( pIStm )
2880 OString aLine;
2882 while( pIStm->ReadLine( aLine ) )
2884 aScriptBuf.appendAscii( aLine.getStr() );
2885 if( bUnix )
2887 aScriptBuf.append("\n");
2889 else
2891 aScriptBuf.append("\r\n");
2895 nErr = pIStm->GetError();
2896 delete pIStm;
2899 if( nErr != 0 )
2901 ErrorHandler::HandleError( nErr );
2902 return (bool) nErr;
2905 OUString aScript(aScriptBuf.makeStringAndClear());
2906 aScript = aScript.replaceAll("$$1", getDocumentTitle());
2907 aScript = aScript.replaceAll("$$2", RESTOHTML(STR_WEBVIEW_SAVE));
2908 aScript = aScript.replaceAll("$$3", maCGIPath);
2909 aScript = aScript.replaceAll("$$4", OUString::number(mnWidthPixel));
2910 aScript = aScript.replaceAll("$$5", OUString::number(mnHeightPixel));
2912 OUString aDest(rPath + rDest);
2914 meEC.SetContext( STR_HTMLEXP_ERROR_CREATE_FILE, rDest );
2915 // write script file
2917 EasyFile aFile;
2918 SvStream* pStr;
2919 nErr = aFile.createStream(aDest, pStr);
2920 if(nErr == 0)
2922 OString aStr(OUStringToOString(aScript,
2923 RTL_TEXTENCODING_UTF8));
2924 pStr->WriteCharPtr( aStr.getStr() );
2926 nErr = aFile.close();
2930 if (mpProgress)
2931 mpProgress->SetState(++mnPagesWritten);
2933 if( nErr != 0 )
2934 ErrorHandler::HandleError( nErr );
2936 return nErr == 0;
2939 static const char * ASP_Scripts[] = { "common.inc", "webcast.asp", "show.asp", "savepic.asp", "poll.asp", "editpic.asp" };
2941 /** creates and saves the ASP scripts for WebShow */
2942 bool HtmlExport::CreateASPScripts()
2944 for( sal_uInt16 n = 0; n < (sizeof( ASP_Scripts ) / sizeof(char *)); n++ )
2946 OUString aScript = OUString::createFromAscii(ASP_Scripts[n]);
2948 if(!CopyScript(maExportPath, aScript, aScript))
2949 return false;
2952 if (!CopyScript(maExportPath, "edit.asp", maIndex))
2953 return false;
2955 return true;
2958 static const char *PERL_Scripts[] = { "webcast.pl", "common.pl", "editpic.pl", "poll.pl", "savepic.pl", "show.pl" };
2960 // creates and saves the PERL scripts for WebShow
2961 bool HtmlExport::CreatePERLScripts()
2963 for( sal_uInt16 n = 0; n < (sizeof( PERL_Scripts ) / sizeof(char *)); n++ )
2965 OUString aScript = OUString::createFromAscii(PERL_Scripts[n]);
2967 if(!CopyScript(maExportPath, aScript, aScript, true))
2968 return false;
2971 if (!CopyScript(maExportPath, "edit.pl", maIndex, true))
2972 return false;
2974 if (!CopyScript(maExportPath, "index.pl", maIndexUrl, true))
2975 return false;
2977 return true;
2980 // creates a list with names of the saved images
2981 bool HtmlExport::CreateImageFileList()
2983 OUStringBuffer aStr;
2984 for( sal_uInt16 nSdPage = 0; nSdPage < mnSdPageCount; nSdPage++)
2986 aStr.append(OUString::number(nSdPage + 1));
2987 aStr.append(';');
2988 aStr.append(maURLPath);
2989 aStr.append(maImageFiles[nSdPage]);
2990 aStr.append("\r\n");
2993 bool bOk = WriteHtml("picture.txt", false, aStr.makeStringAndClear());
2995 if (mpProgress)
2996 mpProgress->SetState(++mnPagesWritten);
2998 return bOk;
3001 // creates a file with the actual page number
3002 bool HtmlExport::CreateImageNumberFile()
3004 OUString aFileName("currpic.txt");
3005 OUString aFull(maExportPath + aFileName);
3007 meEC.SetContext( STR_HTMLEXP_ERROR_CREATE_FILE, aFileName );
3008 EasyFile aFile;
3009 SvStream* pStr;
3010 sal_uLong nErr = aFile.createStream(aFull, pStr);
3011 if(nErr == 0)
3013 pStr->WriteCharPtr( (const char *)"1" );
3014 nErr = aFile.close();
3017 if (mpProgress)
3018 mpProgress->SetState(++mnPagesWritten);
3020 if( nErr != 0 )
3021 ErrorHandler::HandleError( nErr );
3023 return nErr == 0;
3026 OUString HtmlExport::InsertSound( const OUString& rSoundFile )
3028 if (rSoundFile.isEmpty())
3029 return rSoundFile;
3031 INetURLObject aURL( rSoundFile );
3032 OUString aSoundFileName = aURL.getName();
3034 DBG_ASSERT( aURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
3036 OUString aStr("<embed src=\"" + aSoundFileName +
3037 "\" hidden=\"true\" autostart=\"true\">");
3039 CopyFile(rSoundFile, maExportPath + aSoundFileName);
3041 return aStr;
3044 bool HtmlExport::CopyFile( const OUString& rSourceFile, const OUString& rDestFile )
3046 meEC.SetContext( STR_HTMLEXP_ERROR_COPY_FILE, rSourceFile, rDestFile );
3047 osl::FileBase::RC Error = osl::File::copy( rSourceFile, rDestFile );
3049 if( Error != osl::FileBase::E_None )
3051 ErrorHandler::HandleError(Error);
3052 return false;
3054 else
3056 return true;
3060 bool HtmlExport::checkFileExists( Reference< ::com::sun::star::ucb::XSimpleFileAccess3 >& xFileAccess, OUString const & aFileName )
3064 OUString url( maExportPath );
3065 url += aFileName;
3066 return xFileAccess->exists( url );
3068 catch( com::sun::star::uno::Exception& )
3070 OSL_FAIL(OString(OString("sd::HtmlExport::checkFileExists(), exception caught: ") +
3071 OUStringToOString( comphelper::anyToString( cppu::getCaughtException() ), RTL_TEXTENCODING_UTF8 )).getStr() );
3074 return false;
3077 bool HtmlExport::checkForExistingFiles()
3079 bool bFound = false;
3083 Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
3084 uno::Reference<ucb::XSimpleFileAccess3> xFA(ucb::SimpleFileAccess::create(xContext));
3086 sal_uInt16 nSdPage;
3087 for( nSdPage = 0; !bFound && (nSdPage < mnSdPageCount); nSdPage++)
3089 if( checkFileExists( xFA, maImageFiles[nSdPage] ) ||
3090 checkFileExists( xFA, maHTMLFiles[nSdPage] ) ||
3091 checkFileExists( xFA, maThumbnailFiles[nSdPage] ) ||
3092 checkFileExists( xFA, maPageNames[nSdPage] ) ||
3093 checkFileExists( xFA, maTextFiles[nSdPage] ) )
3095 bFound = true;
3099 if( !bFound && mbDownload )
3100 bFound = checkFileExists( xFA, maDocFileName );
3102 if( !bFound && mbFrames )
3103 bFound = checkFileExists( xFA, maFramePage );
3105 if( bFound )
3107 ResMgr *pResMgr = ResMgr::CreateResMgr( "dbw" );
3108 if( pResMgr )
3110 ResId aResId( 4077, *pResMgr );
3111 OUString aMsg( aResId.toString() );
3113 OUString aSystemPath;
3114 osl::FileBase::getSystemPathFromFileURL( maExportPath, aSystemPath );
3115 aMsg = aMsg.replaceFirst( "%FILENAME", aSystemPath );
3116 ScopedVclPtrInstance< WarningBox > aWarning( nullptr, WB_YES_NO | WB_DEF_YES, aMsg );
3117 aWarning->SetImage( WarningBox::GetStandardImage() );
3118 bFound = ( RET_NO == aWarning->Execute() );
3120 delete pResMgr;
3122 else
3124 bFound = false;
3128 catch( Exception& )
3130 OSL_FAIL(OString(OString("sd::HtmlExport::checkForExistingFiles(), exception caught: ") +
3131 OUStringToOString( comphelper::anyToString( cppu::getCaughtException() ), RTL_TEXTENCODING_UTF8 )).getStr() );
3132 bFound = false;
3135 return bFound;
3138 OUString HtmlExport::GetButtonName( int nButton )
3140 return OUString::createFromAscii(pButtonNames[nButton]);
3143 EasyFile::EasyFile()
3145 pMedium = NULL;
3146 pOStm = NULL;
3147 bOpen = false;
3150 EasyFile::~EasyFile()
3152 if( bOpen )
3153 (void)close();
3156 sal_uLong EasyFile::createStream( const OUString& rUrl, SvStream* &rpStr )
3158 sal_uLong nErr = 0;
3160 if(bOpen)
3161 nErr = close();
3163 OUString aFileName;
3165 if( nErr == 0 )
3166 nErr = createFileName( rUrl, aFileName );
3168 if( nErr == 0 )
3170 pOStm = ::utl::UcbStreamHelper::CreateStream( aFileName, StreamMode::WRITE | StreamMode::TRUNC );
3171 if( pOStm )
3173 bOpen = true;
3174 nErr = pOStm->GetError();
3176 else
3178 nErr = ERRCODE_SFX_CANTCREATECONTENT;
3182 if( nErr != 0 )
3184 bOpen = false;
3185 delete pMedium;
3186 delete pOStm;
3187 pOStm = NULL;
3190 rpStr = pOStm;
3192 return nErr;
3195 sal_uLong EasyFile::createFileName( const OUString& rURL, OUString& rFileName )
3197 sal_uLong nErr = 0;
3199 if( bOpen )
3200 nErr = close();
3202 if( nErr == 0 )
3204 INetURLObject aURL( rURL );
3206 if( aURL.GetProtocol() == INetProtocol::NotValid )
3208 OUString aURLStr;
3209 ::utl::LocalFileHelper::ConvertPhysicalNameToURL( rURL, aURLStr );
3210 aURL = INetURLObject( aURLStr );
3212 DBG_ASSERT( aURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
3213 rFileName = aURL.GetMainURL( INetURLObject::NO_DECODE );
3216 return nErr;
3219 sal_uLong EasyFile::close()
3221 sal_uLong nErr = 0;
3223 delete pOStm;
3224 pOStm = NULL;
3226 bOpen = false;
3228 if( pMedium )
3230 // transmitted
3231 pMedium->Close();
3232 pMedium->Commit();
3234 nErr = pMedium->GetError();
3236 delete pMedium;
3237 pMedium = NULL;
3240 return nErr;
3243 // This class helps reporting errors during file i/o
3244 HtmlErrorContext::HtmlErrorContext(vcl::Window *_pWin)
3245 : ErrorContext(_pWin)
3247 mnResId = 0;
3250 bool HtmlErrorContext::GetString( sal_uLong, OUString& rCtxStr )
3252 DBG_ASSERT( mnResId != 0, "No error context set" );
3253 if( mnResId == 0 )
3254 return false;
3256 rCtxStr = SdResId( mnResId ).toString();
3258 rCtxStr = rCtxStr.replaceAll( OUString("$(URL1)"), maURL1 );
3259 rCtxStr = rCtxStr.replaceAll( OUString("$(URL2)"), maURL2 );
3261 return true;
3264 void HtmlErrorContext::SetContext( sal_uInt16 nResId, const OUString& rURL )
3266 mnResId = nResId;
3267 maURL1 = rURL;
3268 maURL2.clear();
3271 void HtmlErrorContext::SetContext( sal_uInt16 nResId, const OUString& rURL1, const OUString& rURL2 )
3273 mnResId = nResId;
3274 maURL1 = rURL1;
3275 maURL2 = rURL2;
3278 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */