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