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