fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / sd / source / filter / html / htmlex.cxx
blobbc5891b64924ea4a6c2a771aa05f2ce0c823074b
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 .
21 #include "htmlex.hxx"
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/progress.hxx>
36 #include <vcl/wrkwin.hxx>
37 #include <svl/aeitem.hxx>
38 #include <svx/svditer.hxx>
39 #include <svtools/imaprect.hxx>
40 #include <svtools/imapcirc.hxx>
41 #include <svtools/imappoly.hxx>
42 #include <vcl/msgbox.hxx>
43 #include <sfx2/app.hxx>
44 #include <editeng/outlobj.hxx>
45 #include <editeng/editobj.hxx>
46 #include <svx/svdopath.hxx>
47 #include <svx/xoutbmp.hxx>
48 #include <svtools/htmlout.hxx>
49 #include <sfx2/docfile.hxx>
50 #include <vcl/cvtgrf.hxx>
51 #include <svtools/colorcfg.hxx>
52 #include <vcl/graphicfilter.hxx>
53 #include <editeng/colritem.hxx>
54 #include <editeng/editeng.hxx>
55 #include <editeng/wghtitem.hxx>
56 #include <editeng/udlnitem.hxx>
57 #include <editeng/postitem.hxx>
58 #include <editeng/crossedoutitem.hxx>
59 #include <editeng/flditem.hxx>
60 #include <sfx2/dispatch.hxx>
61 #include <sfx2/fcontnr.hxx>
62 #include <svl/style.hxx>
63 #include <editeng/frmdiritem.hxx>
64 #include <svx/svdoutl.hxx>
65 #include <tools/urlobj.hxx> // INetURLObject
66 #include <vcl/bmpacc.hxx>
67 #include <svtools/sfxecode.hxx>
68 #include <com/sun/star/beans/PropertyState.hpp>
69 #include <tools/resmgr.hxx>
70 #include "comphelper/anytostring.hxx"
71 #include "cppuhelper/exc_hlp.hxx"
73 #include "drawdoc.hxx"
74 #include "htmlpublishmode.hxx"
75 #include "Outliner.hxx"
76 #include "sdpage.hxx"
77 #include "sdattr.hxx"
78 #include "glob.hrc"
79 #include "anminfo.hxx"
80 #include "imapinfo.hxx"
81 #include "sdresid.hxx"
82 #include "buttonset.hxx"
83 #include <basegfx/polygon/b2dpolygon.hxx>
85 using namespace ::com::sun::star;
86 using namespace ::com::sun::star::uno;
87 using namespace ::com::sun::star::beans;
88 using namespace ::com::sun::star::frame;
89 using namespace ::com::sun::star::lang;
90 using namespace ::com::sun::star::document;
92 // get parameter from Itemset
94 #define RESTOHTML( res ) StringToHTMLString(String(SdResId(res)))
96 const char *pButtonNames[] =
98 "first-inactive.png",
99 "first.png",
100 "left-inactive.png",
101 "left.png",
102 "right-inactive.png",
103 "right.png",
104 "last-inactive.png",
105 "last.png",
106 "home.png",
107 "text.png",
108 "expand.png",
109 "collapse.png",
112 #define BTN_FIRST_0 0
113 #define BTN_FIRST_1 1
114 #define BTN_PREV_0 2
115 #define BTN_PREV_1 3
116 #define BTN_NEXT_0 4
117 #define BTN_NEXT_1 5
118 #define BTN_LAST_0 6
119 #define BTN_LAST_1 7
120 #define BTN_INDEX 8
121 #define BTN_TEXT 9
122 #define BTN_MORE 10
123 #define BTN_LESS 11
125 // *********************************************************************
126 // Helper class for the simple creation of files local/remote
127 // *********************************************************************
128 class EasyFile
130 private:
131 SvStream* pOStm;
132 SfxMedium* pMedium;
133 bool bOpen;
135 public:
137 EasyFile();
138 ~EasyFile();
140 sal_uLong createStream( const String& rUrl, SvStream*& rpStr );
141 sal_uLong createFileName( const String& rUrl, String& rFileName );
142 sal_uLong close();
145 // *********************************************************************
146 // Helper class for the embedding of text attributes into the html output
147 // *********************************************************************
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 String maLink;
160 String maTarget;
162 public:
163 HtmlState( Color aDefColor );
165 String SetWeight( bool bWeight );
166 String SetItalic( bool bItalic );
167 String SetUnderline( bool bUnderline );
168 String SetColor( Color aColor );
169 String SetStrikeout( bool bStrike );
170 String SetLink( const String& aLink, const String& aTarget );
171 String Flush();
174 // =====================================================================
175 // close all still open tags
176 // =====================================================================
177 String HtmlState::Flush()
179 String aStr, aEmpty;
181 aStr += SetWeight(false);
182 aStr += SetItalic(false);
183 aStr += SetUnderline(false);
184 aStr += SetStrikeout(false);
185 aStr += SetColor(maDefColor);
186 aStr += SetLink(aEmpty,aEmpty);
188 return aStr;
191 // =====================================================================
192 // c'tor with default color for the page
193 // =====================================================================
194 HtmlState::HtmlState( Color aDefColor )
196 mbColor = false;
197 mbWeight = false;
198 mbItalic = false;
199 mbUnderline = false;
200 mbLink = false;
201 mbStrike = false;
202 maDefColor = aDefColor;
205 // =====================================================================
206 // enables/disables bold print
207 // =====================================================================
208 String HtmlState::SetWeight( bool bWeight )
210 String aStr;
212 if(bWeight && !mbWeight)
213 aStr.AppendAscii( "<b>" );
214 else if(!bWeight && mbWeight)
215 aStr.AppendAscii( "</b>" );
217 mbWeight = bWeight;
218 return aStr;
221 // =====================================================================
222 // enables/disables italic
223 // =====================================================================
224 String HtmlState::SetItalic( bool bItalic )
226 String aStr;
228 if(bItalic && !mbItalic)
229 aStr.AppendAscii( "<i>" );
230 else if(!bItalic && mbItalic)
231 aStr.AppendAscii( "</i>" );
233 mbItalic = bItalic;
234 return aStr;
237 // =====================================================================
238 // enables/disables underlines
239 // =====================================================================
240 String HtmlState::SetUnderline( bool bUnderline )
242 String aStr;
244 if(bUnderline && !mbUnderline)
245 aStr.AppendAscii( "<u>" );
246 else if(!bUnderline && mbUnderline)
247 aStr.AppendAscii( "</u>" );
249 mbUnderline = bUnderline;
250 return aStr;
253 // =====================================================================
254 // enables/disables strike through
255 // =====================================================================
256 String HtmlState::SetStrikeout( bool bStrike )
258 String aStr;
260 if(bStrike && !mbStrike)
261 aStr.AppendAscii( "<strike>" );
262 else if(!bStrike && mbStrike)
263 aStr.AppendAscii( "</strike>" );
265 mbStrike = bStrike;
266 return aStr;
269 // =====================================================================
270 // Sets the specified text color
271 // =====================================================================
272 String HtmlState::SetColor( Color aColor )
274 String aStr;
276 if(mbColor && aColor == maColor)
277 return aStr;
279 if(mbColor)
281 aStr.AppendAscii( "</font>" );
282 mbColor = false;
285 if(aColor != maDefColor)
287 maColor = aColor;
289 aStr.AppendAscii( "<font color=\"" );
290 aStr += HtmlExport::ColorToHTMLString(aColor);
291 aStr.AppendAscii( "\">" );
293 mbColor = true;
296 return aStr;
299 // =====================================================================
300 // enables/disables a hyperlink
301 // =====================================================================
302 String HtmlState::SetLink( const String& aLink, const String& aTarget )
304 String aStr;
306 if(mbLink&&maLink == aLink&&maTarget==aTarget)
307 return aStr;
309 if(mbLink)
311 aStr.AppendAscii( "</a>" );
312 mbLink = false;
315 if(aLink.Len())
317 aStr.AppendAscii( "<a href=\"" );
318 aStr += HtmlExport::StringToURL(aLink);
319 if(aTarget.Len())
321 aStr.AppendAscii( "\" target=\"" );
322 aStr += aTarget;
324 aStr.AppendAscii( "\">" );
325 mbLink = true;
326 maLink = aLink;
327 maTarget = aTarget;
330 return aStr;
333 // *********************************************************************
334 // methods of the class HtmlExport
335 // *********************************************************************
337 static String getParagraphStyle( SdrOutliner* pOutliner, sal_Int32 nPara )
339 SfxItemSet aParaSet( pOutliner->GetParaAttribs( nPara ) );
341 String sStyle( RTL_CONSTASCII_USTRINGPARAM("direction:") );
342 if( static_cast<const SvxFrameDirectionItem*>(aParaSet.GetItem( EE_PARA_WRITINGDIR ))->GetValue() == FRMDIR_HORI_RIGHT_TOP )
344 sStyle += String( RTL_CONSTASCII_USTRINGPARAM("rtl;") );
346 else
348 sStyle += String( RTL_CONSTASCII_USTRINGPARAM("ltr;") );
350 return sStyle;
353 // =====================================================================
354 // constructor for the html export helper classes
355 // =====================================================================
356 HtmlExport::HtmlExport(
357 OUString aPath,
358 const Sequence< PropertyValue >& rParams,
359 SdDrawDocument* pExpDoc,
360 ::sd::DrawDocShell* pDocShell )
361 : maPath( aPath ),
362 mpDoc(pExpDoc),
363 mpDocSh( pDocShell ),
364 meEC(NULL),
365 meMode( PUBLISH_HTML ),
366 mbContentsPage(false),
367 mnButtonThema(-1),
368 mnWidthPixel( PUB_MEDRES_WIDTH ),
369 meFormat( FORMAT_JPG ),
370 mbNotes(false),
371 mnCompression( -1 ),
372 mbDownload( false ),
373 mbSlideSound(true),
374 mbHiddenSlides(true),
375 mbUserAttr(false),
376 mbDocColors(false),
377 maHTMLExtension(SdResId(STR_HTMLEXP_DEFAULT_EXTENSION)),
378 mpHTMLFiles(NULL),
379 mpImageFiles(NULL),
380 mpThumbnailFiles(NULL),
381 mpPageNames(NULL),
382 mpTextFiles(NULL),
383 maIndexUrl("index"),
384 meScript( SCRIPT_ASP ),
385 maHTMLHeader(
386 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n"
387 " \"http://www.w3.org/TR/html4/transitional.dtd\">\r\n"
388 "<html>\r\n<head>\r\n" ),
389 mpButtonSet( new ButtonSet() )
391 bool bChange = mpDoc->IsChanged();
393 maIndexUrl += maHTMLExtension;
395 InitExportParameters( rParams );
397 switch( meMode )
399 case PUBLISH_HTML:
400 case PUBLISH_FRAMES:
401 ExportHtml();
402 break;
403 case PUBLISH_WEBCAST:
404 ExportWebCast();
405 break;
406 case PUBLISH_KIOSK:
407 ExportKiosk();
408 break;
411 mpDoc->SetChanged(bChange);
414 HtmlExport::~HtmlExport()
416 // ------------------------------------------------------------------
417 // delete lists
418 // ------------------------------------------------------------------
419 if(mpImageFiles && mpHTMLFiles && mpThumbnailFiles && mpPageNames && mpTextFiles )
421 for ( sal_uInt16 nSdPage = 0; nSdPage < mnSdPageCount; nSdPage++)
423 delete mpImageFiles[nSdPage];
424 delete mpHTMLFiles[nSdPage];
425 delete mpThumbnailFiles[nSdPage];
426 delete mpPageNames[nSdPage];
427 delete mpTextFiles[nSdPage];
431 delete[] mpImageFiles;
432 delete[] mpHTMLFiles;
433 delete[] mpThumbnailFiles;
434 delete[] mpPageNames;
435 delete[] mpTextFiles;
438 /** get common export parameters from item set */
439 void HtmlExport::InitExportParameters( const Sequence< PropertyValue >& rParams )
441 mbImpress = mpDoc && mpDoc->GetDocumentType() == DOCUMENT_TYPE_IMPRESS;
443 sal_Int32 nArgs = rParams.getLength();
444 const PropertyValue* pParams = rParams.getConstArray();
445 OUString aStr;
446 while( nArgs-- )
448 if ( pParams->Name == "PublishMode" )
450 sal_Int32 temp = 0;
451 pParams->Value >>= temp;
452 meMode = (HtmlPublishMode)temp;
454 else if ( pParams->Name == "IndexURL" )
456 pParams->Value >>= aStr;
457 maIndexUrl = aStr;
459 else if ( pParams->Name == "Format" )
461 sal_Int32 temp = 0;
462 pParams->Value >>= temp;
463 meFormat = (PublishingFormat)temp;
465 else if ( pParams->Name == "Compression" )
467 pParams->Value >>= aStr;
468 String aTmp( aStr );
469 if(aTmp.Len())
471 xub_StrLen nPos = aTmp.Search( '%' );
472 if(nPos != STRING_NOTFOUND)
473 aTmp.Erase(nPos,1);
474 mnCompression = (sal_Int16)aTmp.ToInt32();
477 else if ( pParams->Name == "Width" )
479 sal_Int32 temp = 0;
480 pParams->Value >>= temp;
481 mnWidthPixel = (sal_uInt16)temp;
483 else if ( pParams->Name == "UseButtonSet" )
485 sal_Int32 temp = 0;
486 pParams->Value >>= temp;
487 mnButtonThema = (sal_Int16)temp;
489 else if ( pParams->Name == "IsExportNotes" )
491 if( mbImpress )
493 sal_Bool temp = sal_False;
494 pParams->Value >>= temp;
495 mbNotes = temp;
498 else if ( pParams->Name == "IsExportContentsPage" )
500 sal_Bool temp = sal_False;
501 pParams->Value >>= temp;
502 mbContentsPage = temp;
504 else if ( pParams->Name == "Author" )
506 pParams->Value >>= aStr;
507 maAuthor = aStr;
509 else if ( pParams->Name == "EMail" )
511 pParams->Value >>= aStr;
512 maEMail = aStr;
514 else if ( pParams->Name == "HomepageURL" )
516 pParams->Value >>= aStr;
517 maHomePage = aStr;
519 else if ( pParams->Name == "UserText" )
521 pParams->Value >>= aStr;
522 maInfo = aStr;
524 else if ( pParams->Name == "EnableDownload" )
526 sal_Bool temp = sal_False;
527 pParams->Value >>= temp;
528 mbDownload = temp;
530 else if ( pParams->Name == "SlideSound" )
532 sal_Bool temp = sal_True;
533 pParams->Value >>= temp;
534 mbSlideSound = temp;
536 else if ( pParams->Name == "HiddenSlides" )
538 sal_Bool temp = sal_True;
539 pParams->Value >>= temp;
540 mbHiddenSlides = temp;
542 else if ( pParams->Name == "BackColor" )
544 sal_Int32 temp = 0;
545 pParams->Value >>= temp;
546 maBackColor = temp;
547 mbUserAttr = true;
549 else if ( pParams->Name == "TextColor" )
551 sal_Int32 temp = 0;
552 pParams->Value >>= temp;
553 maTextColor = temp;
554 mbUserAttr = true;
556 else if ( pParams->Name == "LinkColor" )
558 sal_Int32 temp = 0;
559 pParams->Value >>= temp;
560 maLinkColor = temp;
561 mbUserAttr = true;
563 else if ( pParams->Name == "VLinkColor" )
565 sal_Int32 temp = 0;
566 pParams->Value >>= temp;
567 maVLinkColor = temp;
568 mbUserAttr = true;
570 else if ( pParams->Name == "ALinkColor" )
572 sal_Int32 temp = 0;
573 pParams->Value >>= temp;
574 maALinkColor = temp;
575 mbUserAttr = true;
577 else if ( pParams->Name == "IsUseDocumentColors" )
579 sal_Bool temp = sal_False;
580 pParams->Value >>= temp;
581 mbDocColors = temp;
583 else if ( pParams->Name == "KioskSlideDuration" )
585 double temp = 0.0;
586 pParams->Value >>= temp;
587 mfSlideDuration = temp;
588 mbAutoSlide = true;
590 else if ( pParams->Name == "KioskEndless" )
592 sal_Bool temp = sal_False;
593 pParams->Value >>= temp;
594 mbEndless = temp;
596 else if ( pParams->Name == "WebCastCGIURL" )
598 pParams->Value >>= aStr;
599 maCGIPath = aStr;
601 else if ( pParams->Name == "WebCastTargetURL" )
603 pParams->Value >>= aStr;
604 maURLPath = aStr;
606 else if ( pParams->Name == "WebCastScriptLanguage" )
608 pParams->Value >>= aStr;
609 if ( aStr == "asp" )
611 meScript = SCRIPT_ASP;
613 else
615 meScript = SCRIPT_PERL;
618 else
620 OSL_FAIL("Unknown property for html export detected!");
623 pParams++;
626 if( meMode == PUBLISH_KIOSK )
628 mbContentsPage = false;
629 mbNotes = false;
633 // calculate image sizes
634 SdPage* pPage = mpDoc->GetSdPage(0, PK_STANDARD);
635 Size aTmpSize( pPage->GetSize() );
636 double dRatio=((double)aTmpSize.Width())/aTmpSize.Height();
638 mnHeightPixel = (sal_uInt16)(mnWidthPixel/dRatio);
640 //------------------------------------------------------------------
641 // we come up with a destination...
643 INetURLObject aINetURLObj( maPath );
644 DBG_ASSERT( aINetURLObj.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" );
646 maExportPath = aINetURLObj.GetPartBeforeLastName(); // with trailing '/'
647 maIndex = aINetURLObj.GetLastName();
649 mnSdPageCount = mpDoc->GetSdPageCount( PK_STANDARD );
650 for( sal_uInt16 nPage = 0; nPage < mnSdPageCount; nPage++ )
652 pPage = mpDoc->GetSdPage( nPage, PK_STANDARD );
654 if( mbHiddenSlides || !pPage->IsExcluded() )
656 maPages.push_back( pPage );
657 maNotesPages.push_back( mpDoc->GetSdPage( nPage, PK_NOTES ) );
660 mnSdPageCount = maPages.size();
662 mbFrames = meMode == PUBLISH_FRAMES;
664 maDocFileName = maIndex;
667 ///////////////////////////////////////////////////////////////////////
668 // exports the (in the c'tor specified impress document) to html
669 ///////////////////////////////////////////////////////////////////////
670 void HtmlExport::ExportHtml()
672 if(mbUserAttr)
674 if( maTextColor == COL_AUTO )
676 if( !maBackColor.IsDark() )
677 maTextColor = COL_BLACK;
680 else if( mbDocColors )
682 // default colors for the color schema 'From Document'
683 SetDocColors();
684 maFirstPageColor = maBackColor;
687 // get name for downloadable presentation if needed
688 if( mbDownload )
690 // fade out separator search and extension
691 sal_uInt16 nSepPos = maDocFileName.Search( sal_Unicode('.') );
693 if(nSepPos != STRING_NOTFOUND)
694 maDocFileName.Erase(nSepPos);
696 maDocFileName.AppendAscii( ".odp" );
699 //////
701 sal_uInt16 nProgrCount = mnSdPageCount;
702 nProgrCount += mbImpress?mnSdPageCount:0;
703 nProgrCount += mbContentsPage?1:0;
704 nProgrCount += (mbFrames && mbNotes)?mnSdPageCount:0;
705 nProgrCount += (mbFrames)?8:0;
706 InitProgress( nProgrCount );
708 mpDocSh->SetWaitCursor( true );
710 //------------------------------------------------------------------
711 // Exceptions are cool...
713 CreateFileNames();
715 // this is not a true while
716 while( 1 )
718 if( checkForExistingFiles() )
719 break;
721 if( !CreateImagesForPresPages() )
722 break;
724 if( mbContentsPage &&
725 !CreateImagesForPresPages( true ) )
726 break;
729 if( !CreateHtmlForPresPages() )
730 break;
732 if( mbImpress )
733 if( !CreateHtmlTextForPresPages() )
734 break;
736 if( mbFrames )
738 if( !CreateFrames() )
739 break;
741 if( !CreateOutlinePages() )
742 break;
744 if( !CreateNavBarFrames() )
745 break;
747 if( mbNotes && mbImpress )
748 if( !CreateNotesPages() )
749 break;
753 if( mbContentsPage )
754 if( !CreateContentPage() )
755 break;
757 if( !CreateBitmaps() )
758 break;
760 mpDocSh->SetWaitCursor( false );
761 ResetProgress();
763 if( mbDownload )
764 SavePresentation();
766 return;
769 // if we get to this point the export was
770 // canceled by the user after an error
771 mpDocSh->SetWaitCursor( false );
772 ResetProgress();
775 ///////////////////////////////////////////////////////////////////////
777 void HtmlExport::SetDocColors( SdPage* pPage )
779 if( pPage == NULL )
780 pPage = mpDoc->GetSdPage(0, PK_STANDARD);
782 svtools::ColorConfig aConfig;
783 maVLinkColor = Color(aConfig.GetColorValue(svtools::LINKSVISITED).nColor);
784 maALinkColor = Color(aConfig.GetColorValue(svtools::LINKS).nColor);
785 maLinkColor = Color(aConfig.GetColorValue(svtools::LINKS).nColor);
786 maTextColor = Color(COL_BLACK);
788 SfxStyleSheet* pSheet = NULL;
790 if( mpDoc->GetDocumentType() == DOCUMENT_TYPE_IMPRESS )
792 // default text color from the outline template of the first page
793 pSheet = pPage->GetStyleSheetForPresObj(PRESOBJ_OUTLINE);
794 if(pSheet == NULL)
795 pSheet = pPage->GetStyleSheetForPresObj(PRESOBJ_TEXT);
796 if(pSheet == NULL)
797 pSheet = pPage->GetStyleSheetForPresObj(PRESOBJ_TITLE);
800 if(pSheet == NULL)
801 pSheet = mpDoc->GetDefaultStyleSheet();
803 if(pSheet)
805 SfxItemSet& rSet = pSheet->GetItemSet();
806 if(rSet.GetItemState(EE_CHAR_COLOR,sal_True) == SFX_ITEM_ON)
807 maTextColor = ((SvxColorItem*)rSet.GetItem(EE_CHAR_COLOR,sal_True))->GetValue();
810 // default background from the background of the master page of the first page
811 maBackColor = pPage->GetPageBackgroundColor();
813 if( maTextColor == COL_AUTO )
815 if( !maBackColor.IsDark() )
816 maTextColor = COL_BLACK;
820 ///////////////////////////////////////////////////////////////////////
822 void HtmlExport::InitProgress( sal_uInt16 nProgrCount )
824 String aStr(SdResId(STR_CREATE_PAGES));
825 mpProgress = new SfxProgress( mpDocSh, aStr, nProgrCount );
828 ///////////////////////////////////////////////////////////////////////
830 void HtmlExport::ResetProgress()
832 delete mpProgress;
833 mpProgress = NULL;
836 ///////////////////////////////////////////////////////////////////////
838 void HtmlExport::ExportKiosk()
840 mnPagesWritten = 0;
841 InitProgress( 2*mnSdPageCount );
843 CreateFileNames();
844 if( !checkForExistingFiles() )
846 if( CreateImagesForPresPages() )
847 CreateHtmlForPresPages();
850 ResetProgress();
853 ///////////////////////////////////////////////////////////////////////
854 // Export Document with WebCast (TM) Technology
855 ///////////////////////////////////////////////////////////////////////
856 void HtmlExport::ExportWebCast()
858 mnPagesWritten = 0;
859 InitProgress( mnSdPageCount + 9 );
861 mpDocSh->SetWaitCursor( sal_True );
863 CreateFileNames();
865 if(maCGIPath.Len() == 0)
866 maCGIPath.Assign( sal_Unicode('.') );
868 if( maCGIPath.GetChar( maCGIPath.Len() - 1 ) != sal_Unicode('/') )
869 maCGIPath.Append( sal_Unicode('/') );
871 if( meScript == SCRIPT_ASP )
873 maURLPath.AssignAscii( "./" );
875 else
877 if(maURLPath.Len() == 0)
878 maURLPath.Assign( sal_Unicode('.') );
880 if( maURLPath.GetChar( maURLPath.Len() - 1 ) != sal_Unicode('/') )
881 maURLPath.Append( sal_Unicode('/') );
884 // this is not a true while
885 while(1)
887 if( checkForExistingFiles() )
888 break;
890 if(!CreateImagesForPresPages())
891 break;
893 if( meScript == SCRIPT_ASP )
895 if(!CreateASPScripts())
896 break;
898 else
900 if(!CreatePERLScripts())
901 break;
904 if(!CreateImageFileList())
905 break;
907 if(!CreateImageNumberFile())
908 break;
910 break;
913 mpDocSh->SetWaitCursor( false );
914 ResetProgress();
917 ///////////////////////////////////////////////////////////////////////
918 // Save the presentation as a downloadable file in the dest directory
919 ///////////////////////////////////////////////////////////////////////
921 bool HtmlExport::SavePresentation()
923 meEC.SetContext( STR_HTMLEXP_ERROR_CREATE_FILE, maDocFileName );
925 OUString aURL( maExportPath );
926 aURL += maDocFileName;
929 mpDocSh->EnableSetModified( true );
933 uno::Reference< frame::XStorable > xStorable( mpDoc->getUnoModel(), uno::UNO_QUERY );
934 if( xStorable.is() )
936 uno::Sequence< beans::PropertyValue > aProperties( 2 );
937 aProperties[ 0 ].Name = "Overwrite";
938 aProperties[ 0 ].Value <<= (sal_Bool)sal_True;
939 aProperties[ 1 ].Name = "FilterName";
940 aProperties[ 1 ].Value <<= OUString("impress8");
941 xStorable->storeToURL( aURL, aProperties );
943 mpDocSh->EnableSetModified( false );
945 return true;
948 catch( Exception& )
952 mpDocSh->EnableSetModified( false );
954 return false;
957 // =====================================================================
958 // create image files
959 // =====================================================================
960 bool HtmlExport::CreateImagesForPresPages( bool bThumbnail)
964 Reference < XComponentContext > xContext = ::comphelper::getProcessComponentContext();
966 Reference< drawing::XGraphicExportFilter > xGraphicExporter = drawing::GraphicExportFilter::create( xContext );
968 Sequence< PropertyValue > aFilterData(((meFormat==FORMAT_JPG)&&(mnCompression != -1))? 3 : 2);
969 aFilterData[0].Name = "PixelWidth";
970 aFilterData[0].Value <<= (sal_Int32)(bThumbnail ? PUB_THUMBNAIL_WIDTH : mnWidthPixel );
971 aFilterData[1].Name = "PixelHeight";
972 aFilterData[1].Value <<= (sal_Int32)(bThumbnail ? PUB_THUMBNAIL_HEIGHT : mnHeightPixel);
973 if((meFormat==FORMAT_JPG)&&(mnCompression != -1))
975 aFilterData[2].Name = "Quality";
976 aFilterData[2].Value <<= (sal_Int32)mnCompression;
979 Sequence< PropertyValue > aDescriptor( 3 );
980 aDescriptor[0].Name = "URL";
981 aDescriptor[1].Name = "FilterName";
982 OUString sFormat;
983 if( meFormat == FORMAT_PNG )
984 sFormat = "PNG";
985 else if( meFormat == FORMAT_GIF )
986 sFormat = "GIF";
987 else
988 sFormat = "JPG";
990 aDescriptor[1].Value <<= sFormat;
991 aDescriptor[2].Name = "FilterData";
992 aDescriptor[2].Value <<= aFilterData;
994 for (sal_uInt16 nSdPage = 0; nSdPage < mnSdPageCount; nSdPage++)
996 SdPage* pPage = maPages[ nSdPage ];
998 OUString aFull(maExportPath);
999 if (bThumbnail)
1000 aFull += *mpThumbnailFiles[nSdPage];
1001 else
1002 aFull += *mpImageFiles[nSdPage];
1005 aDescriptor[0].Value <<= aFull;
1007 Reference< XComponent > xPage( pPage->getUnoPage(), UNO_QUERY );
1008 xGraphicExporter->setSourceDocument( xPage );
1009 xGraphicExporter->filter( aDescriptor );
1011 if (mpProgress)
1012 mpProgress->SetState(++mnPagesWritten);
1015 catch( Exception& )
1017 return false;
1020 return true;
1023 // =====================================================================
1024 // get SdrTextObject with layout text of this page
1025 // =====================================================================
1026 SdrTextObj* HtmlExport::GetLayoutTextObject(SdrPage* pPage)
1028 sal_uLong nObjectCount = pPage->GetObjCount();
1029 SdrObject* pObject = NULL;
1030 SdrTextObj* pResult = NULL;
1032 for (sal_uLong nObject = 0; nObject < nObjectCount; nObject++)
1034 pObject = pPage->GetObj(nObject);
1035 if (pObject->GetObjInventor() == SdrInventor &&
1036 pObject->GetObjIdentifier() == OBJ_OUTLINETEXT)
1038 pResult = (SdrTextObj*)pObject;
1039 break;
1042 return pResult;
1045 // =====================================================================
1046 // create HTML text version of impress pages
1047 // =====================================================================
1049 String HtmlExport::WriteMetaCharset() const
1051 String aStr;
1052 const sal_Char *pCharSet = rtl_getBestMimeCharsetFromTextEncoding( RTL_TEXTENCODING_UTF8 );
1053 if ( pCharSet )
1055 aStr.AppendAscii( " <meta HTTP-EQUIV=CONTENT-TYPE CONTENT=\"text/html; charset=" );
1056 aStr.AppendAscii( pCharSet );
1057 aStr.AppendAscii( "\">\r\n" );
1059 return aStr;
1062 bool HtmlExport::CreateHtmlTextForPresPages()
1064 bool bOk = true;
1066 SdrOutliner* pOutliner = mpDoc->GetInternalOutliner();
1068 for(sal_uInt16 nSdPage = 0; nSdPage < mnSdPageCount && bOk; nSdPage++)
1070 SdPage* pPage = maPages[ nSdPage ];
1072 if( mbDocColors )
1074 SetDocColors( pPage );
1077 // HTML head
1078 String aStr(maHTMLHeader);
1079 aStr += WriteMetaCharset();
1080 aStr.AppendAscii( " <title>" );
1081 aStr += StringToHTMLString( *mpPageNames[nSdPage] );
1082 aStr.AppendAscii( "</title>\r\n" );
1083 aStr.AppendAscii( "</head>\r\n" );
1084 aStr += CreateBodyTag();
1086 // navigation bar
1087 aStr += CreateNavBar(nSdPage, true);
1089 // page title
1090 String sTitleText( CreateTextForTitle(pOutliner,pPage, pPage->GetPageBackgroundColor()) );
1091 aStr.AppendAscii( "<h1 style=\"");
1092 aStr.Append( getParagraphStyle( pOutliner, 0 ) );
1093 aStr.AppendAscii( "\">" );
1094 aStr += sTitleText;
1095 aStr.AppendAscii( "</h1>\r\n" );
1097 // write outline text
1098 aStr += CreateTextForPage( pOutliner, pPage, true, pPage->GetPageBackgroundColor() );
1100 // notes
1101 if(mbNotes)
1103 SdPage* pNotesPage = maNotesPages[ nSdPage ];
1104 String aNotesStr( CreateTextForNotesPage( pOutliner, pNotesPage, true, maBackColor) );
1106 if( aNotesStr.Len() )
1108 aStr.AppendAscii( "<br>\r\n<h3>" );
1109 aStr += RESTOHTML(STR_HTMLEXP_NOTES);
1110 aStr.AppendAscii( ":</h3>\r\n" );
1112 aStr += aNotesStr;
1116 // clsoe page
1117 aStr.AppendAscii( "</body>\r\n</html>" );
1119 bOk = WriteHtml( *mpTextFiles[nSdPage], false, aStr );
1121 if (mpProgress)
1122 mpProgress->SetState(++mnPagesWritten);
1126 pOutliner->Clear();
1128 return bOk;
1131 /** exports the given html data into a non unicode file in the current export path with
1132 the given filename */
1133 bool HtmlExport::WriteHtml( const String& rFileName, bool bAddExtension, const String& rHtmlData )
1135 sal_uLong nErr = 0;
1137 String aFileName( rFileName );
1138 if( bAddExtension )
1139 aFileName += maHTMLExtension;
1141 meEC.SetContext( STR_HTMLEXP_ERROR_CREATE_FILE, rFileName );
1142 EasyFile aFile;
1143 SvStream* pStr;
1144 String aFull( maExportPath );
1145 aFull += aFileName;
1146 nErr = aFile.createStream(aFull , pStr);
1147 if(nErr == 0)
1149 OString aStr(OUStringToOString(rHtmlData,
1150 RTL_TEXTENCODING_UTF8));
1151 *pStr << aStr.getStr();
1152 nErr = aFile.close();
1155 if( nErr != 0 )
1156 ErrorHandler::HandleError(nErr);
1158 return nErr == 0;
1161 // =====================================================================
1163 /** creates a outliner text for the title objects of a page
1165 String HtmlExport::CreateTextForTitle( SdrOutliner* pOutliner, SdPage* pPage, const Color& rBackgroundColor )
1167 SdrTextObj* pTO = (SdrTextObj*)pPage->GetPresObj(PRESOBJ_TITLE);
1168 if(!pTO)
1169 pTO = GetLayoutTextObject(pPage);
1171 if (pTO && !pTO->IsEmptyPresObj())
1173 OutlinerParaObject* pOPO = pTO->GetOutlinerParaObject();
1174 if(pOPO && pOutliner->GetParagraphCount() != 0)
1176 pOutliner->Clear();
1177 pOutliner->SetText(*pOPO);
1178 return ParagraphToHTMLString(pOutliner,0, rBackgroundColor);
1182 return String();
1185 // =====================================================================
1186 // creates a outliner text for a page
1187 // =====================================================================
1188 String HtmlExport::CreateTextForPage( SdrOutliner* pOutliner,
1189 SdPage* pPage,
1190 bool bHeadLine, const Color& rBackgroundColor )
1192 String aStr;
1194 SdrTextObj* pTO = (SdrTextObj*)pPage->GetPresObj(PRESOBJ_TEXT);
1195 if(!pTO)
1196 pTO = GetLayoutTextObject(pPage);
1198 if (pTO && !pTO->IsEmptyPresObj())
1200 OutlinerParaObject* pOPO = pTO->GetOutlinerParaObject();
1201 if (pOPO)
1203 pOutliner->Clear();
1204 pOutliner->SetText( *pOPO );
1206 sal_Int32 nCount = pOutliner->GetParagraphCount();
1208 Paragraph* pPara = NULL;
1209 sal_Int16 nActDepth = -1;
1211 String aParaText;
1212 for (sal_Int32 nPara = 0; nPara < nCount; nPara++)
1214 pPara = pOutliner->GetParagraph(nPara);
1215 if(pPara == 0)
1216 continue;
1218 const sal_Int16 nDepth = (sal_uInt16) pOutliner->GetDepth( nPara );
1219 aParaText = ParagraphToHTMLString(pOutliner,nPara,rBackgroundColor);
1221 if(aParaText.Len() == 0)
1222 continue;
1224 if(nDepth < nActDepth )
1228 aStr.AppendAscii( "</ul>" );
1229 nActDepth--;
1231 while(nDepth < nActDepth);
1233 else if(nDepth > nActDepth )
1237 aStr.AppendAscii( "<ul>" );
1238 nActDepth++;
1240 while( nDepth > nActDepth );
1243 String sStyle( getParagraphStyle( pOutliner, nPara ) );
1244 if(nActDepth >= 0 )
1246 aStr.AppendAscii( "<li style=\"");
1247 aStr.Append( sStyle );
1248 aStr.AppendAscii( "\">" );
1251 if(nActDepth <= 0 && bHeadLine)
1253 if( nActDepth == 0 )
1255 aStr.AppendAscii( "<h2>" );
1257 else
1259 aStr.AppendAscii( "<h2 style=\"");
1260 aStr.Append( sStyle );
1261 aStr.AppendAscii( "\">" );
1264 aStr += aParaText;
1265 if(nActDepth == 0 && bHeadLine)
1266 aStr.AppendAscii( "</h2>" );
1267 if(nActDepth >= 0 )
1268 aStr.AppendAscii( "</li>" );
1269 aStr.AppendAscii( "\r\n" );
1272 while( nActDepth >= 0 )
1274 aStr.AppendAscii( "</ul>" );
1275 nActDepth--;
1280 return aStr;
1283 // =====================================================================
1284 // creates a outliner text for a note page
1285 // =====================================================================
1286 String HtmlExport::CreateTextForNotesPage( SdrOutliner* pOutliner,
1287 SdPage* pPage,
1288 bool,
1289 const Color& rBackgroundColor )
1291 String aStr;
1293 SdrTextObj* pTO = (SdrTextObj*)pPage->GetPresObj(PRESOBJ_NOTES);
1295 if (pTO && !pTO->IsEmptyPresObj())
1297 OutlinerParaObject* pOPO = pTO->GetOutlinerParaObject();
1298 if (pOPO)
1300 pOutliner->Clear();
1301 pOutliner->SetText( *pOPO );
1303 sal_Int32 nCount = pOutliner->GetParagraphCount();
1304 for (sal_Int32 nPara = 0; nPara < nCount; nPara++)
1306 aStr.AppendAscii("<p style=\"");
1307 aStr.Append( getParagraphStyle( pOutliner, nPara ) );
1308 aStr.AppendAscii("\">");
1309 aStr += ParagraphToHTMLString( pOutliner, nPara,rBackgroundColor );
1310 aStr.AppendAscii( "</p>\r\n" );
1315 return aStr;
1318 // =====================================================================
1319 // converts a paragraph of the outliner to html
1320 // =====================================================================
1321 String HtmlExport::ParagraphToHTMLString( SdrOutliner* pOutliner, sal_Int32 nPara, const Color& rBackgroundColor )
1323 String aStr;
1325 if(NULL == pOutliner)
1326 return aStr;
1328 // TODO: MALTE!!!
1329 EditEngine& rEditEngine = *(EditEngine*)&pOutliner->GetEditEngine();
1330 bool bOldUpdateMode = rEditEngine.GetUpdateMode();
1331 rEditEngine.SetUpdateMode(sal_True);
1333 Paragraph* pPara = pOutliner->GetParagraph(nPara);
1334 if(NULL == pPara)
1335 return aStr;
1337 HtmlState aState( (mbUserAttr || mbDocColors) ? maTextColor : Color(COL_BLACK) );
1338 std::vector<sal_uInt16> aPortionList;
1339 rEditEngine.GetPortions( nPara, aPortionList );
1341 sal_uInt16 nPos1 = 0;
1342 for( std::vector<sal_uInt16>::const_iterator it( aPortionList.begin() ); it != aPortionList.end(); ++it )
1344 sal_uInt16 nPos2 = *it;
1346 ESelection aSelection( nPara, nPos1, nPara, nPos2);
1348 SfxItemSet aSet( rEditEngine.GetAttribs( aSelection ) );
1350 String aPortion(StringToHTMLString(rEditEngine.GetText( aSelection )));
1352 aStr += TextAttribToHTMLString( &aSet, &aState, rBackgroundColor );
1353 aStr += aPortion;
1355 nPos1 = nPos2;
1357 aStr += aState.Flush();
1358 rEditEngine.SetUpdateMode(bOldUpdateMode);
1360 return aStr;
1363 // =====================================================================
1364 // Depending on the attributes of the specified set and the specified
1365 // HtmlState, it creates the needed html tags in order to get the
1366 // attributes.
1367 // =====================================================================
1368 String HtmlExport::TextAttribToHTMLString( SfxItemSet* pSet, HtmlState* pState, const Color& rBackgroundColor )
1370 String aStr;
1372 if(NULL == pSet)
1373 return aStr;
1375 String aLink, aTarget;
1376 if ( pSet->GetItemState( EE_FEATURE_FIELD ) == SFX_ITEM_ON )
1378 SvxFieldItem* pItem = (SvxFieldItem*)pSet->GetItem( EE_FEATURE_FIELD );
1379 if(pItem)
1381 SvxURLField* pURL = PTR_CAST(SvxURLField, pItem->GetField());
1382 if(pURL)
1384 aLink = pURL->GetURL();
1385 aTarget = pURL->GetTargetFrame();
1390 bool bTemp;
1391 String aTemp;
1393 if ( pSet->GetItemState( EE_CHAR_WEIGHT ) == SFX_ITEM_ON )
1395 bTemp = ((const SvxWeightItem&)pSet->Get( EE_CHAR_WEIGHT )).GetWeight() == WEIGHT_BOLD;
1396 aTemp = pState->SetWeight( bTemp );
1397 if( bTemp )
1398 aStr.Insert( aTemp, 0 );
1399 else
1400 aStr += aTemp;
1403 if ( pSet->GetItemState( EE_CHAR_UNDERLINE ) == SFX_ITEM_ON )
1405 bTemp = ((const SvxUnderlineItem&)pSet->Get( EE_CHAR_UNDERLINE )).GetLineStyle() != UNDERLINE_NONE;
1406 aTemp = pState->SetUnderline( bTemp );
1407 if( bTemp )
1408 aStr.Insert( aTemp, 0 );
1409 else
1410 aStr += aTemp;
1413 if ( pSet->GetItemState( EE_CHAR_STRIKEOUT ) == SFX_ITEM_ON )
1415 bTemp = ((const SvxCrossedOutItem&)pSet->Get( EE_CHAR_STRIKEOUT )).GetStrikeout() != STRIKEOUT_NONE;
1416 aTemp = pState->SetStrikeout( bTemp );
1417 if( bTemp )
1418 aStr.Insert( aTemp, 0 );
1419 else
1420 aStr += aTemp;
1423 if ( pSet->GetItemState( EE_CHAR_ITALIC ) == SFX_ITEM_ON )
1425 bTemp = ((const SvxPostureItem&)pSet->Get( EE_CHAR_ITALIC )).GetPosture() != ITALIC_NONE;
1426 aTemp = pState->SetItalic( bTemp );
1427 if( bTemp )
1428 aStr.Insert( aTemp, 0 );
1429 else
1430 aStr += aTemp;
1433 if(mbDocColors)
1435 if ( pSet->GetItemState( EE_CHAR_COLOR ) == SFX_ITEM_ON )
1437 Color aTextColor = ((const SvxColorItem&) pSet->Get( EE_CHAR_COLOR )).GetValue();
1438 if( aTextColor == COL_AUTO )
1440 if( !rBackgroundColor.IsDark() )
1441 aTextColor = COL_BLACK;
1443 aStr += pState->SetColor( aTextColor );
1447 if( aLink.Len() )
1448 aStr.Insert( pState->SetLink(aLink, aTarget), 0 );
1449 else
1450 aStr += pState->SetLink(aLink, aTarget);
1452 return aStr;
1455 // =====================================================================
1456 // create HTML wrapper for picture files
1457 // =====================================================================
1458 bool HtmlExport::CreateHtmlForPresPages()
1460 bool bOk = true;
1462 std::vector<SdrObject*> aClickableObjects;
1464 for(sal_uInt16 nSdPage = 0; nSdPage < mnSdPageCount && bOk; nSdPage++)
1466 // find clickable objects (also on the master page) and put it in the
1467 // list. This in reverse order character order since in html the first
1468 // area is taken in the case they overlap.
1470 SdPage* pPage = maPages[ nSdPage ];
1472 if( mbDocColors )
1474 SetDocColors( pPage );
1477 bool bMasterDone = false;
1479 while (!bMasterDone)
1481 // sal_True = backwards
1482 SdrObjListIter aIter(*pPage, IM_DEEPWITHGROUPS, sal_True);
1484 SdrObject* pObject = aIter.Next();
1485 while (pObject)
1487 SdAnimationInfo* pInfo = mpDoc->GetAnimationInfo(pObject);
1488 SdIMapInfo* pIMapInfo = mpDoc->GetIMapInfo(pObject);
1490 if ((pInfo &&
1491 (pInfo->meClickAction == presentation::ClickAction_BOOKMARK ||
1492 pInfo->meClickAction == presentation::ClickAction_DOCUMENT ||
1493 pInfo->meClickAction == presentation::ClickAction_PREVPAGE ||
1494 pInfo->meClickAction == presentation::ClickAction_NEXTPAGE ||
1495 pInfo->meClickAction == presentation::ClickAction_FIRSTPAGE ||
1496 pInfo->meClickAction == presentation::ClickAction_LASTPAGE)) ||
1497 pIMapInfo)
1499 aClickableObjects.push_back(pObject);
1502 pObject = aIter.Next();
1504 // now to the master page or finishing
1505 if (!pPage->IsMasterPage())
1506 pPage = (SdPage*)(&(pPage->TRG_GetMasterPage()));
1507 else
1508 bMasterDone = true;
1511 // HTML Head
1512 String aStr(maHTMLHeader);
1513 aStr += WriteMetaCharset();
1514 aStr.AppendAscii( " <title>" );
1515 aStr += StringToHTMLString(*mpPageNames[nSdPage]);
1516 aStr.AppendAscii( "</title>\r\n" );
1518 // insert timing information
1519 pPage = maPages[ nSdPage ];
1520 if( meMode == PUBLISH_KIOSK )
1522 double fSecs = 0;
1523 bool bEndless = false;
1524 if( !mbAutoSlide )
1526 if( pPage->GetPresChange() != PRESCHANGE_MANUAL )
1528 fSecs = pPage->GetTime();
1529 bEndless = mpDoc->getPresentationSettings().mbEndless;
1532 else
1534 fSecs = mfSlideDuration;
1535 bEndless = mbEndless;
1538 if( fSecs != 0 )
1540 if( nSdPage < (mnSdPageCount-1) || bEndless )
1542 aStr.AppendAscii( "<meta http-equiv=\"refresh\" content=\"" );
1543 aStr += OUString::number(fSecs);
1544 aStr.AppendAscii( "; URL=" );
1546 int nPage = nSdPage + 1;
1547 if( nPage == mnSdPageCount )
1548 nPage = 0;
1550 aStr += StringToURL(*mpHTMLFiles[nPage]);
1552 aStr.AppendAscii( "\">\r\n" );
1557 aStr.AppendAscii( "</head>\r\n" );
1559 // HTML Body
1560 aStr += CreateBodyTag();
1562 if( mbSlideSound && pPage->IsSoundOn() )
1563 aStr += InsertSound( pPage->GetSoundFile() );
1565 // navigation bar
1566 if(!mbFrames )
1567 aStr += CreateNavBar( nSdPage, false );
1568 // Image
1569 aStr.AppendAscii( "<center>" );
1570 aStr.AppendAscii( "<img src=\"" );
1571 aStr += StringToURL( *mpImageFiles[nSdPage] );
1572 aStr.AppendAscii( "\" alt=\"\"" );
1574 if (!aClickableObjects.empty())
1575 aStr.AppendAscii( " USEMAP=\"#map0\"" );
1577 aStr.AppendAscii( "></center>\r\n" );
1579 // notes
1580 if(mbNotes && !mbFrames)
1582 SdrOutliner* pOutliner = mpDoc->GetInternalOutliner();
1583 SdPage* pNotesPage = maNotesPages[ nSdPage ];
1584 String aNotesStr( CreateTextForNotesPage( pOutliner, pNotesPage, true, maBackColor) );
1585 pOutliner->Clear();
1587 if( aNotesStr.Len() )
1589 aStr.AppendAscii( "<h3>" );
1590 aStr += RESTOHTML(STR_HTMLEXP_NOTES);
1591 aStr.AppendAscii( ":</h3><br>\r\n\r\n<p>" );
1593 aStr += aNotesStr;
1594 aStr.AppendAscii( "\r\n</p>\r\n" );
1598 // create Imagemap if necessary
1599 if (!aClickableObjects.empty())
1601 aStr.AppendAscii( "<map name=\"map0\">\r\n" );
1603 for (sal_uInt32 nObject = 0, n = aClickableObjects.size(); nObject < n; nObject++)
1605 SdrObject* pObject = aClickableObjects[nObject];
1606 SdAnimationInfo* pInfo = mpDoc->GetAnimationInfo(pObject);
1607 SdIMapInfo* pIMapInfo = mpDoc->GetIMapInfo(pObject);
1609 Rectangle aRect(pObject->GetCurrentBoundRect());
1610 Point aLogPos(aRect.TopLeft());
1611 bool bIsSquare = aRect.GetWidth() == aRect.GetHeight();
1613 sal_uLong nPageWidth = pPage->GetSize().Width() - pPage->GetLftBorder() -
1614 pPage->GetRgtBorder();
1616 // BoundRect is relative to the physical page origin, not the
1617 // origin of ordinates
1618 aRect.Move(-pPage->GetLftBorder(), -pPage->GetUppBorder());
1620 double fLogicToPixel = ((double)mnWidthPixel) / nPageWidth;
1621 aRect.Left() = (long)(aRect.Left() * fLogicToPixel);
1622 aRect.Top() = (long)(aRect.Top() * fLogicToPixel);
1623 aRect.Right() = (long)(aRect.Right() * fLogicToPixel);
1624 aRect.Bottom() = (long)(aRect.Bottom() * fLogicToPixel);
1625 long nRadius = aRect.GetWidth() / 2;
1628 /*************************************************************
1629 |* insert areas into Imagemap of the object, if the object has
1630 |* such a Imagemap
1631 \************************************************************/
1632 if (pIMapInfo)
1634 const ImageMap& rIMap = pIMapInfo->GetImageMap();
1635 sal_uInt16 nAreaCount = rIMap.GetIMapObjectCount();
1636 for (sal_uInt16 nArea = 0; nArea < nAreaCount; nArea++)
1638 IMapObject* pArea = rIMap.GetIMapObject(nArea);
1639 sal_uInt16 nType = pArea->GetType();
1640 String aURL( pArea->GetURL() );
1642 // if necessary, convert page and object names into the
1643 // corresponding names of the html file
1644 sal_Bool bIsMasterPage;
1645 sal_uInt16 nPgNum = mpDoc->GetPageByName( aURL, bIsMasterPage );
1646 SdrObject* pObj = NULL;
1648 if (nPgNum == SDRPAGE_NOTFOUND)
1650 // is the bookmark a object?
1651 pObj = mpDoc->GetObj( aURL );
1652 if (pObj)
1653 nPgNum = pObj->GetPage()->GetPageNum();
1655 if (nPgNum != SDRPAGE_NOTFOUND)
1657 nPgNum = (nPgNum - 1) / 2; // SdrPageNum --> SdPageNum
1658 aURL = CreatePageURL(nPgNum);
1661 switch(nType)
1663 case IMAP_OBJ_RECTANGLE:
1665 Rectangle aArea(((IMapRectangleObject*)pArea)->
1666 GetRectangle(false));
1668 // conversion into pixel coordinates
1669 aArea.Move(aLogPos.X() - pPage->GetLftBorder(),
1670 aLogPos.Y() - pPage->GetUppBorder());
1671 aArea.Left() = (long)(aArea.Left() * fLogicToPixel);
1672 aArea.Top() = (long)(aArea.Top() * fLogicToPixel);
1673 aArea.Right() = (long)(aArea.Right() * fLogicToPixel);
1674 aArea.Bottom() = (long)(aArea.Bottom() * fLogicToPixel);
1676 aStr += CreateHTMLRectArea(aArea, aURL);
1678 break;
1680 case IMAP_OBJ_CIRCLE:
1682 Point aCenter(((IMapCircleObject*)pArea)->
1683 GetCenter(false));
1684 aCenter += Point(aLogPos.X() - pPage->GetLftBorder(),
1685 aLogPos.Y() - pPage->GetUppBorder());
1686 aCenter.X() = (long)(aCenter.X() * fLogicToPixel);
1687 aCenter.Y() = (long)(aCenter.Y() * fLogicToPixel);
1689 sal_uLong nCircleRadius = (((IMapCircleObject*)pArea)->
1690 GetRadius(false));
1691 nCircleRadius = (sal_uLong)(nCircleRadius * fLogicToPixel);
1692 aStr += CreateHTMLCircleArea(nCircleRadius,
1693 aCenter.X(), aCenter.Y(),
1694 aURL);
1696 break;
1698 case IMAP_OBJ_POLYGON:
1700 Polygon aArea(((IMapPolygonObject*)pArea)->GetPolygon(false));
1701 aStr += CreateHTMLPolygonArea(::basegfx::B2DPolyPolygon(aArea.getB2DPolygon()), Size(aLogPos.X() - pPage->GetLftBorder(), aLogPos.Y() - pPage->GetUppBorder()), fLogicToPixel, aURL);
1703 break;
1705 default:
1707 DBG_WARNING("unknown IMAP_OBJ_type");
1709 break;
1716 /*************************************************************
1717 |* if there is a presentation::ClickAction, determine bookmark
1718 |* and create area for the whole object
1719 \************************************************************/
1720 if( pInfo )
1722 String aHRef;
1723 presentation::ClickAction eClickAction = pInfo->meClickAction;
1725 switch( eClickAction )
1727 case presentation::ClickAction_BOOKMARK:
1729 sal_Bool bIsMasterPage;
1730 sal_uInt16 nPgNum = mpDoc->GetPageByName( pInfo->GetBookmark(), bIsMasterPage );
1731 SdrObject* pObj = NULL;
1733 if( nPgNum == SDRPAGE_NOTFOUND )
1735 // is the bookmark a object?
1736 pObj = mpDoc->GetObj(pInfo->GetBookmark());
1737 if (pObj)
1738 nPgNum = pObj->GetPage()->GetPageNum();
1741 if( SDRPAGE_NOTFOUND != nPgNum )
1742 aHRef = CreatePageURL(( nPgNum - 1 ) / 2 );
1744 break;
1746 case presentation::ClickAction_DOCUMENT:
1747 aHRef = pInfo->GetBookmark();
1748 break;
1750 case presentation::ClickAction_PREVPAGE:
1752 sal_uLong nPage = nSdPage;
1753 if (nSdPage == 0)
1754 nPage = 0;
1755 else
1756 nPage = nSdPage - 1;
1758 aHRef = CreatePageURL( (sal_uInt16) nPage);
1760 break;
1762 case presentation::ClickAction_NEXTPAGE:
1764 sal_uLong nPage = nSdPage;
1765 if (nSdPage == mnSdPageCount - 1)
1766 nPage = mnSdPageCount - 1;
1767 else
1768 nPage = nSdPage + 1;
1770 aHRef = CreatePageURL( (sal_uInt16) nPage);
1772 break;
1774 case presentation::ClickAction_FIRSTPAGE:
1775 aHRef = CreatePageURL(0);
1776 break;
1778 case presentation::ClickAction_LASTPAGE:
1779 aHRef = CreatePageURL(mnSdPageCount - 1);
1780 break;
1782 default:
1783 break;
1786 // and now the areas
1787 if( aHRef.Len() )
1789 // a circle?
1790 if (pObject->GetObjInventor() == SdrInventor &&
1791 pObject->GetObjIdentifier() == OBJ_CIRC &&
1792 bIsSquare )
1794 aStr += CreateHTMLCircleArea(aRect.GetWidth() / 2,
1795 aRect.Left() + nRadius,
1796 aRect.Top() + nRadius,
1797 aHRef);
1799 // a polygon?
1800 else if (pObject->GetObjInventor() == SdrInventor &&
1801 (pObject->GetObjIdentifier() == OBJ_PATHLINE ||
1802 pObject->GetObjIdentifier() == OBJ_PLIN ||
1803 pObject->GetObjIdentifier() == OBJ_POLY))
1805 aStr += CreateHTMLPolygonArea(((SdrPathObj*)pObject)->GetPathPoly(), Size(-pPage->GetLftBorder(), -pPage->GetUppBorder()), fLogicToPixel, aHRef);
1807 // something completely different: use the BoundRect
1808 else
1810 aStr += CreateHTMLRectArea(aRect, aHRef);
1817 aStr.AppendAscii( "</map>\r\n" );
1819 aClickableObjects.clear();
1821 aStr.AppendAscii( "</body>\r\n</html>" );
1823 bOk = WriteHtml( *mpHTMLFiles[nSdPage], false, aStr );
1825 if (mpProgress)
1826 mpProgress->SetState(++mnPagesWritten);
1829 return bOk;
1832 // =====================================================================
1833 // create overview pages
1834 // =====================================================================
1835 bool HtmlExport::CreateContentPage()
1837 if( mbDocColors )
1838 SetDocColors();
1840 // html head
1841 String aStr(maHTMLHeader);
1842 aStr += WriteMetaCharset();
1843 aStr.AppendAscii( " <title>" );
1844 aStr += StringToHTMLString(*mpPageNames[0]);
1845 aStr.AppendAscii( "</title>\r\n</head>\r\n" );
1846 aStr += CreateBodyTag();
1848 // page head
1849 aStr.AppendAscii( "<center>\r\n" );
1851 if(mbHeader)
1853 aStr.AppendAscii( "<h1>" );
1854 aStr += getDocumentTitle();
1855 aStr.AppendAscii( "</h1><br>\r\n" );
1858 aStr.AppendAscii( "<h2>" );
1860 // Solaris compiler bug workaround
1861 if( mbFrames )
1862 aStr += CreateLink( maFramePage,
1863 RESTOHTML(STR_HTMLEXP_CLICKSTART) );
1864 else
1865 aStr += CreateLink( StringToHTMLString(*mpHTMLFiles[0]),
1866 RESTOHTML(STR_HTMLEXP_CLICKSTART) );
1868 aStr.AppendAscii( "</h2>\r\n</center>\r\n" );
1870 aStr.AppendAscii( "<center><table width=\"90%\"><tr>\r\n" );
1872 // table of content
1873 aStr.AppendAscii( "<td valign=\"top\" align=\"left\" width=\"25%\">\r\n" );
1874 aStr.AppendAscii( "<h3>" );
1875 aStr += RESTOHTML(STR_HTMLEXP_CONTENTS);
1876 aStr.AppendAscii( "</h3>" );
1878 for(sal_uInt16 nSdPage = 0; nSdPage < mnSdPageCount; nSdPage++)
1880 String aPageName = *mpPageNames[nSdPage];
1881 aStr.AppendAscii( "<div align=\"left\">" );
1882 if(mbFrames)
1883 aStr += StringToHTMLString(aPageName);
1884 else
1885 aStr += CreateLink(*mpHTMLFiles[nSdPage], aPageName);
1886 aStr.AppendAscii( "</div>\r\n" );
1888 aStr.AppendAscii( "</td>\r\n" );
1890 // document information
1891 aStr.AppendAscii( "<td valign=\"top\" align=\"left\" width=\"75%\">\r\n" );
1893 if(maAuthor.Len())
1895 aStr.AppendAscii( "<p><strong>" );
1896 aStr += RESTOHTML(STR_HTMLEXP_AUTHOR);
1897 aStr.AppendAscii( ":</strong> " );
1898 aStr += StringToHTMLString(maAuthor);
1899 aStr.AppendAscii( "</p>\r\n" );
1902 if(maEMail.Len())
1904 aStr.AppendAscii( "<p><strong>" );
1905 aStr += RESTOHTML(STR_HTMLEXP_EMAIL);
1906 aStr.AppendAscii( ":</strong> <a href=\"mailto:" );
1907 aStr += StringToURL(maEMail);
1908 aStr.AppendAscii( "\">" );
1909 aStr += StringToHTMLString(maEMail);
1910 aStr.AppendAscii( "</a></p>\r\n" );
1913 if(maHomePage.Len())
1915 aStr.AppendAscii( "<p><strong>" );
1916 aStr += RESTOHTML(STR_HTMLEXP_HOMEPAGE);
1917 aStr.AppendAscii( ":</strong> <a href=\"" );
1918 aStr += StringToURL(maHomePage);
1919 aStr.AppendAscii( "\">" );
1920 aStr += StringToHTMLString(maHomePage);
1921 aStr.AppendAscii( "</a> </p>\r\n" );
1924 if(maInfo.Len())
1926 aStr.AppendAscii( "<p><strong>" );
1927 aStr += RESTOHTML(STR_HTMLEXP_INFO);
1928 aStr.AppendAscii( ":</strong><br>\r\n" );
1929 aStr += StringToHTMLString(maInfo);
1930 aStr.AppendAscii( "</p>\r\n" );
1933 if(mbDownload)
1935 aStr.AppendAscii( "<p><a href=\"" );
1936 aStr += StringToURL(maDocFileName);
1937 aStr.AppendAscii( "\">" );
1938 aStr += RESTOHTML(STR_HTMLEXP_DOWNLOAD);
1939 aStr.AppendAscii( "</a></p>\r\n" );
1942 for(sal_uInt16 nSdPage = 0; nSdPage < mnSdPageCount; nSdPage++)
1944 String aText;
1946 aText.AppendAscii( "<img src=\"" );
1947 aText += StringToURL( *mpThumbnailFiles[nSdPage] );
1948 aText.AppendAscii( "\" width=\"256\" height=\"192\" alt=\"" );
1949 aText += StringToHTMLString( *mpPageNames[nSdPage] );
1950 aText.AppendAscii( "\">" );
1952 aStr += CreateLink(*mpHTMLFiles[nSdPage], aText);
1953 aStr.AppendAscii( "\r\n" );
1957 aStr.AppendAscii( "</td></tr></table></center>\r\n" );
1959 aStr.AppendAscii( "</body>\r\n</html>" );
1961 bool bOk = WriteHtml( maIndex, false, aStr );
1963 if (mpProgress)
1964 mpProgress->SetState(++mnPagesWritten);
1966 return bOk;
1969 // =====================================================================
1970 // create note pages (for frames)
1971 // =====================================================================
1972 bool HtmlExport::CreateNotesPages()
1974 bool bOk = true;
1976 SdrOutliner* pOutliner = mpDoc->GetInternalOutliner();
1977 for( sal_uInt16 nSdPage = 0; bOk && nSdPage < mnSdPageCount; nSdPage++ )
1979 SdPage* pPage = maNotesPages[nSdPage];
1980 if( mbDocColors )
1981 SetDocColors( pPage );
1983 // Html head
1984 String aStr(maHTMLHeader);
1985 aStr += WriteMetaCharset();
1986 aStr.AppendAscii( " <title>" );
1987 aStr += StringToHTMLString(*mpPageNames[0]);
1988 aStr.AppendAscii( "</title>\r\n</head>\r\n" );
1989 aStr += CreateBodyTag();
1991 if(pPage)
1992 aStr += CreateTextForNotesPage( pOutliner, pPage, true, maBackColor );
1994 aStr.AppendAscii( "</body>\r\n</html>" );
1996 OUString aFileName( "note" );
1997 aFileName += OUString::valueOf(nSdPage);
1998 bOk = WriteHtml( aFileName, true, aStr );
2002 if (mpProgress)
2003 mpProgress->SetState(++mnPagesWritten);
2006 pOutliner->Clear();
2008 return bOk;
2011 // =====================================================================
2012 // create outline pages (for frames)
2013 // =====================================================================
2014 bool HtmlExport::CreateOutlinePages()
2016 bool bOk = true;
2018 if( mbDocColors )
2020 SetDocColors();
2023 // page 0 will be the closed outline, page 1 the opened
2024 for (sal_Int32 nPage = 0; nPage < (mbImpress?2:1) && bOk; ++nPage)
2026 // Html head
2027 String aStr(maHTMLHeader);
2028 aStr += WriteMetaCharset();
2029 aStr.AppendAscii( " <title>" );
2030 aStr += StringToHTMLString(*mpPageNames[0]);
2031 aStr.AppendAscii( "</title>\r\n</head>\r\n" );
2032 aStr += CreateBodyTag();
2034 SdrOutliner* pOutliner = mpDoc->GetInternalOutliner();
2035 for(sal_uInt16 nSdPage = 0; nSdPage < mnSdPageCount; nSdPage++)
2037 SdPage* pPage = maPages[ nSdPage ];
2039 aStr.AppendAscii( "<div align=\"left\">" );
2040 String aLink( RTL_CONSTASCII_USTRINGPARAM( "JavaScript:parent.NavigateAbs(" ) );
2041 aLink += OUString::number(nSdPage);
2042 aLink.Append( sal_Unicode(')') );
2044 String aTitle = CreateTextForTitle(pOutliner,pPage, maBackColor);
2045 if(aTitle.Len() == 0)
2046 aTitle = *mpPageNames[nSdPage];
2048 aStr.AppendAscii("<p style=\"");
2049 aStr.Append( getParagraphStyle( pOutliner, 0 ) );
2050 aStr.AppendAscii("\">");
2051 aStr += CreateLink(aLink, aTitle);
2052 aStr.AppendAscii("</p>");
2054 if(nPage==1)
2056 aStr += CreateTextForPage( pOutliner, pPage, false, maBackColor );
2058 aStr.AppendAscii( "</div>\r\n" );
2060 pOutliner->Clear();
2062 aStr.AppendAscii( "</body>\r\n</html>" );
2064 OUString aFileName( "outline" );
2065 aFileName += OUString::valueOf(nPage);
2066 bOk = WriteHtml( aFileName, true, aStr );
2068 if (mpProgress)
2069 mpProgress->SetState(++mnPagesWritten);
2072 return bOk;
2075 // =====================================================================
2076 // set file name
2077 // =====================================================================
2078 void HtmlExport::CreateFileNames()
2080 // create lists with new file names
2081 mpHTMLFiles = new String*[mnSdPageCount];
2082 mpImageFiles = new String*[mnSdPageCount];
2083 mpThumbnailFiles = new String*[mnSdPageCount];
2084 mpPageNames = new String*[mnSdPageCount];
2085 mpTextFiles = new String*[mnSdPageCount];
2087 mbHeader = false; // headline on overview page?
2089 for (sal_uInt16 nSdPage = 0; nSdPage < mnSdPageCount; nSdPage++)
2091 String* pName;
2092 if(nSdPage == 0 && !mbContentsPage && !mbFrames )
2093 pName = new String(maIndex);
2094 else
2096 pName = new String( RTL_CONSTASCII_USTRINGPARAM("img") );
2097 *pName += OUString::number(nSdPage);
2098 *pName += maHTMLExtension;
2101 mpHTMLFiles[nSdPage] = pName;
2103 pName = new String( RTL_CONSTASCII_USTRINGPARAM("img") );
2104 *pName += OUString::number(nSdPage);
2105 if( meFormat==FORMAT_GIF )
2106 pName->AppendAscii( ".gif" );
2107 else if( meFormat==FORMAT_JPG )
2108 pName->AppendAscii( ".jpg" );
2109 else
2110 pName->AppendAscii( ".png" );
2112 mpImageFiles[nSdPage] = pName;
2114 pName = new String( RTL_CONSTASCII_USTRINGPARAM("thumb") );
2115 *pName += OUString::number(nSdPage);
2116 if( meFormat!=FORMAT_JPG )
2117 pName->AppendAscii( ".png" );
2118 else
2119 pName->AppendAscii( ".jpg" );
2121 mpThumbnailFiles[nSdPage] = pName;
2123 pName = new String( RTL_CONSTASCII_USTRINGPARAM("text"));
2124 *pName += OUString::number(nSdPage);
2125 *pName += maHTMLExtension;
2126 mpTextFiles[nSdPage] = pName;
2128 SdPage* pSdPage = maPages[ nSdPage ];
2130 // get slide title from page name
2131 String* pPageTitle = new String();
2132 *pPageTitle = pSdPage->GetName();
2133 mpPageNames[nSdPage] = pPageTitle;
2136 if(!mbContentsPage && mbFrames)
2137 maFramePage = maIndex;
2138 else
2140 maFramePage.AssignAscii( "siframes" );
2141 maFramePage += maHTMLExtension;
2145 String HtmlExport::getDocumentTitle()
2147 // check for a title object in this page, if its the first
2148 // title it becomes this documents title for the content
2149 // page
2150 if( !mbHeader )
2152 if(mbImpress)
2154 // if there is a non-empty title object, use their first passage
2155 // as page title
2156 SdPage* pSdPage = mpDoc->GetSdPage(0, PK_STANDARD);
2157 SdrObject* pTitleObj = pSdPage->GetPresObj(PRESOBJ_TITLE);
2158 if (pTitleObj && !pTitleObj->IsEmptyPresObj())
2160 OutlinerParaObject* pParaObject = pTitleObj->GetOutlinerParaObject();
2161 if (pParaObject)
2163 const EditTextObject& rEditTextObject =
2164 pParaObject->GetTextObject();
2165 if (&rEditTextObject)
2167 String aTest(rEditTextObject.GetText(0));
2168 if (aTest.Len() > 0)
2169 mDocTitle = aTest;
2174 for( sal_uInt16 i = 0; i < mDocTitle.Len(); i++ )
2175 if( mDocTitle.GetChar(i) == (sal_Unicode)0xff)
2176 mDocTitle.SetChar(i, sal_Unicode(' ') );
2179 if( !mDocTitle.Len() )
2181 mDocTitle = maDocFileName;
2182 int nDot = mDocTitle.Search( '.' );
2183 if( nDot > 0 )
2184 mDocTitle.Erase( (sal_uInt16)nDot );
2186 mbHeader = true;
2189 return mDocTitle;
2192 static const char* JS_NavigateAbs =
2193 "function NavigateAbs( nPage )\r\n"
2194 "{\r\n"
2195 " frames[\"show\"].location.href = \"img\" + nPage + \".$EXT\";\r\n"
2196 " //frames[\"notes\"].location.href = \"note\" + nPage + \".$EXT\";\r\n"
2197 " nCurrentPage = nPage;\r\n"
2198 " if(nCurrentPage==0)\r\n"
2199 " {\r\n"
2200 " frames[\"navbar1\"].location.href = \"navbar0.$EXT\";\r\n"
2201 " }\r\n"
2202 " else if(nCurrentPage==nPageCount-1)\r\n"
2203 " {\r\n"
2204 " frames[\"navbar1\"].location.href = \"navbar2.$EXT\";\r\n"
2205 " }\r\n"
2206 " else\r\n"
2207 " {\r\n"
2208 " frames[\"navbar1\"].location.href = \"navbar1.$EXT\";\r\n"
2209 " }\r\n"
2210 "}\r\n\r\n";
2212 static const char* JS_NavigateRel =
2213 "function NavigateRel( nDelta )\r\n"
2214 "{\r\n"
2215 " var nPage = parseInt(nCurrentPage) + parseInt(nDelta);\r\n"
2216 " if( (nPage >= 0) && (nPage < nPageCount) )\r\n"
2217 " {\r\n"
2218 " NavigateAbs( nPage );\r\n"
2219 " }\r\n"
2220 "}\r\n\r\n";
2222 static const char* JS_ExpandOutline =
2223 "function ExpandOutline()\r\n"
2224 "{\r\n"
2225 " frames[\"navbar2\"].location.href = \"navbar4.$EXT\";\r\n"
2226 " frames[\"outline\"].location.href = \"outline1.$EXT\";\r\n"
2227 "}\r\n\r\n";
2229 static const char * JS_CollapseOutline =
2230 "function CollapseOutline()\r\n"
2231 "{\r\n"
2232 " frames[\"navbar2\"].location.href = \"navbar3.$EXT\";\r\n"
2233 " frames[\"outline\"].location.href = \"outline0.$EXT\";\r\n"
2234 "}\r\n\r\n";
2236 // ====================================================================
2237 // create page with the frames
2238 // ====================================================================
2239 bool HtmlExport::CreateFrames()
2241 String aTmp;
2242 String aStr( RTL_CONSTASCII_USTRINGPARAM(
2243 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\"\r\n"
2244 " \"http://www.w3.org/TR/html4/frameset.dtd\">\r\n"
2245 "<html>\r\n<head>\r\n" ) );
2247 aStr += WriteMetaCharset();
2248 aStr.AppendAscii( " <title>" );
2249 aStr += StringToHTMLString(*mpPageNames[0]);
2250 aStr.AppendAscii( "</title>\r\n" );
2252 aStr.AppendAscii( "<script type=\"text/javascript\">\r\n<!--\r\n" );
2254 aStr.AppendAscii( "var nCurrentPage = 0;\r\nvar nPageCount = " );
2255 aStr += OUString::number(mnSdPageCount);
2256 aStr.AppendAscii( ";\r\n\r\n" );
2258 String aFunction;
2259 aFunction.AssignAscii(JS_NavigateAbs);
2261 if(mbNotes)
2263 String aSlash( RTL_CONSTASCII_USTRINGPARAM( "//" ) );
2264 aFunction.SearchAndReplaceAll(aSlash, OUString());
2267 // substitute HTML file extension
2268 String aPlaceHolder(RTL_CONSTASCII_USTRINGPARAM(".$EXT"));
2269 aFunction.SearchAndReplaceAll(aPlaceHolder, maHTMLExtension);
2270 aStr += aFunction;
2272 aTmp.AssignAscii( JS_NavigateRel );
2273 aTmp.SearchAndReplaceAll(aPlaceHolder, maHTMLExtension);
2274 aStr += aTmp;
2276 if(mbImpress)
2278 aTmp.AssignAscii( JS_ExpandOutline );
2279 aTmp.SearchAndReplaceAll(aPlaceHolder, maHTMLExtension);
2280 aStr += aTmp;
2282 aTmp.AssignAscii( JS_CollapseOutline );
2283 aTmp.SearchAndReplaceAll(aPlaceHolder, maHTMLExtension);
2284 aStr += aTmp;
2286 aStr.AppendAscii( "// -->\r\n</script>\r\n" );
2288 aStr.AppendAscii( "</head>\r\n" );
2290 aStr.AppendAscii( "<frameset cols=\"*," );
2291 aStr += OUString::number((mnWidthPixel + 16));
2292 aStr.AppendAscii( "\">\r\n" );
2293 if(mbImpress)
2295 aStr.AppendAscii( " <frameset rows=\"42,*\">\r\n" );
2296 aStr.AppendAscii( " <frame src=\"navbar3" );
2297 aStr += StringToURL(maHTMLExtension);
2298 aStr.AppendAscii( "\" name=\"navbar2\" marginwidth=\"4\" marginheight=\"4\" scrolling=\"no\">\r\n" );
2300 aStr.AppendAscii( " <frame src=\"outline0" );
2301 aStr += StringToURL(maHTMLExtension);
2302 aStr.AppendAscii( "\" name=\"outline\">\r\n" );
2303 if(mbImpress)
2304 aStr.AppendAscii( " </frameset>\r\n" );
2306 if(mbNotes)
2308 aStr.AppendAscii( " <frameset rows=\"42," );
2309 aStr += OUString::number((int)((double)mnWidthPixel * 0.75) + 16);
2310 aStr.AppendAscii( ",*\">\r\n" );
2312 else
2313 aStr.AppendAscii( " <frameset rows=\"42,*\">\r\n" );
2315 aStr.AppendAscii( " <frame src=\"navbar0" );
2316 aStr += StringToURL(maHTMLExtension);
2317 aStr.AppendAscii( "\" name=\"navbar1\" marginwidth=\"4\" marginheight=\"4\" scrolling=\"no\">\r\n" );
2319 aStr.AppendAscii( " <frame src=\"" );
2320 aStr += StringToURL(*mpHTMLFiles[0]);
2321 aStr.AppendAscii( "\" name=\"show\" marginwidth=\"4\" marginheight=\"4\">\r\n" );
2323 if(mbNotes)
2325 aStr.AppendAscii( " <frame src=\"note0" );
2326 aStr += StringToURL(maHTMLExtension);
2327 aStr.AppendAscii( "\" name=\"notes\">\r\n" );
2329 aStr.AppendAscii( " </frameset>\r\n" );
2331 aStr.AppendAscii( "<noframes>\r\n" );
2332 aStr += CreateBodyTag();
2333 aStr += RESTOHTML(STR_HTMLEXP_NOFRAMES);
2334 aStr.AppendAscii( "\r\n</noframes>\r\n</frameset>\r\n</html>" );
2336 bool bOk = WriteHtml( maFramePage, false, aStr );
2338 if (mpProgress)
2339 mpProgress->SetState(++mnPagesWritten);
2341 return bOk;
2344 // ====================================================================
2345 // create button bar for standard
2346 // we create the following html files
2347 // navbar0.htm navigation bar graphic for the first page
2348 // navbar1.htm navigation bar graphic for the second until second last page
2349 // navbar2.htm navigation bar graphic for the last page
2350 // navbar3.htm navigation outline closed
2351 // navbar4.htm navigation outline open
2352 // ====================================================================
2353 bool HtmlExport::CreateNavBarFrames()
2355 bool bOk = true;
2356 String aButton;
2358 if( mbDocColors )
2360 SetDocColors();
2361 maBackColor = maFirstPageColor;
2364 for( int nFile = 0; nFile < 3 && bOk; nFile++ )
2366 String aStr(maHTMLHeader);
2367 aStr += WriteMetaCharset();
2368 aStr.AppendAscii( " <title>" );
2369 aStr += StringToHTMLString(*mpPageNames[0]);
2370 aStr.AppendAscii( "</title>\r\n</head>\r\n" );
2371 aStr += CreateBodyTag();
2372 aStr.AppendAscii( "<center>\r\n" );
2374 // first page
2375 aButton = String(SdResId(STR_HTMLEXP_FIRSTPAGE));
2376 if(mnButtonThema != -1)
2377 aButton = CreateImage(GetButtonName((nFile == 0 || mnSdPageCount == 1?
2378 BTN_FIRST_0:BTN_FIRST_1)), aButton);
2380 if(nFile != 0 && mnSdPageCount > 1)
2381 aButton = CreateLink( String(RTL_CONSTASCII_USTRINGPARAM("JavaScript:parent.NavigateAbs(0)")), aButton);
2383 aStr += aButton;
2384 aStr.AppendAscii( "\r\n" );
2386 // to the previous page
2387 aButton = String(SdResId(STR_PUBLISH_BACK));
2388 if(mnButtonThema != -1)
2389 aButton = CreateImage(GetButtonName((nFile == 0 || mnSdPageCount == 1?
2390 BTN_PREV_0:BTN_PREV_1)), aButton);
2392 if(nFile != 0 && mnSdPageCount > 1)
2393 aButton = CreateLink( String(RTL_CONSTASCII_USTRINGPARAM("JavaScript:parent.NavigateRel(-1)")), aButton);
2395 aStr += aButton;
2396 aStr.AppendAscii( "\r\n" );
2398 // to the next page
2399 aButton = String(SdResId(STR_PUBLISH_NEXT));
2400 if(mnButtonThema != -1)
2401 aButton = CreateImage(GetButtonName((nFile ==2 || mnSdPageCount == 1?
2402 BTN_NEXT_0:BTN_NEXT_1)), aButton);
2404 if(nFile != 2 && mnSdPageCount > 1)
2405 aButton = CreateLink(String(RTL_CONSTASCII_USTRINGPARAM("JavaScript:parent.NavigateRel(1)")), aButton);
2407 aStr += aButton;
2408 aStr.AppendAscii( "\r\n" );
2410 // to the last page
2411 aButton = String(SdResId(STR_HTMLEXP_LASTPAGE));
2412 if(mnButtonThema != -1)
2413 aButton = CreateImage(GetButtonName((nFile ==2 || mnSdPageCount == 1?
2414 BTN_LAST_0:BTN_LAST_1)), aButton);
2416 if(nFile != 2 && mnSdPageCount > 1)
2418 String aLink(RTL_CONSTASCII_USTRINGPARAM("JavaScript:parent.NavigateAbs("));
2419 aLink += OUString::number(mnSdPageCount-1);
2420 aLink.AppendAscii( ")" );
2421 aButton = CreateLink( aLink, aButton);
2424 aStr += aButton;
2425 aStr.AppendAscii( "\r\n" );
2427 // content
2428 if (mbContentsPage)
2430 aButton = String(SdResId(STR_PUBLISH_OUTLINE));
2431 if(mnButtonThema != -1)
2432 aButton = CreateImage(GetButtonName(BTN_INDEX), aButton);
2434 // to the overview
2435 aStr += CreateLink(maIndex, aButton, String(RTL_CONSTASCII_USTRINGPARAM("_top")));
2436 aStr.AppendAscii( "\r\n" );
2439 // text mode
2440 if(mbImpress)
2442 aButton = String(SdResId(STR_HTMLEXP_SETTEXT));
2443 if(mnButtonThema != -1)
2444 aButton = CreateImage(GetButtonName(BTN_TEXT), aButton);
2446 String aText0( RTL_CONSTASCII_USTRINGPARAM("text0"));
2447 aText0 += maHTMLExtension;
2448 aStr += CreateLink( aText0, aButton, String(RTL_CONSTASCII_USTRINGPARAM("_top")));
2449 aStr.AppendAscii( "\r\n" );
2452 // and finished...
2453 aStr.AppendAscii( "</center>\r\n" );
2454 aStr.AppendAscii( "</body>\r\n</html>" );
2456 String aFileName( RTL_CONSTASCII_USTRINGPARAM("navbar") );
2457 aFileName += OUString::number(nFile);
2459 bOk = WriteHtml( aFileName, true, aStr );
2461 if (mpProgress)
2462 mpProgress->SetState(++mnPagesWritten);
2465 // the navigation bar outliner closed...
2466 if(bOk)
2468 String aStr(maHTMLHeader);
2469 aStr += WriteMetaCharset();
2470 aStr.AppendAscii( " <title>" );
2471 aStr += StringToHTMLString(*mpPageNames[0]);
2472 aStr.AppendAscii( "</title>\r\n</head>\r\n" );
2473 aStr += CreateBodyTag();
2475 aButton = String(SdResId(STR_HTMLEXP_OUTLINE));
2476 if(mnButtonThema != -1)
2477 aButton = CreateImage(GetButtonName(BTN_MORE), aButton);
2479 aStr += CreateLink(String(RTL_CONSTASCII_USTRINGPARAM("JavaScript:parent.ExpandOutline()")), aButton);
2480 aStr.AppendAscii( "</body>\r\n</html>" );
2482 String aFileName( RTL_CONSTASCII_USTRINGPARAM("navbar3") );
2484 bOk = WriteHtml( aFileName, true, aStr );
2486 if (mpProgress)
2487 mpProgress->SetState(++mnPagesWritten);
2490 // ... and the outliner open
2491 if( bOk )
2493 String aStr(maHTMLHeader);
2494 aStr += WriteMetaCharset();
2495 aStr.AppendAscii( " <title>" );
2496 aStr += StringToHTMLString(*mpPageNames[0]);
2497 aStr.AppendAscii( "</title>\r\n</head>\r\n" );
2498 aStr += CreateBodyTag();
2500 aButton = String(SdResId(STR_HTMLEXP_NOOUTLINE));
2501 if(mnButtonThema != -1)
2502 aButton = CreateImage(GetButtonName(BTN_LESS), aButton);
2504 aStr += CreateLink(String(RTL_CONSTASCII_USTRINGPARAM("JavaScript:parent.CollapseOutline()")), aButton);
2505 aStr.AppendAscii( "</body>\r\n</html>" );
2507 String aFileName( RTL_CONSTASCII_USTRINGPARAM("navbar4") );
2508 bOk = WriteHtml( aFileName, true, aStr );
2510 if (mpProgress)
2511 mpProgress->SetState(++mnPagesWritten);
2515 return bOk;
2518 // ====================================================================
2519 // create button bar for standard
2520 // ====================================================================
2521 String HtmlExport::CreateNavBar( sal_uInt16 nSdPage, bool bIsText ) const
2523 // prepare button bar
2524 String aStrNavFirst( SdResId(STR_HTMLEXP_FIRSTPAGE) );
2525 String aStrNavPrev( SdResId(STR_PUBLISH_BACK) );
2526 String aStrNavNext( SdResId(STR_PUBLISH_NEXT) );
2527 String aStrNavLast( SdResId(STR_HTMLEXP_LASTPAGE) );
2528 String aStrNavContent( SdResId(STR_PUBLISH_OUTLINE) );
2529 String aStrNavText;
2530 if( bIsText )
2532 aStrNavText = String( SdResId(STR_HTMLEXP_SETGRAPHIC) );
2534 else
2536 aStrNavText = String( SdResId(STR_HTMLEXP_SETTEXT) );
2539 if(!bIsText && mnButtonThema != -1)
2541 if(nSdPage<1 || mnSdPageCount == 1)
2543 aStrNavFirst = CreateImage(GetButtonName(BTN_FIRST_0), aStrNavFirst);
2544 aStrNavPrev = CreateImage(GetButtonName(BTN_PREV_0), aStrNavPrev);
2546 else
2548 aStrNavFirst = CreateImage(GetButtonName(BTN_FIRST_1), aStrNavFirst);
2549 aStrNavPrev = CreateImage(GetButtonName(BTN_PREV_1), aStrNavPrev);
2552 if(nSdPage == mnSdPageCount-1 || mnSdPageCount == 1)
2554 aStrNavNext = CreateImage(GetButtonName(BTN_NEXT_0), aStrNavNext);
2555 aStrNavLast = CreateImage(GetButtonName(BTN_LAST_0), aStrNavLast);
2557 else
2559 aStrNavNext = CreateImage(GetButtonName(BTN_NEXT_1), aStrNavNext);
2560 aStrNavLast = CreateImage(GetButtonName(BTN_LAST_1), aStrNavLast);
2563 aStrNavContent = CreateImage(GetButtonName(BTN_INDEX), aStrNavContent);
2564 aStrNavText = CreateImage(GetButtonName(BTN_TEXT), aStrNavText);
2567 String aStr( RTL_CONSTASCII_USTRINGPARAM("<center>\r\n")); //<table><tr>\r\n");
2569 // first page
2570 if(nSdPage > 0)
2571 aStr += CreateLink(bIsText?*mpTextFiles[0]:*mpHTMLFiles[0],aStrNavFirst);
2572 else
2573 aStr += aStrNavFirst;
2574 aStr.Append(sal_Unicode(' '));
2576 // to Previous page
2577 if(nSdPage > 0)
2578 aStr += CreateLink( bIsText?*mpTextFiles[nSdPage-1]:
2579 *mpHTMLFiles[nSdPage-1], aStrNavPrev);
2580 else
2581 aStr += aStrNavPrev;
2582 aStr.Append(sal_Unicode(' '));
2584 // to Next page
2585 if(nSdPage < mnSdPageCount-1)
2586 aStr += CreateLink( bIsText?*mpTextFiles[nSdPage+1]:
2587 *mpHTMLFiles[nSdPage+1], aStrNavNext);
2588 else
2589 aStr += aStrNavNext;
2590 aStr.Append(sal_Unicode(' '));
2592 // to Last page
2593 if(nSdPage < mnSdPageCount-1)
2594 aStr += CreateLink( bIsText?*mpTextFiles[mnSdPageCount-1]:
2595 *mpHTMLFiles[mnSdPageCount-1],
2596 aStrNavLast );
2597 else
2598 aStr += aStrNavLast;
2599 aStr.Append(sal_Unicode(' '));
2601 // to Index page
2602 if (mbContentsPage)
2604 aStr += CreateLink(maIndex, aStrNavContent);
2605 aStr.Append(sal_Unicode(' '));
2608 // Text/Graphics
2609 if(mbImpress)
2611 aStr += CreateLink( bIsText?(mbFrames?maFramePage:*mpHTMLFiles[nSdPage]):
2612 *mpTextFiles[nSdPage], aStrNavText);
2616 aStr.AppendAscii( "</center><br>\r\n" );
2618 return aStr;
2621 /** export navigation graphics from button set */
2622 bool HtmlExport::CreateBitmaps()
2624 if(mnButtonThema != -1 && mpButtonSet.get() )
2626 for( int nButton = 0; nButton != SAL_N_ELEMENTS(pButtonNames); nButton++ )
2628 if(!mbFrames && (nButton == BTN_MORE || nButton == BTN_LESS))
2629 continue;
2631 if(!mbImpress && (nButton == BTN_TEXT || nButton == BTN_MORE || nButton == BTN_LESS ))
2632 continue;
2634 OUString aFull(maExportPath);
2635 aFull += GetButtonName(nButton);
2636 mpButtonSet->exportButton( mnButtonThema, aFull, GetButtonName(nButton) );
2639 return true;
2642 // =====================================================================
2643 // creates the <body> tag, including the specified color attributes
2644 // =====================================================================
2645 String HtmlExport::CreateBodyTag() const
2647 String aStr( RTL_CONSTASCII_USTRINGPARAM("<body") );
2649 if( mbUserAttr || mbDocColors )
2651 Color aTextColor( maTextColor );
2652 if( (aTextColor == COL_AUTO) && (!maBackColor.IsDark()) )
2653 aTextColor = COL_BLACK;
2655 aStr.AppendAscii( " text=\"" );
2656 aStr += ColorToHTMLString( aTextColor );
2657 aStr.AppendAscii( "\" bgcolor=\"" );
2658 aStr += ColorToHTMLString( maBackColor );
2659 aStr.AppendAscii( "\" link=\"" );
2660 aStr += ColorToHTMLString( maLinkColor );
2661 aStr.AppendAscii( "\" vlink=\"" );
2662 aStr += ColorToHTMLString( maVLinkColor );
2663 aStr.AppendAscii( "\" alink=\"" );
2664 aStr += ColorToHTMLString( maALinkColor );
2665 aStr.AppendAscii( "\"" );
2668 aStr.AppendAscii( ">\r\n" );
2670 return aStr;
2673 // =====================================================================
2674 // creates a hyperlink
2675 // =====================================================================
2676 String HtmlExport::CreateLink( const String& aLink,
2677 const String& aText,
2678 const String& aTarget ) const
2680 String aStr( RTL_CONSTASCII_USTRINGPARAM("<a href=\""));
2681 aStr += StringToURL(aLink);
2682 if(aTarget.Len())
2684 aStr.AppendAscii( "\" target=\"" );
2685 aStr += aTarget;
2687 aStr.AppendAscii( "\">" );
2688 aStr += aText;
2689 aStr.AppendAscii( "</a>" );
2691 return aStr;
2694 // =====================================================================
2695 // creates a image tag
2696 // =====================================================================
2697 String HtmlExport::CreateImage( const String& aImage, const String& aAltText,
2698 sal_Int16 nWidth,
2699 sal_Int16 nHeight ) const
2701 String aStr( RTL_CONSTASCII_USTRINGPARAM("<img src=\""));
2702 aStr += StringToURL(aImage);
2703 aStr.AppendAscii( "\" border=0" );
2705 if( aAltText.Len())
2707 aStr.AppendAscii( " alt=\"" );
2708 aStr += aAltText;
2709 aStr.Append(sal_Unicode('"'));
2711 else
2713 // Agerskov: HTML 4.01 has to have an alt attribut even if it is an empty string
2714 aStr.AppendAscii( " alt=\"\"" );
2717 if(nWidth > -1)
2719 aStr.AppendAscii( " width=" );
2720 aStr += OUString::number(nWidth);
2723 if(nHeight > -1)
2725 aStr.AppendAscii( " height=" );
2726 aStr += OUString::number(nHeight);
2729 aStr.Append(sal_Unicode('>'));
2731 return aStr;
2734 // =====================================================================
2735 // create area for a circle; we expect pixel coordinates
2736 // =====================================================================
2737 String HtmlExport::ColorToHTMLString( Color aColor )
2739 static char hex[] = "0123456789ABCDEF";
2740 String aStr( RTL_CONSTASCII_USTRINGPARAM("#xxxxxx"));
2741 aStr.SetChar(1, hex[(aColor.GetRed() >> 4) & 0xf] );
2742 aStr.SetChar(2, hex[aColor.GetRed() & 0xf] );
2743 aStr.SetChar(3, hex[(aColor.GetGreen() >> 4) & 0xf] );
2744 aStr.SetChar(4, hex[aColor.GetGreen() & 0xf] );
2745 aStr.SetChar(5, hex[(aColor.GetBlue() >> 4) & 0xf] );
2746 aStr.SetChar(6, hex[aColor.GetBlue() & 0xf] );
2748 return aStr;
2751 // =====================================================================
2752 // create area for a circle; we expect pixel coordinates
2753 // =====================================================================
2754 String HtmlExport::CreateHTMLCircleArea( sal_uLong nRadius,
2755 sal_uLong nCenterX,
2756 sal_uLong nCenterY,
2757 const String& rHRef ) const
2759 String aStr( RTL_CONSTASCII_USTRINGPARAM("<area shape=\"circle\" alt=\"\" coords=\"" ));
2761 aStr += OUString::number(nCenterX);
2762 aStr.Append(sal_Unicode(','));
2763 aStr += OUString::number(nCenterY);
2764 aStr.Append(sal_Unicode(','));
2765 aStr += OUString::number(nRadius);
2766 aStr.AppendAscii( "\" href=\"" );
2767 aStr += StringToURL(rHRef);
2768 aStr.AppendAscii( "\">\n" );
2770 return aStr;
2774 // =====================================================================
2775 // create area for a polygon; we expect pixel coordinates
2776 // =====================================================================
2777 String HtmlExport::CreateHTMLPolygonArea( const ::basegfx::B2DPolyPolygon& rPolyPolygon,
2778 Size aShift, double fFactor, const String& rHRef ) const
2780 String aStr;
2781 const sal_uInt32 nNoOfPolygons(rPolyPolygon.count());
2783 for ( sal_uInt32 nXPoly = 0L; nXPoly < nNoOfPolygons; nXPoly++ )
2785 const ::basegfx::B2DPolygon& aPolygon = rPolyPolygon.getB2DPolygon(nXPoly);
2786 const sal_uInt32 nNoOfPoints(aPolygon.count());
2788 aStr.AppendAscii( "<area shape=\"polygon\" alt=\"\" coords=\"" );
2790 for ( sal_uInt32 nPoint = 0L; nPoint < nNoOfPoints; nPoint++ )
2792 const ::basegfx::B2DPoint aB2DPoint(aPolygon.getB2DPoint(nPoint));
2793 Point aPnt(FRound(aB2DPoint.getX()), FRound(aB2DPoint.getY()));
2794 // coordinates are relative to the physical page origin, not the
2795 // origin of ordinates
2796 aPnt.Move(aShift.Width(), aShift.Height());
2798 aPnt.X() = (long)(aPnt.X() * fFactor);
2799 aPnt.Y() = (long)(aPnt.Y() * fFactor);
2800 aStr += OUString::number(aPnt.X());
2801 aStr.Append(sal_Unicode(','));
2802 aStr += OUString::number(aPnt.Y());
2804 if (nPoint < nNoOfPoints - 1)
2805 aStr.Append( sal_Unicode(',') );
2807 aStr.AppendAscii( "\" href=\"" );
2808 aStr += StringToURL(rHRef);
2809 aStr.AppendAscii( "\">\n" );
2812 return aStr;
2815 // =====================================================================
2816 // create area for a rectangle; we expect pixel coordinates
2817 // =====================================================================
2818 String HtmlExport::CreateHTMLRectArea( const Rectangle& rRect,
2819 const String& rHRef ) const
2821 String aStr( RTL_CONSTASCII_USTRINGPARAM("<area shape=\"rect\" alt=\"\" coords=\"") );
2823 aStr += OUString::number(rRect.Left());
2824 aStr.Append(sal_Unicode(','));
2825 aStr += OUString::number(rRect.Top());
2826 aStr.Append(sal_Unicode(','));
2827 aStr += OUString::number(rRect.Right());
2828 aStr.Append(sal_Unicode(','));
2829 aStr += OUString::number(rRect.Bottom());
2830 aStr.AppendAscii( "\" href=\"" );
2831 aStr += StringToURL(rHRef);
2832 aStr.AppendAscii( "\">\n" );
2834 return aStr;
2837 // =====================================================================
2838 // escapes a string for html
2839 // =====================================================================
2840 String HtmlExport::StringToHTMLString( const String& rString )
2842 SvMemoryStream aMemStm;
2843 HTMLOutFuncs::Out_String( aMemStm, rString, RTL_TEXTENCODING_UTF8 );
2844 aMemStm << (char) 0;
2845 return String( (char*)aMemStm.GetData(), RTL_TEXTENCODING_UTF8 );
2848 // =====================================================================
2849 // creates a url for a specific page
2850 // =====================================================================
2851 String HtmlExport::CreatePageURL( sal_uInt16 nPgNum )
2853 if(mbFrames)
2855 String aUrl( RTL_CONSTASCII_USTRINGPARAM("JavaScript:parent.NavigateAbs("));
2856 aUrl += OUString::number(nPgNum);
2857 aUrl.Append(sal_Unicode(')'));
2858 return aUrl;
2860 else
2861 return *mpHTMLFiles[nPgNum];
2864 bool HtmlExport::CopyScript( const String& rPath, const String& rSource, const String& rDest, bool bUnix /* = false */ )
2866 INetURLObject aURL( SvtPathOptions().GetConfigPath() );
2867 String aScript;
2869 aURL.Append( OUString("webcast") );
2870 aURL.Append( rSource );
2872 meEC.SetContext( STR_HTMLEXP_ERROR_OPEN_FILE, rSource );
2874 sal_uLong nErr = 0;
2875 SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ );
2877 if( pIStm )
2879 OString aLine;
2881 while( pIStm->ReadLine( aLine ) )
2883 aScript.AppendAscii( aLine.getStr() );
2884 if( bUnix )
2886 aScript.AppendAscii( "\n" );
2888 else
2890 aScript.AppendAscii( "\r\n" );
2894 nErr = pIStm->GetError();
2895 delete pIStm;
2898 if( nErr != 0 )
2900 ErrorHandler::HandleError( nErr );
2901 return (bool) nErr;
2905 aScript.SearchAndReplaceAll( String(RTL_CONSTASCII_USTRINGPARAM("$$1")), getDocumentTitle() );
2907 const String aSaveStr( RESTOHTML( STR_WEBVIEW_SAVE ));
2908 aScript.SearchAndReplaceAll( String(RTL_CONSTASCII_USTRINGPARAM("$$2")), aSaveStr );
2910 aScript.SearchAndReplaceAll( String(RTL_CONSTASCII_USTRINGPARAM("$$3")), maCGIPath );
2912 aScript.SearchAndReplaceAll( String(RTL_CONSTASCII_USTRINGPARAM("$$4")), OUString::number(mnWidthPixel) );
2913 aScript.SearchAndReplaceAll( String(RTL_CONSTASCII_USTRINGPARAM("$$5")), OUString::number(mnHeightPixel) );
2916 String aDest( rPath );
2917 aDest += rDest;
2919 meEC.SetContext( STR_HTMLEXP_ERROR_CREATE_FILE, rDest );
2920 // write script file
2922 EasyFile aFile;
2923 SvStream* pStr;
2924 nErr = aFile.createStream(aDest, pStr);
2925 if(nErr == 0)
2927 OString aStr(OUStringToOString(aScript,
2928 RTL_TEXTENCODING_UTF8));
2929 *pStr << aStr.getStr();
2931 nErr = aFile.close();
2935 if (mpProgress)
2936 mpProgress->SetState(++mnPagesWritten);
2938 if( nErr != 0 )
2939 ErrorHandler::HandleError( nErr );
2941 return nErr == 0;
2944 static const char * ASP_Scripts[] = { "common.inc", "webcast.asp", "show.asp", "savepic.asp", "poll.asp", "editpic.asp" };
2946 /** creates and saves the ASP scripts for WebShow */
2947 bool HtmlExport::CreateASPScripts()
2949 for( sal_uInt16 n = 0; n < (sizeof( ASP_Scripts ) / sizeof(char *)); n++ )
2951 String aScript;
2953 aScript.AssignAscii( ASP_Scripts[n] );
2954 if(!CopyScript(maExportPath, aScript, aScript))
2955 return false;
2958 if(!CopyScript(maExportPath, String(RTL_CONSTASCII_USTRINGPARAM("edit.asp")), maIndex ))
2959 return false;
2961 return true;
2965 static const char *PERL_Scripts[] = { "webcast.pl", "common.pl", "editpic.pl", "poll.pl", "savepic.pl", "show.pl" };
2967 /** creates and saves the PERL scripts for WebShow */
2968 bool HtmlExport::CreatePERLScripts()
2970 for( sal_uInt16 n = 0; n < (sizeof( PERL_Scripts ) / sizeof(char *)); n++ )
2972 String aScript;
2973 aScript.AssignAscii( PERL_Scripts[n] );
2974 if(!CopyScript(maExportPath, aScript, aScript, true))
2975 return false;
2978 if(!CopyScript(maExportPath, OUString("edit.pl"), maIndex, true ))
2979 return false;
2981 if(!CopyScript(maExportPath, OUString("index.pl"), maIndexUrl, true ))
2982 return false;
2984 return true;
2987 /** creates a list with names of the saved images */
2988 bool HtmlExport::CreateImageFileList()
2990 String aStr;
2991 for( sal_uInt16 nSdPage = 0; nSdPage < mnSdPageCount; nSdPage++)
2993 aStr += OUString::number( nSdPage + 1 );
2994 aStr.Append(sal_Unicode(';'));
2995 aStr += maURLPath;
2996 aStr += *mpImageFiles[nSdPage];
2997 aStr.AppendAscii( "\r\n" );
3000 String aFileName( RTL_CONSTASCII_USTRINGPARAM("picture.txt") );
3001 bool bOk = WriteHtml( aFileName, false, aStr );
3003 if (mpProgress)
3004 mpProgress->SetState(++mnPagesWritten);
3006 return bOk;
3009 /** creates a file with the actual page number */
3010 bool HtmlExport::CreateImageNumberFile()
3012 String aFull( maExportPath );
3013 String aFileName( RTL_CONSTASCII_USTRINGPARAM("currpic.txt") );
3014 aFull += aFileName;
3016 meEC.SetContext( STR_HTMLEXP_ERROR_CREATE_FILE, aFileName );
3017 EasyFile aFile;
3018 SvStream* pStr;
3019 sal_uLong nErr = aFile.createStream(aFull, pStr);
3020 if(nErr == 0)
3022 *pStr << (const char *)"1";
3023 nErr = aFile.close();
3026 if (mpProgress)
3027 mpProgress->SetState(++mnPagesWritten);
3029 if( nErr != 0 )
3030 ErrorHandler::HandleError( nErr );
3032 return nErr == 0;
3035 // =====================================================================
3037 String HtmlExport::InsertSound( const String& rSoundFile )
3039 if( rSoundFile.Len() == 0 )
3040 return rSoundFile;
3042 String aStr( RTL_CONSTASCII_USTRINGPARAM("<embed src=\"") );
3043 INetURLObject aURL( rSoundFile );
3044 String aSoundFileName = String(aURL.getName());
3046 DBG_ASSERT( aURL.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" );
3048 aStr += aSoundFileName;
3049 aStr.AppendAscii( "\" hidden=\"true\" autostart=\"true\">" );
3051 CopyFile( OUString(rSoundFile), OUString(maExportPath) + OUString(aSoundFileName) );
3053 return aStr;
3056 // =====================================================================
3058 bool HtmlExport::CopyFile( const OUString& rSourceFile, const OUString& rDestFile )
3060 meEC.SetContext( STR_HTMLEXP_ERROR_COPY_FILE, rSourceFile, rDestFile );
3061 osl::FileBase::RC Error = osl::File::copy( rSourceFile, rDestFile );
3063 if( Error != osl::FileBase::E_None )
3065 ErrorHandler::HandleError(Error);
3066 return false;
3068 else
3070 return true;
3074 // =====================================================================
3076 bool HtmlExport::checkFileExists( Reference< ::com::sun::star::ucb::XSimpleFileAccess3 >& xFileAccess, String const & aFileName )
3080 OUString url( maExportPath );
3081 url += aFileName;
3082 return xFileAccess->exists( url );
3084 catch( com::sun::star::uno::Exception& )
3086 OSL_FAIL(OString(OString("sd::HtmlExport::checkFileExists(), exception caught: ") +
3087 OUStringToOString( comphelper::anyToString( cppu::getCaughtException() ), RTL_TEXTENCODING_UTF8 )).getStr() );
3090 return false;
3093 // ---------------------------------------------------------------------
3095 bool HtmlExport::checkForExistingFiles()
3097 bool bFound = false;
3101 Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
3102 uno::Reference<ucb::XSimpleFileAccess3> xFA(ucb::SimpleFileAccess::create(xContext));
3104 sal_uInt16 nSdPage;
3105 for( nSdPage = 0; !bFound && (nSdPage < mnSdPageCount); nSdPage++)
3107 if( (mpImageFiles[nSdPage] && checkFileExists( xFA, *mpImageFiles[nSdPage] )) ||
3108 (mpHTMLFiles[nSdPage] && checkFileExists( xFA, *mpHTMLFiles[nSdPage] )) ||
3109 (mpThumbnailFiles[nSdPage] && checkFileExists( xFA, *mpThumbnailFiles[nSdPage] )) ||
3110 (mpPageNames[nSdPage] && checkFileExists( xFA, *mpPageNames[nSdPage] )) ||
3111 (mpTextFiles[nSdPage] && checkFileExists( xFA, *mpTextFiles[nSdPage] )) )
3113 bFound = true;
3117 if( !bFound && mbDownload )
3118 bFound = checkFileExists( xFA, maDocFileName );
3120 if( !bFound && mbFrames )
3121 bFound = checkFileExists( xFA, maFramePage );
3123 if( bFound )
3125 ResMgr *pResMgr = CREATERESMGR( dbw );
3126 if( pResMgr )
3128 ResId aResId( 4077, *pResMgr );
3129 String aMsg( aResId );
3131 OUString aSystemPath;
3132 osl::FileBase::getSystemPathFromFileURL( maExportPath, aSystemPath );
3133 aMsg.SearchAndReplaceAscii( "%FILENAME", aSystemPath );
3134 WarningBox aWarning( 0, WB_YES_NO | WB_DEF_YES, aMsg );
3135 aWarning.SetImage( WarningBox::GetStandardImage() );
3136 bFound = ( RET_NO == aWarning.Execute() );
3138 delete pResMgr;
3140 else
3142 bFound = false;
3146 catch( Exception& )
3148 OSL_FAIL(OString(OString("sd::HtmlExport::checkForExistingFiles(), exception caught: ") +
3149 OUStringToOString( comphelper::anyToString( cppu::getCaughtException() ), RTL_TEXTENCODING_UTF8 )).getStr() );
3150 bFound = false;
3153 return bFound;
3156 // ---------------------------------------------------------------------
3158 String HtmlExport::StringToURL( const String& rURL )
3160 return rURL;
3163 String HtmlExport::GetButtonName( int nButton ) const
3165 String aName;
3166 aName.AssignAscii( pButtonNames[nButton] );
3167 return aName;
3170 // =====================================================================
3171 EasyFile::EasyFile()
3173 pMedium = NULL;
3174 pOStm = NULL;
3175 bOpen = false;
3178 // =====================================================================
3179 EasyFile::~EasyFile()
3181 if( bOpen )
3182 close();
3185 // =====================================================================
3186 sal_uLong EasyFile::createStream( const String& rUrl, SvStream* &rpStr )
3188 sal_uLong nErr = 0;
3190 if(bOpen)
3191 nErr = close();
3193 String aFileName;
3195 if( nErr == 0 )
3196 nErr = createFileName( rUrl, aFileName );
3198 if( nErr == 0 )
3200 pOStm = ::utl::UcbStreamHelper::CreateStream( aFileName, STREAM_WRITE | STREAM_TRUNC );
3201 if( pOStm )
3203 bOpen = true;
3204 nErr = pOStm->GetError();
3206 else
3208 nErr = ERRCODE_SFX_CANTCREATECONTENT;
3212 if( nErr != 0 )
3214 bOpen = false;
3215 delete pMedium;
3216 delete pOStm;
3217 pOStm = NULL;
3220 rpStr = pOStm;
3222 return nErr;
3225 // =====================================================================
3226 sal_uLong EasyFile::createFileName( const String& rURL, String& rFileName )
3228 sal_uLong nErr = 0;
3230 if( bOpen )
3231 nErr = close();
3233 if( nErr == 0 )
3235 INetURLObject aURL( rURL );
3237 if( aURL.GetProtocol() == INET_PROT_NOT_VALID )
3239 OUString aURLStr;
3240 ::utl::LocalFileHelper::ConvertPhysicalNameToURL( rURL, aURLStr );
3241 aURL = INetURLObject( aURLStr );
3243 DBG_ASSERT( aURL.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" );
3244 rFileName = aURL.GetMainURL( INetURLObject::NO_DECODE );
3247 return nErr;
3250 // =====================================================================
3251 sal_uLong EasyFile::close()
3253 sal_uLong nErr = 0;
3255 delete pOStm;
3256 pOStm = NULL;
3258 bOpen = false;
3260 if( pMedium )
3262 // transmitted
3263 pMedium->Close();
3264 pMedium->Commit();
3266 nErr = pMedium->GetError();
3268 delete pMedium;
3269 pMedium = NULL;
3272 return nErr;
3275 // =====================================================================
3276 // This class helps reporting errors during file i/o
3277 // =====================================================================
3279 HtmlErrorContext::HtmlErrorContext(Window *_pWin)
3280 : ErrorContext(_pWin)
3282 mnResId = 0;
3285 // =====================================================================
3287 sal_Bool HtmlErrorContext::GetString( sal_uLong, OUString& rCtxStr )
3289 DBG_ASSERT( mnResId != 0, "No error context set" );
3290 if( mnResId == 0 )
3291 return false;
3293 rCtxStr = SdResId( mnResId );
3295 rCtxStr = rCtxStr.replaceAll( OUString("$(URL1)"), maURL1 );
3296 rCtxStr = rCtxStr.replaceAll( OUString("$(URL2)"), maURL2 );
3298 return true;
3301 // =====================================================================
3303 void HtmlErrorContext::SetContext( sal_uInt16 nResId, const String& rURL )
3305 mnResId = nResId;
3306 maURL1 = rURL;
3307 maURL2.Erase();
3310 // =====================================================================
3312 void HtmlErrorContext::SetContext( sal_uInt16 nResId, const String& rURL1, const String& rURL2 )
3314 mnResId = nResId;
3315 maURL1 = rURL1;
3316 maURL2 = rURL2;
3319 // =====================================================================
3322 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */