xref: /trunk/main/sd/source/filter/eppt/eppt.cxx (revision 96eff784)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sd.hxx"
26 #include <eppt.hxx>
27 #include "epptdef.hxx"
28 #include <tools/globname.hxx>
29 #include <tools/datetime.hxx>
30 #include <tools/poly.hxx>
31 #include <vcl/graph.hxx>
32 #include <vcl/bmpacc.hxx>
33 #include <vcl/gradient.hxx>
34 #include <rtl/ustring.hxx>
35 #include <tools/stream.hxx>
36 #include <svtools/fltcall.hxx>
37 #include <sfx2/docfile.hxx>
38 #include <svx/unoapi.hxx>
39 #include <svx/svdobj.hxx>
40 #include <svx/svdoole2.hxx>
41 #include <svx/svdmodel.hxx>
42 #include <svx/svdpage.hxx>
43 #include <com/sun/star/view/PaperOrientation.hpp>
44 #include <com/sun/star/view/PaperFormat.hpp>
45 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
46 #include <com/sun/star/office/XAnnotation.hpp>
47 #include <com/sun/star/office/XAnnotationAccess.hpp>
48 #include <com/sun/star/office/XAnnotationEnumeration.hpp>
49 #include <com/sun/star/geometry/RealPoint2D.hpp>
50 #include <com/sun/star/util/DateTime.hpp>
51 #include <tools/zcodec.hxx>
52 #include <editeng/svxenum.hxx>
53 #include <sot/storinfo.hxx>
54 #include <filter/msfilter/msoleexp.hxx>
55 #include <vcl/virdev.hxx>
56 #include <svtools/wmf.hxx>
57 #include <filter/msfilter/msdffimp.hxx>
58 #include <filter/msfilter/svxmsbas.hxx>
59 #include <editeng/flditem.hxx>
60 #include <sfx2/docinf.hxx>
61 
62 #define PPT_TRANSITION_TYPE_NONE            0
63 #define PPT_TRANSITION_TYPE_RANDOM          1
64 #define PPT_TRANSITION_TYPE_BLINDS          2
65 #define PPT_TRANSITION_TYPE_CHECKER         3
66 #define PPT_TRANSITION_TYPE_COVER           4
67 #define PPT_TRANSITION_TYPE_DISSOLVE        5
68 #define PPT_TRANSITION_TYPE_FADE            6
69 #define PPT_TRANSITION_TYPE_PULL            7
70 #define PPT_TRANSITION_TYPE_RANDOM_BARS     8
71 #define PPT_TRANSITION_TYPE_STRIPS          9
72 #define PPT_TRANSITION_TYPE_WIPE           10
73 #define PPT_TRANSITION_TYPE_ZOOM           11
74 #define PPT_TRANSITION_TYPE_SPLIT          13
75 
76 // effects, new in xp
77 #define PPT_TRANSITION_TYPE_DIAMOND			17
78 #define PPT_TRANSITION_TYPE_PLUS			18
79 #define PPT_TRANSITION_TYPE_WEDGE			19
80 #define PPT_TRANSITION_TYPE_PUSH			20
81 #define PPT_TRANSITION_TYPE_COMB			21
82 #define PPT_TRANSITION_TYPE_NEWSFLASH		22
83 #define PPT_TRANSITION_TYPE_SMOOTHFADE		23
84 #define PPT_TRANSITION_TYPE_WHEEL			26
85 #define PPT_TRANSITION_TYPE_CIRCLE			27
86 
87 using namespace com::sun::star;
88 
89 static PHLayout pPHLayout[] =
90 {
91 	{ EPP_LAYOUT_TITLESLIDE,			{ 0x0d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x00, 0x0d, 0x10, sal_True, sal_True, sal_False },
92 	{ EPP_LAYOUT_TITLEANDBODYSLIDE,		{ 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x00, 0x0d, 0x0e, sal_True, sal_True, sal_False },
93 	{ EPP_LAYOUT_TITLEANDBODYSLIDE,		{ 0x0d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x14, 0x0d, 0x0e, sal_True, sal_True, sal_False },
94 	{ EPP_LAYOUT_2COLUMNSANDTITLE,		{ 0x0d, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x00, 0x0d, 0x0e, sal_True, sal_True, sal_True },
95 	{ EPP_LAYOUT_2COLUMNSANDTITLE,		{ 0x0d, 0x0e, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x14, 0x0d, 0x0e, sal_True, sal_True, sal_False },
96 	{ EPP_LAYOUT_BLANCSLIDE,			{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x00, 0x0d, 0x0e, sal_False, sal_False, sal_False },
97 	{ EPP_LAYOUT_2COLUMNSANDTITLE,		{ 0x0d, 0x0e, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x16, 0x0d, 0x0e, sal_True, sal_True, sal_False },
98 	{ EPP_LAYOUT_2COLUMNSANDTITLE,		{ 0x0d, 0x14, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x14, 0x0d, 0x0e, sal_True, sal_True, sal_False },
99 	{ EPP_LAYOUT_TITLEANDBODYSLIDE,		{ 0x0d, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x15, 0x0d, 0x0e, sal_True, sal_False, sal_False },
100 	{ EPP_LAYOUT_2COLUMNSANDTITLE,		{ 0x0d, 0x16, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x16, 0x0d, 0x0e, sal_True, sal_True, sal_False },
101 	{ EPP_LAYOUT_2COLUMNSANDTITLE,		{ 0x0d, 0x0e, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x13, 0x0d, 0x0e, sal_True, sal_True, sal_False },
102 	{ EPP_LAYOUT_TITLEANDBODYSLIDE,		{ 0x0d, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x13, 0x0d, 0x0e, sal_True, sal_False, sal_False },
103 	{ EPP_LAYOUT_RIGHTCOLUMN2ROWS,		{ 0x0d, 0x0e, 0x13, 0x13, 0x00, 0x00, 0x00, 0x00 }, 0x13, 0x0d, 0x0e, sal_True, sal_True, sal_False },
104 	{ EPP_LAYOUT_2COLUMNSANDTITLE,		{ 0x0d, 0x13, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x13, 0x0d, 0x0e, sal_True, sal_True, sal_False },
105 	{ EPP_LAYOUT_2ROWSANDTITLE,			{ 0x0d, 0x13, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x13, 0x0d, 0x0e, sal_True, sal_True, sal_False },
106 	{ EPP_LAYOUT_LEFTCOLUMN2ROWS,		{ 0x0d, 0x13, 0x13, 0x0e, 0x00, 0x00, 0x00, 0x00 }, 0x13, 0x0d, 0x0e, sal_True, sal_True, sal_False },
107 	{ EPP_LAYOUT_TOPROW2COLUMN,			{ 0x0d, 0x13, 0x13, 0x0e, 0x00, 0x00, 0x00, 0x00 }, 0x13, 0x0d, 0x0e, sal_True, sal_True, sal_False },
108 	{ EPP_LAYOUT_2ROWSANDTITLE,			{ 0x0d, 0x0e, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x13, 0x0d, 0x0e, sal_True, sal_True, sal_False },
109 	{ EPP_LAYOUT_4OBJECTS,				{ 0x0d, 0x13, 0x13, 0x13, 0x13, 0x00, 0x00, 0x00 }, 0x13, 0x0d, 0x0e, sal_True, sal_False, sal_False },
110 	{ EPP_LAYOUT_ONLYTITLE,				{ 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x00, 0x0d, 0x0e, sal_True, sal_False, sal_False },
111 	{ EPP_LAYOUT_BLANCSLIDE,			{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x00, 0x0d, 0x0e, sal_False, sal_False, sal_False },
112 	{ EPP_LAYOUT_TITLERIGHT2BODIESLEFT, { 0x11, 0x12, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x14, 0x11, 0x12, sal_True, sal_True, sal_False },
113 	{ EPP_LAYOUT_TITLERIGHTBODYLEFT,	{ 0x11, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x00, 0x11, 0x12, sal_True, sal_True, sal_False },
114 	{ EPP_LAYOUT_TITLEANDBODYSLIDE,		{ 0x0d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x00, 0x0d, 0x12, sal_True, sal_True, sal_False },
115 	{ EPP_LAYOUT_2COLUMNSANDTITLE,		{ 0x0d, 0x16, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x16, 0x0d, 0x12, sal_True, sal_True, sal_False }
116 };
117 
118 //============================ PPTWriter ==================================
119 
PPTWriter(const std::vector<com::sun::star::beans::PropertyValue> & rMediaData,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)120 PPTWriter::PPTWriter( const std::vector< com::sun::star::beans::PropertyValue >& rMediaData, SvStorageRef& rSvStorage,
121             ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > & rXModel,
122             ::com::sun::star::uno::Reference< ::com::sun::star::task::XStatusIndicator > & rXStatInd,
123             SvMemoryStream* pVBA, sal_uInt32 nCnvrtFlags ) :
124     mbStatus                ( sal_False ),
125 	mbUseNewAnimations		( sal_True ),
126     mnLatestStatValue       ( 0 ),
127     maFraction              ( 1, 576 ),
128     maMapModeSrc            ( MAP_100TH_MM ),
129     maMapModeDest           ( MAP_INCH, Point(), maFraction, maFraction ),
130     meLatestPageType        ( NORMAL ),
131     mXModel                 ( rXModel ),
132 	mXStatusIndicator       ( rXStatInd ),
133 	mbStatusIndicator       ( sal_False ),
134 	mpCurUserStrm           ( NULL ),
135 	mpStrm                  ( NULL ),
136     mpPicStrm               ( NULL ),
137 	mpPptEscherEx           ( NULL ),
138     mnVBAOleOfs             ( 0 ),
139     mpVBA                   ( pVBA ),
140     mnExEmbed               ( 0 ),
141     mpExEmbed               ( new SvMemoryStream ),
142     mnPagesWritten          ( 0 ),
143 	mnTxId                  ( 0x7a2f64 )
144 {
145     sal_uInt32 i;
146     if ( !ImplInitSOIface() )
147         return;
148 
149     FontCollectionEntry aDefaultFontDesc( String( RTL_CONSTASCII_USTRINGPARAM( "Times New Roman" ) ),
150                                             ::com::sun::star::awt::FontFamily::ROMAN,
151                                                 ::com::sun::star::awt::FontPitch::VARIABLE,
152                                                     RTL_TEXTENCODING_MS_1252 );
153     maFontCollection.GetId( aDefaultFontDesc ); // default is always times new roman
154 
155     if ( !ImplGetPageByIndex( 0, NOTICE ) )
156         return;
157     sal_Int32 nWidth = 21000;
158     if ( ImplGetPropertyValue( mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM(  "Width" ) ) ) )
159         mAny >>= nWidth;
160     sal_Int32 nHeight = 29700;
161     if ( ImplGetPropertyValue( mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Height" ) ) ) )
162         mAny >>= nHeight;
163 
164     maNotesPageSize = ImplMapSize( ::com::sun::star::awt::Size( nWidth, nHeight ) );
165 
166     if ( !ImplGetPageByIndex( 0, MASTER ) )
167         return;
168     nWidth = 28000;
169     if ( ImplGetPropertyValue( mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Width" ) ) ) )
170         mAny >>= nWidth;
171     nHeight = 21000;
172     if ( ImplGetPropertyValue( mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Height" ) ) ) )
173         mAny >>= nHeight;
174     maDestPageSize = ImplMapSize( ::com::sun::star::awt::Size( nWidth, nHeight ) );
175     maPageSize = Size(nWidth, nHeight);
176 
177     mrStg = rSvStorage;
178     if ( !mrStg.Is() )
179         return;
180 
181     // MasterPages + Slides und Notizen + NotesMasterPage
182     mnDrawings = mnMasterPages + ( mnPages << 1 ) + 1;
183 
184     if ( mXStatusIndicator.is() )
185     {
186         mbStatusIndicator = sal_True;
187         mnStatMaxValue = ( mnPages + mnMasterPages ) * 5;
188         mXStatusIndicator->start( String( RTL_CONSTASCII_USTRINGPARAM( "PowerPoint Export" ) ),
189                                     mnStatMaxValue + ( mnStatMaxValue >> 3 ) );
190     }
191 
192     SvGlobalName aGName( 0x64818d10L, 0x4f9b, 0x11cf, 0x86, 0xea, 0x00, 0xaa, 0x00, 0xb9, 0x29, 0xe8 );
193     mrStg->SetClass( aGName, 0, String( RTL_CONSTASCII_USTRINGPARAM( "MS PowerPoint 97" ) ) );
194 
195     if ( !ImplCreateCurrentUserStream() )
196         return;
197 
198     mpStrm = mrStg->OpenSotStream( String( RTL_CONSTASCII_USTRINGPARAM( "PowerPoint Document" ) ) );
199     if ( !mpStrm )
200         return;
201 
202     if ( !mpPicStrm )
203         mpPicStrm = mrStg->OpenSotStream( String( RTL_CONSTASCII_USTRINGPARAM( "Pictures" ) ) );
204 
205 	const String sBaseURI( RTL_CONSTASCII_USTRINGPARAM( "BaseURI" ) );
206 	std::vector< com::sun::star::beans::PropertyValue >::const_iterator aIter( rMediaData.begin() );
207 	while( aIter != rMediaData.end() )
208 	{
209 		if ( (*aIter).Name.equals( sBaseURI ) )
210 		{
211 			(*aIter).Value >>= maBaseURI;
212 			break;
213 		}
214 		aIter++;
215 	}
216     mpPptEscherEx = new PptEscherEx( *mpStrm, maBaseURI );
217 
218     if ( !ImplGetStyleSheets() )
219         return;
220 
221     if ( !ImplCreateDocument() )
222         return;
223 
224     for ( i = 0; i < mnMasterPages; i++ )
225     {
226         if ( !ImplCreateMaster( i ) )
227             return;
228     }
229 	if ( !ImplCreateMainNotes() )
230 		return;
231     for ( i = 0; i < mnPages; i++ )
232     {
233         if ( !ImplCreateSlide( i ) )
234             return;
235     }
236     for ( i = 0; i < mnPages; i++ )
237     {
238         if ( !ImplCreateNotes( i ) )
239             return;
240     }
241     if ( !ImplCloseDocument() )
242         return;
243 
244     if ( mbStatusIndicator )
245     {
246         mXStatusIndicator->setText( String( RTL_CONSTASCII_USTRINGPARAM( "PowerPoint Export" ) ) );
247         sal_uInt32 nValue = mnStatMaxValue + ( mnStatMaxValue >> 3 );
248         if ( nValue > mnLatestStatValue )
249         {
250             mXStatusIndicator->setValue( nValue );
251             mnLatestStatValue = nValue;
252         }
253     }
254 
255     ImplWriteOLE( nCnvrtFlags );
256 
257     ImplWriteVBA( pVBA );
258 
259     if ( !ImplWriteAtomEnding() )
260         return;
261 
262     if ( !ImplCreateDocumentSummaryInformation( nCnvrtFlags ) )
263         return;
264 
265     mbStatus = sal_True;
266 };
267 
268 
269 // ---------------------------------------------------------------------------------------------
270 
~PPTWriter()271 PPTWriter::~PPTWriter()
272 {
273     void*  pPtr;
274     delete mpExEmbed;
275     delete mpPptEscherEx;
276 	delete mpCurUserStrm;
277 	delete mpPicStrm;
278 	delete mpStrm;
279 
280 
281 
282 	std::vector< PPTExStyleSheet* >::iterator aStyleSheetIter( maStyleSheetList.begin() );
283 	while( aStyleSheetIter < maStyleSheetList.end() )
284 		delete *aStyleSheetIter++;
285 
286     for ( pPtr = maSlideNameList.First(); pPtr; pPtr = maSlideNameList.Next() )
287         delete (::rtl::OUString*)pPtr;
288     for ( pPtr = maHyperlink.First(); pPtr; pPtr = maHyperlink.Next() )
289         delete (EPPTHyperlink*)pPtr;
290     for ( pPtr = maExOleObj.First(); pPtr; pPtr = maExOleObj.Next() )
291         delete (PPTExOleObjEntry*)pPtr;
292 
293     if ( mbStatusIndicator )
294         mXStatusIndicator->end();
295 }
296 
297 // ---------------------------------------------------------------------------------------------
298 
PPTtoEMU(sal_Int32 nPPT)299 static inline sal_uInt32 PPTtoEMU( sal_Int32 nPPT )
300 {
301     return (sal_uInt32)( (double)nPPT * 1587.5 );
302 }
303 
304 // ---------------------------------------------------------------------------------------------
305 
ImplCreateCurrentUserStream()306 sal_Bool PPTWriter::ImplCreateCurrentUserStream()
307 {
308     mpCurUserStrm = mrStg->OpenSotStream( String( RTL_CONSTASCII_USTRINGPARAM( "Current User" ) ) );
309     if ( !mpCurUserStrm )
310         return sal_False;
311     char pUserName[] = "Current User";
312     sal_uInt32 nLenOfUserName = strlen( pUserName );
313     sal_uInt32 nSizeOfRecord = 0x14 + ( ( nLenOfUserName + 4 ) & ~ 3 );
314 
315     *mpCurUserStrm << (sal_uInt16)0 << (sal_uInt16)EPP_CurrentUserAtom << nSizeOfRecord;
316     *mpCurUserStrm << (sal_uInt32)0x14                  // Len
317                    << (sal_uInt32)0xe391c05f;           // Magic
318 
319     sal_uInt32 nEditPos = mpCurUserStrm->Tell();
320     *mpCurUserStrm << (sal_uInt32)0x0                   // OffsetToCurrentEdit;
321                    << (sal_uInt16)nLenOfUserName        //
322                    << (sal_uInt16)0x3f4                 // DocFileVersion
323                    << (sal_uInt8)3                      // MajorVersion
324                    << (sal_uInt8)0                      // MinorVersion
325                    << (sal_uInt16)0;                    // Pad Word
326     pUserName[ nLenOfUserName ] = 8;
327     mpCurUserStrm->Write( pUserName, nLenOfUserName + 1 );
328     for ( sal_uInt32 i = 0x15 + nLenOfUserName; i < nSizeOfRecord; i++ )
329     {
330         *mpCurUserStrm << (sal_uInt8)0;                 // pad bytes
331     };
332     mpCurUserStrm->Seek( nEditPos );
333     return sal_True;
334 };
335 
336 // ---------------------------------------------------------------------------------------------
337 
ImplCreateDocumentSummaryInformation(sal_uInt32 nCnvrtFlags)338 sal_Bool PPTWriter::ImplCreateDocumentSummaryInformation( sal_uInt32 nCnvrtFlags )
339 {
340     uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
341         mXModel, uno::UNO_QUERY_THROW);
342     uno::Reference<document::XDocumentProperties> xDocProps(
343         xDPS->getDocumentProperties());
344 
345     if (xDocProps.is()) {
346 
347         // no idea what this is...
348         static sal_uInt8 aGuid[ 0x52 ] =
349         {
350             0x4e, 0x00, 0x00, 0x00,
351             '{',0,'D',0,'B',0,'1',0,'A',0,'C',0,'9',0,'6',0,'4',0,'-',0,
352             'E',0,'3',0,'9',0,'C',0,'-',0,'1',0,'1',0,'D',0,'2',0,'-',0,
353             'A',0,'1',0,'E',0,'F',0,'-',0,'0',0,'0',0,'6',0,'0',0,'9',0,
354             '7',0,'D',0,'A',0,'5',0,'6',0,'8',0,'9',0,'}',0
355         };
356         uno::Sequence<sal_uInt8> aGuidSeq(aGuid, 0x52);
357 
358         SvMemoryStream  aHyperBlob;
359         ImplCreateHyperBlob( aHyperBlob );
360 
361         uno::Sequence<sal_uInt8> aHyperSeq(aHyperBlob.Tell());
362         const sal_uInt8* pBlob(
363             static_cast<const sal_uInt8*>(aHyperBlob.GetData()));
364         for (sal_Int32 j = 0; j < aHyperSeq.getLength(); ++j) {
365             aHyperSeq[j] = pBlob[j];
366         }
367 
368 		if ( nCnvrtFlags & 0x8000 )
369 		{
370 			uno::Sequence<sal_uInt8> aThumbSeq;
371 			if ( ImplGetPageByIndex( 0, NORMAL ) &&
372 				 ImplGetPropertyValue( mXPagePropSet,
373 					String( RTL_CONSTASCII_USTRINGPARAM( "PreviewBitmap" ) ) ) )
374 			{
375 				aThumbSeq =
376 					*static_cast<const uno::Sequence<sal_uInt8>*>(mAny.getValue());
377 			}
378 			sfx2::SaveOlePropertySet( xDocProps, mrStg,
379 					&aThumbSeq, &aGuidSeq, &aHyperSeq);
380 		}
381 		else
382 		{
383 			sfx2::SaveOlePropertySet( xDocProps, mrStg,
384 					NULL, &aGuidSeq, &aHyperSeq );
385 		}
386     }
387 
388     return sal_True;
389 }
390 
391 // ---------------------------------------------------------------------------------------------
392 
ImplWriteExtParaHeader(SvMemoryStream & rSt,sal_uInt32 nRef,sal_uInt32 nInstance,sal_uInt32 nSlideId)393 void PPTWriter::ImplWriteExtParaHeader( SvMemoryStream& rSt, sal_uInt32 nRef, sal_uInt32 nInstance, sal_uInt32 nSlideId )
394 {
395     if ( rSt.Tell() )
396     {
397         aBuExOutlineStream << (sal_uInt32)( ( EPP_PST_ExtendedParagraphHeaderAtom << 16 )
398                                 | ( nRef << 4 ) )
399                             << (sal_uInt32)8
400                             << (sal_uInt32)nSlideId
401                             << (sal_uInt32)nInstance;
402         aBuExOutlineStream.Write( rSt.GetData(), rSt.Tell() );
403     }
404 }
405 
406 // ---------------------------------------------------------------------------------------------
407 
ImplCreateHeaderFooterStrings(SvStream & rStrm,::com::sun::star::uno::Reference<::com::sun::star::beans::XPropertySet> & rXPagePropSet)408 void PPTWriter::ImplCreateHeaderFooterStrings( SvStream& rStrm, ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& rXPagePropSet )
409 {
410 	if ( rXPagePropSet.is() )
411 	{
412 		rtl::OUString aString;
413         ::com::sun::star::uno::Any aAny;
414         if ( PropValue::GetPropertyValue( aAny, rXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "HeaderText" ) ), sal_True ) )
415 		{
416             if ( aAny >>= aString )
417 				PPTWriter::WriteCString( rStrm, aString, 1 );
418 		}
419         if ( PropValue::GetPropertyValue( aAny, rXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FooterText" ) ), sal_True ) )
420 		{
421             if ( aAny >>= aString )
422 				PPTWriter::WriteCString( rStrm, aString, 2 );
423 		}
424         if ( PropValue::GetPropertyValue( aAny, rXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "DateTimeText" ) ), sal_True ) )
425 		{
426             if ( aAny >>= aString )
427 				PPTWriter::WriteCString( rStrm, aString, 0 );
428 		}
429 	}
430 }
431 
432 // ---------------------------------------------------------------------------------------------
433 
ImplCreateHeaderFooters(::com::sun::star::uno::Reference<::com::sun::star::beans::XPropertySet> & rXPagePropSet)434 void PPTWriter::ImplCreateHeaderFooters( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& rXPagePropSet )
435 {
436 	if ( rXPagePropSet.is() )
437 	{
438 		sal_Bool bVal = sal_False;
439 		sal_uInt32 nVal = 0;
440         ::com::sun::star::uno::Any aAny;
441         if ( PropValue::GetPropertyValue( aAny, rXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsHeaderVisible" ) ), sal_True ) )
442 		{
443 			if ( ( aAny >>= bVal ) && bVal )
444 				nVal |= 0x100000;
445 		}
446         if ( PropValue::GetPropertyValue( aAny, rXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsFooterVisible" ) ), sal_True ) )
447 		{
448 			if ( ( aAny >>= bVal ) && bVal )
449 				nVal |= 0x200000;
450 		}
451         if ( PropValue::GetPropertyValue( aAny, rXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsDateTimeVisible" ) ), sal_True ) )
452 		{
453 			if ( ( aAny >>= bVal ) && bVal )
454 				nVal |= 0x010000;
455 		}
456         if ( PropValue::GetPropertyValue( aAny, rXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsPageNumberVisible" ) ), sal_True ) )
457 		{
458 			if ( ( aAny >>= bVal ) && bVal )
459 				nVal |= 0x080000;
460 		}
461         if ( PropValue::GetPropertyValue( aAny, rXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsDateTimeFixed" ) ), sal_True ) )
462 		{
463 			if ( ( aAny >>= bVal ) && !bVal )
464 				nVal |= 0x20000;
465 			else
466 				nVal |= 0x40000;
467 		}
468 		if ( PropValue::GetPropertyValue( aAny, rXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "DateTimeFormat" ) ), sal_True ) )
469 		{
470 			sal_Int32 nFormat = *(sal_Int32*)aAny.getValue();
471 			SvxDateFormat eDateFormat = (SvxDateFormat)( nFormat & 0xf );
472 			SvxTimeFormat eTimeFormat = (SvxTimeFormat)( ( nFormat >> 4 ) & 0xf );
473 			switch( eDateFormat )
474 			{
475 				case SVXDATEFORMAT_F :
476 					nFormat = 1;
477 				break;
478 				case SVXDATEFORMAT_D :
479 					nFormat = 2;
480 				break;
481 				case SVXDATEFORMAT_C :
482 					nFormat = 4;
483 				break;
484 				default:
485 				case SVXDATEFORMAT_A :
486 					nFormat = 0;
487 			}
488 			switch( eTimeFormat )
489 			{
490 				case SVXTIMEFORMAT_24_HM :
491 					nFormat = 9;
492 				break;
493 				case SVXTIMEFORMAT_12_HM :
494 					nFormat = 11;
495 				break;
496 				case SVXTIMEFORMAT_24_HMS :
497 					nFormat = 10;
498 				break;
499 				case SVXTIMEFORMAT_12_HMS :
500 					nFormat = 12;
501 				break;
502 				default:
503 					break;
504 			}
505 			nVal |= nFormat;
506 		}
507 
508 		mpPptEscherEx->OpenContainer( EPP_HeadersFooters, 0 );
509 		mpPptEscherEx->AddAtom( 4, EPP_HeadersFootersAtom );
510 		*mpStrm << nVal;
511 		ImplCreateHeaderFooterStrings( *mpStrm, rXPagePropSet );
512 		mpPptEscherEx->CloseContainer();
513 	}
514 }
515 
516 // ---------------------------------------------------------------------------------------------
517 
ImplCreateDocument()518 sal_Bool PPTWriter::ImplCreateDocument()
519 {
520     sal_uInt32 i;
521     sal_uInt16 nSlideType = EPP_SLIDESIZE_TYPECUSTOM;
522 
523     sal_uInt32 nWidth = maDestPageSize.Width;
524     sal_uInt32 nHeight = maDestPageSize.Height;
525 
526     if ( ( nWidth == 0x1680 ) && ( nHeight == 0x10e0 ) )
527         nSlideType = EPP_SLIDESIZE_TYPEONSCREEN;
528     else if ( ( nWidth == 0x1200 ) && ( nHeight == 0x240 ) )
529         nSlideType = EPP_SLIDESIZE_TYPEBANNER;
530     else if ( ( nWidth == 0x1950 ) && ( nHeight == 0x10e0 ) )
531         nSlideType = EPP_SLIDESIZE_TYPE35MM;
532     else if ( ( nWidth == 0x1860 ) && ( nHeight == 0x10e0 ) )
533         nSlideType = EPP_SLIDESIZE_TYPEA4PAPER;
534 
535     mpPptEscherEx->OpenContainer( EPP_Document );
536     // CREATE DOCUMENT ATOM
537     mpPptEscherEx->AddAtom( 40, EPP_DocumentAtom, 1 );
538     *mpStrm << nWidth                           // Slide Size in Master coordinates X
539             << nHeight                          //   "     "   "    "        "      Y
540             << (sal_Int32)maNotesPageSize.Width     // Notes Page Size                  X
541             << (sal_Int32)maNotesPageSize.Height    //   "     "   "                    Y
542             << (sal_Int32)1 << (sal_Int32)2;            // the scale used when the PowerPoint document is embedded. the default is 1:2
543     mpPptEscherEx->InsertPersistOffset( EPP_MAINNOTESMASTER_PERSIST_KEY, mpStrm->Tell() );
544     *mpStrm << (sal_uInt32)0                        // Reference to NotesMaster ( 0 if none );
545             << (sal_uInt32)0                        // Reference to HandoutMaster ( 0 if none );
546             << (sal_Int16)1                         // Number of the first slide;
547             << nSlideType                           // Size of the document slides ( default: EPP_SLIDESIZETYPEONSCREEN )
548             << (sal_uInt8)0                         // bool1 indicates if document was saved with embedded true type fonts
549             << (sal_uInt8)0                         // bool1 indicates if the placeholders on the title slide are omitted
550             << (sal_uInt8)0                         // bool1 right to left ( flag for Bidi version )
551             << (sal_uInt8)1;                            // bool1 visibility of comments shapes
552 
553     mpPptEscherEx->PtInsert( EPP_Persist_Document, mpStrm->Tell() );
554 
555 	mpPptEscherEx->OpenContainer( EPP_HeadersFooters, 3 );	//Master footer	(default)
556 	mpPptEscherEx->AddAtom( 4, EPP_HeadersFootersAtom );
557 	*mpStrm << (sal_uInt32)0x25000d;
558     if ( ImplGetPageByIndex( 0, MASTER ) )
559 		ImplCreateHeaderFooterStrings( *mpStrm, mXPagePropSet );
560 	mpPptEscherEx->CloseContainer();
561 	mpPptEscherEx->OpenContainer( EPP_HeadersFooters, 4 );	//NotesMaster footer (default)
562 	mpPptEscherEx->AddAtom( 4, EPP_HeadersFootersAtom );
563 	*mpStrm << (sal_uInt32)0x3d000d;
564     if ( ImplGetPageByIndex( 0, NOTICE ) )
565 		ImplCreateHeaderFooterStrings( *mpStrm, mXPagePropSet );
566 	mpPptEscherEx->CloseContainer();
567 
568     mpPptEscherEx->OpenContainer( EPP_SlideListWithText );      // Animation info fuer die Slides
569 
570     for ( i = 0; i < mnPages; i++ )
571     {
572         mpPptEscherEx->AddAtom( 20, EPP_SlidePersistAtom );
573         mpPptEscherEx->InsertPersistOffset( EPP_MAINSLIDE_PERSIST_KEY | i, mpStrm->Tell() );
574         *mpStrm << (sal_uInt32)0								// psrReference - logical reference to the slide persist object ( EPP_MAINSLIDE_PERSIST_KEY )
575 				<< (sal_uInt32)4                                // flags - only bit 3 used, if set then slide contains shapes other than placeholders
576                 << (sal_Int32)0                                     // numberTexts - number of placeholder texts stored with the persist object.  Allows to display outline view without loading the slide persist objects
577                 << (sal_Int32)i + 0x100                             // slideId - Unique slide identifier, used for OLE link monikers for example
578                 << (sal_uInt32)0;                               // reserved, usually 0
579 
580         if ( !ImplGetPageByIndex( i, NORMAL ) )                 // sehr aufregend: noch einmal ueber alle seiten
581             return sal_False;
582 		ImplSetCurrentStyleSheet( ImplGetMasterIndex( NORMAL ) );
583 
584         ::com::sun::star::uno::Reference< ::com::sun::star::container::XNamed >
585             aXName( mXDrawPage, ::com::sun::star::uno::UNO_QUERY );
586 
587         if ( aXName.is() )
588         {
589             ::rtl::OUString aStr = aXName->getName();
590             ::rtl::OUString *pUStr = new ::rtl::OUString( aStr );
591             maSlideNameList.Insert( pUStr, LIST_APPEND );
592         }
593         else
594             maSlideNameList.Insert( new ::rtl::OUString(), LIST_APPEND );
595     }
596     mpPptEscherEx->CloseContainer();    // EPP_SlideListWithText
597 
598     mpPptEscherEx->OpenContainer( EPP_SlideListWithText, 2 );   // Animation info fuer die notes
599     for( i = 0; i < mnPages; i++ )
600     {
601         mpPptEscherEx->AddAtom( 20, EPP_SlidePersistAtom );
602         mpPptEscherEx->InsertPersistOffset( EPP_MAINNOTES_PERSIST_KEY | i, mpStrm->Tell() );
603         *mpStrm << (sal_uInt32)0
604                 << (sal_uInt32)4
605                 << (sal_Int32)0
606                 << (sal_Int32)i + 0x100
607                 << (sal_uInt32)0;
608     }
609     mpPptEscherEx->CloseContainer();        // EPP_SlideListWithText
610 
611     ::com::sun::star::uno::Reference< ::com::sun::star::presentation::XPresentationSupplier >
612         aXPresSupplier( mXModel, ::com::sun::star::uno::UNO_QUERY );            ;
613     if ( aXPresSupplier.is() )
614     {
615         ::com::sun::star::uno::Reference< ::com::sun::star::presentation::XPresentation >
616             aXPresentation( aXPresSupplier->getPresentation() );
617         if ( aXPresentation.is() )
618         {
619             mXPropSet = ::com::sun::star::uno::Reference<
620                 ::com::sun::star::beans::XPropertySet >
621                     ( aXPresentation, ::com::sun::star::uno::UNO_QUERY );
622             if ( mXPropSet.is() )
623             {
624                 ::rtl::OUString aCustomShow;
625                 sal_uInt32  nPenColor = 0x1000000;
626                 sal_Int32   nRestartTime = 0x7fffffff;
627                 sal_Int16   nStartSlide = 0;
628                 sal_Int16   nEndSlide = 0;
629                 sal_uInt32  nFlags = 0;             // Bit 0:   Auto advance
630                                                     // Bit 1    Skip builds ( do not allow slide effects )
631                                                     // Bit 2    Use slide range
632                                                     // Bit 3    Use named show
633                                                     // Bit 4    Browse mode on
634                                                     // Bit 5    Kiosk mode on
635                                                     // Bit 7    loop continuously
636                                                     // Bit ?    show scrollbar
637 
638                 if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "CustomShow" ) ) ) )
639                 {
640                     aCustomShow = ( *(::rtl::OUString*)mAny.getValue() );
641                     if ( aCustomShow.getLength() )
642                     {
643                         nFlags |= 8;
644                     }
645                 }
646                 if ( ( nFlags & 8 ) == 0 )
647                 {
648                     if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "FirstPage" ) ) ) )
649                     {
650                         ::rtl::OUString aSlideName( *(::rtl::OUString*)mAny.getValue() );
651                         ::rtl::OUString* pStr;
652                         for ( pStr = (::rtl::OUString*)maSlideNameList.First(); pStr;
653                                     pStr = (::rtl::OUString*)maSlideNameList.Next(), nStartSlide++ )
654                         {
655                             if ( *pStr == aSlideName )
656                             {
657                                 nStartSlide++;
658                                 nFlags |= 4;
659                                 nEndSlide = (sal_uInt16)mnPages;
660                                 break;
661                             }
662                         }
663                         if ( !pStr )
664                             nStartSlide = 0;
665                     }
666                 }
667 
668 //              if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "DiaName" ) ) ) )
669 //              {
670 //              }
671 //              if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "IsAlwaysOnTop" ) ) ) )
672 //              {
673 //              }
674                 if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "IsAutomatic" ) ) ) )
675                 {
676                     sal_Bool bBool = sal_False;
677                     mAny >>= bBool;
678                     if ( !bBool )
679                         nFlags |= 1;
680                 }
681 
682                 if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "IsEndless" ) ) ) ) // muesste eigendlich heissen IsNotEndless !=)"�()&
683                 {
684                     sal_Bool bBool = sal_False;
685                     mAny >>= bBool;
686                     if ( bBool )
687                         nFlags |= 0x80;
688                 }
689                 if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "IsFullScreen" ) ) ) )
690                 {
691                     sal_Bool bBool = sal_False;
692                     mAny >>= bBool;
693                     if ( !bBool )
694                         nFlags |= 0x11;
695                 }
696 //              if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "IsMouseVisible" ) ) ) )
697 //              {
698 //              }
699 //              if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "PageRange" ) ) ) )
700 //              {
701 //              }
702 //              if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "StartWithNavigator" ) ) ) )
703 //              {
704 //              }
705 //              if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "UsePen" ) ) ) )
706 //              {
707 //              }
708                 mpPptEscherEx->AddAtom( 80, EPP_SSDocInfoAtom, 1 );
709                 *mpStrm << nPenColor << nRestartTime << nStartSlide << nEndSlide;
710 
711                 sal_uInt32 nCustomShowNameLen = aCustomShow.getLength();
712                 if ( nCustomShowNameLen > 31 )
713                     nCustomShowNameLen = 31;
714                 if ( nCustomShowNameLen )       // named show identifier
715                 {
716                     const sal_Unicode* pCustomShow = aCustomShow.getStr();
717                     for ( i = 0; i < nCustomShowNameLen; i++ )
718                     {
719                         *mpStrm << (sal_uInt16)( pCustomShow[ i ] );
720                     }
721                 }
722                 for ( i = nCustomShowNameLen; i < 32; i++, *mpStrm << (sal_uInt16)0 ) ;
723 
724                 *mpStrm << nFlags;
725                 ::com::sun::star::uno::Reference< ::com::sun::star::presentation::XCustomPresentationSupplier >
726                     aXCPSup( mXModel, ::com::sun::star::uno::UNO_QUERY );
727                 if ( aXCPSup.is() )
728                 {
729                     ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >
730                         aXCont( aXCPSup->getCustomPresentations() );
731                     if ( aXCont.is() )
732                     {
733                         ::com::sun::star::uno::Sequence< ::rtl::OUString> aNameSeq( aXCont->getElementNames() );
734                         const ::rtl::OUString* pUString = aNameSeq.getArray();
735                         sal_uInt32 nCount = aNameSeq.getLength();
736                         if ( nCount )
737                         {
738                             mpPptEscherEx->OpenContainer( EPP_NamedShows );
739                             sal_uInt32 nCustomShowIndex = 0;
740                             for( i = 0; i < nCount; i++ )        // Anzahl der Custom Shows
741                             {
742                                 if ( pUString[ i ].getLength() )
743                                 {
744                                     mpPptEscherEx->OpenContainer( EPP_NamedShow, nCustomShowIndex++ );
745 
746                                     sal_uInt32 nNamedShowLen = pUString[ i ].getLength();
747                                     if ( nNamedShowLen > 31 )
748                                         nNamedShowLen = 31;
749                                     mpPptEscherEx->AddAtom( nNamedShowLen << 1, EPP_CString );
750                                     const sal_Unicode* pCustomShowName = pUString[ i ].getStr();
751                                     for ( sal_uInt32 k = 0; k < nNamedShowLen; *mpStrm << (sal_uInt16)( pCustomShowName[ k++ ] ) ) ;
752                                     mAny = aXCont->getByName( pUString[ i ] );
753                                     if ( mAny.getValue() )
754                                     {
755 
756                                         ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer > aXIC;
757                                         if ( mAny >>= aXIC )
758                                         {
759                                             mpPptEscherEx->BeginAtom();
760 
761                                             sal_Int32 nSlideCount = aXIC->getCount();
762                                             for ( sal_Int32 j = 0; j < nSlideCount; j++ )   // Anzahl der Slides
763                                             {
764                                                 mAny = aXIC->getByIndex( j );
765                                                 if ( mAny.getValue() )
766                                                 {
767                                                     ::com::sun::star::uno::Reference<
768                                                         ::com::sun::star::drawing::XDrawPage > aXDrawPage;
769                                                     if ( mAny >>= aXDrawPage )
770                                                     {
771                                                         ::com::sun::star::uno::Reference<
772                                                             ::com::sun::star::container::XNamed >
773                                                             aXName( aXDrawPage, ::com::sun::star::uno::UNO_QUERY );
774                                                         if ( aXName.is() )
775                                                         {
776                                                             ::rtl::OUString aSlideName( aXName->getName() );
777                                                             sal_uInt32 nPageNumber = 0;
778                                                             for ( ::rtl::OUString* pSlideName = (::rtl::OUString*)maSlideNameList.First();
779                                                                 pSlideName;
780                                                                 pSlideName = (::rtl::OUString*)maSlideNameList.Next(), nPageNumber++ )
781                                                             {
782                                                                 if ( *pSlideName == aSlideName )
783                                                                 {
784                                                                     *mpStrm << (sal_uInt32)( nPageNumber + 0x100 ); // unique slide id
785                                                                     break;
786                                                                 }
787                                                             }
788                                                         }
789                                                     }
790                                                 }
791                                             }
792                                             mpPptEscherEx->EndAtom( EPP_NamedShowSlides );
793                                         }
794                                     }
795                                     mpPptEscherEx->CloseContainer();            // EPP_NamedShow
796                                 }
797                             }
798                             mpPptEscherEx->CloseContainer();                // EPP_NamedShows
799                         }
800                     }
801                 }
802             }
803         }
804     }
805     mpPptEscherEx->AddAtom( 0, EPP_EndDocument );
806     mpPptEscherEx->CloseContainer();    // EPP_Document
807     return sal_True;
808 };
809 
810 // ---------------------------------------------------------------------------------------------
811 
ImplCreateHyperBlob(SvMemoryStream & rStrm)812 sal_Bool PPTWriter::ImplCreateHyperBlob( SvMemoryStream& rStrm )
813 {
814     sal_uInt32 nCurrentOfs, nParaOfs, nParaCount = 0;
815 // SfxOlePropertySection does this...
816 //    rStrm << (sal_uInt32)0x41;      // property type VT_BLOB
817     nParaOfs = rStrm.Tell();
818     rStrm << (sal_uInt32)0;         // property size
819     rStrm << (sal_uInt32)0;         // property count
820 
821     for ( EPPTHyperlink* pLink = (EPPTHyperlink*)maHyperlink.First(); pLink; pLink = (EPPTHyperlink*)maHyperlink.Next() )
822     {
823         nParaCount += 6;
824         rStrm   << (sal_uInt32)3    // Type VT_I4
825                 << (sal_uInt32)7    // (VTI4 - Private1)
826                 << (sal_uInt32)3    // Type VT_I4
827                 << (sal_uInt32)6    // (VTI4 - Private2)
828                 << (sal_uInt32)3    // Type VT_I4
829                 << (sal_uInt32)0;   // (VTI4 - Private3)
830 
831         // INFO
832         // HIWORD:  = 0 : do not change anything
833         //          = 1 : replace the hyperlink with the target and subadress in the following two VTLPWSTR
834         //          = 2 : delete the hyperlink
835         // LOWORD:  = 0 : graphic shown as background (link)
836         //          = 1 : graphic shown as shape (link)
837         //          = 2 : graphic is used to fill a shape
838         //          = 3 : graphic used to fill a shape outline (future use)
839         //          = 4 : hyperlink attached to a shape
840         //          = 5 :    "         "      " " (Word) field
841         //          = 6 :    "         "      " " (Excel) range
842         //          = 7 :    "         "      " " (PPT) text range
843         //          = 8 :    "         "      " " (Project) task
844 
845         sal_uInt32 nUrlLen = pLink->aURL.Len();
846         const sal_Unicode* pUrl = pLink->aURL.GetBuffer();
847 
848         sal_uInt32 nInfo = 7;
849 
850         rStrm   << (sal_uInt32)3    // Type VT_I4
851                 << nInfo;       // Info
852 
853         switch( pLink->nType & 0xff )
854         {
855             case 1 :        // click action to slidenumber
856             {
857                 rStrm << (sal_uInt32)0x1f << (sal_uInt32)1 << (sal_uInt32)0;    // path
858                 rStrm << (sal_uInt32)0x1f << (sal_uInt32)( nUrlLen + 1 );
859                 for ( sal_uInt32 i = 0; i < nUrlLen; i++ )
860                 {
861                     rStrm << pUrl[ i ];
862                 }
863                 rStrm << (sal_uInt16)0;
864             }
865             break;
866             case 2 :
867             {
868                 sal_uInt32 i;
869 
870                 rStrm   << (sal_uInt32)0x1f
871                         << (sal_uInt32)( nUrlLen + 1 );
872                 for ( i = 0; i < nUrlLen; i++ )
873                 {
874                     rStrm << pUrl[ i ];
875                 }
876                 if ( ! ( i & 1 ) )
877                     rStrm << (sal_uInt16)0;
878                 rStrm   << (sal_uInt16)0
879                         << (sal_uInt32)0x1f
880                         << (sal_uInt32)1
881                         << (sal_uInt32)0;
882             }
883             break;
884         }
885     }
886     nCurrentOfs = rStrm.Tell();
887     rStrm.Seek( nParaOfs );
888     rStrm << (sal_uInt32)( nCurrentOfs - ( nParaOfs + 4 ) );
889     rStrm << nParaCount;
890     rStrm.Seek( nCurrentOfs );
891     return sal_True;
892 }
893 
ImplGetLayout(const::com::sun::star::uno::Reference<::com::sun::star::beans::XPropertySet> & rXPropSet) const894 PHLayout& PPTWriter::ImplGetLayout(  const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& rXPropSet ) const
895 {
896     ::com::sun::star::uno::Any aAny;
897     sal_Int16 nLayout = 20;
898     if ( GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Layout" ) ) ), sal_True )
899         aAny >>= nLayout;
900 
901     if ( ( nLayout >= 21 ) && ( nLayout <= 26 ) )   // NOTES _> HANDOUT6
902         nLayout = 20;
903     if ( ( nLayout >= 27 ) && ( nLayout <= 30 ) )   // VERTICAL LAYOUT
904         nLayout -= 6;
905     else if ( nLayout > 30 )
906         nLayout = 20;
907     return pPHLayout[ nLayout ];
908 }
909 
910 
911 // ---------------------------------------------------------------------------------------------
912 
ImplCreateMaster(sal_uInt32 nPageNum)913 sal_Bool PPTWriter::ImplCreateMaster( sal_uInt32 nPageNum )
914 {
915     if ( !ImplGetPageByIndex( nPageNum, MASTER ) )
916         return sal_False;
917 	ImplSetCurrentStyleSheet( nPageNum );
918 
919     if ( !ImplGetPropertyValue( mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Background" ) ) ) )                // Backgroundshape laden
920         return sal_False;
921     ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > aXBackgroundPropSet;
922     if ( !( mAny >>= aXBackgroundPropSet ) )
923         return sal_False;
924 
925     sal_uInt32 nFillColor = 0xffffff;
926     sal_uInt32 nFillBackColor = 0x000000;
927 
928     ::com::sun::star::drawing::FillStyle aFS = ::com::sun::star::drawing::FillStyle_NONE;
929     if ( ImplGetPropertyValue( aXBackgroundPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillStyle" ) ) ) )
930         mAny >>= aFS;
931     switch ( aFS )
932     {
933         case ::com::sun::star::drawing::FillStyle_GRADIENT :
934         {
935             if ( ImplGetPropertyValue( aXBackgroundPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillGradient" ) ) ) )
936             {
937                 nFillColor = EscherPropertyContainer::GetGradientColor( (::com::sun::star::awt::Gradient*)mAny.getValue(), 0 );
938                 nFillBackColor = EscherPropertyContainer::GetGradientColor( (::com::sun::star::awt::Gradient*)mAny.getValue(), 1 );
939             }
940         }
941         break;
942 
943         case ::com::sun::star::drawing::FillStyle_SOLID :
944         {
945             if ( ImplGetPropertyValue( aXBackgroundPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillColor" ) ) ) )
946             {
947                 nFillColor = mpPptEscherEx->GetColor( *((sal_uInt32*)mAny.getValue()) );
948                 nFillBackColor = nFillColor ^ 0xffffff;
949             }
950         }
951 		break;
952 
953 		default:
954 			break;
955     }
956 
957     mpPptEscherEx->PtReplaceOrInsert( EPP_Persist_MainMaster | nPageNum, mpStrm->Tell() );
958     mpPptEscherEx->OpenContainer( EPP_MainMaster );
959     mpPptEscherEx->AddAtom( 24, EPP_SlideAtom, 2 );
960     *mpStrm << (sal_Int32)EPP_LAYOUT_TITLEANDBODYSLIDE  // slide layout -> title and body slide
961             << (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
962             << (sal_uInt32)0		// master ID ( ist gleich null bei einer masterpage )
963             << (sal_uInt32)0        // notes ID ( ist gleich null wenn keine notizen vorhanden )
964             << (sal_uInt16)0        // Bit 1: Follow master objects, Bit 2: Follow master scheme, Bit 3: Follow master background
965             << (sal_uInt16)0;       // padword
966 
967     mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 6 );
968     *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;
969     mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 6 );
970     *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;
971     mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 6 );
972     *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;
973     mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 6 );
974     *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;
975     mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 6 );
976     *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;
977     mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 6 );
978     *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;
979     mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 6 );
980     *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;
981 
982     for ( int nInstance = EPP_TEXTTYPE_Title; nInstance <= EPP_TEXTTYPE_QuarterBody; nInstance++ )
983     {
984         if ( nInstance == EPP_TEXTTYPE_notUsed )
985             continue;
986 
987         // the auto color is dependent to the page background,so we have to set a page that is in the right context
988         if ( nInstance == EPP_TEXTTYPE_Notes )
989             ImplGetPageByIndex( 0, NOTICE );
990         else
991             ImplGetPageByIndex( 0, MASTER );
992 
993         mpPptEscherEx->BeginAtom();
994 
995         sal_Bool bFirst = sal_True;
996         sal_Bool bSimpleText = sal_False;
997 
998         *mpStrm << (sal_uInt16)5;                           // paragraph count
999 
1000         for ( sal_uInt16 nLev = 0; nLev < 5; nLev++ )
1001         {
1002             if ( nInstance >= EPP_TEXTTYPE_CenterBody )
1003             {
1004                 bFirst = sal_False;
1005                 bSimpleText = sal_True;
1006                 *mpStrm << nLev;
1007             }
1008             mpStyleSheet->mpParaSheet[ nInstance ]->Write( *mpStrm, mpPptEscherEx, nLev, bFirst, bSimpleText, mXPagePropSet );
1009             mpStyleSheet->mpCharSheet[ nInstance ]->Write( *mpStrm, mpPptEscherEx, nLev, bFirst, bSimpleText, mXPagePropSet );
1010             bFirst = sal_False;
1011         }
1012         mpPptEscherEx->EndAtom( EPP_TxMasterStyleAtom, 0, nInstance );
1013     }
1014     ImplGetPageByIndex( nPageNum, MASTER );
1015 
1016     EscherSolverContainer aSolverContainer;
1017 
1018     mpPptEscherEx->OpenContainer( EPP_PPDrawing );
1019     mpPptEscherEx->OpenContainer( ESCHER_DgContainer );
1020 
1021 	mpPptEscherEx->EnterGroup(0,0);
1022     ImplWritePage( pPHLayout[ 0 ], aSolverContainer, MASTER, sal_True );    // Die Shapes der Seite werden im PPT Dok. erzeugt
1023     mpPptEscherEx->LeaveGroup();
1024 
1025     ImplWriteBackground( aXBackgroundPropSet );
1026 
1027     aSolverContainer.WriteSolver( *mpStrm );
1028 
1029     mpPptEscherEx->CloseContainer();    // ESCHER_DgContainer
1030     mpPptEscherEx->CloseContainer();    // EPP_Drawing
1031     mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 1 );
1032     *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;
1033 
1034 	if ( aBuExMasterStream.Tell() )
1035     {
1036         ImplProgTagContainer( mpStrm, &aBuExMasterStream );
1037     }
1038     mpPptEscherEx->CloseContainer();    // EPP_MainMaster
1039     return sal_True;
1040 };
1041 
1042 // ---------------------------------------------------------------------------------------------
1043 
ImplCreateMainNotes()1044 sal_Bool PPTWriter::ImplCreateMainNotes()
1045 {
1046     if ( !ImplGetPageByIndex( 0, NOTICE ) )
1047         return sal_False;
1048 	ImplSetCurrentStyleSheet( 0 );
1049 
1050     ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XMasterPageTarget >
1051         aXMasterPageTarget( mXDrawPage, ::com::sun::star::uno::UNO_QUERY );
1052 
1053     if ( !aXMasterPageTarget.is() )
1054         return sal_False;
1055 
1056     mXDrawPage = aXMasterPageTarget->getMasterPage();
1057     if ( !mXDrawPage.is() )
1058         return sal_False;
1059 
1060     mXPropSet = ::com::sun::star::uno::Reference<
1061         ::com::sun::star::beans::XPropertySet >
1062             ( mXDrawPage, ::com::sun::star::uno::UNO_QUERY );
1063     if ( !mXPropSet.is() )
1064         return sal_False;
1065 
1066     mXShapes = ::com::sun::star::uno::Reference<
1067         ::com::sun::star::drawing::XShapes >
1068             ( mXDrawPage, ::com::sun::star::uno::UNO_QUERY );
1069     if ( !mXShapes.is() )
1070         return sal_False;
1071 
1072     EscherSolverContainer aSolverContainer;
1073 
1074     mpPptEscherEx->PtReplaceOrInsert( EPP_Persist_MainNotes, mpStrm->Tell() );
1075     mpPptEscherEx->OpenContainer( EPP_Notes );
1076     mpPptEscherEx->AddAtom( 8, EPP_NotesAtom, 1 );
1077     *mpStrm << (sal_uInt32)0x80000001                                               // Number that identifies this slide
1078             << (sal_uInt32)0;                                                       // follow nothing
1079     mpPptEscherEx->OpenContainer( EPP_PPDrawing );
1080     mpPptEscherEx->OpenContainer( ESCHER_DgContainer );
1081     mpPptEscherEx->EnterGroup(0,0);
1082 
1083     ImplWritePage( pPHLayout[ 20 ], aSolverContainer, NOTICE, sal_True );
1084 
1085     mpPptEscherEx->LeaveGroup();
1086     mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
1087     mpPptEscherEx->AddShape( ESCHER_ShpInst_Rectangle, 0xc00 );
1088     EscherPropertyContainer aPropOpt;
1089     aPropOpt.AddOpt( ESCHER_Prop_fillColor, 0xffffff );								// stock valued fill color
1090     aPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0 );
1091     aPropOpt.AddOpt( ESCHER_Prop_fillRectRight, 0x68bdde );
1092     aPropOpt.AddOpt( ESCHER_Prop_fillRectBottom, 0x8b9f8e );
1093     aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x120012 );
1094     aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0 );
1095     aPropOpt.AddOpt( ESCHER_Prop_bWMode, ESCHER_wDontShow );
1096     aPropOpt.AddOpt( ESCHER_Prop_fBackground, 0x10001 );							// if true, this is the background shape
1097     aPropOpt.Commit( *mpStrm );
1098     mpPptEscherEx->CloseContainer();    // ESCHER_SpContainer
1099 
1100     aSolverContainer.WriteSolver( *mpStrm );
1101 
1102     mpPptEscherEx->CloseContainer();    // ESCHER_DgContainer
1103     mpPptEscherEx->CloseContainer();    // EPP_Drawing
1104     mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 1 );
1105     *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;
1106     mpPptEscherEx->CloseContainer();    // EPP_Notes
1107     return sal_True;
1108 }
1109 
1110 // ---------------------------------------------------------------------------------------------
1111 
getInitials(const rtl::OUString & rName)1112 static rtl::OUString getInitials( const rtl::OUString& rName )
1113 {
1114 	rtl::OUString sInitials;
1115 
1116 	const sal_Unicode * pStr = rName.getStr();
1117 	sal_Int32 nLength = rName.getLength();
1118 
1119 	while( nLength )
1120 	{
1121 		// skip whitespace
1122 		while( nLength && (*pStr <= ' ') )
1123 		{
1124 			nLength--; pStr++;
1125 		}
1126 
1127 		// take letter
1128 		if( nLength )
1129 		{
1130 			sInitials += rtl::OUString( *pStr );
1131 			nLength--; pStr++;
1132 		}
1133 
1134 		// skip letters until whitespace
1135 		while( nLength && (*pStr > ' ') )
1136 		{
1137 			nLength--; pStr++;
1138 		}
1139 	}
1140 
1141 	return sInitials;
1142 }
1143 
ImplExportComments(uno::Reference<drawing::XDrawPage> xPage,SvMemoryStream & rBinaryTagData10Atom)1144 void ImplExportComments( uno::Reference< drawing::XDrawPage > xPage, SvMemoryStream& rBinaryTagData10Atom )
1145 {
1146 	try
1147 	{
1148 		uno::Reference< office::XAnnotationAccess > xAnnotationAccess( xPage, uno::UNO_QUERY_THROW );
1149 		uno::Reference< office::XAnnotationEnumeration > xAnnotationEnumeration( xAnnotationAccess->createAnnotationEnumeration() );
1150 
1151 		sal_Int32 nIndex = 1;
1152 
1153 		while( xAnnotationEnumeration->hasMoreElements() )
1154 		{
1155 			EscherExContainer aComment10( rBinaryTagData10Atom, EPP_Comment10 );
1156 			{
1157 				uno::Reference< office::XAnnotation > xAnnotation( xAnnotationEnumeration->nextElement() );
1158 
1159 				geometry::RealPoint2D aRealPoint2D( xAnnotation->getPosition() );
1160 				MapMode aMapDest( MAP_INCH, Point(), Fraction( 1, 576 ), Fraction( 1, 576 ) );
1161 				Point aPoint( OutputDevice::LogicToLogic( Point( static_cast< sal_Int32 >( aRealPoint2D.X * 100.0 ),
1162 					static_cast< sal_Int32 >( aRealPoint2D.Y * 100.0 ) ), MAP_100TH_MM, aMapDest ) );
1163 
1164 				rtl::OUString sAuthor( xAnnotation->getAuthor() );
1165 				uno::Reference< text::XText > xText( xAnnotation->getTextRange() );
1166 				rtl::OUString sText( xText->getString() );
1167 				rtl::OUString sInitials( getInitials( sAuthor ) );
1168 				util::DateTime aDateTime( xAnnotation->getDateTime() );
1169 				if ( sAuthor.getLength() )
1170 					PPTWriter::WriteCString( rBinaryTagData10Atom, sAuthor, 0 );
1171 				if ( sText.getLength() )
1172 					PPTWriter::WriteCString( rBinaryTagData10Atom, sText, 1 );
1173 				if ( sInitials.getLength() )
1174 					PPTWriter::WriteCString( rBinaryTagData10Atom, sInitials, 2 );
1175 
1176 				sal_Int16 nMilliSeconds = aDateTime.HundredthSeconds * 10;
1177 				EscherExAtom aCommentAtom10( rBinaryTagData10Atom, EPP_CommentAtom10 );
1178 				rBinaryTagData10Atom << nIndex++
1179 									 << aDateTime.Year
1180 									 << aDateTime.Month
1181 									 << aDateTime.Day	// todo: day of week
1182 									 << aDateTime.Day
1183 									 << aDateTime.Hours
1184 									 << aDateTime.Minutes
1185 									 << aDateTime.Seconds
1186 									 << nMilliSeconds
1187 									 << static_cast< sal_Int32 >( aPoint.X() )
1188 									 << static_cast< sal_Int32 >( aPoint.Y() );
1189 			}
1190 		}
1191 	}
1192 	catch ( uno::Exception& )
1193 	{
1194 	}
1195 }
1196 
1197 // ---------------------------------------------------------------------------------------------
1198 
ImplCreateSlide(sal_uInt32 nPageNum)1199 sal_Bool PPTWriter::ImplCreateSlide( sal_uInt32 nPageNum )
1200 {
1201     ::com::sun::star::uno::Any aAny;
1202 
1203     if ( !ImplGetPageByIndex( nPageNum, NORMAL ) )
1204         return sal_False;
1205     sal_uInt32 nMasterID = ImplGetMasterIndex( NORMAL );
1206 	ImplSetCurrentStyleSheet( nMasterID );
1207 	nMasterID |= 0x80000000;
1208 
1209     ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > aXBackgroundPropSet;
1210     sal_Bool bHasBackground = GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Background" ) ) );
1211     if ( bHasBackground )
1212         bHasBackground = ( aAny >>= aXBackgroundPropSet );
1213 
1214 	sal_uInt16 nMode = 7;   // Bit 1: Follow master objects, Bit 2: Follow master scheme, Bit 3: Follow master background
1215 	if ( bHasBackground )
1216 		nMode &=~4;
1217 
1218 /* sj: Don't know what's IsBackgroundVisible for, have to ask cl
1219 	if ( GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsBackgroundVisible" ) ) ) )
1220 	{
1221 		sal_Bool bBackgroundVisible;
1222         if ( aAny >>= bBackgroundVisible )
1223 		{
1224 			if ( bBackgroundVisible )
1225 				nMode &= ~4;
1226 		}
1227 	}
1228 */
1229 	if ( GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsBackgroundObjectsVisible" ) ) ) )
1230 	{
1231 		sal_Bool bBackgroundObjectsVisible = sal_False;
1232         if ( aAny >>= bBackgroundObjectsVisible )
1233 		{
1234 			if ( !bBackgroundObjectsVisible )
1235 				nMode &= ~1;
1236 		}
1237 	}
1238 
1239     const PHLayout& rLayout = ImplGetLayout( mXPagePropSet );
1240     mpPptEscherEx->PtReplaceOrInsert( EPP_Persist_Slide | nPageNum, mpStrm->Tell() );
1241     mpPptEscherEx->OpenContainer( EPP_Slide );
1242     mpPptEscherEx->AddAtom( 24, EPP_SlideAtom, 2 );
1243     *mpStrm << rLayout.nLayout;
1244     mpStrm->Write( rLayout.nPlaceHolder, 8 );       // placeholderIDs ( 8Stueck )
1245     *mpStrm << (sal_uInt32)nMasterID                // master ID ( ist gleich 0x80000000 bei einer masterpage   )
1246             << (sal_uInt32)nPageNum + 0x100         // notes ID ( ist gleich null wenn keine notizen vorhanden )
1247             << nMode
1248             << (sal_uInt16)0;                       // padword
1249 
1250     mnDiaMode = 0;
1251     sal_Bool bVisible = sal_True;
1252     ::com::sun::star::presentation::FadeEffect eFe = ::com::sun::star::presentation::FadeEffect_NONE;
1253 
1254     if ( GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Visible" ) ) ) )
1255         aAny >>= bVisible;
1256     if ( GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Change" ) ) ) )
1257     {
1258         switch ( *(sal_Int32*)aAny.getValue() )
1259         {
1260             case 1 :        // automatisch
1261                 mnDiaMode++;
1262             case 2 :        // halbautomatisch
1263                 mnDiaMode++;
1264             default :
1265             case 0 :        // manuell
1266             break;
1267         }
1268     }
1269     if ( GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Effect" ) ) ) )
1270         aAny >>= eFe;
1271 
1272     sal_uInt32  nSoundRef = 0;
1273     sal_Bool    bIsSound = sal_False;
1274 	sal_Bool	bStopSound = sal_False;
1275 	sal_Bool	bLoopSound = sal_False;
1276 
1277 	if ( GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Sound" ) ) ) )
1278 	{
1279 		rtl::OUString aSoundURL;
1280 		if ( aAny >>= aSoundURL )
1281 		{
1282 	        nSoundRef = maSoundCollection.GetId( aSoundURL );
1283 			bIsSound = sal_True;
1284 		}
1285 		else
1286 			aAny >>= bStopSound;
1287 	}
1288 	if ( GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "LoopSound" ) ) ) )
1289 		aAny >>= bLoopSound;
1290 
1291 
1292     sal_Bool bNeedsSSSlideInfoAtom = ( bVisible == sal_False )
1293                                     || ( mnDiaMode == 2 )
1294                                     || ( bIsSound )
1295 									|| ( bStopSound )
1296                                     || ( eFe != ::com::sun::star::presentation::FadeEffect_NONE );
1297     if ( bNeedsSSSlideInfoAtom )
1298     {
1299         sal_uInt8   nDirection = 0;
1300         sal_uInt8   nTransitionType = 0;
1301         sal_uInt16  nBuildFlags = 1;        // advange by mouseclick
1302         sal_Int32       nSlideTime = 0;         // muss noch !!!
1303         sal_uInt8   nSpeed = 1;
1304 
1305         if ( GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Speed" ) ) ) )
1306         {
1307             ::com::sun::star::presentation::AnimationSpeed aAs;
1308             aAny >>= aAs;
1309             nSpeed = (sal_uInt8)aAs;
1310         }
1311 		sal_Int16 nTT = 0, nTST = 0;
1312 		if ( GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TransitionType" ) ) )
1313 			&& ( aAny >>= nTT ) )
1314 		{
1315 			if ( GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TransitionSubtype" ) ) )
1316 				&& ( aAny >>= nTST ) )
1317 			{
1318 				switch( nTT )
1319 				{
1320 					case animations::TransitionType::FADE :
1321 					{
1322 						if ( nTST == animations::TransitionSubType::CROSSFADE )
1323 							nTransitionType = PPT_TRANSITION_TYPE_SMOOTHFADE;
1324 						else if ( nTST == animations::TransitionSubType::FADEOVERCOLOR )
1325 							nTransitionType = PPT_TRANSITION_TYPE_FADE;
1326 					}
1327 					break;
1328 					case PPT_TRANSITION_TYPE_COMB :
1329 					{
1330 						nTransitionType = PPT_TRANSITION_TYPE_COMB;
1331 						if ( nTST == animations::TransitionSubType::COMBVERTICAL )
1332 							nDirection++;
1333 					}
1334 					break;
1335 					case animations::TransitionType::PUSHWIPE :
1336 					{
1337 						nTransitionType = PPT_TRANSITION_TYPE_PUSH;
1338 						switch( nTST )
1339 						{
1340 							case animations::TransitionSubType::FROMRIGHT: nDirection = 0; break;
1341 							case animations::TransitionSubType::FROMBOTTOM: nDirection = 1; break;
1342 							case animations::TransitionSubType::FROMLEFT: nDirection = 2; break;
1343 							case animations::TransitionSubType::FROMTOP: nDirection = 3; break;
1344 						}
1345 					}
1346 					break;
1347 					case animations::TransitionType::PINWHEELWIPE :
1348 					{
1349 						nTransitionType = PPT_TRANSITION_TYPE_WHEEL;
1350 						switch( nTST )
1351 						{
1352 							case animations::TransitionSubType::ONEBLADE: nDirection = 1; break;
1353 							case animations::TransitionSubType::TWOBLADEVERTICAL : nDirection = 2; break;
1354 							case animations::TransitionSubType::THREEBLADE : nDirection = 3; break;
1355 							case animations::TransitionSubType::FOURBLADE: nDirection = 4; break;
1356 							case animations::TransitionSubType::EIGHTBLADE: nDirection = 8; break;
1357 						}
1358 					}
1359 					break;
1360 					case animations::TransitionType::FANWIPE :
1361 					{
1362 						nTransitionType = PPT_TRANSITION_TYPE_WEDGE;
1363 					}
1364 					break;
1365 					case animations::TransitionType::ELLIPSEWIPE :
1366 					{
1367 						nTransitionType = PPT_TRANSITION_TYPE_CIRCLE;
1368 					}
1369 					break;
1370 					case animations::TransitionType::FOURBOXWIPE :
1371 					{
1372 						nTransitionType = PPT_TRANSITION_TYPE_PLUS;
1373 					}
1374 					break;
1375 					case animations::TransitionType::IRISWIPE :
1376 					{
1377 						nTransitionType = PPT_TRANSITION_TYPE_DIAMOND;
1378 					}
1379 					break;
1380 				}
1381 			}
1382 		}
1383 		if ( !nTransitionType )
1384 		{
1385 			switch ( eFe )
1386 			{
1387 				default :
1388 				case ::com::sun::star::presentation::FadeEffect_RANDOM :
1389 					nTransitionType = PPT_TRANSITION_TYPE_RANDOM;
1390 				break;
1391 
1392 				case ::com::sun::star::presentation::FadeEffect_HORIZONTAL_STRIPES :
1393 					nDirection++;
1394 				case ::com::sun::star::presentation::FadeEffect_VERTICAL_STRIPES :
1395 					nTransitionType = PPT_TRANSITION_TYPE_BLINDS;
1396 				break;
1397 
1398 				case ::com::sun::star::presentation::FadeEffect_VERTICAL_CHECKERBOARD :
1399 					nDirection++;
1400 				case ::com::sun::star::presentation::FadeEffect_HORIZONTAL_CHECKERBOARD :
1401 					nTransitionType = PPT_TRANSITION_TYPE_CHECKER;
1402 				break;
1403 
1404 				case ::com::sun::star::presentation::FadeEffect_MOVE_FROM_UPPERLEFT :
1405 					nDirection++;
1406 				case ::com::sun::star::presentation::FadeEffect_MOVE_FROM_UPPERRIGHT :
1407 					nDirection++;
1408 				case ::com::sun::star::presentation::FadeEffect_MOVE_FROM_LOWERLEFT :
1409 					nDirection++;
1410 				case ::com::sun::star::presentation::FadeEffect_MOVE_FROM_LOWERRIGHT :
1411 					nDirection++;
1412 				case ::com::sun::star::presentation::FadeEffect_MOVE_FROM_TOP :
1413 					nDirection++;
1414 				case ::com::sun::star::presentation::FadeEffect_MOVE_FROM_LEFT :
1415 					nDirection++;
1416 				case ::com::sun::star::presentation::FadeEffect_MOVE_FROM_BOTTOM :
1417 					nDirection++;
1418 				case ::com::sun::star::presentation::FadeEffect_MOVE_FROM_RIGHT :
1419 					nTransitionType = PPT_TRANSITION_TYPE_COVER;
1420 				break;
1421 
1422 				case ::com::sun::star::presentation::FadeEffect_DISSOLVE :
1423 					nTransitionType = PPT_TRANSITION_TYPE_DISSOLVE;
1424 				break;
1425 
1426 				case ::com::sun::star::presentation::FadeEffect_VERTICAL_LINES :
1427 					nDirection++;
1428 				case ::com::sun::star::presentation::FadeEffect_HORIZONTAL_LINES :
1429 					nTransitionType = PPT_TRANSITION_TYPE_RANDOM_BARS;
1430 				break;
1431 
1432 				case ::com::sun::star::presentation::FadeEffect_CLOSE_HORIZONTAL :
1433 					nDirection++;
1434 				case ::com::sun::star::presentation::FadeEffect_OPEN_HORIZONTAL :
1435 					nDirection++;
1436 				case ::com::sun::star::presentation::FadeEffect_CLOSE_VERTICAL :
1437 					nDirection++;
1438 				case ::com::sun::star::presentation::FadeEffect_OPEN_VERTICAL :
1439 					nTransitionType = PPT_TRANSITION_TYPE_SPLIT;
1440 				break;
1441 
1442 				case ::com::sun::star::presentation::FadeEffect_FADE_FROM_UPPERLEFT :
1443 					nDirection++;
1444 				case ::com::sun::star::presentation::FadeEffect_FADE_FROM_UPPERRIGHT :
1445 					nDirection++;
1446 				case ::com::sun::star::presentation::FadeEffect_FADE_FROM_LOWERLEFT :
1447 					nDirection++;
1448 				case ::com::sun::star::presentation::FadeEffect_FADE_FROM_LOWERRIGHT :
1449 					nDirection += 4;
1450 					nTransitionType = PPT_TRANSITION_TYPE_STRIPS;
1451 				break;
1452 
1453 				case ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_LOWERRIGHT :
1454 					nDirection++;
1455 				case ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_LOWERLEFT :
1456 					nDirection++;
1457 				case ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_UPPERRIGHT :
1458 					nDirection++;
1459 				case ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_UPPERLEFT :
1460 					nDirection++;
1461 				case ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_BOTTOM :
1462 					nDirection++;
1463 				case ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_RIGHT :
1464 					nDirection++;
1465 				case ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_TOP :
1466 					nDirection++;
1467 				case ::com::sun::star::presentation::FadeEffect_UNCOVER_TO_LEFT :
1468 					nTransitionType = PPT_TRANSITION_TYPE_PULL;
1469 				break;
1470 
1471 				case ::com::sun::star::presentation::FadeEffect_FADE_FROM_TOP :
1472 					nDirection++;
1473 				case ::com::sun::star::presentation::FadeEffect_FADE_FROM_LEFT :
1474 					nDirection++;
1475 				case ::com::sun::star::presentation::FadeEffect_FADE_FROM_BOTTOM :
1476 					nDirection++;
1477 				case ::com::sun::star::presentation::FadeEffect_FADE_FROM_RIGHT :
1478 					nTransitionType = PPT_TRANSITION_TYPE_WIPE;
1479 				break;
1480 
1481 				case ::com::sun::star::presentation::FadeEffect_ROLL_FROM_TOP :
1482 					nDirection++;
1483 				case ::com::sun::star::presentation::FadeEffect_ROLL_FROM_LEFT :
1484 					nDirection++;
1485 				case ::com::sun::star::presentation::FadeEffect_ROLL_FROM_BOTTOM :
1486 					nDirection++;
1487 				case ::com::sun::star::presentation::FadeEffect_ROLL_FROM_RIGHT :
1488 					nTransitionType = PPT_TRANSITION_TYPE_WIPE;
1489 				break;
1490 
1491 				case ::com::sun::star::presentation::FadeEffect_FADE_TO_CENTER :
1492 					nDirection++;
1493 				case ::com::sun::star::presentation::FadeEffect_FADE_FROM_CENTER :
1494 					nTransitionType = PPT_TRANSITION_TYPE_ZOOM;
1495 				break;
1496 
1497 				case ::com::sun::star::presentation::FadeEffect_NONE :
1498 					nDirection = 2;
1499 				break;
1500 			}
1501 		}
1502         if ( mnDiaMode == 2 )                                   // automatic ?
1503             nBuildFlags |= 0x400;
1504         if ( bVisible == sal_False )
1505             nBuildFlags |= 4;
1506         if ( bIsSound )
1507             nBuildFlags |= 16;
1508 		if ( bLoopSound )
1509 			nBuildFlags |= 64;
1510 		if ( bStopSound )
1511 			nBuildFlags |= 256;
1512 
1513         if ( GetPropertyValue( aAny, mXPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Duration" ) ) ) )// duration of this slide
1514             nSlideTime = *(sal_Int32*)aAny.getValue() << 10;        // in ticks
1515 
1516 
1517         mpPptEscherEx->AddAtom( 16, EPP_SSSlideInfoAtom );
1518         *mpStrm << nSlideTime       // standtime in ticks
1519                 << nSoundRef
1520                 << nDirection
1521                 << nTransitionType
1522                 << nBuildFlags
1523                 << nSpeed
1524                 << (sal_uInt8)0 << (sal_uInt8)0 << (sal_uInt8)0;
1525     }
1526 
1527 	ImplCreateHeaderFooters( mXPagePropSet );
1528 
1529     EscherSolverContainer aSolverContainer;
1530     mpPptEscherEx->OpenContainer( EPP_PPDrawing );
1531     mpPptEscherEx->OpenContainer( ESCHER_DgContainer );
1532     mpPptEscherEx->EnterGroup(0,0);
1533     ImplWritePage( rLayout, aSolverContainer, NORMAL, sal_False, nPageNum );    // Die Shapes der Seite werden im PPT Dok. erzeugt
1534     mpPptEscherEx->LeaveGroup();
1535 
1536     if ( bHasBackground )
1537         ImplWriteBackground( aXBackgroundPropSet );
1538     else
1539     {
1540         mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
1541         mpPptEscherEx->AddShape( ESCHER_ShpInst_Rectangle, 0xc00 );             // Flags: Connector | Background | HasSpt
1542         EscherPropertyContainer aPropOpt;
1543 		aPropOpt.AddOpt( ESCHER_Prop_fillRectRight, PPTtoEMU( maDestPageSize.Width ) );
1544         aPropOpt.AddOpt( ESCHER_Prop_fillRectBottom, PPTtoEMU( maDestPageSize.Width ) );
1545         aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x120012 );
1546         aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x80000 );
1547         aPropOpt.AddOpt( ESCHER_Prop_bWMode, ESCHER_wDontShow );
1548         aPropOpt.AddOpt( ESCHER_Prop_fBackground, 0x10001 );                // if true, this is the background shape
1549         aPropOpt.Commit( *mpStrm );
1550         mpPptEscherEx->CloseContainer();    // ESCHER_SpContainer
1551     }
1552 
1553     aSolverContainer.WriteSolver( *mpStrm );
1554 
1555     mpPptEscherEx->CloseContainer();    // ESCHER_DgContainer
1556     mpPptEscherEx->CloseContainer();    // EPP_Drawing
1557     mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 1 );
1558     *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;
1559 
1560 	SvMemoryStream aBinaryTagData10Atom;
1561 	ImplExportComments( mXDrawPage, aBinaryTagData10Atom );
1562 	if ( mbUseNewAnimations )
1563 	{
1564 		SvMemoryStream amsofbtAnimGroup;
1565 		ppt::AnimationExporter aExporter( aSolverContainer, maSoundCollection );
1566 		aExporter.doexport( mXDrawPage, amsofbtAnimGroup );
1567 		sal_uInt32 nmsofbtAnimGroupSize = amsofbtAnimGroup.Tell();
1568 		if ( nmsofbtAnimGroupSize )
1569 		{
1570 			{
1571 				EscherExAtom aMagic2( aBinaryTagData10Atom, 0x2eeb );
1572 				aBinaryTagData10Atom << (sal_uInt32)0x01c45df9
1573 									 << (sal_uInt32)0xe1471b30;
1574 			}
1575 			{
1576 				EscherExAtom aMagic( aBinaryTagData10Atom, 0x2b00 );
1577 				aBinaryTagData10Atom << (sal_uInt32)0;
1578 			}
1579 			aBinaryTagData10Atom.Write( amsofbtAnimGroup.GetData(), amsofbtAnimGroup.Tell() );
1580 			{
1581 				EscherExContainer aMagic2( aBinaryTagData10Atom, 0x2b02 );
1582 			}
1583 		}
1584 	}
1585 	if ( aBinaryTagData10Atom.Tell() )
1586 	{
1587 		EscherExContainer aProgTags		( *mpStrm, EPP_ProgTags );
1588 		EscherExContainer aProgBinaryTag( *mpStrm, EPP_ProgBinaryTag );
1589 		{
1590 			EscherExAtom aCString( *mpStrm, EPP_CString );
1591 			*mpStrm << (sal_uInt32)0x5f005f
1592 					<< (sal_uInt32)0x50005f
1593 					<< (sal_uInt32)0x540050
1594 					<< (sal_uInt16)0x31
1595 					<< (sal_uInt16)0x30;
1596 		}
1597 		{
1598 			EscherExAtom aBinaryTagData( *mpStrm, EPP_BinaryTagData );
1599 			mpStrm->Write( aBinaryTagData10Atom.GetData(), aBinaryTagData10Atom.Tell() );
1600 		}
1601 	}
1602 /*
1603 	if ( mbUseNewAnimations )
1604 	{
1605 		SvMemoryStream amsofbtAnimGroup;
1606 		ppt::AnimationExporter aExporter( aSolverContainer, maSoundCollection );
1607 		aExporter.doexport( mXDrawPage, amsofbtAnimGroup );
1608 		sal_uInt32 nmsofbtAnimGroupSize = amsofbtAnimGroup.Tell();
1609 		if ( nmsofbtAnimGroupSize )
1610 		{
1611 			EscherExContainer aProgTags		( *mpStrm, EPP_ProgTags );
1612 			EscherExContainer aProgBinaryTag( *mpStrm, EPP_ProgBinaryTag );
1613 			{
1614 				EscherExAtom aCString( *mpStrm, EPP_CString );
1615 				*mpStrm << (sal_uInt32)0x5f005f
1616 						<< (sal_uInt32)0x50005f
1617 						<< (sal_uInt32)0x540050
1618 						<< (sal_uInt16)0x31
1619 						<< (sal_uInt16)0x30;
1620 			}
1621 			{
1622 				EscherExAtom aBinaryTagData( *mpStrm, EPP_BinaryTagData );
1623 				{
1624 					{
1625 						EscherExAtom aMagic2( *mpStrm, 0x2eeb );
1626 						*mpStrm << (sal_uInt32)0x01c45df9
1627 								<< (sal_uInt32)0xe1471b30;
1628 					}
1629 					{
1630 						EscherExAtom aMagic( *mpStrm, 0x2b00 );
1631 						*mpStrm << (sal_uInt32)0;
1632 					}
1633 				}
1634 				mpStrm->Write( amsofbtAnimGroup.GetData(), amsofbtAnimGroup.Tell() );
1635 				{
1636 					EscherExContainer aMagic2( *mpStrm, 0x2b02 );
1637 				}
1638 			}
1639 		}
1640     }
1641 */
1642 	mpPptEscherEx->CloseContainer();    // EPP_Slide
1643     return sal_True;
1644 };
1645 
1646 // ---------------------------------------------------------------------------------------------
1647 
ImplCreateNotes(sal_uInt32 nPageNum)1648 sal_Bool PPTWriter::ImplCreateNotes( sal_uInt32 nPageNum )
1649 {
1650     if ( !ImplGetPageByIndex( nPageNum, NOTICE ) )
1651         return sal_False;
1652 	ImplSetCurrentStyleSheet( ImplGetMasterIndex( NORMAL ) );
1653 
1654 
1655     mpPptEscherEx->PtReplaceOrInsert( EPP_Persist_Notes | nPageNum, mpStrm->Tell() );
1656     mpPptEscherEx->OpenContainer( EPP_Notes );
1657     mpPptEscherEx->AddAtom( 8, EPP_NotesAtom, 1 );
1658     *mpStrm << (sal_uInt32)nPageNum + 0x100
1659             << (sal_uInt16)3                                        // follow master ....
1660             << (sal_uInt16)0;
1661 
1662 	ImplCreateHeaderFooters( mXPagePropSet );
1663 
1664     EscherSolverContainer aSolverContainer;
1665 
1666     mpPptEscherEx->OpenContainer( EPP_PPDrawing );
1667     mpPptEscherEx->OpenContainer( ESCHER_DgContainer );
1668     mpPptEscherEx->EnterGroup(0,0);
1669 
1670     ImplWritePage( pPHLayout[ 20 ], aSolverContainer, NOTICE, sal_False );  // Die Shapes der Seite werden im PPT Dok. erzeugt
1671 
1672     mpPptEscherEx->LeaveGroup();
1673     mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
1674     mpPptEscherEx->AddShape( ESCHER_ShpInst_Rectangle, 0xc00 ); // Flags: Connector | Background | HasSpt
1675     EscherPropertyContainer aPropOpt;
1676     aPropOpt.AddOpt( ESCHER_Prop_fillColor, 0xffffff );     // stock valued fill color
1677     aPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0 );
1678     aPropOpt.AddOpt( ESCHER_Prop_fillRectRight, 0x8b9f8e );
1679     aPropOpt.AddOpt( ESCHER_Prop_fillRectBottom, 0x68bdde );
1680     aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x120012 );
1681     aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x80000 );
1682     aPropOpt.AddOpt( ESCHER_Prop_bWMode, ESCHER_wDontShow );
1683     aPropOpt.AddOpt( ESCHER_Prop_fBackground, 0x10001 );
1684     aPropOpt.Commit( *mpStrm );
1685     mpPptEscherEx->CloseContainer();    // ESCHER_SpContainer
1686 
1687     aSolverContainer.WriteSolver( *mpStrm );
1688 
1689     mpPptEscherEx->CloseContainer();    // ESCHER_DgContainer
1690     mpPptEscherEx->CloseContainer();    // EPP_Drawing
1691     mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 1 );
1692     *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;
1693     mpPptEscherEx->CloseContainer();    // EPP_Notes
1694     return sal_True;
1695 };
1696 
ImplWriteBackground(::com::sun::star::uno::Reference<::com::sun::star::beans::XPropertySet> & rXPropSet)1697 void PPTWriter::ImplWriteBackground( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet )
1698 {
1699     //************************ ******
1700     //** DEFAULT BACKGROUND SHAPE **
1701     //******************************
1702 
1703     sal_uInt32 nFillColor = 0xffffff;
1704     sal_uInt32 nFillBackColor = 0;
1705 
1706     mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
1707     mpPptEscherEx->AddShape( ESCHER_ShpInst_Rectangle, 0xc00 );                     // Flags: Connector | Background | HasSpt
1708 
1709     // #121183# Use real PageSize in 100th mm
1710     Rectangle aRect(Point(0, 0), maPageSize);
1711 
1712     EscherPropertyContainer aPropOpt( mpPptEscherEx->GetGraphicProvider(), mpPicStrm, aRect );
1713     aPropOpt.AddOpt( ESCHER_Prop_fillType, ESCHER_FillSolid );
1714     ::com::sun::star::drawing::FillStyle aFS( ::com::sun::star::drawing::FillStyle_NONE );
1715     if ( ImplGetPropertyValue( rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillStyle" ) ) ) )
1716         mAny >>= aFS;
1717 
1718     switch( aFS )
1719     {
1720         case ::com::sun::star::drawing::FillStyle_GRADIENT :
1721         {
1722             aPropOpt.CreateGradientProperties( rXPropSet );
1723             aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x1f001e );
1724             aPropOpt.GetOpt( ESCHER_Prop_fillColor, nFillColor );
1725             aPropOpt.GetOpt( ESCHER_Prop_fillBackColor, nFillBackColor );
1726         }
1727         break;
1728 
1729         case ::com::sun::star::drawing::FillStyle_BITMAP :
1730             aPropOpt.CreateGraphicProperties( rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillBitmapURL" ) ), sal_True );
1731         break;
1732 
1733         case ::com::sun::star::drawing::FillStyle_HATCH :
1734 			aPropOpt.CreateGraphicProperties( rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillHatch" ) ), sal_True );
1735         break;
1736 
1737         case ::com::sun::star::drawing::FillStyle_SOLID :
1738         {
1739             if ( ImplGetPropertyValue( rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillColor" ) ) ) )
1740             {
1741                 nFillColor = mpPptEscherEx->GetColor( *((sal_uInt32*)mAny.getValue()) );
1742                 nFillBackColor = nFillColor ^ 0xffffff;
1743             }
1744         }	// PASSTHROUGH INTENDED
1745         case ::com::sun::star::drawing::FillStyle_NONE :
1746         default:
1747             aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x120012 );
1748         break;
1749     }
1750     aPropOpt.AddOpt( ESCHER_Prop_fillColor, nFillColor );
1751     aPropOpt.AddOpt( ESCHER_Prop_fillBackColor, nFillBackColor );
1752     aPropOpt.AddOpt( ESCHER_Prop_fillRectRight, PPTtoEMU( maDestPageSize.Width ) );
1753     aPropOpt.AddOpt( ESCHER_Prop_fillRectBottom, PPTtoEMU( maDestPageSize.Height ) );
1754     aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x80000 );
1755     aPropOpt.AddOpt( ESCHER_Prop_bWMode, ESCHER_bwWhite );
1756     aPropOpt.AddOpt( ESCHER_Prop_fBackground, 0x10001 );
1757     aPropOpt.Commit( *mpStrm );
1758     mpPptEscherEx->CloseContainer();    // ESCHER_SpContainer
1759 }
1760 
ImplWriteVBA(SvMemoryStream * pVBA)1761 void PPTWriter::ImplWriteVBA( SvMemoryStream* pVBA )
1762 {
1763     if ( pVBA )
1764     {
1765         pVBA->Seek( STREAM_SEEK_TO_END );
1766         sal_uInt32 nLen = pVBA->Tell();
1767         if ( nLen > 8 )
1768         {
1769             nLen -= 8;
1770             mnVBAOleOfs = mpStrm->Tell();
1771             mpPptEscherEx->BeginAtom();
1772             mpStrm->Write( (sal_Int8*)pVBA->GetData() + 8, nLen );
1773             mpPptEscherEx->EndAtom( EPP_ExOleObjStg, 0, 1 );
1774         }
1775     }
1776 }
1777 
1778 // ---------------------------------------------------------------------------------------------
1779 
ImplWriteOLE(sal_uInt32 nCnvrtFlags)1780 void PPTWriter::ImplWriteOLE( sal_uInt32 nCnvrtFlags )
1781 {
1782     PPTExOleObjEntry* pPtr;
1783 
1784     SvxMSExportOLEObjects aOleExport( nCnvrtFlags );
1785 
1786     for ( pPtr = (PPTExOleObjEntry*)maExOleObj.First(); pPtr;
1787         pPtr = (PPTExOleObjEntry*)maExOleObj.Next() )
1788     {
1789         SvMemoryStream* pStrm = NULL;
1790         pPtr->nOfsB = mpStrm->Tell();
1791         switch ( pPtr->eType )
1792         {
1793             case NORMAL_OLE_OBJECT :
1794             {
1795 				SdrObject* pSdrObj = GetSdrObjectFromXShape( pPtr->xShape );
1796 				if ( pSdrObj && pSdrObj->ISA( SdrOle2Obj ) )
1797 				{
1798                     ::uno::Reference < embed::XEmbeddedObject > xObj( ( (SdrOle2Obj*) pSdrObj )->GetObjRef() );
1799                     if( xObj.is() )
1800 					{
1801 						SvStorageRef xTempStorage( new SvStorage( new SvMemoryStream(), sal_True ) );
1802                         aOleExport.ExportOLEObject( xObj, *xTempStorage );
1803 
1804                         //TODO/MBA: testing
1805                         String aPersistStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( SVEXT_PERSIST_STREAM ) ) );
1806                         SvMemoryStream aStream;
1807                         SvStorageRef xCleanStorage( new SvStorage( sal_False, aStream ) );
1808 						xTempStorage->CopyTo( xCleanStorage );
1809 						// SJ: #99809# create a dummy content stream, the dummy content is necessary for ppt, but not for
1810 						// doc files, so we can't share code.
1811 						SotStorageStreamRef xStm = xCleanStorage->OpenSotStream( aPersistStream, STREAM_STD_READWRITE );
1812 						*xStm	<< (sal_uInt32)0		// no ClipboardId
1813 								<< (sal_uInt32)4		// no target device
1814 								<< (sal_uInt32)1		// aspect ratio
1815 								<< (sal_Int32)-1		// L-Index
1816 								<< (sal_uInt32)0		// Advanced Flags
1817 								<< (sal_uInt32)0		// compression
1818 								<< (sal_uInt32)0		// Size
1819 								<< (sal_uInt32)0		//  "
1820 								<< (sal_uInt32)0;
1821 						pStrm = xCleanStorage->CreateMemoryStream();
1822                     }
1823                 }
1824             }
1825             break;
1826 
1827             case OCX_CONTROL :
1828             {
1829                 if ( pPtr->xControlModel.is() )
1830                 {
1831                     String aName;
1832                     //Initialize the graphic size which will be used on export
1833                     ::com::sun::star::awt::Size  aSize( pPtr->xShape->getSize() );
1834                     SvStorageRef xDest( new SvStorage( new SvMemoryStream(), sal_True ) );
1835                     sal_Bool bOk = SvxMSConvertOCXControls::WriteOCXStream( xDest, pPtr->xControlModel, aSize, aName );
1836                     if ( bOk )
1837                         pStrm = xDest->CreateMemoryStream();
1838                 }
1839             }
1840         }
1841         if ( pStrm )
1842         {
1843             mpPptEscherEx->BeginAtom();
1844             pStrm->Seek( STREAM_SEEK_TO_END );
1845 			sal_uInt32 npStrmSize = pStrm->Tell();
1846             *mpStrm << npStrmSize;					// uncompressed size
1847 
1848 #ifdef DBG_EXTRACTOLEOBJECTS
1849 			SvFileStream aOut( String::CreateFromAscii( "D:\\OUT.OLE" ), STREAM_TRUNC | STREAM_WRITE );
1850 			pStrm->Seek( 0 );
1851 			aOut.Write( pStrm->GetData(), npStrmSize );
1852 #endif
1853 
1854             pStrm->Seek( 0 );
1855             ZCodec aZCodec( 0x8000, 0x8000 );
1856             aZCodec.BeginCompression();
1857             aZCodec.Compress( *pStrm, *mpStrm );
1858             aZCodec.EndCompression();
1859             delete pStrm;
1860             mpPptEscherEx->EndAtom( EPP_ExOleObjStg, 0, 1 );
1861         }
1862     }
1863 }
1864 
1865 // ---------------------------------------------------------------------------------------------
1866 // PersistantTable und UserEditAtom schreiben
1867 
ImplWriteAtomEnding()1868 sal_Bool PPTWriter::ImplWriteAtomEnding()
1869 {
1870 
1871 #define EPP_LastViewTypeNone        0
1872 #define EPP_LastViewTypeSlideView   1
1873 #define EPP_LastViewTypeOutlineView 2
1874 #define EPP_LastViewTypeNotes       3
1875 
1876 
1877     sal_uInt32  i, nPos, nOfs, nPersistOfs = mpStrm->Tell();
1878     sal_uInt32  nPersistEntrys = 0;
1879     *mpStrm << (sal_uInt32)0 << (sal_uInt32)0 << (sal_uInt32)0;         // Record Header und ersten Eintrag ueberspringen
1880 
1881     // Document pesist schreiben
1882         nPersistEntrys++;
1883         *mpStrm << (sal_uInt32)0;
1884     // MasterPages persists schreiben
1885     for ( i = 0; i < mnMasterPages; i++ )
1886     {
1887         nOfs = mpPptEscherEx->PtGetOffsetByID( EPP_Persist_MainMaster | i );
1888         if ( nOfs )
1889         {
1890             *mpStrm << nOfs;
1891             mpPptEscherEx->InsertAtPersistOffset( EPP_MAINMASTER_PERSIST_KEY | i, ++nPersistEntrys );
1892         }
1893     }
1894     // MainNotesMaster persist schreiben
1895     nOfs = mpPptEscherEx->PtGetOffsetByID( EPP_Persist_MainNotes );
1896     if ( nOfs )
1897     {
1898         *mpStrm << nOfs;
1899         mpPptEscherEx->InsertAtPersistOffset( EPP_MAINNOTESMASTER_PERSIST_KEY, ++nPersistEntrys );
1900     }
1901     // Slide persists schreiben -> es gilt hier auch den EPP_SlidePersistAtome mit einem gueltigen wert zu beschreiben
1902     for ( i = 0; i < mnPages; i++ )
1903     {
1904         nOfs = mpPptEscherEx->PtGetOffsetByID( EPP_Persist_Slide | i );
1905         if ( nOfs )
1906         {
1907             *mpStrm << nOfs;
1908             mpPptEscherEx->InsertAtPersistOffset( EPP_MAINSLIDE_PERSIST_KEY | i, ++nPersistEntrys );
1909         }
1910     }
1911     // Notes persists schreiben
1912     for ( i = 0; i < mnPages; i++ )
1913     {
1914         nOfs = mpPptEscherEx->PtGetOffsetByID( EPP_Persist_Notes | i );
1915         if ( nOfs )
1916         {
1917             *mpStrm << nOfs;
1918             mpPptEscherEx->InsertAtPersistOffset( EPP_MAINNOTES_PERSIST_KEY | i, ++nPersistEntrys );
1919         }
1920     }
1921     // Ole persists
1922     PPTExOleObjEntry* pPtr;
1923     for ( pPtr = (PPTExOleObjEntry*)maExOleObj.First(); pPtr; pPtr = (PPTExOleObjEntry*)maExOleObj.Next() )
1924     {
1925         nOfs = mpPptEscherEx->PtGetOffsetByID( EPP_Persist_ExObj );
1926         if ( nOfs )
1927         {
1928             nPersistEntrys++;
1929             *mpStrm << pPtr->nOfsB;
1930             sal_uInt32 nOldPos, nPersOfs = nOfs + pPtr->nOfsA + 16 + 8;     // 8 bytes atom header, +16 to the persist entry
1931             nOldPos = mpStrm->Tell();
1932             mpStrm->Seek( nPersOfs );
1933             *mpStrm << nPersistEntrys;
1934             mpStrm->Seek( nOldPos );
1935         }
1936     }
1937     // VB persist
1938     if ( mnVBAOleOfs && mpVBA )
1939     {
1940         nOfs = mpPptEscherEx->PtGetOffsetByID( EPP_Persist_VBAInfoAtom );
1941         if ( nOfs )
1942         {
1943             nPersistEntrys++;
1944             sal_uInt32 n1, n2;
1945 
1946             mpVBA->Seek( 0 );
1947             *mpVBA >> n1
1948                    >> n2;
1949 
1950             *mpStrm << mnVBAOleOfs;
1951             sal_uInt32 nOldPos = mpStrm->Tell();
1952             mpStrm->Seek( nOfs );               // Fill the VBAInfoAtom with the correct index to the persisttable
1953             *mpStrm << nPersistEntrys
1954                     << n1
1955                     << 2;
1956             mpStrm->Seek( nOldPos );
1957 
1958         }
1959     }
1960     nPos = mpStrm->Tell();
1961     mpStrm->Seek( nPersistOfs );
1962     mpPptEscherEx->AddAtom( ( nPersistEntrys + 1 ) << 2, EPP_PersistPtrIncrementalBlock );      // Record Header eintragen
1963     *mpStrm << (sal_uInt32)( ( nPersistEntrys << 20 ) | 1 );
1964     mpStrm->Seek( nPos );
1965 
1966     *mpCurUserStrm << (sal_uInt32)nPos;             // offset to current edit setzen
1967     mpPptEscherEx->AddAtom( 28, EPP_UserEditAtom );
1968     *mpStrm << (sal_Int32)0x100                     // last slide ID
1969             << (sal_uInt32)0x03000dbc               // minor and major app version that did the save
1970             << (sal_uInt32)0                        // offset last save, 0 after a full save
1971             << nPersistOfs                      // File offset to persist pointers for this save operation
1972             << (sal_uInt32)1                        // Persist reference to the document persist object
1973             << (sal_uInt32)nPersistEntrys           // max persists written, Seed value for persist object id management
1974             << (sal_Int16)EPP_LastViewTypeSlideView // last view type
1975             << (sal_Int16)0x12;                     // padword
1976 
1977     return sal_True;
1978 }
1979 
1980 // ---------------------------------------------------------------------------------------------
1981 
PPTExCharSheet(int nInstance)1982 PPTExCharSheet::PPTExCharSheet( int nInstance )
1983 {
1984     sal_uInt16 nFontHeight = 24;
1985 
1986     for ( int nDepth = 0; nDepth < 5; nDepth++ )
1987     {
1988         PPTExCharLevel& rLev = maCharLevel[ nDepth ];
1989         switch ( nInstance )
1990         {
1991             case EPP_TEXTTYPE_Title :
1992             case EPP_TEXTTYPE_CenterTitle :
1993                 nFontHeight = 44;
1994             break;
1995             case EPP_TEXTTYPE_Body :
1996             case EPP_TEXTTYPE_CenterBody :
1997             case EPP_TEXTTYPE_HalfBody :
1998             case EPP_TEXTTYPE_QuarterBody :
1999             {
2000                 switch ( nDepth )
2001                 {
2002                     case 0 : nFontHeight = 32; break;
2003                     case 1 : nFontHeight = 28; break;
2004                     case 2 : nFontHeight = 24; break;
2005                     default :nFontHeight = 20; break;
2006                 }
2007             }
2008             break;
2009             case EPP_TEXTTYPE_Notes :
2010                 nFontHeight = 12;
2011             break;
2012             case EPP_TEXTTYPE_notUsed :
2013             case EPP_TEXTTYPE_Other :
2014                 nFontHeight = 24;
2015             break;
2016         }
2017         rLev.mnFlags = 0;
2018         rLev.mnFont = 0;
2019         rLev.mnAsianOrComplexFont = 0xffff;
2020         rLev.mnFontHeight = nFontHeight;
2021         rLev.mnFontColor = 0;
2022         rLev.mnEscapement = 0;
2023     }
2024 }
2025 
2026 
SetStyleSheet(const::com::sun::star::uno::Reference<::com::sun::star::beans::XPropertySet> & rXPropSet,FontCollection & rFontCollection,int nLevel)2027 void PPTExCharSheet::SetStyleSheet( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
2028                                     FontCollection& rFontCollection, int nLevel )
2029 {
2030     PortionObj  aPortionObj( rXPropSet, rFontCollection );
2031 
2032     PPTExCharLevel& rLev = maCharLevel[ nLevel ];
2033 
2034     if ( aPortionObj.meCharColor == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
2035         rLev.mnFontColor = aPortionObj.mnCharColor;
2036     if ( aPortionObj.meCharEscapement == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
2037         rLev.mnEscapement = aPortionObj.mnCharEscapement;
2038     if ( aPortionObj.meCharHeight == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
2039         rLev.mnFontHeight = aPortionObj.mnCharHeight;
2040     if ( aPortionObj.meFontName == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
2041         rLev.mnFont = aPortionObj.mnFont;
2042     if ( aPortionObj.meAsianOrComplexFont == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
2043         rLev.mnAsianOrComplexFont = aPortionObj.mnAsianOrComplexFont;
2044     rLev.mnFlags = aPortionObj.mnCharAttr;
2045 }
2046 
Write(SvStream & rSt,PptEscherEx *,sal_uInt16 nLev,sal_Bool,sal_Bool bSimpleText,const::com::sun::star::uno::Reference<::com::sun::star::beans::XPropertySet> & rPagePropSet)2047 void PPTExCharSheet::Write( SvStream& rSt, PptEscherEx*, sal_uInt16 nLev, sal_Bool, sal_Bool bSimpleText,
2048     const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rPagePropSet )
2049 {
2050     const PPTExCharLevel& rLev = maCharLevel[ nLev ];
2051 
2052     sal_uInt32 nCharFlags = 0xefffff;
2053     if ( bSimpleText )
2054         nCharFlags = 0x7ffff;
2055 
2056     rSt << nCharFlags
2057         << rLev.mnFlags
2058         << rLev.mnFont;
2059 
2060     sal_uInt32 nFontColor = rLev.mnFontColor;
2061     if ( nFontColor == COL_AUTO )
2062     {
2063         sal_Bool bIsDark = sal_False;
2064         ::com::sun::star::uno::Any aAny;
2065         if ( PropValue::GetPropertyValue( aAny, rPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsBackgroundDark" ) ), sal_True ) )
2066             aAny >>= bIsDark;
2067         nFontColor = bIsDark ? 0xffffff : 0x000000;
2068     }
2069     nFontColor &= 0xffffff;
2070     nFontColor |= 0xfe000000;
2071     if ( bSimpleText )
2072     {
2073         rSt << rLev.mnFontHeight
2074             << nFontColor;
2075     }
2076     else
2077     {
2078         rSt << rLev.mnAsianOrComplexFont
2079             << (sal_uInt16)0xffff       // unbekannt
2080             << (sal_uInt16)0xffff       // unbekannt
2081             << rLev.mnFontHeight
2082             << nFontColor
2083             << rLev.mnEscapement;
2084     }
2085 }
2086 
PPTExParaSheet(int nInstance,sal_uInt16 nDefaultTab,PPTExBulletProvider & rProv)2087 PPTExParaSheet::PPTExParaSheet( int nInstance, sal_uInt16 nDefaultTab, PPTExBulletProvider& rProv ) :
2088     rBuProv     ( rProv ),
2089     mnInstance  ( nInstance )
2090 {
2091     sal_Bool bHasBullet = sal_False;
2092 
2093     sal_uInt16 nUpperDist = 0;
2094     sal_uInt16 nBulletChar = 0x2022;
2095     sal_uInt16 nBulletOfs = 0;
2096     sal_uInt16 nTextOfs = 0;
2097 
2098     for ( int nDepth = 0; nDepth < 5; nDepth++ )
2099     {
2100         PPTExParaLevel& rLev = maParaLevel[ nDepth ];
2101         switch ( nInstance )
2102         {
2103             case EPP_TEXTTYPE_Title :
2104             case EPP_TEXTTYPE_CenterTitle :
2105             break;
2106             case EPP_TEXTTYPE_Body :
2107             case EPP_TEXTTYPE_CenterBody :
2108             case EPP_TEXTTYPE_HalfBody :
2109             case EPP_TEXTTYPE_QuarterBody :
2110             {
2111                 bHasBullet = sal_True;
2112                 nUpperDist = 0x14;
2113             }
2114             break;
2115             case EPP_TEXTTYPE_Notes :
2116                 nUpperDist = 0x1e;
2117             break;
2118 
2119 //          default :
2120 //          case EPP_TEXTTYPE_notUsed :
2121 //          case EPP_TEXTTYPE_Other :
2122 //          break;
2123         }
2124         switch ( nDepth )
2125         {
2126             case 0 :
2127             {
2128                 nBulletChar = 0x2022;
2129                 nBulletOfs = 0;
2130                 nTextOfs = ( bHasBullet ) ? 0xd8 : 0;
2131             }
2132             break;
2133             case 1 :
2134             {
2135                 nBulletChar = 0x2013;
2136                 nBulletOfs = 0x120;
2137                 nTextOfs = 0x1d4;
2138             }
2139             break;
2140             case 2 :
2141             {
2142                 nBulletChar = 0x2022;
2143                 nBulletOfs = 0x240;
2144                 nTextOfs = 0x2d0;
2145             }
2146             break;
2147             case 3 :
2148             {
2149                 nBulletChar = 0x2013;
2150                 nBulletOfs = 0x360;
2151                 nTextOfs = 0x3f0;
2152             }
2153             break;
2154             case 4 :
2155             {
2156                 nBulletChar = 0xbb;
2157                 nBulletOfs = 0x480;
2158                 nTextOfs = 0x510;
2159             }
2160             break;
2161         }
2162         rLev.mbIsBullet = bHasBullet;
2163         rLev.mnBulletChar = nBulletChar;
2164         rLev.mnBulletFont = 0;
2165         rLev.mnBulletHeight = 100;
2166         rLev.mnBulletColor = 0;
2167         rLev.mnAdjust = 0;
2168         rLev.mnLineFeed = 100;
2169         rLev.mnLowerDist = 0;
2170         rLev.mnUpperDist = nUpperDist;
2171         rLev.mnTextOfs = nTextOfs;
2172         rLev.mnBulletOfs = nBulletOfs;
2173         rLev.mnDefaultTab = nDefaultTab;
2174         rLev.mnAsianSettings = 2;
2175 		rLev.mnBiDi = 0;
2176 
2177         rLev.mbExtendedBulletsUsed = sal_False;
2178         rLev.mnBulletId = 0xffff;
2179         rLev.mnBulletStart = 0;
2180         rLev.mnMappedNumType = 0;
2181         rLev.mnNumberingType = 0;
2182     }
2183 }
2184 
SetStyleSheet(const::com::sun::star::uno::Reference<::com::sun::star::beans::XPropertySet> & rXPropSet,FontCollection & rFontCollection,int nLevel,const PPTExCharLevel & rCharLevel)2185 void PPTExParaSheet::SetStyleSheet( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
2186                                         FontCollection& rFontCollection, int nLevel, const PPTExCharLevel& rCharLevel )
2187 {
2188     ParagraphObj aParagraphObj( rXPropSet, rBuProv );
2189     aParagraphObj.CalculateGraphicBulletSize( rCharLevel.mnFontHeight );
2190     PPTExParaLevel& rLev = maParaLevel[ nLevel ];
2191 
2192     if ( aParagraphObj.meTextAdjust == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
2193         rLev.mnAdjust = aParagraphObj.mnTextAdjust;
2194     if ( aParagraphObj.meLineSpacing == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
2195     {
2196         sal_Int16 nLineSpacing = aParagraphObj.mnLineSpacing;
2197         if ( nLineSpacing > 0 ) // if nLinespacing is < 0 the linespacing is an absolute spacing
2198         {
2199 			sal_Bool bFixedLineSpacing = sal_False;
2200 			uno::Any aAny = rXPropSet->getPropertyValue( ::rtl::OUString(
2201 															 RTL_CONSTASCII_USTRINGPARAM(
2202 																 "FontIndependentLineSpacing" ) ) );
2203 			if( !(aAny >>= bFixedLineSpacing) || !bFixedLineSpacing )
2204 			{
2205 				const FontCollectionEntry* pDesc = rFontCollection.GetById( rCharLevel.mnFont );
2206 				if ( pDesc )
2207 					nLineSpacing = (sal_Int16)( (double)nLineSpacing * pDesc->Scaling + 0.5 );
2208 			}
2209         }
2210         else
2211         {
2212             if ( rCharLevel.mnFontHeight > (sal_uInt16)( ((double)-nLineSpacing) * 0.001 * 72.0 / 2.54 ) ) // 1/100mm to point
2213             {
2214                 const FontCollectionEntry* pDesc = rFontCollection.GetById( rCharLevel.mnFont );
2215                 if ( pDesc )
2216                      nLineSpacing = (sal_Int16)( (double)100.0 * pDesc->Scaling + 0.5 );
2217                 else
2218                     nLineSpacing = 100;
2219             }
2220             else
2221                 nLineSpacing = (sal_Int16)( (double)nLineSpacing / 4.40972 );
2222         }
2223         rLev.mnLineFeed = nLineSpacing;
2224     }
2225     if ( aParagraphObj.meLineSpacingBottom == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
2226         rLev.mnLowerDist = aParagraphObj.mnLineSpacingBottom;
2227     if ( aParagraphObj.meLineSpacingTop == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
2228         rLev.mnUpperDist = aParagraphObj.mnLineSpacingTop;
2229     if ( aParagraphObj.meForbiddenRules == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
2230     {
2231         rLev.mnAsianSettings &=~1;
2232         if ( aParagraphObj.mbForbiddenRules )
2233             rLev.mnAsianSettings |= 1;
2234     }
2235     if ( aParagraphObj.meParagraphPunctation == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
2236     {
2237         rLev.mnAsianSettings &=~4;
2238         if ( aParagraphObj.mbParagraphPunctation )
2239             rLev.mnAsianSettings |= 4;
2240     }
2241 
2242 	if ( aParagraphObj.meBiDi == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
2243 		rLev.mnBiDi = aParagraphObj.mnBiDi;
2244 
2245 	rLev.mbIsBullet = aParagraphObj.mbIsBullet; //( ( aParagraphObj.nBulletFlags & 1 ) != 0 );
2246 
2247     if ( !nLevel )
2248     {
2249         if ( ( aParagraphObj.meBullet ==  ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
2250                     && aParagraphObj.bExtendedParameters )
2251         {
2252             for ( sal_Int16 i = 0; i < 5; i++ )
2253             {
2254                 PPTExParaLevel& rLevel = maParaLevel[ i ];
2255                 if ( i )
2256                     aParagraphObj.ImplGetNumberingLevel( rBuProv, i, sal_False );
2257 //              rLevel.mbIsBullet = ( ( aParagraphObj.nBulletFlags & 1 ) != 0 );
2258                 rLevel.mnTextOfs = aParagraphObj.nTextOfs;
2259                 rLevel.mnBulletOfs = (sal_uInt16)aParagraphObj.nBulletOfs;
2260                 rLevel.mnBulletChar = aParagraphObj.cBulletId;
2261                 FontCollectionEntry aFontDescEntry( aParagraphObj.aFontDesc.Name, aParagraphObj.aFontDesc.Family,
2262                                                         aParagraphObj.aFontDesc.Pitch, aParagraphObj.aFontDesc.CharSet );
2263                 rLevel.mnBulletFont = (sal_uInt16)rFontCollection.GetId( aFontDescEntry );
2264                 rLevel.mnBulletHeight = aParagraphObj.nBulletRealSize;
2265                 rLevel.mnBulletColor = aParagraphObj.nBulletColor;
2266 
2267                 rLevel.mbExtendedBulletsUsed = aParagraphObj.bExtendedBulletsUsed;
2268                 rLevel.mnBulletId = aParagraphObj.nBulletId;
2269                 rLevel.mnNumberingType = aParagraphObj.nNumberingType;
2270                 rLevel.mnBulletStart = aParagraphObj.nStartWith;
2271                 rLevel.mnMappedNumType = aParagraphObj.nMappedNumType;
2272 			}
2273         }
2274     }
2275 }
2276 
Write(SvStream & rSt,PptEscherEx *,sal_uInt16 nLev,sal_Bool,sal_Bool bSimpleText,const::com::sun::star::uno::Reference<::com::sun::star::beans::XPropertySet> & rPagePropSet)2277 void PPTExParaSheet::Write( SvStream& rSt, PptEscherEx*, sal_uInt16 nLev, sal_Bool, sal_Bool bSimpleText,
2278     const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rPagePropSet )
2279 {
2280     const PPTExParaLevel& rLev = maParaLevel[ nLev ];
2281 
2282     if ( maParaLevel[ 0 ].mbExtendedBulletsUsed || maParaLevel[ 1 ].mbExtendedBulletsUsed ||
2283             maParaLevel[ 2 ].mbExtendedBulletsUsed || maParaLevel[ 3 ].mbExtendedBulletsUsed ||
2284                 maParaLevel[ 4 ].mbExtendedBulletsUsed )
2285     {
2286         SvStream& rOut = rBuProv.aBuExMasterStream;
2287         if ( !nLev )
2288         {
2289             rOut << (sal_uInt32)( ( EPP_PST_ExtendedParagraphMasterAtom << 16 ) | ( mnInstance << 4 ) )
2290                  << (sal_uInt32)( 5 * 16 + 2 )
2291                  << (sal_uInt16)5;              // depth
2292         }
2293         sal_uInt16 nBulletId = rLev.mnBulletId;
2294         if ( rLev.mnNumberingType != SVX_NUM_BITMAP )
2295             nBulletId = 0xffff;
2296         rOut << (sal_uInt32)0x03800000
2297              << (sal_uInt16)nBulletId
2298              << (sal_uInt32)rLev.mnMappedNumType
2299              << (sal_uInt16)rLev.mnBulletStart
2300              << (sal_uInt32)0;
2301     }
2302 
2303     sal_uInt32 nParaFlags = 0x3ffdff;
2304     sal_uInt16 nBulletFlags = ( rLev.mbIsBullet ) ? 0xf : 0xe;
2305 
2306     if ( nLev )
2307 		nParaFlags &= 0x207fff;
2308 	if ( bSimpleText )
2309 		nParaFlags &= 0x7fff;
2310     sal_uInt32 nBulletColor = rLev.mnBulletColor;
2311     if ( nBulletColor == COL_AUTO )
2312     {
2313         sal_Bool bIsDark = sal_False;
2314         ::com::sun::star::uno::Any aAny;
2315         if ( PropValue::GetPropertyValue( aAny, rPagePropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsBackgroundDark" ) ), sal_True ) )
2316             aAny >>= bIsDark;
2317         nBulletColor = bIsDark ? 0xffffff : 0x000000;
2318     }
2319     nBulletColor &= 0xffffff;
2320     nBulletColor |= 0xfe000000;
2321     rSt << nParaFlags
2322         << nBulletFlags
2323         << rLev.mnBulletChar
2324         << rLev.mnBulletFont
2325         << rLev.mnBulletHeight
2326         << nBulletColor
2327         << rLev.mnAdjust
2328         << rLev.mnLineFeed
2329         << rLev.mnUpperDist
2330         << rLev.mnLowerDist
2331         << rLev.mnTextOfs
2332         << rLev.mnBulletOfs;
2333 
2334     if ( bSimpleText || nLev )
2335 	{
2336 		if ( nParaFlags & 0x200000 )
2337 			rSt << rLev.mnBiDi;
2338 	}
2339 	else
2340 	{
2341 		rSt << rLev.mnDefaultTab
2342 			<< (sal_uInt16)0
2343 			<< (sal_uInt16)0
2344 			<< rLev.mnAsianSettings
2345 			<< rLev.mnBiDi;
2346 	}
2347 }
2348 
2349 
PPTExStyleSheet(sal_uInt16 nDefaultTab,PPTExBulletProvider & rBuProv)2350 PPTExStyleSheet::PPTExStyleSheet( sal_uInt16 nDefaultTab, PPTExBulletProvider& rBuProv )
2351 {
2352     for ( int nInstance = EPP_TEXTTYPE_Title; nInstance <= EPP_TEXTTYPE_QuarterBody; nInstance++ )
2353     {
2354         mpParaSheet[ nInstance ] = ( nInstance == EPP_TEXTTYPE_notUsed ) ? NULL : new PPTExParaSheet( nInstance, nDefaultTab, rBuProv );
2355         mpCharSheet[ nInstance ] = ( nInstance == EPP_TEXTTYPE_notUsed ) ? NULL : new PPTExCharSheet( nInstance );
2356     }
2357 }
2358 
~PPTExStyleSheet()2359 PPTExStyleSheet::~PPTExStyleSheet()
2360 {
2361     for ( int nInstance = EPP_TEXTTYPE_Title; nInstance <= EPP_TEXTTYPE_QuarterBody; nInstance++ )
2362     {
2363         if ( nInstance == EPP_TEXTTYPE_notUsed )
2364             continue;
2365 
2366         delete mpParaSheet[ nInstance ];
2367         delete mpCharSheet[ nInstance ];
2368     }
2369 }
2370 
SetStyleSheet(const::com::sun::star::uno::Reference<::com::sun::star::beans::XPropertySet> & rXPropSet,FontCollection & rFontCollection,int nInstance,int nLevel)2371 void PPTExStyleSheet::SetStyleSheet( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
2372                                         FontCollection& rFontCollection, int nInstance, int nLevel )
2373 {
2374     if ( nInstance == EPP_TEXTTYPE_notUsed )
2375         return;
2376     mpCharSheet[ nInstance ]->SetStyleSheet( rXPropSet, rFontCollection, nLevel );
2377     mpParaSheet[ nInstance ]->SetStyleSheet( rXPropSet, rFontCollection, nLevel, mpCharSheet[ nInstance ]->maCharLevel[ nLevel ] );
2378 }
2379 
IsHardAttribute(sal_uInt32 nInstance,sal_uInt32 nLevel,PPTExTextAttr eAttr,sal_uInt32 nValue)2380 sal_Bool PPTExStyleSheet::IsHardAttribute( sal_uInt32 nInstance, sal_uInt32 nLevel, PPTExTextAttr eAttr, sal_uInt32 nValue )
2381 {
2382     const PPTExParaLevel& rPara = mpParaSheet[ nInstance ]->maParaLevel[ nLevel ];
2383     const PPTExCharLevel& rChar = mpCharSheet[ nInstance ]->maCharLevel[ nLevel ];
2384 
2385     sal_uInt32 nFlag = 0;
2386 
2387     switch ( eAttr )
2388     {
2389         case ParaAttr_BulletOn : return ( rPara.mbIsBullet ) ? ( nValue ) ? sal_False : sal_True : ( nValue ) ? sal_True : sal_False;
2390         case ParaAttr_BuHardFont :
2391         case ParaAttr_BulletFont : return ( rPara.mnBulletFont != nValue );
2392         case ParaAttr_BuHardColor :
2393         case ParaAttr_BulletColor : return ( rPara.mnBulletColor != nValue );
2394         case ParaAttr_BuHardHeight :
2395         case ParaAttr_BulletHeight : return ( rPara.mnBulletHeight != nValue );
2396         case ParaAttr_BulletChar : return ( rPara.mnBulletChar != nValue );
2397         case ParaAttr_Adjust : return ( rPara.mnAdjust != nValue );
2398         case ParaAttr_LineFeed : return ( rPara.mnLineFeed != nValue );
2399         case ParaAttr_UpperDist : return ( rPara.mnUpperDist != nValue );
2400         case ParaAttr_LowerDist : return ( rPara.mnLowerDist != nValue );
2401         case ParaAttr_TextOfs : return ( rPara.mnTextOfs != nValue );
2402         case ParaAttr_BulletOfs : return ( rPara.mnBulletOfs != nValue );
2403         case ParaAttr_DefaultTab : return ( rPara.mnDefaultTab != nValue );
2404 		case ParaAttr_BiDi : return ( rPara.mnBiDi != nValue );
2405         case CharAttr_Bold : nFlag = 1; break;
2406         case CharAttr_Italic : nFlag = 2; break;
2407         case CharAttr_Underline : nFlag = 4; break;
2408         case CharAttr_Shadow : nFlag = 16; break;
2409         case CharAttr_Strikeout : nFlag = 256; break;
2410         case CharAttr_Embossed : nFlag = 512; break;
2411         case CharAttr_Font : return ( rChar.mnFont != nValue );
2412         case CharAttr_AsianOrComplexFont : return ( rChar.mnAsianOrComplexFont != nValue );
2413         case CharAttr_Symbol : return sal_True;
2414         case CharAttr_FontHeight : return ( rChar.mnFontHeight != nValue );
2415         case CharAttr_FontColor : return ( rChar.mnFontColor != nValue );
2416         case CharAttr_Escapement : return ( rChar.mnEscapement != nValue );
2417 		default:
2418 			break;
2419     };
2420     if ( nFlag )
2421     {
2422         if ( rChar.mnFlags & nFlag )
2423             return ( ( nValue & nFlag ) == 0 );
2424         else
2425             return ( ( nValue & nFlag ) != 0 );
2426     }
2427     return sal_True;
2428 }
2429 
SizeOfTxCFStyleAtom() const2430 sal_uInt32 PPTExStyleSheet::SizeOfTxCFStyleAtom() const
2431 {
2432     return 24;
2433 }
2434 
2435 // the TxCFStyleAtom stores the text properties that are used
2436 // when creating new objects in PowerPoint.
2437 
WriteTxCFStyleAtom(SvStream & rSt)2438 void PPTExStyleSheet::WriteTxCFStyleAtom( SvStream& rSt )
2439 {
2440     const PPTExCharLevel& rCharStyle = mpCharSheet[ EPP_TEXTTYPE_Other ]->maCharLevel[ 0 ];
2441 
2442     sal_uInt16 nFlags = 0x60        // ??
2443                       | 0x02        // fontsize;
2444                       | 0x04;       // fontcolor
2445 
2446     sal_uInt32 nCharFlags = rCharStyle.mnFlags;
2447     nCharFlags &= CharAttr_Italic | CharAttr_Bold | CharAttr_Underline | CharAttr_Shadow;
2448 
2449     rSt << (sal_uInt32)( EPP_TxCFStyleAtom << 16 )  // recordheader
2450         << SizeOfTxCFStyleAtom() - 8
2451         << (sal_uInt16)( 0x80 | nCharFlags )
2452         << (sal_uInt16)nFlags
2453         << (sal_uInt16)nCharFlags
2454         << (sal_Int32)-1                            // ?
2455         << rCharStyle.mnFontHeight
2456         << rCharStyle.mnFontColor;
2457 }
2458 
2459 
2460 // ---------------------------------------------------------------------------------------------
2461 
2462 // ---------------------
2463 // - exported function -
2464 // ---------------------
2465 
ExportPPT(const std::vector<com::sun::star::beans::PropertyValue> & rMediaData,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)2466 extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool __LOADONCALLAPI ExportPPT( const std::vector< com::sun::star::beans::PropertyValue >& rMediaData, SvStorageRef& rSvStorage,
2467                     ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > & rXModel,
2468                         ::com::sun::star::uno::Reference< ::com::sun::star::task::XStatusIndicator > & rXStatInd,
2469                             SvMemoryStream* pVBA, sal_uInt32 nCnvrtFlags )
2470 {
2471     PPTWriter*  pPPTWriter;
2472     sal_Bool bStatus = sal_False;
2473 
2474     pPPTWriter = new PPTWriter( rMediaData, rSvStorage, rXModel, rXStatInd, pVBA, nCnvrtFlags );
2475     if ( pPPTWriter )
2476     {
2477         bStatus = ( pPPTWriter->IsValid() == sal_True );
2478         delete pPPTWriter;
2479     }
2480 
2481     return bStatus;
2482 }
2483 
SaveVBA(SfxObjectShell & rDocShell,SvMemoryStream * & pBas)2484 extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool __LOADONCALLAPI SaveVBA( SfxObjectShell& rDocShell, SvMemoryStream*& pBas )
2485 {
2486 	SvStorageRef xDest( new SvStorage( new SvMemoryStream(), sal_True ) );
2487 	SvxImportMSVBasic aMSVBas( rDocShell, *xDest, sal_False, sal_False );
2488 	aMSVBas.SaveOrDelMSVBAStorage( sal_True, String( RTL_CONSTASCII_USTRINGPARAM("_MS_VBA_Overhead") ) );
2489 
2490     SvStorageRef xOverhead = xDest->OpenSotStorage( String( RTL_CONSTASCII_USTRINGPARAM("_MS_VBA_Overhead") ) );
2491 	if ( xOverhead.Is() && ( xOverhead->GetError() == SVSTREAM_OK ) )
2492 	{
2493         SvStorageRef xOverhead2 = xOverhead->OpenSotStorage( String( RTL_CONSTASCII_USTRINGPARAM("_MS_VBA_Overhead") ) );
2494 		if ( xOverhead2.Is() && ( xOverhead2->GetError() == SVSTREAM_OK ) )
2495 		{
2496             SvStorageStreamRef xTemp = xOverhead2->OpenSotStream( String( RTL_CONSTASCII_USTRINGPARAM("_MS_VBA_Overhead2") ) );
2497 			if ( xTemp.Is() && ( xTemp->GetError() == SVSTREAM_OK ) )
2498 			{
2499 				sal_uInt32 nLen = xTemp->GetSize();
2500 				if ( nLen )
2501 				{
2502 					char* pTemp = new char[ nLen ];
2503 					if ( pTemp )
2504 					{
2505 						xTemp->Seek( STREAM_SEEK_TO_BEGIN );
2506 						xTemp->Read( pTemp, nLen );
2507 						pBas = new SvMemoryStream( pTemp, nLen, STREAM_READ );
2508 						pBas->ObjectOwnsMemory( sal_True );
2509 						return sal_True;
2510 					}
2511 				}
2512 			}
2513 		}
2514 	}
2515 
2516 	return sal_False;
2517 }
2518 
2519