Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <eppt.hxx>
21 : #include "epptdef.hxx"
22 : #include <tools/globname.hxx>
23 : #include <tools/poly.hxx>
24 : #include <vcl/graph.hxx>
25 : #include <vcl/bmpacc.hxx>
26 : #include <vcl/gradient.hxx>
27 : #include <rtl/ustring.hxx>
28 : #include <tools/stream.hxx>
29 : #include <vcl/fltcall.hxx>
30 : #include <sfx2/docfile.hxx>
31 : #include <svx/unoapi.hxx>
32 : #include <svx/svdobj.hxx>
33 : #include <svx/svdoole2.hxx>
34 : #include <svx/svdmodel.hxx>
35 : #include <svx/svdpage.hxx>
36 : #include <com/sun/star/view/PaperOrientation.hpp>
37 : #include <com/sun/star/view/PaperFormat.hpp>
38 : #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
39 : #include <com/sun/star/office/XAnnotation.hpp>
40 : #include <com/sun/star/office/XAnnotationAccess.hpp>
41 : #include <com/sun/star/office/XAnnotationEnumeration.hpp>
42 : #include <com/sun/star/geometry/RealPoint2D.hpp>
43 : #include <com/sun/star/util/DateTime.hpp>
44 : #include <tools/zcodec.hxx>
45 : #include <editeng/svxenum.hxx>
46 : #include <sot/storinfo.hxx>
47 : #include <filter/msfilter/msoleexp.hxx>
48 : #include <vcl/virdev.hxx>
49 : #include <vcl/wmf.hxx>
50 : #include <filter/msfilter/msdffimp.hxx>
51 : #include <filter/msfilter/svxmsbas.hxx>
52 : #include <editeng/flditem.hxx>
53 : #include <sfx2/docinf.hxx>
54 : #include <oox/export/utils.hxx>
55 : #include <oox/ole/olehelper.hxx>
56 : #include <rtl/math.hxx>
57 :
58 : #include <sfx2/objsh.hxx>
59 : // complete SfxObjectShell for SaveVBA under -fsanitize=function
60 :
61 : using namespace com::sun::star;
62 : using namespace ::com::sun::star::uno;
63 : using namespace ::com::sun::star::presentation;
64 :
65 : using ::com::sun::star::beans::XPropertySet;
66 :
67 : //============================ PPTWriter ==================================
68 :
69 3 : PPTWriter::PPTWriter( tools::SvRef<SotStorage>& rSvStorage,
70 : ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > & rXModel,
71 : ::com::sun::star::uno::Reference< ::com::sun::star::task::XStatusIndicator > & rXStatInd,
72 : SvMemoryStream* pVBA, sal_uInt32 nCnvrtFlags ) :
73 : PPTWriterBase ( rXModel, rXStatInd ),
74 : mnCnvrtFlags ( nCnvrtFlags ),
75 : mbStatus ( false ),
76 : mbUseNewAnimations ( true ),
77 : mnStatMaxValue ( 0 ),
78 : mnLatestStatValue ( 0 ),
79 : mnTextStyle( 0 ),
80 : mbFontIndependentLineSpacing( false ),
81 : mnTextSize( 0 ),
82 : mrStg ( rSvStorage ),
83 : mpCurUserStrm ( NULL ),
84 : mpStrm ( NULL ),
85 : mpPicStrm ( NULL ),
86 : mpPptEscherEx ( NULL ),
87 : mnVBAOleOfs ( 0 ),
88 : mpVBA ( pVBA ),
89 : mnExEmbed ( 0 ),
90 3 : mpExEmbed ( new SvMemoryStream ),
91 : mnDrawings ( 0 ),
92 : mnPagesWritten ( 0 ),
93 : mnUniqueSlideIdentifier ( 0 ),
94 : mnTxId ( 0x7a2f64 ),
95 : mnDiaMode ( 0 ),
96 : mnShapeMasterTitle ( 0 ),
97 6 : mnShapeMasterBody ( 0 )
98 : {
99 3 : }
100 :
101 3 : void PPTWriter::exportPPTPre( const std::vector< com::sun::star::beans::PropertyValue >& rMediaData )
102 : {
103 3 : if ( !mrStg.Is() )
104 0 : return;
105 :
106 : // master pages + slides and notes + notes master page
107 3 : mnDrawings = mnMasterPages + ( mnPages << 1 ) + 1;
108 :
109 3 : if ( mXStatusIndicator.is() )
110 : {
111 0 : mbStatusIndicator = true;
112 0 : mnStatMaxValue = ( mnPages + mnMasterPages ) * 5;
113 0 : mXStatusIndicator->start( OUString( "PowerPoint Export" ), mnStatMaxValue + ( mnStatMaxValue >> 3 ) );
114 : }
115 :
116 3 : SvGlobalName aGName( 0x64818d10L, 0x4f9b, 0x11cf, 0x86, 0xea, 0x00, 0xaa, 0x00, 0xb9, 0x29, 0xe8 );
117 3 : mrStg->SetClass( aGName, SotClipboardFormatId::NONE, OUString("MS PowerPoint 97") );
118 :
119 3 : if ( !ImplCreateCurrentUserStream() )
120 0 : return;
121 :
122 3 : mpStrm = mrStg->OpenSotStream( OUString( "PowerPoint Document" ) );
123 3 : if ( !mpStrm )
124 0 : return;
125 :
126 3 : if ( !mpPicStrm )
127 3 : mpPicStrm = mrStg->OpenSotStream( OUString( "Pictures" ) );
128 :
129 3 : for (std::vector< com::sun::star::beans::PropertyValue >::const_iterator aIter( rMediaData.begin() ), aEnd( rMediaData.end() );
130 : aIter != aEnd ; ++aIter)
131 : {
132 3 : if ( (*aIter).Name == "BaseURI" )
133 : {
134 3 : (*aIter).Value >>= maBaseURI;
135 3 : break;
136 : }
137 : }
138 3 : mpPptEscherEx = new PptEscherEx( *mpStrm, maBaseURI );
139 : }
140 :
141 3 : void PPTWriter::exportPPTPost( )
142 : {
143 3 : if ( !ImplCloseDocument() )
144 0 : return;
145 :
146 3 : if ( mbStatusIndicator )
147 : {
148 0 : mXStatusIndicator->setText( OUString( "PowerPoint Export" ) );
149 0 : sal_uInt32 nValue = mnStatMaxValue + ( mnStatMaxValue >> 3 );
150 0 : if ( nValue > mnLatestStatValue )
151 : {
152 0 : mXStatusIndicator->setValue( nValue );
153 0 : mnLatestStatValue = nValue;
154 : }
155 : }
156 :
157 3 : ImplWriteOLE();
158 :
159 3 : ImplWriteVBA();
160 :
161 3 : if ( !ImplWriteAtomEnding() )
162 0 : return;
163 :
164 3 : if ( !ImplCreateDocumentSummaryInformation() )
165 0 : return;
166 :
167 3 : mbStatus = true;
168 : };
169 :
170 : void ImplExportComments( uno::Reference< drawing::XDrawPage > xPage, SvMemoryStream& rBinaryTagData10Atom );
171 :
172 5 : void PPTWriter::ImplWriteSlide( sal_uInt32 nPageNum, sal_uInt32 nMasterNum, sal_uInt16 nMode,
173 : bool bHasBackground, Reference< XPropertySet > aXBackgroundPropSet )
174 : {
175 5 : Any aAny;
176 :
177 5 : const PHLayout& rLayout = GetLayout( mXPagePropSet );
178 5 : mpPptEscherEx->PtReplaceOrInsert( EPP_Persist_Slide | nPageNum, mpStrm->Tell() );
179 5 : mpPptEscherEx->OpenContainer( EPP_Slide );
180 5 : mpPptEscherEx->AddAtom( 24, EPP_SlideAtom, 2 );
181 5 : mpStrm->WriteInt32( static_cast<sal_Int32>(rLayout.nLayout) );
182 5 : mpStrm->Write( rLayout.nPlaceHolder, 8 ); // placeholderIDs (8 parts)
183 5 : mpStrm->WriteUInt32( nMasterNum | 0x80000000 ) // master ID (equals 0x80000000 on a master page)
184 10 : .WriteUInt32( nPageNum + 0x100 ) // notes ID (equals null if no notes are present)
185 10 : .WriteUInt16( nMode )
186 5 : .WriteUInt16( 0 ); // padword
187 :
188 5 : mnDiaMode = 0;
189 5 : bool bVisible = true;
190 5 : ::com::sun::star::presentation::FadeEffect eFe = ::com::sun::star::presentation::FadeEffect_NONE;
191 :
192 5 : if ( GetPropertyValue( aAny, mXPagePropSet, OUString( "Visible" ) ) )
193 5 : aAny >>= bVisible;
194 5 : if ( GetPropertyValue( aAny, mXPagePropSet, OUString( "Change" ) ) )
195 : {
196 5 : switch ( *static_cast<sal_Int32 const *>(aAny.getValue()) )
197 : {
198 : case 1 : // automatic
199 0 : mnDiaMode++;
200 : // fall-through
201 : case 2 : // semi-automatic
202 0 : mnDiaMode++;
203 : default :
204 : case 0 : // manual
205 5 : break;
206 : }
207 : }
208 5 : if ( GetPropertyValue( aAny, mXPagePropSet, OUString( "Effect" ) ) )
209 5 : aAny >>= eFe;
210 :
211 5 : sal_uInt32 nSoundRef = 0;
212 5 : bool bIsSound = false;
213 5 : bool bStopSound = false;
214 5 : bool bLoopSound = false;
215 :
216 5 : if ( GetPropertyValue( aAny, mXPagePropSet, OUString( "Sound" ) ) )
217 : {
218 5 : OUString aSoundURL;
219 5 : if ( aAny >>= aSoundURL )
220 : {
221 5 : nSoundRef = maSoundCollection.GetId( aSoundURL );
222 5 : bIsSound = true;
223 : }
224 : else
225 0 : aAny >>= bStopSound;
226 : }
227 5 : if ( GetPropertyValue( aAny, mXPagePropSet, OUString( "LoopSound" ) ) )
228 5 : aAny >>= bLoopSound;
229 :
230 5 : bool bNeedsSSSlideInfoAtom = !bVisible
231 5 : || ( mnDiaMode == 2 )
232 5 : || ( bIsSound )
233 0 : || ( bStopSound )
234 5 : || ( eFe != ::com::sun::star::presentation::FadeEffect_NONE );
235 5 : if ( bNeedsSSSlideInfoAtom )
236 : {
237 5 : sal_uInt8 nDirection = 0;
238 5 : sal_uInt8 nTransitionType = 0;
239 5 : sal_uInt16 nBuildFlags = 1; // advange by mouseclick
240 5 : sal_Int32 nSlideTime = 0; // still has to !!!
241 5 : sal_uInt8 nSpeed = 1;
242 :
243 5 : if ( GetPropertyValue( aAny, mXPagePropSet, OUString( "Speed" ) ) )
244 : {
245 : ::com::sun::star::presentation::AnimationSpeed aAs;
246 5 : aAny >>= aAs;
247 5 : nSpeed = (sal_uInt8)aAs;
248 : }
249 5 : sal_Int16 nTT = 0;
250 15 : if ( GetPropertyValue( aAny, mXPagePropSet, OUString( "TransitionType" ) )
251 15 : && ( aAny >>= nTT ) )
252 : {
253 5 : sal_Int16 nTST = 0;
254 15 : if ( GetPropertyValue( aAny, mXPagePropSet, OUString( "TransitionSubtype" ) )
255 15 : && ( aAny >>= nTST ) )
256 5 : nTransitionType = GetTransition( nTT, nTST, eFe, nDirection );
257 :
258 : }
259 5 : if ( !nTransitionType )
260 5 : nTransitionType = GetTransition( eFe, nDirection );
261 5 : if ( mnDiaMode == 2 ) // automatic ?
262 0 : nBuildFlags |= 0x400;
263 5 : if ( !bVisible )
264 0 : nBuildFlags |= 4;
265 5 : if ( bIsSound )
266 5 : nBuildFlags |= 16;
267 5 : if ( bLoopSound )
268 0 : nBuildFlags |= 64;
269 5 : if ( bStopSound )
270 0 : nBuildFlags |= 256;
271 :
272 5 : if ( GetPropertyValue( aAny, mXPagePropSet, OUString( "Duration" ) ) )// duration of this slide
273 5 : nSlideTime = *static_cast<sal_Int32 const *>(aAny.getValue()) << 10; // in ticks
274 :
275 5 : mpPptEscherEx->AddAtom( 16, EPP_SSSlideInfoAtom );
276 5 : mpStrm->WriteInt32( nSlideTime ) // standtime in ticks
277 5 : .WriteUInt32( nSoundRef )
278 10 : .WriteUChar( nDirection )
279 10 : .WriteUChar( nTransitionType )
280 10 : .WriteUInt16( nBuildFlags )
281 10 : .WriteUChar( nSpeed )
282 5 : .WriteUChar( 0 ).WriteUChar( 0 ).WriteUChar( 0 );
283 : }
284 :
285 5 : ImplCreateHeaderFooters( mXPagePropSet );
286 :
287 5 : EscherSolverContainer aSolverContainer;
288 5 : mpPptEscherEx->OpenContainer( EPP_PPDrawing );
289 5 : mpPptEscherEx->OpenContainer( ESCHER_DgContainer );
290 5 : mpPptEscherEx->EnterGroup(0,0);
291 5 : ImplWritePage( rLayout, aSolverContainer, NORMAL, false, nPageNum ); // the shapes of the pages are created in the PPT document
292 5 : mpPptEscherEx->LeaveGroup();
293 :
294 5 : if ( bHasBackground )
295 0 : ImplWriteBackground( aXBackgroundPropSet );
296 : else
297 : {
298 5 : mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
299 5 : mpPptEscherEx->AddShape( ESCHER_ShpInst_Rectangle, 0xc00 ); // Flags: Connector | Background | HasSpt
300 5 : EscherPropertyContainer aPropOpt;
301 5 : aPropOpt.AddOpt( ESCHER_Prop_fillRectRight, PPTtoEMU( maDestPageSize.Width ) );
302 5 : aPropOpt.AddOpt( ESCHER_Prop_fillRectBottom, PPTtoEMU( maDestPageSize.Width ) );
303 5 : aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x120012 );
304 5 : aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x80000 );
305 5 : aPropOpt.AddOpt( ESCHER_Prop_bWMode, ESCHER_wDontShow );
306 5 : aPropOpt.AddOpt( ESCHER_Prop_fBackground, 0x10001 ); // if true, this is the background shape
307 5 : aPropOpt.Commit( *mpStrm );
308 5 : mpPptEscherEx->CloseContainer(); // ESCHER_SpContainer
309 : }
310 :
311 5 : aSolverContainer.WriteSolver( *mpStrm );
312 :
313 5 : mpPptEscherEx->CloseContainer(); // ESCHER_DgContainer
314 5 : mpPptEscherEx->CloseContainer(); // EPP_Drawing
315 5 : mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 1 );
316 5 : mpStrm->WriteUInt32( 0xffffff ).WriteUInt32( 0x000000 ).WriteUInt32( 0x808080 ).WriteUInt32( 0x000000 ).WriteUInt32( 0x99cc00 ).WriteUInt32( 0xcc3333 ).WriteUInt32( 0xffcccc ).WriteUInt32( 0xb2b2b2 );
317 :
318 10 : SvMemoryStream aBinaryTagData10Atom;
319 5 : ImplExportComments( mXDrawPage, aBinaryTagData10Atom );
320 5 : if ( mbUseNewAnimations )
321 : {
322 5 : SvMemoryStream amsofbtAnimGroup;
323 10 : ppt::AnimationExporter aExporter( aSolverContainer, maSoundCollection );
324 5 : aExporter.doexport( mXDrawPage, amsofbtAnimGroup );
325 5 : sal_uInt32 nmsofbtAnimGroupSize = amsofbtAnimGroup.Tell();
326 5 : if ( nmsofbtAnimGroupSize )
327 : {
328 : {
329 5 : EscherExAtom aMagic2( aBinaryTagData10Atom, 0x2eeb );
330 5 : aBinaryTagData10Atom.WriteUInt32( 0x01c45df9 )
331 5 : .WriteUInt32( 0xe1471b30 );
332 : }
333 : {
334 5 : EscherExAtom aMagic( aBinaryTagData10Atom, 0x2b00 );
335 5 : aBinaryTagData10Atom.WriteUInt32( 0 );
336 : }
337 5 : aBinaryTagData10Atom.Write( amsofbtAnimGroup.GetData(), amsofbtAnimGroup.Tell() );
338 : {
339 5 : EscherExContainer aMagic2( aBinaryTagData10Atom, 0x2b02 );
340 : }
341 5 : }
342 : }
343 5 : if ( aBinaryTagData10Atom.Tell() )
344 : {
345 5 : EscherExContainer aProgTags ( *mpStrm, EPP_ProgTags );
346 10 : EscherExContainer aProgBinaryTag( *mpStrm, EPP_ProgBinaryTag );
347 : {
348 5 : EscherExAtom aCString( *mpStrm, EPP_CString );
349 5 : mpStrm->WriteUInt32( 0x5f005f )
350 5 : .WriteUInt32( 0x50005f )
351 5 : .WriteUInt32( 0x540050 )
352 5 : .WriteUInt16( 0x31 )
353 5 : .WriteUInt16( 0x30 );
354 : }
355 : {
356 5 : EscherExAtom aBinaryTagData( *mpStrm, EPP_BinaryTagData );
357 5 : mpStrm->Write( aBinaryTagData10Atom.GetData(), aBinaryTagData10Atom.Tell() );
358 5 : }
359 : }
360 10 : mpPptEscherEx->CloseContainer(); // EPP_Slide
361 5 : }
362 :
363 3 : void PPTWriter::ImplWriteSlideMaster( sal_uInt32 nPageNum, Reference< XPropertySet > aXBackgroundPropSet )
364 : {
365 3 : mpPptEscherEx->PtReplaceOrInsert( EPP_Persist_MainMaster | nPageNum, mpStrm->Tell() );
366 3 : mpPptEscherEx->OpenContainer( EPP_MainMaster );
367 3 : mpPptEscherEx->AddAtom( 24, EPP_SlideAtom, 2 );
368 3 : mpStrm->WriteInt32( static_cast<sal_Int32>(EppLayout::TITLEANDBODYSLIDE) ) // slide layout -> title and body slide
369 3 : .WriteUChar( 1 ).WriteUChar( 2 ).WriteUChar( 0 ).WriteUChar( 0 ).WriteUChar( 0 ).WriteUChar( 0 ).WriteUChar( 0 ).WriteUChar( 0 ) // placeholderID
370 3 : .WriteUInt32( 0 ) // master ID (equals null at a master page)
371 3 : .WriteUInt32( 0 ) // notes ID (equals null if no notes are present)
372 3 : .WriteUInt16( 0 ) // Bit 1: Follow master objects, Bit 2: Follow master scheme, Bit 3: Follow master background
373 3 : .WriteUInt16( 0 ); // padword
374 :
375 3 : mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 6 );
376 3 : mpStrm->WriteUInt32( 0xffffff ).WriteUInt32( 0x000000 ).WriteUInt32( 0x808080 ).WriteUInt32( 0x000000 ).WriteUInt32( 0x99cc00 ).WriteUInt32( 0xcc3333 ).WriteUInt32( 0xffcccc ).WriteUInt32( 0xb2b2b2 );
377 3 : mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 6 );
378 3 : mpStrm->WriteUInt32( 0xff0000 ).WriteUInt32( 0xffffff ).WriteUInt32( 0x000000 ).WriteUInt32( 0x00ffff ).WriteUInt32( 0x0099ff ).WriteUInt32( 0xffff00 ).WriteUInt32( 0x0000ff ).WriteUInt32( 0x969696 );
379 3 : mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 6 );
380 3 : mpStrm->WriteUInt32( 0xccffff ).WriteUInt32( 0x000000 ).WriteUInt32( 0x336666 ).WriteUInt32( 0x008080 ).WriteUInt32( 0x339933 ).WriteUInt32( 0x000080 ).WriteUInt32( 0xcc3300 ).WriteUInt32( 0x66ccff );
381 3 : mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 6 );
382 3 : mpStrm->WriteUInt32( 0xffffff ).WriteUInt32( 0x000000 ).WriteUInt32( 0x333333 ).WriteUInt32( 0x000000 ).WriteUInt32( 0xdddddd ).WriteUInt32( 0x808080 ).WriteUInt32( 0x4d4d4d ).WriteUInt32( 0xeaeaea );
383 3 : mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 6 );
384 3 : mpStrm->WriteUInt32( 0xffffff ).WriteUInt32( 0x000000 ).WriteUInt32( 0x808080 ).WriteUInt32( 0x000000 ).WriteUInt32( 0x66ccff ).WriteUInt32( 0xff0000 ).WriteUInt32( 0xcc00cc ).WriteUInt32( 0xc0c0c0 );
385 3 : mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 6 );
386 3 : mpStrm->WriteUInt32( 0xffffff ).WriteUInt32( 0x000000 ).WriteUInt32( 0x808080 ).WriteUInt32( 0x000000 ).WriteUInt32( 0xc0c0c0 ).WriteUInt32( 0xff6600 ).WriteUInt32( 0x0000ff ).WriteUInt32( 0x009900 );
387 3 : mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 6 );
388 3 : mpStrm->WriteUInt32( 0xffffff ).WriteUInt32( 0x000000 ).WriteUInt32( 0x808080 ).WriteUInt32( 0x000000 ).WriteUInt32( 0xff9933 ).WriteUInt32( 0xccff99 ).WriteUInt32( 0xcc00cc ).WriteUInt32( 0xb2b2b2 );
389 :
390 30 : for ( int nInstance = EPP_TEXTTYPE_Title; nInstance <= EPP_TEXTTYPE_QuarterBody; nInstance++ )
391 : {
392 27 : if ( nInstance == EPP_TEXTTYPE_notUsed )
393 3 : continue;
394 :
395 : // the auto color is dependent to the page background,so we have to set a page that is in the right context
396 24 : if ( nInstance == EPP_TEXTTYPE_Notes )
397 3 : (void)GetPageByIndex(0, NOTICE);
398 : else
399 21 : (void)GetPageByIndex(0, MASTER);
400 :
401 24 : mpPptEscherEx->BeginAtom();
402 :
403 24 : bool bFirst = true;
404 24 : bool bSimpleText = false;
405 :
406 24 : mpStrm->WriteUInt16( 5 ); // paragraph count
407 :
408 144 : for ( sal_uInt16 nLev = 0; nLev < 5; nLev++ )
409 : {
410 120 : if ( nInstance >= EPP_TEXTTYPE_CenterBody )
411 : {
412 60 : bFirst = false;
413 60 : bSimpleText = true;
414 60 : mpStrm->WriteUInt16( nLev );
415 : }
416 120 : mpStyleSheet->mpParaSheet[ nInstance ]->Write( *mpStrm, mpPptEscherEx, nLev, bFirst, bSimpleText, mXPagePropSet );
417 120 : mpStyleSheet->mpCharSheet[ nInstance ]->Write( *mpStrm, mpPptEscherEx, nLev, bFirst, bSimpleText, mXPagePropSet );
418 120 : bFirst = false;
419 : }
420 24 : mpPptEscherEx->EndAtom( EPP_TxMasterStyleAtom, 0, nInstance );
421 : }
422 3 : GetPageByIndex( nPageNum, MASTER );
423 :
424 3 : EscherSolverContainer aSolverContainer;
425 :
426 3 : mpPptEscherEx->OpenContainer( EPP_PPDrawing );
427 3 : mpPptEscherEx->OpenContainer( ESCHER_DgContainer );
428 :
429 3 : mpPptEscherEx->EnterGroup(0,0);
430 3 : ImplWritePage( GetLayout( 0 ), aSolverContainer, MASTER, true ); // the shapes of the pages are created in the PPT document
431 3 : mpPptEscherEx->LeaveGroup();
432 :
433 3 : ImplWriteBackground( aXBackgroundPropSet );
434 :
435 3 : aSolverContainer.WriteSolver( *mpStrm );
436 :
437 3 : mpPptEscherEx->CloseContainer(); // ESCHER_DgContainer
438 3 : mpPptEscherEx->CloseContainer(); // EPP_Drawing
439 3 : mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 1 );
440 3 : mpStrm->WriteUInt32( 0xffffff ).WriteUInt32( 0x000000 ).WriteUInt32( 0x808080 ).WriteUInt32( 0x000000 ).WriteUInt32( 0x99cc00 ).WriteUInt32( 0xcc3333 ).WriteUInt32( 0xffcccc ).WriteUInt32( 0xb2b2b2 );
441 :
442 3 : if ( aBuExMasterStream.Tell() )
443 : {
444 0 : ImplProgTagContainer( mpStrm, &aBuExMasterStream );
445 : }
446 3 : mpPptEscherEx->CloseContainer(); // EPP_MainMaster
447 3 : };
448 :
449 9 : PPTWriter::~PPTWriter()
450 : {
451 3 : delete mpExEmbed;
452 3 : delete mpPptEscherEx;
453 3 : delete mpCurUserStrm;
454 3 : delete mpPicStrm;
455 3 : delete mpStrm;
456 :
457 3 : std::vector< PPTExStyleSheet* >::iterator aStyleSheetIter( maStyleSheetList.begin() );
458 9 : while( aStyleSheetIter < maStyleSheetList.end() )
459 3 : delete *aStyleSheetIter++;
460 :
461 3 : for ( std::vector<PPTExOleObjEntry*>::const_iterator it = maExOleObj.begin(); it != maExOleObj.end(); ++it )
462 0 : delete *it;
463 :
464 3 : if ( mbStatusIndicator )
465 0 : mXStatusIndicator->end();
466 6 : }
467 :
468 3 : bool PPTWriter::ImplCreateCurrentUserStream()
469 : {
470 3 : mpCurUserStrm = mrStg->OpenSotStream( OUString( "Current User" ) );
471 3 : if ( !mpCurUserStrm )
472 0 : return false;
473 3 : char pUserName[] = "Current User";
474 3 : sal_uInt32 nLenOfUserName = strlen( pUserName );
475 3 : sal_uInt32 nSizeOfRecord = 0x14 + ( ( nLenOfUserName + 4 ) & ~ 3 );
476 :
477 3 : mpCurUserStrm->WriteUInt16( 0 ).WriteUInt16( EPP_CurrentUserAtom ).WriteUInt32( nSizeOfRecord );
478 3 : mpCurUserStrm->WriteUInt32( 0x14 ) // Len
479 3 : .WriteUInt32( 0xe391c05f ); // Magic
480 :
481 3 : sal_uInt32 nEditPos = mpCurUserStrm->Tell();
482 3 : mpCurUserStrm->WriteUInt32( 0x0 ) // OffsetToCurrentEdit;
483 6 : .WriteUInt16( nLenOfUserName )
484 3 : .WriteUInt16( 0x3f4 ) // DocFileVersion
485 3 : .WriteUChar( 3 ) // MajorVersion
486 3 : .WriteUChar( 0 ) // MinorVersion
487 3 : .WriteUInt16( 0 ); // Pad Word
488 3 : pUserName[ nLenOfUserName ] = 8;
489 3 : mpCurUserStrm->Write( pUserName, nLenOfUserName + 1 );
490 12 : for ( sal_uInt32 i = 0x15 + nLenOfUserName; i < nSizeOfRecord; i++ )
491 : {
492 9 : mpCurUserStrm->WriteUChar( 0 ); // pad bytes
493 : }
494 3 : mpCurUserStrm->Seek( nEditPos );
495 3 : return true;
496 : };
497 :
498 3 : bool PPTWriter::ImplCreateDocumentSummaryInformation()
499 : {
500 : uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
501 3 : mXModel, uno::UNO_QUERY_THROW);
502 : uno::Reference<document::XDocumentProperties> xDocProps(
503 6 : xDPS->getDocumentProperties());
504 :
505 3 : if (xDocProps.is()) {
506 :
507 : // no idea what this is...
508 : static const sal_uInt8 aGuid[ 0x52 ] =
509 : {
510 : 0x4e, 0x00, 0x00, 0x00,
511 : '{',0,'D',0,'B',0,'1',0,'A',0,'C',0,'9',0,'6',0,'4',0,'-',0,
512 : 'E',0,'3',0,'9',0,'C',0,'-',0,'1',0,'1',0,'D',0,'2',0,'-',0,
513 : 'A',0,'1',0,'E',0,'F',0,'-',0,'0',0,'0',0,'6',0,'0',0,'9',0,
514 : '7',0,'D',0,'A',0,'5',0,'6',0,'8',0,'9',0,'}',0
515 : };
516 3 : uno::Sequence<sal_uInt8> aGuidSeq(aGuid, 0x52);
517 :
518 6 : SvMemoryStream aHyperBlob;
519 3 : ImplCreateHyperBlob( aHyperBlob );
520 :
521 6 : uno::Sequence<sal_uInt8> aHyperSeq(aHyperBlob.Tell());
522 : const sal_uInt8* pBlob(
523 3 : static_cast<const sal_uInt8*>(aHyperBlob.GetData()));
524 27 : for (sal_Int32 j = 0; j < aHyperSeq.getLength(); ++j) {
525 24 : aHyperSeq[j] = pBlob[j];
526 : }
527 :
528 3 : if ( mnCnvrtFlags & 0x8000 )
529 : {
530 3 : uno::Sequence<sal_uInt8> aThumbSeq;
531 3 : if ( GetPageByIndex( 0, NORMAL ) && ImplGetPropertyValue( mXPagePropSet, OUString( "PreviewBitmap" ) ) )
532 : {
533 : aThumbSeq =
534 3 : *static_cast<const uno::Sequence<sal_uInt8>*>(mAny.getValue());
535 : }
536 : sfx2::SaveOlePropertySet( xDocProps, mrStg,
537 3 : &aThumbSeq, &aGuidSeq, &aHyperSeq);
538 : }
539 : else
540 : {
541 : sfx2::SaveOlePropertySet( xDocProps, mrStg,
542 0 : NULL, &aGuidSeq, &aHyperSeq );
543 3 : }
544 : }
545 :
546 6 : return true;
547 : }
548 :
549 0 : void PPTWriter::ImplWriteExtParaHeader( SvMemoryStream& rSt, sal_uInt32 nRef, sal_uInt32 nInstance, sal_uInt32 nSlideId )
550 : {
551 0 : if ( rSt.Tell() )
552 : {
553 : aBuExOutlineStream.WriteUInt32( ( EPP_PST_ExtendedParagraphHeaderAtom << 16 )
554 0 : | ( nRef << 4 ) )
555 0 : .WriteUInt32( 8 )
556 0 : .WriteUInt32( nSlideId )
557 0 : .WriteUInt32( nInstance );
558 0 : aBuExOutlineStream.Write( rSt.GetData(), rSt.Tell() );
559 : }
560 0 : }
561 :
562 16 : void PPTWriter::ImplCreateHeaderFooterStrings( SvStream& rStrm, ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& rXPagePropSet )
563 : {
564 16 : if ( rXPagePropSet.is() )
565 : {
566 16 : OUString aString;
567 32 : ::com::sun::star::uno::Any aAny;
568 16 : if ( PropValue::GetPropertyValue( aAny, rXPagePropSet, OUString( "HeaderText" ), true ) )
569 : {
570 8 : if ( aAny >>= aString )
571 8 : PPTWriter::WriteCString( rStrm, aString, 1 );
572 : }
573 16 : if ( PropValue::GetPropertyValue( aAny, rXPagePropSet, OUString( "FooterText" ), true ) )
574 : {
575 13 : if ( aAny >>= aString )
576 13 : PPTWriter::WriteCString( rStrm, aString, 2 );
577 : }
578 16 : if ( PropValue::GetPropertyValue( aAny, rXPagePropSet, OUString( "DateTimeText" ), true ) )
579 : {
580 13 : if ( aAny >>= aString )
581 13 : PPTWriter::WriteCString( rStrm, aString, 0 );
582 16 : }
583 : }
584 16 : }
585 :
586 10 : void PPTWriter::ImplCreateHeaderFooters( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& rXPagePropSet )
587 : {
588 10 : if ( rXPagePropSet.is() )
589 : {
590 10 : bool bVal = false;
591 10 : sal_uInt32 nVal = 0;
592 10 : ::com::sun::star::uno::Any aAny;
593 10 : if ( PropValue::GetPropertyValue( aAny, rXPagePropSet, OUString( "IsHeaderVisible" ), true ) )
594 : {
595 5 : if ( ( aAny >>= bVal ) && bVal )
596 5 : nVal |= 0x100000;
597 : }
598 10 : if ( PropValue::GetPropertyValue( aAny, rXPagePropSet, OUString( "IsFooterVisible" ), true ) )
599 : {
600 10 : if ( ( aAny >>= bVal ) && bVal )
601 10 : nVal |= 0x200000;
602 : }
603 10 : if ( PropValue::GetPropertyValue( aAny, rXPagePropSet, OUString( "IsDateTimeVisible" ), true ) )
604 : {
605 10 : if ( ( aAny >>= bVal ) && bVal )
606 10 : nVal |= 0x010000;
607 : }
608 10 : if ( PropValue::GetPropertyValue( aAny, rXPagePropSet, OUString( "IsPageNumberVisible" ), true ) )
609 : {
610 10 : if ( ( aAny >>= bVal ) && bVal )
611 0 : nVal |= 0x080000;
612 : }
613 10 : if ( PropValue::GetPropertyValue( aAny, rXPagePropSet, OUString( "IsDateTimeFixed" ), true ) )
614 : {
615 10 : if ( ( aAny >>= bVal ) && !bVal )
616 0 : nVal |= 0x20000;
617 : else
618 10 : nVal |= 0x40000;
619 : }
620 10 : if ( PropValue::GetPropertyValue( aAny, rXPagePropSet, OUString( "DateTimeFormat" ), true ) )
621 : {
622 10 : sal_Int32 nFormat = *static_cast<sal_Int32 const *>(aAny.getValue());
623 10 : SvxDateFormat eDateFormat = (SvxDateFormat)( nFormat & 0xf );
624 10 : SvxTimeFormat eTimeFormat = (SvxTimeFormat)( ( nFormat >> 4 ) & 0xf );
625 10 : switch( eDateFormat )
626 : {
627 : case SVXDATEFORMAT_F :
628 0 : nFormat = 1;
629 0 : break;
630 : case SVXDATEFORMAT_D :
631 0 : nFormat = 2;
632 0 : break;
633 : case SVXDATEFORMAT_C :
634 0 : nFormat = 4;
635 0 : break;
636 : default:
637 : case SVXDATEFORMAT_A :
638 10 : nFormat = 0;
639 : }
640 10 : switch( eTimeFormat )
641 : {
642 : case SVXTIMEFORMAT_24_HM :
643 0 : nFormat = 9;
644 0 : break;
645 : case SVXTIMEFORMAT_12_HM :
646 0 : nFormat = 11;
647 0 : break;
648 : case SVXTIMEFORMAT_24_HMS :
649 0 : nFormat = 10;
650 0 : break;
651 : case SVXTIMEFORMAT_12_HMS :
652 0 : nFormat = 12;
653 0 : break;
654 : default:
655 10 : break;
656 : }
657 10 : nVal |= nFormat;
658 : }
659 :
660 10 : mpPptEscherEx->OpenContainer( EPP_HeadersFooters, 0 );
661 10 : mpPptEscherEx->AddAtom( 4, EPP_HeadersFootersAtom );
662 10 : mpStrm->WriteUInt32( nVal );
663 10 : ImplCreateHeaderFooterStrings( *mpStrm, rXPagePropSet );
664 10 : mpPptEscherEx->CloseContainer();
665 : }
666 10 : }
667 :
668 3 : bool PPTWriter::ImplCreateDocument()
669 : {
670 : sal_uInt32 i;
671 3 : sal_uInt16 nSlideType = EPP_SLIDESIZE_TYPECUSTOM;
672 :
673 3 : sal_uInt32 nWidth = maDestPageSize.Width;
674 3 : sal_uInt32 nHeight = maDestPageSize.Height;
675 :
676 3 : if ( ( nWidth == 0x1680 ) && ( nHeight == 0x10e0 ) )
677 0 : nSlideType = EPP_SLIDESIZE_TYPEONSCREEN;
678 3 : else if ( ( nWidth == 0x1200 ) && ( nHeight == 0x240 ) )
679 0 : nSlideType = EPP_SLIDESIZE_TYPEBANNER;
680 3 : else if ( ( nWidth == 0x1950 ) && ( nHeight == 0x10e0 ) )
681 0 : nSlideType = EPP_SLIDESIZE_TYPE35MM;
682 3 : else if ( ( nWidth == 0x1860 ) && ( nHeight == 0x10e0 ) )
683 0 : nSlideType = EPP_SLIDESIZE_TYPEA4PAPER;
684 :
685 3 : mpPptEscherEx->OpenContainer( EPP_Document );
686 : // CREATE DOCUMENT ATOM
687 3 : mpPptEscherEx->AddAtom( 40, EPP_DocumentAtom, 1 );
688 3 : mpStrm->WriteUInt32( nWidth ) // Slide Size in Master coordinates X
689 3 : .WriteUInt32( nHeight ) // " " " " " Y
690 6 : .WriteInt32( maNotesPageSize.Width ) // Notes Page Size X
691 6 : .WriteInt32( maNotesPageSize.Height ) // " " " Y
692 3 : .WriteInt32( 1 ).WriteInt32( 2 ); // the scale used when the Powerpoint document is embedded. the default is 1:2
693 3 : mpPptEscherEx->InsertPersistOffset( EPP_MAINNOTESMASTER_PERSIST_KEY, mpStrm->Tell() );
694 3 : mpStrm->WriteUInt32( 0 ) // Reference to NotesMaster ( 0 if none );
695 3 : .WriteUInt32( 0 ) // Reference to HandoutMaster ( 0 if none );
696 3 : .WriteInt16( 1 ) // Number of the first slide;
697 6 : .WriteUInt16( nSlideType ) // Size of the document slides ( default: EPP_SLIDESIZETYPEONSCREEN )
698 3 : .WriteUChar( 0 ) // bool1 indicates if document was saved with embedded true type fonts
699 3 : .WriteUChar( 0 ) // bool1 indicates if the placeholders on the title slide are omitted
700 3 : .WriteUChar( 0 ) // bool1 right to left ( flag for Bidi version )
701 3 : .WriteUChar( 1 ); // bool1 visibility of comments shapes
702 :
703 3 : mpPptEscherEx->PtInsert( EPP_Persist_Document, mpStrm->Tell() );
704 :
705 3 : mpPptEscherEx->OpenContainer( EPP_HeadersFooters, 3 ); //Master footer (default)
706 3 : mpPptEscherEx->AddAtom( 4, EPP_HeadersFootersAtom );
707 3 : mpStrm->WriteUInt32( 0x25000d );
708 3 : if ( GetPageByIndex( 0, MASTER ) )
709 3 : ImplCreateHeaderFooterStrings( *mpStrm, mXPagePropSet );
710 3 : mpPptEscherEx->CloseContainer();
711 3 : mpPptEscherEx->OpenContainer( EPP_HeadersFooters, 4 ); //NotesMaster footer (default)
712 3 : mpPptEscherEx->AddAtom( 4, EPP_HeadersFootersAtom );
713 3 : mpStrm->WriteUInt32( 0x3d000d );
714 3 : if ( GetPageByIndex( 0, NOTICE ) )
715 3 : ImplCreateHeaderFooterStrings( *mpStrm, mXPagePropSet );
716 3 : mpPptEscherEx->CloseContainer();
717 :
718 3 : mpPptEscherEx->OpenContainer( EPP_SlideListWithText ); // animation information for the slides
719 :
720 8 : for ( i = 0; i < mnPages; i++ )
721 : {
722 5 : mpPptEscherEx->AddAtom( 20, EPP_SlidePersistAtom );
723 5 : mpPptEscherEx->InsertPersistOffset( EPP_MAINSLIDE_PERSIST_KEY | i, mpStrm->Tell() );
724 5 : mpStrm->WriteUInt32( 0 ) // psrReference - logical reference to the slide persist object ( EPP_MAINSLIDE_PERSIST_KEY )
725 5 : .WriteUInt32( 4 ) // flags - only bit 3 used, if set then slide contains shapes other than placeholders
726 5 : .WriteInt32( 0 ) // numberTexts - number of placeholder texts stored with the persist object. Allows to display outline view without loading the slide persist objects
727 10 : .WriteInt32( i + 0x100 ) // slideId - Unique slide identifier, used for OLE link monikers for example
728 5 : .WriteUInt32( 0 ); // reserved, usually 0
729 :
730 5 : if ( !GetPageByIndex( i, NORMAL ) ) // very exciting: once again through all pages
731 0 : return false;
732 5 : SetCurrentStyleSheet( GetMasterIndex( NORMAL ) );
733 :
734 : ::com::sun::star::uno::Reference< ::com::sun::star::container::XNamed >
735 5 : aXName( mXDrawPage, ::com::sun::star::uno::UNO_QUERY );
736 :
737 5 : if ( aXName.is() )
738 5 : maSlideNameList.push_back( aXName->getName() );
739 : else
740 0 : maSlideNameList.push_back( OUString() );
741 5 : }
742 3 : mpPptEscherEx->CloseContainer(); // EPP_SlideListWithText
743 :
744 3 : mpPptEscherEx->OpenContainer( EPP_SlideListWithText, 2 ); // animation information for the notes
745 8 : for( i = 0; i < mnPages; i++ )
746 : {
747 5 : mpPptEscherEx->AddAtom( 20, EPP_SlidePersistAtom );
748 5 : mpPptEscherEx->InsertPersistOffset( EPP_MAINNOTES_PERSIST_KEY | i, mpStrm->Tell() );
749 5 : mpStrm->WriteUInt32( 0 )
750 5 : .WriteUInt32( 4 )
751 5 : .WriteInt32( 0 )
752 10 : .WriteInt32( i + 0x100 )
753 5 : .WriteUInt32( 0 );
754 : }
755 3 : mpPptEscherEx->CloseContainer(); // EPP_SlideListWithText
756 :
757 : ::com::sun::star::uno::Reference< ::com::sun::star::presentation::XPresentationSupplier >
758 3 : aXPresSupplier( mXModel, ::com::sun::star::uno::UNO_QUERY ); ;
759 3 : if ( aXPresSupplier.is() )
760 : {
761 : ::com::sun::star::uno::Reference< ::com::sun::star::presentation::XPresentation >
762 3 : aXPresentation( aXPresSupplier->getPresentation() );
763 3 : if ( aXPresentation.is() )
764 : {
765 6 : mXPropSet = ::com::sun::star::uno::Reference<
766 : ::com::sun::star::beans::XPropertySet >
767 3 : ( aXPresentation, ::com::sun::star::uno::UNO_QUERY );
768 3 : if ( mXPropSet.is() )
769 : {
770 3 : OUString aCustomShow;
771 3 : sal_uInt32 nPenColor = 0x1000000;
772 3 : sal_Int32 nRestartTime = 0x7fffffff;
773 3 : sal_Int16 nStartSlide = 0;
774 3 : sal_Int16 nEndSlide = 0;
775 3 : sal_uInt32 nFlags = 0; // Bit 0: Auto advance
776 : // Bit 1 Skip builds ( do not allow slide effects )
777 : // Bit 2 Use slide range
778 : // Bit 3 Use named show
779 : // Bit 4 Browse mode on
780 : // Bit 5 Kiosk mode on
781 : // Bit 7 loop continuously
782 : // Bit ? show scrollbar
783 :
784 3 : if ( ImplGetPropertyValue( OUString( "CustomShow" ) ) )
785 : {
786 3 : aCustomShow = *static_cast<OUString const *>(mAny.getValue());
787 3 : if ( !aCustomShow.isEmpty() )
788 : {
789 0 : nFlags |= 8;
790 : }
791 : }
792 3 : if ( ( nFlags & 8 ) == 0 )
793 : {
794 3 : if ( ImplGetPropertyValue( OUString( "FirstPage" ) ) )
795 : {
796 3 : OUString aSlideName( *static_cast<OUString const *>(mAny.getValue()) );
797 :
798 : std::vector<OUString>::const_iterator pIter = std::find(
799 3 : maSlideNameList.begin(),maSlideNameList.end(),aSlideName);
800 :
801 3 : if (pIter != maSlideNameList.end())
802 : {
803 0 : nStartSlide = pIter - maSlideNameList.begin() + 1;
804 0 : nFlags |= 4;
805 0 : nEndSlide = (sal_uInt16)mnPages;
806 3 : }
807 : }
808 : }
809 :
810 3 : if ( ImplGetPropertyValue( OUString("IsAutomatic" ) ) )
811 : {
812 3 : bool bBool = false;
813 3 : mAny >>= bBool;
814 3 : if ( !bBool )
815 3 : nFlags |= 1;
816 : }
817 :
818 3 : if ( ImplGetPropertyValue( OUString( "IsEndless" ) ) ) // the correct name would be IsNotEndless: WTF?
819 : {
820 3 : bool bBool = false;
821 3 : mAny >>= bBool;
822 3 : if ( bBool )
823 0 : nFlags |= 0x80;
824 : }
825 3 : if ( ImplGetPropertyValue( OUString( "IsFullScreen" ) ) )
826 : {
827 3 : bool bBool = false;
828 3 : mAny >>= bBool;
829 3 : if ( !bBool )
830 0 : nFlags |= 0x11;
831 : }
832 :
833 3 : mpPptEscherEx->AddAtom( 80, EPP_SSDocInfoAtom, 1 );
834 3 : mpStrm->WriteUInt32( nPenColor ).WriteInt32( nRestartTime ).WriteInt16( nStartSlide ).WriteInt16( nEndSlide );
835 :
836 3 : sal_uInt32 nCustomShowNameLen = aCustomShow.getLength();
837 3 : if ( nCustomShowNameLen > 31 )
838 0 : nCustomShowNameLen = 31;
839 3 : if ( nCustomShowNameLen ) // named show identifier
840 : {
841 0 : const sal_Unicode* pCustomShow = aCustomShow.getStr();
842 0 : for ( i = 0; i < nCustomShowNameLen; i++ )
843 : {
844 0 : mpStrm->WriteUInt16( pCustomShow[ i ] );
845 : }
846 : }
847 3 : for ( i = nCustomShowNameLen; i < 32; i++, mpStrm->WriteUInt16( 0 ) ) ;
848 :
849 3 : mpStrm->WriteUInt32( nFlags );
850 : ::com::sun::star::uno::Reference< ::com::sun::star::presentation::XCustomPresentationSupplier >
851 6 : aXCPSup( mXModel, ::com::sun::star::uno::UNO_QUERY );
852 3 : if ( aXCPSup.is() )
853 : {
854 : ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >
855 3 : aXCont( aXCPSup->getCustomPresentations() );
856 3 : if ( aXCont.is() )
857 : {
858 3 : ::com::sun::star::uno::Sequence< OUString> aNameSeq( aXCont->getElementNames() );
859 3 : const OUString* pUString = aNameSeq.getArray();
860 3 : sal_uInt32 nCount = aNameSeq.getLength();
861 3 : if ( nCount )
862 : {
863 0 : mpPptEscherEx->OpenContainer( EPP_NamedShows );
864 0 : sal_uInt32 nCustomShowIndex = 0;
865 0 : for( i = 0; i < nCount; i++ ) // number of custom shows
866 : {
867 0 : if ( !pUString[ i ].isEmpty() )
868 : {
869 0 : mpPptEscherEx->OpenContainer( EPP_NamedShow, nCustomShowIndex++ );
870 :
871 0 : sal_uInt32 nNamedShowLen = pUString[ i ].getLength();
872 0 : if ( nNamedShowLen > 31 )
873 0 : nNamedShowLen = 31;
874 0 : mpPptEscherEx->AddAtom( nNamedShowLen << 1, EPP_CString );
875 0 : const sal_Unicode* pCustomShowName = pUString[ i ].getStr();
876 0 : for ( sal_uInt32 k = 0; k < nNamedShowLen; mpStrm->WriteUInt16( pCustomShowName[ k++ ] ) ) ;
877 0 : mAny = aXCont->getByName( pUString[ i ] );
878 0 : if ( mAny.getValue() )
879 : {
880 :
881 0 : ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer > aXIC;
882 0 : if ( mAny >>= aXIC )
883 : {
884 0 : mpPptEscherEx->BeginAtom();
885 :
886 0 : sal_Int32 nSlideCount = aXIC->getCount();
887 0 : for ( sal_Int32 j = 0; j < nSlideCount; j++ ) // number of slides
888 : {
889 0 : mAny = aXIC->getByIndex( j );
890 0 : if ( mAny.getValue() )
891 : {
892 : ::com::sun::star::uno::Reference<
893 0 : ::com::sun::star::drawing::XDrawPage > aXDrawPage;
894 0 : if ( mAny >>= aXDrawPage )
895 : {
896 : ::com::sun::star::uno::Reference<
897 : ::com::sun::star::container::XNamed >
898 0 : aXName( aXDrawPage, ::com::sun::star::uno::UNO_QUERY );
899 0 : if ( aXName.is() )
900 : {
901 0 : OUString aSlideName( aXName->getName() );
902 : std::vector<OUString>::const_iterator pIter = std::find(
903 0 : maSlideNameList.begin(),maSlideNameList.end(),aSlideName);
904 :
905 0 : if (pIter != maSlideNameList.end())
906 : {
907 0 : sal_uInt32 nPageNumber = pIter - maSlideNameList.begin();
908 0 : mpStrm->WriteUInt32( nPageNumber + 0x100 ); // unique slide id
909 0 : }
910 0 : }
911 0 : }
912 : }
913 : }
914 0 : mpPptEscherEx->EndAtom( EPP_NamedShowSlides );
915 0 : }
916 : }
917 0 : mpPptEscherEx->CloseContainer(); // EPP_NamedShow
918 : }
919 : }
920 0 : mpPptEscherEx->CloseContainer(); // EPP_NamedShows
921 3 : }
922 3 : }
923 3 : }
924 : }
925 3 : }
926 : }
927 3 : mpPptEscherEx->AddAtom( 0, EPP_EndDocument );
928 3 : mpPptEscherEx->CloseContainer(); // EPP_Document
929 3 : return true;
930 : };
931 :
932 3 : bool PPTWriter::ImplCreateHyperBlob( SvMemoryStream& rStrm )
933 : {
934 3 : sal_uInt32 nCurrentOfs, nParaOfs, nParaCount = 0;
935 :
936 3 : nParaOfs = rStrm.Tell();
937 3 : rStrm.WriteUInt32( 0 ); // property size
938 3 : rStrm.WriteUInt32( 0 ); // property count
939 :
940 3 : for ( std::vector<EPPTHyperlink>::const_iterator pIter = maHyperlink.begin(); pIter != maHyperlink.end(); ++pIter )
941 : {
942 0 : nParaCount += 6;
943 0 : rStrm .WriteUInt32( 3 ) // Type VT_I4
944 0 : .WriteUInt32( 7 ) // (VTI4 - Private1)
945 0 : .WriteUInt32( 3 ) // Type VT_I4
946 0 : .WriteUInt32( 6 ) // (VTI4 - Private2)
947 0 : .WriteUInt32( 3 ) // Type VT_I4
948 0 : .WriteUInt32( 0 ); // (VTI4 - Private3)
949 :
950 : // INFO
951 : // HIWORD: = 0 : do not change anything
952 : // = 1 : replace the hyperlink with the target and subaddress in the following two VTLPWSTR
953 : // = 2 : delete the hyperlink
954 : // LOWORD: = 0 : graphic shown as background (link)
955 : // = 1 : graphic shown as shape (link)
956 : // = 2 : graphic is used to fill a shape
957 : // = 3 : graphic used to fill a shape outline (future use)
958 : // = 4 : hyperlink attached to a shape
959 : // = 5 : " " " " (Word) field
960 : // = 6 : " " " " (Excel) range
961 : // = 7 : " " " " (PPT) text range
962 : // = 8 : " " " " (Project) task
963 :
964 0 : sal_Int32 nUrlLen = pIter->aURL.getLength();
965 0 : const OUString& rUrl = pIter->aURL;
966 :
967 0 : sal_uInt32 nInfo = 7;
968 :
969 0 : rStrm .WriteUInt32( 3 ) // Type VT_I4
970 0 : .WriteUInt32( nInfo ); // Info
971 :
972 0 : switch( pIter->nType & 0xff )
973 : {
974 : case 1 : // click action to slidenumber
975 : {
976 0 : rStrm.WriteUInt32( 0x1f ).WriteUInt32( 1 ).WriteUInt32( 0 ); // path
977 0 : rStrm.WriteUInt32( 0x1f ).WriteUInt32( nUrlLen + 1 );
978 0 : for ( sal_Int32 i = 0; i < nUrlLen; i++ )
979 : {
980 0 : rStrm.WriteUInt16( rUrl[ i ] );
981 : }
982 0 : rStrm.WriteUInt16( 0 );
983 : }
984 0 : break;
985 : case 2 :
986 : {
987 : sal_Int32 i;
988 :
989 0 : rStrm .WriteUInt32( 0x1f )
990 0 : .WriteUInt32( nUrlLen + 1 );
991 0 : for ( i = 0; i < nUrlLen; i++ )
992 : {
993 0 : rStrm.WriteUInt16( rUrl[ i ] );
994 : }
995 0 : if ( ! ( i & 1 ) )
996 0 : rStrm.WriteUInt16( 0 );
997 0 : rStrm .WriteUInt16( 0 )
998 0 : .WriteUInt32( 0x1f )
999 0 : .WriteUInt32( 1 )
1000 0 : .WriteUInt32( 0 );
1001 : }
1002 0 : break;
1003 : }
1004 : }
1005 3 : nCurrentOfs = rStrm.Tell();
1006 3 : rStrm.Seek( nParaOfs );
1007 3 : rStrm.WriteUInt32( nCurrentOfs - ( nParaOfs + 4 ) );
1008 3 : rStrm.WriteUInt32( nParaCount );
1009 3 : rStrm.Seek( nCurrentOfs );
1010 3 : return true;
1011 : }
1012 :
1013 3 : bool PPTWriter::ImplCreateMainNotes()
1014 : {
1015 3 : EscherSolverContainer aSolverContainer;
1016 :
1017 3 : mpPptEscherEx->PtReplaceOrInsert( EPP_Persist_MainNotes, mpStrm->Tell() );
1018 3 : mpPptEscherEx->OpenContainer( EPP_Notes );
1019 3 : mpPptEscherEx->AddAtom( 8, EPP_NotesAtom, 1 );
1020 3 : mpStrm->WriteUInt32( 0x80000001 ) // Number that identifies this slide
1021 3 : .WriteUInt32( 0 ); // follow nothing
1022 3 : mpPptEscherEx->OpenContainer( EPP_PPDrawing );
1023 3 : mpPptEscherEx->OpenContainer( ESCHER_DgContainer );
1024 3 : mpPptEscherEx->EnterGroup(0,0);
1025 :
1026 3 : ImplWritePage( GetLayout( 20 ), aSolverContainer, NOTICE, true );
1027 :
1028 3 : mpPptEscherEx->LeaveGroup();
1029 3 : mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
1030 3 : mpPptEscherEx->AddShape( ESCHER_ShpInst_Rectangle, 0xc00 );
1031 6 : EscherPropertyContainer aPropOpt;
1032 3 : aPropOpt.AddOpt( ESCHER_Prop_fillColor, 0xffffff ); // stock valued fill color
1033 3 : aPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0 );
1034 3 : aPropOpt.AddOpt( ESCHER_Prop_fillRectRight, 0x68bdde );
1035 3 : aPropOpt.AddOpt( ESCHER_Prop_fillRectBottom, 0x8b9f8e );
1036 3 : aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x120012 );
1037 3 : aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0 );
1038 3 : aPropOpt.AddOpt( ESCHER_Prop_bWMode, ESCHER_wDontShow );
1039 3 : aPropOpt.AddOpt( ESCHER_Prop_fBackground, 0x10001 ); // if true, this is the background shape
1040 3 : aPropOpt.Commit( *mpStrm );
1041 3 : mpPptEscherEx->CloseContainer(); // ESCHER_SpContainer
1042 :
1043 3 : aSolverContainer.WriteSolver( *mpStrm );
1044 :
1045 3 : mpPptEscherEx->CloseContainer(); // ESCHER_DgContainer
1046 3 : mpPptEscherEx->CloseContainer(); // EPP_Drawing
1047 3 : mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 1 );
1048 3 : mpStrm->WriteUInt32( 0xffffff ).WriteUInt32( 0x000000 ).WriteUInt32( 0x808080 ).WriteUInt32( 0x000000 ).WriteUInt32( 0x99cc00 ).WriteUInt32( 0xcc3333 ).WriteUInt32( 0xffcccc ).WriteUInt32( 0xb2b2b2 );
1049 3 : mpPptEscherEx->CloseContainer(); // EPP_Notes
1050 6 : return true;
1051 : }
1052 :
1053 0 : static OUString getInitials( const OUString& rName )
1054 : {
1055 0 : OUString sInitials;
1056 :
1057 0 : const sal_Unicode * pStr = rName.getStr();
1058 0 : sal_Int32 nLength = rName.getLength();
1059 :
1060 0 : while( nLength )
1061 : {
1062 : // skip whitespace
1063 0 : while( nLength && (*pStr <= ' ') )
1064 : {
1065 0 : nLength--; pStr++;
1066 : }
1067 :
1068 : // take letter
1069 0 : if( nLength )
1070 : {
1071 0 : sInitials += OUString( *pStr );
1072 0 : nLength--; pStr++;
1073 : }
1074 :
1075 : // skip letters until whitespace
1076 0 : while( nLength && (*pStr > ' ') )
1077 : {
1078 0 : nLength--; pStr++;
1079 : }
1080 : }
1081 :
1082 0 : return sInitials;
1083 : }
1084 :
1085 5 : void ImplExportComments( uno::Reference< drawing::XDrawPage > xPage, SvMemoryStream& rBinaryTagData10Atom )
1086 : {
1087 : try
1088 : {
1089 5 : uno::Reference< office::XAnnotationAccess > xAnnotationAccess( xPage, uno::UNO_QUERY_THROW );
1090 10 : uno::Reference< office::XAnnotationEnumeration > xAnnotationEnumeration( xAnnotationAccess->createAnnotationEnumeration() );
1091 :
1092 5 : sal_Int32 nIndex = 1;
1093 :
1094 10 : while( xAnnotationEnumeration->hasMoreElements() )
1095 : {
1096 0 : EscherExContainer aComment10( rBinaryTagData10Atom, EPP_Comment10 );
1097 : {
1098 0 : uno::Reference< office::XAnnotation > xAnnotation( xAnnotationEnumeration->nextElement() );
1099 :
1100 0 : geometry::RealPoint2D aRealPoint2D( xAnnotation->getPosition() );
1101 0 : MapMode aMapDest( MAP_INCH, Point(), Fraction( 1, 576 ), Fraction( 1, 576 ) );
1102 0 : Point aPoint( OutputDevice::LogicToLogic( Point( static_cast< sal_Int32 >( aRealPoint2D.X * 100.0 ),
1103 0 : static_cast< sal_Int32 >( aRealPoint2D.Y * 100.0 ) ), MAP_100TH_MM, aMapDest ) );
1104 :
1105 0 : OUString sAuthor( xAnnotation->getAuthor() );
1106 0 : uno::Reference< text::XText > xText( xAnnotation->getTextRange() );
1107 0 : OUString sText( xText->getString() );
1108 0 : OUString sInitials( getInitials( sAuthor ) );
1109 0 : util::DateTime aDateTime( xAnnotation->getDateTime() );
1110 0 : if ( !sAuthor.isEmpty() )
1111 0 : PPTWriter::WriteCString( rBinaryTagData10Atom, sAuthor, 0 );
1112 0 : if ( !sText.isEmpty() )
1113 0 : PPTWriter::WriteCString( rBinaryTagData10Atom, sText, 1 );
1114 0 : if ( !sInitials.isEmpty() )
1115 0 : PPTWriter::WriteCString( rBinaryTagData10Atom, sInitials, 2 );
1116 :
1117 0 : sal_Int16 nMilliSeconds = static_cast<sal_Int16>(::rtl::math::round(static_cast<double>(aDateTime.NanoSeconds) / 1000000000.0));
1118 0 : EscherExAtom aCommentAtom10( rBinaryTagData10Atom, EPP_CommentAtom10 );
1119 0 : rBinaryTagData10Atom.WriteInt32( nIndex++ )
1120 0 : .WriteInt16( aDateTime.Year )
1121 0 : .WriteUInt16( aDateTime.Month )
1122 0 : .WriteUInt16( aDateTime.Day ) // todo: day of week
1123 0 : .WriteUInt16( aDateTime.Day )
1124 0 : .WriteUInt16( aDateTime.Hours )
1125 0 : .WriteUInt16( aDateTime.Minutes )
1126 0 : .WriteUInt16( aDateTime.Seconds )
1127 0 : .WriteInt16( nMilliSeconds )
1128 0 : .WriteInt32( aPoint.X() )
1129 0 : .WriteInt32( aPoint.Y() );
1130 : }
1131 5 : }
1132 : }
1133 0 : catch ( uno::Exception& )
1134 : {
1135 : }
1136 5 : }
1137 :
1138 5 : void PPTWriter::ImplWriteNotes( sal_uInt32 nPageNum )
1139 : {
1140 5 : mpPptEscherEx->PtReplaceOrInsert( EPP_Persist_Notes | nPageNum, mpStrm->Tell() );
1141 5 : mpPptEscherEx->OpenContainer( EPP_Notes );
1142 5 : mpPptEscherEx->AddAtom( 8, EPP_NotesAtom, 1 );
1143 5 : mpStrm->WriteUInt32( nPageNum + 0x100 )
1144 5 : .WriteUInt16( 3 ) // follow master ....
1145 5 : .WriteUInt16( 0 );
1146 :
1147 5 : ImplCreateHeaderFooters( mXPagePropSet );
1148 :
1149 5 : EscherSolverContainer aSolverContainer;
1150 :
1151 5 : mpPptEscherEx->OpenContainer( EPP_PPDrawing );
1152 5 : mpPptEscherEx->OpenContainer( ESCHER_DgContainer );
1153 5 : mpPptEscherEx->EnterGroup(0,0);
1154 :
1155 5 : ImplWritePage( GetLayout( 20 ), aSolverContainer, NOTICE, false ); // the shapes of the pages are created in the PPT document
1156 :
1157 5 : mpPptEscherEx->LeaveGroup();
1158 5 : mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
1159 5 : mpPptEscherEx->AddShape( ESCHER_ShpInst_Rectangle, 0xc00 ); // Flags: Connector | Background | HasSpt
1160 10 : EscherPropertyContainer aPropOpt;
1161 5 : aPropOpt.AddOpt( ESCHER_Prop_fillColor, 0xffffff ); // stock valued fill color
1162 5 : aPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0 );
1163 5 : aPropOpt.AddOpt( ESCHER_Prop_fillRectRight, 0x8b9f8e );
1164 5 : aPropOpt.AddOpt( ESCHER_Prop_fillRectBottom, 0x68bdde );
1165 5 : aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x120012 );
1166 5 : aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x80000 );
1167 5 : aPropOpt.AddOpt( ESCHER_Prop_bWMode, ESCHER_wDontShow );
1168 5 : aPropOpt.AddOpt( ESCHER_Prop_fBackground, 0x10001 );
1169 5 : aPropOpt.Commit( *mpStrm );
1170 5 : mpPptEscherEx->CloseContainer(); // ESCHER_SpContainer
1171 :
1172 5 : aSolverContainer.WriteSolver( *mpStrm );
1173 :
1174 5 : mpPptEscherEx->CloseContainer(); // ESCHER_DgContainer
1175 5 : mpPptEscherEx->CloseContainer(); // EPP_Drawing
1176 5 : mpPptEscherEx->AddAtom( 32, EPP_ColorSchemeAtom, 0, 1 );
1177 5 : mpStrm->WriteUInt32( 0xffffff ).WriteUInt32( 0x000000 ).WriteUInt32( 0x808080 ).WriteUInt32( 0x000000 ).WriteUInt32( 0x99cc00 ).WriteUInt32( 0xcc3333 ).WriteUInt32( 0xffcccc ).WriteUInt32( 0xb2b2b2 );
1178 10 : mpPptEscherEx->CloseContainer(); // EPP_Notes
1179 5 : };
1180 :
1181 3 : void PPTWriter::ImplWriteBackground( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet )
1182 : {
1183 : //************************ ******
1184 : //** DEFAULT BACKGROUND SHAPE **
1185 :
1186 3 : sal_uInt32 nFillColor = 0xffffff;
1187 3 : sal_uInt32 nFillBackColor = 0;
1188 :
1189 3 : mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
1190 3 : mpPptEscherEx->AddShape( ESCHER_ShpInst_Rectangle, 0xc00 ); // Flags: Connector | Background | HasSpt
1191 :
1192 : // #i121183# Use real PageSize in 100th mm
1193 3 : Rectangle aRect(Point(0, 0), Size(maPageSize.Width, maPageSize.Height));
1194 :
1195 3 : EscherPropertyContainer aPropOpt( mpPptEscherEx->GetGraphicProvider(), mpPicStrm, aRect );
1196 3 : aPropOpt.AddOpt( ESCHER_Prop_fillType, ESCHER_FillSolid );
1197 3 : ::com::sun::star::drawing::FillStyle aFS( ::com::sun::star::drawing::FillStyle_NONE );
1198 3 : if ( ImplGetPropertyValue( rXPropSet, OUString( "FillStyle" ) ) )
1199 3 : mAny >>= aFS;
1200 :
1201 3 : switch( aFS )
1202 : {
1203 : case ::com::sun::star::drawing::FillStyle_GRADIENT :
1204 : {
1205 0 : aPropOpt.CreateGradientProperties( rXPropSet );
1206 0 : aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x1f001e );
1207 0 : aPropOpt.GetOpt( ESCHER_Prop_fillColor, nFillColor );
1208 0 : aPropOpt.GetOpt( ESCHER_Prop_fillBackColor, nFillBackColor );
1209 : }
1210 0 : break;
1211 :
1212 : case ::com::sun::star::drawing::FillStyle_BITMAP :
1213 0 : aPropOpt.CreateGraphicProperties( rXPropSet, OUString( "FillBitmapURL" ), true );
1214 0 : break;
1215 :
1216 : case ::com::sun::star::drawing::FillStyle_HATCH :
1217 0 : aPropOpt.CreateGraphicProperties( rXPropSet, OUString( "FillHatch" ), true );
1218 0 : break;
1219 :
1220 : case ::com::sun::star::drawing::FillStyle_SOLID :
1221 : {
1222 0 : if ( ImplGetPropertyValue( rXPropSet, OUString( "FillColor" ) ) )
1223 : {
1224 0 : nFillColor = EscherEx::GetColor( *static_cast<sal_uInt32 const *>(mAny.getValue()) );
1225 0 : nFillBackColor = nFillColor ^ 0xffffff;
1226 : }
1227 : } // PASSTHROUGH INTENDED
1228 : case ::com::sun::star::drawing::FillStyle_NONE :
1229 : default:
1230 3 : aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x120012 );
1231 3 : break;
1232 : }
1233 3 : aPropOpt.AddOpt( ESCHER_Prop_fillColor, nFillColor );
1234 3 : aPropOpt.AddOpt( ESCHER_Prop_fillBackColor, nFillBackColor );
1235 3 : aPropOpt.AddOpt( ESCHER_Prop_fillRectRight, PPTtoEMU( maDestPageSize.Width ) );
1236 3 : aPropOpt.AddOpt( ESCHER_Prop_fillRectBottom, PPTtoEMU( maDestPageSize.Height ) );
1237 3 : aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x80000 );
1238 3 : aPropOpt.AddOpt( ESCHER_Prop_bWMode, ESCHER_bwWhite );
1239 3 : aPropOpt.AddOpt( ESCHER_Prop_fBackground, 0x10001 );
1240 3 : aPropOpt.Commit( *mpStrm );
1241 3 : mpPptEscherEx->CloseContainer(); // ESCHER_SpContainer
1242 3 : }
1243 :
1244 3 : void PPTWriter::ImplWriteVBA()
1245 : {
1246 3 : if ( mpVBA )
1247 : {
1248 0 : mpVBA->Seek( STREAM_SEEK_TO_END );
1249 0 : sal_uInt32 nLen = mpVBA->Tell();
1250 0 : if ( nLen > 8 )
1251 : {
1252 0 : nLen -= 8;
1253 0 : mnVBAOleOfs = mpStrm->Tell();
1254 0 : mpPptEscherEx->BeginAtom();
1255 0 : mpStrm->Write( static_cast<sal_Int8 const *>(mpVBA->GetData()) + 8, nLen );
1256 0 : mpPptEscherEx->EndAtom( EPP_ExOleObjStg, 0, 1 );
1257 : }
1258 : }
1259 3 : }
1260 :
1261 3 : void PPTWriter::ImplWriteOLE( )
1262 : {
1263 :
1264 3 : SvxMSExportOLEObjects aOleExport( mnCnvrtFlags );
1265 :
1266 3 : for ( std::vector<PPTExOleObjEntry*>::const_iterator it = maExOleObj.begin(); it != maExOleObj.end(); ++it )
1267 : {
1268 0 : PPTExOleObjEntry* pPtr = *it;
1269 0 : SvMemoryStream* pStrm = NULL;
1270 0 : pPtr->nOfsB = mpStrm->Tell();
1271 0 : switch ( pPtr->eType )
1272 : {
1273 : case NORMAL_OLE_OBJECT :
1274 : {
1275 0 : SdrObject* pSdrObj = GetSdrObjectFromXShape( pPtr->xShape );
1276 0 : if ( pSdrObj && pSdrObj->ISA( SdrOle2Obj ) )
1277 : {
1278 0 : ::uno::Reference < embed::XEmbeddedObject > xObj( static_cast<SdrOle2Obj*>(pSdrObj)->GetObjRef() );
1279 0 : if( xObj.is() )
1280 : {
1281 0 : tools::SvRef<SotStorage> xTempStorage( new SotStorage( new SvMemoryStream(), true ) );
1282 0 : aOleExport.ExportOLEObject( xObj, *xTempStorage );
1283 :
1284 : //TODO/MBA: testing
1285 0 : OUString aPersistStream( SVEXT_PERSIST_STREAM );
1286 0 : SvMemoryStream aStream;
1287 0 : tools::SvRef<SotStorage> xCleanStorage( new SotStorage( false, aStream ) );
1288 0 : xTempStorage->CopyTo( xCleanStorage );
1289 : // create a dummy content stream, the dummy content is necessary for ppt, but not for
1290 : // doc files, so we can't share code.
1291 0 : tools::SvRef<SotStorageStream> xStm = xCleanStorage->OpenSotStream( aPersistStream, STREAM_STD_READWRITE );
1292 0 : xStm->WriteUInt32( 0 ) // no ClipboardId
1293 0 : .WriteUInt32( 4 ) // no target device
1294 0 : .WriteUInt32( 1 ) // aspect ratio
1295 0 : .WriteInt32( -1 ) // L-Index
1296 0 : .WriteUInt32( 0 ) // Advanced Flags
1297 0 : .WriteUInt32( 0 ) // compression
1298 0 : .WriteUInt32( 0 ) // Size
1299 0 : .WriteUInt32( 0 ) // "
1300 0 : .WriteUInt32( 0 );
1301 0 : pStrm = xCleanStorage->CreateMemoryStream();
1302 0 : }
1303 : }
1304 : }
1305 0 : break;
1306 :
1307 : case OCX_CONTROL :
1308 : {
1309 0 : if ( pPtr->xControlModel.is() )
1310 : {
1311 0 : OUString aName;
1312 : //Initialize the graphic size which will be used on export
1313 0 : ::com::sun::star::awt::Size aSize( pPtr->xShape->getSize() );
1314 0 : tools::SvRef<SotStorage> xDest( new SotStorage( new SvMemoryStream(), true ) );
1315 0 : bool bOk = oox::ole::MSConvertOCXControls::WriteOCXStream( mXModel, xDest, pPtr->xControlModel, aSize, aName );
1316 0 : if ( bOk )
1317 0 : pStrm = xDest->CreateMemoryStream();
1318 : }
1319 : }
1320 : }
1321 0 : if ( pStrm )
1322 : {
1323 0 : mpPptEscherEx->BeginAtom();
1324 0 : pStrm->Seek( STREAM_SEEK_TO_END );
1325 0 : sal_uInt32 npStrmSize = pStrm->Tell();
1326 0 : mpStrm->WriteUInt32( npStrmSize ); // uncompressed size
1327 :
1328 0 : pStrm->Seek( 0 );
1329 0 : ZCodec aZCodec( 0x8000, 0x8000 );
1330 0 : aZCodec.BeginCompression();
1331 0 : aZCodec.Compress( *pStrm, *mpStrm );
1332 0 : aZCodec.EndCompression();
1333 0 : delete pStrm;
1334 0 : mpPptEscherEx->EndAtom( EPP_ExOleObjStg, 0, 1 );
1335 : }
1336 : }
1337 3 : }
1338 :
1339 : // write PersistantTable and UserEditAtom
1340 :
1341 3 : bool PPTWriter::ImplWriteAtomEnding()
1342 : {
1343 :
1344 : #define EPP_LastViewTypeSlideView 1
1345 :
1346 3 : sal_uInt32 i, nPos, nOfs, nPersistOfs = mpStrm->Tell();
1347 3 : sal_uInt32 nPersistEntrys = 0;
1348 3 : mpStrm->WriteUInt32( 0 ).WriteUInt32( 0 ).WriteUInt32( 0 ); // skip record header and first entry
1349 :
1350 : // write document persist
1351 3 : nPersistEntrys++;
1352 3 : mpStrm->WriteUInt32( 0 );
1353 : // write MasterPages persists
1354 6 : for ( i = 0; i < mnMasterPages; i++ )
1355 : {
1356 3 : nOfs = mpPptEscherEx->PtGetOffsetByID( EPP_Persist_MainMaster | i );
1357 3 : if ( nOfs )
1358 : {
1359 3 : mpStrm->WriteUInt32( nOfs );
1360 3 : mpPptEscherEx->InsertAtPersistOffset( EPP_MAINMASTER_PERSIST_KEY | i, ++nPersistEntrys );
1361 : }
1362 : }
1363 : // write MainNotesMaster persist
1364 3 : nOfs = mpPptEscherEx->PtGetOffsetByID( EPP_Persist_MainNotes );
1365 3 : if ( nOfs )
1366 : {
1367 3 : mpStrm->WriteUInt32( nOfs );
1368 3 : mpPptEscherEx->InsertAtPersistOffset( EPP_MAINNOTESMASTER_PERSIST_KEY, ++nPersistEntrys );
1369 : }
1370 : // write slide persists -> we have to write a valid value into EPP_SlidePersistAtome too
1371 8 : for ( i = 0; i < mnPages; i++ )
1372 : {
1373 5 : nOfs = mpPptEscherEx->PtGetOffsetByID( EPP_Persist_Slide | i );
1374 5 : if ( nOfs )
1375 : {
1376 5 : mpStrm->WriteUInt32( nOfs );
1377 5 : mpPptEscherEx->InsertAtPersistOffset( EPP_MAINSLIDE_PERSIST_KEY | i, ++nPersistEntrys );
1378 : }
1379 : }
1380 : // write Notes persists
1381 8 : for ( i = 0; i < mnPages; i++ )
1382 : {
1383 5 : nOfs = mpPptEscherEx->PtGetOffsetByID( EPP_Persist_Notes | i );
1384 5 : if ( nOfs )
1385 : {
1386 5 : mpStrm->WriteUInt32( nOfs );
1387 5 : mpPptEscherEx->InsertAtPersistOffset( EPP_MAINNOTES_PERSIST_KEY | i, ++nPersistEntrys );
1388 : }
1389 : }
1390 : // Ole persists
1391 3 : for ( std::vector<PPTExOleObjEntry*>::const_iterator it = maExOleObj.begin(); it != maExOleObj.end(); ++it )
1392 : {
1393 0 : PPTExOleObjEntry* pPtr = *it;
1394 0 : nOfs = mpPptEscherEx->PtGetOffsetByID( EPP_Persist_ExObj );
1395 0 : if ( nOfs )
1396 : {
1397 0 : nPersistEntrys++;
1398 0 : mpStrm->WriteUInt32( pPtr->nOfsB );
1399 0 : sal_uInt32 nOldPos, nPersOfs = nOfs + pPtr->nOfsA + 16 + 8; // 8 bytes atom header, +16 to the persist entry
1400 0 : nOldPos = mpStrm->Tell();
1401 0 : mpStrm->Seek( nPersOfs );
1402 0 : mpStrm->WriteUInt32( nPersistEntrys );
1403 0 : mpStrm->Seek( nOldPos );
1404 : }
1405 : }
1406 : // VB persist
1407 3 : if ( mnVBAOleOfs && mpVBA )
1408 : {
1409 0 : nOfs = mpPptEscherEx->PtGetOffsetByID( EPP_Persist_VBAInfoAtom );
1410 0 : if ( nOfs )
1411 : {
1412 0 : nPersistEntrys++;
1413 : sal_uInt32 n1, n2;
1414 :
1415 0 : mpVBA->Seek( 0 );
1416 0 : mpVBA->ReadUInt32( n1 )
1417 0 : .ReadUInt32( n2 );
1418 :
1419 0 : mpStrm->WriteUInt32( mnVBAOleOfs );
1420 0 : sal_uInt32 nOldPos = mpStrm->Tell();
1421 0 : mpStrm->Seek( nOfs ); // Fill the VBAInfoAtom with the correct index to the persisttable
1422 0 : mpStrm->WriteUInt32( nPersistEntrys )
1423 0 : .WriteUInt32( n1 )
1424 0 : .WriteInt32( 2 );
1425 0 : mpStrm->Seek( nOldPos );
1426 :
1427 : }
1428 : }
1429 3 : nPos = mpStrm->Tell();
1430 3 : mpStrm->Seek( nPersistOfs );
1431 3 : mpPptEscherEx->AddAtom( ( nPersistEntrys + 1 ) << 2, EPP_PersistPtrIncrementalBlock ); // insert Record Header
1432 3 : mpStrm->WriteUInt32( ( nPersistEntrys << 20 ) | 1 );
1433 3 : mpStrm->Seek( nPos );
1434 :
1435 3 : mpCurUserStrm->WriteUInt32( nPos ); // set offset to current edit
1436 3 : mpPptEscherEx->AddAtom( 28, EPP_UserEditAtom );
1437 3 : mpStrm->WriteInt32( 0x100 ) // last slide ID
1438 3 : .WriteUInt32( 0x03000dbc ) // minor and major app version that did the save
1439 3 : .WriteUInt32( 0 ) // offset last save, 0 after a full save
1440 3 : .WriteUInt32( nPersistOfs ) // File offset to persist pointers for this save operation
1441 3 : .WriteUInt32( 1 ) // Persist reference to the document persist object
1442 3 : .WriteUInt32( nPersistEntrys ) // max persists written, Seed value for persist object id management
1443 3 : .WriteInt16( EPP_LastViewTypeSlideView ) // last view type
1444 3 : .WriteInt16( 0x12 ); // padword
1445 :
1446 3 : return true;
1447 : }
1448 :
1449 : // - exported function -
1450 :
1451 3 : extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL ExportPPT( const std::vector< com::sun::star::beans::PropertyValue >& rMediaData, tools::SvRef<SotStorage>& rSvStorage,
1452 : ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > & rXModel,
1453 : ::com::sun::star::uno::Reference< ::com::sun::star::task::XStatusIndicator > & rXStatInd,
1454 : SvMemoryStream* pVBA, sal_uInt32 nCnvrtFlags )
1455 : {
1456 3 : PPTWriter* pPPTWriter = new PPTWriter( rSvStorage, rXModel, rXStatInd, pVBA, nCnvrtFlags );
1457 3 : pPPTWriter->exportPPT(rMediaData);
1458 3 : bool bStatus = pPPTWriter->IsValid();
1459 3 : delete pPPTWriter;
1460 3 : return bStatus;
1461 : }
1462 :
1463 3 : extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL SaveVBA( SfxObjectShell& rDocShell, SvMemoryStream*& pBas )
1464 : {
1465 3 : tools::SvRef<SotStorage> xDest( new SotStorage( new SvMemoryStream(), true ) );
1466 6 : SvxImportMSVBasic aMSVBas( rDocShell, *xDest );
1467 3 : aMSVBas.SaveOrDelMSVBAStorage( true, OUString( "_MS_VBA_Overhead" ) );
1468 :
1469 6 : tools::SvRef<SotStorage> xOverhead = xDest->OpenSotStorage( OUString( "_MS_VBA_Overhead") );
1470 3 : if ( xOverhead.Is() && ( xOverhead->GetError() == SVSTREAM_OK ) )
1471 : {
1472 3 : tools::SvRef<SotStorage> xOverhead2 = xOverhead->OpenSotStorage( OUString( "_MS_VBA_Overhead") );
1473 3 : if ( xOverhead2.Is() && ( xOverhead2->GetError() == SVSTREAM_OK ) )
1474 : {
1475 3 : tools::SvRef<SotStorageStream> xTemp = xOverhead2->OpenSotStream( OUString( "_MS_VBA_Overhead2") );
1476 3 : if ( xTemp.Is() && ( xTemp->GetError() == SVSTREAM_OK ) )
1477 : {
1478 3 : sal_uInt32 nLen = xTemp->GetSize();
1479 3 : if ( nLen )
1480 : {
1481 0 : char* pTemp = new char[ nLen ];
1482 0 : xTemp->Seek( STREAM_SEEK_TO_BEGIN );
1483 0 : xTemp->Read( pTemp, nLen );
1484 0 : pBas = new SvMemoryStream( pTemp, nLen, StreamMode::READ );
1485 0 : pBas->ObjectOwnsMemory( true );
1486 0 : return true;
1487 : }
1488 3 : }
1489 3 : }
1490 : }
1491 :
1492 6 : return false;
1493 12 : }
1494 :
1495 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|