diff options
Diffstat (limited to 'sd/source/filter')
44 files changed, 32125 insertions, 0 deletions
diff --git a/sd/source/filter/cgm/makefile.mk b/sd/source/filter/cgm/makefile.mk new file mode 100644 index 000000000000..65ac2c48557d --- /dev/null +++ b/sd/source/filter/cgm/makefile.mk @@ -0,0 +1,43 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. +PRJNAME=sd +TARGET=cgm + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = $(SLO)$/sdcgmfilter.obj + +# --- Targets -------------------------------------------------------------- + +.INCLUDE : target.mk diff --git a/sd/source/filter/cgm/sdcgmfilter.cxx b/sd/source/filter/cgm/sdcgmfilter.cxx new file mode 100644 index 000000000000..7d28e5285f40 --- /dev/null +++ b/sd/source/filter/cgm/sdcgmfilter.cxx @@ -0,0 +1,159 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" + +#include <osl/module.hxx> +#include <tools/urlobj.hxx> +#include <svl/itemset.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/docfilt.hxx> +#include <svx/xflclit.hxx> +#include <svx/xfillit0.hxx> + +#include "sdpage.hxx" +#include "drawdoc.hxx" +#include "sdcgmfilter.hxx" + +// ----------- +// - Defines - +// ----------- + +#define CGM_IMPORT_CGM 0x00000001 +#define CGM_IMPORT_IM 0x00000002 + +#define CGM_EXPORT_IMPRESS 0x00000100 +#define CGM_EXPORT_META 0x00000200 +#define CGM_EXPORT_COMMENT 0x00000400 + +#define CGM_NO_PAD_BYTE 0x00010000 +#define CGM_BIG_ENDIAN 0x00020000 +#define CGM_LITTLE_ENDIAN 0x00040000 + +// -------------- +// - Namespaces - +// -------------- + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::task; +using namespace ::com::sun::star::frame; + +// ------------ +// - Typedefs - +// ------------ + +typedef UINT32 ( __LOADONCALLAPI *ImportCGM )( ::rtl::OUString&, Reference< XModel >&, UINT32, Reference< XStatusIndicator >& ); +typedef BOOL ( __LOADONCALLAPI *ExportCGM )( ::rtl::OUString&, Reference< XModel >&, Reference< XStatusIndicator >&, void* ); + +// --------------- +// - SdPPTFilter - +// --------------- + +SdCGMFilter::SdCGMFilter( SfxMedium& rMedium, ::sd::DrawDocShell& rDocShell, sal_Bool bShowProgress ) : + SdFilter( rMedium, rDocShell, bShowProgress ) +{ +} + +// ----------------------------------------------------------------------------- + +SdCGMFilter::~SdCGMFilter() +{ +} + +// ----------------------------------------------------------------------------- + +sal_Bool SdCGMFilter::Import() +{ + ::osl::Module* pLibrary = OpenLibrary( mrMedium.GetFilter()->GetUserData() ); + sal_Bool bRet = sal_False; + + if( pLibrary && mxModel.is() ) + { + ImportCGM FncImportCGM = reinterpret_cast< ImportCGM >( pLibrary->getFunctionSymbol( ::rtl::OUString::createFromAscii( "ImportCGM" ) ) ); + ::rtl::OUString aFileURL( mrMedium.GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ); + UINT32 nRetValue; + + if( mrDocument.GetPageCount() == 0L ) + mrDocument.CreateFirstPages(); + + CreateStatusIndicator(); + nRetValue = FncImportCGM( aFileURL, mxModel, CGM_IMPORT_CGM | CGM_BIG_ENDIAN | CGM_EXPORT_IMPRESS, mxStatusIndicator ); + + if( nRetValue ) + { + bRet = TRUE; + + if( ( nRetValue &~0xff000000 ) != 0xffffff ) // maybe the backgroundcolor is already white + { // so we must not set a master page + mrDocument.StopWorkStartupDelay(); + SdPage* pSdPage = mrDocument.GetMasterSdPage(0, PK_STANDARD); + + if(pSdPage) + { + // set PageFill to given color + const Color aColor((BYTE)(nRetValue >> 16), (BYTE)(nRetValue >> 8), (BYTE)(nRetValue >> 16)); + pSdPage->getSdrPageProperties().PutItem(XFillColorItem(String(), aColor)); + pSdPage->getSdrPageProperties().PutItem(XFillStyleItem(XFILL_SOLID)); + } + } + } + } + + delete pLibrary; + + return bRet; +} + +// ----------------------------------------------------------------------------- + +sal_Bool SdCGMFilter::Export() +{ + ::osl::Module* pLibrary = OpenLibrary( mrMedium.GetFilter()->GetUserData() ); + sal_Bool bRet = sal_False; + + if( pLibrary && mxModel.is() ) + { + ExportCGM FncCGMExport = reinterpret_cast< ExportCGM >( pLibrary->getFunctionSymbol( ::rtl::OUString::createFromAscii( "ExportCGM" ) ) ); + + if( FncCGMExport ) + { + ::rtl::OUString aPhysicalName( mrMedium.GetPhysicalName() ); + + /* !!! + if ( pViewShell && pViewShell->GetView() ) + pViewShell->GetView()->SdrEndTextEdit(); + */ + CreateStatusIndicator(); + bRet = FncCGMExport( aPhysicalName, mxModel, mxStatusIndicator, NULL ); + } + } + + delete pLibrary; + + return bRet; +} diff --git a/sd/source/filter/eppt/eppt.cxx b/sd/source/filter/eppt/eppt.cxx new file mode 100644 index 000000000000..2a40c8707866 --- /dev/null +++ b/sd/source/filter/eppt/eppt.cxx @@ -0,0 +1,2502 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" +#include <eppt.hxx> +#include "epptdef.hxx" +#include <tools/globname.hxx> +#include <tools/datetime.hxx> +#include <tools/poly.hxx> +#include <vcl/graph.hxx> +#include <vcl/bmpacc.hxx> +#include <vcl/gradient.hxx> +#include <rtl/ustring.hxx> +#include <tools/stream.hxx> +#include <svtools/fltcall.hxx> +#include <sfx2/docfile.hxx> +#include <svx/unoapi.hxx> +#include <svx/svdobj.hxx> +#include <svx/svdoole2.hxx> +#include <svx/svdmodel.hxx> +#include <svx/svdpage.hxx> +#include <com/sun/star/view/PaperOrientation.hpp> +#include <com/sun/star/view/PaperFormat.hpp> +#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> +#include <com/sun/star/office/XAnnotation.hpp> +#include <com/sun/star/office/XAnnotationAccess.hpp> +#include <com/sun/star/office/XAnnotationEnumeration.hpp> +#include <com/sun/star/geometry/RealPoint2D.hpp> +#include <com/sun/star/util/DateTime.hpp> +#include <tools/zcodec.hxx> +#include <editeng/svxenum.hxx> +#include <sot/storinfo.hxx> +#include <filter/msfilter/msoleexp.hxx> +#include <vcl/virdev.hxx> +#include <svtools/wmf.hxx> +#include <filter/msfilter/msdffimp.hxx> +#include <filter/msfilter/svxmsbas.hxx> +#include <editeng/flditem.hxx> +#include <sfx2/docinf.hxx> + +#define PPT_TRANSITION_TYPE_NONE 0 +#define PPT_TRANSITION_TYPE_RANDOM 1 +#define PPT_TRANSITION_TYPE_BLINDS 2 +#define PPT_TRANSITION_TYPE_CHECKER 3 +#define PPT_TRANSITION_TYPE_COVER 4 +#define PPT_TRANSITION_TYPE_DISSOLVE 5 +#define PPT_TRANSITION_TYPE_FADE 6 +#define PPT_TRANSITION_TYPE_PULL 7 +#define PPT_TRANSITION_TYPE_RANDOM_BARS 8 +#define PPT_TRANSITION_TYPE_STRIPS 9 +#define PPT_TRANSITION_TYPE_WIPE 10 +#define PPT_TRANSITION_TYPE_ZOOM 11 +#define PPT_TRANSITION_TYPE_SPLIT 13 + +// effects, new in xp +#define PPT_TRANSITION_TYPE_DIAMOND 17 +#define PPT_TRANSITION_TYPE_PLUS 18 +#define PPT_TRANSITION_TYPE_WEDGE 19 +#define PPT_TRANSITION_TYPE_PUSH 20 +#define PPT_TRANSITION_TYPE_COMB 21 +#define PPT_TRANSITION_TYPE_NEWSFLASH 22 +#define PPT_TRANSITION_TYPE_SMOOTHFADE 23 +#define PPT_TRANSITION_TYPE_WHEEL 26 +#define PPT_TRANSITION_TYPE_CIRCLE 27 + +using namespace com::sun::star; + +static PHLayout pPHLayout[] = +{ + { EPP_LAYOUT_TITLESLIDE, { 0x0d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x00, 0x0d, 0x10, TRUE, TRUE, FALSE }, + { EPP_LAYOUT_TITLEANDBODYSLIDE, { 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x00, 0x0d, 0x0e, TRUE, TRUE, FALSE }, + { EPP_LAYOUT_TITLEANDBODYSLIDE, { 0x0d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x14, 0x0d, 0x0e, TRUE, TRUE, FALSE }, + { EPP_LAYOUT_2COLUMNSANDTITLE, { 0x0d, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x00, 0x0d, 0x0e, TRUE, TRUE, TRUE }, + { EPP_LAYOUT_2COLUMNSANDTITLE, { 0x0d, 0x0e, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x14, 0x0d, 0x0e, TRUE, TRUE, FALSE }, + { EPP_LAYOUT_BLANCSLIDE, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x00, 0x0d, 0x0e, FALSE, FALSE, FALSE }, + { EPP_LAYOUT_2COLUMNSANDTITLE, { 0x0d, 0x0e, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x16, 0x0d, 0x0e, TRUE, TRUE, FALSE }, + { EPP_LAYOUT_2COLUMNSANDTITLE, { 0x0d, 0x14, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x14, 0x0d, 0x0e, TRUE, TRUE, FALSE }, + { EPP_LAYOUT_TITLEANDBODYSLIDE, { 0x0d, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x15, 0x0d, 0x0e, TRUE, FALSE, FALSE }, + { EPP_LAYOUT_2COLUMNSANDTITLE, { 0x0d, 0x16, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x16, 0x0d, 0x0e, TRUE, TRUE, FALSE }, + { EPP_LAYOUT_2COLUMNSANDTITLE, { 0x0d, 0x0e, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x13, 0x0d, 0x0e, TRUE, TRUE, FALSE }, + { EPP_LAYOUT_TITLEANDBODYSLIDE, { 0x0d, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x13, 0x0d, 0x0e, TRUE, FALSE, FALSE }, + { EPP_LAYOUT_RIGHTCOLUMN2ROWS, { 0x0d, 0x0e, 0x13, 0x13, 0x00, 0x00, 0x00, 0x00 }, 0x13, 0x0d, 0x0e, TRUE, TRUE, FALSE }, + { EPP_LAYOUT_2COLUMNSANDTITLE, { 0x0d, 0x13, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x13, 0x0d, 0x0e, TRUE, TRUE, FALSE }, + { EPP_LAYOUT_2ROWSANDTITLE, { 0x0d, 0x13, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x13, 0x0d, 0x0e, TRUE, TRUE, FALSE }, + { EPP_LAYOUT_LEFTCOLUMN2ROWS, { 0x0d, 0x13, 0x13, 0x0e, 0x00, 0x00, 0x00, 0x00 }, 0x13, 0x0d, 0x0e, TRUE, TRUE, FALSE }, + { EPP_LAYOUT_TOPROW2COLUMN, { 0x0d, 0x13, 0x13, 0x0e, 0x00, 0x00, 0x00, 0x00 }, 0x13, 0x0d, 0x0e, TRUE, TRUE, FALSE }, + { EPP_LAYOUT_2ROWSANDTITLE, { 0x0d, 0x0e, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x13, 0x0d, 0x0e, TRUE, TRUE, FALSE }, + { EPP_LAYOUT_4OBJECTS, { 0x0d, 0x13, 0x13, 0x13, 0x13, 0x00, 0x00, 0x00 }, 0x13, 0x0d, 0x0e, TRUE, FALSE, FALSE }, + { EPP_LAYOUT_ONLYTITLE, { 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x00, 0x0d, 0x0e, TRUE, FALSE, FALSE }, + { EPP_LAYOUT_BLANCSLIDE, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x00, 0x0d, 0x0e, FALSE, FALSE, FALSE }, + { EPP_LAYOUT_TITLERIGHT2BODIESLEFT, { 0x11, 0x12, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x14, 0x11, 0x12, TRUE, TRUE, FALSE }, + { EPP_LAYOUT_TITLERIGHTBODYLEFT, { 0x11, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x00, 0x11, 0x12, TRUE, TRUE, FALSE }, + { EPP_LAYOUT_TITLEANDBODYSLIDE, { 0x0d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x00, 0x0d, 0x12, TRUE, TRUE, FALSE }, + { EPP_LAYOUT_2COLUMNSANDTITLE, { 0x0d, 0x16, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x16, 0x0d, 0x12, TRUE, TRUE, FALSE } +}; + +//============================ PPTWriter ================================== + +PPTWriter::PPTWriter( SvStorageRef& rSvStorage, + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > & rXModel, + ::com::sun::star::uno::Reference< ::com::sun::star::task::XStatusIndicator > & rXStatInd, + SvMemoryStream* pVBA, sal_uInt32 nCnvrtFlags ) : + mbStatus ( sal_False ), + mbUseNewAnimations ( sal_True ), + mnLatestStatValue ( 0 ), + maFraction ( 1, 576 ), + maMapModeSrc ( MAP_100TH_MM ), + maMapModeDest ( MAP_INCH, Point(), maFraction, maFraction ), + meLatestPageType ( NORMAL ), + mXModel ( rXModel ), + mXStatusIndicator ( rXStatInd ), + mbStatusIndicator ( FALSE ), + mpCurUserStrm ( NULL ), + mpStrm ( NULL ), + mpPicStrm ( NULL ), + mpPptEscherEx ( NULL ), + mnVBAOleOfs ( 0 ), + mpVBA ( pVBA ), + mnExEmbed ( 0 ), + mpExEmbed ( new SvMemoryStream ), + mnPagesWritten ( 0 ), + mnTxId ( 0x7a2f64 ) +{ + sal_uInt32 i; + if ( !ImplInitSOIface() ) + return; + + FontCollectionEntry aDefaultFontDesc( String( RTL_CONSTASCII_USTRINGPARAM( "Times New Roman" ) ), + ::com::sun::star::awt::FontFamily::ROMAN, + ::com::sun::star::awt::FontPitch::VARIABLE, + RTL_TEXTENCODING_MS_1252 ); + maFontCollection.GetId( aDefaultFontDesc ); // default is always times new roman + + if ( !ImplGetPageByIndex( 0, NOTICE ) ) + return; + INT32 nWidth = 21000; + if ( ImplGetPropertyValue( mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Width" ) ) ) ) + mAny >>= nWidth; + INT32 nHeight = 29700; + if ( ImplGetPropertyValue( mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Height" ) ) ) ) + mAny >>= nHeight; + + maNotesPageSize = ImplMapSize( ::com::sun::star::awt::Size( nWidth, nHeight ) ); + + if ( !ImplGetPageByIndex( 0, MASTER ) ) + return; + nWidth = 28000; + if ( ImplGetPropertyValue( mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Width" ) ) ) ) + mAny >>= nWidth; + nHeight = 21000; + if ( ImplGetPropertyValue( mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Height" ) ) ) ) + mAny >>= nHeight; + maDestPageSize = ImplMapSize( ::com::sun::star::awt::Size( nWidth, nHeight ) ); + + mrStg = rSvStorage; + if ( !mrStg.Is() ) + return; + + // MasterPages + Slides und Notizen + NotesMasterPage + mnDrawings = mnMasterPages + ( mnPages << 1 ) + 1; + + if ( mXStatusIndicator.is() ) + { + mbStatusIndicator = TRUE; + mnStatMaxValue = ( mnPages + mnMasterPages ) * 5; + mXStatusIndicator->start( String( RTL_CONSTASCII_USTRINGPARAM( "PowerPoint Export" ) ), + mnStatMaxValue + ( mnStatMaxValue >> 3 ) ); + } + + SvGlobalName aGName( 0x64818d10L, 0x4f9b, 0x11cf, 0x86, 0xea, 0x00, 0xaa, 0x00, 0xb9, 0x29, 0xe8 ); + mrStg->SetClass( aGName, 0, String( RTL_CONSTASCII_USTRINGPARAM( "MS PowerPoint 97" ) ) ); + + if ( !ImplCreateCurrentUserStream() ) + return; + + mpStrm = mrStg->OpenSotStream( String( RTL_CONSTASCII_USTRINGPARAM( "PowerPoint Document" ) ) ); + if ( !mpStrm ) + return; + + if ( !mpPicStrm ) + mpPicStrm = mrStg->OpenSotStream( String( RTL_CONSTASCII_USTRINGPARAM( "Pictures" ) ) ); + + mpPptEscherEx = new PptEscherEx( *mpStrm ); + + if ( !ImplGetStyleSheets() ) + return; + + if ( !ImplCreateDocument() ) + return; + + for ( i = 0; i < mnMasterPages; i++ ) + { + if ( !ImplCreateMaster( i ) ) + return; + } + if ( !ImplCreateMainNotes() ) + return; + for ( i = 0; i < mnPages; i++ ) + { + if ( !ImplCreateSlide( i ) ) + return; + } + for ( i = 0; i < mnPages; i++ ) + { + if ( !ImplCreateNotes( i ) ) + return; + } + if ( !ImplCloseDocument() ) + return; + + if ( mbStatusIndicator ) + { + mXStatusIndicator->setText( String( RTL_CONSTASCII_USTRINGPARAM( "PowerPoint Export" ) ) ); + sal_uInt32 nValue = mnStatMaxValue + ( mnStatMaxValue >> 3 ); + if ( nValue > mnLatestStatValue ) + { + mXStatusIndicator->setValue( nValue ); + mnLatestStatValue = nValue; + } + } + + ImplWriteOLE( nCnvrtFlags ); + + ImplWriteVBA( pVBA ); + + if ( !ImplWriteAtomEnding() ) + return; + + if ( !ImplCreateDocumentSummaryInformation( nCnvrtFlags ) ) + return; + + mbStatus = TRUE; +}; + + +// --------------------------------------------------------------------------------------------- + +PPTWriter::~PPTWriter() +{ + void* pPtr; + delete mpExEmbed; + delete mpPptEscherEx; + + std::vector< PPTExStyleSheet* >::iterator aStyleSheetIter( maStyleSheetList.begin() ); + while( aStyleSheetIter < maStyleSheetList.end() ) + delete *aStyleSheetIter++; + + for ( pPtr = maSlideNameList.First(); pPtr; pPtr = maSlideNameList.Next() ) + delete (::rtl::OUString*)pPtr; + for ( pPtr = maHyperlink.First(); pPtr; pPtr = maHyperlink.Next() ) + delete (EPPTHyperlink*)pPtr; + for ( pPtr = maExOleObj.First(); pPtr; pPtr = maExOleObj.Next() ) + delete (PPTExOleObjEntry*)pPtr; + + if ( mbStatusIndicator ) + mXStatusIndicator->end(); +} + +// --------------------------------------------------------------------------------------------- + +static inline sal_uInt32 PPTtoEMU( INT32 nPPT ) +{ + return (sal_uInt32)( (double)nPPT * 1587.5 ); +} + +// --------------------------------------------------------------------------------------------- + +sal_Bool PPTWriter::ImplCreateCurrentUserStream() +{ + mpCurUserStrm = mrStg->OpenSotStream( String( RTL_CONSTASCII_USTRINGPARAM( "Current User" ) ) ); + if ( !mpCurUserStrm ) + return FALSE; + char pUserName[] = "Current User"; + sal_uInt32 nLenOfUserName = strlen( pUserName ); + sal_uInt32 nSizeOfRecord = 0x14 + ( ( nLenOfUserName + 4 ) & ~ 3 ); + + *mpCurUserStrm << (sal_uInt16)0 << (sal_uInt16)EPP_CurrentUserAtom << nSizeOfRecord; + *mpCurUserStrm << (sal_uInt32)0x14 // Len + << (sal_uInt32)0xe391c05f; // Magic + + sal_uInt32 nEditPos = mpCurUserStrm->Tell(); + *mpCurUserStrm << (sal_uInt32)0x0 // OffsetToCurrentEdit; + << (sal_uInt16)nLenOfUserName // + << (sal_uInt16)0x3f4 // DocFileVersion + << (sal_uInt8)3 // MajorVersion + << (sal_uInt8)0 // MinorVersion + << (sal_uInt16)0; // Pad Word + pUserName[ nLenOfUserName ] = 8; + mpCurUserStrm->Write( pUserName, nLenOfUserName + 1 ); + for ( sal_uInt32 i = 0x15 + nLenOfUserName; i < nSizeOfRecord; i++ ) + { + *mpCurUserStrm << (sal_uInt8)0; // pad bytes + }; + mpCurUserStrm->Seek( nEditPos ); + return TRUE; +}; + +// --------------------------------------------------------------------------------------------- + +sal_Bool PPTWriter::ImplCreateDocumentSummaryInformation( sal_uInt32 nCnvrtFlags ) +{ + uno::Reference<document::XDocumentPropertiesSupplier> xDPS( + mXModel, uno::UNO_QUERY_THROW); + uno::Reference<document::XDocumentProperties> xDocProps( + xDPS->getDocumentProperties()); + + if (xDocProps.is()) { + + // no idea what this is... + static sal_uInt8 aGuid[ 0x52 ] = + { + 0x4e, 0x00, 0x00, 0x00, + '{',0,'D',0,'B',0,'1',0,'A',0,'C',0,'9',0,'6',0,'4',0,'-',0, + 'E',0,'3',0,'9',0,'C',0,'-',0,'1',0,'1',0,'D',0,'2',0,'-',0, + 'A',0,'1',0,'E',0,'F',0,'-',0,'0',0,'0',0,'6',0,'0',0,'9',0, + '7',0,'D',0,'A',0,'5',0,'6',0,'8',0,'9',0,'}',0 + }; + uno::Sequence<sal_uInt8> aGuidSeq(aGuid, 0x52); + + SvMemoryStream aHyperBlob; + ImplCreateHyperBlob( aHyperBlob ); + + uno::Sequence<sal_uInt8> aHyperSeq(aHyperBlob.Tell()); + const sal_uInt8* pBlob( + static_cast<const sal_uInt8*>(aHyperBlob.GetData())); + for (sal_Int32 j = 0; j < aHyperSeq.getLength(); ++j) { + aHyperSeq[j] = pBlob[j]; + } + + if ( nCnvrtFlags & 0x8000 ) + { + uno::Sequence<sal_uInt8> aThumbSeq; + if ( ImplGetPageByIndex( 0, NORMAL ) && + ImplGetPropertyValue( mXPagePropSet, + String( RTL_CONSTASCII_USTRINGPARAM( "PreviewBitmap" ) ) ) ) + { + aThumbSeq = + *static_cast<const uno::Sequence<sal_uInt8>*>(mAny.getValue()); + } + sfx2::SaveOlePropertySet( xDocProps, mrStg, + &aThumbSeq, &aGuidSeq, &aHyperSeq); + } + else + { + sfx2::SaveOlePropertySet( xDocProps, mrStg, + NULL, &aGuidSeq, &aHyperSeq ); + } + } + + return sal_True; +} + +// --------------------------------------------------------------------------------------------- + +void PPTWriter::ImplWriteExtParaHeader( SvMemoryStream& rSt, sal_uInt32 nRef, sal_uInt32 nInstance, sal_uInt32 nSlideId ) +{ + if ( rSt.Tell() ) + { + aBuExOutlineStream << (sal_uInt32)( ( EPP_PST_ExtendedParagraphHeaderAtom << 16 ) + | ( nRef << 4 ) ) + << (sal_uInt32)8 + << (sal_uInt32)nSlideId + << (sal_uInt32)nInstance; + aBuExOutlineStream.Write( rSt.GetData(), rSt.Tell() ); + } +} + +// --------------------------------------------------------------------------------------------- + +void PPTWriter::ImplCreateHeaderFooterStrings( SvStream& rStrm, ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& rXPagePropSet ) +{ + if ( rXPagePropSet.is() ) + { + rtl::OUString aString; + ::com::sun::star::uno::Any aAny; + if ( PropValue::GetPropertyValue( aAny, rXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "HeaderText" ) ), sal_True ) ) + { + if ( aAny >>= aString ) + PPTWriter::WriteCString( rStrm, aString, 1 ); + } + if ( PropValue::GetPropertyValue( aAny, rXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FooterText" ) ), sal_True ) ) + { + if ( aAny >>= aString ) + PPTWriter::WriteCString( rStrm, aString, 2 ); + } + if ( PropValue::GetPropertyValue( aAny, rXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "DateTimeText" ) ), sal_True ) ) + { + if ( aAny >>= aString ) + PPTWriter::WriteCString( rStrm, aString, 0 ); + } + } +} + +// --------------------------------------------------------------------------------------------- + +void PPTWriter::ImplCreateHeaderFooters( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& rXPagePropSet ) +{ + if ( rXPagePropSet.is() ) + { + sal_Bool bVal = sal_False; + sal_uInt32 nVal = 0; + ::com::sun::star::uno::Any aAny; + if ( PropValue::GetPropertyValue( aAny, rXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsHeaderVisible" ) ), sal_True ) ) + { + if ( ( aAny >>= bVal ) && bVal ) + nVal |= 0x100000; + } + if ( PropValue::GetPropertyValue( aAny, rXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsFooterVisible" ) ), sal_True ) ) + { + if ( ( aAny >>= bVal ) && bVal ) + nVal |= 0x200000; + } + if ( PropValue::GetPropertyValue( aAny, rXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsDateTimeVisible" ) ), sal_True ) ) + { + if ( ( aAny >>= bVal ) && bVal ) + nVal |= 0x010000; + } + if ( PropValue::GetPropertyValue( aAny, rXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsPageNumberVisible" ) ), sal_True ) ) + { + if ( ( aAny >>= bVal ) && bVal ) + nVal |= 0x080000; + } + if ( PropValue::GetPropertyValue( aAny, rXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsDateTimeFixed" ) ), sal_True ) ) + { + if ( ( aAny >>= bVal ) && !bVal ) + nVal |= 0x20000; + else + nVal |= 0x40000; + } + if ( PropValue::GetPropertyValue( aAny, rXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "DateTimeFormat" ) ), sal_True ) ) + { + sal_Int32 nFormat = *(sal_Int32*)aAny.getValue(); + SvxDateFormat eDateFormat = (SvxDateFormat)( nFormat & 0xf ); + SvxTimeFormat eTimeFormat = (SvxTimeFormat)( ( nFormat >> 4 ) & 0xf ); + switch( eDateFormat ) + { + case SVXDATEFORMAT_F : + nFormat = 1; + break; + case SVXDATEFORMAT_D : + nFormat = 2; + break; + case SVXDATEFORMAT_C : + nFormat = 4; + break; + default: + case SVXDATEFORMAT_A : + nFormat = 0; + } + switch( eTimeFormat ) + { + case SVXTIMEFORMAT_24_HM : + nFormat = 9; + break; + case SVXTIMEFORMAT_12_HM : + nFormat = 11; + break; + case SVXTIMEFORMAT_24_HMS : + nFormat = 10; + break; + case SVXTIMEFORMAT_12_HMS : + nFormat = 12; + break; + default: + break; + } + nVal |= nFormat; + } + + mpPptEscherEx->OpenContainer( EPP_HeadersFooters, 0 ); + mpPptEscherEx->AddAtom( 4, EPP_HeadersFootersAtom ); + *mpStrm << nVal; + ImplCreateHeaderFooterStrings( *mpStrm, rXPagePropSet ); + mpPptEscherEx->CloseContainer(); + } +} + +// --------------------------------------------------------------------------------------------- + +sal_Bool PPTWriter::ImplCreateDocument() +{ + sal_uInt32 i; + sal_uInt16 nSlideType = EPP_SLIDESIZE_TYPECUSTOM; + + sal_uInt32 nWidth = maDestPageSize.Width; + sal_uInt32 nHeight = maDestPageSize.Height; + + if ( ( nWidth == 0x1680 ) && ( nHeight == 0x10e0 ) ) + nSlideType = EPP_SLIDESIZE_TYPEONSCREEN; + else if ( ( nWidth == 0x1200 ) && ( nHeight == 0x240 ) ) + nSlideType = EPP_SLIDESIZE_TYPEBANNER; + else if ( ( nWidth == 0x1950 ) && ( nHeight == 0x10e0 ) ) + nSlideType = EPP_SLIDESIZE_TYPE35MM; + else if ( ( nWidth == 0x1860 ) && ( nHeight == 0x10e0 ) ) + nSlideType = EPP_SLIDESIZE_TYPEA4PAPER; + + mpPptEscherEx->OpenContainer( EPP_Document ); + // CREATE DOCUMENT ATOM + mpPptEscherEx->AddAtom( 40, EPP_DocumentAtom, 1 ); + *mpStrm << nWidth // Slide Size in Master coordinates X + << nHeight // " " " " " Y + << (INT32)maNotesPageSize.Width // Notes Page Size X + << (INT32)maNotesPageSize.Height // " " " Y + << (INT32)1 << (INT32)2; // the scale used when the Powerpoint document is embedded. the default is 1:2 + mpPptEscherEx->InsertPersistOffset( EPP_MAINNOTESMASTER_PERSIST_KEY, mpStrm->Tell() ); + *mpStrm << (sal_uInt32)0 // Reference to NotesMaster ( 0 if none ); + << (sal_uInt32)0 // Reference to HandoutMaster ( 0 if none ); + << (sal_Int16)1 // Number of the first slide; + << nSlideType // Size of the document slides ( default: EPP_SLIDESIZETYPEONSCREEN ) + << (sal_uInt8)0 // bool1 indicates if document was saved with embedded true type fonts + << (sal_uInt8)0 // bool1 indicates if the placeholders on the title slide are omitted + << (sal_uInt8)0 // bool1 right to left ( flag for Bidi version ) + << (sal_uInt8)1; // bool1 visibility of comments shapes + + mpPptEscherEx->PtInsert( EPP_Persist_Document, mpStrm->Tell() ); + + mpPptEscherEx->OpenContainer( EPP_HeadersFooters, 3 ); //Master footer (default) + mpPptEscherEx->AddAtom( 4, EPP_HeadersFootersAtom ); + *mpStrm << (sal_uInt32)0x25000d; + if ( ImplGetPageByIndex( 0, MASTER ) ) + ImplCreateHeaderFooterStrings( *mpStrm, mXPagePropSet ); + mpPptEscherEx->CloseContainer(); + mpPptEscherEx->OpenContainer( EPP_HeadersFooters, 4 ); //NotesMaster footer (default) + mpPptEscherEx->AddAtom( 4, EPP_HeadersFootersAtom ); + *mpStrm << (sal_uInt32)0x3d000d; + if ( ImplGetPageByIndex( 0, NOTICE ) ) + ImplCreateHeaderFooterStrings( *mpStrm, mXPagePropSet ); + mpPptEscherEx->CloseContainer(); + + mpPptEscherEx->OpenContainer( EPP_SlideListWithText ); // Animation info fuer die Slides + + for ( i = 0; i < mnPages; i++ ) + { + mpPptEscherEx->AddAtom( 20, EPP_SlidePersistAtom ); + mpPptEscherEx->InsertPersistOffset( EPP_MAINSLIDE_PERSIST_KEY | i, mpStrm->Tell() ); + *mpStrm << (sal_uInt32)0 // psrReference - logical reference to the slide persist object ( EPP_MAINSLIDE_PERSIST_KEY ) + << (sal_uInt32)4 // flags - only bit 3 used, if set then slide contains shapes other than placeholders + << (INT32)0 // numberTexts - number of placeholder texts stored with the persist object. Allows to display outline view without loading the slide persist objects + << (INT32)i + 0x100 // slideId - Unique slide identifier, used for OLE link monikers for example + << (sal_uInt32)0; // reserved, usualy 0 + + if ( !ImplGetPageByIndex( i, NORMAL ) ) // sehr aufregend: noch einmal ueber alle seiten + return FALSE; + ImplSetCurrentStyleSheet( ImplGetMasterIndex( NORMAL ) ); + + ::com::sun::star::uno::Reference< ::com::sun::star::container::XNamed > + aXName( mXDrawPage, ::com::sun::star::uno::UNO_QUERY ); + + if ( aXName.is() ) + { + ::rtl::OUString aStr = aXName->getName(); + ::rtl::OUString *pUStr = new ::rtl::OUString( aStr ); + maSlideNameList.Insert( pUStr, LIST_APPEND ); + } + else + maSlideNameList.Insert( new ::rtl::OUString(), LIST_APPEND ); + } + mpPptEscherEx->CloseContainer(); // EPP_SlideListWithText + + mpPptEscherEx->OpenContainer( EPP_SlideListWithText, 2 ); // Animation info fuer die notes + for( i = 0; i < mnPages; i++ ) + { + mpPptEscherEx->AddAtom( 20, EPP_SlidePersistAtom ); + mpPptEscherEx->InsertPersistOffset( EPP_MAINNOTES_PERSIST_KEY | i, mpStrm->Tell() ); + *mpStrm << (sal_uInt32)0 + << (sal_uInt32)4 + << (INT32)0 + << (INT32)i + 0x100 + << (sal_uInt32)0; + } + mpPptEscherEx->CloseContainer(); // EPP_SlideListWithText + + ::com::sun::star::uno::Reference< ::com::sun::star::presentation::XPresentationSupplier > + aXPresSupplier( mXModel, ::com::sun::star::uno::UNO_QUERY ); ; + if ( aXPresSupplier.is() ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::presentation::XPresentation > + aXPresentation( aXPresSupplier->getPresentation() ); + if ( aXPresentation.is() ) + { + mXPropSet = ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertySet > + ( aXPresentation, ::com::sun::star::uno::UNO_QUERY ); + if ( mXPropSet.is() ) + { + ::rtl::OUString aCustomShow; + sal_uInt32 nPenColor = 0x1000000; + INT32 nRestartTime = 0x7fffffff; + sal_Int16 nStartSlide = 0; + sal_Int16 nEndSlide = 0; + sal_uInt32 nFlags = 0; // Bit 0: Auto advance + // Bit 1 Skip builds ( do not allow slide effects ) + // Bit 2 Use slide range + // Bit 3 Use named show + // Bit 4 Browse mode on + // Bit 5 Kiosk mode on + // Bit 7 loop continously + // Bit ? show scrollbar + + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CustomShow" ) ) ) ) + { + aCustomShow = ( *(::rtl::OUString*)mAny.getValue() ); + if ( aCustomShow.getLength() ) + { + nFlags |= 8; + } + } + if ( ( nFlags & 8 ) == 0 ) + { + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "FirstPage" ) ) ) ) + { + ::rtl::OUString aSlideName( *(::rtl::OUString*)mAny.getValue() ); + ::rtl::OUString* pStr; + for ( pStr = (::rtl::OUString*)maSlideNameList.First(); pStr; + pStr = (::rtl::OUString*)maSlideNameList.Next(), nStartSlide++ ) + { + if ( *pStr == aSlideName ) + { + nStartSlide++; + nFlags |= 4; + nEndSlide = (sal_uInt16)mnPages; + break; + } + } + if ( !pStr ) + nStartSlide = 0; + } + } + +// if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "DiaName" ) ) ) ) +// { +// } +// if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "IsAlwaysOnTop" ) ) ) ) +// { +// } + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "IsAutomatic" ) ) ) ) + { + sal_Bool bBool = sal_False; + mAny >>= bBool; + if ( !bBool ) + nFlags |= 1; + } + + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "IsEndless" ) ) ) ) // muesste eigendlich heissen IsNotEndless !=)"§()& + { + sal_Bool bBool = sal_False; + mAny >>= bBool; + if ( bBool ) + nFlags |= 0x80; + } + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "IsFullScreen" ) ) ) ) + { + sal_Bool bBool = sal_False; + mAny >>= bBool; + if ( !bBool ) + nFlags |= 0x11; + } +// if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "IsMouseVisible" ) ) ) ) +// { +// } +// if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "PageRange" ) ) ) ) +// { +// } +// if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "StartWithNavigator" ) ) ) ) +// { +// } +// if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "UsePen" ) ) ) ) +// { +// } + mpPptEscherEx->AddAtom( 80, EPP_SSDocInfoAtom, 1 ); + *mpStrm << nPenColor << nRestartTime << nStartSlide << nEndSlide; + + sal_uInt32 nCustomShowNameLen = aCustomShow.getLength(); + if ( nCustomShowNameLen > 31 ) + nCustomShowNameLen = 31; + if ( nCustomShowNameLen ) // named show identifier + { + const sal_Unicode* pCustomShow = aCustomShow.getStr(); + for ( i = 0; i < nCustomShowNameLen; i++ ) + { + *mpStrm << (sal_uInt16)( pCustomShow[ i ] ); + } + } + for ( i = nCustomShowNameLen; i < 32; i++, *mpStrm << (sal_uInt16)0 ) ; + + *mpStrm << nFlags; + ::com::sun::star::uno::Reference< ::com::sun::star::presentation::XCustomPresentationSupplier > + aXCPSup( mXModel, ::com::sun::star::uno::UNO_QUERY ); + if ( aXCPSup.is() ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer > + aXCont( aXCPSup->getCustomPresentations() ); + if ( aXCont.is() ) + { + ::com::sun::star::uno::Sequence< ::rtl::OUString> aNameSeq( aXCont->getElementNames() ); + const ::rtl::OUString* pUString = aNameSeq.getArray(); + sal_uInt32 nCount = aNameSeq.getLength(); + if ( nCount ) + { + mpPptEscherEx->OpenContainer( EPP_NamedShows ); + sal_uInt32 nCustomShowIndex = 0; + for( i = 0; i < nCount; i++ ) // Anzahl der Custom Shows + { + if ( pUString[ i ].getLength() ) + { + mpPptEscherEx->OpenContainer( EPP_NamedShow, nCustomShowIndex++ ); + + sal_uInt32 nNamedShowLen = pUString[ i ].getLength(); + if ( nNamedShowLen > 31 ) + nNamedShowLen = 31; + mpPptEscherEx->AddAtom( nNamedShowLen << 1, EPP_CString ); + const sal_Unicode* pCustomShowName = pUString[ i ].getStr(); + for ( sal_uInt32 k = 0; k < nNamedShowLen; *mpStrm << (sal_uInt16)( pCustomShowName[ k++ ] ) ) ; + mAny = aXCont->getByName( pUString[ i ] ); + if ( mAny.getValue() ) + { + + ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer > aXIC; + if ( mAny >>= aXIC ) + { + mpPptEscherEx->BeginAtom(); + + INT32 nSlideCount = aXIC->getCount(); + for ( INT32 j = 0; j < nSlideCount; j++ ) // Anzahl der Slides + { + mAny = aXIC->getByIndex( j ); + if ( mAny.getValue() ) + { + ::com::sun::star::uno::Reference< + ::com::sun::star::drawing::XDrawPage > aXDrawPage; + if ( mAny >>= aXDrawPage ) + { + ::com::sun::star::uno::Reference< + ::com::sun::star::container::XNamed > + aXName( aXDrawPage, ::com::sun::star::uno::UNO_QUERY ); + if ( aXName.is() ) + { + ::rtl::OUString aSlideName( aXName->getName() ); + sal_uInt32 nPageNumber = 0; + for ( ::rtl::OUString* pSlideName = (::rtl::OUString*)maSlideNameList.First(); + pSlideName; + pSlideName = (::rtl::OUString*)maSlideNameList.Next(), nPageNumber++ ) + { + if ( *pSlideName == aSlideName ) + { + *mpStrm << (sal_uInt32)( nPageNumber + 0x100 ); // unique slide id + break; + } + } + } + } + } + } + mpPptEscherEx->EndAtom( EPP_NamedShowSlides ); + } + } + mpPptEscherEx->CloseContainer(); // EPP_NamedShow + } + } + mpPptEscherEx->CloseContainer(); // EPP_NamedShows + } + } + } + } + } + } + mpPptEscherEx->AddAtom( 0, EPP_EndDocument ); + mpPptEscherEx->CloseContainer(); // EPP_Document + return TRUE; +}; + +// --------------------------------------------------------------------------------------------- + +sal_Bool PPTWriter::ImplCreateHyperBlob( SvMemoryStream& rStrm ) +{ + sal_uInt32 nCurrentOfs, nParaOfs, nParaCount = 0; +// SfxOlePropertySection does this... +// rStrm << (sal_uInt32)0x41; // property type VT_BLOB + nParaOfs = rStrm.Tell(); + rStrm << (sal_uInt32)0; // property size + rStrm << (sal_uInt32)0; // property count + + for ( EPPTHyperlink* pLink = (EPPTHyperlink*)maHyperlink.First(); pLink; pLink = (EPPTHyperlink*)maHyperlink.Next() ) + { + nParaCount += 6; + rStrm << (sal_uInt32)3 // Type VT_I4 + << (sal_uInt32)7 // (VTI4 - Private1) + << (sal_uInt32)3 // Type VT_I4 + << (sal_uInt32)6 // (VTI4 - Private2) + << (sal_uInt32)3 // Type VT_I4 + << (sal_uInt32)0; // (VTI4 - Private3) + + // INFO + // HIWORD: = 0 : do not change anything + // = 1 : replace the hyperlink with the target and subadress in the following two VTLPWSTR + // = 2 : delete the hyperlink + // LOWORD: = 0 : graphic shown as background (link) + // = 1 : graphic shown as shape (link) + // = 2 : graphic is used to fill a shape + // = 3 : graphic used to fill a shape outline (future use) + // = 4 : hyperlink attached to a shape + // = 5 : " " " " (Word) field + // = 6 : " " " " (Excel) range + // = 7 : " " " " (PPT) text range + // = 8 : " " " " (Project) task + + sal_uInt32 nUrlLen = pLink->aURL.Len(); + const sal_Unicode* pUrl = pLink->aURL.GetBuffer(); + + sal_uInt32 nInfo = 7; + + rStrm << (sal_uInt32)3 // Type VT_I4 + << nInfo; // Info + + switch( pLink->nType & 0xff ) + { + case 1 : // click action to slidenumber + { + rStrm << (sal_uInt32)0x1f << (sal_uInt32)1 << (sal_uInt32)0; // path + rStrm << (sal_uInt32)0x1f << (sal_uInt32)( nUrlLen + 1 ); + for ( sal_uInt32 i = 0; i < nUrlLen; i++ ) + { + rStrm << pUrl[ i ]; + } + rStrm << (sal_uInt16)0; + } + break; + case 2 : + { + sal_uInt32 i; + + rStrm << (sal_uInt32)0x1f + << (sal_uInt32)( nUrlLen + 1 ); + for ( i = 0; i < nUrlLen; i++ ) + { + rStrm << pUrl[ i ]; + } + if ( ! ( i & 1 ) ) + rStrm << (sal_uInt16)0; + rStrm << (sal_uInt16)0 + << (sal_uInt32)0x1f + << (sal_uInt32)1 + << (sal_uInt32)0; + } + break; + } + } + nCurrentOfs = rStrm.Tell(); + rStrm.Seek( nParaOfs ); + rStrm << (sal_uInt32)( nCurrentOfs - ( nParaOfs + 4 ) ); + rStrm << nParaCount; + rStrm.Seek( nCurrentOfs ); + return TRUE; +} + +PHLayout& PPTWriter::ImplGetLayout( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& rXPropSet ) const +{ + ::com::sun::star::uno::Any aAny; + sal_Int16 nLayout = 20; + if ( GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Layout" ) ) ), sal_True ) + aAny >>= nLayout; + + if ( ( nLayout >= 21 ) && ( nLayout <= 26 ) ) // NOTES _> HANDOUT6 + nLayout = 20; + if ( ( nLayout >= 27 ) && ( nLayout <= 30 ) ) // VERTICAL LAYOUT + nLayout -= 6; + else if ( nLayout > 30 ) + nLayout = 20; + return pPHLayout[ nLayout ]; +} + + +// --------------------------------------------------------------------------------------------- + +sal_Bool PPTWriter::ImplCreateMaster( sal_uInt32 nPageNum ) +{ + if ( !ImplGetPageByIndex( nPageNum, MASTER ) ) + return FALSE; + ImplSetCurrentStyleSheet( nPageNum ); + + if ( !ImplGetPropertyValue( mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Background" ) ) ) ) // Backgroundshape laden + return FALSE; + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > aXBackgroundPropSet; + if ( !( mAny >>= aXBackgroundPropSet ) ) + return FALSE; + + sal_uInt32 nFillColor = 0xffffff; + sal_uInt32 nFillBackColor = 0x000000; + + ::com::sun::star::drawing::FillStyle aFS = ::com::sun::star::drawing::FillStyle_NONE; + if ( ImplGetPropertyValue( aXBackgroundPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillStyle" ) ) ) ) + mAny >>= aFS; + switch ( aFS ) + { + case ::com::sun::star::drawing::FillStyle_GRADIENT : + { + if ( ImplGetPropertyValue( aXBackgroundPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillGradient" ) ) ) ) + { + nFillColor = EscherPropertyContainer::GetGradientColor( (::com::sun::star::awt::Gradient*)mAny.getValue(), 0 ); + nFillBackColor = EscherPropertyContainer::GetGradientColor( (::com::sun::star::awt::Gradient*)mAny.getValue(), 1 ); + } + } + break; + + case ::com::sun::star::drawing::FillStyle_SOLID : + { + if ( ImplGetPropertyValue( aXBackgroundPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillColor" ) ) ) ) + { + nFillColor = mpPptEscherEx->GetColor( *((sal_uInt32*)mAny.getValue()) ); + nFillBackColor = nFillColor ^ 0xffffff; + } + } + break; + + default: + break; + } + + mpPptEscherEx->PtReplaceOrInsert( EPP_Persist_MainMaster | nPageNum, mpStrm->Tell() ); + mpPptEscherEx->OpenContainer( EPP_MainMaster ); + mpPptEscherEx->AddAtom( 24, EPP_SlideAtom, 2 ); + *mpStrm << (INT32)EPP_LAYOUT_TITLEANDBODYSLIDE // slide layout -> title and body slide + << (sal_uInt8)1 << (sal_uInt8)2 << (sal_uInt8)0 << (sal_uInt8)0 << (sal_uInt8)0 << (sal_uInt8)0 << (sal_uInt8)0 << (sal_uInt8)0 // placeholderID + << (sal_uInt32)0 // master ID ( ist gleich null bei einer masterpage ) + << (sal_uInt32)0 // notes ID ( ist gleich null wenn keine notizen vorhanden ) + << (sal_uInt16)0 // Bit 1: Follow master objects, Bit 2: Follow master scheme, Bit 3: Follow master background + << (sal_uInt16)0; // padword + + mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 6 ); + *mpStrm << (sal_uInt32)0xffffff << (sal_uInt32)0x000000 << (sal_uInt32)0x808080 << (sal_uInt32)0x000000 << (sal_uInt32)0x99cc00 << (sal_uInt32)0xcc3333 << (sal_uInt32)0xffcccc << (sal_uInt32)0xb2b2b2; + mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 6 ); + *mpStrm << (sal_uInt32)0xff0000 << (sal_uInt32)0xffffff << (sal_uInt32)0x000000 << (sal_uInt32)0x00ffff << (sal_uInt32)0x0099ff << (sal_uInt32)0xffff00 << (sal_uInt32)0x0000ff << (sal_uInt32)0x969696; + mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 6 ); + *mpStrm << (sal_uInt32)0xccffff << (sal_uInt32)0x000000 << (sal_uInt32)0x336666 << (sal_uInt32)0x008080 << (sal_uInt32)0x339933 << (sal_uInt32)0x000080 << (sal_uInt32)0xcc3300 << (sal_uInt32)0x66ccff; + mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 6 ); + *mpStrm << (sal_uInt32)0xffffff << (sal_uInt32)0x000000 << (sal_uInt32)0x333333 << (sal_uInt32)0x000000 << (sal_uInt32)0xdddddd << (sal_uInt32)0x808080 << (sal_uInt32)0x4d4d4d << (sal_uInt32)0xeaeaea; + mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 6 ); + *mpStrm << (sal_uInt32)0xffffff << (sal_uInt32)0x000000 << (sal_uInt32)0x808080 << (sal_uInt32)0x000000 << (sal_uInt32)0x66ccff << (sal_uInt32)0xff0000 << (sal_uInt32)0xcc00cc << (sal_uInt32)0xc0c0c0; + mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 6 ); + *mpStrm << (sal_uInt32)0xffffff << (sal_uInt32)0x000000 << (sal_uInt32)0x808080 << (sal_uInt32)0x000000 << (sal_uInt32)0xc0c0c0 << (sal_uInt32)0xff6600 << (sal_uInt32)0x0000ff << (sal_uInt32)0x009900; + mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 6 ); + *mpStrm << (sal_uInt32)0xffffff << (sal_uInt32)0x000000 << (sal_uInt32)0x808080 << (sal_uInt32)0x000000 << (sal_uInt32)0xff9933 << (sal_uInt32)0xccff99 << (sal_uInt32)0xcc00cc << (sal_uInt32)0xb2b2b2; + + for ( int nInstance = EPP_TEXTTYPE_Title; nInstance <= EPP_TEXTTYPE_QuarterBody; nInstance++ ) + { + if ( nInstance == EPP_TEXTTYPE_notUsed ) + continue; + + // the auto color is dependent to the page background,so we have to set a page that is in the right context + if ( nInstance == EPP_TEXTTYPE_Notes ) + ImplGetPageByIndex( 0, NOTICE ); + else + ImplGetPageByIndex( 0, MASTER ); + + mpPptEscherEx->BeginAtom(); + + sal_Bool bFirst = TRUE; + sal_Bool bSimpleText = FALSE; + + *mpStrm << (sal_uInt16)5; // paragraph count + + for ( sal_uInt16 nLev = 0; nLev < 5; nLev++ ) + { + if ( nInstance >= EPP_TEXTTYPE_CenterBody ) + { + bFirst = FALSE; + bSimpleText = TRUE; + *mpStrm << nLev; + } + mpStyleSheet->mpParaSheet[ nInstance ]->Write( *mpStrm, mpPptEscherEx, nLev, bFirst, bSimpleText, mXPagePropSet ); + mpStyleSheet->mpCharSheet[ nInstance ]->Write( *mpStrm, mpPptEscherEx, nLev, bFirst, bSimpleText, mXPagePropSet ); + bFirst = FALSE; + } + mpPptEscherEx->EndAtom( EPP_TxMasterStyleAtom, 0, nInstance ); + } + ImplGetPageByIndex( nPageNum, MASTER ); + + EscherSolverContainer aSolverContainer; + + mpPptEscherEx->OpenContainer( EPP_PPDrawing ); + mpPptEscherEx->OpenContainer( ESCHER_DgContainer ); + + mpPptEscherEx->EnterGroup(0,0); + ImplWritePage( pPHLayout[ 0 ], aSolverContainer, MASTER, TRUE ); // Die Shapes der Seite werden im PPT Dok. erzeugt + mpPptEscherEx->LeaveGroup(); + + ImplWriteBackground( aXBackgroundPropSet ); + + aSolverContainer.WriteSolver( *mpStrm ); + + mpPptEscherEx->CloseContainer(); // ESCHER_DgContainer + mpPptEscherEx->CloseContainer(); // EPP_Drawing + mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 1 ); + *mpStrm << (sal_uInt32)0xffffff << (sal_uInt32)0x000000 << (sal_uInt32)0x808080 << (sal_uInt32)0x000000 << (sal_uInt32)0x99cc00 << (sal_uInt32)0xcc3333 << (sal_uInt32)0xffcccc << (sal_uInt32)0xb2b2b2; + + if ( aBuExMasterStream.Tell() ) + { + ImplProgTagContainer( mpStrm, &aBuExMasterStream ); + } + mpPptEscherEx->CloseContainer(); // EPP_MainMaster + return TRUE; +}; + +// --------------------------------------------------------------------------------------------- + +sal_Bool PPTWriter::ImplCreateMainNotes() +{ + if ( !ImplGetPageByIndex( 0, NOTICE ) ) + return FALSE; + ImplSetCurrentStyleSheet( 0 ); + + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XMasterPageTarget > + aXMasterPageTarget( mXDrawPage, ::com::sun::star::uno::UNO_QUERY ); + + if ( !aXMasterPageTarget.is() ) + return FALSE; + + mXDrawPage = aXMasterPageTarget->getMasterPage(); + if ( !mXDrawPage.is() ) + return FALSE; + + mXPropSet = ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertySet > + ( mXDrawPage, ::com::sun::star::uno::UNO_QUERY ); + if ( !mXPropSet.is() ) + return FALSE; + + mXShapes = ::com::sun::star::uno::Reference< + ::com::sun::star::drawing::XShapes > + ( mXDrawPage, ::com::sun::star::uno::UNO_QUERY ); + if ( !mXShapes.is() ) + return FALSE; + + EscherSolverContainer aSolverContainer; + + mpPptEscherEx->PtReplaceOrInsert( EPP_Persist_MainNotes, mpStrm->Tell() ); + mpPptEscherEx->OpenContainer( EPP_Notes ); + mpPptEscherEx->AddAtom( 8, EPP_NotesAtom, 1 ); + *mpStrm << (sal_uInt32)0x80000001 // Number that identifies this slide + << (sal_uInt32)0; // follow nothing + mpPptEscherEx->OpenContainer( EPP_PPDrawing ); + mpPptEscherEx->OpenContainer( ESCHER_DgContainer ); + mpPptEscherEx->EnterGroup(0,0); + + ImplWritePage( pPHLayout[ 20 ], aSolverContainer, NOTICE, TRUE ); + + mpPptEscherEx->LeaveGroup(); + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + mpPptEscherEx->AddShape( ESCHER_ShpInst_Rectangle, 0xc00 ); + EscherPropertyContainer aPropOpt; + aPropOpt.AddOpt( ESCHER_Prop_fillColor, 0xffffff ); // stock valued fill color + aPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0 ); + aPropOpt.AddOpt( ESCHER_Prop_fillRectRight, 0x68bdde ); + aPropOpt.AddOpt( ESCHER_Prop_fillRectBottom, 0x8b9f8e ); + aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x120012 ); + aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0 ); + aPropOpt.AddOpt( ESCHER_Prop_bWMode, ESCHER_wDontShow ); + aPropOpt.AddOpt( ESCHER_Prop_fBackground, 0x10001 ); // if true, this is the background shape + aPropOpt.Commit( *mpStrm ); + mpPptEscherEx->CloseContainer(); // ESCHER_SpContainer + + aSolverContainer.WriteSolver( *mpStrm ); + + mpPptEscherEx->CloseContainer(); // ESCHER_DgContainer + mpPptEscherEx->CloseContainer(); // EPP_Drawing + mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 1 ); + *mpStrm << (sal_uInt32)0xffffff << (sal_uInt32)0x000000 << (sal_uInt32)0x808080 << (sal_uInt32)0x000000 << (sal_uInt32)0x99cc00 << (sal_uInt32)0xcc3333 << (sal_uInt32)0xffcccc << (sal_uInt32)0xb2b2b2; + mpPptEscherEx->CloseContainer(); // EPP_Notes + return TRUE; +} + +// --------------------------------------------------------------------------------------------- + +static rtl::OUString getInitials( const rtl::OUString& rName ) +{ + rtl::OUString sInitials; + + const sal_Unicode * pStr = rName.getStr(); + sal_Int32 nLength = rName.getLength(); + + while( nLength ) + { + // skip whitespace + while( nLength && (*pStr <= ' ') ) + { + nLength--; pStr++; + } + + // take letter + if( nLength ) + { + sInitials += rtl::OUString( *pStr ); + nLength--; pStr++; + } + + // skip letters until whitespace + while( nLength && (*pStr > ' ') ) + { + nLength--; pStr++; + } + } + + return sInitials; +} + +void ImplExportComments( uno::Reference< drawing::XDrawPage > xPage, SvMemoryStream& rBinaryTagData10Atom ) +{ + try + { + uno::Reference< office::XAnnotationAccess > xAnnotationAccess( xPage, uno::UNO_QUERY_THROW ); + uno::Reference< office::XAnnotationEnumeration > xAnnotationEnumeration( xAnnotationAccess->createAnnotationEnumeration() ); + + sal_Int32 nIndex = 1; + + while( xAnnotationEnumeration->hasMoreElements() ) + { + EscherExContainer aComment10( rBinaryTagData10Atom, EPP_Comment10 ); + { + uno::Reference< office::XAnnotation > xAnnotation( xAnnotationEnumeration->nextElement() ); + + geometry::RealPoint2D aRealPoint2D( xAnnotation->getPosition() ); + MapMode aMapDest( MAP_INCH, Point(), Fraction( 1, 576 ), Fraction( 1, 576 ) ); + Point aPoint( OutputDevice::LogicToLogic( Point( static_cast< sal_Int32 >( aRealPoint2D.X * 100.0 ), + static_cast< sal_Int32 >( aRealPoint2D.Y * 100.0 ) ), MAP_100TH_MM, aMapDest ) ); + + rtl::OUString sAuthor( xAnnotation->getAuthor() ); + uno::Reference< text::XText > xText( xAnnotation->getTextRange() ); + rtl::OUString sText( xText->getString() ); + rtl::OUString sInitials( getInitials( sAuthor ) ); + util::DateTime aDateTime( xAnnotation->getDateTime() ); + if ( sAuthor.getLength() ) + PPTWriter::WriteCString( rBinaryTagData10Atom, sAuthor, 0 ); + if ( sText.getLength() ) + PPTWriter::WriteCString( rBinaryTagData10Atom, sText, 1 ); + if ( sInitials.getLength() ) + PPTWriter::WriteCString( rBinaryTagData10Atom, sInitials, 2 ); + + sal_Int16 nMilliSeconds = aDateTime.HundredthSeconds * 10; + EscherExAtom aCommentAtom10( rBinaryTagData10Atom, EPP_CommentAtom10 ); + rBinaryTagData10Atom << nIndex++ + << aDateTime.Year + << aDateTime.Month + << aDateTime.Day // todo: day of week + << aDateTime.Day + << aDateTime.Hours + << aDateTime.Minutes + << aDateTime.Seconds + << nMilliSeconds + << static_cast< sal_Int32 >( aPoint.X() ) + << static_cast< sal_Int32 >( aPoint.Y() ); + } + } + } + catch ( uno::Exception& ) + { + } +} + +// --------------------------------------------------------------------------------------------- + +sal_Bool PPTWriter::ImplCreateSlide( sal_uInt32 nPageNum ) +{ + ::com::sun::star::uno::Any aAny; + + if ( !ImplGetPageByIndex( nPageNum, NORMAL ) ) + return FALSE; + sal_uInt32 nMasterID = ImplGetMasterIndex( NORMAL ); + ImplSetCurrentStyleSheet( nMasterID ); + nMasterID |= 0x80000000; + + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > aXBackgroundPropSet; + sal_Bool bHasBackground = GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Background" ) ) ); + if ( bHasBackground ) + bHasBackground = ( aAny >>= aXBackgroundPropSet ); + + sal_uInt16 nMode = 7; // Bit 1: Follow master objects, Bit 2: Follow master scheme, Bit 3: Follow master background + if ( bHasBackground ) + nMode &=~4; + +/* sj: Don't know what's IsBackgroundVisible for, have to ask cl + if ( GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsBackgroundVisible" ) ) ) ) + { + sal_Bool bBackgroundVisible; + if ( aAny >>= bBackgroundVisible ) + { + if ( bBackgroundVisible ) + nMode &= ~4; + } + } +*/ + if ( GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsBackgroundObjectsVisible" ) ) ) ) + { + sal_Bool bBackgroundObjectsVisible = sal_False; + if ( aAny >>= bBackgroundObjectsVisible ) + { + if ( !bBackgroundObjectsVisible ) + nMode &= ~1; + } + } + + const PHLayout& rLayout = ImplGetLayout( mXPagePropSet ); + mpPptEscherEx->PtReplaceOrInsert( EPP_Persist_Slide | nPageNum, mpStrm->Tell() ); + mpPptEscherEx->OpenContainer( EPP_Slide ); + mpPptEscherEx->AddAtom( 24, EPP_SlideAtom, 2 ); + *mpStrm << rLayout.nLayout; + mpStrm->Write( rLayout.nPlaceHolder, 8 ); // placeholderIDs ( 8Stueck ) + *mpStrm << (sal_uInt32)nMasterID // master ID ( ist gleich 0x80000000 bei einer masterpage ) + << (sal_uInt32)nPageNum + 0x100 // notes ID ( ist gleich null wenn keine notizen vorhanden ) + << nMode + << (sal_uInt16)0; // padword + + mnDiaMode = 0; + sal_Bool bVisible = sal_True; + ::com::sun::star::presentation::FadeEffect eFe = ::com::sun::star::presentation::FadeEffect_NONE; + + if ( GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Visible" ) ) ) ) + aAny >>= bVisible; + if ( GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Change" ) ) ) ) + { + switch ( *(INT32*)aAny.getValue() ) + { + case 1 : // automatisch + mnDiaMode++; + case 2 : // halbautomatisch + mnDiaMode++; + default : + case 0 : // manuell + break; + } + } + if ( GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Effect" ) ) ) ) + aAny >>= eFe; + + sal_uInt32 nSoundRef = 0; + sal_Bool bIsSound = sal_False; + sal_Bool bStopSound = sal_False; + sal_Bool bLoopSound = sal_False; + + if ( GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Sound" ) ) ) ) + { + rtl::OUString aSoundURL; + if ( aAny >>= aSoundURL ) + { + nSoundRef = maSoundCollection.GetId( aSoundURL ); + bIsSound = sal_True; + } + else + aAny >>= bStopSound; + } + if ( GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "LoopSound" ) ) ) ) + aAny >>= bLoopSound; + + + sal_Bool bNeedsSSSlideInfoAtom = ( bVisible == FALSE ) + || ( mnDiaMode == 2 ) + || ( bIsSound ) + || ( bStopSound ) + || ( eFe != ::com::sun::star::presentation::FadeEffect_NONE ); + if ( bNeedsSSSlideInfoAtom ) + { + sal_uInt8 nDirection = 0; + sal_uInt8 nTransitionType = 0; + sal_uInt16 nBuildFlags = 1; // advange by mouseclick + INT32 nSlideTime = 0; // muss noch !!! + sal_uInt8 nSpeed = 1; + + if ( GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Speed" ) ) ) ) + { + ::com::sun::star::presentation::AnimationSpeed aAs; + aAny >>= aAs; + nSpeed = (sal_uInt8)aAs; + } + sal_Int16 nTT = 0, nTST = 0; + if ( GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TransitionType" ) ) ) + && ( aAny >>= nTT ) ) + { + if ( GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TransitionSubtype" ) ) ) + && ( aAny >>= nTST ) ) + { + switch( nTT ) + { + case animations::TransitionType::FADE : + { + if ( nTST == animations::TransitionSubType::CROSSFADE ) + nTransitionType = PPT_TRANSITION_TYPE_SMOOTHFADE; + else if ( nTST == animations::TransitionSubType::FADEOVERCOLOR ) + nTransitionType = PPT_TRANSITION_TYPE_FADE; + } + break; + case PPT_TRANSITION_TYPE_COMB : + { + nTransitionType = PPT_TRANSITION_TYPE_COMB; + if ( nTST == animations::TransitionSubType::COMBVERTICAL ) + nDirection++; + } + break; + case animations::TransitionType::PUSHWIPE : + { + nTransitionType = PPT_TRANSITION_TYPE_PUSH; + switch( nTST ) + { + case animations::TransitionSubType::FROMRIGHT: nDirection = 0; break; + case animations::TransitionSubType::FROMBOTTOM: nDirection = 1; break; + case animations::TransitionSubType::FROMLEFT: nDirection = 2; break; + case animations::TransitionSubType::FROMTOP: nDirection = 3; break; + } + } + break; + case animations::TransitionType::PINWHEELWIPE : + { + nTransitionType = PPT_TRANSITION_TYPE_WHEEL; + switch( nTST ) + { + case animations::TransitionSubType::ONEBLADE: nDirection = 1; break; + case animations::TransitionSubType::TWOBLADEVERTICAL : nDirection = 2; break; + case animations::TransitionSubType::THREEBLADE : nDirection = 3; break; + case animations::TransitionSubType::FOURBLADE: nDirection = 4; break; + case animations::TransitionSubType::EIGHTBLADE: nDirection = 8; break; + } + } + break; + case animations::TransitionType::FANWIPE : + { + nTransitionType = PPT_TRANSITION_TYPE_WEDGE; + } + break; + case animations::TransitionType::ELLIPSEWIPE : + { + nTransitionType = PPT_TRANSITION_TYPE_CIRCLE; + } + break; + case animations::TransitionType::FOURBOXWIPE : + { + nTransitionType = PPT_TRANSITION_TYPE_PLUS; + } + break; + case animations::TransitionType::IRISWIPE : + { + nTransitionType = PPT_TRANSITION_TYPE_DIAMOND; + } + break; + } + } + } + if ( !nTransitionType ) + { + switch ( eFe ) + { + default : + case ::com::sun::star::presentation::FadeEffect_RANDOM : + nTransitionType = PPT_TRANSITION_TYPE_RANDOM; + break; + + case ::com::sun::star::presentation::FadeEffect_HORIZONTAL_STRIPES : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_VERTICAL_STRIPES : + nTransitionType = PPT_TRANSITION_TYPE_BLINDS; + break; + + case ::com::sun::star::presentation::FadeEffect_VERTICAL_CHECKERBOARD : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_HORIZONTAL_CHECKERBOARD : + nTransitionType = PPT_TRANSITION_TYPE_CHECKER; + break; + + case ::com::sun::star::presentation::FadeEffect_MOVE_FROM_UPPERLEFT : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_MOVE_FROM_UPPERRIGHT : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_MOVE_FROM_LOWERLEFT : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_MOVE_FROM_LOWERRIGHT : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_MOVE_FROM_TOP : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_MOVE_FROM_LEFT : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_MOVE_FROM_BOTTOM : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_MOVE_FROM_RIGHT : + nTransitionType = PPT_TRANSITION_TYPE_COVER; + break; + + case ::com::sun::star::presentation::FadeEffect_DISSOLVE : + nTransitionType = PPT_TRANSITION_TYPE_DISSOLVE; + break; + + case ::com::sun::star::presentation::FadeEffect_VERTICAL_LINES : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_HORIZONTAL_LINES : + nTransitionType = PPT_TRANSITION_TYPE_RANDOM_BARS; + break; + + case ::com::sun::star::presentation::FadeEffect_CLOSE_HORIZONTAL : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_OPEN_HORIZONTAL : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_CLOSE_VERTICAL : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_OPEN_VERTICAL : + nTransitionType = PPT_TRANSITION_TYPE_SPLIT; + break; + + case ::com::sun::star::presentation::FadeEffect_FADE_FROM_UPPERLEFT : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_FADE_FROM_UPPERRIGHT : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_FADE_FROM_LOWERLEFT : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_FADE_FROM_LOWERRIGHT : + nDirection += 4; + nTransitionType = PPT_TRANSITION_TYPE_STRIPS; + break; + + case ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_LOWERRIGHT : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_LOWERLEFT : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_UPPERRIGHT : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_UPPERLEFT : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_BOTTOM : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_RIGHT : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_TOP : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_LEFT : + nTransitionType = PPT_TRANSITION_TYPE_PULL; + break; + + case ::com::sun::star::presentation::FadeEffect_FADE_FROM_TOP : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_FADE_FROM_LEFT : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_FADE_FROM_BOTTOM : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_FADE_FROM_RIGHT : + nTransitionType = PPT_TRANSITION_TYPE_WIPE; + break; + + case ::com::sun::star::presentation::FadeEffect_ROLL_FROM_TOP : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_ROLL_FROM_LEFT : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_ROLL_FROM_BOTTOM : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_ROLL_FROM_RIGHT : + nTransitionType = PPT_TRANSITION_TYPE_WIPE; + break; + + case ::com::sun::star::presentation::FadeEffect_FADE_TO_CENTER : + nDirection++; + case ::com::sun::star::presentation::FadeEffect_FADE_FROM_CENTER : + nTransitionType = PPT_TRANSITION_TYPE_ZOOM; + break; + + case ::com::sun::star::presentation::FadeEffect_NONE : + nDirection = 2; + break; + } + } + if ( mnDiaMode == 2 ) // automatic ? + nBuildFlags |= 0x400; + if ( bVisible == FALSE ) + nBuildFlags |= 4; + if ( bIsSound ) + nBuildFlags |= 16; + if ( bLoopSound ) + nBuildFlags |= 64; + if ( bStopSound ) + nBuildFlags |= 256; + + if ( GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Duration" ) ) ) )// duration of this slide + nSlideTime = *(INT32*)aAny.getValue() << 10; // in ticks + + + mpPptEscherEx->AddAtom( 16, EPP_SSSlideInfoAtom ); + *mpStrm << nSlideTime // standtime in ticks + << nSoundRef + << nDirection + << nTransitionType + << nBuildFlags + << nSpeed + << (sal_uInt8)0 << (sal_uInt8)0 << (sal_uInt8)0; + } + + ImplCreateHeaderFooters( mXPagePropSet ); + + EscherSolverContainer aSolverContainer; + mpPptEscherEx->OpenContainer( EPP_PPDrawing ); + mpPptEscherEx->OpenContainer( ESCHER_DgContainer ); + mpPptEscherEx->EnterGroup(0,0); + ImplWritePage( rLayout, aSolverContainer, NORMAL, FALSE, nPageNum ); // Die Shapes der Seite werden im PPT Dok. erzeugt + mpPptEscherEx->LeaveGroup(); + + if ( bHasBackground ) + ImplWriteBackground( aXBackgroundPropSet ); + else + { + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + mpPptEscherEx->AddShape( ESCHER_ShpInst_Rectangle, 0xc00 ); // Flags: Connector | Background | HasSpt + EscherPropertyContainer aPropOpt; + aPropOpt.AddOpt( ESCHER_Prop_fillRectRight, PPTtoEMU( maDestPageSize.Width ) ); + aPropOpt.AddOpt( ESCHER_Prop_fillRectBottom, PPTtoEMU( maDestPageSize.Width ) ); + aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x120012 ); + aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x80000 ); + aPropOpt.AddOpt( ESCHER_Prop_bWMode, ESCHER_wDontShow ); + aPropOpt.AddOpt( ESCHER_Prop_fBackground, 0x10001 ); // if true, this is the background shape + aPropOpt.Commit( *mpStrm ); + mpPptEscherEx->CloseContainer(); // ESCHER_SpContainer + } + + aSolverContainer.WriteSolver( *mpStrm ); + + mpPptEscherEx->CloseContainer(); // ESCHER_DgContainer + mpPptEscherEx->CloseContainer(); // EPP_Drawing + mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 1 ); + *mpStrm << (sal_uInt32)0xffffff << (sal_uInt32)0x000000 << (sal_uInt32)0x808080 << (sal_uInt32)0x000000 << (sal_uInt32)0x99cc00 << (sal_uInt32)0xcc3333 << (sal_uInt32)0xffcccc << (sal_uInt32)0xb2b2b2; + + SvMemoryStream aBinaryTagData10Atom; + ImplExportComments( mXDrawPage, aBinaryTagData10Atom ); + if ( mbUseNewAnimations ) + { + SvMemoryStream amsofbtAnimGroup; + ppt::AnimationExporter aExporter( aSolverContainer, maSoundCollection ); + aExporter.doexport( mXDrawPage, amsofbtAnimGroup ); + sal_uInt32 nmsofbtAnimGroupSize = amsofbtAnimGroup.Tell(); + if ( nmsofbtAnimGroupSize ) + { + { + EscherExAtom aMagic2( aBinaryTagData10Atom, 0x2eeb ); + aBinaryTagData10Atom << (sal_uInt32)0x01c45df9 + << (sal_uInt32)0xe1471b30; + } + { + EscherExAtom aMagic( aBinaryTagData10Atom, 0x2b00 ); + aBinaryTagData10Atom << (sal_uInt32)0; + } + aBinaryTagData10Atom.Write( amsofbtAnimGroup.GetData(), amsofbtAnimGroup.Tell() ); + { + EscherExContainer aMagic2( aBinaryTagData10Atom, 0x2b02 ); + } + } + } + if ( aBinaryTagData10Atom.Tell() ) + { + EscherExContainer aProgTags ( *mpStrm, EPP_ProgTags ); + EscherExContainer aProgBinaryTag( *mpStrm, EPP_ProgBinaryTag ); + { + EscherExAtom aCString( *mpStrm, EPP_CString ); + *mpStrm << (sal_uInt32)0x5f005f + << (sal_uInt32)0x50005f + << (sal_uInt32)0x540050 + << (sal_uInt16)0x31 + << (sal_uInt16)0x30; + } + { + EscherExAtom aBinaryTagData( *mpStrm, EPP_BinaryTagData ); + mpStrm->Write( aBinaryTagData10Atom.GetData(), aBinaryTagData10Atom.Tell() ); + } + } +/* + if ( mbUseNewAnimations ) + { + SvMemoryStream amsofbtAnimGroup; + ppt::AnimationExporter aExporter( aSolverContainer, maSoundCollection ); + aExporter.doexport( mXDrawPage, amsofbtAnimGroup ); + sal_uInt32 nmsofbtAnimGroupSize = amsofbtAnimGroup.Tell(); + if ( nmsofbtAnimGroupSize ) + { + EscherExContainer aProgTags ( *mpStrm, EPP_ProgTags ); + EscherExContainer aProgBinaryTag( *mpStrm, EPP_ProgBinaryTag ); + { + EscherExAtom aCString( *mpStrm, EPP_CString ); + *mpStrm << (sal_uInt32)0x5f005f + << (sal_uInt32)0x50005f + << (sal_uInt32)0x540050 + << (sal_uInt16)0x31 + << (sal_uInt16)0x30; + } + { + EscherExAtom aBinaryTagData( *mpStrm, EPP_BinaryTagData ); + { + { + EscherExAtom aMagic2( *mpStrm, 0x2eeb ); + *mpStrm << (sal_uInt32)0x01c45df9 + << (sal_uInt32)0xe1471b30; + } + { + EscherExAtom aMagic( *mpStrm, 0x2b00 ); + *mpStrm << (sal_uInt32)0; + } + } + mpStrm->Write( amsofbtAnimGroup.GetData(), amsofbtAnimGroup.Tell() ); + { + EscherExContainer aMagic2( *mpStrm, 0x2b02 ); + } + } + } + } +*/ + mpPptEscherEx->CloseContainer(); // EPP_Slide + return TRUE; +}; + +// --------------------------------------------------------------------------------------------- + +sal_Bool PPTWriter::ImplCreateNotes( sal_uInt32 nPageNum ) +{ + if ( !ImplGetPageByIndex( nPageNum, NOTICE ) ) + return FALSE; + ImplSetCurrentStyleSheet( ImplGetMasterIndex( NORMAL ) ); + + + mpPptEscherEx->PtReplaceOrInsert( EPP_Persist_Notes | nPageNum, mpStrm->Tell() ); + mpPptEscherEx->OpenContainer( EPP_Notes ); + mpPptEscherEx->AddAtom( 8, EPP_NotesAtom, 1 ); + *mpStrm << (sal_uInt32)nPageNum + 0x100 + << (sal_uInt16)3 // follow master .... + << (sal_uInt16)0; + + ImplCreateHeaderFooters( mXPagePropSet ); + + EscherSolverContainer aSolverContainer; + + mpPptEscherEx->OpenContainer( EPP_PPDrawing ); + mpPptEscherEx->OpenContainer( ESCHER_DgContainer ); + mpPptEscherEx->EnterGroup(0,0); + + ImplWritePage( pPHLayout[ 20 ], aSolverContainer, NOTICE, FALSE ); // Die Shapes der Seite werden im PPT Dok. erzeugt + + mpPptEscherEx->LeaveGroup(); + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + mpPptEscherEx->AddShape( ESCHER_ShpInst_Rectangle, 0xc00 ); // Flags: Connector | Background | HasSpt + EscherPropertyContainer aPropOpt; + aPropOpt.AddOpt( ESCHER_Prop_fillColor, 0xffffff ); // stock valued fill color + aPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0 ); + aPropOpt.AddOpt( ESCHER_Prop_fillRectRight, 0x8b9f8e ); + aPropOpt.AddOpt( ESCHER_Prop_fillRectBottom, 0x68bdde ); + aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x120012 ); + aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x80000 ); + aPropOpt.AddOpt( ESCHER_Prop_bWMode, ESCHER_wDontShow ); + aPropOpt.AddOpt( ESCHER_Prop_fBackground, 0x10001 ); + aPropOpt.Commit( *mpStrm ); + mpPptEscherEx->CloseContainer(); // ESCHER_SpContainer + + aSolverContainer.WriteSolver( *mpStrm ); + + mpPptEscherEx->CloseContainer(); // ESCHER_DgContainer + mpPptEscherEx->CloseContainer(); // EPP_Drawing + mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 1 ); + *mpStrm << (sal_uInt32)0xffffff << (sal_uInt32)0x000000 << (sal_uInt32)0x808080 << (sal_uInt32)0x000000 << (sal_uInt32)0x99cc00 << (sal_uInt32)0xcc3333 << (sal_uInt32)0xffcccc << (sal_uInt32)0xb2b2b2; + mpPptEscherEx->CloseContainer(); // EPP_Notes + return TRUE; +}; + +void PPTWriter::ImplWriteBackground( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet ) +{ + //************************ ****** + //** DEFAULT BACKGROUND SHAPE ** + //****************************** + + sal_uInt32 nFillColor = 0xffffff; + sal_uInt32 nFillBackColor = 0; + + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + mpPptEscherEx->AddShape( ESCHER_ShpInst_Rectangle, 0xc00 ); // Flags: Connector | Background | HasSpt + Point aEmptyPoint = Point(); + Rectangle aRect( aEmptyPoint, Size( 28000, 21000 ) ); + EscherPropertyContainer aPropOpt( mpPptEscherEx->GetGraphicProvider(), mpPicStrm, aRect ); + aPropOpt.AddOpt( ESCHER_Prop_fillType, ESCHER_FillSolid ); + ::com::sun::star::drawing::FillStyle aFS( ::com::sun::star::drawing::FillStyle_NONE ); + if ( ImplGetPropertyValue( rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillStyle" ) ) ) ) + mAny >>= aFS; + + switch( aFS ) + { + case ::com::sun::star::drawing::FillStyle_GRADIENT : + { + aPropOpt.CreateGradientProperties( rXPropSet ); + aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x1f001e ); + aPropOpt.GetOpt( ESCHER_Prop_fillColor, nFillColor ); + aPropOpt.GetOpt( ESCHER_Prop_fillBackColor, nFillBackColor ); + } + break; + + case ::com::sun::star::drawing::FillStyle_BITMAP : + aPropOpt.CreateGraphicProperties( rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillBitmapURL" ) ), sal_True ); + break; + + case ::com::sun::star::drawing::FillStyle_HATCH : + aPropOpt.CreateGraphicProperties( rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillHatch" ) ), sal_True ); + break; + + case ::com::sun::star::drawing::FillStyle_SOLID : + { + if ( ImplGetPropertyValue( rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillColor" ) ) ) ) + { + nFillColor = mpPptEscherEx->GetColor( *((sal_uInt32*)mAny.getValue()) ); + nFillBackColor = nFillColor ^ 0xffffff; + } + } // PASSTHROUGH INTENDED + case ::com::sun::star::drawing::FillStyle_NONE : + default: + aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x120012 ); + break; + } + aPropOpt.AddOpt( ESCHER_Prop_fillColor, nFillColor ); + aPropOpt.AddOpt( ESCHER_Prop_fillBackColor, nFillBackColor ); + aPropOpt.AddOpt( ESCHER_Prop_fillRectRight, PPTtoEMU( maDestPageSize.Width ) ); + aPropOpt.AddOpt( ESCHER_Prop_fillRectBottom, PPTtoEMU( maDestPageSize.Height ) ); + aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x80000 ); + aPropOpt.AddOpt( ESCHER_Prop_bWMode, ESCHER_bwWhite ); + aPropOpt.AddOpt( ESCHER_Prop_fBackground, 0x10001 ); + aPropOpt.Commit( *mpStrm ); + mpPptEscherEx->CloseContainer(); // ESCHER_SpContainer +} + +void PPTWriter::ImplWriteVBA( SvMemoryStream* pVBA ) +{ + if ( pVBA ) + { + pVBA->Seek( STREAM_SEEK_TO_END ); + sal_uInt32 nLen = pVBA->Tell(); + if ( nLen > 8 ) + { + nLen -= 8; + mnVBAOleOfs = mpStrm->Tell(); + mpPptEscherEx->BeginAtom(); + mpStrm->Write( (sal_Int8*)pVBA->GetData() + 8, nLen ); + mpPptEscherEx->EndAtom( EPP_ExOleObjStg, 0, 1 ); + } + } +} + +// --------------------------------------------------------------------------------------------- + +void PPTWriter::ImplWriteOLE( sal_uInt32 nCnvrtFlags ) +{ + PPTExOleObjEntry* pPtr; + + SvxMSExportOLEObjects aOleExport( nCnvrtFlags ); + + for ( pPtr = (PPTExOleObjEntry*)maExOleObj.First(); pPtr; + pPtr = (PPTExOleObjEntry*)maExOleObj.Next() ) + { + SvMemoryStream* pStrm = NULL; + pPtr->nOfsB = mpStrm->Tell(); + switch ( pPtr->eType ) + { + case NORMAL_OLE_OBJECT : + { + SdrObject* pSdrObj = GetSdrObjectFromXShape( pPtr->xShape ); + if ( pSdrObj && pSdrObj->ISA( SdrOle2Obj ) ) + { + ::uno::Reference < embed::XEmbeddedObject > xObj( ( (SdrOle2Obj*) pSdrObj )->GetObjRef() ); + if( xObj.is() ) + { + SvStorageRef xTempStorage( new SvStorage( new SvMemoryStream(), TRUE ) ); + aOleExport.ExportOLEObject( xObj, *xTempStorage ); + + //TODO/MBA: testing + String aPersistStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( SVEXT_PERSIST_STREAM ) ) ); + SvMemoryStream aStream; + SvStorageRef xCleanStorage( new SvStorage( FALSE, aStream ) ); + xTempStorage->CopyTo( xCleanStorage ); + // SJ: #99809# create a dummy content stream, the dummy content is necessary for ppt, but not for + // doc files, so we can't share code. + SotStorageStreamRef xStm = xCleanStorage->OpenSotStream( aPersistStream, STREAM_STD_READWRITE ); + *xStm << (sal_uInt32)0 // no ClipboardId + << (sal_uInt32)4 // no target device + << (sal_uInt32)1 // aspect ratio + << (sal_Int32)-1 // L-Index + << (sal_uInt32)0 // Advanced Flags + << (sal_uInt32)0 // compression + << (sal_uInt32)0 // Size + << (sal_uInt32)0 // " + << (sal_uInt32)0; + pStrm = xCleanStorage->CreateMemoryStream(); + } + } + } + break; + + case OCX_CONTROL : + { + if ( pPtr->xControlModel.is() ) + { + String aName; + ::com::sun::star::awt::Size aSize; + SvStorageRef xDest( new SvStorage( new SvMemoryStream(), TRUE ) ); + sal_Bool bOk = SvxMSConvertOCXControls::WriteOCXStream( xDest, pPtr->xControlModel, aSize, aName ); + if ( bOk ) + pStrm = xDest->CreateMemoryStream(); + } + } + } + if ( pStrm ) + { + mpPptEscherEx->BeginAtom(); + pStrm->Seek( STREAM_SEEK_TO_END ); + sal_uInt32 npStrmSize = pStrm->Tell(); + *mpStrm << npStrmSize; // uncompressed size + +#ifdef DBG_EXTRACTOLEOBJECTS + SvFileStream aOut( String::CreateFromAscii( "D:\\OUT.OLE" ), STREAM_TRUNC | STREAM_WRITE ); + pStrm->Seek( 0 ); + aOut.Write( pStrm->GetData(), npStrmSize ); +#endif + + pStrm->Seek( 0 ); + ZCodec aZCodec( 0x8000, 0x8000 ); + aZCodec.BeginCompression(); + aZCodec.Compress( *pStrm, *mpStrm ); + aZCodec.EndCompression(); + delete pStrm; + mpPptEscherEx->EndAtom( EPP_ExOleObjStg, 0, 1 ); + } + } +} + +// --------------------------------------------------------------------------------------------- +// PersistantTable und UserEditAtom schreiben + +sal_Bool PPTWriter::ImplWriteAtomEnding() +{ + +#define EPP_LastViewTypeNone 0 +#define EPP_LastViewTypeSlideView 1 +#define EPP_LastViewTypeOutlineView 2 +#define EPP_LastViewTypeNotes 3 + + + sal_uInt32 i, nPos, nOfs, nPersistOfs = mpStrm->Tell(); + sal_uInt32 nPersistEntrys = 0; + *mpStrm << (sal_uInt32)0 << (sal_uInt32)0 << (sal_uInt32)0; // Record Header und ersten Eintrag ueberspringen + + // Document pesist schreiben + nPersistEntrys++; + *mpStrm << (sal_uInt32)0; + // MasterPages persists schreiben + for ( i = 0; i < mnMasterPages; i++ ) + { + nOfs = mpPptEscherEx->PtGetOffsetByID( EPP_Persist_MainMaster | i ); + if ( nOfs ) + { + *mpStrm << nOfs; + mpPptEscherEx->InsertAtPersistOffset( EPP_MAINMASTER_PERSIST_KEY | i, ++nPersistEntrys ); + } + } + // MainNotesMaster persist schreiben + nOfs = mpPptEscherEx->PtGetOffsetByID( EPP_Persist_MainNotes ); + if ( nOfs ) + { + *mpStrm << nOfs; + mpPptEscherEx->InsertAtPersistOffset( EPP_MAINNOTESMASTER_PERSIST_KEY, ++nPersistEntrys ); + } + // Slide persists schreiben -> es gilt hier auch den EPP_SlidePersistAtome mit einem gueltigen wert zu beschreiben + for ( i = 0; i < mnPages; i++ ) + { + nOfs = mpPptEscherEx->PtGetOffsetByID( EPP_Persist_Slide | i ); + if ( nOfs ) + { + *mpStrm << nOfs; + mpPptEscherEx->InsertAtPersistOffset( EPP_MAINSLIDE_PERSIST_KEY | i, ++nPersistEntrys ); + } + } + // Notes persists schreiben + for ( i = 0; i < mnPages; i++ ) + { + nOfs = mpPptEscherEx->PtGetOffsetByID( EPP_Persist_Notes | i ); + if ( nOfs ) + { + *mpStrm << nOfs; + mpPptEscherEx->InsertAtPersistOffset( EPP_MAINNOTES_PERSIST_KEY | i, ++nPersistEntrys ); + } + } + // Ole persists + PPTExOleObjEntry* pPtr; + for ( pPtr = (PPTExOleObjEntry*)maExOleObj.First(); pPtr; pPtr = (PPTExOleObjEntry*)maExOleObj.Next() ) + { + nOfs = mpPptEscherEx->PtGetOffsetByID( EPP_Persist_ExObj ); + if ( nOfs ) + { + nPersistEntrys++; + *mpStrm << pPtr->nOfsB; + sal_uInt32 nOldPos, nPersOfs = nOfs + pPtr->nOfsA + 16 + 8; // 8 bytes atom header, +16 to the persist entry + nOldPos = mpStrm->Tell(); + mpStrm->Seek( nPersOfs ); + *mpStrm << nPersistEntrys; + mpStrm->Seek( nOldPos ); + } + } + // VB persist + if ( mnVBAOleOfs && mpVBA ) + { + nOfs = mpPptEscherEx->PtGetOffsetByID( EPP_Persist_VBAInfoAtom ); + if ( nOfs ) + { + nPersistEntrys++; + sal_uInt32 n1, n2; + + mpVBA->Seek( 0 ); + *mpVBA >> n1 + >> n2; + + *mpStrm << mnVBAOleOfs; + sal_uInt32 nOldPos = mpStrm->Tell(); + mpStrm->Seek( nOfs ); // Fill the VBAInfoAtom with the correct index to the persisttable + *mpStrm << nPersistEntrys + << n1 + << 2; + mpStrm->Seek( nOldPos ); + + } + } + nPos = mpStrm->Tell(); + mpStrm->Seek( nPersistOfs ); + mpPptEscherEx->AddAtom( ( nPersistEntrys + 1 ) << 2, EPP_PersistPtrIncrementalBlock ); // Record Header eintragen + *mpStrm << (sal_uInt32)( ( nPersistEntrys << 20 ) | 1 ); + mpStrm->Seek( nPos ); + + *mpCurUserStrm << (sal_uInt32)nPos; // offset to current edit setzen + mpPptEscherEx->AddAtom( 28, EPP_UserEditAtom ); + *mpStrm << (INT32)0x100 // last slide ID + << (sal_uInt32)0x03000dbc // minor and major app version that did the save + << (sal_uInt32)0 // offset last save, 0 after a full save + << nPersistOfs // File offset to persist pointers for this save operation + << (sal_uInt32)1 // Persist reference to the document persist object + << (sal_uInt32)nPersistEntrys // max persists written, Seed value for persist object id management + << (sal_Int16)EPP_LastViewTypeSlideView // last view type + << (sal_Int16)0x12; // padword + + return TRUE; +} + +// --------------------------------------------------------------------------------------------- + +PPTExCharSheet::PPTExCharSheet( int nInstance ) +{ + sal_uInt16 nFontHeight = 24; + + for ( int nDepth = 0; nDepth < 5; nDepth++ ) + { + PPTExCharLevel& rLev = maCharLevel[ nDepth ]; + switch ( nInstance ) + { + case EPP_TEXTTYPE_Title : + case EPP_TEXTTYPE_CenterTitle : + nFontHeight = 44; + break; + case EPP_TEXTTYPE_Body : + case EPP_TEXTTYPE_CenterBody : + case EPP_TEXTTYPE_HalfBody : + case EPP_TEXTTYPE_QuarterBody : + { + switch ( nDepth ) + { + case 0 : nFontHeight = 32; break; + case 1 : nFontHeight = 28; break; + case 2 : nFontHeight = 24; break; + default :nFontHeight = 20; break; + } + } + break; + case EPP_TEXTTYPE_Notes : + nFontHeight = 12; + break; + case EPP_TEXTTYPE_notUsed : + case EPP_TEXTTYPE_Other : + nFontHeight = 24; + break; + } + rLev.mnFlags = 0; + rLev.mnFont = 0; + rLev.mnAsianOrComplexFont = 0xffff; + rLev.mnFontHeight = nFontHeight; + rLev.mnFontColor = 0; + rLev.mnEscapement = 0; + } +} + + +void PPTExCharSheet::SetStyleSheet( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet, + FontCollection& rFontCollection, int nLevel ) +{ + PortionObj aPortionObj( rXPropSet, rFontCollection ); + + PPTExCharLevel& rLev = maCharLevel[ nLevel ]; + + if ( aPortionObj.meCharColor == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) + rLev.mnFontColor = aPortionObj.mnCharColor; + if ( aPortionObj.meCharEscapement == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) + rLev.mnEscapement = aPortionObj.mnCharEscapement; + if ( aPortionObj.meCharHeight == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) + rLev.mnFontHeight = aPortionObj.mnCharHeight; + if ( aPortionObj.meFontName == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) + rLev.mnFont = aPortionObj.mnFont; + if ( aPortionObj.meAsianOrComplexFont == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) + rLev.mnAsianOrComplexFont = aPortionObj.mnAsianOrComplexFont; + rLev.mnFlags = aPortionObj.mnCharAttr; +} + +void PPTExCharSheet::Write( SvStream& rSt, PptEscherEx*, sal_uInt16 nLev, sal_Bool, sal_Bool bSimpleText, + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rPagePropSet ) +{ + const PPTExCharLevel& rLev = maCharLevel[ nLev ]; + + sal_uInt32 nCharFlags = 0xefffff; + if ( bSimpleText ) + nCharFlags = 0x7ffff; + + rSt << nCharFlags + << rLev.mnFlags + << rLev.mnFont; + + sal_uInt32 nFontColor = rLev.mnFontColor; + if ( nFontColor == COL_AUTO ) + { + sal_Bool bIsDark = sal_False; + ::com::sun::star::uno::Any aAny; + if ( PropValue::GetPropertyValue( aAny, rPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsBackgroundDark" ) ), sal_True ) ) + aAny >>= bIsDark; + nFontColor = bIsDark ? 0xffffff : 0x000000; + } + nFontColor &= 0xffffff; + nFontColor |= 0xfe000000; + if ( bSimpleText ) + { + rSt << rLev.mnFontHeight + << nFontColor; + } + else + { + rSt << rLev.mnAsianOrComplexFont + << (sal_uInt16)0xffff // unbekannt + << (sal_uInt16)0xffff // unbekannt + << rLev.mnFontHeight + << nFontColor + << rLev.mnEscapement; + } +} + +PPTExParaSheet::PPTExParaSheet( int nInstance, sal_uInt16 nDefaultTab, PPTExBulletProvider& rProv ) : + rBuProv ( rProv ), + mnInstance ( nInstance ) +{ + sal_Bool bHasBullet = FALSE; + + sal_uInt16 nUpperDist = 0; + sal_uInt16 nBulletChar = 0x2022; + sal_uInt16 nBulletOfs = 0; + sal_uInt16 nTextOfs = 0; + + for ( int nDepth = 0; nDepth < 5; nDepth++ ) + { + PPTExParaLevel& rLev = maParaLevel[ nDepth ]; + switch ( nInstance ) + { + case EPP_TEXTTYPE_Title : + case EPP_TEXTTYPE_CenterTitle : + break; + case EPP_TEXTTYPE_Body : + case EPP_TEXTTYPE_CenterBody : + case EPP_TEXTTYPE_HalfBody : + case EPP_TEXTTYPE_QuarterBody : + { + bHasBullet = TRUE; + nUpperDist = 0x14; + } + break; + case EPP_TEXTTYPE_Notes : + nUpperDist = 0x1e; + break; + +// default : +// case EPP_TEXTTYPE_notUsed : +// case EPP_TEXTTYPE_Other : +// break; + } + switch ( nDepth ) + { + case 0 : + { + nBulletChar = 0x2022; + nBulletOfs = 0; + nTextOfs = ( bHasBullet ) ? 0xd8 : 0; + } + break; + case 1 : + { + nBulletChar = 0x2013; + nBulletOfs = 0x120; + nTextOfs = 0x1d4; + } + break; + case 2 : + { + nBulletChar = 0x2022; + nBulletOfs = 0x240; + nTextOfs = 0x2d0; + } + break; + case 3 : + { + nBulletChar = 0x2013; + nBulletOfs = 0x360; + nTextOfs = 0x3f0; + } + break; + case 4 : + { + nBulletChar = 0xbb; + nBulletOfs = 0x480; + nTextOfs = 0x510; + } + break; + } + rLev.mbIsBullet = bHasBullet; + rLev.mnBulletChar = nBulletChar; + rLev.mnBulletFont = 0; + rLev.mnBulletHeight = 100; + rLev.mnBulletColor = 0; + rLev.mnAdjust = 0; + rLev.mnLineFeed = 100; + rLev.mnLowerDist = 0; + rLev.mnUpperDist = nUpperDist; + rLev.mnTextOfs = nTextOfs; + rLev.mnBulletOfs = nBulletOfs; + rLev.mnDefaultTab = nDefaultTab; + rLev.mnAsianSettings = 2; + rLev.mnBiDi = 0; + + rLev.mbExtendedBulletsUsed = FALSE; + rLev.mnBulletId = 0xffff; + rLev.mnBulletStart = 0; + rLev.mnMappedNumType = 0; + rLev.mnNumberingType = 0; + } +} + +void PPTExParaSheet::SetStyleSheet( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet, + FontCollection& rFontCollection, int nLevel, const PPTExCharLevel& rCharLevel ) +{ + ParagraphObj aParagraphObj( rXPropSet, rBuProv ); + aParagraphObj.CalculateGraphicBulletSize( rCharLevel.mnFontHeight ); + PPTExParaLevel& rLev = maParaLevel[ nLevel ]; + + if ( aParagraphObj.meTextAdjust == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) + rLev.mnAdjust = aParagraphObj.mnTextAdjust; + if ( aParagraphObj.meLineSpacing == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) + { + sal_Int16 nLineSpacing = aParagraphObj.mnLineSpacing; + if ( nLineSpacing > 0 ) // if nLinespacing is < 0 the linespacing is an absolute spacing + { + sal_Bool bFixedLineSpacing = sal_False; + uno::Any aAny = rXPropSet->getPropertyValue( ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "FontIndependentLineSpacing" ) ) ); + if( !(aAny >>= bFixedLineSpacing) || !bFixedLineSpacing ) + { + const FontCollectionEntry* pDesc = rFontCollection.GetById( rCharLevel.mnFont ); + if ( pDesc ) + nLineSpacing = (sal_Int16)( (double)nLineSpacing * pDesc->Scaling + 0.5 ); + } + } + else + { + if ( rCharLevel.mnFontHeight > (sal_uInt16)( ((double)-nLineSpacing) * 0.001 * 72.0 / 2.54 ) ) // 1/100mm to point + { + const FontCollectionEntry* pDesc = rFontCollection.GetById( rCharLevel.mnFont ); + if ( pDesc ) + nLineSpacing = (sal_Int16)( (double)100.0 * pDesc->Scaling + 0.5 ); + else + nLineSpacing = 100; + } + else + nLineSpacing = (sal_Int16)( (double)nLineSpacing / 4.40972 ); + } + rLev.mnLineFeed = nLineSpacing; + } + if ( aParagraphObj.meLineSpacingBottom == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) + rLev.mnLowerDist = aParagraphObj.mnLineSpacingBottom; + if ( aParagraphObj.meLineSpacingTop == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) + rLev.mnUpperDist = aParagraphObj.mnLineSpacingTop; + if ( aParagraphObj.meForbiddenRules == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) + { + rLev.mnAsianSettings &=~1; + if ( aParagraphObj.mbForbiddenRules ) + rLev.mnAsianSettings |= 1; + } + if ( aParagraphObj.meParagraphPunctation == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) + { + rLev.mnAsianSettings &=~4; + if ( aParagraphObj.mbParagraphPunctation ) + rLev.mnAsianSettings |= 4; + } + + if ( aParagraphObj.meBiDi == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) + rLev.mnBiDi = aParagraphObj.mnBiDi; + + rLev.mbIsBullet = aParagraphObj.mbIsBullet; //( ( aParagraphObj.nBulletFlags & 1 ) != 0 ); + + if ( !nLevel ) + { + if ( ( aParagraphObj.meBullet == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) + && aParagraphObj.bExtendedParameters ) + { + for ( sal_Int16 i = 0; i < 5; i++ ) + { + PPTExParaLevel& rLevel = maParaLevel[ i ]; + if ( i ) + aParagraphObj.ImplGetNumberingLevel( rBuProv, i, FALSE ); +// rLevel.mbIsBullet = ( ( aParagraphObj.nBulletFlags & 1 ) != 0 ); + rLevel.mnTextOfs = aParagraphObj.nTextOfs; + rLevel.mnBulletOfs = (sal_uInt16)aParagraphObj.nBulletOfs; + rLevel.mnBulletChar = aParagraphObj.cBulletId; + FontCollectionEntry aFontDescEntry( aParagraphObj.aFontDesc.Name, aParagraphObj.aFontDesc.Family, + aParagraphObj.aFontDesc.Pitch, aParagraphObj.aFontDesc.CharSet ); + rLevel.mnBulletFont = (sal_uInt16)rFontCollection.GetId( aFontDescEntry ); + rLevel.mnBulletHeight = aParagraphObj.nBulletRealSize; + rLevel.mnBulletColor = aParagraphObj.nBulletColor; + + rLevel.mbExtendedBulletsUsed = aParagraphObj.bExtendedBulletsUsed; + rLevel.mnBulletId = aParagraphObj.nBulletId; + rLevel.mnNumberingType = aParagraphObj.nNumberingType; + rLevel.mnBulletStart = aParagraphObj.nStartWith; + rLevel.mnMappedNumType = aParagraphObj.nMappedNumType; + } + } + } +} + +void PPTExParaSheet::Write( SvStream& rSt, PptEscherEx*, sal_uInt16 nLev, sal_Bool, sal_Bool bSimpleText, + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rPagePropSet ) +{ + const PPTExParaLevel& rLev = maParaLevel[ nLev ]; + + if ( maParaLevel[ 0 ].mbExtendedBulletsUsed || maParaLevel[ 1 ].mbExtendedBulletsUsed || + maParaLevel[ 2 ].mbExtendedBulletsUsed || maParaLevel[ 3 ].mbExtendedBulletsUsed || + maParaLevel[ 4 ].mbExtendedBulletsUsed ) + { + SvStream& rOut = rBuProv.aBuExMasterStream; + if ( !nLev ) + { + rOut << (sal_uInt32)( ( EPP_PST_ExtendedParagraphMasterAtom << 16 ) | ( mnInstance << 4 ) ) + << (sal_uInt32)( 5 * 16 + 2 ) + << (sal_uInt16)5; // depth + } + sal_uInt16 nBulletId = rLev.mnBulletId; + if ( rLev.mnNumberingType != SVX_NUM_BITMAP ) + nBulletId = 0xffff; + rOut << (sal_uInt32)0x03800000 + << (sal_uInt16)nBulletId + << (sal_uInt32)rLev.mnMappedNumType + << (sal_uInt16)rLev.mnBulletStart + << (sal_uInt32)0; + } + + sal_uInt32 nParaFlags = 0x3ffdff; + sal_uInt16 nBulletFlags = ( rLev.mbIsBullet ) ? 0xf : 0xe; + + if ( nLev ) + nParaFlags &= 0x207fff; + if ( bSimpleText ) + nParaFlags &= 0x7fff; + sal_uInt32 nBulletColor = rLev.mnBulletColor; + if ( nBulletColor == COL_AUTO ) + { + sal_Bool bIsDark = sal_False; + ::com::sun::star::uno::Any aAny; + if ( PropValue::GetPropertyValue( aAny, rPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsBackgroundDark" ) ), sal_True ) ) + aAny >>= bIsDark; + nBulletColor = bIsDark ? 0xffffff : 0x000000; + } + nBulletColor &= 0xffffff; + nBulletColor |= 0xfe000000; + rSt << nParaFlags + << nBulletFlags + << rLev.mnBulletChar + << rLev.mnBulletFont + << rLev.mnBulletHeight + << nBulletColor + << rLev.mnAdjust + << rLev.mnLineFeed + << rLev.mnUpperDist + << rLev.mnLowerDist + << rLev.mnTextOfs + << rLev.mnBulletOfs; + + if ( bSimpleText || nLev ) + { + if ( nParaFlags & 0x200000 ) + rSt << rLev.mnBiDi; + } + else + { + rSt << rLev.mnDefaultTab + << (sal_uInt16)0 + << (sal_uInt16)0 + << rLev.mnAsianSettings + << rLev.mnBiDi; + } +} + + +PPTExStyleSheet::PPTExStyleSheet( sal_uInt16 nDefaultTab, PPTExBulletProvider& rBuProv ) +{ + for ( int nInstance = EPP_TEXTTYPE_Title; nInstance <= EPP_TEXTTYPE_QuarterBody; nInstance++ ) + { + mpParaSheet[ nInstance ] = ( nInstance == EPP_TEXTTYPE_notUsed ) ? NULL : new PPTExParaSheet( nInstance, nDefaultTab, rBuProv ); + mpCharSheet[ nInstance ] = ( nInstance == EPP_TEXTTYPE_notUsed ) ? NULL : new PPTExCharSheet( nInstance ); + } +} + +PPTExStyleSheet::~PPTExStyleSheet() +{ + for ( int nInstance = EPP_TEXTTYPE_Title; nInstance <= EPP_TEXTTYPE_QuarterBody; nInstance++ ) + { + if ( nInstance == EPP_TEXTTYPE_notUsed ) + continue; + + delete mpParaSheet[ nInstance ]; + delete mpCharSheet[ nInstance ]; + } +} + +void PPTExStyleSheet::SetStyleSheet( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet, + FontCollection& rFontCollection, int nInstance, int nLevel ) +{ + if ( nInstance == EPP_TEXTTYPE_notUsed ) + return; + mpCharSheet[ nInstance ]->SetStyleSheet( rXPropSet, rFontCollection, nLevel ); + mpParaSheet[ nInstance ]->SetStyleSheet( rXPropSet, rFontCollection, nLevel, mpCharSheet[ nInstance ]->maCharLevel[ nLevel ] ); +} + +sal_Bool PPTExStyleSheet::IsHardAttribute( sal_uInt32 nInstance, sal_uInt32 nLevel, PPTExTextAttr eAttr, sal_uInt32 nValue ) +{ + const PPTExParaLevel& rPara = mpParaSheet[ nInstance ]->maParaLevel[ nLevel ]; + const PPTExCharLevel& rChar = mpCharSheet[ nInstance ]->maCharLevel[ nLevel ]; + + sal_uInt32 nFlag = 0; + + switch ( eAttr ) + { + case ParaAttr_BulletOn : return ( rPara.mbIsBullet ) ? ( nValue ) ? FALSE : TRUE : ( nValue ) ? TRUE : FALSE; + case ParaAttr_BuHardFont : + case ParaAttr_BulletFont : return ( rPara.mnBulletFont != nValue ); + case ParaAttr_BuHardColor : + case ParaAttr_BulletColor : return ( rPara.mnBulletColor != nValue ); + case ParaAttr_BuHardHeight : + case ParaAttr_BulletHeight : return ( rPara.mnBulletHeight != nValue ); + case ParaAttr_BulletChar : return ( rPara.mnBulletChar != nValue ); + case ParaAttr_Adjust : return ( rPara.mnAdjust != nValue ); + case ParaAttr_LineFeed : return ( rPara.mnLineFeed != nValue ); + case ParaAttr_UpperDist : return ( rPara.mnUpperDist != nValue ); + case ParaAttr_LowerDist : return ( rPara.mnLowerDist != nValue ); + case ParaAttr_TextOfs : return ( rPara.mnTextOfs != nValue ); + case ParaAttr_BulletOfs : return ( rPara.mnBulletOfs != nValue ); + case ParaAttr_DefaultTab : return ( rPara.mnDefaultTab != nValue ); + case ParaAttr_BiDi : return ( rPara.mnBiDi != nValue ); + case CharAttr_Bold : nFlag = 1; break; + case CharAttr_Italic : nFlag = 2; break; + case CharAttr_Underline : nFlag = 4; break; + case CharAttr_Shadow : nFlag = 16; break; + case CharAttr_Strikeout : nFlag = 256; break; + case CharAttr_Embossed : nFlag = 512; break; + case CharAttr_Font : return ( rChar.mnFont != nValue ); + case CharAttr_AsianOrComplexFont : return ( rChar.mnAsianOrComplexFont != nValue ); + case CharAttr_Symbol : return TRUE; + case CharAttr_FontHeight : return ( rChar.mnFontHeight != nValue ); + case CharAttr_FontColor : return ( rChar.mnFontColor != nValue ); + case CharAttr_Escapement : return ( rChar.mnEscapement != nValue ); + default: + break; + }; + if ( nFlag ) + { + if ( rChar.mnFlags & nFlag ) + return ( ( nValue & nFlag ) == 0 ); + else + return ( ( nValue & nFlag ) != 0 ); + } + return TRUE; +} + +sal_uInt32 PPTExStyleSheet::SizeOfTxCFStyleAtom() const +{ + return 24; +} + +// the TxCFStyleAtom stores the text properties that are used +// when creating new objects in PowerPoint. + +void PPTExStyleSheet::WriteTxCFStyleAtom( SvStream& rSt ) +{ + const PPTExCharLevel& rCharStyle = mpCharSheet[ EPP_TEXTTYPE_Other ]->maCharLevel[ 0 ]; + + sal_uInt16 nFlags = 0x60 // ?? + | 0x02 // fontsize; + | 0x04; // fontcolor + + sal_uInt32 nCharFlags = rCharStyle.mnFlags; + nCharFlags &= CharAttr_Italic | CharAttr_Bold | CharAttr_Underline | CharAttr_Shadow; + + rSt << (sal_uInt32)( EPP_TxCFStyleAtom << 16 ) // recordheader + << SizeOfTxCFStyleAtom() - 8 + << (sal_uInt16)( 0x80 | nCharFlags ) + << (sal_uInt16)nFlags + << (sal_uInt16)nCharFlags + << (sal_Int32)-1 // ? + << rCharStyle.mnFontHeight + << rCharStyle.mnFontColor; +} + + +// --------------------------------------------------------------------------------------------- + +// --------------------- +// - exported function - +// --------------------- + +extern "C" SAL_DLLPUBLIC_EXPORT BOOL __LOADONCALLAPI ExportPPT( SvStorageRef& rSvStorage, + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > & rXModel, + ::com::sun::star::uno::Reference< ::com::sun::star::task::XStatusIndicator > & rXStatInd, + SvMemoryStream* pVBA, sal_uInt32 nCnvrtFlags ) +{ + PPTWriter* pPPTWriter; + BOOL bStatus = FALSE; + + pPPTWriter = new PPTWriter( rSvStorage, rXModel, rXStatInd, pVBA, nCnvrtFlags ); + if ( pPPTWriter ) + { + bStatus = ( pPPTWriter->IsValid() == TRUE ); + delete pPPTWriter; + } + + return bStatus; +} + +extern "C" SAL_DLLPUBLIC_EXPORT BOOL __LOADONCALLAPI SaveVBA( SfxObjectShell& rDocShell, SvMemoryStream*& pBas ) +{ + SvStorageRef xDest( new SvStorage( new SvMemoryStream(), TRUE ) ); + SvxImportMSVBasic aMSVBas( rDocShell, *xDest, FALSE, FALSE ); + aMSVBas.SaveOrDelMSVBAStorage( TRUE, String( RTL_CONSTASCII_USTRINGPARAM("_MS_VBA_Overhead") ) ); + + SvStorageRef xOverhead = xDest->OpenSotStorage( String( RTL_CONSTASCII_USTRINGPARAM("_MS_VBA_Overhead") ) ); + if ( xOverhead.Is() && ( xOverhead->GetError() == SVSTREAM_OK ) ) + { + SvStorageRef xOverhead2 = xOverhead->OpenSotStorage( String( RTL_CONSTASCII_USTRINGPARAM("_MS_VBA_Overhead") ) ); + if ( xOverhead2.Is() && ( xOverhead2->GetError() == SVSTREAM_OK ) ) + { + SvStorageStreamRef xTemp = xOverhead2->OpenSotStream( String( RTL_CONSTASCII_USTRINGPARAM("_MS_VBA_Overhead2") ) ); + if ( xTemp.Is() && ( xTemp->GetError() == SVSTREAM_OK ) ) + { + UINT32 nLen = xTemp->GetSize(); + if ( nLen ) + { + char* pTemp = new char[ nLen ]; + if ( pTemp ) + { + xTemp->Seek( STREAM_SEEK_TO_BEGIN ); + xTemp->Read( pTemp, nLen ); + pBas = new SvMemoryStream( pTemp, nLen, STREAM_READ ); + pBas->ObjectOwnsMemory( TRUE ); + return TRUE; + } + } + } + } + } + + return FALSE; +} + diff --git a/sd/source/filter/eppt/eppt.hxx b/sd/source/filter/eppt/eppt.hxx new file mode 100644 index 000000000000..f3ec27d8093c --- /dev/null +++ b/sd/source/filter/eppt/eppt.hxx @@ -0,0 +1,850 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _EPPT_HXX_ +#define _EPPT_HXX_ +#include <vector> +#ifndef _PptEscherEx_HXX +#include "escherex.hxx" +#endif +#include <tools/solar.h> +#include <sot/storage.hxx> +#include <tools/gen.hxx> +#include <vcl/graph.hxx> +#include <unotools/fontcvt.hxx> +#include <tools/string.hxx> +#include "pptexanimations.hxx" +#include <pptexsoundcollection.hxx> + +// ------------------------------------------------------------------------ + +#include <vcl/mapmod.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/drawing/FillStyle.hpp> +#include <com/sun/star/drawing/LineStyle.hpp> +#include <com/sun/star/drawing/DashStyle.hpp> +#include <com/sun/star/drawing/HatchStyle.hpp> +#include <com/sun/star/drawing/LineEndType.hpp> +#include <com/sun/star/drawing/Alignment.hpp> +#include <com/sun/star/drawing/TextAdjust.hpp> +#include <com/sun/star/drawing/CircleKind.hpp> +#include <com/sun/star/drawing/PolygonKind.hpp> +#include <com/sun/star/drawing/PolygonFlags.hpp> +#include <com/sun/star/drawing/XUniversalShapeDescriptor.hpp> +#include <com/sun/star/drawing/XShapeGrouper.hpp> +#include <com/sun/star/text/XSimpleText.hpp> +#include <com/sun/star/drawing/XConnectorShape.hpp> +#include <com/sun/star/drawing/BezierPoint.hpp> +#include <com/sun/star/drawing/Hatch.hpp> +#include <com/sun/star/drawing/LineDash.hpp> +#include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp> +#include <com/sun/star/presentation/XPresentationSupplier.hpp> +#include <com/sun/star/presentation/XCustomPresentationSupplier.hpp> +#include <com/sun/star/drawing/XMasterPageTarget.hpp> +#include <com/sun/star/drawing/XDrawPagesSupplier.hpp> +#include <com/sun/star/drawing/XMasterPagesSupplier.hpp> +#include <com/sun/star/awt/XGraphics.hpp> +#include <com/sun/star/task/XStatusIndicatorSupplier.hpp> +#include <com/sun/star/presentation/AnimationEffect.hpp> +#include <com/sun/star/presentation/FadeEffect.hpp> +#include <com/sun/star/presentation/ClickAction.hpp> +#include <com/sun/star/presentation/AnimationSpeed.hpp> +#include <com/sun/star/presentation/PresentationRange.hpp> +#include <com/sun/star/text/XTextFieldsSupplier.hpp> +#include <com/sun/star/text/XTextField.hpp> +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/awt/FontDescriptor.hpp> +#include <com/sun/star/container/XIndexContainer.hpp> +#include <com/sun/star/awt/XControlModel.hpp> +#include <com/sun/star/style/TabStop.hpp> +#include <filter/msfilter/msocximex.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XPropertyState.hpp> +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <com/sun/star/awt/FontFamily.hpp> +#include <com/sun/star/awt/FontPitch.hpp> +#include <com/sun/star/awt/CharSet.hpp> +#include <com/sun/star/text/WritingMode.hpp> +#include <com/sun/star/lang/Locale.hpp> + +enum PageType { NORMAL = 0, MASTER = 1, NOTICE = 2, UNDEFINED = 3 }; + +#define EPP_MAINMASTER_PERSIST_KEY 0x80010000 +#define EPP_MAINNOTESMASTER_PERSIST_KEY 0x80020000 +#define EPP_MAINSLIDE_PERSIST_KEY 0x80030000 +#define EPP_MAINNOTES_PERSIST_KEY 0x80040000 + +#define EPP_Persist_Document 0x80080000 +#define EPP_Persist_MainMaster 0x80100000 +#define EPP_Persist_MainNotes 0x80200000 +#define EPP_Persist_Slide 0x80400000 +#define EPP_Persist_Notes 0x80800000 +#define EPP_Persist_CurrentPos 0x81000000 +#define EPP_Persist_VBAInfoAtom 0x84000000 +#define EPP_Persist_ExObj 0x88000000 + +#define EPP_TEXTSTYLE_NORMAL 0x00000001 +#define EPP_TEXTSTYLE_TITLE 0x00000010 +#define EPP_TEXTSTYLE_BODY 0x00000100 +#define EPP_TEXTSTYLE_TEXT 0x00001000 + +// PLACEMENT_ID +#define EPP_LAYOUT_TITLESLIDE 0 /* The slide is a title slide */ +#define EPP_LAYOUT_TITLEANDBODYSLIDE 1 /* Title and body slide */ +#define EPP_LAYOUT_TITLEMASTERSLIDE 2 /* Title master slide */ +#define EPP_LAYOUT_MASTERSLIDE 3 /* Master slide layout */ +#define EPP_LAYOUT_MASTERNOTES 4 /* Master notes layout */ +#define EPP_LAYOUT_NOTESTITLEBODY 5 /* Notes title/body layout */ +#define EPP_LAYOUT_HANDOUTLAYOUT 6 /* Handout layout, therefore it doesn't have placeholders except header, footer, and date */ +#define EPP_LAYOUT_ONLYTITLE 7 /* Only title placeholder */ +#define EPP_LAYOUT_2COLUMNSANDTITLE 8 /* Body of the slide has 2 columns and a title */ +#define EPP_LAYOUT_2ROWSANDTITLE 9 /* Slide's body has 2 rows and a title */ +#define EPP_LAYOUT_RIGHTCOLUMN2ROWS 10 /* Body contains 2 columns, right column has 2 rows */ +#define EPP_LAYOUT_LEFTCOLUMN2ROWS 11 /* Body contains 2 columns, left column has 2 rows */ +#define EPP_LAYOUT_BOTTOMROW2COLUMNS 12 /* Body contains 2 rows, bottom row has 2 columns */ +#define EPP_LAYOUT_TOPROW2COLUMN 13 /* Body contains 2 rows, top row has 2 columns */ +#define EPP_LAYOUT_4OBJECTS 14 /* 4 objects */ +#define EPP_LAYOUT_BIGOBJECT 15 /* Big object */ +#define EPP_LAYOUT_BLANCSLIDE 16 /* Blank slide */ +#define EPP_LAYOUT_TITLERIGHTBODYLEFT 17 /* Vertical title on the right, body on the left */ +#define EPP_LAYOUT_TITLERIGHT2BODIESLEFT 18 /* Vertical title on the right, body on the left split into 2 rows */ + +class Polygon; +class PptEscherEx; +class XStatusIndicatorRef; + +struct PHLayout +{ + sal_Int32 nLayout; + sal_uInt8 nPlaceHolder[ 8 ]; + + sal_uInt8 nUsedObjectPlaceHolder; + sal_uInt8 nTypeOfTitle; + sal_uInt8 nTypeOfOutliner; + + BOOL bTitlePossible; + BOOL bOutlinerPossible; + BOOL bSecOutlinerPossible; +}; + +struct SOParagraph +{ + sal_Bool bExtendedParameters; + sal_uInt32 nParaFlags; + sal_Int16 nBulletFlags; + String sPrefix; + String sSuffix; + String sGraphicUrl; // String auf eine Graphic + Size aBuGraSize; + sal_uInt32 nNumberingType; // in wirlichkeit ist dies ein SvxEnum + sal_uInt32 nHorzAdjust; + sal_uInt32 nBulletColor; + sal_Int32 nBulletOfs; + sal_Int16 nStartWith; // Start der nummerierung + sal_Int16 nTextOfs; + sal_Int16 nBulletRealSize; // GroessenVerhaeltnis in Proz + sal_Int16 nDepth; // aktuelle tiefe + sal_Unicode cBulletId; // wenn Numbering Type == CharSpecial + ::com::sun::star::awt::FontDescriptor aFontDesc; + + sal_Bool bExtendedBulletsUsed; + sal_uInt16 nBulletId; + sal_uInt32 nMappedNumType; + sal_Bool bNumberingIsNumber; + + SOParagraph() + { + nDepth = 0; + bExtendedParameters = FALSE; + nParaFlags = 0; + nBulletFlags = 0; + nBulletOfs = 0; + nTextOfs = 0; + bExtendedBulletsUsed = FALSE; + nBulletId = 0xffff; + bNumberingIsNumber = sal_True; + }; +}; + +// ------------------------------------------------------------------------ + +class EscherGraphicProvider; +class PPTExBulletProvider +{ + friend struct PPTExParaSheet; + + protected : + + SvMemoryStream aBuExPictureStream; + SvMemoryStream aBuExOutlineStream; + SvMemoryStream aBuExMasterStream; + + EscherGraphicProvider* pGraphicProv; + + public : + + sal_uInt16 GetId( const ByteString& rUniqueId, Size& rGraphicSize ); + + PPTExBulletProvider(); + ~PPTExBulletProvider(); +}; + +struct FontCollectionEntry +{ + String Name; + double Scaling; + sal_Int16 Family; + sal_Int16 Pitch; + sal_Int16 CharSet; + + String Original; + sal_Bool bIsConverted; + + FontCollectionEntry( const String& rName, sal_Int16 nFamily, sal_Int16 nPitch, sal_Int16 nCharSet ) : + Scaling ( 1.0 ), + Family ( nFamily ), + Pitch ( nPitch ), + CharSet ( nCharSet ), + Original( rName ) + { + ImplInit( rName ); + }; + + FontCollectionEntry( const String& rName ) : + Scaling ( 1.0 ), + Original( rName ) + { + ImplInit( rName ); + }; + ~FontCollectionEntry(); + + private : + + FontCollectionEntry() {}; + + void ImplInit( const String& rName ); +}; + +class VirtualDevice; +class FontCollection : private List +{ + VirtualDevice* pVDev; + public : + FontCollection(); + ~FontCollection(); + + short GetScriptDirection( const String& rText ) const; + sal_uInt32 GetId( FontCollectionEntry& rFontDescriptor ); + sal_uInt32 GetCount() const { return List::Count(); }; + const FontCollectionEntry* GetById( sal_uInt32 nId ); + FontCollectionEntry& GetLast() { return *(FontCollectionEntry*)List::Last(); }; +}; + +// ------------------------------------------------------------------------ + +#define PPTEX_STYLESHEETENTRYS 9 + +enum PPTExTextAttr +{ + ParaAttr_BulletOn, + ParaAttr_BuHardFont, + ParaAttr_BuHardColor, + ParaAttr_BuHardHeight, + ParaAttr_BulletChar, + ParaAttr_BulletFont, + ParaAttr_BulletHeight, + ParaAttr_BulletColor, + ParaAttr_Adjust, + ParaAttr_LineFeed, + ParaAttr_UpperDist, + ParaAttr_LowerDist, + ParaAttr_TextOfs, + ParaAttr_BulletOfs, + ParaAttr_DefaultTab, + ParaAttr_AsianLB_1, + ParaAttr_AsianLB_2, + ParaAttr_AsianLB_3, + ParaAttr_BiDi, + CharAttr_Bold, + CharAttr_Italic, + CharAttr_Underline, + CharAttr_Shadow, + CharAttr_Strikeout, + CharAttr_Embossed, + CharAttr_Font, + CharAttr_AsianOrComplexFont, + CharAttr_Symbol, + CharAttr_FontHeight, + CharAttr_FontColor, + CharAttr_Escapement +}; + +struct PPTExCharLevel +{ + sal_uInt16 mnFlags; + sal_uInt16 mnFont; + sal_uInt16 mnAsianOrComplexFont; + sal_uInt16 mnFontHeight; + sal_uInt16 mnEscapement; + sal_uInt32 mnFontColor; +}; + +struct PPTExCharSheet +{ + PPTExCharLevel maCharLevel[ 5 ]; + + PPTExCharSheet( int nInstance ); + + void SetStyleSheet( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > &, + FontCollection& rFontCollection, int nLevel ); + void Write( SvStream& rSt, PptEscherEx* pEx, sal_uInt16 nLev, sal_Bool bFirst, sal_Bool bSimpleText, + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rPagePropSet ); + +}; + +struct PPTExParaLevel +{ + sal_Bool mbIsBullet; + sal_uInt16 mnBulletChar; + sal_uInt16 mnBulletFont; + sal_uInt16 mnBulletHeight; + sal_uInt32 mnBulletColor; + + sal_uInt16 mnAdjust; + sal_uInt16 mnLineFeed; + sal_uInt16 mnUpperDist; + sal_uInt16 mnLowerDist; + sal_uInt16 mnTextOfs; + sal_uInt16 mnBulletOfs; + sal_uInt16 mnDefaultTab; + + sal_Bool mbExtendedBulletsUsed; + sal_uInt16 mnBulletId; + sal_uInt16 mnBulletStart; + sal_uInt32 mnMappedNumType; + sal_uInt32 mnNumberingType; + sal_uInt16 mnAsianSettings; + sal_uInt16 mnBiDi; +}; + +struct PPTExParaSheet +{ + PPTExBulletProvider& rBuProv; + + sal_uInt32 mnInstance; + + PPTExParaLevel maParaLevel[ 5 ]; + PPTExParaSheet( int nInstance, sal_uInt16 nDefaultTab, PPTExBulletProvider& rProv ); + + void SetStyleSheet( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > &, + FontCollection& rFontCollection, int nLevel, const PPTExCharLevel& rCharLevel ); + void Write( SvStream& rSt, PptEscherEx* pEx, sal_uInt16 nLev, sal_Bool bFirst, sal_Bool bSimpleText, + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rPagePropSet ); +}; + +class PPTExStyleSheet +{ + + public : + + PPTExCharSheet* mpCharSheet[ PPTEX_STYLESHEETENTRYS ]; + PPTExParaSheet* mpParaSheet[ PPTEX_STYLESHEETENTRYS ]; + + PPTExStyleSheet( sal_uInt16 nDefaultTab, PPTExBulletProvider& rBuProv ); + ~PPTExStyleSheet(); + + PPTExParaSheet& GetParaSheet( int nInstance ) { return *mpParaSheet[ nInstance ]; }; + PPTExCharSheet& GetCharSheet( int nInstance ) { return *mpCharSheet[ nInstance ]; }; + + void SetStyleSheet( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > &, + FontCollection& rFontCollection, int nInstance, int nLevel ); + sal_Bool IsHardAttribute( sal_uInt32 nInstance, sal_uInt32 nLevel, PPTExTextAttr eAttr, sal_uInt32 nValue ); + + sal_uInt32 SizeOfTxCFStyleAtom() const; + void WriteTxCFStyleAtom( SvStream& rSt ); +}; + + +struct EPPTHyperlink +{ + String aURL; + sal_uInt32 nType; // bit 0-7 : type ( 1: click action to a slide ) + // ( 2: hyperlink url ) + // bit 8-23: index + // bit 31 : hyperlink is attached to a shape + + EPPTHyperlink( const String rURL, sal_uInt32 nT ) : + aURL ( rURL ), + nType ( nT ){}; +}; + +enum PPTExOleObjEntryType +{ + NORMAL_OLE_OBJECT, OCX_CONTROL +}; + +struct PPTExOleObjEntry +{ + PPTExOleObjEntryType eType; + sal_uInt32 nOfsA; // offset to the EPP_ExOleObjAtom in mpExEmbed (set at creation) + sal_uInt32 nOfsB; // offset to the EPP_ExOleObjStg + + ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > xControlModel; + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape; + + PPTExOleObjEntry( PPTExOleObjEntryType eT, sal_uInt32 nOfs ) : + eType ( eT ), + nOfsA ( nOfs ) {}; +}; + +struct TextRuleEntry +{ + int nPageNumber; + SvMemoryStream* pOut; + + TextRuleEntry( int nPg ) : + nPageNumber( nPg ), + pOut ( NULL ){}; + + ~TextRuleEntry() { delete pOut; }; +}; + +// ------------------------------------------------------------------------ + +struct GroupEntry +{ + sal_uInt32 mnCurrentPos; + sal_uInt32 mnCount; + ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess > mXIndexAccess; + GroupEntry( ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess > & rIndex ) + { + mXIndexAccess = rIndex; + mnCount =mXIndexAccess->getCount(); + mnCurrentPos = 0; + }; + GroupEntry( sal_uInt32 nCount ) + { + mnCount = nCount; + mnCurrentPos = 0; + }; + ~GroupEntry(){}; +}; + +// ------------------------------------------------------------------------ + +class GroupTable +{ + protected: + + sal_uInt32 mnIndex; + sal_uInt32 mnCurrentGroupEntry; + sal_uInt32 mnMaxGroupEntry; + sal_uInt32 mnGroupsClosed; + GroupEntry** mpGroupEntry; + + void ImplResizeGroupTable( sal_uInt32 nEntrys ); + + public: + + sal_uInt32 GetCurrentGroupIndex() const { return mnIndex; }; + sal_Int32 GetCurrentGroupLevel() const { return mnCurrentGroupEntry - 1; }; + ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess > & + GetCurrentGroupAccess() const { return mpGroupEntry[ mnCurrentGroupEntry - 1 ]->mXIndexAccess; }; + sal_uInt32 GetGroupsClosed(); + void SkipCurrentGroup(); + void ResetGroupTable( sal_uInt32 nCount ); + void ClearGroupTable(); + sal_Bool EnterGroup( ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess > & rIndex ); + sal_Bool GetNextGroupEntry(); + GroupTable(); + ~GroupTable(); +}; + +class PropValue +{ + protected : + + ::com::sun::star::uno::Any mAny; + + ::com::sun::star::uno::Reference + < ::com::sun::star::beans::XPropertySet > mXPropSet; + + sal_Bool ImplGetPropertyValue( const String& rString ); + sal_Bool ImplGetPropertyValue( const ::com::sun::star::uno::Reference + < ::com::sun::star::beans::XPropertySet > &, const String& ); + + public : + + static sal_Bool GetPropertyValue( + ::com::sun::star::uno::Any& rAny, + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > &, + const String& rPropertyName, + sal_Bool bTestPropertyAvailability = sal_False ); + + static ::com::sun::star::beans::PropertyState GetPropertyState( + const ::com::sun::star::uno::Reference < ::com::sun::star::beans::XPropertySet > &, + const String& rPropertyName ); +}; + +class PropStateValue : public PropValue +{ + protected : + + ::com::sun::star::beans::PropertyState ePropState; + ::com::sun::star::uno::Reference + < ::com::sun::star::beans::XPropertyState > mXPropState; + + sal_Bool ImplGetPropertyValue( const String& rString, sal_Bool bGetPropertyState = TRUE ); + +}; + +// ------------------------------------------------------------------------ + +struct FieldEntry; +class PortionObj : public PropStateValue +{ + + friend class ParagraphObj; + + protected : + + void ImplClear(); + void ImplConstruct( PortionObj& rPortionObj ); + sal_uInt32 ImplGetTextField( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > & rXTextRangeRef, + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSetRef, String& rURL ); + sal_uInt32 ImplCalculateTextPositions( sal_uInt32 nCurrentTextPosition ); + void ImplGetPortionValues( FontCollection& rFontCollection, sal_Bool bGetPropStateValue = FALSE ); + + public : + + ::com::sun::star::beans::PropertyState meCharColor; + ::com::sun::star::beans::PropertyState meCharHeight; + ::com::sun::star::beans::PropertyState meFontName; + ::com::sun::star::beans::PropertyState meAsianOrComplexFont; + ::com::sun::star::beans::PropertyState meCharEscapement; + ::com::sun::star::lang::Locale meCharLocale; + sal_uInt16 mnCharAttrHard; + + sal_uInt32 mnCharColor; + sal_uInt16 mnCharAttr; + sal_uInt16 mnCharHeight; + sal_uInt16 mnFont; + sal_uInt16 mnAsianOrComplexFont; + sal_Int16 mnCharEscapement; + + sal_uInt32 mnTextSize; + sal_Bool mbLastPortion; + + sal_uInt16* mpText; + FieldEntry* mpFieldEntry; + + PortionObj( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > & rXTextRangeRef, + sal_Bool bLast, FontCollection& rFontCollection ); + PortionObj( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSetRef, + FontCollection& rFontCollection ); + PortionObj( PortionObj& rPortionObj ); + ~PortionObj(); + + void Write( SvStream* pStrm, sal_Bool bLast ); + sal_uInt32 Count() const { return mnTextSize; }; + + PortionObj& operator=( PortionObj& rPortionObj ); +}; + +struct ParaFlags +{ + sal_Bool bFirstParagraph : 1; + sal_Bool bLastParagraph : 1; + + ParaFlags() { bFirstParagraph = TRUE; bLastParagraph = FALSE; }; +}; + +class ParagraphObj : public List, public PropStateValue, public SOParagraph +{ + friend class TextObj; + friend struct PPTExParaSheet; + + MapMode maMapModeSrc; + MapMode maMapModeDest; + + protected : + + void ImplConstruct( ParagraphObj& rParagraphObj ); + void ImplClear(); + sal_uInt32 ImplCalculateTextPositions( sal_uInt32 nCurrentTextPosition ); + ::com::sun::star::awt::Size ImplMapSize( const ::com::sun::star::awt::Size& rSize ); + void ImplGetParagraphValues( PPTExBulletProvider& rBuProv, sal_Bool bGetPropStateValue = FALSE ); + void ImplGetNumberingLevel( PPTExBulletProvider& rBuProv, sal_Int16 nDepth, sal_Bool bIsBullet, sal_Bool bGetPropStateValue = FALSE ); + + public : + + ::com::sun::star::uno::Sequence< ::com::sun::star::style::TabStop > maTabStop; + + sal_uInt32 mnTextSize; + + sal_Bool mbIsBullet; + sal_Bool mbFirstParagraph; + sal_Bool mbLastParagraph; + + ::com::sun::star::beans::PropertyState meBullet; + ::com::sun::star::beans::PropertyState meTextAdjust; + ::com::sun::star::beans::PropertyState meLineSpacing; + ::com::sun::star::beans::PropertyState meLineSpacingTop; + ::com::sun::star::beans::PropertyState meLineSpacingBottom; + ::com::sun::star::beans::PropertyState meForbiddenRules; + ::com::sun::star::beans::PropertyState meParagraphPunctation; + ::com::sun::star::beans::PropertyState meBiDi; + + sal_uInt16 mnTextAdjust; + sal_Int16 mnLineSpacing; + sal_Int16 mnLineSpacingTop; + sal_Int16 mnLineSpacingBottom; + sal_Bool mbForbiddenRules; + sal_Bool mbParagraphPunctation; + sal_uInt16 mnBiDi; + + ParagraphObj( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextContent > & rXTextContentRef, + ParaFlags, FontCollection& rFontCollection, + PPTExBulletProvider& rBuProv ); + ParagraphObj( ParagraphObj& rParargraphObj ); + ParagraphObj( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSetRef, + PPTExBulletProvider& rBuProv ); + + void CalculateGraphicBulletSize( sal_uInt16 nFontHeight ); + ~ParagraphObj(); + + void Write( SvStream* pStrm ); + sal_uInt32 Count() const { return mnTextSize; }; + + ParagraphObj& operator=( ParagraphObj& rParagraphObj ); +}; + +struct ImplTextObj +{ + sal_uInt32 mnRefCount; + sal_uInt32 mnTextSize; + int mnInstance; + List* mpList; + sal_Bool mbHasExtendedBullets; + sal_Bool mbFixedCellHeightUsed; + + ImplTextObj( int nInstance ); + ~ImplTextObj(); +}; + +class TextObj +{ + ImplTextObj* mpImplTextObj; + void ImplCalculateTextPositions(); + + public : + TextObj( ::com::sun::star::uno::Reference< ::com::sun::star::text::XSimpleText > & + rXText, int nInstance, FontCollection& rFontCollection, PPTExBulletProvider& rBuProv ); + TextObj( TextObj& rTextObj ); + ~TextObj(); + + void Write( SvStream* pStrm ); + + ParagraphObj* First(){ return (ParagraphObj*)mpImplTextObj->mpList->First(); }; + ParagraphObj* Next(){ return(ParagraphObj*)mpImplTextObj->mpList->Next(); }; + sal_uInt32 Count() const { return mpImplTextObj->mnTextSize; }; + int GetInstance() const { return mpImplTextObj->mnInstance; }; + sal_Bool HasExtendedBullets(){ return mpImplTextObj->mbHasExtendedBullets; }; + void WriteTextSpecInfo( SvStream* pStrm ); + + TextObj& operator=( TextObj& rTextObj ); +}; + +// ------------------------------------------------------------------------ +struct CellBorder; +class PPTWriter : public GroupTable, public PropValue, public PPTExBulletProvider +{ + sal_Bool mbStatus; + sal_Bool mbUseNewAnimations; + sal_uInt32 mnStatMaxValue; + sal_uInt32 mnLatestStatValue; + std::vector< PPTExStyleSheet* > maStyleSheetList; + PPTExStyleSheet* mpStyleSheet; + + EscherGraphicProvider* mpGraphicProvider; + Fraction maFraction; + MapMode maMapModeSrc; + MapMode maMapModeDest; + ::com::sun::star::awt::Size maDestPageSize; + ::com::sun::star::awt::Size maNotesPageSize; + PageType meLatestPageType; + List maSlideNameList; + + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > mXModel; + ::com::sun::star::uno::Reference< ::com::sun::star::task::XStatusIndicator > mXStatusIndicator; + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPagesSupplier > mXDrawPagesSupplier; + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XMasterPagesSupplier > mXMasterPagesSupplier; + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPages > mXDrawPages; + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage > mXDrawPage; + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > mXPagePropSet; + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > mXBackgroundPropSet; + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes > mXShapes; + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > mXShape; + ::com::sun::star::uno::Reference< ::com::sun::star::text::XSimpleText > mXText; // TextRef des globalen Text + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextCursor > mXCursor; + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > mXCursorText; // TextRef des Teilstuecks des Cursors + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > mXCursorPropSet; // die Properties des Teilstueckes + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextField > mXTextField; + ::com::sun::star::awt::Size maSize; + ::com::sun::star::awt::Point maPosition; + Rectangle maRect; + ByteString mType; + sal_Bool mbPresObj; + sal_Bool mbEmptyPresObj; + sal_Bool mbStatusIndicator; + sal_Int32 mnAngle; + sal_uInt32 mnTextStyle; + + sal_Bool mbFontIndependentLineSpacing; + sal_uInt32 mnTextSize; + + SvStorageRef mrStg; + SvStorageStream* mpCurUserStrm; + SvStorageStream* mpStrm; + SvStorageStream* mpPicStrm; + PptEscherEx* mpPptEscherEx; + + List maExOleObj; + sal_uInt32 mnVBAOleOfs; + SvMemoryStream* mpVBA; + sal_uInt32 mnExEmbed; + SvMemoryStream* mpExEmbed; + + sal_uInt32 mnPages; // anzahl einzelner Slides ( ohne masterpages & notes & handout ) + sal_uInt32 mnMasterPages; // + sal_uInt32 mnDrawings; // anzahl Slides + masterpages + notes + handout + sal_uInt32 mnPagesWritten; + sal_uInt32 mnUniqueSlideIdentifier; + sal_uInt32 mnTxId; // Identifier determined by the HOST (PP) ???? + sal_uInt32 mnDiaMode; // 0 -> manuell + // 1 -> halbautomatisch + // 2 -> automatisch + + sal_uInt32 mnShapeMasterTitle; + sal_uInt32 mnShapeMasterBody; + + List maHyperlink; + + FontCollection maFontCollection; + ppt::ExSoundCollection maSoundCollection; + + PHLayout& ImplGetLayout( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& rXPropSet ) const; + void ImplWriteExtParaHeader( SvMemoryStream& rSt, sal_uInt32 nRef, sal_uInt32 nInstance, sal_uInt32 nSlideId ); + + + sal_uInt32 ImplProgBinaryTag( SvStream* pOutStrm = NULL ); + sal_uInt32 ImplProgBinaryTagContainer( SvStream* pOutStrm = NULL, SvMemoryStream* pBinTag = NULL ); + sal_uInt32 ImplProgTagContainer( SvStream* pOutStrm = NULL, SvMemoryStream* pBinTag = NULL ); + sal_uInt32 ImplOutlineViewInfoContainer( SvStream* pOutStrm = NULL ); + sal_uInt32 ImplSlideViewInfoContainer( sal_uInt32 nInstance, SvStream* pOutStrm = NULL ); + sal_uInt32 ImplVBAInfoContainer( SvStream* pOutStrm = NULL ); + sal_uInt32 ImplDocumentListContainer( SvStream* pOutStrm = NULL ); + sal_uInt32 ImplMasterSlideListContainer( SvStream* pOutStrm = NULL ); + + public: + static void WriteCString( SvStream&, const String&, sal_uInt32 nInstance = 0 ); + + protected: + + sal_Bool ImplCreateDocumentSummaryInformation( sal_uInt32 nCnvrtFlags ); + sal_Bool ImplCreateCurrentUserStream(); + void ImplCreateHeaderFooterStrings( SvStream& rOut, + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& rXPagePropSet ); + void ImplCreateHeaderFooters( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& rXPagePropSet ); + sal_Bool ImplCreateDocument(); + sal_Bool ImplCreateHyperBlob( SvMemoryStream& rStream ); + sal_uInt32 ImplInsertBookmarkURL( const String& rBookmark, const sal_uInt32 nType, + const String& rStringVer0, const String& rStringVer1, const String& rStringVer2, const String& rStringVer3 ); + sal_Bool ImplCreateMaster( sal_uInt32 nPageNum ); + sal_Bool ImplCreateMainNotes(); + sal_Bool ImplCreateSlide( sal_uInt32 nPageNum ); + sal_Bool ImplCreateNotes( sal_uInt32 nPageNum ); + void ImplWriteBackground( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXBackgroundPropSet ); + void ImplWriteVBA( SvMemoryStream* pVBA ); + void ImplWriteOLE( sal_uInt32 nCnvrtFlags ); + sal_Bool ImplWriteAtomEnding(); + + sal_Bool ImplInitSOIface(); + sal_Bool ImplSetCurrentStyleSheet( sal_uInt32 nPageNum ); + sal_Bool ImplGetPageByIndex( sal_uInt32 nIndex, PageType ); + sal_Bool ImplGetShapeByIndex( sal_uInt32 nIndex, sal_Bool bGroup = FALSE ); + sal_uInt32 ImplGetMasterIndex( PageType ePageType ); + void ImplFlipBoundingBox( EscherPropertyContainer& rPropOpt ); + sal_Bool ImplGetText(); + sal_Bool ImplCreatePresentationPlaceholder( const sal_Bool bMaster, const PageType PageType, + const sal_uInt32 StyleInstance, const sal_uInt8 PlaceHolderId ); + sal_Bool ImplGetEffect( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > &, + ::com::sun::star::presentation::AnimationEffect& eEffect, + ::com::sun::star::presentation::AnimationEffect& eTextEffect, + sal_Bool& bHasSound ); + void ImplWriteObjectEffect( SvStream& rSt, + ::com::sun::star::presentation::AnimationEffect eEffect, + ::com::sun::star::presentation::AnimationEffect eTextEffect, + sal_uInt16 nOrder ); + void ImplWriteClickAction( SvStream& rSt, ::com::sun::star::presentation::ClickAction eAction, sal_Bool bMediaClickAction ); + sal_Bool ImplGetStyleSheets(); + void ImplWriteParagraphs( SvStream& rOutStrm, TextObj& rTextObj ); + void ImplWritePortions( SvStream& rOutStrm, TextObj& rTextObj ); + void ImplWriteTextStyleAtom( SvStream& rOut, int nTextInstance, sal_uInt32 nAtomInstance, + TextRuleEntry* pTextRule, SvStream& rExtBu, EscherPropertyContainer* ); + void ImplAdjustFirstLineLineSpacing( TextObj& rTextObj, EscherPropertyContainer& rPropOpt ); + void ImplCreateShape( sal_uInt32 nType, sal_uInt32 nFlags, EscherSolverContainer& ); + void ImplCreateTextShape( EscherPropertyContainer&, EscherSolverContainer&, sal_Bool bFill ); + + void ImplWritePage( const PHLayout& rLayout, + EscherSolverContainer& rSolver, + PageType ePageType, + sal_Bool bMaster, + int nPageNumber = 0 ); + void ImplCreateCellBorder( const CellBorder* pCellBorder, sal_Int32 nX1, sal_Int32 nY1, sal_Int32 nX2, sal_Int32 nY2 ); + void ImplCreateTable( com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& rXShape, EscherSolverContainer& aSolverContainer, + EscherPropertyContainer& aPropOpt ); + ::com::sun::star::awt::Point ImplMapPoint( const ::com::sun::star::awt::Point& ); + ::com::sun::star::awt::Size ImplMapSize( const ::com::sun::star::awt::Size& ); + Rectangle ImplMapRectangle( const ::com::sun::star::awt::Rectangle& ); + + sal_Bool ImplCloseDocument(); // die font-, hyper-, Soundliste wird geschrieben .. + + public: + PPTWriter( SvStorageRef& rSvStorage, + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > & rModel, + ::com::sun::star::uno::Reference< ::com::sun::star::task::XStatusIndicator > & rStatInd, + SvMemoryStream* pVBA, sal_uInt32 nCnvrtFlags ); + + ~PPTWriter(); + + sal_Bool IsValid() const { return mbStatus; }; +}; + + +#endif diff --git a/sd/source/filter/eppt/epptdef.hxx b/sd/source/filter/eppt/epptdef.hxx new file mode 100644 index 000000000000..7d23fee19344 --- /dev/null +++ b/sd/source/filter/eppt/epptdef.hxx @@ -0,0 +1,263 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _EPPT_DEF_HXX +#define _EPPT_DEF_HXX + +#include <tools/solar.h> + +#define EPP_FLAG_CONTAINER 0x0F // If the version field of a record + // header takes on this value, the + // record header marks the start of + // a container. + +#define EPP_Unknown 0 +#define EPP_SubContainerCompleted 1 +#define EPP_IRRAtom 2 +#define EPP_PSS 3 +#define EPP_SubContainerException 4 +#define EPP_ClientSignal1 6 +#define EPP_ClientSignal2 7 +#define EPP_PowerPointStateInfoAtom 10 +#define EPP_Document 1000 +#define EPP_DocumentAtom 1001 +#define EPP_EndDocument 1002 +#define EPP_SlidePersist 1003 +#define EPP_SlideBase 1004 +#define EPP_SlideBaseAtom 1005 +#define EPP_Slide 1006 +#define EPP_SlideAtom 1007 +#define EPP_Notes 1008 +#define EPP_NotesAtom 1009 +#define EPP_Environment 1010 +#define EPP_SlidePersistAtom 1011 //0x03F3 +#define EPP_Scheme 1012 +#define EPP_SchemeAtom 1013 +#define EPP_DocViewInfo 1014 +#define EPP_SslideLayoutAtom 1015 +#define EPP_MainMaster 1016 +#define EPP_SSSlideInfoAtom 1017 +#define EPP_SlideViewInfo 1018 +#define EPP_GuideAtom 1019 +#define EPP_ViewInfo 1020 +#define EPP_ViewInfoAtom 1021 +#define EPP_SlideViewInfoAtom 1022 +#define EPP_VBAInfo 1023 +#define EPP_VBAInfoAtom 1024 +#define EPP_SSDocInfoAtom 1025 +#define EPP_Summary 1026 +#define EPP_Texture 1027 +#define EPP_VBASlideInfo 1028 +#define EPP_VBASlideInfoAtom 1029 +#define EPP_DocRoutingSlip 1030 +#define EPP_OutlineViewInfo 1031 +#define EPP_SorterViewInfo 1032 +#define EPP_ExObjList 1033 +#define EPP_ExObjListAtom 1034 +#define EPP_PPDrawingGroup 1035 +#define EPP_PPDrawing 1036 +#define EPP_NamedShows 1040 +#define EPP_NamedShow 1041 +#define EPP_NamedShowSlides 1042 +#define EPP_List 2000 +#define EPP_FontCollection 2005 +#define EPP_ListPlaceholder 2017 +#define EPP_BookmarkCollection 2019 +#define EPP_SoundCollection 2020 +#define EPP_SoundCollAtom 2021 +#define EPP_Sound 2022 +#define EPP_SoundData 2023 +#define EPP_BookmarkSeedAtom 2025 +#define EPP_GuideList 2026 +#define EPP_RunArray 2028 +#define EPP_RunArrayAtom 2029 +#define EPP_ArrayElementAtom 2030 +#define EPP_Int4ArrayAtom 2031 +#define EPP_ColorSchemeAtom 2032 + +// these atoms first was seen in ppt2000 in a private Tag atom +#define EPP_PST_ExtendedBuGraContainer 2040 // consist of 4041 +#define EPP_PST_ExtendedBuGraAtom 2041 // the instance of this atom indices the current graphic + +#define EPP_OEShape 3008 +#define EPP_ExObjRefAtom 3009 +#define EPP_OEPlaceholderAtom 3011 +#define EPP_GrColor 3020 +#define EPP_GrectAtom 3025 +#define EPP_GratioAtom 3031 +#define EPP_Gscaling 3032 +#define EPP_GpointAtom 3034 +#define EPP_OEShapeAtom 3035 +#define EPP_OutlineTextRefAtom 3998 +#define EPP_TextHeaderAtom 3999 +#define EPP_TextCharsAtom 4000 +#define EPP_StyleTextPropAtom 4001 +#define EPP_BaseTextPropAtom 4002 +#define EPP_TxMasterStyleAtom 4003 +#define EPP_TxCFStyleAtom 4004 +#define EPP_TxPFStyleAtom 4005 +#define EPP_TextRulerAtom 4006 +#define EPP_TextBookmarkAtom 4007 +#define EPP_TextBytesAtom 4008 +#define EPP_TxSIStyleAtom 4009 +#define EPP_TextSpecInfoAtom 4010 +#define EPP_DefaultRulerAtom 4011 + +// these atoms first was seen in ppt2000 in a private Tag atom +#define EPP_PST_ExtendedParagraphAtom 4012 +#define EPP_PST_ExtendedParagraphMasterAtom 4013 +#define EPP_PST_ExtendedPresRuleContainer 4014 // consist of 4012, 4015, +#define EPP_PST_ExtendedParagraphHeaderAtom 4015 // the instance of this atom indices the current presobj + // the first UINT32 in this atom indices the current slideId + +#define EPP_FontEnityAtom 4023 +#define EPP_FontEmbedData 4024 +#define EPP_TypeFace 4025 +#define EPP_CString 4026 +#define EPP_ExternalObject 4027 +#define EPP_MetaFile 4033 +#define EPP_ExOleObj 4034 +#define EPP_ExOleObjAtom 4035 +#define EPP_ExPlainLinkAtom 4036 +#define EPP_CorePict 4037 +#define EPP_CorePictAtom 4038 +#define EPP_ExPlainAtom 4039 +#define EPP_SrKinsoku 4040 +#define EPP_Handout 4041 +#define EPP_ExEmbed 4044 +#define EPP_ExEmbedAtom 4045 +#define EPP_ExLink 4046 +#define EPP_ExLinkAtom_old 4047 +#define EPP_BookmarkEntityAtom 4048 +#define EPP_ExLinkAtom 4049 +#define EPP_SrKinsokuAtom 4050 +#define EPP_ExHyperlinkAtom 4051 +#define EPP_ExPlain 4053 +#define EPP_ExPlainLink 4054 +#define EPP_ExHyperlink 4055 +#define EPP_SlideNumberMCAtom 4056 +#define EPP_HeadersFooters 4057 +#define EPP_HeadersFootersAtom 4058 +#define EPP_RecolorEntryAtom 4062 +#define EPP_TxInteractiveInfoAtom 4063 +#define EPP_EmFormatAtom 4065 +#define EPP_CharFormatAtom 4066 +#define EPP_ParaFormatAtom 4067 +#define EPP_MasterText 4068 +#define EPP_RecolorInfoAtom 4071 +#define EPP_ExQuickTime 4073 +#define EPP_ExQuickTimeMovie 4074 +#define EPP_ExQuickTimeMovieData 4075 +#define EPP_ExSubscription 4076 +#define EPP_ExSubscriptionSection 4077 +#define EPP_ExControl 4078 +#define EPP_ExControlAtom 4091 +#define EPP_SlideListWithText 4080 // 0x0FF0 +#define EPP_AnimationInfoAtom 4081 +#define EPP_InteractiveInfo 4082 +#define EPP_InteractiveInfoAtom 4083 +#define EPP_SlideList 4084 +#define EPP_UserEditAtom 4085 +#define EPP_CurrentUserAtom 4086 +#define EPP_DateTimeMCAtom 4087 +#define EPP_GenericDateMCAtom 4088 +#define EPP_HeaderMCAtom 4089 +#define EPP_FooterMCAtom 4090 +#define EPP_ExMediaAtom 4100 +#define EPP_ExVideo 4101 +#define EPP_ExAviMovie 4102 +#define EPP_ExMCIMovie 4103 +#define EPP_ExMIDIAudio 4109 +#define EPP_ExCDAudio 4110 +#define EPP_ExWAVAudioEmbedded 4111 +#define EPP_ExWAVAudioLink 4112 +#define EPP_ExOleObjStg 4113 +#define EPP_ExCDAudioAtom 4114 +#define EPP_ExWAVAudioEmbeddedAtom 4115 +#define EPP_AnimationInfo 4116 +#define EPP_RTFDateTimeMCAtom 4117 +#define EPP_ProgTags 5000 +#define EPP_ProgStringTag 5001 +#define EPP_ProgBinaryTag 5002 +#define EPP_BinaryTagData 5003 +#define EPP_PrintOptions 6000 +#define EPP_PersistPtrFullBlock 6001 +#define EPP_PersistPtrIncrementalBlock 6002 +#define EPP_RulerIndentAtom 10000 +#define EPP_GscalingAtom 10001 +#define EPP_GrColorAtom 10002 +#define EPP_GLPointAtom 10003 +#define EPP_Comment10 12000 +#define EPP_CommentAtom10 12001 + + +#define EPP_PLACEHOLDER_NONE 0 // 0 None +#define EPP_PLACEHOLDER_MASTERTITLE 1 // 1 Master title +#define EPP_PLACEHOLDER_MASTERBODY 2 // 2 Master body +#define EPP_PLACEHOLDER_MASTERCENTEREDTITLE 3 // 3 Master centered title +#define EPP_PLACEHOLDER_MASTERSUBTITLE 4 // 10 Master subtitle +#define EPP_PLACEHOLDER_MASTERNOTESSLIDEIMAGE 5 // 4 Master notes slide image +#define EPP_PLACEHOLDER_MASTERNOTESBODYIMAGE 6 // 5 Master notes body image +#define EPP_PLACEHOLDER_MASTERDATE 7 // 6 Master date +#define EPP_PLACEHOLDER_MASTERSLIDENUMBER 8 // 7 Master slide number +#define EPP_PLACEHOLDER_MASTERFOOTER 9 // 8 Master footer +#define EPP_PLACEHOLDER_MASTERHEADER 10 // 9 Master header +#define EPP_PLACEHOLDER_GENERICTEXTOBJECT // 11 Generic text object +#define EPP_PLACEHOLDER_TITLE 13 // 12 Title +#define EPP_PLACEHOLDER_BODY 14 // 13 Body +#define EPP_PLACEHOLDER_NOTESBODY 12 // 14 Notes body +#define EPP_PLACEHOLDER_CENTEREDTITLE 15 // 15 Centered title +#define EPP_PLACEHOLDER_SUBTITLE 16 // 16 Subtitle +#define EPP_PLACEHOLDER_VERTICALTEXTTITLE 17 // 17 Vertical text title +#define EPP_PLACEHOLDER_VERTICALTEXTBODY 18 // 18 Vertical text body +#define EPP_PLACEHOLDER_NOTESSLIDEIMAGE 11 // 19 Notes slide image +#define EPP_PLACEHOLDER_OBJECT 19 // 20 Object (no matter the size) +#define EPP_PLACEHOLDER_GRAPH 20 // 21 Graph +#define EPP_PLACEHOLDER_TABLE 21 // 22 Table +#define EPP_PLACEHOLDER_CLIPART 22 // 23 Clip Art +#define EPP_PLACEHOLDER_ORGANISZATIONCHART 23 // 24 Organization Chart +#define EPP_PLACEHOLDER_MEDIACLIP 24 // 25 Media Clip + +#define EPP_TEXTTYPE_Title 0 +#define EPP_TEXTTYPE_Body 1 +#define EPP_TEXTTYPE_Notes 2 +#define EPP_TEXTTYPE_notUsed 3 +#define EPP_TEXTTYPE_Other 4 // ( Text in a shape ) +#define EPP_TEXTTYPE_CenterBody 5 // ( subtitle in title slide ) +#define EPP_TEXTTYPE_CenterTitle 6 // ( title in title slide ) +#define EPP_TEXTTYPE_HalfBody 7 // ( body in two-column slide ) +#define EPP_TEXTTYPE_QuarterBody 8 // ( body in four-body slide ) + +#define EPP_SLIDESIZE_TYPEONSCREEN 0 +#define EPP_SLIDESIZE_TYPELETTERSIZERPAPER 1 +#define EPP_SLIDESIZE_TYPEA4PAPER 2 +#define EPP_SLIDESIZE_TYPE35MM 3 +#define EPP_SLIDESIZE_TYPEOVERHEAD 4 +#define EPP_SLIDESIZE_TYPEBANNER 5 +#define EPP_SLIDESIZE_TYPECUSTOM 6 + +#endif diff --git a/sd/source/filter/eppt/epptso.cxx b/sd/source/filter/eppt/epptso.cxx new file mode 100644 index 000000000000..f07245d1ff31 --- /dev/null +++ b/sd/source/filter/eppt/epptso.cxx @@ -0,0 +1,5844 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" +#include <osl/endian.h> +#include <eppt.hxx> +#include "epptdef.hxx" +#ifndef _PptEscherEx_HXX +#include "escherex.hxx" +#endif +#include <tools/poly.hxx> +#include <vcl/bmpacc.hxx> +#include <vcl/gradient.hxx> +#include <vcl/gfxlink.hxx> +#include <tools/stream.hxx> +#include <sot/storage.hxx> +#include <vcl/outdev.hxx> +#include <vcl/virdev.hxx> +#include <vcl/gradient.hxx> +#include <sfx2/app.hxx> +#include <svl/languageoptions.hxx> +//#ifndef _SVX_XIT_HXX +//#include <svx/xit.hxx> +//#endif +#include <editeng/svxenum.hxx> +#include <svx/unoapi.hxx> +#include <svx/svdoashp.hxx> +#include <com/sun/star/style/VerticalAlignment.hpp> +#include <com/sun/star/container/XIndexReplace.hpp> +#include <com/sun/star/presentation/XPresentationPage.hpp> +#include <com/sun/star/awt/XFont.hpp> +#ifndef _COM_SUN_STAR_AWT_XFONTWEIGHT_HPP_ +#include <com/sun/star/awt/FontWeight.hpp> +#endif +#ifndef _COM_SUN_STAR_AWT_XFONTUNDERLINE_HPP_ +#include <com/sun/star/awt/FontUnderline.hpp> +#endif +#include <com/sun/star/style/ParagraphAdjust.hpp> +#include <com/sun/star/style/LineSpacing.hpp> +#include <com/sun/star/style/LineSpacingMode.hpp> +#ifndef _COM_SUN_STAR_STYLE_XSTYLEFAMILIESSUPPLIER_PP_ +#include <com/sun/star/style/XStyleFamiliesSupplier.hpp> +#endif +#include <com/sun/star/style/XStyle.hpp> +#include <com/sun/star/drawing/PointSequence.hpp> +#include <com/sun/star/drawing/FlagSequence.hpp> +#include <com/sun/star/drawing/PolygonFlags.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/drawing/XControlShape.hpp> +#include <comphelper/processfactory.hxx> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/i18n/XBreakIterator.hpp> +#include <com/sun/star/i18n/XScriptTypeDetector.hpp> +#include <com/sun/star/i18n/ScriptType.hpp> +#include <com/sun/star/i18n/ScriptDirection.hpp> +#include <com/sun/star/embed/Aspects.hpp> +#include <vcl/cvtgrf.hxx> +#include <tools/urlobj.hxx> +#ifndef _CPPUHELPER_EXTRACT_HXX_ +#include <comphelper/extract.hxx> +#endif +#ifndef _CPPUHELPER_PROPTYPEHLP_HXX_ +#include <cppuhelper/proptypehlp.hxx> +#endif +#ifndef _UCBHELPER_CONTENT_HXX_ +#include <ucbhelper/content.hxx> +#endif +#ifndef _UCBHELPER_CONTENTBROKER_HXX_ +#include <ucbhelper/contentbroker.hxx> +#endif +#ifndef _TOOLKIT_UNOHLP_HXX +#include <toolkit/unohlp.hxx> +#endif +#include <rtl/crc.h> +#include <sot/clsids.hxx> +#include <unotools/ucbstreamhelper.hxx> +#include <com/sun/star/text/FontRelief.hpp> +#include <editeng/frmdiritem.hxx> +/* +#include <editeng/outliner.hxx> +#include <editeng/outlobj.hxx> +#include <svx/svdmodel.hxx> +*/ +#include <svtools/fltcall.hxx> +#include <com/sun/star/table/XTable.hpp> +#include <com/sun/star/table/XMergeableCell.hpp> +#include <com/sun/star/table/BorderLine.hpp> +#include <set> + +//#include <svx/xbtmpit.hxx> + +#include "i18npool/mslangid.hxx" + +#include <vos/xception.hxx> +#ifndef _VOS_NO_NAMESPACE +using namespace vos; +#endif + +using namespace ::com::sun::star; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +#define ANSI_CHARSET 0 +#define DEFAULT_CHARSET 1 +#define SYMBOL_CHARSET 2 +#define SHIFTJIS_CHARSET 128 +#define HANGEUL_CHARSET 129 +#define CHINESEBIG5_CHARSET 136 +#define OEM_CHARSET 255 + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/* Font Families */ +#define FF_DONTCARE 0x00 +#define FF_ROMAN 0x10 +#define FF_SWISS 0x20 +#define FF_MODERN 0x30 +#define FF_SCRIPT 0x40 +#define FF_DECORATIVE 0x50 + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +#define DEFAULT_PITCH 0x00 +#define FIXED_PITCH 0x01 +#define VARIABLE_PITCH 0x02 + +// --------------------------------------------------------------------------------------------- + +com::sun::star::uno::Reference< com::sun::star::i18n::XBreakIterator > xPPTBreakIter; +com::sun::star::uno::Reference< com::sun::star::i18n::XScriptTypeDetector > xScriptTypeDetector; + +PPTExBulletProvider::PPTExBulletProvider() +{ + pGraphicProv = new EscherGraphicProvider( _E_GRAPH_PROV_USE_INSTANCES | _E_GRAPH_PROV_DO_NOT_ROTATE_METAFILES ); +} + +PPTExBulletProvider::~PPTExBulletProvider() +{ + delete pGraphicProv; +} + +sal_uInt16 PPTExBulletProvider::GetId( const ByteString& rUniqueId, Size& rGraphicSize ) +{ + sal_uInt16 nRetValue = 0xffff; + sal_uInt32 nId = 0; + + if ( rUniqueId.Len() ) + { + Rectangle aRect; + GraphicObject aGraphicObject( rUniqueId ); + Graphic aMappedGraphic, aGraphic( aGraphicObject.GetGraphic() ); + Size aPrefSize( aGraphic.GetPrefSize() ); + BitmapEx aBmpEx( aGraphic.GetBitmapEx() ); + + if ( rGraphicSize.Width() && rGraphicSize.Height() ) + { + double fQ1 = ( (double)aPrefSize.Width() / (double)aPrefSize.Height() ); + double fQ2 = ( (double)rGraphicSize.Width() / (double)rGraphicSize.Height() ); + double fXScale = 1; + double fYScale = 1; + + if ( fQ1 > fQ2 ) + fYScale = fQ1 / fQ2; + else if ( fQ1 < fQ2 ) + fXScale = fQ2 / fQ1; + + if ( ( fXScale != 1.0 ) || ( fYScale != 1.0 ) ) + { + aBmpEx.Scale( fXScale, fYScale ); + Size aNewSize( (sal_Int32)((double)rGraphicSize.Width() / fXScale + 0.5 ), + (sal_Int32)((double)rGraphicSize.Height() / fYScale + 0.5 ) ); + + rGraphicSize = aNewSize; + + aMappedGraphic = Graphic( aBmpEx ); + aGraphicObject = GraphicObject( aMappedGraphic ); + } + } + + nId = pGraphicProv->GetBlibID( aBuExPictureStream, aGraphicObject.GetUniqueID(), aRect, NULL, NULL ); + + if ( nId && ( nId < 0x10000 ) ) + nRetValue = (sal_uInt16)nId - 1; + } + return nRetValue; +} + +// --------------------------------------------------------------------------------------------- + +GroupTable::GroupTable() : + mnCurrentGroupEntry ( 0 ), + mnMaxGroupEntry ( 0 ), + mnGroupsClosed ( 0 ), + mpGroupEntry ( NULL ) +{ + ImplResizeGroupTable( 32 ); +} + +// --------------------------------------------------------------------------------------------- + +GroupTable::~GroupTable() +{ + for ( sal_uInt32 i = 0; i < mnCurrentGroupEntry; delete mpGroupEntry[ i++ ] ) ; + delete[] mpGroupEntry; +} + +// --------------------------------------------------------------------------------------------- + +void GroupTable::ImplResizeGroupTable( sal_uInt32 nEntrys ) +{ + if ( nEntrys > mnMaxGroupEntry ) + { + mnMaxGroupEntry = nEntrys; + GroupEntry** pTemp = new GroupEntry*[ nEntrys ]; + for ( sal_uInt32 i = 0; i < mnCurrentGroupEntry; i++ ) + pTemp[ i ] = mpGroupEntry[ i ]; + if ( mpGroupEntry ) + delete[] mpGroupEntry; + mpGroupEntry = pTemp; + } +} + +// --------------------------------------------------------------------------------------------- + +sal_Bool GroupTable::EnterGroup( ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess >& rXIndexAccessRef ) +{ + sal_Bool bRet = sal_False; + if ( rXIndexAccessRef.is() ) + { + GroupEntry* pNewGroup = new GroupEntry( rXIndexAccessRef ); + if ( pNewGroup->mnCount ) + { + if ( mnMaxGroupEntry == mnCurrentGroupEntry ) + ImplResizeGroupTable( mnMaxGroupEntry + 8 ); + mpGroupEntry[ mnCurrentGroupEntry++ ] = pNewGroup; + bRet = sal_True; + } + else + delete pNewGroup; + } + return bRet; +} + +// --------------------------------------------------------------------------------------------- + +sal_uInt32 GroupTable::GetGroupsClosed() +{ + sal_uInt32 nRet = mnGroupsClosed; + mnGroupsClosed = 0; + return nRet; +} + +// --------------------------------------------------------------------------------------------- + +void GroupTable::ClearGroupTable() +{ + for ( sal_uInt32 i = 0; i < mnCurrentGroupEntry; i++, delete mpGroupEntry[ i ] ) ; + mnCurrentGroupEntry = 0; +} + +// --------------------------------------------------------------------------------------------- + +void GroupTable::ResetGroupTable( sal_uInt32 nCount ) +{ + ClearGroupTable(); + mpGroupEntry[ mnCurrentGroupEntry++ ] = new GroupEntry( nCount ); +} + +// --------------------------------------------------------------------------------------------- + +sal_Bool GroupTable::GetNextGroupEntry() +{ + while ( mnCurrentGroupEntry ) + { + mnIndex = mpGroupEntry[ mnCurrentGroupEntry - 1 ]->mnCurrentPos++; + + if ( mpGroupEntry[ mnCurrentGroupEntry - 1 ]->mnCount > mnIndex ) + return TRUE; + + delete ( mpGroupEntry[ --mnCurrentGroupEntry ] ); + + if ( mnCurrentGroupEntry ) + mnGroupsClosed++; + } + return FALSE; +} + +// --------------------------------------------------------------------------------------------- + +void GroupTable::SkipCurrentGroup() +{ + if ( mnCurrentGroupEntry ) + delete ( mpGroupEntry[ --mnCurrentGroupEntry ] ); +} + +// --------------------------------------------------------------------------------------------- + +FontCollectionEntry::~FontCollectionEntry() +{ +} + +// --------------------------------------------------------------------------------------------- + +void FontCollectionEntry::ImplInit( const String& rName ) +{ + String aSubstName( GetSubsFontName( rName, SUBSFONT_ONLYONE | SUBSFONT_MS ) ); + if ( aSubstName.Len() ) + { + Name = aSubstName; + bIsConverted = sal_True; + } + else + { + Name = rName; + bIsConverted = sal_False; + } +} + +FontCollection::~FontCollection() +{ + for( void* pStr = List::First(); pStr; pStr = List::Next() ) + delete (FontCollectionEntry*)pStr; + delete pVDev; + xPPTBreakIter = NULL; + xScriptTypeDetector = NULL; +} + +FontCollection::FontCollection() : + pVDev ( NULL ) +{ + com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > + xMSF = ::comphelper::getProcessServiceFactory(); + com::sun::star::uno::Reference< com::sun::star::uno::XInterface > + xInterface = xMSF->createInstance( rtl::OUString::createFromAscii( "com.sun.star.i18n.BreakIterator" ) ); + if ( xInterface.is() ) + xPPTBreakIter = com::sun::star::uno::Reference< com::sun::star::i18n::XBreakIterator > + ( xInterface, com::sun::star::uno::UNO_QUERY ); + + xInterface = xMSF->createInstance( rtl::OUString::createFromAscii( "com.sun.star.i18n.ScriptTypeDetector" ) ); + if ( xInterface.is() ) + xScriptTypeDetector = com::sun::star::uno::Reference< com::sun::star::i18n::XScriptTypeDetector > + ( xInterface, com::sun::star::uno::UNO_QUERY ); +} + +short FontCollection::GetScriptDirection( const String& rString ) const +{ + short nRet = com::sun::star::i18n::ScriptDirection::NEUTRAL; + if ( xScriptTypeDetector.is() ) + { + const rtl::OUString sT( rString ); + nRet = xScriptTypeDetector->getScriptDirection( sT, 0, com::sun::star::i18n::ScriptDirection::NEUTRAL ); + } + return nRet; +} + +sal_uInt32 FontCollection::GetId( FontCollectionEntry& rEntry ) +{ + if( rEntry.Name.Len() ) + { + const sal_uInt32 nFonts = GetCount(); + + for( sal_uInt32 i = 0; i < nFonts; i++ ) + { + const FontCollectionEntry* pEntry = GetById( i ); + if( pEntry->Name == rEntry.Name ) + return i; + } + Font aFont; + aFont.SetCharSet( rEntry.CharSet ); + aFont.SetName( rEntry.Original ); +// aFont.SetFamily( rEntry.Family ); +// aFont.SetPitch( rEntry.Pitch ); + aFont.SetHeight( 100 ); + + if ( !pVDev ) + pVDev = new VirtualDevice; + + pVDev->SetFont( aFont ); + FontMetric aMetric( pVDev->GetFontMetric() ); + + sal_uInt16 nTxtHeight = (sal_uInt16)aMetric.GetAscent() + (sal_uInt16)aMetric.GetDescent(); + + if ( nTxtHeight ) + { + double fScaling = (double)nTxtHeight / 120.0; + if ( ( fScaling > 0.50 ) && ( fScaling < 1.5 ) ) + rEntry.Scaling = fScaling; + } + + List::Insert( new FontCollectionEntry( rEntry ), LIST_APPEND ); + return nFonts; + } + return 0; +} + +const FontCollectionEntry* FontCollection::GetById( sal_uInt32 nId ) +{ + return (FontCollectionEntry*)List::GetObject( nId ); +} + +// --------------------------------------------------------------------------------------------- + +sal_uInt32 PPTWriter::ImplVBAInfoContainer( SvStream* pStrm ) +{ + sal_uInt32 nSize = 28; + if ( pStrm ) + { + *pStrm << (sal_uInt32)( 0x1f | ( EPP_VBAInfo << 16 ) ) + << (sal_uInt32)( nSize - 8 ) + << (sal_uInt32)( 2 | ( EPP_VBAInfoAtom << 16 ) ) + << (sal_uInt32)12; + mpPptEscherEx->InsertPersistOffset( EPP_Persist_VBAInfoAtom, pStrm->Tell() ); + *pStrm << (sal_uInt32)0 + << (sal_uInt32)0 + << (sal_uInt32)1; + } + return nSize; +} + +// --------------------------------------------------------------------------------------------- + +sal_uInt32 PPTWriter::ImplSlideViewInfoContainer( sal_uInt32 nInstance, SvStream* pStrm ) +{ + sal_uInt32 nSize = 111; + if ( pStrm ) + { + sal_uInt8 bShowGuides = 0; + sal_uInt8 bSnapToGrid = 1; + sal_uInt8 bSnapToShape = 0; + + sal_Int32 nScaling = 85; + sal_Int32 nMasterCoordinate = 0xdda; + sal_Int32 nXOrigin = -780; + sal_Int32 nYOrigin = -84; + + sal_Int32 nPosition1 = 0x870; + sal_Int32 nPosition2 = 0xb40; + + if ( nInstance ) + { + bShowGuides = 1; + nScaling = 0x3b; + nMasterCoordinate = 0xf0c; + nXOrigin = -1752; + nYOrigin = -72; + nPosition1 = 0xb40; + nPosition2 = 0x870; + } + *pStrm << (sal_uInt32)( 0xf | ( EPP_SlideViewInfo << 16 ) | ( nInstance << 4 ) ) + << (sal_uInt32)( nSize - 8 ) + << (sal_uInt32)( EPP_SlideViewInfoAtom << 16 ) << (sal_uInt32)3 + << bShowGuides << bSnapToGrid << bSnapToShape + << (sal_uInt32)( EPP_ViewInfoAtom << 16 ) << (sal_uInt32)52 + << nScaling << (sal_Int32)100 << nScaling << (sal_Int32)100 // scaling atom - Keeps the current scale + << nScaling << (sal_Int32)100 << nScaling << (sal_Int32)100 // scaling atom - Keeps the previous scale + << (sal_Int32)0x17ac << nMasterCoordinate// Origin - Keeps the origin in master coordinates + << nXOrigin << nYOrigin // Origin + << (sal_uInt8)1 // Bool1 varScale - Set if zoom to fit is set + << (sal_uInt8)0 // bool1 draftMode - Not used + << (sal_uInt16)0 // padword + << (sal_uInt32)( ( 7 << 4 ) | ( EPP_GuideAtom << 16 ) ) << (sal_uInt32)8 + << (sal_uInt32)0 // Type of the guide. If the guide is horizontal this value is zero. If it's vertical, it's one. + << nPosition1 // Position of the guide in master coordinates. X coordinate if it's vertical, and Y coordinate if it's horizontal. + << (sal_uInt32)( ( 7 << 4 ) | ( EPP_GuideAtom << 16 ) ) << (sal_uInt32)8 + << (sal_Int32)1 // Type of the guide. If the guide is horizontal this value is zero. If it's vertical, it's one. + << nPosition2; // Position of the guide in master coordinates. X coordinate if it's vertical, and Y coordinate if it's horizontal. + } + return nSize; +} + +// --------------------------------------------------------------------------------------------- + +sal_uInt32 PPTWriter::ImplOutlineViewInfoContainer( SvStream* pStrm ) +{ + sal_uInt32 nSize = 68; + if ( pStrm ) + { + *pStrm << (sal_uInt32)( 0xf | ( EPP_OutlineViewInfo << 16 ) ) << (sal_uInt32)( nSize - 8 ) + << (sal_uInt32)( EPP_ViewInfoAtom << 16 ) << (sal_uInt32)52 + << (sal_Int32)170 << (sal_Int32)200 << (sal_Int32)170 << (sal_Int32)200 // scaling atom - Keeps the current scale + << (sal_Int32)170 << (sal_Int32)200 << (sal_Int32)170 << (sal_Int32)200 // scaling atom - Keeps the previous scale + << (sal_Int32)0x17ac << 0xdda // Origin - Keeps the origin in master coordinates + << (sal_Int32)-780 << (sal_Int32)-84 // Origin + << (sal_uInt8)1 // bool1 varScale - Set if zoom to fit is set + << (sal_uInt8)0 // bool1 draftMode - Not used + << (sal_uInt16)0; // padword + } + return nSize; +} + +// --------------------------------------------------------------------------------------------- + +sal_uInt32 PPTWriter::ImplProgBinaryTag( SvStream* pStrm ) +{ + sal_uInt32 nPictureStreamSize, nOutlineStreamSize, nSize = 8; + + nPictureStreamSize = aBuExPictureStream.Tell(); + if ( nPictureStreamSize ) + nSize += nPictureStreamSize + 8; + + nOutlineStreamSize = aBuExOutlineStream.Tell(); + if ( nOutlineStreamSize ) + nSize += nOutlineStreamSize + 8; + + if ( pStrm ) + { + *pStrm << (sal_uInt32)( EPP_BinaryTagData << 16 ) << (sal_uInt32)( nSize - 8 ); + if ( nPictureStreamSize ) + { + *pStrm << (sal_uInt32)( 0xf | ( EPP_PST_ExtendedBuGraContainer << 16 ) ) << nPictureStreamSize; + pStrm->Write( aBuExPictureStream.GetData(), nPictureStreamSize ); + } + if ( nOutlineStreamSize ) + { + *pStrm << (sal_uInt32)( 0xf | ( EPP_PST_ExtendedPresRuleContainer << 16 ) ) << nOutlineStreamSize; + pStrm->Write( aBuExOutlineStream.GetData(), nOutlineStreamSize ); + } + } + return nSize; +} + +// --------------------------------------------------------------------------------------------- + +sal_uInt32 PPTWriter::ImplProgBinaryTagContainer( SvStream* pStrm, SvMemoryStream* pBinTagStrm ) +{ + sal_uInt32 nSize = 8 + 8 + 14; + if ( pStrm ) + { + *pStrm << (sal_uInt32)( 0xf | ( EPP_ProgBinaryTag << 16 ) ) << (sal_uInt32)0 + << (sal_uInt32)( EPP_CString << 16 ) << (sal_uInt32)14 + << (sal_uInt32)0x5f005f << (sal_uInt32)0x50005f + << (sal_uInt32)0x540050 << (sal_uInt16)0x39; + } + if ( pBinTagStrm ) + { + sal_uInt32 nLen = pBinTagStrm->Tell(); + nSize += nLen + 8; + *pStrm << (sal_uInt32)( EPP_BinaryTagData << 16 ) << nLen; + pStrm->Write( pBinTagStrm->GetData(), nLen ); + } + else + nSize += ImplProgBinaryTag( pStrm ); + + if ( pStrm ) + { + pStrm->SeekRel( - ( (sal_Int32)nSize - 4 ) ); + *pStrm << (sal_uInt32)( nSize - 8 ); + pStrm->SeekRel( nSize - 8 ); + } + return nSize; +} + +// --------------------------------------------------------------------------------------------- + +sal_uInt32 PPTWriter::ImplProgTagContainer( SvStream* pStrm, SvMemoryStream* pBinTagStrm ) +{ + sal_uInt32 nSize = 0; + if ( aBuExPictureStream.Tell() || aBuExOutlineStream.Tell() || pBinTagStrm ) + { + nSize = 8; + if ( pStrm ) + { + *pStrm << (sal_uInt32)( 0xf | ( EPP_ProgTags << 16 ) ) << (sal_uInt32)0; + } + nSize += ImplProgBinaryTagContainer( pStrm, pBinTagStrm ); + if ( pStrm ) + { + pStrm->SeekRel( - ( (sal_Int32)nSize - 4 ) ); + *pStrm << (sal_uInt32)( nSize - 8 ); + pStrm->SeekRel( nSize - 8 ); + } + } + return nSize; +} + +// --------------------------------------------------------------------------------------------- + +sal_uInt32 PPTWriter::ImplDocumentListContainer( SvStream* pStrm ) +{ + sal_uInt32 nSize = 8; + if ( pStrm ) + { + *pStrm << (sal_uInt32)( ( EPP_List << 16 ) | 0xf ) << (sal_uInt32)0; + } + + nSize += ImplVBAInfoContainer( pStrm ); + nSize += ImplSlideViewInfoContainer( 0, pStrm ); + nSize += ImplOutlineViewInfoContainer( pStrm ); + nSize += ImplSlideViewInfoContainer( 1, pStrm ); + nSize += ImplProgTagContainer( pStrm ); + + if ( pStrm ) + { + pStrm->SeekRel( - ( (sal_Int32)nSize - 4 ) ); + *pStrm << (sal_uInt32)( nSize - 8 ); + pStrm->SeekRel( nSize - 8 ); + } + return nSize; +} + +// --------------------------------------------------------------------------------------------- + +sal_uInt32 PPTWriter::ImplMasterSlideListContainer( SvStream* pStrm ) +{ + sal_uInt32 i, nSize = 28 * mnMasterPages + 8; + if ( pStrm ) + { + *pStrm << (sal_uInt32)( 0x1f | ( EPP_SlideListWithText << 16 ) ) << (sal_uInt32)( nSize - 8 ); + + for ( i = 0; i < mnMasterPages; i++ ) + { + *pStrm << (sal_uInt32)( EPP_SlidePersistAtom << 16 ) << (sal_uInt32)20; + mpPptEscherEx->InsertPersistOffset( EPP_MAINMASTER_PERSIST_KEY | i, pStrm->Tell() ); + *pStrm << (sal_uInt32)0 // psrReference - logical reference to the slide persist object ( EPP_MAINMASTER_PERSIST_KEY ) + << (sal_uInt32)0 // flags - only bit 3 used, if set then slide contains shapes other than placeholders + << (sal_Int32)0 // numberTexts - number of placeholder texts stored with the persist object. Allows to display outline view without loading the slide persist objects + << (sal_Int32)( 0x80000000 | i ) // slideId - Unique slide identifier, used for OLE link monikers for example + << (sal_uInt32)0; // reserved, usualy 0 + } + } + return nSize; +} + +// --------------------------------------------------------------------------------------------- + +sal_uInt32 PPTWriter::ImplInsertBookmarkURL( const String& rBookmarkURL, const sal_uInt32 nType, + const String& rStringVer0, const String& rStringVer1, const String& rStringVer2, const String& rStringVer3 ) +{ + sal_uInt32 nHyperId = ++mnExEmbed; + maHyperlink.Insert( new EPPTHyperlink( rBookmarkURL, nType ), LIST_APPEND ); + + *mpExEmbed << (sal_uInt16)0xf + << (sal_uInt16)EPP_ExHyperlink + << (sal_uInt32)0; + sal_uInt32 nHyperSize, nHyperStart = mpExEmbed->Tell(); + *mpExEmbed << (sal_uInt16)0 + << (sal_uInt16)EPP_ExHyperlinkAtom + << (sal_uInt32)4 + << nHyperId; + + sal_uInt16 i, nStringLen; + nStringLen = rStringVer0.Len(); + if ( nStringLen ) + { + *mpExEmbed << (sal_uInt32)( EPP_CString << 16 ) << (sal_uInt32)( nStringLen * 2 ); + for ( i = 0; i < nStringLen; i++ ) + { + *mpExEmbed << rStringVer0.GetChar( i ); + } + } + nStringLen = rStringVer1.Len(); + if ( nStringLen ) + { + *mpExEmbed << (sal_uInt32)( ( EPP_CString << 16 ) | 0x10 ) << (sal_uInt32)( nStringLen * 2 ); + for ( i = 0; i < nStringLen; i++ ) + { + *mpExEmbed << rStringVer1.GetChar( i ); + } + } + nStringLen = rStringVer2.Len(); + if ( nStringLen ) + { + *mpExEmbed << (sal_uInt32)( ( EPP_CString << 16 ) | 0x20 ) << (sal_uInt32)( nStringLen * 2 ); + for ( i = 0; i < nStringLen; i++ ) + { + *mpExEmbed << rStringVer2.GetChar( i ); + } + } + nStringLen = rStringVer3.Len(); + if ( nStringLen ) + { + *mpExEmbed << (sal_uInt32)( ( EPP_CString << 16 ) | 0x30 ) << (sal_uInt32)( nStringLen * 2 ); + for ( i = 0; i < nStringLen; i++ ) + { + *mpExEmbed << rStringVer3.GetChar( i ); + } + } + nHyperSize = mpExEmbed->Tell() - nHyperStart; + mpExEmbed->SeekRel( - ( (sal_Int32)nHyperSize + 4 ) ); + *mpExEmbed << nHyperSize; + mpExEmbed->SeekRel( nHyperSize ); + return nHyperId; +} + +// --------------------------------------------------------------------------------------------- + +sal_Bool PPTWriter::ImplCloseDocument() +{ + sal_uInt32 nOfs = mpPptEscherEx->PtGetOffsetByID( EPP_Persist_Document ); + if ( nOfs ) + { + mpPptEscherEx->PtReplaceOrInsert( EPP_Persist_CurrentPos, mpStrm->Tell() ); + mpStrm->Seek( nOfs ); + + // creating the TxMasterStyleAtom + SvMemoryStream aTxMasterStyleAtomStrm( 0x200, 0x200 ); + { + EscherExAtom aTxMasterStyleAtom( aTxMasterStyleAtomStrm, EPP_TxMasterStyleAtom, EPP_TEXTTYPE_Other ); + aTxMasterStyleAtomStrm << (sal_uInt16)5; // paragraph count + sal_uInt16 nLev; + sal_Bool bFirst = sal_True; + for ( nLev = 0; nLev < 5; nLev++ ) + { + mpStyleSheet->mpParaSheet[ EPP_TEXTTYPE_Other ]->Write( aTxMasterStyleAtomStrm, mpPptEscherEx, nLev, bFirst, sal_False, mXPagePropSet ); + mpStyleSheet->mpCharSheet[ EPP_TEXTTYPE_Other ]->Write( aTxMasterStyleAtomStrm, mpPptEscherEx, nLev, bFirst, sal_False, mXPagePropSet ); + bFirst = sal_False; + } + } + + mpExEmbed->Seek( STREAM_SEEK_TO_END ); + sal_uInt32 nExEmbedSize = mpExEmbed->Tell(); + + // nEnviroment : Gesamtgroesse des Environment Containers + sal_uInt32 nEnvironment = maFontCollection.GetCount() * 76 // 68 bytes pro Fontenityatom und je 8 Bytes fuer die Header + + 8 // 1 FontCollection Container + + 20 // SrKinsoku Container + + 18 // 1 TxSiStyleAtom + + aTxMasterStyleAtomStrm.Tell() // 1 TxMasterStyleAtom; + + mpStyleSheet->SizeOfTxCFStyleAtom(); + + sal_uInt32 nBytesToInsert = nEnvironment + 8; + + if ( nExEmbedSize ) + nBytesToInsert += nExEmbedSize + 8 + 12; + + nBytesToInsert += maSoundCollection.GetSize(); + nBytesToInsert += mpPptEscherEx->DrawingGroupContainerSize(); + nBytesToInsert += ImplMasterSlideListContainer( NULL ); + nBytesToInsert += ImplDocumentListContainer( NULL ); + + // nBytes im Stream einfuegen, und abhaengige Container anpassen + mpPptEscherEx->InsertAtCurrentPos( nBytesToInsert, false ); + + // CREATE HYPERLINK CONTAINER + if ( nExEmbedSize ) + { + *mpStrm << (sal_uInt16)0xf + << (sal_uInt16)EPP_ExObjList + << (sal_uInt32)( nExEmbedSize + 12 ) + << (sal_uInt16)0 + << (sal_uInt16)EPP_ExObjListAtom + << (sal_uInt32)4 + << (sal_uInt32)mnExEmbed; + mpPptEscherEx->InsertPersistOffset( EPP_Persist_ExObj, mpStrm->Tell() ); + mpStrm->Write( mpExEmbed->GetData(), nExEmbedSize ); + } + + // CREATE ENVIRONMENT + *mpStrm << (sal_uInt16)0xf << (sal_uInt16)EPP_Environment << (sal_uInt32)nEnvironment; + + // Open Container ( EPP_SrKinsoku ) + *mpStrm << (sal_uInt16)0x2f << (sal_uInt16)EPP_SrKinsoku << (sal_uInt32)12; + mpPptEscherEx->AddAtom( 4, EPP_SrKinsokuAtom, 0, 3 ); + *mpStrm << (sal_Int32)0; // SrKinsoku Level 0 + + // Open Container ( EPP_FontCollection ) + *mpStrm << (sal_uInt16)0xf << (sal_uInt16)EPP_FontCollection << (sal_uInt32)maFontCollection.GetCount() * 76; + + for ( sal_uInt32 i = 0; i < maFontCollection.GetCount(); i++ ) + { + mpPptEscherEx->AddAtom( 68, EPP_FontEnityAtom, 0, i ); + const FontCollectionEntry* pDesc = maFontCollection.GetById( i ); + sal_uInt32 nFontLen = pDesc->Name.Len(); + if ( nFontLen > 31 ) + nFontLen = 31; + for ( sal_uInt16 n = 0; n < 32; n++ ) + { + sal_Unicode nUniCode = 0; + if ( n < nFontLen ) + nUniCode = pDesc->Name.GetChar( n ); + *mpStrm << nUniCode; + } + sal_uInt8 lfCharSet = ANSI_CHARSET; + sal_uInt8 lfClipPrecision = 0; + sal_uInt8 lfQuality = 6; + sal_uInt8 lfPitchAndFamily = 0; + + if ( pDesc->CharSet == RTL_TEXTENCODING_SYMBOL ) + lfCharSet = SYMBOL_CHARSET; + + switch( pDesc->Family ) + { + case ::com::sun::star::awt::FontFamily::ROMAN : + lfPitchAndFamily |= FF_ROMAN; + break; + + case ::com::sun::star::awt::FontFamily::SWISS : + lfPitchAndFamily |= FF_SWISS; + break; + + case ::com::sun::star::awt::FontFamily::MODERN : + lfPitchAndFamily |= FF_MODERN; + break; + + case ::com::sun::star::awt::FontFamily::SCRIPT: + lfPitchAndFamily |= FF_SCRIPT; + break; + + case ::com::sun::star::awt::FontFamily::DECORATIVE: + lfPitchAndFamily |= FF_DECORATIVE; + break; + + default: + lfPitchAndFamily |= FAMILY_DONTKNOW; + break; + } + switch( pDesc->Pitch ) + { + case ::com::sun::star::awt::FontPitch::FIXED: + lfPitchAndFamily |= FIXED_PITCH; + break; + + default: + lfPitchAndFamily |= DEFAULT_PITCH; + break; + } + *mpStrm << lfCharSet + << lfClipPrecision + << lfQuality + << lfPitchAndFamily; + } + mpStyleSheet->WriteTxCFStyleAtom( *mpStrm ); // create style that is used for new standard objects + mpPptEscherEx->AddAtom( 10, EPP_TxSIStyleAtom ); + *mpStrm << (sal_uInt32)7 // ? + << (sal_Int16)2 // ? + << (sal_uInt8)9 // ? + << (sal_uInt8)8 // ? + << (sal_Int16)0; // ? + + mpStrm->Write( aTxMasterStyleAtomStrm.GetData(), aTxMasterStyleAtomStrm.Tell() ); + maSoundCollection.Write( *mpStrm ); + mpPptEscherEx->WriteDrawingGroupContainer( *mpStrm ); + ImplMasterSlideListContainer( mpStrm ); + ImplDocumentListContainer( mpStrm ); + + sal_uInt32 nOldPos = mpPptEscherEx->PtGetOffsetByID( EPP_Persist_CurrentPos ); + if ( nOldPos ) + { + mpStrm->Seek( nOldPos ); + return TRUE; + } + } + return FALSE; +} + +// --------------------------------------------------------------------------------------------- + +sal_Bool PropValue::GetPropertyValue( + ::com::sun::star::uno::Any& rAny, + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet, + const String& rString, + sal_Bool bTestPropertyAvailability ) +{ + sal_Bool bRetValue = sal_True; + if ( bTestPropertyAvailability ) + { + bRetValue = sal_False; + try + { + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > + aXPropSetInfo( rXPropSet->getPropertySetInfo() ); + if ( aXPropSetInfo.is() ) + bRetValue = aXPropSetInfo->hasPropertyByName( rString ); + } + catch( ::com::sun::star::uno::Exception& ) + { + bRetValue = sal_False; + } + } + if ( bRetValue ) + { + try + { + rAny = rXPropSet->getPropertyValue( rString ); + if ( !rAny.hasValue() ) + bRetValue = sal_False; + } + catch( ::com::sun::star::uno::Exception& ) + { + bRetValue = sal_False; + } + } + return bRetValue; +} + +// --------------------------------------------------------------------------------------------- + +::com::sun::star::beans::PropertyState PropValue::GetPropertyState( + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet, + const String& rPropertyName ) +{ + ::com::sun::star::beans::PropertyState eRetValue = ::com::sun::star::beans::PropertyState_AMBIGUOUS_VALUE; + try + { + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyState > aXPropState + ( rXPropSet, ::com::sun::star::uno::UNO_QUERY ); + if ( aXPropState.is() ) + eRetValue = aXPropState->getPropertyState( rPropertyName ); + } + catch( ::com::sun::star::uno::Exception& ) + { + //... + } + return eRetValue; +} + +// --------------------------------------------------------------------------------------------- + +sal_Bool PropValue::ImplGetPropertyValue( const String& rString ) +{ + return GetPropertyValue( mAny, mXPropSet, rString ); +} + +// --------------------------------------------------------------------------------------------- + +sal_Bool PropValue::ImplGetPropertyValue( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & aXPropSet, const String& rString ) +{ + return GetPropertyValue( mAny, aXPropSet, rString ); +} + +// --------------------------------------------------------------------------------------------- + +sal_Bool PropStateValue::ImplGetPropertyValue( const String& rString, sal_Bool bGetPropertyState ) +{ + ePropState = ::com::sun::star::beans::PropertyState_AMBIGUOUS_VALUE; + sal_Bool bRetValue = TRUE; +#ifdef UNX + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > + aXPropSetInfo( mXPropSet->getPropertySetInfo() ); + if ( !aXPropSetInfo.is() ) + return sal_False; +#endif + try + { + mAny = mXPropSet->getPropertyValue( rString ); + if ( !mAny.hasValue() ) + bRetValue = FALSE; + else if ( bGetPropertyState ) + ePropState = mXPropState->getPropertyState( rString ); + else + ePropState = ::com::sun::star::beans::PropertyState_DIRECT_VALUE; + } + catch( ::com::sun::star::uno::Exception& ) + { + bRetValue = FALSE; + } + return bRetValue; +} + +// --------------------------------------------------------------------------------------------- + +sal_Bool PPTWriter::ImplInitSOIface() +{ + while( TRUE ) + { + mXDrawPagesSupplier = ::com::sun::star::uno::Reference< + ::com::sun::star::drawing::XDrawPagesSupplier > + ( mXModel, ::com::sun::star::uno::UNO_QUERY ); + if ( !mXDrawPagesSupplier.is() ) + break; + + mXMasterPagesSupplier = ::com::sun::star::uno::Reference< + ::com::sun::star::drawing::XMasterPagesSupplier > + ( mXModel, ::com::sun::star::uno::UNO_QUERY ); + if ( !mXMasterPagesSupplier.is() ) + break; + mXDrawPages = mXMasterPagesSupplier->getMasterPages(); + if ( !mXDrawPages.is() ) + break; + mnMasterPages = mXDrawPages->getCount(); + mXDrawPages = mXDrawPagesSupplier->getDrawPages(); + if( !mXDrawPages.is() ) + break; + mnPages = mXDrawPages->getCount(); + if ( !ImplGetPageByIndex( 0, NORMAL ) ) + break; + + return TRUE; + } + return FALSE; +} + +// --------------------------------------------------------------------------------------------- + +sal_Bool PPTWriter::ImplSetCurrentStyleSheet( sal_uInt32 nPageNum ) +{ + sal_Bool bRet = sal_False; + if ( nPageNum >= maStyleSheetList.size() ) + nPageNum = 0; + else + bRet = sal_True; + mpStyleSheet = maStyleSheetList[ nPageNum ]; + return bRet; +} + +// --------------------------------------------------------------------------------------------- + +sal_Bool PPTWriter::ImplGetPageByIndex( sal_uInt32 nIndex, PageType ePageType ) +{ + while( TRUE ) + { + if ( ePageType != meLatestPageType ) + { + switch( ePageType ) + { + case NORMAL : + case NOTICE : + { + mXDrawPages = mXDrawPagesSupplier->getDrawPages(); + if( !mXDrawPages.is() ) + return FALSE; + } + break; + + case MASTER : + { + mXDrawPages = mXMasterPagesSupplier->getMasterPages(); + if( !mXDrawPages.is() ) + return FALSE; + } + break; + default: + break; + } + meLatestPageType = ePageType; + } + ::com::sun::star::uno::Any aAny( mXDrawPages->getByIndex( nIndex ) ); + aAny >>= mXDrawPage; + if ( !mXDrawPage.is() ) + break; + if ( ePageType == NOTICE ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::presentation::XPresentationPage > + aXPresentationPage( mXDrawPage, ::com::sun::star::uno::UNO_QUERY ); + if ( !aXPresentationPage.is() ) + break; + mXDrawPage = aXPresentationPage->getNotesPage(); + if ( !mXDrawPage.is() ) + break; + } + mXPagePropSet = ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > + ( mXDrawPage, ::com::sun::star::uno::UNO_QUERY ); + if ( !mXPagePropSet.is() ) + break; + + mXShapes = ::com::sun::star::uno::Reference< + ::com::sun::star::drawing::XShapes > + ( mXDrawPage, ::com::sun::star::uno::UNO_QUERY ); + if ( !mXShapes.is() ) + break; + + /* try to get the "real" background PropertySet. If the normal page is not supporting this property, it is + taken the property from the master */ + sal_Bool bHasBackground = GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Background" ) ), sal_True ); + if ( bHasBackground ) + bHasBackground = ( aAny >>= mXBackgroundPropSet ); + if ( !bHasBackground ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XMasterPageTarget > + aXMasterPageTarget( mXDrawPage, ::com::sun::star::uno::UNO_QUERY ); + if ( aXMasterPageTarget.is() ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage > aXMasterDrawPage; + aXMasterDrawPage = aXMasterPageTarget->getMasterPage(); + if ( aXMasterDrawPage.is() ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > aXMasterPagePropSet; + aXMasterPagePropSet = ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > + ( aXMasterDrawPage, ::com::sun::star::uno::UNO_QUERY ); + if ( aXMasterPagePropSet.is() ) + { + sal_Bool bBackground = GetPropertyValue( aAny, aXMasterPagePropSet, + String( RTL_CONSTASCII_USTRINGPARAM( "Background" ) ) ); + if ( bBackground ) + { + aAny >>= mXBackgroundPropSet; + } + } + } + } + } + return TRUE; + } + return FALSE; +} + +// --------------------------------------------------------------------------------------------- + +sal_Bool PPTWriter::ImplGetShapeByIndex( sal_uInt32 nIndex, sal_Bool bGroup ) +{ + while(TRUE) + { + if ( ( bGroup == FALSE ) || ( GetCurrentGroupLevel() == 0 ) ) + { + ::com::sun::star::uno::Any aAny( mXShapes->getByIndex( nIndex ) ); + aAny >>= mXShape; + } + else + { + ::com::sun::star::uno::Any aAny( GetCurrentGroupAccess()->getByIndex( GetCurrentGroupIndex() ) ); + aAny >>= mXShape; + } + if ( !mXShape.is() ) + break; + + ::com::sun::star::uno::Any aAny( mXShape->queryInterface( ::getCppuType( (const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >*) 0 ) )); + aAny >>= mXPropSet; + + if ( !mXPropSet.is() ) + break; + maPosition = ImplMapPoint( mXShape->getPosition() ); + maSize = ImplMapSize( mXShape->getSize() ); + maRect = Rectangle( Point( maPosition.X, maPosition.Y ), Size( maSize.Width, maSize.Height ) ); + mType = ByteString( String( mXShape->getShapeType() ), RTL_TEXTENCODING_UTF8 ); + mType.Erase( 0, 13 ); // "com.sun.star." entfernen + sal_uInt16 nPos = mType.Search( (const char*)"Shape" ); + mType.Erase( nPos, 5 ); + + mbPresObj = mbEmptyPresObj = FALSE; + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "IsPresentationObject" ) ) ) ) + mAny >>= mbPresObj; + + if ( mbPresObj && ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "IsEmptyPresentationObject" ) ) ) ) + mAny >>= mbEmptyPresObj; + + mnAngle = ( PropValue::GetPropertyValue( aAny, + mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "RotateAngle" ) ), sal_True ) ) + ? *((sal_Int32*)aAny.getValue() ) + : 0; + + return TRUE; + } + return FALSE; +} + +// ----------------------------------------------------------------------- + +sal_uInt32 PPTWriter::ImplGetMasterIndex( PageType ePageType ) +{ + sal_uInt32 nRetValue = 0; + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XMasterPageTarget > + aXMasterPageTarget( mXDrawPage, ::com::sun::star::uno::UNO_QUERY ); + + if ( aXMasterPageTarget.is() ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage > + aXDrawPage = aXMasterPageTarget->getMasterPage(); + if ( aXDrawPage.is() ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > + aXPropertySet( aXDrawPage, ::com::sun::star::uno::UNO_QUERY ); + + if ( aXPropertySet.is() ) + { + if ( ImplGetPropertyValue( aXPropertySet, String( RTL_CONSTASCII_USTRINGPARAM( "Number" ) ) ) ) + nRetValue |= *(sal_Int16*)mAny.getValue(); + if ( nRetValue & 0xffff ) // ueberlauf vermeiden + nRetValue--; + } + } + } + if ( ePageType == NOTICE ) + nRetValue += mnMasterPages; + return nRetValue; +} + +// ----------------------------------------------------------------------- + +sal_Bool PPTWriter::ImplGetStyleSheets() +{ + int nInstance, nLevel; + sal_Bool bRetValue = sal_False; + sal_uInt32 nPageNum; + + for ( nPageNum = 0; nPageNum < mnMasterPages; nPageNum++ ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::container::XNamed > + aXNamed; + + ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > + aXNameAccess; + + ::com::sun::star::uno::Reference< ::com::sun::star::style::XStyleFamiliesSupplier > + aXStyleFamiliesSupplier( mXModel, ::com::sun::star::uno::UNO_QUERY ); + + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > + aXPropSet( mXModel, ::com::sun::star::uno::UNO_QUERY ); + + sal_uInt16 nDefaultTab = ( aXPropSet.is() && ImplGetPropertyValue( aXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TabStop" ) ) ) ) + ? (sal_uInt16)( *(sal_Int32*)mAny.getValue() / 4.40972 ) + : 1250; + + maStyleSheetList.push_back( new PPTExStyleSheet( nDefaultTab, (PPTExBulletProvider&)*this ) ); + ImplSetCurrentStyleSheet( nPageNum ); + if ( ImplGetPageByIndex( nPageNum, MASTER ) ) + aXNamed = ::com::sun::star::uno::Reference< ::com::sun::star::container::XNamed > + ( mXDrawPage, ::com::sun::star::uno::UNO_QUERY ); + + if ( aXStyleFamiliesSupplier.is() ) + aXNameAccess = aXStyleFamiliesSupplier->getStyleFamilies(); + + bRetValue = aXNamed.is() && aXNameAccess.is() && aXStyleFamiliesSupplier.is(); + if ( bRetValue ) + { + for ( nInstance = EPP_TEXTTYPE_Title; nInstance <= EPP_TEXTTYPE_CenterTitle; nInstance++ ) + { + String aStyle; + String aFamily; + switch ( nInstance ) + { + case EPP_TEXTTYPE_CenterTitle : + case EPP_TEXTTYPE_Title : + { + aStyle = String( RTL_CONSTASCII_USTRINGPARAM( "title" ) ); + aFamily = aXNamed->getName(); + } + break; + case EPP_TEXTTYPE_Body : + { + aStyle = String( RTL_CONSTASCII_USTRINGPARAM( "outline1" ) ); // SD_LT_SEPARATOR + aFamily = aXNamed->getName(); + } + break; + case EPP_TEXTTYPE_Other : + { + aStyle = String( RTL_CONSTASCII_USTRINGPARAM( "standard" ) ); + aFamily = String( RTL_CONSTASCII_USTRINGPARAM( "graphics" ) ); + } + break; + case EPP_TEXTTYPE_CenterBody : + { + aStyle = String( RTL_CONSTASCII_USTRINGPARAM( "subtitle" ) ); + aFamily = aXNamed->getName(); + } + break; + } + if ( aStyle.Len() && aFamily.Len() ) + { + try + { + ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >xNameAccess; + if ( aXNameAccess->hasByName( aFamily ) ) + { + ::com::sun::star::uno::Any aAny( aXNameAccess->getByName( aFamily ) ); + if( aAny.getValue() && ::cppu::extractInterface( xNameAccess, aAny ) ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > aXFamily; + if ( aAny >>= aXFamily ) + { + if ( aXFamily->hasByName( aStyle ) ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::style::XStyle > xStyle; + aAny = aXFamily->getByName( aStyle ); + if( aAny.getValue() && ::cppu::extractInterface( xStyle, aAny ) ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::style::XStyle > aXStyle; + aAny >>= aXStyle; + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > + xPropSet( aXStyle, ::com::sun::star::uno::UNO_QUERY ); + if( xPropSet.is() ) + mpStyleSheet->SetStyleSheet( xPropSet, maFontCollection, nInstance, 0 ); + for ( nLevel = 1; nLevel < 5; nLevel++ ) + { + if ( nInstance == EPP_TEXTTYPE_Body ) + { + sal_Unicode cTemp = aStyle.GetChar( aStyle.Len() - 1 ); + aStyle.SetChar( aStyle.Len() - 1, ++cTemp ); + if ( aXFamily->hasByName( aStyle ) ) + { + aXFamily->getByName( aStyle ) >>= xStyle; + if( xStyle.is() ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > + xPropertySet( xStyle, ::com::sun::star::uno::UNO_QUERY ); + if ( xPropertySet.is() ) + mpStyleSheet->SetStyleSheet( xPropertySet, maFontCollection, nInstance, nLevel ); + } + } + } + else + mpStyleSheet->SetStyleSheet( xPropSet, maFontCollection, nInstance, nLevel ); + } + } + } + } + } + } + } + catch( ::com::sun::star::uno::Exception& ) + { + // + } + } + } + for ( ; nInstance <= EPP_TEXTTYPE_QuarterBody; nInstance++ ) + { + + } + } + } + return bRetValue; +} + +// ----------------------------------------------------------------------- + +void PPTWriter::ImplWriteParagraphs( SvStream& rOut, TextObj& rTextObj ) +{ + sal_Bool bFirstParagraph = TRUE; + sal_uInt32 nCharCount; + sal_uInt32 nPropertyFlags = 0; + sal_uInt16 nDepth = 0; + sal_Int16 nLineSpacing; + int nInstance = rTextObj.GetInstance(); + + for ( ParagraphObj* pPara = rTextObj.First() ; pPara; pPara = rTextObj.Next(), bFirstParagraph = FALSE ) + { + PortionObj* pPortion = (PortionObj*)pPara->First(); + nCharCount = pPara->Count(); + + nDepth = pPara->nDepth; + if ( nDepth > 4) + nDepth = 4; + + if ( ( pPara->meTextAdjust == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) || + ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, ParaAttr_Adjust, pPara->mnTextAdjust ) ) ) + nPropertyFlags |= 0x00000800; + nLineSpacing = pPara->mnLineSpacing; + + const FontCollectionEntry* pDesc = maFontCollection.GetById( pPortion->mnFont ); + sal_Int16 nNormalSpacing = 100; + if ( !mbFontIndependentLineSpacing && pDesc ) + { + double fN = 100.0; + fN *= pDesc->Scaling; + nNormalSpacing = (sal_Int16)( fN + 0.5 ); + } + if ( !mbFontIndependentLineSpacing && bFirstParagraph && ( nLineSpacing > nNormalSpacing ) ) // sj: i28747, no replacement for fixed linespacing + { + nLineSpacing = nNormalSpacing; + nPropertyFlags |= 0x00001000; + } + else + { + if ( nLineSpacing > 0 ) + { + if ( !mbFontIndependentLineSpacing && pDesc ) + nLineSpacing = (sal_Int16)( (double)nLineSpacing * pDesc->Scaling + 0.5 ); + } + else + { + if ( pPortion && pPortion->mnCharHeight > (sal_uInt16)( ((double)-nLineSpacing) * 0.001 * 72.0 / 2.54 ) ) // 1/100mm to point + nLineSpacing = nNormalSpacing; + else + nLineSpacing = (sal_Int16)( (double)nLineSpacing / 4.40972 ); + } + if ( ( pPara->meLineSpacing == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) || + ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, ParaAttr_LineFeed, nLineSpacing ) ) ) + nPropertyFlags |= 0x00001000; + } + if ( ( pPara->meLineSpacingTop == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) || + ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, ParaAttr_UpperDist, pPara->mnLineSpacingTop ) ) ) + nPropertyFlags |= 0x00002000; + if ( ( pPara->meLineSpacingBottom == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) || + ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, ParaAttr_LowerDist, pPara->mnLineSpacingBottom ) ) ) + nPropertyFlags |= 0x00004000; + if ( ( pPara->meForbiddenRules == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) || + ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, ParaAttr_UpperDist, pPara->mbForbiddenRules ) ) ) + nPropertyFlags |= 0x00020000; + if ( ( pPara->meParagraphPunctation == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) || + ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, ParaAttr_UpperDist, pPara->mbParagraphPunctation ) ) ) + nPropertyFlags |= 0x00080000; + if ( ( pPara->meBiDi == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) || + ( mpStyleSheet->IsHardAttribute( nInstance, nDepth, ParaAttr_BiDi, pPara->mnBiDi ) ) ) + nPropertyFlags |= 0x00200000; + + + sal_Int32 nBuRealSize = pPara->nBulletRealSize; + sal_Int16 nBulletFlags = pPara->nBulletFlags; + + if ( pPara->bExtendedParameters ) + nPropertyFlags |= pPara->nParaFlags; + else + { + nPropertyFlags |= 1; // turn off bullet explicit + nBulletFlags = 0; + } + FontCollectionEntry aFontDescEntry( pPara->aFontDesc.Name, pPara->aFontDesc.Family, pPara->aFontDesc.Pitch, pPara->aFontDesc.CharSet ); + sal_uInt16 nFontId = (sal_uInt16)maFontCollection.GetId( aFontDescEntry ); + + rOut << nCharCount + << nDepth // Level + << (sal_uInt32)nPropertyFlags; // Paragraph Attribut Set + + if ( nPropertyFlags & 0xf ) + rOut << nBulletFlags; + if ( nPropertyFlags & 0x80 ) + rOut << (sal_uInt16)( pPara->cBulletId ); + if ( nPropertyFlags & 0x10 ) + rOut << nFontId; + if ( nPropertyFlags & 0x40 ) + rOut << (sal_Int16)nBuRealSize; + if ( nPropertyFlags & 0x20 ) + { + sal_uInt32 nBulletColor = pPara->nBulletColor; + if ( nBulletColor == COL_AUTO ) + { + sal_Bool bIsDark = sal_False; + ::com::sun::star::uno::Any aAny; + if ( PropValue::GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsBackgroundDark" ) ), sal_True ) ) + aAny >>= bIsDark; + nBulletColor = bIsDark ? 0xffffff : 0x000000; + } + nBulletColor &= 0xffffff; + nBulletColor |= 0xfe000000; + rOut << nBulletColor; + } + if ( nPropertyFlags & 0x00000800 ) + rOut << (sal_uInt16)( pPara->mnTextAdjust ); + if ( nPropertyFlags & 0x00001000 ) + rOut << (sal_uInt16)( nLineSpacing ); + if ( nPropertyFlags & 0x00002000 ) + rOut << (sal_uInt16)( pPara->mnLineSpacingTop ); + if ( nPropertyFlags & 0x00004000 ) + rOut << (sal_uInt16)( pPara->mnLineSpacingBottom ); + if ( nPropertyFlags & 0x000e0000 ) + { + sal_uInt16 nAsianSettings = 0; + if ( pPara->mbForbiddenRules ) + nAsianSettings |= 1; + if ( pPara->mbParagraphPunctation ) + nAsianSettings |= 4; + rOut << nAsianSettings; + } + if ( nPropertyFlags & 0x200000 ) + rOut << pPara->mnBiDi; + } +} + +// ----------------------------------------------------------------------- + +void PPTWriter::ImplWritePortions( SvStream& rOut, TextObj& rTextObj ) +{ + sal_uInt32 nPropertyFlags, i = 0; + int nInstance = rTextObj.GetInstance(); + + for ( ParagraphObj* pPara = rTextObj.First(); pPara; pPara = rTextObj.Next(), i++ ) + { + for ( PortionObj* pPortion = (PortionObj*)pPara->First(); pPortion; pPortion = (PortionObj*)pPara->Next() ) + { + nPropertyFlags = 0; + sal_uInt32 nCharAttr = pPortion->mnCharAttr; + sal_uInt32 nCharColor = pPortion->mnCharColor; + + if ( nCharColor == COL_AUTO ) // nCharColor depends to the background color + { + sal_Bool bIsDark = sal_False; + ::com::sun::star::uno::Any aAny; + if ( PropValue::GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsBackgroundDark" ) ), sal_True ) ) + aAny >>= bIsDark; + nCharColor = bIsDark ? 0xffffff : 0x000000; + } + + nCharColor &= 0xffffff; + + /* the portion is using the embossed or engraved attribute, which we want to map to the relief feature of PPT. + Because the relief feature of PPT is dependent to the background color, such a mapping can not always be used. */ + if ( nCharAttr & 0x200 ) + { + sal_uInt32 nBackgroundColor = 0xffffff; + + if ( !nCharColor ) // special threatment for + nCharColor = 0xffffff; // black fontcolor + + ::com::sun::star::uno::Any aAny; + ::com::sun::star::drawing::FillStyle aFS( ::com::sun::star::drawing::FillStyle_NONE ); + if ( PropValue::GetPropertyValue( aAny, mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillStyle" ) ) ) ) + aAny >>= aFS; + switch( aFS ) + { + case ::com::sun::star::drawing::FillStyle_GRADIENT : + { + Point aEmptyPoint = Point(); + Rectangle aRect( aEmptyPoint, Size( 28000, 21000 ) ); + EscherPropertyContainer aPropOpt( mpPptEscherEx->GetGraphicProvider(), mpPicStrm, aRect ); + aPropOpt.CreateGradientProperties( mXPropSet ); + aPropOpt.GetOpt( ESCHER_Prop_fillColor, nBackgroundColor ); + } + break; + case ::com::sun::star::drawing::FillStyle_SOLID : + { + if ( PropValue::GetPropertyValue( aAny, mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillColor" ) ) ) ) + nBackgroundColor = mpPptEscherEx->GetColor( *((sal_uInt32*)aAny.getValue()) ); + } + break; + case ::com::sun::star::drawing::FillStyle_NONE : + { + ::com::sun::star::uno::Any aBackAny; + ::com::sun::star::drawing::FillStyle aBackFS( ::com::sun::star::drawing::FillStyle_NONE ); + if ( PropValue::GetPropertyValue( aBackAny, mXBackgroundPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillStyle" ) ) ) ) + aBackAny >>= aBackFS; + switch( aBackFS ) + { + case ::com::sun::star::drawing::FillStyle_GRADIENT : + { + Point aEmptyPoint = Point(); + Rectangle aRect( aEmptyPoint, Size( 28000, 21000 ) ); + EscherPropertyContainer aPropOpt( mpPptEscherEx->GetGraphicProvider(), mpPicStrm, aRect ); + aPropOpt.CreateGradientProperties( mXBackgroundPropSet ); + aPropOpt.GetOpt( ESCHER_Prop_fillColor, nBackgroundColor ); + } + break; + case ::com::sun::star::drawing::FillStyle_SOLID : + { + if ( PropValue::GetPropertyValue( aAny, mXBackgroundPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillColor" ) ) ) ) + nBackgroundColor = mpPptEscherEx->GetColor( *((sal_uInt32*)aAny.getValue()) ); + } + break; + default: + break; + } + } + break; + default: + break; + } + + sal_Int32 nB = nBackgroundColor & 0xff; + nB += (sal_uInt8)( nBackgroundColor >> 8 ); + nB += (sal_uInt8)( nBackgroundColor >> 16 ); + // if the background color is nearly black, relief can't been used, because the text would not be visible + if ( nB < 0x60 || ( nBackgroundColor != nCharColor ) ) + { + nCharAttr &=~ 0x200; + + // now check if the text is part of a group, and if the previous object has the same color than the fontcolor + // ( and if fillcolor is not available the background color ), it is sometimes + // not possible to export the 'embossed' flag + if ( ( GetCurrentGroupLevel() > 0 ) && ( GetCurrentGroupIndex() >= 1 ) ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > aGroupedShape( GetCurrentGroupAccess()->getByIndex( GetCurrentGroupIndex() - 1 ), uno::UNO_QUERY ); + if( aGroupedShape.is() ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > aPropSetOfNextShape + ( aGroupedShape, ::com::sun::star::uno::UNO_QUERY ); + if ( aPropSetOfNextShape.is() ) + { + if ( PropValue::GetPropertyValue( aAny, aPropSetOfNextShape, + String( RTL_CONSTASCII_USTRINGPARAM( "FillColor" ) ), sal_True ) ) + { + if ( nCharColor == mpPptEscherEx->GetColor( *((sal_uInt32*)aAny.getValue()) ) ) + { + nCharAttr |= 0x200; + } + } + } + } + } + } + } + nCharColor |= 0xfe000000; + if ( nInstance == 4 ) // special handling for normal textobjects: + nPropertyFlags |= nCharAttr & 0x217; // not all attributes ar inherited + else + { + if ( /* ( pPortion->mnCharAttrHard & 1 ) || */ + ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_Bold, nCharAttr ) ) ) + nPropertyFlags |= 1; + if ( /* ( pPortion->mnCharAttrHard & 2 ) || */ + ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_Italic, nCharAttr ) ) ) + nPropertyFlags |= 2; + if ( /* ( pPortion->mnCharAttrHard & 4 ) || */ + ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_Underline, nCharAttr ) ) ) + nPropertyFlags |= 4; + if ( /* ( pPortion->mnCharAttrHard & 0x10 ) || */ + ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_Shadow, nCharAttr ) ) ) + nPropertyFlags |= 0x10; + if ( /* ( pPortion->mnCharAttrHard & 0x200 ) || */ + ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_Embossed, nCharAttr ) ) ) + nPropertyFlags |= 512; + } + if ( rTextObj.HasExtendedBullets() ) + { + nPropertyFlags |= ( i & 0x3f ) << 10 ; + nCharAttr |= ( i & 0x3f ) << 10; + } + if ( ( pPortion->meFontName == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) || + ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_Font, pPortion->mnFont ) ) ) + nPropertyFlags |= 0x00010000; + if ( ( pPortion->meAsianOrComplexFont == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) || + ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_AsianOrComplexFont, pPortion->mnAsianOrComplexFont ) ) ) + nPropertyFlags |= 0x00200000; + if ( ( pPortion->meCharHeight == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) || + ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_FontHeight, pPortion->mnCharHeight ) ) ) + nPropertyFlags |= 0x00020000; + if ( ( pPortion->meCharColor == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) || + ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_FontColor, nCharColor & 0xffffff ) ) ) + nPropertyFlags |= 0x00040000; + if ( ( pPortion->meCharEscapement == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) || + ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_Escapement, pPortion->mnCharEscapement ) ) ) + nPropertyFlags |= 0x00080000; + + sal_uInt32 nCharCount = pPortion->Count(); + + rOut << nCharCount + << nPropertyFlags; //PropertyFlags + + if ( nPropertyFlags & 0xffff ) + rOut << (sal_uInt16)( nCharAttr ); + if ( nPropertyFlags & 0x00010000 ) + rOut << pPortion->mnFont; + if ( nPropertyFlags & 0x00200000 ) + rOut << pPortion->mnAsianOrComplexFont; + if ( nPropertyFlags & 0x00020000 ) + rOut << (sal_uInt16)( pPortion->mnCharHeight ); + if ( nPropertyFlags & 0x00040000 ) + rOut << (sal_uInt32)nCharColor; + if ( nPropertyFlags & 0x00080000 ) + rOut << pPortion->mnCharEscapement; + } + } +} + +// ---------------------------------------------------------------------------------------- +// laedt und konvertiert text aus shape, ergebnis ist mnTextSize gespeichert; +sal_Bool PPTWriter::ImplGetText() +{ + mnTextSize = 0; + mbFontIndependentLineSpacing = sal_False; + mXText = ::com::sun::star::uno::Reference< + ::com::sun::star::text::XSimpleText > + ( mXShape, ::com::sun::star::uno::UNO_QUERY ); + + if ( mXText.is() ) + { + mnTextSize = mXText->getString().getLength(); + ::com::sun::star::uno::Any aAny; + if ( GetPropertyValue( aAny, mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FontIndependentLineSpacing" ) ) ), sal_True ) + aAny >>= mbFontIndependentLineSpacing; + } + return ( mnTextSize != 0 ); +} + +// ----------------------------------------------------------------------- + +void PPTWriter::ImplFlipBoundingBox( EscherPropertyContainer& rPropOpt ) +{ + if ( mnAngle < 0 ) + mnAngle = ( 36000 + mnAngle ) % 36000; + else + mnAngle = ( 36000 - ( mnAngle % 36000 ) ); + + double fCos = cos( (double)mnAngle * F_PI18000 ); + double fSin = sin( (double)mnAngle * F_PI18000 ); + + double fWidthHalf = maRect.GetWidth() / 2; + double fHeightHalf = maRect.GetHeight() / 2; + + double fXDiff = fCos * fWidthHalf + fSin * (-fHeightHalf); + double fYDiff = - ( fSin * fWidthHalf - fCos * ( -fHeightHalf ) ); + + maRect.Move( (sal_Int32)( -( fWidthHalf - fXDiff ) ), (sal_Int32)( - ( fHeightHalf + fYDiff ) ) ); + mnAngle *= 655; + mnAngle += 0x8000; + mnAngle &=~0xffff; // nAngle auf volle Gradzahl runden + rPropOpt.AddOpt( ESCHER_Prop_Rotation, mnAngle ); + + if ( ( mnAngle >= ( 45 << 16 ) && mnAngle < ( 135 << 16 ) ) || + ( mnAngle >= ( 225 << 16 ) && mnAngle < ( 315 << 16 ) ) ) + { + // In diesen beiden Bereichen steht in PPT gemeinerweise die + // BoundingBox bereits senkrecht. Daher muss diese VOR + // DER ROTATION flachgelegt werden. + ::com::sun::star::awt::Point + aTopLeft( (sal_Int32)( maRect.Left() + fWidthHalf - fHeightHalf ), (sal_Int32)( maRect.Top() + fHeightHalf - fWidthHalf ) ); + Size aNewSize( maRect.GetHeight(), maRect.GetWidth() ); + maRect = Rectangle( Point( aTopLeft.X, aTopLeft.Y ), aNewSize ); + } +} + +// ----------------------------------------------------------------------- + +struct FieldEntry +{ + sal_uInt32 nFieldType; + sal_uInt32 nFieldStartPos; + sal_uInt32 nFieldEndPos; + String aRepresentation; + String aFieldUrl; + + FieldEntry( sal_uInt32 nType, sal_uInt32 nStart, sal_uInt32 nEnd ) + { + nFieldType = nType; + nFieldStartPos = nStart; + nFieldEndPos = nEnd; + } +}; + +// ----------------------------------------------------------------------- + +PortionObj::PortionObj( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet, + FontCollection& rFontCollection ) : + mnCharAttrHard ( 0 ), + mnCharAttr ( 0 ), + mnFont ( 0 ), + mnAsianOrComplexFont( 0xffff ), + mnTextSize ( 0 ), + mbLastPortion ( TRUE ), + mpText ( NULL ), + mpFieldEntry ( NULL ) +{ + mXPropSet = rXPropSet; + + ImplGetPortionValues( rFontCollection, FALSE ); +} + +PortionObj::PortionObj( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > & rXTextRange, + sal_Bool bLast, FontCollection& rFontCollection ) : + mnCharAttrHard ( 0 ), + mnCharAttr ( 0 ), + mnFont ( 0 ), + mnAsianOrComplexFont ( 0xffff ), + mbLastPortion ( bLast ), + mpText ( NULL ), + mpFieldEntry ( NULL ) +{ + String aString( rXTextRange->getString() ); + String aURL; + BOOL bRTL_endingParen = FALSE; + + mnTextSize = aString.Len(); + if ( bLast ) + mnTextSize++; + + if ( mnTextSize ) + { + mpFieldEntry = NULL; + sal_uInt32 nFieldType = 0; + + mXPropSet = ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertySet > + ( rXTextRange, ::com::sun::star::uno::UNO_QUERY ); + mXPropState = ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertyState > + ( rXTextRange, ::com::sun::star::uno::UNO_QUERY ); + + sal_Bool bPropSetsValid = ( mXPropSet.is() && mXPropState.is() ); + if ( bPropSetsValid ) + nFieldType = ImplGetTextField( rXTextRange, mXPropSet, aURL ); + if ( nFieldType ) + { + mpFieldEntry = new FieldEntry( nFieldType, 0, mnTextSize ); + if ( ( nFieldType >> 28 == 4 ) ) + { + mpFieldEntry->aRepresentation = aString; + mpFieldEntry->aFieldUrl = aURL; + } + } + sal_Bool bSymbol = FALSE; + + if ( bPropSetsValid && ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharFontCharSet" ) ), FALSE ) ) + { + sal_Int16 nCharset; + mAny >>= nCharset; + if ( nCharset == ::com::sun::star::awt::CharSet::SYMBOL ) + bSymbol = TRUE; + } + if ( mpFieldEntry && ( nFieldType & 0x800000 ) ) // placeholder ? + { + mnTextSize = 1; + if ( bLast ) + mnTextSize++; + mpText = new sal_uInt16[ mnTextSize ]; + mpText[ 0 ] = 0x2a; + } + else + { + const sal_Unicode* pText = aString.GetBuffer(); + // For i39516 - a closing parenthesis that ends an RTL string is displayed backwards by PPT + // Solution: add a Unicode Right-to-Left Mark, following the method described in i18024 + if ( bLast && pText[ aString.Len() - 1 ] == sal_Unicode(')') && rFontCollection.GetScriptDirection( aString ) == com::sun::star::i18n::ScriptDirection::RIGHT_TO_LEFT ) + { + mnTextSize++; + bRTL_endingParen = TRUE; + } + mpText = new sal_uInt16[ mnTextSize ]; + sal_uInt16 nChar; + for ( int i = 0; i < aString.Len(); i++ ) + { + nChar = (sal_uInt16)pText[ i ]; + if ( nChar == 0xa ) + nChar++; + else if ( !bSymbol ) + { + switch ( nChar ) + { + // Currency + case 128: nChar = 0x20AC; break; + // Punctuation and other + case 130: nChar = 0x201A; break;// SINGLE LOW-9 QUOTATION MARK + case 131: nChar = 0x0192; break;// LATIN SMALL LETTER F WITH HOOK + case 132: nChar = 0x201E; break;// DOUBLE LOW-9 QUOTATION MARK + // LOW DOUBLE PRIME QUOTATION MARK + case 133: nChar = 0x2026; break;// HORIZONTAL ELLIPSES + case 134: nChar = 0x2020; break;// DAGGER + case 135: nChar = 0x2021; break;// DOUBLE DAGGER + case 136: nChar = 0x02C6; break;// MODIFIER LETTER CIRCUMFLEX ACCENT + case 137: nChar = 0x2030; break;// PER MILLE SIGN + case 138: nChar = 0x0160; break;// LATIN CAPITAL LETTER S WITH CARON + case 139: nChar = 0x2039; break;// SINGLE LEFT-POINTING ANGLE QUOTATION MARK + case 140: nChar = 0x0152; break;// LATIN CAPITAL LIGATURE OE + case 142: nChar = 0x017D; break;// LATIN CAPITAL LETTER Z WITH CARON + case 145: nChar = 0x2018; break;// LEFT SINGLE QUOTATION MARK + // MODIFIER LETTER TURNED COMMA + case 146: nChar = 0x2019; break;// RIGHT SINGLE QUOTATION MARK + // MODIFIER LETTER APOSTROPHE + case 147: nChar = 0x201C; break;// LEFT DOUBLE QUOTATION MARK + // REVERSED DOUBLE PRIME QUOTATION MARK + case 148: nChar = 0x201D; break;// RIGHT DOUBLE QUOTATION MARK + // REVERSED DOUBLE PRIME QUOTATION MARK + case 149: nChar = 0x2022; break;// BULLET + case 150: nChar = 0x2013; break;// EN DASH + case 151: nChar = 0x2014; break;// EM DASH + case 152: nChar = 0x02DC; break;// SMALL TILDE + case 153: nChar = 0x2122; break;// TRADE MARK SIGN + case 154: nChar = 0x0161; break;// LATIN SMALL LETTER S WITH CARON + case 155: nChar = 0x203A; break;// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + case 156: nChar = 0x0153; break;// LATIN SMALL LIGATURE OE + case 158: nChar = 0x017E; break;// LATIN SMALL LETTER Z WITH CARON + case 159: nChar = 0x0178; break;// LATIN CAPITAL LETTER Y WITH DIAERESIS +// case 222: nChar = 0x00B6; break;// PILCROW SIGN / PARAGRAPH SIGN + } + } + mpText[ i ] = nChar; + } + } + if ( bRTL_endingParen ) + mpText[ mnTextSize - 2 ] = 0x200F; // Unicode Right-to-Left mark + + if ( bLast ) + mpText[ mnTextSize - 1 ] = 0xd; + + if ( bPropSetsValid ) + ImplGetPortionValues( rFontCollection, TRUE ); + } +} + +PortionObj::PortionObj( PortionObj& rPortionObj ) +: PropStateValue( rPortionObj ) +{ + ImplConstruct( rPortionObj ); +} + +PortionObj::~PortionObj() +{ + ImplClear(); +} + +void PortionObj::Write( SvStream* pStrm, sal_Bool bLast ) +{ + sal_uInt32 nCount = mnTextSize; + if ( bLast && mbLastPortion ) + nCount--; + for ( sal_uInt32 i = 0; i < nCount; i++ ) + *pStrm << (sal_uInt16)mpText[ i ]; +} + +void PortionObj::ImplGetPortionValues( FontCollection& rFontCollection, sal_Bool bGetPropStateValue ) +{ + + sal_Bool bOk = ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharFontName" ) ), bGetPropStateValue ); + meFontName = ePropState; + if ( bOk ) + { + FontCollectionEntry aFontDesc( *(::rtl::OUString*)mAny.getValue() ); + sal_uInt32 nCount = rFontCollection.GetCount(); + mnFont = (sal_uInt16)rFontCollection.GetId( aFontDesc ); + if ( mnFont == nCount ) + { + FontCollectionEntry& rFontDesc = rFontCollection.GetLast(); + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharFontCharSet" ) ), sal_False ) ) + mAny >>= rFontDesc.CharSet; + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharFontFamily" ) ), sal_False ) ) + mAny >>= rFontDesc.Family; + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharFontPitch" ) ), sal_False ) ) + mAny >>= rFontDesc.Pitch; + } + } + + sal_Int16 nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( Application::GetSettings().GetLanguage() ); + if ( mpText && mnTextSize && xPPTBreakIter.is() ) + { + rtl::OUString sT( mpText, mnTextSize ); + nScriptType = xPPTBreakIter->getScriptType( sT, 0 ); + } + if ( nScriptType != com::sun::star::i18n::ScriptType::COMPLEX ) + { + bOk = ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharFontNameAsian" ) ), bGetPropStateValue ); + meAsianOrComplexFont = ePropState; + if ( bOk ) + { + FontCollectionEntry aFontDesc( *(::rtl::OUString*)mAny.getValue() ); + sal_uInt32 nCount = rFontCollection.GetCount(); + mnAsianOrComplexFont = (sal_uInt16)rFontCollection.GetId( aFontDesc ); + if ( mnAsianOrComplexFont == nCount ) + { + FontCollectionEntry& rFontDesc = rFontCollection.GetLast(); + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharFontCharSetAsian" ) ), sal_False ) ) + mAny >>= rFontDesc.CharSet; + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharFontFamilyAsian" ) ), sal_False ) ) + mAny >>= rFontDesc.Family; + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharFontPitchAsian" ) ), sal_False ) ) + mAny >>= rFontDesc.Pitch; + } + } + } + else + { + bOk = ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharFontNameComplex" ) ), bGetPropStateValue ); + meAsianOrComplexFont = ePropState; + if ( bOk ) + { + FontCollectionEntry aFontDesc( *(::rtl::OUString*)mAny.getValue() ); + sal_uInt32 nCount = rFontCollection.GetCount(); + mnAsianOrComplexFont = (sal_uInt16)rFontCollection.GetId( aFontDesc ); + if ( mnAsianOrComplexFont == nCount ) + { + FontCollectionEntry& rFontDesc = rFontCollection.GetLast(); + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharFontCharSetComplex" ) ), sal_False ) ) + mAny >>= rFontDesc.CharSet; + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharFontFamilyComplex" ) ), sal_False ) ) + mAny >>= rFontDesc.Family; + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharFontPitchComplex" ) ), sal_False ) ) + mAny >>= rFontDesc.Pitch; + } + } + } + + rtl::OUString aCharHeightName, aCharWeightName, aCharLocaleName, aCharPostureName; + switch( nScriptType ) + { + case com::sun::star::i18n::ScriptType::ASIAN : + { + aCharHeightName = String( RTL_CONSTASCII_USTRINGPARAM( "CharHeightAsian" ) ); + aCharWeightName = String( RTL_CONSTASCII_USTRINGPARAM( "CharWeightAsian" ) ); + aCharLocaleName = String( RTL_CONSTASCII_USTRINGPARAM( "CharLocaleAsian" ) ); + aCharPostureName = String( RTL_CONSTASCII_USTRINGPARAM( "CharPostureAsian" ) ); + break; + } + case com::sun::star::i18n::ScriptType::COMPLEX : + { + aCharHeightName = String( RTL_CONSTASCII_USTRINGPARAM( "CharHeightComplex" ) ); + aCharWeightName = String( RTL_CONSTASCII_USTRINGPARAM( "CharWeightComplex" ) ); + aCharLocaleName = String( RTL_CONSTASCII_USTRINGPARAM( "CharLocaleComplex" ) ); + aCharPostureName = String( RTL_CONSTASCII_USTRINGPARAM( "CharPostureComplex" ) ); + break; + } + default: + { + aCharHeightName = String( RTL_CONSTASCII_USTRINGPARAM( "CharHeight" ) ); + aCharWeightName = String( RTL_CONSTASCII_USTRINGPARAM( "CharWeight" ) ); + aCharLocaleName = String( RTL_CONSTASCII_USTRINGPARAM( "CharLocale" ) ); + aCharPostureName = String( RTL_CONSTASCII_USTRINGPARAM( "CharPosture" ) ); + break; + } + } + + mnCharHeight = 24; + if ( GetPropertyValue( mAny, mXPropSet, aCharHeightName, sal_False ) ) + { + float fVal(0.0); + if ( mAny >>= fVal ) + { + mnCharHeight = (sal_uInt16)( fVal + 0.5 ); + meCharHeight = GetPropertyState( mXPropSet, aCharHeightName ); + } + } + if ( GetPropertyValue( mAny, mXPropSet, aCharWeightName, sal_False ) ) + { + float fFloat(0.0); + if ( mAny >>= fFloat ) + { + if ( fFloat >= ::com::sun::star::awt::FontWeight::SEMIBOLD ) + mnCharAttr |= 1; + if ( GetPropertyState( mXPropSet, aCharWeightName ) == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) + mnCharAttrHard |= 1; + } + } + if ( GetPropertyValue( mAny, mXPropSet, aCharLocaleName, sal_False ) ) + { + com::sun::star::lang::Locale eLocale; + if ( mAny >>= eLocale ) + meCharLocale = eLocale; + } + if ( GetPropertyValue( mAny, mXPropSet, aCharPostureName, sal_False ) ) + { + ::com::sun::star::awt::FontSlant aFS; + if ( mAny >>= aFS ) + { + switch( aFS ) + { + case ::com::sun::star::awt::FontSlant_OBLIQUE : + case ::com::sun::star::awt::FontSlant_ITALIC : + mnCharAttr |= 2; + break; + default: + break; + } + if ( GetPropertyState( mXPropSet, aCharPostureName ) == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) + mnCharAttrHard |= 2; + } + } + + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharUnderline" ) ), bGetPropStateValue ) ) + { + sal_Int16 nVal(0); + mAny >>= nVal; + switch ( nVal ) + { + case ::com::sun::star::awt::FontUnderline::SINGLE : + case ::com::sun::star::awt::FontUnderline::DOUBLE : + case ::com::sun::star::awt::FontUnderline::DOTTED : + mnCharAttr |= 4; + } + } + if ( ePropState == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) + mnCharAttrHard |= 4; + + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharShadowed" ) ), bGetPropStateValue ) ) + { + sal_Bool bBool(sal_False); + mAny >>= bBool; + if ( bBool ) + mnCharAttr |= 0x10; + } + if ( ePropState == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) + mnCharAttrHard |= 16; + + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharRelief" ) ), bGetPropStateValue ) ) + { + sal_Int16 nVal(0); + mAny >>= nVal; + if ( nVal != ::com::sun::star::text::FontRelief::NONE ) + mnCharAttr |= 512; + } + if ( ePropState == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) + mnCharAttrHard |= 512; + + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharColor" ) ), bGetPropStateValue ) ) + { + sal_uInt32 nSOColor = *( (sal_uInt32*)mAny.getValue() ); + mnCharColor = nSOColor & 0xff00ff00; // green and hibyte + mnCharColor |= (sal_uInt8)( nSOColor ) << 16; // red and blue is switched + mnCharColor |= (sal_uInt8)( nSOColor >> 16 ); + } + meCharColor = ePropState; + + mnCharEscapement = 0; + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CharEscapement" ) ), bGetPropStateValue ) ) + { + mAny >>= mnCharEscapement; + if ( mnCharEscapement > 100 ) + mnCharEscapement = 33; + else if ( mnCharEscapement < -100 ) + mnCharEscapement = -33; + } + meCharEscapement = ePropState; +} + +void PortionObj::ImplClear() +{ + delete (FieldEntry*)mpFieldEntry; + delete[] mpText; +} + +void PortionObj::ImplConstruct( PortionObj& rPortionObj ) +{ + mbLastPortion = rPortionObj.mbLastPortion; + mnTextSize = rPortionObj.mnTextSize; + mnCharColor = rPortionObj.mnCharColor; + mnCharEscapement = rPortionObj.mnCharEscapement; + mnCharAttr = rPortionObj.mnCharAttr; + mnCharHeight = rPortionObj.mnCharHeight; + mnFont = rPortionObj.mnFont; + mnAsianOrComplexFont = rPortionObj.mnAsianOrComplexFont; + + if ( rPortionObj.mpText ) + { + mpText = new sal_uInt16[ mnTextSize ]; + memcpy( mpText, rPortionObj.mpText, mnTextSize << 1 ); + } + else + mpText = NULL; + + if ( rPortionObj.mpFieldEntry ) + mpFieldEntry = new FieldEntry( *( rPortionObj.mpFieldEntry ) ); + else + mpFieldEntry = NULL; +} + +sal_uInt32 PortionObj::ImplCalculateTextPositions( sal_uInt32 nCurrentTextPosition ) +{ + if ( mpFieldEntry && ( !mpFieldEntry->nFieldStartPos ) ) + { + mpFieldEntry->nFieldStartPos += nCurrentTextPosition; + mpFieldEntry->nFieldEndPos += nCurrentTextPosition; + } + return mnTextSize; +} + +// ----------------------------------------------------------------------- +// Rueckgabe: 0 = kein TextField +// bit28->31 text field type : +// 1 = Date +// 2 = Time +// 3 = SlideNumber +// 4 = Url +// 5 = DateTime +// 6 = header +// 7 = footer +// bit24->27 text field sub type (optional) +// 23-> PPT Textfield needs a placeholder + +sal_uInt32 PortionObj::ImplGetTextField( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > & , + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet, String& rURL ) +{ + sal_uInt32 nRetValue = 0; + sal_Int32 nFormat; + ::com::sun::star::uno::Any aAny; + if ( GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextPortionType" ) ), sal_True ) ) + { + String aTextFieldType( *(::rtl::OUString*)aAny.getValue() ); + if ( aTextFieldType == String( RTL_CONSTASCII_USTRINGPARAM( "TextField" ) ) ) + { + if ( GetPropertyValue( aAny, rXPropSet, aTextFieldType, sal_True ) ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextField > aXTextField; + if ( aAny >>= aXTextField ) + { + if ( aXTextField.is() ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > + xFieldPropSet( aXTextField, ::com::sun::star::uno::UNO_QUERY ); + if ( xFieldPropSet.is() ) + { + String aFieldKind( aXTextField->getPresentation( TRUE ) ); + if ( aFieldKind == String( RTL_CONSTASCII_USTRINGPARAM( "Date" ) ) ) + { + if ( GetPropertyValue( aAny, xFieldPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsFix" ) ) ), sal_True ) + { + sal_Bool bBool; + aAny >>= bBool; + if ( !bBool ) // Fixed DateFields gibt es in PPT nicht + { + if ( GetPropertyValue( aAny, xFieldPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Format" ) ) ), sal_True ) + { + nFormat = *(sal_Int32*)aAny.getValue(); + switch ( nFormat ) + { + default: + case 5 : + case 4 : + case 2 : nFormat = 0; break; + case 8 : + case 9 : + case 3 : nFormat = 1; break; + case 7 : + case 6 : nFormat = 2; break; + } + nRetValue |= ( ( ( 1 << 4 ) | nFormat ) << 24 ) | 0x800000; + } + } + } + } + else if ( aFieldKind == String( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ) ) + { + if ( GetPropertyValue( aAny, xFieldPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ) ), sal_True ) + rURL = String( *(::rtl::OUString*)aAny.getValue() ); + nRetValue = 4 << 28; + } + else if ( aFieldKind == String( RTL_CONSTASCII_USTRINGPARAM( "Page" ) ) ) + { + nRetValue = 3 << 28 | 0x800000; + } + else if ( aFieldKind == String( RTL_CONSTASCII_USTRINGPARAM( "Pages" ) ) ) + { + + } + else if ( aFieldKind == String( RTL_CONSTASCII_USTRINGPARAM( "Time" ) ) ) + { + if ( GetPropertyValue( aAny, xFieldPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsFix" ) ) ), sal_True ) + { + sal_Bool bBool; + aAny >>= bBool; + if ( !bBool ) + { + if ( GetPropertyValue( aAny, xFieldPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsFix" ) ) ), sal_True ) + { + nFormat = *(sal_Int32*)aAny.getValue(); + nRetValue |= ( ( ( 2 << 4 ) | nFormat ) << 24 ) | 0x800000; + } + } + } + } + else if ( aFieldKind == String( RTL_CONSTASCII_USTRINGPARAM( "File" ) ) ) + { + + } + else if ( aFieldKind == String( RTL_CONSTASCII_USTRINGPARAM( "Table" ) ) ) + { + + } + else if ( aFieldKind == String( RTL_CONSTASCII_USTRINGPARAM( "ExtTime" ) ) ) + { + if ( GetPropertyValue( aAny, xFieldPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsFix" ) ) ), sal_True ) + { + sal_Bool bBool; + aAny >>= bBool; + if ( !bBool ) + { + if ( GetPropertyValue( aAny, xFieldPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Format" ) ) ), sal_True ) + { + nFormat = *(sal_Int32*)aAny.getValue(); + switch ( nFormat ) + { + default: + case 6 : + case 7 : + case 8 : + case 2 : nFormat = 12; break; + case 3 : nFormat = 9; break; + case 5 : + case 4 : nFormat = 10; break; + + } + nRetValue |= ( ( ( 2 << 4 ) | nFormat ) << 24 ) | 0x800000; + } + } + } + } + else if ( aFieldKind == String( RTL_CONSTASCII_USTRINGPARAM( "ExtFile" ) ) ) + { + + } + else if ( aFieldKind == String( RTL_CONSTASCII_USTRINGPARAM( "Author" ) ) ) + { + + } + else if ( aFieldKind == String( RTL_CONSTASCII_USTRINGPARAM( "DateTime" ) ) ) + { + nRetValue = 5 << 28 | 0x800000; + } + else if ( aFieldKind == String( RTL_CONSTASCII_USTRINGPARAM( "Header" ) ) ) + { + nRetValue = 6 << 28 | 0x800000; + } + else if ( aFieldKind == String( RTL_CONSTASCII_USTRINGPARAM( "Footer" ) ) ) + { + nRetValue = 7 << 28 | 0x800000; + } + } + } + } + } + } + } + return nRetValue; +} + +PortionObj& PortionObj::operator=( PortionObj& rPortionObj ) +{ + if ( this != &rPortionObj ) + { + ImplClear(); + ImplConstruct( rPortionObj ); + } + return *this; +} + +// ----------------------------------------------------------------------- + +ParagraphObj::ParagraphObj( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet, + PPTExBulletProvider& rProv ) : + maMapModeSrc ( MAP_100TH_MM ), + maMapModeDest ( MAP_INCH, Point(), Fraction( 1, 576 ), Fraction( 1, 576 ) ) +{ + mXPropSet = rXPropSet; + + bExtendedParameters = FALSE; + + nDepth = 0; + nBulletFlags = 0; + nParaFlags = 0; + + ImplGetParagraphValues( rProv, FALSE ); +} + + ParagraphObj::ParagraphObj( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextContent > & rXTextContent, + ParaFlags aParaFlags, FontCollection& rFontCollection, PPTExBulletProvider& rProv ) : + maMapModeSrc ( MAP_100TH_MM ), + maMapModeDest ( MAP_INCH, Point(), Fraction( 1, 576 ), Fraction( 1, 576 ) ), + mbFirstParagraph ( aParaFlags.bFirstParagraph ), + mbLastParagraph ( aParaFlags.bLastParagraph ) +{ + bExtendedParameters = FALSE; + + nDepth = 0; + nBulletFlags = 0; + nParaFlags = 0; + + mXPropSet = ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertySet > + ( rXTextContent, ::com::sun::star::uno::UNO_QUERY ); + + mXPropState = ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertyState > + ( rXTextContent, ::com::sun::star::uno::UNO_QUERY ); + + if ( mXPropSet.is() && mXPropState.is() ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumerationAccess > + aXTextPortionEA( rXTextContent, ::com::sun::star::uno::UNO_QUERY ); + if ( aXTextPortionEA.is() ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration > + aXTextPortionE( aXTextPortionEA->createEnumeration() ); + if ( aXTextPortionE.is() ) + { + while ( aXTextPortionE->hasMoreElements() ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > aXCursorText; + ::com::sun::star::uno::Any aAny( aXTextPortionE->nextElement() ); + if ( aAny >>= aXCursorText ) + { + PortionObj* pPortionObj = new PortionObj( aXCursorText, !aXTextPortionE->hasMoreElements(), rFontCollection ); + if ( pPortionObj->Count() ) + Insert( pPortionObj, LIST_APPEND ); + else + delete pPortionObj; + } + } + } + } + ImplGetParagraphValues( rProv, TRUE );// + } +} + +ParagraphObj::ParagraphObj( ParagraphObj& rObj ) +: List() +, PropStateValue() +, SOParagraph() +{ + ImplConstruct( rObj ); +} + +ParagraphObj::~ParagraphObj() +{ + ImplClear(); +} + +void ParagraphObj::Write( SvStream* pStrm ) +{ + for ( void* pPtr = First(); pPtr; pPtr = Next() ) + ((PortionObj*)pPtr)->Write( pStrm, mbLastParagraph ); +} + +void ParagraphObj::ImplClear() +{ + for ( void* pPtr = First(); pPtr; pPtr = Next() ) + delete (PortionObj*)pPtr; +} + +void ParagraphObj::CalculateGraphicBulletSize( sal_uInt16 nFontHeight ) +{ + if ( ( (SvxExtNumType)nNumberingType == SVX_NUM_BITMAP ) && ( nBulletId != 0xffff ) ) + { + // calculate the bulletrealsize for this grafik + if ( aBuGraSize.Width() && aBuGraSize.Height() ) + { + double fCharHeight = nFontHeight; + double fLen = aBuGraSize.Height(); + fCharHeight = fCharHeight * 0.2540; + double fQuo = fLen / fCharHeight; + nBulletRealSize = (sal_Int16)( fQuo + 0.5 ); + if ( (sal_uInt16)nBulletRealSize > 400 ) + nBulletRealSize = 400; + } + } +} + +// from sw/source/filter/ww8/wrtw8num.cxx for default bullets to export to MS intact +static void lcl_SubstituteBullet(String& rNumStr, rtl_TextEncoding& rChrSet, String& rFontName) +{ + sal_Unicode cChar = rNumStr.GetChar(0); + StarSymbolToMSMultiFont *pConvert = CreateStarSymbolToMSMultiFont(); + String sFont = pConvert->ConvertChar(cChar); + delete pConvert; + if (sFont.Len()) + { + rNumStr = static_cast< sal_Unicode >(cChar | 0xF000); + rFontName = sFont; + rChrSet = RTL_TEXTENCODING_SYMBOL; + } + else if ( (rNumStr.GetChar(0) < 0xE000 || rNumStr.GetChar(0) > 0xF8FF) ) + { + /* + Ok we can't fit into a known windows unicode font, but + we are not in the private area, so we are a + standardized symbol, so turn off the symbol bit and + let words own font substitution kick in + */ + rChrSet = RTL_TEXTENCODING_UNICODE; + rFontName = ::GetFontToken(rFontName, 0); + } + else + { + /* + Well we don't have an available substition, and we're + in our private area, so give up and show a standard + bullet symbol + */ + rFontName.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Wingdings")); + rNumStr = static_cast< sal_Unicode >(0x6C); + } +} + +void ParagraphObj::ImplGetNumberingLevel( PPTExBulletProvider& rBuProv, sal_Int16 nNumberingDepth, sal_Bool bIsBullet, sal_Bool bGetPropStateValue ) +{ + ::com::sun::star::uno::Any aAny; + if ( GetPropertyValue( aAny, mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "ParaLeftMargin" ) ) ) ) + { + sal_Int32 nVal; + if ( aAny >>= nVal ) + nTextOfs = static_cast< sal_Int16 >( nVal / ( 2540.0 / 576 ) + 0.5 ) ; + } + if ( GetPropertyValue( aAny, mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "ParaFirstLineIndent" ) ) ) ) + { + if ( aAny >>= nBulletOfs ) + nBulletOfs = static_cast< sal_Int32 >( nBulletOfs / ( 2540.0 / 576 ) + 0.5 ); + } + if ( GetPropertyValue( aAny, mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "NumberingIsNumber" ) ) ) ) + aAny >>= bNumberingIsNumber; + + ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexReplace > aXIndexReplace; + + if ( bIsBullet && ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "NumberingRules" ) ), bGetPropStateValue ) ) + { + if ( ( mAny >>= aXIndexReplace ) && nNumberingDepth < aXIndexReplace->getCount() ) + { + mAny <<= aXIndexReplace->getByIndex( nNumberingDepth ); + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue> + aPropertySequence( *( ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue>*)mAny.getValue() ); + + const ::com::sun::star::beans::PropertyValue* pPropValue = aPropertySequence.getArray(); + + sal_Int32 nPropertyCount = aPropertySequence.getLength(); + if ( nPropertyCount ) + { + bExtendedParameters = TRUE; + nBulletRealSize = 100; + nMappedNumType = 0; + + String aGraphicURL; + for ( sal_Int32 i = 0; i < nPropertyCount; i++ ) + { + const void* pValue = pPropValue[ i ].Value.getValue(); + if ( pValue ) + { + ::rtl::OUString aPropName( pPropValue[ i ].Name ); + if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "NumberingType" ) ) ) + nNumberingType = *( (sal_Int16*)pValue ); + else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Adjust" ) ) ) + nHorzAdjust = *( (sal_Int16*)pValue ); + else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "BulletChar" ) ) ) + { + String aString( *( (String*)pValue ) ); + if ( aString.Len() ) + cBulletId = aString.GetChar( 0 ); + } + else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "BulletFont" ) ) ) + { + aFontDesc = *( (::com::sun::star::awt::FontDescriptor*)pValue ); + + // Our numbullet dialog has set the wrong textencoding for our "StarSymbol" font, + // instead of a Unicode encoding the encoding RTL_TEXTENCODING_SYMBOL was used. + // Because there might exist a lot of damaged documemts I added this two lines + // which fixes the bullet problem for the export. + if ( aFontDesc.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "StarSymbol" ) ) ) + aFontDesc.CharSet = RTL_TEXTENCODING_MS_1252; + + } + else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "GraphicURL" ) ) ) + aGraphicURL = ( *(::rtl::OUString*)pValue ); + else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "GraphicSize" ) ) ) + { + if ( pPropValue[ i ].Value.getValueType() == ::getCppuType( (::com::sun::star::awt::Size*)0) ) + { + // don't cast awt::Size to Size as on 64-bits they are not the same. + ::com::sun::star::awt::Size aSize; + pPropValue[ i ].Value >>= aSize; + aBuGraSize.nA = aSize.Width; + aBuGraSize.nB = aSize.Height; + } + } + else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "StartWith" ) ) ) + nStartWith = *( (sal_Int16*)pValue ); + else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "LeftMargin" ) ) ) + nTextOfs = nTextOfs + static_cast< sal_Int16 >( *( (sal_Int32*)pValue ) / ( 2540.0 / 576 ) ); + else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "FirstLineOffset" ) ) ) + nBulletOfs += (sal_Int16)( *( (sal_Int32*)pValue ) / ( 2540.0 / 576 ) ); + else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "BulletColor" ) ) ) + { + sal_uInt32 nSOColor = *( (sal_uInt32*)pValue ); + nBulletColor = nSOColor & 0xff00ff00; // green and hibyte + nBulletColor |= (sal_uInt8)( nSOColor ) << 16; // red + nBulletColor |= (sal_uInt8)( nSOColor >> 16 ) | 0xfe000000; // blue + } + else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "BulletRelSize" ) ) ) + { + nBulletRealSize = *( (sal_Int16*)pValue ); + nParaFlags |= 0x40; + nBulletFlags |= 8; + } + else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Prefix" ) ) ) + sPrefix = ( *(::rtl::OUString*)pValue ); + else if ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Suffix" ) ) ) + sSuffix = ( *(::rtl::OUString*)pValue ); +#ifdef DBG_UTIL + else if ( ! ( + ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "SymbolTextDistance" ) ) ) + || ( aPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Graphic" ) ) ) ) ) + { + DBG_ERROR( "Unbekanntes Property" ); + } +#endif + } + } + + if ( aGraphicURL.Len() ) + { + if ( aBuGraSize.Width() && aBuGraSize.Height() ) + { + xub_StrLen nIndex = aGraphicURL.Search( (sal_Unicode)':', 0 ); + if ( nIndex != STRING_NOTFOUND ) + { + nIndex++; + if ( aGraphicURL.Len() > nIndex ) + { + ByteString aUniqueId( aGraphicURL, nIndex, aGraphicURL.Len() - nIndex, RTL_TEXTENCODING_UTF8 ); + if ( aUniqueId.Len() ) + { + nBulletId = rBuProv.GetId( aUniqueId, aBuGraSize ); + if ( nBulletId != 0xffff ) + bExtendedBulletsUsed = TRUE; + } + } + } + } + else + { + nNumberingType = SVX_NUM_NUMBER_NONE; + } + } + + PortionObj* pPortion = (PortionObj*)First(); + CalculateGraphicBulletSize( ( pPortion ) ? pPortion->mnCharHeight : 24 ); + + switch( (SvxExtNumType)nNumberingType ) + { + case SVX_NUM_NUMBER_NONE : nParaFlags |= 0xf; break; + + case SVX_NUM_CHAR_SPECIAL : // Bullet + { + if ( aFontDesc.Name.equalsIgnoreAsciiCaseAscii("starsymbol") || + aFontDesc.Name.equalsIgnoreAsciiCaseAscii("opensymbol") ) + { + String sFontName = aFontDesc.Name; + String sNumStr = cBulletId; + rtl_TextEncoding eChrSet = aFontDesc.CharSet; + lcl_SubstituteBullet(sNumStr,eChrSet,sFontName); + aFontDesc.Name = sFontName; + cBulletId = sNumStr.GetChar( 0 ); + aFontDesc.CharSet = eChrSet; + } + + if ( aFontDesc.Name.getLength() ) + { +/* + if ( aFontDesc.CharSet != ::com::sun::star::awt::CharSet::SYMBOL ) + { + switch ( cBulletId ) + { + // Currency + case 128: cBulletId = 0x20AC; break; + // Punctuation and other + case 130: cBulletId = 0x201A; break;// SINGLE LOW-9 QUOTATION MARK + case 131: cBulletId = 0x0192; break;// LATIN SMALL LETTER F WITH HOOK + case 132: cBulletId = 0x201E; break;// DOUBLE LOW-9 QUOTATION MARK + // LOW DOUBLE PRIME QUOTATION MARK + case 133: cBulletId = 0x2026; break;// HORIZONTAL ELLIPSES + case 134: cBulletId = 0x2020; break;// DAGGER + case 135: cBulletId = 0x2021; break;// DOUBLE DAGGER + case 136: cBulletId = 0x02C6; break;// MODIFIER LETTER CIRCUMFLEX ACCENT + case 137: cBulletId = 0x2030; break;// PER MILLE SIGN + case 138: cBulletId = 0x0160; break;// LATIN CAPITAL LETTER S WITH CARON + case 139: cBulletId = 0x2039; break;// SINGLE LEFT-POINTING ANGLE QUOTATION MARK + case 140: cBulletId = 0x0152; break;// LATIN CAPITAL LIGATURE OE + case 142: cBulletId = 0x017D; break;// LATIN CAPITAL LETTER Z WITH CARON + case 145: cBulletId = 0x2018; break;// LEFT SINGLE QUOTATION MARK + // MODIFIER LETTER TURNED COMMA + case 146: cBulletId = 0x2019; break;// RIGHT SINGLE QUOTATION MARK + // MODIFIER LETTER APOSTROPHE + case 147: cBulletId = 0x201C; break;// LEFT DOUBLE QUOTATION MARK + // REVERSED DOUBLE PRIME QUOTATION MARK + case 148: cBulletId = 0x201D; break;// RIGHT DOUBLE QUOTATION MARK + // REVERSED DOUBLE PRIME QUOTATION MARK + case 149: cBulletId = 0x2022; break;// BULLET + case 150: cBulletId = 0x2013; break;// EN DASH + case 151: cBulletId = 0x2014; break;// EM DASH + case 152: cBulletId = 0x02DC; break;// SMALL TILDE + case 153: cBulletId = 0x2122; break;// TRADE MARK SIGN + case 154: cBulletId = 0x0161; break;// LATIN SMALL LETTER S WITH CARON + case 155: cBulletId = 0x203A; break;// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + case 156: cBulletId = 0x0153; break;// LATIN SMALL LIGATURE OE + case 158: cBulletId = 0x017E; break;// LATIN SMALL LETTER Z WITH CARON + case 159: cBulletId = 0x0178; break;// LATIN CAPITAL LETTER Y WITH DIAERESIS +// case 222: cBulletId = 0x00B6; break;// PILCROW SIGN / PARAGRAPH SIGN + } + } +*/ + nParaFlags |= 0x90; // wir geben den Font und den Charset vor + } + } + case SVX_NUM_CHARS_UPPER_LETTER : // zaehlt von a-z, aa - az, ba - bz, ... + case SVX_NUM_CHARS_LOWER_LETTER : + case SVX_NUM_ROMAN_UPPER : + case SVX_NUM_ROMAN_LOWER : + case SVX_NUM_ARABIC : + case SVX_NUM_PAGEDESC : // Numerierung aus der Seitenvorlage + case SVX_NUM_BITMAP : + case SVX_NUM_CHARS_UPPER_LETTER_N : // zaehlt von a-z, aa-zz, aaa-zzz + case SVX_NUM_CHARS_LOWER_LETTER_N : + { + if ( nNumberingType != SVX_NUM_CHAR_SPECIAL ) + { + bExtendedBulletsUsed = TRUE; + if ( nNumberingDepth & 1 ) + cBulletId = 0x2013; // defaulting bullet characters for ppt97 + else if ( nNumberingDepth == 4 ) + cBulletId = 0xbb; + else + cBulletId = 0x2022; + + switch( (SvxExtNumType)nNumberingType ) + { + case SVX_NUM_CHARS_UPPER_LETTER : + case SVX_NUM_CHARS_UPPER_LETTER_N : + { + if ( sSuffix == String( RTL_CONSTASCII_USTRINGPARAM( ")" ) ) ) + { + if ( sPrefix == String( RTL_CONSTASCII_USTRINGPARAM( "(" ) ) ) + nMappedNumType = 0xa0001; // (A) + else + nMappedNumType = 0xb0001; // A) + } + else + nMappedNumType = 0x10001; // A. + } + break; + case SVX_NUM_CHARS_LOWER_LETTER : + case SVX_NUM_CHARS_LOWER_LETTER_N : + { + if ( sSuffix == String( RTL_CONSTASCII_USTRINGPARAM( ")" ) ) ) + { + if ( sPrefix == String( RTL_CONSTASCII_USTRINGPARAM( "(" ) ) ) + nMappedNumType = 0x80001; // (a) + else + nMappedNumType = 0x90001; // a) + } + else + nMappedNumType = 0x00001; // a. + } + break; + case SVX_NUM_ROMAN_UPPER : + { + if ( sSuffix == String( RTL_CONSTASCII_USTRINGPARAM( ")" ) ) ) + { + if ( sPrefix == String( RTL_CONSTASCII_USTRINGPARAM( "(" ) ) ) + nMappedNumType = 0xe0001; // (I) + else + nMappedNumType = 0xf0001; // I) + } + else + nMappedNumType = 0x70001; // I. + } + break; + case SVX_NUM_ROMAN_LOWER : + { + if ( sSuffix == String( RTL_CONSTASCII_USTRINGPARAM( ")" ) ) ) + { + if ( sPrefix == String( RTL_CONSTASCII_USTRINGPARAM( "(" ) ) ) + nMappedNumType = 0x40001; // (i) + else + nMappedNumType = 0x50001; // i) + } + else + nMappedNumType = 0x60001; // i. + } + break; + case SVX_NUM_ARABIC : + { + if ( sSuffix == String( RTL_CONSTASCII_USTRINGPARAM( ")" ) ) ) + { + if ( sPrefix == String( RTL_CONSTASCII_USTRINGPARAM( "(" ) ) ) + nMappedNumType = 0xc0001; // (1) + else + nMappedNumType = 0x20001; // 1) + } + else + { + if ( ! ( sSuffix.Len() + sPrefix.Len() ) ) + nMappedNumType = 0xd0001; // 1 + else + nMappedNumType = 0x30001; // 1. + } + } + break; + default: + break; + } + } + nParaFlags |= 0x2f; + nBulletFlags |= 6; + if ( mbIsBullet && bNumberingIsNumber ) + nBulletFlags |= 1; + } + } + } + } + } + nBulletOfs = nTextOfs + nBulletOfs; + if ( nBulletOfs < 0 ) + nBulletOfs = 0; +} + +void ParagraphObj::ImplGetParagraphValues( PPTExBulletProvider& rBuProv, sal_Bool bGetPropStateValue ) +{ + static String sNumberingLevel ( RTL_CONSTASCII_USTRINGPARAM( "NumberingLevel" ) ); + + ::com::sun::star::uno::Any aAny; + if ( GetPropertyValue( aAny, mXPropSet, sNumberingLevel, sal_True ) ) + { + if ( bGetPropStateValue ) + meBullet = GetPropertyState( mXPropSet, sNumberingLevel ); + nDepth = *( (sal_Int16*)aAny.getValue() ); + + if ( nDepth < 0 ) + { + mbIsBullet = sal_False; + nDepth = 0; + } + else + { + if ( nDepth > 4 ) + nDepth = 4; + mbIsBullet = sal_True; + } + } + else + { + nDepth = 0; + mbIsBullet = sal_False; + } + ImplGetNumberingLevel( rBuProv, nDepth, mbIsBullet, bGetPropStateValue ); + + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "ParaTabStops" ) ), bGetPropStateValue ) ) + maTabStop = *( ::com::sun::star::uno::Sequence< ::com::sun::star::style::TabStop>*)mAny.getValue(); + sal_Int16 eTextAdjust( ::com::sun::star::style::ParagraphAdjust_LEFT ); + if ( GetPropertyValue( aAny, mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "ParaAdjust" ) ), bGetPropStateValue ) ) + aAny >>= eTextAdjust; + switch ( (::com::sun::star::style::ParagraphAdjust)eTextAdjust ) + { + case ::com::sun::star::style::ParagraphAdjust_CENTER : + mnTextAdjust = 1; + break; + case ::com::sun::star::style::ParagraphAdjust_RIGHT : + mnTextAdjust = 2; + break; + case ::com::sun::star::style::ParagraphAdjust_BLOCK : + mnTextAdjust = 3; + break; + default : + case ::com::sun::star::style::ParagraphAdjust_LEFT : + mnTextAdjust = 0; + break; + } + meTextAdjust = ePropState; + + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "ParaLineSpacing" ) ), bGetPropStateValue ) ) + { + ::com::sun::star::style::LineSpacing aLineSpacing + = *( (::com::sun::star::style::LineSpacing*)mAny.getValue() ); + switch ( aLineSpacing.Mode ) + { + case ::com::sun::star::style::LineSpacingMode::MINIMUM : + case ::com::sun::star::style::LineSpacingMode::LEADING : + case ::com::sun::star::style::LineSpacingMode::FIX : + mnLineSpacing = (sal_Int16)(-( aLineSpacing.Height ) ); + break; + + case ::com::sun::star::style::LineSpacingMode::PROP : + default: + mnLineSpacing = (sal_Int16)( aLineSpacing.Height ); + break; + } + } + meLineSpacing = ePropState; + + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "ParaBottomMargin" ) ), bGetPropStateValue ) ) + { + double fSpacing = *( (sal_uInt32*)mAny.getValue() ) + ( 2540.0 / 576.0 ) - 1; + mnLineSpacingBottom = (sal_Int16)(-( fSpacing * 576.0 / 2540.0 ) ); + } + meLineSpacingBottom = ePropState; + + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "ParaTopMargin" ) ), bGetPropStateValue ) ) + { + double fSpacing = *( (sal_uInt32*)mAny.getValue() ) + ( 2540.0 / 576.0 ) - 1; + mnLineSpacingTop = (sal_Int16)(-( fSpacing * 576.0 / 2540.0 ) ); + } + meLineSpacingTop = ePropState; + + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "ParaIsForbiddenRules" ) ), bGetPropStateValue ) ) + mAny >>= mbForbiddenRules; + meForbiddenRules = ePropState; + + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "ParaIsHangingPunctuation" ) ), bGetPropStateValue ) ) + mAny >>= mbParagraphPunctation; + meParagraphPunctation = ePropState; + + mnBiDi = 0; + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "WritingMode" ) ), bGetPropStateValue ) ) + { + sal_Int16 nWritingMode; + mAny >>= nWritingMode; + + SvxFrameDirection eWritingMode( (SvxFrameDirection)nWritingMode ); + if ( ( eWritingMode == FRMDIR_HORI_RIGHT_TOP ) + || ( eWritingMode == FRMDIR_VERT_TOP_RIGHT ) ) + { + mnBiDi = 1; + } + } + meBiDi = ePropState; +} + +void ParagraphObj::ImplConstruct( ParagraphObj& rParagraphObj ) +{ + mnTextSize = rParagraphObj.mnTextSize; + mnTextAdjust = rParagraphObj.mnTextAdjust; + mnLineSpacing = rParagraphObj.mnLineSpacing; + mnLineSpacingTop = rParagraphObj.mnLineSpacingTop; + mnLineSpacingBottom = rParagraphObj.mnLineSpacingBottom; + mbFirstParagraph = rParagraphObj.mbFirstParagraph; + mbLastParagraph = rParagraphObj.mbLastParagraph; + mbParagraphPunctation = rParagraphObj.mbParagraphPunctation; + mbForbiddenRules = rParagraphObj.mbForbiddenRules; + mnBiDi = rParagraphObj.mnBiDi; + + for ( void* pPtr = rParagraphObj.First(); pPtr; pPtr = rParagraphObj.Next() ) + Insert( new PortionObj( *(PortionObj*)pPtr ), LIST_APPEND ); + + maTabStop = rParagraphObj.maTabStop; + bExtendedParameters = rParagraphObj.bExtendedParameters; + nParaFlags = rParagraphObj.nParaFlags; + nBulletFlags = rParagraphObj.nBulletFlags; + sPrefix = rParagraphObj.sPrefix; + sSuffix = rParagraphObj.sSuffix; + sGraphicUrl = rParagraphObj.sGraphicUrl; // String auf eine Graphic + aBuGraSize = rParagraphObj.aBuGraSize; + nNumberingType = rParagraphObj.nNumberingType; // in wirlichkeit ist dies ein SvxEnum + nHorzAdjust = rParagraphObj.nHorzAdjust; + nBulletColor = rParagraphObj.nBulletColor; + nBulletOfs = rParagraphObj.nBulletOfs; + nStartWith = rParagraphObj.nStartWith; // Start der nummerierung + nTextOfs = rParagraphObj.nTextOfs; + nBulletRealSize = rParagraphObj.nBulletRealSize; // GroessenVerhaeltnis in Proz + nDepth = rParagraphObj.nDepth; // aktuelle tiefe + cBulletId = rParagraphObj.cBulletId; // wenn Numbering Type == CharSpecial + aFontDesc = rParagraphObj.aFontDesc; + + bExtendedBulletsUsed = rParagraphObj.bExtendedBulletsUsed; + nBulletId = rParagraphObj.nBulletId; +} + +::com::sun::star::awt::Size ParagraphObj::ImplMapSize( const ::com::sun::star::awt::Size& rSize ) +{ + Size aSize( OutputDevice::LogicToLogic( Size( rSize.Width, rSize.Height ), maMapModeSrc, maMapModeDest ) ); + if ( !aSize.Width() ) + aSize.Width()++; + if ( !aSize.Height() ) + aSize.Height()++; + return ::com::sun::star::awt::Size( aSize.Width(), aSize.Height() ); +} + +sal_uInt32 ParagraphObj::ImplCalculateTextPositions( sal_uInt32 nCurrentTextPosition ) +{ + mnTextSize = 0; + for ( void* pPtr = First(); pPtr; pPtr = Next() ) + mnTextSize += ((PortionObj*)pPtr)->ImplCalculateTextPositions( nCurrentTextPosition + mnTextSize ); + return mnTextSize; +} + +ParagraphObj& ParagraphObj::operator=( ParagraphObj& rParagraphObj ) +{ + if ( this != &rParagraphObj ) + { + ImplClear(); + ImplConstruct( rParagraphObj ); + } + return *this; +} + +// ----------------------------------------------------------------------- + +ImplTextObj::ImplTextObj( int nInstance ) +{ + mnRefCount = 1; + mnTextSize = 0; + mnInstance = nInstance; + mpList = new List; + mbHasExtendedBullets = FALSE; + mbFixedCellHeightUsed = FALSE; +} + +ImplTextObj::~ImplTextObj() +{ + for ( ParagraphObj* pPtr = (ParagraphObj*)mpList->First(); pPtr; pPtr = (ParagraphObj*)mpList->Next() ) + delete pPtr; + delete mpList; +} + +TextObj::TextObj( ::com::sun::star::uno::Reference< ::com::sun::star::text::XSimpleText > & rXTextRef, + int nInstance, FontCollection& rFontCollection, PPTExBulletProvider& rProv ) +{ + mpImplTextObj = new ImplTextObj( nInstance ); + + ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumerationAccess > + aXTextParagraphEA( rXTextRef, ::com::sun::star::uno::UNO_QUERY ); + + if ( aXTextParagraphEA.is() ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration > + aXTextParagraphE( aXTextParagraphEA->createEnumeration() ); + if ( aXTextParagraphE.is() ) + { + ParaFlags aParaFlags; + while ( aXTextParagraphE->hasMoreElements() ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextContent > aXParagraph; + ::com::sun::star::uno::Any aAny( aXTextParagraphE->nextElement() ); + if ( aAny >>= aXParagraph ) + { + if ( !aXTextParagraphE->hasMoreElements() ) + aParaFlags.bLastParagraph = TRUE; + ParagraphObj* pPara = new ParagraphObj( aXParagraph, aParaFlags, rFontCollection, rProv ); + mpImplTextObj->mbHasExtendedBullets |= pPara->bExtendedBulletsUsed; + mpImplTextObj->mpList->Insert( pPara, LIST_APPEND ); + aParaFlags.bFirstParagraph = FALSE; + } + } + } + } + ImplCalculateTextPositions(); +} + +TextObj::TextObj( TextObj& rTextObj ) +{ + mpImplTextObj = rTextObj.mpImplTextObj; + mpImplTextObj->mnRefCount++; +} + +TextObj::~TextObj() +{ + if ( ! ( --mpImplTextObj->mnRefCount ) ) + delete mpImplTextObj; +} + +void TextObj::Write( SvStream* pStrm ) +{ + sal_uInt32 nSize, nPos = pStrm->Tell(); + *pStrm << (sal_uInt32)( EPP_TextCharsAtom << 16 ) << (sal_uInt32)0; + for ( void* pPtr = First(); pPtr; pPtr = Next() ) + ((ParagraphObj*)pPtr)->Write( pStrm ); + nSize = pStrm->Tell() - nPos; + pStrm->SeekRel( - ( (sal_Int32)nSize - 4 ) ); + *pStrm << (sal_uInt32)( nSize - 8 ); + pStrm->SeekRel( nSize - 8 ); +} + +void TextObj::ImplCalculateTextPositions() +{ + mpImplTextObj->mnTextSize = 0; + for ( void* pPtr = First(); pPtr; pPtr = Next() ) + mpImplTextObj->mnTextSize += ((ParagraphObj*)pPtr)->ImplCalculateTextPositions( mpImplTextObj->mnTextSize ); +} + +TextObj& TextObj::operator=( TextObj& rTextObj ) +{ + if ( this != &rTextObj ) + { + if ( ! ( --mpImplTextObj->mnRefCount ) ) + delete mpImplTextObj; + mpImplTextObj = rTextObj.mpImplTextObj; + mpImplTextObj->mnRefCount++; + } + return *this; +} + +void TextObj::WriteTextSpecInfo( SvStream* pStrm ) +{ + sal_uInt32 nCharactersLeft( Count() ); + if ( nCharactersLeft >= 1 ) + { + EscherExAtom aAnimationInfoAtom( *pStrm, EPP_TextSpecInfoAtom, 0, 0 ); + for ( ParagraphObj* pPtr = static_cast < ParagraphObj * >( First() ); nCharactersLeft && pPtr; pPtr = static_cast< ParagraphObj* >( Next() ) ) + { + for ( PortionObj* pPortion = static_cast< PortionObj* >( pPtr->First() ); nCharactersLeft && pPortion; pPortion = static_cast< PortionObj* >( pPtr->Next() ) ) + { + sal_Int32 nPortionSize = pPortion->mnTextSize >= nCharactersLeft ? nCharactersLeft : pPortion->mnTextSize; + sal_Int32 nFlags = 7; + nCharactersLeft -= nPortionSize; + *pStrm << static_cast< sal_uInt32 >( nPortionSize ) + << nFlags + << static_cast< sal_Int16 >( 1 ) // spellinfo -> needs rechecking + << static_cast< sal_Int16 >( MsLangId::convertLocaleToLanguageWithFallback( pPortion->meCharLocale ) ) + << static_cast< sal_Int16 >( 0 ); // alt language + } + } + if ( nCharactersLeft ) + *pStrm << nCharactersLeft << static_cast< sal_Int32 >( 1 ) << static_cast< sal_Int16 >( 1 ); + + } +} + +// ----------------------------------------------------------------------- + +void PPTWriter::ImplAdjustFirstLineLineSpacing( TextObj& rTextObj, EscherPropertyContainer& rPropOpt ) +{ + if ( !mbFontIndependentLineSpacing ) + { + ParagraphObj* pPara = rTextObj.First(); + if ( pPara ) + { + PortionObj* pPortion = (PortionObj*)pPara->First(); + if ( pPortion ) + { + sal_Int16 nLineSpacing = pPara->mnLineSpacing; + const FontCollectionEntry* pDesc = maFontCollection.GetById( pPortion->mnFont ); + if ( pDesc ) + nLineSpacing = (sal_Int16)( (double)nLineSpacing * pDesc->Scaling + 0.5 ); + + if ( ( nLineSpacing > 0 ) && ( nLineSpacing < 100 ) ) + { + /* + if ( rxText.is() ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape( rxText, ::com::sun::star::uno::UNO_QUERY ); + if ( xShape.is() ) + { + SdrObject* pObj = GetSdrObjectFromXShape( mXShape ); + if ( pObj ) + { + const OutlinerParaObject* pParaObj = pObj->GetOutlinerParaObject(); + if ( pParaObj ) + { + SdrModel* pModel = pObj->GetModel(); + if ( pModel ) + { + Outliner aOutliner( &pModel->GetItemPool(), pParaObj->GetOutlinerMode() ); + aOutliner.SetText( *pParaObj ); + ULONG nTextHeight = aOutliner.GetLineHeight( 0, 0 ); + if ( nTextHeight ) + { + } + } + } + } + } + } + */ + double fCharHeight = pPortion->mnCharHeight; + fCharHeight *= 2540 / 72; + fCharHeight *= 100 - nLineSpacing; + fCharHeight /= 100; + + sal_uInt32 nUpperDistance = 0; + rPropOpt.GetOpt( ESCHER_Prop_dyTextTop, nUpperDistance ); + nUpperDistance += static_cast< sal_uInt32 >( fCharHeight * 360.0 ); + rPropOpt.AddOpt( ESCHER_Prop_dyTextTop, nUpperDistance ); + } + } + } + } +} + +// ----------------------------------------------------------------------- + +void PPTWriter::ImplWriteTextStyleAtom( SvStream& rOut, int nTextInstance, sal_uInt32 nAtomInstance, + TextRuleEntry* pTextRule, SvStream& rExtBuStr, EscherPropertyContainer* pPropOpt ) +{ + PPTExParaSheet& rParaSheet = mpStyleSheet->GetParaSheet( nTextInstance ); + + rOut << (sal_uInt32)( ( EPP_TextHeaderAtom << 16 ) | ( nAtomInstance << 4 ) ) << (sal_uInt32)4 + << nTextInstance; + + if ( mbEmptyPresObj ) + mnTextSize = 0; + if ( !mbEmptyPresObj ) + { + ParagraphObj* pPara; + TextObj aTextObj( mXText, nTextInstance, maFontCollection, (PPTExBulletProvider&)*this ); + + // leaving out EPP_TextCharsAtom w/o text - still write out + // attribute info though + if ( mnTextSize ) + aTextObj.Write( &rOut ); + + if ( pPropOpt ) + ImplAdjustFirstLineLineSpacing( aTextObj, *pPropOpt ); + + sal_uInt32 nSize, nPos = rOut.Tell(); + + rOut << (sal_uInt32)( EPP_StyleTextPropAtom << 16 ) << (sal_uInt32)0; + ImplWriteParagraphs( rOut, aTextObj ); + ImplWritePortions( rOut, aTextObj ); + nSize = rOut.Tell() - nPos; + rOut.SeekRel( - ( (sal_Int32)nSize - 4 ) ); + rOut << (sal_uInt32)( nSize - 8 ); + rOut.SeekRel( nSize - 8 ); + + for ( pPara = aTextObj.First(); pPara; pPara = aTextObj.Next() ) + { + for ( PortionObj* pPortion = (PortionObj*)pPara->First(); pPortion; pPortion = (PortionObj*)pPara->Next() ) + { + if ( pPortion->mpFieldEntry ) + { + const FieldEntry* pFieldEntry = pPortion->mpFieldEntry; + + switch ( pFieldEntry->nFieldType >> 28 ) + { + case 1 : + case 2 : + { + rOut << (sal_uInt32)( EPP_DateTimeMCAtom << 16 ) << (sal_uInt32)8 + << (sal_uInt32)( pFieldEntry->nFieldStartPos ) // TxtOffset auf TxtField; + << (sal_uInt8)( pFieldEntry->nFieldType & 0xff ) // Type + << (sal_uInt8)0 << (sal_uInt16)0; // PadBytes + } + break; + case 3 : + { + rOut << (sal_uInt32)( EPP_SlideNumberMCAtom << 16 ) << (sal_uInt32 ) 4 + << (sal_uInt32)( pFieldEntry->nFieldStartPos ); + } + break; + case 4 : + { + sal_uInt32 nPageIndex = 0; + String aPageUrl; + String aEmpty; + String aFile( pFieldEntry->aFieldUrl ); + INetURLObject aUrl( pFieldEntry->aFieldUrl ); + if ( INET_PROT_FILE == aUrl.GetProtocol() ) + aFile = aUrl.PathToFileName(); + else if ( pFieldEntry->aFieldUrl.GetChar( 0 ) == '#' ) + { + String aPage( INetURLObject::decode( pFieldEntry->aFieldUrl, '%', INetURLObject::DECODE_WITH_CHARSET ) ); + aPage.Erase( 0, 1 ); + for ( String* pStr = (String*)maSlideNameList.First(); pStr; pStr = (String*)maSlideNameList.Next(), nPageIndex++ ) + { + if ( *pStr == aPage ) + { + aPageUrl = UniString::CreateFromInt32( 256 + nPageIndex ); + aPageUrl.Append( String( RTL_CONSTASCII_USTRINGPARAM( "," ) ) ); + aPageUrl.Append( String::CreateFromInt32( nPageIndex + 1 ) ); + aPageUrl.Append( String( RTL_CONSTASCII_USTRINGPARAM( ",Slide " ) ) ); + aPageUrl.Append( String::CreateFromInt32( nPageIndex + 1 ) ); + } + } + } + sal_uInt32 nHyperId; + if ( aPageUrl.Len() ) + nHyperId = ImplInsertBookmarkURL( aPageUrl, 1 | ( nPageIndex << 8 ) | ( 1 << 31 ), pFieldEntry->aRepresentation, aEmpty, aEmpty, aPageUrl ); + else + nHyperId = ImplInsertBookmarkURL( pFieldEntry->aFieldUrl, 2 | ( nHyperId << 8 ), aFile, pFieldEntry->aFieldUrl, aEmpty, aEmpty ); + + rOut << (sal_uInt32)( ( EPP_InteractiveInfo << 16 ) | 0xf ) << (sal_uInt32)24 + << (sal_uInt32)( EPP_InteractiveInfoAtom << 16 ) << (sal_uInt32)16 + << (sal_uInt32)0 // soundref + << nHyperId // hyperlink id + << (sal_uInt8)4 // hyperlink action + << (sal_uInt8)0 // ole verb + << (sal_uInt8)0 // jump + << (sal_uInt8)0 // flags + << (sal_uInt8)8 // hyperlink type ? + << (sal_uInt8)0 << (sal_uInt8)0 << (sal_uInt8)0 + << (sal_uInt32)( EPP_TxInteractiveInfoAtom << 16 ) << (sal_uInt32)8 + << (sal_uInt32)( pFieldEntry->nFieldStartPos ) + << (sal_uInt32)( pFieldEntry->nFieldEndPos ); + } + break; + case 5 : + { + rOut << (sal_uInt32)( EPP_GenericDateMCAtom << 16 ) << (sal_uInt32)4 + << (sal_uInt32)( pFieldEntry->nFieldStartPos ); + } + break; + case 6 : + { + rOut << (sal_uInt32)( EPP_HeaderMCAtom << 16 ) << (sal_uInt32 ) 4 + << (sal_uInt32)( pFieldEntry->nFieldStartPos ); + } + break; + case 7 : + { + rOut << (sal_uInt32)( EPP_FooterMCAtom << 16 ) << (sal_uInt32 ) 4 + << (sal_uInt32)( pFieldEntry->nFieldStartPos ); + } + break; + default: + break; + } + } + } + } + + aTextObj.WriteTextSpecInfo( &rOut ); + + // Star Office Default TabSizes schreiben ( wenn noetig ) + pPara = aTextObj.First(); + if ( pPara ) + { + sal_uInt32 nParaFlags = 0x1f; + sal_Int16 nDepth, nMask, nNumberingRule[ 10 ]; + sal_uInt32 nTextOfs = pPara->nTextOfs; + sal_uInt32 nTabs = pPara->maTabStop.getLength(); + const ::com::sun::star::style::TabStop* pTabStop = ( const ::com::sun::star::style::TabStop* )pPara->maTabStop.getConstArray(); + + for ( ; pPara; pPara = aTextObj.Next() ) + { + if ( pPara->bExtendedParameters ) + { + nDepth = pPara->nDepth; + if ( nDepth < 5 ) + { + nMask = 1 << nDepth; + if ( nParaFlags & nMask ) + { + nParaFlags &=~ nMask; + if ( ( rParaSheet.maParaLevel[ nDepth ].mnTextOfs != pPara->nTextOfs ) || + ( rParaSheet.maParaLevel[ nDepth ].mnBulletOfs != pPara->nBulletOfs ) ) + { + nParaFlags |= nMask << 16; + nNumberingRule[ nDepth << 1 ] = pPara->nTextOfs; + nNumberingRule[ ( nDepth << 1 ) + 1 ] = (sal_Int16)pPara->nBulletOfs; + } + } + } + } + } + nParaFlags >>= 16; + + sal_uInt32 nDefaultTabSize = ImplMapSize( ::com::sun::star::awt::Size( 2011, 1 ) ).Width; + sal_uInt32 nDefaultTabs = abs( maRect.GetWidth() ) / nDefaultTabSize; + if ( nTabs ) + nDefaultTabs -= (sal_Int32)( ( ( pTabStop[ nTabs - 1 ].Position / 4.40972 ) + nTextOfs ) / nDefaultTabSize ); + if ( (sal_Int32)nDefaultTabs < 0 ) + nDefaultTabs = 0; + + sal_uInt32 nTabCount = nTabs + nDefaultTabs; + sal_uInt32 i, nTextRulerAtomFlags = 0; + + if ( nTabCount ) + nTextRulerAtomFlags |= 4; + if ( nParaFlags ) + nTextRulerAtomFlags |= ( ( nParaFlags << 3 ) | ( nParaFlags << 8 ) ); + + if ( nTextRulerAtomFlags ) + { + SvStream* pRuleOut = &rOut; + if ( pTextRule ) + pRuleOut = pTextRule->pOut = new SvMemoryStream( 0x100, 0x100 ); + + sal_uInt32 nRulePos = pRuleOut->Tell(); + *pRuleOut << (sal_uInt32)( EPP_TextRulerAtom << 16 ) << (sal_uInt32)0; + *pRuleOut << nTextRulerAtomFlags; + if ( nTextRulerAtomFlags & 4 ) + { + *pRuleOut << (sal_uInt16)nTabCount; + for ( i = 0; i < nTabs; i++ ) + { + sal_uInt16 nPosition = (sal_uInt16)( ( pTabStop[ i ].Position / 4.40972 ) + nTextOfs ); + sal_uInt16 nType; + switch ( pTabStop[ i ].Alignment ) + { + case ::com::sun::star::style::TabAlign_DECIMAL : nType = 3; break; + case ::com::sun::star::style::TabAlign_RIGHT : nType = 2; break; + case ::com::sun::star::style::TabAlign_CENTER : nType = 1; break; + + case ::com::sun::star::style::TabAlign_LEFT : + default: nType = 0; + }; + *pRuleOut << nPosition + << nType; + } + + sal_uInt32 nWidth = 1; + if ( nTabs ) + nWidth += (sal_Int32)( ( ( pTabStop[ nTabs - 1 ].Position / 4.40972 + nTextOfs ) / nDefaultTabSize ) ); + nWidth *= nDefaultTabSize; + for ( i = 0; i < nDefaultTabs; i++, nWidth += nDefaultTabSize ) + *pRuleOut << nWidth; + } + for ( i = 0; i < 5; i++ ) + { + if ( nTextRulerAtomFlags & ( 8 << i ) ) + *pRuleOut << nNumberingRule[ i << 1 ]; + if ( nTextRulerAtomFlags & ( 256 << i ) ) + *pRuleOut << nNumberingRule[ ( i << 1 ) + 1 ]; + } + sal_uInt32 nBufSize = pRuleOut->Tell() - nRulePos; + pRuleOut->SeekRel( - ( (sal_Int32)nBufSize - 4 ) ); + *pRuleOut << (sal_uInt32)( nBufSize - 8 ); + pRuleOut->SeekRel( nBufSize - 8 ); + } + } + if ( aTextObj.HasExtendedBullets() ) + { + ParagraphObj* pBulletPara = aTextObj.First(); + if ( pBulletPara ) + { + sal_uInt32 nBulletFlags = 0; + sal_uInt32 nNumberingType = 0, nPos2 = rExtBuStr.Tell(); + + rExtBuStr << (sal_uInt32)( EPP_PST_ExtendedParagraphAtom << 16 ) << (sal_uInt32)0; + + for ( ; pBulletPara; pBulletPara = aTextObj.Next() ) + { + nBulletFlags = 0; + sal_uInt16 nBulletId = pBulletPara->nBulletId; + if ( pBulletPara->bExtendedBulletsUsed ) + { + nBulletFlags = 0x800000; + if ( pBulletPara->nNumberingType != SVX_NUM_BITMAP ) + nBulletFlags = 0x3000000; + } + rExtBuStr << (sal_uInt32)nBulletFlags; + + if ( nBulletFlags & 0x800000 ) + rExtBuStr << nBulletId; + if ( nBulletFlags & 0x1000000 ) + { + switch( pBulletPara->nNumberingType ) + { + case SVX_NUM_NUMBER_NONE : + case SVX_NUM_CHAR_SPECIAL : + nNumberingType = 0; + break; + case SVX_NUM_CHARS_UPPER_LETTER : + case SVX_NUM_CHARS_UPPER_LETTER_N : + case SVX_NUM_CHARS_LOWER_LETTER : + case SVX_NUM_CHARS_LOWER_LETTER_N : + case SVX_NUM_ROMAN_UPPER : + case SVX_NUM_ROMAN_LOWER : + case SVX_NUM_ARABIC : + nNumberingType = pBulletPara->nMappedNumType; + break; + + // case SVX_NUM_PAGEDESC : + case SVX_NUM_BITMAP : + nNumberingType = 0; + break; + + } + rExtBuStr << (sal_uInt32)nNumberingType; + } + if ( nBulletFlags & 0x2000000 ) + rExtBuStr << (sal_uInt16)pBulletPara->nStartWith; + rExtBuStr << (sal_uInt32)0 << (sal_uInt32)0; + } + sal_uInt32 nBulletSize = ( rExtBuStr.Tell() - nPos2 ) - 8; + rExtBuStr.SeekRel( - ( (sal_Int32)nBulletSize + 4 ) ); + rExtBuStr << nBulletSize; + rExtBuStr.SeekRel( nBulletSize ); + } + } + } +} + +// ----------------------------------------------------------------------- + +void PPTWriter::ImplWriteObjectEffect( SvStream& rSt, + ::com::sun::star::presentation::AnimationEffect eAe, + ::com::sun::star::presentation::AnimationEffect eTe, + sal_uInt16 nOrder ) +{ + EscherExContainer aAnimationInfo( rSt, EPP_AnimationInfo ); + EscherExAtom aAnimationInfoAtom( rSt, EPP_AnimationInfoAtom, 0, 1 ); + sal_uInt32 nDimColor = 0x7000000; // color to use for dimming + sal_uInt32 nFlags = 0x4400; // set of flags that determine type of build + sal_uInt32 nSoundRef = 0; // 0 if storage is from clipboard. Otherwise index(ID) in SoundCollection list. + sal_uInt32 nDelayTime = 0; // delay before playing object + sal_uInt16 nSlideCount = 1; // number of slides to play object + UINT8 nBuildType = 1; // type of build + UINT8 nFlyMethod = 0; // animation effect( fly, zoom, appear, etc ) + UINT8 nFlyDirection = 0; // Animation direction( left, right, up, down, etc ) + UINT8 nAfterEffect = 0; // what to do after build + UINT8 nSubEffect = 0; // build by word or letter + UINT8 nOleVerb = 0; // Determines object's class (sound, video, other) + + if ( eAe == ::com::sun::star::presentation::AnimationEffect_NONE ) + { + nBuildType = 0; + eAe = eTe; + } + switch ( eAe ) + { + case ::com::sun::star::presentation::AnimationEffect_NONE : + break; + case ::com::sun::star::presentation::AnimationEffect_FADE_FROM_LEFT : + { + nFlyDirection = 2; + nFlyMethod = 10; + } + break; + case ::com::sun::star::presentation::AnimationEffect_FADE_FROM_TOP : + { + nFlyDirection = 3; + nFlyMethod = 10; + } + break; + case ::com::sun::star::presentation::AnimationEffect_FADE_FROM_RIGHT : + { + nFlyDirection = 0; + nFlyMethod = 10; + } + break; + case ::com::sun::star::presentation::AnimationEffect_FADE_FROM_BOTTOM : + { + nFlyDirection = 1; + nFlyMethod = 10; + } + break; + case ::com::sun::star::presentation::AnimationEffect_FADE_TO_CENTER : + { + nFlyDirection = 1; + nFlyMethod = 11; + } + break; + case ::com::sun::star::presentation::AnimationEffect_FADE_FROM_CENTER : + { + nFlyDirection = 0; + nFlyMethod = 11; + } + break; + case ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_LEFT : + { + nFlyDirection = 0; + nFlyMethod = 12; + } + break; + case ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_TOP : + { + nFlyDirection = 1; + nFlyMethod = 12; + } + break; + case ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_RIGHT : + { + nFlyDirection = 2; + nFlyMethod = 12; + } + break; + case ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_BOTTOM : + { + nFlyDirection = 3; + nFlyMethod = 12; + } + break; + case ::com::sun::star::presentation::AnimationEffect_VERTICAL_STRIPES : + { + nFlyDirection = 0; + nFlyMethod = 2; + } + break; + case ::com::sun::star::presentation::AnimationEffect_HORIZONTAL_STRIPES : + { + nFlyDirection = 1; + nFlyMethod = 2; + } + break; + case ::com::sun::star::presentation::AnimationEffect_CLOCKWISE : + { + nFlyDirection = 1; + nFlyMethod = 3; + } + break; + case ::com::sun::star::presentation::AnimationEffect_COUNTERCLOCKWISE : + { + nFlyDirection = 0; + nFlyMethod = 3; + } + break; + case ::com::sun::star::presentation::AnimationEffect_FADE_FROM_UPPERLEFT : + { + nFlyDirection = 7; + nFlyMethod = 9; + } + break; + case ::com::sun::star::presentation::AnimationEffect_FADE_FROM_UPPERRIGHT : + { + nFlyDirection = 6; + nFlyMethod = 9; + } + break; + case ::com::sun::star::presentation::AnimationEffect_FADE_FROM_LOWERLEFT : + { + nFlyDirection = 5; + nFlyMethod = 9; + } + break; + case ::com::sun::star::presentation::AnimationEffect_FADE_FROM_LOWERRIGHT : + { + nFlyDirection = 4; + nFlyMethod = 9; + } + break; + case ::com::sun::star::presentation::AnimationEffect_CLOSE_VERTICAL : + { + nFlyDirection = 1; + nFlyMethod = 13; + } + break; + case ::com::sun::star::presentation::AnimationEffect_CLOSE_HORIZONTAL : + { + nFlyDirection = 3; + nFlyMethod = 13; + } + break; + case ::com::sun::star::presentation::AnimationEffect_OPEN_VERTICAL : + { + nFlyDirection = 0; + nFlyMethod = 13; + } + break; + case ::com::sun::star::presentation::AnimationEffect_OPEN_HORIZONTAL : + { + nFlyDirection = 2; + nFlyMethod = 13; + } + break; + case ::com::sun::star::presentation::AnimationEffect_PATH : + { + nFlyDirection = 28; + nFlyMethod = 12; + } + break; + case ::com::sun::star::presentation::AnimationEffect_MOVE_TO_LEFT : + { + nFlyDirection = 0; + nFlyMethod = 1; + } + break; + case ::com::sun::star::presentation::AnimationEffect_MOVE_TO_TOP : + { + nFlyDirection = 0; + nFlyMethod = 1; + } + break; + case ::com::sun::star::presentation::AnimationEffect_MOVE_TO_RIGHT : + { + nFlyDirection = 0; + nFlyMethod = 1; + } + break; + case ::com::sun::star::presentation::AnimationEffect_MOVE_TO_BOTTOM : + { + nFlyDirection = 0; + nFlyMethod = 1; + } + break; + case ::com::sun::star::presentation::AnimationEffect_SPIRALIN_LEFT : + case ::com::sun::star::presentation::AnimationEffect_SPIRALIN_RIGHT : + case ::com::sun::star::presentation::AnimationEffect_SPIRALOUT_LEFT : + case ::com::sun::star::presentation::AnimationEffect_SPIRALOUT_RIGHT : + { + nFlyDirection = 0x1c; + nFlyMethod = 0xc; + } + break; + case ::com::sun::star::presentation::AnimationEffect_DISSOLVE : + { + nFlyDirection = 0; + nFlyMethod = 5; + } + break; + case ::com::sun::star::presentation::AnimationEffect_WAVYLINE_FROM_LEFT : + { + nFlyDirection = 2; + nFlyMethod = 10; + } + break; + case ::com::sun::star::presentation::AnimationEffect_WAVYLINE_FROM_TOP : + { + nFlyDirection = 3; + nFlyMethod = 10; + } + break; + case ::com::sun::star::presentation::AnimationEffect_WAVYLINE_FROM_RIGHT : + { + nFlyDirection = 0; + nFlyMethod = 10; + } + break; + case ::com::sun::star::presentation::AnimationEffect_WAVYLINE_FROM_BOTTOM : + { + nFlyDirection = 1; + nFlyMethod = 10; + } + break; + case ::com::sun::star::presentation::AnimationEffect_RANDOM : + { + nFlyDirection = 0; + nFlyMethod = 1; + } + break; + case ::com::sun::star::presentation::AnimationEffect_VERTICAL_LINES : + { + nFlyDirection = 1; + nFlyMethod = 8; + } + break; + case ::com::sun::star::presentation::AnimationEffect_HORIZONTAL_LINES : + { + nFlyDirection = 0; + nFlyMethod = 8; + } + break; + case ::com::sun::star::presentation::AnimationEffect_LASER_FROM_LEFT : + { + nFlyDirection = 2; + nFlyMethod = 10; + } + break; + case ::com::sun::star::presentation::AnimationEffect_LASER_FROM_TOP : + { + nFlyDirection = 3; + nFlyMethod = 10; + } + break; + case ::com::sun::star::presentation::AnimationEffect_LASER_FROM_RIGHT : + { + nFlyDirection = 0; + nFlyMethod = 10; + } + break; + case ::com::sun::star::presentation::AnimationEffect_LASER_FROM_BOTTOM : + { + nFlyDirection = 1; + nFlyMethod = 10; + } + break; + case ::com::sun::star::presentation::AnimationEffect_LASER_FROM_UPPERLEFT : + { + nFlyDirection = 7; + nFlyMethod = 9; + } + break; + case ::com::sun::star::presentation::AnimationEffect_LASER_FROM_UPPERRIGHT : + { + nFlyDirection = 6; + nFlyMethod = 9; + } + break; + case ::com::sun::star::presentation::AnimationEffect_LASER_FROM_LOWERLEFT : + { + nFlyDirection = 5; + nFlyMethod = 9; + } + break; + case ::com::sun::star::presentation::AnimationEffect_LASER_FROM_LOWERRIGHT : + { + nFlyDirection = 4; + nFlyMethod = 9; + } + break; + case ::com::sun::star::presentation::AnimationEffect_APPEAR : + break; + case ::com::sun::star::presentation::AnimationEffect_HIDE : + { + nFlyDirection = 0; + nFlyMethod = 1; + } + break; + case ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_UPPERLEFT : + { + nFlyDirection = 4; + nFlyMethod = 12; + } + break; + case ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_UPPERRIGHT : + { + nFlyDirection = 5; + nFlyMethod = 12; + } + break; + case ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_LOWERRIGHT : + { + nFlyDirection = 7; + nFlyMethod = 12; + } + break; + case ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_LOWERLEFT : + { + nFlyDirection = 6; + nFlyMethod = 12; + } + break; + case ::com::sun::star::presentation::AnimationEffect_MOVE_TO_UPPERLEFT : + case ::com::sun::star::presentation::AnimationEffect_MOVE_TO_UPPERRIGHT : + case ::com::sun::star::presentation::AnimationEffect_MOVE_TO_LOWERRIGHT : + case ::com::sun::star::presentation::AnimationEffect_MOVE_TO_LOWERLEFT : + nAfterEffect |= 2; + break; + case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_LEFT : + case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_UPPERLEFT : + { + nFlyDirection = 8; + nFlyMethod = 12; + } + break; + case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_TOP : + case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_UPPERRIGHT : + { + nFlyDirection = 11; + nFlyMethod = 12; + } + break; + case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_RIGHT : + case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_LOWERRIGHT : + { + nFlyDirection = 10; + nFlyMethod = 12; + } + break; + case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_BOTTOM : + case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_LOWERLEFT : + { + nFlyDirection = 9; + nFlyMethod = 12; + } + break; + case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_TO_LEFT : + case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_TO_UPPERLEFT : + case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_TO_TOP : + case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_TO_UPPERRIGHT : + case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_TO_RIGHT : + case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_TO_LOWERRIGHT : + case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_TO_BOTTOM : + case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_TO_LOWERLEFT : + nAfterEffect |= 2; + break; + case ::com::sun::star::presentation::AnimationEffect_VERTICAL_CHECKERBOARD : + { + nFlyDirection = 1; + nFlyMethod = 3; + } + break; + case ::com::sun::star::presentation::AnimationEffect_HORIZONTAL_CHECKERBOARD : + { + nFlyDirection = 0; + nFlyMethod = 3; + } + break; + case ::com::sun::star::presentation::AnimationEffect_HORIZONTAL_ROTATE : + case ::com::sun::star::presentation::AnimationEffect_VERTICAL_ROTATE : + { + nFlyDirection = 27; + nFlyMethod = 12; + } + break; + case ::com::sun::star::presentation::AnimationEffect_HORIZONTAL_STRETCH : + case ::com::sun::star::presentation::AnimationEffect_VERTICAL_STRETCH : + { + nFlyDirection = 22; + nFlyMethod = 12; + } + break; + case ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_LEFT : + case ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_UPPERLEFT : + { + nFlyDirection = 23; + nFlyMethod = 12; + } + break; + case ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_TOP : + case ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_UPPERRIGHT : + { + nFlyDirection = 24; + nFlyMethod = 12; + } + break; + case ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_RIGHT : + case ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_LOWERRIGHT : + { + nFlyDirection = 25; + nFlyMethod = 12; + } + break; + case ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_BOTTOM : + case ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_LOWERLEFT : + { + nFlyDirection = 26; + nFlyMethod = 12; + } + break; + case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN : + { + nFlyDirection = 16; + nFlyMethod = 12; + } + break; + case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_SMALL : + case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_SPIRAL : + { + nFlyDirection = 17; + nFlyMethod = 12; + } + break; + case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT : + { + nFlyDirection = 18; + nFlyMethod = 12; + } + break; + case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_SMALL : + case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_SPIRAL : + { + nFlyDirection = 19; + nFlyMethod = 12; + } + break; + case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_FROM_LEFT : + case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_FROM_UPPERLEFT : + case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_FROM_TOP : + case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_FROM_UPPERRIGHT : + case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_FROM_RIGHT : + case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_FROM_LOWERRIGHT : + case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_FROM_BOTTOM : + case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_FROM_LOWERLEFT : + case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_FROM_CENTER : + { + nFlyDirection = 16; + nFlyMethod = 12; + } + break; + case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_FROM_LEFT : + case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_FROM_UPPERLEFT : + case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_FROM_TOP : + case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_FROM_UPPERRIGHT : + case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_FROM_RIGHT : + case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_FROM_LOWERRIGHT : + case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_FROM_BOTTOM : + case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_FROM_LOWERLEFT : + case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_FROM_CENTER : + nAfterEffect |= 2; + break; + default: + break; + } + if ( mnDiaMode >= 1 ) + nFlags |= 4; + if ( eTe != ::com::sun::star::presentation::AnimationEffect_NONE ) + nBuildType = 2; + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "SoundOn" ) ) ) ) + { + sal_Bool bBool; + mAny >>= bBool; + if ( bBool ) + { + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "Sound" ) ) ) ) + { + nSoundRef = maSoundCollection.GetId( *(::rtl::OUString*)mAny.getValue() ); + if ( nSoundRef ) + nFlags |= 0x10; + } + } + } + sal_Bool bDimHide = FALSE; + sal_Bool bDimPrevious = FALSE; + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "DimHide" ) ) ) ) + mAny >>= bDimHide; + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "DimPrevious" ) ) ) ) + mAny >>= bDimPrevious; + if ( bDimPrevious ) + nAfterEffect |= 1; + if ( bDimHide ) + nAfterEffect |= 2; + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "DimColor" ) ) ) ) + nDimColor = mpPptEscherEx->GetColor( *((sal_uInt32*)mAny.getValue()) ) | 0xfe000000; + + rSt << nDimColor << nFlags << nSoundRef << nDelayTime + << nOrder // order of build ( 1.. ) + << nSlideCount << nBuildType << nFlyMethod << nFlyDirection + << nAfterEffect << nSubEffect << nOleVerb + << (sal_uInt16)0; // PadWord +} + +// ----------------------------------------------------------------------- + +void PPTWriter::ImplWriteClickAction( SvStream& rSt, ::com::sun::star::presentation::ClickAction eCa, sal_Bool bMediaClickAction ) +{ + sal_uInt32 nSoundRef = 0; // a reference to a sound in the sound collection, or NULL. + sal_uInt32 nHyperLinkID = 0;// a persistent unique identifier to an external hyperlink object (only valid when action == HyperlinkAction). + sal_uInt8 nAction = 0; // Action See Action Table + sal_uInt8 nOleVerb = 0; // OleVerb Only valid when action == OLEAction. OLE verb to use, 0 = first verb, 1 = second verb, etc. + sal_uInt8 nJump = 0; // Jump See Jump Table + sal_uInt8 nFlags = 0; // Bit 1: Animated. If 1, then button is animated + // Bit 2: Stop sound. If 1, then stop current sound when button is pressed. + // Bit 3: CustomShowReturn. If 1, and this is a jump to custom show, then return to this slide after custom show. + sal_uInt8 nHyperLinkType = 0;// HyperlinkType a value from the LinkTo enum, such as LT_URL (only valid when action == HyperlinkAction). + + String aFile; + + /* + Action Table: Action Value + NoAction 0 + MacroAction 1 + RunProgramAction 2 + JumpAction 3 + HyperlinkAction 4 + OLEAction 5 + MediaAction 6 + CustomShowAction 7 + + Jump Table: Jump Value + NoJump 0 + NextSlide, 1 + PreviousSlide, 2 + FirstSlide, 3 + LastSlide, 4 + LastSlideViewed 5 + EndShow 6 + */ + + if ( bMediaClickAction ) + nAction = 6; + else switch( eCa ) + { + case ::com::sun::star::presentation::ClickAction_STOPPRESENTATION : + nJump += 2; + case ::com::sun::star::presentation::ClickAction_LASTPAGE : + nJump++; + case ::com::sun::star::presentation::ClickAction_FIRSTPAGE : + nJump++; + case ::com::sun::star::presentation::ClickAction_PREVPAGE : + nJump++; + case ::com::sun::star::presentation::ClickAction_NEXTPAGE : + { + nJump++; + nAction = 3; + } + break; + case ::com::sun::star::presentation::ClickAction_SOUND : + { + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "Bookmark" ) ) ) ) + nSoundRef = maSoundCollection.GetId( *(::rtl::OUString*)mAny.getValue() ); + } + break; + case ::com::sun::star::presentation::ClickAction_PROGRAM : + { + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "Bookmark" ) ) ) ) + { + INetURLObject aUrl( *(::rtl::OUString*)mAny.getValue() ); + if ( INET_PROT_FILE == aUrl.GetProtocol() ) + { + aFile = aUrl.PathToFileName(); + nAction = 2; + } + } + } + break; + + case ::com::sun::star::presentation::ClickAction_BOOKMARK : + { + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "Bookmark" ) ) ) ) + { + String aBookmark( *(::rtl::OUString*)mAny.getValue() ); + sal_uInt32 nIndex = 0; + for ( String* pStr = (String*)maSlideNameList.First(); pStr; pStr = (String*)maSlideNameList.Next(), nIndex++ ) + { + if ( *pStr == aBookmark ) + { + // Bookmark ist ein link zu einer Dokumentseite + nAction = 4; + nHyperLinkType = 7; + + String aEmpty; + String aHyperString = UniString::CreateFromInt32( 256 + nIndex ); + aHyperString.Append( String( RTL_CONSTASCII_USTRINGPARAM( "," ) ) ); + aHyperString.Append( String::CreateFromInt32( nIndex + 1 ) ); + aHyperString.Append( String( RTL_CONSTASCII_USTRINGPARAM( ",Slide " ) ) ); + aHyperString.Append( String::CreateFromInt32( nIndex + 1 ) ); + nHyperLinkID = ImplInsertBookmarkURL( aHyperString, 1 | ( nIndex << 8 ) | ( 1 << 31 ), aBookmark, aEmpty, aEmpty, aHyperString ); + } + } + } + } + break; + + case ::com::sun::star::presentation::ClickAction_DOCUMENT : + { + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "Bookmark" ) ) ) ) + { + String aBookmark( *(::rtl::OUString*)mAny.getValue() ); + if ( aBookmark.Len() ) + { + nAction = 4; + nHyperLinkType = 8; + + String aEmpty; + String aBookmarkFile( aBookmark ); + INetURLObject aUrl( aBookmark ); + if ( INET_PROT_FILE == aUrl.GetProtocol() ) + aBookmarkFile = aUrl.PathToFileName(); + nHyperLinkID = ImplInsertBookmarkURL( aBookmark, (sal_uInt32)(2 | ( 1 << 31 )), aBookmarkFile, aBookmark, aEmpty, aEmpty ); + } + } + } + break; + + case ::com::sun::star::presentation::ClickAction_INVISIBLE : + case ::com::sun::star::presentation::ClickAction_VERB : + case ::com::sun::star::presentation::ClickAction_VANISH : + case ::com::sun::star::presentation::ClickAction_MACRO : + default : + break; + } + + sal_uInt32 nContainerSize = 24; + if ( nAction == 2 ) + nContainerSize += ( aFile.Len() * 2 ) + 8; + rSt << (sal_uInt32)( ( EPP_InteractiveInfo << 16 ) | 0xf ) << (sal_uInt32)nContainerSize + << (sal_uInt32)( EPP_InteractiveInfoAtom << 16 ) << (sal_uInt32)16 + << nSoundRef + << nHyperLinkID + << nAction + << nOleVerb + << nJump + << nFlags + << (sal_uInt32)nHyperLinkType; + + if ( nAction == 2 ) // run program Action + { + sal_uInt16 i, nLen = aFile.Len(); + rSt << (sal_uInt32)( ( EPP_CString << 16 ) | 0x20 ) << (sal_uInt32)( nLen * 2 ); + for ( i = 0; i < nLen; i++ ) + rSt << aFile.GetChar( i ); + } + + rSt << (sal_uInt32)( ( EPP_InteractiveInfo << 16 ) | 0x1f ) << (sal_uInt32)24 // Mouse Over Action + << (sal_uInt32)( EPP_InteractiveInfo << 16 ) << (sal_uInt32)16; + for ( int i = 0; i < 4; i++, rSt << (sal_uInt32)0 ) ; +} + +// ----------------------------------------------------------------------- + +sal_Bool PPTWriter::ImplGetEffect( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rPropSet, + ::com::sun::star::presentation::AnimationEffect& eEffect, + ::com::sun::star::presentation::AnimationEffect& eTextEffect, + sal_Bool& bIsSound ) +{ + ::com::sun::star::uno::Any aAny; + if ( GetPropertyValue( aAny, rPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Effect" ) ) ) ) + aAny >>= eEffect; + else + eEffect = ::com::sun::star::presentation::AnimationEffect_NONE; + + if ( GetPropertyValue( aAny, rPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextEffect" ) ) ) ) + aAny >>= eTextEffect; + else + eTextEffect = ::com::sun::star::presentation::AnimationEffect_NONE; + if ( GetPropertyValue( aAny, rPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "SoundOn" ) ) ) ) + aAny >>= bIsSound; + else + bIsSound = FALSE; + + sal_Bool bHasEffect = ( ( eEffect != ::com::sun::star::presentation::AnimationEffect_NONE ) + || ( eTextEffect != ::com::sun::star::presentation::AnimationEffect_NONE ) + || bIsSound ); + return bHasEffect; +}; + +// ----------------------------------------------------------------------- + +sal_Bool PPTWriter::ImplCreatePresentationPlaceholder( const sal_Bool bMasterPage, const PageType /* ePageType */, + const sal_uInt32 nStyleInstance, const sal_uInt8 nPlaceHolderId ) +{ + sal_Bool bRet = ImplGetText(); + if ( bRet && bMasterPage ) + { + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + sal_uInt32 nPresShapeID = mpPptEscherEx->GenerateShapeId(); + mpPptEscherEx->AddShape( ESCHER_ShpInst_Rectangle, 0xa00, nPresShapeID );// Flags: HaveAnchor | HasSpt + EscherPropertyContainer aPropOpt; + aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x50001 ); + aPropOpt.AddOpt( ESCHER_Prop_lTxid, mnTxId += 0x60 ); + aPropOpt.AddOpt( ESCHER_Prop_AnchorText, ESCHER_AnchorMiddle ); + aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x110001 ); + aPropOpt.AddOpt( ESCHER_Prop_lineColor, 0x8000001 ); + aPropOpt.AddOpt( ESCHER_Prop_shadowColor, 0x8000002 ); + aPropOpt.CreateFillProperties( mXPropSet, sal_True ); + sal_uInt32 nLineFlags = 0x90001; + if ( aPropOpt.GetOpt( ESCHER_Prop_fNoLineDrawDash, nLineFlags ) ) + nLineFlags |= 0x10001; // draw dashed line if no line + aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, nLineFlags ); + + SvMemoryStream aExtBu( 0x200, 0x200 ); + SvMemoryStream aClientTextBox( 0x200, 0x200 ); + ImplWriteTextStyleAtom( aClientTextBox, nStyleInstance, 0, NULL, aExtBu, &aPropOpt ); + + aPropOpt.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_True ); + aPropOpt.Commit( *mpStrm ); + mpPptEscherEx->AddAtom( 8, ESCHER_ClientAnchor ); + *mpStrm << (sal_Int16)maRect.Top() << (sal_Int16)maRect.Left() << (sal_Int16)maRect.Right() << (sal_Int16)maRect.Bottom(); // oben, links, rechts, unten ???? + mpPptEscherEx->OpenContainer( ESCHER_ClientData ); + mpPptEscherEx->AddAtom( 8, EPP_OEPlaceholderAtom ); + *mpStrm << (sal_uInt32)0 // PlacementID + << (sal_uInt8)nPlaceHolderId // PlaceHolderID + << (sal_uInt8)0 // Size of PlaceHolder ( 0 = FULL, 1 = HALF, 2 = QUARTER ) + << (sal_uInt16)0; // padword + mpPptEscherEx->CloseContainer(); // ESCHER_ClientData +/* + if ( aExtBu.Tell() ) + { + if ( !pClientData ) + pClientData = new SvMemoryStream( 0x200, 0x200 ); + ImplProgTagContainer( pClientData, &aExtBu ); + } +*/ + if ( aClientTextBox.Tell() ) + { + *mpStrm << (sal_uInt32)( ( ESCHER_ClientTextbox << 16 ) | 0xf ) + << (sal_uInt32)aClientTextBox.Tell(); + + mpStrm->Write( aClientTextBox.GetData(), aClientTextBox.Tell() ); + } + mpPptEscherEx->CloseContainer(); // ESCHER_SpContainer + } + else + bRet = sal_False; + return bRet; +} + +// ----------------------------------------------------------------------- + +void PPTWriter::ImplCreateShape( sal_uInt32 nType, sal_uInt32 nFlags, EscherSolverContainer& rSolver ) +{ + sal_uInt32 nId = mpPptEscherEx->GenerateShapeId(); + mpPptEscherEx->AddShape( nType, nFlags, nId ); + rSolver.AddShape( mXShape, nId ); +} + +void PPTWriter::ImplCreateTextShape( EscherPropertyContainer& rPropOpt, EscherSolverContainer& rSolver, sal_Bool bFill ) +{ + mnTextStyle = EPP_TEXTSTYLE_TEXT; + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + ImplCreateShape( ESCHER_ShpInst_TextBox, 0xa00, rSolver ); + if ( bFill ) + rPropOpt.CreateFillProperties( mXPropSet, sal_True ); + if ( ImplGetText() ) + rPropOpt.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_True ); +} + +void PPTWriter::ImplWritePage( const PHLayout& rLayout, EscherSolverContainer& aSolverContainer, PageType ePageType, sal_Bool bMasterPage, int nPageNumber ) +{ + sal_uInt32 nInstance, nGroups, nShapes, nShapeCount, nPer, nLastPer, nIndices, nGroupLevel = 0, nOlePictureId; + sal_uInt16 nEffectCount; + ::com::sun::star::awt::Point aTextRefPoint; + + ResetGroupTable( nShapes = mXShapes->getCount() ); + + nIndices = nInstance = nLastPer = nShapeCount = nEffectCount = 0; + + sal_Bool bIsTitlePossible = TRUE; // bei mehr als einem title geht powerpoint in die knie + + sal_uInt32 nOutlinerCount = 0; // die gliederungsobjekte muessen dem layout entsprechen, + sal_uInt32 nPrevTextStyle = 0; // es darf nicht mehr als zwei geben + + nOlePictureId = 0; + + sal_Bool bAdditionalText = FALSE; + + sal_Bool bSecOutl = FALSE; + sal_uInt32 nPObjects = 0; + + SvMemoryStream* pClientTextBox = NULL; + SvMemoryStream* pClientData = NULL; + + while( GetNextGroupEntry() ) + { + nShapeCount++; + + nPer = ( 5 * nShapeCount ) / nShapes; + if ( nPer != nLastPer ) + { + nLastPer = nPer; + sal_uInt32 nValue = mnPagesWritten * 5 + nPer; + if ( nValue > mnStatMaxValue ) + nValue = mnStatMaxValue; + if ( mbStatusIndicator && ( nValue > mnLatestStatValue ) ) + { + mXStatusIndicator->setValue( nValue ); + mnLatestStatValue = nValue; + } + } + nGroups = GetGroupsClosed(); + for ( sal_uInt32 i = 0; i < nGroups; i++, mpPptEscherEx->LeaveGroup() ) ; + + if ( ImplGetShapeByIndex( GetCurrentGroupIndex(), TRUE ) ) + { + sal_Bool bIsSound; + sal_Bool bMediaClickAction = sal_False; + ::com::sun::star::presentation::AnimationEffect eAe; + ::com::sun::star::presentation::AnimationEffect eTe; + + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "PresentationOrder" ) ) ) ) + nEffectCount = *(sal_uInt16*)mAny.getValue(); + + sal_Bool bEffect = ImplGetEffect( mXPropSet, eAe, eTe, bIsSound ); + ::com::sun::star::presentation::ClickAction eCa = ::com::sun::star::presentation::ClickAction_NONE; + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "OnClick" ) ) ) ) + mAny >>= eCa; + + sal_Bool bGroup = mType == "drawing.Group"; + sal_Bool bOpenBezier = mType == "drawing.OpenBezier"; + sal_Bool bClosedBezier = mType == "drawing.ClosedBezier"; + sal_Bool bPolyPolygon = mType == "drawing.PolyPolygon"; + sal_Bool bPolyLine = mType == "drawing.PolyLine"; + + List aAdjustmentList; + Rectangle aPolyBoundRect; + + const ::com::sun::star::awt::Size aSize100thmm( mXShape->getSize() ); + const ::com::sun::star::awt::Point aPoint100thmm( mXShape->getPosition() ); + Rectangle aRect100thmm( Point( aPoint100thmm.X, aPoint100thmm.Y ), Size( aSize100thmm.Width, aSize100thmm.Height ) ); + EscherPropertyContainer aPropOpt( mpPptEscherEx->GetGraphicProvider(), mpPicStrm, aRect100thmm ); + + if ( bGroup ) + { + SvMemoryStream* pTmp = NULL; + ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess > + aXIndexAccess( mXShape, ::com::sun::star::uno::UNO_QUERY ); + if ( EnterGroup( aXIndexAccess ) ) + { + if ( bEffect && !mbUseNewAnimations ) + { + pTmp = new SvMemoryStream( 0x200, 0x200 ); + ImplWriteObjectEffect( *pTmp, eAe, eTe, ++nEffectCount ); + } + if ( eCa != ::com::sun::star::presentation::ClickAction_NONE ) + { + if ( !pTmp ) + pTmp = new SvMemoryStream( 0x200, 0x200 ); + ImplWriteClickAction( *pTmp, eCa, bMediaClickAction ); + } + sal_uInt32 nShapeId = mpPptEscherEx->EnterGroup( &maRect, pTmp ); + aSolverContainer.AddShape( mXShape, nShapeId ); + delete pTmp; + } + } + else + { + sal_Bool bIsFontwork = sal_False; + sal_Bool bIsHatching = sal_False; + ::com::sun::star::uno::Any aAny; + ::com::sun::star::drawing::FillStyle eFS; + if ( GetPropertyValue( aAny, mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsFontwork" ) ), sal_True ) ) + aAny >>= bIsFontwork; + if ( GetPropertyValue( aAny, mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillStyle" ) ), sal_True ) ) + { + aAny >>= eFS; + bIsHatching = eFS == ::com::sun::star::drawing::FillStyle_HATCH; + } + if ( bIsHatching || bIsFontwork || ( mType == "drawing.Measure" ) || ( mType == "drawing.Caption" ) ) + { + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "BoundRect" ) ) ) ) + { + ::com::sun::star::awt::Rectangle aRect( *(::com::sun::star::awt::Rectangle*)mAny.getValue() ); + maPosition = ImplMapPoint( ::com::sun::star::awt::Point( aRect.X, aRect.Y ) ); + maSize = ImplMapSize( ::com::sun::star::awt::Size( aRect.Width, aRect.Height ) ); + maRect = Rectangle( Point( maPosition.X, maPosition.Y ), Size( maSize.Width, maSize.Height ) ); + } + mType = "drawing.dontknow"; + } + } + sal_uInt8 nPlaceHolderAtom = EPP_PLACEHOLDER_NONE; + + mnTextSize = 0; + mnTextStyle = EPP_TEXTSTYLE_NORMAL; + + if ( mType == "drawing.Custom" ) + { + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + sal_uInt32 nMirrorFlags; + rtl::OUString sCustomShapeType; + MSO_SPT eShapeType = aPropOpt.GetCustomShapeType( mXShape, nMirrorFlags, sCustomShapeType ); + if ( sCustomShapeType.equalsAscii( "col-502ad400" ) || sCustomShapeType.equalsAscii( "col-60da8460" ) ) + { // sj: creating metafile for customshapes that can't be saved to ms format properly + ImplCreateShape( ESCHER_ShpInst_PictureFrame, 0xa00, aSolverContainer ); + if ( aPropOpt.CreateGraphicProperties( mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "MetaFile" ) ), sal_False ) ) + { + aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 ); + SdrObject* pObj = GetSdrObjectFromXShape( mXShape ); + if ( pObj ) + { + Rectangle aBound = pObj->GetCurrentBoundRect(); + maPosition = ImplMapPoint( ::com::sun::star::awt::Point( aBound.Left(), aBound.Top() ) ); + maSize = ImplMapSize( ::com::sun::star::awt::Size ( aBound.GetWidth(), aBound.GetHeight() ) ); + maRect = Rectangle( Point( maPosition.X, maPosition.Y ), Size( maSize.Width, maSize.Height ) ); + mnAngle = 0; + } + } + } + else + { + ImplCreateShape( eShapeType, nMirrorFlags | 0xa00, aSolverContainer ); + aPropOpt.CreateCustomShapeProperties( eShapeType, mXShape ); + aPropOpt.CreateFillProperties( mXPropSet, sal_True ); + if ( ImplGetText() ) + { + if ( !aPropOpt.IsFontWork() ) + aPropOpt.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_True, sal_True ); + } + } + } + else if ( mType == "drawing.Rectangle" ) + { + sal_Int32 nRadius = 0; + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CornerRadius" ) ) ) ) + { + mAny >>= nRadius; + nRadius = ImplMapSize( ::com::sun::star::awt::Size( nRadius, 0 ) ).Width; + } + if ( nRadius ) + { + ImplCreateShape( ESCHER_ShpInst_RoundRectangle, 0xa00, aSolverContainer ); // Flags: Connector | HasSpt + sal_Int32 nLenght = maRect.GetWidth(); + if ( nLenght > maRect.GetHeight() ) + nLenght = maRect.GetHeight(); + nLenght >>= 1; + if ( nRadius >= nLenght ) + nRadius = 0x2a30; // 0x2a30 ist PPTs maximum radius + else + nRadius = ( 0x2a30 * nRadius ) / nLenght; + aPropOpt.AddOpt( ESCHER_Prop_adjustValue, nRadius ); + } + else + { + ImplCreateShape( ESCHER_ShpInst_Rectangle, 0xa00, aSolverContainer ); // Flags: Connector | HasSpt + } + aPropOpt.CreateFillProperties( mXPropSet, sal_True ); + if ( ImplGetText() ) + aPropOpt.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_False ); + } + else if ( mType == "drawing.Ellipse" ) + { + ::com::sun::star::drawing::CircleKind eCircleKind( ::com::sun::star::drawing::CircleKind_FULL ); + PolyStyle ePolyKind = POLY_CHORD; + if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CircleKind" ) ) ) ) + { + mAny >>= eCircleKind; + switch ( eCircleKind ) + { + case ::com::sun::star::drawing::CircleKind_SECTION : + { + ePolyKind = POLY_PIE; + } + break; + case ::com::sun::star::drawing::CircleKind_ARC : + { + ePolyKind = POLY_ARC; + } + break; + + case ::com::sun::star::drawing::CircleKind_CUT : + { + ePolyKind = POLY_CHORD; + } + break; + + default: + eCircleKind = ::com::sun::star::drawing::CircleKind_FULL; + } + } + if ( eCircleKind == ::com::sun::star::drawing::CircleKind_FULL ) + { + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + ImplCreateShape( ESCHER_ShpInst_Ellipse, 0xa00, aSolverContainer ); // Flags: Connector | HasSpt + aPropOpt.CreateFillProperties( mXPropSet, sal_True ); + if ( ImplGetText() ) + aPropOpt.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_False ); + } + else + { + sal_Int32 nStartAngle, nEndAngle; + if ( !ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CircleStartAngle" ) ) ) ) + continue; + nStartAngle = *( (sal_Int32*)mAny.getValue() ); + if( !ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CircleEndAngle" ) ) ) ) + continue; + nEndAngle = *( (sal_Int32*)mAny.getValue() ); + ::com::sun::star::awt::Point aPoint( mXShape->getPosition() ); + ::com::sun::star::awt::Size aSize( mXShape->getSize() ); + ::com::sun::star::awt::Point aStart, aEnd, aCenter; + Rectangle aRect( Point( aPoint.X, aPoint.Y ), Size( aSize.Width, aSize.Height ) ); + aStart.X = (sal_Int32)( ( cos( (double)( nStartAngle * F_PI18000 ) ) * 100.0 ) ); + aStart.Y = - (sal_Int32)( ( sin( (double)( nStartAngle * F_PI18000 ) ) * 100.0 ) ); + aEnd.X = (sal_Int32)( ( cos( (double)( nEndAngle * F_PI18000 ) ) * 100.0 ) ); + aEnd.Y = - (sal_Int32)( ( sin( (double)( nEndAngle * F_PI18000 ) ) * 100.0 ) ); + aCenter.X = aPoint.X + ( aSize.Width / 2 ); + aCenter.Y = aPoint.Y + ( aSize.Height / 2 ); + aStart.X += aCenter.X; + aStart.Y += aCenter.Y; + aEnd.X += aCenter.X; + aEnd.Y += aCenter.Y; + Polygon aPolygon( aRect, Point( aStart.X, aStart.Y ), Point( aEnd.X, aEnd.Y ), ePolyKind ); + sal_Bool bNeedText = sal_True; + if ( mnAngle ) + { + aPolygon.Rotate( aRect.TopLeft(), (sal_uInt16)( mnAngle / 10 ) ); + if ( ImplGetText() ) + { + mpPptEscherEx->EnterGroup( 0,0 ); + nGroupLevel = mpPptEscherEx->GetGroupLevel(); + bNeedText = sal_False; + bAdditionalText = TRUE; + mnTextSize = 0; + } + mnAngle = 0; + } + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + ImplCreateShape( ESCHER_ShpInst_NotPrimitive, 0xa00, aSolverContainer ); // Flags: Connector | HasSpt + ::com::sun::star::awt::Rectangle aNewRect; + switch ( ePolyKind ) + { + case POLY_PIE : + case POLY_CHORD : + { + if ( aPropOpt.CreatePolygonProperties( mXPropSet, ESCHER_CREATEPOLYGON_POLYPOLYGON, sal_False, aNewRect, &aPolygon ) ) + aPropOpt.CreateFillProperties( mXPropSet, sal_True ); + } + break; + + case POLY_ARC : + { + if ( aPropOpt.CreatePolygonProperties( mXPropSet, ESCHER_CREATEPOLYGON_POLYLINE, sal_False, aNewRect, &aPolygon ) ) + aPropOpt.CreateLineProperties( mXPropSet, sal_False ); + } + break; + } + maRect = ImplMapRectangle( aNewRect ); + maPosition = ::com::sun::star::awt::Point( maRect.Left(), maRect.Top() ); + maSize = ::com::sun::star::awt::Size( maRect.GetWidth(), maRect.GetHeight() ); + if ( bNeedText && ImplGetText() ) + aPropOpt.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_False ); + } + } + else if ( mType == "drawing.Control" ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XControlShape > + aXControlShape( mXShape, ::com::sun::star::uno::UNO_QUERY ); + if ( !aXControlShape.is() ) + continue; + ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > + aXControlModel( aXControlShape->getControl() ); + if ( !aXControlModel.is() ) + continue; + + sal_Int64 nAspect = ::com::sun::star::embed::Aspects::MSOLE_CONTENT; + try + { + // try to get the aspect when available + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > + xShapeProps( mXShape, ::com::sun::star::uno::UNO_QUERY_THROW ); + xShapeProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Aspect" ) ) ) >>= nAspect; + } + catch( ::com::sun::star::uno::Exception& ) + {} + + *mpExEmbed << (sal_uInt32)( 0xf | ( EPP_ExControl << 16 ) ) + << (sal_uInt32)0; // Size of this container + + sal_uInt32 nSize, nOldPos = mpExEmbed->Tell(); + + sal_uInt32 nPageId = nPageNumber; + if ( ePageType == MASTER ) + nPageId |= 0x80000000; + else + nPageId += 0x100; + *mpExEmbed << (sal_uInt32)( EPP_ExControlAtom << 16 ) + << (sal_uInt32)4 + << nPageId; + PPTExOleObjEntry* pEntry = new PPTExOleObjEntry( OCX_CONTROL, mpExEmbed->Tell() ); + pEntry->xControlModel = aXControlModel; + maExOleObj.Insert( pEntry ); + + mnExEmbed++; + + *mpExEmbed << (sal_uInt32)( 1 | ( EPP_ExOleObjAtom << 16 ) ) + << (sal_uInt32)24 + << (sal_uInt32)nAspect + << (sal_uInt32)2 + << (sal_uInt32)mnExEmbed + << (sal_uInt32)0 + << (sal_uInt32)4 // index to the persist table + << (sal_uInt32)0x0012de00; + + + ::com::sun::star::awt::Size aSize; + String aControlName; + SvStorageRef xTemp( new SvStorage( new SvMemoryStream(), TRUE ) ); + if ( SvxMSConvertOCXControls::WriteOCXStream( xTemp, aXControlModel, aSize, aControlName ) ) + { + String aUserName( xTemp->GetUserName() ); + String aOleIdentifier; + if ( aUserName.Len() ) + { + SvStorageStreamRef xCompObj = xTemp->OpenSotStream( + String( RTL_CONSTASCII_USTRINGPARAM( "\1CompObj" ) ), + STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYALL ); + xCompObj->Seek( STREAM_SEEK_TO_END ); + sal_uInt32 nStreamLen = xCompObj->Tell(); + xCompObj->Seek( 0 ); + sal_Int16 nVersion, nByteOrder; + sal_Int32 nWinVersion, nVal, nStringLen; + *xCompObj >> nVersion + >> nByteOrder + >> nWinVersion + >> nVal; + xCompObj->SeekRel( 16 ); // skipping clsid + *xCompObj >> nStringLen; + if ( ( xCompObj->Tell() + nStringLen ) < nStreamLen ) + { + xCompObj->SeekRel( nStringLen ); // now skipping the UserName; + *xCompObj >> nStringLen; + if ( ( xCompObj->Tell() + nStringLen ) < nStreamLen ) + { + xCompObj->SeekRel( nStringLen ); // now skipping the clipboard formatname + *xCompObj >> nStringLen; + if ( ( nStringLen > 1 ) && ( ( xCompObj->Tell() + nStringLen ) < nStreamLen ) ) + { // i think that the OleIdentifier will follow + ByteString aTemp; + sal_Char* p = aTemp.AllocBuffer( (USHORT)(nStringLen - 1) ); + xCompObj->Read( p, nStringLen - 1 ); + aOleIdentifier = String( aTemp, gsl_getSystemTextEncoding() ); + } + } + } + } + if ( aControlName.Len() ) + PPTWriter::WriteCString( *mpExEmbed, aControlName, 1 ); + if ( aOleIdentifier.Len() ) + PPTWriter::WriteCString( *mpExEmbed, aOleIdentifier, 2 ); + if ( aUserName.Len() ) + PPTWriter::WriteCString( *mpExEmbed, aUserName, 3 ); + } + nSize = mpExEmbed->Tell() - nOldPos; + mpExEmbed->Seek( nOldPos - 4 ); + *mpExEmbed << nSize; + mpExEmbed->Seek( STREAM_SEEK_TO_END ); + nOlePictureId = mnExEmbed; + + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + sal_uInt32 nSpFlags = SHAPEFLAG_HAVESPT | SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_OLESHAPE; + ImplCreateShape( ESCHER_ShpInst_HostControl, nSpFlags, aSolverContainer ); + if ( aPropOpt.CreateGraphicProperties( mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "MetaFile" ) ), sal_False ) ) + aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 ); + aPropOpt.AddOpt( ESCHER_Prop_pictureId, mnExEmbed ); + aPropOpt.AddOpt( ESCHER_Prop_pictureActive, 0x10000 ); + + if ( aControlName.Len() ) + { + sal_uInt16 i, nBufSize; + nBufSize = ( aControlName.Len() + 1 ) << 1; + sal_uInt8* pBuf = new sal_uInt8[ nBufSize ]; + sal_uInt8* pTmp = pBuf; + for ( i = 0; i < aControlName.Len(); i++ ) + { + sal_Unicode nUnicode = aControlName.GetChar( i ); + *pTmp++ = (sal_uInt8)nUnicode; + *pTmp++ = (sal_uInt8)( nUnicode >> 8 ); + } + *pTmp++ = 0; + *pTmp = 0; + aPropOpt.AddOpt( ESCHER_Prop_wzName, TRUE, nBufSize, pBuf, nBufSize ); + } + } + else if ( mType == "drawing.Connector" ) + { + sal_uInt16 nSpType, nSpFlags; + ::com::sun::star::awt::Rectangle aNewRect; + if ( aPropOpt.CreateConnectorProperties( mXShape, aSolverContainer, aNewRect, nSpType, nSpFlags ) == sal_False ) + continue; + + maRect = ImplMapRectangle( aNewRect ); + maPosition = ::com::sun::star::awt::Point( maRect.Left(), maRect.Top() ); + maSize = ::com::sun::star::awt::Size( maRect.GetWidth(), maRect.GetHeight() ); + + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + ImplCreateShape( nSpType, nSpFlags, aSolverContainer ); + } + else if ( mType == "drawing.Measure" ) + { + continue; + } + else if ( mType == "drawing.Line" ) + { + ::com::sun::star::awt::Rectangle aNewRect; + aPropOpt.CreatePolygonProperties( mXPropSet, ESCHER_CREATEPOLYGON_LINE, sal_False, aNewRect, NULL ); + maRect = ImplMapRectangle( aNewRect ); + maPosition = ::com::sun::star::awt::Point( maRect.Left(), maRect.Top() ); + maSize = ::com::sun::star::awt::Size( maRect.GetWidth(), maRect.GetHeight() ); + if ( ImplGetText() ) + { + aTextRefPoint = ::com::sun::star::awt::Point( maRect.Left(), maRect.Top() ); + mnTextSize = 0; + bAdditionalText = TRUE; + mpPptEscherEx->EnterGroup( &maRect,0 ); + } + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + sal_uInt32 nFlags = 0xa00; // Flags: Connector | HasSpt + if ( maRect.Top() > maRect.Bottom() ) + nFlags |= 0x80; // Flags: VertMirror + if ( maRect.Left() > maRect.Right() ) + nFlags |= 0x40; // Flags: HorzMirror + + ImplCreateShape( ESCHER_ShpInst_Line, nFlags, aSolverContainer ); + aPropOpt.AddOpt( ESCHER_Prop_shapePath, ESCHER_ShapeComplex ); + aPropOpt.CreateLineProperties( mXPropSet, sal_False ); + mnAngle = 0; + } + else if ( bPolyPolygon ) + { + if ( ImplGetText() ) + { + mpPptEscherEx->EnterGroup( 0,0 ); + nGroupLevel = mpPptEscherEx->GetGroupLevel(); + bAdditionalText = TRUE; + mnTextSize = 0; + } + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + ImplCreateShape( ESCHER_ShpInst_NotPrimitive, 0xa00, aSolverContainer ); // Flags: Connector | HasSpt + ::com::sun::star::awt::Rectangle aNewRect; + aPropOpt.CreatePolygonProperties( mXPropSet, ESCHER_CREATEPOLYGON_POLYPOLYGON, sal_False, aNewRect, NULL ); + maRect = ImplMapRectangle( aNewRect ); + maPosition = ::com::sun::star::awt::Point( maRect.Left(), maRect.Top() ); + maSize = ::com::sun::star::awt::Size( maRect.GetWidth(), maRect.GetHeight() ); + aPropOpt.CreateFillProperties( mXPropSet, sal_True ); + mnAngle = 0; + } + else if ( bPolyLine ) + { + if ( ImplGetText() ) + { + mpPptEscherEx->EnterGroup( 0,0 ); + nGroupLevel = mpPptEscherEx->GetGroupLevel(); + bAdditionalText = TRUE; + mnTextSize = 0; + } + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + ImplCreateShape( ESCHER_ShpInst_NotPrimitive, 0xa00, aSolverContainer ); // Flags: Connector | HasSpt + ::com::sun::star::awt::Rectangle aNewRect; + aPropOpt.CreatePolygonProperties( mXPropSet, ESCHER_CREATEPOLYGON_POLYLINE, sal_False, aNewRect, NULL ); + maRect = ImplMapRectangle( aNewRect ); + maPosition = ::com::sun::star::awt::Point( maRect.Left(), maRect.Top() ); + maSize = ::com::sun::star::awt::Size( maRect.GetWidth(), maRect.GetHeight() ); + aPropOpt.CreateLineProperties( mXPropSet, sal_False ); + mnAngle = 0; + } + else if ( bOpenBezier ) + { + if ( ImplGetText() ) + { + mpPptEscherEx->EnterGroup( 0,0 ); + nGroupLevel = mpPptEscherEx->GetGroupLevel(); + bAdditionalText = TRUE; + mnTextSize = 0; + } + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + ImplCreateShape( ESCHER_ShpInst_NotPrimitive, 0xa00, aSolverContainer ); // Flags: Connector | HasSpt + ::com::sun::star::awt::Rectangle aNewRect; + aPropOpt.CreatePolygonProperties( mXPropSet, ESCHER_CREATEPOLYGON_POLYLINE, sal_True, aNewRect, NULL ); + maRect = ImplMapRectangle( aNewRect ); + maPosition = ::com::sun::star::awt::Point( maRect.Left(), maRect.Top() ); + maSize = ::com::sun::star::awt::Size( maRect.GetWidth(), maRect.GetHeight() ); + aPropOpt.CreateLineProperties( mXPropSet, sal_False ); + mnAngle = 0; + } + else if ( bClosedBezier ) + { + if ( ImplGetText() ) + { + mpPptEscherEx->EnterGroup( 0,0 ); + nGroupLevel = mpPptEscherEx->GetGroupLevel(); + bAdditionalText = TRUE; + mnTextSize = 0; + } + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + ImplCreateShape( ESCHER_ShpInst_NotPrimitive, 0xa00, aSolverContainer ); // Flags: Connector | HasSpt + ::com::sun::star::awt::Rectangle aNewRect; + aPropOpt.CreatePolygonProperties( mXPropSet, ESCHER_CREATEPOLYGON_POLYPOLYGON, sal_True, aNewRect, NULL ); + maRect = ImplMapRectangle( aNewRect ); + maPosition = ::com::sun::star::awt::Point( maRect.Left(), maRect.Top() ); + maSize = ::com::sun::star::awt::Size( maRect.GetWidth(), maRect.GetHeight() ); + aPropOpt.CreateFillProperties( mXPropSet, sal_True ); + mnAngle = 0; + } + else if ( ( mType == "drawing.GraphicObject" ) || ( mType == "presentation.GraphicObject" ) ) + { + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + + // ein GraphicObject kann auch ein ClickMe Element sein + if ( mbEmptyPresObj && ( ePageType == NORMAL ) ) + { + nPlaceHolderAtom = rLayout.nUsedObjectPlaceHolder; + ImplCreateShape( ESCHER_ShpInst_Rectangle, 0x220, aSolverContainer ); // Flags: HaveAnchor | HaveMaster + aPropOpt.AddOpt( ESCHER_Prop_lTxid, mnTxId += 0x60 ); + aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x10001 ); + aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x10001 ); + aPropOpt.AddOpt( ESCHER_Prop_hspMaster, mnShapeMasterBody ); + } + else + { + mXText = ::com::sun::star::uno::Reference< + ::com::sun::star::text::XSimpleText > + ( mXShape, ::com::sun::star::uno::UNO_QUERY ); + + if ( mXText.is() ) + mnTextSize = mXText->getString().getLength(); + + if ( mnTextSize ) // graphic object oder Flachenfuellung + { + /* SJ #i34951#: because M. documents are not allowing GraphicObjects containing text, we + have to create a simpe Rectangle with fill bitmap instead (while not allowing BitmapMode_Repeat). + */ + ImplCreateShape( ESCHER_ShpInst_Rectangle, 0xa00, aSolverContainer ); // Flags: Connector | HasSpt + if ( aPropOpt.CreateGraphicProperties( mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "GraphicURL" ) ), sal_True, sal_True, sal_False ) ) + { + aPropOpt.AddOpt( ESCHER_Prop_WrapText, ESCHER_WrapNone ); + aPropOpt.AddOpt( ESCHER_Prop_AnchorText, ESCHER_AnchorMiddle ); + aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x140014 ); + aPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0x8000000 ); + aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x80000 ); + if ( ImplGetText() ) + aPropOpt.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_False ); + } + } + else + { + ImplCreateShape( ESCHER_ShpInst_PictureFrame, 0xa00, aSolverContainer ); + if ( aPropOpt.CreateGraphicProperties( mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "GraphicURL" ) ), sal_False, sal_True ) ) + aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 ); + } + } + } + else if ( ( mType == "drawing.Text" ) || ( mType == "presentation.Notes" ) ) + { + if ( ( ePageType == NOTICE ) && mbPresObj ) + { + if ( ImplCreatePresentationPlaceholder( bMasterPage, ePageType, EPP_TEXTTYPE_Notes, EPP_PLACEHOLDER_MASTERNOTESBODYIMAGE ) ) + continue; + else + nPlaceHolderAtom = EPP_PLACEHOLDER_NOTESBODY; + } + ImplCreateTextShape( aPropOpt, aSolverContainer, TRUE ); + } + else if ( mType == "presentation.TitleText" ) + { + if ( mbPresObj ) + { + if ( ( ePageType == NOTICE ) && mbEmptyPresObj ) + { + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + nPlaceHolderAtom = EPP_PLACEHOLDER_MASTERNOTESBODYIMAGE; + ImplCreateShape( ESCHER_ShpInst_Rectangle, 0x200, aSolverContainer ); + aPropOpt.CreateLineProperties( mXPropSet, sal_False ); + aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x10001 ); + } + else if ( rLayout.bTitlePossible && bIsTitlePossible ) + { + bIsTitlePossible = FALSE; + + ImplGetText(); + TextObj aTextObj( mXText, EPP_TEXTTYPE_Title, maFontCollection, (PPTExBulletProvider&)*this ); + if ( ePageType == MASTER ) + { + if ( mnTextSize ) + { + ::rtl::OUString aUString( mXText->getString() ); + sal_uInt16 nChar; + + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + mnShapeMasterTitle = mpPptEscherEx->GenerateShapeId(); + mpPptEscherEx->AddShape( ESCHER_ShpInst_Rectangle, 0xa00, mnShapeMasterTitle );// Flags: HaveAnchor | HasSpt + EscherPropertyContainer aPropertyOptions; + aPropertyOptions.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x50001 ); + aPropertyOptions.AddOpt( ESCHER_Prop_lTxid, mnTxId += 0x60 ); + aPropertyOptions.AddOpt( ESCHER_Prop_AnchorText, ESCHER_AnchorMiddle ); +// aPropertyOptions.AddOpt( ESCHER_Prop_fillColor, nFillColor ); +// aPropertyOptions.AddOpt( ESCHER_Prop_fillBackColor, nFillBackColor ); + aPropertyOptions.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x110001 ); + aPropertyOptions.AddOpt( ESCHER_Prop_lineColor, 0x8000001 ); + aPropertyOptions.AddOpt( ESCHER_Prop_shadowColor, 0x8000002 ); + aPropertyOptions.CreateFillProperties( mXPropSet, sal_True ); + sal_uInt32 nLineFlags = 0x90001; + if ( aPropertyOptions.GetOpt( ESCHER_Prop_fNoLineDrawDash, nLineFlags ) ) + nLineFlags |= 0x10001; // draw dashed line if no line + aPropertyOptions.AddOpt( ESCHER_Prop_fNoLineDrawDash, nLineFlags ); + aPropertyOptions.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_True ); + ImplAdjustFirstLineLineSpacing( aTextObj, aPropOpt ); + aPropertyOptions.Commit( *mpStrm ); + mpPptEscherEx->AddAtom( 8, ESCHER_ClientAnchor ); + *mpStrm << (sal_Int16)maRect.Top() << (sal_Int16)maRect.Left() << (sal_Int16)maRect.Right() << (sal_Int16)maRect.Bottom(); // oben, links, rechts, unten ???? + mpPptEscherEx->OpenContainer( ESCHER_ClientData ); + mpPptEscherEx->AddAtom( 8, EPP_OEPlaceholderAtom ); + *mpStrm << (sal_uInt32)0 // PlacementID + << (sal_uInt8)EPP_PLACEHOLDER_MASTERTITLE // PlaceHolderID + << (sal_uInt8)0 // Size of PlaceHolder ( 0 = FULL, 1 = HALF, 2 = QUARTER ) + << (sal_uInt16)0; // padword + mpPptEscherEx->CloseContainer(); // ESCHER_ClientData + mpPptEscherEx->OpenContainer( ESCHER_ClientTextbox ); + mpPptEscherEx->AddAtom( 4, EPP_TextHeaderAtom ); + *mpStrm << (sal_uInt32)EPP_TEXTTYPE_Title; + mpPptEscherEx->AddAtom( mnTextSize << 1, EPP_TextCharsAtom ); + const sal_Unicode* pString = aUString; + for ( sal_uInt32 i = 0; i < mnTextSize; i++ ) + { + nChar = pString[ i ]; // 0xa -> 0xb weicher Zeilenumbruch + if ( nChar == 0xa ) + nChar++; // 0xd -> 0xd harter Zeilenumbruch + *mpStrm << nChar; + } + mpPptEscherEx->AddAtom( 6, EPP_BaseTextPropAtom ); + *mpStrm << (sal_uInt32)( mnTextSize + 1 ) << (sal_uInt16)0; + mpPptEscherEx->AddAtom( 10, EPP_TextSpecInfoAtom ); + *mpStrm << (sal_uInt32)( mnTextSize + 1 ) << (sal_uInt32)1 << (sal_uInt16)0; + mpPptEscherEx->CloseContainer(); // ESCHER_ClientTextBox + mpPptEscherEx->CloseContainer(); // ESCHER_SpContainer + } + continue; + } + else + { + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + mnTextStyle = EPP_TEXTSTYLE_TITLE; + nPlaceHolderAtom = rLayout.nTypeOfTitle; + ImplCreateShape( ESCHER_ShpInst_Rectangle, 0x220, aSolverContainer ); // Flags: HaveAnchor | HaveMaster + aPropOpt.AddOpt( ESCHER_Prop_hspMaster, mnShapeMasterTitle ); + aPropOpt.CreateFillProperties( mXPropSet, sal_True ); + aPropOpt.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_True ); + ImplAdjustFirstLineLineSpacing( aTextObj, aPropOpt ); + if ( mbEmptyPresObj ) + { + sal_uInt32 nNoLineDrawDash = 0; + aPropOpt.GetOpt( ESCHER_Prop_fNoLineDrawDash, nNoLineDrawDash ); + nNoLineDrawDash |= 0x10001; + aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, nNoLineDrawDash ); + } + } + } + else + mbPresObj = FALSE; + } + if ( !mbPresObj ) + { + mType = "drawing.Text"; + ImplCreateTextShape( aPropOpt, aSolverContainer, TRUE ); + } + } + else if ( ( mType == "presentation.Outliner" ) || ( mType == "presentation.Subtitle" ) ) + { + if ( mbPresObj ) + { + nOutlinerCount++; + if ( (rLayout.bOutlinerPossible && ( nOutlinerCount == 1 )) || + (( rLayout.bSecOutlinerPossible && ( nOutlinerCount == 2 ) ) && ( nPrevTextStyle == EPP_TEXTSTYLE_BODY )) + ) + { + ImplGetText(); + TextObj aTextObj( mXText, EPP_TEXTTYPE_Body, maFontCollection, (PPTExBulletProvider&)*this ); + if ( ePageType == MASTER ) + { + nPrevTextStyle = EPP_TEXTSTYLE_TITLE; + if ( mnTextSize ) + { + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + mnShapeMasterBody = mpPptEscherEx->GenerateShapeId(); + mpPptEscherEx->AddShape( ESCHER_ShpInst_Rectangle, 0xa00, mnShapeMasterBody ); // Flags: HaveAnchor | HasSpt + EscherPropertyContainer aPropOpt2; + aPropOpt2.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x50001 ); + aPropOpt2.AddOpt( ESCHER_Prop_lTxid, mnTxId += 0x60 ); +// aPropOpt2.AddOpt( ESCHER_Prop_fillColor, nFillColor ); +// aPropOpt2.AddOpt( ESCHER_Prop_fillBackColor, nFillBackColor ); + aPropOpt2.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x110001 ); + aPropOpt2.AddOpt( ESCHER_Prop_lineColor, 0x8000001 ); + aPropOpt2.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x90001 ); + aPropOpt2.AddOpt( ESCHER_Prop_shadowColor, 0x8000002 ); + aPropOpt2.CreateFillProperties( mXPropSet, sal_True ); + sal_uInt32 nLineFlags = 0x90001; + if ( aPropOpt2.GetOpt( ESCHER_Prop_fNoLineDrawDash, nLineFlags ) ) + nLineFlags |= 0x10001; // draw dashed line if no line + aPropOpt2.AddOpt( ESCHER_Prop_fNoLineDrawDash, nLineFlags ); + aPropOpt2.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_True ); + ImplAdjustFirstLineLineSpacing( aTextObj, aPropOpt2 ); + aPropOpt2.Commit( *mpStrm ); + mpPptEscherEx->AddAtom( 8, ESCHER_ClientAnchor ); + *mpStrm << (sal_Int16)maRect.Top() << (sal_Int16)maRect.Left() << (sal_Int16)maRect.Right() << (sal_Int16)maRect.Bottom(); // oben, links, rechts, unten ???? + mpPptEscherEx->OpenContainer( ESCHER_ClientData ); + mpPptEscherEx->AddAtom( 8, EPP_OEPlaceholderAtom ); + *mpStrm << (sal_uInt32)1 // PlacementID + << (sal_uInt8)EPP_PLACEHOLDER_MASTERBODY // PlaceHolderID + << (sal_uInt8)0 // Size of PlaceHolder ( 0 = FULL, 1 = HALF, 2 = QUARTER ) + << (sal_uInt16)0; // padword + mpPptEscherEx->CloseContainer(); // ESCHER_ClientData + mpPptEscherEx->OpenContainer( ESCHER_ClientTextbox ); // printf + mpPptEscherEx->AddAtom( 4, EPP_TextHeaderAtom ); + *mpStrm << (sal_uInt32)EPP_TEXTTYPE_Body; + mnTextSize = aTextObj.Count(); + aTextObj.Write( mpStrm ); + mpPptEscherEx->BeginAtom(); + for ( ParagraphObj* pPara = aTextObj.First() ; pPara; pPara = aTextObj.Next() ) + { + sal_uInt32 nCharCount = pPara->Count(); + sal_uInt16 nDepth = pPara->nDepth; + if ( nDepth > 4) + nDepth = 4; + + *mpStrm << nCharCount + << nDepth; + } + mpPptEscherEx->EndAtom( EPP_BaseTextPropAtom ); + mpPptEscherEx->AddAtom( 10, EPP_TextSpecInfoAtom ); + *mpStrm << (sal_uInt32)( mnTextSize ) << (sal_uInt32)1 << (sal_uInt16)0; + + mpPptEscherEx->CloseContainer(); // ESCHER_ClientTextBox + mpPptEscherEx->CloseContainer(); // ESCHER_SpContainer + } + continue; + } + else + { + mnTextStyle = EPP_TEXTSTYLE_BODY; + nPlaceHolderAtom = rLayout.nTypeOfOutliner; + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + ImplCreateShape( ESCHER_ShpInst_Rectangle, 0x220, aSolverContainer ); // Flags: HaveAnchor | HaveMaster + aPropOpt.AddOpt( ESCHER_Prop_hspMaster, mnShapeMasterBody ); + aPropOpt.CreateFillProperties( mXPropSet, sal_True ); + aPropOpt.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_True ); + ImplAdjustFirstLineLineSpacing( aTextObj, aPropOpt ); + if ( mbEmptyPresObj ) + { + sal_uInt32 nNoLineDrawDash = 0; + aPropOpt.GetOpt( ESCHER_Prop_fNoLineDrawDash, nNoLineDrawDash ); + nNoLineDrawDash |= 0x10001; + aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, nNoLineDrawDash ); + } + } + } + else + mbPresObj = FALSE; + } + if ( !mbPresObj ) + { + mType = "drawing.Text"; + ImplCreateTextShape( aPropOpt, aSolverContainer, TRUE ); + } + } + else if ( ( mType == "drawing.Page" ) || ( mType == "presentation.Page" ) ) + { + if ( ( ePageType == NOTICE ) && mbPresObj ) + { + if ( ImplCreatePresentationPlaceholder( bMasterPage, ePageType, EPP_TEXTTYPE_Notes, EPP_PLACEHOLDER_MASTERNOTESSLIDEIMAGE ) ) + continue; + else + nPlaceHolderAtom = EPP_PLACEHOLDER_NOTESSLIDEIMAGE; + } + ImplCreateTextShape( aPropOpt, aSolverContainer, TRUE ); + } + else if ( mType == "drawing.Frame" ) + { + continue; + } + else if ( ( mType == "drawing.OLE2" ) || ( mType == "presentation.OLE2" ) + || ( mType == "presentation.Chart" ) || ( mType == "presentation.Table" ) + || ( mType == "presentation.OrgChart" ) ) + { + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + if ( mbEmptyPresObj && ( ePageType == NORMAL ) ) + { + nPlaceHolderAtom = rLayout.nUsedObjectPlaceHolder; + ImplCreateShape( ESCHER_ShpInst_Rectangle, 0x220, aSolverContainer ); // Flags: HaveAnchor | HaveMaster + aPropOpt.AddOpt( ESCHER_Prop_lTxid, mnTxId += 0x60 ); + aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x10001 ); + aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x10001 ); + aPropOpt.AddOpt( ESCHER_Prop_hspMaster, mnShapeMasterBody ); + } + else + { + *mpExEmbed << (sal_uInt32)( 0xf | ( EPP_ExEmbed << 16 ) ) + << (sal_uInt32)0; // Size of this container + + sal_uInt32 nSize, nOldPos = mpExEmbed->Tell(); + + *mpExEmbed << (sal_uInt32)( EPP_ExEmbedAtom << 16 ) + << (sal_uInt32)8 + << (sal_uInt32)0 // follow colorscheme : 0->do not follow + // 1->follow collorscheme + // 2->follow text and background scheme + << (sal_uInt8)1 // (bool)set if embedded server can not be locked + << (sal_uInt8)0 // (bool)do not need to send dimension + << (sal_uInt8)0 // (bool)is object a world table + << (sal_uInt8)0; // pad byte + + PPTExOleObjEntry* pE = new PPTExOleObjEntry( NORMAL_OLE_OBJECT, mpExEmbed->Tell() ); + pE->xShape = mXShape; + maExOleObj.Insert( pE ); + + mnExEmbed++; + + sal_Int64 nAspect = ::com::sun::star::embed::Aspects::MSOLE_CONTENT; + try + { + // try to get the aspect when available + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > + xShapeProps( mXShape, ::com::sun::star::uno::UNO_QUERY_THROW ); + xShapeProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Aspect" ) ) ) >>= nAspect; + } + catch( ::com::sun::star::uno::Exception& ) + {} + + *mpExEmbed << (sal_uInt32)( 1 | ( EPP_ExOleObjAtom << 16 ) ) + << (sal_uInt32)24 + << (sal_uInt32)nAspect // Aspect + << (sal_uInt32)0 + << (sal_uInt32)mnExEmbed // index to the persist table + << (sal_uInt32)0 // subtype + << (sal_uInt32)0 + << (sal_uInt32)0x0012b600; + +// PPTWriter::WriteCString( *mpExEmbed, "Photo Editor Photo", 1 ); +// PPTWriter::WriteCString( *mpExEmbed, "MSPhotoEd.3", 2 ); +// PPTWriter::WriteCString( *mpExEmbed, "Microsoft Photo Editor 3.0 Photo", 3 ); + + nSize = mpExEmbed->Tell() - nOldPos; + mpExEmbed->Seek( nOldPos - 4 ); + *mpExEmbed << nSize; + mpExEmbed->Seek( STREAM_SEEK_TO_END ); + nOlePictureId = mnExEmbed; + + sal_uInt32 nSpFlags = 0xa00; + if ( nOlePictureId ) + nSpFlags |= 0x10; + ImplCreateShape( ESCHER_ShpInst_PictureFrame, nSpFlags, aSolverContainer ); + if ( aPropOpt.CreateOLEGraphicProperties( mXShape ) ) + aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 ); + if ( nOlePictureId ) + aPropOpt.AddOpt( ESCHER_Prop_pictureId, nOlePictureId ); + } + } + else if ( mType == "presentation.Header" ) + { + if ( ImplCreatePresentationPlaceholder( bMasterPage, ePageType, EPP_TEXTTYPE_Other, EPP_PLACEHOLDER_MASTERHEADER ) ) + continue; + else + { + mbPresObj = sal_False; + mType = "drawing.Text"; + ImplCreateTextShape( aPropOpt, aSolverContainer, TRUE ); + } + } + else if ( mType == "presentation.Footer" ) + { + if ( ImplCreatePresentationPlaceholder( bMasterPage, ePageType, EPP_TEXTTYPE_Other, EPP_PLACEHOLDER_MASTERFOOTER ) ) + continue; + else + { + mbPresObj = sal_False; + mType = "drawing.Text"; + ImplCreateTextShape( aPropOpt, aSolverContainer, TRUE ); + } + } + else if ( mType == "presentation.DateTime" ) + { + if ( ImplCreatePresentationPlaceholder( bMasterPage, ePageType, EPP_TEXTTYPE_Other, EPP_PLACEHOLDER_MASTERDATE ) ) + continue; + else + { + mbPresObj = sal_False; + mType = "drawing.Text"; + ImplCreateTextShape( aPropOpt, aSolverContainer, TRUE ); + } + } + else if ( mType == "presentation.SlideNumber" ) + { + if ( ImplCreatePresentationPlaceholder( bMasterPage, ePageType, EPP_TEXTTYPE_Other, EPP_PLACEHOLDER_MASTERSLIDENUMBER ) ) + continue; + else + { + mbPresObj = sal_False; + mType = "drawing.Text"; + ImplCreateTextShape( aPropOpt, aSolverContainer, TRUE ); + } + } + else if ( ( (sal_Char)'3' == mType.GetChar( 8 ) ) && ( (char)'D' == mType.GetChar( 9 ) ) ) // drawing.3D + { + // SceneObject, CubeObject, SphereObject, LatheObject, ExtrudeObject, PolygonObject + if ( !ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "Bitmap" ) ) ) ) + continue; + + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + ImplCreateShape( ESCHER_ShpInst_PictureFrame, 0xa00, aSolverContainer ); + + if ( aPropOpt.CreateGraphicProperties( mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Bitmap" ) ), sal_False ) ) + aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 ); + } + else if ( mType == "drawing.Media" ) + { + mnAngle = 0; + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + ImplCreateShape( ESCHER_ShpInst_PictureFrame, 0xa00, aSolverContainer ); + + ::com::sun::star::uno::Any aAny; + if ( PropValue::GetPropertyValue( aAny, mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "MediaURL" ) ), sal_True ) ) + { + rtl::OUString aMediaURL; + if ( (aAny >>= aMediaURL ) && aMediaURL.getLength() ) + { + // SJ: creating the Media RefObj + sal_uInt32 nRefId = ++mnExEmbed; + + *mpExEmbed << (sal_uInt16)0xf + << (sal_uInt16)EPP_ExMCIMovie // PPT_PST_ExAviMovie + << (sal_uInt32)0; + sal_uInt32 nSize, nStart = mpExEmbed->Tell(); + *mpExEmbed << (sal_uInt16)0 + << (sal_uInt16)EPP_ExObjRefAtom + << (sal_uInt32)4 + << nRefId; + *mpExEmbed << (sal_uInt16)0xf + << (sal_uInt16)EPP_ExVideo + << (sal_uInt32)0; + + *mpExEmbed << (sal_uInt16)0 + << (sal_uInt16)EPP_ExMediaAtom + << (sal_uInt32)8 + << nRefId + << (sal_uInt16)0 + << (sal_uInt16)0x435; + + + sal_uInt16 i, nStringLen = (sal_uInt16)aMediaURL.getLength(); + *mpExEmbed << (sal_uInt32)( EPP_CString << 16 ) << (sal_uInt32)( nStringLen * 2 ); + for ( i = 0; i < nStringLen; i++ ) + { + sal_Unicode nChar = aMediaURL[ i ]; + *mpExEmbed << nChar; + } + nSize = mpExEmbed->Tell() - nStart; + mpExEmbed->SeekRel( - ( (sal_Int32)nSize + 4 ) ); + *mpExEmbed << nSize; // size of PPT_PST_ExMCIMovie + mpExEmbed->SeekRel( 0x10 ); + nSize -= 20; + *mpExEmbed << nSize; // PPT_PST_ExMediaAtom + mpExEmbed->SeekRel( nSize ); + + if ( !pClientData ) + pClientData = new SvMemoryStream( 0x200, 0x200 ); + *pClientData << (sal_uInt16)0 + << (sal_uInt16)EPP_ExObjRefAtom + << (sal_uInt32)4 + << nRefId; + } + } + } + else if ( mType == "drawing.Table" ) + { + SvMemoryStream* pTmp = NULL; + if ( bEffect && !mbUseNewAnimations ) + { + pTmp = new SvMemoryStream( 0x200, 0x200 ); + ImplWriteObjectEffect( *pTmp, eAe, eTe, ++nEffectCount ); + } + if ( eCa != ::com::sun::star::presentation::ClickAction_NONE ) + { + if ( !pTmp ) + pTmp = new SvMemoryStream( 0x200, 0x200 ); + ImplWriteClickAction( *pTmp, eCa, bMediaClickAction ); + } + ImplCreateTable( mXShape, aSolverContainer, aPropOpt ); + continue; + } + else if ( mType == "drawing.dontknow" ) + { + mnAngle = 0; + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + ImplCreateShape( ESCHER_ShpInst_PictureFrame, 0xa00, aSolverContainer ); + if ( aPropOpt.CreateGraphicProperties( mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "MetaFile" ) ), sal_False ) ) + aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 ); + } + else + { + continue; + } + sal_Int32 nPlacementID = -1; + + sal_Bool bClientData = ( bEffect || ( eCa != ::com::sun::star::presentation::ClickAction_NONE ) || + nPlaceHolderAtom || nOlePictureId ); + if ( bClientData ) + { + if ( nPlaceHolderAtom ) + { + if ( ( mnTextStyle == EPP_TEXTSTYLE_TITLE ) || ( mnTextStyle == EPP_TEXTSTYLE_BODY ) ) + nPlacementID = nIndices++; + else + { + switch ( nPlaceHolderAtom ) + { + default : + { + if ( nPlaceHolderAtom < 19 ) + break; + } + case EPP_PLACEHOLDER_NOTESBODY : + case EPP_PLACEHOLDER_MASTERDATE : + case EPP_PLACEHOLDER_NOTESSLIDEIMAGE : + case EPP_PLACEHOLDER_MASTERNOTESBODYIMAGE : + nPlacementID = nIndices++; + } + } + if ( !pClientData ) + pClientData = new SvMemoryStream( 0x200, 0x200 ); + + *pClientData << (sal_uInt32)( EPP_OEPlaceholderAtom << 16 ) << (sal_uInt32)8 + << nPlacementID // PlacementID + << (sal_uInt8)nPlaceHolderAtom // PlaceHolderID + << (sal_uInt8)0 // Size of PlaceHolder ( 0 = FULL, 1 = HALF, 2 = QUARTER ) + << (sal_uInt16)0; // padword + } + if ( nOlePictureId ) + { + if ( !pClientData ) + pClientData = new SvMemoryStream( 0x200, 0x200 ); + + *pClientData << (sal_uInt32)( EPP_ExObjRefAtom << 16 ) << (sal_uInt32)4 + << nOlePictureId; + nOlePictureId = 0; + } + if ( bEffect ) + { + if ( !pClientData ) + pClientData = new SvMemoryStream( 0x200, 0x200 ); + + // check if it is sensible to replace the object effect with text effect, + // because in Impress there is the possibility to use a compound effect, + // e.g. the object effect is an AnimationEffect_FADE_FROM_LEFT and the + // text effect is a AnimationEffect_FADE_FROM_TOP, in PowerPoint there + // can be used only one effect + if ( mnTextSize && ( eTe != ::com::sun::star::presentation::AnimationEffect_NONE ) + && ( eAe != ::com::sun::star::presentation::AnimationEffect_NONE ) + && ( eTe != eAe ) ) + { + sal_uInt32 nFillStyleFlags, nLineStyleFlags; + if ( aPropOpt.GetOpt( ESCHER_Prop_fNoFillHitTest, nFillStyleFlags ) + && aPropOpt.GetOpt( ESCHER_Prop_fNoLineDrawDash, nLineStyleFlags ) ) + { + // there is no fillstyle and also no linestyle + if ( ! ( ( nFillStyleFlags & 0x10 ) + ( nLineStyleFlags & 9 ) ) ) + eAe = eTe; + } + } + if ( !mbUseNewAnimations ) + ImplWriteObjectEffect( *pClientData, eAe, eTe, ++nEffectCount ); + } + + if ( eCa != ::com::sun::star::presentation::ClickAction_NONE ) + { + if ( !pClientData ) + pClientData = new SvMemoryStream( 0x200, 0x200 ); + ImplWriteClickAction( *pClientData, eCa, bMediaClickAction ); + } + } + if ( ( mnTextStyle == EPP_TEXTSTYLE_TITLE ) || ( mnTextStyle == EPP_TEXTSTYLE_BODY ) ) + { + if ( !pClientTextBox ) + pClientTextBox = new SvMemoryStream( 0x200, 0x200 ); + + if ( mbEmptyPresObj == FALSE ) + { + if ( ( ePageType == NORMAL ) && ( bMasterPage == FALSE ) ) + { + sal_uInt32 nTextType = EPP_TEXTTYPE_Body; + if ( mnTextStyle == EPP_TEXTSTYLE_BODY ) + { + if ( bSecOutl ) + nTextType = EPP_TEXTTYPE_HalfBody; + else if ( mType == "presentation.Subtitle" ) + nTextType = EPP_TEXTTYPE_CenterBody; + bSecOutl = sal_True; + } + else + nTextType = EPP_TEXTTYPE_Title; + + TextRuleEntry aTextRule( nPageNumber ); + SvMemoryStream aExtBu( 0x200, 0x200 ); + ImplGetText(); + ImplWriteTextStyleAtom( *pClientTextBox, nTextType, nPObjects, &aTextRule, aExtBu, NULL ); + ImplWriteExtParaHeader( aExtBu, nPObjects++, nTextType, nPageNumber + 0x100 ); + SvMemoryStream* pOut = aTextRule.pOut; + if ( pOut ) + { + pClientTextBox->Write( pOut->GetData(), pOut->Tell() ); + delete pOut, aTextRule.pOut = NULL; + } + } + } + } + else + { + if ( !aPropOpt.IsFontWork() ) + { + if ( mnTextSize || ( nPlaceHolderAtom == EPP_PLACEHOLDER_MASTERDATE ) || ( nPlaceHolderAtom == EPP_PLACEHOLDER_NOTESBODY ) ) + { + int nInstance2; + if ( ( nPlaceHolderAtom == EPP_PLACEHOLDER_MASTERDATE ) || ( nPlaceHolderAtom == EPP_PLACEHOLDER_NOTESBODY ) ) + nInstance2 = 2; + else + nInstance2 = EPP_TEXTTYPE_Other; // Text in a Shape + + if ( !pClientTextBox ) + pClientTextBox = new SvMemoryStream( 0x200, 0x200 ); + + SvMemoryStream aExtBu( 0x200, 0x200 ); + ImplWriteTextStyleAtom( *pClientTextBox, nInstance2, 0, NULL, aExtBu, &aPropOpt ); + if ( aExtBu.Tell() ) + { + if ( !pClientData ) + pClientData = new SvMemoryStream( 0x200, 0x200 ); + ImplProgTagContainer( pClientData, &aExtBu ); + } + } + else if ( nPlaceHolderAtom >= 19 ) + { + if ( !pClientTextBox ) + pClientTextBox = new SvMemoryStream( 12 ); + + *pClientTextBox << (sal_uInt32)( EPP_TextHeaderAtom << 16 ) << (sal_uInt32)4 + << (sal_uInt32)7; + } + } + } + + aPropOpt.CreateShadowProperties( mXPropSet ); + maRect.Justify(); + if ( mnAngle ) + ImplFlipBoundingBox( aPropOpt ); + aPropOpt.Commit( *mpStrm ); + mpPptEscherEx->AddClientAnchor( maRect ); + + if ( pClientData ) + { + *mpStrm << (sal_uInt32)( ( ESCHER_ClientData << 16 ) | 0xf ) + << (sal_uInt32)pClientData->Tell(); + + mpStrm->Write( pClientData->GetData(), pClientData->Tell() ); + delete pClientData, pClientData = NULL; + } + if ( pClientTextBox ) + { + *mpStrm << (sal_uInt32)( ( ESCHER_ClientTextbox << 16 ) | 0xf ) + << (sal_uInt32)pClientTextBox->Tell(); + + mpStrm->Write( pClientTextBox->GetData(), pClientTextBox->Tell() ); + delete pClientTextBox, pClientTextBox = NULL; + } + mpPptEscherEx->CloseContainer(); // ESCHER_SpContainer + } + nPrevTextStyle = mnTextStyle; + + if ( bAdditionalText ) + { + bAdditionalText = FALSE; + + ::com::sun::star::uno::Any aAny; + EscherPropertyContainer aPropOpt; + mnAngle = ( PropValue::GetPropertyValue( aAny, + mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "RotateAngle" ) ), sal_True ) ) + ? *((sal_Int32*)aAny.getValue() ) + : 0; + + aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x90000 ); + aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x100000 ); + if ( mType == "drawing.Line" ) + { + double fDist = hypot( maRect.GetWidth(), maRect.GetHeight() ); + maRect = Rectangle( Point( aTextRefPoint.X, aTextRefPoint.Y ), + Point( (sal_Int32)( aTextRefPoint.X + fDist ), aTextRefPoint.Y - 1 ) ); + ImplCreateTextShape( aPropOpt, aSolverContainer, FALSE ); + aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x60006 ); // Size Shape To Fit Text + if ( mnAngle < 0 ) + mnAngle = ( 36000 + mnAngle ) % 36000; + if ( mnAngle ) + ImplFlipBoundingBox( aPropOpt ); + } + else + { + ImplCreateTextShape( aPropOpt, aSolverContainer, FALSE ); + if ( mnAngle < 0 ) + mnAngle = ( 36000 + mnAngle ) % 36000; + else + mnAngle = ( 36000 - ( mnAngle % 36000 ) ); + + mnAngle *= 655; + mnAngle += 0x8000; + mnAngle &=~0xffff; // nAngle auf volle Gradzahl runden + aPropOpt.AddOpt( ESCHER_Prop_Rotation, mnAngle ); + mpPptEscherEx->SetGroupSnapRect( nGroupLevel, maRect ); + mpPptEscherEx->SetGroupLogicRect( nGroupLevel, maRect ); + } + if ( !pClientTextBox ) + pClientTextBox = new SvMemoryStream( 0x200, 0x200 ); + + SvMemoryStream aExtBu( 0x200, 0x200 ); + ImplWriteTextStyleAtom( *pClientTextBox, EPP_TEXTTYPE_Other, 0, NULL, aExtBu, &aPropOpt ); + + aPropOpt.Commit( *mpStrm ); + mpPptEscherEx->AddClientAnchor( maRect ); + + *mpStrm << (sal_uInt32)( ( ESCHER_ClientTextbox << 16 ) | 0xf ) + << (sal_uInt32)pClientTextBox->Tell(); + + mpStrm->Write( pClientTextBox->GetData(), pClientTextBox->Tell() ); + delete pClientTextBox, pClientTextBox = NULL; + + mpPptEscherEx->CloseContainer(); // ESCHER_SpContainer + mpPptEscherEx->LeaveGroup(); + } + } + ClearGroupTable(); // gruppierungen wegschreiben, sofern noch irgendwelche offen sind, was eigendlich nicht sein sollte + nGroups = GetGroupsClosed(); + for ( sal_uInt32 i = 0; i < nGroups; i++, mpPptEscherEx->LeaveGroup() ) ; + mnPagesWritten++; +} + +// ----------------------------------------------------------------------- + +::com::sun::star::awt::Point PPTWriter::ImplMapPoint( const ::com::sun::star::awt::Point& rPoint ) +{ + Point aRet( OutputDevice::LogicToLogic( Point( rPoint.X, rPoint.Y ), maMapModeSrc, maMapModeDest ) ); + return ::com::sun::star::awt::Point( aRet.X(), aRet.Y() ); +} + +// ----------------------------------------------------------------------- + +::com::sun::star::awt::Size PPTWriter::ImplMapSize( const ::com::sun::star::awt::Size& rSize ) +{ + Size aRetSize( OutputDevice::LogicToLogic( Size( rSize.Width, rSize.Height ), maMapModeSrc, maMapModeDest ) ); + + if ( !aRetSize.Width() ) + aRetSize.Width()++; + if ( !aRetSize.Height() ) + aRetSize.Height()++; + return ::com::sun::star::awt::Size( aRetSize.Width(), aRetSize.Height() ); +} + +// ----------------------------------------------------------------------- + +Rectangle PPTWriter::ImplMapRectangle( const ::com::sun::star::awt::Rectangle& rRect ) +{ + ::com::sun::star::awt::Point aPoint( rRect.X, rRect.Y ); + ::com::sun::star::awt::Size aSize( rRect.Width, rRect.Height ); + ::com::sun::star::awt::Point aP( ImplMapPoint( aPoint ) ); + ::com::sun::star::awt::Size aS( ImplMapSize( aSize ) ); + return Rectangle( Point( aP.X, aP.Y ), Size( aS.Width, aS.Height ) ); +} + +// ----------------------------------------------------------------------- + +struct CellBorder +{ + sal_Int32 mnPos; // specifies the distance to the top/left position of the table + sal_Int32 mnLength; + table::BorderLine maCellBorder; + + CellBorder() : mnPos ( 0 ), mnLength( 0 ){}; +}; + +void PPTWriter::ImplCreateCellBorder( const CellBorder* pCellBorder, sal_Int32 nX1, sal_Int32 nY1, sal_Int32 nX2, sal_Int32 nY2 ) +{ + sal_Int32 nLineWidth = pCellBorder->maCellBorder.OuterLineWidth + pCellBorder->maCellBorder.InnerLineWidth; + if ( nLineWidth ) + { + mnAngle = 0; + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + EscherPropertyContainer aPropOptSp; + + sal_uInt32 nId = mpPptEscherEx->GenerateShapeId(); + mpPptEscherEx->AddShape( ESCHER_ShpInst_Line, 0xa02, nId ); + aPropOptSp.AddOpt( ESCHER_Prop_shapePath, ESCHER_ShapeComplex ); + aPropOptSp.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0xa0008 ); + aPropOptSp.AddOpt( ESCHER_Prop_fshadowObscured, 0x20000 ); + + sal_uInt32 nBorderColor = pCellBorder->maCellBorder.Color & 0xff00; // green + nBorderColor |= static_cast< sal_uInt8 >( pCellBorder->maCellBorder.Color ) << 16; // red + nBorderColor |= static_cast< sal_uInt8 >( pCellBorder->maCellBorder.Color >> 16 ); // blue + aPropOptSp.AddOpt( ESCHER_Prop_lineColor, nBorderColor ); + + aPropOptSp.AddOpt( ESCHER_Prop_lineWidth, nLineWidth * 360 ); + aPropOptSp.AddOpt( ESCHER_Prop_fc3DLightFace, 0x80000 ); + aPropOptSp.Commit( *mpStrm ); + mpPptEscherEx->AddAtom( 16, ESCHER_ChildAnchor ); + *mpStrm << nX1 + << nY1 + << nX2 + << nY2; + mpPptEscherEx->CloseContainer(); + } +} + +void PPTWriter::WriteCString( SvStream& rSt, const String& rString, sal_uInt32 nInstance ) +{ + sal_uInt32 i, nLen = rString.Len(); + if ( nLen ) + { + rSt << (sal_uInt32)( ( nInstance << 4 ) | ( EPP_CString << 16 ) ) + << (sal_uInt32)( nLen << 1 ); + for ( i = 0; i < nLen; i++ ) + rSt << rString.GetChar( (sal_uInt16)i ); + } +} + +void PPTWriter::ImplCreateTable( uno::Reference< drawing::XShape >& rXShape, EscherSolverContainer& aSolverContainer, + EscherPropertyContainer& aPropOpt ) +{ + mpPptEscherEx->OpenContainer( ESCHER_SpgrContainer ); + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + mpPptEscherEx->AddAtom( 16, ESCHER_Spgr, 1 ); + *mpStrm << (INT32)maRect.Left() // Bounding box fuer die Gruppierten shapes an die sie attached werden + << (INT32)maRect.Top() + << (INT32)maRect.Right() + << (INT32)maRect.Bottom(); + + sal_uInt32 nShapeId = mpPptEscherEx->GenerateShapeId(); + mpPptEscherEx->AddShape( ESCHER_ShpInst_Min, 0x201, nShapeId ); // Flags: Group | Patriarch + aSolverContainer.AddShape( rXShape, nShapeId ); + EscherPropertyContainer aPropOpt2; + try + { + static const rtl::OUString sModel( RTL_CONSTASCII_USTRINGPARAM ( "Model" ) ); + static const rtl::OUString sWidth( RTL_CONSTASCII_USTRINGPARAM ( "Width" ) ); + static const rtl::OUString sHeight( RTL_CONSTASCII_USTRINGPARAM ( "Height" ) ); + + uno::Reference< table::XTable > xTable; + if ( mXPropSet->getPropertyValue( sModel ) >>= xTable ) + { + uno::Reference< table::XColumnRowRange > xColumnRowRange( xTable, uno::UNO_QUERY_THROW ); + uno::Reference< container::XIndexAccess > xColumns( xColumnRowRange->getColumns(), uno::UNO_QUERY_THROW ); + uno::Reference< container::XIndexAccess > xRows( xColumnRowRange->getRows(), uno::UNO_QUERY_THROW ); + sal_uInt16 nRowCount = static_cast< sal_uInt16 >( xRows->getCount() ); + sal_uInt16 nColumnCount = static_cast< sal_uInt16 >( xColumns->getCount() ); + + std::vector< std::pair< sal_Int32, sal_Int32 > > aColumns; + std::vector< std::pair< sal_Int32, sal_Int32 > > aRows; + + awt::Point aPosition( ImplMapPoint( rXShape->getPosition() ) ); + sal_uInt32 nPosition = aPosition.X; + for ( sal_Int32 x = 0; x < nColumnCount; x++ ) + { + uno::Reference< beans::XPropertySet > xPropSet( xColumns->getByIndex( x ), uno::UNO_QUERY_THROW ); + awt::Size aS( 0, 0 ); + xPropSet->getPropertyValue( sWidth ) >>= aS.Width; + awt::Size aM( ImplMapSize( aS ) ); + aColumns.push_back( std::pair< sal_Int32, sal_Int32 >( nPosition, aM.Width ) ); + nPosition += aM.Width; + } + + nPosition = aPosition.Y; + for ( sal_Int32 y = 0; y < nRowCount; y++ ) + { + uno::Reference< beans::XPropertySet > xPropSet( xRows->getByIndex( y ), uno::UNO_QUERY_THROW ); + awt::Size aS( 0, 0 ); + xPropSet->getPropertyValue( sHeight ) >>= aS.Height; + awt::Size aM( ImplMapSize( aS ) ); + aRows.push_back( std::pair< sal_Int32, sal_Int32 >( nPosition, aM.Height ) ); + nPosition += aM.Height; + } + + if ( nRowCount ) + { + SvMemoryStream aMemStrm; + aMemStrm.ObjectOwnsMemory( FALSE ); + aMemStrm << nRowCount + << nRowCount + << (sal_uInt16)4; + + std::vector< std::pair< sal_Int32, sal_Int32 > >::const_iterator aIter( aRows.begin() ); + while( aIter != aRows.end() ) + aMemStrm << (*aIter++).second; + + aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x1000100 ); + aPropOpt2.AddOpt( ESCHER_Prop_tableProperties, 1 ); + aPropOpt2.AddOpt( ESCHER_Prop_tableRowProperties, sal_True, aMemStrm.Tell(), static_cast< sal_uInt8* >( const_cast< void* >( aMemStrm.GetData() ) ), aMemStrm.Tell() ); + aPropOpt.Commit( *mpStrm ); + aPropOpt2.Commit( *mpStrm, 3, ESCHER_UDefProp ); + mpPptEscherEx->AddAtom( 8, ESCHER_ClientAnchor ); + *mpStrm << (sal_Int16)maRect.Top() + << (sal_Int16)maRect.Left() + << (sal_Int16)( maRect.GetWidth() + maRect.Left() ) + << (sal_Int16)( maRect.GetHeight() + maRect.Top() ); + mpPptEscherEx->CloseContainer(); + + + uno::Reference< table::XCellRange > xCellRange( xTable, uno::UNO_QUERY_THROW ); + for( sal_Int32 nRow = 0; nRow < xRows->getCount(); nRow++ ) + { + for( sal_Int32 nColumn = 0; nColumn < xColumns->getCount(); nColumn++ ) + { + uno::Reference< table::XMergeableCell > xCell( xCellRange->getCellByPosition( nColumn, nRow ), uno::UNO_QUERY_THROW ); + if ( !xCell->isMerged() ) + { + sal_Int32 nLeft = aColumns[ nColumn ].first; + sal_Int32 nTop = aRows[ nRow ].first; + sal_Int32 nRight = nLeft + aColumns[ nColumn ].second; + sal_Int32 nBottom = nTop + aRows[ nRow ].second; + + for ( sal_Int32 nColumnSpan = 1; nColumnSpan < xCell->getColumnSpan(); nColumnSpan++ ) + { + sal_uInt32 nC = nColumnSpan + nColumn; + if ( nC < aColumns.size() ) + nRight += aColumns[ nC ].second; + else + nRight = maRect.Right(); + } + for ( sal_Int32 nRowSpan = 1; nRowSpan < xCell->getRowSpan(); nRowSpan++ ) + { + sal_uInt32 nR = nRowSpan + nRow; + if ( nR < aColumns.size() ) + nBottom += aRows[ nR ].second; + else + nBottom = maRect.Bottom(); + } + + mbFontIndependentLineSpacing = sal_False; + mXPropSet = uno::Reference< beans::XPropertySet >( xCell, uno::UNO_QUERY_THROW ); + mXText = uno::Reference< text::XSimpleText >( xCell, uno::UNO_QUERY_THROW ); + mnTextSize = mXText->getString().getLength(); + + ::com::sun::star::uno::Any aAny; + if ( GetPropertyValue( aAny, mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FontIndependentLineSpacing" ) ) ), sal_True ) + aAny >>= mbFontIndependentLineSpacing; + + EscherPropertyContainer aPropOptSp; + mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); + ImplCreateShape( ESCHER_ShpInst_Rectangle, 0xa02, aSolverContainer ); // Flags: Connector | HasSpt | Child + aPropOptSp.CreateFillProperties( mXPropSet, sal_True ); + aPropOptSp.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x90000 ); + aPropOptSp.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_True ); + aPropOptSp.AddOpt( ESCHER_Prop_WrapText, ESCHER_WrapSquare ); + + SvMemoryStream aClientTextBox( 0x200, 0x200 ); + SvMemoryStream aExtBu( 0x200, 0x200 ); + + ImplWriteTextStyleAtom( aClientTextBox, EPP_TEXTTYPE_Other, 0, NULL, aExtBu, &aPropOptSp ); + + aPropOptSp.Commit( *mpStrm ); + mpPptEscherEx->AddAtom( 16, ESCHER_ChildAnchor ); + *mpStrm << nLeft + << nTop + << nRight + << nBottom; + + *mpStrm << (sal_uInt32)( ( ESCHER_ClientTextbox << 16 ) | 0xf ) + << (sal_uInt32)aClientTextBox.Tell(); + + mpStrm->Write( aClientTextBox.GetData(), aClientTextBox.Tell() ); + mpPptEscherEx->CloseContainer(); + } + } + } + + static const rtl::OUString sTopBorder( String( RTL_CONSTASCII_USTRINGPARAM( "TopBorder" ) ) ); + static const rtl::OUString sBottomBorder( String( RTL_CONSTASCII_USTRINGPARAM( "BottomBorder" ) ) ); + static const rtl::OUString sLeftBorder( String( RTL_CONSTASCII_USTRINGPARAM( "LeftBorder" ) ) ); + static const rtl::OUString sRightBorder( String( RTL_CONSTASCII_USTRINGPARAM( "RightBorder" ) ) ); + static const rtl::OUString sDiagonalTLBR( RTL_CONSTASCII_USTRINGPARAM ( "DiagonalTLBR" ) ); + static const rtl::OUString sDiagonalBLTR( RTL_CONSTASCII_USTRINGPARAM ( "DiagonalBLTR" ) ); + + // creating horz lines + sal_Int32 nYPos = ImplMapPoint( rXShape->getPosition() ).Y; + for( sal_Int32 nLine = 0; nLine < ( xRows->getCount() + 1 ); nLine++ ) + { + sal_Int32 nXPos = ImplMapPoint( rXShape->getPosition() ).X; + std::vector< CellBorder > vCellBorders; + for( sal_Int32 nColumn = 0; nColumn < xColumns->getCount(); nColumn++ ) + { + uno::Reference< beans::XPropertySet > xPropSet( xColumns->getByIndex( nColumn ), uno::UNO_QUERY_THROW ); + awt::Size aS( 0, 0 ); + xPropSet->getPropertyValue( sWidth ) >>= aS.Width; + awt::Size aM( ImplMapSize( aS ) ); + + CellBorder aCellBorder; + aCellBorder.mnPos = nXPos; + aCellBorder.mnLength = aM.Width; + if ( nLine < xRows->getCount() ) + { // top border + uno::Reference< table::XMergeableCell > xCell( xCellRange->getCellByPosition( nColumn, nLine ), uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xPropSet2( xCell, uno::UNO_QUERY_THROW ); + table::BorderLine aBorderLine; + if ( xPropSet2->getPropertyValue( sTopBorder ) >>= aBorderLine ) + aCellBorder.maCellBorder = aBorderLine; + } + if ( nLine ) + { // bottom border + uno::Reference< table::XMergeableCell > xCell( xCellRange->getCellByPosition( nColumn, nLine - 1 ), uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xPropSet2( xCell, uno::UNO_QUERY_THROW ); + table::BorderLine aBorderLine; + if ( xPropSet2->getPropertyValue( sBottomBorder ) >>= aBorderLine ) + aCellBorder.maCellBorder = aBorderLine; + } + vCellBorders.push_back( aCellBorder ); + nXPos += aM.Width; + } + std::vector< CellBorder >::const_iterator aCellBorderIter( vCellBorders.begin() ); + while( aCellBorderIter != vCellBorders.end() ) + { + ImplCreateCellBorder( &*aCellBorderIter, aCellBorderIter->mnPos, nYPos, + static_cast< sal_Int32 >( aCellBorderIter->mnPos + aCellBorderIter->mnLength ), nYPos ); + aCellBorderIter++; + } + if ( nLine < xRows->getCount() ) + { + uno::Reference< beans::XPropertySet > xPropSet( xRows->getByIndex( nLine ), uno::UNO_QUERY_THROW ); + awt::Size aS( 0, 0 ); + xPropSet->getPropertyValue( sHeight ) >>= aS.Height; + awt::Size aM( ImplMapSize( aS ) ); + nYPos += aM.Height; + } + } + + // creating vertical lines + sal_Int32 nXPos = ImplMapPoint( rXShape->getPosition() ).X; + for( sal_Int32 nLine = 0; nLine < ( xColumns->getCount() + 1 ); nLine++ ) + { + nYPos = ImplMapPoint( rXShape->getPosition() ).Y; + std::vector< CellBorder > vCellBorders; + for( sal_Int32 nRow = 0; nRow < xRows->getCount(); nRow++ ) + { + uno::Reference< beans::XPropertySet > xPropSet( xRows->getByIndex( nRow ), uno::UNO_QUERY_THROW ); + awt::Size aS( 0, 0 ); + xPropSet->getPropertyValue( sHeight ) >>= aS.Height; + awt::Size aM( ImplMapSize( aS ) ); + + CellBorder aCellBorder; + aCellBorder.mnPos = nYPos; + aCellBorder.mnLength = aM.Height; + if ( nLine < xColumns->getCount() ) + { // left border + uno::Reference< table::XMergeableCell > xCell( xCellRange->getCellByPosition( nLine, nRow ), uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xCellSet( xCell, uno::UNO_QUERY_THROW ); + table::BorderLine aBorderLine; + if ( xCellSet->getPropertyValue( sLeftBorder ) >>= aBorderLine ) + aCellBorder.maCellBorder = aBorderLine; + } + if ( nLine ) + { // right border + uno::Reference< table::XMergeableCell > xCell( xCellRange->getCellByPosition( nLine - 1, nRow ), uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xCellSet( xCell, uno::UNO_QUERY_THROW ); + table::BorderLine aBorderLine; + if ( xCellSet->getPropertyValue( sRightBorder ) >>= aBorderLine ) + aCellBorder.maCellBorder = aBorderLine; + } + vCellBorders.push_back( aCellBorder ); + nYPos += aM.Height; + } + std::vector< CellBorder >::const_iterator aCellBorderIter( vCellBorders.begin() ); + while( aCellBorderIter != vCellBorders.end() ) + { + ImplCreateCellBorder( &*aCellBorderIter, nXPos, aCellBorderIter->mnPos, + nXPos, static_cast< sal_Int32 >( aCellBorderIter->mnPos + aCellBorderIter->mnLength ) ); + aCellBorderIter++; + } + if ( nLine < xColumns->getCount() ) + { + uno::Reference< beans::XPropertySet > xPropSet( xColumns->getByIndex( nLine ), uno::UNO_QUERY_THROW ); + awt::Size aS( 0, 0 ); + xPropSet->getPropertyValue( sWidth ) >>= aS.Width; + awt::Size aM( ImplMapSize( aS ) ); + nXPos += aM.Width; + } + } + } + } + } + catch( uno::Exception& ) + { + } + mpPptEscherEx->CloseContainer(); +} diff --git a/sd/source/filter/eppt/escherex.cxx b/sd/source/filter/eppt/escherex.cxx new file mode 100644 index 000000000000..fbb94de67ae7 --- /dev/null +++ b/sd/source/filter/eppt/escherex.cxx @@ -0,0 +1,294 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" + + +#ifndef _PptEscherEx_HXX +#include "escherex.hxx" +#endif + +// --------------------------------------------------------------------------------------------- +// --------------------------------------------------------------------------------------------- +// --------------------------------------------------------------------------------------------- + +PptEscherEx::PptEscherEx( SvStream& rOutStrm ) : + EscherEx( EscherExGlobalRef( new EscherExGlobal ), rOutStrm ) +{ + mnCurrentDg = 0; +} + +// --------------------------------------------------------------------------------------------- + +sal_uInt32 PptEscherEx::DrawingGroupContainerSize() +{ + return ImplDggContainerSize() + 8; +} + +void PptEscherEx::WriteDrawingGroupContainer( SvStream& rSt ) +{ + UINT32 nSize = DrawingGroupContainerSize(); + rSt << (sal_uInt32)( 0xf | ( 1035 << 16 ) ) // EPP_PPDrawingGroup + << (sal_uInt32)( nSize - 8 ); + + ImplWriteDggContainer( rSt ); +} + +// --------------------------------------------------------------------------------------------- + +sal_uInt32 PptEscherEx::ImplDggContainerSize() +{ + UINT32 nSize; + + nSize = mxGlobal->GetDggAtomSize(); + nSize += mxGlobal->GetBlibStoreContainerSize(); + nSize += ImplOptAtomSize(); + nSize += ImplSplitMenuColorsAtomSize(); + + return nSize + 8; +} + +void PptEscherEx::ImplWriteDggContainer( SvStream& rSt ) +{ + sal_uInt32 nSize = ImplDggContainerSize(); + if ( nSize ) + { + rSt << (sal_uInt32)( 0xf | ( ESCHER_DggContainer << 16 ) ) + << (sal_uInt32)( nSize - 8 ); + + mxGlobal->SetDggContainer(); + mxGlobal->WriteDggAtom( rSt ); + mxGlobal->WriteBlibStoreContainer( rSt ); + ImplWriteOptAtom( rSt ); + ImplWriteSplitMenuColorsAtom( rSt ); + } +} + +// --------------------------------------------------------------------------------------------- + +#define ESCHER_OPT_COUNT 6 + +sal_uInt32 PptEscherEx::ImplOptAtomSize() +{ + sal_uInt32 nSize = 0; + if ( ESCHER_OPT_COUNT ) + nSize = ( ESCHER_OPT_COUNT * 6 ) + 8; + return nSize; +} + +void PptEscherEx::ImplWriteOptAtom( SvStream& rSt ) +{ + sal_uInt32 nSize = ImplOptAtomSize(); + if ( nSize ) + { + rSt << (sal_uInt32)( ( ESCHER_OPT << 16 ) | ( ESCHER_OPT_COUNT << 4 ) | 0x3 ) + << (sal_uInt32)( nSize - 8 ) + << (sal_uInt16)ESCHER_Prop_fillColor << (sal_uInt32)0xffb800 + << (sal_uInt16)ESCHER_Prop_fillBackColor << (sal_uInt32)0 + << (sal_uInt16)ESCHER_Prop_fNoFillHitTest << (sal_uInt32)0x00100010 + << (sal_uInt16)ESCHER_Prop_lineColor << (sal_uInt32)0x8000001 + << (sal_uInt16)ESCHER_Prop_fNoLineDrawDash << (sal_uInt32)0x00080008 + << (sal_uInt16)ESCHER_Prop_shadowColor << (sal_uInt32)0x8000002; + } +} + +// --------------------------------------------------------------------------------------------- + +#define ESCHER_SPLIT_MENU_COLORS_COUNT 4 + +sal_uInt32 PptEscherEx::ImplSplitMenuColorsAtomSize() +{ + sal_uInt32 nSize = 0; + if ( ESCHER_SPLIT_MENU_COLORS_COUNT ) + nSize = ( ESCHER_SPLIT_MENU_COLORS_COUNT << 2 ) + 8; + return nSize; +} + +void PptEscherEx::ImplWriteSplitMenuColorsAtom( SvStream& rSt ) +{ + UINT32 nSize = ImplSplitMenuColorsAtomSize(); + if ( nSize ) + { + rSt << (sal_uInt32)( ( ESCHER_SplitMenuColors << 16 ) | ( ESCHER_SPLIT_MENU_COLORS_COUNT << 4 ) ) + << (sal_uInt32)( nSize - 8 ) + << (sal_uInt32)0x08000004 + << (sal_uInt32)0x08000001 + << (sal_uInt32)0x08000002 + << (sal_uInt32)0x100000f7; + } + +} + +// --------------------------------------------------------------------------------------------- + +PptEscherEx::~PptEscherEx() +{ +} + +// --------------------------------------------------------------------------------------------- + +void PptEscherEx::OpenContainer( UINT16 n_EscherContainer, int nRecInstance ) +{ + *mpOutStrm << (UINT16)( ( nRecInstance << 4 ) | 0xf ) << n_EscherContainer << (UINT32)0; + mOffsets.push_back( mpOutStrm->Tell() - 4 ); + mRecTypes.push_back( n_EscherContainer ); + + switch( n_EscherContainer ) + { + case ESCHER_DgContainer : + { + if ( !mbEscherDg ) + { + mbEscherDg = TRUE; + mnCurrentDg = mxGlobal->GenerateDrawingId(); + AddAtom( 8, ESCHER_Dg, 0, mnCurrentDg ); + PtReplaceOrInsert( ESCHER_Persist_Dg | mnCurrentDg, mpOutStrm->Tell() ); + *mpOutStrm << (UINT32)0 // The number of shapes in this drawing + << (UINT32)0; // The last MSOSPID given to an SP in this DG + } + } + break; + + case ESCHER_SpgrContainer : + { + if ( mbEscherDg ) + { + mbEscherSpgr = TRUE; + } + } + break; + + case ESCHER_SpContainer : + { + } + break; + + default: + break; + } +} + +// --------------------------------------------------------------------------------------------- + +void PptEscherEx::CloseContainer() +{ + /* SJ: #Issue 26747# + not creating group objects with a depth higher than 16, because then + PPT is having a big performance problem when starting a slide show + */ + if ( ( mRecTypes.back() != ESCHER_SpgrContainer ) || ( mnGroupLevel < 12 ) ) + { + UINT32 nSize, nPos = mpOutStrm->Tell(); + nSize = ( nPos - mOffsets.back() ) - 4; + mpOutStrm->Seek( mOffsets.back() ); + *mpOutStrm << nSize; + + switch( mRecTypes.back() ) + { + case ESCHER_DgContainer : + { + if ( mbEscherDg ) + { + mbEscherDg = FALSE; + if ( DoSeek( ESCHER_Persist_Dg | mnCurrentDg ) ) + *mpOutStrm << mxGlobal->GetDrawingShapeCount( mnCurrentDg ) << mxGlobal->GetLastShapeId( mnCurrentDg ); + } + } + break; + + case ESCHER_SpgrContainer : + { + if ( mbEscherSpgr ) + { + mbEscherSpgr = FALSE; + + } + } + break; + + default: + break; + } + mOffsets.pop_back(); + mRecTypes.pop_back(); + mpOutStrm->Seek( nPos ); + } +} + +// --------------------------------------------------------------------------------------------- + +sal_uInt32 PptEscherEx::EnterGroup( Rectangle* pBoundRect, SvMemoryStream* pClientData ) +{ + sal_uInt32 nShapeId = 0; + /* SJ: #Issue 26747# + not creating group objects with a depth higher than 16, because then + PPT is having a big performance problem when starting a slide show + */ + if ( mnGroupLevel < 12 ) + { + Rectangle aRect; + if ( pBoundRect ) + aRect = *pBoundRect; + + OpenContainer( ESCHER_SpgrContainer ); + OpenContainer( ESCHER_SpContainer ); + AddAtom( 16, ESCHER_Spgr, 1 ); + PtReplaceOrInsert( ESCHER_Persist_Grouping_Snap | mnGroupLevel, mpOutStrm->Tell() ); + *mpOutStrm << (INT32)aRect.Left() // Bounding box fuer die Gruppierten shapes an die sie attached werden + << (INT32)aRect.Top() + << (INT32)aRect.Right() + << (INT32)aRect.Bottom(); + + nShapeId = GenerateShapeId(); + if ( !mnGroupLevel ) + AddShape( ESCHER_ShpInst_Min, 5, nShapeId ); // Flags: Group | Patriarch + else + { + AddShape( ESCHER_ShpInst_Min, 0x201, nShapeId ); // Flags: Group | HaveAnchor + AddAtom( 8, ESCHER_ClientAnchor ); + PtReplaceOrInsert( ESCHER_Persist_Grouping_Logic | mnGroupLevel, mpOutStrm->Tell() ); + *mpOutStrm << (INT16)aRect.Top() << (INT16)aRect.Left() << (INT16)aRect.Right() << (INT16)aRect.Bottom(); + } + if ( pClientData ) + { + pClientData->Seek( STREAM_SEEK_TO_END ); + sal_uInt32 nSize = pClientData->Tell(); + if ( nSize ) + { + *mpOutStrm << (sal_uInt32)( ( ESCHER_ClientData << 16 ) | 0xf ) + << nSize; + mpOutStrm->Write( pClientData->GetData(), nSize ); + } + } + CloseContainer(); // ESCHER_SpContainer + } + mnGroupLevel++; + return nShapeId; +} + +// --------------------------------------------------------------------------------------------- diff --git a/sd/source/filter/eppt/escherex.hxx b/sd/source/filter/eppt/escherex.hxx new file mode 100644 index 000000000000..739ef6300d1c --- /dev/null +++ b/sd/source/filter/eppt/escherex.hxx @@ -0,0 +1,77 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _PptEscherEX_HXX +#define _PptEscherEX_HXX +#include <filter/msfilter/escherex.hxx> + +// --------------------------------------------------------------------------------------------- +// Werte fuer den ULONG im PPT_PST_TextHeaderAtom +enum PPT_TextHeader +{ + PPTTH_TITLE, + PPTTH_BODY, + PPTTH_NOTES, + PPTTH_NOTUSED, + PPTTH_OTHER, // Text in a Shape + PPTTH_CENTERBODY, // Subtitle in Title-Slide + PPTTH_CENTERTITLE, // Title in Title-Slide + PPTTH_HALFBODY, // Body in two-column slide + PPTTH_QUARTERBODY // Body in four-body slide +}; + +// --------------------------------------------------------------------------------------------- + +class PptEscherEx : public EscherEx +{ + sal_uInt32 ImplDggContainerSize(); + void ImplWriteDggContainer( SvStream& rSt ); + + sal_uInt32 ImplOptAtomSize(); + void ImplWriteOptAtom( SvStream& rSt ); + + sal_uInt32 ImplSplitMenuColorsAtomSize(); + void ImplWriteSplitMenuColorsAtom( SvStream& rSt ); + + public: + + PptEscherEx( SvStream& rOut ); + ~PptEscherEx(); + + void OpenContainer( UINT16 n_EscherContainer, int nRecInstance = 0 ); + void CloseContainer(); + + sal_uInt32 EnterGroup( Rectangle* pBoundRect, SvMemoryStream* pClientData ); + + UINT32 DrawingGroupContainerSize(); + void WriteDrawingGroupContainer( SvStream& rSt ); + + using EscherEx::EnterGroup; +}; + + +#endif diff --git a/sd/source/filter/eppt/makefile.mk b/sd/source/filter/eppt/makefile.mk new file mode 100644 index 000000000000..85a8ee18152d --- /dev/null +++ b/sd/source/filter/eppt/makefile.mk @@ -0,0 +1,52 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. +PRJNAME=sd +TARGET=eppt +ENABLE_EXCEPTIONS=TRUE +VISIBILITY_HIDDEN=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +.IF "$(COM)"=="GCC" +NOOPTFILES= $(SLO)$/epptso.obj +.ENDIF + +SLOFILES = $(SLO)$/eppt.obj \ + $(SLO)$/epptso.obj \ + $(SLO)$/escherex.obj \ + $(SLO)$/pptexanimations.obj \ + $(SLO)$/pptexsoundcollection.obj + +# --- Targets -------------------------------------------------------------- + +.INCLUDE : target.mk diff --git a/sd/source/filter/eppt/pptexanimations.cxx b/sd/source/filter/eppt/pptexanimations.cxx new file mode 100644 index 000000000000..4e4b50007443 --- /dev/null +++ b/sd/source/filter/eppt/pptexanimations.cxx @@ -0,0 +1,2191 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" +#include <com/sun/star/animations/XAnimationNodeSupplier.hpp> +#include <com/sun/star/animations/AnimationFill.hpp> +#include <com/sun/star/animations/AnimationRestart.hpp> +#include <com/sun/star/animations/Timing.hpp> +#include <com/sun/star/animations/Event.hpp> +#include <com/sun/star/animations/AnimationEndSync.hpp> +#include <com/sun/star/animations/EventTrigger.hpp> +#include <com/sun/star/presentation/EffectNodeType.hpp> +#include <com/sun/star/presentation/EffectPresetClass.hpp> +#include <com/sun/star/animations/AnimationNodeType.hpp> +#include <com/sun/star/animations/AnimationTransformType.hpp> +#include <com/sun/star/animations/AnimationCalcMode.hpp> +#include <com/sun/star/animations/AnimationValueType.hpp> +#include <com/sun/star/util/XCloneable.hpp> +#include <com/sun/star/animations/AnimationAdditiveMode.hpp> +#include <com/sun/star/animations/XAnimateSet.hpp> +#include <com/sun/star/animations/XAudio.hpp> +#include <com/sun/star/animations/XTransitionFilter.hpp> +#include <com/sun/star/animations/XAnimateColor.hpp> +#include <com/sun/star/animations/XAnimateMotion.hpp> +#include <com/sun/star/animations/XAnimateTransform.hpp> +#include <com/sun/star/animations/TransitionType.hpp> +#include <com/sun/star/animations/TransitionSubType.hpp> +#include <com/sun/star/animations/ValuePair.hpp> +#include <com/sun/star/animations/AnimationColorSpace.hpp> +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/drawing/FillStyle.hpp> +#include <com/sun/star/drawing/LineStyle.hpp> +#include <com/sun/star/awt/FontWeight.hpp> +#include <com/sun/star/awt/FontUnderline.hpp> +#include <com/sun/star/awt/FontSlant.hpp> +#include <com/sun/star/container/XEnumerationAccess.hpp> +#include <com/sun/star/presentation/ParagraphTarget.hpp> +#include <com/sun/star/text/XSimpleText.hpp> +#include <com/sun/star/animations/XIterateContainer.hpp> +#include <com/sun/star/presentation/TextAnimationType.hpp> +#include <com/sun/star/container/XChild.hpp> +#include <comphelper/processfactory.hxx> +#include <rtl/ustrbuf.hxx> +#ifndef _RTL_MEMORY_H_ +#include <rtl/memory.hxx> +#endif + +#include <vcl/vclenum.hxx> +#include <svx/svdotext.hxx> +#include <editeng/outlobj.hxx> +#include <editeng/editobj.hxx> +#include <pptexanimations.hxx> +#include <osl/endian.h> + +#include <algorithm> + +using ::std::map; +using ::rtl::OUString; +using ::rtl::OUStringBuffer; +using ::com::sun::star::uno::Any; +using ::com::sun::star::container::XChild; +using ::com::sun::star::util::XCloneable; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::uno::UNO_QUERY_THROW; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::makeAny; +using ::com::sun::star::uno::Exception; +using ::com::sun::star::uno::XInterface; +using ::com::sun::star::beans::NamedValue; +using ::com::sun::star::container::XEnumerationAccess; +using ::com::sun::star::container::XEnumeration; +using ::com::sun::star::lang::XMultiServiceFactory; + +using namespace ::com::sun::star::text; +using namespace ::com::sun::star::drawing; +using namespace ::com::sun::star::animations; +using namespace ::com::sun::star::presentation; + +namespace ppt +{ + +void ImplTranslateAttribute( rtl::OUString& rString, const TranslateMode eTranslateMode ) +{ + if ( eTranslateMode != TRANSLATE_NONE ) + { + if ( ( eTranslateMode & TRANSLATE_VALUE ) || ( eTranslateMode & TRANSLATE_ATTRIBUTE ) ) + { + const ImplAttributeNameConversion* p = gImplConversionList; + while( p->mpAPIName ) + { + if( rString.compareToAscii( p->mpAPIName ) == 0 ) + break; + p++; + } + if( p->mpMSName ) + { + if ( eTranslateMode & TRANSLATE_VALUE ) + { + rString = rtl::OUString( (sal_Unicode)'#' ); + rString += OUString::createFromAscii( p->mpMSName ); + } + else + rString = OUString::createFromAscii( p->mpMSName ); + } + } + else if ( eTranslateMode & TRANSLATE_MEASURE ) + { + const sal_Char* pDest[] = { "#ppt_x", "#ppt_y", "#ppt_w", "#ppt_h", NULL }; + const sal_Char* pSource[] = { "x", "y", "width", "height", NULL }; + sal_Int32 nIndex = 0; + + const sal_Char** ps = pSource; + const sal_Char** pd = pDest; + + while( *ps ) + { + const OUString aSearch( OUString::createFromAscii( *ps ) ); + while( (nIndex = rString.indexOf( aSearch, nIndex )) != -1 ) + { + sal_Int32 nLength = aSearch.getLength(); + if( nIndex && (rString.getStr()[nIndex-1] == '#' ) ) + { + nIndex--; + nLength++; + } + + const OUString aNew( OUString::createFromAscii( *pd ) ); + rString = rString.replaceAt( nIndex, nLength, aNew ); + nIndex += aNew.getLength(); + } + ps++; + pd++; + } + } + } +} + +sal_uInt32 ImplTranslatePresetSubType( const sal_uInt32 nPresetClass, const sal_uInt32 nPresetId, const rtl::OUString& rPresetSubType ) +{ + sal_uInt32 nPresetSubType = 0; + sal_Bool bTranslated = sal_False; + + if ( ( nPresetClass == (sal_uInt32)EffectPresetClass::ENTRANCE ) || ( nPresetClass == (sal_uInt32)EffectPresetClass::EXIT ) ) + { + if ( nPresetId != 21 ) + { + switch( nPresetId ) + { + case 5 : + { + if ( rPresetSubType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "downward" ) ) ) + { + nPresetSubType = 5; + bTranslated = sal_True; + } + else if ( rPresetSubType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "across" ) ) ) + { + nPresetSubType = 10; + bTranslated = sal_True; + } + } + break; + case 17 : + { + if ( rPresetSubType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "across" ) ) ) + { + nPresetSubType = 10; + bTranslated = sal_True; + } + } + break; + case 18 : + { + if ( rPresetSubType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "right-to-top" ) ) ) + { + nPresetSubType = 3; + bTranslated = sal_True; + } + else if ( rPresetSubType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "right-to-bottom" ) ) ) + { + nPresetSubType = 6; + bTranslated = sal_True; + } + else if ( rPresetSubType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "left-to-top" ) ) ) + { + nPresetSubType = 9; + bTranslated = sal_True; + } + else if ( rPresetSubType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "left-to-bottom" ) ) ) + { + nPresetSubType = 12; + bTranslated = sal_True; + } + } + break; + } + } + if ( !bTranslated ) + { + const convert_subtype* p = gConvertArray; + while( p->mpStrSubType ) + { + if ( rPresetSubType.equalsAscii( p->mpStrSubType ) ) + { + nPresetSubType = p->mnID; + bTranslated = sal_True; + break; + } + p++; + } + } + } + if ( !bTranslated ) + nPresetSubType = (sal_uInt32)rPresetSubType.toInt32(); + return nPresetSubType; +} + +const sal_Char* transition::find( const sal_Int16 nType, const sal_Int16 nSubType, const sal_Bool bDirection ) +{ + const sal_Char* pRet = NULL; + int nFit = 0; + + const transition* p = gTransitions; + while( p->mpName ) + { + int nF = 0; + if ( nType == p->mnType ) + nF += 4; + if ( nSubType == p->mnSubType ) + nF += 2; + if ( bDirection == p->mbDirection ) + nF += 1; + if ( nF > nFit ) + { + pRet = p->mpName; + nFit = nF; + } + if ( nFit == 7 ) // maximum + break; + p++; + } + return pRet; +} + +SvStream& operator<<(SvStream& rOut, AnimationNode& rNode ) +{ + rOut << rNode.mnU1; + rOut << rNode.mnRestart; + rOut << rNode.mnGroupType; + rOut << rNode.mnFill; + rOut << rNode.mnU3; + rOut << rNode.mnU4; + rOut << rNode.mnDuration; + rOut << rNode.mnNodeType; + + return rOut; +} + +AnimationExporter::AnimationExporter( const EscherSolverContainer& rSolverContainer, ppt::ExSoundCollection& rExSoundCollection ) : + mrSolverContainer ( rSolverContainer ), + mrExSoundCollection ( rExSoundCollection ), + mnCurrentGroup(0) +{ +} + +// -------------------------------------------------------------------- + +static sal_Int16 GetFillMode( const Reference< XAnimationNode >& xNode, const sal_Int16 nFillDefault ) +{ + sal_Int16 nFill = xNode->getFill(); + if ( ( nFill == AnimationFill::DEFAULT ) || + ( nFill == AnimationFill::INHERIT ) ) + { + if ( nFill != AnimationFill::AUTO ) + nFill = nFillDefault; + } + if( nFill == AnimationFill::AUTO ) + { + nFill = AnimationFill::REMOVE; + sal_Bool bIsIndefiniteTiming = sal_True; + Any aAny = xNode->getDuration(); + if( aAny.hasValue() ) + { + Timing eTiming; + if( aAny >>= eTiming ) + bIsIndefiniteTiming = eTiming == Timing_INDEFINITE; + } + if ( bIsIndefiniteTiming ) + { + aAny = xNode->getEnd(); + if( aAny.hasValue() ) + { + Timing eTiming; + if( aAny >>= eTiming ) + bIsIndefiniteTiming = eTiming == Timing_INDEFINITE; + } + if ( bIsIndefiniteTiming ) + { + if ( !xNode->getRepeatCount().hasValue() ) + { + aAny = xNode->getRepeatDuration(); + if( aAny.hasValue() ) + { + Timing eTiming; + if( aAny >>= eTiming ) + bIsIndefiniteTiming = eTiming == Timing_INDEFINITE; + } + if ( bIsIndefiniteTiming ) + nFill = AnimationFill::FREEZE; + } + } + } + } + return nFill; +} + +void AnimationExporter::doexport( const Reference< XDrawPage >& xPage, SvStream& rStrm ) +{ + Reference< XAnimationNodeSupplier > xNodeSupplier( xPage, UNO_QUERY ); + if( xNodeSupplier.is() ) + { + const Reference< XAnimationNode > xRootNode( xNodeSupplier->getAnimationNode() ); + if( xRootNode.is() ) + { + processAfterEffectNodes( xRootNode ); + exportNode( rStrm, xRootNode, NULL, DFF_msofbtAnimGroup, 1, 0, sal_False, AnimationFill::AUTO ); + } + } +} + +void AnimationExporter::processAfterEffectNodes( const Reference< XAnimationNode >& xRootNode ) +{ + try + { + Reference< XEnumerationAccess > xEnumerationAccess( xRootNode, UNO_QUERY_THROW ); + Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW ); + while( xEnumeration->hasMoreElements() ) + { + Reference< XAnimationNode > xNode( xEnumeration->nextElement(), UNO_QUERY_THROW ); + + Reference< XEnumerationAccess > xEnumerationAccess2( xNode, UNO_QUERY ); + if ( xEnumerationAccess2.is() ) + { + Reference< XEnumeration > xEnumeration2( xEnumerationAccess2->createEnumeration(), UNO_QUERY_THROW ); + while( xEnumeration2->hasMoreElements() ) + { + Reference< XAnimationNode > xChildNode( xEnumeration2->nextElement(), UNO_QUERY_THROW ); + + Reference< XEnumerationAccess > xEnumerationAccess3( xChildNode, UNO_QUERY_THROW ); + Reference< XEnumeration > xEnumeration3( xEnumerationAccess3->createEnumeration(), UNO_QUERY_THROW ); + while( xEnumeration3->hasMoreElements() ) + { + Reference< XAnimationNode > xChildNode2( xEnumeration3->nextElement(), UNO_QUERY_THROW ); + + Reference< XEnumerationAccess > xEnumerationAccess4( xChildNode2, UNO_QUERY_THROW ); + Reference< XEnumeration > xEnumeration4( xEnumerationAccess4->createEnumeration(), UNO_QUERY_THROW ); + while( xEnumeration4->hasMoreElements() ) + { + Reference< XAnimationNode > xChildNode3( xEnumeration4->nextElement(), UNO_QUERY_THROW ); + + switch( xChildNode3->getType() ) + { + // found an after effect + case AnimationNodeType::SET: + case AnimationNodeType::ANIMATECOLOR: + { + Reference< XAnimationNode > xMaster; + + Sequence< NamedValue > aUserData( xChildNode3->getUserData() ); + sal_Int32 nLength = aUserData.getLength(); + const NamedValue* p = aUserData.getConstArray(); + + while( nLength-- ) + { + if( p->Name.equalsAscii( "master-element" ) ) + { + p->Value >>= xMaster; + break; + } + p++; + } + + AfterEffectNodePtr pAfterEffectNode( new AfterEffectNode( xChildNode3, xMaster ) ); + maAfterEffectNodes.push_back( pAfterEffectNode ); + } + break; + } + } + } + } + } + } + } + catch( Exception& e ) + { + (void)e; + DBG_ERROR( "(@CL)AnimationExporter::processAfterEffectNodes(), exception cought!" ); + } +} + +bool AnimationExporter::isAfterEffectNode( const Reference< XAnimationNode >& xNode ) const +{ + std::list< AfterEffectNodePtr >::const_iterator aIter( maAfterEffectNodes.begin() ); + const std::list< AfterEffectNodePtr >::const_iterator aEnd( maAfterEffectNodes.end() ); + while( aIter != aEnd ) + { + if( (*aIter)->mxNode == xNode ) + return true; + aIter++; + } + + return false; +} + +bool AnimationExporter::hasAfterEffectNode( const Reference< XAnimationNode >& xNode, Reference< XAnimationNode >& xAfterEffectNode ) const +{ + std::list< AfterEffectNodePtr >::const_iterator aIter( maAfterEffectNodes.begin() ); + const std::list< AfterEffectNodePtr >::const_iterator aEnd( maAfterEffectNodes.end() ); + while( aIter != aEnd ) + { + if( (*aIter)->mxMaster == xNode ) + { + xAfterEffectNode = (*aIter)->mxNode; + return true; + } + aIter++; + } + + return false; +} + +// check if this group only contain empty groups. this may happen when +// after effect nodes are not exported at theire original position +bool AnimationExporter::isEmptyNode( const Reference< XAnimationNode >& xNode ) const +{ + if( xNode.is() ) switch( xNode->getType() ) + { + case AnimationNodeType::PAR : + case AnimationNodeType::SEQ : + case AnimationNodeType::ITERATE : + { + Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY ); + if( xEnumerationAccess.is() ) + { + Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY ); + if( xEnumeration.is() ) + { + while( xEnumeration->hasMoreElements() ) + { + Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY ); + if( xChildNode.is() && !isEmptyNode( xChildNode ) ) + return false; + } + } + } + } + break; + + case AnimationNodeType::SET : + case AnimationNodeType::ANIMATECOLOR : + return isAfterEffectNode( xNode ); + default: + return false; + } + + return true; +} + +void AnimationExporter::exportNode( SvStream& rStrm, Reference< XAnimationNode > xNode, const Reference< XAnimationNode >* pParent, const sal_uInt16 nContainerRecType, + const sal_uInt16 nInstance, const sal_Int32 nGroupLevel, const sal_Bool bTakeBackInteractiveSequenceTiming, const sal_Int16 nFDef ) +{ + if( (nGroupLevel == 4) && isEmptyNode( xNode ) ) + return; + + if ( ( nContainerRecType == DFF_msofbtAnimGroup ) && ( nGroupLevel == 2 ) && isEmptyNode( xNode ) ) + return; + + if( nContainerRecType == DFF_msofbtAnimGroup ) + mnCurrentGroup++; + + sal_Bool bTakeBackInteractiveSequenceTimingForChild = sal_False; + sal_Int16 nFillDefault = GetFillMode( xNode, nFDef ); + + bool bSkipChildren = false; + + Reference< XAnimationNode > xAudioNode; + static sal_uInt32 nAudioGroup; + + { + EscherExContainer aContainer( rStrm, nContainerRecType, nInstance ); + switch( xNode->getType() ) + { + case AnimationNodeType::CUSTOM : + { + exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault ); + exportAnimPropertySet( rStrm, xNode ); + exportAnimEvent( rStrm, xNode, 0 ); + exportAnimValue( rStrm, xNode, sal_False ); + } + break; + + case AnimationNodeType::PAR : + { + exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault ); + exportAnimPropertySet( rStrm, xNode ); + sal_Int32 nFlags = nGroupLevel == 2 ? 0x10 : 0; + if ( bTakeBackInteractiveSequenceTiming ) + nFlags |= 0x40; + exportAnimEvent( rStrm, xNode, nFlags ); + exportAnimValue( rStrm, xNode, nGroupLevel == 4 ); + } + break; + + case AnimationNodeType::SEQ : + { + exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault ); + sal_Int16 nNodeType = exportAnimPropertySet( rStrm, xNode ); + sal_Int32 nFlags = 12; + if ( ( nGroupLevel == 1 ) && ( nNodeType == ::com::sun::star::presentation::EffectNodeType::INTERACTIVE_SEQUENCE ) ) + { + nFlags |= 0x20; + bTakeBackInteractiveSequenceTimingForChild = sal_True; + } + exportAnimAction( rStrm, xNode ); + exportAnimEvent( rStrm, xNode, nFlags ); + exportAnimValue( rStrm, xNode, sal_False ); + } + break; + + case AnimationNodeType::ITERATE : + { + { + EscherExAtom aAnimNodeExAtom( rStrm, DFF_msofbtAnimNode ); + AnimationNode aAnim; + rtl_zeroMemory( &aAnim, sizeof( aAnim ) ); + aAnim.mnGroupType = mso_Anim_GroupType_PAR; + aAnim.mnNodeType = 1; + // attribute Restart + switch( xNode->getRestart() ) + { + default: + case AnimationRestart::DEFAULT : aAnim.mnRestart = 0; break; + case AnimationRestart::ALWAYS : aAnim.mnRestart = 1; break; + case AnimationRestart::WHEN_NOT_ACTIVE : aAnim.mnRestart = 2; break; + case AnimationRestart::NEVER : aAnim.mnRestart = 3; break; + } + // attribute Fill + switch( xNode->getFill() ) + { + default: + case AnimationFill::DEFAULT : aAnim.mnFill = 0; break; + case AnimationFill::REMOVE : aAnim.mnFill = 1; break; + case AnimationFill::FREEZE : aAnim.mnFill = 2; break; + case AnimationFill::HOLD : aAnim.mnFill = 3; break; + case AnimationFill::TRANSITION : aAnim.mnFill = 4; break; + } + rStrm << aAnim; + } + exportIterate( rStrm, xNode ); + exportAnimPropertySet( rStrm, xNode ); + exportAnimEvent( rStrm, xNode, 0 ); + exportAnimValue( rStrm, xNode, sal_False ); + + /* + EscherExContainer aContainer( rStrm, DFF_msofbtAnimGroup, 1 ); + exportAnimNode( rStrm, xNode, pParent, nGroupLevel + 1, nFillDefault ); + exportAnimPropertySet( rStrm, xNode ); + exportAnimEvent( rStrm, xNode, 0 ); + exportAnimValue( rStrm, xNode, sal_False ); + */ + } + break; + + case AnimationNodeType::ANIMATE : + { + exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault ); + exportAnimPropertySet( rStrm, xNode ); + exportAnimEvent( rStrm, xNode, 0 ); + exportAnimValue( rStrm, xNode, sal_False ); + exportAnimate( rStrm, xNode ); + } + break; + + case AnimationNodeType::SET : + { + bool bIsAfterEffectNode( isAfterEffectNode( xNode ) ); + if( (nGroupLevel != 4) || !bIsAfterEffectNode ) + { + exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault ); + exportAnimPropertySet( rStrm, xNode ); + exportAnimateSet( rStrm, xNode, bIsAfterEffectNode ? AFTEREFFECT_SET : AFTEREFFECT_NONE ); + exportAnimEvent( rStrm, xNode, 0 ); + exportAnimValue( rStrm, xNode, sal_False ); + } + else + { + bSkipChildren = true; + } + } + break; + + case AnimationNodeType::ANIMATEMOTION : + { + exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault ); + exportAnimPropertySet( rStrm, xNode ); + exportAnimateMotion( rStrm, xNode ); + exportAnimEvent( rStrm, xNode, 0 ); + exportAnimValue( rStrm, xNode, sal_False ); + } + break; + + case AnimationNodeType::ANIMATECOLOR : + { + bool bIsAfterEffectNode( isAfterEffectNode( xNode ) ); + if( (nGroupLevel != 4) || !bIsAfterEffectNode ) + { + if( bIsAfterEffectNode ) + xNode = createAfterEffectNodeClone( xNode ); + + exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault ); + exportAnimPropertySet( rStrm, xNode ); + exportAnimateColor( rStrm, xNode, bIsAfterEffectNode ? AFTEREFFECT_COLOR : AFTEREFFECT_NONE ); + exportAnimEvent( rStrm, xNode, 0 ); + exportAnimValue( rStrm, xNode, sal_False ); + } + else + { + bSkipChildren = true; + } + } + break; + + case AnimationNodeType::ANIMATETRANSFORM : + { + exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault ); + exportAnimPropertySet( rStrm, xNode ); + exportAnimateTransform( rStrm, xNode ); + exportAnimEvent( rStrm, xNode, 0 ); + exportAnimValue( rStrm, xNode, sal_False ); + } + break; + + case AnimationNodeType::TRANSITIONFILTER : + { + exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault ); + exportAnimPropertySet( rStrm, xNode ); + exportAnimEvent( rStrm, xNode, 0 ); + exportAnimValue( rStrm, xNode, sal_False ); + exportTransitionFilter( rStrm, xNode ); + } + break; + + case AnimationNodeType::AUDIO : // #i58428# + { + exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault ); + exportAnimPropertySet( rStrm, xNode ); + + Reference< XAudio > xAudio( xNode, UNO_QUERY ); + if( xAudio.is() ) + { + Any aAny( xAudio->getSource() ); + rtl::OUString aURL; + + if ( ( aAny >>= aURL ) && ( aURL.getLength() ) ) + { + sal_Int32 nU1 = 2; + sal_Int32 nTrigger = 3; + sal_Int32 nU3 = nAudioGroup; + sal_Int32 nBegin = 0; + { + EscherExContainer aAnimEvent( rStrm, DFF_msofbtAnimEvent, 1 ); + { + EscherExAtom aAnimTrigger( rStrm, DFF_msofbtAnimTrigger ); + rStrm << nU1 << nTrigger << nU3 << nBegin; + } + } + nU1 = 1; + nTrigger = 0xb; + nU3 = 0; + { + EscherExContainer aAnimEvent( rStrm, DFF_msofbtAnimEvent, 2 ); + { + EscherExAtom aAnimTrigger( rStrm, DFF_msofbtAnimTrigger ); + rStrm << nU1 << nTrigger << nU3 << nBegin; + } + } + EscherExContainer aAnimateTargetElement( rStrm, DFF_msofbtAnimateTargetElement ); + { + sal_uInt32 nRefMode = 3; + sal_uInt32 nRefType = 2; + sal_uInt32 nRefId = mrExSoundCollection.GetId( aURL ); + sal_Int32 begin = -1; + sal_Int32 end = -1; + + EscherExAtom aAnimReference( rStrm, DFF_msofbtAnimReference ); + rStrm << nRefMode << nRefType << nRefId << begin << end; + } + } + } + exportAnimValue( rStrm, xNode, sal_False ); + } + break; + } + if( !bSkipChildren ) + { + // export after effect node if one exists for this node + Reference< XAnimationNode > xAfterEffectNode; + if( hasAfterEffectNode( xNode, xAfterEffectNode ) ) + { + exportNode( rStrm, xAfterEffectNode, &xNode, DFF_msofbtAnimSubGoup, 1, nGroupLevel + 1, bTakeBackInteractiveSequenceTimingForChild, nFillDefault ); + } + + Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY ); + if( xEnumerationAccess.is() ) + { + Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY ); + if( xEnumeration.is() ) + { + while( xEnumeration->hasMoreElements() ) + { + Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY ); + if( xChildNode.is() ) + { + if ( xChildNode->getType() == AnimationNodeType::AUDIO ) + { + xAudioNode = xChildNode; + nAudioGroup = mnCurrentGroup; + } + else + exportNode( rStrm, xChildNode, &xNode, DFF_msofbtAnimGroup, 1, nGroupLevel + 1, bTakeBackInteractiveSequenceTimingForChild, nFillDefault ); + } + } + } + } + } + } + if ( xAudioNode.is() ) + exportNode( rStrm, xAudioNode, &xNode, DFF_msofbtAnimGroup, 1, nGroupLevel, bTakeBackInteractiveSequenceTimingForChild, nFillDefault ); + + if( xNode->getType() == AnimationNodeType::ITERATE ) + aTarget = Any(); +} + +Reference< XAnimationNode > AnimationExporter::createAfterEffectNodeClone( const Reference< XAnimationNode >& xNode ) const +{ + try + { + Reference< ::com::sun::star::util::XCloneable > xClonable( xNode, UNO_QUERY_THROW ); + Reference< XAnimationNode > xCloneNode( xClonable->createClone(), UNO_QUERY_THROW ); + + Any aEmpty; + xCloneNode->setBegin( aEmpty ); + + + return xCloneNode; + } + catch( Exception& e ) + { + (void)e; + DBG_ERROR("(@CL)sd::ppt::AnimationExporter::createAfterEffectNodeClone(), could not create clone!" ); + } + return xNode; +} + +void AnimationExporter::exportAnimNode( SvStream& rStrm, const Reference< XAnimationNode >& xNode, + const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >*, const sal_Int32, const sal_Int16 nFillDefault ) +{ + EscherExAtom aAnimNodeExAtom( rStrm, DFF_msofbtAnimNode ); + AnimationNode aAnim; + rtl_zeroMemory( &aAnim, sizeof( aAnim ) ); + + // attribute Restart + switch( xNode->getRestart() ) + { + default: + case AnimationRestart::DEFAULT : aAnim.mnRestart = 0; break; + case AnimationRestart::ALWAYS : aAnim.mnRestart = 1; break; + case AnimationRestart::WHEN_NOT_ACTIVE : aAnim.mnRestart = 2; break; + case AnimationRestart::NEVER : aAnim.mnRestart = 3; break; + } + + // attribute Fill +// aAnim.mnFill = GetFillMode( xNode, pParent ); + switch( nFillDefault ) + { + default: + case AnimationFill::DEFAULT : aAnim.mnFill = 0; break; + case AnimationFill::REMOVE : aAnim.mnFill = 1; break; + case AnimationFill::FREEZE : // aAnim.mnFill = 2; break; + case AnimationFill::HOLD : aAnim.mnFill = 3; break; + case AnimationFill::TRANSITION : aAnim.mnFill = 4; break; + } + // attribute Duration + double fDuration = 0.0; + com::sun::star::animations::Timing eTiming; + if ( xNode->getDuration() >>= eTiming ) + { + if ( eTiming == Timing_INDEFINITE ) + aAnim.mnDuration = -1; + } + else if ( xNode->getDuration() >>= fDuration ) + { + aAnim.mnDuration = (sal_Int32)( fDuration * 1000.0 ); + } + else + aAnim.mnDuration = -1; + + // NodeType, NodeGroup + aAnim.mnNodeType = 1; + aAnim.mnGroupType = mso_Anim_GroupType_SEQ; + switch( xNode->getType() ) + { + case AnimationNodeType::PAR : // PASSTROUGH!!! (as it was intended) + aAnim.mnGroupType = mso_Anim_GroupType_PAR; + case AnimationNodeType::SEQ : + { + // trying to get the nodetype + Sequence< NamedValue > aUserData = xNode->getUserData(); + if ( aUserData.getLength() ) + { + const NamedValue* p = aUserData.getConstArray(); + sal_Int32 nLength = aUserData.getLength(); + while( nLength-- ) + { + if( p->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "node-type" ) ) ) + { + sal_Int16 nType = 0; + if ( p->Value >>= nType ) + { + switch( nType ) + { + case ::com::sun::star::presentation::EffectNodeType::TIMING_ROOT : aAnim.mnNodeType = 0x12; break; + case ::com::sun::star::presentation::EffectNodeType::MAIN_SEQUENCE : aAnim.mnNodeType = 0x18; break; + /* + case ::com::sun::star::presentation::EffectNodeType::ON_CLICK : + case ::com::sun::star::presentation::EffectNodeType::WITH_PREVIOUS : + case ::com::sun::star::presentation::EffectNodeType::AFTER_PREVIOUS : + case ::com::sun::star::presentation::EffectNodeType::INTERACTIVE_SEQUENCE : + default: + */ + } + } + break; + } + } + } + } + break; + + case AnimationNodeType::ANIMATE : + case AnimationNodeType::SET : + + case AnimationNodeType::CUSTOM : + case AnimationNodeType::ITERATE : + case AnimationNodeType::ANIMATEMOTION : + case AnimationNodeType::ANIMATECOLOR : + case AnimationNodeType::ANIMATETRANSFORM : + { + aAnim.mnGroupType = mso_Anim_GroupType_NODE; + aAnim.mnNodeType = mso_Anim_Behaviour_ANIMATION; + } + break; + + case AnimationNodeType::AUDIO : + { + aAnim.mnGroupType = mso_Anim_GroupType_MEDIA; + aAnim.mnNodeType = mso_Anim_Behaviour_ANIMATION; + } + break; + + case AnimationNodeType::TRANSITIONFILTER : + { + aAnim.mnGroupType = mso_Anim_GroupType_NODE; + aAnim.mnNodeType = mso_Anim_Behaviour_FILTER; + } + break; + } + rStrm << aAnim; +} + +sal_Int16 AnimationExporter::exportAnimPropertySet( SvStream& rStrm, const Reference< XAnimationNode >& xNode ) +{ + sal_Int16 nNodeType = ::com::sun::star::presentation::EffectNodeType::DEFAULT; + + EscherExContainer aAnimPropertySet( rStrm, DFF_msofbtAnimPropertySet ); + const ::com::sun::star::uno::Any* pAny[ DFF_ANIM_PROPERTY_ID_COUNT ]; + rtl_zeroMemory( pAny, sizeof( pAny ) ); + + Reference< XAnimationNode > xMaster; + + const Any aTrue( makeAny( (sal_Bool)sal_True ) ); + Any aMasterRel, aOverride, aRunTimeContext; + + // storing user data into pAny, to allow direct access later + Sequence< NamedValue > aUserData = xNode->getUserData(); + if ( aUserData.getLength() ) + { + const NamedValue* p = aUserData.getConstArray(); + sal_Int32 nLength = aUserData.getLength(); + while( nLength-- ) + { + if( p->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "node-type" ) ) ) + { + pAny[ DFF_ANIM_NODE_TYPE ] = &(p->Value); + } + else if ( p->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "preset-class" ) ) ) + { + pAny[ DFF_ANIM_PRESET_CLASS ] = &(p->Value); + } + else if ( p->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "preset-id" ) ) ) + { + pAny[ DFF_ANIM_PRESET_ID ] = &(p->Value); + } + else if ( p->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "preset-sub-type" ) ) ) + { + pAny[ DFF_ANIM_PRESET_SUB_TYPE ] = &(p->Value); + } + else if ( p->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "master-element" ) ) ) + { + pAny[ DFF_ANIM_AFTEREFFECT ] = &aTrue; + p->Value >>= xMaster; + } + p++; + } + } + + // calculate master-rel + if( xMaster.is() ) + { + sal_Int32 nMasterRel = 2; + Reference< XChild > xNodeChild( xNode, UNO_QUERY ); + Reference< XChild > xMasterChild( xMaster, UNO_QUERY ); + if( xNodeChild.is() && xMasterChild.is() && (xNodeChild->getParent() == xMasterChild->getParent() ) ) + nMasterRel = 0; + + aMasterRel <<= nMasterRel; + + pAny[ DFF_ANIM_MASTERREL ] = &aMasterRel; + + aOverride <<= (sal_Int32)1; + pAny[ DFF_ANIM_OVERRIDE ] = &aOverride; + + aRunTimeContext <<= (sal_Int32)1; + pAny[ DFF_ANIM_RUNTIMECONTEXT ] = &aRunTimeContext; + } + + // the order is important + if ( pAny[ DFF_ANIM_NODE_TYPE ] ) + { + if ( *pAny[ DFF_ANIM_NODE_TYPE ] >>= nNodeType ) + { + sal_uInt32 nPPTNodeType = DFF_ANIM_NODE_TYPE_ON_CLICK; + switch( nNodeType ) + { + case ::com::sun::star::presentation::EffectNodeType::ON_CLICK : nPPTNodeType = DFF_ANIM_NODE_TYPE_ON_CLICK; break; + case ::com::sun::star::presentation::EffectNodeType::WITH_PREVIOUS : nPPTNodeType = DFF_ANIM_NODE_TYPE_WITH_PREVIOUS; break; + case ::com::sun::star::presentation::EffectNodeType::AFTER_PREVIOUS : nPPTNodeType = DFF_ANIM_NODE_TYPE_AFTER_PREVIOUS; break; + case ::com::sun::star::presentation::EffectNodeType::MAIN_SEQUENCE : nPPTNodeType = DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE; break; + case ::com::sun::star::presentation::EffectNodeType::TIMING_ROOT : nPPTNodeType = DFF_ANIM_NODE_TYPE_TIMING_ROOT; break; + case ::com::sun::star::presentation::EffectNodeType::INTERACTIVE_SEQUENCE: nPPTNodeType = DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ; break; + } + exportAnimPropertyuInt32( rStrm, DFF_ANIM_NODE_TYPE, nPPTNodeType, TRANSLATE_NONE ); + } + } + sal_uInt32 nPresetId = 0; + sal_uInt32 nPresetSubType = 0; + sal_uInt32 nAPIPresetClass = EffectPresetClass::CUSTOM; + sal_uInt32 nPresetClass = DFF_ANIM_PRESS_CLASS_USER_DEFINED; + sal_Bool bPresetClass, bPresetId, bPresetSubType; + bPresetClass = bPresetId = bPresetSubType = sal_False; + + if ( pAny[ DFF_ANIM_PRESET_CLASS ] ) + { + if ( *pAny[ DFF_ANIM_PRESET_CLASS ] >>= nAPIPresetClass ) + { + sal_uInt8 nPPTPresetClass; + switch( nAPIPresetClass ) + { + case EffectPresetClass::ENTRANCE : nPPTPresetClass = DFF_ANIM_PRESS_CLASS_ENTRANCE; break; + case EffectPresetClass::EXIT : nPPTPresetClass = DFF_ANIM_PRESS_CLASS_EXIT; break; + case EffectPresetClass::EMPHASIS : nPPTPresetClass = DFF_ANIM_PRESS_CLASS_EMPHASIS; break; + case EffectPresetClass::MOTIONPATH : nPPTPresetClass = DFF_ANIM_PRESS_CLASS_MOTIONPATH; break; + case EffectPresetClass::OLEACTION : nPPTPresetClass = DFF_ANIM_PRESS_CLASS_OLE_ACTION; break; + case EffectPresetClass::MEDIACALL : nPPTPresetClass = DFF_ANIM_PRESS_CLASS_MEDIACALL; break; + default : + nPPTPresetClass = DFF_ANIM_PRESS_CLASS_USER_DEFINED; + } + nPresetClass = nPPTPresetClass; + bPresetClass = sal_True; + } + } + if ( pAny[ DFF_ANIM_PRESET_ID ] ) + { + rtl::OUString sPreset; + if ( *pAny[ DFF_ANIM_PRESET_ID ] >>= sPreset ) + { + if ( sPreset.match( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ppt_" ) ), 0 ) ) + { + sal_Int32 nLast = sPreset.lastIndexOf( '_' ); + if ( ( nLast != -1 ) && ( ( nLast + 1 ) < sPreset.getLength() ) ) + { + rtl::OUString aNumber( sPreset.copy( nLast + 1 ) ); + nPresetId = aNumber.toInt32(); + bPresetId = sal_True; + } + } + else + { + const preset_maping* p = gPresetMaping; + while( p->mpStrPresetId && ((p->mnPresetClass != (sal_Int32)nAPIPresetClass) || !sPreset.equalsAscii( p->mpStrPresetId )) ) + p++; + + if( p->mpStrPresetId ) + { + nPresetId = p->mnPresetId; + bPresetId = sal_True; + } + } + } + } + + if ( pAny[ DFF_ANIM_PRESET_SUB_TYPE ] ) + { + rtl::OUString sPresetSubType; + if ( *pAny[ DFF_ANIM_PRESET_SUB_TYPE ] >>= sPresetSubType ) + { + nPresetSubType = ImplTranslatePresetSubType( nPresetClass, nPresetId, sPresetSubType ); + bPresetSubType = sal_True; + } + } + if ( bPresetId ) + exportAnimPropertyuInt32( rStrm, DFF_ANIM_PRESET_ID, nPresetId, TRANSLATE_NONE ); + if ( bPresetSubType ) + exportAnimPropertyuInt32( rStrm, DFF_ANIM_PRESET_SUB_TYPE, nPresetSubType, TRANSLATE_NONE ); + if ( bPresetClass ) + exportAnimPropertyuInt32( rStrm, DFF_ANIM_PRESET_CLASS, nPresetClass, TRANSLATE_NONE ); + + if ( pAny[ DFF_ANIM_ID ] ) + { + // TODO DFF_ANIM_ID + } + + if ( pAny[ DFF_ANIM_AFTEREFFECT ] ) + { + sal_Bool bAfterEffect = sal_False; + if ( *pAny[ DFF_ANIM_AFTEREFFECT ] >>= bAfterEffect ) + exportAnimPropertyByte( rStrm, DFF_ANIM_AFTEREFFECT, bAfterEffect, TRANSLATE_NONE ); + } + + if ( pAny[ DFF_ANIM_RUNTIMECONTEXT ] ) + { + sal_Int32 nRunTimeContext = 0; + if ( *pAny[ DFF_ANIM_RUNTIMECONTEXT ] >>= nRunTimeContext ) + exportAnimPropertyuInt32( rStrm, DFF_ANIM_RUNTIMECONTEXT, nRunTimeContext, TRANSLATE_NONE ); + } + if ( pAny[ DFF_ANIM_PATH_EDIT_MODE ] ) + { + // TODO DFF_ANIM_ID + } + + if( !xMaster.is() ) + { + Reference< XAnimateColor > xColor( xNode, UNO_QUERY ); + if( xColor.is() ) + { +// sal_uInt32 nColorSpace = xColor->getColorSpace() == AnimationColorSpace::RGB ? 0 : 1; +// exportAnimPropertyuInt32( rStrm, DFF_ANIM_COLORSPACE, nColorSpace, TRANSLATE_NONE ); + + sal_Bool bDirection = !xColor->getDirection(); + exportAnimPropertyuInt32( rStrm, DFF_ANIM_DIRECTION, bDirection, TRANSLATE_NONE ); + } + } + + if ( pAny[ DFF_ANIM_OVERRIDE ] ) + { + sal_Int32 nOverride = 0; + if ( *pAny[ DFF_ANIM_OVERRIDE ] >>= nOverride ) + exportAnimPropertyuInt32( rStrm, DFF_ANIM_OVERRIDE, nOverride, TRANSLATE_NONE ); + } + + if ( pAny[ DFF_ANIM_MASTERREL ] ) + { + sal_Int32 nMasterRel = 0; + if ( *pAny[ DFF_ANIM_MASTERREL ] >>= nMasterRel ) + exportAnimPropertyuInt32( rStrm, DFF_ANIM_MASTERREL, nMasterRel, TRANSLATE_NONE ); + } + +/* todo + Reference< XAudio > xAudio( xNode, UNO_QUERY ); + if( xAudio.is() ) + { + sal_Int16 nEndAfterSlide = 0; + nEndAfterSlide = xAudio->getEndAfterSlide(); + exportAnimPropertyuInt32( rStrm, DFF_ANIM_ENDAFTERSLIDE, nEndAfterSlide, TRANSLATE_NONE ); + } +*/ + Reference< XAnimate > xAnim( xNode, UNO_QUERY ); + if( xAnim.is() ) + { + // TODO: DFF_ANIM_TIMEFILTER + } + if ( pAny[ DFF_ANIM_EVENT_FILTER ] ) + { + // TODO DFF_ANIM_EVENT_FILTER + } + if ( pAny[ DFF_ANIM_VOLUME ] ) + { + // TODO DFF_ANIM_VOLUME + } + return nNodeType; +} + +sal_Bool AnimationExporter::exportAnimProperty( SvStream& rStrm, const sal_uInt16 nPropertyId, const ::com::sun::star::uno::Any& rAny, const TranslateMode eTranslateMode ) +{ + sal_Bool bRet = sal_False; + if ( rAny.hasValue() ) + { + switch( rAny.getValueType().getTypeClass() ) + { + case ::com::sun::star::uno::TypeClass_UNSIGNED_SHORT : + case ::com::sun::star::uno::TypeClass_SHORT : + case ::com::sun::star::uno::TypeClass_UNSIGNED_LONG : + case ::com::sun::star::uno::TypeClass_LONG : + { + sal_Int32 nVal = 0; + if ( rAny >>= nVal ) + { + exportAnimPropertyuInt32( rStrm, nPropertyId, nVal, eTranslateMode ); + bRet = sal_True; + } + } + break; + + case ::com::sun::star::uno::TypeClass_DOUBLE : + { + double fVal = 0.0; + if ( rAny >>= fVal ) + { + exportAnimPropertyFloat( rStrm, nPropertyId, fVal, eTranslateMode ); + bRet = sal_True; + } + } + break; + case ::com::sun::star::uno::TypeClass_FLOAT : + { + float fVal = 0.0; + if ( rAny >>= fVal ) + { + if ( eTranslateMode & TRANSLATE_NUMBER_TO_STRING ) + { + Any aAny; + rtl::OUString aNumber( rtl::OUString::valueOf( fVal ) ); + aAny <<= aNumber; + exportAnimPropertyString( rStrm, nPropertyId, aNumber, eTranslateMode ); + } + else + { + exportAnimPropertyFloat( rStrm, nPropertyId, fVal, eTranslateMode ); + bRet = sal_True; + } + } + } + break; + case ::com::sun::star::uno::TypeClass_STRING : + { + rtl::OUString aStr; + if ( rAny >>= aStr ) + { + exportAnimPropertyString( rStrm, nPropertyId, aStr, eTranslateMode ); + bRet = sal_True; + } + } + break; + default: + break; + } + } + return bRet; +} +void AnimationExporter::exportAnimPropertyString( SvStream& rStrm, const sal_uInt16 nPropertyId, const rtl::OUString& rVal, const TranslateMode eTranslateMode ) +{ + EscherExAtom aExAtom( rStrm, DFF_msofbtAnimAttributeValue, nPropertyId ); + sal_uInt8 nType = DFF_ANIM_PROP_TYPE_UNISTRING; + rStrm << nType; + rtl::OUString aStr( rVal ); + if ( eTranslateMode != TRANSLATE_NONE ) + ImplTranslateAttribute( aStr, eTranslateMode ); + writeZString( rStrm, aStr ); +} + +void AnimationExporter::exportAnimPropertyFloat( SvStream& rStrm, const sal_uInt16 nPropertyId, const double& rVal, const TranslateMode ) +{ + EscherExAtom aExAtom( rStrm, DFF_msofbtAnimAttributeValue, nPropertyId ); + sal_uInt8 nType = DFF_ANIM_PROP_TYPE_FLOAT; + float fFloat = (float)rVal; + rStrm << nType + << fFloat; +} + +void AnimationExporter::exportAnimPropertyuInt32( SvStream& rStrm, const sal_uInt16 nPropertyId, const sal_uInt32 nVal, const TranslateMode ) +{ + EscherExAtom aExAtom( rStrm, DFF_msofbtAnimAttributeValue, nPropertyId ); + sal_uInt8 nType = DFF_ANIM_PROP_TYPE_INT32 ; + rStrm << nType + << nVal; +} + +void AnimationExporter::exportAnimPropertyByte( SvStream& rStrm, const sal_uInt16 nPropertyId, const sal_uInt8 nVal, const TranslateMode ) +{ + EscherExAtom aExAtom( rStrm, DFF_msofbtAnimAttributeValue, nPropertyId ); + sal_uInt8 nType = DFF_ANIM_PROP_TYPE_BYTE; + rStrm << nType + << nVal; +} + +void AnimationExporter::writeZString( SvStream& rStrm, const rtl::OUString& rVal ) +{ + sal_Int32 i; + for ( i = 0; i < rVal.getLength(); i++ ) + rStrm << rVal[ i ]; + rStrm << (sal_Unicode)0; +} + +void AnimationExporter::exportAnimAction( SvStream& rStrm, const Reference< XAnimationNode >& xNode ) +{ + EscherExAtom aExAtom( rStrm, DFF_msofbtAnimAction ); + + sal_Int32 nConcurrent = 1; + sal_Int32 nNextAction = 1; + sal_Int32 nEndSync = 0; + sal_Int32 nU4 = 0; + sal_Int32 nU5 = 3; + + sal_Int16 nAnimationEndSync = 0; + if ( xNode->getEndSync() >>= nAnimationEndSync ) + { + if ( nAnimationEndSync == AnimationEndSync::ALL ) + nEndSync = 1; + } + rStrm << nConcurrent + << nNextAction + << nEndSync + << nU4 + << nU5; + +} + +// nFlags Bit 6 = fixInteractiveSequenceTiming (for child) +// nFlags Bit 5 = fixInteractiveSequenceTiming (for root) +// nFlags Bit 4 = first node of main sequence -> begin event next has to be replaced to indefinite +void AnimationExporter::exportAnimEvent( SvStream& rStrm, const Reference< XAnimationNode >& xNode, const sal_Int32 nFlags ) +{ + sal_uInt16 i; + for ( i = 0; i < 4; i++ ) + { + sal_Int32 nU1 = 0; + sal_Int32 nTrigger = 0; + sal_Int32 nU3 = 0; + sal_Int32 nBegin = 0; + + sal_Bool bCreateEvent = sal_False; + Any aSource; + + switch( i ) + { + case 0 : + case 1 : + { + Any aAny; + Event aEvent; + com::sun::star::animations::Timing eTiming; + if ( i == 0 ) + { + if ( nFlags & 0x20 ) + { + // taking the first child + Reference< XEnumerationAccess > xEA( xNode, UNO_QUERY_THROW ); + Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_QUERY_THROW ); + if ( xE.is() && xE->hasMoreElements() ) + { +// while( xE->hasMoreElements() ) + { + Reference< XAnimationNode > xClickNode( xE->nextElement(), UNO_QUERY ); + aAny = xClickNode->getBegin(); + } + } + } + else if ( nFlags & 0x40 ) + { + // begin has to be replaced with void, so don't do anything + } + else + { + aAny = xNode->getBegin(); + if ( nFlags & 0x10 ) // replace ON_NEXT with IDEFINITE + { + if ( ( aAny >>= aEvent ) && ( aEvent.Trigger == EventTrigger::ON_NEXT ) ) + { + eTiming = Timing_INDEFINITE; + aAny <<= eTiming; + } + } + } + } + else + aAny = xNode->getEnd(); + + double fTiming = 0.0; + if ( aAny >>= aEvent ) + { + bCreateEvent = sal_True; + switch( aEvent.Trigger ) + { + case EventTrigger::NONE : nTrigger = 0; break; + case EventTrigger::ON_BEGIN : nTrigger = 1; break; + case EventTrigger::ON_END : nTrigger = 2; break; + case EventTrigger::BEGIN_EVENT : nTrigger = 3; break; + case EventTrigger::END_EVENT : nTrigger = 4; nU1 = 2; nU3 = mnCurrentGroup; break; + case EventTrigger::ON_CLICK : nTrigger = 5; break; + case EventTrigger::ON_DBL_CLICK : nTrigger = 6; break; + case EventTrigger::ON_MOUSE_ENTER : nTrigger = 7; break; + case EventTrigger::ON_MOUSE_LEAVE : nTrigger = 8; break; + case EventTrigger::ON_NEXT : nTrigger = 9; break; + case EventTrigger::ON_PREV : nTrigger = 10; break; + case EventTrigger::ON_STOP_AUDIO : nTrigger = 11; break; + } + if ( aEvent.Offset.hasValue() ) + { + if ( aEvent.Offset >>= eTiming ) + { + if ( eTiming == Timing_INDEFINITE ) + nBegin = -1; + } + else if ( aEvent.Offset >>= fTiming ) + nBegin = (sal_Int32)( fTiming * 1000.0 ); + } + aSource = aEvent.Source; + } + else if ( aAny >>= eTiming ) + { + bCreateEvent = sal_True; + if ( eTiming == Timing_INDEFINITE ) + nBegin = -1; + } + else if ( aAny >>= fTiming ) + { + bCreateEvent = sal_True; + if ( eTiming == Timing_INDEFINITE ) + nBegin = (sal_Int32)( fTiming * 1000.0 ); + } + } + break; + + case 2 : + { + if ( nFlags & ( 1 << i ) ) + { + bCreateEvent = sal_True; + nU1 = 1; + nTrigger = 9; + } + } + break; + case 3 : + { + if ( nFlags & ( 1 << i ) ) + { + bCreateEvent = sal_True; + nU1 = 1; + nTrigger = 10; + } + } + break; + }; + if ( bCreateEvent ) + { + EscherExContainer aAnimEvent( rStrm, DFF_msofbtAnimEvent, i + 1 ); + { + EscherExAtom aAnimTrigger( rStrm, DFF_msofbtAnimTrigger ); + rStrm << nU1 + << nTrigger + << nU3 + << nBegin; + } + exportAnimateTargetElement( rStrm, aSource, ( nFlags & ( 1 << i ) ) != 0 ); + } + } +} + +Any AnimationExporter::convertAnimateValue( const Any& rSourceValue, const rtl::OUString& rAttributeName ) const +{ + rtl::OUString aDest; + if ( rAttributeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "X" ) ) + || rAttributeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Y" ) ) + || rAttributeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Width" ) ) + || rAttributeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Height" ) ) + ) + { + rtl::OUString aStr; + if ( rSourceValue >>= aStr ) + { + ImplTranslateAttribute( aStr, TRANSLATE_MEASURE ); + aDest += aStr; + } + } + else if ( rAttributeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Rotate" ) ) // "r" or "style.rotation" ? + || rAttributeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "SkewX" ) ) + || rAttributeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Opacity" ) ) + || rAttributeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CharHeight" ) ) + ) + { + double fNumber = 0.0; + if ( rSourceValue >>= fNumber ) + aDest += rtl::OUString::valueOf( fNumber ); + } + else if ( rAttributeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Color" ) ) + || rAttributeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "FillColor" ) ) // "Fillcolor" or "FillColor" ? + || rAttributeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "LineColor" ) ) + || rAttributeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CharColor" ) ) + ) + { + sal_Int32 nColor = 0; + Sequence< double > aHSL( 3 ); + rtl::OUString aP( RTL_CONSTASCII_USTRINGPARAM( "," ) ); + if ( rSourceValue >>= aHSL ) + { + aDest += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "hsl(" ) ); + aDest += rtl::OUString::valueOf( (sal_Int32)( aHSL[ 0 ] / ( 360.0 / 255 ) ) ); + aDest += aP; + aDest += rtl::OUString::valueOf( (sal_Int32)( aHSL[ 1 ] * 255.0 ) ); + aDest += aP; + aDest += rtl::OUString::valueOf( (sal_Int32)( aHSL[ 2 ] * 255.0 ) ); + aDest += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ")" ) ); + } + else if ( rSourceValue >>= nColor ) + { + aDest += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "rgb(" ) ); + aDest += rtl::OUString::valueOf( (sal_Int32)( (sal_Int8)nColor ) ); + aDest += aP; + aDest += rtl::OUString::valueOf( (sal_Int32)( (sal_Int8)( nColor >> 8 ) ) ); + aDest += aP; + aDest += rtl::OUString::valueOf( (sal_Int32)( (sal_Int8)( nColor >> 16 ) ) ); + aDest += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ")" ) ); + } + } + else if ( rAttributeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "FillStyle" ) ) ) + { + ::com::sun::star::drawing::FillStyle eFillStyle; + if ( rSourceValue >>= eFillStyle ) + { + if ( eFillStyle == ::com::sun::star::drawing::FillStyle_NONE ) + aDest += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "none" ) ); // ? + else + aDest += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "solid" ) ); + } + } + else if ( rAttributeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "LineStyle" ) ) ) + { + ::com::sun::star::drawing::LineStyle eLineStyle; + if ( rSourceValue >>= eLineStyle ) + { + if ( eLineStyle == ::com::sun::star::drawing::LineStyle_NONE ) + aDest += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "false" ) ); + else + aDest += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "true" ) ); + } + } + else if ( rAttributeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CharWeight" ) ) ) + { + float fFontWeight = 0.0; + if ( rSourceValue >>= fFontWeight ) + { + if ( fFontWeight == com::sun::star::awt::FontWeight::BOLD ) + aDest += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "bold" ) ); + else + aDest += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "normal" ) ); + } + } + else if ( rAttributeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CharUnderline" ) ) ) + { + sal_Int16 nFontUnderline = 0; + if ( rSourceValue >>= nFontUnderline ) + { + if ( nFontUnderline == com::sun::star::awt::FontUnderline::NONE ) + aDest += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "false" ) ); + else + aDest += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "true" ) ); + } + } + else if ( rAttributeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CharPosture" ) ) ) + { + ::com::sun::star::awt::FontSlant eFontSlant; + if ( rSourceValue >>= eFontSlant ) + { + if ( eFontSlant == com::sun::star::awt::FontSlant_ITALIC ) + aDest += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "italic" ) ); + else + aDest += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "normal" ) ); // ? + } + } + else if ( rAttributeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Visibility" ) ) ) + { + sal_Bool bVisible = sal_True; + if ( rSourceValue >>= bVisible ) + { + if ( bVisible ) + aDest += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "visible" ) ); + else + aDest += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "hidden" ) ); + } + } + Any aRet; + if ( aDest.getLength() ) + aRet <<= aDest; + else + aRet = rSourceValue; + return aRet; +} + +void AnimationExporter::exportAnimateSet( SvStream& rStrm, const Reference< XAnimationNode >& xNode, int nAfterEffectType ) +{ + Reference< XAnimateSet > xSet( xNode, UNO_QUERY ); + if( xSet.is() ) + { + EscherExContainer aAnimateSet( rStrm, DFF_msofbtAnimateSet, 0 ); + { + EscherExAtom aAnimateSetData( rStrm, DFF_msofbtAnimateSetData ); + sal_uInt32 nId1 = 1; // ?? + sal_uInt32 nId2 = 1; // ?? + rStrm << nId1 << nId2; + } + Any aConvertedValue( convertAnimateValue( xSet->getTo(), xSet->getAttributeName() ) ); + if ( aConvertedValue.hasValue() ) + exportAnimProperty( rStrm, 1, aConvertedValue, TRANSLATE_NONE ); + exportAnimateTarget( rStrm, xNode, 0, nAfterEffectType ); + } +} + +sal_uInt32 GetValueTypeForAttributeName( const rtl::OUString& rAttributeName ) +{ + sal_uInt32 nValueType = 0; + +/* + AnimationValueType::STRING == 0; + AnimationValueType::NUMBER == 1; + AnimationValueType::COLOR == 2; +*/ + + struct Entry + { + const sal_Char* pName; + sal_uInt8 nType; + }; + static const Entry lcl_attributeMap[] = + { + { "charcolor", 2 }, + { "charfontname", 0 }, + { "charheight", 1 }, + { "charposture", 0 }, + // TODO(Q1): This should prolly be changed in PPT import + // { "charrotation", ATTRIBUTE_CHAR_ROTATION }, + { "charrotation", 1 }, + { "charunderline", 0 }, + { "charweight", 0 }, + { "color", 2 }, + { "dimcolor", 2 }, + { "fillcolor", 2 }, + { "fillstyle", 0 }, + { "height", 1 }, + { "linecolor", 2 }, + { "linestyle", 0 }, + { "opacity", 0 }, + { "rotate", 1 }, + { "skewx", 1 }, + { "skewy", 1 }, + { "visibility", 1 }, + { "width", 1 }, + { "x", 1 }, + { "y", 1 }, + { NULL, 0 } + }; + const Entry* pPtr = &lcl_attributeMap[ 0 ]; + while( pPtr->pName ) + { + if ( rAttributeName.equalsIgnoreAsciiCaseAscii( pPtr->pName ) ) + { + nValueType = pPtr->nType; + break; + } + pPtr++; + } + DBG_ASSERT( pPtr->pName, "GetValueTypeForAttributeName, unknown property value!" ); + return nValueType; +} + +void AnimationExporter::exportAnimate( SvStream& rStrm, const Reference< XAnimationNode >& xNode ) +{ + Reference< XAnimate > xAnimate( xNode, UNO_QUERY ); + if ( xAnimate.is() ) + { + Any aBy ( xAnimate->getBy() ); + Any aFrom( xAnimate->getFrom() ); + Any aTo ( xAnimate->getTo() ); + + EscherExContainer aContainer( rStrm, DFF_msofbtAnimate, 0 ); + { + EscherExAtom aAnimateData( rStrm, DFF_msofbtAnimateData ); + sal_uInt32 nBits = 0x38; + sal_Int16 nTmp = xAnimate->getCalcMode(); + sal_uInt32 nCalcMode = /* (nTmp == AnimationCalcMode::FORMULA) ? 2 : */ (nTmp == AnimationCalcMode::LINEAR) ? 1 : 0; + nTmp = xAnimate->getValueType(); + sal_uInt32 nValueType = GetValueTypeForAttributeName( xAnimate->getAttributeName() ); + + if ( aBy.hasValue() ) + nBits |= 1; + if ( aFrom.hasValue() ) + nBits |= 2; + if ( aTo.hasValue() ) + nBits |= 4; + + rStrm << nCalcMode + << nBits + << nValueType; + } + if ( aBy.hasValue() ) + exportAnimProperty( rStrm, 1, aBy, TRANSLATE_NUMBER_TO_STRING | TRANSLATE_MEASURE ); + if ( aFrom.hasValue() ) + exportAnimProperty( rStrm, 2, aFrom, TRANSLATE_NUMBER_TO_STRING | TRANSLATE_MEASURE ); + if ( aTo.hasValue() ) + exportAnimProperty( rStrm, 3, aTo, TRANSLATE_NUMBER_TO_STRING | TRANSLATE_MEASURE ); + + exportAnimateKeyPoints( rStrm, xAnimate ); + exportAnimateTarget( rStrm, xNode ); + } +} + +void AnimationExporter::exportAnimateTarget( SvStream& rStrm, const Reference< XAnimationNode >& xNode, const sal_uInt32 nForceAttributeNames, int nAfterEffectType ) +{ + EscherExContainer aAnimateTarget( rStrm, DFF_msofbtAnimateTarget, 0 ); + Reference< XAnimate > xAnimate( xNode, UNO_QUERY ); + if ( xAnimate.is() ) + { + { + EscherExAtom aAnimateTargetSettings( rStrm, DFF_msofbtAnimateTargetSettings, 0 ); + // nBits %0001: additive, %0010: accumulate, %0100: attributeName, %1000: transformtype + // nAdditive 0 = base, 1 = sum, 2 = replace, 3 = multiply, 4 = none + // nAccumulate 0 = none, 1 = always + // nTransformType 0: "property" else "image" + sal_uInt32 nBits = 0; + sal_uInt32 nAdditive = 0; + sal_uInt32 nAccumulate = 0; + sal_uInt32 nTransformType = 0; + if ( xAnimate.is() ) + { + if ( xAnimate->getAttributeName().getLength() ) + nBits |= 4; // what is attributeName ?, maybe this is set if a DFF_msofbtAnimateAttributeNames is written + sal_Int16 nAdditiveMode = xAnimate->getAdditive(); + if ( nAdditiveMode != AnimationAdditiveMode::BASE ) + { + nBits |= 1; + switch( nAdditiveMode ) + { + case AnimationAdditiveMode::SUM : nAdditive = 1; break; + case AnimationAdditiveMode::REPLACE : nAdditive = 2; break; + case AnimationAdditiveMode::MULTIPLY : nAdditive = 3; break; + case AnimationAdditiveMode::NONE : nAdditive = 4; break; + } + } + if ( xAnimate->getAccumulate() ) + { + nBits |= 2; + nAccumulate = 1; + } + } + rStrm << nBits + << nAdditive + << nAccumulate + << nTransformType; + } + if ( xAnimate->getAttributeName().getLength() || nForceAttributeNames ) + { + EscherExContainer aAnimateAttributeNames( rStrm, DFF_msofbtAnimateAttributeNames, 1 ); + rtl::OUString aAttributeName( xAnimate->getAttributeName() ); + if ( nForceAttributeNames ) + { + switch( nForceAttributeNames ) + { + case 1 : aAttributeName = rtl::OUString::createFromAscii( "r" ); break; + } + } + sal_Int32 nIndex = 0; + do + { + OUString aToken( aAttributeName.getToken( 0, ';', nIndex ) ); + exportAnimPropertyString( rStrm, 0, aToken, TRANSLATE_ATTRIBUTE ); + } + while ( nIndex >= 0 ); + } + + if( nAfterEffectType != AFTEREFFECT_NONE ) + { + EscherExContainer aAnimPropertySet( rStrm, DFF_msofbtAnimPropertySet ); + exportAnimPropertyuInt32( rStrm, 6, 1, TRANSLATE_NONE ); + if( nAfterEffectType == AFTEREFFECT_COLOR ) + { + exportAnimPropertyuInt32( rStrm, 4, 0, TRANSLATE_NONE ); + exportAnimPropertyuInt32( rStrm, 5, 0, TRANSLATE_NONE ); + } + } + exportAnimateTargetElement( rStrm, aTarget.hasValue() ? aTarget : xAnimate->getTarget(), sal_False ); + } +} + +void AnimationExporter::exportAnimateTargetElement( SvStream& rStrm, const Any aAny, const sal_Bool bCreate2b01Atom ) +{ + Reference< XShape > xShape; + aAny >>= xShape; + sal_uInt32 nRefMode = 0; // nRefMode == 2 -> Paragraph + sal_Int32 begin = -1; + sal_Int32 end = -1; + + if( !xShape.is() ) + { + ParagraphTarget aParaTarget; + if( aAny >>= aParaTarget ) + xShape = aParaTarget.Shape; + if ( xShape.is() ) + { + // now calculating the character range for the paragraph + sal_Int16 nParagraph = aParaTarget.Paragraph; + Reference< XSimpleText > xText( xShape, UNO_QUERY ); + if ( xText.is() ) + { + nRefMode = 2; + Reference< XEnumerationAccess > xTextParagraphEnumerationAccess( xText, UNO_QUERY ); + if ( xTextParagraphEnumerationAccess.is() ) + { + Reference< XEnumeration > xTextParagraphEnumeration( xTextParagraphEnumerationAccess->createEnumeration() ); + if ( xTextParagraphEnumeration.is() ) + { + sal_Int16 nCurrentParagraph; + begin = end = nCurrentParagraph = 0; + while ( xTextParagraphEnumeration->hasMoreElements() ) + { + Reference< XTextRange > xTextRange( xTextParagraphEnumeration->nextElement(), UNO_QUERY ); + if ( xTextRange.is() ) + { + rtl::OUString aParaText( xTextRange->getString() ); + sal_Int32 nLength = aParaText.getLength() + 1; + end += nLength; + if ( nCurrentParagraph == nParagraph ) + break; + nCurrentParagraph++; + begin += nLength; + } + } + } + } + } + } + } + if ( xShape.is() || bCreate2b01Atom ) + { + EscherExContainer aAnimateTargetElement( rStrm, DFF_msofbtAnimateTargetElement ); + if ( xShape.is() ) + { + EscherExAtom aAnimReference( rStrm, DFF_msofbtAnimReference ); + + sal_uInt32 nRefType = 1; // TODO: nRefType == 2 -> Sound; + sal_uInt32 nRefId = ((EscherSolverContainer&)mrSolverContainer).GetShapeId( xShape ); + + rStrm << nRefMode + << nRefType + << nRefId + << begin + << end; + } + if ( bCreate2b01Atom ) + { + EscherExAtom a2b01Atom( rStrm, 0x2b01 ); + rStrm << (sal_uInt32)1; // ? + } + } +} + +void AnimationExporter::exportAnimateKeyPoints( SvStream& rStrm, const Reference< XAnimate >& xAnimate ) +{ + Sequence< double > aKeyTimes( xAnimate->getKeyTimes() ); + Sequence< Any > aValues( xAnimate->getValues() ); + OUString aFormula( xAnimate->getFormula() ); + if ( aKeyTimes.getLength() ) + { + EscherExContainer aAnimKeyPoints( rStrm, DFF_msofbtAnimKeyPoints ); + sal_Int32 i; + for ( i = 0; i < aKeyTimes.getLength(); i++ ) + { + { + EscherExAtom aAnimKeyTime( rStrm, DFF_msofbtAnimKeyTime ); + sal_Int32 nKeyTime = (sal_Int32)( aKeyTimes[ i ] * 1000.0 ); + rStrm << nKeyTime; + } + Any aAny[ 2 ]; + if ( aValues[ i ].hasValue() ) + { + ValuePair aPair; + if ( aValues[ i ] >>= aPair ) + { + aAny[ 0 ] = convertAnimateValue( aPair.First, xAnimate->getAttributeName() ); + aAny[ 1 ] = convertAnimateValue( aPair.Second, xAnimate->getAttributeName() ); + } + else + { + aAny[ 0 ] = convertAnimateValue( aValues[ i ], xAnimate->getAttributeName() ); + } + if ( !i && aFormula.getLength() ) + { + ImplTranslateAttribute( aFormula, TRANSLATE_MEASURE ); + aAny[ 1 ] <<= aFormula; + } + exportAnimProperty( rStrm, 0, aAny[ 0 ], TRANSLATE_NONE ); + exportAnimProperty( rStrm, 1, aAny[ 1 ], TRANSLATE_NONE ); + } + } + } +} + +void AnimationExporter::exportAnimValue( SvStream& rStrm, const Reference< XAnimationNode >& xNode, const sal_Bool bExportAlways ) +{ + Any aAny; + // repeat count (0) + double fRepeat = 0.0; + float fRepeatCount = 0.0; + com::sun::star::animations::Timing eTiming; + aAny = xNode->getRepeatCount(); + if ( aAny >>= eTiming ) + { + if ( eTiming == Timing_INDEFINITE ) + fRepeatCount = ((float)3.40282346638528860e+38); + } + else if ( aAny >>= fRepeat ) + fRepeatCount = (float)fRepeat; + if ( fRepeatCount != 0.0 ) + { + EscherExAtom aExAtom( rStrm, DFF_msofbtAnimValue ); + sal_uInt32 nType = 0; + rStrm << nType + << fRepeatCount; + } + // accelerate (3) + float fAccelerate = (float)xNode->getAcceleration(); + if ( bExportAlways || ( fAccelerate != 0.0 ) ) + { + EscherExAtom aExAtom( rStrm, DFF_msofbtAnimValue ); + sal_uInt32 nType = 3; + rStrm << nType + << fAccelerate; + } + + // decelerate (4) + float fDecelerate = (float)xNode->getDecelerate(); + if ( bExportAlways || ( fDecelerate != 0.0 ) ) + { + EscherExAtom aExAtom( rStrm, DFF_msofbtAnimValue ); + sal_uInt32 nType = 4; + rStrm << nType + << fDecelerate; + } + + // autoreverse (5) + sal_Bool bAutoReverse = xNode->getAutoReverse(); + if ( bExportAlways || bAutoReverse ) + { + EscherExAtom aExAtom( rStrm, DFF_msofbtAnimValue ); + sal_uInt32 nType = 5; + sal_uInt32 nVal = bAutoReverse ? 1 : 0; + rStrm << nType + << nVal; + } +} + +void AnimationExporter::exportTransitionFilter( SvStream& rStrm, const Reference< XAnimationNode >& xNode ) +{ + Reference< XTransitionFilter > xFilter( xNode, UNO_QUERY ); + if ( xFilter.is() ) + { + EscherExContainer aAnimateFilter( rStrm, DFF_msofbtAnimateFilter ); + { + EscherExAtom aAnimateFilterData( rStrm, DFF_msofbtAnimateFilterData ); + sal_uInt32 nBits = 3; // bit 0 -> use AnimAttributeValue + // bit 1 -> use nTransition + + sal_uInt32 nTransition = xFilter->getMode() ? 0 : 1; + rStrm << nBits + << nTransition; + } + const sal_Char* pFilter = transition::find( xFilter->getTransition(), xFilter->getSubtype(), xFilter->getDirection() ); + if ( pFilter ) + { + const OUString aStr( OUString::createFromAscii( pFilter ) ); + exportAnimPropertyString( rStrm, 1, aStr, TRANSLATE_NONE ); + } + exportAnimateTarget( rStrm, xNode ); + } +} + +void AnimationExporter::exportAnimateMotion( SvStream& rStrm, const Reference< XAnimationNode >& xNode ) +{ + Reference< XAnimateMotion > xMotion( xNode, UNO_QUERY ); + if ( xMotion.is() ) + { + EscherExContainer aAnimateMotion( rStrm, DFF_msofbtAnimateMotion ); + { + { //SJ: Ignored from import filter + EscherExAtom aAnimateMotionData( rStrm, DFF_msofbtAnimateMotionData ); + sal_uInt32 nBits = 0x98; + sal_uInt32 nOrigin = 0x2; + float fByX = 100.0; // nBits&1 + float fByY = 100.0; // nBits&1 + float fFromX = 0.0; // nBits&2 + float fFromY = 0.0; // nBits&2 + float fToX = 100.0; // nBits&4 + float fToY = 100.0; // nBits&4 + rStrm << nBits << fByX << fByY << fFromX << fFromY << fToX << fToY << nOrigin; + } +/* ? + { + EscherExAtom aF137( rStrm, 0xf137 ); + } +*/ + OUString aStr; + if ( xMotion->getPath() >>= aStr ) + { + if ( aStr.getLength() ) + exportAnimPropertyString( rStrm, 1, aStr, TRANSLATE_NONE ); + } + exportAnimateTarget( rStrm, xNode ); + } + } +} + +void AnimationExporter::exportAnimateTransform( SvStream& rStrm, const Reference< XAnimationNode >& xNode ) +{ + Reference< XAnimateTransform > xTransform( xNode, UNO_QUERY ); + if ( xTransform.is() ) + { + if ( xTransform->getTransformType() == AnimationTransformType::SCALE ) + { + EscherExContainer aAnimateScale( rStrm, DFF_msofbtAnimateScale ); + { + EscherExAtom aAnimateScaleData( rStrm, DFF_msofbtAnimateScaleData ); + sal_uInt32 nBits = 0; + sal_uInt32 nZoomContents = 1; + float fByX = 100.0; + float fByY = 100.0; + float fFromX = 0.0; + float fFromY = 0.0; + float fToX = 100.0; + float fToY = 100.0; + + double fX = 0.0, fY = 0.0; + ValuePair aPair; + if ( xTransform->getBy() >>= aPair ) + { + if ( ( aPair.First >>= fX ) && ( aPair.Second >>= fY ) ) + { + nBits |= 1; + fByX = (float)( fX * 100 ); + fByY = (float)( fY * 100 ); + } + } + if ( xTransform->getFrom() >>= aPair ) + { + if ( ( aPair.First >>= fX ) && ( aPair.Second >>= fY ) ) + { + nBits |= 2; + fFromX = (float)( fX * 100 ); + fFromY = (float)( fY * 100 ); + } + } + if( xTransform->getTo() >>= aPair ) + { + if ( ( aPair.First >>= fX ) && ( aPair.Second >>= fY ) ) + { + nBits |= 4; + fToX = (float)( fX * 100 ); + fToY = (float)( fY * 100 ); + } + } + + // TODO: ZoomContents: + //if( nBits & 8 ) + //( fprintf( mpFile, " zoomContents=\"%s\"", nZoomContents ? "true" : "false" ); + + rStrm << nBits << fByX << fByY << fFromX << fFromY << fToX << fToY << nZoomContents; + } + exportAnimateTarget( rStrm, xNode ); + } + else if ( xTransform->getTransformType() == AnimationTransformType::ROTATE ) + { + EscherExContainer aAnimateRotation( rStrm, DFF_msofbtAnimateRotation ); + { + EscherExAtom aAnimateRotationData( rStrm, DFF_msofbtAnimateRotationData ); + sal_uInt32 nBits = 0; + sal_uInt32 nU1 = 0; + float fBy = 360.0; + float fFrom = 0.0; + float fTo = 360.0; + + double fVal = 0.0; + if ( xTransform->getBy() >>= fVal ) + { + nBits |= 1; + fBy = (float)fVal; + } + if ( xTransform->getFrom() >>= fVal ) + { + nBits |= 2; + fFrom = (float)fVal; + } + if ( xTransform->getTo() >>= fVal ) + { + nBits |= 4; + fTo = (float)fVal; + } + rStrm << nBits << fBy << fFrom << fTo << nU1; + } + exportAnimateTarget( rStrm, xNode, 1 ); + } + } +} + +sal_Bool AnimationExporter::getColorAny( const Any& rAny, const sal_Int16 nColorSpace, sal_Int32& rMode, sal_Int32& rA, sal_Int32& rB, sal_Int32& rC ) const +{ + sal_Bool bIsColor = sal_True; + + rMode = 0; + if ( nColorSpace == AnimationColorSpace::HSL ) + rMode = 1; + + sal_Int32 nColor = 0; + Sequence< double > aHSL( 3 ); + if ( rAny >>= nColor ) // RGB color + { + rA = (sal_uInt8)( nColor >> 24 ); + rB = (sal_uInt8)( nColor >> 8 ); + rC = (sal_uInt8)( nColor ); + } + else if ( rAny >>= aHSL ) // HSL + { + rA = (sal_Int32) ( aHSL[ 0 ] * 255.0 / 360.0 ); + rB = (sal_Int32) ( aHSL[ 1 ] * 255.0 ); + rC = (sal_Int32) ( aHSL[ 2 ] * 255.0 ); + } + else + bIsColor = sal_False; + return bIsColor; +} + +void AnimationExporter::exportAnimateColor( SvStream& rStrm, const Reference< XAnimationNode >& xNode, int nAfterEffectType ) +{ + Reference< XAnimateColor > xColor( xNode, UNO_QUERY ); + if ( xColor.is() ) + { + EscherExContainer aAnimateColor( rStrm, DFF_msofbtAnimateColor ); + { + EscherExAtom aAnimateColorData( rStrm, DFF_msofbtAnimateColorData ); + sal_uInt32 nBits = 8; + + sal_Int32 nByMode, nByA, nByB, nByC; + nByMode = nByA = nByB = nByC = 0; + + sal_Int32 nFromMode, nFromA, nFromB, nFromC; + nFromMode = nFromA = nFromB = nFromC = 0; + + sal_Int32 nToMode, nToA, nToB, nToC; + nToMode = nToA = nToB = nToC = 0; + + sal_Int16 nColorSpace = xColor->getColorInterpolation(); + + Any aAny( xColor->getBy() ); + if ( aAny.hasValue() ) + { + if ( getColorAny( aAny, nColorSpace, nByMode, nByA, nByB, nByC ) ) + nBits |= 0x11; + } + aAny = xColor->getFrom(); + if ( aAny.hasValue() ) + { + if ( getColorAny( aAny, nColorSpace, nFromMode, nFromA, nFromB, nFromC ) ) + nBits |= 0x12; + } + aAny = xColor->getTo(); + if ( aAny.hasValue() ) + { + if ( getColorAny( aAny, nColorSpace, nToMode, nToA, nToB, nToC ) ) + nBits |= 0x14; + } + rStrm << nBits + << nByMode << nByA << nByB << nByC + << nFromMode << nFromA << nFromB << nFromC + << nToMode << nToA << nToB << nToC; + } + exportAnimateTarget( rStrm, xNode, 0, nAfterEffectType ); + } +} + +void AnimationExporter::exportIterate( SvStream& rStrm, const Reference< XAnimationNode >& xNode ) +{ + Reference< XIterateContainer > xIterate( xNode, UNO_QUERY ); + if ( xIterate.is() ) + { + EscherExAtom aAnimIteration( rStrm, DFF_msofbtAnimIteration ); + + float fInterval = 10.0; + sal_Int32 nTextUnitEffect = 0; + sal_Int32 nU1 = 1; + sal_Int32 nU2 = 1; + sal_Int32 nU3 = 0xe; + + sal_Int16 nIterateType = xIterate->getIterateType(); + switch( nIterateType ) + { + case TextAnimationType::BY_WORD : nTextUnitEffect = 1; break; + case TextAnimationType::BY_LETTER : nTextUnitEffect = 2; break; + } + + fInterval = (float)xIterate->getIterateInterval(); + + // convert interval from absolute to percentage + double fDuration = 0.0; + + Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY ); + if( xEnumerationAccess.is() ) + { + Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY ); + if( xEnumeration.is() ) + { + while( xEnumeration->hasMoreElements() ) + { + Reference< XAnimate > xChildNode( xEnumeration->nextElement(), UNO_QUERY ); + if( xChildNode.is() ) + { + double fChildBegin = 0.0; + double fChildDuration = 0.0; + xChildNode->getBegin() >>= fChildBegin; + xChildNode->getDuration() >>= fChildDuration; + + fChildDuration += fChildBegin; + if( fChildDuration > fDuration ) + fDuration = fChildDuration; + } + } + } + } + + if( fDuration ) + fInterval = (float)(100.0 * fInterval / fDuration); + + rStrm << fInterval << nTextUnitEffect << nU1 << nU2 << nU3; + aTarget = xIterate->getTarget(); + } +} + +} // namespace ppt; + diff --git a/sd/source/filter/eppt/pptexanimations.hxx b/sd/source/filter/eppt/pptexanimations.hxx new file mode 100644 index 000000000000..b0f38519366d --- /dev/null +++ b/sd/source/filter/eppt/pptexanimations.hxx @@ -0,0 +1,137 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SD_PPT_EXANIMATIONS_HXX +#define _SD_PPT_EXANIMATIONS_HXX + +#include <com/sun/star/animations/XTimeContainer.hpp> +#include <com/sun/star/drawing/XDrawPage.hpp> +#include <com/sun/star/animations/XAnimate.hpp> +#ifndef _SD_PPTANIMATIONS_HXX +#include "../ppt/pptanimations.hxx" +#endif +#include <pptexsoundcollection.hxx> +#include <filter/msfilter/escherex.hxx> + +#ifdef DBG_ANIM_LOG +#include <stdio.h> +#endif + +#ifndef BOOST_SHARED_PTR_HPP_INCLUDED +#include <boost/shared_ptr.hpp> +#endif + +#include <list> + +class DffRecordHeader; +class SdPage; +class SvStream; + +namespace ppt +{ + + struct AfterEffectNode + { + ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode > mxNode; + ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode > mxMaster; + + AfterEffectNode( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode, + const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xMaster ) + : mxNode( xNode ), mxMaster( xMaster ) {} + }; + + typedef boost::shared_ptr< AfterEffectNode > AfterEffectNodePtr; + +typedef sal_uInt32 TranslateMode; +#define TRANSLATE_NONE 0 +#define TRANSLATE_VALUE 1 +#define TRANSLATE_ATTRIBUTE 2 +#define TRANSLATE_MEASURE 4 +#define TRANSLATE_NUMBER_TO_STRING 8 + +const int AFTEREFFECT_NONE = 0; +const int AFTEREFFECT_COLOR = 1; +const int AFTEREFFECT_SET = 2; + +class AnimationExporter +{ + ::com::sun::star::uno::Any aTarget; + + void writeZString( SvStream& rStrm, const rtl::OUString& rVal ); + sal_Bool getColorAny( const ::com::sun::star::uno::Any& rAny, const sal_Int16 nColorSpace, sal_Int32& rMode, sal_Int32& rA, sal_Int32& rB, sal_Int32& rC ) const; + sal_Bool exportAnimProperty( SvStream& rStrm, const sal_uInt16 nPropertyId, const ::com::sun::star::uno::Any& rAny, const TranslateMode eTranslateMode ); + ::com::sun::star::uno::Any convertAnimateValue( const ::com::sun::star::uno::Any& rSource, const rtl::OUString& rAttributeName ) const; + void exportAnimPropertyString( SvStream& rStrm, const sal_uInt16 nPropertyId, const rtl::OUString& rVal, const TranslateMode eTranslateMode ); + void exportAnimPropertyFloat( SvStream& rStrm, const sal_uInt16 nPropertyId, const double& rVal, const TranslateMode eTranslateMode ); + void exportAnimPropertyuInt32( SvStream& rStrm, const sal_uInt16 nPropertyId, const sal_uInt32 nVal, const TranslateMode eTranslateMode ); + void exportAnimPropertyByte( SvStream& rStrm, const sal_uInt16 nPropertyId, const sal_uInt8 nVal, const TranslateMode eTranslateMode ); + + // if available exportAnimPropertySet returns the ::com::sun::star::presentation::EffectNodeType + sal_Int16 exportAnimPropertySet( SvStream& rStrm, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void exportAnimNode( SvStream& rStrm, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode, + const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >* pParent, const sal_Int32 nGroupLevel, const sal_Int16 nFillDefault ); + void exportAnimate( SvStream& rStrm, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void exportAnimateTarget( SvStream& rStrm, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode, const sal_uInt32 nForceAttributeName = 0, int nAfterEffectType = AFTEREFFECT_NONE ); + void exportAnimateSet( SvStream& rStrm, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode, int nAfterEffectType ); + void exportAnimAction( SvStream& rStrm, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void exportAnimEvent( SvStream& rStrm, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode, const sal_Int32 nFlags = 0 ); + void exportNode( SvStream& rStrm, ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode > xNode, + const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >* xParent, + const sal_uInt16 nContainerRecType, const sal_uInt16 nInstance, const sal_Int32 nGroupLevel, const sal_Bool bTakeBackInteractiveSequenceTiming, + const sal_Int16 nFillDefault ); + void exportAnimateTargetElement( SvStream& rStrm, const ::com::sun::star::uno::Any aAny, const sal_Bool bCreate2b01Atom ); + void exportAnimateKeyPoints( SvStream& rStrm, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimate >& xAnimate ); + void exportAnimValue( SvStream& rStrm, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode, const sal_Bool bExportAlways ); + void exportTransitionFilter( SvStream& rStrm, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void exportAnimateMotion( SvStream& rStrm, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void exportAnimateTransform( SvStream& rStrm, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void exportAnimateColor( SvStream& rStrm, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode, int nAfterEffectType ); + void exportIterate( SvStream& rStrm, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + + const EscherSolverContainer& mrSolverContainer; + ppt::ExSoundCollection& mrExSoundCollection; + void processAfterEffectNodes( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + + bool isAfterEffectNode( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ) const; + bool hasAfterEffectNode( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode, ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xAfterEffectNode ) const; + bool isEmptyNode( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ) const; + + ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode > createAfterEffectNodeClone( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ) const; + + std::list< AfterEffectNodePtr > maAfterEffectNodes; + +public: + AnimationExporter( const EscherSolverContainer& rSolverContainer, ppt::ExSoundCollection& rExSoundCollection ); + + void doexport( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage >& xPage, SvStream& rStrm ); + + sal_Int32 mnCurrentGroup; +}; + +} // namespace ppt + +#endif diff --git a/sd/source/filter/eppt/pptexsoundcollection.cxx b/sd/source/filter/eppt/pptexsoundcollection.cxx new file mode 100644 index 000000000000..9510da8757e3 --- /dev/null +++ b/sd/source/filter/eppt/pptexsoundcollection.cxx @@ -0,0 +1,229 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" +#include <pptexsoundcollection.hxx> +#include "epptdef.hxx" +#include <tools/urlobj.hxx> +#ifndef _UCBHELPER_CONTENT_HXX_ +#include <ucbhelper/content.hxx> +#endif +#ifndef _UCBHELPER_CONTENTBROKER_HXX_ +#include <ucbhelper/contentbroker.hxx> +#endif +#ifndef _CPPUHELPER_PROPTYPEHLP_HXX_ +#include <cppuhelper/proptypehlp.hxx> +#endif +#include <unotools/ucbstreamhelper.hxx> + +namespace ppt +{ + +ExSoundEntry::ExSoundEntry( const String& rString ) +: nFileSize( 0 ) +, aSoundURL( rString ) +{ + try + { + ::ucbhelper::Content aCnt( aSoundURL, + ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() ); + sal_Int64 nVal = 0; + ::cppu::convertPropertyValue( nVal, aCnt.getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Size" ) ) ) ); + nFileSize = (sal_uInt32)nVal; + } + catch( ::com::sun::star::uno::Exception& ) + { + + } +}; + +String ExSoundEntry::ImplGetName() const +{ + INetURLObject aTmp( aSoundURL ); + return aTmp.GetName(); +} + +String ExSoundEntry::ImplGetExtension() const +{ + INetURLObject aTmp( aSoundURL ); + String aExtension( aTmp.GetExtension() ); + if ( aExtension.Len() ) + aExtension.Insert( (sal_Unicode)'.', 0 ); + return aExtension; +} + +sal_Bool ExSoundEntry::IsSameURL( const String& rURL ) const +{ + return ( rURL == aSoundURL ); +} + +sal_uInt32 ExSoundEntry::GetSize( sal_uInt32 nId ) const +{ + String aName( ImplGetName() ); + String aExtension( ImplGetExtension() ); + + sal_uInt32 nSize = 8; // SoundContainer Header + if ( aName.Len() ) // String Atom ( instance 0 - name of sound ) + nSize += aName.Len() * 2 + 8; + if ( aExtension.Len() ) // String Atom ( instance 1 - extension of sound ) + nSize += aExtension.Len() * 2 + 8; + + String aId( String::CreateFromInt32( nId ) ); // String Atom ( instance 2 - reference id ) + nSize += 2 * aId.Len() + 8; + + nSize += nFileSize + 8; // SoundData Atom + + return nSize; +} + +void ExSoundEntry::Write( SvStream& rSt, sal_uInt32 nId ) +{ + try + { + ::ucbhelper::Content aCnt( aSoundURL, + ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() ); + + // create SoundContainer + rSt << (sal_uInt32)( ( EPP_Sound << 16 ) | 0xf ) << (sal_uInt32)( GetSize( nId ) - 8 ); + + String aSoundName( ImplGetName() ); + sal_uInt16 i, nSoundNameLen = aSoundName.Len(); + if ( nSoundNameLen ) + { + // name of sound ( instance 0 ) + rSt << (sal_uInt32)( EPP_CString << 16 ) << (sal_uInt32)( nSoundNameLen * 2 ); + for ( i = 0; i < nSoundNameLen; i++ ) + rSt << aSoundName.GetChar( i ); + } + String aExtension( ImplGetExtension() ); + sal_uInt32 nExtensionLen = aExtension.Len(); + if ( nExtensionLen ) + { + // extension of sound ( instance 1 ) + rSt << (sal_uInt32)( ( EPP_CString << 16 ) | 16 ) << (sal_uInt32)( nExtensionLen * 2 ); + for ( i = 0; i < nExtensionLen; i++ ) + rSt << aExtension.GetChar( i ); + } + // id of sound ( instance 2 ) + String aId( String::CreateFromInt32( nId ) ); + sal_uInt32 nIdLen = aId.Len(); + rSt << (sal_uInt32)( ( EPP_CString << 16 ) | 32 ) << (sal_uInt32)( nIdLen * 2 ); + for ( i = 0; i < nIdLen; i++ ) + rSt << aId.GetChar( i ); + + rSt << (sal_uInt32)( EPP_SoundData << 16 ) << (sal_uInt32)( nFileSize ); + sal_uInt32 nBytesLeft = nFileSize; + SvStream* pSourceFile = ::utl::UcbStreamHelper::CreateStream( aSoundURL, STREAM_READ ); + if ( pSourceFile ) + { + sal_uInt8* pBuf = new sal_uInt8[ 0x10000 ]; // 64 kB Buffer + while ( nBytesLeft ) + { + sal_uInt32 nToDo = ( nBytesLeft > 0x10000 ) ? 0x10000 : nBytesLeft; + pSourceFile->Read( pBuf, nToDo ); + rSt.Write( pBuf, nToDo ); + nBytesLeft -= nToDo; + } + delete pSourceFile; + delete[] pBuf; + } + } + catch( ::com::sun::star::uno::Exception& ) + { + + } +} + +ExSoundCollection::~ExSoundCollection() +{ + for( void* pPtr = List::First(); pPtr; pPtr = List::Next() ) + delete (ExSoundEntry*)pPtr; +} + +sal_uInt32 ExSoundCollection::GetId( const String& rString ) +{ + sal_uInt32 nSoundId = 0; + if( rString.Len() ) + { + const sal_uInt32 nSoundCount = Count(); + + for( ; nSoundId < nSoundCount; nSoundId++ ) + if( ImplGetByIndex( nSoundId )->IsSameURL( rString ) ) + break; + if ( nSoundId++ == nSoundCount ) + { + ExSoundEntry* pEntry = new ExSoundEntry( rString ); + if ( pEntry->GetFileSize() ) + List::Insert( pEntry, LIST_APPEND ); + else + { + nSoundId = 0; // only insert sounds that are accessible + delete pEntry; + } + } + } + return nSoundId; +} + +const ExSoundEntry* ExSoundCollection::ImplGetByIndex( sal_uInt32 nIndex ) const +{ + return (ExSoundEntry*)List::GetObject( nIndex ); +} + +sal_uInt32 ExSoundCollection::GetSize() const +{ + sal_uInt32 nSize = 0; + sal_uInt32 i, nSoundCount = Count(); + if ( nSoundCount ) + { + nSize += 8 + 12; // size of SoundCollectionContainerHeader + SoundCollAtom + for ( i = 0; i < nSoundCount; i++ ) + nSize += ImplGetByIndex( i )->GetSize( i + 1 ); + } + return nSize; +} + +void ExSoundCollection::Write( SvStream& rSt ) +{ + sal_uInt32 i, nSoundCount = Count(); + if ( nSoundCount ) + { + // create SoundCollection Container + rSt << (sal_uInt16)0xf << (sal_uInt16)EPP_SoundCollection << (sal_uInt32)( GetSize() - 8 ); + + // create SoundCollAtom ( reference to the next free SoundId ); + rSt << (sal_uInt32)( EPP_SoundCollAtom << 16 ) << (sal_uInt32)4 << nSoundCount; + + for ( i = 0; i < nSoundCount; i++ ) + ((ExSoundEntry*)List::GetObject( i ))->Write( rSt, i + 1 ); + } +} + + +} // namespace ppt; + diff --git a/sd/source/filter/eppt/pptexsoundcollection.hxx b/sd/source/filter/eppt/pptexsoundcollection.hxx new file mode 100644 index 000000000000..88965abe71ef --- /dev/null +++ b/sd/source/filter/eppt/pptexsoundcollection.hxx @@ -0,0 +1,83 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SD_PPT_EXSOUNDCOLLECTION_HXX +#define _SD_PPT_EXSOUNDCOLLECTION_HXX + +#ifdef DBG_ANIM_LOG +#include <stdio.h> +#endif +#include <tools/string.hxx> +#include <tools/stream.hxx> +#ifndef BOOST_SHARED_PTR_HPP_INCLUDED +#include <boost/shared_ptr.hpp> +#endif + +#include <list> + +namespace ppt +{ + +class ExSoundEntry +{ + sal_uInt32 nFileSize; + String aSoundURL; + + String ImplGetName() const; + String ImplGetExtension() const; + + public : + + sal_Bool IsSameURL( const String& rURL ) const; + sal_uInt32 GetFileSize( ) const { return nFileSize; }; + + ExSoundEntry( const String& rSoundURL ); + + // returns the size of a complete SoundContainer + sal_uInt32 GetSize( sal_uInt32 nId ) const; + void Write( SvStream& rSt, sal_uInt32 nId ); +}; + +class ExSoundCollection : private List +{ + const ExSoundEntry* ImplGetByIndex( sal_uInt32 nId ) const; + + public: + + ExSoundCollection() {} + ~ExSoundCollection(); + + sal_uInt32 GetId( const String& ); + + // returns the size of a complete SoundCollectionContainer + sal_uInt32 GetSize() const; + void Write( SvStream& rSt ); +}; + +} // namespace ppt + +#endif diff --git a/sd/source/filter/grf/makefile.mk b/sd/source/filter/grf/makefile.mk new file mode 100644 index 000000000000..7b6ad7121cce --- /dev/null +++ b/sd/source/filter/grf/makefile.mk @@ -0,0 +1,44 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. +PRJNAME=sd +TARGET=grf +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = $(SLO)$/sdgrffilter.obj + +# --- Targets -------------------------------------------------------------- + +.INCLUDE : target.mk diff --git a/sd/source/filter/grf/sdgrffilter.cxx b/sd/source/filter/grf/sdgrffilter.cxx new file mode 100644 index 000000000000..0d91df41500f --- /dev/null +++ b/sd/source/filter/grf/sdgrffilter.cxx @@ -0,0 +1,558 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" + +#ifdef _MSC_VER +#pragma warning (disable:4190) +#endif +#include <com/sun/star/graphic/XGraphicProvider.hpp> +#include <com/sun/star/graphic/GraphicType.hpp> +#include <com/sun/star/ucb/XSimpleFileAccess2.hpp> + +#include <unotools/localfilehelper.hxx> +#include <tools/errinf.hxx> +#include <vcl/msgbox.hxx> +#include <vcl/metaact.hxx> +#include <vcl/virdev.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/docfilt.hxx> +#include <sfx2/frame.hxx> +#include <svx/svdograf.hxx> +#include <svx/svdpagv.hxx> + +#include "../../ui/inc/strings.hrc" +#include "../../ui/inc/DrawViewShell.hxx" +#include "../../ui/inc/DrawDocShell.hxx" +#include "../../ui/inc/ClientView.hxx" +#include "../../ui/inc/FrameView.hxx" + +#include "comphelper/anytostring.hxx" +#include "cppuhelper/exc_hlp.hxx" + +// -- +#include <comphelper/processfactory.hxx> +#include <unotools/pathoptions.hxx> +#include <com/sun/star/ui/dialogs/XFilePicker.hpp> +#include <com/sun/star/ui/dialogs/XFilterManager.hpp> +#include <com/sun/star/ui/dialogs/TemplateDescription.hpp> +#include <sfx2/filedlghelper.hxx> +#include <tools/urlobj.hxx> +#include <svtools/filter.hxx> +#include <svx/xoutbmp.hxx> + +// -- + +#include "sdpage.hxx" +#include "drawdoc.hxx" +#include "sdresid.hxx" +#include "sdgrffilter.hxx" +#include "../../ui/inc/ViewShellBase.hxx" +#include <com/sun/star/uno/Sequence.h> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/PropertyValues.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/document/XFilter.hpp> +#include <com/sun/star/document/XExporter.hpp> +#include <comphelper/processfactory.hxx> +#include <com/sun/star/view/XSelectionSupplier.hpp> +#include <com/sun/star/drawing/XDrawView.hpp> +#include "../../ui/inc/DrawController.hxx" +#include <cppuhelper/implbase2.hxx> +#include <com/sun/star/drawing/XShape.hpp> +#include <com/sun/star/task/XInteractionHandler.hpp> +#include <com/sun/star/task/XInteractionRequest.hpp> +#include <com/sun/star/drawing/GraphicFilterRequest.hpp> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::graphic; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::ucb; +using namespace com::sun::star::ui::dialogs; +using rtl::OUString; +using namespace ::sfx2; + + +// ----------------------------------------------------------------------------- + +class SdGRFFilter_ImplInteractionHdl : public ::cppu::WeakImplHelper1< com::sun::star::task::XInteractionHandler > +{ + com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > m_xInter; + USHORT nFilterError; + + public: + + SdGRFFilter_ImplInteractionHdl( com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > xInteraction ) : + m_xInter( xInteraction ), + nFilterError( GRFILTER_OK ) + {} + + ~SdGRFFilter_ImplInteractionHdl(); + + USHORT GetErrorCode() const { return nFilterError; }; + + virtual void SAL_CALL handle( const com::sun::star::uno::Reference< com::sun::star::task::XInteractionRequest >& ) + throw( com::sun::star::uno::RuntimeException ); +}; + +SdGRFFilter_ImplInteractionHdl::~SdGRFFilter_ImplInteractionHdl() +{ +} + +void SdGRFFilter_ImplInteractionHdl::handle( const com::sun::star::uno::Reference< com::sun::star::task::XInteractionRequest >& xRequest ) + throw( com::sun::star::uno::RuntimeException ) +{ + if( !m_xInter.is() ) + return; + + com::sun::star::drawing::GraphicFilterRequest aErr; + if ( xRequest->getRequest() >>= aErr ) + nFilterError = (USHORT)aErr.ErrCode; + else + m_xInter->handle( xRequest ); +} + + +// --------------- +// - SdPPTFilter - +// --------------- + +SdGRFFilter::SdGRFFilter( SfxMedium& rMedium, ::sd::DrawDocShell& rDocShell ) : + SdFilter( rMedium, rDocShell, sal_True ) +{ +} + +// ----------------------------------------------------------------------------- + +SdGRFFilter::~SdGRFFilter() +{ +} + +// ----------------------------------------------------------------------------- + +void SdGRFFilter::HandleGraphicFilterError( USHORT nFilterError, ULONG nStreamError ) +{ + USHORT nId; + + switch( nFilterError ) + { + case GRFILTER_OPENERROR: + nId = STR_IMPORT_GRFILTER_OPENERROR; + break; + case GRFILTER_IOERROR: + nId = STR_IMPORT_GRFILTER_IOERROR; + break; + case GRFILTER_FORMATERROR: + nId = STR_IMPORT_GRFILTER_FORMATERROR; + break; + case GRFILTER_VERSIONERROR: + nId = STR_IMPORT_GRFILTER_VERSIONERROR; + break; + case GRFILTER_TOOBIG: + nId = STR_IMPORT_GRFILTER_TOOBIG; + break; + case 0 : + nId = 0; + break; + + default: + case GRFILTER_FILTERERROR: + nId = STR_IMPORT_GRFILTER_FILTERERROR; + break; + } + + if( ERRCODE_NONE != nStreamError ) + ErrorHandler::HandleError( nStreamError ); + else if( STR_IMPORT_GRFILTER_IOERROR == nId ) + ErrorHandler::HandleError( ERRCODE_IO_GENERAL ); + else + { + ErrorBox aErrorBox( NULL, WB_OK, String( SdResId( nId ) ) ); + aErrorBox.Execute(); + } +} + +// ----------------------------------------------------------------------------- + +sal_Bool SdGRFFilter::Import() +{ + Graphic aGraphic; + const String aFileName( mrMedium.GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ); + GraphicFilter* pGraphicFilter = GraphicFilter::GetGraphicFilter(); + const USHORT nFilter = pGraphicFilter->GetImportFormatNumberForTypeName( mrMedium.GetFilter()->GetTypeName() ); + sal_Bool bRet = sal_False; + + // ggf. Filterdialog ausfuehren + if ( !pGraphicFilter->HasImportDialog( nFilter ) || pGraphicFilter->DoImportDialog( NULL, nFilter ) ) + { + SvStream* pIStm = mrMedium.GetInStream(); + USHORT nReturn = pIStm ? pGraphicFilter->ImportGraphic( aGraphic, aFileName, *pIStm, nFilter ) : 1; + + if( nReturn ) + HandleGraphicFilterError( nReturn, pGraphicFilter->GetLastError().nStreamError ); + else + { + if( mrDocument.GetPageCount() == 0L ) + mrDocument.CreateFirstPages(); + + SdPage* pPage = mrDocument.GetSdPage( 0, PK_STANDARD ); + Point aPos; + Size aPagSize( pPage->GetSize() ); + Size aGrfSize( OutputDevice::LogicToLogic( aGraphic.GetPrefSize(), + aGraphic.GetPrefMapMode(), MAP_100TH_MM ) ); + + aPagSize.Width() -= pPage->GetLftBorder() + pPage->GetRgtBorder(); + aPagSize.Height() -= pPage->GetUppBorder() + pPage->GetLwrBorder(); + + // scale to fit page + if ( ( ( aGrfSize.Height() > aPagSize.Height() ) || ( aGrfSize.Width() > aPagSize.Width() ) ) && + aGrfSize.Height() && aPagSize.Height() ) + { + double fGrfWH = (double) aGrfSize.Width() / aGrfSize.Height(); + double fWinWH = (double) aPagSize.Width() / aPagSize.Height(); + + // Grafik an Pagesize anpassen (skaliert) + if( fGrfWH < fWinWH ) + { + aGrfSize.Width() = (long) ( aPagSize.Height() * fGrfWH ); + aGrfSize.Height() = aPagSize.Height(); + } + else if( fGrfWH > 0.F ) + { + aGrfSize.Width() = aPagSize.Width(); + aGrfSize.Height()= (long) ( aPagSize.Width() / fGrfWH ); + } + } + + // Ausgaberechteck fuer Grafik setzen + aPos.X() = ( ( aPagSize.Width() - aGrfSize.Width() ) >> 1 ) + pPage->GetLftBorder(); + aPos.Y() = ( ( aPagSize.Height() - aGrfSize.Height() ) >> 1 ) + pPage->GetUppBorder(); + + pPage->InsertObject( new SdrGrafObj( aGraphic, Rectangle( aPos, aGrfSize ) ) ); + bRet = sal_True; + } + } + return bRet; +} + +// ----------------------------------------------------------------------------- + +sal_Bool SdGRFFilter::Export() +{ + // SJ: todo: error handling, the GraphicExportFilter does not support proper errorhandling + + sal_Bool bRet = sal_False; + + uno::Reference< lang::XMultiServiceFactory > + xSMgr( ::comphelper::getProcessServiceFactory() ); + uno::Reference< uno::XInterface > xComponent + ( xSMgr->createInstance( rtl::OUString::createFromAscii( "com.sun.star.drawing.GraphicExportFilter" ) ), + uno::UNO_QUERY ); + if ( xComponent.is() ) + { + uno::Reference< document::XExporter > xExporter + ( xComponent, uno::UNO_QUERY ); + uno::Reference< document::XFilter > xFilter + ( xComponent, uno::UNO_QUERY ); + if ( xExporter.is() && xFilter.is() ) + { + SdPage* pPage = NULL; + sd::DrawViewShell* pDrawViewShell = static_cast< ::sd::DrawViewShell* > + ( ( ( mrDocShell.GetViewShell() && mrDocShell.GetViewShell()->ISA(::sd::DrawViewShell ) ) ? mrDocShell.GetViewShell() : NULL ) ); + + PageKind ePageKind = PK_STANDARD; + if( pDrawViewShell ) + { + ePageKind = pDrawViewShell->GetPageKind(); + if( PK_HANDOUT == ePageKind ) + pPage = mrDocument.GetSdPage( 0, PK_HANDOUT ); + else + pPage = pDrawViewShell->GetActualPage(); + } + else + pPage = mrDocument.GetSdPage( 0, PK_STANDARD ); + + if ( pPage ) + { + // taking the 'correct' page number, seems that there might exist a better method to archive this + pPage = mrDocument.GetSdPage( pPage->GetPageNum() ? ( pPage->GetPageNum() - 1 ) >> 1 : 0, ePageKind ); + if ( pPage ) + { + uno::Reference< lang::XComponent > xSource( pPage->getUnoPage(), uno::UNO_QUERY ); + SfxItemSet* pSet = mrMedium.GetItemSet(); + GraphicFilter* pGraphicFilter = GraphicFilter::GetGraphicFilter(); + if ( pSet && pGraphicFilter && xSource.is() ) + { + const String aTypeName( mrMedium.GetFilter()->GetTypeName() ); + const USHORT nFilter = pGraphicFilter->GetExportFormatNumberForTypeName( aTypeName ); + if ( nFilter != GRFILTER_FORMAT_NOTFOUND ) + { + uno::Reference< task::XInteractionHandler > mXInteractionHandler; + + beans::PropertyValues aArgs; + TransformItems( SID_SAVEASDOC, *pSet, aArgs ); + + rtl::OUString sInteractionHandler( RTL_CONSTASCII_USTRINGPARAM( "InteractionHandler" ) ); + rtl::OUString sFilterName( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) ); + rtl::OUString sShortName( pGraphicFilter->GetExportFormatShortName( nFilter ) ); + + sal_Bool bFilterNameFound = sal_False; + sal_Int32 i, nCount; + for ( i = 0, nCount = aArgs.getLength(); i < nCount; i++ ) + { + rtl::OUString& rStr = aArgs[ i ].Name; + if ( rStr == sFilterName ) + { + bFilterNameFound = sal_True; + aArgs[ i ].Name = sFilterName; + aArgs[ i ].Value <<= sShortName; + } + else if ( rStr == sInteractionHandler ) + { + uno::Reference< task::XInteractionHandler > xHdl; + if ( aArgs[ i ].Value >>= xHdl ) + { + mXInteractionHandler = new SdGRFFilter_ImplInteractionHdl( xHdl ); + aArgs[ i ].Value <<= mXInteractionHandler; + } + } + } + if ( !bFilterNameFound ) + { + aArgs.realloc( ++nCount ); + aArgs[ i ].Name = sFilterName; + aArgs[ i ].Value <<= sShortName; + } + + // take selection if needed + if( ( SFX_ITEM_SET == pSet->GetItemState( SID_SELECTION ) ) + && static_cast< const SfxBoolItem& >( pSet->Get( SID_SELECTION ) ).GetValue() + && pDrawViewShell ) + { + uno::Reference< view::XSelectionSupplier > xSelectionSupplier( + pDrawViewShell->GetViewShellBase().GetController(), uno::UNO_QUERY ); + if ( xSelectionSupplier.is() ) + { + uno::Any aSelection( xSelectionSupplier->getSelection() ); + uno::Reference< lang::XComponent > xSelection; + if ( aSelection >>= xSelection ) + xSource = xSelection; + } + } + xExporter->setSourceDocument( xSource ); + bRet = xFilter->filter( aArgs ); + if ( !bRet && mXInteractionHandler.is() ) + SdGRFFilter::HandleGraphicFilterError( + static_cast< SdGRFFilter_ImplInteractionHdl* >( mXInteractionHandler.get() )->GetErrorCode(), + pGraphicFilter->GetLastError().nStreamError ); + } + } + } + } + } + } + return bRet; +} + +void SdGRFFilter::SaveGraphic( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& xShape ) +{ + try + { + Reference< XMultiServiceFactory > xSM( ::comphelper::getProcessServiceFactory(), UNO_QUERY_THROW ); + + Reference< XGraphicProvider > xProvider( xSM->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.graphic.GraphicProvider" ) ) ), UNO_QUERY_THROW ); + Reference< XPropertySet > xShapeSet( xShape, UNO_QUERY_THROW ); + + // detect mime type of graphic + OUString aMimeType; + OUString sGraphicURL; + + // first try to detect from graphic object + Reference< XPropertySet > xGraphicSet( xShapeSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Graphic" ) ) ), UNO_QUERY_THROW ); + xShapeSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "GraphicURL" ) ) ) >>= sGraphicURL; + + bool bIsLinked = (sGraphicURL.getLength() != 0) && (sGraphicURL.compareToAscii( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.GraphicObject:") ) != 0); + + if( !bIsLinked ) + xGraphicSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "MimeType" ) ) ) >>= aMimeType; + + if( bIsLinked || aMimeType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "image/x-vclgraphic" ) ) || !aMimeType.getLength() ) + { + // this failed, try to detect it from graphic stream and URL + OUString aURL( sGraphicURL ); + + if( aURL.getLength() == 0 ) + xShapeSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "GraphicStreamURL" ) ) ) >>= aURL; + + { + Reference< XInputStream > xGraphStream( xShapeSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "GraphicStream" ) ) ), UNO_QUERY ); + PropertyValues aDesc(2); + aDesc[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ); + aDesc[0].Value <<= aURL; + aDesc[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "InputStream" ) ); + aDesc[1].Value <<= xGraphStream; + + Reference< XPropertySet > xDescSet( xProvider->queryGraphicDescriptor( aDesc ), UNO_QUERY_THROW ); + + xDescSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "MimeType" ) ) ) >>= aMimeType; + } + } + + if( aMimeType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "image/x-vclgraphic" ) ) || !aMimeType.getLength() ) + { + // this also failed, now set a mimetype that fits graphic best + + // gif for animated pixel + // png for non animated pixel + // svm for vector format + sal_Int8 nGraphicType = 0; + xGraphicSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "GraphicType" ) ) ) >>= nGraphicType; + switch( nGraphicType ) + { + case ::com::sun::star::graphic::GraphicType::VECTOR: + aMimeType = OUString::createFromAscii( "image/x-svm" ); + break; + + case ::com::sun::star::graphic::GraphicType::PIXEL: + { + sal_Bool bAnimated = sal_False; + xGraphicSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Animated" ) ) ) >>= bAnimated; + + if( bAnimated ) + { + aMimeType = OUString::createFromAscii( "image/gif" ); + break; + } + } + // Fallthrough! +// case ::com::sun::star::graphic::GraphicType::EMPTY: + default: + aMimeType = OUString::createFromAscii( "image/png" ); + break; + } + } + + // init dialog + SvtPathOptions aPathOpt; + String sGrfPath( aPathOpt.GetGraphicPath() ); + + FileDialogHelper aDlgHelper( TemplateDescription::FILESAVE_AUTOEXTENSION, 0 ); + Reference < XFilePicker > xFP = aDlgHelper.GetFilePicker(); + + String aTitle( SdResId( STR_TITLE_SAVE_AS_PICTURE ) ); + aDlgHelper.SetTitle( aTitle ); + + INetURLObject aPath; + aPath.SetSmartURL( sGrfPath); + xFP->setDisplayDirectory( aPath.GetMainURL(INetURLObject::DECODE_TO_IURI) ); + + // populate filter dialog filter list and select default filter to match graphic mime type + + GraphicFilter& rGF = *GraphicFilter::GetGraphicFilter(); + Reference<XFilterManager> xFltMgr(xFP, UNO_QUERY); + OUString aDefaultFormatName; + USHORT nCount = rGF.GetExportFormatCount(); + + std::map< OUString, OUString > aMimeTypeMap; + + for ( USHORT i = 0; i < nCount; i++ ) + { + const OUString aExportFormatName( rGF.GetExportFormatName( i ) ); + const OUString aFilterMimeType( rGF.GetExportFormatMediaType( i ) ); + xFltMgr->appendFilter( aExportFormatName, rGF.GetExportWildcard( i ) ); + aMimeTypeMap[ aExportFormatName ] = aFilterMimeType; + if( aMimeType == aFilterMimeType ) + aDefaultFormatName = aExportFormatName; + } + + if( aDefaultFormatName.getLength() == 0 ) + { + nCount = rGF.GetImportFormatCount(); + for( USHORT i = 0; i < nCount; i++ ) + { + const OUString aFilterMimeType( rGF.GetImportFormatMediaType( i ) ); + if( aMimeType == aFilterMimeType ) + { + aDefaultFormatName = rGF.GetImportFormatName( i ); + xFltMgr->appendFilter( aDefaultFormatName, rGF.GetImportWildcard( i ) ); + aMimeTypeMap[ aDefaultFormatName ] = aFilterMimeType; + break; + } + } + } + + if( aDefaultFormatName.getLength() == 0 ) + aDefaultFormatName = OUString( RTL_CONSTASCII_USTRINGPARAM( "PNG - Portable Network Graphic" ) ); + + xFltMgr->setCurrentFilter( aDefaultFormatName ); + + // execute dialog + + if( aDlgHelper.Execute() == ERRCODE_NONE ) + { + OUString sPath( xFP->getFiles().getConstArray()[0] ); + aPath.SetSmartURL( sPath); + sGrfPath = aPath.GetPath(); + + OUString aExportMimeType( aMimeTypeMap[xFltMgr->getCurrentFilter()] ); + + Reference< XInputStream > xGraphStream; + if( aMimeType == aExportMimeType ) + xShapeSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "GraphicStream" ) ) ) >>= xGraphStream; + + if( xGraphStream.is() ) + { + Reference< XSimpleFileAccess2 > xFileAccess( xSM->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.SimpleFileAccess" ) ) ), UNO_QUERY_THROW ); + xFileAccess->writeFile( sPath, xGraphStream ); + } + else + { + PropertyValues aDesc(2); + aDesc[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ); + aDesc[0].Value <<= sPath; + aDesc[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "MimeType" ) ); + aDesc[1].Value <<= aExportMimeType; + Reference< XGraphic > xGraphic( xShapeSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Graphic" ) ) ), UNO_QUERY_THROW ); + xProvider->storeGraphic( xGraphic, aDesc ); + } + } + } + catch( Exception& ) + { + DBG_ERROR( + (rtl::OString("SdGRFFilter::SaveGraphic(), " + "exception caught: ") + + rtl::OUStringToOString( + comphelper::anyToString( cppu::getCaughtException() ), + RTL_TEXTENCODING_UTF8 )).getStr() ); + } +} diff --git a/sd/source/filter/html/HtmlOptionsDialog.cxx b/sd/source/filter/html/HtmlOptionsDialog.cxx new file mode 100644 index 000000000000..14bd3e46c581 --- /dev/null +++ b/sd/source/filter/html/HtmlOptionsDialog.cxx @@ -0,0 +1,287 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" +#include <osl/file.hxx> +#include <vos/module.hxx> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/document/XViewDataSupplier.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/uno/Sequence.h> +#include <com/sun/star/uno/Any.h> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/beans/XPropertyAccess.hpp> +#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp> +#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp> +#include <com/sun/star/document/XExporter.hpp> +#include <cppuhelper/implbase5.hxx> +#include <vcl/svapp.hxx> + +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::document; +using namespace com::sun::star::beans; +using namespace com::sun::star::container; +using namespace com::sun::star::frame; +using namespace com::sun::star::ui::dialogs; + +#include "pres.hxx" +#include "sdabstdlg.hxx" +#include "tools/debug.hxx" +class SdHtmlOptionsDialog : public cppu::WeakImplHelper5 +< + XExporter, + XExecutableDialog, + XPropertyAccess, + XInitialization, + XServiceInfo +> +{ + const Reference< XMultiServiceFactory > &mrxMgr; + Sequence< PropertyValue > maMediaDescriptor; + Sequence< PropertyValue > maFilterDataSequence; + ::rtl::OUString aDialogTitle; + DocumentType meDocType; + +public: + + SdHtmlOptionsDialog( const Reference< XMultiServiceFactory >& _rxORB ); + ~SdHtmlOptionsDialog(); + + // XInterface + virtual void SAL_CALL acquire() throw(); + virtual void SAL_CALL release() throw(); + + // XInitialization + virtual void SAL_CALL initialize( const Sequence< Any > & aArguments ) throw ( Exception, RuntimeException ); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() throw ( RuntimeException ); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw ( RuntimeException ); + virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw ( RuntimeException ); + + // XPropertyAccess + virtual Sequence< PropertyValue > SAL_CALL getPropertyValues() throw ( RuntimeException ); + virtual void SAL_CALL setPropertyValues( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > & aProps ) + throw ( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, + ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException ); + + // XExecuteDialog + virtual sal_Int16 SAL_CALL execute() + throw ( com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL setTitle( const ::rtl::OUString& aTitle ) + throw ( ::com::sun::star::uno::RuntimeException ); + + // XExporter + virtual void SAL_CALL setSourceDocument( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& xDoc ) + throw ( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException ); + +}; + +// ------------------------- +// - SdHtmlOptionsDialog - +// ------------------------- + +Reference< XInterface > + SAL_CALL SdHtmlOptionsDialog_CreateInstance( + const Reference< XMultiServiceFactory > & _rxFactory ) +{ + return static_cast< ::cppu::OWeakObject* > ( new SdHtmlOptionsDialog( _rxFactory ) ); +} + +::rtl::OUString SdHtmlOptionsDialog_getImplementationName() + throw( RuntimeException ) +{ + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.draw.SdHtmlOptionsDialog" ) ); +} +#define SERVICE_NAME "com.sun.star.ui.dialog.FilterOptionsDialog" +sal_Bool SAL_CALL SdHtmlOptionsDialog_supportsService( const ::rtl::OUString& ServiceName ) + throw( RuntimeException ) +{ + return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( SERVICE_NAME ) ); +} + +Sequence< ::rtl::OUString > SAL_CALL SdHtmlOptionsDialog_getSupportedServiceNames() + throw( RuntimeException ) +{ + Sequence< ::rtl::OUString > aRet(1); + ::rtl::OUString* pArray = aRet.getArray(); + pArray[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICE_NAME ) ); + return aRet; +} +#undef SERVICE_NAME + +// ----------------------------------------------------------------------------- + +SdHtmlOptionsDialog::SdHtmlOptionsDialog( const Reference< XMultiServiceFactory > & xMgr ) : + mrxMgr ( xMgr ), + meDocType ( DOCUMENT_TYPE_DRAW ) +{ +} + +// ----------------------------------------------------------------------------- + +SdHtmlOptionsDialog::~SdHtmlOptionsDialog() +{ +} + +// ----------------------------------------------------------------------------- + +void SAL_CALL SdHtmlOptionsDialog::acquire() throw() +{ + OWeakObject::acquire(); +} + +// ----------------------------------------------------------------------------- + +void SAL_CALL SdHtmlOptionsDialog::release() throw() +{ + OWeakObject::release(); +} + +// XInitialization +void SAL_CALL SdHtmlOptionsDialog::initialize( const Sequence< Any > & ) + throw ( Exception, RuntimeException ) +{ +} + +// XServiceInfo +::rtl::OUString SAL_CALL SdHtmlOptionsDialog::getImplementationName() + throw( RuntimeException ) +{ + return SdHtmlOptionsDialog_getImplementationName(); +} +sal_Bool SAL_CALL SdHtmlOptionsDialog::supportsService( const ::rtl::OUString& rServiceName ) + throw( RuntimeException ) +{ + return SdHtmlOptionsDialog_supportsService( rServiceName ); +} +Sequence< ::rtl::OUString > SAL_CALL SdHtmlOptionsDialog::getSupportedServiceNames() + throw ( RuntimeException ) +{ + return SdHtmlOptionsDialog_getSupportedServiceNames(); +} + + +// XPropertyAccess +Sequence< PropertyValue > SdHtmlOptionsDialog::getPropertyValues() + throw ( RuntimeException ) +{ + sal_Int32 i, nCount; + for ( i = 0, nCount = maMediaDescriptor.getLength(); i < nCount; i++ ) + { + if ( maMediaDescriptor[ i ].Name.equalsAscii( "FilterData" ) ) + break; + } + if ( i == nCount ) + maMediaDescriptor.realloc( ++nCount ); + + // the "FilterData" Property is an Any that will contain our PropertySequence of Values + maMediaDescriptor[ i ].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterData" ) ); + maMediaDescriptor[ i ].Value <<= maFilterDataSequence; + return maMediaDescriptor; +} + +void SdHtmlOptionsDialog::setPropertyValues( const Sequence< PropertyValue > & aProps ) + throw ( UnknownPropertyException, PropertyVetoException, + IllegalArgumentException, WrappedTargetException, + RuntimeException ) +{ + maMediaDescriptor = aProps; + + sal_Int32 i, nCount; + for ( i = 0, nCount = maMediaDescriptor.getLength(); i < nCount; i++ ) + { + if ( maMediaDescriptor[ i ].Name.equalsAscii( "FilterData" ) ) + { + maMediaDescriptor[ i ].Value >>= maFilterDataSequence; + break; + } + } +} + +// XExecutableDialog +void SdHtmlOptionsDialog::setTitle( const ::rtl::OUString& aTitle ) + throw ( RuntimeException ) +{ + aDialogTitle = aTitle; +} + +sal_Int16 SdHtmlOptionsDialog::execute() + throw ( RuntimeException ) +{ + sal_Int16 nRet = ExecutableDialogResults::CANCEL; + + SdAbstractDialogFactory* pFact = SdAbstractDialogFactory::Create(); + if( pFact ) + { + AbstractSdPublishingDlg* pDlg = pFact->CreateSdPublishingDlg( Application::GetDefDialogParent(), meDocType ); + if( pDlg ) + { + if( pDlg->Execute() ) + { + pDlg->GetParameterSequence( maFilterDataSequence ); + nRet = ExecutableDialogResults::OK; + } + else + { + nRet = ExecutableDialogResults::CANCEL; + } + delete pDlg; + } + } + return nRet; +} + +// XEmporter +void SdHtmlOptionsDialog::setSourceDocument( const Reference< XComponent >& xDoc ) + throw ( IllegalArgumentException, RuntimeException ) +{ + // try to set the corresponding metric unit + String aConfigPath; + Reference< XServiceInfo > xServiceInfo + ( xDoc, UNO_QUERY ); + if ( xServiceInfo.is() ) + { + if ( xServiceInfo->supportsService( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.PresentationDocument" ) ) ) ) + { + meDocType = DOCUMENT_TYPE_IMPRESS; + return; + } + else if ( xServiceInfo->supportsService( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.DrawingDocument" ) ) ) ) + { + meDocType = DOCUMENT_TYPE_DRAW; + return; + } + } + throw IllegalArgumentException(); +} diff --git a/sd/source/filter/html/buttonset.cxx b/sd/source/filter/html/buttonset.cxx new file mode 100644 index 000000000000..be6da8ddb74b --- /dev/null +++ b/sd/source/filter/html/buttonset.cxx @@ -0,0 +1,309 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" + +#include <com/sun/star/embed/ElementModes.hpp> +#include <com/sun/star/graphic/XGraphicProvider.hpp> + +#include <osl/file.hxx> +#include <comphelper/storagehelper.hxx> +#include <comphelper/oslfile2streamwrap.hxx> +#include <comphelper/processfactory.hxx> +#include <tools/debug.hxx> +#include <vcl/graph.hxx> +#include <vcl/virdev.hxx> +#include <vcl/image.hxx> +#include <unotools/pathoptions.hxx> + +#include <boost/shared_ptr.hpp> + +#include "buttonset.hxx" + +using ::rtl::OUString; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::graphic; +using namespace ::com::sun::star::embed; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; + +class ButtonsImpl +{ +public: + ButtonsImpl( const OUString& rURL ); + + Reference< XInputStream > getInputStream( const OUString& rName ); + + bool getGraphic( const Reference< XGraphicProvider >& xGraphicProvider, const OUString& rName, Graphic& rGraphic ); + + bool copyGraphic( const OUString& rName, const OUString& rPath ); + +private: + Reference< XStorage > mxStorage; +}; + +ButtonsImpl::ButtonsImpl( const OUString& rURL ) +{ + try + { + mxStorage = comphelper::OStorageHelper::GetStorageOfFormatFromURL( ZIP_STORAGE_FORMAT_STRING, rURL, ElementModes::READ ); + } + catch( Exception& ) + { + DBG_ERROR("sd::ButtonsImpl::ButtonsImpl(), exception caught!" ); + } +} + +Reference< XInputStream > ButtonsImpl::getInputStream( const OUString& rName ) +{ + Reference< XInputStream > xInputStream; + if( mxStorage.is() ) try + { + Reference< XStream > xStream( mxStorage->openStreamElement( rName, ElementModes::READ ) ); + if( xStream.is() ) + xInputStream = xStream->getInputStream(); + } + catch( Exception& ) + { + DBG_ERROR( "sd::ButtonsImpl::getInputStream(), exception caught!" ); + } + return xInputStream; +} + +bool ButtonsImpl::getGraphic( const Reference< XGraphicProvider >& xGraphicProvider, const rtl::OUString& rName, Graphic& rGraphic ) +{ + Reference< XInputStream > xInputStream( getInputStream( rName ) ); + if( xInputStream.is() && xGraphicProvider.is() ) try + { + Sequence< PropertyValue > aMediaProperties( 1 ); + aMediaProperties[0].Name = ::rtl::OUString::createFromAscii( "InputStream" ); + aMediaProperties[0].Value <<= xInputStream; + Reference< XGraphic > xGraphic( xGraphicProvider->queryGraphic( aMediaProperties ) ); + + if( xGraphic.is() ) + { + rGraphic = Graphic( xGraphic ); + return true; + } + } + catch( Exception& ) + { + DBG_ERROR( "sd::ButtonsImpl::getGraphic(), exception caught!" ); + } + return false; +} + +bool ButtonsImpl::copyGraphic( const OUString& rName, const OUString& rPath ) +{ + Reference< XInputStream > xInput( getInputStream( rName ) ); + if( xInput.is() ) try + { + osl::File::remove( rPath ); + osl::File aOutputFile( rPath ); + if( aOutputFile.open( OpenFlag_Write|OpenFlag_Create ) == osl::FileBase::E_None ) + { + Reference< XOutputStream > xOutput( new comphelper::OSLOutputStreamWrapper( aOutputFile ) ); + comphelper::OStorageHelper::CopyInputToOutput( xInput, xOutput ); + return true; + } + } + catch( Exception& ) + { + DBG_ERROR( "sd::ButtonsImpl::copyGraphic(), exception caught!" ); + } + + return false; +} + +typedef std::vector< boost::shared_ptr< ButtonsImpl > > ButtonVector; +class ButtonSetImpl +{ +public: + ButtonSetImpl(); + + int getCount() const; + + bool getPreview( int nSet, const std::vector< rtl::OUString >& rButtons, Image& rImage ); + bool exportButton( int nSet, const rtl::OUString& rPath, const rtl::OUString& rName ); + + void scanForButtonSets( const OUString& rPath ); + + Reference< XGraphicProvider > getGraphicProvider(); + + ButtonVector maButtons; + Reference< XGraphicProvider > mxGraphicProvider; +}; + +ButtonSetImpl::ButtonSetImpl() +{ + const OUString sSubPath( RTL_CONSTASCII_USTRINGPARAM( "/wizard/web/buttons" ) ); + + OUString sSharePath( SvtPathOptions().GetConfigPath() ); + sSharePath += sSubPath; + scanForButtonSets( sSharePath ); + + OUString sUserPath( SvtPathOptions().GetUserConfigPath() ); + sUserPath += sSubPath; + scanForButtonSets( sUserPath ); +} + +void ButtonSetImpl::scanForButtonSets( const OUString& rPath ) +{ + OUString aSystemPath; + osl::Directory aDirectory( rPath ); + if( aDirectory.open() == osl::FileBase::E_None ) + { + osl::DirectoryItem aItem; + while( aDirectory.getNextItem( aItem, 2211 ) == osl::FileBase::E_None ) + { + osl::FileStatus aStatus( FileStatusMask_FileName|FileStatusMask_FileURL ); + if( aItem.getFileStatus( aStatus ) == osl::FileBase::E_None ) + { + OUString sFileName( aStatus.getFileName() ); + if( sFileName.endsWithIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM(".zip" ) ) ) + maButtons.push_back( boost::shared_ptr< ButtonsImpl >( new ButtonsImpl( aStatus.getFileURL() ) ) ); + } + } + } +} + +int ButtonSetImpl::getCount() const +{ + return maButtons.size(); +} + +bool ButtonSetImpl::getPreview( int nSet, const std::vector< rtl::OUString >& rButtons, Image& rImage ) +{ + if( (nSet >= 0) && (nSet < static_cast<int>(maButtons.size()))) + { + ButtonsImpl& rSet = *maButtons[nSet].get(); + + std::vector< Graphic > aGraphics; + + VirtualDevice aDev; + aDev.SetMapMode(MapMode(MAP_PIXEL)); + + Size aSize; + std::vector< rtl::OUString >::const_iterator aIter( rButtons.begin() ); + while( aIter != rButtons.end() ) + { + Graphic aGraphic; + if( !rSet.getGraphic( getGraphicProvider(), (*aIter++), aGraphic ) ) + return false; + + aGraphics.push_back(aGraphic); + + Size aGraphicSize( aGraphic.GetSizePixel( &aDev ) ); + aSize.Width() += aGraphicSize.Width(); + + if( aSize.Height() < aGraphicSize.Height() ) + aSize.Height() = aGraphicSize.Height(); + + if( aIter != rButtons.end() ) + aSize.Width() += 3; + } + + aDev.SetOutputSizePixel( aSize ); + + Point aPos; + + std::vector< Graphic >::iterator aGraphIter( aGraphics.begin() ); + while( aGraphIter != aGraphics.end() ) + { + Graphic aGraphic( (*aGraphIter++) ); + + aGraphic.Draw( &aDev, aPos ); + + aPos.X() += aGraphic.GetSizePixel().Width() + 3; + } + + rImage = Image( aDev.GetBitmapEx( Point(), aSize ) ); + return true; + } + return false; +} + +bool ButtonSetImpl::exportButton( int nSet, const rtl::OUString& rPath, const rtl::OUString& rName ) +{ + if( (nSet >= 0) && (nSet < static_cast<int>(maButtons.size()))) + { + ButtonsImpl& rSet = *maButtons[nSet].get(); + + return rSet.copyGraphic( rName, rPath ); + } + return false; +} + +Reference< XGraphicProvider > ButtonSetImpl::getGraphicProvider() +{ + if( !mxGraphicProvider.is() ) + { + Reference< XMultiServiceFactory > xServiceManager( ::comphelper::getProcessServiceFactory() ); + if( xServiceManager.is() ) try + { + Reference< XGraphicProvider > xGraphProvider( + xServiceManager->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.graphic.GraphicProvider" ) ) ), UNO_QUERY_THROW ); + + mxGraphicProvider = xGraphProvider; + } + catch( Exception& ) + { + DBG_ERROR("sd::ButtonSetImpl::getGraphicProvider(), could not get graphic provider!"); + } + } + return mxGraphicProvider; +} + + +ButtonSet::ButtonSet() +: mpImpl( new ButtonSetImpl() ) +{ +} + +ButtonSet::~ButtonSet() +{ + delete mpImpl; +} + +int ButtonSet::getCount() const +{ + return mpImpl->getCount(); +} + +bool ButtonSet::getPreview( int nSet, const std::vector< rtl::OUString >& rButtons, Image& rImage ) +{ + return mpImpl->getPreview( nSet, rButtons, rImage ); +} + +bool ButtonSet::exportButton( int nSet, const rtl::OUString& rPath, const rtl::OUString& rName ) +{ + return mpImpl->exportButton( nSet, rPath, rName ); +} + diff --git a/sd/source/filter/html/buttonset.hxx b/sd/source/filter/html/buttonset.hxx new file mode 100644 index 000000000000..6027ad4dbf01 --- /dev/null +++ b/sd/source/filter/html/buttonset.hxx @@ -0,0 +1,53 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SD_HTMLEX_BUTTONSET_HXX +#define _SD_HTMLEX_BUTTONSET_HXX + +#include <rtl/ustring.hxx> +#include <boost/scoped_ptr.hpp> +#include <vector> + +class Image; +class ButtonSetImpl; + +class ButtonSet +{ +public: + ButtonSet(); + ~ButtonSet(); + + int getCount() const; + + bool getPreview( int nSet, const std::vector< rtl::OUString >& rButtons, Image& rImage ); + bool exportButton( int nSet, const rtl::OUString& rPath, const rtl::OUString& rName ); + +private: + ButtonSetImpl* mpImpl; +}; + +#endif // _SD_HTMLEX_BUTTONSET_HXX diff --git a/sd/source/filter/html/htmlattr.cxx b/sd/source/filter/html/htmlattr.cxx new file mode 100644 index 000000000000..5adcbd5fc56a --- /dev/null +++ b/sd/source/filter/html/htmlattr.cxx @@ -0,0 +1,114 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" + +#ifdef SD_DLLIMPLEMENTATION +#undef SD_DLLIMPLEMENTATION +#endif + +#include "htmlattr.hxx" +#include "htmlex.hxx" +#include <tools/link.hxx> +#include <vcl/decoview.hxx> + + +// ===================================================================== +// ===================================================================== +SdHtmlAttrPreview::SdHtmlAttrPreview( Window* pParent, const ResId& rResId ) +:Control( pParent, rResId ) +{ +// SetMapMode( MAP_100TH_MM ); +} + +// ===================================================================== +// ===================================================================== +SdHtmlAttrPreview::~SdHtmlAttrPreview() +{ +} + +// ===================================================================== +// ===================================================================== +void SdHtmlAttrPreview::Paint( const Rectangle& rRect ) +{ + DecorationView aDecoView( this ); + + Rectangle aTextRect; + aTextRect.SetSize(GetOutputSize()); + + SetLineColor(m_aBackColor); + SetFillColor(m_aBackColor); + DrawRect(rRect); + SetFillColor(); + + int nHeight = (aTextRect.nBottom - aTextRect.nTop) >> 2; + aTextRect.nBottom = nHeight + aTextRect.nTop; + + SetTextColor(m_aTextColor); + DrawText( aTextRect, String(SdResId(STR_HTMLATTR_TEXT)), + TEXT_DRAW_CENTER|TEXT_DRAW_VCENTER ); + + aTextRect.Move(0,nHeight); + SetTextColor(m_aLinkColor); + DrawText( aTextRect, String(SdResId(STR_HTMLATTR_LINK)), + TEXT_DRAW_CENTER|TEXT_DRAW_VCENTER ); + + aTextRect.Move(0,nHeight); + SetTextColor(m_aALinkColor); + DrawText( aTextRect, String(SdResId(STR_HTMLATTR_ALINK)), + TEXT_DRAW_CENTER|TEXT_DRAW_VCENTER ); + + aTextRect.Move(0,nHeight); + SetTextColor(m_aVLinkColor); + DrawText( aTextRect, String(SdResId(STR_HTMLATTR_VLINK)), + TEXT_DRAW_CENTER|TEXT_DRAW_VCENTER ); +} + +// ===================================================================== +// ===================================================================== +void SdHtmlAttrPreview::SetColors( Color& aBack, Color& aText, Color& aLink, + Color& aVLink, Color& aALink ) +{ + m_aBackColor = aBack; + m_aTextColor = aText; + m_aLinkColor = aLink; + m_aVLinkColor = aVLink; + m_aALinkColor = aALink; +} + +// ===================================================================== +// ===================================================================== +void SdHtmlAttrPreview::GetColors( Color& aBack, Color& aText, Color& aLink, + Color& aVLink, Color& aALink ) const +{ + aBack = m_aBackColor; + aText = m_aTextColor; + aLink = m_aLinkColor; + aVLink = m_aVLinkColor; + aALink = m_aALinkColor; +} diff --git a/sd/source/filter/html/htmlattr.hxx b/sd/source/filter/html/htmlattr.hxx new file mode 100644 index 000000000000..b076b2a29307 --- /dev/null +++ b/sd/source/filter/html/htmlattr.hxx @@ -0,0 +1,53 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SD_HTMLATTR_HXX +#define _SD_HTMLATTR_HXX + +#include <vcl/ctrl.hxx> +#include <tools/color.hxx> + +class SdHtmlAttrPreview : public Control +{ +protected: + + Color m_aBackColor, m_aTextColor, m_aLinkColor; + Color m_aVLinkColor, m_aALinkColor; + +public: + SdHtmlAttrPreview( Window* pParent, const ResId& rResId ); + ~SdHtmlAttrPreview(); + + virtual void Paint( const Rectangle& rRect ); + + void SetColors( Color& aBack, Color& aText, Color& aLink, + Color& aVLink, Color& aALink ); + void GetColors( Color& aBack, Color& aText, Color& aLink, + Color& aVLink, Color& aALink ) const; +}; + +#endif // _SD_HTMLATTR_HXX diff --git a/sd/source/filter/html/htmlex.cxx b/sd/source/filter/html/htmlex.cxx new file mode 100644 index 000000000000..82fabc73aed2 --- /dev/null +++ b/sd/source/filter/html/htmlex.cxx @@ -0,0 +1,3401 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" + +#include "htmlex.hxx" +#include <com/sun/star/document/XExporter.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/document/XFilter.hpp> + +#include <rtl/uri.hxx> +#include <comphelper/processfactory.hxx> +#include <osl/file.hxx> +#include <tools/fsys.hxx> +#include <unotools/pathoptions.hxx> +#include <svtools/FilterConfigItem.hxx> +#ifndef _UNOTOOLS_UCBSTREAMHELPER_HXX +#include <unotools/ucbstreamhelper.hxx> +#endif +#include <unotools/localfilehelper.hxx> +#include <com/sun/star/frame/XStorable.hpp> +#include <sfx2/progress.hxx> +#include <sfx2/progress.hxx> +#include <vcl/wrkwin.hxx> +#include <svl/aeitem.hxx> +#include <svx/svditer.hxx> +#include <svtools/imaprect.hxx> +#include <svtools/imapcirc.hxx> +#include <svtools/imappoly.hxx> +#include <vcl/msgbox.hxx> +#include <sfx2/app.hxx> +#include <editeng/outlobj.hxx> +#include <editeng/editobj.hxx> +#include <svx/svdopath.hxx> +#include <svx/xoutbmp.hxx> +#include <svtools/htmlout.hxx> +#include <sfx2/docfile.hxx> +#include <vcl/cvtgrf.hxx> +#include <svtools/colorcfg.hxx> +#include <svtools/filter.hxx> +#include <editeng/colritem.hxx> +#include <editeng/editeng.hxx> +#include <editeng/wghtitem.hxx> +#include <editeng/udlnitem.hxx> +#include <editeng/postitem.hxx> +#include <editeng/crsditem.hxx> +#include <editeng/flditem.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/fcontnr.hxx> +#include <svl/style.hxx> +#define _SVSTDARR_USHORTS +#include <svl/svstdarr.hxx> +#include <editeng/frmdiritem.hxx> +#include <svx/svdoutl.hxx> +#include <tools/urlobj.hxx> // INetURLObject +#include <vcl/bmpacc.hxx> +#include <svtools/sfxecode.hxx> +#include <com/sun/star/beans/PropertyState.hpp> +#include <tools/resmgr.hxx> +#include "comphelper/anytostring.hxx" +#include "cppuhelper/exc_hlp.hxx" + +#include "drawdoc.hxx" +#include "Outliner.hxx" +#include "sdpage.hxx" +#include "sdattr.hxx" +#include "glob.hrc" +#include "anminfo.hxx" +#include "imapinfo.hxx" +#include "sdresid.hxx" +#include "buttonset.hxx" +#include <basegfx/polygon/b2dpolygon.hxx> + +using ::rtl::OUString; +using ::rtl::OString; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::document; + +#define KEY_QUALITY "JPG-EXPORT-QUALITY" + +// Parameter aus Itemset abfragen + +#define RESTOHTML( res ) StringToHTMLString(String(SdResId(res))) +#define S2H( str ) StringToHTMLString( str ) + +// bei Aenderungen auch NUM_BUTTONS in pubdlg.hxx aendern!! +const char *pButtonNames[NUM_BUTTONS] = +{ + "first-inactive.png", + "first.png", + "left-inactive.png", + "left.png", + "right-inactive.png", + "right.png", + "last-inactive.png", + "last.png", + "home.png", + "text.png", + "expand.png", + "collapse.png", +}; + +#define BTN_FIRST_0 0 +#define BTN_FIRST_1 1 +#define BTN_PREV_0 2 +#define BTN_PREV_1 3 +#define BTN_NEXT_0 4 +#define BTN_NEXT_1 5 +#define BTN_LAST_0 6 +#define BTN_LAST_1 7 +#define BTN_INDEX 8 +#define BTN_TEXT 9 +#define BTN_MORE 10 +#define BTN_LESS 11 + +// Fuer Detectfilter +#define CALC_OPTIONS "9,34,SYSTEM" + +// ********************************************************************* +// Hilfsklasse fuer das simple erzeugen von Dateien lokal/remote +// ********************************************************************* +class EasyFile +{ +private: + SvStream* pOStm; + SfxMedium* pMedium; + bool bOpen; + +public: + + EasyFile(); + ~EasyFile(); + + ULONG createStream( const String& rUrl, SvStream*& rpStr ); + ULONG createFileName( const String& rUrl, String& rFileName ); + ULONG close(); +}; + +// ********************************************************************* +// Hilfsklasse fuer das einbinden von Textattributen in die Html-Ausgabe +// ********************************************************************* +class HtmlState +{ +private: + bool mbColor; + bool mbWeight; + bool mbItalic; + bool mbUnderline; + bool mbStrike; + bool mbLink; + Color maColor; + Color maDefColor; + String maLink; + String maTarget; + +public: + HtmlState( Color aDefColor ); + + String SetWeight( bool bWeight ); + String SetItalic( bool bItalic ); + String SetUnderline( bool bUnderline ); + String SetColor( Color aColor ); + String SetStrikeout( bool bStrike ); + String SetLink( const String& aLink, const String& aTarget ); + String Flush(); +}; + +// ===================================================================== +// alle noch offennen Tags schliessen +// ===================================================================== +String HtmlState::Flush() +{ + String aStr, aEmpty; + + aStr += SetWeight(false); + aStr += SetItalic(false); + aStr += SetUnderline(false); + aStr += SetStrikeout(false); + aStr += SetColor(maDefColor); + aStr += SetLink(aEmpty,aEmpty); + + return aStr; +} + +// ===================================================================== +// c'tor mit Defaultfarbe fuer die Seite +// ===================================================================== +HtmlState::HtmlState( Color aDefColor ) +{ + mbColor = false; + mbWeight = false; + mbItalic = false; + mbUnderline = false; + mbLink = false; + mbStrike = false; + maDefColor = aDefColor; +} + +// ===================================================================== +// aktiviert/deaktiviert Fettdruck +// ===================================================================== +String HtmlState::SetWeight( bool bWeight ) +{ + String aStr; + + if(bWeight && !mbWeight) + aStr.AppendAscii( "<b>" ); + else if(!bWeight && mbWeight) + aStr.AppendAscii( "</b>" ); + + mbWeight = bWeight; + return aStr; +} + +// ===================================================================== +// aktiviert/deaktiviert Italic +// ===================================================================== +String HtmlState::SetItalic( bool bItalic ) +{ + String aStr; + + if(bItalic && !mbItalic) + aStr.AppendAscii( "<i>" ); + else if(!bItalic && mbItalic) + aStr.AppendAscii( "</i>" ); + + mbItalic = bItalic; + return aStr; +} + +// ===================================================================== +// aktiviert/deaktiviert Unterstrichen +// ===================================================================== +String HtmlState::SetUnderline( bool bUnderline ) +{ + String aStr; + + if(bUnderline && !mbUnderline) + aStr.AppendAscii( "<u>" ); + else if(!bUnderline && mbUnderline) + aStr.AppendAscii( "</u>" ); + + mbUnderline = bUnderline; + return aStr; +} + +// ===================================================================== +// aktiviert/deaktiviert Durchstreichen +// ===================================================================== +String HtmlState::SetStrikeout( bool bStrike ) +{ + String aStr; + + if(bStrike && !mbStrike) + aStr.AppendAscii( "<strike>" ); + else if(!bStrike && mbStrike) + aStr.AppendAscii( "</strike>" ); + + mbStrike = bStrike; + return aStr; +} + +// ===================================================================== +// Setzt die angegebenne Textfarbe +// ===================================================================== +String HtmlState::SetColor( Color aColor ) +{ + String aStr; + + if(mbColor && aColor == maColor) + return aStr; + + if(mbColor) + { + aStr.AppendAscii( "</font>" ); + mbColor = false; + } + + if(aColor != maDefColor) + { + maColor = aColor; + + aStr.AppendAscii( "<font color=\"" ); + aStr += HtmlExport::ColorToHTMLString(aColor); + aStr.AppendAscii( "\">" ); + + mbColor = true; + } + + return aStr; +} + +// ===================================================================== +// aktiviert/deaktiviert einen Hyperlink +// ===================================================================== +String HtmlState::SetLink( const String& aLink, const String& aTarget ) +{ + String aStr; + + if(mbLink&&maLink == aLink&&maTarget==aTarget) + return aStr; + + if(mbLink) + { + aStr.AppendAscii( "</a>" ); + mbLink = false; + } + + if(aLink.Len()) + { + aStr.AppendAscii( "<a href=\"" ); + aStr += HtmlExport::StringToURL(aLink); + if(aTarget.Len()) + { + aStr.AppendAscii( "\" target=\"" ); + aStr += aTarget; + } + aStr.AppendAscii( "\">" ); + mbLink = true; + maLink = aLink; + maTarget = aTarget; + } + + return aStr; +} + +// ********************************************************************* +// class HtmlExport Methoden +// ********************************************************************* + +static String getParagraphStyle( SdrOutliner* pOutliner, USHORT nPara ) +{ + SfxItemSet aParaSet( pOutliner->GetParaAttribs( nPara ) ); + + String sStyle( RTL_CONSTASCII_USTRINGPARAM("direction:") ); + if( static_cast<const SvxFrameDirectionItem*>(aParaSet.GetItem( EE_PARA_WRITINGDIR ))->GetValue() == FRMDIR_HORI_RIGHT_TOP ) + { + sStyle += String( RTL_CONSTASCII_USTRINGPARAM("rtl;") ); + } + else + { + sStyle += String( RTL_CONSTASCII_USTRINGPARAM("ltr;") ); + } + return sStyle; +} + +// ===================================================================== +// Konstruktor fuer die Html Export Hilfsklasse +// ===================================================================== +HtmlExport::HtmlExport( + OUString aPath, + const Sequence< PropertyValue >& rParams, + SdDrawDocument* pExpDoc, + ::sd::DrawDocShell* pDocShell ) + : maPath( aPath ), + mpDoc(pExpDoc), + mpDocSh( pDocShell ), + meEC(NULL), + meMode( PUBLISH_HTML ), + mbContentsPage(false), + mnButtonThema(-1), + mnWidthPixel( PUB_LOWRES_WIDTH ), + meFormat( FORMAT_JPG ), + mbNotes(false), + mnCompression( -1 ), + mbDownload( false ), + mbSlideSound(true), + mbHiddenSlides(true), + mbUserAttr(false), + mbDocColors(false), + maHTMLExtension(SdResId(STR_HTMLEXP_DEFAULT_EXTENSION)), + mpHTMLFiles(NULL), + mpImageFiles(NULL), + mpPageNames(NULL), + mpTextFiles(NULL), + maIndexUrl(RTL_CONSTASCII_USTRINGPARAM("index")), + meScript( SCRIPT_ASP ), + maHTMLHeader( RTL_CONSTASCII_USTRINGPARAM( + "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n" + " \"http://www.w3.org/TR/html4/transitional.dtd\">\r\n" + "<html>\r\n<head>\r\n" ) ), + mpButtonSet( new ButtonSet() ) +{ + bool bChange = mpDoc->IsChanged(); + + maIndexUrl += maHTMLExtension; + + InitExportParameters( rParams ); + + switch( meMode ) + { + case PUBLISH_HTML: + case PUBLISH_FRAMES: + ExportHtml(); + break; + case PUBLISH_WEBCAST: + ExportWebCast(); + break; + case PUBLISH_KIOSK: + ExportKiosk(); + break; + } + + mpDoc->SetChanged(bChange); +} + +HtmlExport::~HtmlExport() +{ + // ------------------------------------------------------------------ + // Listen loeschen + // ------------------------------------------------------------------ + if(mpImageFiles && mpHTMLFiles && mpPageNames && mpTextFiles) + { + for ( USHORT nSdPage = 0; nSdPage < mnSdPageCount; nSdPage++) + { + delete mpImageFiles[nSdPage]; + delete mpHTMLFiles[nSdPage]; + delete mpPageNames[nSdPage]; + delete mpTextFiles[nSdPage]; + } + } + + delete[] mpImageFiles; + delete[] mpHTMLFiles; + delete[] mpPageNames; + delete[] mpTextFiles; +} + +/** get common export parameters from item set */ +void HtmlExport::InitExportParameters( const Sequence< PropertyValue >& rParams ) +{ + mbImpress = mpDoc && mpDoc->GetDocumentType() == DOCUMENT_TYPE_IMPRESS; + + sal_Int32 nArgs = rParams.getLength(); + const PropertyValue* pParams = rParams.getConstArray(); + OUString aStr; + while( nArgs-- ) + { + if( pParams->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "PublishMode" ) ) ) + { + sal_Int32 temp = 0; + pParams->Value >>= temp; + meMode = (HtmlPublishMode)temp; + } + else if( pParams->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IndexURL" ) ) ) + { + pParams->Value >>= aStr; + maIndexUrl = aStr; + } + else if( pParams->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Format" ) ) ) + { + sal_Int32 temp = 0; + pParams->Value >>= temp; + meFormat = (PublishingFormat)temp; + } + else if( pParams->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Compression" ) ) ) + { + pParams->Value >>= aStr; + String aTmp( aStr ); + if(aTmp.Len()) + { + xub_StrLen nPos = aTmp.Search( '%' ); + if(nPos != STRING_NOTFOUND) + aTmp.Erase(nPos,1); + mnCompression = (INT16)aTmp.ToInt32(); + } + } + else if( pParams->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Width" ) ) ) + { + sal_Int32 temp = 0; + pParams->Value >>= temp; + mnWidthPixel = (sal_uInt16)temp; + } + else if( pParams->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "UseButtonSet" ) ) ) + { + sal_Int32 temp = 0; + pParams->Value >>= temp; + mnButtonThema = (sal_Int16)temp; + } + else if( pParams->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsExportNotes" ) ) ) + { + if( mbImpress ) + { + sal_Bool temp = sal_False; + pParams->Value >>= temp; + mbNotes = temp; + } + } + else if( pParams->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsExportContentsPage" ) ) ) + { + sal_Bool temp = sal_False; + pParams->Value >>= temp; + mbContentsPage = temp; + } + else if( pParams->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Author" ) ) ) + { + pParams->Value >>= aStr; + maAuthor = aStr; + } + else if( pParams->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "EMail" ) ) ) + { + pParams->Value >>= aStr; + maEMail = aStr; + } + else if( pParams->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "HomepageURL" ) ) ) + { + pParams->Value >>= aStr; + maHomePage = aStr; + } + else if( pParams->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "UserText" ) ) ) + { + pParams->Value >>= aStr; + maInfo = aStr; + } + else if( pParams->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "EnableDownload" ) ) ) + { + sal_Bool temp = sal_False; + pParams->Value >>= temp; + mbDownload = temp; + } + else if( pParams->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "SlideSound" ) ) ) + { + sal_Bool temp = sal_True; + pParams->Value >>= temp; + mbSlideSound = temp; + } + else if( pParams->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "HiddenSlides" ) ) ) + { + sal_Bool temp = sal_True; + pParams->Value >>= temp; + mbHiddenSlides = temp; + } + else if( pParams->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "BackColor" ) ) ) + { + sal_Int32 temp = 0; + pParams->Value >>= temp; + maBackColor = temp; + mbUserAttr = true; + } + else if( pParams->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "TextColor" ) ) ) + { + sal_Int32 temp = 0; + pParams->Value >>= temp; + maTextColor = temp; + mbUserAttr = true; + } + else if( pParams->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "LinkColor" ) ) ) + { + sal_Int32 temp = 0; + pParams->Value >>= temp; + maLinkColor = temp; + mbUserAttr = true; + } + else if( pParams->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "VLinkColor" ) ) ) + { + sal_Int32 temp = 0; + pParams->Value >>= temp; + maVLinkColor = temp; + mbUserAttr = true; + } + else if( pParams->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ALinkColor" ) ) ) + { + sal_Int32 temp = 0; + pParams->Value >>= temp; + maALinkColor = temp; + mbUserAttr = true; + } + else if( pParams->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsUseDocumentColors" ) ) ) + { + sal_Bool temp = sal_False; + pParams->Value >>= temp; + mbDocColors = temp; + } + else if( pParams->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "KioskSlideDuration" ) ) ) + { + sal_Int32 temp = sal_False; + pParams->Value >>= temp; + mnSlideDuration = temp; + mbAutoSlide = true; + } + else if( pParams->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "KioskEndless" ) ) ) + { + sal_Bool temp = sal_False; + pParams->Value >>= temp; + mbEndless = temp; + } + else if( pParams->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "WebCastCGIURL" ) ) ) + { + pParams->Value >>= aStr; + maCGIPath = aStr; + } + else if( pParams->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "WebCastTargetURL" ) ) ) + { + pParams->Value >>= aStr; + maURLPath = aStr; + } + else if( pParams->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "WebCastScriptLanguage" ) ) ) + { + pParams->Value >>= aStr; + if( aStr.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM( "asp" ) ) ) + { + meScript = SCRIPT_ASP; + } + else + { + meScript = SCRIPT_PERL; + } + } + else + { + DBG_ERROR("Unknown property for html export detected!"); + } + + pParams++; + } + + if( meMode == PUBLISH_KIOSK ) + { + mbContentsPage = false; + mbNotes = false; + + } + + // calculate image sizes + SdPage* pPage = mpDoc->GetSdPage(0, PK_STANDARD); + Size aTmpSize( pPage->GetSize() ); + double dRatio=((double)aTmpSize.Width())/aTmpSize.Height(); + +/* + switch( mnWidthPixel ) + { + case 800: + mnWidthPixel = 640; + break; + case 1024: + mnWidthPixel = 800; + break; + case 640: + default: + mnWidthPixel = 512; + break; + } +*/ + mnHeightPixel = (USHORT)(mnWidthPixel/dRatio); + + //------------------------------------------------------------------ + // Ziel ausklamuestern... + + INetURLObject aINetURLObj( maPath ); + DBG_ASSERT( aINetURLObj.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" ); + + maExportPath = aINetURLObj.GetPartBeforeLastName(); // with trailing '/' + maIndex = aINetURLObj.GetLastName(); + + mnSdPageCount = mpDoc->GetSdPageCount( PK_STANDARD ); +// USHORT nHiddenSlides = 0; + for( USHORT nPage = 0; nPage < mnSdPageCount; nPage++ ) + { + pPage = mpDoc->GetSdPage( nPage, PK_STANDARD ); + + if( mbHiddenSlides || !pPage->IsExcluded() ) + { + maPages.push_back( pPage ); + maNotesPages.push_back( mpDoc->GetSdPage( nPage, PK_NOTES ) ); + } + } + mnSdPageCount = maPages.size(); + + mbFrames = meMode == PUBLISH_FRAMES; + + maDocFileName = maIndex; +} + +/////////////////////////////////////////////////////////////////////// +// Exportiert das im Konstruktor angegebenne Impress Dokument nach HTML +/////////////////////////////////////////////////////////////////////// +void HtmlExport::ExportHtml() +{ + if(mbUserAttr) + { + if( maTextColor == COL_AUTO ) + { + if( !maBackColor.IsDark() ) + maTextColor = COL_BLACK; + } + } + else if( mbDocColors ) + { + // Standard Farben fuer das Farbschema 'Aus Dokument' + SetDocColors(); + maFirstPageColor = maBackColor; + } + + // get name for downloadable presentation if needed + if( mbDownload ) + { + // Separator such und Extension ausblenden + USHORT nSepPos = maDocFileName.Search( sal_Unicode('.') ); + + if(nSepPos != STRING_NOTFOUND) + maDocFileName.Erase(nSepPos); + + maDocFileName.AppendAscii( ".odp" ); + } + + ////// + + USHORT nProgrCount = mnSdPageCount; + nProgrCount += mbImpress?mnSdPageCount:0; + nProgrCount += mbContentsPage?1:0; + nProgrCount += (mbFrames && mbNotes)?mnSdPageCount:0; + nProgrCount += (mbFrames)?8:0; + InitProgress( nProgrCount ); + + mpDocSh->SetWaitCursor( true ); + + //------------------------------------------------------------------ + // Exceptions sind doch was schoennes... + + CreateFileNames(); + + // this is not a true while + while( 1 ) + { + if( checkForExistingFiles() ) + break; + + if( !CreateImagesForPresPages() ) + break; + + if( !CreateHtmlForPresPages() ) + break; + + if( mbImpress ) + if( !CreateHtmlTextForPresPages() ) + break; + + if( mbFrames ) + { + if( !CreateFrames() ) + break; + + if( !CreateOutlinePages() ) + break; + + if( !CreateNavBarFrames() ) + break; + + if( mbNotes && mbImpress ) + if( !CreateNotesPages() ) + break; + + } + + if( mbContentsPage ) + if( !CreateContentPage() ) + break; + + if( !CreateBitmaps() ) + break; + + mpDocSh->SetWaitCursor( false ); + ResetProgress(); + + if( mbDownload ) + SavePresentation(); + + return; + } + + // if we get to this point the export was + // canceled by the user after an error + mpDocSh->SetWaitCursor( false ); + ResetProgress(); +} + +/////////////////////////////////////////////////////////////////////// + +void HtmlExport::SetDocColors( SdPage* pPage ) +{ + if( pPage == NULL ) + pPage = mpDoc->GetSdPage(0, PK_STANDARD); + + svtools::ColorConfig aConfig; + maVLinkColor = Color(aConfig.GetColorValue(svtools::LINKSVISITED).nColor); + maALinkColor = Color(aConfig.GetColorValue(svtools::LINKS).nColor); + maLinkColor = Color(aConfig.GetColorValue(svtools::LINKS).nColor); + maTextColor = Color(COL_BLACK); + + SfxStyleSheet* pSheet = NULL; + + if( mpDoc->GetDocumentType() == DOCUMENT_TYPE_IMPRESS ) + { + // Standard Textfarbe aus Outline-Vorlage der ersten Seite + pSheet = pPage->GetStyleSheetForPresObj(PRESOBJ_OUTLINE); + if(pSheet == NULL) + pSheet = pPage->GetStyleSheetForPresObj(PRESOBJ_TEXT); + if(pSheet == NULL) + pSheet = pPage->GetStyleSheetForPresObj(PRESOBJ_TITLE); + } + + if(pSheet == NULL) + pSheet = mpDoc->GetDefaultStyleSheet(); + + if(pSheet) + { + SfxItemSet& rSet = pSheet->GetItemSet(); + if(rSet.GetItemState(EE_CHAR_COLOR,TRUE) == SFX_ITEM_ON) + maTextColor = ((SvxColorItem*)rSet.GetItem(EE_CHAR_COLOR,TRUE))->GetValue(); + } + + // Standard Hintergrundfarbe aus Background der MasterPage der ersten Seite + maBackColor = pPage->GetPageBackgroundColor(); + + if( maTextColor == COL_AUTO ) + { + if( !maBackColor.IsDark() ) + maTextColor = COL_BLACK; + } +} + +/////////////////////////////////////////////////////////////////////// + +void HtmlExport::InitProgress( USHORT nProgrCount ) +{ + String aStr(SdResId(STR_CREATE_PAGES)); + mpProgress = new SfxProgress( mpDocSh, aStr, nProgrCount ); +} + +/////////////////////////////////////////////////////////////////////// + +void HtmlExport::ResetProgress() +{ + delete mpProgress; + mpProgress = NULL; +} + +/////////////////////////////////////////////////////////////////////// + +void HtmlExport::ExportKiosk() +{ + mnPagesWritten = 0; + InitProgress( 2*mnSdPageCount ); + + CreateFileNames(); + if( !checkForExistingFiles() ) + { + if( CreateImagesForPresPages() ) + CreateHtmlForPresPages(); + } + + ResetProgress(); +} + +/////////////////////////////////////////////////////////////////////// +// Export Document with WebCast (TM) Technology +/////////////////////////////////////////////////////////////////////// +void HtmlExport::ExportWebCast() +{ + mnPagesWritten = 0; + InitProgress( mnSdPageCount + 9 ); + + mpDocSh->SetWaitCursor( TRUE ); + + CreateFileNames(); + + String aEmpty; + if(maCGIPath.Len() == 0) + maCGIPath.Assign( sal_Unicode('.') ); + + if( maCGIPath.GetChar( maCGIPath.Len() - 1 ) != sal_Unicode('/') ) + maCGIPath.Append( sal_Unicode('/') ); + + if( meScript == SCRIPT_ASP ) + { + maURLPath.AssignAscii( "./" ); + } + else + { + String aEmpty2; + if(maURLPath.Len() == 0) + maURLPath.Assign( sal_Unicode('.') ); + + if( maURLPath.GetChar( maURLPath.Len() - 1 ) != sal_Unicode('/') ) + maURLPath.Append( sal_Unicode('/') ); + } + + // this is not a true while + while(1) + { + if( checkForExistingFiles() ) + break; + + if(!CreateImagesForPresPages()) + break; + + if( meScript == SCRIPT_ASP ) + { + if(!CreateASPScripts()) + break; + } + else + { + if(!CreatePERLScripts()) + break; + } + + if(!CreateImageFileList()) + break; + + if(!CreateImageNumberFile()) + break; + + break; + } + + mpDocSh->SetWaitCursor( false ); + ResetProgress(); +} + +/////////////////////////////////////////////////////////////////////// +// Save the presentation as a downloadable file in the dest directory +/////////////////////////////////////////////////////////////////////// + +bool HtmlExport::SavePresentation() +{ + meEC.SetContext( STR_HTMLEXP_ERROR_CREATE_FILE, maDocFileName ); + + OUString aURL( maExportPath ); + aURL += maDocFileName; + + + mpDocSh->EnableSetModified( true ); + + try + { + uno::Reference< frame::XStorable > xStorable( mpDoc->getUnoModel(), uno::UNO_QUERY ); + if( xStorable.is() ) + { + uno::Sequence< beans::PropertyValue > aProperties( 2 ); + aProperties[ 0 ].Name = OUString(RTL_CONSTASCII_USTRINGPARAM("Overwrite")); + aProperties[ 0 ].Value <<= (sal_Bool)sal_True; + aProperties[ 1 ].Name = OUString(RTL_CONSTASCII_USTRINGPARAM("FilterName")); + aProperties[ 1 ].Value <<= OUString(RTL_CONSTASCII_USTRINGPARAM("impress8")); + xStorable->storeToURL( aURL, aProperties ); + + mpDocSh->EnableSetModified( false ); + + return true; + } + } + catch( Exception& ) + { + } + + mpDocSh->EnableSetModified( false ); + + return false; +} + +// ===================================================================== +// Image-Dateien anlegen +// ===================================================================== +bool HtmlExport::CreateImagesForPresPages() +{ + try + { + Reference < XMultiServiceFactory > xMSF( ::comphelper::getProcessServiceFactory() ); + if( !xMSF.is() ) + return false; + + Reference< XExporter > xGraphicExporter( xMSF->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.GraphicExportFilter") ) ), UNO_QUERY ); + Reference< XFilter > xFilter( xGraphicExporter, UNO_QUERY ); + + DBG_ASSERT( xFilter.is(), "no com.sun.star.drawing.GraphicExportFilter?" ); + if( !xFilter.is() ) + return false; + + Sequence< PropertyValue > aFilterData(((meFormat==FORMAT_JPG)&&(mnCompression != -1))? 3 : 2); + aFilterData[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM("PixelWidth") ); + aFilterData[0].Value <<= (sal_Int32)mnWidthPixel; + aFilterData[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM("PixelHeight") ); + aFilterData[1].Value <<= (sal_Int32)mnHeightPixel; + if((meFormat==FORMAT_JPG)&&(mnCompression != -1)) + { + aFilterData[2].Name = OUString( RTL_CONSTASCII_USTRINGPARAM("Quality") ); + aFilterData[2].Value <<= (sal_Int32)mnCompression; + } + + Sequence< PropertyValue > aDescriptor( 3 ); + aDescriptor[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM("URL") ); + aDescriptor[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM("FilterName") ); + OUString sFormat; + if( meFormat == FORMAT_PNG ) + sFormat = OUString( RTL_CONSTASCII_USTRINGPARAM("PNG") ); + else if( meFormat == FORMAT_GIF ) + sFormat = OUString( RTL_CONSTASCII_USTRINGPARAM("GIF") ); + else + sFormat = OUString( RTL_CONSTASCII_USTRINGPARAM("JPG") ); + + aDescriptor[1].Value <<= sFormat; + aDescriptor[2].Name = OUString( RTL_CONSTASCII_USTRINGPARAM("FilterData") ); + aDescriptor[2].Value <<= aFilterData; + + for (USHORT nSdPage = 0; nSdPage < mnSdPageCount; nSdPage++) + { + SdPage* pPage = maPages[ nSdPage ]; + + OUString aFull(maExportPath); + aFull += *mpImageFiles[nSdPage]; + + aDescriptor[0].Value <<= aFull; + + Reference< XComponent > xPage( pPage->getUnoPage(), UNO_QUERY ); + xGraphicExporter->setSourceDocument( xPage ); + xFilter->filter( aDescriptor ); + + if (mpProgress) + mpProgress->SetState(++mnPagesWritten); + } + } + catch( Exception& ) + { + return false; + } + + return true; +} + +// ===================================================================== +// Ermittelt das SdrTextObject mit dem Layout Text dieser Seite +// ===================================================================== +SdrTextObj* HtmlExport::GetLayoutTextObject(SdrPage* pPage) +{ + ULONG nObjectCount = pPage->GetObjCount(); + SdrObject* pObject = NULL; + SdrTextObj* pResult = NULL; + + for (ULONG nObject = 0; nObject < nObjectCount; nObject++) + { + pObject = pPage->GetObj(nObject); + if (pObject->GetObjInventor() == SdrInventor && + pObject->GetObjIdentifier() == OBJ_OUTLINETEXT) + { + pResult = (SdrTextObj*)pObject; + break; + } + } + return pResult; +} + +// ===================================================================== +// HTML-Text Versionen fuer Impress Seiten erzeugen +// ===================================================================== + +String HtmlExport::WriteMetaCharset() const +{ + String aStr; + const sal_Char *pCharSet = rtl_getBestMimeCharsetFromTextEncoding( RTL_TEXTENCODING_UTF8 ); + if ( pCharSet ) + { + aStr.AppendAscii( " <meta HTTP-EQUIV=CONTENT-TYPE CONTENT=\"text/html; charset=" ); + aStr.AppendAscii( pCharSet ); + aStr.AppendAscii( "\">\r\n" ); + } + return aStr; +} + +bool HtmlExport::CreateHtmlTextForPresPages() +{ + bool bOk = true; + + SdrOutliner* pOutliner = mpDoc->GetInternalOutliner(); + + for(USHORT nSdPage = 0; nSdPage < mnSdPageCount && bOk; nSdPage++) + { + SdPage* pPage = maPages[ nSdPage ]; + + if( mbDocColors ) + { + SetDocColors( pPage ); +// maBackColor = pPage->GetPageBackgroundColor(); + } + +// HTML Kopf + String aStr(maHTMLHeader); + aStr += WriteMetaCharset(); + aStr.AppendAscii( " <title>" ); + aStr += StringToHTMLString( *mpPageNames[nSdPage] ); + aStr.AppendAscii( "</title>\r\n" ); + aStr.AppendAscii( "</head>\r\n" ); + aStr += CreateBodyTag(); + +// Navigationsleiste + aStr += CreateNavBar(nSdPage, true); + +// Seitentitel + String sTitleText( CreateTextForTitle(pOutliner,pPage, pPage->GetPageBackgroundColor()) ); + aStr.AppendAscii( "<h1 style=\""); + aStr.Append( getParagraphStyle( pOutliner, 0 ) ); + aStr.AppendAscii( "\">" ); + aStr += sTitleText; + aStr.AppendAscii( "</h1>\r\n" ); + +// Gliederungstext schreiben + aStr += CreateTextForPage( pOutliner, pPage, true, pPage->GetPageBackgroundColor() ); + +// Notizen + if(mbNotes) + { + SdPage* pNotesPage = maNotesPages[ nSdPage ]; + String aNotesStr( CreateTextForNotesPage( pOutliner, pNotesPage, true, maBackColor) ); + + if( aNotesStr.Len() ) + { + aStr.AppendAscii( "<br>\r\n<h3>" ); + aStr += RESTOHTML(STR_HTMLEXP_NOTES); + aStr.AppendAscii( ":</h3>\r\n" ); + + aStr += aNotesStr; + } + } + +// Seite beenden + aStr.AppendAscii( "</body>\r\n</html>" ); + + bOk = WriteHtml( *mpTextFiles[nSdPage], false, aStr ); + + if (mpProgress) + mpProgress->SetState(++mnPagesWritten); + + } + + pOutliner->Clear(); + + return bOk; +} + +/** exports the given html data into a non unicode file in the current export path with + the given filename */ +bool HtmlExport::WriteHtml( const String& rFileName, bool bAddExtension, const String& rHtmlData ) +{ + ULONG nErr = 0; + + String aFileName( rFileName ); + if( bAddExtension ) + aFileName += maHTMLExtension; + + meEC.SetContext( STR_HTMLEXP_ERROR_CREATE_FILE, rFileName ); + EasyFile aFile; + SvStream* pStr; + String aFull( maExportPath ); + aFull += aFileName; + nErr = aFile.createStream(aFull , pStr); + if(nErr == 0) + { + ByteString aStr( rHtmlData , RTL_TEXTENCODING_UTF8 ) ; + *pStr << aStr.GetBuffer(); + nErr = aFile.close(); + } + + if( nErr != 0 ) + ErrorHandler::HandleError(nErr); + + return nErr == 0; +} + +// ===================================================================== + +/** Erzeugt den Outliner Text fuer das Titelobjekt einer Seite + */ +String HtmlExport::CreateTextForTitle( SdrOutliner* pOutliner, SdPage* pPage, const Color& rBackgroundColor ) +{ + SdrTextObj* pTO = (SdrTextObj*)pPage->GetPresObj(PRESOBJ_TITLE); + if(!pTO) + pTO = GetLayoutTextObject(pPage); + + if (pTO && !pTO->IsEmptyPresObj()) + { + OutlinerParaObject* pOPO = pTO->GetOutlinerParaObject(); + if(pOPO && pOutliner->GetParagraphCount() != 0) + { + pOutliner->Clear(); + pOutliner->SetText(*pOPO); + return ParagraphToHTMLString(pOutliner,0, rBackgroundColor); + } + } + + return String(); +} + +// ===================================================================== +// Erzeugt den Outliner Text fuer eine Seite +// ===================================================================== +String HtmlExport::CreateTextForPage( SdrOutliner* pOutliner, + SdPage* pPage, + bool bHeadLine, const Color& rBackgroundColor ) +{ + String aStr; + + SdrTextObj* pTO = (SdrTextObj*)pPage->GetPresObj(PRESOBJ_TEXT); + if(!pTO) + pTO = GetLayoutTextObject(pPage); + + if (pTO && !pTO->IsEmptyPresObj()) + { + OutlinerParaObject* pOPO = pTO->GetOutlinerParaObject(); + if (pOPO) + { + pOutliner->Clear(); + pOutliner->SetText( *pOPO ); + + ULONG nCount = pOutliner->GetParagraphCount(); + + Paragraph* pPara = NULL; + sal_Int16 nActDepth = -1; + + String aParaText; + for (ULONG nPara = 0; nPara < nCount; nPara++) + { + pPara = pOutliner->GetParagraph(nPara); + if(pPara == 0) + continue; + + const sal_Int16 nDepth = (USHORT) pOutliner->GetDepth( (USHORT) nPara ); + aParaText = ParagraphToHTMLString(pOutliner,nPara,rBackgroundColor); + + if(aParaText.Len() == 0) + continue; + + if(nDepth < nActDepth ) + { + do + { + aStr.AppendAscii( "</ul>" ); + nActDepth--; + } + while(nDepth < nActDepth); + } + else if(nDepth > nActDepth ) + { + do + { + aStr.AppendAscii( "<ul>" ); + nActDepth++; + } + while( nDepth > nActDepth ); + } + + String sStyle( getParagraphStyle( pOutliner, nPara ) ); + if(nActDepth >= 0 ) + { + aStr.AppendAscii( "<li style=\""); + aStr.Append( sStyle ); + aStr.AppendAscii( "\">" ); + } + + if(nActDepth <= 0 && bHeadLine) + { + if( nActDepth == 0 ) + { + aStr.AppendAscii( "<h2>" ); + } + else + { + aStr.AppendAscii( "<h2 style=\""); + aStr.Append( sStyle ); + aStr.AppendAscii( "\">" ); + } + } + aStr += aParaText; + if(nActDepth == 0 && bHeadLine) + aStr.AppendAscii( "</h2>" ); + if(nActDepth >= 0 ) + aStr.AppendAscii( "</li>" ); + aStr.AppendAscii( "\r\n" ); + } + + while( nActDepth >= 0 ) + { + aStr.AppendAscii( "</ul>" ); + nActDepth--; + }; + } + } + + return aStr; +} + +// ===================================================================== +// Erzeugt den Outliner Text fuer eine Notizseite +// ===================================================================== +String HtmlExport::CreateTextForNotesPage( SdrOutliner* pOutliner, + SdPage* pPage, + bool, + const Color& rBackgroundColor ) +{ + String aStr; + + SdrTextObj* pTO = (SdrTextObj*)pPage->GetPresObj(PRESOBJ_NOTES); + + if (pTO && !pTO->IsEmptyPresObj()) + { + OutlinerParaObject* pOPO = pTO->GetOutlinerParaObject(); + if (pOPO) + { + pOutliner->Clear(); + pOutliner->SetText( *pOPO ); + + ULONG nCount = pOutliner->GetParagraphCount(); + for (ULONG nPara = 0; nPara < nCount; nPara++) + { + aStr.AppendAscii("<p style=\""); + aStr.Append( getParagraphStyle( pOutliner, nPara ) ); + aStr.AppendAscii("\">"); + aStr += ParagraphToHTMLString( pOutliner, nPara,rBackgroundColor ); + aStr.AppendAscii( "</p>\r\n" ); + } + } + } + + return aStr; +} + +// ===================================================================== +// Wandelt einen Paragraphen des Outliners in Html +// ===================================================================== +String HtmlExport::ParagraphToHTMLString( SdrOutliner* pOutliner, ULONG nPara, const Color& rBackgroundColor ) +{ + String aStr; + + if(NULL == pOutliner) + return aStr; + + // TODO: MALTE!!! + EditEngine& rEditEngine = *(EditEngine*)&pOutliner->GetEditEngine(); + bool bOldUpdateMode = rEditEngine.GetUpdateMode(); + rEditEngine.SetUpdateMode(TRUE); + + Paragraph* pPara = pOutliner->GetParagraph(nPara); + if(NULL == pPara) + return aStr; + + HtmlState aState( (mbUserAttr || mbDocColors) ? maTextColor : Color(COL_BLACK) ); + SvUShorts aPortionList; + rEditEngine.GetPortions( (USHORT) nPara, aPortionList ); + USHORT nPortionCount = aPortionList.Count(); + + USHORT nPos1 = 0; + for( USHORT nPortion = 0; nPortion < nPortionCount; nPortion++ ) + { + USHORT nPos2 = aPortionList.GetObject(nPortion); + + ESelection aSelection( (USHORT) nPara, nPos1, (USHORT) nPara, nPos2); + + SfxItemSet aSet( rEditEngine.GetAttribs( aSelection ) ); + + String aPortion(StringToHTMLString(rEditEngine.GetText( aSelection ))); + + aStr += TextAttribToHTMLString( &aSet, &aState, rBackgroundColor ); + aStr += aPortion; + + nPos1 = nPos2; + } + aStr += aState.Flush(); + rEditEngine.SetUpdateMode(bOldUpdateMode); + + return aStr; +} + +// ===================================================================== +// Erzeugt anhand der Attribute im angegebennen Set und dem gegebennen +// HtmlState die noetigen Html-Tags um die Attribute zu uebernehmen +// ===================================================================== +String HtmlExport::TextAttribToHTMLString( SfxItemSet* pSet, HtmlState* pState, const Color& rBackgroundColor ) +{ + String aStr; + + if(NULL == pSet) + return aStr; + + String aLink, aTarget; + if ( pSet->GetItemState( EE_FEATURE_FIELD ) == SFX_ITEM_ON ) + { + SvxFieldItem* pItem = (SvxFieldItem*)pSet->GetItem( EE_FEATURE_FIELD ); + if(pItem) + { + SvxURLField* pURL = PTR_CAST(SvxURLField, pItem->GetField()); + if(pURL) + { + aLink = pURL->GetURL(); + aTarget = pURL->GetTargetFrame(); + } + } + } + + bool bTemp; + String aTemp; + + if ( pSet->GetItemState( EE_CHAR_WEIGHT ) == SFX_ITEM_ON ) + { + bTemp = ((const SvxWeightItem&)pSet->Get( EE_CHAR_WEIGHT )).GetWeight() == WEIGHT_BOLD; + aTemp = pState->SetWeight( bTemp ); + if( bTemp ) + aStr.Insert( aTemp, 0 ); + else + aStr += aTemp; + } + + if ( pSet->GetItemState( EE_CHAR_UNDERLINE ) == SFX_ITEM_ON ) + { + bTemp = ((const SvxUnderlineItem&)pSet->Get( EE_CHAR_UNDERLINE )).GetLineStyle() != UNDERLINE_NONE; + aTemp = pState->SetUnderline( bTemp ); + if( bTemp ) + aStr.Insert( aTemp, 0 ); + else + aStr += aTemp; + } + + if ( pSet->GetItemState( EE_CHAR_STRIKEOUT ) == SFX_ITEM_ON ) + { + bTemp = ((const SvxCrossedOutItem&)pSet->Get( EE_CHAR_STRIKEOUT )).GetStrikeout() != STRIKEOUT_NONE; + aTemp = pState->SetStrikeout( bTemp ); + if( bTemp ) + aStr.Insert( aTemp, 0 ); + else + aStr += aTemp; + } + + if ( pSet->GetItemState( EE_CHAR_ITALIC ) == SFX_ITEM_ON ) + { + bTemp = ((const SvxPostureItem&)pSet->Get( EE_CHAR_ITALIC )).GetPosture() != ITALIC_NONE; + aTemp = pState->SetItalic( bTemp ); + if( bTemp ) + aStr.Insert( aTemp, 0 ); + else + aStr += aTemp; + } + + if(mbDocColors) + { + if ( pSet->GetItemState( EE_CHAR_COLOR ) == SFX_ITEM_ON ) + { + Color aTextColor = ((const SvxColorItem&) pSet->Get( EE_CHAR_COLOR )).GetValue(); + if( aTextColor == COL_AUTO ) + { + if( !rBackgroundColor.IsDark() ) + aTextColor = COL_BLACK; + } + aStr += pState->SetColor( aTextColor ); + } + } + + if( aLink.Len() ) + aStr.Insert( pState->SetLink(aLink, aTarget), 0 ); + else + aStr += pState->SetLink(aLink, aTarget); + + return aStr; +} + +// ===================================================================== +// HTML-Wrapper fuer Bild-Dateien erzeugen +// ===================================================================== +bool HtmlExport::CreateHtmlForPresPages() +{ + bool bOk = true; + + List aClickableObjects; + + for(USHORT nSdPage = 0; nSdPage < mnSdPageCount && bOk; nSdPage++) + { + // Klickbare Objekte finden (auch auf der Masterpage) und + // in Liste stellen. In umgekehrter Zeichenreihenfolge in + // die Liste stellen, da in HTML bei Ueberlappungen die + // _erstgenannte_ Area wirkt. + + SdPage* pPage = maPages[ nSdPage ]; + + if( mbDocColors ) + { + SetDocColors( pPage ); + } + + bool bMasterDone = false; + + while (!bMasterDone) + { + // TRUE = rueckwaerts + SdrObjListIter aIter(*pPage, IM_DEEPWITHGROUPS, TRUE); + + SdrObject* pObject = aIter.Next(); + while (pObject) + { + SdAnimationInfo* pInfo = mpDoc->GetAnimationInfo(pObject); + SdIMapInfo* pIMapInfo = mpDoc->GetIMapInfo(pObject); + + if ((pInfo && + (pInfo->meClickAction == presentation::ClickAction_BOOKMARK || + pInfo->meClickAction == presentation::ClickAction_DOCUMENT || + pInfo->meClickAction == presentation::ClickAction_PREVPAGE || + pInfo->meClickAction == presentation::ClickAction_NEXTPAGE || + pInfo->meClickAction == presentation::ClickAction_FIRSTPAGE || + pInfo->meClickAction == presentation::ClickAction_LASTPAGE)) || + pIMapInfo) + { + aClickableObjects.Insert(pObject, LIST_APPEND); + } + + pObject = aIter.Next(); + } + // jetzt zur Masterpage oder beenden + if (!pPage->IsMasterPage()) + pPage = (SdPage*)(&(pPage->TRG_GetMasterPage())); + else + bMasterDone = true; + } + ULONG nClickableObjectCount = aClickableObjects.Count(); + +// HTML Head + String aStr(maHTMLHeader); + aStr += WriteMetaCharset(); + aStr.AppendAscii( " <title>" ); + aStr += StringToHTMLString(*mpPageNames[nSdPage]); + aStr.AppendAscii( "</title>\r\n" ); + +// insert timing information + pPage = maPages[ nSdPage ]; + if( meMode == PUBLISH_KIOSK ) + { + ULONG nSecs = 0; + bool bEndless = false; + if( !mbAutoSlide ) + { + if( pPage->GetPresChange() != PRESCHANGE_MANUAL ) + { + nSecs = pPage->GetTime(); + bEndless = mpDoc->getPresentationSettings().mbEndless; + } + } + else + { + nSecs = mnSlideDuration; + bEndless = mbEndless; + } + + if( nSecs != 0 ) + { + if( nSdPage < (mnSdPageCount-1) || bEndless ) + { + aStr.AppendAscii( "<meta http-equiv=\"refresh\" content=\"" ); + aStr += String::CreateFromInt32(nSecs); + aStr.AppendAscii( "; URL=" ); + + int nPage = nSdPage + 1; + if( nPage == mnSdPageCount ) + nPage = 0; + + aStr += StringToURL(*mpHTMLFiles[nPage]); + + aStr.AppendAscii( "\">\r\n" ); + } + } + } + + aStr.AppendAscii( "</head>\r\n" ); + +// HTML Body + aStr += CreateBodyTag(); + + if( mbSlideSound && pPage->IsSoundOn() ) + aStr += InsertSound( pPage->GetSoundFile() ); + +// Navigationsleiste + if(!mbFrames ) + aStr += CreateNavBar( nSdPage, false ); +// Image + aStr.AppendAscii( "<center>" ); + aStr.AppendAscii( "<img src=\"" ); + aStr += StringToURL( *mpImageFiles[nSdPage] ); + aStr.AppendAscii( "\" alt=\"\"" ); + + if (nClickableObjectCount > 0) + aStr.AppendAscii( " USEMAP=\"#map0\"" ); + + aStr.AppendAscii( "></center>\r\n" ); + +// Notizen + if(mbNotes && !mbFrames) + { + SdrOutliner* pOutliner = mpDoc->GetInternalOutliner(); + SdPage* pNotesPage = maNotesPages[ nSdPage ]; + String aNotesStr( CreateTextForNotesPage( pOutliner, pNotesPage, true, maBackColor) ); + pOutliner->Clear(); + + if( aNotesStr.Len() ) + { + aStr.AppendAscii( "<h3>" ); + aStr += RESTOHTML(STR_HTMLEXP_NOTES); + aStr.AppendAscii( ":</h3><br>\r\n\r\n<p>" ); + + aStr += aNotesStr; + aStr.AppendAscii( "\r\n</p>\r\n" ); + } + } + +// ggfs. Imagemap erzeugen + if (nClickableObjectCount > 0) + { + aStr.AppendAscii( "<map name=\"map0\">\r\n" ); + + for (ULONG nObject = 0; nObject < nClickableObjectCount; nObject++) + { + SdrObject* pObject = (SdrObject*)aClickableObjects.GetObject(nObject); + SdAnimationInfo* pInfo = mpDoc->GetAnimationInfo(pObject); + SdIMapInfo* pIMapInfo = mpDoc->GetIMapInfo(pObject); + + Rectangle aRect(pObject->GetCurrentBoundRect()); + Point aLogPos(aRect.TopLeft()); + bool bIsSquare = aRect.GetWidth() == aRect.GetHeight(); + + ULONG nPageWidth = pPage->GetSize().Width() - pPage->GetLftBorder() - + pPage->GetRgtBorder(); + + // das BoundRect bezieht sich auf den physikalischen + // Seitenursprung, nicht auf den Koordinatenursprung + aRect.Move(-pPage->GetLftBorder(), -pPage->GetUppBorder()); + + double fLogicToPixel = ((double)mnWidthPixel) / nPageWidth; + aRect.Left() = (long)(aRect.Left() * fLogicToPixel); + aRect.Top() = (long)(aRect.Top() * fLogicToPixel); + aRect.Right() = (long)(aRect.Right() * fLogicToPixel); + aRect.Bottom() = (long)(aRect.Bottom() * fLogicToPixel); + long nRadius = aRect.GetWidth() / 2; + + + /************************************************************* + |* wenn das Objekt eine eigene Imagemap enthaelt, werden ihre + |* Areas in diese Imagemap eingefuegt + \************************************************************/ + if (pIMapInfo) + { + const ImageMap& rIMap = pIMapInfo->GetImageMap(); + UINT16 nAreaCount = rIMap.GetIMapObjectCount(); + for (UINT16 nArea = 0; nArea < nAreaCount; nArea++) + { + IMapObject* pArea = rIMap.GetIMapObject(nArea); + UINT16 nType = pArea->GetType(); + String aURL( pArea->GetURL() ); + + // ggfs. Seiten- oder Objektnamen umwandeln in den + // Namen der entsprechenden HTML-Datei + BOOL bIsMasterPage; + USHORT nPgNum = mpDoc->GetPageByName( aURL, bIsMasterPage ); + SdrObject* pObj = NULL; + + if (nPgNum == SDRPAGE_NOTFOUND) + { + // Ist das Bookmark ein Objekt? + pObj = mpDoc->GetObj( aURL ); + if (pObj) + nPgNum = pObj->GetPage()->GetPageNum(); + } + if (nPgNum != SDRPAGE_NOTFOUND) + { + nPgNum = (nPgNum - 1) / 2; // SdrPageNum --> SdPageNum + aURL = CreatePageURL(nPgNum); + } + + switch(nType) + { + case IMAP_OBJ_RECTANGLE: + { + Rectangle aArea(((IMapRectangleObject*)pArea)-> + GetRectangle(false)); + + // Umrechnung in Pixelkoordinaten + aArea.Move(aLogPos.X() - pPage->GetLftBorder(), + aLogPos.Y() - pPage->GetUppBorder()); + aArea.Left() = (long)(aArea.Left() * fLogicToPixel); + aArea.Top() = (long)(aArea.Top() * fLogicToPixel); + aArea.Right() = (long)(aArea.Right() * fLogicToPixel); + aArea.Bottom() = (long)(aArea.Bottom() * fLogicToPixel); + + aStr += CreateHTMLRectArea(aArea, aURL); + } + break; + + case IMAP_OBJ_CIRCLE: + { + Point aCenter(((IMapCircleObject*)pArea)-> + GetCenter(false)); + aCenter += Point(aLogPos.X() - pPage->GetLftBorder(), + aLogPos.Y() - pPage->GetUppBorder()); + aCenter.X() = (long)(aCenter.X() * fLogicToPixel); + aCenter.Y() = (long)(aCenter.Y() * fLogicToPixel); + + ULONG nCircleRadius = (((IMapCircleObject*)pArea)-> + GetRadius(false)); + nCircleRadius = (ULONG)(nCircleRadius * fLogicToPixel); + aStr += CreateHTMLCircleArea(nCircleRadius, + aCenter.X(), aCenter.Y(), + aURL); + } + break; + + case IMAP_OBJ_POLYGON: + { + Polygon aArea(((IMapPolygonObject*)pArea)->GetPolygon(false)); + aStr += CreateHTMLPolygonArea(::basegfx::B2DPolyPolygon(aArea.getB2DPolygon()), Size(aLogPos.X() - pPage->GetLftBorder(), aLogPos.Y() - pPage->GetUppBorder()), fLogicToPixel, aURL); + } + break; + + default: + { + DBG_WARNING("unbekannter IMAP_OBJ_Typ"); + } + break; + } + } + } + + + + /************************************************************* + |* wenn es eine presentation::ClickAction gibt, Bookmark bestimmen und eine + |* Area fuer das ganze Objekt erzeugen + \************************************************************/ + if( pInfo ) + { + String aHRef; + presentation::ClickAction eClickAction = pInfo->meClickAction; + + switch( eClickAction ) + { + case presentation::ClickAction_BOOKMARK: + { + BOOL bIsMasterPage; + USHORT nPgNum = mpDoc->GetPageByName( pInfo->GetBookmark(), bIsMasterPage ); + SdrObject* pObj = NULL; + + if( nPgNum == SDRPAGE_NOTFOUND ) + { + // Ist das Bookmark ein Objekt? + pObj = mpDoc->GetObj(pInfo->GetBookmark()); + if (pObj) + nPgNum = pObj->GetPage()->GetPageNum(); + } + + if( SDRPAGE_NOTFOUND != nPgNum ) + aHRef = CreatePageURL(( nPgNum - 1 ) / 2 ); + } + break; + + case presentation::ClickAction_DOCUMENT: + aHRef = pInfo->GetBookmark(); + break; + + case presentation::ClickAction_PREVPAGE: + { + ULONG nPage = nSdPage; + if (nSdPage == 0) + nPage = 0; + else + nPage = nSdPage - 1; + + aHRef = CreatePageURL( (USHORT) nPage); + } + break; + + case presentation::ClickAction_NEXTPAGE: + { + ULONG nPage = nSdPage; + if (nSdPage == mnSdPageCount - 1) + nPage = mnSdPageCount - 1; + else + nPage = nSdPage + 1; + + aHRef = CreatePageURL( (USHORT) nPage); + } + break; + + case presentation::ClickAction_FIRSTPAGE: + aHRef = CreatePageURL(0); + break; + + case presentation::ClickAction_LASTPAGE: + aHRef = CreatePageURL(mnSdPageCount - 1); + break; + + default: + break; + } + + // jetzt die Areas + if( aHRef.Len() ) + { + // ein Kreis? + if (pObject->GetObjInventor() == SdrInventor && + pObject->GetObjIdentifier() == OBJ_CIRC && + bIsSquare ) + { + aStr += CreateHTMLCircleArea(aRect.GetWidth() / 2, + aRect.Left() + nRadius, + aRect.Top() + nRadius, + aHRef); + } + // ein Polygon? + else if (pObject->GetObjInventor() == SdrInventor && + (pObject->GetObjIdentifier() == OBJ_PATHLINE || + pObject->GetObjIdentifier() == OBJ_PLIN || + pObject->GetObjIdentifier() == OBJ_POLY)) + { + aStr += CreateHTMLPolygonArea(((SdrPathObj*)pObject)->GetPathPoly(), Size(-pPage->GetLftBorder(), -pPage->GetUppBorder()), fLogicToPixel, aHRef); + } + // was anderes: das BoundRect nehmen + else + { + aStr += CreateHTMLRectArea(aRect, aHRef); + } + + } + } + } + + aStr.AppendAscii( "</map>\r\n" ); + } + aClickableObjects.Clear(); + + aStr.AppendAscii( "</body>\r\n</html>" ); + + bOk = WriteHtml( *mpHTMLFiles[nSdPage], false, aStr ); + + if (mpProgress) + mpProgress->SetState(++mnPagesWritten); + } + + return bOk; +} + +// ===================================================================== +// Uebersichtsseite erzeugen +// ===================================================================== +bool HtmlExport::CreateContentPage() +{ + // Parameter + String aEmpty; + + if( mbDocColors ) + SetDocColors(); + + // Html Kopf + String aStr(maHTMLHeader); + aStr += WriteMetaCharset(); + aStr.AppendAscii( " <title>" ); + aStr += StringToHTMLString(*mpPageNames[0]); + aStr.AppendAscii( "</title>\r\n</head>\r\n" ); + aStr += CreateBodyTag(); + + // Seitenkopf + aStr.AppendAscii( "<center>\r\n" ); + + if(mbHeader) + { + aStr.AppendAscii( "<h1>" ); + aStr += getDocumentTitle(); + aStr.AppendAscii( "</h1><br>\r\n" ); + } + + aStr.AppendAscii( "<h2>" ); + + // #92564# Solaris compiler bug workaround + if( mbFrames ) + aStr += CreateLink( maFramePage, + RESTOHTML(STR_HTMLEXP_CLICKSTART) ); + else + aStr += CreateLink( StringToHTMLString(*mpHTMLFiles[0]), + RESTOHTML(STR_HTMLEXP_CLICKSTART) ); + + aStr.AppendAscii( "</h2>\r\n</center>\r\n" ); + + aStr.AppendAscii( "<center><table width=\"90%\"><tr>\r\n" ); + + // Inhaltsverzeichnis + aStr.AppendAscii( "<td valign=\"top\" align=\"left\" width=\"50%\">\r\n" ); + aStr.AppendAscii( "<h3>" ); + aStr += RESTOHTML(STR_HTMLEXP_CONTENTS); + aStr.AppendAscii( "</h3>" ); + + for(USHORT nSdPage = 0; nSdPage < mnSdPageCount; nSdPage++) + { + String aPageName = *mpPageNames[nSdPage]; + aStr.AppendAscii( "<div align=\"left\">" ); + if(mbFrames) + aStr += StringToHTMLString(aPageName); + else + aStr += CreateLink(*mpHTMLFiles[nSdPage], aPageName); + aStr.AppendAscii( "</div>\r\n" ); + } + aStr.AppendAscii( "</td>\r\n" ); + + // Dokument Infos + aStr.AppendAscii( "<td valign=\"top\" width=\"50%\">\r\n" ); + + if(maAuthor.Len()) + { + aStr.AppendAscii( "<p><strong>" ); + aStr += RESTOHTML(STR_HTMLEXP_AUTHOR); + aStr.AppendAscii( ":</strong> " ); + aStr += StringToHTMLString(maAuthor); + aStr.AppendAscii( "</p>\r\n" ); + } + + if(maEMail.Len()) + { + aStr.AppendAscii( "<p><strong>" ); + aStr += RESTOHTML(STR_HTMLEXP_EMAIL); + aStr.AppendAscii( ":</strong> <a href=\"mailto:" ); + aStr += StringToURL(maEMail); + aStr.AppendAscii( "\">" ); + aStr += StringToHTMLString(maEMail); + aStr.AppendAscii( "</a></p>\r\n" ); + } + + if(maHomePage.Len()) + { + aStr.AppendAscii( "<p><strong>" ); + aStr += RESTOHTML(STR_HTMLEXP_HOMEPAGE); + aStr.AppendAscii( ":</strong> <a href=\"" ); + aStr += StringToURL(maHomePage); + aStr.AppendAscii( "\">" ); + aStr += StringToHTMLString(maHomePage); + aStr.AppendAscii( "</a> </p>\r\n" ); + } + + if(maInfo.Len()) + { + aStr.AppendAscii( "<p><strong>" ); + aStr += RESTOHTML(STR_HTMLEXP_INFO); + aStr.AppendAscii( ":</strong><br>\r\n" ); + aStr += StringToHTMLString(maInfo); + aStr.AppendAscii( "</p>\r\n" ); + } + + if(mbDownload) + { + aStr.AppendAscii( "<p><a href=\"" ); + aStr += StringToURL(maDocFileName); + aStr.AppendAscii( "\">" ); + aStr += RESTOHTML(STR_HTMLEXP_DOWNLOAD); + aStr.AppendAscii( "</a></p>\r\n" ); + } + + aStr.AppendAscii( "</td></tr></table></center>\r\n" ); + + aStr.AppendAscii( "</body>\r\n</html>" ); + + bool bOk = WriteHtml( maIndex, false, aStr ); + + if (mpProgress) + mpProgress->SetState(++mnPagesWritten); + + return bOk; +} + +// ===================================================================== +// Notiz Seiten erzeugen (fuer Frames) +// ===================================================================== +bool HtmlExport::CreateNotesPages() +{ + bool bOk = true; + + SdrOutliner* pOutliner = mpDoc->GetInternalOutliner(); + for( USHORT nSdPage = 0; bOk && nSdPage < mnSdPageCount; nSdPage++ ) + { + SdPage* pPage = maNotesPages[nSdPage]; + if( mbDocColors ) + SetDocColors( pPage ); + + // Html Kopf + String aStr(maHTMLHeader); + aStr += WriteMetaCharset(); + aStr.AppendAscii( " <title>" ); + aStr += StringToHTMLString(*mpPageNames[0]); + aStr.AppendAscii( "</title>\r\n</head>\r\n" ); + aStr += CreateBodyTag(); + + if(pPage) + aStr += CreateTextForNotesPage( pOutliner, pPage, true, maBackColor ); + + aStr.AppendAscii( "</body>\r\n</html>" ); + + String aFileName( RTL_CONSTASCII_USTRINGPARAM("note") ); + aFileName += String::CreateFromInt32(nSdPage); + bOk = WriteHtml( aFileName, true, aStr ); + + if (mpProgress) + mpProgress->SetState(++mnPagesWritten); + } + + pOutliner->Clear(); + + return bOk; +} + +// ===================================================================== +// Outline Seiten erzeugen (fuer Frames) +// ===================================================================== +bool HtmlExport::CreateOutlinePages() +{ + bool bOk = true; + + if( mbDocColors ) + { + SetDocColors(); + } + + // Seite 0 wird der zugeklappte Outline, Seite 1 der aufgeklappte + for( int nPage = 0; nPage < (mbImpress?2:1) && bOk; nPage++ ) + { + // Html Kopf + String aStr(maHTMLHeader); + aStr += WriteMetaCharset(); + aStr.AppendAscii( " <title>" ); + aStr += StringToHTMLString(*mpPageNames[0]); + aStr.AppendAscii( "</title>\r\n</head>\r\n" ); + aStr += CreateBodyTag(); + + SdrOutliner* pOutliner = mpDoc->GetInternalOutliner(); + for(USHORT nSdPage = 0; nSdPage < mnSdPageCount; nSdPage++) + { + SdPage* pPage = maPages[ nSdPage ]; + + aStr.AppendAscii( "<div align=\"left\">" ); + String aLink( RTL_CONSTASCII_USTRINGPARAM( "JavaScript:parent.NavigateAbs(" ) ); + aLink += String::CreateFromInt32(nSdPage); + aLink.Append( sal_Unicode(')') ); + + String aTitle = CreateTextForTitle(pOutliner,pPage, maBackColor); + if(aTitle.Len() == 0) + aTitle = *mpPageNames[nSdPage]; + + aStr.AppendAscii("<p style=\""); + aStr.Append( getParagraphStyle( pOutliner, 0 ) ); + aStr.AppendAscii("\">"); + aStr += CreateLink(aLink, aTitle); + aStr.AppendAscii("</p>"); + + if(nPage==1) + { + aStr += CreateTextForPage( pOutliner, pPage, false, maBackColor ); + } + aStr.AppendAscii( "</div>\r\n" ); + } + pOutliner->Clear(); + + aStr.AppendAscii( "</body>\r\n</html>" ); + + String aFileName( RTL_CONSTASCII_USTRINGPARAM("outline") ); + aFileName += String::CreateFromInt32(nPage); + bOk = WriteHtml( aFileName, true, aStr ); + + if (mpProgress) + mpProgress->SetState(++mnPagesWritten); + } + + return bOk; +} + +// ===================================================================== +// Dateinamen festlegen +// ===================================================================== +void HtmlExport::CreateFileNames() +{ + // Listen mit neuen Dateinamen anlegen + mpHTMLFiles = new String*[mnSdPageCount]; + mpImageFiles = new String*[mnSdPageCount]; + mpPageNames = new String*[mnSdPageCount]; + mpTextFiles = new String*[mnSdPageCount]; + + mbHeader = false; // Ueberschrift auf Uebersichtsseite? + + for (USHORT nSdPage = 0; nSdPage < mnSdPageCount; nSdPage++) + { + String* pName; + if(nSdPage == 0 && !mbContentsPage && !mbFrames ) + pName = new String(maIndex); + else + { + pName = new String( RTL_CONSTASCII_USTRINGPARAM("img") ); + *pName += String::CreateFromInt32(nSdPage); + *pName += maHTMLExtension; + } + + mpHTMLFiles[nSdPage] = pName; + + pName = new String( RTL_CONSTASCII_USTRINGPARAM("img") ); + *pName += String::CreateFromInt32(nSdPage); + if( meFormat==FORMAT_GIF ) + pName->AppendAscii( ".gif" ); + else if( meFormat==FORMAT_JPG ) + pName->AppendAscii( ".jpg" ); + else + pName->AppendAscii( ".png" ); + + mpImageFiles[nSdPage] = pName; + + pName = new String( RTL_CONSTASCII_USTRINGPARAM("text")); + *pName += String::CreateFromInt32(nSdPage); + *pName += maHTMLExtension; + mpTextFiles[nSdPage] = pName; + + SdPage* pSdPage = maPages[ nSdPage ]; + + // get slide title from page name + String* pPageTitle = new String(); + *pPageTitle = pSdPage->GetName(); + mpPageNames[nSdPage] = pPageTitle; + } + + if(!mbContentsPage && mbFrames) + maFramePage = maIndex; + else + { + maFramePage.AssignAscii( "siframes" ); + maFramePage += maHTMLExtension; + } +} + +String HtmlExport::getDocumentTitle() +{ + // check for a title object in this page, if its the first + // title it becomes this documents title for the content + // page + if( !mbHeader ) + { + if(mbImpress) + { + // falls es ein nicht-leeres Titelobjekt gibt, dessen ersten Absatz + // als Seitentitel benutzen + SdPage* pSdPage = mpDoc->GetSdPage(0, PK_STANDARD); + SdrObject* pTitleObj = pSdPage->GetPresObj(PRESOBJ_TITLE); + if (pTitleObj && !pTitleObj->IsEmptyPresObj()) + { + OutlinerParaObject* pParaObject = pTitleObj->GetOutlinerParaObject(); + if (pParaObject) + { + const EditTextObject& rEditTextObject = + pParaObject->GetTextObject(); + if (&rEditTextObject) + { + String aTest(rEditTextObject.GetText(0)); + if (aTest.Len() > 0) + mDocTitle = aTest; + } + } + } + + for( UINT16 i = 0; i < mDocTitle.Len(); i++ ) + if( mDocTitle.GetChar(i) == (sal_Unicode)0xff) + mDocTitle.SetChar(i, sal_Unicode(' ') ); + } + + if( !mDocTitle.Len() ) + { + mDocTitle = maDocFileName; + int nDot = mDocTitle.Search( '.' ); + if( nDot > 0 ) + mDocTitle.Erase( (USHORT)nDot ); + } + mbHeader = true; + } + + return mDocTitle; +} + +/* +var nCurrentPage = 0; +var nPageCount = JSCRIPT2; + +function NavigateAbs( nPage ) +{ + frames[\"show\"].location.href = \"img\" + nPage + \".htm\"; + frames[\"notes\"].location.href = \"note\" + nPage + \".htm\"; + nCurrentPage = nPage; + if(nCurrentPage==0) + { + frames[\"navbar1\"].location.href = \"navbar0.htm\"; + } + else if(nCurrentPage==nPageCount-1) + { + frames[\"navbar1\"].location.href = \"navbar2.htm\"; + } + else + frames[\"navbar1\"].location.href = \"navbar1.htm\"; + } +} + +function NavigateRel( nDelta ) +{ + var nPage = parseInt(nCurrentPage) + parseInt(nDelta); + if( (nPage >= 0) && (nPage < nPageCount) ) + { + NavigateAbs( nPage ); + } +} + +function ExpandOutline() +{ + frames[\"navbar2\"].location.href = \"navbar4.htm\"; + frames[\"outline\"].location.href = \"outline1.htm\"; +} + +function CollapseOutline() +{ + frames[\"navbar2\"].location.href = \"navbar3.htm\"; + frames[\"outline\"].location.href = \"outline0.htm\"; +} +*/ + +static const char* JS_NavigateAbs = + "function NavigateAbs( nPage )\r\n" + "{\r\n" + " frames[\"show\"].location.href = \"img\" + nPage + \".$EXT\";\r\n" + " //frames[\"notes\"].location.href = \"note\" + nPage + \".$EXT\";\r\n" + " nCurrentPage = nPage;\r\n" + " if(nCurrentPage==0)\r\n" + " {\r\n" + " frames[\"navbar1\"].location.href = \"navbar0.$EXT\";\r\n" + " }\r\n" + " else if(nCurrentPage==nPageCount-1)\r\n" + " {\r\n" + " frames[\"navbar1\"].location.href = \"navbar2.$EXT\";\r\n" + " }\r\n" + " else\r\n" + " {\r\n" + " frames[\"navbar1\"].location.href = \"navbar1.$EXT\";\r\n" + " }\r\n" + "}\r\n\r\n"; + +static const char* JS_NavigateRel = + "function NavigateRel( nDelta )\r\n" + "{\r\n" + " var nPage = parseInt(nCurrentPage) + parseInt(nDelta);\r\n" + " if( (nPage >= 0) && (nPage < nPageCount) )\r\n" + " {\r\n" + " NavigateAbs( nPage );\r\n" + " }\r\n" + "}\r\n\r\n"; + +static const char* JS_ExpandOutline = + "function ExpandOutline()\r\n" + "{\r\n" + " frames[\"navbar2\"].location.href = \"navbar4.$EXT\";\r\n" + " frames[\"outline\"].location.href = \"outline1.$EXT\";\r\n" + "}\r\n\r\n"; + +static const char * JS_CollapseOutline = + "function CollapseOutline()\r\n" + "{\r\n" + " frames[\"navbar2\"].location.href = \"navbar3.$EXT\";\r\n" + " frames[\"outline\"].location.href = \"outline0.$EXT\";\r\n" + "}\r\n\r\n"; + +// ==================================================================== +// Seite mit den Frames erzeugen +// ==================================================================== +bool HtmlExport::CreateFrames() +{ + String aTmp; + String aStr( RTL_CONSTASCII_USTRINGPARAM( + "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\"\r\n" + " \"http://www.w3.org/TR/html4/frameset.dtd\">\r\n" + "<html>\r\n<head>\r\n" ) ); + + aStr += WriteMetaCharset(); + aStr.AppendAscii( " <title>" ); + aStr += StringToHTMLString(*mpPageNames[0]); + aStr.AppendAscii( "</title>\r\n" ); + + aStr.AppendAscii( "<script type=\"text/javascript\">\r\n<!--\r\n" ); + + aStr.AppendAscii( "var nCurrentPage = 0;\r\nvar nPageCount = " ); + aStr += String::CreateFromInt32(mnSdPageCount); + aStr.AppendAscii( ";\r\n\r\n" ); + + String aFunction; + aFunction.AssignAscii(JS_NavigateAbs); + + if(mbNotes) + { + String aEmpty; + String aSlash( RTL_CONSTASCII_USTRINGPARAM( "//" ) ); + aFunction.SearchAndReplaceAll( aSlash, aEmpty); + } + + // substitute HTML file extension + String aPlaceHolder(RTL_CONSTASCII_USTRINGPARAM(".$EXT")); + aFunction.SearchAndReplaceAll(aPlaceHolder, maHTMLExtension); + aStr += aFunction; + + aTmp.AssignAscii( JS_NavigateRel ); + aTmp.SearchAndReplaceAll(aPlaceHolder, maHTMLExtension); + aStr += aTmp; + + if(mbImpress) + { + aTmp.AssignAscii( JS_ExpandOutline ); + aTmp.SearchAndReplaceAll(aPlaceHolder, maHTMLExtension); + aStr += aTmp; + + aTmp.AssignAscii( JS_CollapseOutline ); + aTmp.SearchAndReplaceAll(aPlaceHolder, maHTMLExtension); + aStr += aTmp; + } + aStr.AppendAscii( "// -->\r\n</script>\r\n" ); + + aStr.AppendAscii( "</head>\r\n" ); + + aStr.AppendAscii( "<frameset cols=\"*," ); + aStr += String::CreateFromInt32((mnWidthPixel + 16)); + aStr.AppendAscii( "\">\r\n" ); + if(mbImpress) + { + aStr.AppendAscii( " <frameset rows=\"42,*\">\r\n" ); + aStr.AppendAscii( " <frame src=\"navbar3" ); + aStr += StringToURL(maHTMLExtension); + aStr.AppendAscii( "\" name=\"navbar2\" marginwidth=\"4\" marginheight=\"4\" scrolling=\"no\">\r\n" ); + } + aStr.AppendAscii( " <frame src=\"outline0" ); + aStr += StringToURL(maHTMLExtension); + aStr.AppendAscii( "\" name=\"outline\">\r\n" ); + if(mbImpress) + aStr.AppendAscii( " </frameset>\r\n" ); + + if(mbNotes) + { + aStr.AppendAscii( " <frameset rows=\"42," ); + aStr += String::CreateFromInt32((int)((double)mnWidthPixel * 0.75) + 16); + aStr.AppendAscii( ",*\">\r\n" ); + } + else + aStr.AppendAscii( " <frameset rows=\"42,*\">\r\n" ); + + aStr.AppendAscii( " <frame src=\"navbar0" ); + aStr += StringToURL(maHTMLExtension); + aStr.AppendAscii( "\" name=\"navbar1\" marginwidth=\"4\" marginheight=\"4\" scrolling=\"no\">\r\n" ); + + aStr.AppendAscii( " <frame src=\"" ); + aStr += StringToURL(*mpHTMLFiles[0]); + aStr.AppendAscii( "\" name=\"show\" marginwidth=\"4\" marginheight=\"4\">\r\n" ); + + if(mbNotes) + { + aStr.AppendAscii( " <frame src=\"note0" ); + aStr += StringToURL(maHTMLExtension); + aStr.AppendAscii( "\" name=\"notes\">\r\n" ); + } + aStr.AppendAscii( " </frameset>\r\n" ); + + aStr.AppendAscii( "<noframes>\r\n" ); + aStr += CreateBodyTag(); + aStr += RESTOHTML(STR_HTMLEXP_NOFRAMES); + aStr.AppendAscii( "\r\n</noframes>\r\n</frameset>\r\n</html>" ); + + bool bOk = WriteHtml( maFramePage, false, aStr ); + + if (mpProgress) + mpProgress->SetState(++mnPagesWritten); + + return bOk; +} + +// ==================================================================== +// Buttonleiste fuer Standard ausgeben +// Es werden 4 html files erstellt +// navbar0.htm Navigationsleiste Grafik fuer erste Seite +// navbar1.htm Navigationsleiste Grafik fuer zweite bis vorletzte Seite +// navbar2.htm Navigationsleiste Grafik fuer letzte Seite +// navbar3.htm Navigationsleiste Outline zugeklappt +// navbar4.htm Navigationsleiste Outline aufgeklappt +// ==================================================================== +bool HtmlExport::CreateNavBarFrames() +{ + bool bOk = true; + String aButton; + + if( mbDocColors ) + { + SetDocColors(); + maBackColor = maFirstPageColor; + } + + for( int nFile = 0; nFile < 3 && bOk; nFile++ ) + { + String aStr(maHTMLHeader); + aStr += WriteMetaCharset(); + aStr.AppendAscii( " <title>" ); + aStr += StringToHTMLString(*mpPageNames[0]); + aStr.AppendAscii( "</title>\r\n</head>\r\n" ); + aStr += CreateBodyTag(); + aStr.AppendAscii( "<center>\r\n" ); + + // erste Seite + aButton = String(SdResId(STR_HTMLEXP_FIRSTPAGE)); + if(mnButtonThema != -1) + aButton = CreateImage(GetButtonName((nFile == 0 || mnSdPageCount == 1? + BTN_FIRST_0:BTN_FIRST_1)), aButton); + + if(nFile != 0 && mnSdPageCount > 1) + aButton = CreateLink( String(RTL_CONSTASCII_USTRINGPARAM("JavaScript:parent.NavigateAbs(0)")), aButton); + + aStr += aButton; + aStr.AppendAscii( "\r\n" ); + + // zur vorherigen Seite + aButton = String(SdResId(STR_PUBLISH_BACK)); + if(mnButtonThema != -1) + aButton = CreateImage(GetButtonName((nFile == 0 || mnSdPageCount == 1? + BTN_PREV_0:BTN_PREV_1)), aButton); + + if(nFile != 0 && mnSdPageCount > 1) + aButton = CreateLink( String(RTL_CONSTASCII_USTRINGPARAM("JavaScript:parent.NavigateRel(-1)")), aButton); + + aStr += aButton; + aStr.AppendAscii( "\r\n" ); + + // zur naechsten Seite + aButton = String(SdResId(STR_PUBLISH_NEXT)); + if(mnButtonThema != -1) + aButton = CreateImage(GetButtonName((nFile ==2 || mnSdPageCount == 1? + BTN_NEXT_0:BTN_NEXT_1)), aButton); + + if(nFile != 2 && mnSdPageCount > 1) + aButton = CreateLink(String(RTL_CONSTASCII_USTRINGPARAM("JavaScript:parent.NavigateRel(1)")), aButton); + + aStr += aButton; + aStr.AppendAscii( "\r\n" ); + + // zur letzten Seite + aButton = String(SdResId(STR_HTMLEXP_LASTPAGE)); + if(mnButtonThema != -1) + aButton = CreateImage(GetButtonName((nFile ==2 || mnSdPageCount == 1? + BTN_LAST_0:BTN_LAST_1)), aButton); + + if(nFile != 2 && mnSdPageCount > 1) + { + String aLink(RTL_CONSTASCII_USTRINGPARAM("JavaScript:parent.NavigateAbs(")); + aLink += String::CreateFromInt32(mnSdPageCount-1); + aLink.AppendAscii( ")" ); + aButton = CreateLink( aLink, aButton); + } + + aStr += aButton; + aStr.AppendAscii( "\r\n" ); + + // Inhalt + if (mbContentsPage) + { + aButton = String(SdResId(STR_PUBLISH_OUTLINE)); + if(mnButtonThema != -1) + aButton = CreateImage(GetButtonName(BTN_INDEX), aButton); + + // zur Uebersicht + aStr += CreateLink(maIndex, aButton, String(RTL_CONSTASCII_USTRINGPARAM("_top"))); + aStr.AppendAscii( "\r\n" ); + } + + // Textmodus + if(mbImpress) + { + aButton = String(SdResId(STR_HTMLEXP_SETTEXT)); + if(mnButtonThema != -1) + aButton = CreateImage(GetButtonName(BTN_TEXT), aButton); + + String aText0( RTL_CONSTASCII_USTRINGPARAM("text0")); + aText0 += maHTMLExtension; + aStr += CreateLink( aText0, aButton, String(RTL_CONSTASCII_USTRINGPARAM("_top"))); + aStr.AppendAscii( "\r\n" ); + } + + // Und fertich... + aStr.AppendAscii( "</center>\r\n" ); + aStr.AppendAscii( "</body>\r\n</html>" ); + + String aFileName( RTL_CONSTASCII_USTRINGPARAM("navbar") ); + aFileName += String::CreateFromInt32(nFile); + + bOk = WriteHtml( aFileName, true, aStr ); + + if (mpProgress) + mpProgress->SetState(++mnPagesWritten); + } + + // Jetzt kommt die Navigatonsleiste Outliner zugeklappt... + if(bOk) + { + String aStr(maHTMLHeader); + aStr += WriteMetaCharset(); + aStr.AppendAscii( " <title>" ); + aStr += StringToHTMLString(*mpPageNames[0]); + aStr.AppendAscii( "</title>\r\n</head>\r\n" ); + aStr += CreateBodyTag(); + + aButton = String(SdResId(STR_HTMLEXP_OUTLINE)); + if(mnButtonThema != -1) + aButton = CreateImage(GetButtonName(BTN_MORE), aButton); + + aStr += CreateLink(String(RTL_CONSTASCII_USTRINGPARAM("JavaScript:parent.ExpandOutline()")), aButton); + aStr.AppendAscii( "</body>\r\n</html>" ); + + String aFileName( RTL_CONSTASCII_USTRINGPARAM("navbar3") ); + + bOk = WriteHtml( aFileName, true, aStr ); + + if (mpProgress) + mpProgress->SetState(++mnPagesWritten); + } + + // ... und jetzt Outliner aufgeklappt + if( bOk ) + { + String aStr(maHTMLHeader); + aStr += WriteMetaCharset(); + aStr.AppendAscii( " <title>" ); + aStr += StringToHTMLString(*mpPageNames[0]); + aStr.AppendAscii( "</title>\r\n</head>\r\n" ); + aStr += CreateBodyTag(); + + aButton = String(SdResId(STR_HTMLEXP_NOOUTLINE)); + if(mnButtonThema != -1) + aButton = CreateImage(GetButtonName(BTN_LESS), aButton); + + aStr += CreateLink(String(RTL_CONSTASCII_USTRINGPARAM("JavaScript:parent.CollapseOutline()")), aButton); + aStr.AppendAscii( "</body>\r\n</html>" ); + + String aFileName( RTL_CONSTASCII_USTRINGPARAM("navbar4") ); + bOk = WriteHtml( aFileName, true, aStr ); + + if (mpProgress) + mpProgress->SetState(++mnPagesWritten); + + } + + return bOk; +} + +// ==================================================================== +// Buttonleiste fuer Standard ausgeben +// ==================================================================== +String HtmlExport::CreateNavBar( USHORT nSdPage, bool bIsText ) const +{ + // Navigationsleiste vorbereiten + String aStrNavFirst( SdResId(STR_HTMLEXP_FIRSTPAGE) ); + String aStrNavPrev( SdResId(STR_PUBLISH_BACK) ); + String aStrNavNext( SdResId(STR_PUBLISH_NEXT) ); + String aStrNavLast( SdResId(STR_HTMLEXP_LASTPAGE) ); + String aStrNavContent( SdResId(STR_PUBLISH_OUTLINE) ); + String aStrNavText; + if( bIsText ) + { + aStrNavText = String( SdResId(STR_HTMLEXP_SETGRAPHIC) ); + } + else + { + aStrNavText = String( SdResId(STR_HTMLEXP_SETTEXT) ); + } + + if(!bIsText && mnButtonThema != -1) + { + if(nSdPage<1 || mnSdPageCount == 1) + { + aStrNavFirst = CreateImage(GetButtonName(BTN_FIRST_0), aStrNavFirst); + aStrNavPrev = CreateImage(GetButtonName(BTN_PREV_0), aStrNavPrev); + } + else + { + aStrNavFirst = CreateImage(GetButtonName(BTN_FIRST_1), aStrNavFirst); + aStrNavPrev = CreateImage(GetButtonName(BTN_PREV_1), aStrNavPrev); + } + + if(nSdPage == mnSdPageCount-1 || mnSdPageCount == 1) + { + aStrNavNext = CreateImage(GetButtonName(BTN_NEXT_0), aStrNavNext); + aStrNavLast = CreateImage(GetButtonName(BTN_LAST_0), aStrNavLast); + } + else + { + aStrNavNext = CreateImage(GetButtonName(BTN_NEXT_1), aStrNavNext); + aStrNavLast = CreateImage(GetButtonName(BTN_LAST_1), aStrNavLast); + } + + aStrNavContent = CreateImage(GetButtonName(BTN_INDEX), aStrNavContent); + aStrNavText = CreateImage(GetButtonName(BTN_TEXT), aStrNavText); + } + + String aStr( RTL_CONSTASCII_USTRINGPARAM("<center>\r\n")); //<table><tr>\r\n"); + + // erste Seite + if(nSdPage > 0) + aStr += CreateLink(bIsText?*mpTextFiles[0]:*mpHTMLFiles[0],aStrNavFirst); + else + aStr += aStrNavFirst; + aStr.Append(sal_Unicode(' ')); + + // to Previous page + if(nSdPage > 0) + aStr += CreateLink( bIsText?*mpTextFiles[nSdPage-1]: + *mpHTMLFiles[nSdPage-1], aStrNavPrev); + else + aStr += aStrNavPrev; + aStr.Append(sal_Unicode(' ')); + + // to Next page + if(nSdPage < mnSdPageCount-1) + aStr += CreateLink( bIsText?*mpTextFiles[nSdPage+1]: + *mpHTMLFiles[nSdPage+1], aStrNavNext); + else + aStr += aStrNavNext; + aStr.Append(sal_Unicode(' ')); + + // to Last page + if(nSdPage < mnSdPageCount-1) + aStr += CreateLink( bIsText?*mpTextFiles[mnSdPageCount-1]: + *mpHTMLFiles[mnSdPageCount-1], + aStrNavLast ); + else + aStr += aStrNavLast; + aStr.Append(sal_Unicode(' ')); + + // to Index page + if (mbContentsPage) + { + aStr += CreateLink(maIndex, aStrNavContent); + aStr.Append(sal_Unicode(' ')); + } + + // Text/Graphics + if(mbImpress) + { + aStr += CreateLink( bIsText?(mbFrames?maFramePage:*mpHTMLFiles[nSdPage]): + *mpTextFiles[nSdPage], aStrNavText); + + } + + aStr.AppendAscii( "</center><br>\r\n" ); + + return aStr; +} + +/** export navigation graphics from button set */ +bool HtmlExport::CreateBitmaps() +{ + if(mnButtonThema != -1 && mpButtonSet.get() ) + { + for( int nButton = 0; nButton < NUM_BUTTONS; nButton++ ) + { + if(!mbFrames && (nButton == BTN_MORE || nButton == BTN_LESS)) + continue; + + if(!mbImpress && (nButton == BTN_TEXT || nButton == BTN_MORE || nButton == BTN_LESS )) + continue; + + OUString aFull(maExportPath); + aFull += GetButtonName(nButton); + mpButtonSet->exportButton( mnButtonThema, aFull, GetButtonName(nButton) ); + } + } + return true; +} + +// ===================================================================== +// Erzeugt den <body> Tag, inkl. der eingestellten Farbattribute +// ===================================================================== +String HtmlExport::CreateBodyTag() const +{ + String aStr( RTL_CONSTASCII_USTRINGPARAM("<body") ); + + if( mbUserAttr || mbDocColors ) + { + Color aTextColor( maTextColor ); + if( (aTextColor == COL_AUTO) && (!maBackColor.IsDark()) ) + aTextColor = COL_BLACK; + + aStr.AppendAscii( " text=\"" ); + aStr += ColorToHTMLString( aTextColor ); + aStr.AppendAscii( "\" bgcolor=\"" ); + aStr += ColorToHTMLString( maBackColor ); + aStr.AppendAscii( "\" link=\"" ); + aStr += ColorToHTMLString( maLinkColor ); + aStr.AppendAscii( "\" vlink=\"" ); + aStr += ColorToHTMLString( maVLinkColor ); + aStr.AppendAscii( "\" alink=\"" ); + aStr += ColorToHTMLString( maALinkColor ); + aStr.AppendAscii( "\"" ); + } + + aStr.AppendAscii( ">\r\n" ); + + return aStr; +} + +// ===================================================================== +// Erzeugt einen Hyperlink +// ===================================================================== +String HtmlExport::CreateLink( const String& aLink, + const String& aText, + const String& aTarget ) const +{ + String aStr( RTL_CONSTASCII_USTRINGPARAM("<a href=\"")); + aStr += StringToURL(aLink); + if(aTarget.Len()) + { + aStr.AppendAscii( "\" target=\"" ); + aStr += aTarget; + } + aStr.AppendAscii( "\">" ); + aStr += aText; + aStr.AppendAscii( "</a>" ); + + return aStr; +} + +// ===================================================================== +// Erzeugt ein Image-tag +// ===================================================================== +String HtmlExport::CreateImage( const String& aImage, const String& aAltText, + INT16 nWidth, + INT16 nHeight ) const +{ + String aStr( RTL_CONSTASCII_USTRINGPARAM("<img src=\"")); + aStr += StringToURL(aImage); + aStr.AppendAscii( "\" border=0" ); + + if( aAltText.Len()) + { + aStr.AppendAscii( " alt=\"" ); + aStr += aAltText; + aStr.Append(sal_Unicode('"')); + } + else + { + // Agerskov: HTML 4.01 has to have an alt attribut even if it is an empty string + aStr.AppendAscii( " alt=\"\"" ); + } + + if(nWidth > -1) + { + aStr.AppendAscii( " width=" ); + aStr += String::CreateFromInt32(nWidth); + } + + if(nHeight > -1) + { + aStr.AppendAscii( " height=" ); + aStr += String::CreateFromInt32(nHeight); + } + + aStr.Append(sal_Unicode('>')); + + return aStr; +} + +// ===================================================================== +// Area fuer Kreis erzeugen; es werden Pixelkoordinaten erwartet +// ===================================================================== +String HtmlExport::ColorToHTMLString( Color aColor ) +{ + static char hex[] = "0123456789ABCDEF"; + String aStr( RTL_CONSTASCII_USTRINGPARAM("#xxxxxx")); + aStr.SetChar(1, hex[(aColor.GetRed() >> 4) & 0xf] ); + aStr.SetChar(2, hex[aColor.GetRed() & 0xf] ); + aStr.SetChar(3, hex[(aColor.GetGreen() >> 4) & 0xf] ); + aStr.SetChar(4, hex[aColor.GetGreen() & 0xf] ); + aStr.SetChar(5, hex[(aColor.GetBlue() >> 4) & 0xf] ); + aStr.SetChar(6, hex[aColor.GetBlue() & 0xf] ); + + return aStr; +} + +// ===================================================================== +// Area fuer Kreis erzeugen; es werden Pixelkoordinaten erwartet +// ===================================================================== +String HtmlExport::CreateHTMLCircleArea( ULONG nRadius, + ULONG nCenterX, + ULONG nCenterY, + const String& rHRef ) const +{ + String aStr( RTL_CONSTASCII_USTRINGPARAM("<area shape=\"circle\" alt=\"\" coords=\"" )); + + aStr += String::CreateFromInt32(nCenterX); + aStr.Append(sal_Unicode(',')); + aStr += String::CreateFromInt32(nCenterY); + aStr.Append(sal_Unicode(',')); + aStr += String::CreateFromInt32(nRadius); + aStr.AppendAscii( "\" href=\"" ); + aStr += StringToURL(rHRef); + aStr.AppendAscii( "\">\n" ); + + return aStr; +} + + +// ===================================================================== +// Area fuer Polygon erzeugen; es werden Pixelkoordinaten erwartet +// ===================================================================== +String HtmlExport::CreateHTMLPolygonArea( const ::basegfx::B2DPolyPolygon& rPolyPolygon, + Size aShift, double fFactor, const String& rHRef ) const +{ + String aStr; + const sal_uInt32 nNoOfPolygons(rPolyPolygon.count()); + + for ( sal_uInt32 nXPoly = 0L; nXPoly < nNoOfPolygons; nXPoly++ ) + { + const ::basegfx::B2DPolygon& aPolygon = rPolyPolygon.getB2DPolygon(nXPoly); + const sal_uInt32 nNoOfPoints(aPolygon.count()); + + aStr.AppendAscii( "<area shape=\"polygon\" alt=\"\" coords=\"" ); + + for ( sal_uInt32 nPoint = 0L; nPoint < nNoOfPoints; nPoint++ ) + { + const ::basegfx::B2DPoint aB2DPoint(aPolygon.getB2DPoint(nPoint)); + Point aPnt(FRound(aB2DPoint.getX()), FRound(aB2DPoint.getY())); + // das Koordinaten beziehen sich auf den + // physikalischen Seitenursprung, nicht auf den + // Koordinatenursprung + aPnt.Move(aShift.Width(), aShift.Height()); + + aPnt.X() = (long)(aPnt.X() * fFactor); + aPnt.Y() = (long)(aPnt.Y() * fFactor); + aStr += String::CreateFromInt32(aPnt.X()); + aStr.Append(sal_Unicode(',')); + aStr += String::CreateFromInt32(aPnt.Y()); + + if (nPoint < nNoOfPoints - 1) + aStr.Append( sal_Unicode(',') ); + } + aStr.AppendAscii( "\" href=\"" ); + aStr += StringToURL(rHRef); + aStr.AppendAscii( "\">\n" ); + } + + return aStr; +} + +// ===================================================================== +// Area fuer Rechteck erzeugen; es werden Pixelkoordinaten erwartet +// ===================================================================== +String HtmlExport::CreateHTMLRectArea( const Rectangle& rRect, + const String& rHRef ) const +{ + String aStr( RTL_CONSTASCII_USTRINGPARAM("<area shape=\"rect\" alt=\"\" coords=\"") ); + + aStr += String::CreateFromInt32(rRect.Left()); + aStr.Append(sal_Unicode(',')); + aStr += String::CreateFromInt32(rRect.Top()); + aStr.Append(sal_Unicode(',')); + aStr += String::CreateFromInt32(rRect.Right()); + aStr.Append(sal_Unicode(',')); + aStr += String::CreateFromInt32(rRect.Bottom()); + aStr.AppendAscii( "\" href=\"" ); + aStr += StringToURL(rHRef); + aStr.AppendAscii( "\">\n" ); + + return aStr; +} + +// ===================================================================== +// StringToHTMLString, konvertiert einen String in +// seine HTML-Repraesentation (Umlaute etc.) +// ===================================================================== +String HtmlExport::StringToHTMLString( const String& rString ) +{ + SvMemoryStream aMemStm; + HTMLOutFuncs::Out_String( aMemStm, rString, RTL_TEXTENCODING_UTF8 ); + aMemStm << (char) 0; + return String( (char*)aMemStm.GetData(), RTL_TEXTENCODING_UTF8 ); +} + +// ===================================================================== +// Erzeugt die URL einer bestimmten Seite +// ===================================================================== +String HtmlExport::CreatePageURL( USHORT nPgNum ) +{ + if(mbFrames) + { + String aUrl( RTL_CONSTASCII_USTRINGPARAM("JavaScript:parent.NavigateAbs(")); + aUrl += String::CreateFromInt32(nPgNum); + aUrl.Append(sal_Unicode(')')); + return aUrl; + } + else + return *mpHTMLFiles[nPgNum]; +} + +bool HtmlExport::CopyScript( const String& rPath, const String& rSource, const String& rDest, bool bUnix /* = false */ ) +{ + INetURLObject aURL( SvtPathOptions().GetConfigPath() ); + String aScript; + + aURL.Append( String( RTL_CONSTASCII_USTRINGPARAM("webcast") ) ); + aURL.Append( rSource ); + + meEC.SetContext( STR_HTMLEXP_ERROR_OPEN_FILE, rSource ); + + ULONG nErr = 0; + SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ ); + + if( pIStm ) + { + ByteString aLine; + + while( pIStm->ReadLine( aLine ) ) + { + aScript.AppendAscii( aLine.GetBuffer() ); + if( bUnix ) + { + aScript.AppendAscii( "\n" ); + } + else + { + aScript.AppendAscii( "\r\n" ); + } + } + + nErr = pIStm->GetError(); + delete pIStm; + } + + if( nErr != 0 ) + { + ErrorHandler::HandleError( nErr ); + return (bool) nErr; + } + + + aScript.SearchAndReplaceAll( String(RTL_CONSTASCII_USTRINGPARAM("$$1")), getDocumentTitle() ); + + const String aSaveStr( RESTOHTML( STR_WEBVIEW_SAVE )); + aScript.SearchAndReplaceAll( String(RTL_CONSTASCII_USTRINGPARAM("$$2")), aSaveStr ); + + aScript.SearchAndReplaceAll( String(RTL_CONSTASCII_USTRINGPARAM("$$3")), maCGIPath ); + + aScript.SearchAndReplaceAll( String(RTL_CONSTASCII_USTRINGPARAM("$$4")), String::CreateFromInt32(mnWidthPixel) ); + aScript.SearchAndReplaceAll( String(RTL_CONSTASCII_USTRINGPARAM("$$5")), String::CreateFromInt32(mnHeightPixel) ); + + + String aDest( rPath ); + aDest += rDest; + + meEC.SetContext( STR_HTMLEXP_ERROR_CREATE_FILE, rDest ); + // write script file + { + EasyFile aFile; + SvStream* pStr; + nErr = aFile.createStream(aDest, pStr); + if(nErr == 0) + { + ByteString aStr( aScript, RTL_TEXTENCODING_UTF8 ); + *pStr << aStr.GetBuffer(); + + nErr = aFile.close(); + } + } + + if (mpProgress) + mpProgress->SetState(++mnPagesWritten); + + if( nErr != 0 ) + ErrorHandler::HandleError( nErr ); + + return nErr == 0; +} + +static const char * ASP_Scripts[] = { "common.inc", "webcast.asp", "show.asp", "savepic.asp", "poll.asp", "editpic.asp" }; + +/** erzeugt und speichert die f�r WebShow ben�tigte ASP Scripte */ +bool HtmlExport::CreateASPScripts() +{ + for( USHORT n = 0; n < (sizeof( ASP_Scripts ) / sizeof(char *)); n++ ) + { + String aScript; + + aScript.AssignAscii( ASP_Scripts[n] ); + if(!CopyScript(maExportPath, aScript, aScript)) + return false; + } + + if(!CopyScript(maExportPath, String(RTL_CONSTASCII_USTRINGPARAM("edit.asp")), maIndex )) + return false; + + return true; +} + + +static const char *PERL_Scripts[] = { "webcast.pl", "common.pl", "editpic.pl", "poll.pl", "savepic.pl", "show.pl" }; + +/** erzeugt und speichert die f�r WebShow ben�tigte PERL Scripte */ +bool HtmlExport::CreatePERLScripts() +{ + for( USHORT n = 0; n < (sizeof( PERL_Scripts ) / sizeof(char *)); n++ ) + { + String aScript; + aScript.AssignAscii( PERL_Scripts[n] ); + if(!CopyScript(maExportPath, aScript, aScript, true)) + return false; + } + + if(!CopyScript(maExportPath, String( RTL_CONSTASCII_USTRINGPARAM("edit.pl")), maIndex, true )) + return false; + + if(!CopyScript(maExportPath, String( RTL_CONSTASCII_USTRINGPARAM("index.pl")), maIndexUrl, true )) + return false; + + return true; +} + +/** Erzeugt eine Liste mit den Namen der gespeicherten Images */ +bool HtmlExport::CreateImageFileList() +{ + String aStr; + for( USHORT nSdPage = 0; nSdPage < mnSdPageCount; nSdPage++) + { + aStr += String::CreateFromInt32( nSdPage + 1 ); + aStr.Append(sal_Unicode(';')); + aStr += maURLPath; + aStr += *mpImageFiles[nSdPage]; + aStr.AppendAscii( "\r\n" ); + } + + String aFileName( RTL_CONSTASCII_USTRINGPARAM("picture.txt") ); + bool bOk = WriteHtml( aFileName, false, aStr ); + + if (mpProgress) + mpProgress->SetState(++mnPagesWritten); + + return bOk; +} + +/** Erzeugt das File mit der aktuellen Seitennumer */ +bool HtmlExport::CreateImageNumberFile() +{ + String aFull( maExportPath ); + String aFileName( RTL_CONSTASCII_USTRINGPARAM("currpic.txt") ); + aFull += aFileName; + + meEC.SetContext( STR_HTMLEXP_ERROR_CREATE_FILE, aFileName ); + EasyFile aFile; + SvStream* pStr; + ULONG nErr = aFile.createStream(aFull, pStr); + if(nErr == 0) + { + *pStr << (const char *)"1"; + nErr = aFile.close(); + } + + if (mpProgress) + mpProgress->SetState(++mnPagesWritten); + + if( nErr != 0 ) + ErrorHandler::HandleError( nErr ); + + return nErr == 0; +} + +// ===================================================================== + +String HtmlExport::InsertSound( const String& rSoundFile ) +{ + if( rSoundFile.Len() == 0 ) + return rSoundFile; + + String aStr( RTL_CONSTASCII_USTRINGPARAM("<embed src=\"") ); + INetURLObject aURL( rSoundFile ); + + DBG_ASSERT( aURL.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" ); + + aStr += String(aURL.getName()); + aStr.AppendAscii( "\" hidden=\"true\" autostart=\"true\">" ); + + CopyFile( rSoundFile, maExportPath ); + + return aStr; +} + +// ===================================================================== + +bool HtmlExport::CopyFile( const String& rSourceFile, const String& rDestPath ) +{ + DirEntry aSourceEntry( rSourceFile ); + DirEntry aDestEntry( rDestPath ); + + meEC.SetContext( STR_HTMLEXP_ERROR_COPY_FILE, aSourceEntry.GetName(), rDestPath ); + FSysError nError = aSourceEntry.CopyTo( aDestEntry, FSYS_ACTION_COPYFILE ); + + if( nError != FSYS_ERR_OK ) + { + ErrorHandler::HandleError(nError); + return false; + } + else + { + return true; + } +} + +// ===================================================================== + +bool HtmlExport::checkFileExists( Reference< ::com::sun::star::ucb::XSimpleFileAccess >& xFileAccess, String const & aFileName ) +{ + try + { + OUString url( maExportPath ); + url += aFileName; + return xFileAccess->exists( url ); + } + catch( com::sun::star::uno::Exception& e ) + { + (void)e; + DBG_ERROR((OString("sd::HtmlExport::checkFileExists(), exception caught: ") + + rtl::OUStringToOString( comphelper::anyToString( cppu::getCaughtException() ), RTL_TEXTENCODING_UTF8 )).getStr() ); + } + + return false; +} + +// --------------------------------------------------------------------- + +bool HtmlExport::checkForExistingFiles() +{ + bool bFound = false; + + try + { + Reference< XMultiServiceFactory > xMsf( ::comphelper::getProcessServiceFactory() ); + Reference< ::com::sun::star::ucb::XSimpleFileAccess > xFA( xMsf->createInstance( + OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.SimpleFileAccess"))), UNO_QUERY_THROW ); + + sal_uInt16 nSdPage; + for( nSdPage = 0; !bFound && (nSdPage < mnSdPageCount); nSdPage++) + { + if( (mpImageFiles[nSdPage] && checkFileExists( xFA, *mpImageFiles[nSdPage] )) || + (mpHTMLFiles[nSdPage] && checkFileExists( xFA, *mpHTMLFiles[nSdPage] )) || + (mpPageNames[nSdPage] && checkFileExists( xFA, *mpPageNames[nSdPage] )) || + (mpTextFiles[nSdPage] && checkFileExists( xFA, *mpTextFiles[nSdPage] )) ) + { + bFound = true; + } + } + + if( !bFound && mbDownload ) + bFound = checkFileExists( xFA, maDocFileName ); + + if( !bFound && mbFrames ) + bFound = checkFileExists( xFA, maFramePage ); + + if( bFound ) + { + ResMgr *pResMgr = CREATERESMGR( dbw ); + if( pResMgr ) + { + ResId aResId( 4077, *pResMgr ); + String aMsg( aResId ); + + OUString aSystemPath; + osl::FileBase::getSystemPathFromFileURL( maExportPath, aSystemPath ); + aMsg.SearchAndReplaceAscii( "%FILENAME", aSystemPath ); + WarningBox aWarning( 0, WB_YES_NO | WB_DEF_YES, aMsg ); + aWarning.SetImage( WarningBox::GetStandardImage() ); + bFound = ( RET_NO == aWarning.Execute() ); + + delete pResMgr; + } + else + { + bFound = false; + } + } + } + catch( Exception& e ) + { + (void)e; + DBG_ERROR((OString("sd::HtmlExport::checkForExistingFiles(), exception caught: ") + + rtl::OUStringToOString( comphelper::anyToString( cppu::getCaughtException() ), RTL_TEXTENCODING_UTF8 )).getStr() ); + bFound = false; + } + + return bFound; +} + +// --------------------------------------------------------------------- + +String HtmlExport::StringToURL( const String& rURL ) +{ + return rURL; +/* + return StringToHTMLString(rURL); + OUString aURL( StringToHTMLString(rURL) ); + + aURL = Uri::encode( aURL, rtl_UriCharClassUric, rtl_UriEncodeCheckEscapes, RTL_TEXTENCODING_UTF8); + return String( aURL ); +*/ +} + +String HtmlExport::GetButtonName( int nButton ) const +{ + String aName; + aName.AssignAscii( pButtonNames[nButton] ); + return aName; +} + +// ===================================================================== +EasyFile::EasyFile() +{ + pMedium = NULL; + pOStm = NULL; + bOpen = false; +} + +// ===================================================================== +EasyFile::~EasyFile() +{ + if( bOpen ) + close(); +} + +// ===================================================================== +ULONG EasyFile::createStream( const String& rUrl, SvStream* &rpStr ) +{ + ULONG nErr = 0; + + if(bOpen) + nErr = close(); + + String aFileName; + + if( nErr == 0 ) + nErr = createFileName( rUrl, aFileName ); + + if( nErr == 0 ) + { + pOStm = ::utl::UcbStreamHelper::CreateStream( aFileName, STREAM_WRITE | STREAM_TRUNC ); + if( pOStm ) + { + bOpen = true; + nErr = pOStm->GetError(); + } + else + { + nErr = ERRCODE_SFX_CANTCREATECONTENT; + } + } + + if( nErr != 0 ) + { + bOpen = false; + delete pMedium; + delete pOStm; + pOStm = NULL; + } + + rpStr = pOStm; + + return nErr; +} + +// ===================================================================== +ULONG EasyFile::createFileName( const String& rURL, String& rFileName ) +{ + ULONG nErr = 0; + + if( bOpen ) + nErr = close(); + + if( nErr == 0 ) + { + INetURLObject aURL( rURL ); + + if( aURL.GetProtocol() == INET_PROT_NOT_VALID ) + { + String aURLStr; + ::utl::LocalFileHelper::ConvertPhysicalNameToURL( rURL, aURLStr ); + aURL = INetURLObject( aURLStr ); + } + DBG_ASSERT( aURL.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" ); + rFileName = aURL.GetMainURL( INetURLObject::NO_DECODE ); + } + + return nErr; +} + +// ===================================================================== +ULONG EasyFile::close() +{ + ULONG nErr = 0; + + delete pOStm; + pOStm = NULL; + + bOpen = false; + + if( pMedium ) + { + // uebertragen + pMedium->Close(); + pMedium->Commit(); + + nErr = pMedium->GetError(); + + delete pMedium; + pMedium = NULL; + } + + return nErr; +} + +// ===================================================================== +// This class helps reporting errors during file i/o +// ===================================================================== + +HtmlErrorContext::HtmlErrorContext(Window *_pWin) +: ErrorContext(_pWin) +{ + mnResId = 0; +} + +// ===================================================================== + +BOOL HtmlErrorContext::GetString( ULONG, String& rCtxStr ) +{ + DBG_ASSERT( mnResId != 0, "No error context set" ); + if( mnResId == 0 ) + return false; + + rCtxStr = String( SdResId( mnResId ) ); + + rCtxStr.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM("$(URL1)")), maURL1 ); + rCtxStr.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM("$(URL2)")), maURL2 ); + + return true; +} + +// ===================================================================== + +void HtmlErrorContext::SetContext( USHORT nResId ) +{ + mnResId = nResId; + maURL1.Erase(); + maURL2.Erase(); +} + +// ===================================================================== + +void HtmlErrorContext::SetContext( USHORT nResId, const String& rURL ) +{ + mnResId = nResId; + maURL1 = rURL; + maURL2.Erase(); +} + +// ===================================================================== + +void HtmlErrorContext::SetContext( USHORT nResId, const String& rURL1, const String& rURL2 ) +{ + mnResId = nResId; + maURL1 = rURL1; + maURL2 = rURL2; +} + +// ===================================================================== + + diff --git a/sd/source/filter/html/htmlex.hxx b/sd/source/filter/html/htmlex.hxx new file mode 100644 index 000000000000..34ca8182d22f --- /dev/null +++ b/sd/source/filter/html/htmlex.hxx @@ -0,0 +1,240 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SD_HTMLEX_HXX +#define _SD_HTMLEX_HXX + +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/ucb/XSimpleFileAccess.hpp> +#include <vcl/gdimtf.hxx> +#include <svl/itemset.hxx> +#include "resltn.hxx" // enum PublishingResolution +#include <svtools/colrdlg.hxx> +#include <svtools/ehdl.hxx> + +#include "strings.hrc" +#include "DrawDocShell.hxx" +#include "Window.hxx" +#include "ViewShell.hxx" +#include "assclass.hxx" + +#ifndef _SD_RESID_HXX +#include "sdresid.hxx" +#endif +#include "pubdlg.hxx" + +#include <vector> +#include <boost/scoped_ptr.hpp> + +#define NUM_BUTTONS 12 + +#define PUB_LOWRES_WIDTH 640 +#define PUB_LOWRES_HEIGHT 480 +#define PUB_MEDRES_WIDTH 800 +#define PUB_MEDRES_HEIGHT 600 +#define PUB_HIGHRES_WIDTH 1024 +#define PUB_HIGHRES_HEIGHT 768 + +#define HtmlButtonThemaStr = "private://gallery/hidden/HtmlExportButtons"; + +class List; +class SfxProgress; +class SdrOutliner; +class SdPage; +class HtmlState; +class SdrTextObj; +class SdrPage; +class SdDrawDocument; +class ButtonSet; + +namespace sd { +class View; +} + +class HtmlErrorContext : public ErrorContext +{ +private: + USHORT mnResId; + String maURL1; + String maURL2; + +public: + HtmlErrorContext(Window *pWin=0); + ~HtmlErrorContext() {}; + + virtual BOOL GetString( ULONG nErrId, String& rCtxStr ); + + void SetContext( USHORT nResId ); + void SetContext( USHORT nResId, const String& rURL ); + void SetContext( USHORT nResId, const String& rURL1, const String& rURL2 ); +}; + +// ===================================================================== +// this class exports an Impress Document as a HTML Presentation +// ===================================================================== +class HtmlExport +{ + std::vector< SdPage* > maPages; + std::vector< SdPage* > maNotesPages; + + String maPath; + + SdDrawDocument* mpDoc; + ::sd::DrawDocShell* mpDocSh; + + HtmlErrorContext meEC; + + HtmlPublishMode meMode; + SfxProgress* mpProgress; + bool mbImpress; + USHORT mnSdPageCount; + USHORT mnPagesWritten; + bool mbContentsPage; + INT16 mnButtonThema; + UINT16 mnWidthPixel; + UINT16 mnHeightPixel; + PublishingFormat meFormat; + bool mbHeader; + bool mbNotes; + bool mbFrames; + bool mbKiosk; + String maIndex; + String maEMail; + String maAuthor; + String maHomePage; + String maInfo; + INT16 mnCompression; + String maDocFileName; + String maFramePage; + String mDocTitle; + bool mbDownload; + + bool mbAutoSlide; + UINT32 mnSlideDuration; + bool mbSlideSound; + bool mbHiddenSlides; + bool mbEndless; + + bool mbUserAttr; // die folgenden Farben werden fuer das <body> + Color maTextColor; // tag genutzt, wenn mbUserAttr true ist + Color maBackColor; + Color maLinkColor; + Color maVLinkColor; + Color maALinkColor; + Color maFirstPageColor; + bool mbDocColors; + + String maHTMLExtension; + String** mpHTMLFiles; + String** mpImageFiles; + String** mpPageNames; + String** mpTextFiles; + + String maExportPath; // Das Ausgabeverzeichnes bzw. die URL + String maIndexUrl; + String maURLPath; + String maCGIPath; + PublishingScript meScript; + + const String maHTMLHeader; + + boost::scoped_ptr< ButtonSet > mpButtonSet; + + SdrTextObj* GetLayoutTextObject(SdrPage* pPage); + + void SetDocColors( SdPage* pPage = NULL ); + + bool CreateImagesForPresPages(); + bool CreateHtmlTextForPresPages(); + bool CreateHtmlForPresPages(); + bool CreateContentPage(); + void CreateFileNames(); + bool CreateBitmaps(); + bool CreateOutlinePages(); + bool CreateFrames(); + bool CreateNotesPages(); + bool CreateNavBarFrames(); + + bool CreateASPScripts(); + bool CreatePERLScripts(); + bool CreateImageFileList(); + bool CreateImageNumberFile(); + + bool checkForExistingFiles(); + bool checkFileExists( ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess >& xFileAccess, String const & aFileName ); + + String getDocumentTitle(); + bool SavePresentation(); + + String CreateLink( const String& aLink, const String& aText, + const String& aTarget = String()) const; + String CreateImage( const String& aImage, const String& aAltText, INT16 nWidth = -1, INT16 nHeight = -1 ) const; + String CreateNavBar( USHORT nSdPage, bool bIsText ) const; + String CreateBodyTag() const; + + String ParagraphToHTMLString( SdrOutliner* pOutliner, ULONG nPara, const Color& rBackgroundColor ); + String TextAttribToHTMLString( SfxItemSet* pSet, HtmlState* pState, const Color& rBackgroundColor ); + + String CreateTextForTitle( SdrOutliner* pOutliner, SdPage* pPage, const Color& rBackgroundColor ); + String CreateTextForPage( SdrOutliner* pOutliner, SdPage* pPage, bool bHeadLine, const Color& rBackgroundColor ); + String CreateTextForNotesPage( SdrOutliner* pOutliner, SdPage* pPage, bool bHeadLine, const Color& rBackgroundColor ); + + String CreateHTMLCircleArea( ULONG nRadius, ULONG nCenterX, + ULONG nCenterY, const String& rHRef ) const; + String CreateHTMLPolygonArea( const ::basegfx::B2DPolyPolygon& rPolyPoly, Size aShift, double fFactor, const String& rHRef ) const; + String CreateHTMLRectArea( const Rectangle& rRect, + const String& rHRef ) const; + + String CreatePageURL( USHORT nPgNum ); + + String InsertSound( const String& rSoundFile ); + bool CopyFile( const String& rSourceFile, const String& rDestPath ); + bool CopyScript( const String& rPath, const String& rSource, const String& rDest, bool bUnix = false ); + + void InitProgress( USHORT nProgrCount ); + void ResetProgress(); + + String WriteMetaCharset() const; + + void InitExportParameters( const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& rParams); + void ExportHtml(); + void ExportKiosk(); + void ExportWebCast(); + + bool WriteHtml( const String& rFileName, bool bAddExtension, const String& rHtmlData ); + String GetButtonName( int nButton ) const; + + public: + HtmlExport( rtl::OUString aPath, const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& rParams, SdDrawDocument* pExpDoc, ::sd::DrawDocShell* pDocShell ); + virtual ~HtmlExport(); + + static String ColorToHTMLString( Color aColor ); + static String StringToHTMLString( const String& rString ); + static String StringToURL( const String& rURL ); +}; + +#endif // _SD_HTMLEX_HXX diff --git a/sd/source/filter/html/makefile.mk b/sd/source/filter/html/makefile.mk new file mode 100644 index 000000000000..dc228764323c --- /dev/null +++ b/sd/source/filter/html/makefile.mk @@ -0,0 +1,68 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. +PRJNAME=sd +TARGET=html +LIBTARGET=NO +ENABLE_EXCEPTIONS=TRUE; + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +INCPRE += ..$/..$/ui$/inc + +# --- Files -------------------------------------------------------- + +SLOFILES = $(SLO)$/HtmlOptionsDialog.obj\ + $(SLO)$/buttonset.obj \ + $(SLO)$/sdhtmlfilter.obj \ + $(SLO)$/htmlex.obj \ + $(SLO)$/htmlattr.obj \ + $(SLO)$/pubdlg.obj + +SRS1NAME=$(TARGET) +SRC1FILES = pubdlg.src + +LIB1TARGET= $(SLB)$/$(TARGET).lib +LIB1OBJFILES = \ + $(SLO)$/HtmlOptionsDialog.obj\ + $(SLO)$/sdhtmlfilter.obj \ + $(SLO)$/buttonset.obj \ + $(SLO)$/htmlex.obj + +LIB2TARGET= $(SLB)$/$(TARGET)_ui.lib +LIB2OBJFILES = \ + $(SLO)$/htmlattr.obj \ + $(SLO)$/buttonset.obj \ + $(SLO)$/pubdlg.obj + +# --- Targets -------------------------------------------------------------- + +.INCLUDE : target.mk diff --git a/sd/source/filter/html/pubdlg.cxx b/sd/source/filter/html/pubdlg.cxx new file mode 100644 index 000000000000..55e141f8d4cb --- /dev/null +++ b/sd/source/filter/html/pubdlg.cxx @@ -0,0 +1,1755 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" + +#ifdef SD_DLLIMPLEMENTATION +#undef SD_DLLIMPLEMENTATION +#endif +#include <com/sun/star/beans/PropertyValue.hpp> +#include <unotools/ucbstreamhelper.hxx> +#include <vcl/lstbox.hxx> +#include <svtools/FilterConfigItem.hxx> +#ifndef _SV_BUTTON_HXX +#include <vcl/button.hxx> +#endif +#include <vcl/fixed.hxx> +#include <vcl/combobox.hxx> +#include <svtools/svmedit.hxx> +#include <svl/intitem.hxx> +#include <svl/aeitem.hxx> +#include <svl/itemset.hxx> +#include <svl/stritem.hxx> +#include <vcl/msgbox.hxx> +#include <svtools/valueset.hxx> +#include <vcl/graph.hxx> +#include <svl/eitem.hxx> +#include <svtools/colrdlg.hxx> +#include <editeng/colritem.hxx> +#include <tools/list.hxx> +#include <sdiocmpt.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/app.hxx> +#include <pres.hxx> +#include <unotools/useroptions.hxx> +#include <unotools/pathoptions.hxx> + +#include "sdresid.hxx" +#include "sdattr.hxx" +#include "pubdlg.hrc" +#include "htmlattr.hxx" +#include "htmlex.hxx" +#include "helpids.h" +#include "buttonset.hxx" + +using namespace std; +using namespace rtl; +using namespace com::sun::star::uno; +using namespace com::sun::star::beans; + +extern void InterpolateFixedBitmap( FixedBitmap * pBitmap ); + +// Kennung fuer die Config Datei mit den Html Einstellungen +const UINT16 nMagic = (UINT16)0x1977; + +// Key fuer die soffice.ini +#define KEY_QUALITY "JPG-EXPORT-QUALITY" + +// Die Help Ids der einzelnen Seiten +ULONG aPageHelpIds[NOOFPAGES] = +{ + HID_SD_HTMLEXPORT_PAGE1, + HID_SD_HTMLEXPORT_PAGE2, + HID_SD_HTMLEXPORT_PAGE3, + HID_SD_HTMLEXPORT_PAGE4, + HID_SD_HTMLEXPORT_PAGE5, + HID_SD_HTMLEXPORT_PAGE6 +}; + +// ********************************************************************* +// Diese Klasse enthaelt alle Einstellungen des Html-Export Autopiloten +// ********************************************************************* +class SdPublishingDesign +{ +public: + String m_aDesignName; + + HtmlPublishMode m_eMode; + + // special WebCast options + PublishingScript m_eScript; + String m_aCGI; + String m_aURL; + + // special Kiosk options + BOOL m_bAutoSlide; + UINT32 m_nSlideDuration; + BOOL m_bEndless; + + // special HTML options + BOOL m_bContentPage; + BOOL m_bNotes; + + // misc options + UINT16 m_nResolution; + String m_aCompression; + PublishingFormat m_eFormat; + BOOL m_bSlideSound; + BOOL m_bHiddenSlides; + + // titel page information + String m_aAuthor; + String m_aEMail; + String m_aWWW; + String m_aMisc; + BOOL m_bDownload; + BOOL m_bCreated; // not used + + // buttons and colorscheme + INT16 m_nButtonThema; + BOOL m_bUserAttr; + Color m_aBackColor; + Color m_aTextColor; + Color m_aLinkColor; + Color m_aVLinkColor; + Color m_aALinkColor; + BOOL m_bUseAttribs; + BOOL m_bUseColor; + + SdPublishingDesign(); + + int operator ==(const SdPublishingDesign & rDesign) const; + friend SvStream& operator >> (SvStream& rIn, SdPublishingDesign& rDesign); + friend SvStream& operator << (SvStream& rOut, const SdPublishingDesign& rDesign); +}; + +// ===================================================================== +// Default Einstellungen erzeugen +// ===================================================================== +SdPublishingDesign::SdPublishingDesign() +{ + m_eMode = PUBLISH_HTML; + m_bContentPage = TRUE; + m_bNotes = TRUE; + + m_eFormat = FORMAT_PNG; + + String aFilterConfigPath( RTL_CONSTASCII_USTRINGPARAM( "Office.Common/Filter/Graphic/Export/JPG" ) ); + FilterConfigItem aFilterConfigItem( aFilterConfigPath ); + sal_Int32 nCompression = aFilterConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( KEY_QUALITY ) ), 75 ); + m_aCompression = UniString::CreateFromInt32( nCompression ); + m_aCompression.Append( sal_Unicode('%') ); + + SvtUserOptions aUserOptions; + + m_nResolution = PUB_LOWRES_WIDTH; + m_aAuthor = aUserOptions.GetFirstName(); + if( m_aAuthor.Len() && aUserOptions.GetLastName().getLength() ) + m_aAuthor += sal_Unicode(' '); + m_aAuthor += (String)aUserOptions.GetLastName(); + m_aEMail = aUserOptions.GetEmail(); + m_bDownload = FALSE; +//-/ m_bCreated = TRUE; + m_nButtonThema = -1; + + m_bUserAttr = FALSE; + m_bUseAttribs = TRUE; + m_bUseColor = TRUE; + + m_aBackColor = COL_WHITE; + m_aTextColor = COL_BLACK; + m_aLinkColor = COL_BLUE; + m_aVLinkColor = COL_LIGHTBLUE; + m_aALinkColor = COL_GRAY; + + m_eScript = SCRIPT_ASP; + + m_bAutoSlide = TRUE; + m_nSlideDuration = 15; + m_bEndless = TRUE; + + m_bSlideSound = TRUE; + m_bHiddenSlides = FALSE; +} + +// ===================================================================== +// Vergleicht die Member ohne den Namen zu beachten +// ===================================================================== +int SdPublishingDesign::operator ==(const SdPublishingDesign & rDesign) const +{ + return + ( + m_eMode == rDesign.m_eMode && + m_nResolution == rDesign.m_nResolution && + m_aCompression == rDesign.m_aCompression && + m_eFormat == rDesign.m_eFormat && + m_bHiddenSlides == rDesign.m_bHiddenSlides && + ( // compare html options + (m_eMode != PUBLISH_HTML && m_eMode != PUBLISH_FRAMES) || + ( + m_bContentPage == rDesign.m_bContentPage && + m_bNotes == rDesign.m_bNotes && + m_aAuthor == rDesign.m_aAuthor && + m_aEMail == rDesign.m_aEMail && + m_aWWW == rDesign.m_aWWW && + m_aMisc == rDesign.m_aMisc && + m_bDownload == rDesign.m_bDownload && +//-/ m_bCreated == rDesign.m_bCreated && + m_nButtonThema == rDesign.m_nButtonThema && + m_bUserAttr == rDesign.m_bUserAttr && + m_aBackColor == rDesign.m_aBackColor && + m_aTextColor == rDesign.m_aTextColor && + m_aLinkColor == rDesign.m_aLinkColor && + m_aVLinkColor == rDesign.m_aVLinkColor && + m_aALinkColor == rDesign.m_aALinkColor && + m_bUseAttribs == rDesign.m_bUseAttribs && + m_bSlideSound == rDesign.m_bSlideSound && + m_bUseColor == rDesign.m_bUseColor + ) + ) && + ( // compare kiosk options + (m_eMode != PUBLISH_KIOSK) || + ( + m_bAutoSlide == rDesign.m_bAutoSlide && + m_bSlideSound == rDesign.m_bSlideSound && + ( + !m_bAutoSlide || + ( + m_nSlideDuration == rDesign.m_nSlideDuration && + m_bEndless == rDesign.m_bEndless + ) + ) + ) + ) && + ( // compare WebCast options + (m_eMode != PUBLISH_WEBCAST) || + ( + m_eScript == rDesign.m_eScript && + ( + m_eScript != SCRIPT_PERL || + ( + m_aURL == rDesign.m_aURL && + m_aCGI == rDesign.m_aCGI + ) + ) + ) + ) + ); +} + +// ===================================================================== +// Dieses Design aus Stream laden +// ===================================================================== +SvStream& operator >> (SvStream& rIn, SdPublishingDesign& rDesign) +{ + SdIOCompat aIO(rIn, STREAM_READ); + + UINT16 nTemp16; + + rIn.ReadByteString( rDesign.m_aDesignName, RTL_TEXTENCODING_UTF8 ); + rIn >> nTemp16; + rDesign.m_eMode = (HtmlPublishMode)nTemp16; + rIn >> rDesign.m_bContentPage; + rIn >> rDesign.m_bNotes; + rIn >> rDesign.m_nResolution; + rIn.ReadByteString( rDesign.m_aCompression, RTL_TEXTENCODING_UTF8 ); + rIn >> nTemp16; + rDesign.m_eFormat = (PublishingFormat)nTemp16; + rIn.ReadByteString( rDesign.m_aAuthor, RTL_TEXTENCODING_UTF8 ); + rIn.ReadByteString( rDesign.m_aEMail, RTL_TEXTENCODING_UTF8 ); + rIn.ReadByteString( rDesign.m_aWWW, RTL_TEXTENCODING_UTF8 ); + rIn.ReadByteString( rDesign.m_aMisc, RTL_TEXTENCODING_UTF8 ); + rIn >> rDesign.m_bDownload; + rIn >> rDesign.m_bCreated; // not used + rIn >> rDesign.m_nButtonThema; + rIn >> rDesign.m_bUserAttr; + rIn >> rDesign.m_aBackColor; + rIn >> rDesign.m_aTextColor; + rIn >> rDesign.m_aLinkColor; + rIn >> rDesign.m_aVLinkColor; + rIn >> rDesign.m_aALinkColor; + rIn >> rDesign.m_bUseAttribs; + rIn >> rDesign.m_bUseColor; + + rIn >> nTemp16; + rDesign.m_eScript = (PublishingScript)nTemp16; + rIn.ReadByteString( rDesign.m_aURL, RTL_TEXTENCODING_UTF8 ); + rIn.ReadByteString( rDesign.m_aCGI, RTL_TEXTENCODING_UTF8 ); + + rIn >> rDesign.m_bAutoSlide; + rIn >> rDesign.m_nSlideDuration; + rIn >> rDesign.m_bEndless; + rIn >> rDesign.m_bSlideSound; + rIn >> rDesign.m_bHiddenSlides; + + return rIn; +} + +// ===================================================================== +// Dieses Design in Stream speichern +// ===================================================================== +SvStream& operator << (SvStream& rOut, const SdPublishingDesign& rDesign) +{ + // Letzter Parameter ist die aktuelle Versionsnummer des Codes + SdIOCompat aIO(rOut, STREAM_WRITE, 0); + + // Name + rOut.WriteByteString( rDesign.m_aDesignName, RTL_TEXTENCODING_UTF8 ); + + rOut << (UINT16)rDesign.m_eMode; + rOut << rDesign.m_bContentPage; + rOut << rDesign.m_bNotes; + rOut << rDesign.m_nResolution; + rOut.WriteByteString( rDesign.m_aCompression, RTL_TEXTENCODING_UTF8 ); + rOut << (UINT16)rDesign.m_eFormat; + rOut.WriteByteString( rDesign.m_aAuthor, RTL_TEXTENCODING_UTF8 ); + rOut.WriteByteString( rDesign.m_aEMail, RTL_TEXTENCODING_UTF8 ); + rOut.WriteByteString( rDesign.m_aWWW, RTL_TEXTENCODING_UTF8 ); + rOut.WriteByteString( rDesign.m_aMisc, RTL_TEXTENCODING_UTF8 ); + rOut << rDesign.m_bDownload; + rOut << rDesign.m_bCreated; // not used + rOut << rDesign.m_nButtonThema; + rOut << rDesign.m_bUserAttr; + rOut << rDesign.m_aBackColor; + rOut << rDesign.m_aTextColor; + rOut << rDesign.m_aLinkColor; + rOut << rDesign.m_aVLinkColor; + rOut << rDesign.m_aALinkColor; + rOut << rDesign.m_bUseAttribs; + rOut << rDesign.m_bUseColor; + + rOut << (UINT16)rDesign.m_eScript; + rOut.WriteByteString( rDesign.m_aURL, RTL_TEXTENCODING_UTF8 ); + rOut.WriteByteString( rDesign.m_aCGI, RTL_TEXTENCODING_UTF8 ); + + rOut << rDesign.m_bAutoSlide; + rOut << rDesign.m_nSlideDuration; + rOut << rDesign.m_bEndless; + rOut << rDesign.m_bSlideSound; + rOut << rDesign.m_bHiddenSlides; + + return rOut; +} + +// ********************************************************************* +// Dialog zur eingabe eines Namens fuer ein Design +// ********************************************************************* +class SdDesignNameDlg : public ModalDialog +{ +private: + Edit m_aEdit; + OKButton m_aBtnOK; + CancelButton m_aBtnCancel; + +public: + SdDesignNameDlg(Window* pWindow, const String& aName ); + + String GetDesignName(); + DECL_LINK( ModifyHdl, Edit* ); +}; + +// ********************************************************************* +// SdPublishingDlg Methoden +// ********************************************************************* + +// ===================================================================== +// Konstruktor des Dialogs +// ===================================================================== +SdPublishingDlg::SdPublishingDlg(Window* pWindow, DocumentType eDocType) +: ModalDialog(pWindow, SdResId( DLG_PUBLISHING )) +, mpButtonSet( new ButtonSet() ) +, aBottomLine( this, SdResId( BOTTOM_LINE ) ) +, aHelpButton(this,SdResId(BUT_HELP)) +, aCancelButton(this,SdResId(BUT_CANCEL)) +, aLastPageButton(this,SdResId(BUT_LAST)) +, aNextPageButton(this,SdResId(BUT_NEXT)) +, aFinishButton(this,SdResId(BUT_FINISH)) +, aAssistentFunc(NOOFPAGES) +, m_bButtonsDirty(TRUE) +, m_bDesignListDirty(FALSE) +, m_pDesign(NULL) +{ + m_bImpress = eDocType == DOCUMENT_TYPE_IMPRESS; + + CreatePages(); + Load(); + + //setzt die Ausgangsseite + aAssistentFunc.GotoPage(1); + aLastPageButton.Disable(); + + //Buttonbelegung + aFinishButton.SetClickHdl(LINK(this,SdPublishingDlg,FinishHdl)); + aLastPageButton.SetClickHdl(LINK(this,SdPublishingDlg,LastPageHdl)); + aNextPageButton.SetClickHdl(LINK(this,SdPublishingDlg,NextPageHdl)); + + pPage1_NewDesign->SetClickHdl(LINK(this,SdPublishingDlg,DesignHdl)); + pPage1_OldDesign->SetClickHdl(LINK(this,SdPublishingDlg,DesignHdl)); + pPage1_Designs->SetSelectHdl(LINK(this,SdPublishingDlg,DesignSelectHdl)); + pPage1_DelDesign->SetClickHdl(LINK(this,SdPublishingDlg,DesignDeleteHdl)); + + pPage2_Standard->SetClickHdl(LINK(this,SdPublishingDlg,BaseHdl)); + pPage2_Standard_FB->SetBorderStyle(WINDOW_BORDER_MONO); + pPage2_Frames->SetClickHdl(LINK(this,SdPublishingDlg,BaseHdl)); + pPage2_Frames_FB->SetBorderStyle(WINDOW_BORDER_MONO); + pPage2_Kiosk->SetClickHdl(LINK(this,SdPublishingDlg,BaseHdl)); + pPage2_Kiosk_FB->SetBorderStyle(WINDOW_BORDER_MONO); + pPage2_WebCast->SetClickHdl(LINK(this,SdPublishingDlg,BaseHdl)); + pPage2_WebCast_FB->SetBorderStyle(WINDOW_BORDER_MONO); + + pPage2_Content->SetClickHdl(LINK(this,SdPublishingDlg,ContentHdl)); + + pPage2_ASP->SetClickHdl(LINK(this,SdPublishingDlg,WebServerHdl)); + pPage2_PERL->SetClickHdl(LINK(this,SdPublishingDlg,WebServerHdl)); + String aText( UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("index")) ); + aText += String(SdResId(STR_HTMLEXP_DEFAULT_EXTENSION)); + pPage2_Index->SetText(aText); + pPage2_CGI->SetText( UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "/cgi-bin/" ) ) ); + + pPage3_Png->SetClickHdl(LINK(this,SdPublishingDlg, GfxFormatHdl)); + pPage3_Gif->SetClickHdl(LINK(this,SdPublishingDlg, GfxFormatHdl)); + pPage3_Jpg->SetClickHdl(LINK(this,SdPublishingDlg, GfxFormatHdl)); + pPage3_Quality->Enable(FALSE); + + pPage3_Resolution_1->SetClickHdl(LINK(this,SdPublishingDlg, ResolutionHdl )); + pPage3_Resolution_2->SetClickHdl(LINK(this,SdPublishingDlg, ResolutionHdl )); + pPage3_Resolution_3->SetClickHdl(LINK(this,SdPublishingDlg, ResolutionHdl )); + + pPage2_ChgDefault->SetClickHdl(LINK(this,SdPublishingDlg, SlideChgHdl)); + pPage2_ChgAuto->SetClickHdl(LINK(this,SdPublishingDlg, SlideChgHdl)); + pPage2_Duration->SetFormat( TIMEF_SEC ); + + pPage5_Buttons->SetSelectHdl(LINK(this,SdPublishingDlg, ButtonsHdl )); + pPage5_Buttons->SetStyle( pPage5_Buttons->GetStyle() | WB_VSCROLL ); + + pPage6_Back->SetClickHdl(LINK(this,SdPublishingDlg, ColorHdl )); + pPage6_Text->SetClickHdl(LINK(this,SdPublishingDlg, ColorHdl )); + pPage6_Link->SetClickHdl(LINK(this,SdPublishingDlg, ColorHdl )); + pPage6_VLink->SetClickHdl(LINK(this,SdPublishingDlg, ColorHdl )); + pPage6_ALink->SetClickHdl(LINK(this,SdPublishingDlg, ColorHdl )); + + pPage6_DocColors->Check(); + + FreeResource(); + + pPage3_Quality->InsertEntry( UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "25%" ) ) ); + pPage3_Quality->InsertEntry( UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "50%" ) ) ); + pPage3_Quality->InsertEntry( UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "75%" ) ) ); + pPage3_Quality->InsertEntry( UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "100%" ) ) ); + + pPage5_Buttons->SetColCount( 1 ); + pPage5_Buttons->SetLineCount( 4 ); + pPage5_Buttons->SetExtraSpacing( 1 ); + + for( UINT16 nIndex = 0; nIndex < m_pDesignList->Count(); nIndex++ ) + { + SdPublishingDesign *pDesign = (SdPublishingDesign*) + m_pDesignList->GetObject(nIndex); + + pPage1_Designs->InsertEntry(pDesign->m_aDesignName); + } + + pPage6_Preview->SetBorderStyle(WINDOW_BORDER_MONO); + + SetDefaults(); + + SetHelpId(aPageHelpIds[0]); + + aNextPageButton.GrabFocus(); +} + +// ===================================================================== +// Destruktor +// ===================================================================== +SdPublishingDlg::~SdPublishingDlg() +{ + if( m_pDesignList ) + { + for( UINT16 nIndex = 0; nIndex < m_pDesignList->Count(); nIndex++ ) + delete (SdPublishingDesign*)m_pDesignList->GetObject(nIndex); + } + + delete m_pDesignList; + RemovePages(); +} + +// ===================================================================== +// Dialog Controls erzeugen und in die Seiten des Assistenten einbinden +// ===================================================================== +void SdPublishingDlg::CreatePages() +{ + // Page 1 + aAssistentFunc.InsertControl(1, + pPage1_Bmp = new FixedBitmap(this,SdResId(PAGE1_BMP))); + aAssistentFunc.InsertControl(1, + pPage1_Titel = new FixedLine(this,SdResId(PAGE1_TITEL))); + aAssistentFunc.InsertControl(1, + pPage1_NewDesign = new RadioButton(this,SdResId(PAGE1_NEW_DESIGN))); + aAssistentFunc.InsertControl(1, + pPage1_OldDesign = new RadioButton(this,SdResId(PAGE1_OLD_DESIGN))); + aAssistentFunc.InsertControl(1, + pPage1_Designs = new ListBox(this,SdResId(PAGE1_DESIGNS))); + aAssistentFunc.InsertControl(1, + pPage1_DelDesign = new PushButton(this,SdResId(PAGE1_DEL_DESIGN))); + aAssistentFunc.InsertControl(1, + pPage1_Desc = new FixedText(this,SdResId(PAGE1_DESC))); + + + // Page 2 + aAssistentFunc.InsertControl(2, + pPage2_Bmp = new FixedBitmap(this,SdResId(PAGE2_BMP))); + aAssistentFunc.InsertControl(2, + pPage2_Titel = new FixedLine(this,SdResId(PAGE2_TITEL ))); + aAssistentFunc.InsertControl(2, + pPage2_Standard = new RadioButton(this,SdResId(PAGE2_STANDARD))); + aAssistentFunc.InsertControl(2, + pPage2_Frames = new RadioButton(this,SdResId(PAGE2_FRAMES))); + aAssistentFunc.InsertControl(2, + pPage2_Kiosk = new RadioButton(this,SdResId(PAGE2_KIOSK))); + aAssistentFunc.InsertControl(2, + pPage2_WebCast = new RadioButton(this,SdResId(PAGE2_WEBCAST))); + aAssistentFunc.InsertControl(2, + pPage2_Standard_FB = new FixedBitmap(this,SdResId(PAGE2_NOFRAMES_FB))); + aAssistentFunc.InsertControl(2, + pPage2_Frames_FB = new FixedBitmap(this,SdResId(PAGE2_FRAMES_FB))); + aAssistentFunc.InsertControl(2, + pPage2_Kiosk_FB = new FixedBitmap(this,SdResId(PAGE2_KIOSK_FB))); + aAssistentFunc.InsertControl(2, + pPage2_WebCast_FB = new FixedBitmap(this,SdResId(PAGE2_WEBCAST_FB))); + + aAssistentFunc.InsertControl(2, + pPage2_Titel_Html = new FixedLine(this,SdResId(PAGE2_TITEL_HTML))); + aAssistentFunc.InsertControl(2, + pPage2_Content = new CheckBox(this,SdResId(PAGE2_CONTENT))); + if(m_bImpress) + aAssistentFunc.InsertControl(2, + pPage2_Notes = new CheckBox(this,SdResId(PAGE2_NOTES))); + + aAssistentFunc.InsertControl(2, + pPage2_Titel_WebCast = new FixedLine(this,SdResId(PAGE2_TITEL_WEBCAST))); + aAssistentFunc.InsertControl(2, + pPage2_Index_txt = new FixedText(this,SdResId(PAGE2_INDEX_TXT))); + aAssistentFunc.InsertControl(2, + pPage2_Index = new Edit(this,SdResId(PAGE2_INDEX))); + aAssistentFunc.InsertControl(2, + pPage2_ASP = new RadioButton(this,SdResId(PAGE2_ASP))); + aAssistentFunc.InsertControl(2, + pPage2_PERL = new RadioButton(this,SdResId(PAGE2_PERL))); + aAssistentFunc.InsertControl(2, + pPage2_URL_txt = new FixedText(this,SdResId(PAGE2_URL_TXT))); + aAssistentFunc.InsertControl(2, + pPage2_URL = new Edit(this,SdResId(PAGE2_URL))); + aAssistentFunc.InsertControl(2, + pPage2_CGI_txt = new FixedText(this,SdResId(PAGE2_CGI_TXT))); + aAssistentFunc.InsertControl(2, + pPage2_CGI = new Edit(this,SdResId(PAGE2_CGI))); + aAssistentFunc.InsertControl(2, + pPage2_Vert = new FixedLine( this,SdResId( PAGE2_VERT ))); + aAssistentFunc.InsertControl(2, + pPage2_Titel_Kiosk = new FixedLine(this,SdResId(PAGE2_TITEL_KIOSK))); + aAssistentFunc.InsertControl(2, + pPage2_ChgDefault = new RadioButton(this,SdResId(PAGE2_CHG_DEFAULT))); + aAssistentFunc.InsertControl(2, + pPage2_ChgAuto = new RadioButton(this,SdResId(PAGE2_CHG_AUTO))); + aAssistentFunc.InsertControl(2, + pPage2_Duration_txt = new FixedText(this,SdResId(PAGE2_DURATION_TXT))); + aAssistentFunc.InsertControl(2, + pPage2_Duration = new TimeField(this,SdResId(PAGE2_DURATION_TMF))); + aAssistentFunc.InsertControl(2, + pPage2_Endless = new CheckBox(this,SdResId(PAGE2_ENDLESS))); + + // Page 3 + aAssistentFunc.InsertControl(3, + pPage3_Bmp = new FixedBitmap(this,SdResId(PAGE3_BMP))); + aAssistentFunc.InsertControl(3, + pPage3_Titel1 = new FixedLine(this,SdResId(PAGE3_TITEL_1))); + aAssistentFunc.InsertControl(3, + pPage3_Png = new RadioButton(this,SdResId(PAGE3_PNG))); + aAssistentFunc.InsertControl(3, + pPage3_Gif = new RadioButton(this,SdResId(PAGE3_GIF))); + aAssistentFunc.InsertControl(3, + pPage3_Jpg = new RadioButton(this,SdResId(PAGE3_JPG))); + aAssistentFunc.InsertControl(3, + pPage3_Quality_txt = new FixedText(this,SdResId(PAGE3_QUALITY_TXT))); + aAssistentFunc.InsertControl(3, + pPage3_Quality = new ComboBox(this,SdResId(PAGE3_QUALITY))); + aAssistentFunc.InsertControl(3, + pPage3_Vert = new FixedLine( this,SdResId( PAGE3_VERT ))); + aAssistentFunc.InsertControl(3, + pPage3_Titel2 = new FixedLine(this,SdResId(PAGE3_TITEL_2))); + aAssistentFunc.InsertControl(3, + pPage3_Resolution_1 = new RadioButton(this,SdResId(PAGE3_RESOLUTION_1))); + aAssistentFunc.InsertControl(3, + pPage3_Resolution_2 = new RadioButton(this,SdResId(PAGE3_RESOLUTION_2))); + aAssistentFunc.InsertControl(3, + pPage3_Resolution_3 = new RadioButton(this,SdResId(PAGE3_RESOLUTION_3))); + aAssistentFunc.InsertControl(3, + pPage3_Titel3 = new FixedLine(this,SdResId(PAGE3_TITEL_3))); + aAssistentFunc.InsertControl(3, + pPage3_SldSound = new CheckBox(this,SdResId(PAGE3_SLD_SOUND))); + aAssistentFunc.InsertControl(3, + pPage3_HiddenSlides = new CheckBox(this,SdResId(PAGE3_HIDDEN_SLIDES))); + + // Seite 4 + aAssistentFunc.InsertControl(4, + pPage4_Bmp = new FixedBitmap(this,SdResId(PAGE4_BMP))); + aAssistentFunc.InsertControl(4, + pPage4_Titel1 = new FixedLine(this,SdResId(PAGE4_TITEL_1))); + aAssistentFunc.InsertControl(4, + pPage4_Author_txt = new FixedText(this,SdResId(PAGE4_AUTHOR_TXT))); + aAssistentFunc.InsertControl(4, + pPage4_Author = new Edit(this,SdResId(PAGE4_AUTHOR))); + aAssistentFunc.InsertControl(4, + pPage4_Email_txt = new FixedText(this,SdResId(PAGE4_EMAIL_TXT))); + aAssistentFunc.InsertControl(4, + pPage4_Email = new Edit(this,SdResId(PAGE4_EMAIL_EDIT))); + aAssistentFunc.InsertControl(4, + pPage4_WWW_txt = new FixedText(this,SdResId(PAGE4_WWW_TXT))); + aAssistentFunc.InsertControl(4, + pPage4_WWW = new Edit(this,SdResId(PAGE4_WWW_EDIT))); + aAssistentFunc.InsertControl(4, + pPage4_Titel2 = new FixedText(this,SdResId(PAGE4_TITEL_2))); + aAssistentFunc.InsertControl(4, + pPage4_Misc = new MultiLineEdit(this,SdResId(PAGE4_MISC))); + if(m_bImpress) + aAssistentFunc.InsertControl(4, + pPage4_Download = new CheckBox(this,SdResId(PAGE4_DOWNLOAD))); +//-/ aAssistentFunc.InsertControl(4, +//-/ pPage4_Created = new CheckBox(this,SdResId(PAGE4_CREATED))); + + // Seite 5 + aAssistentFunc.InsertControl(5, + pPage5_Bmp = new FixedBitmap(this,SdResId(PAGE5_BMP))); + aAssistentFunc.InsertControl(5, + pPage5_Titel = new FixedLine(this,SdResId(PAGE5_TITEL))); + aAssistentFunc.InsertControl(5, + pPage5_TextOnly = new CheckBox(this, SdResId(PAGE5_TEXTONLY))); + aAssistentFunc.InsertControl(5, + pPage5_Buttons = new ValueSet(this,SdResId(PAGE5_BUTTONS))); + + // Seite 6 + aAssistentFunc.InsertControl(6, + pPage6_Bmp = new FixedBitmap(this,SdResId(PAGE6_BMP))); + aAssistentFunc.InsertControl(6, + pPage6_Titel = new FixedLine(this,SdResId(PAGE6_TITEL))); + aAssistentFunc.InsertControl(6, + pPage6_DocColors = new RadioButton(this,SdResId(PAGE6_DOCCOLORS))); + aAssistentFunc.InsertControl(6, + pPage6_Default = new RadioButton(this,SdResId(PAGE6_DEFAULT))); + aAssistentFunc.InsertControl(6, + pPage6_User = new RadioButton(this,SdResId(PAGE6_USER))); + aAssistentFunc.InsertControl(6, + pPage6_Text = new PushButton(this,SdResId(PAGE6_TEXT))); + aAssistentFunc.InsertControl(6, + pPage6_Link = new PushButton(this,SdResId(PAGE6_LINK))); + aAssistentFunc.InsertControl(6, + pPage6_ALink = new PushButton(this,SdResId(PAGE6_ALINK))); + aAssistentFunc.InsertControl(6, + pPage6_VLink = new PushButton(this,SdResId(PAGE6_VLINK))); + aAssistentFunc.InsertControl(6, + pPage6_Back = new PushButton(this,SdResId(PAGE6_BACK))); + aAssistentFunc.InsertControl(6, + pPage6_Preview = new SdHtmlAttrPreview(this,SdResId(PAGE6_PREVIEW))); + + InterpolateFixedBitmap(pPage1_Bmp); + + InterpolateFixedBitmap(pPage2_Bmp); + InterpolateFixedBitmap(pPage2_Standard_FB); + InterpolateFixedBitmap(pPage2_Frames_FB); + InterpolateFixedBitmap(pPage2_Kiosk_FB); + InterpolateFixedBitmap(pPage2_WebCast_FB); + + InterpolateFixedBitmap(pPage3_Bmp); + InterpolateFixedBitmap(pPage4_Bmp); + + InterpolateFixedBitmap(pPage5_Bmp); + InterpolateFixedBitmap(pPage6_Bmp); +} + +// ===================================================================== +// Dialog Controls wieder entfernen +// ===================================================================== +void SdPublishingDlg::RemovePages() +{ + delete pPage1_Bmp; + delete pPage1_Titel; + delete pPage1_NewDesign; + delete pPage1_OldDesign; + delete pPage1_Designs; + delete pPage1_DelDesign; + delete pPage1_Desc; + + delete pPage2_Bmp; + delete pPage2_Titel; + delete pPage2_Standard; + delete pPage2_Frames; + delete pPage2_Kiosk; + delete pPage2_WebCast; + delete pPage2_Standard_FB; + delete pPage2_Frames_FB; + delete pPage2_Kiosk_FB; + delete pPage2_WebCast_FB; + + delete pPage2_Titel_Html; + delete pPage2_Content; + if(m_bImpress) + delete pPage2_Notes; + + delete pPage2_Vert; + delete pPage2_Titel_WebCast; + delete pPage2_Index_txt; + delete pPage2_Index; + delete pPage2_ASP; + delete pPage2_PERL; + delete pPage2_URL_txt; + delete pPage2_URL; + delete pPage2_CGI_txt; + delete pPage2_CGI; + + delete pPage2_Titel_Kiosk; + delete pPage2_ChgDefault; + delete pPage2_ChgAuto; + delete pPage2_Duration_txt; + delete pPage2_Duration; + delete pPage2_Endless; + + delete pPage3_Bmp; + delete pPage3_Titel1; + delete pPage3_Png; + delete pPage3_Gif; + delete pPage3_Jpg; + delete pPage3_Quality_txt; + delete pPage3_Quality; + delete pPage3_Vert; + delete pPage3_Titel2; + delete pPage3_Resolution_1; + delete pPage3_Resolution_2; + delete pPage3_Resolution_3; + delete pPage3_Titel3; + delete pPage3_SldSound; + delete pPage3_HiddenSlides; + + delete pPage4_Bmp; + delete pPage4_Titel1; + delete pPage4_Author_txt; + delete pPage4_Author; + delete pPage4_Email_txt; + delete pPage4_Email; + delete pPage4_WWW_txt; + delete pPage4_WWW; + delete pPage4_Titel2; + delete pPage4_Misc; + if(m_bImpress) + delete pPage4_Download; +//-/ delete pPage4_Created; + + delete pPage5_Bmp; + delete pPage5_Titel; + delete pPage5_TextOnly; + delete pPage5_Buttons; + + delete pPage6_Bmp; + delete pPage6_Titel; + delete pPage6_Default; + delete pPage6_User; + delete pPage6_Back; + delete pPage6_Text; + delete pPage6_Link; + delete pPage6_VLink; + delete pPage6_ALink; + delete pPage6_DocColors; + delete pPage6_Preview; +} + +// ===================================================================== +// Dialog mit defaultwerten initialisieren +// ===================================================================== +void SdPublishingDlg::SetDefaults() +{ + SdPublishingDesign aDefault; + SetDesign(&aDefault); + + pPage1_NewDesign->Check(TRUE); + pPage1_OldDesign->Check(FALSE); + UpdatePage(); +} + +// ===================================================================== +// Das SfxItemSet mit den Einstellungen des Dialogs fuettern +// ===================================================================== +void SdPublishingDlg::GetParameterSequence( Sequence< PropertyValue >& rParams ) +{ + std::vector< PropertyValue > aProps; + + PropertyValue aValue; + + + // Page 2 + aValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "PublishMode" ) ); + aValue.Value <<= (sal_Int32)(pPage2_Standard->IsChecked()?PUBLISH_HTML: + pPage2_Frames->IsChecked()?PUBLISH_FRAMES: + pPage2_Kiosk->IsChecked()?PUBLISH_KIOSK:PUBLISH_WEBCAST); + aProps.push_back( aValue ); + + aValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsExportContentsPage" ) ); + aValue.Value <<= (sal_Bool)pPage2_Content->IsChecked(); + aProps.push_back( aValue ); + + if(m_bImpress) + { + aValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsExportNotes" ) ); + aValue.Value <<= (sal_Bool)pPage2_Notes->IsChecked(); + aProps.push_back( aValue ); + } + + if( pPage2_WebCast->IsChecked() ) + { + aValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "WebCastScriptLanguage" ) ); + if( pPage2_ASP->IsChecked() ) + aValue.Value <<= OUString( RTL_CONSTASCII_USTRINGPARAM( "asp" ) ); + else + aValue.Value <<= OUString( RTL_CONSTASCII_USTRINGPARAM( "perl" ) ); + aProps.push_back( aValue ); + + aValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "WebCastCGIURL" ) ); + aValue.Value <<= OUString( pPage2_CGI->GetText() ); + aProps.push_back( aValue ); + + aValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "WebCastTargetURL" ) ); + aValue.Value <<= OUString( pPage2_URL->GetText() ); + aProps.push_back( aValue ); + } + aValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "IndexURL" ) ); + aValue.Value <<= OUString( pPage2_Index->GetText() ); + aProps.push_back( aValue ); + + + if( pPage2_Kiosk->IsChecked() && pPage2_ChgAuto->IsChecked() ) + { + aValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "KioskSlideDuration" ) ); + aValue.Value <<= (sal_uInt32)pPage2_Duration->GetTime().GetMSFromTime() / 1000; + aProps.push_back( aValue ); + + aValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "KioskEndless" ) ); + aValue.Value <<= (sal_Bool)pPage2_Endless->IsChecked(); + aProps.push_back( aValue ); + } + + // Page 3 + + aValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "Width" ) ); + sal_Int32 nTmpWidth = 512; + if( pPage3_Resolution_2->IsChecked() ) + nTmpWidth = 640; + else if( pPage3_Resolution_3->IsChecked() ) + nTmpWidth = 800; + + aValue.Value <<= nTmpWidth; + aProps.push_back( aValue ); + + aValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "Compression" ) ); + aValue.Value <<= OUString( pPage3_Quality->GetText() ); + aProps.push_back( aValue ); + + aValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "Format" ) ); + sal_Int32 nFormat; + if( pPage3_Png->IsChecked() ) + nFormat = static_cast<sal_Int32>(FORMAT_PNG); + else if( pPage3_Gif->IsChecked() ) + nFormat = static_cast<sal_Int32>(FORMAT_GIF); + else + nFormat = static_cast<sal_Int32>(FORMAT_JPG); + aValue.Value <<= nFormat; + aProps.push_back( aValue ); + + aValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "SlideSound" ) ); + aValue.Value <<= pPage3_SldSound->IsChecked() ? sal_True : sal_False; + aProps.push_back( aValue ); + + aValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "HiddenSlides" ) ); + aValue.Value <<= pPage3_HiddenSlides->IsChecked() ? sal_True : sal_False; + aProps.push_back( aValue ); + + // Page 4 + aValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "Author" ) ); + aValue.Value <<= OUString( pPage4_Author->GetText() ); + aProps.push_back( aValue ); + + aValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "EMail" ) ); + aValue.Value <<= OUString( pPage4_Email->GetText() ); + aProps.push_back( aValue ); + + // #92433# try to guess protocol for user's homepage + INetURLObject aHomeURL( pPage4_WWW->GetText(), + INET_PROT_HTTP, // default proto is HTTP + INetURLObject::ENCODE_ALL ); + + aValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "HomepageURL" ) ); + aValue.Value <<= OUString( aHomeURL.GetMainURL( INetURLObject::NO_DECODE ) ); + aProps.push_back( aValue ); + + aValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "UserText" ) ); + aValue.Value <<= OUString( pPage4_Misc->GetText() ); + aProps.push_back( aValue ); + + if( m_bImpress ) + { + aValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "EnableDownload" ) ); + aValue.Value <<= (sal_Bool)pPage4_Download->IsChecked(); + aProps.push_back( aValue ); + } + + // Page 5 + if( !pPage5_TextOnly->IsChecked() ) + { + aValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "UseButtonSet" ) ); + aValue.Value <<= (sal_Int32)(pPage5_Buttons->GetSelectItemId() - 1); + aProps.push_back( aValue ); + } + + // Page 6 + if( pPage6_User->IsChecked() ) + { + aValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "BackColor" ) ); + aValue.Value <<= (sal_Int32)m_aBackColor.GetColor(); + aProps.push_back( aValue ); + + aValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "TextColor" ) ); + aValue.Value <<= (sal_Int32)m_aTextColor.GetColor(); + aProps.push_back( aValue ); + + aValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "LinkColor" ) ); + aValue.Value <<= (sal_Int32)m_aLinkColor.GetColor(); + aProps.push_back( aValue ); + + aValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "VLinkColor" ) ); + aValue.Value <<= (sal_Int32)m_aVLinkColor.GetColor(); + aProps.push_back( aValue ); + + aValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "ALinkColor" ) ); + aValue.Value <<= (sal_Int32)m_aALinkColor.GetColor(); + aProps.push_back( aValue ); + } + + if( pPage6_DocColors->IsChecked() ) + { + aValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsUseDocumentColors" ) ); + aValue.Value <<= (sal_Bool)sal_True; + aProps.push_back( aValue ); + } + + // Seite 6 +// aSet.Put(SfxBoolItem(ATTR_PUBLISH_SLIDESOUND,pPage6_Sound->IsChecked())); + + + rParams.realloc( aProps.size() ); + PropertyValue* pParams = rParams.getArray(); + + for( std::vector< PropertyValue >::iterator i = aProps.begin(); i != aProps.end(); i++ ) + { + *pParams++ = (*i); + } +} + +// ===================================================================== +// Clickhandler fuer die Radiobuttons zur Designauswahl +// ===================================================================== +IMPL_LINK( SdPublishingDlg, DesignHdl, RadioButton *, pButton ) +{ + if(pButton == pPage1_NewDesign) + { + pPage1_NewDesign->Check(TRUE); // wegen DesignDeleteHdl + pPage1_OldDesign->Check(FALSE); + pPage1_Designs->Disable(); + pPage1_DelDesign->Disable(); + m_pDesign = NULL; + + SdPublishingDesign aDefault; + SetDesign(&aDefault); + } + else + { + pPage1_NewDesign->Check(FALSE); + pPage1_Designs->Enable(); + pPage1_DelDesign->Enable(); + + if(pPage1_Designs->GetSelectEntryCount() == 0) + pPage1_Designs->SelectEntryPos(0); + + USHORT nPos = pPage1_Designs->GetSelectEntryPos(); + m_pDesign = (SdPublishingDesign*)m_pDesignList->GetObject(nPos); + DBG_ASSERT(m_pDesign, "Kein Design? Das darf nicht sein! (CL)"); + + if(m_pDesign) + SetDesign(m_pDesign); + } + + return 0; +} + +// ===================================================================== +// Clickhandler fuer die auswahl eines Designs +// ===================================================================== +IMPL_LINK( SdPublishingDlg, DesignSelectHdl, ListBox *, EMPTYARG ) +{ + USHORT nPos = pPage1_Designs->GetSelectEntryPos(); + m_pDesign = (SdPublishingDesign*)m_pDesignList->GetObject(nPos); + DBG_ASSERT(m_pDesign, "Kein Design? Das darf nicht sein! (CL)"); + + if(m_pDesign) + SetDesign(m_pDesign); + + UpdatePage(); + + return 0; +} + +// ===================================================================== +// Clickhandler fuer das loeschen eines Designs +// ===================================================================== +IMPL_LINK( SdPublishingDlg, DesignDeleteHdl, PushButton *, EMPTYARG ) +{ + USHORT nPos = pPage1_Designs->GetSelectEntryPos(); + SdPublishingDesign* pDesign = (SdPublishingDesign*) + m_pDesignList->GetObject(nPos); + DBG_ASSERT(pDesign, "Kein Design? Das darf nicht sein! (CL)"); + + if(pDesign) + { + m_pDesignList->Remove(pDesign); + pPage1_Designs->RemoveEntry(nPos); + } + + if(m_pDesign == pDesign) + DesignHdl( pPage1_NewDesign ); + + delete pDesign; + + m_bDesignListDirty = TRUE; + + UpdatePage(); + + return 0; +} + +// ===================================================================== +// Clickhandler fuer das ändern des Servertyps +// ===================================================================== +IMPL_LINK( SdPublishingDlg, WebServerHdl, RadioButton *, pButton ) +{ + BOOL bASP = pButton == pPage2_ASP; + + pPage2_ASP->Check( bASP ); + pPage2_PERL->Check( !bASP ); + UpdatePage(); + + return 0; +} + +// ===================================================================== +// Clickhandler fuer die Radiobuttons der Auswahl des Grafikformates +// ===================================================================== +IMPL_LINK( SdPublishingDlg, GfxFormatHdl, RadioButton *, pButton ) +{ + pPage3_Png->Check( pButton == pPage3_Png ); + pPage3_Gif->Check( pButton == pPage3_Gif ); + pPage3_Jpg->Check( pButton == pPage3_Jpg ); + pPage3_Quality->Enable(pButton == pPage3_Jpg); + return 0; +} + +// ===================================================================== +// Clickhandler fuer die Radiobuttons Stanrard/Frames +// ===================================================================== +IMPL_LINK( SdPublishingDlg, BaseHdl, RadioButton *, EMPTYARG ) +{ +/* + if(pButton == pPage3_Standard) + pPage3_Frames->Check( pButton == pPage3 ); + else + pPage3_Standard->Check(FALSE); +*/ + UpdatePage(); + + return 0; +} + +// ===================================================================== +// Clickhandler fuer die CheckBox der Titelseite +// ===================================================================== +IMPL_LINK( SdPublishingDlg, ContentHdl, RadioButton *, EMPTYARG ) +{ + if(pPage2_Content->IsChecked()) + { + if(!aAssistentFunc.IsEnabled(4)) + { + aAssistentFunc.EnablePage(4); + UpdatePage(); + } + } + else + { + if(aAssistentFunc.IsEnabled(4)) + { + aAssistentFunc.DisablePage(4); + UpdatePage(); + } + } + return 0; +} + +// ===================================================================== +// Clickhandler fuer die Radiobuttons Aufloesung +// ===================================================================== +IMPL_LINK( SdPublishingDlg, ResolutionHdl, RadioButton *, pButton ) +{ + pPage3_Resolution_1->Check(pButton == pPage3_Resolution_1); + pPage3_Resolution_2->Check(pButton == pPage3_Resolution_2); + pPage3_Resolution_3->Check(pButton == pPage3_Resolution_3); + + return 0; +} + +// ===================================================================== +// Clickhandler fuer das ValueSet mit den Bitmap Schaltflaechen +// ===================================================================== +IMPL_LINK( SdPublishingDlg, ButtonsHdl, ValueSet *, EMPTYARG ) +{ + // wird eine Bitmap Schaltflaeche gewaehlt, TexOnly ausschalten + pPage5_TextOnly->Check(FALSE); + return 0; +} + +// ===================================================================== +// Das SfxItemSet mit den Einstellungen des Dialogs fuettern +// ===================================================================== +IMPL_LINK( SdPublishingDlg, ColorHdl, PushButton *, pButton) +{ + SvColorDialog aDlg(this); + + if(pButton == pPage6_Back) + { + aDlg.SetColor( m_aBackColor ); + if(aDlg.Execute() == RET_OK ) + m_aBackColor = aDlg.GetColor(); + } + else if(pButton == pPage6_Text) + { + aDlg.SetColor( m_aTextColor ); + if(aDlg.Execute() == RET_OK ) + m_aTextColor = aDlg.GetColor(); + } + else if(pButton == pPage6_Link) + { + aDlg.SetColor( m_aLinkColor ); + if(aDlg.Execute() == RET_OK ) + m_aLinkColor = aDlg.GetColor(); + } + else if(pButton == pPage6_VLink) + { + aDlg.SetColor( m_aVLinkColor ); + if(aDlg.Execute() == RET_OK ) + m_aVLinkColor = aDlg.GetColor(); + } + else if(pButton == pPage6_ALink) + { + aDlg.SetColor( m_aALinkColor ); + if(aDlg.Execute() == RET_OK ) + m_aALinkColor = aDlg.GetColor(); + } + + pPage6_User->Check(TRUE); + pPage6_Preview->SetColors( m_aBackColor, m_aTextColor, m_aLinkColor, + m_aVLinkColor, m_aALinkColor ); + pPage6_Preview->Invalidate(); + return 0; +} + +IMPL_LINK( SdPublishingDlg, SlideChgHdl, RadioButton*, EMPTYARG ) +{ + UpdatePage(); + return 0; +} + +// ===================================================================== +// Clickhandler fuer den Ok Button +// ===================================================================== +IMPL_LINK( SdPublishingDlg, FinishHdl, OKButton *, EMPTYARG ) +{ + //Ende + SdPublishingDesign* pDesign = new SdPublishingDesign(); + GetDesign(pDesign); + + BOOL bSave = FALSE; + + if(pPage1_OldDesign->IsChecked() && m_pDesign) + { + // aenderungen?? + if(!(*pDesign == *m_pDesign)) + bSave = TRUE; + } + else + { + SdPublishingDesign aDefaultDesign; + if(!(aDefaultDesign == *pDesign)) + bSave = TRUE; + } + + if(bSave) + { + String aName; + if(m_pDesign) + aName = m_pDesign->m_aDesignName; + + BOOL bRetry; + do + { + bRetry = FALSE; + + SdDesignNameDlg aDlg(this, aName ); + + if ( aDlg.Execute() == RET_OK ) + { + pDesign->m_aDesignName = aDlg.GetDesignName(); + + SdPublishingDesign* pSameNameDes = NULL; + UINT16 nIndex; + for( nIndex = 0; nIndex < m_pDesignList->Count(); nIndex++ ) + { + pSameNameDes = (SdPublishingDesign*) + m_pDesignList->GetObject(nIndex); + if(pSameNameDes->m_aDesignName == pDesign->m_aDesignName) + break; + } + + if(nIndex < m_pDesignList->Count()) + { + ErrorBox aErrorBox(this, WB_YES_NO, + String(SdResId(STR_PUBDLG_SAMENAME))); + bRetry = aErrorBox.Execute() == RET_NO; + + if(!bRetry) + { + m_pDesignList->Remove(pSameNameDes); + delete pSameNameDes; + } + } + + if(!bRetry) + { + m_pDesignList->Insert(pDesign); + m_bDesignListDirty = TRUE; + pDesign = NULL; + } + } + } + while(bRetry); + } + + delete pDesign; + + if(m_bDesignListDirty) + Save(); + + EndDialog(RET_OK); + return 0; +} + +// ===================================================================== +// Refresh des Dialogs beim wechsel der Seite +// ===================================================================== +void SdPublishingDlg::ChangePage() +{ + int nPage = aAssistentFunc.GetCurrentPage(); + SetHelpId(aPageHelpIds[nPage-1]); + + UpdatePage(); + + if( aNextPageButton.IsEnabled() ) + aNextPageButton.GrabFocus(); + else + aFinishButton.GrabFocus(); +} + +void SdPublishingDlg::UpdatePage() +{ + aNextPageButton.Enable(!aAssistentFunc.IsLastPage()); + aLastPageButton.Enable(!aAssistentFunc.IsFirstPage()); + + int nPage = aAssistentFunc.GetCurrentPage(); + + switch( nPage ) + { + case 1: + if(pPage1_NewDesign->IsChecked()) + { + pPage1_Designs->Disable(); + pPage1_DelDesign->Disable(); + } + + if(m_pDesignList && m_pDesignList->Count() == 0) + pPage1_OldDesign->Disable(); + break; + case 2: + pPage2_Frames_FB->Show(pPage2_Frames->IsChecked()); + pPage2_Standard_FB->Show(pPage2_Standard->IsChecked()); + pPage2_Kiosk_FB->Show(pPage2_Kiosk->IsChecked()); + pPage2_WebCast_FB->Show(pPage2_WebCast->IsChecked()); + + if( pPage2_WebCast->IsChecked() ) + { + pPage2_Titel_WebCast->Show(); + pPage2_ASP->Show(); + pPage2_PERL->Show(); + pPage2_URL_txt->Show(); + pPage2_URL->Show(); + pPage2_CGI_txt->Show(); + pPage2_CGI->Show(); + pPage2_Index_txt->Show(); + pPage2_Index->Show(); + + BOOL bPerl = pPage2_PERL->IsChecked(); + pPage2_Index->Enable(bPerl); + pPage2_Index_txt->Enable(bPerl); + pPage2_URL_txt->Enable(bPerl); + pPage2_URL->Enable(bPerl); + pPage2_CGI_txt->Enable(bPerl); + pPage2_CGI->Enable(bPerl); + } + else + { + pPage2_Titel_WebCast->Hide(); + pPage2_ASP->Hide(); + pPage2_PERL->Hide(); + pPage2_URL_txt->Hide(); + pPage2_URL->Hide(); + pPage2_CGI_txt->Hide(); + pPage2_CGI->Hide(); + pPage2_Index->Hide(); + pPage2_Index_txt->Hide(); + } + + if( pPage2_Kiosk->IsChecked() ) + { + pPage2_Titel_Kiosk->Show(); + pPage2_ChgDefault->Show(); + pPage2_ChgAuto->Show(); + pPage2_Duration_txt->Show(); + pPage2_Duration->Show(); + pPage2_Endless->Show(); + BOOL bAuto = pPage2_ChgAuto->IsChecked(); + pPage2_Duration->Enable(bAuto); + pPage2_Endless->Enable(bAuto); + } + else + { + pPage2_Titel_Kiosk->Hide(); + pPage2_ChgDefault->Hide(); + pPage2_ChgAuto->Hide(); + pPage2_Duration->Hide(); + pPage2_Duration_txt->Hide(); + pPage2_Endless->Hide(); + } + + if( pPage2_Standard->IsChecked() || pPage2_Frames->IsChecked() ) + { + pPage2_Titel_Html->Show(); + pPage2_Content->Show(); + if(m_bImpress) + pPage2_Notes->Show(); + } + else + { + pPage2_Titel_Html->Hide(); + pPage2_Content->Hide(); + if(m_bImpress) + pPage2_Notes->Hide(); + } + break; + case 3: + if( pPage2_Kiosk->IsChecked() || pPage2_WebCast->IsChecked() ) + aNextPageButton.Disable(); + + if( pPage2_WebCast->IsChecked() ) + pPage3_SldSound->Disable(); + + pPage3_Quality->Enable(pPage3_Jpg->IsChecked()); + + break; + case 5: + if( m_bButtonsDirty ) + LoadPreviewButtons(); + break; + } +} + +/** loads the html buttons from the button sets, creates a preview and fills the + itemset for page 5 + */ +void SdPublishingDlg::LoadPreviewButtons() +{ + if( mpButtonSet.get() ) + { + const int nButtonCount = 8; + static const char *pButtonNames[nButtonCount] = + { + "first.png", + "left.png", + "right.png", + "last.png", + "home.png", + "text.png", + "expand.png", + "collapse.png", + }; + + std::vector< rtl::OUString > aButtonNames; + for( int i = 0; i < nButtonCount; ++i ) + aButtonNames.push_back( rtl::OUString::createFromAscii( pButtonNames[i] ) ); + + int nSetCount = mpButtonSet->getCount(); + + int nHeight = 32; + Image aImage; + for( int nSet = 0; nSet < nSetCount; ++nSet ) + { + if( mpButtonSet->getPreview( nSet, aButtonNames, aImage ) ) + { + pPage5_Buttons->InsertItem( (USHORT)nSet+1, aImage ); + if( nHeight < aImage.GetSizePixel().Height() ) + nHeight = aImage.GetSizePixel().Height(); + } + } + + pPage5_Buttons->SetItemHeight( nHeight ); + m_bButtonsDirty = FALSE; + } +} + +// ===================================================================== +// Clickhandler fuer den Weiter Button +// ===================================================================== +IMPL_LINK( SdPublishingDlg, NextPageHdl, PushButton *, EMPTYARG ) +{ + aAssistentFunc.NextPage(); + ChangePage(); + return 0; +} + +// ===================================================================== +// Setzt die Controlls im Dialog gemaess den Einstellungen im Design +// ===================================================================== +void SdPublishingDlg::SetDesign( SdPublishingDesign* pDesign ) +{ + if(!pDesign) + return; + + pPage2_Standard->Check(pDesign->m_eMode == PUBLISH_HTML); + pPage2_Frames->Check(pDesign->m_eMode == PUBLISH_FRAMES); + pPage2_Kiosk->Check(pDesign->m_eMode == PUBLISH_KIOSK ); + pPage2_WebCast->Check(pDesign->m_eMode == PUBLISH_WEBCAST ); + + pPage2_Content->Check(pDesign->m_bContentPage); + if(pDesign->m_bContentPage) + aAssistentFunc.EnablePage(4); + else + aAssistentFunc.DisablePage(4); + + if(m_bImpress) + pPage2_Notes->Check(pDesign->m_bNotes); + + pPage2_ASP->Check(pDesign->m_eScript == SCRIPT_ASP); + pPage2_PERL->Check(pDesign->m_eScript == SCRIPT_PERL); + pPage2_CGI->SetText(pDesign->m_aCGI); + pPage2_URL->SetText(pDesign->m_aURL); + + pPage2_ChgDefault->Check( !pDesign->m_bAutoSlide ); + pPage2_ChgAuto->Check( pDesign->m_bAutoSlide ); + + Time aTime; + aTime.MakeTimeFromMS( pDesign->m_nSlideDuration * 1000 ); + pPage2_Duration->SetTime( aTime ); + + pPage2_Endless->Check( pDesign->m_bEndless ); + + pPage3_Png->Check(pDesign->m_eFormat == FORMAT_PNG); + pPage3_Gif->Check(pDesign->m_eFormat == FORMAT_GIF); + pPage3_Jpg->Check(pDesign->m_eFormat == FORMAT_JPG); + pPage3_Quality->Enable(pDesign->m_eFormat == FORMAT_JPG); + + pPage3_Quality->SetText(pDesign->m_aCompression); + pPage3_Resolution_1->Check(pDesign->m_nResolution == PUB_LOWRES_WIDTH); + pPage3_Resolution_2->Check(pDesign->m_nResolution == PUB_MEDRES_WIDTH); + pPage3_Resolution_3->Check(pDesign->m_nResolution == PUB_HIGHRES_WIDTH); + + pPage3_SldSound->Check( pDesign->m_bSlideSound ); + pPage3_HiddenSlides->Check( pDesign->m_bHiddenSlides ); + + pPage4_Author->SetText(pDesign->m_aAuthor); + pPage4_Email->SetText(pDesign->m_aEMail); + pPage4_WWW->SetText(pDesign->m_aWWW); + pPage4_Misc->SetText(pDesign->m_aMisc); + if(m_bImpress) + pPage4_Download->Check(pDesign->m_bDownload); +//-/ pPage4_Created->Check(pDesign->m_bCreated); + + pPage5_TextOnly->Check(pDesign->m_nButtonThema == -1); + if(pDesign->m_nButtonThema != -1) + { + if(m_bButtonsDirty) + LoadPreviewButtons(); + pPage5_Buttons->SelectItem(pDesign->m_nButtonThema + 1); + } + else + pPage5_Buttons->SetNoSelection(); + + pPage6_User->Check(pDesign->m_bUserAttr); + m_aBackColor = pDesign->m_aBackColor; + m_aTextColor = pDesign->m_aTextColor; + m_aLinkColor = pDesign->m_aLinkColor; + m_aVLinkColor = pDesign->m_aVLinkColor; + m_aALinkColor = pDesign->m_aALinkColor; + + pPage6_DocColors->Check(pDesign->m_bUseColor); + + pPage6_Preview->SetColors( m_aBackColor, m_aTextColor, m_aLinkColor, + m_aVLinkColor, m_aALinkColor ); + pPage6_Preview->Invalidate(); + + UpdatePage(); +} + +// ===================================================================== +// Uebertraegt den Status der Dialog Controlls in das Design +// ===================================================================== +void SdPublishingDlg::GetDesign( SdPublishingDesign* pDesign ) +{ + if(!pDesign) + return; + + pDesign->m_eMode = pPage2_Standard->IsChecked()?PUBLISH_HTML: + pPage2_Frames->IsChecked()?PUBLISH_FRAMES: + pPage2_Kiosk->IsChecked()?PUBLISH_KIOSK: + PUBLISH_WEBCAST; + + pDesign->m_bContentPage = pPage2_Content->IsChecked(); + if(m_bImpress) + pDesign->m_bNotes = pPage2_Notes->IsChecked(); + + if( pPage3_Gif->IsChecked() ) + pDesign->m_eFormat = FORMAT_GIF; + else if( pPage3_Jpg->IsChecked() ) + pDesign->m_eFormat = FORMAT_JPG; + else + pDesign->m_eFormat = FORMAT_PNG; + + pDesign->m_aCompression = pPage3_Quality->GetText(); + + pDesign->m_nResolution = pPage3_Resolution_1->IsChecked()?PUB_LOWRES_WIDTH: + (pPage3_Resolution_2->IsChecked()?PUB_MEDRES_WIDTH:PUB_HIGHRES_WIDTH); + + pDesign->m_bSlideSound = pPage3_SldSound->IsChecked(); + pDesign->m_bHiddenSlides = pPage3_HiddenSlides->IsChecked(); + + pDesign->m_aAuthor = pPage4_Author->GetText(); + pDesign->m_aEMail = pPage4_Email->GetText(); + pDesign->m_aWWW = pPage4_WWW->GetText(); + pDesign->m_aMisc = pPage4_Misc->GetText(); + pDesign->m_bDownload = m_bImpress?pPage4_Download->IsChecked():FALSE; +//-/ pDesign->m_bCreated = pPage4_Created->IsChecked(); + + if(pPage5_TextOnly->IsChecked()) + pDesign->m_nButtonThema = -1; + else + pDesign->m_nButtonThema = pPage5_Buttons->GetSelectItemId() - 1; + + pDesign->m_bUserAttr = pPage6_User->IsChecked(); + pDesign->m_aBackColor = m_aBackColor; + pDesign->m_aTextColor = m_aTextColor; + pDesign->m_aLinkColor = m_aLinkColor; + pDesign->m_aVLinkColor = m_aVLinkColor; + pDesign->m_aALinkColor = m_aALinkColor; + pDesign->m_bUseColor = pPage6_DocColors->IsChecked(); + + + pDesign->m_eScript = pPage2_ASP->IsChecked()?SCRIPT_ASP:SCRIPT_PERL; + pDesign->m_aCGI = pPage2_CGI->GetText(); + pDesign->m_aURL = pPage2_URL->GetText(); + + pDesign->m_bAutoSlide = pPage2_ChgAuto->IsChecked(); + pDesign->m_nSlideDuration = (UINT32)pPage2_Duration->GetTime().GetMSFromTime() / 1000; + pDesign->m_bEndless = pPage2_Endless->IsChecked(); +} + +// ===================================================================== +// Clickhandler fuer den Zurueck Button +// ===================================================================== +IMPL_LINK( SdPublishingDlg, LastPageHdl, PushButton *, EMPTYARG ) +{ + aAssistentFunc.PreviousPage(); + ChangePage(); + return 0; +} + +// ===================================================================== +// Designs laden +// ===================================================================== +BOOL SdPublishingDlg::Load() +{ + m_bDesignListDirty = FALSE; + + m_pDesignList = new List(); + + INetURLObject aURL( SvtPathOptions().GetUserConfigPath() ); + aURL.Append( UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "designs.sod" ) ) ); + + // check if file exists, SfxMedium shows an errorbox else + { + com::sun::star::uno::Reference < com::sun::star::task::XInteractionHandler > xHandler; + SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ, xHandler ); + + sal_Bool bOk = pIStm && ( pIStm->GetError() == 0); + + if( pIStm ) + delete pIStm; + + if( !bOk ) + return sal_False; + } + + SfxMedium aMedium( aURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ | STREAM_NOCREATE, TRUE ); + + SvStream* pStream = aMedium.GetInStream(); + + if( !pStream ) + return( FALSE ); + + UINT16 aCheck; + *pStream >> aCheck; + + if(aCheck != nMagic) + return FALSE; + + SdIOCompat aIO(*pStream, STREAM_READ); + + UINT16 nDesigns; + *pStream >> nDesigns; + + for( UINT16 nIndex = 0; + pStream->GetError() == SVSTREAM_OK && nIndex < nDesigns; + nIndex++ ) + { + SdPublishingDesign* pDesign = new SdPublishingDesign(); + *pStream >> *pDesign; + + m_pDesignList->Insert(pDesign); + } + + return( pStream->GetError() == SVSTREAM_OK ); +} + +// ===================================================================== +// Designs speichern +// ===================================================================== +BOOL SdPublishingDlg::Save() +{ + INetURLObject aURL( SvtPathOptions().GetUserConfigPath() ); + aURL.Append( UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "designs.sod" ) ) ); + SfxMedium aMedium( aURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_WRITE | STREAM_TRUNC, FALSE ); + aMedium.IsRemote(); + + SvStream* pStream = aMedium.GetOutStream(); + + if( !pStream ) + return( FALSE ); + + UINT16 aCheck = nMagic; + *pStream << aCheck; + + // damit SdIOCompat vor dem Stream destruiert wird + { + SdIOCompat aIO(*pStream, STREAM_WRITE, 0); + + UINT16 nDesigns = (UINT16) m_pDesignList->Count(); + *pStream << nDesigns; + + for( UINT16 nIndex = 0; + pStream->GetError() == SVSTREAM_OK && nIndex < nDesigns; + nIndex++ ) + { + SdPublishingDesign* pDesign = (SdPublishingDesign*) + m_pDesignList->GetObject(nIndex); + *pStream << *pDesign; + } + } + + aMedium.Close(); + aMedium.Commit(); + + return( aMedium.GetError() == 0 ); +} + +// ********************************************************************* +// SdDesignNameDlg Methoden +// ********************************************************************* + +// ===================================================================== +// +// ===================================================================== +SdDesignNameDlg::SdDesignNameDlg(Window* pWindow, const String& aName): + ModalDialog (pWindow, SdResId( DLG_DESIGNNAME )), + m_aEdit (this, SdResId(EDT_NAME)), + m_aBtnOK (this, SdResId(BTN_SAVE)), + m_aBtnCancel (this, SdResId(BTN_NOSAVE)) +{ + FreeResource(); + m_aEdit.SetModifyHdl(LINK(this, SdDesignNameDlg, ModifyHdl )); + m_aEdit.SetText(aName); + m_aBtnOK.Enable(aName.Len() != 0); +} + +// ===================================================================== +// +// ===================================================================== +String SdDesignNameDlg::GetDesignName() +{ + return m_aEdit.GetText(); +} + +// ===================================================================== +// +// ===================================================================== +IMPL_LINK( SdDesignNameDlg, ModifyHdl, Edit*, EMPTYARG ) +{ + m_aBtnOK.Enable(m_aEdit.GetText().Len() != 0); + + return 0; +} + + + diff --git a/sd/source/filter/html/pubdlg.src b/sd/source/filter/html/pubdlg.src new file mode 100644 index 000000000000..00e9b4af75e4 --- /dev/null +++ b/sd/source/filter/html/pubdlg.src @@ -0,0 +1,817 @@ + /************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "helpids.h" +#include "pubdlg.hrc" + +ModalDialog DLG_PUBLISHING +{ + OutputSize = TRUE ; + SVLook = TRUE ; + Size = MAP_APPFONT ( 272 , 190 ) ; + Text [ en-US ] = "HTML Export" ; + Moveable = TRUE ; + + ///////////////////////////// + // Page 1, choose a design // + ///////////////////////////// + + FixedBitmap PAGE1_BMP + { + OutputSize = TRUE ; + Scale = TRUE; + Border = TRUE; + Pos = MAP_APPFONT ( 6 , 4 ) ; + Size = MAP_APPFONT ( 256 , 29 ) ; + Fixed = Bitmap { File = "pubdlg1.bmp" ; }; + }; + + FixedLine PAGE1_TITEL + { + Pos = MAP_APPFONT ( 6 , 38 ) ; + Size = MAP_APPFONT ( 258 , 8 ) ; + Text [ en-US ] = "Assign design"; + }; + + RadioButton PAGE1_NEW_DESIGN + { + Pos = MAP_APPFONT( 12, 50 ); + Size = MAP_APPFONT( 153, 10 ); + Text [ en-US ] = "New design"; + }; + + RadioButton PAGE1_OLD_DESIGN + { + Pos = MAP_APPFONT( 12, 63 ); + Size = MAP_APPFONT( 153, 10 ); + Text [ en-US ] = "Existing design"; + }; + + ListBox PAGE1_DESIGNS + { + Border = TRUE ; + Pos = MAP_APPFONT ( 21 , 75 ) ; + Size = MAP_APPFONT ( 144 , 63 ) ; + TabStop = TRUE ; + VScroll = TRUE ; + }; + + PushButton PAGE1_DEL_DESIGN + { + Pos = MAP_APPFONT ( 168 , 75 ) ; + Size = MAP_APPFONT ( 92 , 14 ) ; + TabStop = TRUE ; + DefButton = TRUE ; + Text [ en-US ] = "Delete Selected Design"; + }; + + FixedText PAGE1_DESC + { + Pos = MAP_APPFONT ( 12 , 142 ) ; + Size = MAP_APPFONT ( 258 , 8 ) ; + Text [ en-US ] = "Select an existing design or create a new one"; + }; + + + //////////////////////////////// + // Page 2, type of publishing // + //////////////////////////////// + + FixedBitmap PAGE2_BMP + { + OutputSize = TRUE ; + Scale = TRUE; + Border = TRUE; + Pos = MAP_APPFONT ( 6 , 4 ) ; + Size = MAP_APPFONT ( 256 , 29 ) ; + Fixed = Bitmap { File = "pubdlg1.bmp" ; }; + }; + + FixedLine PAGE2_TITEL + { + Pos = MAP_APPFONT ( 6, 38 ) ; + Size = MAP_APPFONT ( 124, 8 ) ; + Text [ en-US ] = "Publication type"; + }; + + RadioButton PAGE2_STANDARD + { + Pos = MAP_APPFONT( 12, 50 ); + Size = MAP_APPFONT( 116, 10 ); + Text [ en-US ] = "Standard H~TML format"; + }; + + RadioButton PAGE2_FRAMES + { + Pos = MAP_APPFONT( 12, 63 ); + Size = MAP_APPFONT( 116, 10 ); + Text [ en-US ] = "Standard HTML with ~frames"; + }; + + RadioButton PAGE2_KIOSK + { + Pos = MAP_APPFONT( 12, 76 ); + Size = MAP_APPFONT( 116, 10 ); + Text [ en-US ] = "~Automatic"; + }; + + RadioButton PAGE2_WEBCAST + { + Pos = MAP_APPFONT( 12, 89 ); + Size = MAP_APPFONT( 116, 10 ); + Text [ en-US ] = "~WebCast"; + }; + + FixedBitmap PAGE2_NOFRAMES_FB + { + Pos = MAP_APPFONT( 21, 102 ); + Scale = TRUE; + Size = MAP_APPFONT( 60, 50 ); + Fixed = Bitmap { File = "pubdes.bmp"; }; + OutputSize = TRUE ; + Border = TRUE; + }; + + FixedBitmap PAGE2_FRAMES_FB + { + Pos = MAP_APPFONT( 21, 102 ); + Scale = TRUE; + Size = MAP_APPFONT( 60, 50 ); + Fixed = Bitmap { File = "pubdes2.bmp"; }; + OutputSize = TRUE ; + Border = TRUE; + }; + + FixedBitmap PAGE2_KIOSK_FB + { + Pos = MAP_APPFONT( 21, 102 ); + Scale = TRUE; + Size = MAP_APPFONT( 60, 50 ); + Fixed = Bitmap { File = "pubdes3.bmp"; }; + OutputSize = TRUE ; + Border = TRUE; + }; + + FixedBitmap PAGE2_WEBCAST_FB + { + Pos = MAP_APPFONT( 21, 102 ); + Scale = TRUE; + Size = MAP_APPFONT( 60, 50 ); + Fixed = Bitmap { File = "pubdes4.bmp"; }; + OutputSize = TRUE ; + Border = TRUE; + }; + + ////////////////////////////// + // Special options for html // + ////////////////////////////// + + FixedLine PAGE2_TITEL_HTML + { + Pos = MAP_APPFONT( 138, 38 ); + Size = MAP_APPFONT( 128, 8 ); + Text [ en-US ] = "Options"; + }; + + CheckBox PAGE2_CONTENT + { + Pos = MAP_APPFONT( 144, 49 ); + Size = MAP_APPFONT( 116, 10 ); + Text [ en-US ] = "Create title page"; + }; + + FixedLine PAGE2_VERT + { + Pos = MAP_APPFONT ( 132 , 49 ) ; + Size = MAP_APPFONT ( 4, 109 ) ; + Vert = TRUE; + }; + + CheckBox PAGE2_NOTES + { + Pos = MAP_APPFONT( 144, 63 ); + Size = MAP_APPFONT( 116, 10 ); + Text [ en-US ] = "Show notes"; + }; + + /////////////////////////////// + // Special options for kiosk // + /////////////////////////////// + + FixedLine PAGE2_TITEL_KIOSK + { + Pos = MAP_APPFONT( 138, 38 ); + Size = MAP_APPFONT( 128, 8 ); + Text [ en-US ] = "Advance slides" ; + }; + + RadioButton PAGE2_CHG_DEFAULT + { + Pos = MAP_APPFONT ( 144 , 49 ) ; + Size = MAP_APPFONT ( 116 , 10 ) ; + TabStop = TRUE ; + Text [ en-US ] = "~As stated in document" ; + }; + + RadioButton PAGE2_CHG_AUTO + { + Pos = MAP_APPFONT ( 144 , 63 ) ; + Size = MAP_APPFONT ( 116 , 10 ) ; + TabStop = TRUE ; + Text [ en-US ] = "~Automatic" ; + }; + + FixedText PAGE2_DURATION_TXT + { + Pos = MAP_APPFONT ( 154, 77 ) ; + Size = MAP_APPFONT ( 40, 10 ) ; + Text [ en-US ] = "~Slide view time:" ; + }; + + TimeField PAGE2_DURATION_TMF + { + Pos = MAP_APPFONT ( 196, 76 ) ; + Size = MAP_APPFONT ( 48, 12 ) ; + Border = TRUE ; + TabStop = TRUE ; + Repeat = TRUE ; + Spin = TRUE ; + Duration = TRUE ; + StrictFormat = TRUE ; + Maximum = Time + { + Hour = 23 ; + Minute = 59 ; + Second = 59 ; + }; + Last = Time + { + Hour = 23 ; + Minute = 59 ; + Second = 59 ; + }; + QuickHelpText [ en-US ] = "~Duration of page"; + }; + + CheckBox PAGE2_ENDLESS + { + Pos = MAP_APPFONT ( 154, 91 ); + Size = MAP_APPFONT ( 108, 10 ); + Text [ en-US ] = "~Endless" ; + }; + + ///////////////////////////////// + // Special options for WebCast // + ///////////////////////////////// + + FixedLine PAGE2_TITEL_WEBCAST + { + Pos = MAP_APPFONT( 138, 38 ); + Size = MAP_APPFONT( 128, 8 ); + Text [ en-US ] = "WebCast" ; + }; + + RadioButton PAGE2_ASP + { + Pos = MAP_APPFONT( 144, 49 ); + Size = MAP_APPFONT( 116, 10 ); + Text [ en-US ] = "~Active Server Pages (ASP)"; + }; + + RadioButton PAGE2_PERL + { + Pos = MAP_APPFONT( 144, 63 ); + Size = MAP_APPFONT( 116, 10 ); + Text [ en-US ] = "Perl" ; + }; + + FixedText PAGE2_INDEX_TXT + { + Pos = MAP_APPFONT( 154, 76 ); + Size = MAP_APPFONT( 105, 10 ); + Text [ en-US ] = "~URL for listeners"; + }; + + Edit PAGE2_INDEX + { + BORDER = TRUE; + Pos = MAP_APPFONT( 154, 88 ); + Size = MAP_APPFONT( 105, 12 ); + Left = TRUE; + }; + + FixedText PAGE2_URL_TXT + { + Pos = MAP_APPFONT( 154, 104 ); + Size = MAP_APPFONT( 105, 10 ); + Text [ en-US ] = "URL for ~presentation:"; + }; + + Edit PAGE2_URL + { + BORDER = TRUE; + Pos = MAP_APPFONT( 154, 116 ); + Size = MAP_APPFONT( 105, 12 ); + LEFT = TRUE; + }; + + FixedText PAGE2_CGI_TXT + { + Pos = MAP_APPFONT( 154, 132 ); + Size = MAP_APPFONT( 105, 10 ); + Text [ en-US ] = "URL for ~Perl scripts:"; + }; + + Edit PAGE2_CGI + { + BORDER = TRUE; + Pos = MAP_APPFONT( 154, 144 ); + Size = MAP_APPFONT( 105, 12 ); + LEFT = TRUE; + }; + + + ///////////////////////////////////////////////////////// + // Page 3, Misc Options, Picture Format and Resolution // + ///////////////////////////////////////////////////////// + + FixedBitmap PAGE3_BMP + { + OutputSize = TRUE ; + Border = TRUE; + Pos = MAP_APPFONT ( 6 , 4 ) ; + Size = MAP_APPFONT ( 256 , 29 ) ; + Scale = TRUE; + Fixed = Bitmap { File = "pubdlg2.bmp" ; }; + }; + + //////////////////// + // Picture Format // + //////////////////// + + FixedLine PAGE3_TITEL_1 + { + Pos = MAP_APPFONT ( 6, 38 ) ; + Size = MAP_APPFONT ( 124, 8 ) ; + Text [ en-US ] = "Save graphics as"; + }; + + RadioButton PAGE3_PNG + { + Pos = MAP_APPFONT( 12, 49 ); + Size = MAP_APPFONT( 116, 10 ); + Text [ en-US ] = "~PNG"; + }; + + RadioButton PAGE3_GIF + { + Pos = MAP_APPFONT( 12, 63 ); + Size = MAP_APPFONT( 116, 10 ); + Text [ en-US ] = "~GIF"; + }; + + RadioButton PAGE3_JPG + { + Pos = MAP_APPFONT( 12, 77 ); + Size = MAP_APPFONT( 116, 10 ); + Text [ en-US ] = "~JPG"; + }; + + ComboBox PAGE3_QUALITY + { + Pos = MAP_APPFONT( 18, 91 ); + Size = MAP_APPFONT( 28, 70 ); + TabStop = TRUE ; + DropDown = TRUE ; + }; + + FixedText PAGE3_QUALITY_TXT + { + Pos = MAP_APPFONT( 49, 93 ); + Size = MAP_APPFONT( 79, 10 ); + Text [ en-US ] = "Quality"; + }; + + FixedLine PAGE3_VERT + { + Pos = MAP_APPFONT ( 132 , 49 ) ; + Size = MAP_APPFONT ( 4, 65 ) ; + Vert = TRUE; + }; + + //////////////// + // Resolution // + //////////////// + + FixedLine PAGE3_TITEL_2 + { + Pos = MAP_APPFONT( 138, 38 ); + Size = MAP_APPFONT( 128, 8 ); + Text [ en-US ] = "Monitor resolution"; + }; + + RadioButton PAGE3_RESOLUTION_1 + { + Pos = MAP_APPFONT( 144, 49 ); + Size = MAP_APPFONT( 116, 10 ); + Text [ en-US ] = "Low resolution (~640x480 pixels)"; + }; + + RadioButton PAGE3_RESOLUTION_2 + { + Pos = MAP_APPFONT( 144, 63 ); + Size = MAP_APPFONT( 116, 10 ); + Text [ en-US ] = "Medium resolution (~800x600 pixels)"; + }; + + RadioButton PAGE3_RESOLUTION_3 + { + Pos = MAP_APPFONT ( 144, 77 ) ; + Size = MAP_APPFONT ( 116 , 10 ) ; + Text [ en-US ] = "High resolution (~1024x768 pixels)"; + }; + + //////////////// + // Resolution // + //////////////// + + FixedLine PAGE3_TITEL_3 + { + Pos = MAP_APPFONT( 6, 114 ); + Size = MAP_APPFONT( 258, 8 ); + Text [ en-US ] = "Effects"; + }; + + CheckBox PAGE3_SLD_SOUND + { + Pos = MAP_APPFONT ( 12, 125 ); + Size = MAP_APPFONT ( 252, 10 ); + Text [ en-US ] = "~Export sounds when slide advances" ; + }; + + CheckBox PAGE3_HIDDEN_SLIDES + { + Pos = MAP_APPFONT ( 12, 138 ); + Size = MAP_APPFONT ( 252, 10 ); + Text [ en-US ] = "Export ~hidden slides" ; + }; + + //////////////////////////////////////// + // Page 4, information for titel page // + //////////////////////////////////////// + + FixedBitmap PAGE4_BMP + { + OutputSize = TRUE ; + Border = TRUE; + Pos = MAP_APPFONT ( 6 , 4 ) ; + Size = MAP_APPFONT ( 256 , 29 ) ; + Fixed = Bitmap { File = "pubdlg3.bmp" ; }; + }; + + FixedLine PAGE4_TITEL_1 + { + Pos = MAP_APPFONT ( 6 , 38 ) ; + Size = MAP_APPFONT ( 258 , 8 ) ; + Text [ en-US ] = "Information for the title page"; + }; + + FixedText PAGE4_AUTHOR_TXT + { + Pos = MAP_APPFONT ( 12, 51 ); + Size = MAP_APPFONT ( 121, 8 ); + Text [ en-US ] = "~Author"; + }; + + Edit PAGE4_AUTHOR + { + BORDER = TRUE ; + Pos = MAP_APPFONT ( 136, 49 ); + Size = MAP_APPFONT ( 128, 12 ); + LEFT = TRUE; + }; + + FixedText PAGE4_EMAIL_TXT + { + Pos = MAP_APPFONT ( 12, 67 ); + Size = MAP_APPFONT ( 121, 8 ); + Text [ en-US ] = "E-~mail address"; + }; + + Edit PAGE4_EMAIL_EDIT + { + BORDER = TRUE ; + Pos = MAP_APPFONT ( 136 , 65 ) ; + Size = MAP_APPFONT ( 128 , 12 ) ; + LEFT = TRUE ; + }; + + FixedText PAGE4_WWW_TXT + { + Pos = MAP_APPFONT ( 12, 83 ); + Size = MAP_APPFONT ( 121, 8 ); + Text [ en-US ] = "Your hom~epage"; + }; + + Edit PAGE4_WWW_EDIT + { + BORDER = TRUE ; + Pos = MAP_APPFONT ( 136, 81 ) ; + Size = MAP_APPFONT ( 128, 12 ) ; + LEFT = TRUE ; + }; + + FixedText PAGE4_TITEL_2 + { + Pos = MAP_APPFONT ( 12 , 99 ) ; + Size = MAP_APPFONT ( 121 , 8 ) ; + Text [ en-US ] = "Additional ~information"; + }; + + MultiLineEdit PAGE4_MISC + { + Border = TRUE ; + Pos = MAP_APPFONT ( 136, 97 ) ; + Size = MAP_APPFONT ( 128 , 45 ) ; + TabStop = TRUE ; + VScroll = TRUE ; + IgnoreTab = TRUE ; + }; + + CheckBox PAGE4_DOWNLOAD + { + Pos = MAP_APPFONT ( 12 , 149 ) ; + Size = MAP_APPFONT ( 252 , 10 ) ; + TabStop = TRUE ; + Text [ en-US ] = "Link to a copy of the ~original presentation"; + }; + + CheckBox PAGE4_CREATED + { + Pos = MAP_APPFONT ( 12 , 152 ) ; + Size = MAP_APPFONT ( 252 , 10 ) ; + TabStop = TRUE ; + Text [ en-US ] = "Note: 'Created with %PRODUCTNAME'"; + }; + + ///////////////////// + // Page 5, Buttons // + ///////////////////// + + FixedBitmap PAGE5_BMP + { + OutputSize = TRUE ; + Border = TRUE; + Pos = MAP_APPFONT ( 6 , 4 ) ; + Size = MAP_APPFONT ( 256 , 29 ) ; + Fixed = Bitmap { File = "pubdlg4.bmp" ; }; + }; + + FixedLine PAGE5_TITEL + { + Pos = MAP_APPFONT ( 6 , 38 ) ; + Size = MAP_APPFONT ( 258 , 8 ) ; + Text [ en-US ] = "Select button style"; + }; + + CheckBox PAGE5_TEXTONLY + { + Pos = MAP_APPFONT ( 12, 50 ); + Size = MAP_APPFONT ( 243, 10 ); + Text [ en-US ] = "~Text only"; + }; + + Control PAGE5_BUTTONS + { + Border = TRUE ; + TabStop = TRUE; + Pos = MAP_APPFONT ( 12, 63 ) ; + Size = MAP_APPFONT ( 243, 95 ) ; + }; + + ///////////////////////// + // Page 6, colorscheme // + ///////////////////////// + + FixedBitmap PAGE6_BMP + { + OutputSize = TRUE ; + Border = TRUE; + Pos = MAP_APPFONT ( 6 , 4 ) ; + Size = MAP_APPFONT ( 256 , 29 ) ; + Fixed = Bitmap { File = "pubdlg5.bmp" ; }; + }; + + FixedLine PAGE6_TITEL + { + Pos = MAP_APPFONT ( 6 , 38 ) ; + Size = MAP_APPFONT ( 258 , 8 ) ; + Text [ en-US ] = "Select color scheme"; + }; + + RadioButton PAGE6_DOCCOLORS + { + Pos = MAP_APPFONT( 12, 50 ); + Size = MAP_APPFONT( 246, 10 ); + Text [ en-US ] = "~Apply color scheme from document"; + }; + + RadioButton PAGE6_DEFAULT + { + Pos = MAP_APPFONT( 12, 63 ); + Size = MAP_APPFONT( 246, 10 ); + Text [ en-US ] = "Use ~browser colors"; + }; + + RadioButton PAGE6_USER + { + Pos = MAP_APPFONT( 12, 76 ); + Size = MAP_APPFONT( 246, 10 ); + Text [ en-US ] = "~Use custom color scheme"; + }; + + PushButton PAGE6_TEXT + { + Pos = MAP_APPFONT( 21, 89 ); + Size = MAP_APPFONT( 72, 14 ); + Text [ en-US ] = "Text"; + }; + + PushButton PAGE6_LINK + { + Pos = MAP_APPFONT( 21, 106 ); + Size = MAP_APPFONT( 72, 14 ); + Text [ en-US ] = "Hyper~link"; + }; + + PushButton PAGE6_ALINK + { + Pos = MAP_APPFONT( 21, 123 ); + Size = MAP_APPFONT( 72, 14 ); + Text [ en-US ] = "Active Li~nk"; + }; + + PushButton PAGE6_VLINK + { + Pos = MAP_APPFONT( 21, 140 ); + Size = MAP_APPFONT( 72, 14 ); + Text [ en-US ] = "~Visited Link"; + }; + + Control PAGE6_PREVIEW + { + Pos = MAP_APPFONT( 96, 89 ); + Size = MAP_APPFONT( 100, 64 ); + Border = TRUE; + }; + + PushButton PAGE6_BACK + { + Pos = MAP_APPFONT( 199, 89 ); + Size = MAP_APPFONT( 60, 14 ); + Text [ en-US ] = "Bac~kground"; + }; + + // generell + + FixedLine BOTTOM_LINE + { + Pos = MAP_APPFONT ( 1 , 162 ) ; + Size = MAP_APPFONT ( 272, 4) ; + }; + + PushButton BUT_LAST + { + OutputSize = TRUE ; + Pos = MAP_APPFONT ( 112 , 170 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; + TabStop = TRUE ; + Text [ en-US ] = "<< Back" ; + }; + + PushButton BUT_NEXT + { + DefButton = TRUE ; + OutputSize = TRUE ; + Pos = MAP_APPFONT ( 165 , 170 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; + TabStop = TRUE ; + Text [ en-US ] = "Next >>" ; + }; + + OKButton BUT_FINISH + { + OutputSize = TRUE ; + Pos = MAP_APPFONT ( 218 , 170 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; + TabStop = TRUE ; + Text [ en-US ] = "~Create" ; + }; + + CancelButton BUT_CANCEL + { + OutputSize = TRUE ; + Pos = MAP_APPFONT ( 59 , 170 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; + TabStop = TRUE ; + }; + HelpButton BUT_HELP + { + OutputSize = TRUE ; + Pos = MAP_APPFONT ( 6 , 170 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; + TabStop = TRUE ; + }; +}; + +ModalDialog DLG_DESIGNNAME +{ + HelpID = HID_SD_HTMLEXPORT_DLG_DNAME; + OutputSize = TRUE ; + SVLook = TRUE ; + Size = MAP_APPFONT ( 160 , 40 ) ; + Moveable = TRUE ; + + Edit EDT_NAME + { + BORDER = TRUE ; + Pos = MAP_APPFONT ( 4, 4 ); + Size = MAP_APPFONT ( 152, 14 ); + LEFT = TRUE; + }; + + OKButton BTN_SAVE + { + OutputSize = TRUE ; + Pos = MAP_APPFONT ( 25 , 22 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; + DefButton = TRUE ; + TabStop = TRUE ; + Text [ en-US ] = "~Save"; + }; + + CancelButton BTN_NOSAVE + { + OutputSize = TRUE ; + Pos = MAP_APPFONT ( 80 , 22 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; + TabStop = TRUE ; + Text [ en-US ] = "Do Not Save"; + }; + Text [ en-US ] = "Name HTML Design"; +}; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sd/source/filter/html/sdhtmlfilter.cxx b/sd/source/filter/html/sdhtmlfilter.cxx new file mode 100644 index 000000000000..f447e2039c70 --- /dev/null +++ b/sd/source/filter/html/sdhtmlfilter.cxx @@ -0,0 +1,86 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" + +#include <unotools/localfilehelper.hxx> +#include <tools/errinf.hxx> +#include <tools/urlobj.hxx> +#include <vcl/msgbox.hxx> +#include <vcl/metaact.hxx> +#include <vcl/virdev.hxx> +#include <svtools/FilterConfigItem.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/docfilt.hxx> +#include <sfx2/frame.hxx> +#include <svx/svdograf.hxx> +#include <svx/svdpagv.hxx> +#include <svx/xoutbmp.hxx> +#include <osl/file.hxx> + +#include "sdpage.hxx" +#include "drawdoc.hxx" +#include "sdresid.hxx" +#include "sdattr.hxx" +#include "htmlex.hxx" +#include "sdhtmlfilter.hxx" + +// --------------- +// - SdPPTFilter - +// --------------- + +SdHTMLFilter::SdHTMLFilter( SfxMedium& rMedium, ::sd::DrawDocShell& rDocShell, sal_Bool bShowProgress ) : + SdFilter( rMedium, rDocShell, bShowProgress ) +{ +} + +// ----------------------------------------------------------------------------- + +SdHTMLFilter::~SdHTMLFilter() +{ +} + +// ----------------------------------------------------------------------------- + +sal_Bool SdHTMLFilter::Export() +{ + mrMedium.Close(); + mrMedium.Commit(); + + SfxItemSet *pSet = mrMedium.GetItemSet(); + + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aParams; + + const SfxPoolItem* pItem; + if ( pSet->GetItemState( SID_FILTER_DATA, sal_False, &pItem ) == SFX_ITEM_SET ) + ((SfxUnoAnyItem*)pItem)->GetValue() >>= aParams; + + delete( new HtmlExport( mrMedium.GetName(), aParams, &mrDocument, &mrDocShell ) ); + + return true; +} diff --git a/sd/source/filter/makefile.mk b/sd/source/filter/makefile.mk new file mode 100644 index 000000000000..554b1c5367be --- /dev/null +++ b/sd/source/filter/makefile.mk @@ -0,0 +1,55 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. +PRJNAME=sd +TARGET=filter + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Common ---------------------------------------------------------- + +.IF "$(dbg_anim_log)"!="" || "$(DBG_ANIM_LOG)"!="" +CDEFS+= -DDBG_ANIM_LOG +.ENDIF + +# --- Files -------------------------------------------------------- + +SLOFILES =\ + $(SLO)$/sdfilter.obj \ + $(SLO)$/sdpptwrp.obj + +EXCEPTIONSFILES= \ + $(SLO)$/pptin.obj \ + $(SLO)$/sdfilter.obj + +# --- Tagets ------------------------------------------------------- + +.INCLUDE : target.mk diff --git a/sd/source/filter/ppt/makefile.mk b/sd/source/filter/ppt/makefile.mk new file mode 100644 index 000000000000..bb00675147f5 --- /dev/null +++ b/sd/source/filter/ppt/makefile.mk @@ -0,0 +1,57 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. +PRJNAME=sd +TARGET=ppt +ENABLE_EXCEPTIONS=TRUE +VISIBILITY_HIDDEN=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Common ---------------------------------------------------------- + +.IF "$(dbg_anim_log)"!="" || "$(DBG_ANIM_LOG)"!="" +CDEFS+= -DDBG_ANIM_LOG +.ENDIF + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/propread.obj \ + $(SLO)$/pptin.obj \ + $(SLO)$/pptinanimations.obj \ + $(SLO)$/pptatom.obj \ + $(SLO)$/ppt97animations.obj + +# --- Targets -------------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/sd/source/filter/ppt/ppt97animations.cxx b/sd/source/filter/ppt/ppt97animations.cxx new file mode 100644 index 000000000000..a4a3564d35b0 --- /dev/null +++ b/sd/source/filter/ppt/ppt97animations.cxx @@ -0,0 +1,803 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" + +#include "ppt97animations.hxx" + +// header for class SdrObject +#include <svx/svdobj.hxx> +// header for class SdPage +#include "sdpage.hxx" +// header for define DBG_ERROR +#include <tools/debug.hxx> +// header for define GetXShapeForSdrObject +#include <svx/unoapi.hxx> +#include "EffectMigration.hxx" +#include <CustomAnimationPreset.hxx> +#include <com/sun/star/drawing/XShape.hpp> +#include <com/sun/star/presentation/TextAnimationType.hpp> +#include <com/sun/star/presentation/EffectNodeType.hpp> +#include <com/sun/star/presentation/ShapeAnimationSubType.hpp> + +using namespace ::com::sun::star; + +//--------------------------------------------------------------------------------------- + +void Ppt97AnimationInfoAtom::ReadStream( SvStream& rIn ) +{ + rIn >> nDimColor; + rIn >> nFlags; + rIn >> nSoundRef; + rIn >> nDelayTime; + rIn >> nOrderID; + rIn >> nSlideCount; + rIn >> nBuildType; + rIn >> nFlyMethod; + rIn >> nFlyDirection; + rIn >> nAfterEffect; + rIn >> nSubEffect; + rIn >> nOLEVerb; + rIn >> nUnknown1; + rIn >> nUnknown2; +} + +//--------------------------------------------------------------------------------------- + +#define MEMBER_CONSTRUCTOR_LIST() \ + m_aAtom() \ + , m_aSoundFileUrl() \ + , m_bDirtyCache(true) \ + , m_aPresetId() \ + , m_aSubType() \ + , m_bHasSpecialDuration(false) \ + , m_fDurationInSeconds(0.001) + +Ppt97Animation::Ppt97Animation( SvStream& rInputStream ) + : MEMBER_CONSTRUCTOR_LIST() +{ + m_aAtom.ReadStream( rInputStream ); +} + +Ppt97Animation::Ppt97Animation() + : MEMBER_CONSTRUCTOR_LIST() +{ +} + +Ppt97Animation::Ppt97Animation( const Ppt97Animation& rAnimation ) + : MEMBER_CONSTRUCTOR_LIST() +{ + *this = rAnimation; +} + +Ppt97Animation& Ppt97Animation::operator= ( const Ppt97Animation& rAnimation ) +{ + m_aAtom = rAnimation.m_aAtom; + m_aSoundFileUrl = rAnimation.m_aSoundFileUrl; + m_bDirtyCache = rAnimation.m_bDirtyCache; + m_aPresetId = rAnimation.m_aPresetId; + m_aSubType = rAnimation.m_aSubType; + m_bHasSpecialDuration = rAnimation.m_bHasSpecialDuration; + m_fDurationInSeconds = rAnimation.m_fDurationInSeconds; + + return *this; +} + +Ppt97Animation::~Ppt97Animation() +{ +} + +bool Ppt97Animation::operator < ( const Ppt97Animation& rAnimation ) const +{ + return m_aAtom.nOrderID < rAnimation.m_aAtom.nOrderID; +} +bool Ppt97Animation::operator > ( const Ppt97Animation& rAnimation ) const +{ + return m_aAtom.nOrderID > rAnimation.m_aAtom.nOrderID; +} +bool Ppt97Animation::HasEffect() const +{ + return m_aAtom.nBuildType != 0; +} +bool Ppt97Animation::HasParagraphEffect() const +{ + return m_aAtom.nBuildType > 1; +} +sal_Int32 Ppt97Animation::GetParagraphLevel() const +{ + sal_Int32 nParagraphLevel = 0; + if(m_aAtom.nBuildType>1) + nParagraphLevel = m_aAtom.nBuildType-1; + return nParagraphLevel; +} +bool Ppt97Animation::HasSoundEffect() const +{ + return m_aAtom.nSoundRef && m_aAtom.nFlags & 0x0010; +} +bool Ppt97Animation::HasStopPreviousSound() const +{ + return m_aAtom.nFlags & 0x0040; +} +bool Ppt97Animation::HasReverseOrder() const +{ + return m_aAtom.nFlags & 0x001; +} +bool Ppt97Animation::HasAnimateAssociatedShape() const +{ + return m_aAtom.nFlags & 0x004000; +} +bool Ppt97Animation::HasAfterEffect() const +{ + return m_aAtom.nAfterEffect != 0; +} +bool Ppt97Animation::HasAfterEffect_ChangeColor() const +{ + return m_aAtom.nAfterEffect == 1; +} +bool Ppt97Animation::HasAfterEffect_DimAtNextEffect() const +{ + return m_aAtom.nAfterEffect == 2; +} +bool Ppt97Animation::HasAfterEffect_DimAfterEffect() const +{ + return m_aAtom.nAfterEffect == 3; +} + +UINT32 Ppt97Animation::GetSoundRef() const +{ + return m_aAtom.nSoundRef; +} +void Ppt97Animation::SetSoundFileUrl( const ::rtl::OUString& rSoundFileUrl ) +{ + m_aSoundFileUrl = rSoundFileUrl; +} + +double Ppt97Animation::GetDelayTimeInSeconds() const +{ + return m_aAtom.nDelayTime != 0X7FFFFFFF ? m_aAtom.nDelayTime/1000.0 : 0.0; +} + +bool Ppt97Animation::GetSpecialDuration( double& rfDurationInSeconds ) const +{ + UpdateCacheData(); + if( m_bHasSpecialDuration ) + rfDurationInSeconds = m_fDurationInSeconds; + return m_bHasSpecialDuration; +} + +bool Ppt97Animation::GetSpecialTextIterationDelay( double& rfTextIterationDelay ) const +{ + bool bRet = false; + switch(this->GetTextAnimationType()) + { + case presentation::TextAnimationType::BY_LETTER: + rfTextIterationDelay = 0.075; + bRet = true; + break; + case presentation::TextAnimationType::BY_WORD: + rfTextIterationDelay = 0.3; + bRet = true; + break; + default: + break; + } + return bRet; +} + +sal_Int32 Ppt97Animation::GetDimColor() const +{ + return static_cast<sal_Int32>(m_aAtom.nDimColor); +} + +void Ppt97Animation::SetDimColor( sal_Int32 nDimColor ) +{ + m_aAtom.nDimColor = nDimColor; +} +void Ppt97Animation::SetAnimateAssociatedShape( bool bAnimate ) +{ + if( !bAnimate ) + { + //the appear effect cannot be animated without text + if( this->GetPresetId().equals( ::rtl::OUString::createFromAscii("ooo-entrance-appear") ) ) + return; + //the random effect may be the appear effect and than has the same problem + if( this->GetPresetId().equals( ::rtl::OUString::createFromAscii("ooo-entrance-random") ) ) + { + //this case is not 100% correct -> feel free to complete + //i consider this case as seldom and not that problematic and a simple correct fix is not in sight + DBG_WARNING("you tried to deselect the animation of the form for random animation-> this has been refused"); + return; + } + + } + + if(bAnimate) + m_aAtom.nFlags = m_aAtom.nFlags | 0x004000; + else if( HasAnimateAssociatedShape() ) + { + m_aAtom.nFlags = m_aAtom.nFlags ^ 0x004000; + } +} + +sal_Int16 Ppt97Animation::GetEffectNodeType() const //see com::sun::star::presentation::EffectNodeType +{ + sal_Int16 nRet = presentation::EffectNodeType::ON_CLICK; + if( m_aAtom.nFlags & 0x04 ) + { + nRet = presentation::EffectNodeType::AFTER_PREVIOUS; + } + return nRet; +} + +sal_Int16 Ppt97Animation::GetTextAnimationType() const +{ + sal_Int16 nRet = presentation::TextAnimationType::BY_PARAGRAPH; + switch( m_aAtom.nSubEffect ) + { + case 0: + break; + case 2: + nRet = presentation::TextAnimationType::BY_LETTER; + break; + default: + nRet = presentation::TextAnimationType::BY_WORD; + break; + } + return nRet; +} +::rtl::OUString Ppt97Animation::GetPresetId() const +{ + UpdateCacheData(); + return m_aPresetId; +} +::rtl::OUString Ppt97Animation::GetPresetSubType() const +{ + UpdateCacheData(); + return m_aSubType; +} + +void Ppt97Animation::ClearCacheData() const +{ + m_aPresetId = m_aSubType = rtl::OUString(); + m_bHasSpecialDuration = false; + m_fDurationInSeconds = 0.001; +} +void Ppt97Animation::UpdateCacheData() const +{ + if( !m_bDirtyCache ) + return; + + ClearCacheData(); + + if( !HasEffect() ) + { + m_bDirtyCache = false; + return; + } + + switch( m_aAtom.nFlyMethod ) + { + case 0x0: + //eRetval = ::com::sun::star::presentation::AnimationEffect_APPEAR; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-appear"); // --- appear --- + break; + case 0x01: + //eRetval = ::com::sun::star::presentation::AnimationEffect_RANDOM; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-random"); // --- random --- + break; + case 0x02: // --- blinds effect --- + { + switch ( m_aAtom.nFlyDirection ) + { + case 0x0: + //eRetval = ::com::sun::star::presentation::AnimationEffect_VERTICAL_STRIPES; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-venetian-blinds"); + m_aSubType = ::rtl::OUString::createFromAscii("horizontal"); // horizontal + break; + case 0x1: + //eRetval = ::com::sun::star::presentation::AnimationEffect_HORIZONTAL_STRIPES; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-venetian-blinds"); + m_aSubType = ::rtl::OUString::createFromAscii("vertical"); // vertical + break; + } + } + break; + case 0x03: // --- (hor/ver) shifted appear --- + { + switch ( m_aAtom.nFlyDirection ) + { + case 0x0: + //eRetval = ::com::sun::star::presentation::AnimationEffect_HORIZONTAL_CHECKERBOARD; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-checkerboard"); + m_aSubType = ::rtl::OUString::createFromAscii("across"); // vertical ??? + break; + case 0x1: + //eRetval = ::com::sun::star::presentation::AnimationEffect_VERTICAL_CHECKERBOARD; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-checkerboard"); + m_aSubType = ::rtl::OUString::createFromAscii("downward"); // horizontal ??? + break; + } + } + break; + case 0x05: + //eRetval = ::com::sun::star::presentation::AnimationEffect_DISSOLVE; // --- dissolve ---- + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-dissolve-in"); + break; + case 0x08: // --- (hor/ver) lines --- + { + switch ( m_aAtom.nFlyDirection ) + { + case 0x0: + //eRetval = ::com::sun::star::presentation::AnimationEffect_HORIZONTAL_LINES; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-random-bars"); + m_aSubType = ::rtl::OUString::createFromAscii("vertical"); // horizontal ??? + break; + case 0x1: + //eRetval = ::com::sun::star::presentation::AnimationEffect_VERTICAL_LINES; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-random-bars"); + m_aSubType = rtl::OUString::createFromAscii("horizontal"); // vertical ??? + break; + } + } + break; + case 0x09: // --- diagonal --- + { + switch ( m_aAtom.nFlyDirection ) + { + case 0x4: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_FROM_LOWERRIGHT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-diagonal-squares"); + m_aSubType = rtl::OUString::createFromAscii("left-to-top"); // to left top + break; + case 0x5: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_FROM_LOWERLEFT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-diagonal-squares"); + m_aSubType = rtl::OUString::createFromAscii("right-to-top"); // to right top + break; + case 0x6: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_FROM_UPPERRIGHT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-diagonal-squares"); + m_aSubType = rtl::OUString::createFromAscii("left-to-bottom"); // to left bottom + break; + case 0x7: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_FROM_UPPERLEFT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-diagonal-squares"); + m_aSubType = rtl::OUString::createFromAscii("right-to-bottom"); // to right bottom + break; + } + } + break; + case 0x0a: // --- roll/wipe --- + { + switch ( m_aAtom.nFlyDirection ) + { + case 0x0: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_FROM_RIGHT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-wipe"); + m_aSubType = rtl::OUString::createFromAscii("from-right"); // from right + break; + case 0x1: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_FROM_BOTTOM; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-wipe"); + m_aSubType = rtl::OUString::createFromAscii("from-bottom"); // from bottom + break; + case 0x2: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_FROM_LEFT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-wipe"); + m_aSubType = rtl::OUString::createFromAscii("from-left"); // from left + break; + case 0x3: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_FROM_TOP; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-wipe"); + m_aSubType = rtl::OUString::createFromAscii("from-top"); // from top + break; + } + } + break; + case 0x0b: //--- fade in --- + { + switch ( m_aAtom.nFlyDirection ) + { + case 0x0: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_FROM_CENTER; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-box"); + m_aSubType = rtl::OUString::createFromAscii("out"); // from center + break; + case 0x1: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_TO_CENTER; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-box"); + m_aSubType = rtl::OUString::createFromAscii("in"); // to center + break; + } + } + break; + case 0x0c: // --- text effects --- + { + switch ( m_aAtom.nFlyDirection ) + { + case 0x0: + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_LEFT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-fly-in"); + m_aSubType = rtl::OUString::createFromAscii("from-left"); + + break; + case 0x1: + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_TOP; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-fly-in"); + m_aSubType = rtl::OUString::createFromAscii("from-top"); + break; + case 0x2: + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_RIGHT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-fly-in"); + m_aSubType = rtl::OUString::createFromAscii("from-right"); + break; + case 0x3: + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_BOTTOM; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-fly-in"); + m_aSubType = rtl::OUString::createFromAscii("from-bottom"); + break; + case 0x4: + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_UPPERLEFT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-fly-in"); + m_aSubType = rtl::OUString::createFromAscii("from-top-left"); + break; + case 0x5: + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_UPPERRIGHT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-fly-in"); + m_aSubType = rtl::OUString::createFromAscii("from-top-right"); + break; + case 0x6: + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_LOWERLEFT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-fly-in"); + m_aSubType = rtl::OUString::createFromAscii("from-bottom-left"); + break; + case 0x7: + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_LOWERRIGHT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-fly-in"); + m_aSubType = rtl::OUString::createFromAscii("from-bottom-right"); + break; + case 0x8: // -- short text effects -- + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_LEFT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-peek-in"); + m_aSubType = rtl::OUString::createFromAscii("from-left"); + break; + case 0x9: + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_BOTTOM; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-peek-in"); + m_aSubType = rtl::OUString::createFromAscii("from-bottom"); + break; + case 0xa: + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_RIGHT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-peek-in"); + m_aSubType = rtl::OUString::createFromAscii("from-right"); + break; + case 0xb: + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_TOP; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-peek-in"); + m_aSubType = rtl::OUString::createFromAscii("from-top"); + break; + case 0xc: // -- slow text effects -- + { + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_LEFT; + //rSpeed = ::com::sun::star::presentation::AnimationSpeed_SLOW; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-fly-in-slow"); + m_aSubType = rtl::OUString::createFromAscii("from-left"); + } + break; + case 0xd: + { + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_TOP; + //rSpeed = ::com::sun::star::presentation::AnimationSpeed_SLOW; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-fly-in-slow"); + m_aSubType = rtl::OUString::createFromAscii("from-top"); + } + break; + case 0xe: + { + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_RIGHT; + //rSpeed = ::com::sun::star::presentation::AnimationSpeed_SLOW; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-fly-in-slow"); + m_aSubType = rtl::OUString::createFromAscii("from-right"); + } + break; + case 0xf: + { + //eRetval = ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_BOTTOM; + //rSpeed = ::com::sun::star::presentation::AnimationSpeed_SLOW; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-fly-in-slow"); + m_aSubType = rtl::OUString::createFromAscii("from-bottom"); + } + break; + case 0x10: // --- zoom --- + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_FROM_CENTER; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-zoom"); + m_aSubType = rtl::OUString::createFromAscii("in"); + break; + case 0x11: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_FROM_CENTER; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-zoom"); + m_aSubType = rtl::OUString::createFromAscii("in-slightly"); + break; + case 0x12: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_TO_CENTER; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-zoom"); + m_aSubType = rtl::OUString::createFromAscii("out"); + break; + case 0x13: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_TO_CENTER; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-zoom"); + m_aSubType = rtl::OUString::createFromAscii("out-slightly"); + break; + case 0x14: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_FROM_CENTER; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-zoom"); + m_aSubType = rtl::OUString::createFromAscii("in-from-screen-center"); + break; + case 0x15: + //eRetval = ::com::sun::star::presentation::AnimationEffect_FADE_TO_CENTER; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-zoom"); + m_aSubType = rtl::OUString::createFromAscii("out-from-screen-center"); + break; + case 0x16: // --- stretch --- + //eRetval = ::com::sun::star::presentation::AnimationEffect_HORIZONTAL_STRETCH; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-stretchy"); + m_aSubType = rtl::OUString::createFromAscii("across"); + break; + case 0x17: + //eRetval = ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_LEFT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-stretchy"); + m_aSubType = rtl::OUString::createFromAscii("from-left"); + break; + case 0x18: + //eRetval = ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_TOP; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-stretchy"); + m_aSubType = rtl::OUString::createFromAscii("from-top"); + break; + case 0x19: + //eRetval = ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_RIGHT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-stretchy"); + m_aSubType = rtl::OUString::createFromAscii("from-right"); + break; + case 0x1a: + //eRetval = ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_BOTTOM; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-stretchy"); + m_aSubType = rtl::OUString::createFromAscii("from-bottom"); + break; + case 0x1b: // --- rotate --- + //eRetval = ::com::sun::star::presentation::AnimationEffect_HORIZONTAL_ROTATE; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-swivel"); + m_aSubType = rtl::OUString::createFromAscii("vertical"); + break; + case 0x1c: // --- spirale --- + //eRetval = ::com::sun::star::presentation::AnimationEffect_SPIRALOUT_LEFT; + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-spiral-in"); + break; + } + } + break; + case 0x0d: // --- open/close --- + { + switch ( m_aAtom.nFlyDirection ) + { + case 0x0: + //eRetval = ::com::sun::star::presentation::AnimationEffect_OPEN_VERTICAL ; // ??? + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-split"); + m_aSubType = rtl::OUString::createFromAscii("horizontal-out"); //horizontal open + break; + case 0x1: + //eRetval = ::com::sun::star::presentation::AnimationEffect_CLOSE_VERTICAL; // ??? + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-split"); + m_aSubType = rtl::OUString::createFromAscii("horizontal-in"); //horizontal close + break; + case 0x2: + //eRetval = ::com::sun::star::presentation::AnimationEffect_OPEN_HORIZONTAL; // ??? + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-split"); + m_aSubType = rtl::OUString::createFromAscii("vertical-out"); // vertical open + break; + case 0x3: + //eRetval = ::com::sun::star::presentation::AnimationEffect_CLOSE_HORIZONTAL; // ??? + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-split"); + m_aSubType = rtl::OUString::createFromAscii("vertical-in"); // vertical close + break; + } + } + break; + case 0x0e: // --- blink --- + { + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-flash-once"); + switch ( m_aAtom.nFlyDirection ) + { + case 0x0: //fast + m_fDurationInSeconds = 0.075; + m_bHasSpecialDuration = true; + break; + case 0x1: //medium + m_fDurationInSeconds = 0.5; + m_bHasSpecialDuration = true; + break; + case 0x2: //slow + m_fDurationInSeconds = 1.0; + m_bHasSpecialDuration = true; + break; + } + } + break; + default: + { + m_aPresetId = ::rtl::OUString::createFromAscii("ooo-entrance-appear"); + DBG_ERROR("no effect mapped"); + } + break; + } + m_bDirtyCache = false; +} + +void Ppt97Animation::createAndSetCustomAnimationEffect( SdrObject* pObj ) +{ + + if( !this->HasEffect() ) + return; + if( !pObj || !pObj->GetPage() ) + { + DBG_ERROR("no valid SdrObject or page found for ppt import"); + return; + } + + uno::Reference< drawing::XShape > xShape = GetXShapeForSdrObject( pObj ); + if( !xShape.is() ) + { + DBG_ERROR("no XShape interface found for ppt import"); + return; + } + ::sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence(); + if( !pMainSequence.get() ) + { + DBG_ERROR("no MainSequence found for ppt import"); + return; + } + + const ::sd::CustomAnimationPresets& rPresets( ::sd::CustomAnimationPresets::getCustomAnimationPresets() ); + ::sd::CustomAnimationPresetPtr pPreset( rPresets.getEffectDescriptor( this->GetPresetId() ) ); + if( !pPreset.get() ) + { + DBG_ERROR("no suiteable preset found for ppt import"); + return; + } + + //--------------start doing something + + //1. ------ create an effect from the presets ------ + ::sd::CustomAnimationEffectPtr pEffect( new ::sd::CustomAnimationEffect( pPreset->create( this->GetPresetSubType() ) ) ); + if( !pEffect.get() ) + { + DBG_ASSERT(pEffect.get(),"no suiteable effect found"); + return; + } + + //2. ------ adapt the created effect ------ + + // set the shape targeted by this effect + pEffect->setTarget( makeAny( xShape ) ); + + pEffect->setBegin( this->GetDelayTimeInSeconds() ); + + // some effects need a different duration than that of the mapped preset effect + double fDurationInSeconds = 1.0;//in secunden + if( this->GetSpecialDuration( fDurationInSeconds ) ) + pEffect->setDuration( fDurationInSeconds ); + + // set after effect + if( this->HasAfterEffect() ) + { + pEffect->setHasAfterEffect( sal_True ); + if( this->HasAfterEffect_ChangeColor() ) + pEffect->setDimColor( uno::makeAny( this->GetDimColor() ) ); + else + pEffect->setAfterEffectOnNext( this->HasAfterEffect_DimAtNextEffect() ); + } + + // set sound effect + if( this->HasSoundEffect() ) + pEffect->createAudio( uno::makeAny( m_aSoundFileUrl ) ); + + // text iteration + pEffect->setIterateType( this->GetTextAnimationType() ); + + // some effects need a different delay between text iteration than that of the mapped preset effect + double fTextIterationDelay = 1.0; + if( this->GetSpecialTextIterationDelay( fTextIterationDelay ) ) + pEffect->setIterateInterval( fTextIterationDelay ); + + // is the effect started on click or after the last effect (Another possible value is EffectNodeType::WITH_PREVIOUS ) + pEffect->setNodeType( this->GetEffectNodeType() ); + + //set stop sound effect + if( this->HasStopPreviousSound() ) + pEffect->setStopAudio(); + + // append the effect to the main sequence + if( !this->HasParagraphEffect() ) + { + if( this->HasAnimateAssociatedShape() ) + pEffect->setTargetSubItem( presentation::ShapeAnimationSubType::AS_WHOLE ); + else + pEffect->setTargetSubItem( presentation::ShapeAnimationSubType::AS_WHOLE ); //todo: set ONLY_TEXT again if that is fixed + //pEffect->setTargetSubItem( presentation::ShapeAnimationSubType::ONLY_TEXT ); + } + + //3. ------ put the created effect to the model and do some last changes fro paragraph effects ------ + pMainSequence->append( pEffect ); + if( this->HasParagraphEffect() ) + { + sal_Int32 nParagraphLevel = this->GetParagraphLevel(); + double fDelaySeconds = this->GetDelayTimeInSeconds(); + sal_Bool bAnimateAssociatedShape = this->HasAnimateAssociatedShape();//or only text + sal_Bool bTextReverse = this->HasReverseOrder(); + + // now create effects for each paragraph + ::sd::CustomAnimationTextGroupPtr pGroup = pMainSequence-> + createTextGroup( pEffect, nParagraphLevel, fDelaySeconds, bAnimateAssociatedShape, bTextReverse ); + + if( pGroup ) + { + const ::sd::EffectSequence& rEffects = pGroup->getEffects(); + ::sd::EffectSequence::const_iterator aIter = rEffects.begin(); + + ::sd::CustomAnimationEffectPtr pLastEffect; + sal_Int32 nIndex = 0; + for( ; aIter != rEffects.end(); aIter++ ) + { + ::sd::CustomAnimationEffectPtr pGroupEffect(*aIter); + + ////todo? if( nIndex > 1 && pLastEffect && this->HasSoundEffect() ) + //// pLastEffect->setStopAudio(); + if( nIndex < 2 ) + { + pGroupEffect->setNodeType( this->GetEffectNodeType() ); + } + else if( nIndex > 0 ) + { + bool bAtParagraphBegin = false; + if(!bTextReverse) + bAtParagraphBegin = pGroupEffect->getParaDepth() < nParagraphLevel; + else + bAtParagraphBegin = !pLastEffect || pLastEffect->getParaDepth() < nParagraphLevel; + if( bAtParagraphBegin ) + pGroupEffect->setNodeType( this->GetEffectNodeType() ); + else if( this->GetTextAnimationType() == presentation::TextAnimationType::BY_PARAGRAPH ) + pGroupEffect->setNodeType( presentation::EffectNodeType::WITH_PREVIOUS ); + else + pGroupEffect->setNodeType( presentation::EffectNodeType::AFTER_PREVIOUS ); + } + pLastEffect = pGroupEffect; + nIndex++; + } + } + } + pMainSequence->rebuild(); +} diff --git a/sd/source/filter/ppt/ppt97animations.hxx b/sd/source/filter/ppt/ppt97animations.hxx new file mode 100644 index 000000000000..4aa24ab12de8 --- /dev/null +++ b/sd/source/filter/ppt/ppt97animations.hxx @@ -0,0 +1,158 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SD_PPT_97_ANIMATIONS_HXX +#define _SD_PPT_97_ANIMATIONS_HXX + +// header for class SvStream +#include <tools/stream.hxx> + +class SdrObject; +class Ppt97Animation; + +// helper class for reading PPT AnimationInfoAtom +class Ppt97AnimationInfoAtom +{ + friend class Ppt97Animation; + +//-- member + UINT32 nDimColor; + UINT32 nFlags; // 0x0004: time instead of click + UINT32 nSoundRef; + INT32 nDelayTime; // 1/1000 sec + UINT16 nOrderID; + UINT16 nSlideCount; + UINT8 nBuildType; + UINT8 nFlyMethod; + UINT8 nFlyDirection; + UINT8 nAfterEffect; //nAfterEffect: 0: none; 1: change color; 2: dim on next effect; 3: dim after effect; + UINT8 nSubEffect; + UINT8 nOLEVerb; + + // unknown, because whole size needs to be 28 + UINT8 nUnknown1; + UINT8 nUnknown2; + +//-- methods + void ReadStream( SvStream& rIn ); +/* + nFlags: + decimal / hexadecimal / binary + 1040 0x00000410 10000010000 mouseclick + 17428 0x00004414 100010000010100 after previous 0 sec (animate form) + 17412 0x00004404 100010000000100 after previous 0 sec + 1088 0x00000440 10001000000 stop previous sound and mouseclick + 1044 0x00000414 10000010100 play sound automatic + 1041 0x00000411 10000010001 + | | | | | | + | | | | | reverse order + | | | | after previous + | | | sound + | | stop previous sound + | ? + animate form + + nAfterEffect: + 1: color + 0: nothing + 3: hide after animation + 2: hide at next mouse click +*/ +}; + +class Ppt97Animation +{ + /** this is a helping class for import of PPT 97 animations + 1. use the constructor Ppt97Animation( SvStream& rIn ) to import informations from the stream + 2. use the set methods to modify and complete the data + 3. use the method createAndSetCustomAnimationEffect( ) to create an effect in sd model + */ + +public: //public methods + Ppt97Animation( SvStream& rIn ); + + Ppt97Animation(); + Ppt97Animation( const Ppt97Animation& rAnimation ); + Ppt97Animation& operator= ( const Ppt97Animation& rAnimation ); + bool operator < ( const Ppt97Animation& rAnimation ) const;//later is greater + bool operator > ( const Ppt97Animation& rAnimation ) const;//later is greater + ~Ppt97Animation(); + + //get methods + bool HasEffect() const; + bool HasParagraphEffect() const; + bool HasSoundEffect() const; + sal_Int32 GetDimColor() const; + UINT32 GetSoundRef() const; + bool HasAnimateAssociatedShape() const; //true if the shape should be animated in addition to the text + + //set methods + void SetDimColor( sal_Int32 nDimColor ); + void SetSoundFileUrl( const ::rtl::OUString& rSoundFileUrl ); + void SetAnimateAssociatedShape( bool bAnimate ); //true if the shape should be animated in addition to the text + + //action methods + /** this method creates a CustomAnimationEffect for the given SdrObject + from internal data and stores the created effect at the draw model + */ + void createAndSetCustomAnimationEffect( SdrObject* pObj ); + +private: //private methods + + //read methods + ::rtl::OUString GetPresetId() const; + ::rtl::OUString GetPresetSubType() const; + bool HasAfterEffect() const; + bool HasAfterEffect_ChangeColor() const; + bool HasAfterEffect_DimAtNextEffect() const; + bool HasAfterEffect_DimAfterEffect() const; + bool HasStopPreviousSound() const; + bool HasReverseOrder() const; //true if the text paragraphs should be animated in reverse order + sal_Int32 GetParagraphLevel() const; //paragraph level that is animated ( that paragraph and higher levels ) + sal_Int16 GetTextAnimationType() const; //see com::sun::star::presentation::TextAnimationType + sal_Int16 GetEffectNodeType() const; //see com::sun::star::presentation::EffectNodeType + double GetDelayTimeInSeconds() const;//-1 for start on mouseclick or >= 0 for a delay in seconds for automatic start + bool GetSpecialDuration( double& rfDurationInSeconds ) const; + bool GetSpecialTextIterationDelay( double& rfTextIterationDelay ) const; + + void UpdateCacheData() const; + void ClearCacheData() const; + +private: //private member + //input information: + Ppt97AnimationInfoAtom m_aAtom;//pure input from stream + ::rtl::OUString m_aSoundFileUrl;//this needs to be set in addition from outside as this class has not the knowledge to translate the sound bits to a file url/ + + //cached generated output information: + mutable bool m_bDirtyCache; + mutable ::rtl::OUString m_aPresetId; // m_aPresetId and m_aSubType match to the values in sd/xml/effects.xml + mutable ::rtl::OUString m_aSubType; + mutable bool m_bHasSpecialDuration; + mutable double m_fDurationInSeconds; +}; + +#endif diff --git a/sd/source/filter/ppt/pptanimations.hxx b/sd/source/filter/ppt/pptanimations.hxx new file mode 100644 index 000000000000..7f227476e872 --- /dev/null +++ b/sd/source/filter/ppt/pptanimations.hxx @@ -0,0 +1,559 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SD_PPT_ANIMATIONS_HXX +#define _SD_PPT_ANIMATIONS_HXX + +#include <com/sun/star/uno/Any.h> +#include <com/sun/star/animations/TransitionType.hpp> +#include <com/sun/star/animations/TransitionSubType.hpp> +#include <com/sun/star/presentation/EffectPresetClass.hpp> + +#include <map> +#include <sal/types.h> + +class SvStream; + +namespace ppt +{ + +// old transition types +#define PPT_TRANSITION_TYPE_NONE 0 +#define PPT_TRANSITION_TYPE_RANDOM 1 +#define PPT_TRANSITION_TYPE_BLINDS 2 +#define PPT_TRANSITION_TYPE_CHECKER 3 +#define PPT_TRANSITION_TYPE_COVER 4 +#define PPT_TRANSITION_TYPE_DISSOLVE 5 +#define PPT_TRANSITION_TYPE_FADE 6 +#define PPT_TRANSITION_TYPE_PULL 7 +#define PPT_TRANSITION_TYPE_RANDOM_BARS 8 +#define PPT_TRANSITION_TYPE_STRIPS 9 +#define PPT_TRANSITION_TYPE_WIPE 10 +#define PPT_TRANSITION_TYPE_ZOOM 11 +#define PPT_TRANSITION_TYPE_SPLIT 13 + +// effects, new in xp +#define PPT_TRANSITION_TYPE_DIAMOND 17 +#define PPT_TRANSITION_TYPE_PLUS 18 +#define PPT_TRANSITION_TYPE_WEDGE 19 +#define PPT_TRANSITION_TYPE_PUSH 20 +#define PPT_TRANSITION_TYPE_COMB 21 +#define PPT_TRANSITION_TYPE_NEWSFLASH 22 +#define PPT_TRANSITION_TYPE_SMOOTHFADE 23 +#define PPT_TRANSITION_TYPE_WHEEL 26 +#define PPT_TRANSITION_TYPE_CIRCLE 27 + + + +// atoms +#define DFF_msofbtAnimEvent 0xf125 +#define DFF_msofbtAnimNode 0xf127 +#define DFF_msofbtAnimTrigger 0xf128 +#define DFF_msofbtAnimValue 0xf129 +#define DFF_msofbtAnimateTarget 0xf12a +#define DFF_msofbtAnimate 0xf12b +#define DFF_msofbtAnimateColor 0xf12c +#define DFF_msofbtAnimateFilter 0xf12d +#define DFF_msofbtAnimateMotion 0xf12e +#define DFF_msofbtAnimateRotation 0xf12f +#define DFF_msofbtAnimateScale 0xf130 +#define DFF_msofbtAnimateSet 0xf131 +#define DFF_msofbtAnimCommand 0xf132 +#define DFF_msofbtAnimateTargetSettings 0xf133 +#define DFF_msofbtAnimateData 0xf134 +#define DFF_msofbtAnimateColorData 0xf135 +#define DFF_msofbtAnimateFilterData 0xf136 +#define DFF_msofbtAnimateMotionData 0xf137 +#define DFF_msofbtAnimateScaleData 0xf139 +#define DFF_msofbtAnimateSetData 0xf13a +#define DFF_msofbtCommandData 0xf13b +#define DFF_msofbtAnimateTargetElement 0xf13c +#define DFF_msofbtAnimPropertySet 0xf13d +#define DFF_msofbtAnimateAttributeNames 0xf13e +#define DFF_msofbtAnimKeyPoints 0xf13f +#define DFF_msofbtAnimIteration 0xf140 +#define DFF_msofbtAnimAction 0xf141 // correct name?? +#define DFF_msofbtAnimAttributeValue 0xf142 +#define DFF_msofbtAnimKeyTime 0xf143 +#define DFF_msofbtAnimGroup 0xf144 +#define DFF_msofbtAnimSubGoup 0xf145 +#define DFF_msofbtAnimateRotationData 0xf138 +#define DFF_msofbtAnimReference 0x2afb + +// property ids +#define DFF_ANIM_ID 1 +#define DFF_ANIM_RUNTIMECONTEXT 2 +#define DFF_ANIM_PATH_EDIT_MODE 3 +#define DFF_ANIM_COLORSPACE 4 +#define DFF_ANIM_DIRECTION 5 // TODO: Conflict? +#define DFF_ANIM_MASTERREL 5 // TODO: Conflict? +#define DFF_ANIM_OVERRIDE 6 +#define DFF_ANIM_PRESET_ID 9 +#define DFF_ANIM_PRESET_SUB_TYPE 10 +#define DFF_ANIM_PRESET_CLASS 11 +#define DFF_ANIM_AFTEREFFECT 13 +#define DFF_ANIM_ENDAFTERSLIDE 15 +#define DFF_ANIM_TIMEFILTER 16 +#define DFF_ANIM_EVENT_FILTER 17 +#define DFF_ANIM_GROUP_ID 19 +#define DFF_ANIM_NODE_TYPE 20 +#define DFF_ANIM_VOLUME 22 +#define DFF_ANIM_PROPERTY_ID_COUNT DFF_ANIM_VOLUME + + + +// property types +#define DFF_ANIM_PROP_TYPE_BYTE 0 +#define DFF_ANIM_PROP_TYPE_INT32 1 +#define DFF_ANIM_PROP_TYPE_FLOAT 2 +#define DFF_ANIM_PROP_TYPE_UNISTRING 3 + +#define DFF_ANIM_PATH_EDIT_MODE_FIXED 0 +#define DFF_ANIM_PATH_EDIT_MODE_RELATIVE 1 + +#define DFF_ANIM_PRESS_CLASS_USER_DEFINED 0 +#define DFF_ANIM_PRESS_CLASS_ENTRANCE 1 +#define DFF_ANIM_PRESS_CLASS_EXIT 2 +#define DFF_ANIM_PRESS_CLASS_EMPHASIS 3 +#define DFF_ANIM_PRESS_CLASS_MOTIONPATH 4 +#define DFF_ANIM_PRESS_CLASS_OLE_ACTION 5 +#define DFF_ANIM_PRESS_CLASS_MEDIACALL 6 + +#define DFF_ANIM_NODE_TYPE_ON_CLICK 1 +#define DFF_ANIM_NODE_TYPE_WITH_PREVIOUS 2 +#define DFF_ANIM_NODE_TYPE_AFTER_PREVIOUS 3 +#define DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE 4 +#define DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ 5 +#define DFF_ANIM_NODE_TYPE_TIMING_ROOT 9 + +#define DFF_ANIM_PROPERTY_AFTEREFFECT 20 + +/* constants for fill entry in AnimationNode */ +const sal_Int32 mso_Anim_GroupType_PAR = 0; +const sal_Int32 mso_Anim_GroupType_SEQ = 1; +const sal_Int32 mso_Anim_GroupType_NODE = 3; +const sal_Int32 mso_Anim_GroupType_MEDIA = 4; + +/* constants for fill entry in AnimationNode */ +const sal_Int32 mso_Anim_Fill_ALWAYS = 1; +const sal_Int32 mso_Anim_Fill_WHENOFF = 2; +const sal_Int32 mso_Anim_Fill_NEVER = 3; + +/* constants for fill entry in AnimationNode */ +const sal_Int32 mso_Anim_Fill_REMOVE = 1; +const sal_Int32 mso_Anim_Fill_FREEZE = 2; +const sal_Int32 mso_Anim_Fill_HOLD = 3; + +/* constants for behaviour entry in PPtAnimationNode */ +const sal_Int32 mso_Anim_Behaviour_FILTER = 24; +const sal_Int32 mso_Anim_Behaviour_ANIMATION= 25; + +typedef ::std::map< sal_Int32, ::com::sun::star::uno::Any > PropertySetMap_t; + +class PropertySet +{ +public: + PropertySetMap_t maProperties; + + bool hasProperty( sal_Int32 nProperty ) const; + ::com::sun::star::uno::Any getProperty( sal_Int32 nProperty ) const; +}; + + +enum MS_AttributeNames +{ + MS_PPT_X, MS_PPT_Y, MS_PPT_W, MS_PPT_H, MS_PPT_C, MS_R, MS_XSHEAR, MS_FILLCOLOR, MS_FILLTYPE, + MS_STROKECOLOR, MS_STROKEON, MS_STYLECOLOR, MS_STYLEROTATION, MS_FONTWEIGHT, + MS_STYLEUNDERLINE, MS_STYLEFONTFAMILY, MS_STYLEFONTSIZE, MS_STYLEFONTSTYLE, + MS_STYLEVISIBILITY, MS_STYLEOPACITY, MS_UNKNOWN +}; + +struct ImplAttributeNameConversion +{ + MS_AttributeNames meAttribute; + const char* mpMSName; + const char* mpAPIName; +}; + +/** this atom is the first entry in each animation group */ +struct AnimationNode +{ +public: + /** see mso_Anim_GroupType_? */ + sal_Int32 mnGroupType; + + /** see mso_Anim_Restart_? */ + sal_Int32 mnRestart; + + /** see mso_Anim_Fill_? */ + sal_Int32 mnFill; + + /** see mso_Anim_Behaviour_? */ + sal_Int32 mnNodeType; + + /** duration of this group in 1000th seconds */ + sal_Int32 mnDuration; + + sal_Int32 mnU1, mnU3, mnU4; + +public: + + friend SvStream& operator>>(SvStream& rIn, AnimationNode& rAtom); + friend SvStream& operator<<(SvStream& rOut, AnimationNode& rAtom); +}; + +static const ImplAttributeNameConversion gImplConversionList[] = +{ + { MS_PPT_X, "ppt_x", "X" }, + { MS_PPT_Y, "ppt_y", "Y" }, + { MS_PPT_W, "ppt_w", "Width" }, + { MS_PPT_H, "ppt_h", "Height" }, + { MS_PPT_C, "ppt_c", "DimColor" }, + { MS_R, "r", "Rotate" }, + { MS_XSHEAR, "xshear", "SkewX" }, + { MS_FILLCOLOR, "fillColor", "FillColor" }, + { MS_FILLCOLOR, "fillcolor", "FillColor" }, + { MS_FILLTYPE, "fill.type", "FillStyle" }, + { MS_STROKECOLOR, "stroke.color", "LineColor" }, + { MS_STROKEON, "stroke.on", "LineStyle" }, + { MS_STYLECOLOR, "style.color", "CharColor" }, + { MS_STYLEROTATION, "style.rotation", "Rotate" }, + { MS_FONTWEIGHT, "style.fontWeight", "CharWeight" }, + { MS_STYLEUNDERLINE, "style.textDecorationUnderline","CharUnderline" }, + { MS_STYLEFONTFAMILY, "style.fontFamily", "CharFontName" }, + { MS_STYLEFONTSIZE, "style.fontSize", "CharHeight" }, + { MS_STYLEFONTSTYLE, "style.fontStyle", "CharPosture" }, + { MS_STYLEVISIBILITY, "style.visibility", "Visibility" }, + { MS_STYLEOPACITY, "style.opacity", "Opacity" }, + { MS_UNKNOWN, NULL, NULL } +}; + +struct transition +{ + const sal_Char* mpName; + sal_Int16 mnType; + sal_Int16 mnSubType; + sal_Bool mbDirection; // true: default geometric direction + + static const transition* find( const rtl::OUString& rName ); + static const sal_Char* find( const sal_Int16 mnType, const sal_Int16 mnSubType, const sal_Bool bDirection ); +}; +static const transition gTransitions[] = +{ +{ "wipe(up)", ::com::sun::star::animations::TransitionType::BARWIPE, ::com::sun::star::animations::TransitionSubType::TOPTOBOTTOM, sal_True }, +{ "wipe(right)", ::com::sun::star::animations::TransitionType::BARWIPE, ::com::sun::star::animations::TransitionSubType::LEFTTORIGHT, sal_False }, +{ "wipe(left)", ::com::sun::star::animations::TransitionType::BARWIPE, ::com::sun::star::animations::TransitionSubType::LEFTTORIGHT, sal_True }, +{ "wipe(down)", ::com::sun::star::animations::TransitionType::BARWIPE, ::com::sun::star::animations::TransitionSubType::TOPTOBOTTOM, sal_False }, +{ "wheel(1)", ::com::sun::star::animations::TransitionType::PINWHEELWIPE, ::com::sun::star::animations::TransitionSubType::ONEBLADE, sal_True }, +{ "wheel(2)", ::com::sun::star::animations::TransitionType::PINWHEELWIPE, ::com::sun::star::animations::TransitionSubType::TWOBLADEVERTICAL, sal_True }, +{ "wheel(3)", ::com::sun::star::animations::TransitionType::PINWHEELWIPE, ::com::sun::star::animations::TransitionSubType::THREEBLADE, sal_True }, +{ "wheel(4)", ::com::sun::star::animations::TransitionType::PINWHEELWIPE, ::com::sun::star::animations::TransitionSubType::FOURBLADE, sal_True }, +{ "wheel(8)", ::com::sun::star::animations::TransitionType::PINWHEELWIPE, ::com::sun::star::animations::TransitionSubType::EIGHTBLADE, sal_True }, +{ "strips(downLeft)", ::com::sun::star::animations::TransitionType::WATERFALLWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTALRIGHT, sal_True }, +{ "strips(upLeft)", ::com::sun::star::animations::TransitionType::WATERFALLWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTALLEFT, sal_False }, +{ "strips(downRight)", ::com::sun::star::animations::TransitionType::WATERFALLWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTALLEFT, sal_True }, +{ "strips(upRight)", ::com::sun::star::animations::TransitionType::WATERFALLWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTALRIGHT, sal_False }, +{ "barn(inVertical)", ::com::sun::star::animations::TransitionType::BARNDOORWIPE, ::com::sun::star::animations::TransitionSubType::VERTICAL, sal_False }, +{ "barn(outVertical)", ::com::sun::star::animations::TransitionType::BARNDOORWIPE, ::com::sun::star::animations::TransitionSubType::VERTICAL, sal_True }, +{ "barn(inHorizontal)", ::com::sun::star::animations::TransitionType::BARNDOORWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTAL, sal_False }, +{ "barn(outHorizontal)", ::com::sun::star::animations::TransitionType::BARNDOORWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTAL, sal_True }, +{ "randombar(vertical)", ::com::sun::star::animations::TransitionType::RANDOMBARWIPE, ::com::sun::star::animations::TransitionSubType::VERTICAL, sal_True}, +{ "randombar(horizontal)", ::com::sun::star::animations::TransitionType::RANDOMBARWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTAL, sal_True }, +{ "checkerboard(down)", ::com::sun::star::animations::TransitionType::CHECKERBOARDWIPE, ::com::sun::star::animations::TransitionSubType::DOWN, sal_True}, +{ "checkerboard(across)", ::com::sun::star::animations::TransitionType::CHECKERBOARDWIPE, ::com::sun::star::animations::TransitionSubType::ACROSS, sal_True }, +{ "plus(out)", ::com::sun::star::animations::TransitionType::FOURBOXWIPE, ::com::sun::star::animations::TransitionSubType::CORNERSIN, sal_False }, +{ "plus(in)", ::com::sun::star::animations::TransitionType::FOURBOXWIPE, ::com::sun::star::animations::TransitionSubType::CORNERSIN, sal_True }, +{ "diamond(out)", ::com::sun::star::animations::TransitionType::IRISWIPE, ::com::sun::star::animations::TransitionSubType::DIAMOND, sal_True }, +{ "diamond(in)", ::com::sun::star::animations::TransitionType::IRISWIPE, ::com::sun::star::animations::TransitionSubType::DIAMOND, sal_False }, +{ "circle(out)", ::com::sun::star::animations::TransitionType::ELLIPSEWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTAL, sal_True }, +{ "circle(in)", ::com::sun::star::animations::TransitionType::ELLIPSEWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTAL, sal_False }, +{ "box(out)", ::com::sun::star::animations::TransitionType::IRISWIPE, ::com::sun::star::animations::TransitionSubType::RECTANGLE, sal_True }, +{ "box(in)", ::com::sun::star::animations::TransitionType::IRISWIPE, ::com::sun::star::animations::TransitionSubType::RECTANGLE, sal_False }, +{ "wedge", ::com::sun::star::animations::TransitionType::FANWIPE, ::com::sun::star::animations::TransitionSubType::CENTERTOP, sal_True }, +{ "blinds(vertical)", ::com::sun::star::animations::TransitionType::BLINDSWIPE, ::com::sun::star::animations::TransitionSubType::VERTICAL, sal_True }, +{ "blinds(horizontal)", ::com::sun::star::animations::TransitionType::BLINDSWIPE, ::com::sun::star::animations::TransitionSubType::HORIZONTAL, sal_True }, +{ "fade", ::com::sun::star::animations::TransitionType::FADE, ::com::sun::star::animations::TransitionSubType::CROSSFADE, sal_True }, +{ "slide(fromTop)", ::com::sun::star::animations::TransitionType::SLIDEWIPE, ::com::sun::star::animations::TransitionSubType::FROMTOP, sal_True }, +{ "slide(fromRight)", ::com::sun::star::animations::TransitionType::SLIDEWIPE, ::com::sun::star::animations::TransitionSubType::FROMRIGHT, sal_True }, +{ "slide(fromLeft)", ::com::sun::star::animations::TransitionType::SLIDEWIPE, ::com::sun::star::animations::TransitionSubType::FROMLEFT, sal_True }, +{ "slide(fromBottom)", ::com::sun::star::animations::TransitionType::SLIDEWIPE, ::com::sun::star::animations::TransitionSubType::FROMBOTTOM, sal_True }, +{ "dissolve", ::com::sun::star::animations::TransitionType::DISSOLVE, ::com::sun::star::animations::TransitionSubType::DEFAULT, sal_True }, +{ "image", ::com::sun::star::animations::TransitionType::DISSOLVE, ::com::sun::star::animations::TransitionSubType::DEFAULT, sal_True }, // TODO +{ NULL, 0, 0, sal_False } +}; + +struct convert_subtype +{ + sal_Int32 mnID; + const sal_Char* mpStrSubType; +}; +static const convert_subtype gConvertArray[] = +{ + // fly in + { 1, "from-top" }, + { 2, "from-right" }, + { 3, "from-top-right" }, + { 4, "from-bottom" }, + { 5, "horizontal" }, + { 6, "from-bottom-right" }, + { 8, "from-left" }, + { 9, "from-top-left" }, + { 10, "vertical" }, + { 12, "from-bottom-left" }, + { 16, "in" }, + { 21, "vertical-in" }, + { 26, "horizontal-in" }, + { 32, "out" }, + { 36, "out-from-screen-center" }, + { 37, "vertical-out" }, + { 42, "horizontal-out" }, + { 272, "in-slightly" }, + { 288, "out-slightly" }, + { 528, "in-from-screen-center" }, + { 0, 0 } +}; + +struct preset_maping +{ + sal_Int32 mnPresetClass; + sal_Int32 mnPresetId; + const sal_Char* mpStrPresetId; +}; + +static const preset_maping gPresetMaping[] = +{ + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 1 ,"ooo-entrance-appear" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 2 ,"ooo-entrance-fly-in" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 3 ,"ooo-entrance-venetian-blinds" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 4 ,"ooo-entrance-box" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 5 ,"ooo-entrance-checkerboard" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 6 ,"ooo-entrance-circle" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 7 ,"ooo-entrance-fly-in-slow" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 8 ,"ooo-entrance-diamond" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 9 ,"ooo-entrance-dissolve-in" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 10 ,"ooo-entrance-fade-in" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 11 ,"ooo-entrance-flash-once" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 12 ,"ooo-entrance-peek-in" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 13 ,"ooo-entrance-plus" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 14 ,"ooo-entrance-random-bars" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 15 ,"ooo-entrance-spiral-in" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 16 ,"ooo-entrance-split" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 17 ,"ooo-entrance-stretchy" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 18 ,"ooo-entrance-diagonal-squares" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 19 ,"ooo-entrance-swivel" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 20 ,"ooo-entrance-wedge" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 21 ,"ooo-entrance-wheel" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 22 ,"ooo-entrance-wipe" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 23 ,"ooo-entrance-zoom" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 24 ,"ooo-entrance-random" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 25 ,"ooo-entrance-boomerang" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 26 ,"ooo-entrance-bounce" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 27 ,"ooo-entrance-colored-lettering" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 28 ,"ooo-entrance-movie-credits" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 29 ,"ooo-entrance-ease-in" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 30 ,"ooo-entrance-float" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 31 ,"ooo-entrance-turn-and-grow" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 34 ,"ooo-entrance-breaks" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 35 ,"ooo-entrance-pinwheel" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 37 ,"ooo-entrance-rise-up" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 38 ,"ooo-entrance-falling-in" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 39 ,"ooo-entrance-thread" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 40 ,"ooo-entrance-unfold" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 41 ,"ooo-entrance-whip" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 42 ,"ooo-entrance-ascend" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 43 ,"ooo-entrance-center-revolve" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 45 ,"ooo-entrance-fade-in-and-swivel" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 47 ,"ooo-entrance-descend" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 48 ,"ooo-entrance-sling" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 49 ,"ooo-entrance-spin-in" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 50 ,"ooo-entrance-compress" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 51 ,"ooo-entrance-magnify" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 52 ,"ooo-entrance-curve-up" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 53 ,"ooo-entrance-fade-in-and-zoom" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 54 ,"ooo-entrance-glide" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 55 ,"ooo-entrance-expand" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 56 ,"ooo-entrance-flip" }, + { ::com::sun::star::presentation::EffectPresetClass::ENTRANCE, 58 ,"ooo-entrance-fold" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 1 ,"ooo-emphasis-fill-color" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 2 ,"ooo-emphasis-font" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 3 ,"ooo-emphasis-font-color" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 4 ,"ooo-emphasis-font-size" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 5 ,"ooo-emphasis-font-style" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 6 ,"ooo-emphasis-grow-and-shrink" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 7 ,"ooo-emphasis-line-color" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 8 ,"ooo-emphasis-spin" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 9 ,"ooo-emphasis-transparency" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 10 ,"ooo-emphasis-bold-flash" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 14 ,"ooo-emphasis-blast" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 15 ,"ooo-emphasis-bold-reveal" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 16 ,"ooo-emphasis-color-over-by-word" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 18 ,"ooo-emphasis-reveal-underline" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 19 ,"ooo-emphasis-color-blend" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 20 ,"ooo-emphasis-color-over-by-letter" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 21 ,"ooo-emphasis-complementary-color" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 22 ,"ooo-emphasis-complementary-color-2" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 23 ,"ooo-emphasis-contrasting-color" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 24 ,"ooo-emphasis-darken" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 25 ,"ooo-emphasis-desaturate" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 26 ,"ooo-emphasis-flash-bulb" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 27 ,"ooo-emphasis-flicker" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 28 ,"ooo-emphasis-grow-with-color" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 30 ,"ooo-emphasis-lighten" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 31 ,"ooo-emphasis-style-emphasis" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 32 ,"ooo-emphasis-teeter" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 33 ,"ooo-emphasis-vertical-highlight" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 34 ,"ooo-emphasis-wave" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 35 ,"ooo-emphasis-blink" }, + { ::com::sun::star::presentation::EffectPresetClass::EMPHASIS, 36 ,"ooo-emphasis-shimmer" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 1 ,"ooo-exit-disappear" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 2 ,"ooo-exit-fly-out" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 3 ,"ooo-exit-venetian-blinds" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 4 ,"ooo-exit-box" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 5 ,"ooo-exit-checkerboard" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 6 ,"ooo-exit-circle" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 7 ,"ooo-exit-crawl-out" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 8 ,"ooo-exit-diamond" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 9 ,"ooo-exit-dissolve" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 10 ,"ooo-exit-fade-out" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 11 ,"ooo-exit-flash-once" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 12 ,"ooo-exit-peek-out" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 13 ,"ooo-exit-plus" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 14 ,"ooo-exit-random-bars" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 15 ,"ooo-exit-spiral-out" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 16 ,"ooo-exit-split" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 17 ,"ooo-exit-collapse" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 18 ,"ooo-exit-diagonal-squares" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 19 ,"ooo-exit-swivel" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 20 ,"ooo-exit-wedge" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 21 ,"ooo-exit-wheel" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 22 ,"ooo-exit-wipe" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 23 ,"ooo-exit-zoom" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 24 ,"ooo-exit-random" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 25 ,"ooo-exit-boomerang" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 26 ,"ooo-exit-bounce" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 27 ,"ooo-exit-colored-lettering" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 28 ,"ooo-exit-movie-credits" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 29 ,"ooo-exit-ease-out" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 30 ,"ooo-exit-float" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 31 ,"ooo-exit-turn-and-grow" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 34 ,"ooo-exit-breaks" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 35 ,"ooo-exit-pinwheel" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 37 ,"ooo-exit-sink-down" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 38 ,"ooo-exit-swish" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 39 ,"ooo-exit-thread" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 40 ,"ooo-exit-unfold" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 41 ,"ooo-exit-whip" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 42 ,"ooo-exit-descend" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 43 ,"ooo-exit-center-revolve" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 45 ,"ooo-exit-fade-out-and-swivel" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 47 ,"ooo-exit-ascend" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 48 ,"ooo-exit-sling" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 53 ,"ooo-exit-fade-out-and-zoom" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 55 ,"ooo-exit-contract" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 49 ,"ooo-exit-spin-out" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 50 ,"ooo-exit-stretchy" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 51 ,"ooo-exit-magnify" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 52 ,"ooo-exit-curve-down" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 54 ,"ooo-exit-glide" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 56 ,"ooo-exit-flip" }, + { ::com::sun::star::presentation::EffectPresetClass::EXIT, 58 ,"ooo-exit-fold" }, + + + + + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 16 ,"ooo-motionpath-4-point-star" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 5 ,"ooo-motionpath-5-point-star" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 11 ,"ooo-motionpath-6-point-star" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 17 ,"ooo-motionpath-8-point-star" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 1 ,"ooo-motionpath-circle" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 6 ,"ooo-motionpath-crescent-moon" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 3 ,"ooo-motionpath-diamond" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 13 ,"ooo-motionpath-equal-triangle" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 12 ,"ooo-motionpath-oval" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 9 ,"ooo-motionpath-heart" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 4 ,"ooo-motionpath-hexagon" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 10 ,"ooo-motionpath-octagon" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 14 ,"ooo-motionpath-parallelogram" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 15 ,"ooo-motionpath-pentagon" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 2 ,"ooo-motionpath-right-triangle" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 7 ,"ooo-motionpath-square" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 18 ,"ooo-motionpath-teardrop" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 8 ,"ooo-motionpath-trapezoid" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 37 ,"ooo-motionpath-arc-down" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 51 ,"ooo-motionpath-arc-left" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 58 ,"ooo-motionpath-arc-right" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 44 ,"ooo-motionpath-arc-up" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 41 ,"ooo-motionpath-bounce-left" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 54 ,"ooo-motionpath-bounce-right" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 48 ,"ooo-motionpath-curvy-left" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 61 ,"ooo-motionpath-curvy-right" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 60 ,"ooo-motionpath-decaying-wave" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 49 ,"ooo-motionpath-diagonal-down-right" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 56 ,"ooo-motionpath-diagonal-up-right" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 42 ,"ooo-motionpath-down" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 52 ,"ooo-motionpath-funnel" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 53 ,"ooo-motionpath-spring" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 62 ,"ooo-motionpath-stairs-down" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 50 ,"ooo-motionpath-turn-down" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 36 ,"ooo-motionpath-turn-down-right" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 43 ,"ooo-motionpath-turn-up" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 57 ,"ooo-motionpath-turn-up-right" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 64 ,"ooo-motionpath-up" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 47 ,"ooo-motionpath-wave" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 38 ,"ooo-motionpath-zigzag" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 31 ,"ooo-motionpath-bean" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 25 ,"ooo-motionpath-buzz-saw" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 20 ,"ooo-motionpath-curved-square" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 21 ,"ooo-motionpath-curved-x" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 23 ,"ooo-motionpath-curvy-star" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 28 ,"ooo-motionpath-figure-8-four" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 26 ,"ooo-motionpath-horizontal-figure-8" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 34 ,"ooo-motionpath-inverted-square" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 33 ,"ooo-motionpath-inverted-triangle" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 24 ,"ooo-motionpath-loop-de-loop" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 29 ,"ooo-motionpath-neutron" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 27 ,"ooo-motionpath-peanut" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 32 ,"ooo-motionpath-clover" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 19 ,"ooo-motionpath-pointy-star" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 30 ,"ooo-motionpath-swoosh" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 22 ,"ooo-motionpath-vertical-figure-8" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 35 ,"ooo-motionpath-left" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 63 ,"ooo-motionpath-right" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 55 ,"ooo-motionpath-spiral-left" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 46 ,"ooo-motionpath-spiral-right" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 40 ,"ooo-motionpath-sine-wave" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 59 ,"ooo-motionpath-s-curve-1" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 39 ,"ooo-motionpath-s-curve-2" }, + { ::com::sun::star::presentation::EffectPresetClass::MOTIONPATH, 45 ,"ooo-motionpath-heartbeat" }, + + + { 0,0,0 } +}; + +} // namespace ppt + +#endif diff --git a/sd/source/filter/ppt/pptatom.cpp b/sd/source/filter/ppt/pptatom.cpp new file mode 100644 index 000000000000..21a0c3c3f9f8 --- /dev/null +++ b/sd/source/filter/ppt/pptatom.cpp @@ -0,0 +1,123 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _STREAM_HXX +#include <tools/stream.hxx> +#endif + +#ifndef _PPTATOM_HXX_ +#include "pptatom.hxx" +#endif + +using namespace ppt; + +Atom::Atom( const DffRecordHeader& rRecordHeader, SvStream& rStream ) +: mrStream( rStream ) +, maRecordHeader( rRecordHeader ) +, mpFirstChild( 0 ) +, mpNextAtom( 0 ) +{ + if( isContainer() ) + { + if( seekToContent() ) + { + DffRecordHeader aChildHeader; + + Atom* pLastAtom = NULL; + + while( (mrStream.GetError() == 0 ) && ( mrStream.Tell() < maRecordHeader.GetRecEndFilePos() ) ) + { + mrStream >> aChildHeader; + + if( mrStream.GetError() == 0 ) + { + Atom* pAtom = new Atom( aChildHeader, mrStream ); + + if( pLastAtom ) + pLastAtom->mpNextAtom = pAtom; + if( mpFirstChild == NULL ) + mpFirstChild = pAtom; + + pLastAtom = pAtom; + } + } + } + } + + maRecordHeader.SeekToEndOfRecord( mrStream ); +} + +Atom::~Atom() +{ + Atom* pChild = mpFirstChild; + while( pChild ) + { + Atom* pNextChild = pChild->mpNextAtom; + delete pChild; + pChild = pNextChild; + } +} + +/** imports this atom and its child atoms */ +Atom* Atom::import( const DffRecordHeader& rRootRecordHeader, SvStream& rStCtrl ) +{ + Atom* pRootAtom = new Atom( rRootRecordHeader, rStCtrl ); + + if( rStCtrl.GetError() == 0 ) + { + return pRootAtom; + } + else + { + delete pRootAtom; + return NULL; + } +} + +/** returns the next child atom after pLast with nRecType or NULL */ +const Atom* Atom::findNextChildAtom( sal_uInt16 nRecType, const Atom* pLast ) const +{ + Atom* pChild = pLast != NULL ? pLast->mpNextAtom : mpFirstChild; + while( pChild && pChild->maRecordHeader.nRecType != nRecType ) + { + pChild = pChild->mpNextAtom; + } + + return pChild; +} + +/** returns the next child atom after pLast with nRecType and nRecInstance or NULL */ +const Atom* Atom::findNextChildAtom( sal_uInt16 nRecType, sal_uInt16 nRecInstance, const Atom* pLast ) const +{ + const Atom* pChild = pLast != NULL ? pLast->mpNextAtom : mpFirstChild; + while( pChild && (pChild->maRecordHeader.nRecType != nRecType) && (pChild->maRecordHeader.nRecInstance != nRecInstance) ) + { + pChild = findNextChildAtom( pChild ); + } + + return pChild; +} diff --git a/sd/source/filter/ppt/pptatom.hxx b/sd/source/filter/ppt/pptatom.hxx new file mode 100644 index 000000000000..0b13dc314584 --- /dev/null +++ b/sd/source/filter/ppt/pptatom.hxx @@ -0,0 +1,160 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _PPTATOM_HXX_ +#define _PPTATOM_HXX_ + +#include <svx/msdffdef.hxx> +#include <filter/msfilter/msdffimp.hxx> + +class SvStream; + +namespace ppt +{ + +class Atom +{ +public: + ~Atom(); + + /** imports this atom and its child atoms */ + static Atom* import( const DffRecordHeader& rRootRecordHeader, SvStream& rStCtrl ); + + inline const DffRecordHeader& getHeader() const; + + /** returns true if at least one atim with the given nRecType is found */ + inline bool hasChildAtom( sal_uInt16 nRecType ) const; + + /** returns true if at least one atim with the given nRecType and nRecInstnace is found */ + inline bool hasChildAtom( sal_uInt16 nRecType, sal_uInt16 nRecInstance ) const; + + /** returns the first child atom with nRecType or NULL */ + inline const Atom* findFirstChildAtom( sal_uInt16 nRecType ) const; + + /** returns the next child atom after pLast with nRecType or NULL */ + const Atom* findNextChildAtom( sal_uInt16 nRecType, const Atom* pLast ) const; + + /** returns the first child atom with nRecType and nRecInstance or NULL */ + inline const Atom* findFirstChildAtom( sal_uInt16 nRecType, sal_uInt16 nRecInstance ) const; + + /** returns the next child atom after pLast with nRecType and nRecInstance or NULL */ + const Atom* findNextChildAtom( sal_uInt16 nRecType, sal_uInt16 nRecInstance, const Atom* pLast ) const; + + /** returns the first child atom or NULL */ + inline const Atom* findFirstChildAtom() const; + + /** returns the next child atom after pLast or NULL */ + inline const Atom* findNextChildAtom( const Atom* pLast ) const; + + /** returns true if this atom is a container */ + inline bool isContainer() const; + + /** seeks to the contents of this atom */ + inline bool seekToContent() const; + + /** returns the record type */ + inline sal_uInt16 getType() const; + + /** returns the record instance */ + inline sal_uInt16 getInstance() const; + + /** returns the record length */ + inline sal_uInt32 getLength() const; + +private: + Atom( const DffRecordHeader& rRecordHeader, SvStream& rStCtrl ); + + SvStream& mrStream; + DffRecordHeader maRecordHeader; + Atom* mpFirstChild; + Atom* mpNextAtom; +}; + +inline bool Atom::hasChildAtom( sal_uInt16 nRecType ) const +{ + return findFirstChildAtom( nRecType ) != NULL; +} + +inline bool Atom::hasChildAtom( sal_uInt16 nRecType, sal_uInt16 nRecInstance ) const +{ + return findFirstChildAtom( nRecType, nRecInstance ) != NULL; +} + +inline const Atom* Atom::findFirstChildAtom( sal_uInt16 nRecType ) const +{ + return findNextChildAtom( nRecType, NULL ); +} + +inline const DffRecordHeader& Atom::getHeader() const +{ + return maRecordHeader; +} + +inline const Atom* Atom::findFirstChildAtom( sal_uInt16 nRecType, sal_uInt16 nRecInstance ) const +{ + return findNextChildAtom( nRecType, nRecInstance, NULL ); +} + +inline const Atom* Atom::findFirstChildAtom() const +{ + return mpFirstChild; +} + +inline const Atom* Atom::findNextChildAtom( const Atom* pLast ) const +{ + return pLast ? pLast->mpNextAtom : pLast; +} + +inline bool Atom::isContainer() const +{ + return (bool)maRecordHeader.IsContainer(); +} + +inline bool Atom::seekToContent() const +{ + maRecordHeader.SeekToContent( mrStream ); + return mrStream.GetError() == 0; +} + +inline sal_uInt16 Atom::getType() const +{ + return maRecordHeader.nRecType; +} + +inline sal_uInt16 Atom::getInstance() const +{ + return maRecordHeader.nRecInstance; +} + +inline sal_uInt32 Atom::getLength() const +{ + return maRecordHeader.nRecLen; +} + +} // namespace ppt + +#endif diff --git a/sd/source/filter/ppt/pptin.cxx b/sd/source/filter/ppt/pptin.cxx new file mode 100644 index 000000000000..59d5b5e0b98a --- /dev/null +++ b/sd/source/filter/ppt/pptin.cxx @@ -0,0 +1,2762 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" + +#include <editeng/numitem.hxx> + +#include <unotools/ucbstreamhelper.hxx> +#include <vcl/wrkwin.hxx> +#include <svl/urihelper.hxx> +#include <svx/svxids.hrc> +#include <filter/msfilter/svdfppt.hxx> +#include <svx/svditer.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/app.hxx> +#include <svx/svdograf.hxx> +#include <svx/svdlayer.hxx> +#include <vcl/msgbox.hxx> +#include <svl/style.hxx> +#include <svx/xflclit.hxx> +#include <editeng/eeitem.hxx> +#include <editeng/colritem.hxx> +#include <svl/whiter.hxx> +#include <svx/xgrad.hxx> +#include <svx/xflgrit.hxx> +#include <svx/xbtmpit.hxx> +#include <svx/xlnclit.hxx> +#include <editeng/adjitem.hxx> +#include <editeng/editeng.hxx> +#include <editeng/bulitem.hxx> +#include <editeng/lrspitem.hxx> +#include <editeng/lspcitem.hxx> +#include <editeng/tstpitem.hxx> + +#include <sfx2/docinf.hxx> + +#include "glob.hrc" +#include "pptin.hxx" +#include "Outliner.hxx" +#include "drawdoc.hxx" +#include "sdpage.hxx" +#include "sdresid.hxx" +#include "pres.hxx" +#include "sdresid.hxx" +#include "stlpool.hxx" +#include "anminfo.hxx" +#include <svx/gallery.hxx> +#include <tools/urlobj.hxx> +#include <editeng/numitem.hxx> +#include <svl/itempool.hxx> +#include <editeng/fhgtitem.hxx> +#include <svx/svdopage.hxx> +#include <svx/svdomedia.hxx> +#include <svx/svdogrp.hxx> +#include "propread.hxx" +#include <cusshow.hxx> +#include <vcl/bmpacc.hxx> + +#include "../../ui/inc/DrawDocShell.hxx" +#include "../../ui/inc/FrameView.hxx" +#include "../../ui/inc/optsitem.hxx" + +#include <unotools/fltrcfg.hxx> +#include <sfx2/progress.hxx> +#include <unotools/localfilehelper.hxx> +#include <editeng/editstat.hxx> +#include <unotools/pathoptions.hxx> +#include <sfx2/docfac.hxx> +#define MAX_USER_MOVE 2 + +#include "pptinanimations.hxx" +#include "ppt97animations.hxx" + +#include <com/sun/star/document/XDocumentProperties.hpp> +#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> + + +using namespace ::com::sun::star; + + +SdPPTImport::SdPPTImport( SdDrawDocument* pDocument, SvStream& rDocStream, SvStorage& rStorage, SfxMedium& rMedium, MSFilterTracer* pTracer ) +{ + + sal_uInt32 nImportFlags = 0; + +#ifdef DBG_UTIL + PropRead* pSummaryInformation = new PropRead( rStorage, String( RTL_CONSTASCII_USTRINGPARAM( "\005SummaryInformation" ) ) ); + if ( pSummaryInformation->IsValid() ) + { + pSummaryInformation->Read(); + sal_uInt8 aPropSetGUID[ 16 ] = + { + 0xe0, 0x85, 0x9f, 0xf2, 0xf9, 0x4f, 0x68, 0x10, 0xab, 0x91, 0x08, 0x00, 0x2b, 0x27, 0xb3, 0xd9 + }; + Section* pSection = (Section*)pSummaryInformation->GetSection( aPropSetGUID ); + if ( pSection ) + { + PropItem aPropItem; + if ( pSection->GetProperty( PID_COMMENTS, aPropItem ) ) + { + String aComment; + aPropItem.Read( aComment ); + if ( aComment.Search( String( RTL_CONSTASCII_USTRINGPARAM( "Applixware" ) ), 0 ) != STRING_NOTFOUND ) + { + nImportFlags |= PPT_IMPORTFLAGS_NO_TEXT_ASSERT; + } + } + } + } + delete pSummaryInformation; +#endif + + PowerPointImportParam aParam( rDocStream, nImportFlags, pTracer ); + SvStream* pCurrentUserStream = rStorage.OpenSotStream( String( RTL_CONSTASCII_USTRINGPARAM( "Current User" ) ), STREAM_STD_READ ); + if( pCurrentUserStream ) + { + *pCurrentUserStream >> aParam.aCurrentUserAtom; + delete pCurrentUserStream; + } + + if( pDocument ) + { + // iterate over all styles + SdStyleSheetPool* pStyleSheetPool = pDocument->GetSdStyleSheetPool(); + + sal_uInt32 nStyles = pStyleSheetPool ? pStyleSheetPool->GetStyles().size() : 0; + for (sal_uInt32 nStyle = 0; nStyle < nStyles; nStyle++) + { + SfxStyleSheet* pSheet = static_cast<SfxStyleSheet*>( pStyleSheetPool->GetStyles()[nStyle].get() ); + SfxItemSet& rSet = pSheet->GetItemSet(); + + // if autokerning is set in style, override it, ppt has no autokerning + if( rSet.GetItemState( EE_CHAR_PAIRKERNING, FALSE ) == SFX_ITEM_SET ) + rSet.ClearItem( EE_CHAR_PAIRKERNING ); + } + } + + pFilter = new ImplSdPPTImport( pDocument, rStorage, rMedium, aParam ); +} + +sal_Bool SdPPTImport::Import() +{ + return pFilter->Import(); +} + +SdPPTImport::~SdPPTImport() +{ + delete pFilter; +} + +ImplSdPPTImport::ImplSdPPTImport( SdDrawDocument* pDocument, SvStorage& rStorage_, SfxMedium& rMedium, PowerPointImportParam& rParam ) +: SdrPowerPointImport ( rParam, rMedium.GetBaseURL() ) +, mrMed ( rMedium ) +, mrStorage ( rStorage_ ) +, mbDocumentFound ( FALSE ) +, mnFilterOptions ( 0 ) +{ + mpDoc = pDocument; + if ( bOk ) + { + mbDocumentFound = SeekToDocument( &maDocHd ); // maDocHd = the latest DocumentHeader + while ( SeekToRec( rStCtrl, PPT_PST_Document, nStreamLen, &maDocHd ) ) + mbDocumentFound = TRUE; + + UINT32 nDggContainerOfs = 0; + + if ( mbDocumentFound ) + { + ULONG nPosMerk = rStCtrl.Tell(); + + pStData = rStorage_.OpenSotStream( String( RTL_CONSTASCII_USTRINGPARAM( "Pictures" ) ), STREAM_STD_READ ); + + rStCtrl.Seek( maDocHd.GetRecBegFilePos() + 8 ); + ULONG nDocLen = maDocHd.GetRecEndFilePos(); + DffRecordHeader aPPDGHd; + if ( SeekToRec( rStCtrl, PPT_PST_PPDrawingGroup, nDocLen, &aPPDGHd ) ) + { + ULONG nPPDGLen = aPPDGHd.GetRecEndFilePos(); + if ( SeekToRec( rStCtrl, DFF_msofbtDggContainer, nPPDGLen, NULL ) ) + nDggContainerOfs = rStCtrl.Tell(); + } + rStCtrl.Seek( nPosMerk ); + } + sal_uInt32 nSvxMSDffOLEConvFlags2 = 0; + + SvtFilterOptions* pBasOpt = SvtFilterOptions::Get(); + if ( pBasOpt ) + { + if ( pBasOpt->IsLoadPPointBasicCode() ) + mnFilterOptions |= 1; + if ( pBasOpt->IsMathType2Math() ) + nSvxMSDffOLEConvFlags2 |= OLE_MATHTYPE_2_STARMATH; + if ( pBasOpt->IsWinWord2Writer() ) + nSvxMSDffOLEConvFlags2 |= OLE_WINWORD_2_STARWRITER; + if ( pBasOpt->IsExcel2Calc() ) + nSvxMSDffOLEConvFlags2 |= OLE_EXCEL_2_STARCALC; + if ( pBasOpt->IsPowerPoint2Impress() ) + nSvxMSDffOLEConvFlags2 |= OLE_POWERPOINT_2_STARIMPRESS; + } + + InitSvxMSDffManager( nDggContainerOfs, pStData, nSvxMSDffOLEConvFlags2 ); + SetSvxMSDffSettings( SVXMSDFF_SETTINGS_CROP_BITMAPS + | SVXMSDFF_SETTINGS_IMPORT_PPT ); + SetModel( mpDoc, 576 ); + } +} + +////////////////////////////////////////////////////////////////////////// +// +// Dtor +// +////////////////////////////////////////////////////////////////////////// + +ImplSdPPTImport::~ImplSdPPTImport() +{ + for ( void* pPtr = maSlideNameList.First(); pPtr; pPtr = maSlideNameList.Next() ) + delete (String*)pPtr; + delete pStData; +} + +////////////////////////////////////////////////////////////////////////// +// +// Import +// +////////////////////////////////////////////////////////////////////////// + +sal_Bool ImplSdPPTImport::Import() +{ + if ( !bOk ) + return FALSE; + + pSdrModel->setLock( sal_True ); + pSdrModel->EnableUndo(false); + + SdrOutliner& rOutl = mpDoc->GetDrawOutliner(); + sal_uInt32 nControlWord = rOutl.GetEditEngine().GetControlWord(); + nControlWord |= EE_CNTRL_ULSPACESUMMATION; + nControlWord &=~ EE_CNTRL_ULSPACEFIRSTPARA; + ((EditEngine&)rOutl.GetEditEngine()).SetControlWord( nControlWord ); + + SdrLayerAdmin& rAdmin = mpDoc->GetLayerAdmin(); + mnBackgroundLayerID = rAdmin.GetLayerID( String( SdResId( STR_LAYER_BCKGRND )), FALSE ); + mnBackgroundObjectsLayerID = rAdmin.GetLayerID( String( SdResId( STR_LAYER_BCKGRNDOBJ )), FALSE ); + + ::sd::DrawDocShell* pDocShell = mpDoc->GetDocSh(); + if ( pDocShell ) + SeekOle( pDocShell, mnFilterOptions ); + + // hyperlinks + PropRead* pDInfoSec2 = new PropRead( mrStorage, String( RTL_CONSTASCII_USTRINGPARAM( "\005DocumentSummaryInformation" ) ) ); + if ( pDInfoSec2->IsValid() ) + { + PropItem aPropItem; + + UINT32 nType, nPropSize, nPropCount; + + pDInfoSec2->Read(); + + BYTE aPropSetGUID[ 16 ] = + { + 0x02, 0xd5, 0xcd, 0xd5, 0x9c, 0x2e, 0x1b, 0x10, 0x93, 0x97, 0x08, 0x00, 0x2b, 0x2c, 0xf9, 0xae + }; + Section* pSection = (Section*)pDInfoSec2->GetSection( aPropSetGUID ); + if ( pSection ) + { + if ( pSection->GetProperty( PID_SLIDECOUNT, aPropItem ) ) + { + aPropItem >> nType; + if ( ( nType == VT_I4 ) || ( nType == VT_UI4 ) ) + { + // examine PID_HEADINGPAIR to get the correct entry for PID_DOCPARTS + UINT32 nSlideCount, nVecCount; + aPropItem >> nSlideCount; + if ( nSlideCount && pSection->GetProperty( PID_HEADINGPAIR, aPropItem ) ) + { + UINT32 nSlideTitleIndex = 0, nSlideTitleCount = 0; + UINT32 nFontIndex, nFontCount = 0; + UINT32 nDesignTemplateIndex, nDesignTemplateCount = 0; + UINT32 i, nTemp, nEntryCount = 0; + + String aUString; + + aPropItem >> nType + >> nVecCount; + + if ( ( nType == ( VT_VARIANT | VT_VECTOR ) ) && ( nVecCount ^ 1 ) ) + { + nVecCount >>= 1; + + for ( i = 0; i < nVecCount; i++ ) + { + if ( !aPropItem.Read( aUString, VT_EMPTY, FALSE ) ) + break; + aPropItem >> nType; + if ( ( nType != VT_I4 ) && ( nType != VT_UI4 ) ) + break; + aPropItem >> nTemp; + if ( aUString.EqualsAscii("Slide Titles") || aUString.EqualsAscii("Folientitel") ) + { + nSlideTitleCount = nTemp; + nSlideTitleIndex = nEntryCount; + } + else if ( aUString.EqualsAscii("Fonts Used") ) + { + nFontCount = nTemp; + nFontIndex = nEntryCount; + } + else if ( aUString.EqualsAscii("Design Template") ) + { + nDesignTemplateCount = nTemp; + nDesignTemplateIndex = nEntryCount; + } + nEntryCount += nTemp; + } + } + if ( ( nSlideCount == nSlideTitleCount ) && pSection->GetProperty( PID_DOCPARTS, aPropItem ) ) + { + aPropItem >> nType + >> nVecCount; + + if ( ( nVecCount >= ( nSlideTitleIndex + nSlideTitleCount ) ) + && ( nType == ( VT_LPSTR | VT_VECTOR ) ) ) + { + for ( i = 0; i != nSlideTitleIndex; i++ ) + { + aPropItem >> nTemp; + aPropItem.SeekRel( nTemp ); + } + for ( i = 0; i < nSlideTitleCount; i++ ) + { + if ( !aPropItem.Read( aUString, nType, FALSE ) ) + break; + String* pString = new String( aUString ); + if ( pString->EqualsAscii( "No Slide Title" )) + *pString = String(); + else + { + void* pPtr; + for ( pPtr = maSlideNameList.First(); pPtr; pPtr = maSlideNameList.Next() ) + { + if ( *((String*)pPtr ) == *pString ) + { + *pString = String(); + break; + } + } + } + maSlideNameList.Insert( pString, LIST_APPEND ); + } + } + } + } + } + } + + BYTE aUserPropSetGUID[ 16 ] = + { + 0x05, 0xd5, 0xcd, 0xd5, 0x9c, 0x2e, 0x1b, 0x10, 0x93, 0x97, 0x08, 0x00, 0x2b, 0x2c, 0xf9, 0xae + }; + pSection = (Section*)pDInfoSec2->GetSection( aUserPropSetGUID ); + if ( pSection ) + { + Dictionary aDict; + if ( pSection->GetDictionary( aDict ) ) + { + UINT32 nPropId = aDict.GetProperty( rtl::OUString::createFromAscii("_PID_HLINKS" )); + if ( nPropId ) + { + if ( pSection->GetProperty( nPropId, aPropItem ) ) + { + aPropItem.Seek( STREAM_SEEK_TO_BEGIN ); + aPropItem >> nType; + if ( nType == VT_BLOB ) + { + aPropItem >> nPropSize + >> nPropCount; + + if ( ! ( nPropCount % 6 ) ) + { + UINT32 i; + + nPropCount /= 6; // 6 propertys a hyperlink + + SdHyperlinkEntry* pHyperlink = 0; + for ( i = 0; i < nPropCount; i++ ) + { + pHyperlink = new SdHyperlinkEntry; + pHyperlink->nIndex = 0; + aPropItem >> nType; + if ( nType != VT_I4 ) + break; + aPropItem >> pHyperlink->nPrivate1 + >> nType; + if ( nType != VT_I4 ) + break; + aPropItem >> pHyperlink->nPrivate2 + >> nType; + if ( nType != VT_I4 ) + break; + aPropItem >> pHyperlink->nPrivate3 + >> nType; + if ( nType != VT_I4 ) + break; + aPropItem >> pHyperlink->nInfo; + if ( !aPropItem.Read( pHyperlink->aTarget, VT_EMPTY ) ) + break; + if ( !aPropItem.Read( pHyperlink->aSubAdress, VT_EMPTY ) ) + break; + pHyperlink->nStartPos = pHyperlink->nEndPos = -1; + + if ( pHyperlink->aSubAdress.Len() ) // get the converted subadress + { + sal_uInt32 nPageNumber = 0; + String aString( pHyperlink->aSubAdress ); + ByteString aStringAry[ 3 ]; + sal_uInt16 nTokenCount = aString.GetTokenCount( ',' ); + if ( nTokenCount > 3 ) + nTokenCount = 3; + sal_uInt16 nToken; + for( nToken = 0; nToken < nTokenCount; nToken++ ) + aStringAry[ nToken ] = ByteString( aString.GetToken( nToken, (sal_Unicode)',' ), RTL_TEXTENCODING_UTF8 ); + + sal_Bool bSucceeded = sal_False; + + // first pass, searching for a SlideId + for( nToken = 0; nToken < nTokenCount; nToken++ ) + { + if ( aStringAry[ nToken ].IsNumericAscii() ) + { + sal_Int32 nNumber = aStringAry[ nToken ].ToInt32(); + if ( nNumber & ~0xff ) + { + PptSlidePersistList* pPageList = GetPageList( PPT_SLIDEPAGE ); + if ( pPageList ) + { + sal_uInt16 nPage = pPageList->FindPage( nNumber ); + if ( nPage != PPTSLIDEPERSIST_ENTRY_NOTFOUND ) + { + nPageNumber = nPage; + bSucceeded = sal_True; + break; + } + } + } + } + } + if ( !bSucceeded ) + { // second pass, searching for a SlideName + for ( nToken = 0; nToken < nTokenCount; nToken++ ) + { + String aToken( aString.GetToken( nToken, (sal_Unicode)',' ) ); + for ( void* pPtr = maSlideNameList.First(); pPtr; pPtr = maSlideNameList.Next() ) + { + if ( *(String*)pPtr == aToken ) + { + nPageNumber = maSlideNameList.GetCurPos(); + bSucceeded = sal_True; + break; + } + } + } + } + if ( !bSucceeded ) + { // third pass, searching for a slide number + for ( nToken = 0; nToken < nTokenCount; nToken++ ) + { + if ( aStringAry[ nToken ].IsNumericAscii() ) + { + sal_Int32 nNumber = aStringAry[ nToken ].ToInt32(); + if ( ( nNumber & ~0xff ) == 0 ) + { + nPageNumber = (sal_uInt32)nNumber - 1; + bSucceeded = sal_True; + break; + } + } + } + } + if ( bSucceeded ) + { + if ( nPageNumber < maSlideNameList.Count() ) + pHyperlink->aConvSubString = *(String*)maSlideNameList.GetObject( nPageNumber ); + if ( !pHyperlink->aConvSubString.Len() ) + { + pHyperlink->aConvSubString = String( SdResId( STR_PAGE ) ); + pHyperlink->aConvSubString.Append( sal_Unicode( ' ' ) ); + pHyperlink->aConvSubString.Append( mpDoc->CreatePageNumValue( (USHORT)nPageNumber + 1 ) ); + } + } + } + aHyperList.Insert( pHyperlink, LIST_APPEND ); + } + if ( i != nPropCount ) + delete pHyperlink; + } + } + } + } + } + } + } + } + delete pDInfoSec2; + + if ( mbDocumentFound ) + { + rStCtrl.Seek( maDocHd.GetRecBegFilePos() + 8 ); + // HyperList lesen / Indexe der einzelnen Eintraege setzen + DffRecordHeader aHyperHd; + if ( SeekToRec( rStCtrl, PPT_PST_ExObjList, maDocHd.GetRecEndFilePos(), &aHyperHd ) ) + { + UINT32 nExObjHyperListLen = aHyperHd.GetRecEndFilePos(); + for ( void* pPtr = aHyperList.First(); pPtr; pPtr = aHyperList.Next() ) + { + DffRecordHeader aHyperE; + if ( !SeekToRec( rStCtrl, PPT_PST_ExHyperlink, nExObjHyperListLen, &aHyperE ) ) + break; + if ( !SeekToRec( rStCtrl, PPT_PST_ExHyperlinkAtom, nExObjHyperListLen, NULL, 0 ) ) + break; + rStCtrl.SeekRel( 8 ); + rStCtrl >> ((SdHyperlinkEntry*)pPtr)->nIndex; + aHyperE.SeekToEndOfRecord( rStCtrl ); + } + } + } + + Size aVisAreaSize; + switch ( aUserEditAtom.eLastViewType ) + { + case 5 : // notes master + case 3 : // notes + aVisAreaSize = aDocAtom.GetNotesPageSize(); + break; + default : + aVisAreaSize = aDocAtom.GetSlidesPageSize(); + } + Scale( aVisAreaSize ); + pDocShell->SetVisArea( Rectangle( Point(), aVisAreaSize ) ); + + /////////////////////////////////////////////////////////// + // create master pages: + /////////////////////////////////////////////////////////// + SfxProgress* pStbMgr = new SfxProgress( pDocShell, String( SdResId( STR_POWERPOINT_IMPORT ) ), + pMasterPages->Count() + pSlidePages->Count() + pNotePages->Count() ); + + UINT32 nImportedPages = 0; + { + UINT16 nMasterAnz = GetPageCount( PPT_MASTERPAGE ); + + for ( USHORT nMasterNum = 0; nMasterNum < nMasterAnz; nMasterNum++ ) + { + SetPageNum( nMasterNum, PPT_MASTERPAGE ); + SdPage* pPage = (SdPage*)MakeBlancPage( TRUE ); + if ( pPage ) + { + BOOL bNotesMaster = (*GetPageList( eAktPageKind ) )[ nAktPageNum ]->bNotesMaster; + BOOL bStarDrawFiller = (*GetPageList( eAktPageKind ) )[ nAktPageNum ]->bStarDrawFiller; + + PageKind ePgKind = ( bNotesMaster ) ? PK_NOTES : PK_STANDARD; + pPage->SetPageKind( ePgKind ); + pSdrModel->InsertMasterPage( (SdrPage*)pPage ); + if ( bNotesMaster && bStarDrawFiller ) + ((SdPage*)pPage)->SetAutoLayout( AUTOLAYOUT_NOTES, TRUE ); + if ( nMasterNum ) + { + boost::optional< sal_Int16 > oStartNumbering; + SfxStyleSheet* pSheet; + if ( nMasterNum == 1 ) + { + /////////////////// + // standardsheet // + /////////////////// + pSheet = (SfxStyleSheet*)mpDoc->GetStyleSheetPool()->Find( String(SdResId( STR_STANDARD_STYLESHEET_NAME )), SD_STYLE_FAMILY_GRAPHICS ); + if ( pSheet ) + { + SfxItemSet& rItemSet = pSheet->GetItemSet(); + PPTParagraphObj aParagraph( *pPPTStyleSheet, TSS_TYPE_TEXT_IN_SHAPE, 0 ); + PPTPortionObj aPortion( *pPPTStyleSheet, TSS_TYPE_TEXT_IN_SHAPE, 0 ); + aParagraph.AppendPortion( aPortion ); + aParagraph.ApplyTo( rItemSet, oStartNumbering, (SdrPowerPointImport&)*this, 0xffffffff, NULL ); + aPortion.ApplyTo( rItemSet, (SdrPowerPointImport&)*this, 0xffffffff ); + } + } + + // PSEUDO + pSheet = (SfxStyleSheet*)mpDoc->GetStyleSheetPool()->Find( String(SdResId( STR_PSEUDOSHEET_BACKGROUNDOBJECTS )), SD_STYLE_FAMILY_PSEUDO ); + if ( pSheet ) + { + SfxItemSet& rItemSet = pSheet->GetItemSet(); + PPTParagraphObj aParagraph( *pPPTStyleSheet, TSS_TYPE_TEXT_IN_SHAPE, 0 ); + PPTPortionObj aPortion( *pPPTStyleSheet, TSS_TYPE_TEXT_IN_SHAPE, 0 ); + aParagraph.AppendPortion( aPortion ); + aParagraph.ApplyTo( rItemSet, oStartNumbering, (SdrPowerPointImport&)*this, 0xffffffff, NULL ); + aPortion.ApplyTo( rItemSet, (SdrPowerPointImport&)*this, 0xffffffff ); + } + + /////////////////////////////////////////////////////////// + // create layoutstylesheets, set layoutname and stylesheet + // (nur auf Standard- und Notizseiten) + /////////////////////////////////////////////////////////// + String aLayoutName( SdResId( STR_LAYOUT_DEFAULT_NAME ) ); + if ( nMasterNum > 2 ) + { + if ( ePgKind == PK_STANDARD ) + { // Standardseite: Neues Praesentationslayout erzeugen + aLayoutName = String( SdResId( STR_LAYOUT_DEFAULT_TITLE_NAME ) ); + aLayoutName += String::CreateFromInt32( (sal_Int32)( ( nMasterNum + 1 ) / 2 - 1 ) ); + ( (SdStyleSheetPool*)mpDoc->GetStyleSheetPool() )->CreateLayoutStyleSheets( aLayoutName ); + } + else // Notizseite: Praesentationslayout von der Standardseite verwenden + aLayoutName = ( (SdPage*)mpDoc->GetMasterPage( nMasterNum - 1 ) )->GetName(); + } + pPage->SetName( aLayoutName ); + aLayoutName.AppendAscii( RTL_CONSTASCII_STRINGPARAM( SD_LT_SEPARATOR )); + aLayoutName += String( SdResId( STR_LAYOUT_OUTLINE ) ); + pPage->SetLayoutName( aLayoutName ); + + ///////////////////// + // set stylesheets // + ///////////////////// + if ( pPage->GetPageKind() == PK_STANDARD ) + { + UINT32 nTitleInstance = TSS_TYPE_PAGETITLE; + UINT32 nOutlinerInstance = TSS_TYPE_BODY; +// BOOL bSwapStyleSheet = pSlideLayout->eLayout == PPT_LAYOUT_TITLEMASTERSLIDE; +// if ( bSwapStyleSheet ) +// { +// nTitleInstance = TSS_TYPE_TITLE; +// nOutlinerInstance = TSS_TYPE_SUBTITLE; +// } + ///////////////////// + // titelstylesheet // + ///////////////////// + pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_TITLE ); + if ( pSheet ) + { + SfxItemSet& rItemSet = pSheet->GetItemSet(); + PPTParagraphObj aParagraph( *pPPTStyleSheet, nTitleInstance, 0 ); + PPTPortionObj aPortion( *pPPTStyleSheet, nTitleInstance, 0 ); + aParagraph.AppendPortion( aPortion ); + aParagraph.ApplyTo( rItemSet, oStartNumbering, (SdrPowerPointImport&)*this, 0xffffffff, NULL ); + aPortion.ApplyTo( rItemSet, (SdrPowerPointImport&)*this, 0xffffffff ); + } + //////////////////////// + // outlinerstylesheet // + //////////////////////// + UINT16 nLevel; + PPTParagraphObj* pParagraphs[ 9 ]; + PPTParagraphObj* pPreviousPara = NULL; + + for ( nLevel = 0; nLevel < 9; nLevel++ ) + { + String aName( pPage->GetLayoutName() ); + aName.Append( (sal_Unicode)( ' ' ) ); + aName.Append( String::CreateFromInt32( nLevel + 1 ) ); + SfxStyleSheet* pOutlineSheet = (SfxStyleSheet*)mpDoc->GetStyleSheetPool()->Find( aName, SD_STYLE_FAMILY_MASTERPAGE ); + DBG_ASSERT( pOutlineSheet, "Vorlage fuer Gliederungsobjekt nicht gefunden" ); + if ( pOutlineSheet ) + { + pParagraphs[ nLevel ] = new PPTParagraphObj( *pPPTStyleSheet, nOutlinerInstance, nLevel ); + SfxItemSet& rItemSet = pOutlineSheet->GetItemSet(); + PPTPortionObj aPortion( *pPPTStyleSheet, nOutlinerInstance, nLevel ); + pParagraphs[ nLevel ]->AppendPortion( aPortion ); + pParagraphs[ nLevel ]->ApplyTo( rItemSet, oStartNumbering, (SdrPowerPointImport&)*this, 0xffffffff, pPreviousPara ); + aPortion.ApplyTo( rItemSet, (SdrPowerPointImport&)*this, 0xffffffff ); + pPreviousPara = pParagraphs[ nLevel ]; + } + else + pParagraphs[ nLevel ] = NULL; + } + for ( nLevel = 0; nLevel < 9; delete pParagraphs[ nLevel++ ] ) ; + ///////////////////////// + // subtitle stylesheet // + ///////////////////////// + pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_TEXT ); + if ( pSheet ) + { + SfxItemSet& rItemSet = pSheet->GetItemSet(); + PPTParagraphObj aParagraph( *pPPTStyleSheet, TSS_TYPE_SUBTITLE, 0 ); + PPTPortionObj aPortion( *pPPTStyleSheet, TSS_TYPE_SUBTITLE, 0 ); + aParagraph.AppendPortion( aPortion ); + aParagraph.ApplyTo( rItemSet, oStartNumbering, (SdrPowerPointImport&)*this, 0xffffffff, NULL ); + aPortion.ApplyTo( rItemSet, (SdrPowerPointImport&)*this, 0xffffffff ); + } + } + else if ( ePgKind == PK_NOTES ) + { + pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_NOTES ); + if ( pSheet ) + { + SfxItemSet& rItemSet = pSheet->GetItemSet(); + PPTParagraphObj aParagraph( *pPPTStyleSheet, TSS_TYPE_NOTES, 0 ); + PPTPortionObj aPortion( *pPPTStyleSheet, TSS_TYPE_NOTES, 0 ); + aParagraph.AppendPortion( aPortion ); + aParagraph.ApplyTo( rItemSet, oStartNumbering, (SdrPowerPointImport&)*this, 0xffffffff, NULL ); + aPortion.ApplyTo( rItemSet, (SdrPowerPointImport&)*this, 0xffffffff ); + } + } + } + } + } + } + SdPage* pMPage; + sal_uInt16 i; + for ( i = 1; i < mpDoc->GetMasterPageCount() && ( (pMPage = (SdPage*)mpDoc->GetMasterPage( i )) != 0 ); i++ ) + { + SetPageNum( i, PPT_MASTERPAGE ); + ///////////////////////////////////////////// + // importing master page objects // + ///////////////////////////////////////////// + PptSlidePersistList* pList = GetPageList( eAktPageKind ); + PptSlidePersistEntry* pPersist = ( pList && ( nAktPageNum < pList->Count() ) ) + ? (*pList)[ nAktPageNum ] : NULL; + if ( pPersist ) + { + if ( pPersist->bStarDrawFiller && pPersist->bNotesMaster && ( nAktPageNum > 2 ) && ( ( nAktPageNum & 1 ) == 0 ) ) + { + pSdrModel->DeleteMasterPage( nAktPageNum ); + SdrPage* pNotesClone = ((SdPage*)pSdrModel->GetMasterPage( 2 ))->Clone(); + pSdrModel->InsertMasterPage( pNotesClone, nAktPageNum ); + if ( pNotesClone ) + { + String aLayoutName( ((SdPage*)pSdrModel->GetMasterPage( nAktPageNum - 1 ))->GetLayoutName() ); + ((SdPage*)pNotesClone)->SetPresentationLayout( aLayoutName, sal_False, sal_False, sal_False ); + ((SdPage*)pNotesClone)->SetLayoutName( aLayoutName ); + } + } + else if ( ( pPersist->bStarDrawFiller == FALSE ) ) + { + PptSlidePersistEntry* pE = pPersist; + while( ( pE->aSlideAtom.nFlags & 4 ) && pE->aSlideAtom.nMasterId ) + { + sal_uInt16 nNextMaster = pMasterPages->FindPage( pE->aSlideAtom.nMasterId ); + if ( nNextMaster == PPTSLIDEPERSIST_ENTRY_NOTFOUND ) + break; + else + pE = (*pList)[ nNextMaster ]; + } + SdrObject* pObj = ImportPageBackgroundObject( *pMPage, pE->nBackgroundOffset, TRUE ); // import background + if ( pObj ) + pMPage->NbcInsertObject( pObj ); + + sal_Bool bNewAnimationsUsed = sal_False; + ProcessData aProcessData( *(*pList)[ nAktPageNum ], (SdPage*)pMPage ); + sal_uInt32 nFPosMerk = rStCtrl.Tell(); + DffRecordHeader aPageHd; + if ( SeekToAktPage( &aPageHd ) ) + { + if ( mbTracing ) + mpTracer->AddAttribute( rtl::OUString::createFromAscii( "MasterPage" ), rtl::OUString::valueOf( (sal_Int32) (nAktPageNum + 1) ) ); + + while( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < aPageHd.GetRecEndFilePos() ) ) + { + DffRecordHeader aHd; + rStCtrl >> aHd; + switch( aHd.nRecType ) + { + case PPT_PST_PPDrawing : + { + aHd.SeekToBegOfRecord( rStCtrl ); + DffRecordHeader aPPDrawHd; + if ( SeekToRec( rStCtrl, PPT_PST_PPDrawing, aHd.GetRecEndFilePos(), &aPPDrawHd ) ) + { + sal_uInt32 nPPDrawEnd = aPPDrawHd.GetRecEndFilePos(); + DffRecordHeader aEscherF002Hd; + if ( SeekToRec( rStCtrl, DFF_msofbtDgContainer, nPPDrawEnd, &aEscherF002Hd ) ) + { + sal_uInt32 nEscherF002End = aEscherF002Hd.GetRecEndFilePos(); + DffRecordHeader aEscherObjListHd; + if ( SeekToRec( rStCtrl, DFF_msofbtSpgrContainer, nEscherF002End, &aEscherObjListHd ) ) + { + sal_uInt32 nObjCount = 0; + while( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < aEscherObjListHd.GetRecEndFilePos() ) ) + { + DffRecordHeader aHd2; + rStCtrl >> aHd2; + if ( ( aHd2.nRecType == DFF_msofbtSpContainer ) || ( aHd2.nRecType == DFF_msofbtSpgrContainer ) ) + { + if ( nObjCount++ ) // skipping the first object + { + Rectangle aEmpty; + aHd2.SeekToBegOfRecord( rStCtrl ); + SdrObject* pImpObj = ImportObj( rStCtrl, (void*)&aProcessData, aEmpty, aEmpty ); + if ( pImpObj ) + { + pImpObj->SetLayer( mnBackgroundObjectsLayerID ); + pMPage->NbcInsertObject( pImpObj ); + } + } + } + aHd2.SeekToEndOfRecord( rStCtrl ); + } + } + } + } + } + break; + + case PPT_PST_ProgTags : + { + DffRecordHeader aProgTagHd; + if ( SeekToContentOfProgTag( 10, rStCtrl, aPageHd, aProgTagHd ) ) + { + while ( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < aProgTagHd.GetRecEndFilePos() ) ) + { + DffRecordHeader aProgTagContentHd; + rStCtrl >> aProgTagContentHd; + switch( aProgTagContentHd.nRecType ) + { + case DFF_msofbtAnimGroup : + { + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage > xPage( pMPage->getUnoPage(), ::com::sun::star::uno::UNO_QUERY ); + ppt::AnimationImporter aImporter( this, rStCtrl ); + aImporter.import( xPage, aProgTagContentHd ); + bNewAnimationsUsed = sal_True; + } + break; + } + aProgTagContentHd.SeekToEndOfRecord( rStCtrl ); + } + } + } + break; + } + aHd.SeekToEndOfRecord( rStCtrl ); + } + if ( mbTracing ) + mpTracer->RemoveAttribute( rtl::OUString::createFromAscii( "MasterPage" ) ); + } + rStCtrl.Seek( nFPosMerk ); + ImportPageEffect( (SdPage*)pMPage, bNewAnimationsUsed ); + + /////////////////////// + // background object // + /////////////////////// + pObj = pMPage->GetObj( 0 ); + if ( pObj && pObj->GetObjIdentifier() == OBJ_RECT ) + { + if ( pMPage->GetPageKind() == PK_STANDARD ) + { + // transform data from imported background object to new form + // and delete the object. It was used as container to transport + // the attributes of the MasterPage background fill + SfxStyleSheet* pSheet = pMPage->GetStyleSheetForMasterPageBackground(); + + if(pSheet) + { + // if we have a StyleSheet (for Masterpages), set attributes there and use it + pSheet->GetItemSet().ClearItem(); + pSheet->GetItemSet().Put(pObj->GetMergedItemSet()); + pMPage->getSdrPageProperties().ClearItem(); + pMPage->getSdrPageProperties().SetStyleSheet(pSheet); + } + else + { + // without StyleSheet, set attributes directly. This + // should not be done at all and is an error (will be asserted by SdrPage) + pMPage->getSdrPageProperties().ClearItem(); + pMPage->getSdrPageProperties().PutItemSet(pObj->GetMergedItemSet()); + } + + pMPage->RemoveObject(pObj->GetOrdNum()); + SdrObject::Free(pObj); + } + } + } + } + if( pStbMgr ) + pStbMgr->SetState( nImportedPages++ ); + } + //////////////////////////////////// + // importing slide pages // + //////////////////////////////////// + { + UINT32 nFPosMerk = rStCtrl.Tell(); + PptPageKind ePageKind = eAktPageKind; + UINT16 nPageNum = nAktPageNum; + + SdPage* pHandoutPage = (SdPage*)MakeBlancPage( FALSE ); + pHandoutPage->SetPageKind( PK_HANDOUT ); + pSdrModel->InsertPage( pHandoutPage ); + + USHORT nPageAnz = GetPageCount( PPT_SLIDEPAGE ); + if ( nPageAnz ) + { + for ( USHORT nPage = 0; nPage < nPageAnz; nPage++ ) + { + sal_Bool bNewAnimationsUsed = sal_False; + + mePresChange = PRESCHANGE_SEMIAUTO; + SetPageNum( nPage, PPT_SLIDEPAGE ); + SdPage* pPage = (SdPage*)MakeBlancPage( FALSE ); + PptSlidePersistEntry* pMasterPersist = NULL; + if ( HasMasterPage( nPage, PPT_SLIDEPAGE ) ) // try to get the LayoutName from the masterpage + { + sal_uInt16 nMasterNum = GetMasterPageIndex( nAktPageNum, eAktPageKind ); + pPage->TRG_SetMasterPage(*pSdrModel->GetMasterPage(nMasterNum)); + PptSlidePersistList* pPageList = GetPageList( PPT_MASTERPAGE ); + if ( pPageList && nMasterNum < pPageList->Count() ) + pMasterPersist = (*pPageList)[ nMasterNum ]; + pPage->SetLayoutName(((SdPage&)pPage->TRG_GetMasterPage()).GetLayoutName()); + } + pPage->SetPageKind( PK_STANDARD ); + pSdrModel->InsertPage( pPage ); // SJ: #i29625# because of form controls, the + ImportPage( pPage, pMasterPersist ); // page must be inserted before importing + SetHeaderFooterPageSettings( pPage, pMasterPersist ); + // CWS preseng01: pPage->SetPageKind( PK_STANDARD ); + + DffRecordHeader aPageHd; + if ( SeekToAktPage( &aPageHd ) ) + { + aPageHd.SeekToContent( rStCtrl ); + while ( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < aPageHd.GetRecEndFilePos() ) ) + { + DffRecordHeader aHd; + rStCtrl >> aHd; + switch ( aHd.nRecType ) + { + case PPT_PST_ProgTags : + { + DffRecordHeader aProgTagHd; + if ( SeekToContentOfProgTag( 10, rStCtrl, aPageHd, aProgTagHd ) ) + { + while ( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < aProgTagHd.GetRecEndFilePos() ) ) + { + DffRecordHeader aProgTagContentHd; + rStCtrl >> aProgTagContentHd; + switch( aProgTagContentHd.nRecType ) + { +/* + case PPT_PST_CommentContainer : + { + + } + break; +*/ + case DFF_msofbtAnimGroup : + { + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage > xPage( pPage->getUnoPage(), ::com::sun::star::uno::UNO_QUERY ); + ppt::AnimationImporter aImporter( this, rStCtrl ); + aImporter.import( xPage, aProgTagContentHd ); + bNewAnimationsUsed = sal_True; + } + break; + + case PPT_PST_NewlyAddedAtomByXP11008 : // ??? + break; + + case PPT_PST_NewlyAddedAtomByXP12011 : // ??? don't know, this atom is always 8 bytes big + break; // and is appearing in nearly every l10 progtag + } + aProgTagContentHd.SeekToEndOfRecord( rStCtrl ); + } + } + } + break; + + case PPT_PST_HeadersFooters : + case PPT_PST_PPDrawing : + default: + break; + } + + aHd.SeekToEndOfRecord( rStCtrl ); + } + ImportPageEffect( (SdPage*)pPage, bNewAnimationsUsed ); + } + + // creating the corresponding note page + eAktPageKind = PPT_NOTEPAGE; + SdPage* pNotesPage = (SdPage*)MakeBlancPage( FALSE ); + sal_uInt16 nNotesMasterNum = GetMasterPageIndex( nPage, PPT_SLIDEPAGE ) + 1; + sal_uInt32 nNotesPageId = GetNotesPageId( nPage ); + if ( nNotesPageId ) + { + nImportedPages++; + sal_uInt16 nNotesPageIndex = pNotePages->FindPage( nNotesPageId ); + if ( nNotesPageIndex == PPTSLIDEPERSIST_ENTRY_NOTFOUND ) + nNotesPageIndex = 0; + SetPageNum( nNotesPageIndex, PPT_NOTEPAGE ); + PptSlidePersistEntry* pMasterPersist2 = NULL; + if ( HasMasterPage( nNotesPageIndex, PPT_NOTEPAGE ) ) // try to get the LayoutName from the masterpage + { + pNotesPage->TRG_SetMasterPage(*pSdrModel->GetMasterPage(nNotesMasterNum)); + PptSlidePersistList* pPageList = GetPageList( PPT_MASTERPAGE ); + if ( pPageList && nNotesMasterNum < pPageList->Count() ) + pMasterPersist2 = (*pPageList)[ nNotesMasterNum ]; + pNotesPage->SetLayoutName( ((SdPage&)pNotesPage->TRG_GetMasterPage()).GetLayoutName() ); + } + pNotesPage->SetPageKind( PK_NOTES ); + pNotesPage->TRG_SetMasterPage(*pSdrModel->GetMasterPage(nNotesMasterNum)); + pSdrModel->InsertPage( pNotesPage ); // SJ: #i29625# because of form controls, the + ImportPage( pNotesPage, pMasterPersist2 ); // page must be inserted before importing + SetHeaderFooterPageSettings( pNotesPage, pMasterPersist2 ); + pNotesPage->SetAutoLayout( AUTOLAYOUT_NOTES, FALSE ); + } + else + { + pNotesPage->SetPageKind( PK_NOTES ); + pNotesPage->TRG_SetMasterPage(*pSdrModel->GetMasterPage(nNotesMasterNum)); + pNotesPage->SetAutoLayout( AUTOLAYOUT_NOTES, TRUE ); + pSdrModel->InsertPage( pNotesPage ); + SdrObject* pPageObj = pNotesPage->GetPresObj( PRESOBJ_PAGE, 1 ); + if ( pPageObj ) + ((SdrPageObj*)pPageObj)->SetReferencedPage(pSdrModel->GetPage(( nPage << 1 ) + 1)); + } + + if( pStbMgr ) + pStbMgr->SetState( nImportedPages++ ); + } + ////////////// + } + else + { + // Das kann bei Dokumentvorlagen vorkommen + eAktPageKind = PPT_SLIDEPAGE; + SdrPage* pPage = MakeBlancPage( FALSE ); + pSdrModel->InsertPage( pPage ); + + // #i37397#, trying to set the title master for the first page + sal_uInt16 nMaster, nMasterCount = pSdrModel->GetMasterPageCount(); + SdPage* pFoundMaster = NULL; + for ( nMaster = 1; nMaster < nMasterCount; nMaster++ ) + { + SdPage* pMaster = static_cast<SdPage*>( pSdrModel->GetMasterPage( nMaster ) ); + if ( pMaster->GetPageKind() == PK_STANDARD ) + { + SetPageNum( nMaster, PPT_MASTERPAGE ); + if ( !pFoundMaster ) + pFoundMaster = pMaster; + else if ( GetSlideLayoutAtom()->eLayout == PPT_LAYOUT_TITLEMASTERSLIDE ) + pFoundMaster = pMaster; + if ( GetSlideLayoutAtom()->eLayout == PPT_LAYOUT_TITLEMASTERSLIDE ) + break; + } + } + if ( pFoundMaster ) + { + ((SdPage*)pPage)->TRG_SetMasterPage( *((SdPage*)pFoundMaster) ); + ((SdPage*)pPage)->SetLayoutName( ((SdPage*)pFoundMaster)->GetLayoutName() ); + } + ((SdPage*)pPage)->SetAutoLayout( AUTOLAYOUT_TITLE, TRUE, TRUE ); + + eAktPageKind = PPT_NOTEPAGE; + SdrPage* pNPage = MakeBlancPage( FALSE ); + pSdrModel->InsertPage( pNPage ); + } + SetPageNum( nPageNum, ePageKind ); + rStCtrl.Seek( nFPosMerk ); + } + /////////////////////////////////////////////////////////////////// + // Handzettel und Notiz-Seiten erzeugen // + /////////////////////////////////////////////////////////////////// + bOk = mpDoc->CreateMissingNotesAndHandoutPages(); + if ( bOk ) + { + for ( i = 0; i < mpDoc->GetSdPageCount( PK_STANDARD ); i++ ) + { + //////////////////// + // set AutoLayout // + //////////////////// + SetPageNum( i, PPT_SLIDEPAGE ); + SdPage* pPage = mpDoc->GetSdPage( i, PK_STANDARD ); + AutoLayout eAutoLayout = AUTOLAYOUT_NONE; + const PptSlideLayoutAtom* pSlideLayout = GetSlideLayoutAtom(); + if ( pSlideLayout ) + { + switch ( pSlideLayout->eLayout ) // Praesentationslayouts fuer Standard-Seiten + { + case PPT_LAYOUT_TITLEANDBODYSLIDE : + { + eAutoLayout = AUTOLAYOUT_ENUM; + USHORT nID1 = pSlideLayout->aPlaceholderId[ 1 ]; + switch ( nID1 ) + { + case PPT_PLACEHOLDER_BODY : + eAutoLayout = AUTOLAYOUT_ENUM; + break; + case PPT_PLACEHOLDER_TABLE : + eAutoLayout = AUTOLAYOUT_TAB; + break; + case PPT_PLACEHOLDER_ORGANISZATIONCHART : + eAutoLayout = AUTOLAYOUT_ORG; + break; + case PPT_PLACEHOLDER_GRAPH : + eAutoLayout = AUTOLAYOUT_CHART; + break; + case PPT_PLACEHOLDER_OBJECT : + eAutoLayout = AUTOLAYOUT_OBJ; + break; + case PPT_PLACEHOLDER_VERTICALTEXTBODY : + eAutoLayout = AUTOLAYOUT_TITLE_VERTICAL_OUTLINE; + break; + } + } + break; + + case PPT_LAYOUT_2COLUMNSANDTITLE : + { + eAutoLayout = AUTOLAYOUT_2TEXT; + USHORT nID1 = pSlideLayout->aPlaceholderId[ 1 ]; + USHORT nID2 = pSlideLayout->aPlaceholderId[ 2 ]; + if ( nID1 == PPT_PLACEHOLDER_BODY && nID2 == PPT_PLACEHOLDER_GRAPH ) + eAutoLayout = AUTOLAYOUT_TEXTCHART; + else if ( nID1 == PPT_PLACEHOLDER_GRAPH && nID2 == PPT_PLACEHOLDER_BODY ) + eAutoLayout = AUTOLAYOUT_CHARTTEXT; + else if ( nID1 == PPT_PLACEHOLDER_BODY && nID2 == PPT_PLACEHOLDER_CLIPART ) + eAutoLayout = AUTOLAYOUT_TEXTCLIP; + else if ( nID1 == PPT_PLACEHOLDER_CLIPART && nID2 == PPT_PLACEHOLDER_BODY ) + eAutoLayout = AUTOLAYOUT_CLIPTEXT; + else if ( nID1 == PPT_PLACEHOLDER_CLIPART && nID2 == PPT_PLACEHOLDER_VERTICALTEXTBODY ) + eAutoLayout = AUTOLAYOUT_TITLE_VERTICAL_OUTLINE_CLIPART; + else if ( ( nID1 == PPT_PLACEHOLDER_BODY ) + && ( ( nID2 == PPT_PLACEHOLDER_OBJECT ) || ( nID2 == PPT_PLACEHOLDER_MEDIACLIP ) ) ) + eAutoLayout = AUTOLAYOUT_TEXTOBJ; + else if ( ( nID2 == PPT_PLACEHOLDER_BODY ) + && ( ( nID1 == PPT_PLACEHOLDER_OBJECT ) || ( nID1 == PPT_PLACEHOLDER_MEDIACLIP ) ) ) + eAutoLayout = AUTOLAYOUT_OBJTEXT; + else if ( ( nID1 == PPT_PLACEHOLDER_OBJECT ) && ( nID2 == PPT_PLACEHOLDER_OBJECT ) ) + eAutoLayout = AUTOLAYOUT_OBJ; + } + break; + + case PPT_LAYOUT_2ROWSANDTITLE : + { + eAutoLayout = AUTOLAYOUT_2TEXT; + USHORT nID1 = pSlideLayout->aPlaceholderId[ 1 ]; + USHORT nID2 = pSlideLayout->aPlaceholderId[ 2 ]; + if ( nID1 == PPT_PLACEHOLDER_BODY && nID2 == PPT_PLACEHOLDER_OBJECT ) + eAutoLayout = AUTOLAYOUT_TEXTOVEROBJ; + else if ( nID1 == PPT_PLACEHOLDER_OBJECT && nID2 == PPT_PLACEHOLDER_BODY ) + eAutoLayout = AUTOLAYOUT_OBJOVERTEXT; + } + break; + + case PPT_LAYOUT_TITLESLIDE : + eAutoLayout = AUTOLAYOUT_TITLE; + break; + case PPT_LAYOUT_ONLYTITLE : + eAutoLayout = AUTOLAYOUT_ONLY_TITLE; + break; + case PPT_LAYOUT_RIGHTCOLUMN2ROWS : + eAutoLayout = AUTOLAYOUT_TEXT2OBJ; + break; + case PPT_LAYOUT_LEFTCOLUMN2ROWS : + eAutoLayout = AUTOLAYOUT_2OBJTEXT; + break; + case PPT_LAYOUT_TOPROW2COLUMN : + eAutoLayout = AUTOLAYOUT_2OBJOVERTEXT; + break; + case PPT_LAYOUT_4OBJECTS : + eAutoLayout = AUTOLAYOUT_4OBJ; + break; + case PPT_LAYOUT_BIGOBJECT : + eAutoLayout = AUTOLAYOUT_OBJ; + break; + case PPT_LAYOUT_TITLERIGHTBODYLEFT : + eAutoLayout = AUTOLAYOUT_VERTICAL_TITLE_VERTICAL_OUTLINE; // AUTOLAYOUT_ENUM; + break; + case PPT_LAYOUT_TITLERIGHT2BODIESLEFT : + eAutoLayout = AUTOLAYOUT_VERTICAL_TITLE_TEXT_CHART; // AUTOLAYOUT_TEXT2OBJ; + break; + + case PPT_LAYOUT_BOTTOMROW2COLUMNS : + case PPT_LAYOUT_BLANCSLIDE : + case PPT_LAYOUT_MASTERSLIDE : // Layout der Standard- und Titel-MasterPage + case PPT_LAYOUT_TITLEMASTERSLIDE : + case PPT_LAYOUT_MASTERNOTES : // Layout der Notizen-MasterPage + case PPT_LAYOUT_NOTESTITLEBODY : // Praesentationslayout fuer Notiz-Seiten + case PPT_LAYOUT_HANDOUTLAYOUT : // Praesentationslayout fuer Handzettelseiten + eAutoLayout = AUTOLAYOUT_NONE; + break; + } + if ( eAutoLayout != AUTOLAYOUT_NONE ) + pPage->SetAutoLayout( eAutoLayout, FALSE ); + } + } + ////////////////////////////////////////////////////////////// + // Handzettel-MasterPage: Autolayout setzen // + ////////////////////////////////////////////////////////////// + SdPage* pHandoutMPage = mpDoc->GetMasterSdPage( 0, PK_HANDOUT ); + pHandoutMPage->SetAutoLayout( AUTOLAYOUT_HANDOUT6, TRUE, TRUE ); + } + + UINT32 nSlideCount = GetPageCount(); + for ( i = 0; ( i < nSlideCount) && ( i < maSlideNameList.Count() ); i++ ) + { + SdPage* pPage = mpDoc->GetSdPage( i, PK_STANDARD ); + String* pName = (String*)maSlideNameList.GetObject( i ); + if ( pPage && pName ) + { + if ( pName->Len() ) + pPage->SetName( *pName ); + else + *pName = pPage->GetName(); + } + } + if ( mbDocumentFound ) + { + mpDoc->SetSummationOfParagraphs( sal_True ); + if ( pDocShell ) + { + ::sd::FrameView* pFrameView = mpDoc->GetFrameView( 0 ); + if ( !pFrameView ) + { + List* pFrameViewList = mpDoc->GetFrameViewList(); + if ( pFrameViewList ) + { + pFrameView = new ::sd::FrameView( mpDoc ); + if ( pFrameView ) + pFrameViewList->Insert( pFrameView ); + } + } + if ( pFrameView ) + { + sal_uInt16 nSelectedPage = 0; + PageKind ePageKind = PK_STANDARD; + EditMode eEditMode = EM_PAGE; + + switch ( aUserEditAtom.eLastViewType ) + { + case 7 : // outliner view + { + SfxItemSet* pSet = mrMed.GetItemSet(); + if ( pSet ) + pSet->Put( SfxUInt16Item( SID_VIEW_ID, 3 ) ); + } + break; + case 8 : // slide sorter + { + SfxItemSet* pSet = mrMed.GetItemSet(); + if ( pSet ) + pSet->Put( SfxUInt16Item( SID_VIEW_ID, 2 ) ); + } + break; + case 10 : // titlemaster + nSelectedPage = 1; + case 2 : // master + { + ePageKind = PK_STANDARD; + eEditMode = EM_MASTERPAGE; + } + break; + case 5 : // notes master + eEditMode = EM_MASTERPAGE; + case 3 : // notes + ePageKind = PK_NOTES; + break; + case 4 : // handout + ePageKind = PK_HANDOUT; + break; + default : + case 1 : // normal + break; + } + pFrameView->SetPageKind( ePageKind ); + pFrameView->SetSelectedPage( nSelectedPage ); + pFrameView->SetViewShEditMode( eEditMode, ePageKind ); + } + } + DffRecordHeader aCustomShowHeader; + // custom show einlesen und setzen + rStCtrl.Seek( maDocHd.GetRecBegFilePos() + 8 ); + if ( SeekToRec( rStCtrl, PPT_PST_NamedShows, maDocHd.GetRecEndFilePos(), &aCustomShowHeader ) ) + { + DffRecordHeader aCuHeader; + while( SeekToRec( rStCtrl, PPT_PST_NamedShow, aCustomShowHeader.GetRecEndFilePos(), &aCuHeader ) ) + { + DffRecordHeader aContent; + if ( SeekToRec( rStCtrl, PPT_PST_CString, aCuHeader.GetRecEndFilePos(), &aContent ) ) + { + String aCuShow; + aContent.SeekToBegOfRecord( rStCtrl ); + if ( ReadString( aCuShow ) ) + { + if ( SeekToRec( rStCtrl, PPT_PST_NamedShowSlides, aCuHeader.GetRecEndFilePos(), &aContent ) ) + { + PptSlidePersistList* pPageList = GetPageList( PPT_SLIDEPAGE ); + UINT32 nSCount = aContent.nRecLen >> 2; + if ( pPageList && nSCount ) + { + List* pList = mpDoc->GetCustomShowList( TRUE ); + if ( pList ) + { + SdCustomShow* pSdCustomShow = new SdCustomShow( mpDoc ); + if ( pSdCustomShow ) + { + pSdCustomShow->SetName( aCuShow ); + UINT32 nFound = 0; + for ( UINT32 nS = 0; nS < nSCount; nS++ ) + { + UINT32 nPageNumber; + rStCtrl >> nPageNumber; + USHORT nPage = pPageList->FindPage( nPageNumber ); + if ( nPage != PPTSLIDEPERSIST_ENTRY_NOTFOUND ) + { + SdPage* pPage = mpDoc->GetSdPage( nPage, PK_STANDARD ); + if ( pPage ) + { + pSdCustomShow->Insert( pPage, LIST_APPEND ); + nFound++; + } + } + } + if ( nFound ) + pList->Insert( pSdCustomShow, LIST_APPEND ); + else + delete pSdCustomShow; + } + } + } + } + } + } + } + } + // this is defaulted, maybe there is no SSDocInfoAtom + String aCustomShow; + sal_uInt32 nFlags = 1; // Bit 0: Auto advance + sal_uInt32 nPenColor = 0x1000000; + sal_Int32 nRestartTime = 0x7fffffff; + sal_uInt16 nStartSlide = 0; + sal_Int16 nEndSlide = 0; + + // read the pres. configuration + rStCtrl.Seek( maDocHd.GetRecBegFilePos() + 8 ); + if ( SeekToRec( rStCtrl, PPT_PST_SSDocInfoAtom, maDocHd.GetRecEndFilePos(), &aCustomShowHeader ) ) + { + rStCtrl >> nPenColor + >> nRestartTime + >> nStartSlide + >> nEndSlide; + + sal_Unicode nChar; + for ( UINT32 i2 = 0; i2 < 32; i2++ ) + { + rStCtrl >> nChar; + if ( nChar ) + aCustomShow.Append( nChar ); + else + { + rStCtrl.SeekRel( ( 31 - i2 ) << 1 ); + break; + } + } + rStCtrl >> nFlags; + } + // set the current custom show + if ( aCustomShow.Len() ) + { + void* pPtr; + List* pList = mpDoc->GetCustomShowList( FALSE ); + if ( pList ) + { + for ( pPtr = pList->First(); pPtr; pPtr = pList->Next() ) + { + if ( ((SdCustomShow*)pPtr)->GetName() == aCustomShow ) + break; + } + if ( !pPtr ) + pList->First(); + } + } + sd::PresentationSettings& rPresSettings = mpDoc->getPresentationSettings(); + + rPresSettings.mbManual = ( nFlags & 1 ) == 0; + rPresSettings.mbAnimationAllowed = ( nFlags & 2 ) == 0; + rPresSettings.mbAll = ( nFlags & 4 ) == 0; + rPresSettings.mbCustomShow = ( nFlags & 8 ) != 0; + rPresSettings.mbEndless = ( nFlags & 0x80 ) != 0; + rPresSettings.mbFullScreen = ( nFlags & 0x10 ) == 0; +// rPresSettings.mnPauseTimeout; +// rPresSettings.mbShowLogo; + if ( nStartSlide && ( nStartSlide <= GetPageCount() ) ) + { + SdPage* pPage = mpDoc->GetSdPage( nStartSlide - 1, PK_STANDARD ); + if ( pPage ) + rPresSettings.maPresPage = pPage->GetName(); + } + } + + delete pStbMgr; + + // read DocumentInfo + uno::Reference<document::XDocumentPropertiesSupplier> xDPS( + mpDoc->GetObjectShell()->GetModel(), uno::UNO_QUERY_THROW); + uno::Reference<document::XDocumentProperties> xDocProps + = xDPS->getDocumentProperties(); + sfx2::LoadOlePropertySet(xDocProps, &mrStorage); + xDocProps->setTemplateName(::rtl::OUString()); + + pSdrModel->setLock( sal_False ); + pSdrModel->EnableUndo(true); + return bOk; +} + +void ImplSdPPTImport::SetHeaderFooterPageSettings( SdPage* pPage, const PptSlidePersistEntry* pMasterPersist ) +{ + sal_uInt32 i; + PptSlidePersistList* pList = GetPageList( eAktPageKind ); + if ( ( !pList ) || ( pList->Count() <= nAktPageNum ) ) + return; + PptSlidePersistEntry& rSlidePersist = *(*pList)[ nAktPageNum ]; + HeaderFooterEntry* pHFE = rSlidePersist.pHeaderFooterEntry; + if ( pHFE ) + { + for ( i = 0; i < 4; i++ ) + { + bool bVisible = pHFE->IsToDisplay( i ); + if ( ( eAktPageKind == PPT_SLIDEPAGE ) + && ( rSlidePersist.aSlideAtom.aLayout.eLayout == PPT_LAYOUT_TITLESLIDE ) + && ( aDocAtom.bTitlePlaceholdersOmitted == TRUE ) ) + { + bVisible = sal_False; + } + if ( bVisible && pMasterPersist ) + { + sal_uInt32 nPosition = pHFE->NeedToImportInstance( i, rSlidePersist ); + if ( nPosition ) + { + Rectangle aEmpty; + bVisible = sal_False; + rStCtrl.Seek( nPosition ); + ProcessData aProcessData( rSlidePersist, (SdPage*)pPage ); + SdrObject* pObj = ImportObj( rStCtrl, (void*)&aProcessData, aEmpty, aEmpty ); + if ( pObj ) + pPage->NbcInsertObject( pObj, 0 ); + } + } + String aPlaceHolderString; + if ( pHFE->pPlaceholder ) + aPlaceHolderString = pHFE->pPlaceholder[ i ]; + + sd::HeaderFooterSettings rHeaderFooterSettings( pPage->getHeaderFooterSettings() ); + switch( i ) + { + case 0 : + { + rHeaderFooterSettings.mbDateTimeVisible = bVisible; + rHeaderFooterSettings.mbDateTimeIsFixed = ( pHFE->nAtom & 0x20000 ) == 0; + rHeaderFooterSettings.maDateTimeText = aPlaceHolderString; + SvxDateFormat eDateFormat; + SvxTimeFormat eTimeFormat; + PPTFieldEntry::GetDateTime( pHFE->nAtom & 0xff, eDateFormat, eTimeFormat ); + rHeaderFooterSettings.meDateTimeFormat = eDateFormat | ( eTimeFormat << 4 ); + } + break; + case 1 : + { + rHeaderFooterSettings.mbHeaderVisible = bVisible; + rHeaderFooterSettings.maHeaderText = aPlaceHolderString; + } + break; + case 2 : + { + rHeaderFooterSettings.mbFooterVisible = bVisible; + rHeaderFooterSettings.maFooterText = aPlaceHolderString; + } + break; + case 3 : + { + rHeaderFooterSettings.mbSlideNumberVisible = bVisible; + } + break; + } + pPage->setHeaderFooterSettings( rHeaderFooterSettings ); + } + } +} + +////////////////////////////////////////////////////////////////////////// +// +// Import von Seiten +// +////////////////////////////////////////////////////////////////////////// + +struct Ppt97AnimationStlSortHelper +{ + bool operator()( const std::pair< SdrObject*, Ppt97AnimationPtr >& p1, const std::pair< SdrObject*, Ppt97AnimationPtr >& p2 ); +}; + +bool Ppt97AnimationStlSortHelper::operator()( const std::pair< SdrObject*, Ppt97AnimationPtr >& p1, const std::pair< SdrObject*, Ppt97AnimationPtr >& p2 ) +{ + if( !p1.second.get() || !p2.second.get() ) + return true; + if( *p1.second < *p2.second ) + return true; + if( *p1.second > *p2.second ) + return false; + if( p1.first->GetOrdNum() < p2.first->GetOrdNum() ) + return true; + return false; +} + +void ImplSdPPTImport::ImportPageEffect( SdPage* pPage, const sal_Bool bNewAnimationsUsed ) +{ + ULONG nFilePosMerk = rStCtrl.Tell(); + + // PageKind an der Seite setzen (bisher nur PK_STANDARD oder PK_NOTES) + if ( pPage->GetPageKind() == PK_STANDARD ) + { + PptSlidePersistList* pPersistList = GetPageList( eAktPageKind ); + PptSlidePersistEntry* pActualSlidePersist = ( pPersistList && ( nAktPageNum < pPersistList->Count() ) ) + ? (*pPersistList)[ nAktPageNum ] : NULL; + + if ( pActualSlidePersist && ( eAktPageKind == PPT_SLIDEPAGE ) ) + { + if ( ! ( pActualSlidePersist->aSlideAtom.nFlags & 1 ) ) // do not follow master objects ? + { + if(pPage->TRG_HasMasterPage()) + { + SetOfByte aVisibleLayers = pPage->TRG_GetMasterPageVisibleLayers(); + aVisibleLayers.Set(mnBackgroundObjectsLayerID, FALSE); + pPage->TRG_SetMasterPageVisibleLayers(aVisibleLayers); + } + } + } + DffRecordHeader aPageRecHd; + if ( pPage && SeekToAktPage( &aPageRecHd ) ) + { + ULONG nPageRecEnd = aPageRecHd.GetRecEndFilePos(); + + BOOL bTryTwice = ( eAktPageKind == PPT_SLIDEPAGE ); + BOOL bSSSlideInfoAtom = FALSE; + while ( TRUE ) + { + while ( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < nPageRecEnd ) ) + { + DffRecordHeader aHd; + rStCtrl >> aHd; + switch ( aHd.nRecType ) + { + case PPT_PST_SSSlideInfoAtom: + { + bSSSlideInfoAtom = TRUE; + if ( eAktPageKind == PPT_MASTERPAGE ) + { + if ( pActualSlidePersist ) + pActualSlidePersist->aPersistAtom.nReserved = aHd.GetRecBegFilePos(); + } + else + { + sal_Int8 nDirection, nTransitionType, nByteDummy, nSpeed; + sal_Int16 nBuildFlags; + sal_Int32 nSlideTime, nSoundRef; + rStCtrl >> nSlideTime // Standzeit (in Ticks) + >> nSoundRef // Index in SoundCollection + >> nDirection // Richtung des Ueberblendeffekts + >> nTransitionType // Ueberblendeffekt + >> nBuildFlags // Buildflags (s.u.) + >> nSpeed // Geschwindigkeit (langsam, mittel, schnell) + >> nByteDummy >> nByteDummy >> nByteDummy; + + switch ( nTransitionType ) + { + case PPT_TRANSITION_TYPE_BLINDS : + { + if ( nDirection == 0 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_VERTICAL_STRIPES );// Vertikal blenden + else if ( nDirection == 1 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_HORIZONTAL_STRIPES );// Horizontal blenden + } + break; + case PPT_TRANSITION_TYPE_CHECKER : + { + if ( nDirection == 0 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_HORIZONTAL_CHECKERBOARD );// Vertikal versetzt einblenden ?? + else if ( nDirection == 1 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_VERTICAL_CHECKERBOARD );// Horizontal versetzt einblenden ?? + } + break; + case PPT_TRANSITION_TYPE_COVER : + { + if ( nDirection == 0 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_MOVE_FROM_RIGHT ); // Von rechts ueberdecken + else if ( nDirection == 1 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_MOVE_FROM_BOTTOM ); // Von unten ueberdecken + else if ( nDirection == 2 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_MOVE_FROM_LEFT ); // Von links ueberdecken + else if ( nDirection == 3 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_MOVE_FROM_TOP ); // Von oben ueberdecken + else if ( nDirection == 4 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_MOVE_FROM_LOWERRIGHT );// Von rechts unten ueberdecken ?? + else if ( nDirection == 5 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_MOVE_FROM_LOWERLEFT ); // Von links unten ueberdecken ?? + else if ( nDirection == 6 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_MOVE_FROM_UPPERRIGHT );// Von rechts oben ueberdecken + else if ( nDirection == 7 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_MOVE_FROM_UPPERLEFT ); // Von links oben ueberdecken ?? + } + break; + case PPT_TRANSITION_TYPE_NONE : + { + if ( nBuildFlags ) + { + if ( nDirection == 0 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_NONE ); // Direkt + else if ( nDirection == 1 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_NONE ); // Direkt ueber Schwarz + } + else + pPage->setTransitionType( 0 ); + } + break; + case PPT_TRANSITION_TYPE_DISSOLVE : + pPage->SetFadeEffect(::com::sun::star::presentation::FadeEffect_DISSOLVE); // Aufloesen + break; + case PPT_TRANSITION_TYPE_RANDOM_BARS : + { + if ( nDirection == 0 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_HORIZONTAL_LINES ); // Horizontale Linien + else if ( nDirection == 1 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_VERTICAL_LINES ); // Vertikale Linien + } + break; + case PPT_TRANSITION_TYPE_SPLIT : + { + if ( nDirection == 0 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_OPEN_VERTICAL ); // Horizontal oeffnen + else if ( nDirection == 1 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_CLOSE_VERTICAL ); // Horizontal schliessen + else if ( nDirection == 2 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_OPEN_HORIZONTAL ); // Vertikal oeffnen + else if ( nDirection == 3 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_CLOSE_HORIZONTAL );// Vertikal schliessen + } + break; + case PPT_TRANSITION_TYPE_STRIPS : + { + if ( nDirection == 4 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_FADE_FROM_LOWERRIGHT );// Diagonal nach links oben + else if ( nDirection == 5 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_FADE_FROM_LOWERLEFT ); // Diagonal nach rechts oben + else if ( nDirection == 6 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_FADE_FROM_UPPERRIGHT );// Diagonal nach links unten + else if ( nDirection == 7 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_FADE_FROM_UPPERLEFT ); // Diagonal nach rechts unten + } + break; + case PPT_TRANSITION_TYPE_PULL : + { + if ( nDirection == 0 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_LEFT ); // Nach links aufdecken + else if ( nDirection == 1 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_TOP ); // Nach oben aufdecken + else if ( nDirection == 2 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_RIGHT ); // Nach rechts aufdecken + else if ( nDirection == 3 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_BOTTOM ); // Nach unten aufdecken + else if ( nDirection == 4 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_UPPERLEFT );// Nach links oben aufdecken + else if ( nDirection == 5 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_UPPERRIGHT );// Nach rechts oben aufdecken + else if ( nDirection == 6 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_LOWERLEFT );// Nach links unten aufdecken + else if ( nDirection == 7 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_LOWERRIGHT );// Nach rechts unten aufdecken + } + break; + case PPT_TRANSITION_TYPE_WIPE : + { + if ( nDirection == 0 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_FADE_FROM_RIGHT ); // Von rechts rollen + else if ( nDirection == 1 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_FADE_FROM_BOTTOM );// Von unten rollen + else if ( nDirection == 2 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_FADE_FROM_LEFT ); // Von links rollen + else if ( nDirection == 3 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_FADE_FROM_TOP ); // Von oben rollen + } + break; + case PPT_TRANSITION_TYPE_RANDOM : + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_RANDOM ); // Automatisch + break; + case PPT_TRANSITION_TYPE_FADE : + { + pPage->setTransitionType( animations::TransitionType::FADE ); + pPage->setTransitionSubtype( animations::TransitionSubType::FADEOVERCOLOR ); + pPage->setTransitionFadeColor( 0 ); + } + break; + case PPT_TRANSITION_TYPE_ZOOM : + { + if ( nDirection == 0 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_FADE_FROM_CENTER );// Von innen einblenden + else if ( nDirection == 1 ) + pPage->SetFadeEffect( ::com::sun::star::presentation::FadeEffect_FADE_TO_CENTER ); // Von aussen einblenden + } + break; + case PPT_TRANSITION_TYPE_DIAMOND : + { + pPage->setTransitionType( animations::TransitionType::IRISWIPE ); + pPage->setTransitionSubtype( animations::TransitionSubType::DIAMOND ); + } + break; + case PPT_TRANSITION_TYPE_PLUS : + { + pPage->setTransitionType( animations::TransitionType::FOURBOXWIPE ); + pPage->setTransitionSubtype( animations::TransitionSubType::CORNERSOUT ); + } + break; + case PPT_TRANSITION_TYPE_CIRCLE : + { + pPage->setTransitionType( animations::TransitionType::ELLIPSEWIPE ); + pPage->setTransitionSubtype( animations::TransitionSubType::CIRCLE ); + } + break; + case PPT_TRANSITION_TYPE_WEDGE : + { + pPage->setTransitionType( animations::TransitionType::FANWIPE ); + pPage->setTransitionSubtype( animations::TransitionSubType::CENTERTOP ); + } + break; + case PPT_TRANSITION_TYPE_WHEEL : + { + pPage->setTransitionType( animations::TransitionType::PINWHEELWIPE ); + sal_Int16 nSubType; + switch( nDirection ) + { + default: + case 1 : nSubType = animations::TransitionSubType::ONEBLADE; break; + case 2 : nSubType = animations::TransitionSubType::TWOBLADEVERTICAL; break; + case 3 : nSubType = animations::TransitionSubType::THREEBLADE; break; + case 4 : nSubType = animations::TransitionSubType::FOURBLADE; break; + case 8 : nSubType = animations::TransitionSubType::EIGHTBLADE; break; + } + pPage->setTransitionSubtype( nSubType ); + } + break; + case PPT_TRANSITION_TYPE_PUSH : + { + pPage->setTransitionType( animations::TransitionType::PUSHWIPE ); + sal_Int16 nSubType; + switch( nDirection ) + { + default: + case 0 : nSubType = animations::TransitionSubType::FROMRIGHT; break; + case 1 : nSubType = animations::TransitionSubType::FROMBOTTOM; break; + case 2 : nSubType = animations::TransitionSubType::FROMLEFT; break; + case 3 : nSubType = animations::TransitionSubType::FROMTOP; break; + } + pPage->setTransitionSubtype( nSubType ); + } + break; + case PPT_TRANSITION_TYPE_COMB : + { + pPage->setTransitionType( animations::TransitionType::PUSHWIPE ); + pPage->setTransitionSubtype( nDirection ? animations::TransitionSubType::COMBVERTICAL : animations::TransitionSubType::COMBHORIZONTAL ); + } + break; + case PPT_TRANSITION_TYPE_NEWSFLASH : + { + pPage->setTransitionType( animations::TransitionType::FOURBOXWIPE ); + pPage->setTransitionSubtype( animations::TransitionSubType::CORNERSOUT ); +/* + pPage->setTransitionType( animations::TransitionType::ZOOM ); + pPage->setTransitionSubtype( animations::TransitionSubType::ROTATEIN ); +*/ + } + break; + case PPT_TRANSITION_TYPE_SMOOTHFADE : + { + pPage->setTransitionType( animations::TransitionType::FADE ); + pPage->setTransitionSubtype( animations::TransitionSubType::CROSSFADE ); + } + break; + } + + if ( nSpeed == 0 ) + pPage->setTransitionDuration( 3.0 ); // langsam + else if ( nSpeed == 1 ) + pPage->setTransitionDuration( 2.0 ); // mittel + else if ( nSpeed == 2 ) + pPage->setTransitionDuration( 1.0 ); // schnell + + if ( nBuildFlags & 0x400 ) // slidechange by time + { // Standzeit (in Ticks) + pPage->SetPresChange( PRESCHANGE_AUTO ); + pPage->SetTime( nSlideTime / 1000 ); + } + else + pPage->SetPresChange( mePresChange ); + +// if ( nBuildFlags & 1 ) // slidechange by mouseclick +// pPage->SetPresChange( mePresChange ); + + if ( nBuildFlags & 4 ) + pPage->SetExcluded( TRUE ); // Dia nicht anzeigen + if ( nBuildFlags & 16 ) + { // Dia mit Soundeffekt + pPage->SetSound( TRUE ); + String aSoundFile( ReadSound( nSoundRef ) ); + pPage->SetSoundFile( aSoundFile ); + } + if ( nBuildFlags & ( 1 << 6 ) ) // Loop until next sound + pPage->SetLoopSound( sal_True ); + if ( nBuildFlags & ( 1 << 8 ) ) // Stop the previous sound + pPage->SetStopSound( sal_True ); + break; + } + } + } + aHd.SeekToEndOfRecord( rStCtrl ); + } + if ( bTryTwice && ( bSSSlideInfoAtom == FALSE ) ) + { + bTryTwice = FALSE; + if ( HasMasterPage( nAktPageNum, eAktPageKind ) ) + { + USHORT nMasterNum = GetMasterPageIndex( nAktPageNum, eAktPageKind ); + PptSlidePersistList* pPageList = GetPageList( PPT_MASTERPAGE ); + if ( pPageList && ( nMasterNum < pPageList->Count() ) ) + { + PptSlidePersistEntry* pE = (*pPageList)[ nMasterNum ]; + if ( pE ) + { + UINT32 nOfs = pE->aPersistAtom.nReserved; + if ( nOfs ) + { + rStCtrl.Seek( nOfs ); + nPageRecEnd = nOfs + 16; + continue; + } + } + } + + } + } + break; + } + } + } + + if ( !bNewAnimationsUsed ) + { + tAnimationVector aAnimationsOnThisPage; + + // add effects from page in correct order + SdrObjListIter aSdrIter( *pPage, IM_FLAT ); + while ( aSdrIter.IsMore() ) + { + SdrObject* pObj = aSdrIter.Next(); + tAnimationMap::iterator aFound = maAnimations.find( pObj ); + if( aFound != maAnimations.end() ) + { + std::pair< SdrObject*, Ppt97AnimationPtr > aPair( (*aFound).first, (*aFound).second ); + aAnimationsOnThisPage.push_back( aPair ); + } + } + + Ppt97AnimationStlSortHelper aSortHelper; + std::sort( aAnimationsOnThisPage.begin(), aAnimationsOnThisPage.end(), aSortHelper ); + + tAnimationVector::iterator aIter( aAnimationsOnThisPage.begin() ); + const tAnimationVector::iterator aEnd( aAnimationsOnThisPage.end() ); + + for( ;aIter != aEnd; aIter++ ) + { + Ppt97AnimationPtr pPpt97Animation = (*aIter).second;; + if( pPpt97Animation.get() ) + pPpt97Animation->createAndSetCustomAnimationEffect( (*aIter).first ); + } + } + rStCtrl.Seek( nFilePosMerk ); +} + +////////////////////////////////////////////////////////////////////////// +// +// Import von Sounds +// +// Die Sounds werden nicht nur als String importiert sondern auch +// in die Gallery einefuegt, falls dort noch nicht vorhanden. +// +/////////////////////////////////////////////////////////////////////////// + +String ImplSdPPTImport::ReadSound(UINT32 nSoundRef) const +{ + String aRetval; + UINT32 nPosMerk = rStCtrl.Tell(); + DffRecordHeader aDocHd; + if ( SeekToDocument( &aDocHd ) ) + { + UINT32 nSoundLen = aDocHd.GetRecEndFilePos(); + DffRecordHeader aSoundBlockRecHd; + if( SeekToRec( rStCtrl, PPT_PST_SoundCollection, nSoundLen, &aSoundBlockRecHd ) ) + { + UINT32 nDataLen = aSoundBlockRecHd.GetRecEndFilePos(); + DffRecordHeader aSoundRecHd; + BOOL bRefStrValid = FALSE; + BOOL bDone = FALSE; + + while( !bDone && SeekToRec( rStCtrl, PPT_PST_Sound, nDataLen, &aSoundRecHd ) ) + { + UINT32 nStrLen = aSoundRecHd.GetRecEndFilePos(); + String aRefStr; + UINT32 nPosMerk2 = rStCtrl.Tell(); + if ( SeekToRec( rStCtrl, PPT_PST_CString, nStrLen, NULL, 2 ) ) + { + if ( ReadString( aRefStr ) ) + bRefStrValid = TRUE; + } + if ( bRefStrValid ) + { + if ( UniString::CreateFromInt32( nSoundRef ) == aRefStr ) + { + rStCtrl.Seek( nPosMerk2 ); + if ( SeekToRec( rStCtrl, PPT_PST_CString, nStrLen, NULL, 0 ) ) + { + ReadString( aRetval ); + bDone = TRUE; + } + } + } + if ( bDone ) + { + // ueberpruefen, ob diese Sound-Datei schon + // existiert. Wenn nicht, exportiere diese + // in unser lokales Sound-Verzeichnis. + BOOL bSoundExists = FALSE; + List* pSoundList = new List(); + + GalleryExplorer::FillObjList( GALLERY_THEME_SOUNDS, *pSoundList ); + GalleryExplorer::FillObjList( GALLERY_THEME_USERSOUNDS, *pSoundList ); + + for( ULONG n = 0; ( n < pSoundList->Count() ) && !bSoundExists; n++ ) + { + INetURLObject aURL( *(String*)pSoundList->GetObject( n ) ); + String aSoundName( aURL.GetName() ); + + if( aSoundName == aRetval ) + { + aRetval = *(String*)pSoundList->GetObject( n ); + bSoundExists = TRUE; + } + } + + for ( void* pPtr = pSoundList->First(); pPtr; pPtr = pSoundList->Next() ) + delete (String*)pPtr; + + delete pSoundList; + + if ( !bSoundExists ) + { + rStCtrl.Seek( nPosMerk2 ); + DffRecordHeader aSoundDataRecHd; + if ( SeekToRec( rStCtrl, PPT_PST_SoundData, nStrLen, &aSoundDataRecHd, 0 ) ) + { + String aGalleryDir( SvtPathOptions().GetGalleryPath() ); + INetURLObject aGalleryUserSound( aGalleryDir.GetToken( aGalleryDir.GetTokenCount( ';' ) - 1 ) ); + + aGalleryUserSound.Append( aRetval ); + UINT32 nSoundDataLen = aSoundDataRecHd.nRecLen; + UINT8* pBuf = new UINT8[ nSoundDataLen ]; + + rStCtrl.Read( pBuf, nSoundDataLen ); + SvStream* pOStm = ::utl::UcbStreamHelper::CreateStream( aGalleryUserSound.GetMainURL( INetURLObject::NO_DECODE ), STREAM_WRITE | STREAM_TRUNC ); + + if( pOStm ) + { + pOStm->Write( pBuf, nSoundDataLen ); + + if( pOStm->GetError() == ERRCODE_NONE ) + { + GalleryExplorer::InsertURL( GALLERY_THEME_USERSOUNDS, aGalleryUserSound.GetMainURL( INetURLObject::NO_DECODE ) ); + aRetval = aGalleryUserSound.GetMainURL( INetURLObject::NO_DECODE ); + } + + delete pOStm; + } + + delete[] pBuf; + } + } + } + if ( !bDone ) + aSoundRecHd.SeekToEndOfRecord( rStCtrl ); + } + } + } + rStCtrl.Seek( nPosMerk ); + return aRetval; +} + +////////////////////////////////////////////////////////////////////////// +// +// media object import, the return value is the url to the media object +// +////////////////////////////////////////////////////////////////////////// + +String ImplSdPPTImport::ReadMedia( sal_uInt32 nMediaRef ) const +{ + String aRetVal; + DffRecordHeader* pHd( const_cast<ImplSdPPTImport*>(this)->aDocRecManager.GetRecordHeader( PPT_PST_ExObjList, SEEK_FROM_BEGINNING ) ); + if ( pHd ) + { + pHd->SeekToContent( rStCtrl ); + while ( ( rStCtrl.Tell() < pHd->GetRecEndFilePos() ) && !aRetVal.Len() ) + { + DffRecordHeader aHdMovie; + rStCtrl >> aHdMovie; + switch( aHdMovie.nRecType ) + { + case PPT_PST_ExAviMovie : + case PPT_PST_ExMCIMovie : + { + DffRecordHeader aExVideoHd; + if ( SeekToRec( rStCtrl, PPT_PST_ExVideo, aHdMovie.GetRecEndFilePos(), &aExVideoHd ) ) + { + DffRecordHeader aExMediaAtomHd; + if ( SeekToRec( rStCtrl, PPT_PST_ExMediaAtom, aExVideoHd.GetRecEndFilePos(), &aExMediaAtomHd ) ) + { + sal_uInt32 nRef; + rStCtrl >> nRef; + if ( nRef == nMediaRef ) + { + aExVideoHd.SeekToContent( rStCtrl ); + while( rStCtrl.Tell() < aExVideoHd.GetRecEndFilePos() ) + { + DffRecordHeader aHd; + rStCtrl >> aHd; + switch( aHd.nRecType ) + { + case PPT_PST_CString : + { + aHd.SeekToBegOfRecord( rStCtrl ); + String aStr; + if ( ReadString( aStr ) ) + { + if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aStr, aRetVal ) ) + { + aRetVal = INetURLObject( aRetVal ).GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS ); + } + } + } + break; + } + aHd.SeekToEndOfRecord( rStCtrl ); + } + break; + } + } + } + } + break; + } + aHdMovie.SeekToEndOfRecord( rStCtrl ); + } + } + return aRetVal; +} + +////////////////////////////////////////////////////////////////////////// +// +// Import von Objekten +// +////////////////////////////////////////////////////////////////////////// + +void ImplSdPPTImport::FillSdAnimationInfo( SdAnimationInfo* pInfo, PptInteractiveInfoAtom* pIAtom, String aMacroName ) +{ + // Lokale Informationen in pInfo eintragen + if( pIAtom->nSoundRef ) + { + pInfo->SetBookmark( ReadSound( pIAtom->nSoundRef ) ); // Pfad zum Soundfile in MSDOS-Notation + pInfo->meClickAction = ::com::sun::star::presentation::ClickAction_SOUND; // RunProgramAction + } +// if ( nFlags & 0x01 ) // koennen wir nicht ( beim Anklicken markieren ) + switch ( pIAtom->nAction ) + { +// case 0x01 : // MacroAction +// { +// pInfo->meClickAction = ::com::sun::star::presentation::::com::sun::star::presentation::ClickAction_MACRO; +// // aMacro liegt in folgender Form vor: +// // "Macroname.Modulname.Libname.Dokumentname" oder +// // "Macroname.Modulname.Libname.Applikationsname" +// pInfo->maBookmark = aMacroName; +// } +// break; + case 0x02 : // RunProgramAction + { + pInfo->meClickAction = ::com::sun::star::presentation::ClickAction_PROGRAM; + pInfo->SetBookmark( aMacroName ); // Programmname in aBookmark + } + break; + case 0x03 : // JumpAction + { + switch( pIAtom->nJump ) + { + case 0x01 : + pInfo->meClickAction = ::com::sun::star::presentation::ClickAction_NEXTPAGE; // Next slide + break; + case 0x02 : + pInfo->meClickAction = ::com::sun::star::presentation::ClickAction_PREVPAGE; // Previous slide + break; + case 0x03 : + pInfo->meClickAction = ::com::sun::star::presentation::ClickAction_FIRSTPAGE; // First slide + break; + case 0x04 : + pInfo->meClickAction = ::com::sun::star::presentation::ClickAction_LASTPAGE; // last Slide + break; + case 0x05 : + pInfo->meClickAction = ::com::sun::star::presentation::ClickAction_PREVPAGE; // Last slide viewed + break; + case 0x06 : + pInfo->meClickAction = ::com::sun::star::presentation::ClickAction_STOPPRESENTATION; // End show + break; + default : + pInfo->meClickAction = ::com::sun::star::presentation::ClickAction_NONE; // 0x00: no action, else unknown + break; + } + } + break; + case 0x04 : + { + SdHyperlinkEntry* pPtr; + for ( pPtr = (SdHyperlinkEntry*)aHyperList.First(); pPtr; pPtr = (SdHyperlinkEntry*)aHyperList.Next() ) + { + if ( pPtr->nIndex == pIAtom->nExHyperlinkId ) + break; + } + if ( pPtr ) + { + switch( pIAtom->nHyperlinkType ) + { + case 9: + case 8: // hyperlink : URL + { + if ( pPtr->aTarget.Len() ) + { + ::sd::DrawDocShell* pDocShell = mpDoc->GetDocSh(); + if ( pDocShell ) + { + String aBaseURL = pDocShell->GetMedium()->GetBaseURL(); + String aBookmarkURL( pInfo->GetBookmark() ); + INetURLObject aURL( pPtr->aTarget ); + if( INET_PROT_NOT_VALID == aURL.GetProtocol() ) + utl::LocalFileHelper::ConvertSystemPathToURL( pPtr->aTarget, aBaseURL, aBookmarkURL ); + if( !aBookmarkURL.Len() ) + aBookmarkURL = URIHelper::SmartRel2Abs( INetURLObject(aBaseURL), pPtr->aTarget, URIHelper::GetMaybeFileHdl(), true ); + pInfo->SetBookmark( aBookmarkURL ); + pInfo->meClickAction = ::com::sun::star::presentation::ClickAction_PROGRAM; + } + } + } + break; + + case 10: + break; + + case 7: // hyperlink auf eine Seite + { + if ( pPtr->aConvSubString.Len() ) + { + pInfo->meClickAction = ::com::sun::star::presentation::ClickAction_BOOKMARK; + pInfo->SetBookmark( pPtr->aConvSubString ); + } + } + break; + } + } + } + break; + case 0x05 : // OLEAction ( OLEVerb to use, 0==first, 1==secnd, .. ) + case 0x06 : // MediaAction + case 0x07 : // CustomShowAction + default : // 0x00: no action, else unknown action + break; + } +} + +SdrObject* ImplSdPPTImport::ApplyTextObj( PPTTextObj* pTextObj, SdrTextObj* pObj, SdPage* pPage, + SfxStyleSheet* pSheet, SfxStyleSheet** ppStyleSheetAry ) const +{ + SfxStyleSheet* pStyleSheetAry[ 9 ]; + SdrTextObj* pText = pObj; + SdrObject* pRet = pText; + + ppStyleSheetAry = NULL; + + PresObjKind ePresKind = PRESOBJ_NONE; + PptOEPlaceholderAtom* pPlaceHolder = pTextObj->GetOEPlaceHolderAtom(); + String aPresentationText; + if ( pPlaceHolder ) + { + switch( pPlaceHolder->nPlaceholderId ) + { + case PPT_PLACEHOLDER_MASTERNOTESSLIDEIMAGE : + case PPT_PLACEHOLDER_MASTERCENTEREDTITLE : + case PPT_PLACEHOLDER_MASTERTITLE : + { + ePresKind = PRESOBJ_TITLE; + aPresentationText = pPage->GetPresObjText( ePresKind ); + } + break; + case PPT_PLACEHOLDER_MASTERBODY : + { + ePresKind = PRESOBJ_OUTLINE; + aPresentationText = pPage->GetPresObjText( ePresKind ); + } + break; + case PPT_PLACEHOLDER_MASTERSUBTITLE : + { + ePresKind = PRESOBJ_TEXT; + aPresentationText = pPage->GetPresObjText( ePresKind ); + } + break; + case PPT_PLACEHOLDER_MASTERNOTESBODYIMAGE : + { + ePresKind = PRESOBJ_NOTES; + aPresentationText = pPage->GetPresObjText( ePresKind ); + } + break; + case PPT_PLACEHOLDER_MASTERDATE : ePresKind = PRESOBJ_DATETIME; break; + case PPT_PLACEHOLDER_MASTERSLIDENUMBER : ePresKind = PRESOBJ_SLIDENUMBER;break; + case PPT_PLACEHOLDER_MASTERFOOTER : ePresKind = PRESOBJ_FOOTER; break; + case PPT_PLACEHOLDER_MASTERHEADER : ePresKind = PRESOBJ_HEADER; break; + } + } + switch ( pTextObj->GetDestinationInstance() ) + { + case TSS_TYPE_PAGETITLE : + case TSS_TYPE_TITLE : + { + pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_TITLE ); + if ( pSheet ) + ((SdrAttrObj*)pText)->SdrAttrObj::NbcSetStyleSheet( pSheet, TRUE ); + DBG_ASSERT( pSheet, "ImplSdPPTImport::ApplyTextObj -> could not get stylesheet for titleobject (SJ)" ); + } + break; + case TSS_TYPE_SUBTITLE : + { + pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_TEXT ); + if ( pSheet ) + ((SdrAttrObj*)pText)->SdrAttrObj::NbcSetStyleSheet( pSheet, TRUE ); + DBG_ASSERT( pSheet, "ImplSdPPTImport::ApplyTextObj -> could not get stylesheet for subtitleobject (SJ)" ); + } + break; + case TSS_TYPE_BODY : + case TSS_TYPE_HALFBODY : + case TSS_TYPE_QUARTERBODY : + { + for ( UINT16 nLevel = 9; nLevel; nLevel-- ) + { + String aName( pPage->GetLayoutName() ); + aName.Append( (sal_Unicode)( ' ' ) ); + aName.Append( String::CreateFromInt32( nLevel ) ); + pSheet = (SfxStyleSheet*)mpDoc->GetStyleSheetPool()->Find( aName, SD_STYLE_FAMILY_MASTERPAGE ); + if ( pSheet ) + pText->StartListening( *pSheet ); + pStyleSheetAry[ nLevel - 1 ] = pSheet; + } + DBG_ASSERT( pSheet, "ImplSdPPTImport::ApplyTextObj -> could not get stylesheet for outlinerobject (SJ)" ); + if ( pSheet ) + ((SdrAttrObj*)pText)->SdrAttrObj::NbcSetStyleSheet( pSheet, TRUE ); + ppStyleSheetAry = &pStyleSheetAry[ 0 ]; + } + break; + case TSS_TYPE_NOTES : + { + if ( pPlaceHolder && ( ( pPlaceHolder->nPlaceholderId == PPT_PLACEHOLDER_NOTESSLIDEIMAGE ) + || ( pPlaceHolder->nPlaceholderId == PPT_PLACEHOLDER_MASTERNOTESSLIDEIMAGE ) ) ) + { + pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_TITLE ); + if ( pSheet ) + ((SdrAttrObj*)pText)->SdrAttrObj::NbcSetStyleSheet( pSheet, TRUE ); + DBG_ASSERT( pSheet, "ImplSdPPTImport::ApplyTextObj -> could not get stylesheet for titleobject (SJ)" ); + } + else + { + pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_NOTES ); + DBG_ASSERT( pSheet, "ImplSdPPTImport::ApplyTextObj -> could not get stylesheet for notesobj (SJ)" ); + if ( pSheet ) + ((SdrAttrObj*)pText)->SdrAttrObj::NbcSetStyleSheet( pSheet, TRUE ); + } + } + break; + case TSS_TYPE_UNUSED : + case TSS_TYPE_TEXT_IN_SHAPE : + { + switch( ePresKind ) + { + case PRESOBJ_DATETIME : + case PRESOBJ_SLIDENUMBER : + case PRESOBJ_FOOTER : + case PRESOBJ_HEADER : + pSheet = (SfxStyleSheet*)mpDoc->GetStyleSheetPool()->Find( String(SdResId( STR_PSEUDOSHEET_BACKGROUNDOBJECTS )), SD_STYLE_FAMILY_PSEUDO ); + break; + default : + pSheet = (SfxStyleSheet*)mpDoc->GetStyleSheetPool()->Find( String(SdResId( STR_STANDARD_STYLESHEET_NAME )), SD_STYLE_FAMILY_GRAPHICS ); + } + } + break; + } + pText = (SdrTextObj*)SdrPowerPointImport::ApplyTextObj( pTextObj, pText, pPage, pSheet, ppStyleSheetAry ); + if ( pPlaceHolder && pPlaceHolder->nPlaceholderId ) + { + if ( eAktPageKind == PPT_MASTERPAGE ) + { + sal_Bool bCreatePlaceHolder = ( pTextObj->GetInstance() != TSS_TYPE_SUBTITLE ) && ( pTextObj->GetInstance() != TSS_TYPE_UNUSED ); + sal_Bool bIsHeaderFooter = ( ePresKind == PRESOBJ_HEADER) || (ePresKind == PRESOBJ_FOOTER) + || (ePresKind == PRESOBJ_DATETIME) || (ePresKind == PRESOBJ_SLIDENUMBER); + if ( bCreatePlaceHolder && ( pTextObj->GetInstance() == TSS_TYPE_TEXT_IN_SHAPE ) ) + bCreatePlaceHolder = bIsHeaderFooter; + if ( bCreatePlaceHolder ) + { + if ( !bIsHeaderFooter ) + { + pText->SetNotVisibleAsMaster( TRUE ); + pText->SetEmptyPresObj( TRUE ); + } + pText->SetUserCall( pPage ); + pPage->InsertPresObj( pText, ePresKind ); + SdrOutliner* pOutl = NULL; + if ( pTextObj->GetInstance() == TSS_TYPE_NOTES ) + pOutl = GetDrawOutliner( pText ); + if ( aPresentationText.Len() ) + pPage->SetObjText( (SdrTextObj*)pText, pOutl, ePresKind, aPresentationText ); + + if ( pPage->GetPageKind() != PK_NOTES ) + { + SfxStyleSheet* pSheet2( pPage->GetStyleSheetForPresObj( ePresKind ) ); + if ( pSheet2 ) + { + SfxItemSet& rItemSet = pSheet2->GetItemSet(); + rItemSet.Put( (SdrTextLeftDistItem&)pText->GetMergedItem( SDRATTR_TEXT_LEFTDIST ) ); + rItemSet.Put( (SdrTextRightDistItem&)pText->GetMergedItem( SDRATTR_TEXT_RIGHTDIST ) ); + rItemSet.Put( (SdrTextUpperDistItem&)pText->GetMergedItem( SDRATTR_TEXT_UPPERDIST ) ); + rItemSet.Put( (SdrTextLowerDistItem&)pText->GetMergedItem( SDRATTR_TEXT_LOWERDIST ) ); + rItemSet.Put( (SdrTextVertAdjustItem&)pText->GetMergedItem( SDRATTR_TEXT_VERTADJUST ) ); + rItemSet.Put( (SdrTextHorzAdjustItem&)pText->GetMergedItem( SDRATTR_TEXT_HORZADJUST ) ); + } + pText->NbcSetStyleSheet( pSheet2, FALSE ); + } + + SfxItemSet aTempAttr( mpDoc->GetPool() ); + SdrTextMinFrameHeightItem aMinHeight( pText->GetLogicRect().GetSize().Height() ); + aTempAttr.Put( aMinHeight ); + SdrTextAutoGrowHeightItem aAutoGrowHeight( FALSE ); + aTempAttr.Put( aAutoGrowHeight ); + pText->SetMergedItemSet(aTempAttr); + } + else + { + pRet = NULL; + } + } + else + { + const PptSlideLayoutAtom* pSlideLayout = GetSlideLayoutAtom(); + if ( pSlideLayout || ( eAktPageKind == PPT_NOTEPAGE ) ) + { + INT16 nPlaceholderId = pPlaceHolder->nPlaceholderId; + UINT16 i = 0; + if ( eAktPageKind == PPT_SLIDEPAGE ) + { + for ( ; i < 8; i++ ) + { + if ( pSlideLayout->aPlaceholderId[ i ] == nPlaceholderId ) + break; + } + } + if ( i < 8 ) + { + PresObjKind ePresObjKind = PRESOBJ_NONE; + sal_Bool bEmptyPresObj = sal_True; + sal_Bool bVertical = sal_False; + if ( ( pTextObj->GetShapeType() == mso_sptRectangle ) || ( pTextObj->GetShapeType() == mso_sptTextBox ) ) + { + if ( pTextObj->Count() ) + bEmptyPresObj = sal_False; + switch ( nPlaceholderId ) + { + case PPT_PLACEHOLDER_NOTESBODY : ePresObjKind = PRESOBJ_NOTES; break; + case PPT_PLACEHOLDER_VERTICALTEXTTITLE : + bVertical = sal_True; // PASSTHROUGH !!! + case PPT_PLACEHOLDER_TITLE : ePresObjKind = PRESOBJ_TITLE; break; + case PPT_PLACEHOLDER_VERTICALTEXTBODY : + bVertical = sal_True; // PASSTHROUGH !!! + case PPT_PLACEHOLDER_BODY : ePresObjKind = PRESOBJ_OUTLINE; break; + case PPT_PLACEHOLDER_CENTEREDTITLE : ePresObjKind = PRESOBJ_TITLE; break; + case PPT_PLACEHOLDER_SUBTITLE : ePresObjKind = PRESOBJ_TEXT; break; // PRESOBJ_OUTLINE + + default : + { + if ( !pTextObj->Count() ) + { + switch ( nPlaceholderId ) + { + case PPT_PLACEHOLDER_MEDIACLIP : + case PPT_PLACEHOLDER_OBJECT : ePresObjKind = PRESOBJ_OBJECT; break; + case PPT_PLACEHOLDER_GRAPH : ePresObjKind = PRESOBJ_CHART; break; + case PPT_PLACEHOLDER_TABLE : ePresObjKind = PRESOBJ_TABLE; break; + case PPT_PLACEHOLDER_CLIPART : ePresObjKind = PRESOBJ_GRAPHIC; break; + case PPT_PLACEHOLDER_ORGANISZATIONCHART : ePresObjKind = PRESOBJ_ORGCHART; break; + } + } + }; + } + } + else if ( pTextObj->GetShapeType() == mso_sptPictureFrame ) + { + if ( !pTextObj->Count() && pObj->ISA( SdrGrafObj ) ) + { + bEmptyPresObj = sal_False; + switch ( nPlaceholderId ) + { + case PPT_PLACEHOLDER_MEDIACLIP : + case PPT_PLACEHOLDER_OBJECT : ePresObjKind = PRESOBJ_OBJECT; break; + case PPT_PLACEHOLDER_GRAPH : ePresObjKind = PRESOBJ_CHART; break; + case PPT_PLACEHOLDER_TABLE : ePresObjKind = PRESOBJ_TABLE; break; + case PPT_PLACEHOLDER_CLIPART : ePresObjKind = PRESOBJ_GRAPHIC; break; + case PPT_PLACEHOLDER_ORGANISZATIONCHART : ePresObjKind = PRESOBJ_ORGCHART; break; + } + } + } + if ( ePresObjKind != PRESOBJ_NONE ) + { + if ( !bEmptyPresObj ) + { + pPage->InsertPresObj( pRet, ePresObjKind ); + } + else + { + SdrObject* pPresObj = pPage->CreatePresObj( ePresObjKind, bVertical, pText->GetLogicRect(), TRUE ); + pPresObj->SetUserCall( pPage ); + + SfxItemSet aSet( pSdrModel->GetItemPool() ); + ApplyAttributes( rStCtrl, aSet ); + pPresObj->SetMergedItemSet(aSet); + + if ( ( eAktPageKind != PPT_NOTEPAGE ) && ( pSlideLayout->aPlacementId[ i ] != (ULONG)-1 ) ) + { + SdrObject* pTitleObj = ((SdPage&)pPage->TRG_GetMasterPage()).GetPresObj( PRESOBJ_TITLE ); + SdrObject* pOutlineObj = ((SdPage&)pPage->TRG_GetMasterPage()).GetPresObj( PRESOBJ_OUTLINE ); + + Rectangle aTitleRect; + Rectangle aOutlineRect; + Size aOutlineSize; + + if ( pTitleObj ) + aTitleRect = pTitleObj->GetLogicRect(); + if ( pOutlineObj ) + { + aOutlineRect = pOutlineObj->GetLogicRect(); + aOutlineSize = aOutlineRect.GetSize(); + } + Rectangle aLogicRect( pPresObj->GetLogicRect() ); + Size aLogicSize( aLogicRect.GetSize() ); + + switch ( pSlideLayout->aPlacementId[ i ] ) + { + case 0 : // Lage im Titelbereich + { + if ( aLogicRect != aTitleRect ) + pPresObj->SetUserCall( NULL ); + } + break; + + case 1: + { + if ( pSlideLayout->eLayout == PPT_LAYOUT_TITLEANDBODYSLIDE ) + { // Lage im Outlinebereich + if ( aLogicRect != aOutlineRect ) + pPresObj->SetUserCall( NULL ); + } + else if ( pSlideLayout->eLayout == PPT_LAYOUT_2COLUMNSANDTITLE ) + { // Lage im Outlinebereich links + if (Abs(aLogicRect.Left() - aOutlineRect.Left()) > MAX_USER_MOVE || + Abs(aLogicRect.Top() - aOutlineRect.Top()) > MAX_USER_MOVE || + Abs(aLogicRect.Bottom() - aOutlineRect.Bottom()) > MAX_USER_MOVE || + aLogicSize.Width() / aOutlineSize.Width() < 0.48 || + aLogicSize.Width() / aOutlineSize.Width() > 0.5) + { + pPresObj->SetUserCall(NULL); + } + } + else if ( pSlideLayout->eLayout == PPT_LAYOUT_2ROWSANDTITLE ) + { // Lage im Outlinebereich oben + if (Abs(aLogicRect.Left() - aOutlineRect.Left()) > MAX_USER_MOVE || + Abs(aLogicRect.Top() - aOutlineRect.Top()) > MAX_USER_MOVE || + Abs(aLogicRect.Right() - aOutlineRect.Right()) > MAX_USER_MOVE) + { + pPresObj->SetUserCall( NULL ); + } + } + else if (Abs(aLogicRect.Left() - aOutlineRect.Left()) > MAX_USER_MOVE || + Abs(aLogicRect.Top() - aOutlineRect.Top()) > MAX_USER_MOVE) + { // Lage im Outlinebereich links oben + pPresObj->SetUserCall( NULL ); + } + } + break; + + case 2: + { + if ( pSlideLayout->eLayout == PPT_LAYOUT_2COLUMNSANDTITLE ) + { // Lage im Outlinebereich rechts + if (Abs(aLogicRect.Right() - aOutlineRect.Right()) > MAX_USER_MOVE || + Abs(aLogicRect.Top() - aOutlineRect.Top()) > MAX_USER_MOVE || + Abs(aLogicRect.Bottom() - aOutlineRect.Bottom()) > MAX_USER_MOVE || + aLogicSize.Width() / aOutlineSize.Width() < 0.48 || + aLogicSize.Width() / aOutlineSize.Width() > 0.5) + { + pPresObj->SetUserCall( NULL ); + } + } + else if ( pSlideLayout->eLayout == PPT_LAYOUT_2ROWSANDTITLE ) + { // Lage im Outlinebereich unten + if (Abs(aLogicRect.Left() - aOutlineRect.Left()) > MAX_USER_MOVE || + Abs(aLogicRect.Bottom() - aOutlineRect.Bottom()) > MAX_USER_MOVE || + Abs(aLogicRect.Right() - aOutlineRect.Right()) > MAX_USER_MOVE) + { + pPresObj->SetUserCall( NULL ); + } + } + else if (Abs(aLogicRect.Right() - aOutlineRect.Right()) > MAX_USER_MOVE || + Abs(aLogicRect.Top() - aOutlineRect.Top()) > MAX_USER_MOVE) + { // Lage im Outlinebereich rechts oben + pPresObj->SetUserCall(NULL); + } + } + break; + + case 3: + { // Lage im Outlinebereich links unten + if (Abs(aLogicRect.Left() - aOutlineRect.Left()) > MAX_USER_MOVE || + Abs(aLogicRect.Bottom() - aOutlineRect.Bottom()) > MAX_USER_MOVE) + { + pPresObj->SetUserCall( NULL ); + } + } + break; + + case 4: + { // Lage im Outlinebereich rechts unten + if (Abs(aLogicRect.Right() - aOutlineRect.Right()) > MAX_USER_MOVE || + Abs(aLogicRect.Bottom() - aOutlineRect.Bottom()) > MAX_USER_MOVE) + { + pObj->SetUserCall( NULL ); + } + } + break; + } + } + pRet = NULL; // return zero cause this obj was already inserted by CreatePresObj + } + } + else if ( !pTextObj->Count() ) + pRet = NULL; + } + } + } + } + if ( pRet != pText ) + { + SdrObject* pFree( pText ); + SdrObject::Free( pFree ); + } + return pRet; +} + +SdrObject* ImplSdPPTImport::ProcessObj( SvStream& rSt, DffObjData& rObjData, void* pData, Rectangle& rTextRect, SdrObject* pRet ) +{ + SdrObject* pObj = SdrPowerPointImport::ProcessObj( rSt, rObjData, pData, rTextRect, pRet ); + + // Animationseffekte des Objektes lesen + if ( pObj ) + { + // further setup placeholder objects + if( pObj->ISA(SdrPageObj) && pData ) + { + const ProcessData* pProcessData=(const ProcessData*)pData; + if( pProcessData->pPage ) + pProcessData->pPage->InsertPresObj( pObj, PRESOBJ_PAGE ); + } + + BOOL bInhabitanceChecked = FALSE; + BOOL bAnimationInfoFound = FALSE; + DffRecordHeader aMasterShapeHd; + + if ( maShapeRecords.SeekToContent( rSt, DFF_msofbtClientData, SEEK_FROM_CURRENT_AND_RESTART ) ) + { + DffRecordHeader& rHdClientData = *maShapeRecords.Current(); + while( TRUE ) + { + UINT32 nClientDataLen = rHdClientData.GetRecEndFilePos(); + DffRecordHeader aHd; + do + { + rSt >> aHd; + UINT32 nHdRecEnd = aHd.GetRecEndFilePos(); + switch ( aHd.nRecType ) + { + case PPT_PST_AnimationInfo : + { + DffRecordHeader aHdAnimInfoAtom; + if ( SeekToRec( rSt, PPT_PST_AnimationInfoAtom, nHdRecEnd, &aHdAnimInfoAtom ) ) + { + // read data from stream + Ppt97AnimationPtr pAnimation( new Ppt97Animation( rSt ) ); + // store animation informations + if( pAnimation->HasEffect() ) + { + // translate color to RGB + pAnimation->SetDimColor( MSO_CLR_ToColor(pAnimation->GetDimColor()).GetColor() ); + // translate sound bits to file url + if( pAnimation->HasSoundEffect() ) + pAnimation->SetSoundFileUrl( ReadSound( pAnimation->GetSoundRef() ) ); + + bool bDontAnimateInvisibleShape = false; + { + SdrTextObj* pTextObj = dynamic_cast<SdrTextObj*>(pObj); + + if( pTextObj && pTextObj->HasText() && + !pObj->ISA( SdrObjGroup ) && + pAnimation->HasAnimateAssociatedShape() ) + { + const SfxItemSet& rObjItemSet = pObj->GetMergedItemSet(); + + XFillStyle eFillStyle = ((XFillStyleItem&)(rObjItemSet.Get(XATTR_FILLSTYLE))).GetValue(); + XLineStyle eLineStyle = ((XLineStyleItem&)(rObjItemSet.Get(XATTR_LINESTYLE))).GetValue(); + + if ( ( eFillStyle == XFILL_NONE ) && ( eLineStyle == XLINE_NONE ) ) + bDontAnimateInvisibleShape = true; + } + } + if( bDontAnimateInvisibleShape ) + pAnimation->SetAnimateAssociatedShape(false); + + //maybe some actions necessary to ensure that animations on master pages are played before animations on normal pages + ///mabe todo in future: bool bIsEffectOnMasterPage = !bInhabitanceChecked;? + + maAnimations[pObj] = pAnimation; + + bAnimationInfoFound = TRUE; + } + } + } + break; + case PPT_PST_InteractiveInfo: + { + UINT32 nFilePosMerk2 = rSt.Tell(); + String aMacroName; + + if(SeekToRec( rSt, PPT_PST_CString, nHdRecEnd, NULL, 0 ) ) + ReadString(aMacroName); + + rSt.Seek( nFilePosMerk2 ); + DffRecordHeader aHdInteractiveInfoAtom; + if ( SeekToRec( rSt, PPT_PST_InteractiveInfoAtom, nHdRecEnd, &aHdInteractiveInfoAtom ) ) + { + PptInteractiveInfoAtom aInteractiveInfoAtom; + rSt >> aInteractiveInfoAtom; + + // interactive object + SdAnimationInfo* pInfo = SdDrawDocument::GetShapeUserData(*pObj, true); + + ( (ImplSdPPTImport*) this )->FillSdAnimationInfo( pInfo, &aInteractiveInfoAtom, aMacroName ); + if ( aInteractiveInfoAtom.nAction == 6 ) // Sj -> media action + { + rHdClientData.SeekToContent( rStCtrl ); + DffRecordHeader aObjRefAtomHd; + if ( SeekToRec( rSt, PPT_PST_ExObjRefAtom, nHdRecEnd, &aObjRefAtomHd ) ) + { + sal_uInt32 nRef; + rSt >> nRef; + String aMediaURL( ReadMedia( nRef ) ); + if ( !aMediaURL.Len() ) + aMediaURL = ReadSound( nRef ); + if ( aMediaURL.Len() ) + { + SdrMediaObj* pMediaObj = new SdrMediaObj( pObj->GetSnapRect() ); + pMediaObj->SetModel( pObj->GetModel() ); + pMediaObj->SetMergedItemSet( pObj->GetMergedItemSet() ); + + //--remove object from maAnimations list and add the new object instead + Ppt97AnimationPtr pAnimation; + { + tAnimationMap::iterator aFound = maAnimations.find( pObj ); + if( aFound != maAnimations.end() ) + { + pAnimation = (*aFound).second; + maAnimations.erase(aFound); + } + maAnimations[pMediaObj] = pAnimation; + } + //-- + + SdrObject::Free( pObj ), pObj = pMediaObj; // SJ: hoping that pObj is not inserted in any list + pMediaObj->setURL( aMediaURL ); + } + } + } + } + } + break; + } + aHd.SeekToEndOfRecord( rSt ); + } + while( ( rSt.GetError() == 0 ) && ( rSt.Tell() < nClientDataLen ) ); + + if ( bInhabitanceChecked || bAnimationInfoFound ) + break; + bInhabitanceChecked = TRUE; + if ( ! ( IsProperty( DFF_Prop_hspMaster ) && SeekToShape( rSt, pData, GetPropertyValue( DFF_Prop_hspMaster ) ) ) ) + break; + rSt >> aMasterShapeHd; + if ( !SeekToRec( rSt, DFF_msofbtClientData, aMasterShapeHd.GetRecEndFilePos(), &aMasterShapeHd ) ) + break; + aMasterShapeHd.SeekToContent( rSt ); + rHdClientData = aMasterShapeHd; + } + } + } + return pObj; +} + +// --------------------- +// - exported function - +// --------------------- + +extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL ImportPPT( const ::rtl::OUString& rConfigPath, + uno::Sequence< beans::PropertyValue >* pConfigData, + SdDrawDocument* pDocument, SvStream& rDocStream, SvStorage& rStorage, SfxMedium& rMedium ) +{ + sal_Bool bRet = sal_False; + + MSFilterTracer aTracer( rConfigPath, pConfigData ); + aTracer.StartTracing(); + + SdPPTImport* pImport = new SdPPTImport( pDocument, rDocStream, rStorage, rMedium, &aTracer ); + bRet = pImport->Import(); + + aTracer.EndTracing(); + delete pImport; + + return bRet; +} diff --git a/sd/source/filter/ppt/pptin.hxx b/sd/source/filter/ppt/pptin.hxx new file mode 100644 index 000000000000..24e300bd79e9 --- /dev/null +++ b/sd/source/filter/ppt/pptin.hxx @@ -0,0 +1,105 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SD_PPTIN_HXX +#define _SD_PPTIN_HXX + +#include <filter/msfilter/svdfppt.hxx> +#include <svx/msdffdef.hxx> +#include <diadef.h> +#include <svx/svdtypes.hxx> +#include <filter/msfilter/msfiltertracer.hxx> +#include <com/sun/star/uno/Any.h> +#include <boost/shared_ptr.hpp> + +class SdDrawDocument; +class SfxMedium; + +/************************************************************************* +|* +|* lokaler Import +|* +\************************************************************************/ + +class SdPage; +class SdAnimationInfo; +struct PptInteractiveInfoAtom; +class Ppt97Animation; + +typedef boost::shared_ptr< Ppt97Animation > Ppt97AnimationPtr; +typedef ::std::map < SdrObject*, Ppt97AnimationPtr > tAnimationMap; +typedef std::vector< std::pair< SdrObject*, Ppt97AnimationPtr > > tAnimationVector; + +class ImplSdPPTImport : public SdrPowerPointImport +{ + SfxMedium& mrMed; + SvStorage& mrStorage; +// SvStream* mpPicStream; + DffRecordHeader maDocHd; + List maSlideNameList; + BOOL mbDocumentFound; + sal_uInt32 mnFilterOptions; + SdDrawDocument* mpDoc; + PresChange mePresChange; + SdrLayerID mnBackgroundLayerID; + SdrLayerID mnBackgroundObjectsLayerID; + + tAnimationMap maAnimations; + + void SetHeaderFooterPageSettings( SdPage* pPage, const PptSlidePersistEntry* pMasterPersist ); + void ImportPageEffect( SdPage* pPage, const sal_Bool bNewAnimationsUsed ); + + void FillSdAnimationInfo( SdAnimationInfo* pInfo, PptInteractiveInfoAtom* pIAtom, String aMacroName ); + + virtual SdrObject* ProcessObj( SvStream& rSt, DffObjData& rData, void* pData, Rectangle& rTextRect, SdrObject* pObj ); + virtual SdrObject* ApplyTextObj( PPTTextObj* pTextObj, SdrTextObj* pText, SdPage* pPage, + SfxStyleSheet*, SfxStyleSheet** ) const; + +public: + + String ReadSound( sal_uInt32 nSoundRef ) const; + String ReadMedia( sal_uInt32 nMediaRef ) const; + + ImplSdPPTImport( SdDrawDocument* pDoc, SvStorage& rStorage, SfxMedium& rMed, PowerPointImportParam& ); + ~ImplSdPPTImport(); + + sal_Bool Import(); +}; + +class SdPPTImport +{ + ImplSdPPTImport* pFilter; + + public: + + SdPPTImport( SdDrawDocument* pDoc, SvStream& rDocStream, SvStorage& rStorage, SfxMedium& rMed, MSFilterTracer* pTracer = NULL ); + ~SdPPTImport(); + + sal_Bool Import(); +}; + +#endif // _SD_PPTIN_HXX diff --git a/sd/source/filter/ppt/pptinanimations.cxx b/sd/source/filter/ppt/pptinanimations.cxx new file mode 100644 index 000000000000..16fc1a99dd8a --- /dev/null +++ b/sd/source/filter/ppt/pptinanimations.cxx @@ -0,0 +1,3948 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" +#include <com/sun/star/animations/XAnimationNodeSupplier.hpp> +#include <com/sun/star/animations/AnimationFill.hpp> +#include <com/sun/star/animations/AnimationRestart.hpp> +#include <com/sun/star/animations/Timing.hpp> +#include <com/sun/star/animations/Event.hpp> +#include <com/sun/star/animations/AnimationEndSync.hpp> +#include <com/sun/star/animations/EventTrigger.hpp> +#include <com/sun/star/presentation/EffectNodeType.hpp> +#include <com/sun/star/presentation/EffectPresetClass.hpp> +#include <com/sun/star/animations/AnimationNodeType.hpp> +#include <com/sun/star/animations/AnimationTransformType.hpp> +#include <com/sun/star/animations/AnimationCalcMode.hpp> +#include <com/sun/star/animations/AnimationValueType.hpp> +#include <com/sun/star/animations/AnimationAdditiveMode.hpp> +#include <com/sun/star/animations/XIterateContainer.hpp> +#include <com/sun/star/animations/XAnimateSet.hpp> +#include <com/sun/star/animations/XAudio.hpp> +#include <com/sun/star/animations/XCommand.hpp> +#include <com/sun/star/animations/XTransitionFilter.hpp> +#include <com/sun/star/animations/XAnimateColor.hpp> +#include <com/sun/star/animations/XAnimateMotion.hpp> +#include <com/sun/star/animations/XAnimateTransform.hpp> +#include <com/sun/star/animations/ValuePair.hpp> +#include <com/sun/star/animations/AnimationColorSpace.hpp> +#include <com/sun/star/presentation/ShapeAnimationSubType.hpp> +#include <com/sun/star/presentation/EffectCommands.hpp> +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/drawing/FillStyle.hpp> +#include <com/sun/star/drawing/LineStyle.hpp> +#include <com/sun/star/awt/FontWeight.hpp> +#include <com/sun/star/awt/FontUnderline.hpp> +#include <com/sun/star/awt/FontSlant.hpp> +#include <com/sun/star/container/XEnumerationAccess.hpp> +#include <com/sun/star/presentation/ParagraphTarget.hpp> +#include <com/sun/star/presentation/TextAnimationType.hpp> +#include <comphelper/processfactory.hxx> +#include <rtl/ustrbuf.hxx> +#include <rtl/math.hxx> + +#include <vcl/vclenum.hxx> +#include <svx/svdotext.hxx> +#include <editeng/outlobj.hxx> +#include <editeng/editobj.hxx> +#include <pptinanimations.hxx> +#include <pptatom.hxx> +#include "pptin.hxx" +#include <algorithm> + +using ::std::map; +using ::rtl::OUString; +using ::rtl::OUStringBuffer; +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::uno::UNO_QUERY_THROW; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::makeAny; +using ::com::sun::star::uno::Exception; +using ::com::sun::star::uno::XInterface; +using ::com::sun::star::beans::NamedValue; +using ::com::sun::star::container::XEnumerationAccess; +using ::com::sun::star::container::XEnumeration; +using ::com::sun::star::lang::XMultiServiceFactory; + +using namespace ::com::sun::star::drawing; +using namespace ::com::sun::star::animations; +using namespace ::com::sun::star::presentation; + +namespace sd +{ +extern Reference< XInterface > RandomAnimationNode_createInstance( sal_Int16 nPresetClass ); +} + +namespace ppt +{ + +const transition* transition::find( const OUString& rName ) +{ + const transition* p = gTransitions; + + while( p->mpName ) + { + if( rName.compareToAscii( p->mpName ) == 0 ) + return p; + + p++; + } + + return NULL; +} + +// ==================================================================== + + + +// ==================================================================== + +SvStream& operator>>(SvStream& rIn, AnimationNode& rNode ) +{ + rIn >> rNode.mnU1; + rIn >> rNode.mnRestart; + rIn >> rNode.mnGroupType; + rIn >> rNode.mnFill; + rIn >> rNode.mnU3; + rIn >> rNode.mnU4; + rIn >> rNode.mnDuration; + rIn >> rNode.mnNodeType; + + return rIn; +} + +// ==================================================================== + +static bool convertMeasure( OUString& rString ) +{ + bool bRet = false; + + const sal_Char* pSource[] = { "ppt_x", "ppt_y", "ppt_w", "ppt_h", NULL }; + const sal_Char* pDest[] = { "x", "y", "width", "height", NULL }; + sal_Int32 nIndex = 0; + + const sal_Char** ps = pSource; + const sal_Char** pd = pDest; + + while( *ps ) + { + const OUString aSearch( OUString::createFromAscii( *ps ) ); + while( (nIndex = rString.indexOf( aSearch, nIndex )) != -1 ) + { + sal_Int32 nLength = aSearch.getLength(); + if( nIndex && (rString.getStr()[nIndex-1] == '#' ) ) + { + nIndex--; + nLength++; + } + + const OUString aNew( OUString::createFromAscii( *pd ) ); + rString = rString.replaceAt( nIndex, nLength, aNew ); + nIndex += aNew.getLength(); + bRet = true; + } + ps++; + pd++; + } + + return bRet; +} + + +// ==================================================================== + +bool PropertySet::hasProperty( sal_Int32 nProperty ) const +{ + return maProperties.find( nProperty ) != maProperties.end(); +} + +// -------------------------------------------------------------------- + +Any PropertySet::getProperty( sal_Int32 nProperty ) const +{ + PropertySetMap_t::const_iterator aIter( maProperties.find( nProperty ) ); + if( aIter != maProperties.end() ) + return (*aIter).second; + else + return Any(); +} + +// ==================================================================== + +/** this adds an any to another any. + if rNewValue is empty, rOldValue is returned. + if rOldValue is empty, rNewValue is returned. + if rOldValue contains a value, a sequence with rOldValue and rNewValue is returned. + if rOldValue contains a sequence, a new sequence with the old sequence and rNewValue is returned. +*/ +static Any addToSequence( const Any& rOldValue, const Any& rNewValue ) +{ + if( !rNewValue.hasValue() ) + { + return rOldValue; + } + else if( !rOldValue.hasValue() ) + { + return rNewValue; + } + else + { + Sequence< Any > aNewSeq; + if( rOldValue >>= aNewSeq ) + { + sal_Int32 nSize = aNewSeq.getLength(); + aNewSeq.realloc(nSize+1); + aNewSeq[nSize] = rNewValue; + } + else + { + aNewSeq.realloc(2); + aNewSeq[0] = rOldValue; + aNewSeq[1] = rNewValue; + } + return makeAny( aNewSeq ); + } +} + +// ==================================================================== + +AnimationImporter::AnimationImporter( ImplSdPPTImport* pPPTImport, SvStream& rStCtrl ) +: mpPPTImport( pPPTImport ), mrStCtrl( rStCtrl ) +{ +} + +// -------------------------------------------------------------------- + +void AnimationImporter::import( const Reference< XDrawPage >& xPage, const DffRecordHeader& rProgTagContentHd ) +{ +#ifdef DBG_ANIM_LOG + mpFile = fopen( "c:\\output.xml", "w+" ); + //mpFile = stdout; +#endif + dump("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); + + Reference< XAnimationNodeSupplier > xNodeSupplier( xPage, UNO_QUERY ); + if( xNodeSupplier.is() ) + { + mxRootNode = xNodeSupplier->getAnimationNode(); + if( mxRootNode.is() ) + { + Reference< XAnimationNode > xParent; + + const Atom* pAtom = Atom::import( rProgTagContentHd, mrStCtrl ); + if( pAtom ) + { + importAnimationContainer( pAtom, xParent ); + } + + processAfterEffectNodes(); + } + } + +#ifdef DBG_ANIM_LOG + fclose( mpFile ); +#endif +} + +// -------------------------------------------------------------------- + +void AnimationImporter::processAfterEffectNodes() +{ + std::for_each( maAfterEffectNodes.begin(), maAfterEffectNodes.end(), sd::stl_process_after_effect_node_func ); +} + +// -------------------------------------------------------------------- + +Reference< XAnimationNode > AnimationImporter::createNode( const Atom* pAtom, const AnimationNode& rNode ) +{ + const char* pServiceName = NULL; + + switch( rNode.mnGroupType ) + { + case mso_Anim_GroupType_PAR: + if( pAtom->hasChildAtom( DFF_msofbtAnimIteration ) ) + pServiceName = "com.sun.star.animations.IterateContainer"; + else + pServiceName = "com.sun.star.animations.ParallelTimeContainer"; + break; + case mso_Anim_GroupType_SEQ: + pServiceName = "com.sun.star.animations.SequenceTimeContainer"; + break; + case mso_Anim_GroupType_NODE: + { + switch( rNode.mnNodeType ) + { + case mso_Anim_Behaviour_FILTER: +/* + pServiceName = "com.sun.star.animations.TransitionFilter"; + break; +*/ + case mso_Anim_Behaviour_ANIMATION: + if( pAtom->hasChildAtom( DFF_msofbtAnimateSet ) ) + pServiceName = "com.sun.star.animations.AnimateSet"; + else if( pAtom->hasChildAtom( DFF_msofbtAnimateColor ) ) + pServiceName = "com.sun.star.animations.AnimateColor"; + else if( pAtom->hasChildAtom( DFF_msofbtAnimateScale ) ) + pServiceName = "com.sun.star.animations.AnimateTransform"; + else if( pAtom->hasChildAtom( DFF_msofbtAnimateRotation ) ) + pServiceName = "com.sun.star.animations.AnimateTransform"; + else if( pAtom->hasChildAtom( DFF_msofbtAnimateMotion ) ) + pServiceName = "com.sun.star.animations.AnimateMotion"; + else if( pAtom->hasChildAtom( DFF_msofbtAnimateFilter ) ) + pServiceName = "com.sun.star.animations.TransitionFilter"; + else if( pAtom->hasChildAtom( DFF_msofbtAnimCommand ) ) + pServiceName = "com.sun.star.animations.Command"; + else + pServiceName = "com.sun.star.animations.Animate"; + break; + } + break; + } + case mso_Anim_GroupType_MEDIA: + pServiceName = "com.sun.star.animations.Audio"; + break; + + default: + pServiceName = "com.sun.star.animations.Animate"; + break; + } + + Reference< XAnimationNode > xNode; + if( pServiceName ) + { + const OUString aServiceName( OUString::createFromAscii(pServiceName) ); + Reference< XInterface > xFac( ::comphelper::getProcessServiceFactory()->createInstance(aServiceName) ); + xNode.set(xFac , UNO_QUERY ); + } + + DBG_ASSERT( xNode.is(), "sd::AnimationImporter::createNode(), node creation failed!" ); + return xNode; +} + +// -------------------------------------------------------------------- + +static bool is_random( const AnimationNode& rNode, const PropertySet& rSet, sal_Int32& rPresetClass ) +{ + if( rNode.mnGroupType != mso_Anim_GroupType_PAR ) + return false; + + if( !rSet.hasProperty( DFF_ANIM_PRESET_ID ) || !rSet.hasProperty( DFF_ANIM_PRESET_CLASS ) ) + return false; + + sal_Int32 nPresetId = 0; + if( !(rSet.getProperty( DFF_ANIM_PRESET_ID ) >>= nPresetId) || (nPresetId != 24) ) + return false; + + sal_Int32 nPresetClass = 0; + if( !(rSet.getProperty( DFF_ANIM_PRESET_CLASS ) >>= nPresetClass) ) + return false; + + switch( nPresetClass ) + { + case DFF_ANIM_PRESS_CLASS_ENTRANCE: rPresetClass = EffectPresetClass::ENTRANCE; return true; + case DFF_ANIM_PRESS_CLASS_EXIT: rPresetClass = EffectPresetClass::EXIT; return true; + } + return false; +} + + +void AnimationImporter::importAnimationContainer( const Atom* pAtom, const Reference< XAnimationNode >& xParent ) +{ + if( pAtom->seekToContent() ) + { + AnimationNode aNode; + const Atom* pAnimationNodeAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimNode ); + if( pAnimationNodeAtom && pAnimationNodeAtom->seekToContent() ) + mrStCtrl >> aNode; + + PropertySet aSet; + const Atom* pAnimationPropertySetAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimPropertySet ); + if( pAnimationPropertySetAtom ) + importPropertySetContainer( pAnimationPropertySetAtom, aSet ); + + Reference< XAnimationNode > xNode; + + if( xParent.is() ) + { + sal_Int32 nPresetClass; + if( is_random( aNode, aSet, nPresetClass ) ) + { + // create a random animation node with the given preset class + xNode.set( sd::RandomAnimationNode_createInstance( (sal_Int16)nPresetClass ), UNO_QUERY ); + } + + if( !xNode.is() ) + { + // create a node for the given atom + xNode = createNode( pAtom, aNode ); + } + } + else + { + // if we have no parent we fill the root node + xNode = mxRootNode; + } + + // import if we have a node and its not random + if( xNode.is() ) + { + fillNode( xNode, aNode, aSet ); + + switch( aNode.mnGroupType ) + { + case mso_Anim_GroupType_PAR: + { + dump( "<par" ); + dump( aNode ); + dump( aSet ); + importTimeContainer( pAtom, xNode ); + dump( "</par>\n" ); + + // for iteration containers, map target from childs to iteration + Reference< XIterateContainer > xIter( xNode, UNO_QUERY ); + if( xIter.is() ) + { + double fDuration = 0.0; + Any aTarget, aEmpty; + Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY ); + if( xEnumerationAccess.is() ) + { + Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY ); + if( xEnumeration.is() ) + { + while( xEnumeration->hasMoreElements() ) + { + Reference< XAnimate > xChildNode( xEnumeration->nextElement(), UNO_QUERY ); + if( xChildNode.is() ) + { + double fChildBegin = 0.0; + double fChildDuration = 0.0; + xChildNode->getBegin() >>= fChildBegin; + xChildNode->getDuration() >>= fChildDuration; + + fChildDuration += fChildBegin; + if( fChildDuration > fDuration ) + fDuration = fChildDuration; + + if( !aTarget.hasValue() ) + aTarget = xChildNode->getTarget(); + + xChildNode->setTarget( aEmpty ); + } + } + } + } + + xIter->setTarget( aTarget ); + + double fIterateInterval = xIter->getIterateInterval() * fDuration / 100; + xIter->setIterateInterval( fIterateInterval ); + } + } + break; + + case mso_Anim_GroupType_SEQ: + { + dump( "<seq" ); + dump( aNode ); + dump( aSet ); + importTimeContainer( pAtom, xNode ); + dump( "</seq>\n" ); + + if( aSet.hasProperty( DFF_ANIM_NODE_TYPE ) ) + { + sal_Int32 nPPTNodeType = 0; + if( aSet.getProperty( DFF_ANIM_NODE_TYPE ) >>= nPPTNodeType ) + { + switch(nPPTNodeType) + { + case DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE: + fixMainSequenceTiming( xNode ); + break; + case DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ: + fixInteractiveSequenceTiming( xNode ); + break; + } + } + } + } + break; + + case mso_Anim_GroupType_NODE: + { +#ifdef DBG_ANIM_LOG + if( pAtom->hasChildAtom( DFF_msofbtAnimateSet ) ) + { + dump( "<set" ); + } + else if( pAtom->hasChildAtom( DFF_msofbtAnimateColor ) ) + { + dump( "<animateColor" ); + } + else if( pAtom->hasChildAtom( DFF_msofbtAnimateScale ) ) + { + dump( "<animateScale" ); + } + else if( pAtom->hasChildAtom( DFF_msofbtAnimateRotation ) ) + { + dump( "<animateRotation" ); + } + else if( pAtom->hasChildAtom( DFF_msofbtAnimateMotion ) ) + { + dump( "<animateMotion" ); + } + else if( pAtom->hasChildAtom( DFF_msofbtAnimate ) ) + { + dump( "<animate" ); + } + else if( pAtom->hasChildAtom( DFF_msofbtAnimateFilter ) ) + { + dump( "<animateFilter" ); + } + else if( pAtom->hasChildAtom( DFF_msofbtAnimCommand ) ) + { + dump( "<command" ); + } + else + { + DBG_ERROR( "unknown node atom!" ); + dump_atom_header( pAtom, true, false ); + dump_atom( pAtom ); + dump_atom_header( pAtom, false, false ); + break; + } + dump( aNode ); + dump( aSet ); +#endif + importAnimationNodeContainer( pAtom, xNode ); + if( !convertAnimationNode( xNode, xParent ) ) + xNode = 0; + dump( "/>\n"); + + } + break; + + case mso_Anim_GroupType_MEDIA: + { + dump( "<audio" ); + dump( aNode ); + dump( aSet ); + importAudioContainer( pAtom, xNode ); + dump( "</audio>\n" ); + } + break; + + default: + DBG_ERROR( "unknown group atom!" ); + + dump_atom_header( pAtom, true, false ); + dump_atom( pAtom ); + dump_atom_header( pAtom, false, false ); + break; + + } + } + + if( xParent.is() && xNode.is() ) + { + Reference< XTimeContainer > xParentContainer( xParent, UNO_QUERY ); + DBG_ASSERT( xParentContainer.is(), "parent is no container, then why do I have a child here?" ); + if( xParentContainer.is() ) + { + xParentContainer->appendChild( xNode ); + } + } + } +} + +// -------------------------------------------------------------------- +void AnimationImporter::fixMainSequenceTiming( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ) +{ + try + { + bool bFirst = true; + Reference< XEnumerationAccess > xEA( xNode, UNO_QUERY_THROW ); + Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_QUERY_THROW ); + while( xE->hasMoreElements() ) + { + // click node + Reference< XAnimationNode > xClickNode( xE->nextElement(), UNO_QUERY ); + + Event aEvent; + aEvent.Trigger = EventTrigger::ON_NEXT; + aEvent.Repeat = 0; + xClickNode->setBegin( makeAny( aEvent ) ); + + if( bFirst ) + { + bFirst = false; + Reference< XEnumerationAccess > xEA2( xClickNode, UNO_QUERY_THROW ); + Reference< XEnumeration > xE2( xEA2->createEnumeration(), UNO_QUERY_THROW ); + if( xE2->hasMoreElements() ) + { + // with node + xE2->nextElement() >>= xEA2; + if( xEA2.is() ) + xE2.query( xEA2->createEnumeration() ); + else + xE2.clear(); + + if( xE2.is() && xE2->hasMoreElements() ) + { + Reference< XAnimationNode > xEffectNode( xE2->nextElement(), UNO_QUERY_THROW ); + const Sequence< NamedValue > aUserData( xEffectNode->getUserData() ); + const NamedValue* p = aUserData.getConstArray(); + sal_Int32 nLength = aUserData.getLength(); + while( nLength-- ) + { + if( p->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "node-type" ) ) ) + { + sal_Int16 nNodeType = 0; + p->Value >>= nNodeType; + if( nNodeType != ::com::sun::star::presentation::EffectNodeType::ON_CLICK ) + { + // first effect does not start on click, so correct + // first click nodes begin to 0s + xClickNode->setBegin( makeAny( (double)0.0 ) ); + break; + } + } + p++; + } + } + } + } + } + } + catch( Exception& e ) + { + (void)e; + DBG_ERROR("sd::AnimationImporter::fixMainSequenceTiming(), exception caught!" ); + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::fixInteractiveSequenceTiming( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ) +{ + try + { + Any aBegin( xNode->getBegin() ); + Any aEmpty; + xNode->setBegin( aEmpty ); + + Reference< XEnumerationAccess > xEA( xNode, UNO_QUERY_THROW ); + Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_QUERY_THROW ); + while( xE->hasMoreElements() ) + { + // click node + Reference< XAnimationNode > xClickNode( xE->nextElement(), UNO_QUERY ); + xClickNode->setBegin( aBegin ); + } + } + catch( Exception& e ) + { + (void)e; + DBG_ERROR("sd::AnimationImporter::fixInteractiveSequenceTiming(), exception caught!" ); + } +} + +// -------------------------------------------------------------------- + +bool AnimationImporter::convertAnimationNode( const Reference< XAnimationNode >& xNode, const Reference< XAnimationNode >& xParent ) +{ + Reference< XAnimate > xAnimate( xNode, UNO_QUERY ); + if( !xAnimate.is() ) + return true; + + if( !xAnimate->getTarget().hasValue() ) + return false; + + const sal_Int16 nNodeType = xNode->getType(); + + if( nNodeType == AnimationNodeType::TRANSITIONFILTER ) + return true; + + OUString aAttributeName( xAnimate->getAttributeName() ); + + if( (nNodeType == AnimationNodeType::SET) && aAttributeName.equalsAscii( "fill.on" ) ) + return false; + + const ImplAttributeNameConversion* p = gImplConversionList; + + MS_AttributeNames eAttribute = MS_UNKNOWN; + + if( (nNodeType == AnimationNodeType::ANIMATEMOTION) || + (nNodeType == AnimationNodeType::ANIMATETRANSFORM) ) + { + OUString aEmpty; + aAttributeName = aEmpty; + } + else + { + while( p->mpMSName ) + { + if( aAttributeName.compareToAscii( p->mpMSName ) == 0 ) + break; + + p++; + } + + DBG_ASSERT( p->mpMSName || (aAttributeName.getLength() == 0), "sd::AnimationImporter::convertAnimationNode(), unknown attribute!" ); +#ifdef DBG_ANIM_LOG + if( p->mpMSName == 0 ) dump( "<error text=\"sd::AnimationImporter::convertAnimationNode(), unknown attribute!\"/>\n" ); +#endif + + eAttribute = p->meAttribute; + + if( p->mpAPIName ) + aAttributeName = OUString::createFromAscii( p->mpAPIName ); + } + + xAnimate->setAttributeName( aAttributeName ); + + if( eAttribute != MS_UNKNOWN ) + { + Any aAny( xAnimate->getFrom() ); + if( aAny.hasValue() ) + { + if( convertAnimationValue( eAttribute, aAny ) ) + xAnimate->setFrom( aAny ); + } + + aAny = xAnimate->getBy(); + if( aAny.hasValue() ) + { + if( convertAnimationValue( eAttribute, aAny ) ) + xAnimate->setBy( aAny ); + } + + aAny = xAnimate->getTo(); + if( aAny.hasValue() ) + { + if( convertAnimationValue( eAttribute, aAny ) ) + xAnimate->setTo( aAny ); + } + + Sequence< Any > aValues( xAnimate->getValues() ); + sal_Int32 nValues = aValues.getLength(); + if( nValues ) + { + Any* p2 = aValues.getArray(); + while( nValues-- ) + convertAnimationValue( eAttribute, *p2++ ); + + xAnimate->setValues( aValues ); + } + + OUString aFormula( xAnimate->getFormula() ); + if( aFormula.getLength() ) + { + if( convertMeasure( aFormula ) ) + xAnimate->setFormula( aFormula ); + } + } + + // check for after-affect + Sequence< NamedValue > aUserData( xNode->getUserData() ); + NamedValue* pValue = aUserData.getArray(); + NamedValue* pLastValue = pValue; + sal_Int32 nLength = aUserData.getLength(), nRemoved = 0; + + sal_Bool bAfterEffect = false; + sal_Int32 nMasterRel = 0; + for( ; nLength--; pValue++ ) + { + if( pValue->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("after-effect") ) ) + { + pValue->Value >>= bAfterEffect; + nRemoved++; + } + else if( pValue->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("master-rel") ) ) + { + pValue->Value >>= nMasterRel; + nRemoved++; + } + else + { + if( nRemoved ) + *pLastValue = *pValue; + pLastValue++; + } + } + + if( nRemoved ) + { + aUserData.realloc( aUserData.getLength() - nRemoved ); + xNode->setUserData( aUserData ); + } + + // if its an after effect node, add it to the list for + // later processing + // after effect nodes are not inserted at their import + // position, so return false in this case + if( bAfterEffect ) + { + if( nMasterRel != 2 ) + { + Event aEvent; + + aEvent.Source <<= xParent; + aEvent.Trigger = EventTrigger::END_EVENT; + aEvent.Repeat = 0; + + xNode->setBegin( makeAny( aEvent ) ); + } + + // add to after effect nodes for later processing + sd::AfterEffectNode aNode( xNode, xParent, nMasterRel == 2 ); + maAfterEffectNodes.push_back( aNode ); + return false; + } + + return true; +} + +static int lcl_gethex( int nChar ) +{ + if( nChar >= '0' && nChar <= '9' ) + return nChar - '0'; + else if( nChar >= 'a' && nChar <= 'f' ) + return nChar - 'a' + 10; + else if( nChar >= 'A' && nChar <= 'F' ) + return nChar - 'A' + 10; + else + return 0; +} + +bool AnimationImporter::convertAnimationValue( MS_AttributeNames eAttribute, Any& rValue ) +{ + bool bRet = false; + switch( eAttribute ) + { + case MS_PPT_X: + case MS_PPT_Y: + case MS_PPT_W: + case MS_PPT_H: + { + OUString aString; + + if( rValue.getValueType() == ::getCppuType((const ValuePair*)0) ) + { + ValuePair aValuePair; + if( rValue >>= aValuePair ) + { + if( aValuePair.First >>= aString ) + { + if( convertMeasure( aString ) ) + { + aValuePair.First <<= aString; + bRet = true; + } + } + + if( aValuePair.Second >>= aString ) + { + if( convertMeasure( aString ) ) + { + aValuePair.Second <<= aString; + bRet = true; + } + } + } + } + else if( rValue.getValueType() == ::getCppuType((const OUString*)0) ) + { + if( rValue >>= aString ) + { + bRet = convertMeasure( aString ); + + if( bRet ) + rValue <<= aString; + } + } + } + break; + + case MS_XSHEAR: + case MS_R: + { + OUString aString; + if( rValue >>= aString ) + { + rValue <<= aString.toDouble(); + bRet = true; + } + } + break; + + case MS_STYLEROTATION: + { + if( rValue.getValueType() == ::getCppuType((const OUString*)0) ) + { + OUString aString; + rValue >>= aString; + rValue <<= (sal_Int16)aString.toDouble(); + bRet = true; + } + else if( rValue.getValueType() == ::getCppuType((const double*)0) ) + { + double fValue = 0.0; + rValue >>= fValue; + rValue <<= (sal_Int16)fValue; + bRet = true; + } + } + break; + + case MS_FILLCOLOR: + case MS_STROKECOLOR: + case MS_STYLECOLOR: + case MS_PPT_C: + { + OUString aString; + if( rValue >>= aString ) + { + if( aString.getLength() >= 7 && aString[0] == '#' ) + { + Color aColor; + aColor.SetRed( (UINT8)(lcl_gethex( aString[1] ) * 16 + lcl_gethex( aString[2] )) ); + aColor.SetGreen( (UINT8)(lcl_gethex( aString[3] ) * 16 + lcl_gethex( aString[4] )) ); + aColor.SetBlue( (UINT8)(lcl_gethex( aString[5] ) * 16 + lcl_gethex( aString[6] )) ); + rValue <<= (sal_Int32)aColor.GetColor(); + bRet = true; + } + else if( aString.matchAsciiL( "rgb(", 4, 0 ) ) + { + aString = aString.copy( 4, aString.getLength() - 5 ); + Color aColor; + sal_Int32 index = 0; + aColor.SetRed( (UINT8)aString.getToken( 0, (sal_Unicode)',', index ).toInt32() ); + aColor.SetGreen( (UINT8)aString.getToken( 0, (sal_Unicode)',', index ).toInt32() ); + aColor.SetRed( (UINT8)aString.getToken( 0, (sal_Unicode)',', index ).toInt32() ); + rValue <<= (sal_Int32)aColor.GetColor(); + bRet = true; + } + else if( aString.matchAsciiL( "hsl(", 4, 0 ) ) + { + sal_Int32 index = 0; + sal_Int32 nA = aString.getToken( 0, (sal_Unicode)',', index ).toInt32(); + sal_Int32 nB = aString.getToken( 0, (sal_Unicode)',', index ).toInt32(); + sal_Int32 nC = aString.getToken( 0, (sal_Unicode)',', index ).toInt32(); + dump( "hsl(%ld", nA ); + dump( ",%ld", nB ); + dump( ",%ld)", nC ); + Sequence< double > aHSL( 3 ); + aHSL[0] = nA * 360.0/255.0; + aHSL[1] = nB / 255.0; + aHSL[2] = nC / 255.0; + rValue <<= aHSL; + bRet = true; + } + } + } + break; + + case MS_FILLTYPE: + { + OUString aString; + if( rValue >>= aString ) + { + rValue <<= aString.equalsAscii( "solid" ) ? FillStyle_SOLID : FillStyle_NONE; + bRet = true; + } + } + break; + + case MS_STROKEON: + { + OUString aString; + if( rValue >>= aString ) + { + rValue <<= aString.equalsAscii( "true" ) ? ::com::sun::star::drawing::LineStyle_SOLID : ::com::sun::star::drawing::LineStyle_NONE; + bRet = true; + } + } + break; + + case MS_FONTWEIGHT: + { + OUString aString; + if( rValue >>= aString ) + { + rValue <<= aString.equalsAscii( "bold" ) ? com::sun::star::awt::FontWeight::BOLD : com::sun::star::awt::FontWeight::NORMAL; + bRet = true; + } + } + break; + + case MS_STYLEFONTSTYLE: + { + OUString aString; + if( rValue >>= aString ) + { + rValue <<= aString.equalsAscii( "italic" ) ? com::sun::star::awt::FontSlant_ITALIC : com::sun::star::awt::FontSlant_NONE; + bRet = true; + } + } + break; + + case MS_STYLEUNDERLINE: + { + OUString aString; + if( rValue >>= aString ) + { + rValue <<= aString.equalsAscii( "true" ) ? com::sun::star::awt::FontUnderline::SINGLE : com::sun::star::awt::FontUnderline::NONE; + bRet = true; + } + } + break; + + case MS_STYLEOPACITY: + case MS_STYLEFONTSIZE: + { + OUString aString; + if( rValue >>= aString ) + { + rValue <<= (float)aString.toDouble(); + bRet = true; + } + } + break; + + case MS_STYLEVISIBILITY: + { + OUString aString; + if( rValue >>= aString ) + { + rValue <<= aString.equalsAscii( "visible" ) ? sal_True : sal_False; + bRet = true; + } + } + break; + default: + break; + } + + return bRet; +} + +// -------------------------------------------------------------------- + +static OUString getConvertedSubType( sal_Int16 nPresetClass, sal_Int32 nPresetId, sal_Int32 nPresetSubType ) +{ + const sal_Char* pStr = 0; + + if( (nPresetClass == EffectPresetClass::ENTRANCE) || (nPresetClass == EffectPresetClass::EXIT) ) + { + // skip wheel effect + if( nPresetId != 21 ) + { + if( nPresetId == 5 ) + { + // checkerboard + switch( nPresetSubType ) + { + case 5: pStr = "downward"; break; + case 10: pStr = "across"; break; + } + } + else if( nPresetId == 17 ) + { + // stretch + if( nPresetSubType == 10 ) + pStr = "across"; + } + else if( nPresetId == 18 ) + { + // strips + switch( nPresetSubType ) + { + case 3: pStr = "right-to-top"; break; + case 6: pStr = "right-to-bottom"; break; + case 9: pStr = "left-to-top"; break; + case 12: pStr = "left-to-bottom"; break; + } + } + + if( pStr == 0 ) + { + const convert_subtype* p = gConvertArray; + + while( p->mpStrSubType ) + { + if( p->mnID == nPresetSubType ) + { + pStr = p->mpStrSubType; + break; + } + p++; + } + } + } + } + + if( pStr ) + return OUString::createFromAscii( pStr ); + else + return OUString::valueOf( nPresetSubType ); +} + +// -------------------------------------------------------------------- + +void AnimationImporter::fillNode( Reference< XAnimationNode >& xNode, const AnimationNode& rNode, const PropertySet& rSet ) +{ + sal_Bool bAfterEffect = false; + + // attribute Restart + if( rNode.mnRestart ) + { + sal_Int16 nRestart = AnimationRestart::DEFAULT; + switch( rNode.mnRestart ) + { + case 1: nRestart = AnimationRestart::ALWAYS; break; + case 2: nRestart = AnimationRestart::WHEN_NOT_ACTIVE; break; + case 3: nRestart = AnimationRestart::NEVER; break; + } + xNode->setRestart( nRestart ); + } + + // attribute Fill + if( rNode.mnFill ) + { + sal_Int16 nFill = AnimationFill::DEFAULT; + switch( rNode.mnFill ) + { + case 1: nFill = AnimationFill::REMOVE; break; + case 2: nFill = AnimationFill::FREEZE; break; + case 3: nFill = AnimationFill::HOLD; break; + case 4: nFill = AnimationFill::TRANSITION; break; + } + xNode->setFill( nFill ); + } + + // attribute Duration + if( rNode.mnDuration ) + { + Any aDuration; + if( rNode.mnDuration > 0 ) + { + aDuration <<= (double)(rNode.mnDuration / 1000.0); + } + else if( rNode.mnDuration < 0 ) + { + aDuration <<= Timing_INDEFINITE; + } + xNode->setDuration( aDuration ); + } + + // TODO: DFF_ANIM_PATH_EDIT_MODE + if( rSet.hasProperty( DFF_ANIM_PATH_EDIT_MODE ) ) + { + sal_Int32 nPathEditMode ; + if( rSet.getProperty( DFF_ANIM_PATH_EDIT_MODE ) >>= nPathEditMode ) + { + } + } + + // set user data + Sequence< NamedValue > aUserData; + + // attribute Type + if( rSet.hasProperty( DFF_ANIM_NODE_TYPE ) ) + { + sal_Int32 nPPTNodeType = 0; + if( rSet.getProperty( DFF_ANIM_NODE_TYPE ) >>= nPPTNodeType ) + { + sal_Int16 nNodeType = ::com::sun::star::presentation::EffectNodeType::DEFAULT; + switch( nPPTNodeType ) + { + case DFF_ANIM_NODE_TYPE_ON_CLICK: nNodeType = ::com::sun::star::presentation::EffectNodeType::ON_CLICK; break; + case DFF_ANIM_NODE_TYPE_WITH_PREVIOUS: nNodeType = ::com::sun::star::presentation::EffectNodeType::WITH_PREVIOUS; break; + case DFF_ANIM_NODE_TYPE_AFTER_PREVIOUS: nNodeType = ::com::sun::star::presentation::EffectNodeType::AFTER_PREVIOUS; break; + case DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE: nNodeType = ::com::sun::star::presentation::EffectNodeType::MAIN_SEQUENCE; break; + case DFF_ANIM_NODE_TYPE_TIMING_ROOT: nNodeType = ::com::sun::star::presentation::EffectNodeType::TIMING_ROOT; break; + case DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ:nNodeType = ::com::sun::star::presentation::EffectNodeType::INTERACTIVE_SEQUENCE; break; + } + + sal_Int32 nSize = aUserData.getLength(); + aUserData.realloc(nSize+1); + aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "node-type" ) ); + aUserData[nSize].Value <<= nNodeType; + } + } + + if( rSet.hasProperty( DFF_ANIM_GROUP_ID ) ) + { + sal_Int32 nGroupId; + if( rSet.getProperty( DFF_ANIM_GROUP_ID ) >>= nGroupId ) + { + sal_Int32 nSize = aUserData.getLength(); + aUserData.realloc(nSize+1); + aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "group-id" ) ); + aUserData[nSize].Value <<= nGroupId; + } + } + + sal_Int16 nEffectPresetClass = EffectPresetClass::CUSTOM; + sal_Int32 nPresetId = 0; + + if( rSet.hasProperty( DFF_ANIM_PRESET_CLASS ) ) + { + sal_Int32 nPresetClass = 0; + if ( rSet.getProperty( DFF_ANIM_PRESET_CLASS ) >>= nPresetClass ) + { + switch( nPresetClass ) + { + case DFF_ANIM_PRESS_CLASS_ENTRANCE: nEffectPresetClass = EffectPresetClass::ENTRANCE; break; + case DFF_ANIM_PRESS_CLASS_EXIT: nEffectPresetClass = EffectPresetClass::EXIT; break; + case DFF_ANIM_PRESS_CLASS_EMPHASIS: nEffectPresetClass = EffectPresetClass::EMPHASIS; break; + case DFF_ANIM_PRESS_CLASS_MOTIONPATH: nEffectPresetClass = EffectPresetClass::MOTIONPATH; break; + case DFF_ANIM_PRESS_CLASS_OLE_ACTION: nEffectPresetClass = EffectPresetClass::OLEACTION; break; + case DFF_ANIM_PRESS_CLASS_MEDIACALL: nEffectPresetClass = EffectPresetClass::MEDIACALL; break; + } + sal_Int32 nSize = aUserData.getLength(); + aUserData.realloc(nSize+1); + aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "preset-class" ) ); + aUserData[nSize].Value <<= nEffectPresetClass; + } + } + + if( rSet.hasProperty( DFF_ANIM_PRESET_ID ) ) + { + if( rSet.getProperty( DFF_ANIM_PRESET_ID ) >>= nPresetId ) + { + sal_Int32 nSize = aUserData.getLength(); + aUserData.realloc(nSize+1); + aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "preset-id" ) ); + + const preset_maping* p = gPresetMaping; + while( p->mpStrPresetId && ((p->mnPresetClass != nEffectPresetClass) || (p->mnPresetId != nPresetId )) ) + p++; + + if( p->mpStrPresetId ) + { + aUserData[nSize].Value <<= OUString::createFromAscii( p->mpStrPresetId ); + } + else + { + OUStringBuffer sBuffer; + sBuffer.appendAscii( "ppt_" ); + switch( nEffectPresetClass ) + { + case EffectPresetClass::ENTRANCE: sBuffer.appendAscii( "entrance_" ); break; + case EffectPresetClass::EXIT: sBuffer.appendAscii( "exit_" ); break; + case EffectPresetClass::EMPHASIS: sBuffer.appendAscii( "emphasis_" ); break; + case EffectPresetClass::MOTIONPATH: sBuffer.appendAscii( "motionpath_" ); break; + case EffectPresetClass::OLEACTION: sBuffer.appendAscii( "oleaction_" ); break; + case EffectPresetClass::MEDIACALL: sBuffer.appendAscii( "mediacall_" ); break; + } + sBuffer.append( nPresetId ); + + aUserData[nSize].Value <<= sBuffer.makeStringAndClear(); + } + } + } + + if( rSet.hasProperty( DFF_ANIM_PRESET_SUB_TYPE ) ) + { + sal_Int32 nPresetSubType = 0; + if( (rSet.getProperty( DFF_ANIM_PRESET_SUB_TYPE ) >>= nPresetSubType) ) + { + if( nPresetSubType ) + { + sal_Int32 nSize = aUserData.getLength(); + aUserData.realloc(nSize+1); + aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "preset-sub-type" ) ); + aUserData[nSize].Value <<= getConvertedSubType( nEffectPresetClass, nPresetId, nPresetSubType ); + } + } + } + + if( rSet.hasProperty( DFF_ANIM_AFTEREFFECT ) ) + { + if( rSet.getProperty( DFF_ANIM_AFTEREFFECT ) >>= bAfterEffect ) + { + sal_Int32 nSize = aUserData.getLength(); + aUserData.realloc(nSize+1); + aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "after-effect" ) ); + aUserData[nSize].Value <<= bAfterEffect; + } + } + + if( bAfterEffect && rSet.hasProperty( DFF_ANIM_MASTERREL ) ) + { + sal_Int32 nMasterRel = 2; + if( rSet.getProperty( DFF_ANIM_MASTERREL ) >>= nMasterRel ) + { + sal_Int32 nSize = aUserData.getLength(); + aUserData.realloc(nSize+1); + aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "master-rel" ) ); + aUserData[nSize].Value <<= nMasterRel; + } + } + + xNode->setUserData( aUserData ); + + // TODO: DFF_ANIM_ID + if( rSet.hasProperty( DFF_ANIM_ID ) ) + { + rtl::OUString aString; + rSet.getProperty( DFF_ANIM_ID ) >>= aString; + if( aString.getLength() ) + { + } + } + + // TODO: DFF_ANIM_EVENT_FILTER + if( rSet.hasProperty( DFF_ANIM_EVENT_FILTER ) ) + { + rtl::OUString aString; + rSet.getProperty( DFF_ANIM_EVENT_FILTER ) >>= aString; + if( aString.getLength() ) + { + } + } + + // DFF_ANIM_TIMEFILTER + if( rSet.hasProperty( DFF_ANIM_TIMEFILTER ) ) + { + Reference< XAnimate > xAnim( xNode, UNO_QUERY ); + if( xAnim.is() ) + { + rtl::OUString aString; + rSet.getProperty( DFF_ANIM_TIMEFILTER ) >>= aString; + if( aString.getLength() ) + { + sal_Int32 nElements = 1; // a non empty string has at least one value + + sal_Int32 fromIndex = 0; + while(true) + { + fromIndex = aString.indexOf( (sal_Unicode)';', fromIndex ); + if( fromIndex == -1 ) + break; + + fromIndex++; + nElements++; + } + + Sequence< TimeFilterPair > aTimeFilter( nElements ); + + TimeFilterPair* pValues = aTimeFilter.getArray(); + sal_Int32 nIndex = 0; + while( (nElements--) && (nIndex >= 0) ) + { + const OUString aToken( aString.getToken( 0, ';', nIndex ) ); + + sal_Int32 nPos = aToken.indexOf( ',' ); + if( nPos >= 0 ) + { + pValues->Time = aToken.copy( 0, nPos ).toDouble(); + pValues->Progress = aToken.copy( nPos+1, aToken.getLength() - nPos - 1 ).toDouble(); + } + pValues++; + } + + xAnim->setTimeFilter( aTimeFilter ); + } + } + } + +/* todo + Reference< XAudio > xAudio( xNode, UNO_QUERY ); + if( xAudio.is() ) + { + if( rSet.hasProperty( DFF_ANIM_ENDAFTERSLIDE ) ) + { + sal_Int16 nEndAfterSlide = 0; + if( rSet.getProperty( DFF_ANIM_ENDAFTERSLIDE ) >>= nEndAfterSlide ) + xAudio->setEndAfterSlide( nEndAfterSlide ); + } + + if( rSet.hasProperty( DFF_ANIM_VOLUME ) ) + { + double fVolume = 1.0; + rSet.getProperty( DFF_ANIM_VOLUME ) >>= fVolume; + xAudio->setVolume( fVolume ); + } + } +*/ + Reference< XAnimateColor > xColor( xNode, UNO_QUERY ); + if( xColor.is() ) + { + if( rSet.hasProperty( DFF_ANIM_DIRECTION ) ) + { + sal_Bool bDirection = sal_False; + if( rSet.getProperty( DFF_ANIM_DIRECTION ) >>= bDirection ) + xColor->setDirection( (sal_Bool)!bDirection ); + } + + if( rSet.hasProperty( DFF_ANIM_COLORSPACE ) ) + { + sal_Int32 nColorSpace = 0; + rSet.getProperty( DFF_ANIM_COLORSPACE ) >>= nColorSpace; + xColor->setColorInterpolation( (nColorSpace == 0) ? AnimationColorSpace::RGB : AnimationColorSpace::HSL ); + } + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importTimeContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + DBG_ASSERT( pAtom && xNode.is(), "invalid call to ppt::AnimationImporter::importTimeContainer()!"); + if( pAtom && xNode.is() ) + { + importAnimationEvents( pAtom, xNode ); + importAnimationValues( pAtom, xNode ); + importAnimationActions( pAtom, xNode ); + + dump(">\n"); + + // import sub containers + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + + while( pChildAtom ) + { + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimNode: + case DFF_msofbtAnimEvent: + case DFF_msofbtAnimValue: + case DFF_msofbtAnimAction: + case DFF_msofbtAnimPropertySet: + break; + + case DFF_msofbtAnimSubGoup : + { + if( pChildAtom->hasChildAtom( DFF_msofbtAnimCommand ) ) + { + const OUString aServiceName( OUString::createFromAscii("com.sun.star.animations.Command") ); + Reference< XAnimationNode > xChildNode( ::comphelper::getProcessServiceFactory()->createInstance(aServiceName), UNO_QUERY ); + importAnimationNodeContainer( pChildAtom, xChildNode ); + Reference< XTimeContainer > xParentContainer( xNode, UNO_QUERY ); + if( xParentContainer.is() && xChildNode.is() ) + xParentContainer->appendChild( xChildNode ); + } + else + { + importAnimationContainer( pChildAtom, xNode ); + } + } + break; + case DFF_msofbtAnimGroup : + { + importAnimationContainer( pChildAtom, xNode ); + } + break; + case DFF_msofbtAnimIteration: + { + if( pChildAtom->seekToContent() ) + { + float fInterval; + sal_Int32 nTextUnitEffect, nU1, nU2, nU3; + + mrStCtrl >> fInterval >> nTextUnitEffect >> nU1 >> nU2 >> nU3; + + Reference< XIterateContainer > xIter( xNode, UNO_QUERY ); + if( xIter.is() ) + { + sal_Int16 nIterateType = TextAnimationType::BY_PARAGRAPH; + switch( nTextUnitEffect ) + { + case 1: nIterateType = TextAnimationType::BY_WORD; break; + case 2: nIterateType = TextAnimationType::BY_LETTER; break; + } + xIter->setIterateType( nIterateType ); + xIter->setIterateInterval( (double)fInterval ); + } + + dump( "<iterate" ); + dump( " iterateType=\"%s\"", (nTextUnitEffect == 0) ? "byElement" : (nTextUnitEffect == 1) ? "byWord" : "byLetter" ); + dump( " iterateInterval=\"%g\"", fInterval ); + dump( " u1=\"%ld\"", nU1 ); + dump( " u2=\"%ld\"", nU2 ); + dump( " u3=\"%ld\"/>\n", nU3 ); + } + } + break; + + case 0xf136: + { +#ifdef DBG_ANIM_LOG + sal_uInt32 nU1, nU2; + mrStCtrl >> nU1 >> nU2; + + fprintf( mpFile, "<unknown_0xf136 nU1=\"%ld\" nU2=\"%ld\"/>\n", nU1, nU2 ); +#endif + } + break; + + default: + { + dump_atom_header( pChildAtom, true, false ); + dump_atom( pChildAtom ); + dump_atom_header( pChildAtom, false, false ); + } + break; + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + } +} + +// -------------------------------------------------------------------- + +/* todo: for now we dump sub containers into its parent container, what else to do with it? */ +void AnimationImporter::importAnimationSubContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + DBG_ASSERT( pAtom && xNode.is(), "invalid call to ppt::AnimationImporter::importTimeContainer()!"); + if( pAtom && xNode.is() ) + { + // import sub containers + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + + while( pChildAtom ) + { + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimNode: + case DFF_msofbtAnimEvent: + case DFF_msofbtAnimValue: + case DFF_msofbtAnimAction: + case DFF_msofbtAnimPropertySet: + break; + case DFF_msofbtAnimCommand: + { + const OUString aServiceName( OUString::createFromAscii("com.sun.star.animations.Command") ); + Reference< XAnimationNode > xChildNode( ::comphelper::getProcessServiceFactory()->createInstance(aServiceName), UNO_QUERY ); + importAnimationNodeContainer( pChildAtom, xChildNode ); + Reference< XTimeContainer > xParentContainer( xNode, UNO_QUERY ); + if( xParentContainer.is() && xChildNode.is() ) + xParentContainer->appendChild( xChildNode ); + } + break; + + default: + { + dump_atom_header( pChildAtom, true, false ); + dump_atom( pChildAtom ); + dump_atom_header( pChildAtom, false, false ); + } + break; + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importAnimationNodeContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + DBG_ASSERT( pAtom && xNode.is(), "invalid call to ppt::AnimationImporter::importAnimationNodeContainer()!"); + if( pAtom && xNode.is() ) + { + importAnimationEvents( pAtom, xNode ); + importAnimationValues( pAtom, xNode ); + importAnimationActions( pAtom, xNode ); + + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + + while( pChildAtom ) + { + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimNode: + case DFF_msofbtAnimEvent: + case DFF_msofbtAnimValue: + case DFF_msofbtAnimAction: + case DFF_msofbtAnimPropertySet: + break; + + case DFF_msofbtAnimateFilter: + importAnimateFilterContainer( pChildAtom, xNode ); + break; + + case DFF_msofbtAnimateSet: + importAnimateSetContainer( pChildAtom, xNode ); + break; + + case DFF_msofbtAnimate: + importAnimateContainer( pChildAtom, xNode ); + break; + + case DFF_msofbtAnimateScale: + importAnimateScaleContainer( pChildAtom, xNode ); + break; + + case DFF_msofbtAnimateColor: + importAnimateColorContainer( pChildAtom, xNode ); + break; + + case DFF_msofbtAnimateRotation: + importAnimateRotationContainer( pChildAtom, xNode ); + break; + + case DFF_msofbtAnimateMotion: + importAnimateMotionContainer( pChildAtom, xNode ); + break; + + case DFF_msofbtAnimCommand: + importCommandContainer( pChildAtom, xNode ); + break; + + default: + { + dump_atom_header( pChildAtom, true, false ); + dump_atom( pChildAtom ); + dump_atom_header( pChildAtom, false, false ); + } + break; + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importAnimateFilterContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + Reference< XTransitionFilter > xFilter( xNode, UNO_QUERY ); + + DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateFilter && xFilter.is(), "invalid call to ppt::AnimationImporter::importAnimateFilterContainer()!"); + if( pAtom && xFilter.is() ) + { + sal_uInt32 nBits = 0; + + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + + while( pChildAtom ) + { + if( !pChildAtom->isContainer() ) + { + if( !pChildAtom->seekToContent() ) + break; + } + + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimateFilterData: + { + sal_uInt32 transition; + mrStCtrl >> nBits; + mrStCtrl >> transition; + + if( nBits & 1 ) + xFilter->setMode( transition == 0 ); + + dump( " transition=\"%s\"", (transition == 0) ? "in" : "out" ); + } + break; + + case DFF_msofbtAnimAttributeValue: + { + if( (nBits & 2 ) && ( pChildAtom->getInstance() == 1 ) ) + { + Any aAny; + if ( importAttributeValue( pChildAtom, aAny ) ) + { + rtl::OUString filter; + aAny >>= filter; + + dump( " filter=\"%s\"", filter ); + + const transition* pTransition = transition::find( filter ); + if( pTransition ) + { + xFilter->setTransition( pTransition->mnType ); + xFilter->setSubtype( pTransition->mnSubType ); + xFilter->setDirection( pTransition->mbDirection ); + } + else + { + DBG_ERROR( "unknown transition!" ); + } + } + } + } + break; + + case DFF_msofbtAnimateTarget: + importAnimateAttributeTargetContainer( pChildAtom, xNode ); + break; + + default: + dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); + break; + + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importAnimateAttributeTargetContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateTarget, "invalid call to ppt::AnimationImporter::importAnimateAttributeTargetContainer()!"); + + Any aTarget; + + Reference< XAnimate > xAnimate( xNode, UNO_QUERY ); + + bool bWrongContext = false; + + if( pAtom ) + { + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + + while( pChildAtom ) + { + if( !pChildAtom->isContainer() ) + { + if( !pChildAtom->seekToContent() ) + break; + } + + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimPropertySet: + { + PropertySet aSet; + importPropertySetContainer( pChildAtom, aSet ); + if( aSet.hasProperty( DFF_ANIM_RUNTIMECONTEXT ) ) + { + OUString aContext; + if( aSet.getProperty( DFF_ANIM_RUNTIMECONTEXT ) >>= aContext ) + { + if( !aContext.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("PPT") ) ) + bWrongContext = true; + } + } + + dump( aSet ); + } + break; + + case DFF_msofbtAnimateTargetSettings: + { + if( xAnimate.is() ) + { + sal_uInt32 nBits; + sal_uInt32 nAdditive; + sal_uInt32 nAccumulate; + sal_uInt32 nTransformType; + + mrStCtrl >> nBits >> nAdditive >> nAccumulate >> nTransformType; + + // nBits %0001: additive, %0010: accumulate, %0100: attributeName, %1000: transformtype + // nAdditive 0 = base, 1 = sum, 2 = replace, 3 = multiply, 4 = none + // nAccumulate 0 = none, 1 = always + // nTransformType 0: "property" else "image" + + if( nBits & 3 ) + { + if( xAnimate.is() ) + { + if( nBits & 1 ) + { + sal_Int16 nTemp = AnimationAdditiveMode::BASE; + switch( nAdditive ) + { + case 1: nTemp = AnimationAdditiveMode::SUM; break; + case 2: nTemp = AnimationAdditiveMode::REPLACE; break; + case 3: nTemp = AnimationAdditiveMode::MULTIPLY; break; + case 4: nTemp = AnimationAdditiveMode::NONE; break; + } + xAnimate->setAdditive( nTemp ); + } + + if( nBits & 2 ) + { + xAnimate->setAccumulate( (nAccumulate == 0) ? sal_True : sal_False ); + } + } + } +#ifdef DBG_ANIM_LOG + if( nBits & 1 ) + fprintf( mpFile, " additive=\"%s\"", (nAdditive == 0) ? "base" : (nAdditive == 2) ? "replace" : (nAdditive == 1) ? "sum" : (nAdditive == 3 ) ? "multiply" : (nAdditive == 4) ? "none" : "unknown" ); + + if( nBits & 2 ) + fprintf( mpFile, " accumulate=\"%s\"", (nAccumulate == 0) ? "none" : "always" ); + + if( nBits & 8 ) + fprintf( mpFile, " transformType=\"%s\"", (nTransformType == 0) ? "property" : "image" ); +#endif + } + } + break; + + case DFF_msofbtAnimateAttributeNames: + { + if( xAnimate.is() ) + { + OUString aAttributeName; + importAttributeNamesContainer( pChildAtom, aAttributeName ); + if( xAnimate.is() ) + xAnimate->setAttributeName( aAttributeName ); + dump( " attributeName=\"%s\"", aAttributeName ); + } + } + break; + + case DFF_msofbtAnimateTargetElement: + { + sal_Int16 nSubType; + importTargetElementContainer( pChildAtom, aTarget, nSubType ); + if( xAnimate.is() ) + xAnimate->setSubItem( nSubType ); + + dump( " target=\"" ); + dump_target( aTarget ); + dump( "\"" ); + } + break; + + default: + dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); + break; + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + } + + if( bWrongContext ) + aTarget.clear(); + + if( xAnimate.is() ) + xAnimate->setTarget( aTarget ); + else + { + Reference< XCommand > xCommand( xNode, UNO_QUERY ); + if( xCommand.is() ) + xCommand->setTarget( aTarget ); + } +} + +// -------------------------------------------------------------------- + +sal_Int16 AnimationImporter::implGetColorSpace( sal_Int32 nMode, sal_Int32 /*nA*/, sal_Int32 /*nB*/, sal_Int32 /*nC*/ ) +{ + switch( nMode ) + { + case 2: // index + // FALLTHROUGH intended + default: + // FALLTHROUGH intended + case 0: // rgb + return AnimationColorSpace::RGB; + + case 1: // hsl + return AnimationColorSpace::HSL; + } +} + +// -------------------------------------------------------------------- + +Any AnimationImporter::implGetColorAny( sal_Int32 nMode, sal_Int32 nA, sal_Int32 nB, sal_Int32 nC ) +{ + switch( nMode ) + { + case 0: // rgb + { + dump( "rgb(%ld", nA ); + dump( ",%ld", nB ); + dump( ",%ld)", nC ); + Color aColor( (UINT8)nA, (UINT8)nB, (UINT8)nC ); + return makeAny( (sal_Int32)aColor.GetRGBColor() ); + } + case 1: // hsl + { + dump( "hsl(%ld", nA ); + dump( ",%ld", nB ); + dump( ",%ld)", nC ); + Sequence< double > aHSL( 3 ); + aHSL[0] = nA * 360.0/255.0; + aHSL[1] = nB / 255.0; + aHSL[2] = nC / 255.0; + return makeAny( aHSL ); + } + + case 2: // index + { + Color aColor; + mpPPTImport->GetColorFromPalette((USHORT)nA, aColor ); + dump( "index(%ld", nA ); + dump( " [%ld", (sal_Int32)aColor.GetRed() ); + dump( ",%ld", (sal_Int32)aColor.GetGreen() ); + dump( ",%ld])", (sal_Int32)aColor.GetBlue() ); + return makeAny( (sal_Int32)aColor.GetRGBColor() ); + } + + default: + { + dump( "unknown_%ld(", nMode ); + dump( "%ld", nA ); + dump( ",%ld", nB ); + dump( ",%ld)", nC ); + DBG_ERROR( "ppt::implGetColorAny(), unhandled color type" ); + + Any aAny; + return aAny; + } + } +} + +void AnimationImporter::importAnimateColorContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + Reference< XAnimateColor > xColor( xNode, UNO_QUERY ); + + DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateColor && xColor.is(), "invalid call to ppt::AnimationImporter::importAnimateColorContainer()!"); + if( pAtom && xColor.is() ) + { + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + + while( pChildAtom ) + { + if( !pChildAtom->isContainer() ) + { + if( !pChildAtom->seekToContent() ) + break; + } + + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimateColorData: + { + sal_uInt32 nBits; + sal_Int32 nByMode, nByA, nByB, nByC; + sal_Int32 nFromMode, nFromA, nFromB, nFromC; + sal_Int32 nToMode, nToA, nToB, nToC; + mrStCtrl >> nBits; + mrStCtrl >> nByMode >> nByA >> nByB >> nByC; + mrStCtrl >> nFromMode >> nFromA >> nFromB >> nFromC; + mrStCtrl >> nToMode >> nToA >> nToB >> nToC; + + if( nBits & 1 ) + { + dump( " by=\"" ); + xColor->setBy( implGetColorAny( nByMode, nByA, nByB, nByC ) ); + xColor->setColorInterpolation( implGetColorSpace( nByMode, nByA, nByB, nByC ) ); + dump( "\""); + } + + if( nBits & 2 ) + { + dump( " from=\"" ); + xColor->setFrom( implGetColorAny( nFromMode, nFromA, nFromB, nFromC ) ); + xColor->setColorInterpolation( implGetColorSpace( nFromMode, nFromA, nFromB, nFromC ) ); + dump( "\""); + } + + if( nBits & 4 ) + { + dump( " to=\"" ); + xColor->setTo( implGetColorAny( nToMode, nToA, nToB, nToC ) ); + xColor->setColorInterpolation( implGetColorSpace( nToMode, nToA, nToB, nToC ) ); + dump( "\""); + } + } + break; + + case DFF_msofbtAnimateTarget: + importAnimateAttributeTargetContainer( pChildAtom, xNode ); + break; + + default: + dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); + break; + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importAnimateSetContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + Reference< XAnimateSet > xSet( xNode, UNO_QUERY ); + + DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateSet && xSet.is(), "invalid call to ppt::AnimationImporter::importAnimateSetContainer()!"); + if( pAtom && xSet.is() ) + { + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + + while( pChildAtom ) + { + if( !pChildAtom->isContainer() ) + { + if( !pChildAtom->seekToContent() ) + break; + } + + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimateSetData: + { + sal_Int32 nU1, nU2; + mrStCtrl >> nU1 >> nU2; + + dump( " set_1=\"%ld\"", nU1 ), + dump( " set_2=\"%ld\"", nU2 ); + } + break; + + case DFF_msofbtAnimAttributeValue: + { + Any aTo; + if ( importAttributeValue( pChildAtom, aTo ) ) + { + xSet->setTo( aTo ); + + dump( " value=\"" ); + dump( aTo ); + dump( "\"" ); + } + } + break; + + case DFF_msofbtAnimateTarget: + importAnimateAttributeTargetContainer( pChildAtom, xNode ); + break; + + default: + dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); + break; + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importAnimateContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + Reference< XAnimate > xAnim( xNode, UNO_QUERY ); + + DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimate && xAnim.is(), "invalid call to ppt::AnimationImporter::importAnimateContainer()!"); + if( pAtom && xAnim.is() ) + { + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + + while( pChildAtom ) + { + if( !pChildAtom->isContainer() ) + { + if( !pChildAtom->seekToContent() ) + break; + } + + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimateData: + { + sal_uInt32 nCalcmode, nBits, nValueType; + mrStCtrl >> nCalcmode >> nBits >> nValueType; + + if( nBits & 0x08 ) + { + sal_Int16 n = (nCalcmode == 1) ? AnimationCalcMode::LINEAR : /* (nCalcmode == 2) ? AnimationCalcMode::FORMULA : */ AnimationCalcMode::DISCRETE; + xAnim->setCalcMode( n ); + dump( " calcmode=\"%s\"", (nCalcmode == 0) ? "discrete" : (nCalcmode == 1) ? "linear" : (nCalcmode == 2) ? "formula" : "unknown" ); + } + + if( nBits & 0x30 ) + { + sal_Int16 n = (nValueType == 1) ? AnimationValueType::NUMBER : (nValueType == 2 ) ? AnimationValueType::COLOR : AnimationValueType::STRING; + xAnim->setValueType( n ); + dump( " valueType=\"%s\"", (nValueType == 0) ? "string" : (nValueType == 1) ? "number" : (nValueType == 2) ? "color" : "unknown" ); + } + } + break; + + case DFF_msofbtAnimateTarget: + importAnimateAttributeTargetContainer( pChildAtom, xNode ); + break; + + case DFF_msofbtAnimKeyPoints: + importAnimateKeyPoints( pChildAtom, xNode ); + break; + + case DFF_msofbtAnimAttributeValue: + { + Any a; + if ( importAttributeValue( pChildAtom, a ) ) + { + switch( pChildAtom->getInstance() ) + { + case 1: xAnim->setBy( a ); dump( " by=\"" ); break; + case 2: xAnim->setFrom( a ); dump( " from=\"" ); break; + case 3: xAnim->setTo( a ); dump( " to=\"" ); break; + default: + dump( " unknown_value=\"" ); + } + + dump( a ); + dump( "\"" ); + } + } + break; + default: + dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); + break; + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importAnimateMotionContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + Reference< XAnimateMotion > xMotion( xNode, UNO_QUERY ); + + DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateMotion && xMotion.is(), "invalid call to ppt::AnimationImporter::importAnimateMotionContainer()!"); + if( pAtom && xMotion.is() ) + { + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + + while( pChildAtom ) + { + if( !pChildAtom->isContainer() ) + { + if( !pChildAtom->seekToContent() ) + break; + } + + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimateMotionData: + { + sal_uInt32 nBits, nOrigin; + float fByX, fByY, fFromX, fFromY, fToX, fToY; + + mrStCtrl >> nBits >> fByX >> fByY >> fFromX >> fFromY >> fToX >> fToY >> nOrigin; + +#ifdef DBG_ANIM_LOG + if( nBits & 1 ) + fprintf( mpFile, " by=\"%g,%g\"", (double)fByX, (double)fByY ); + + if( nBits & 2 ) + fprintf( mpFile, " from=\"%g,%g\"", (double)fFromX, (double)fFromY ); + + if( nBits & 4 ) + fprintf( mpFile, " to=\"%g,%g\"", (double)fToX, (double)fToY ); + + if( nBits & 8 ) + fprintf( mpFile, " origin=\"%s\"", (nOrigin == 1) ? "parent" : (nOrigin == 2) ? "layout" : "unknown" ); + +#endif + } + break; + + case DFF_msofbtAnimAttributeValue: + { + Any aPath; + if ( importAttributeValue( pChildAtom, aPath ) ) + { + rtl::OUString aStr; + if ( aPath >>= aStr ) + { + aStr = aStr.replace( 'E', ' ' ); + aStr = aStr.trim(); + aPath <<= aStr; + xMotion->setPath( aPath ); + dump( " path=\"" ); + dump( aPath ); + dump( "\"" ); + } + } + } + break; + + case DFF_msofbtAnimateTarget: + importAnimateAttributeTargetContainer( pChildAtom, xNode ); + break; + + default: + dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); + break; + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importCommandContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + Reference< XCommand > xCommand( xNode, UNO_QUERY ); + DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimCommand && xCommand.is(), "invalid call to ppt::AnimationImporter::importCommandContainer()!"); + if( pAtom && xCommand.is() ) + { + sal_Int32 nBits = 0, nType = 0; + Any aValue; + + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + + while( pChildAtom ) + { + if( !pChildAtom->isContainer() ) + { + if( !pChildAtom->seekToContent() ) + break; + } + + switch( pChildAtom->getType() ) + { + case DFF_msofbtCommandData: + { + sal_Int32 nCommandType; + // looks like U1 is a bitset, bit 1 enables the type and bit 2 enables + // a propertyvalue that follows + mrStCtrl >> nBits; + mrStCtrl >> nCommandType; + + if( nBits && 1 ) + { + dump( " type=\"%s\"", (nCommandType == 0) ? "event" : ( nCommandType == 1) ? "call" : "verb" ); + } + } + break; + + case DFF_msofbtAnimAttributeValue: + { + if ( importAttributeValue( pChildAtom, aValue ) ) + { + if( nBits && 2 ) + { + dump( " cmd=\"" ); + dump( aValue ); + dump( "\"" ); + } + } + } + break; + + case DFF_msofbtAnimateTarget: + importAnimateAttributeTargetContainer( pChildAtom, xNode ); + break; + + default: + dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); + break; + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + + if( nBits & 3 ) + { + OUString aParam; + aValue >>= aParam; + + sal_Int16 nCommand = EffectCommands::CUSTOM; + + NamedValue aParamValue; + + switch( nType ) + { + case 0: // event + case 1: // call + if( aParam.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "onstopaudio" ) ) ) + { + nCommand = EffectCommands::STOPAUDIO; + } + else if( aParam.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("play") ) ) + { + nCommand = EffectCommands::PLAY; + } + else if( aParam.compareToAscii( RTL_CONSTASCII_STRINGPARAM("playFrom") ) == 0 ) + { + const OUString aMediaTime( aParam.copy( 9, aParam.getLength() - 10 ) ); + rtl_math_ConversionStatus eStatus; + double fMediaTime = ::rtl::math::stringToDouble( aMediaTime, (sal_Unicode)('.'), (sal_Unicode)(','), &eStatus, NULL ); + if( eStatus == rtl_math_ConversionStatus_Ok ) + { + aParamValue.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("MediaTime")); + aParamValue.Value <<= fMediaTime; + } + nCommand = EffectCommands::PLAY; + } + else if( aParam.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("togglePause") ) ) + { + nCommand = EffectCommands::TOGGLEPAUSE; + } + else if( aParam.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("stop") ) ) + { + nCommand = EffectCommands::STOP; + } + break; + case 2: // verb + { + aParamValue.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("Verb")); + aParamValue.Value <<= aParam.toInt32(); + + nCommand = EffectCommands::VERB; + } + break; + } + + xCommand->setCommand( nCommand ); + if( nCommand == EffectCommands::CUSTOM ) + { + DBG_ERROR("sd::AnimationImporter::importCommandContainer(), unknown command!"); + aParamValue.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("UserDefined")); + aParamValue.Value <<= aParam; + } + + if( aParamValue.Value.hasValue() ) + { + Sequence< NamedValue > aParamSeq( &aParamValue, 1 ); + xCommand->setParameter( makeAny( aParamSeq ) ); + } + } + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importAudioContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + Reference< XAudio > xAudio( xNode, UNO_QUERY ); + DBG_ASSERT( pAtom && xAudio.is() && + ( (pAtom->getType() == DFF_msofbtAnimGroup) || + (pAtom->getType() == DFF_msofbtAnimSubGoup) ), "invalid call to ppt::AnimationImporter::importAudioContainer()!"); + if( pAtom && xAudio.is() ) + { + importAnimationEvents( pAtom, xNode ); + importAnimationValues( pAtom, xNode ); + importAnimationActions( pAtom, xNode ); + + dump(">\n"); + + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + + while( pChildAtom ) + { + if( !pChildAtom->isContainer() ) + { + if( !pChildAtom->seekToContent() ) + break; + } + + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimNode: + case DFF_msofbtAnimEvent: + case DFF_msofbtAnimValue: + case DFF_msofbtAnimAction: + case DFF_msofbtAnimPropertySet: + break; + + case DFF_msofbtAnimAttributeValue: + { + Any aValue; + if ( importAttributeValue( pChildAtom, aValue ) ) + { + dump( " value=\"" ); + dump( aValue ); + dump( "\"" ); + } + } + break; + + case DFF_msofbtAnimateTargetElement: + { + sal_Int16 nSubType; + Any aSource; + importTargetElementContainer( pChildAtom, aSource, nSubType ); + if( xAudio.is() ) + xAudio->setSource( aSource ); + } + break; + + default: + dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); + break; + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + + // TODO: What to do with them? + Any aEmpty; + xAudio->setBegin( aEmpty ); + xAudio->setEnd( aEmpty ); + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importAnimateScaleContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + Reference< XAnimateTransform > xTransform( xNode, UNO_QUERY ); + + DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateScale && xTransform.is(), "invalid call to ppt::AnimationImporter::importAnimateScaleContainer()!"); + if( pAtom && xTransform.is() ) + { + xTransform->setTransformType( AnimationTransformType::SCALE ); + + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + + while( pChildAtom ) + { + if( !pChildAtom->isContainer() ) + { + if( !pChildAtom->seekToContent() ) + break; + } + + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimateScaleData: + { + sal_uInt32 nBits, nZoomContents; + float fByX, fByY, fFromX, fFromY, fToX, fToY; + + // nBits %001: by, %010: from, %100: to, %1000: zoomContents(bool) + mrStCtrl >> nBits >> fByX >> fByY >> fFromX >> fFromY >> fToX >> fToY >> nZoomContents; + + ValuePair aPair; + // 'from' value + if( nBits & 2 ) + { + aPair.First <<= (double)fFromX / 100.0; + aPair.Second <<= (double)fFromY / 100.0; + xTransform->setFrom( makeAny( aPair ) ); + } + + // 'to' value + if( nBits & 4 ) + { + aPair.First <<= (double)fToX / 100.0; + aPair.Second <<= (double)fToY / 100.0; + xTransform->setTo( makeAny( aPair ) ); + } + + // 'by' value + if( nBits & 1 ) + { + aPair.First <<= (double)fByX / 100.0; + aPair.Second <<= (double)fByY / 100.0; + + if( nBits & 2 ) + { + // 'from' value given, import normally + xTransform->setBy( makeAny( aPair ) ); + } + else + { + // mapping 'by' to 'to', if no 'from' is + // given. This is due to a non-conformity in + // PPT, which exports animateScale effects + // with a sole 'by' value, but with the + // semantics of a sole 'to' animation + xTransform->setTo( makeAny( aPair ) ); + } + } + + +#ifdef DBG_ANIM_LOG + if( nBits & 1 ) + fprintf( mpFile, " by=\"%g,%g\"", (double)fByX, (double)fByY ); + + if( nBits & 2 ) + fprintf( mpFile, " from=\"%g,%g\"", (double)fFromX, (double)fFromY ); + + if( nBits & 4 ) + fprintf( mpFile, " to=\"%g,%g\"", (double)fToX, (double)fToY ); + + if( nBits & 8 ) + fprintf( mpFile, " zoomContents=\"%s\"", nZoomContents ? "true" : "false" ); +#endif + } + break; + + case DFF_msofbtAnimateTarget: + importAnimateAttributeTargetContainer( pChildAtom, xNode ); + break; + + default: + dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); + break; + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importAnimateRotationContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + Reference< XAnimateTransform > xTransform( xNode, UNO_QUERY ); + + DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateRotation && xTransform.is(), "invalid call to ppt::AnimationImporter::importAnimateRotationContainer()!"); + if( pAtom && xTransform.is() ) + { + xTransform->setTransformType( AnimationTransformType::ROTATE ); + + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + + while( pChildAtom ) + { + if( !pChildAtom->isContainer() ) + { + if( !pChildAtom->seekToContent() ) + break; + } + + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimateRotationData: + { + sal_uInt32 nBits, nU1; + float fBy, fFrom, fTo; + + // nBits %001: by, %010: from, %100: to, %1000: zoomContents(bool) + mrStCtrl >> nBits >> fBy >> fFrom >> fTo >> nU1; + + if( nBits & 1 ) + xTransform->setBy( makeAny( (double) fBy ) ); + + if( nBits & 2 ) + xTransform->setFrom( makeAny( (double) fFrom ) ); + + if( nBits & 4 ) + xTransform->setTo( makeAny( (double) fTo ) ); + +#ifdef DBG_ANIM_LOG + if( nBits & 1 ) + fprintf( mpFile, " by=\"%g\"", (double)fBy ); + + if( nBits & 2 ) + fprintf( mpFile, " from=\"%g\"", (double)fFrom ); + + if( nBits & 4 ) + fprintf( mpFile, " to=\"%g\"", (double)fTo ); + + if( nU1 ) + fprintf( mpFile, " rotation_1=\"%ld\"", nU1 ); +#endif + } + break; + + case DFF_msofbtAnimateTarget: + importAnimateAttributeTargetContainer( pChildAtom, xNode ); + break; + + default: + dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() ); + break; + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + } +} +// -------------------------------------------------------------------- + +bool AnimationImporter::importAttributeNamesContainer( const Atom* pAtom, OUString& rAttributeNames ) +{ + OUStringBuffer aNames; + + DBG_ASSERT( pAtom && (pAtom->getType() == DFF_msofbtAnimateAttributeNames), "invalid call to ppt::AnimationImporter::importAttributeName()!" ); + if( pAtom ) + { + const Atom* pAttributeValueAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimAttributeValue ); + + while( pAttributeValueAtom ) + { + Any aAny; + if ( importAttributeValue( pAttributeValueAtom, aAny ) ) + { + OUString aName; + if( aAny >>= aName ) + { + if( aNames.getLength() ) + aNames.append( (sal_Unicode)';' ); + + aNames.append( aName ); + } + } + else + { + DBG_ERROR( "error during ppt::AnimationImporter::importAttributeName()!" ); + } + + pAttributeValueAtom = pAtom->findNextChildAtom( DFF_msofbtAnimAttributeValue, pAttributeValueAtom ); + } + } + + rAttributeNames = aNames.makeStringAndClear(); + return true; +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importAnimationValues( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + DBG_ASSERT( pAtom, "invalid call to ppt::AnimationImporter::importAnimationValues()!" ); + + if( pAtom ) + { + const Atom* pValueAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimValue ); + + while( pValueAtom && pValueAtom->seekToContent() ) + { + sal_uInt32 nType; + mrStCtrl >> nType; + switch( nType ) + { + case 0: + { + float fRepeat; + mrStCtrl >> fRepeat; + xNode->setRepeatCount( (fRepeat < ((float)3.40282346638528860e+38)) ? makeAny( (double)fRepeat ) : makeAny( Timing_INDEFINITE ) ); + +#ifdef DBG_ANIM_LOG + if( (fRepeat < ((float)3.40282346638528860e+38)) ) + { + dump( " repeat=\"%g\"", (double)fRepeat ); + } + else + { + dump( " repeat=\"indefinite\"" ); + } +#endif + } + break; + + case 3: + { + float faccelerate; + mrStCtrl >> faccelerate; + xNode->setAcceleration( faccelerate ); + dump( " accelerate=\"%g\"", (double)faccelerate ); + } + break; + + case 4: + { + float fdecelerate; + mrStCtrl >> fdecelerate; + xNode->setDecelerate( fdecelerate ); + dump( " decelerate=\"%g\"", (double)fdecelerate ); + } + break; + + case 5: + { + sal_Int32 nAutoreverse; + mrStCtrl >> nAutoreverse; + xNode->setAutoReverse( nAutoreverse != 0 ); + dump( " autoreverse=\"%#lx\"", nAutoreverse ); + } + break; + + default: + { + sal_uInt32 nUnknown; + mrStCtrl >> nUnknown; +#ifdef DBG_ANIM_LOG + fprintf(mpFile, " attribute_%d=\"%#lx\"", nType, nUnknown ); +#endif + } + break; + } + + pValueAtom = pAtom->findNextChildAtom( DFF_msofbtAnimValue, pValueAtom ); + } + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importAnimateKeyPoints( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + Reference< XAnimate > xAnim( xNode, UNO_QUERY ); + + DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimKeyPoints && xAnim.is(), "invalid call to ppt::AnimationImporter::importAnimateKeyPoints()!" ); + + if( pAtom && xAnim.is() ) + { + // first count keytimes + const Atom* pIter = NULL; + int nKeyTimes = 0; + + while( (pIter = pAtom->findNextChildAtom( DFF_msofbtAnimKeyTime, pIter )) != 0 ) + nKeyTimes++; + + Sequence< double > aKeyTimes( nKeyTimes ); + Sequence< Any > aValues( nKeyTimes ); + OUString aFormula; + + pIter = pAtom->findFirstChildAtom(DFF_msofbtAnimKeyTime); + int nKeyTime; + sal_Int32 nTemp; + for( nKeyTime = 0; (nKeyTime < nKeyTimes) && pIter; nKeyTime++ ) + { + if( pIter->seekToContent() ) + { + mrStCtrl >> nTemp; + double fTemp = (double)nTemp / 1000.0; + aKeyTimes[nKeyTime] = fTemp; + + const Atom* pValue = pAtom->findNextChildAtom(pIter); + if( pValue && pValue->getType() == DFF_msofbtAnimAttributeValue ) + { + Any aValue1, aValue2; + if( importAttributeValue( pValue, aValue1 ) ) + { + pValue = pAtom->findNextChildAtom(pValue); + if( pValue && pValue->getType() == DFF_msofbtAnimAttributeValue ) + importAttributeValue( pValue, aValue2 ); + + bool bCouldBeFormula = false; + bool bHasValue = aValue2.hasValue(); + if( bHasValue ) + { + if( aValue2.getValueType() == ::getCppuType((const OUString*)0) ) + { + OUString aTest; + aValue2 >>= aTest; + bHasValue = aTest.getLength() != 0; + bCouldBeFormula = true; + } + } + + if( bHasValue && bCouldBeFormula && (aValue1.getValueType() == ::getCppuType((const double*)0)) ) + { + aValue2 >>= aFormula; + bHasValue = false; + } + + if( bHasValue ) + { + aValues[nKeyTime] = makeAny( ValuePair( aValue1, aValue2 ) ); + } + else + { + aValues[nKeyTime] = aValue1; + } + } + } + } + pIter = pAtom->findNextChildAtom(DFF_msofbtAnimKeyTime, pIter); + } + +#ifdef DBG_ANIM_LOG + dump( " keyTimes=\"" ); + for( int i=0; i<nKeyTimes; ++i ) + dump( "%f;", aKeyTimes[i] ); + + if( aFormula.getLength() ) + { + dump( "formula=\"%s", aFormula ); + } + + dump( "\" values=\"" ); + double nVal; + OUString aStr; + for( int i=0; i<nKeyTimes; ++i ) + { + if( i != 0 ) + dump( ";" ); + + if( aValues[i] >>= aStr ) + dump( "%s", + ::rtl::OUStringToOString( aStr, + RTL_TEXTENCODING_ASCII_US ).getStr() ); + else if( aValues[i] >>= nVal ) + dump( "%f", nVal ); + else + { + ValuePair aValuePair; + + if( aValues[i] >>= aValuePair ) + { + if( aValuePair.First >>= aStr ) + dump( "%s", + ::rtl::OUStringToOString( aStr, + RTL_TEXTENCODING_ASCII_US ).getStr() ); + else if( aValuePair.First >>= nVal ) + dump( "%f", nVal ); + else + dump( "%X", (sal_Int32)&aValuePair.First ); + + if( aValuePair.Second >>= aStr ) + dump( ",%s", + ::rtl::OUStringToOString( aStr, + RTL_TEXTENCODING_ASCII_US ).getStr() ); + else if( aValuePair.Second >>= nVal ) + dump( ",%f", nVal ); + else + dump( ",%X", (sal_Int32)&aValuePair.Second ); + } + } + } + dump( "\"" ); +#endif + + xAnim->setKeyTimes( aKeyTimes ); + xAnim->setValues( aValues ); + xAnim->setFormula( aFormula ); + } +} + +// -------------------------------------------------------------------- + +bool AnimationImporter::importAttributeValue( const Atom* pAtom, Any& rAny ) +{ + DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimAttributeValue, "invalid call to ppt::AnimationImporter::importAttributeValue()!" ); + + bool bOk = false; + + if( pAtom && pAtom->seekToContent() ) + { + sal_uInt32 nRecLen = pAtom->getLength(); + if ( nRecLen >= 1 ) + { + sal_Int8 nType; + mrStCtrl >> nType; + switch( nType ) + { + case DFF_ANIM_PROP_TYPE_BYTE : + { + if ( nRecLen == 2 ) + { + sal_uInt8 nByte; + mrStCtrl >> nByte; + rAny <<= nByte; + + bOk = true; + } + } + break; + + case DFF_ANIM_PROP_TYPE_INT32 : + { + if ( nRecLen == 5 ) + { + sal_uInt32 nInt32; + mrStCtrl >> nInt32; + rAny <<= nInt32; + + bOk = true; + } + } + break; + + case DFF_ANIM_PROP_TYPE_FLOAT: + { + if( nRecLen == 5 ) + { + float fFloat; + mrStCtrl >> fFloat; + rAny <<= (double)fFloat; + + bOk = true; + } + } + break; + + case DFF_ANIM_PROP_TYPE_UNISTRING : + { + if ( ( nRecLen & 1 ) && ( nRecLen > 1 ) ) + { + String aString; + mpPPTImport->MSDFFReadZString( mrStCtrl, aString, nRecLen - 1, sal_True ); + rtl::OUString aOUString( aString ); + rAny <<= aOUString; + + bOk = true; + } + } + break; + } + } + } + + DBG_ASSERT( bOk, "invalid value inside ppt::AnimationImporter::importAttributeValue()!" ); + return bOk; +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importAnimationEvents( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + DBG_ASSERT( xNode.is() && pAtom, "invalid call to ppt::AnimationImporter::importAnimationEvents()!" ); + + Any aBegin, aEnd, aNext, aPrev; + + const Atom* pEventAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimEvent ); + while( pEventAtom ) + { + Any* pEvents = NULL; + + switch( pEventAtom->getInstance() ) + { + case 1: pEvents = &aBegin; break; + case 2: pEvents = &aEnd; break; + case 3: pEvents = &aNext; break; + case 4: pEvents = &aPrev; break; + } + + if( pEvents ) + { + Event aEvent; + aEvent.Trigger = EventTrigger::NONE; + aEvent.Repeat = 0; + + const Atom* pChildAtom = pEventAtom->findFirstChildAtom(); + + while( pChildAtom && pChildAtom->seekToContent() ) + { + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimTrigger: + { + sal_Int32 nU1, nTrigger, nU3, nBegin; + mrStCtrl >> nU1; + mrStCtrl >> nTrigger; + mrStCtrl >> nU3; + mrStCtrl >> nBegin; + + switch( nTrigger ) + { + case 0: aEvent.Trigger = EventTrigger::NONE; break; + case 1: aEvent.Trigger = EventTrigger::ON_BEGIN; break; + case 2: aEvent.Trigger = EventTrigger::ON_END; break; + case 3: aEvent.Trigger = EventTrigger::BEGIN_EVENT; break; + case 4: aEvent.Trigger = EventTrigger::END_EVENT; break; + case 5: aEvent.Trigger = EventTrigger::ON_CLICK; break; + case 6: aEvent.Trigger = EventTrigger::ON_DBL_CLICK; break; + case 7: aEvent.Trigger = EventTrigger::ON_MOUSE_ENTER; break; + case 8: aEvent.Trigger = EventTrigger::ON_MOUSE_LEAVE; break; + case 9: aEvent.Trigger = EventTrigger::ON_NEXT; break; + case 10: aEvent.Trigger = EventTrigger::ON_PREV; break; + case 11: aEvent.Trigger = EventTrigger::ON_STOP_AUDIO; break; + } + + if( (nBegin != 0) || (aEvent.Trigger == EventTrigger::NONE) ) + aEvent.Offset = (nBegin == -1) ? makeAny( Timing_INDEFINITE ) : makeAny( (double)(nBegin / 1000.0) ); + } + break; + case DFF_msofbtAnimateTargetElement: + { + sal_Int16 nSubType; + importTargetElementContainer( pChildAtom, aEvent.Source, nSubType ); + } + break; + default: + { + DBG_ERROR("unknown atom inside ppt::AnimationImporter::importAnimationEvents()!"); + } + } + + pChildAtom = pEventAtom->findNextChildAtom( pChildAtom ); + } + + *pEvents = addToSequence( *pEvents, (aEvent.Trigger == EventTrigger::NONE) ? aEvent.Offset : makeAny( aEvent ) ); + } + + pEventAtom = pAtom->findNextChildAtom( DFF_msofbtAnimEvent, pEventAtom ); + } + + xNode->setBegin( aBegin ); + xNode->setEnd( aEnd ); + // TODO: xNode->setNext( aNext ); + // TODO: xNode->setPrev( aNext ); + +#ifdef DBG_ANIM_LOG + if( aBegin.hasValue() ) + { + dump( " begin=\"" ); + dump( aBegin ); + dump( "\"" ); + } + + if( aEnd.hasValue() ) + { + dump( " end=\"" ); + dump( aEnd ); + dump( "\"" ); + } + + if( aNext.hasValue() ) + { + dump( " next=\"" ); + dump( aNext ); + dump( "\"" ); + } + + if( aPrev.hasValue() ) + { + dump( " prev=\"" ); + dump( aPrev ); + dump( "\"" ); + } +#endif +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importAnimationActions( const Atom* pAtom, const Reference< XAnimationNode >& xNode ) +{ + DBG_ASSERT( pAtom && xNode.is(), "invalid call to ppt::AnimationImporter::importAnimationActions()!"); + + if( pAtom ) + { + const Atom* pActionAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimAction ); + + if( pActionAtom && pActionAtom->seekToContent() ) + { + sal_Int32 nConcurrent, nNextAction, nEndSync, nU4, nU5; + mrStCtrl >> nConcurrent; + mrStCtrl >> nNextAction; + mrStCtrl >> nEndSync; + mrStCtrl >> nU4; + mrStCtrl >> nU5; + + if( nEndSync == 1 ) + xNode->setEndSync( makeAny( AnimationEndSync::ALL ) ); + + #ifdef DBG_ANIM_LOG + dump( " concurrent=\"%s\"", nConcurrent == 0 ? "disabled" : (nConcurrent == 1 ? "enabled" : "unknown") ); + + dump( " nextAction=\"%s\"", nNextAction == 0 ? "none" : (nNextAction == 1 ? "seek" : "unknown") ); + + if( nEndSync != 0 ) + { + dump( " endSync=\"%s\"", nEndSync == 1 ? "all" : "unknown" ); + } + + dump( " action_4=\"%#lx\"", nU4 ); + dump( " action_5=\"%#lx\"", nU5 ); + #endif + } + } +} + +// -------------------------------------------------------------------- + +sal_Int32 AnimationImporter::importTargetElementContainer( const Atom* pAtom, Any& rTarget, sal_Int16& rSubType ) +{ + rSubType = ShapeAnimationSubType::AS_WHOLE; + sal_Int32 nRefMode = -1; + + DBG_ASSERT( pAtom && (pAtom->getType() == DFF_msofbtAnimateTargetElement), "invalid call to ppt::AnimationImporter::importTargetElementContainer()!" ); + if( pAtom ) + { + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + while( pChildAtom && pChildAtom->seekToContent() ) + { + switch( pChildAtom->getType() ) + { + case DFF_msofbtAnimReference: + { + sal_Int32 nRefType,nRefId; + sal_Int32 begin,end; + mrStCtrl >> nRefMode; + mrStCtrl >> nRefType; + mrStCtrl >> nRefId; + mrStCtrl >> begin; + mrStCtrl >> end; + + switch( nRefType ) + { + case 1: // shape + { + SdrObject* pSdrObject = mpPPTImport->getShapeForId( nRefId ); + if( pSdrObject == NULL ) + break; + + rTarget <<= pSdrObject->getUnoShape(); + + switch( nRefMode ) + { +// default case 0: rSubType = ShapeAnimationSubType::AS_WHOLE; break; + case 6: rSubType = ShapeAnimationSubType::ONLY_BACKGROUND; break; + case 8: rSubType = ShapeAnimationSubType::ONLY_TEXT; break; + case 2: // one paragraph + { + if( ((begin == -1) && (end == -1)) || !pSdrObject->ISA( SdrTextObj ) ) + break; + + SdrTextObj* pTextObj = static_cast< SdrTextObj* >( pSdrObject ); + + const OutlinerParaObject* pOPO = pTextObj->GetOutlinerParaObject(); + if( pOPO == NULL ) + break; + + const EditTextObject& rEditTextObject = pOPO->GetTextObject(); + + const USHORT nParaCount = rEditTextObject.GetParagraphCount(); + + USHORT nPara = 0; + + while( (nPara < nParaCount) && (begin > 0) ) + { + sal_Int32 nParaLength = rEditTextObject.GetText( nPara ).Len() + 1; + begin -= nParaLength; + end -= nParaLength; + nPara++; + } + + if( nPara < nParaCount ) + { + ParagraphTarget aParaTarget; + rTarget >>= aParaTarget.Shape; + aParaTarget.Paragraph = nPara; + rTarget = makeAny( aParaTarget ); + + rSubType = ShapeAnimationSubType::ONLY_TEXT; + dump( " paragraph %d,", (sal_Int32)nPara); + dump( " %d characters", (sal_Int32)end ); + } + } + } + } + break; + + case 2: // sound + { + OUString aSoundURL( ((ImplSdPPTImport*)mpPPTImport)->ReadSound( nRefId ) ); + rTarget <<= aSoundURL; + dump( " srcRef=\"%s\"", aSoundURL ); + } + break; + case 3: // audio object + case 4: // video object + { + SdrObject* pSdrObject = mpPPTImport->getShapeForId( nRefId ); + if( pSdrObject == NULL ) + break; + + rTarget <<= pSdrObject->getUnoShape(); + } + break; + default: + DBG_ERROR("unknown reference type"); + } + + +// dump( " ref=\"%s\"", nRefMode == 3 ? "source" : ( nRefMode == 0 ? "target" : "unknown" ) ); +// dump( " type=\"%s\"", nRefType == 1 ? "shape" : ( nRefType == 2 ? "sound": "unknown" ) ); +// dump( " id=\"%lu\"", (sal_Int32)nRefId ); +#ifdef DBG_ANIM_LOG + if((begin != -1) || (end != -1) ) + { +// dump( " text_begin=\"%ld\"", begin ); +// dump( " text_end=\"%ld\"", end ); + } +#endif + } + break; + case 0x2b01: + { + sal_Int32 nU1; + mrStCtrl >> nU1; + + // HINT: nU1 == 1 : target document. ? +// dump( " unknown_0x2b01=\"%#lx\"", nU1 ); + } + break; + default: + DBG_ERROR("unknwon atom inside ppt::AnimationImporter::importTargetElementContainer()!"); + break; + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + + } + } + + return nRefMode; +} + +// -------------------------------------------------------------------- + +void AnimationImporter::importPropertySetContainer( const Atom* pAtom, PropertySet& rSet ) +{ + DBG_ASSERT( pAtom && (pAtom->getType() == DFF_msofbtAnimPropertySet), "invalid call to ppt::AnimationImporter::importPropertySetContainer()!" ); + + if( pAtom ) + { + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + while( pChildAtom ) + { + if( pChildAtom->getType() == DFF_msofbtAnimAttributeValue ) + { + Any aAny; + importAttributeValue( pChildAtom, aAny ); + rSet.maProperties[ pChildAtom->getInstance() ] = aAny; + } + else + { + DBG_ERROR("unknwon atom inside ppt::AnimationImporter::importPropertySetContainer()!"); + } + + pChildAtom = pAtom->findNextChildAtom( pChildAtom ); + } + } +} + +// ==================================================================== + +#ifdef DBG_ANIM_LOG +void AnimationImporter::dump_atom_header( const Atom* pAtom, bool bOpen, bool bAppend ) +{ + if( pAtom ) + { + const char* pTitle; + + bool bUnknown = false; + + switch( pAtom->getType() ) + { + case DFF_msofbtAnimEvent: pTitle = "AnimEvent"; break; + case DFF_msofbtAnimTrigger: pTitle = "AnimTrigger"; break; + case DFF_msofbtAnimateMotion: pTitle = "AnimateMotion"; break; + case DFF_msofbtAnimPropertySet: pTitle = "AnimPropertySet"; break; + case DFF_msofbtAnimateAttributeNames: pTitle = "AnimAttributeName"; break; + case DFF_msofbtAnimAttributeValue: pTitle = "AnimAttributeValue"; break; + case DFF_msofbtAnimGroup: pTitle = "AnimGroup"; break; + case DFF_msofbtAnimNode: pTitle = "AnimNode"; break; + case DFF_msofbtAnimValue: pTitle = "AnimValue"; break; + case DFF_msofbtAnimateFilter: pTitle = "animateFilter"; break; + case DFF_msofbtAnimate: pTitle = "animate"; break; + case DFF_msofbtAnimateSet: pTitle = "set"; break; + case DFF_msofbtAnimKeyTime: pTitle = "AnimKeyTime"; break; + case DFF_msofbtAnimKeyPoints: pTitle = "AnimKeyPoints"; break; + case DFF_msofbtAnimReference: pTitle = "AnimReference"; break; + case DFF_msofbtAnimateTargetElement: pTitle = "AnimTargetElementContainer"; break; + case DFF_msofbtAnimAction: pTitle = "AnimAction"; break; + case DFF_msofbtAnimCommand: pTitle = "AnimCommand"; break; + case DFF_msofbtAnimateTarget: pTitle = "TransformationTarget"; break; + case DFF_msofbtAnimateTargetSettings: pTitle = "TransformationTargetSettings"; break; + case DFF_msofbtAnimIteration: pTitle = "iterate"; break; + case DFF_msofbtAnimateColorData: pTitle = "colorData"; break; + case DFF_msofbtAnimateScaleData: pTitle = "scaleData"; break; + case DFF_msofbtAnimateSetData: pTitle = "setData"; break; + + default: + { + static char buffer[128]; + sprintf( buffer, "unknown_%#x", pAtom->getType() ); + pTitle = buffer; + } + } + + if( bOpen ) + { + fprintf(mpFile, "<%s", pTitle ); + + fprintf(mpFile, " instance=\"%hu\"%s", + pAtom->getInstance(), + bAppend ? "" : ">\n"); + } + else + { + if( bAppend ) + fprintf(mpFile,"/>\n"); + else + fprintf(mpFile, "</%s>\n", pTitle ); + } + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::dump( UINT32 nLen, bool bNewLine ) +{ + char * faul = "0123456789abcdef"; + + UINT32 i = 0; + int b = 0; + sal_Int8 nData; + + for( i = 0; i < nLen; i++ ) + { + mrStCtrl >> nData; + + fprintf( mpFile, "%c%c ", faul[ (nData >> 4) & 0x0f ], faul[ nData & 0x0f ] ); + + b++; + if( bNewLine && (b == 32) ) + { + fprintf(mpFile,"\n"); + b = 0; + } + } + if( (b != 0) && bNewLine ) + fprintf(mpFile,"\n"); +} + +// -------------------------------------------------------------------- + +void AnimationImporter::dump_atom( const Atom* pAtom, bool bNewLine ) +{ + if( pAtom ) + { + if( pAtom->isContainer() ) + { + const Atom* pChildAtom = pAtom->findFirstChildAtom(); + while( pChildAtom ) + { + if( pChildAtom->getType() == DFF_msofbtAnimAttributeValue ) + { + fprintf(mpFile, "<attributeValue instance=\"%hu\"", pChildAtom->getInstance() ); + + Any aValue; + if( importAttributeValue( pChildAtom, aValue ) ) + { + sal_Int32 nInt; + rtl::OUString aString; + double fDouble; + + if( aValue >>= nInt ) + { + fprintf(mpFile, " value=\"%ld\"", nInt ); + } + else if( aValue >>= aString ) + { + UniString aTmp( aString ); + ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 ); + fprintf(mpFile, " value=\"%s\"", aStr.GetBuffer() ); + } + else if( aValue >>= fDouble ) + { + fprintf(mpFile, " value=\"%g\"", fDouble ); + } + } + else + { + if( pChildAtom->seekToContent() ) + { + fprintf(mpFile, " value=\"" ); + dump_atom( pChildAtom, false ); + fprintf(mpFile, "\""); + } + } + + fprintf(mpFile, "/>\n" ); + } + else + { + dump_atom_header( pChildAtom, true, pChildAtom->getType() == DFF_msofbtAnimAttributeValue ); + dump_atom( pChildAtom ); + dump_atom_header( pChildAtom, false, pChildAtom->getType() == DFF_msofbtAnimAttributeValue ); + } + + pChildAtom = pAtom->findNextChildAtom(pChildAtom); + } + } + else if( pAtom->seekToContent() ) + { + dump( pAtom->getLength(), bNewLine ); + } + } +} + +// -------------------------------------------------------------------- + +void AnimationImporter::dump_anim_group( const Atom* pAtom, const AnimationNode& rNode, const PropertySet& rSet, bool bOpen ) +{ + fprintf( mpFile, bOpen ? "<" : "</" ); + + switch( rNode.mnGroupType ) + { + case mso_Anim_GroupType_PAR: + fprintf( mpFile, "par" ); + break; + case mso_Anim_GroupType_SEQ: + fprintf( mpFile, "seq" ); + break; + case mso_Anim_GroupType_NODE: + switch( rNode.mnNodeType ) + { + case mso_Anim_Behaviour_FILTER: + fprintf( mpFile, "animateFilter" ); + break; + case mso_Anim_Behaviour_ANIMATION: + if( pAtom->hasChildAtom( DFF_msofbtAnimateSet ) ) + fprintf( mpFile, "set" ); + else if( pAtom->hasChildAtom( DFF_msofbtAnimateColor ) ) + fprintf( mpFile, "animateColor" ); + else if( pAtom->hasChildAtom( DFF_msofbtAnimateScale ) ) + fprintf( mpFile, "animateScale" ); + else if( pAtom->hasChildAtom( DFF_msofbtAnimateRotation ) ) + fprintf( mpFile, "animateRotation" ); + else if( pAtom->hasChildAtom( DFF_msofbtAnimateMotion ) ) + fprintf( mpFile, "animateMotion" ); + else if( pAtom->hasChildAtom( DFF_msofbtAnimCommand ) ) + fprintf( mpFile, "command" ); + else + fprintf( mpFile, "animation" ); + break; + default: + { + fprintf( mpFile, "unknown_node_%#lx", rNode.mnNodeType ); + } + break; + } + break; + case mso_Anim_GroupType_MEDIA: + fprintf( mpFile, "media" ); + break; + default: + fprintf( mpFile, "unknown_group_%#lx", rNode.mnGroupType ); + break; + } + + if( bOpen ) + { + dump( rNode ); + dump( rSet ); + } + + fprintf(mpFile,">\n"); +} + +void AnimationImporter::dump( const AnimationNode& rNode ) +{ + // dump animation node + if( rNode.mnRestart != 0 ) + { + fprintf(mpFile," restart=\"%s\"", + rNode.mnRestart == 1 ? "always" : (rNode.mnRestart == 2 ? "whenOff" : (rNode.mnRestart == 3 ? "never" : "unknown")) ); + } + + if( rNode.mnFill ) + { + fprintf(mpFile," fill=\"%s\"", + rNode.mnFill == 1 ? "remove" : (rNode.mnFill == 3 ? "hold" : (rNode.mnFill == 2 ? "freeze" : "unknown")) ); + } + + if( rNode.mnDuration > 0 ) + { + double fSeconds = rNode.mnDuration; + fSeconds /= 1000.0; + fprintf(mpFile, " dur=\"%g\"", fSeconds); + } + else if( rNode.mnDuration < 0 ) + { + fprintf(mpFile, " dur=\"indefinite\"" ); + } + + if( rNode.mnU1 ) fprintf(mpFile," u1=\"%#lx\"", rNode.mnU1); + if( rNode.mnU3 ) fprintf(mpFile," u3=\"%#lx\"", rNode.mnU3); + if( rNode.mnU4 ) fprintf(mpFile," u4=\"%#lx\"", rNode.mnU4); +} + +void AnimationImporter::dump( Any& rAny ) +{ + Sequence< Any > aSeq; + sal_Int32 nInt; + double fDouble; + OUString aString; + sal_Bool bBool; + Event aEvent; + Timing aTiming; + + if( rAny >>= aSeq ) + { + const sal_Int32 nSize = aSeq.getLength(); + sal_Int32 nIndex = 0; + while( nIndex < nSize ) + { + dump( aSeq[nIndex++] ); + if(nIndex < nSize) + fprintf( mpFile, "," ); + } + } + else if( rAny >>= aString ) + { + UniString aTmp(aString); + ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 ); + fprintf( mpFile, "%s", aStr.GetBuffer() ); + } + else if( rAny >>= nInt ) + { + fprintf( mpFile, "%ld", nInt ); + } + else if( rAny >>= bBool ) + { + fprintf( mpFile, "%s", bBool ? "true" : "false" ); + } + else if( rAny >>= fDouble ) + { + fprintf( mpFile, "%g", fDouble ); + } + else if( rAny >>= aTiming ) + { + fprintf( mpFile, "%s", aTiming == (Timing_INDEFINITE) ? "indefinite" : "media" ); + } + else if( rAny >>= aEvent ) + { + static const char* triggers[] = + { + "none","onbegin","onend","begin", + "end","onclick","ondoubleclick","onmouseenter", + "onmouseleave","onpptnext","onpptprev","onstopaudio" + }; + + if( aEvent.Trigger != EventTrigger::NONE ) + { + if( aEvent.Source.hasValue() ) + { + dump_target( aEvent.Source ); + dump( "." ); + } + + dump( triggers[ aEvent.Trigger ] ); + } + + if( aEvent.Offset.hasValue() ) + { + double fOffset; + if( aEvent.Offset >>= fOffset ) + fprintf( mpFile, "%g", fOffset ); + else + dump( "indefinite" ); + } + } +} + +void AnimationImporter::dump( const PropertySet& rSet ) +{ + // dump property set + + map< sal_Int32, Any >::const_iterator aIter( rSet.maProperties.begin() ); + const map< sal_Int32, Any >::const_iterator aEnd( rSet.maProperties.end() ); + while( aIter != aEnd ) + { + bool bKnown = false; + + const sal_Int32 nInstance = (*aIter).first; + Any aAny( (*aIter).second ); + + switch ( nInstance ) + { + case DFF_ANIM_COLORSPACE: + { + sal_Int32 nColorSpace; + if( aAny >>= nColorSpace ) + { + fprintf( mpFile, " colorSpace=\"%s\"", (nColorSpace == 0) ? "rgb" : (nColorSpace == 1) ? "hsl" : "unknown" ); + bKnown = true; + } + } + break; + + case DFF_ANIM_DIRECTION: +// case DFF_ANIM_MASTERREL: + { + sal_Bool bDirection; + if( aAny >>= bDirection ) + { + fprintf( mpFile, " direction=\"%s\"", bDirection ? "cclockwise" : "clockwise" ); + bKnown = true; + } + else + { + sal_Int32 nMasterRel; + if( aAny >>= nMasterRel ) + { + fprintf( mpFile, " direction=\"%s\"", nMasterRel == 0 ? "sameClick" : ( nMasterRel == 2 ? "nextClick" : "lastClick" ) ); + bKnown = true; + } + } + } + break; + + case DFF_ANIM_OVERRIDE: // TODO + { + sal_Int32 nOverride; + if( aAny >>= nOverride ) + { + fprintf( mpFile, " override=\"%s\"", (nOverride == 1) ? "childStyle" : (nOverride == 0) ? "normal" : "unknown" ); + bKnown = true; + } + } + break; + + case DFF_ANIM_PATH_EDIT_MODE: + { + sal_Bool bPathEditMode; + if( aAny >>= bPathEditMode ) + { + fprintf( mpFile, " pptPathEditMode=\"%s\"", bPathEditMode ? "relative" : "fixed" ); + bKnown = true; + } + } + break; + + case DFF_ANIM_PRESET_ID : + { + sal_Int32 nPresetId ; + if( aAny >>= nPresetId ) + { + fprintf(mpFile, " presetid=\"%ld\"", nPresetId ); + bKnown = true; + } + } + break; + + case DFF_ANIM_PRESET_SUB_TYPE : + { + sal_Int32 nPointsType ; + if( aAny >>= nPointsType ) + { + fprintf(mpFile, " presetSubType=\"%ld\"", nPointsType ); + bKnown = true; + } + } + break; + + case DFF_ANIM_PRESET_CLASS : + { + sal_Int32 nPresetClass; + if ( aAny >>= nPresetClass ) + { + const char* pMode; + switch( nPresetClass ) + { + case DFF_ANIM_PRESS_CLASS_USER_DEFINED: pMode = "userdefined"; break; + case DFF_ANIM_PRESS_CLASS_ENTRANCE: pMode = "entrance"; break; + case DFF_ANIM_PRESS_CLASS_EXIT: pMode = "exit"; break; + case DFF_ANIM_PRESS_CLASS_EMPHASIS: pMode = "emphasis"; break; + case DFF_ANIM_PRESS_CLASS_MOTIONPATH: pMode = "motionpath"; break; + case DFF_ANIM_PRESS_CLASS_OLE_ACTION: pMode = "oleaction"; break; + case DFF_ANIM_PRESS_CLASS_MEDIACALL: pMode = "mediacall"; break; + default: + { + static char buffer[128]; + sprintf( buffer, "%ld", nPresetClass ); + pMode = buffer; + } + break; + } + + fprintf(mpFile, " class=\"%s\"", pMode); + bKnown = true; + } + } + break; + + case DFF_ANIM_NODE_TYPE : + { + sal_Int32 nNodeType; + if ( aAny >>= nNodeType ) + { + const char* pNode; + switch( nNodeType ) + { + case DFF_ANIM_NODE_TYPE_ON_CLICK: pNode = "onclick"; break; + case DFF_ANIM_NODE_TYPE_WITH_PREVIOUS: pNode = "withprevious"; break; + case DFF_ANIM_NODE_TYPE_AFTER_PREVIOUS: pNode = "afterprevious"; break; + case DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE: pNode = "mainsequence"; break; + case DFF_ANIM_NODE_TYPE_TIMING_ROOT: pNode = "timingroot"; break; + case DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ:pNode = "interactivesequence"; break; + default : + { + static char buffer[128]; + sprintf( buffer, "%ld", nNodeType ); + pNode = buffer; + } + break; + } + + fprintf(mpFile, " nodeType=\"%s\"", pNode); + bKnown = true; + } + } + break; + + case DFF_ANIM_GROUP_ID: + { + sal_Int32 nGroupId; + if ( aAny >>= nGroupId ) + { + fprintf( mpFile, " groupId=\"%ld\"", nGroupId ); + bKnown = true; + } + } + break; + + case DFF_ANIM_ID: + { + rtl::OUString aString; + if( aAny >>= aString ) + { + UniString aTmp(aString); + ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 ); + fprintf( mpFile, " id=\"%s\"", aStr.GetBuffer() ); + bKnown = true; + } + } + break; + + case DFF_ANIM_EVENT_FILTER: + { + rtl::OUString aString; + if( aAny >>= aString ) + { + UniString aTmp(aString); + ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 ); + fprintf( mpFile, " eventFilter=\"%s\"", aStr.GetBuffer() ); + bKnown = true; + } + } + break; + + case DFF_ANIM_ENDAFTERSLIDE: + { + sal_Int32 nEndAfterSlide; + if( aAny >>= nEndAfterSlide ) + { + fprintf(mpFile, " endAfterSlide=\"%ld\"", nEndAfterSlide ); + bKnown = true; + } + } + + case DFF_ANIM_TIMEFILTER: + { + rtl::OUString aString; + if( aAny >>= aString ) + { + UniString aTmp(aString); + ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 ); + fprintf( mpFile, " timeFilter=\"%s\"", aStr.GetBuffer() ); + bKnown = true; + } + } + break; + + case DFF_ANIM_RUNTIMECONTEXT: + { + rtl::OUString aString; + if( aAny >>= aString ) + { + UniString aTmp(aString); + ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 ); + fprintf( mpFile, " runtimeContext=\"%s\"", aStr.GetBuffer() ); + bKnown = true; + } + } + break; + + case DFF_ANIM_VOLUME: + { + double fVolume; + if( aAny >>= fVolume ) + { + fprintf( mpFile, " volume=\"%g%%\"", (double)(fVolume * 100.0) ); + bKnown = true; + } + } + break; + + case DFF_ANIM_AFTEREFFECT: + { + sal_Bool bAfterEffect; + if( aAny >>= bAfterEffect ) + { + fprintf( mpFile, "afterEffect=\"%s\"", bAfterEffect ? "true" : "false" ); + bKnown = true; + } + } + break; + + } + + + if( !bKnown ) + { + fprintf( mpFile, " unknown_%lu=\"", nInstance ); + dump( aAny ); + fprintf( mpFile, "\"" ); + } + + aIter++; + } +} + +void AnimationImporter::dump_target( Any& rAny ) +{ + Any aSource, aSourceData; + Sequence< Any > aSeq; + if( rAny >>= aSeq ) + { + if( aSeq.getLength() >= 1 ) aSource = aSeq[0]; + if( aSeq.getLength() >= 2 ) aSourceData = aSeq[1]; + } + else + { + aSource = rAny; + } + + Reference< XShape > xShape; + aSource >>= xShape; + if( xShape.is() ) + { + OUString aStr( xShape->getShapeType() ); + dump( aStr ); + + if( aSourceData.hasValue() ) + { + dump( "(" ); + dump( aSourceData ); + dump( ")" ); + } + } +} + +void AnimationImporter::dump( const char * pText ) +{ + fprintf( mpFile, "%s", pText ); +} + +void AnimationImporter::dump( const rtl::OUString& rString ) +{ + UniString aTmp( rString ); + ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 ); + fprintf( mpFile, aStr.GetBuffer() ); +} + +void AnimationImporter::dump( const char * pText, sal_Int32 nInt ) +{ + fprintf( mpFile, pText, nInt ); +} + +void AnimationImporter::dump( const char * pText, double fDouble ) +{ + fprintf( mpFile, pText, fDouble ); +} + +void AnimationImporter::dump( const char * pText, const char * pText2 ) +{ + fprintf( mpFile, pText, pText2 ); +} + +void AnimationImporter::dump( const char * pText, const OUString& rString ) +{ + UniString aTmp( rString ); + ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 ); + fprintf( mpFile, pText, aStr.GetBuffer() ); +} + +#else + +void AnimationImporter::dump_atom_header( const Atom* , bool , bool ) +{ +} + +void AnimationImporter::dump_atom( const Atom* , bool ) +{ +} + +void AnimationImporter::dump( sal_uInt32 , bool ) +{ +} + +void AnimationImporter::dump_anim_group( const Atom* , const AnimationNode& , const PropertySet& , bool ) +{ +} + +void AnimationImporter::dump_target( ::com::sun::star::uno::Any& ) +{ +} + +void AnimationImporter::dump( ::com::sun::star::uno::Any& ) +{ +} + +void AnimationImporter::dump( const PropertySet& ) +{ +} + +void AnimationImporter::dump( const AnimationNode& ) +{ +} + +void AnimationImporter::dump( const char * ) +{ +} + +void AnimationImporter::dump( const rtl::OUString& ) +{ +} + +void AnimationImporter::dump( const char * , sal_Int32 ) +{ +} + +void AnimationImporter::dump( const char * , double ) +{ +} + +void AnimationImporter::dump( const char * , const char * ) +{ +} + +void AnimationImporter::dump( const char * , const rtl::OUString& ) +{ +} + +#endif + +} // namespace ppt; + diff --git a/sd/source/filter/ppt/pptinanimations.hxx b/sd/source/filter/ppt/pptinanimations.hxx new file mode 100644 index 000000000000..d29449361861 --- /dev/null +++ b/sd/source/filter/ppt/pptinanimations.hxx @@ -0,0 +1,132 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SD_PPT_INANIMATIONS_HXX +#define _SD_PPT_INANIMATIONS_HXX + +#include <com/sun/star/animations/XTimeContainer.hpp> +#include <com/sun/star/drawing/XDrawPage.hpp> + +#include "pptanimations.hxx" +#include <animations.hxx> + +#ifdef DBG_ANIM_LOG +#include <stdio.h> +#endif +#include <filter/msfilter/svdfppt.hxx> + +#include <list> + +class DffRecordHeader; +class SdPage; +class SvStream; +class ImplSdPPTImport; + +namespace ppt +{ +class PropertySet; +class Atom; + +class AnimationImporter +{ +public: + AnimationImporter( ImplSdPPTImport* pPPTImport, SvStream& rStCtrl ); + + void import( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage >& xPage, const DffRecordHeader& rProgTagContentHd ); + +private: + void importAnimationContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xParent ); + void importTimeContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importAnimationNodeContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importAnimationSubContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + + void importAnimateSetContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importAnimateFilterContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importAnimateContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importAnimateScaleContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importAnimateColorContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importAnimateRotationContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importAnimateMotionContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importCommandContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importAudioContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + + void importAnimationEvents( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importAnimationValues( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importAnimationActions( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importAnimateAttributeTargetContainer( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + + void importAnimateKeyPoints( const Atom* pAtom, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void importPropertySetContainer( const Atom* pAtom,PropertySet& rSet ); + bool importAttributeValue( const Atom* pAtom, com::sun::star::uno::Any& rAny ); + bool importAttributeNamesContainer( const Atom* pAtom, rtl::OUString& rAttributeNames ); + sal_Int32 importTargetElementContainer( const Atom* pAtom, ::com::sun::star::uno::Any& rTarget, sal_Int16& nSubType ); + + void fillNode( ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xTiming, const AnimationNode& rNode, const PropertySet& rSet ); + ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode > createNode( const Atom* pAtom, const AnimationNode& rNode ); + + bool convertAnimationNode( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode, const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xParent ); + bool convertAnimationValue( MS_AttributeNames eAttribute, com::sun::star::uno::Any& rValue ); + + void fixMainSequenceTiming( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + void fixInteractiveSequenceTiming( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode ); + + void processAfterEffectNodes(); + + ::com::sun::star::uno::Any implGetColorAny( sal_Int32 nMode, sal_Int32 nA, sal_Int32 nB, sal_Int32 nC ); + sal_Int16 implGetColorSpace( sal_Int32 nMode, sal_Int32 nA, sal_Int32 nB, sal_Int32 nC ); + +private: + ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode > mxRootNode; + + ImplSdPPTImport* mpPPTImport; + SvStream& mrStCtrl; + + sd::AfterEffectNodeList maAfterEffectNodes; + +#ifdef DBG_ANIM_LOG + FILE * mpFile; +#endif + + void dump_atom_header( const Atom* pAtom, bool bOpen, bool bAppend ); + void dump_atom( const Atom* pAtom, bool bNewLine = true ); + void dump( sal_uInt32 nLen, bool bNewLine = true ); + void dump_anim_group( const Atom* pAtom, const AnimationNode& rNode, const PropertySet& rSet, bool bOpen ); + void dump_target( ::com::sun::star::uno::Any& rAny ); + void dump( ::com::sun::star::uno::Any& rAny ); + void dump( const PropertySet& rSet ); + void dump( const AnimationNode& rNode ); + void dump( const char * pText ); + void dump( const rtl::OUString& rString ); + void dump( const char * pText, sal_Int32 nInt ); + void dump( const char * pText, double fDouble ); + void dump( const char * pText, const char * pText2 ); + void dump( const char * pText, const rtl::OUString& rString ); +}; + +} // namespace ppt + +#endif diff --git a/sd/source/filter/ppt/propread.cxx b/sd/source/filter/ppt/propread.cxx new file mode 100644 index 000000000000..54acab192cb5 --- /dev/null +++ b/sd/source/filter/ppt/propread.cxx @@ -0,0 +1,695 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" +#include <propread.hxx> +#include <tools/bigint.hxx> +#include "rtl/tencinfo.h" +#include "rtl/textenc.h" + +// ------------------------------------------------------------------------ + +struct PropEntry +{ + sal_uInt32 mnId; + sal_uInt32 mnSize; + sal_uInt16 mnTextEnc; + sal_uInt8* mpBuf; + + PropEntry( sal_uInt32 nId, const sal_uInt8* pBuf, sal_uInt32 nBufSize, sal_uInt16 nTextEnc ); + PropEntry( const PropEntry& rProp ); + ~PropEntry() { delete[] mpBuf; } ; + + const PropEntry& operator=(const PropEntry& rPropEntry); +}; + +PropEntry::PropEntry( sal_uInt32 nId, const sal_uInt8* pBuf, sal_uInt32 nBufSize, sal_uInt16 nTextEnc ) : + mnId ( nId ), + mnSize ( nBufSize ), + mnTextEnc ( nTextEnc ), + mpBuf ( new sal_uInt8[ nBufSize ] ) +{ + memcpy( (void*)mpBuf, (void*)pBuf, nBufSize ); +}; + +PropEntry::PropEntry( const PropEntry& rProp ) : + mnId ( rProp.mnId ), + mnSize ( rProp.mnSize ), + mnTextEnc ( rProp.mnTextEnc ), + mpBuf ( new sal_uInt8[ mnSize ] ) +{ + memcpy( (void*)mpBuf, (void*)rProp.mpBuf, mnSize ); +}; + +const PropEntry& PropEntry::operator=(const PropEntry& rPropEntry) +{ + if ( this != &rPropEntry ) + { + delete[] mpBuf; + mnId = rPropEntry.mnId; + mnSize = rPropEntry.mnSize; + mnTextEnc = rPropEntry.mnTextEnc; + mpBuf = new sal_uInt8[ mnSize ]; + memcpy( (void*)mpBuf, (void*)rPropEntry.mpBuf, mnSize ); + } + return *this; +} + +// ----------------------------------------------------------------------- + +void PropItem::Clear() +{ + Seek( STREAM_SEEK_TO_BEGIN ); + delete[] (sal_uInt8*)SwitchBuffer(); +} + +// ----------------------------------------------------------------------- + +BOOL PropItem::Read( String& rString, sal_uInt32 nStringType, sal_Bool bAlign ) +{ + sal_uInt32 i, nItemSize, nType, nItemPos; + sal_Bool bRetValue = sal_False; + + nItemPos = Tell(); + + if ( nStringType == VT_EMPTY ) + *this >> nType; + else + nType = nStringType & VT_TYPEMASK; + + *this >> nItemSize; + + switch( nType ) + { + case VT_LPSTR : + { + if ( (sal_uInt16)nItemSize ) + { + sal_Char* pString = new sal_Char[ (sal_uInt16)nItemSize ]; + if ( mnTextEnc == RTL_TEXTENCODING_UCS2 ) + { + nItemSize >>= 1; + if ( (sal_uInt16)nItemSize > 1 ) + { + sal_Unicode* pWString = (sal_Unicode*)pString; + for ( i = 0; i < (sal_uInt16)nItemSize; i++ ) + *this >> pWString[ i ]; + rString = String( pWString, (sal_uInt16)nItemSize - 1 ); + } + else + rString = String(); + bRetValue = sal_True; + } + else + { + SvMemoryStream::Read( pString, (sal_uInt16)nItemSize ); + if ( pString[ (sal_uInt16)nItemSize - 1 ] == 0 ) + { + if ( (sal_uInt16)nItemSize > 1 ) + rString = String( ByteString( pString ), mnTextEnc ); + else + rString = String(); + bRetValue = sal_True; + } + } + delete[] pString; + } + if ( bAlign ) + SeekRel( ( 4 - ( nItemSize & 3 ) ) & 3 ); // dword align + } + break; + + case VT_LPWSTR : + { + if ( nItemSize ) + { + sal_Unicode* pString = new sal_Unicode[ (sal_uInt16)nItemSize ]; + for ( i = 0; i < (sal_uInt16)nItemSize; i++ ) + *this >> pString[ i ]; + if ( pString[ i - 1 ] == 0 ) + { + if ( (sal_uInt16)nItemSize > 1 ) + rString = String( pString, (sal_uInt16)nItemSize - 1 ); + else + rString = String(); + bRetValue = sal_True; + } + delete[] pString; + } + if ( bAlign && ( nItemSize & 1 ) ) + SeekRel( 2 ); // dword align + } + break; + } + if ( !bRetValue ) + Seek( nItemPos ); + return bRetValue; +} + +// ----------------------------------------------------------------------- + +PropItem& PropItem::operator=( PropItem& rPropItem ) +{ + if ( this != &rPropItem ) + { + Seek( STREAM_SEEK_TO_BEGIN ); + delete[] (sal_uInt8*)SwitchBuffer(); + + mnTextEnc = rPropItem.mnTextEnc; + sal_uInt32 nItemPos = rPropItem.Tell(); + rPropItem.Seek( STREAM_SEEK_TO_END ); + SvMemoryStream::Write( rPropItem.GetData(), rPropItem.Tell() ); + rPropItem.Seek( nItemPos ); + } + return *this; +} + +// ----------------------------------------------------------------------- + +struct Dict +{ + sal_uInt32 mnId; + String aString; + + Dict( sal_uInt32 nId, String rString ) { mnId = nId; aString = rString; }; +}; + +// ----------------------------------------------------------------------- + +Dictionary::~Dictionary() +{ + for ( void* pPtr = First(); pPtr; pPtr = Next() ) + delete (Dict*)pPtr; +} + +// ----------------------------------------------------------------------- + +void Dictionary::AddProperty( sal_uInt32 nId, const String& rString ) +{ + if ( rString.Len() ) // eindeutige namen bei properties + { + // pruefen, ob es die Propertybeschreibung in der Dictionary schon gibt + for ( Dict* pDict = (Dict*)First(); pDict; pDict = (Dict*)Next() ) + { + if ( pDict->mnId == nId ) + { + pDict->aString = rString; + return; + } + } + Insert( new Dict( nId, rString ), LIST_APPEND ); + } +} + +// ----------------------------------------------------------------------- + +UINT32 Dictionary::GetProperty( const String& rString ) +{ + for ( Dict* pDict = (Dict*)First(); pDict; pDict = (Dict*)Next() ) + { + if ( pDict->aString == rString ) + return pDict->mnId; + } + return 0; +} + +// ----------------------------------------------------------------------- + +Dictionary& Dictionary::operator=( Dictionary& rDictionary ) +{ + void* pPtr; + + if ( this != &rDictionary ) + { + for ( pPtr = First(); pPtr; pPtr = Next() ) + delete (Dict*)pPtr; + + for ( pPtr = rDictionary.First(); pPtr; pPtr = rDictionary.Next() ) + Insert( new Dict( ((Dict*)pPtr)->mnId, ((Dict*)pPtr)->aString ), LIST_APPEND ); + } + return *this; +} + +// ----------------------------------------------------------------------- + +Section::Section( Section& rSection ) +: List() +{ + mnTextEnc = rSection.mnTextEnc; + for ( int i = 0; i < 16; i++ ) + aFMTID[ i ] = rSection.aFMTID[ i ]; + for ( PropEntry* pProp = (PropEntry*)rSection.First(); pProp; pProp = (PropEntry*)rSection.Next() ) + Insert( new PropEntry( *pProp ), LIST_APPEND ); +} + +// ----------------------------------------------------------------------- + +Section::Section( const sal_uInt8* pFMTID ) +{ + mnTextEnc = RTL_TEXTENCODING_MS_1252; + for ( int i = 0; i < 16; i++ ) + aFMTID[ i ] = pFMTID[ i ]; +} + +// ----------------------------------------------------------------------- + +sal_Bool Section::GetProperty( sal_uInt32 nId, PropItem& rPropItem ) +{ + PropEntry* pProp; + if ( nId ) + { + for ( pProp = (PropEntry*)First(); pProp; pProp = (PropEntry*)Next() ) + { + if ( pProp->mnId == nId ) + break; + } + if ( pProp ) + { + rPropItem.Clear(); + rPropItem.SetTextEncoding( mnTextEnc ); + rPropItem.Write( pProp->mpBuf, pProp->mnSize ); + rPropItem.Seek( STREAM_SEEK_TO_BEGIN ); + return sal_True; + } + } + return sal_False; +} + +// ----------------------------------------------------------------------- + +void Section::AddProperty( sal_uInt32 nId, const sal_uInt8* pBuf, sal_uInt32 nBufSize ) +{ + // kleiner id check + + if ( !nId ) + return; + if ( nId == 0xffffffff ) + nId = 0; + + // keine doppelten PropId's zulassen, sortieren + for ( sal_uInt32 i = 0; i < Count(); i++ ) + { + PropEntry* pPropEntry = (PropEntry*)GetObject( i ); + if ( pPropEntry->mnId == nId ) + delete (PropEntry*)Replace( new PropEntry( nId, pBuf, nBufSize, mnTextEnc ), i ); + else if ( pPropEntry->mnId > nId ) + Insert( new PropEntry( nId, pBuf, nBufSize, mnTextEnc ), i ); + else + continue; + return; + } + Insert( new PropEntry( nId, pBuf, nBufSize, mnTextEnc ), LIST_APPEND ); +} + +// ----------------------------------------------------------------------- + +sal_Bool Section::GetDictionary( Dictionary& rDict ) +{ + sal_Bool bRetValue = sal_False; + + Dictionary aDict; + PropEntry* pProp; + + for ( pProp = (PropEntry*)First(); pProp; pProp = (PropEntry*)Next() ) + { + if ( pProp->mnId == 0 ) + break; + } + if ( pProp ) + { + sal_uInt32 nDictCount, nId, nSize, nPos; + SvMemoryStream aStream( (sal_Int8*)pProp->mpBuf, pProp->mnSize, STREAM_READ ); + aStream.Seek( STREAM_SEEK_TO_BEGIN ); + aStream >> nDictCount; + for ( sal_uInt32 i = 0; i < nDictCount; i++ ) + { + aStream >> nId >> nSize; + if ( (sal_uInt16)nSize ) + { + String aString; + nPos = aStream.Tell(); + sal_Char* pString = new sal_Char[ (sal_uInt16)nSize ]; + aStream.Read( pString, (sal_uInt16)nSize ); + if ( mnTextEnc == RTL_TEXTENCODING_UCS2 ) + { + nSize >>= 1; + aStream.Seek( nPos ); + sal_Unicode* pWString = (sal_Unicode*)pString; + for ( i = 0; i < (sal_uInt16)nSize; i++ ) + aStream >> pWString[ i ]; + aString = String( pWString, (sal_uInt16)nSize - 1 ); + } + else + aString = String( ByteString( pString, (sal_uInt16)nSize - 1 ), mnTextEnc ); + delete[] pString; + if ( !aString.Len() ) + break; + aDict.AddProperty( nId, aString ); + } + bRetValue = sal_True; + } + } + rDict = aDict; + return bRetValue; +} + +// ----------------------------------------------------------------------- + +Section::~Section() +{ + for ( PropEntry* pProp = (PropEntry*)First(); pProp; pProp = (PropEntry*)Next() ) + delete pProp; +} + +// ----------------------------------------------------------------------- + +void Section::Read( SvStorageStream *pStrm ) +{ + sal_uInt32 i, nSecOfs, nSecSize, nPropCount, nPropId, nPropOfs, nPropType, nPropSize, nCurrent, nVectorCount, nTemp, nStrmSize; + nSecOfs = pStrm->Tell(); + + pStrm->Seek( STREAM_SEEK_TO_END ); + nStrmSize = pStrm->Tell(); + pStrm->Seek( nSecOfs ); + + mnTextEnc = RTL_TEXTENCODING_MS_1252; + *pStrm >> nSecSize >> nPropCount; + while( nPropCount-- && ( pStrm->GetError() == ERRCODE_NONE ) ) + { + *pStrm >> nPropId >> nPropOfs; + nCurrent = pStrm->Tell(); + pStrm->Seek( nPropOfs + nSecOfs ); + if ( nPropId ) // dictionary wird nicht eingelesen + { + + *pStrm >> nPropType; + + nPropSize = 4; + + if ( nPropType & VT_VECTOR ) + { + *pStrm >> nVectorCount; + nPropType &=~VT_VECTOR; + nPropSize += 4; + } + else + nVectorCount = 1; + + + sal_Bool bVariant = ( nPropType == VT_VARIANT ); + + for ( i = 0; nPropSize && ( i < nVectorCount ); i++ ) + { + if ( bVariant ) + { + *pStrm >> nPropType; + nPropSize += 4; + } + switch( nPropType ) + { + case VT_UI1 : + nPropSize++; + break; + + case VT_I2 : + case VT_UI2 : + case VT_BOOL : + nPropSize += 2; + break; + + case VT_I4 : + case VT_R4 : + case VT_UI4 : + case VT_ERROR : + nPropSize += 4; + break; + + case VT_I8 : + case VT_R8 : + case VT_CY : + case VT_UI8 : + case VT_DATE : + case VT_FILETIME : + nPropSize += 8; + break; + + case VT_BSTR : + *pStrm >> nTemp; + nPropSize += ( nTemp + 4 ); + break; + + case VT_LPSTR : + *pStrm >> nTemp; + nPropSize += ( nTemp + 4 ); + break; + + case VT_LPWSTR : + *pStrm >> nTemp; + nPropSize += ( nTemp << 1 ) + 4; + break; + + case VT_BLOB_OBJECT : + case VT_BLOB : + case VT_CF : + *pStrm >> nTemp; + nPropSize += ( nTemp + 4 ); + break; + + case VT_CLSID : + case VT_STREAM : + case VT_STORAGE : + case VT_STREAMED_OBJECT : + case VT_STORED_OBJECT : + case VT_VARIANT : + case VT_VECTOR : + default : + nPropSize = 0; + } + if ( nPropSize ) + { + if ( ( nVectorCount - i ) > 1 ) + pStrm->Seek( nPropOfs + nSecOfs + nPropSize ); + } + else + break; + } + if ( nPropSize ) + { + pStrm->Seek( nPropOfs + nSecOfs ); + sal_uInt8* pBuf = new sal_uInt8[ nPropSize ]; + pStrm->Read( pBuf, nPropSize ); + AddProperty( nPropId, pBuf, nPropSize ); + delete[] pBuf; + } + if ( nPropId == 1 ) + { + PropItem aPropItem; + if ( GetProperty( 1, aPropItem ) ) + { + sal_uInt16 nCodePage; + aPropItem >> nPropType; + if ( nPropType == VT_I2 ) + { + aPropItem >> nCodePage; + + if ( nCodePage == 1200 ) + { + mnTextEnc = RTL_TEXTENCODING_UCS2; + } + else + { + mnTextEnc = rtl_getTextEncodingFromWindowsCodePage( nCodePage ); + if ( mnTextEnc == RTL_TEXTENCODING_DONTKNOW ) + mnTextEnc = RTL_TEXTENCODING_MS_1252; + } + } + else + { + mnTextEnc = RTL_TEXTENCODING_MS_1252; + } + } + } + } + else + { + sal_uInt32 nDictCount, nSize; + *pStrm >> nDictCount; + for ( i = 0; i < nDictCount; i++ ) + { + *pStrm >> nSize >> nSize; + pStrm->SeekRel( nSize ); + } + nSize = pStrm->Tell(); + pStrm->Seek( nPropOfs + nSecOfs ); + nSize -= pStrm->Tell(); + if ( nSize > nStrmSize ) + { + nPropCount = 0; + break; + } + sal_uInt8* pBuf = new sal_uInt8[ nSize ]; + pStrm->Read( pBuf, nSize ); + AddProperty( 0xffffffff, pBuf, nSize ); + delete[] pBuf; + } + pStrm->Seek( nCurrent ); + } + pStrm->Seek( nSecOfs + nSecSize ); +} + +// ----------------------------------------------------------------------- + +Section& Section::operator=( Section& rSection ) +{ + PropEntry* pProp; + + if ( this != &rSection ) + { + memcpy( (void*)aFMTID, (void*)rSection.aFMTID, 16 ); + for ( pProp = (PropEntry*)First(); pProp; pProp = (PropEntry*)Next() ) + delete pProp; + Clear(); + for ( pProp = (PropEntry*)rSection.First(); pProp; pProp = (PropEntry*)rSection.Next() ) + Insert( new PropEntry( *pProp ), LIST_APPEND ); + } + return *this; +} + +// ----------------------------------------------------------------------- + +PropRead::PropRead( SvStorage& rStorage, const String& rName ) : + mbStatus ( sal_False ), + mnByteOrder ( 0xfffe ), + mnFormat ( 0 ), + mnVersionLo ( 4 ), + mnVersionHi ( 2 ) +{ + if ( rStorage.IsStream( rName ) ) + { + mpSvStream = rStorage.OpenSotStream( rName, STREAM_STD_READ ); + if ( mpSvStream ) + { + mpSvStream->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); + memset( mApplicationCLSID, 0, 16 ); + mbStatus = sal_True; + } + } +} + +// ----------------------------------------------------------------------- + +void PropRead::AddSection( Section& rSection ) +{ + Insert( new Section( rSection ), LIST_APPEND ); +} + +// ----------------------------------------------------------------------- + +const Section* PropRead::GetSection( const sal_uInt8* pFMTID ) +{ + Section* pSection; + + for ( pSection = (Section*)First(); pSection; pSection = (Section*)Next() ) + { + if ( memcmp( pSection->GetFMTID(), pFMTID, 16 ) == 0 ) + break; + } + return pSection; +} + +// ----------------------------------------------------------------------- + +PropRead::~PropRead() +{ + for ( Section* pSection = (Section*)First(); pSection; pSection = (Section*)Next() ) + delete pSection; +} + +// ----------------------------------------------------------------------- + +void PropRead::Read() +{ + for ( Section* pSection = (Section*)First(); pSection; pSection = (Section*)Next() ) + delete pSection; + Clear(); + if ( mbStatus ) + { + sal_uInt32 nSections; + sal_uInt32 nSectionOfs; + sal_uInt32 nCurrent; + *mpSvStream >> mnByteOrder >> mnFormat >> mnVersionLo >> mnVersionHi; + if ( mnByteOrder == 0xfffe ) + { + sal_uInt8* pSectCLSID = new sal_uInt8[ 16 ]; + mpSvStream->Read( mApplicationCLSID, 16 ); + *mpSvStream >> nSections; + if ( nSections > 2 ) // sj: PowerPoint documents are containing max 2 sections + { + mbStatus = sal_False; + } + else for ( sal_uInt32 i = 0; i < nSections; i++ ) + { + mpSvStream->Read( pSectCLSID, 16 ); + *mpSvStream >> nSectionOfs; + nCurrent = mpSvStream->Tell(); + mpSvStream->Seek( nSectionOfs ); + Section aSection( pSectCLSID ); + aSection.Read( mpSvStream ); + AddSection( aSection ); + mpSvStream->Seek( nCurrent ); + } + delete[] pSectCLSID; + } + } +} + +// ----------------------------------------------------------------------- + +PropRead& PropRead::operator=( PropRead& rPropRead ) +{ + Section* pSection; + + if ( this != &rPropRead ) + { + mbStatus = rPropRead.mbStatus; + mpSvStream = rPropRead.mpSvStream; + + mnByteOrder = rPropRead.mnByteOrder; + mnFormat = rPropRead.mnFormat; + mnVersionLo = rPropRead.mnVersionLo; + mnVersionHi = rPropRead.mnVersionHi; + memcpy( mApplicationCLSID, rPropRead.mApplicationCLSID, 16 ); + + for ( pSection = (Section*)First(); pSection; pSection = (Section*)Next() ) + delete pSection; + Clear(); + for ( pSection = (Section*)rPropRead.First(); pSection; pSection = (Section*)rPropRead.Next() ) + Insert( new Section( *pSection ), LIST_APPEND ); + } + return *this; +} diff --git a/sd/source/filter/ppt/propread.hxx b/sd/source/filter/ppt/propread.hxx new file mode 100644 index 000000000000..cbb81b8cad1c --- /dev/null +++ b/sd/source/filter/ppt/propread.hxx @@ -0,0 +1,191 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _PROPREAD_HXX_ +#define _PROPREAD_HXX_ + +#include <tools/solar.h> +#include <sot/storage.hxx> +#include <tools/gen.hxx> +#include <tools/list.hxx> +#include <tools/stream.hxx> +#include <tools/datetime.hxx> + +#include <tools/string.hxx> + +// SummaryInformation +#define PID_TITLE 0x02 +#define PID_SUBJECT 0x03 +#define PID_AUTHOR 0x04 +#define PID_KEYWORDS 0x05 +#define PID_COMMENTS 0x06 +#define PID_TEMPLATE 0x07 +#define PID_LASTAUTHOR 0x08 +#define PID_REVNUMBER 0x09 +#define PID_EDITTIME 0x0a +#define PID_LASTPRINTED_DTM 0x0b +#define PID_CREATE_DTM 0x0c +#define PID_LASTSAVED_DTM 0x0d + +// DocumentSummaryInformation +#define PID_CATEGORY 0x02 +#define PID_PRESFORMAT 0x03 +#define PID_BYTECOUNT 0x04 +#define PID_LINECOUNT 0x05 +#define PID_PARACOUNT 0x06 +#define PID_SLIDECOUNT 0x07 +#define PID_NOTECOUNT 0x08 +#define PID_HIDDENCOUNT 0x09 +#define PID_MMCLIPCOUNT 0x0a +#define PID_SCALE 0x0b +#define PID_HEADINGPAIR 0x0c +#define PID_DOCPARTS 0x0d +#define PID_MANAGER 0x0e +#define PID_COMPANY 0x0f +#define PID_LINKSDIRTY 0x10 + +#define VT_EMPTY 0 +#define VT_NULL 1 +#define VT_I2 2 +#define VT_I4 3 +#define VT_R4 4 +#define VT_R8 5 +#define VT_CY 6 +#define VT_DATE 7 +#define VT_BSTR 8 +#define VT_UI4 9 +#define VT_ERROR 10 +#define VT_BOOL 11 +#define VT_VARIANT 12 +#define VT_DECIMAL 14 +#define VT_I1 16 +#define VT_UI1 17 +#define VT_UI2 18 +#define VT_I8 20 +#define VT_UI8 21 +#define VT_INT 22 +#define VT_UINT 23 +#define VT_LPSTR 30 +#define VT_LPWSTR 31 +#define VT_FILETIME 64 +#define VT_BLOB 65 +#define VT_STREAM 66 +#define VT_STORAGE 67 +#define VT_STREAMED_OBJECT 68 +#define VT_STORED_OBJECT 69 +#define VT_BLOB_OBJECT 70 +#define VT_CF 71 +#define VT_CLSID 72 +#define VT_VECTOR 0x1000 +#define VT_ARRAY 0x2000 +#define VT_BYREF 0x4000 +#define VT_TYPEMASK 0xFFF + +// ------------------------------------------------------------------------ + +class PropItem : public SvMemoryStream +{ + sal_uInt16 mnTextEnc; + + public : + PropItem(){}; + void Clear(); + + void SetTextEncoding( sal_uInt16 nTextEnc ){ mnTextEnc = nTextEnc; }; + sal_Bool Read( String& rString, sal_uInt32 nType = VT_EMPTY, sal_Bool bDwordAlign = sal_True ); + PropItem& operator=( PropItem& rPropItem ); + + using SvStream::Read; +}; + +// ------------------------------------------------------------------------ + +class Dictionary : protected List +{ + friend class Section; + + void AddProperty( UINT32 nId, const String& rString ); + + public : + Dictionary(){}; + ~Dictionary(); + Dictionary& operator=( Dictionary& rDictionary ); + UINT32 GetProperty( const String& rPropName ); +}; + +// ------------------------------------------------------------------------ + +class Section : private List +{ + sal_uInt16 mnTextEnc; + + protected: + + BYTE aFMTID[ 16 ]; + + void AddProperty( sal_uInt32 nId, const sal_uInt8* pBuf, sal_uInt32 nBufSize ); + + public: + Section( const sal_uInt8* pFMTID ); + Section( Section& rSection ); + ~Section(); + + Section& operator=( Section& rSection ); + sal_Bool GetProperty( sal_uInt32 nId, PropItem& rPropItem ); + sal_Bool GetDictionary( Dictionary& rDict ); + const sal_uInt8* GetFMTID() const { return aFMTID; }; + void Read( SvStorageStream* pStrm ); +}; + +// ------------------------------------------------------------------------ + +class PropRead : private List +{ + sal_Bool mbStatus; + SvStorageStream* mpSvStream; + + sal_uInt16 mnByteOrder; + sal_uInt16 mnFormat; + sal_uInt16 mnVersionLo; + sal_uInt16 mnVersionHi; + sal_uInt8 mApplicationCLSID[ 16 ]; + + void AddSection( Section& rSection ); + + public: + PropRead( SvStorage& rSvStorage, const String& rName ); + ~PropRead(); + + PropRead& operator=( PropRead& rPropRead ); + const Section* GetSection( const BYTE* pFMTID ); + sal_Bool IsValid() const { return mbStatus; }; + void Read(); +}; + + +#endif + diff --git a/sd/source/filter/sdfilter.cxx b/sd/source/filter/sdfilter.cxx new file mode 100644 index 000000000000..1a7cd380514c --- /dev/null +++ b/sd/source/filter/sdfilter.cxx @@ -0,0 +1,133 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" +#include <com/sun/star/task/XStatusIndicatorFactory.hpp> + +#include <memory> + +#include <tools/debug.hxx> +#include <osl/module.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/viewfrm.hxx> +#include <sfx2/progress.hxx> +#include <svl/itemset.hxx> + +#include "../ui/inc/DrawDocShell.hxx" +#include "../ui/inc/strings.hrc" + +#include "sdresid.hxx" +#include "pres.hxx" +#include "drawdoc.hxx" +#include "sdfilter.hxx" + +// -------------- +// - Namespaces - +// -------------- + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::task; +using namespace ::com::sun::star::frame; + +// ------------ +// - SdFilter - +// ------------ + +SdFilter::SdFilter( SfxMedium& rMedium, ::sd::DrawDocShell& rDocShell, sal_Bool bShowProgress ) +: mxModel( rDocShell.GetModel() ) +, mrMedium( rMedium ) +, mrDocShell( rDocShell ) +, mrDocument( *rDocShell.GetDoc() ) +, mbIsDraw( rDocShell.GetDocumentType() == DOCUMENT_TYPE_DRAW ) +, mbShowProgress( bShowProgress ) +{ +} + +// ----------------------------------------------------------------------------- + +SdFilter::~SdFilter() +{ +} + +// ----------------------------------------------------------------------------- + +::rtl::OUString SdFilter::ImplGetFullLibraryName( const ::rtl::OUString& rLibraryName ) const +{ + String aTemp( ::rtl::OUString::createFromAscii( SVLIBRARY( "?" ) ) ); + xub_StrLen nIndex = aTemp.Search( (sal_Unicode)'?' ); + aTemp.Replace( nIndex, 1, rLibraryName ); + ::rtl::OUString aLibraryName( aTemp ); + return aLibraryName; +} + +// ----------------------------------------------------------------------------- + +extern "C" { static void SAL_CALL thisModule() {} } + +::osl::Module* SdFilter::OpenLibrary( const ::rtl::OUString& rLibraryName ) const +{ + std::auto_ptr< osl::Module > mod(new osl::Module); + return mod->loadRelative(&thisModule, ImplGetFullLibraryName(rLibraryName)) + ? mod.release() : 0; +} + +// ----------------------------------------------------------------------------- + +void SdFilter::CreateStatusIndicator() +{ + // The status indicator must be retrieved from the provided medium arguments + const SfxUnoAnyItem* pStatusBarItem = static_cast<const SfxUnoAnyItem*>( + mrMedium.GetItemSet()->GetItem(SID_PROGRESS_STATUSBAR_CONTROL) ); + + if ( pStatusBarItem ) + pStatusBarItem->GetValue() >>= mxStatusIndicator; + +// try +// { +// if (mxModel.is()) +// { +// Reference< XController > xController( mxModel->getCurrentController()); +// if( xController.is()) +// { +// Reference< XFrame > xFrame( xController->getFrame()); +// if( xFrame.is()) +// { +// Reference< XStatusIndicatorFactory > xFactory( xFrame, UNO_QUERY ); +// if( xFactory.is()) +// { +// mxStatusIndicator = xFactory->createStatusIndicator(); +// } +// } +// } +// } +// } +// catch( Exception& ) +// { +// } +} + diff --git a/sd/source/filter/sdpptwrp.cxx b/sd/source/filter/sdpptwrp.cxx new file mode 100644 index 000000000000..e64cace3c696 --- /dev/null +++ b/sd/source/filter/sdpptwrp.cxx @@ -0,0 +1,199 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" + +#include <sfx2/docfile.hxx> +#include <sfx2/docfilt.hxx> +#include <osl/module.hxx> +#include <filter/msfilter/msoleexp.hxx> +#include <filter/msfilter/svxmsbas.hxx> +#include <svx/svxerr.hxx> +#include <unotools/fltrcfg.hxx> + +#include "sdpptwrp.hxx" +#include "ppt/pptin.hxx" +#include "drawdoc.hxx" +#include <tools/urlobj.hxx> +#include <filter/msfilter/msfiltertracer.hxx> + +// -------------- +// - Namespaces - +// -------------- + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::task; +using namespace ::com::sun::star::frame; + +typedef BOOL ( __LOADONCALLAPI *ExportPPT )( SvStorageRef&, + Reference< XModel > &, + Reference< XStatusIndicator > &, + SvMemoryStream*, sal_uInt32 nCnvrtFlags ); + +typedef sal_Bool ( SAL_CALL *ImportPPT )( const ::rtl::OUString&, Sequence< PropertyValue >*, + SdDrawDocument*, SvStream&, SvStorage&, SfxMedium& ); + +typedef BOOL ( __LOADONCALLAPI *SaveVBA )( SfxObjectShell&, SvMemoryStream*& ); + +// --------------- +// - SdPPTFilter - +// --------------- + +SdPPTFilter::SdPPTFilter( SfxMedium& rMedium, ::sd::DrawDocShell& rDocShell, sal_Bool bShowProgress ) : + SdFilter( rMedium, rDocShell, bShowProgress ), + pBas ( NULL ) +{ +} + +// ----------------------------------------------------------------------------- + +SdPPTFilter::~SdPPTFilter() +{ + delete pBas; // deleting the compressed basic storage +} + +// ----------------------------------------------------------------------------- + +sal_Bool SdPPTFilter::Import() +{ + sal_Bool bRet = sal_False; + SotStorageRef pStorage = new SotStorage( mrMedium.GetInStream(), FALSE ); + if( !pStorage->GetError() ) + { + /* check if there is a dualstorage, then the + document is propably a PPT95 containing PPT97 */ + SvStorageRef xDualStorage; + String sDualStorage( RTL_CONSTASCII_USTRINGPARAM( "PP97_DUALSTORAGE" ) ); + if ( pStorage->IsContained( sDualStorage ) ) + { + xDualStorage = pStorage->OpenSotStorage( sDualStorage, STREAM_STD_READ ); + pStorage = xDualStorage; + } + SvStream* pDocStream = pStorage->OpenSotStream( String( RTL_CONSTASCII_USTRINGPARAM("PowerPoint Document") ), STREAM_STD_READ ); + if( pDocStream ) + { + pDocStream->SetVersion( pStorage->GetVersion() ); + pDocStream->SetKey( pStorage->GetKey() ); + + String aTraceConfigPath( RTL_CONSTASCII_USTRINGPARAM( "Office.Tracing/Import/PowerPoint" ) ); + Sequence< PropertyValue > aConfigData( 1 ); + PropertyValue aPropValue; + aPropValue.Value <<= rtl::OUString( mrMedium.GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ); + aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentURL" ) ); + aConfigData[ 0 ] = aPropValue; + + if ( pStorage->IsStream( String( RTL_CONSTASCII_USTRINGPARAM("EncryptedSummary") ) ) ) + mrMedium.SetError( ERRCODE_SVX_READ_FILTER_PPOINT, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); + else + { + ::osl::Module* pLibrary = OpenLibrary( mrMedium.GetFilter()->GetUserData() ); + if ( pLibrary ) + { + ImportPPT PPTImport = reinterpret_cast< ImportPPT >( pLibrary->getFunctionSymbol( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ImportPPT" ) ) ) ); + if ( PPTImport ) + bRet = PPTImport( aTraceConfigPath, &aConfigData, &mrDocument, *pDocStream, *pStorage, mrMedium ); + + if ( !bRet ) + mrMedium.SetError( SVSTREAM_WRONGVERSION, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); + } + } + + delete pDocStream; + } + } + + return bRet; +} + +// ----------------------------------------------------------------------------- + +sal_Bool SdPPTFilter::Export() +{ + ::osl::Module* pLibrary = OpenLibrary( mrMedium.GetFilter()->GetUserData() ); + sal_Bool bRet = sal_False; + + if( pLibrary ) + { + if( mxModel.is() ) + { + SotStorageRef xStorRef = new SotStorage( mrMedium.GetOutStream(), FALSE ); + ExportPPT PPTExport = reinterpret_cast<ExportPPT>(pLibrary->getFunctionSymbol( ::rtl::OUString::createFromAscii("ExportPPT") )); + + /* !!! + if ( pViewShell && pViewShell->GetView() ) + pViewShell->GetView()->SdrEndTextEdit(); + */ + if( PPTExport && xStorRef.Is() ) + { + sal_uInt32 nCnvrtFlags = 0; + SvtFilterOptions* pFilterOptions = SvtFilterOptions::Get(); + if ( pFilterOptions ) + { + if ( pFilterOptions->IsMath2MathType() ) + nCnvrtFlags |= OLE_STARMATH_2_MATHTYPE; + if ( pFilterOptions->IsWriter2WinWord() ) + nCnvrtFlags |= OLE_STARWRITER_2_WINWORD; + if ( pFilterOptions->IsCalc2Excel() ) + nCnvrtFlags |= OLE_STARCALC_2_EXCEL; + if ( pFilterOptions->IsImpress2PowerPoint() ) + nCnvrtFlags |= OLE_STARIMPRESS_2_POWERPOINT; + if ( pFilterOptions->IsEnablePPTPreview() ) + nCnvrtFlags |= 0x8000; + } + + mrDocument.SetSwapGraphicsMode( SDR_SWAPGRAPHICSMODE_TEMP ); + + if( mbShowProgress ) + CreateStatusIndicator(); + + bRet = PPTExport( xStorRef, mxModel, mxStatusIndicator, pBas, nCnvrtFlags ); + xStorRef->Commit(); + } + } + delete pLibrary; + } + return bRet; +} + +void SdPPTFilter::PreSaveBasic() +{ + SvtFilterOptions* pFilterOptions = SvtFilterOptions::Get(); + if( pFilterOptions && pFilterOptions->IsLoadPPointBasicStorage() ) + { + ::osl::Module* pLibrary = OpenLibrary( mrMedium.GetFilter()->GetUserData() ); + if( pLibrary ) + { + SaveVBA pSaveVBA= reinterpret_cast<SaveVBA>(pLibrary->getFunctionSymbol( ::rtl::OUString::createFromAscii("SaveVBA") )); + if( pSaveVBA ) + { + pSaveVBA( (SfxObjectShell&) mrDocShell, pBas ); + } + } + } +} diff --git a/sd/source/filter/xml/makefile.mk b/sd/source/filter/xml/makefile.mk new file mode 100644 index 000000000000..3abe1f6bd355 --- /dev/null +++ b/sd/source/filter/xml/makefile.mk @@ -0,0 +1,47 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. +PRJNAME=sd +TARGET=xml +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/sdtransform.obj \ + $(SLO)$/sdxmlwrp.obj + +# --- Targets -------------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/sd/source/filter/xml/sdtransform.cxx b/sd/source/filter/xml/sdtransform.cxx new file mode 100644 index 000000000000..8abafc84055e --- /dev/null +++ b/sd/source/filter/xml/sdtransform.cxx @@ -0,0 +1,376 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" + +#include <svl/style.hxx> +#include <svl/itemset.hxx> +#include <svl/itempool.hxx> +#include <svl/whiter.hxx> + +#include <svx/svdoutl.hxx> +#include <editeng/xmlcnitm.hxx> +#include <svx/svdotext.hxx> +#include <svx/svdogrp.hxx> +#include <editeng/eeitem.hxx> +#include <editeng/lrspitem.hxx> +#include <editeng/numitem.hxx> + +#include "drawdoc.hxx" +#include "glob.hxx" + +using ::rtl::OUString; +using namespace ::com::sun::star::style; + +class SdTransformOOo2xDocument +{ +public: + SdTransformOOo2xDocument( SdDrawDocument& rDocument ); + + void transform(); + + void transformMasterPages(); + void transformDrawPages(); + + void transformStyles(); + void transformStyles( SfxStyleFamily eFam ); + void transformStyle( SfxStyleSheetBase& rSheet ); + + void transformShapes( SdrObjList& rShapes ); + void transformShape( SdrObject& rObj ); + + void transformTextShape( SdrTextObj& rTextShape ); + + bool getBulletState( const SfxItemSet& rSet, SfxStyleSheetBase* pSheet, bool& rState ); + bool getBulletState( const SfxItemSet& rSet, sal_uInt16 nWhich, bool& rState ); + + bool transformItemSet( SfxItemSet& rSet, bool bNumbering ); + + bool removeAlienAttributes( SfxItemSet& rSet ); + bool removeAlienAttributes( SfxItemSet& rSet, sal_uInt16 nWhich ); + + SdDrawDocument& mrDocument; + SdrOutliner& mrOutliner; + const OUString msEnableNumbering; + const OUString msTextNamespace; + const OUString msTrue; +}; + +/** transforms the given model from OOo 2.x to OOo 3.x. This maps + the deprecated EE_PARA_BULLETSTATE and clears the EE_PARA_LRSPACE + if used together with a EE_PARA_NUMBULLET */ +void TransformOOo2xDocument( SdDrawDocument* pDocument ) +{ + if( pDocument ) + { + SdTransformOOo2xDocument aTransformer( *pDocument ); + aTransformer.transform(); + } +} + +SdTransformOOo2xDocument::SdTransformOOo2xDocument( SdDrawDocument& rDocument ) +: mrDocument( rDocument ) +, mrOutliner( rDocument.GetDrawOutliner() ) +, msEnableNumbering( RTL_CONSTASCII_USTRINGPARAM( "enable-numbering" ) ) +, msTextNamespace( RTL_CONSTASCII_USTRINGPARAM( "urn:oasis:names:tc:opendocument:xmlns:text:1.0" ) ) +, msTrue( RTL_CONSTASCII_USTRINGPARAM( "true" ) ) +{ +} + +void SdTransformOOo2xDocument::transform() +{ + transformMasterPages(); + transformDrawPages(); + transformStyles(); +} + +void SdTransformOOo2xDocument::transformMasterPages() +{ + sal_uInt16 nMasterPageCount = mrDocument.GetMasterPageCount(); + for( sal_uInt16 nMasterPage = 0; nMasterPage < nMasterPageCount; nMasterPage++ ) + { + SdrObjList* pPage = mrDocument.GetMasterPage( nMasterPage ); + if( pPage ) + transformShapes( *pPage ); + } +} + +void SdTransformOOo2xDocument::transformDrawPages() +{ + sal_uInt16 nPageCount = mrDocument.GetPageCount(); + for( sal_uInt16 nPage = 0; nPage < nPageCount; nPage++ ) + { + SdrObjList* pPage = mrDocument.GetPage( nPage ); + if( pPage ) + transformShapes( *pPage ); + } +} + +void SdTransformOOo2xDocument::transformStyles() +{ + transformStyles( SD_STYLE_FAMILY_GRAPHICS ); + transformStyles( SD_STYLE_FAMILY_MASTERPAGE ); +} + +void SdTransformOOo2xDocument::transformStyles( SfxStyleFamily eFam ) +{ + + rtl::Reference< SfxStyleSheetBasePool > xStyleSheetPool( mrDocument.GetStyleSheetPool() ); + + SfxStyleSheetIterator aIter( xStyleSheetPool.get(), eFam ); + + SfxStyleSheetBase* pSheet = aIter.First(); + while( pSheet ) + { + transformStyle( *pSheet ); + pSheet = aIter.Next(); + } +} + +void SdTransformOOo2xDocument::transformStyle( SfxStyleSheetBase& rSheet ) +{ + SfxItemSet& rSet = rSheet.GetItemSet(); + + bool bState = false; + getBulletState( rSheet.GetItemSet(), rSheet.GetPool().Find( rSheet.GetParent(), rSheet.GetFamily() ), bState ); + + transformItemSet( rSet, bState ); + removeAlienAttributes( rSet ); +} + +void SdTransformOOo2xDocument::transformShapes( SdrObjList& rShapes ) +{ + sal_uInt32 nShapeCount = rShapes.GetObjCount(); + for( sal_uInt32 nShape = 0; nShape < nShapeCount; nShape++ ) + { + SdrObject* pObj = rShapes.GetObj( nShape ); + if( pObj ) + transformShape( *pObj ); + } +} + +void SdTransformOOo2xDocument::transformShape( SdrObject& rObj ) +{ + SdrTextObj* pTextShape = dynamic_cast< SdrTextObj* >( &rObj ); + if( pTextShape ) + { + transformTextShape( *pTextShape ); + return; + } + + SdrObjGroup* pGroupShape = dynamic_cast< SdrObjGroup* >( &rObj ); + if( pGroupShape ) + { + SdrObjList* pObjList = pGroupShape->GetSubList(); + if( pObjList ) + transformShapes( *pObjList ); + return; + } +} + +void SdTransformOOo2xDocument::transformTextShape( SdrTextObj& rTextShape ) +{ +/* + const SfxItemSet& rSet = rTextShape.GetMergedItemSet(); + + if( (rSet.GetItemState( EE_PARA_LRSPACE ) == SFX_ITEM_SET) && (rSet.GetItemState( EE_PARA_NUMBULLET ) == SFX_ITEM_SET) ) + { + SvxLRSpaceItem aItem( *static_cast<const SvxLRSpaceItem*>(rSet.GetItem( EE_PARA_LRSPACE )) ); + aItem.SetLeftValue( 0 ); + aItem.SetTxtFirstLineOfst( 0 ); + rTextShape.SetMergedItem( aItem ); + } +*/ + + if(!rTextShape.IsEmptyPresObj()) + { + OutlinerParaObject* pOPO = rTextShape.GetOutlinerParaObject(); + if (pOPO) + { + mrOutliner.SetText( *pOPO ); + + sal_uInt32 nCount = mrOutliner.GetParagraphCount(); + + //Paragraph* pPara = NULL; + + bool bChange = false; + + for(sal_uInt16 nPara = 0; nPara < nCount; nPara++) + { + SfxItemSet aParaSet( mrOutliner.GetParaAttribs( nPara ) ); + + bool bItemChange = false; + + bool bState = false; + const sal_Int16 nDepth = mrOutliner.GetDepth( nPara ); + if( (nDepth != -1) && (!getBulletState( aParaSet, mrOutliner.GetStyleSheet( nPara ), bState ) || !bState) ) + { + // disable bullet if text::enable-bullet="false" is found + if( (nDepth > 0 ) && (rTextShape.GetObjInventor() == SdrInventor) && (rTextShape.GetObjIdentifier() == OBJ_OUTLINETEXT) ) + { + // for outline object and level > 0 burn in the style sheet because it will be changed to "outline 1" + SfxStyleSheet* pStyleSheet = mrOutliner.GetStyleSheet( nPara ); + + if( pStyleSheet ) + { + // optimize me: only put items hard into paragraph that are not equal to "outline 1" style! + SfxItemSet& rStyleSet = pStyleSheet->GetItemSet(); + + SfxWhichIter aIter(aParaSet); + sal_uInt16 nWhich(aIter.FirstWhich()); + + // now set all none hard attributes from the style + while(nWhich) + { + if(SFX_ITEM_SET != aParaSet.GetItemState(nWhich, true)) + { + aParaSet.Put(rStyleSet.Get(nWhich)); + bItemChange = true; + } + + nWhich = aIter.NextWhich(); + } + } + } + + mrOutliner.SetDepth( mrOutliner.GetParagraph( nPara ), -1 ); + + bChange = true; + } + + bItemChange |= transformItemSet( aParaSet, bState ); + + bItemChange |= removeAlienAttributes( aParaSet ); + + if( bItemChange ) + { + mrOutliner.SetParaAttribs( nPara, aParaSet ); + bChange = true; + } + } + + if( bChange ) + rTextShape.SetOutlinerParaObject(mrOutliner.CreateParaObject()); + + mrOutliner.Clear(); + } + } +} + +bool SdTransformOOo2xDocument::getBulletState( const SfxItemSet& rSet, SfxStyleSheetBase* pSheet, bool& rState ) +{ + if( getBulletState( rSet, EE_PARA_XMLATTRIBS, rState ) ) + return true; + + if( getBulletState( rSet, SDRATTR_XMLATTRIBUTES, rState ) ) + return true; + + if( pSheet && getBulletState( pSheet->GetItemSet(), pSheet->GetPool().Find( pSheet->GetParent(), pSheet->GetFamily() ), rState ) ) + return true; + + return false; +} + +bool SdTransformOOo2xDocument::getBulletState( const SfxItemSet& rSet, sal_uInt16 nWhich, bool& rState ) +{ + if( (rSet.GetItemState( nWhich ) == SFX_ITEM_SET) ) + { + const SvXMLAttrContainerItem& rAttr = *static_cast< const SvXMLAttrContainerItem* >( rSet.GetItem( nWhich ) ); + + const sal_uInt16 nCount = rAttr.GetAttrCount(); + for( sal_uInt16 nItem = 0; nItem < nCount; nItem++ ) + { + if( ( rAttr.GetAttrLName( nItem ) == msEnableNumbering ) && ( rAttr.GetAttrNamespace( nItem ) == msTextNamespace ) ) + { + const OUString sValue( rAttr.GetAttrValue( nItem ) ); + rState = sValue.equals(msTrue); + return true; + } + } + } + + return false; +} + +bool SdTransformOOo2xDocument::transformItemSet( SfxItemSet& rSet, bool bNumbering ) +{ + bool bRet = false; + if( bNumbering /* && (rSet.GetItemState( EE_PARA_LRSPACE ) == SFX_ITEM_SET) && (rSet.GetItemState( EE_PARA_NUMBULLET ) == SFX_ITEM_SET) */ ) + { + SvxLRSpaceItem aItem( *static_cast<const SvxLRSpaceItem*>(rSet.GetItem( EE_PARA_LRSPACE )) ); + if( (aItem.GetLeft() != 0) || (aItem.GetTxtFirstLineOfst() != 0) ) + { + aItem.SetLeftValue( 0 ); + aItem.SetTxtFirstLineOfst( 0 ); + rSet.Put( aItem ); + bRet = true; + } + } + + return bRet; +} + +bool SdTransformOOo2xDocument::removeAlienAttributes( SfxItemSet& rSet ) +{ + return removeAlienAttributes( rSet, EE_PARA_XMLATTRIBS ) | removeAlienAttributes( rSet, SDRATTR_XMLATTRIBUTES ); +} + +bool SdTransformOOo2xDocument::removeAlienAttributes( SfxItemSet& rSet, sal_uInt16 nWhich ) +{ + if( (rSet.GetItemState( nWhich ) == SFX_ITEM_SET) ) + { + const SvXMLAttrContainerItem& rAttr = *static_cast< const SvXMLAttrContainerItem* >( rSet.GetItem( nWhich ) ); + + const sal_uInt16 nCount = rAttr.GetAttrCount(); + for( sal_uInt16 nItem = 0; nItem < nCount; nItem++ ) + { + if( ( rAttr.GetAttrLName( nItem ) == msEnableNumbering ) && ( rAttr.GetAttrNamespace( nItem ) == msTextNamespace ) ) + { + if( nCount == 1 ) + { + rSet.ClearItem( nWhich ); + } + else + { + SvXMLAttrContainerItem aNewItem( nWhich ); + + const sal_uInt16 nFound = nItem; + for( nItem = 0; nItem < nCount; nItem++ ) + { + if( nItem != nFound ) + aNewItem.AddAttr( rAttr.GetAttrPrefix(nItem),rAttr.GetAttrNamespace(nItem), rAttr.GetAttrLName(nItem), rAttr.GetAttrValue(nItem ) ); + } + + rSet.Put( aNewItem ); + } + return true; + } + } + } + return false; +} diff --git a/sd/source/filter/xml/sdxmlwrp.cxx b/sd/source/filter/xml/sdxmlwrp.cxx new file mode 100644 index 000000000000..cb130f059960 --- /dev/null +++ b/sd/source/filter/xml/sdxmlwrp.cxx @@ -0,0 +1,1113 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sd.hxx" +#include <rtl/logfile.hxx> +#include <com/sun/star/container/XChild.hpp> +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <com/sun/star/embed/ElementModes.hpp> +#include <com/sun/star/xml/sax/SAXParseException.hdl> +#include <comphelper/processfactory.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/docfilt.hxx> +#include <tools/urlobj.hxx> +#include "drawdoc.hxx" +#include <unotools/streamwrap.hxx> +#include <svx/xmlgrhlp.hxx> + +#include "../../ui/inc/DrawDocShell.hxx" + +#include "sdxmlwrp.hxx" +#include "strmname.h" +#include <svx/xmleohlp.hxx> +#include <com/sun/star/xml/sax/XDocumentHandler.hpp> +#include <com/sun/star/document/XFilter.hpp> +#include <com/sun/star/document/XImporter.hpp> +#include <com/sun/star/document/XExporter.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/document/XGraphicObjectResolver.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/packages/zip/ZipIOException.hpp> + +#include <com/sun/star/xml/sax/XErrorHandler.hpp> +#include <com/sun/star/xml/sax/XEntityResolver.hpp> +#include <com/sun/star/xml/sax/InputSource.hpp> +#include <com/sun/star/xml/sax/XDTDHandler.hpp> +#include <com/sun/star/xml/sax/XParser.hpp> +#include <com/sun/star/io/XActiveDataSource.hpp> +#include <com/sun/star/io/XActiveDataControl.hpp> +#include <comphelper/genericpropertyset.hxx> +#include <comphelper/propertysetinfo.hxx> +#include <unotools/saveopt.hxx> + +// #80365# include necessary for XML progress bar at load time +#include <svl/itemset.hxx> +#include <svl/stritem.hxx> +#include <svtools/sfxecode.hxx> + +#include "sderror.hxx" +#include "sdresid.hxx" +#include "glob.hrc" + +#include <sfx2/frame.hxx> + +using rtl::OUString; +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::document; +using namespace comphelper; + +#define SD_XML_READERROR 1234 + +extern void TransformOOo2xDocument( SdDrawDocument* pDocument ); + +////////////////////////////////////////////////////////////////////////////// + +#ifndef SEQTYPE + #if defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500) + #define SEQTYPE(x) (new ::com::sun::star::uno::Type( x )) + #else + #define SEQTYPE(x) &(x) + #endif +#endif + +#define MAP_LEN(x) x, sizeof(x) - 1 + +#define XML_STRING(i, x) sal_Char __READONLY_DATA i[sizeof(x)] = x + +XML_STRING( sXML_metaStreamName, "meta.xml"); +XML_STRING( sXML_styleStreamName, "styles.xml" ); +XML_STRING( sXML_contentStreamName, "content.xml" ); +XML_STRING( sXML_oldContentStreamName, "Content.xml" ); +XML_STRING( sXML_settingsStreamName, "settings.xml" ); + +XML_STRING( sXML_export_impress_oasis_service, "com.sun.star.comp.Impress.XMLOasisExporter" ); +XML_STRING( sXML_export_impress_meta_oasis_service, "com.sun.star.comp.Impress.XMLOasisMetaExporter" ); +XML_STRING( sXML_export_impress_styles_oasis_service, "com.sun.star.comp.Impress.XMLOasisStylesExporter" ); +XML_STRING( sXML_export_impress_content_oasis_service, "com.sun.star.comp.Impress.XMLOasisContentExporter" ); +XML_STRING( sXML_export_impress_settings_oasis_service, "com.sun.star.comp.Impress.XMLOasisSettingsExporter" ); + +XML_STRING( sXML_export_draw_oasis_service, "com.sun.star.comp.Draw.XMLOasisExporter" ); +XML_STRING( sXML_export_draw_meta_oasis_service, "com.sun.star.comp.Draw.XMLOasisMetaExporter" ); +XML_STRING( sXML_export_draw_styles_oasis_service, "com.sun.star.comp.Draw.XMLOasisStylesExporter" ); +XML_STRING( sXML_export_draw_content_oasis_service, "com.sun.star.comp.Draw.XMLOasisContentExporter" ); +XML_STRING( sXML_export_draw_settings_oasis_service, "com.sun.star.comp.Draw.XMLOasisSettingsExporter" ); + +XML_STRING( sXML_import_impress_oasis_service, "com.sun.star.comp.Impress.XMLOasisImporter" ); +XML_STRING( sXML_import_impress_meta_oasis_service, "com.sun.star.comp.Impress.XMLOasisMetaImporter" ); +XML_STRING( sXML_import_impress_styles_oasis_service, "com.sun.star.comp.Impress.XMLOasisStylesImporter" ); +XML_STRING( sXML_import_impress_content_oasis_service, "com.sun.star.comp.Impress.XMLOasisContentImporter" ); +XML_STRING( sXML_import_impress_settings_oasis_service, "com.sun.star.comp.Impress.XMLOasisSettingsImporter" ); + +XML_STRING( sXML_import_draw_oasis_service, "com.sun.star.comp.Draw.XMLOasisImporter" ); +XML_STRING( sXML_import_draw_meta_oasis_service, "com.sun.star.comp.Draw.XMLOasisMetaImporter" ); +XML_STRING( sXML_import_draw_styles_oasis_service, "com.sun.star.comp.Draw.XMLOasisStylesImporter" ); +XML_STRING( sXML_import_draw_content_oasis_service, "com.sun.star.comp.Draw.XMLOasisContentImporter" ); +XML_STRING( sXML_import_draw_settings_oasis_service, "com.sun.star.comp.Draw.XMLOasisSettingsImporter" ); + +// OOo +XML_STRING( sXML_export_impress_ooo_service, "com.sun.star.comp.Impress.XMLExporter" ); +XML_STRING( sXML_export_impress_meta_ooo_service, "com.sun.star.comp.Impress.XMLMetaExporter" ); +XML_STRING( sXML_export_impress_styles_ooo_service, "com.sun.star.comp.Impress.XMLStylesExporter" ); +XML_STRING( sXML_export_impress_content_ooo_service, "com.sun.star.comp.Impress.XMLContentExporter" ); +XML_STRING( sXML_export_impress_settings_ooo_service, "com.sun.star.comp.Impress.XMLSettingsExporter" ); + +XML_STRING( sXML_export_draw_ooo_service, "com.sun.star.comp.Draw.XMLExporter" ); +XML_STRING( sXML_export_draw_meta_ooo_service, "com.sun.star.comp.Draw.XMLMetaExporter" ); +XML_STRING( sXML_export_draw_styles_ooo_service, "com.sun.star.comp.Draw.XMLStylesExporter" ); +XML_STRING( sXML_export_draw_content_ooo_service, "com.sun.star.comp.Draw.XMLContentExporter" ); +XML_STRING( sXML_export_draw_settings_ooo_service, "com.sun.star.comp.Draw.XMLSettingsExporter" ); + +XML_STRING( sXML_import_impress_ooo_service, "com.sun.star.comp.Impress.XMLImporter" ); +XML_STRING( sXML_import_impress_meta_ooo_service, "com.sun.star.comp.Impress.XMLMetaImporter" ); +XML_STRING( sXML_import_impress_styles_ooo_service, "com.sun.star.comp.Impress.XMLStylesImporter" ); +XML_STRING( sXML_import_impress_content_ooo_service, "com.sun.star.comp.Impress.XMLContentImporter" ); +XML_STRING( sXML_import_impress_settings_ooo_service, "com.sun.star.comp.Impress.XMLSettingsImporter" ); + +XML_STRING( sXML_import_draw_ooo_service, "com.sun.star.comp.Draw.XMLImporter" ); +XML_STRING( sXML_import_draw_meta_ooo_service, "com.sun.star.comp.Draw.XMLMetaImporter" ); +XML_STRING( sXML_import_draw_styles_ooo_service, "com.sun.star.comp.Draw.XMLStylesImporter" ); +XML_STRING( sXML_import_draw_content_ooo_service, "com.sun.star.comp.Draw.XMLContentImporter" ); +XML_STRING( sXML_import_draw_settings_ooo_service, "com.sun.star.comp.Draw.XMLSettingsImporter" ); + +struct XML_SERVICEMAP +{ + const sal_Char* mpService; + const sal_Char* mpStream; + sal_Bool mbPlain; +}; + +struct XML_SERVICES +{ + const sal_Char* mpAll; + const sal_Char* mpMeta; + const sal_Char* mpStyles; + const sal_Char* mpContent; + const sal_Char* mpSettings; +}; + +XML_SERVICES* getServices( bool bImport, bool bDraw, ULONG nStoreVer ) +{ + static XML_SERVICES gServices[] = + { + { sXML_export_impress_oasis_service, sXML_export_impress_meta_oasis_service, sXML_export_impress_styles_oasis_service, sXML_export_impress_content_oasis_service, sXML_export_impress_settings_oasis_service }, + { sXML_export_draw_oasis_service, sXML_export_draw_meta_oasis_service, sXML_export_draw_styles_oasis_service, sXML_export_draw_content_oasis_service, sXML_export_draw_settings_oasis_service }, + { sXML_import_impress_oasis_service, sXML_import_impress_meta_oasis_service, sXML_import_impress_styles_oasis_service, sXML_import_impress_content_oasis_service, sXML_import_impress_settings_oasis_service }, + { sXML_import_draw_oasis_service, sXML_import_draw_meta_oasis_service, sXML_import_draw_styles_oasis_service, sXML_import_draw_content_oasis_service, sXML_import_draw_settings_oasis_service }, + + { sXML_export_impress_ooo_service, sXML_export_impress_meta_ooo_service, sXML_export_impress_styles_ooo_service, sXML_export_impress_content_ooo_service, sXML_export_impress_settings_ooo_service }, + { sXML_export_draw_ooo_service, sXML_export_draw_meta_ooo_service, sXML_export_draw_styles_ooo_service, sXML_export_draw_content_ooo_service, sXML_export_draw_settings_ooo_service }, + { sXML_import_impress_ooo_service, sXML_import_impress_meta_ooo_service, sXML_import_impress_styles_ooo_service, sXML_import_impress_content_ooo_service, sXML_import_impress_settings_ooo_service }, + { sXML_import_draw_ooo_service, sXML_import_draw_meta_ooo_service, sXML_import_draw_styles_ooo_service, sXML_import_draw_content_ooo_service, sXML_import_draw_settings_ooo_service }, + }; + + return &gServices[ (bImport ? 2 : 0) + ((nStoreVer == SOFFICE_FILEFORMAT_60) ? 4 : 0) + (bDraw ? 1 : 0 ) ]; +} + + +// ---------------- +// - SdXMLWrapper - +// ---------------- + +SdXMLFilter::SdXMLFilter( SfxMedium& rMedium, ::sd::DrawDocShell& rDocShell, sal_Bool bShowProgress, SdXMLFilterMode eFilterMode, ULONG nStoreVer ) : + SdFilter( rMedium, rDocShell, bShowProgress ), meFilterMode( eFilterMode ), mnStoreVer( nStoreVer ) +{ +} + +SdXMLFilter::~SdXMLFilter(void) +{ +} + +sal_Int32 ReadThroughComponent( + Reference<io::XInputStream> xInputStream, + Reference<XComponent> xModelComponent, + const String& rStreamName, + Reference<lang::XMultiServiceFactory> & rFactory, + const sal_Char* pFilterName, + Sequence<Any> rFilterArguments, + const OUString& rName, + sal_Bool bMustBeSuccessfull, + sal_Bool bEncrypted ) +{ + DBG_ASSERT(xInputStream.is(), "input stream missing"); + DBG_ASSERT(xModelComponent.is(), "document missing"); + DBG_ASSERT(rFactory.is(), "factory missing"); + DBG_ASSERT(NULL != pFilterName,"I need a service name for the component!"); + + RTL_LOGFILE_CONTEXT( aLog, "ReadThroughComponent" ); + + // prepare ParserInputSrouce + xml::sax::InputSource aParserInput; + aParserInput.sSystemId = rName; + aParserInput.aInputStream = xInputStream; + + // get parser + Reference< xml::sax::XParser > xParser( + rFactory->createInstance( + OUString::createFromAscii("com.sun.star.xml.sax.Parser") ), + UNO_QUERY ); + DBG_ASSERT( xParser.is(), "Can't create parser" ); + if( !xParser.is() ) + return SD_XML_READERROR; + RTL_LOGFILE_CONTEXT_TRACE( aLog, "parser created" ); + + // get filter + Reference< xml::sax::XDocumentHandler > xFilter( + rFactory->createInstanceWithArguments( + OUString::createFromAscii(pFilterName), rFilterArguments), + UNO_QUERY ); + DBG_ASSERT( xFilter.is(), "Can't instantiate filter component." ); + if( !xFilter.is() ) + return SD_XML_READERROR; + RTL_LOGFILE_CONTEXT_TRACE1( aLog, "%s created", pFilterName ); + + // connect parser and filter + xParser->setDocumentHandler( xFilter ); + + // connect model and filter + Reference < XImporter > xImporter( xFilter, UNO_QUERY ); + xImporter->setTargetDocument( xModelComponent ); + // finally, parser the stream + RTL_LOGFILE_CONTEXT_TRACE( aLog, "parsing stream" ); + try + { + xParser->parseStream( aParserInput ); + } + catch( xml::sax::SAXParseException& r ) + { + // sax parser sends wrapped exceptions, + // try to find the original one + xml::sax::SAXException aSaxEx = *(xml::sax::SAXException*)(&r); + sal_Bool bTryChild = sal_True; + + while( bTryChild ) + { + xml::sax::SAXException aTmp; + if ( aSaxEx.WrappedException >>= aTmp ) + aSaxEx = aTmp; + else + bTryChild = sal_False; + } + + packages::zip::ZipIOException aBrokenPackage; + if ( aSaxEx.WrappedException >>= aBrokenPackage ) + return ERRCODE_IO_BROKENPACKAGE; + + if( bEncrypted ) + return ERRCODE_SFX_WRONGPASSWORD; + +#if OSL_DEBUG_LEVEL > 1 + ByteString aError( "SAX parse exception catched while importing:\n" ); + aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US ); + DBG_ERROR( aError.GetBuffer() ); +#endif + + String sErr( String::CreateFromInt32( r.LineNumber )); + sErr += ','; + sErr += String::CreateFromInt32( r.ColumnNumber ); + + if( rStreamName.Len() ) + { + return *new TwoStringErrorInfo( + (bMustBeSuccessfull ? ERR_FORMAT_FILE_ROWCOL + : WARN_FORMAT_FILE_ROWCOL), + rStreamName, sErr, + ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR ); + } + else + { + DBG_ASSERT( bMustBeSuccessfull, "Warnings are not supported" ); + return *new StringErrorInfo( ERR_FORMAT_ROWCOL, sErr, + ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR ); + } + } + catch( xml::sax::SAXException& r ) + { + packages::zip::ZipIOException aBrokenPackage; + if ( r.WrappedException >>= aBrokenPackage ) + return ERRCODE_IO_BROKENPACKAGE; + + if( bEncrypted ) + return ERRCODE_SFX_WRONGPASSWORD; + +#if OSL_DEBUG_LEVEL > 1 + ByteString aError( "SAX exception catched while importing:\n" ); + aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US ); + DBG_ERROR( aError.GetBuffer() ); +#endif + return SD_XML_READERROR; + } + catch( packages::zip::ZipIOException& r ) + { + (void)r; +#if OSL_DEBUG_LEVEL > 1 + ByteString aError( "Zip exception catched while importing:\n" ); + aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US ); + DBG_ERROR( aError.GetBuffer() ); +#endif + return ERRCODE_IO_BROKENPACKAGE; + } + catch( io::IOException& r ) + { + (void)r; +#if OSL_DEBUG_LEVEL > 1 + ByteString aError( "IO exception catched while importing:\n" ); + aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US ); + DBG_ERROR( aError.GetBuffer() ); +#endif + return SD_XML_READERROR; + } + catch( uno::Exception& r ) + { + (void)r; +#if OSL_DEBUG_LEVEL > 1 + ByteString aError( "uno exception catched while importing:\n" ); + aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US ); + DBG_ERROR( aError.GetBuffer() ); +#endif + return SD_XML_READERROR; + } + + // success! + return 0; +} + +sal_Int32 ReadThroughComponent( + const uno::Reference < embed::XStorage >& xStorage, + Reference<XComponent> xModelComponent, + const sal_Char* pStreamName, + const sal_Char* pCompatibilityStreamName, + Reference<lang::XMultiServiceFactory> & rFactory, + const sal_Char* pFilterName, + Sequence<Any> rFilterArguments, + const OUString& rName, + sal_Bool bMustBeSuccessfull ) +{ + DBG_ASSERT(xStorage.is(), "Need storage!"); + DBG_ASSERT(NULL != pStreamName, "Please, please, give me a name!"); + + // open stream (and set parser input) + OUString sStreamName = OUString::createFromAscii(pStreamName); + sal_Bool bContainsStream = sal_False; + try + { + bContainsStream = xStorage->isStreamElement(sStreamName); + } + catch( container::NoSuchElementException& ) + { + } + + if (!bContainsStream ) + { + // stream name not found! Then try the compatibility name. + // if no stream can be opened, return immediatly with OK signal + + // do we even have an alternative name? + if ( NULL == pCompatibilityStreamName ) + return 0; + + // if so, does the stream exist? + sStreamName = OUString::createFromAscii(pCompatibilityStreamName); + try + { + bContainsStream = xStorage->isStreamElement(sStreamName); + } + catch( container::NoSuchElementException& ) + { + } + + if (! bContainsStream ) + return 0; + } + + // set Base URL + uno::Reference< beans::XPropertySet > xInfoSet; + if( rFilterArguments.getLength() > 0 ) + rFilterArguments.getConstArray()[0] >>= xInfoSet; + DBG_ASSERT( xInfoSet.is(), "missing property set" ); + if( xInfoSet.is() ) + { + OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("StreamName") ); + xInfoSet->setPropertyValue( sPropName, makeAny( sStreamName ) ); + } + + try + { + // get input stream + Reference <io::XStream> xStream = + xStorage->openStreamElement( sStreamName, embed::ElementModes::READ ); + Reference <beans::XPropertySet > xProps( xStream, uno::UNO_QUERY ); + if ( !xStream.is() || ! xProps.is() ) + return SD_XML_READERROR; + + Any aAny = xProps->getPropertyValue( + OUString( RTL_CONSTASCII_USTRINGPARAM("Encrypted") ) ); + + sal_Bool bEncrypted = aAny.getValueType() == ::getBooleanCppuType() && + *(sal_Bool *)aAny.getValue(); + + Reference <io::XInputStream> xInputStream = xStream->getInputStream(); + + // read from the stream + return ReadThroughComponent( + xInputStream, xModelComponent, sStreamName, rFactory, + pFilterName, rFilterArguments, + rName, bMustBeSuccessfull, bEncrypted ); + } + catch ( packages::WrongPasswordException& ) + { + return ERRCODE_SFX_WRONGPASSWORD; + } + catch( packages::zip::ZipIOException& ) + { + return ERRCODE_IO_BROKENPACKAGE; + } + catch ( uno::Exception& ) + {} + + return SD_XML_READERROR; +} + +// ----------------------------------------------------------------------------- + +sal_Bool SdXMLFilter::Import( ErrCode& nError ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sd", "cl93746", "SdXMLFilter::Import" ); +#ifdef TIMELOG + ByteString aFile( mrMedium.GetName(), RTL_TEXTENCODING_ASCII_US ); + RTL_LOGFILE_CONTEXT_TRACE1( aLog, "importing %s", aFile.GetBuffer() ); +#endif + + sal_uInt32 nRet = 0; + + // Get service factory + Reference< lang::XMultiServiceFactory > xServiceFactory = + comphelper::getProcessServiceFactory(); + DBG_ASSERT( xServiceFactory.is(), + "XMLReader::Read: got no service manager" ); + if( !xServiceFactory.is() ) + return sal_False; + + // ------------------------------------- + + SdDrawDocument* pDoc = mrDocShell.GetDoc(); + pDoc->EnableUndo(false); + pDoc->NewOrLoadCompleted( NEW_DOC ); + pDoc->CreateFirstPages(); + pDoc->StopWorkStartupDelay(); + + // ------------------------------------- + + mxModel->lockControllers(); + + // ------------------------------------- + + /** property map for export info set */ + PropertyMapEntry aImportInfoMap[] = + { + // #80365# necessary properties for XML progress bar at load time + { MAP_LEN( "ProgressRange" ), 0, &::getCppuType((const sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, + { MAP_LEN( "ProgressMax" ), 0, &::getCppuType((const sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, + { MAP_LEN( "ProgressCurrent" ), 0, &::getCppuType((const sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, + { MAP_LEN( "Preview" ), 0, &::getCppuType((const sal_Bool*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, + { MAP_LEN( "PageLayouts" ), 0, SEQTYPE(::getCppuType((const uno::Reference< container::XNameAccess >*)0)), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, + { MAP_LEN( "PrivateData" ), 0, + &::getCppuType( (Reference<XInterface> *)0 ), + ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, + { MAP_LEN( "BaseURI" ), 0, + &::getCppuType( (OUString *)0 ), + ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, + { MAP_LEN( "StreamRelPath" ), 0, + &::getCppuType( (OUString *)0 ), + ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, + { MAP_LEN( "StreamName" ), 0, + &::getCppuType( (OUString *)0 ), + ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, + { MAP_LEN( "BuildId" ), 0, + &::getCppuType( (OUString *)0 ), + ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, + { NULL, 0, 0, NULL, 0, 0 } + }; + + uno::Reference< beans::XPropertySet > xInfoSet( GenericPropertySet_CreateInstance( new PropertySetInfo( aImportInfoMap ) ) ); + xInfoSet->setPropertyValue( OUString::createFromAscii( "Preview" ), uno::makeAny( mrDocShell.GetDoc()->IsStarDrawPreviewMode() ) ); + + // ---- get BuildId from parent container if available + + uno::Reference< container::XChild > xChild( mxModel, uno::UNO_QUERY ); + if( xChild.is() ) + { + uno::Reference< beans::XPropertySet > xParentSet( xChild->getParent(), uno::UNO_QUERY ); + if( xParentSet.is() ) + { + uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xParentSet->getPropertySetInfo() ); + OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("BuildId" ) ); + if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(sPropName) ) + { + xInfoSet->setPropertyValue( sPropName, xParentSet->getPropertyValue(sPropName) ); + } + } + } + + // ------------------------------------- + + Reference< io::XActiveDataSource > xSource; + Reference< XInterface > xPipe; + Reference< document::XGraphicObjectResolver > xGraphicResolver; + SvXMLGraphicHelper *pGraphicHelper = 0; + Reference< document::XEmbeddedObjectResolver > xObjectResolver; + SvXMLEmbeddedObjectHelper *pObjectHelper = 0; + + Reference< lang::XComponent > xModelComp( mxModel, uno::UNO_QUERY ); + + // ------------------------------------- + + // #80365# try to get an XStatusIndicator from the Medium + if( mbShowProgress ) + { + SfxItemSet* pSet = mrMedium.GetItemSet(); + if(pSet) + { + const SfxUnoAnyItem* pItem = static_cast<const SfxUnoAnyItem*>( + pSet->GetItem(SID_PROGRESS_STATUSBAR_CONTROL) ); + if (pItem) + { + pItem->GetValue() >>= mxStatusIndicator; + } + } + + if(mxStatusIndicator.is()) + { + sal_Int32 nProgressRange(1000000); + sal_Int32 nProgressCurrent(0); + OUString aMsg = String( SdResId( STR_LOAD_DOC ) ); + mxStatusIndicator->start(aMsg, nProgressRange); + + // set ProgressRange + uno::Any aProgRange; + aProgRange <<= nProgressRange; + xInfoSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ProgressRange")), aProgRange); + + // set ProgressCurrent + uno::Any aProgCurrent; + aProgCurrent <<= nProgressCurrent; + xInfoSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ProgressCurrent")), aProgCurrent); + } + } + + // ------------------------------------- + // get the input stream (storage or stream) + // ------------------------------------- + + SvStorageStreamRef xDocStream; + Reference<io::XInputStream> xInputStream; + uno::Reference < embed::XStorage > xStorage = mrMedium.GetStorage(); + + if( !xStorage.is() ) + nRet = SD_XML_READERROR; + + if( 0 == nRet ) + { + pGraphicHelper = SvXMLGraphicHelper::Create( xStorage, + GRAPHICHELPER_MODE_READ, + sal_False ); + xGraphicResolver = pGraphicHelper; + pObjectHelper = SvXMLEmbeddedObjectHelper::Create( + xStorage, *pDoc->GetPersist(), + EMBEDDEDOBJECTHELPER_MODE_READ, + sal_False ); + xObjectResolver = pObjectHelper; + } + + // Set base URI + const OUString sBaseURI( RTL_CONSTASCII_USTRINGPARAM("BaseURI") ); + xInfoSet->setPropertyValue( sBaseURI, makeAny( mrMedium.GetBaseURL() ) ); + + if( 0 == nRet && SFX_CREATE_MODE_EMBEDDED == mrDocShell.GetCreateMode() ) + { + OUString aName; + if ( mrMedium.GetItemSet() ) + { + const SfxStringItem* pDocHierarchItem = static_cast<const SfxStringItem*>( + mrMedium.GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) ); + if ( pDocHierarchItem ) + aName = pDocHierarchItem->GetValue(); + } + else + aName = ::rtl::OUString::createFromAscii( "dummyObjectName" ); + + if( aName.getLength() ) + { + const OUString sStreamRelPath(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath")); + xInfoSet->setPropertyValue( sStreamRelPath, Any( aName ) ); + } + } + + // ------------------------------------- + + if( 0 == nRet ) + { + + // prepare filter arguments + Sequence<Any> aFilterArgs( 4 ); + Any *pArgs = aFilterArgs.getArray(); + *pArgs++ <<= xInfoSet; + *pArgs++ <<= xGraphicResolver; + *pArgs++ <<= xObjectResolver; + *pArgs++ <<= mxStatusIndicator; + + Sequence<Any> aEmptyArgs( 2 ); + pArgs = aEmptyArgs.getArray(); + *pArgs++ <<= xInfoSet; + *pArgs++ <<= mxStatusIndicator; + + const OUString aName( mrMedium.GetName() ); + + XML_SERVICES* pServices = getServices( true, IsDraw(), mnStoreVer ); + + sal_uInt32 nWarn = 0; + sal_uInt32 nWarn2 = 0; + // read storage streams + if( meFilterMode != SDXMLMODE_Organizer ) + { + nWarn = ReadThroughComponent( + xStorage, xModelComp, "meta.xml", "Meta.xml", xServiceFactory, + pServices->mpMeta, + aEmptyArgs, aName, sal_False ); + + nWarn2 = ReadThroughComponent( + xStorage, xModelComp, "settings.xml", NULL, xServiceFactory, + pServices->mpSettings, + aFilterArgs, aName, sal_False ); + } + + nRet = ReadThroughComponent( + xStorage, xModelComp, "styles.xml", NULL, xServiceFactory, + pServices->mpStyles, + aFilterArgs, aName, sal_True ); + + if( !nRet && (meFilterMode != SDXMLMODE_Organizer) ) + nRet = ReadThroughComponent( + xStorage, xModelComp, "content.xml", "Content.xml", xServiceFactory, + pServices->mpContent, + aFilterArgs, aName, sal_True ); + + if( !nRet ) + { + if( nWarn ) + nRet = nWarn; + else if( nWarn2 ) + nRet = nWarn2; + } + } + + // ------------------------------------- + if( pGraphicHelper ) + SvXMLGraphicHelper::Destroy( pGraphicHelper ); + xGraphicResolver = 0; + if( pObjectHelper ) + SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper ); + xObjectResolver = 0; + + if( mxStatusIndicator.is() ) + mxStatusIndicator->end(); + + if( mxModel.is() ) + mxModel->unlockControllers(); + + if( nRet == 0 ) + pDoc->UpdateAllLinks(); + + switch( nRet ) + { + case 0: break; + // case ERRCODE_SFX_WRONGPASSWORD: break; + case SD_XML_READERROR: break; + case ERRCODE_IO_BROKENPACKAGE: + if( xStorage.is() ) + { + nError = ERRCODE_IO_BROKENPACKAGE; + break; + } + // fall through intented + default: + { + // TODO/LATER: this is completely wrong! Filter code should never call ErrorHandler directly! + ErrorHandler::HandleError( nRet ); + if( IsWarning( nRet ) ) + nRet = 0; + } + } + + + // clear unused named items from item pool + + uno::Reference< lang::XMultiServiceFactory> xModelFactory( mxModel, uno::UNO_QUERY ); + if( xModelFactory.is() ) + { + try + { + const OUString aName( RTL_CONSTASCII_USTRINGPARAM( "~clear~" ) ); + uno::Reference< container::XNameContainer > xGradient( xModelFactory->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.GradientTable") ) ), uno::UNO_QUERY ); + if( xGradient.is() ) + xGradient->removeByName( aName ); + + uno::Reference< container::XNameContainer > xHatch( xModelFactory->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.HatchTable") ) ), uno::UNO_QUERY ); + if( xHatch.is() ) + xHatch->removeByName( aName ); + + uno::Reference< container::XNameContainer > xBitmap( xModelFactory->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.BitmapTable") ) ), uno::UNO_QUERY ); + if( xBitmap.is() ) + xBitmap->removeByName( aName ); + + uno::Reference< container::XNameContainer > xTransGradient( xModelFactory->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.TransparencyGradientTable") ) ), uno::UNO_QUERY ); + if( xTransGradient.is() ) + xTransGradient->removeByName( aName ); + + uno::Reference< container::XNameContainer > xMarker( xModelFactory->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.MarkerTable") ) ), uno::UNO_QUERY ); + if( xMarker.is() ) + xMarker->removeByName( aName ); + + uno::Reference< container::XNameContainer > xDashes( xModelFactory->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.DashTable") ) ), uno::UNO_QUERY ); + if( xDashes.is() ) + xDashes->removeByName( aName ); + } + catch( Exception& ) + { + DBG_ERROR("sd::SdXMLFilter::Import(), exception during clearing of unused named items"); + } + } + + // set BuildId on XModel for later OLE object loading + if( xInfoSet.is() ) + { + uno::Reference< beans::XPropertySet > xModelSet( mxModel, uno::UNO_QUERY ); + if( xModelSet.is() ) + { + uno::Reference< beans::XPropertySetInfo > xModelSetInfo( xModelSet->getPropertySetInfo() ); + const OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("BuildId" ) ); + + OUString sBuildId; + xInfoSet->getPropertyValue(sPropName) >>= sBuildId; + + if( xModelSetInfo.is() && xModelSetInfo->hasPropertyByName(sPropName) ) + { + xModelSet->setPropertyValue( sPropName, Any( sBuildId ) ); + } + + bool bTransform = false; + + if( (nRet == 0) ) + { + if( sBuildId.getLength() ) + { + sal_Int32 nIndex = sBuildId.indexOf('$'); + if( nIndex != -1 ) + { + sal_Int32 nUPD = sBuildId.copy( 0, nIndex ).toInt32(); + + if( nUPD == 300 ) + { + sal_Int32 nBuildId = sBuildId.copy( nIndex+1 ).toInt32(); + if( (nBuildId > 0) && (nBuildId < 9316) ) + bTransform = true; // treat OOo 3.0 beta1 as OOo 2.x + } + else if( (nUPD == 680) || ( nUPD >= 640 && nUPD <= 645 ) ) + bTransform = true; + } + } + else + { + // check for binary formats + const SfxFilter * pFilter = mrMedium.GetFilter(); + if( pFilter ) + { + const String& rTypeName = pFilter->GetRealTypeName(); + + if( (rTypeName.CompareToAscii( RTL_CONSTASCII_STRINGPARAM("impress_StarImpress" ) ) == 0) || + (rTypeName.CompareToAscii( RTL_CONSTASCII_STRINGPARAM("draw_StarDraw" ) ) == 0) ) + { + bTransform = true; + } + } + } + } + + if( bTransform ) + TransformOOo2xDocument( pDoc ); + } + } + + pDoc->EnableUndo(true); + mrDocShell.ClearUndoBuffer(); + return nRet == 0; +} + +// ----------------------------------------------------------------------------- + +sal_Bool SdXMLFilter::Export() +{ +#ifdef TIMELOG + RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sd", "cl93746", "SdXMLFilter::Export" ); + ByteString aFile( mrMedium.GetName(), RTL_TEXTENCODING_ASCII_US ); + RTL_LOGFILE_CONTEXT_TRACE1( aLog, "exporting %s", aFile.GetBuffer() ); +#endif + + SvXMLEmbeddedObjectHelper* pObjectHelper = NULL; + SvXMLGraphicHelper* pGraphicHelper = NULL; + sal_Bool bDocRet = FALSE; + + if( !mxModel.is() ) + { + DBG_ERROR("Got NO Model in XMLExport"); + return FALSE; + } + + sal_Bool bLocked = mxModel->hasControllersLocked(); + + try + { + mxModel->lockControllers(); + + uno::Reference< lang::XServiceInfo > xServiceInfo( mxModel, uno::UNO_QUERY ); + + if( !xServiceInfo.is() || !xServiceInfo->supportsService( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.GenericDrawingDocument" ) ) ) ) + { + DBG_ERROR( "Model is no DrawingDocument in XMLExport" ); + return FALSE; + } + + uno::Reference< lang::XMultiServiceFactory> xServiceFactory( ::comphelper::getProcessServiceFactory() ); + + if( !xServiceFactory.is() ) + { + DBG_ERROR( "got no service manager" ); + return FALSE; + } + + uno::Reference< uno::XInterface > xWriter( xServiceFactory->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Writer" ) ) ) ); + + if( !xWriter.is() ) + { + DBG_ERROR( "com.sun.star.xml.sax.Writer service missing" ); + return FALSE; + } + uno::Reference<xml::sax::XDocumentHandler> xHandler( xWriter, uno::UNO_QUERY ); + + /** property map for export info set */ + PropertyMapEntry aExportInfoMap[] = + { + // #82003# + { MAP_LEN( "ProgressRange" ), 0, &::getCppuType((const sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, + { MAP_LEN( "ProgressMax" ), 0, &::getCppuType((const sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, + { MAP_LEN( "ProgressCurrent" ), 0, &::getCppuType((const sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, + { MAP_LEN( "UsePrettyPrinting"),0, &::getBooleanCppuType(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, + + { MAP_LEN( "PageLayoutNames" ), 0, SEQTYPE(::getCppuType((const OUString*)0)), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, + { MAP_LEN( "BaseURI" ), 0, + &::getCppuType( (OUString *)0 ), + ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, + { MAP_LEN( "StreamRelPath" ), 0, + &::getCppuType( (OUString *)0 ), + ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, + { MAP_LEN( "StreamName" ), 0, + &::getCppuType( (OUString *)0 ), + ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, + { MAP_LEN( "StyleNames" ), 0, + &::getCppuType( (Sequence<OUString>*)0 ), + ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, + { MAP_LEN( "StyleFamilies" ), 0, + &::getCppuType( (Sequence<sal_Int32>*)0 ), + ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, + { MAP_LEN( "TargetStorage" ), 0, &embed::XStorage::static_type(), + ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, + + { NULL, 0, 0, NULL, 0, 0 } + }; + + uno::Reference< beans::XPropertySet > xInfoSet( GenericPropertySet_CreateInstance( new PropertySetInfo( aExportInfoMap ) ) ); + + + SvtSaveOptions aSaveOpt; + OUString sUsePrettyPrinting(RTL_CONSTASCII_USTRINGPARAM("UsePrettyPrinting")); + sal_Bool bUsePrettyPrinting( aSaveOpt.IsPrettyPrinting() ); + xInfoSet->setPropertyValue( sUsePrettyPrinting, makeAny( bUsePrettyPrinting ) ); + + const uno::Reference < embed::XStorage >& xStorage = mrMedium.GetOutputStorage(); + + // Set base URI + OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("BaseURI") ); + xInfoSet->setPropertyValue( sPropName, makeAny( mrMedium.GetBaseURL( true ) ) ); + + OUString sTargetStorage( RTL_CONSTASCII_USTRINGPARAM("TargetStorage") ); + xInfoSet->setPropertyValue( sTargetStorage, Any( xStorage ) ); + + if( SFX_CREATE_MODE_EMBEDDED == mrDocShell.GetCreateMode() ) + { + OUString aName; + if ( mrMedium.GetItemSet() ) + { + const SfxStringItem* pDocHierarchItem = static_cast<const SfxStringItem*>( + mrMedium.GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) ); + if ( pDocHierarchItem ) + aName = pDocHierarchItem->GetValue(); + } + + if( aName.getLength() ) + { + sPropName = OUString(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath")); + xInfoSet->setPropertyValue( sPropName, makeAny( aName ) ); + } + } + + // initialize descriptor + uno::Sequence< beans::PropertyValue > aDescriptor( 1 ); + beans::PropertyValue* pProps = aDescriptor.getArray(); + + pProps[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "FileName" ) ); + pProps[0].Value <<= OUString( mrMedium.GetName() ); + + { + uno::Reference< document::XEmbeddedObjectResolver > xObjectResolver; + uno::Reference< document::XGraphicObjectResolver > xGrfResolver; + + // create helper for graphic and ole export if we have a storage + if( xStorage.is() ) + { + pObjectHelper = SvXMLEmbeddedObjectHelper::Create( xStorage, *mrDocShell.GetDoc()->GetPersist(), EMBEDDEDOBJECTHELPER_MODE_WRITE, sal_False ); + xObjectResolver = pObjectHelper; + + pGraphicHelper = SvXMLGraphicHelper::Create( xStorage, GRAPHICHELPER_MODE_WRITE, FALSE ); + xGrfResolver = pGraphicHelper; + } + + // #82003# + if(mbShowProgress) + { + CreateStatusIndicator(); + if(mxStatusIndicator.is()) + { + sal_Int32 nProgressRange(1000000); + sal_Int32 nProgressCurrent(0); + OUString aMsg = String( SdResId( STR_SAVE_DOC ) ); + mxStatusIndicator->start(aMsg, nProgressRange); + + // set ProgressRange + uno::Any aProgRange; + aProgRange <<= nProgressRange; + xInfoSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ProgressRange")), aProgRange); + + // set ProgressCurrent + uno::Any aProgCurrent; + aProgCurrent <<= nProgressCurrent; + xInfoSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ProgressCurrent")), aProgCurrent); + } + } + + uno::Reference< lang::XComponent > xComponent( mxModel, uno::UNO_QUERY ); + + XML_SERVICES* pServiceNames = getServices( false, IsDraw(), mnStoreVer ); + + XML_SERVICEMAP aServices[5]; sal_uInt16 i = 0; + aServices[i ].mpService = pServiceNames->mpStyles; + aServices[i ].mpStream = sXML_styleStreamName; + aServices[i++].mbPlain = sal_False; + + aServices[i ].mpService = pServiceNames->mpContent; + aServices[i ].mpStream = sXML_contentStreamName; + aServices[i++].mbPlain = sal_False; + + aServices[i ].mpService = pServiceNames->mpSettings; + aServices[i ].mpStream = sXML_settingsStreamName; + aServices[i++].mbPlain = sal_False; + + if( mrDocShell.GetCreateMode() != SFX_CREATE_MODE_EMBEDDED ) + { + aServices[i ].mpService = pServiceNames->mpMeta; + aServices[i ].mpStream = sXML_metaStreamName; + aServices[i++].mbPlain = sal_True; + }; + + aServices[i].mpService = NULL; + aServices[i].mpStream = NULL; + + XML_SERVICEMAP* pServices = aServices; + + // doc export + do + { + RTL_LOGFILE_CONTEXT_TRACE1( aLog, "exporting substream %s", pServices->mpStream ); + + uno::Reference<io::XOutputStream> xDocOut; + if( xStorage.is() ) + { + const OUString sDocName( OUString::createFromAscii( pServices->mpStream ) ); + uno::Reference<io::XStream> xStream = + xStorage->openStreamElement( sDocName, + embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE ); + + DBG_ASSERT(xStream.is(), "Can't create output stream in package!"); + if( !xStream.is() ) + return sal_False; + + xDocOut = xStream->getOutputStream(); + Reference <beans::XPropertySet > xProps( xStream, uno::UNO_QUERY ); + if( !xDocOut.is() || !xProps.is() ) + return sal_False; + + uno::Any aAny; aAny <<= OUString( RTL_CONSTASCII_USTRINGPARAM("text/xml") ); + xProps->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MediaType")), aAny); + + OUString aUseCommonPassPropName( RTL_CONSTASCII_USTRINGPARAM("UseCommonStoragePasswordEncryption") ); + if( pServices->mbPlain ) + xProps->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Compressed") ), uno::makeAny( (sal_Bool) sal_False ) ); + // if the document is encrypted even the plain streams should be encrypted + xProps->setPropertyValue( aUseCommonPassPropName, uno::makeAny( (sal_Bool)sal_True ) ); + + const OUString sStreamName( RTL_CONSTASCII_USTRINGPARAM("StreamName") ); + xInfoSet->setPropertyValue( sStreamName, Any( sDocName ) ); + } + + uno::Reference< io::XActiveDataSource > xDocSrc( xWriter, uno::UNO_QUERY ); + xDocSrc->setOutputStream( xDocOut ); + + uno::Sequence< uno::Any > aArgs( 2 + ( mxStatusIndicator.is() ? 1 : 0 ) + ( xGrfResolver.is() ? 1 : 0 ) + ( xObjectResolver.is() ? 1 : 0 ) ); + uno::Any* pArgs = aArgs.getArray(); + *pArgs++ <<= xInfoSet; + if( xGrfResolver.is() ) *pArgs++ <<= xGrfResolver; + if( xObjectResolver.is() ) *pArgs++ <<= xObjectResolver; + if( mxStatusIndicator.is() ) *pArgs++ <<= mxStatusIndicator; + + *pArgs <<= xHandler; + + uno::Reference< document::XFilter > xFilter( xServiceFactory->createInstanceWithArguments( OUString::createFromAscii( pServices->mpService ), aArgs ), uno::UNO_QUERY ); + if( xFilter.is() ) + { + uno::Reference< document::XExporter > xExporter( xFilter, uno::UNO_QUERY ); + if( xExporter.is() ) + { + xExporter->setSourceDocument( xComponent ); + // outputstream will be closed by SAX parser + bDocRet = xFilter->filter( aDescriptor ); + } + } + + pServices++; + } + while( bDocRet && pServices->mpService ); + + // #82003# + if(mbShowProgress) + { + if(mxStatusIndicator.is()) + mxStatusIndicator->end(); + } + } + } + catch(uno::Exception e) + { +#if OSL_DEBUG_LEVEL > 1 + ByteString aError( "uno Exception caught while exporting:\n" ); + aError += ByteString( String( e.Message), RTL_TEXTENCODING_ASCII_US ); + DBG_ERROR( aError.GetBuffer() ); +#endif + bDocRet = sal_False; + } + if ( !bLocked ) + mxModel->unlockControllers(); + + if( pGraphicHelper ) + SvXMLGraphicHelper::Destroy( pGraphicHelper ); + + if( pObjectHelper ) + SvXMLEmbeddedObjectHelper::Destroy( pObjectHelper ); + + return bDocRet; +} |