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 <osl/file.hxx>
21 #include <sal/log.hxx>
22 #include <unotools/configmgr.hxx>
23 #include <unotools/ucbstreamhelper.hxx>
24 #include <svl/urihelper.hxx>
25 #include <svx/svxids.hrc>
26 #include <filter/msfilter/svdfppt.hxx>
27 #include <svx/svditer.hxx>
28 #include <sfx2/docfile.hxx>
29 #include <svx/svdograf.hxx>
30 #include <svx/svdlayer.hxx>
31 #include <svx/sdmetitm.hxx>
32 #include <svx/sdtmfitm.hxx>
33 #include <svx/sdtagitm.hxx>
34 #include <svl/style.hxx>
35 #include <svl/intitem.hxx>
36 #include <editeng/eeitem.hxx>
37 #include <editeng/editeng.hxx>
38 #include <svx/svdoutl.hxx>
39 #include <svx/xfillit0.hxx>
40 #include <svx/xlineit0.hxx>
41
42 #include <sfx2/docinf.hxx>
43
44 #include <strings.hrc>
45 #include <strings.hxx>
46 #include "pptin.hxx"
47 #include <drawdoc.hxx>
48 #include <sdpage.hxx>
49 #include <sdresid.hxx>
50 #include <pres.hxx>
51 #include <stlpool.hxx>
52 #include <anminfo.hxx>
53 #include <svx/gallery.hxx>
54 #include <tools/debug.hxx>
55 #include <tools/urlobj.hxx>
56 #include <svx/svdopage.hxx>
57 #include <svx/svdomedia.hxx>
58 #include <svx/svdogrp.hxx>
59 #include "propread.hxx"
60 #include <cusshow.hxx>
61 #include <xmloff/autolayout.hxx>
62
63 #include <customshowlist.hxx>
64 #include <sddll.hxx>
65
66 #include <DrawDocShell.hxx>
67 #include <FrameView.hxx>
68 #include <unokywds.hxx>
69
70 #include <unotools/fltrcfg.hxx>
71 #include <sfx2/progress.hxx>
72 #include <editeng/editstat.hxx>
73 #include <unotools/pathoptions.hxx>
74
75 #define MAX_USER_MOVE 2
76
77 #include "pptanimations.hxx"
78 #include "pptinanimations.hxx"
79 #include "ppt97animations.hxx"
80
81 #include <com/sun/star/animations/TransitionSubType.hpp>
82 #include <com/sun/star/animations/TransitionType.hpp>
83 #include <com/sun/star/document/XDocumentProperties.hpp>
84 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
85 #include <com/sun/star/drawing/LineStyle.hpp>
86
87 #include <comphelper/string.hxx>
88 #include <oox/ole/olehelper.hxx>
89
90 #include <boost/optional.hpp>
91
92 #include <cassert>
93 #include <memory>
94
95 using namespace ::com::sun::star;
96
SdPPTImport(SdDrawDocument * pDocument,SvStream & rDocStream,SotStorage & rStorage,SfxMedium & rMedium)97 SdPPTImport::SdPPTImport( SdDrawDocument* pDocument, SvStream& rDocStream, SotStorage& rStorage, SfxMedium& rMedium )
98 : maParam(rDocStream)
99 {
100 #ifdef DBG_UTIL
101 std::unique_ptr<PropRead> pSummaryInformation(new PropRead( rStorage, "\005SummaryInformation" ));
102 if ( pSummaryInformation->IsValid() )
103 {
104 pSummaryInformation->Read();
105 sal_uInt8 const aPropSetGUID[ 16 ]
106 {
107 0xe0, 0x85, 0x9f, 0xf2, 0xf9, 0x4f, 0x68, 0x10, 0xab, 0x91, 0x08, 0x00, 0x2b, 0x27, 0xb3, 0xd9
108 };
109 Section* pSection = const_cast<Section*>(pSummaryInformation->GetSection( aPropSetGUID ));
110 if ( pSection )
111 {
112 PropItem aPropItem;
113 if ( pSection->GetProperty( PID_COMMENTS, aPropItem ) )
114 {
115 OUString aComment;
116 aPropItem.Read( aComment );
117 if ( aComment.indexOf( "Applixware" ) >= 0 )
118 {
119 maParam.nImportFlags |= PPT_IMPORTFLAGS_NO_TEXT_ASSERT;
120 }
121 }
122 }
123 }
124 pSummaryInformation.reset();
125 #endif
126
127 if (auto pCurrentUserStream
128 = std::unique_ptr<SvStream>(rStorage.OpenSotStream("Current User", StreamMode::STD_READ)))
129 {
130 ReadPptCurrentUserAtom(*pCurrentUserStream, maParam.aCurrentUserAtom);
131 }
132
133 if( pDocument )
134 {
135 // iterate over all styles
136 SdStyleSheetPool* pStyleSheetPool = pDocument->GetSdStyleSheetPool();
137 std::shared_ptr<SfxStyleSheetIterator> aIter =
138 std::make_shared<SfxStyleSheetIterator>(pStyleSheetPool, SfxStyleFamily::All);
139
140 for (SfxStyleSheetBase *pSheet = aIter->First(); pSheet; pSheet = aIter->Next())
141 {
142 SfxItemSet& rSet = pSheet->GetItemSet();
143 // if autokerning is set in style, override it, ppt has no autokerning
144 if( rSet.GetItemState( EE_CHAR_PAIRKERNING, false ) == SfxItemState::SET )
145 rSet.ClearItem( EE_CHAR_PAIRKERNING );
146 }
147 }
148
149 pFilter.reset(new ImplSdPPTImport(pDocument, rStorage, rMedium, maParam));
150 }
151
Import()152 bool SdPPTImport::Import()
153 {
154 return pFilter->Import();
155 }
156
~SdPPTImport()157 SdPPTImport::~SdPPTImport()
158 {
159 }
160
ImplSdPPTImport(SdDrawDocument * pDocument,SotStorage & rStorage_,SfxMedium & rMedium,PowerPointImportParam & rParam)161 ImplSdPPTImport::ImplSdPPTImport( SdDrawDocument* pDocument, SotStorage& rStorage_, SfxMedium& rMedium, PowerPointImportParam& rParam )
162 : SdrPowerPointImport(rParam, rMedium.GetBaseURL())
163 , mrMed(rMedium)
164 , mrStorage(rStorage_)
165 , mbDocumentFound(false)
166 , mnFilterOptions(0)
167 , mpDoc(pDocument)
168 , mePresChange(PRESCHANGE_MANUAL)
169 , mnBackgroundObjectsLayerID(0)
170 {
171 if ( !m_bOk )
172 return;
173
174 mbDocumentFound = SeekToDocument( &maDocHd ); // maDocHd = the latest DocumentHeader
175 while ( SeekToRec( rStCtrl, PPT_PST_Document, nStreamLen, &maDocHd ) )
176 mbDocumentFound = true;
177
178 sal_uInt32 nDggContainerOfs = 0;
179
180 if ( mbDocumentFound )
181 {
182 sal_uLong nOldPos = rStCtrl.Tell();
183
184 pStData = rStorage_.OpenSotStream( "Pictures", StreamMode::STD_READ );
185
186 rStCtrl.Seek( maDocHd.GetRecBegFilePos() + 8 );
187 sal_uLong nDocLen = maDocHd.GetRecEndFilePos();
188 DffRecordHeader aPPDGHd;
189 if ( SeekToRec( rStCtrl, PPT_PST_PPDrawingGroup, nDocLen, &aPPDGHd ) )
190 {
191 sal_uLong nPPDGLen = aPPDGHd.GetRecEndFilePos();
192 if ( SeekToRec( rStCtrl, DFF_msofbtDggContainer, nPPDGLen ) )
193 nDggContainerOfs = rStCtrl.Tell();
194 }
195 rStCtrl.Seek( nOldPos );
196 }
197 sal_uInt32 nSvxMSDffOLEConvFlags2 = 0;
198
199 const SvtFilterOptions& rBasOpt = SvtFilterOptions::Get();
200 if ( rBasOpt.IsLoadPPointBasicCode() )
201 mnFilterOptions |= 1;
202 if ( rBasOpt.IsMathType2Math() )
203 nSvxMSDffOLEConvFlags2 |= OLE_MATHTYPE_2_STARMATH;
204 if ( rBasOpt.IsWinWord2Writer() )
205 nSvxMSDffOLEConvFlags2 |= OLE_WINWORD_2_STARWRITER;
206 if ( rBasOpt.IsExcel2Calc() )
207 nSvxMSDffOLEConvFlags2 |= OLE_EXCEL_2_STARCALC;
208 if ( rBasOpt.IsPowerPoint2Impress() )
209 nSvxMSDffOLEConvFlags2 |= OLE_POWERPOINT_2_STARIMPRESS;
210
211 InitSvxMSDffManager( nDggContainerOfs, pStData, nSvxMSDffOLEConvFlags2 );
212 SetSvxMSDffSettings( SVXMSDFF_SETTINGS_CROP_BITMAPS
213 | SVXMSDFF_SETTINGS_IMPORT_PPT );
214 SetModel( mpDoc, 576 );
215 }
216
217 // Dtor
~ImplSdPPTImport()218 ImplSdPPTImport::~ImplSdPPTImport()
219 {
220 delete pStData;
221 }
222
223 // Import
Import()224 bool ImplSdPPTImport::Import()
225 {
226 if ( !m_bOk )
227 return false;
228
229 bool bWasLocked = pSdrModel->isLocked();
230 pSdrModel->setLock(true);
231 const bool bSavedUndoEnabled = pSdrModel->IsUndoEnabled();
232 pSdrModel->EnableUndo(false);
233
234 SdrOutliner& rOutl = mpDoc->GetDrawOutliner();
235 EEControlBits nControlWord = rOutl.GetEditEngine().GetControlWord();
236 nControlWord |= EEControlBits::ULSPACESUMMATION;
237 const_cast<EditEngine&>(rOutl.GetEditEngine()).SetControlWord( nControlWord );
238
239 SdrLayerAdmin& rAdmin = mpDoc->GetLayerAdmin();
240 mnBackgroundObjectsLayerID = rAdmin.GetLayerID( sUNO_LayerName_background_objects );
241
242 ::sd::DrawDocShell* pDocShell = mpDoc->GetDocSh();
243 if ( pDocShell )
244 SeekOle( pDocShell, mnFilterOptions );
245
246 // hyperlinks
247 std::unique_ptr<PropRead> pDInfoSec2(new PropRead( mrStorage, "\005DocumentSummaryInformation" ));
248 if ( pDInfoSec2->IsValid() )
249 {
250 PropItem aPropItem;
251
252 sal_uInt32 nType, nPropSize, nPropCount;
253
254 pDInfoSec2->Read();
255
256 sal_uInt8 const aPropSetGUID[ 16 ]
257 {
258 0x02, 0xd5, 0xcd, 0xd5, 0x9c, 0x2e, 0x1b, 0x10, 0x93, 0x97, 0x08, 0x00, 0x2b, 0x2c, 0xf9, 0xae
259 };
260 Section* pSection = const_cast<Section*>(pDInfoSec2->GetSection( aPropSetGUID ));
261 if ( pSection )
262 {
263 if ( pSection->GetProperty( PID_SLIDECOUNT, aPropItem ) )
264 {
265 aPropItem.ReadUInt32( nType );
266 if ( ( nType == VT_I4 ) || ( nType == VT_UI4 ) )
267 {
268 // examine PID_HEADINGPAIR to get the correct entry for PID_DOCPARTS
269 sal_uInt32 nSlideCount, nVecCount;
270 aPropItem.ReadUInt32( nSlideCount );
271 if ( nSlideCount && pSection->GetProperty( PID_HEADINGPAIR, aPropItem ) )
272 {
273 sal_uInt32 nSlideTitleIndex = 0, nSlideTitleCount = 0;
274
275 OUString aUString;
276
277 aPropItem.ReadUInt32( nType )
278 .ReadUInt32( nVecCount );
279
280 if ( ( nType == ( VT_VARIANT | VT_VECTOR ) ) && ( nVecCount ^ 1 ) )
281 {
282 nVecCount >>= 1;
283 sal_uInt32 nEntryCount = 0;
284 for (sal_uInt32 i = 0; i < nVecCount; ++i)
285 {
286 if ( !aPropItem.Read( aUString, VT_EMPTY, false ) )
287 break;
288 aPropItem.ReadUInt32( nType );
289 if ( ( nType != VT_I4 ) && ( nType != VT_UI4 ) )
290 break;
291 sal_uInt32 nTemp(0);
292 aPropItem.ReadUInt32( nTemp );
293 if ( aUString == "Slide Titles" || aUString == "Folientitel" )
294 {
295 nSlideTitleCount = nTemp;
296 nSlideTitleIndex = nEntryCount;
297 }
298 nEntryCount += nTemp;
299 }
300 }
301 if ( ( nSlideCount == nSlideTitleCount ) && pSection->GetProperty( PID_DOCPARTS, aPropItem ) )
302 {
303 aPropItem.ReadUInt32( nType )
304 .ReadUInt32( nVecCount );
305
306 bool bVecOk = ( ( nVecCount >= (nSlideTitleIndex + nSlideTitleCount) )
307 && ( nType == ( VT_LPSTR | VT_VECTOR ) ) );
308
309 if (bVecOk)
310 {
311 for (sal_uInt32 i = 0; i != nSlideTitleIndex; ++i)
312 {
313 sal_uInt32 nTemp(0);
314 aPropItem.ReadUInt32(nTemp);
315 if (!aPropItem.good())
316 {
317 bVecOk = false;
318 break;
319 }
320 auto nPos = aPropItem.Tell() + nTemp;
321 if (!checkSeek(aPropItem, nPos))
322 {
323 bVecOk = false;
324 break;
325 }
326 }
327 }
328 if (bVecOk)
329 {
330 for (sal_uInt32 i = 0; i < nSlideTitleCount; ++i)
331 {
332 if (!aPropItem.Read(aUString, nType, false))
333 break;
334
335 OUString aString( aUString );
336 if ( aString == "No Slide Title" )
337 aString.clear();
338 else
339 {
340 std::vector<OUString>::const_iterator pIter =
341 std::find(maSlideNameList.begin(),maSlideNameList.end(),aString);
342
343 if (pIter != maSlideNameList.end())
344 aString.clear();
345 }
346 maSlideNameList.push_back( aString );
347 }
348 }
349 }
350 }
351 }
352 }
353
354 sal_uInt8 const aUserPropSetGUID[ 16 ]
355 {
356 0x05, 0xd5, 0xcd, 0xd5, 0x9c, 0x2e, 0x1b, 0x10, 0x93, 0x97, 0x08, 0x00, 0x2b, 0x2c, 0xf9, 0xae
357 };
358 pSection = const_cast<Section*>(pDInfoSec2->GetSection( aUserPropSetGUID ));
359 if ( pSection )
360 {
361 Dictionary aDict;
362 pSection->GetDictionary(aDict);
363 if (!aDict.empty())
364 {
365 Dictionary::const_iterator iter = aDict.find( OUString("_PID_HLINKS") );
366
367 if ( iter != aDict.end() )
368 {
369 if ( pSection->GetProperty( iter->second, aPropItem ) )
370 {
371 aPropItem.Seek( STREAM_SEEK_TO_BEGIN );
372 aPropItem.ReadUInt32( nType );
373 if ( nType == VT_BLOB )
374 {
375 aPropItem.ReadUInt32( nPropSize )
376 .ReadUInt32( nPropCount );
377
378 if ( ! ( nPropCount % 6 ) )
379 {
380 sal_uInt32 i;
381
382 nPropCount /= 6; // 6 properties per hyperlink
383
384 for ( i = 0; i < nPropCount; i++ )
385 {
386 SdHyperlinkEntry aHyperlink;
387 aHyperlink.nIndex = 0;
388 aPropItem.ReadUInt32( nType );
389 if ( nType != VT_I4 )
390 break;
391 aPropItem.ReadInt32( aHyperlink.nPrivate1 )
392 .ReadUInt32( nType );
393 if ( nType != VT_I4 )
394 break;
395 aPropItem.ReadInt32( aHyperlink.nPrivate2 )
396 .ReadUInt32( nType );
397 if ( nType != VT_I4 )
398 break;
399 aPropItem.ReadInt32( aHyperlink.nPrivate3 )
400 .ReadUInt32( nType );
401 if ( nType != VT_I4 )
402 break;
403 aPropItem.ReadInt32( aHyperlink.nInfo );
404 if ( !aPropItem.Read( aHyperlink.aTarget ) )
405 break;
406
407 // Convert '\\' notation to 'smb://'
408 INetURLObject aUrl( aHyperlink.aTarget, INetProtocol::File );
409 aHyperlink.aTarget = aUrl.GetMainURL( INetURLObject::DecodeMechanism::NONE );
410
411 if ( !aPropItem.Read( aHyperlink.aSubAdress ) )
412 break;
413
414 if ( !aHyperlink.aSubAdress.isEmpty() ) // get the converted subaddress
415 {
416 sal_uInt32 nPageNumber = 0;
417 OUString aString( aHyperlink.aSubAdress );
418 OString aStringAry[ 3 ];
419 size_t nTokenCount = 0;
420 sal_Int32 nPos = 0;
421 do
422 {
423 aStringAry[nTokenCount] =
424 OUStringToOString(aString.getToken( 0, ',', nPos ), RTL_TEXTENCODING_UTF8);
425 }
426 while ( ++nTokenCount < SAL_N_ELEMENTS(aStringAry) && nPos >= 0 );
427
428 bool bDocInternalSubAddress = false;
429
430 // first pass, searching for a SlideId
431 for( size_t nToken = 0; nToken < nTokenCount; ++nToken )
432 {
433 if (comphelper::string::isdigitAsciiString(aStringAry[nToken]))
434 {
435 sal_Int32 nNumber = aStringAry[ nToken ].toInt32();
436 if ( nNumber & ~0xff )
437 {
438 PptSlidePersistList* pPageList = GetPageList( PPT_SLIDEPAGE );
439 if ( pPageList )
440 {
441 sal_uInt16 nPage = pPageList->FindPage( nNumber );
442 if ( nPage != PPTSLIDEPERSIST_ENTRY_NOTFOUND )
443 {
444 nPageNumber = nPage;
445 bDocInternalSubAddress = true;
446 break;
447 }
448 }
449 }
450 }
451 }
452 if ( !bDocInternalSubAddress )
453 { // second pass, searching for a SlideName
454 for ( size_t nToken = 0; nToken < nTokenCount; ++nToken )
455 {
456 OUString aToken(OStringToOUString(aStringAry[nToken], RTL_TEXTENCODING_UTF8));
457 std::vector<OUString>::const_iterator pIter =
458 std::find(maSlideNameList.begin(),maSlideNameList.end(),aToken);
459
460 if (pIter != maSlideNameList.end())
461 {
462 nPageNumber = pIter - maSlideNameList.begin();
463 bDocInternalSubAddress = true;
464 }
465 }
466 }
467 if ( !bDocInternalSubAddress )
468 { // third pass, searching for a slide number
469 for ( size_t nToken = 0; nToken < nTokenCount; ++nToken )
470 {
471 if (comphelper::string::isdigitAsciiString(aStringAry[nToken]))
472 {
473 sal_Int32 nNumber = aStringAry[ nToken ].toInt32();
474 if ( ( nNumber & ~0xff ) == 0 )
475 {
476 nPageNumber = static_cast<sal_uInt32>(nNumber) - 1;
477 bDocInternalSubAddress = true;
478 break;
479 }
480 }
481 }
482 }
483 // if a document internal sub address
484 if ( bDocInternalSubAddress )
485 {
486 if ( nPageNumber < maSlideNameList.size() )
487 aHyperlink.aConvSubString = maSlideNameList[ nPageNumber ];
488 if ( aHyperlink.aConvSubString.isEmpty() )
489 {
490 aHyperlink.aConvSubString = SdResId( STR_PAGE ) + " " + mpDoc->CreatePageNumValue( static_cast<sal_uInt16>(nPageNumber) + 1 );
491 }
492 } else {
493 // if sub address is given but not internal, use it as it is
494 if ( aHyperlink.aConvSubString.isEmpty() )
495 {
496 aHyperlink.aConvSubString = aString;
497 }
498 }
499 }
500 m_aHyperList.push_back( aHyperlink );
501 }
502 }
503 }
504 }
505 }
506 }
507 }
508 }
509 }
510 pDInfoSec2.reset();
511
512 if ( mbDocumentFound )
513 {
514 rStCtrl.Seek( maDocHd.GetRecBegFilePos() + 8 );
515 // read hyperlist / set indices of the entries
516 DffRecordHeader aHyperHd;
517 if ( SeekToRec( rStCtrl, PPT_PST_ExObjList, maDocHd.GetRecEndFilePos(), &aHyperHd ) )
518 {
519 sal_uInt32 nExObjHyperListLen = aHyperHd.GetRecEndFilePos();
520 for (SdHyperlinkEntry & entry : m_aHyperList)
521 {
522 DffRecordHeader aHyperE;
523 if ( !SeekToRec( rStCtrl, PPT_PST_ExHyperlink, nExObjHyperListLen, &aHyperE ) )
524 break;
525 if ( !SeekToRec( rStCtrl, PPT_PST_ExHyperlinkAtom, nExObjHyperListLen ) )
526 break;
527 rStCtrl.SeekRel( 8 );
528 rStCtrl.ReadUInt32( entry.nIndex );
529 if (!aHyperE.SeekToEndOfRecord(rStCtrl))
530 break;
531 }
532 }
533 }
534
535 if (pDocShell)
536 {
537 Size aVisAreaSize;
538 switch ( m_aUserEditAtom.eLastViewType )
539 {
540 case PptViewTypeEnum::Notes:
541 case PptViewTypeEnum::NotesMaster:
542 aVisAreaSize = aDocAtom.GetNotesPageSize();
543 break;
544 default :
545 aVisAreaSize = aDocAtom.GetSlidesPageSize();
546 }
547 Scale( aVisAreaSize );
548 pDocShell->SetVisArea( ::tools::Rectangle( Point(), aVisAreaSize ) );
549 }
550
551 // create master pages:
552
553 std::unique_ptr<SfxProgress> xStbMgr;
554 if (!utl::ConfigManager::IsFuzzing())
555 {
556 xStbMgr.reset(new SfxProgress(pDocShell,
557 SdResId( STR_POWERPOINT_IMPORT),
558 m_pMasterPages->size() +
559 m_pSlidePages->size() + m_pNotePages->size()));
560 }
561
562 sal_uInt32 nImportedPages = 0;
563 {
564 sal_uInt16 nMasterCnt = GetPageCount( PPT_MASTERPAGE );
565
566 for ( sal_uInt16 nMasterNum = 0; nMasterNum < nMasterCnt; nMasterNum++ )
567 {
568 SetPageNum( nMasterNum, PPT_MASTERPAGE );
569 SdPage* pPage = static_cast<SdPage*>(MakeBlancPage( true ));
570 if ( pPage )
571 {
572 bool bNotesMaster = (*GetPageList( m_eCurrentPageKind ) )[ m_nCurrentPageNum ].bNotesMaster;
573 bool bStarDrawFiller = (*GetPageList( m_eCurrentPageKind ) )[ m_nCurrentPageNum ].bStarDrawFiller;
574
575 PageKind ePgKind = bNotesMaster ? PageKind::Notes : PageKind::Standard;
576 bool bHandout = (*GetPageList( m_eCurrentPageKind ) )[ m_nCurrentPageNum ].bHandoutMaster;
577 if ( bHandout )
578 ePgKind = PageKind::Handout;
579
580 pPage->SetPageKind( ePgKind );
581 pSdrModel->InsertMasterPage( static_cast<SdrPage*>(pPage) );
582 if ( bNotesMaster && bStarDrawFiller )
583 pPage->SetAutoLayout( AUTOLAYOUT_NOTES, true );
584 if ( nMasterNum )
585 {
586 boost::optional< sal_Int16 > oStartNumbering;
587 SfxStyleSheet* pSheet;
588 if ( nMasterNum == 1 )
589 {
590 // standardsheet
591 pSheet = static_cast<SfxStyleSheet*>(mpDoc->GetStyleSheetPool()->Find(SdResId(STR_STANDARD_STYLESHEET_NAME), SfxStyleFamily::Para ));
592 if ( pSheet )
593 {
594 SfxItemSet& rItemSet = pSheet->GetItemSet();
595 PPTParagraphObj aParagraph( *m_pPPTStyleSheet, TSS_Type::TextInShape, 0 );
596 PPTPortionObj aPortion( *m_pPPTStyleSheet, TSS_Type::TextInShape, 0 );
597 aParagraph.AppendPortion( aPortion );
598 aParagraph.ApplyTo( rItemSet, oStartNumbering, static_cast<SdrPowerPointImport&>(*this), TSS_Type::Unknown );
599 aPortion.ApplyTo( rItemSet, static_cast<SdrPowerPointImport&>(*this), TSS_Type::Unknown );
600 }
601 }
602
603 // PSEUDO
604 pSheet = static_cast<SfxStyleSheet*>(mpDoc->GetStyleSheetPool()->Find(SdResId(STR_PSEUDOSHEET_BACKGROUNDOBJECTS), SfxStyleFamily::Pseudo ));
605 if ( pSheet )
606 {
607 SfxItemSet& rItemSet = pSheet->GetItemSet();
608 PPTParagraphObj aParagraph( *m_pPPTStyleSheet, TSS_Type::TextInShape, 0 );
609 PPTPortionObj aPortion( *m_pPPTStyleSheet, TSS_Type::TextInShape, 0 );
610 aParagraph.AppendPortion( aPortion );
611 aParagraph.ApplyTo( rItemSet, oStartNumbering, static_cast<SdrPowerPointImport&>(*this), TSS_Type::Unknown );
612 aPortion.ApplyTo( rItemSet, static_cast<SdrPowerPointImport&>(*this), TSS_Type::Unknown );
613 }
614
615 // create layoutstylesheets, set layoutname and stylesheet
616 // (only on standard and not pages)
617
618 OUString aLayoutName( SdResId( STR_LAYOUT_DEFAULT_NAME ) );
619 if ( nMasterNum > 2 )
620 {
621 if ( ePgKind == PageKind::Standard )
622 { // standard page: create new presentation layout
623 aLayoutName = SdResId( STR_LAYOUT_DEFAULT_TITLE_NAME ) +
624 OUString::number( static_cast<sal_Int32>( ( nMasterNum + 1 ) / 2 - 1 ) );
625 static_cast<SdStyleSheetPool*>( mpDoc->GetStyleSheetPool() )->CreateLayoutStyleSheets( aLayoutName );
626 }
627 else // note page: use presentation layout of standard page
628 aLayoutName = static_cast<SdPage*>( mpDoc->GetMasterPage( nMasterNum - 1 ) )->GetName();
629 }
630 pPage->SetName( aLayoutName );
631 aLayoutName += SD_LT_SEPARATOR STR_LAYOUT_OUTLINE;
632 pPage->SetLayoutName( aLayoutName );
633
634 // set stylesheets
635 if ( pPage->GetPageKind() == PageKind::Standard )
636 {
637 TSS_Type nTitleInstance = TSS_Type::PageTitle;
638 TSS_Type nOutlinerInstance = TSS_Type::Body;
639 const PptSlideLayoutAtom* pSlideLayout = GetSlideLayoutAtom();
640 bool bSwapStyleSheet = pSlideLayout->eLayout == PptSlideLayout::TITLEMASTERSLIDE;
641 if ( bSwapStyleSheet )
642 {
643 nTitleInstance = TSS_Type::Title;
644 nOutlinerInstance = TSS_Type::Subtitle;
645 }
646
647 // titlestylesheet
648 pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_TITLE );
649 if ( pSheet )
650 {
651 SfxItemSet& rItemSet = pSheet->GetItemSet();
652 PPTParagraphObj aParagraph( *m_pPPTStyleSheet, nTitleInstance, 0 );
653 PPTPortionObj aPortion( *m_pPPTStyleSheet, nTitleInstance, 0 );
654 aParagraph.AppendPortion( aPortion );
655 aParagraph.ApplyTo( rItemSet, oStartNumbering, static_cast<SdrPowerPointImport&>(*this), TSS_Type::Unknown );
656 aPortion.ApplyTo( rItemSet, static_cast<SdrPowerPointImport&>(*this), TSS_Type::Unknown );
657 }
658
659 // outlinerstylesheet
660 sal_uInt16 nLevel;
661 PPTParagraphObj* pParagraphs[ 9 ];
662
663 for ( nLevel = 0; nLevel < 9; nLevel++ )
664 {
665 OUString aName = pPage->GetLayoutName() +
666 " " + OUString::number( nLevel + 1 );
667 SfxStyleSheet* pOutlineSheet = static_cast<SfxStyleSheet*>( mpDoc->GetStyleSheetPool()->Find( aName, SfxStyleFamily::Page ) );
668 DBG_ASSERT( pOutlineSheet, "Template for outline object not found" );
669 if ( pOutlineSheet )
670 {
671 pParagraphs[ nLevel ] = new PPTParagraphObj( *m_pPPTStyleSheet, nOutlinerInstance, nLevel );
672 SfxItemSet& rItemSet = pOutlineSheet->GetItemSet();
673 PPTPortionObj aPortion( *m_pPPTStyleSheet, nOutlinerInstance, nLevel );
674 pParagraphs[ nLevel ]->AppendPortion( aPortion );
675 pParagraphs[ nLevel ]->ApplyTo( rItemSet, oStartNumbering, static_cast<SdrPowerPointImport&>(*this), TSS_Type::Unknown );
676 aPortion.ApplyTo( rItemSet, static_cast<SdrPowerPointImport&>(*this), TSS_Type::Unknown );
677 }
678 else
679 pParagraphs[ nLevel ] = nullptr;
680 }
681 for ( nLevel = 0; nLevel < 9; delete pParagraphs[ nLevel++ ] ) ;
682
683 // subtitle stylesheet
684 pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_TEXT );
685 if ( pSheet )
686 {
687 SfxItemSet& rItemSet = pSheet->GetItemSet();
688 PPTParagraphObj aParagraph( *m_pPPTStyleSheet, TSS_Type::Subtitle, 0 );
689 PPTPortionObj aPortion( *m_pPPTStyleSheet, TSS_Type::Subtitle, 0 );
690 aParagraph.AppendPortion( aPortion );
691 aParagraph.ApplyTo( rItemSet, oStartNumbering, static_cast<SdrPowerPointImport&>(*this), TSS_Type::Unknown );
692 aPortion.ApplyTo( rItemSet, static_cast<SdrPowerPointImport&>(*this), TSS_Type::Unknown );
693 }
694 }
695 else if ( ePgKind == PageKind::Notes )
696 {
697 pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_NOTES );
698 if ( pSheet )
699 {
700 SfxItemSet& rItemSet = pSheet->GetItemSet();
701 PPTParagraphObj aParagraph( *m_pPPTStyleSheet, TSS_Type::Notes, 0 );
702 PPTPortionObj aPortion( *m_pPPTStyleSheet, TSS_Type::Notes, 0 );
703 aParagraph.AppendPortion( aPortion );
704 aParagraph.ApplyTo( rItemSet, oStartNumbering, static_cast<SdrPowerPointImport&>(*this), TSS_Type::Unknown );
705 aPortion.ApplyTo( rItemSet, static_cast<SdrPowerPointImport&>(*this), TSS_Type::Unknown );
706 }
707 }
708 }
709 }
710 }
711 }
712 for (sal_uInt16 i = 0; i < mpDoc->GetMasterPageCount(); ++i)
713 {
714 SdPage *const pMPage(static_cast<SdPage*>(mpDoc->GetMasterPage(i)));
715 if (pMPage == nullptr)
716 break;
717 SetPageNum( i, PPT_MASTERPAGE );
718
719 // importing master page objects
720 PptSlidePersistList* pList = GetPageList( m_eCurrentPageKind );
721 PptSlidePersistEntry* pPersist = ( pList && ( m_nCurrentPageNum < pList->size() ) )
722 ? &(*pList)[ m_nCurrentPageNum ] : nullptr;
723 if ( pPersist )
724 {
725 if ( pPersist->bStarDrawFiller && pPersist->bNotesMaster && ( m_nCurrentPageNum > 2 ) && ( ( m_nCurrentPageNum & 1 ) == 0 ) )
726 {
727 pSdrModel->DeleteMasterPage( m_nCurrentPageNum );
728 SdrPage* pNotesClone = static_cast<SdPage*>(pSdrModel->GetMasterPage( 2 ))->CloneSdrPage(*pSdrModel);
729 pSdrModel->InsertMasterPage( pNotesClone, m_nCurrentPageNum );
730 if ( pNotesClone )
731 {
732 OUString aLayoutName( static_cast<SdPage*>(pSdrModel->GetMasterPage( m_nCurrentPageNum - 1 ))->GetLayoutName() );
733 static_cast<SdPage*>(pNotesClone)->SetPresentationLayout( aLayoutName, false, false );
734 static_cast<SdPage*>(pNotesClone)->SetLayoutName( aLayoutName );
735 }
736 }
737 else if ( !pPersist->bStarDrawFiller )
738 {
739 PptSlidePersistEntry* pE = pPersist;
740 while( ( pE->aSlideAtom.nFlags & 4 ) && pE->aSlideAtom.nMasterId )
741 {
742 auto nOrigMasterId = pE->aSlideAtom.nMasterId;
743 sal_uInt16 nNextMaster = m_pMasterPages->FindPage(nOrigMasterId);
744 if ( nNextMaster == PPTSLIDEPERSIST_ENTRY_NOTFOUND )
745 break;
746 else
747 pE = &(*pList)[ nNextMaster ];
748 if (pE->aSlideAtom.nMasterId == nOrigMasterId)
749 {
750 SAL_WARN("filter.ms", "loop in atom chain");
751 break;
752 }
753 }
754 SdrObject* pObj = ImportPageBackgroundObject( *pMPage, pE->nBackgroundOffset ); // import background
755 if ( pObj )
756 pMPage->NbcInsertObject( pObj );
757
758 bool bNewAnimationsUsed = false;
759 ProcessData aProcessData( (*pList)[ m_nCurrentPageNum ], SdPageCapsule(pMPage) );
760 sal_uInt32 nOldFPos = rStCtrl.Tell();
761 DffRecordHeader aPageHd;
762 if ( SeekToCurrentPage( &aPageHd ) )
763 {
764 auto nEndRecPos = SanitizeEndPos(rStCtrl, aPageHd.GetRecEndFilePos());
765 while( ( rStCtrl.GetError() == ERRCODE_NONE ) && ( rStCtrl.Tell() < nEndRecPos ) )
766 {
767 DffRecordHeader aHd;
768 ReadDffRecordHeader( rStCtrl, aHd );
769 switch( aHd.nRecType )
770 {
771 case PPT_PST_PPDrawing :
772 {
773 aHd.SeekToBegOfRecord( rStCtrl );
774 DffRecordHeader aPPDrawHd;
775 if ( SeekToRec( rStCtrl, PPT_PST_PPDrawing, aHd.GetRecEndFilePos(), &aPPDrawHd ) )
776 {
777 sal_uInt32 nPPDrawEnd = aPPDrawHd.GetRecEndFilePos();
778 DffRecordHeader aEscherF002Hd;
779 if ( SeekToRec( rStCtrl, DFF_msofbtDgContainer, nPPDrawEnd, &aEscherF002Hd ) )
780 {
781 sal_uInt32 nEscherF002End = aEscherF002Hd.GetRecEndFilePos();
782 DffRecordHeader aEscherObjListHd;
783 if ( SeekToRec( rStCtrl, DFF_msofbtSpgrContainer, nEscherF002End, &aEscherObjListHd ) )
784 {
785 sal_uInt32 nObjCount = 0;
786 auto nListEndRecPos = SanitizeEndPos(rStCtrl, aEscherObjListHd.GetRecEndFilePos());
787 while( ( rStCtrl.GetError() == ERRCODE_NONE ) && ( rStCtrl.Tell() < nListEndRecPos ) )
788 {
789 DffRecordHeader aHd2;
790 ReadDffRecordHeader( rStCtrl, aHd2 );
791 if ( ( aHd2.nRecType == DFF_msofbtSpContainer ) || ( aHd2.nRecType == DFF_msofbtSpgrContainer ) )
792 {
793 if ( nObjCount++ ) // skipping the first object
794 {
795 ::tools::Rectangle aEmpty;
796 if (!aHd2.SeekToBegOfRecord(rStCtrl))
797 break;
798 SdrObject* pImpObj = ImportObj( rStCtrl, aProcessData, aEmpty, aEmpty, /*nCalledByGroup*/0, /*pShapeId*/ nullptr );
799 if ( pImpObj )
800 {
801 pImpObj->SetLayer( mnBackgroundObjectsLayerID );
802 pMPage->NbcInsertObject( pImpObj );
803 }
804 }
805 }
806 if (!aHd2.SeekToEndOfRecord(rStCtrl))
807 break;
808 }
809 }
810 }
811 }
812 }
813 break;
814
815 case PPT_PST_ProgTags :
816 {
817 DffRecordHeader aProgTagHd;
818 if ( SeekToContentOfProgTag( 10, rStCtrl, aPageHd, aProgTagHd ) )
819 {
820 auto nTagEndRecPos = SanitizeEndPos(rStCtrl, aProgTagHd.GetRecEndFilePos());
821 while ( ( rStCtrl.GetError() == ERRCODE_NONE ) && ( rStCtrl.Tell() < nTagEndRecPos ) )
822 {
823 DffRecordHeader aProgTagContentHd;
824 ReadDffRecordHeader( rStCtrl, aProgTagContentHd );
825 switch( aProgTagContentHd.nRecType )
826 {
827 case DFF_msofbtAnimGroup :
828 {
829 css::uno::Reference< css::drawing::XDrawPage > xPage( pMPage->getUnoPage(), css::uno::UNO_QUERY );
830 ppt::AnimationImporter aImporter( this, rStCtrl );
831 bNewAnimationsUsed = aImporter.import( xPage, aProgTagContentHd ) > 0;
832 }
833 break;
834 }
835 if (!aProgTagContentHd.SeekToEndOfRecord(rStCtrl))
836 break;
837 }
838 }
839 }
840 break;
841 }
842 bool bSuccess = aHd.SeekToEndOfRecord(rStCtrl);
843 if (!bSuccess)
844 {
845 SAL_WARN("filter.ms", "Could not seek to end of record");
846 break;
847 }
848 }
849 }
850 rStCtrl.Seek( nOldFPos );
851 ImportPageEffect( pMPage, bNewAnimationsUsed );
852
853 // background object
854 pObj = pMPage->GetObj( 0 );
855 if ( pObj && pObj->GetObjIdentifier() == OBJ_RECT )
856 {
857 if ( pMPage->GetPageKind() == PageKind::Standard )
858 {
859 // transform data from imported background object to new form
860 // and delete the object. It was used as container to transport
861 // the attributes of the MasterPage background fill
862 SfxStyleSheet* pSheet = pMPage->GetStyleSheetForMasterPageBackground();
863
864 if(pSheet)
865 {
866 // if we have a StyleSheet (for Masterpages), set attributes there and use it
867 pSheet->GetItemSet().ClearItem();
868 pSheet->GetItemSet().Put(pObj->GetMergedItemSet());
869 pMPage->getSdrPageProperties().ClearItem();
870 pMPage->getSdrPageProperties().SetStyleSheet(pSheet);
871 }
872 else
873 {
874 // without StyleSheet, set attributes directly. This
875 // should not be done at all and is an error (will be asserted by SdrPage)
876 pMPage->getSdrPageProperties().ClearItem();
877 pMPage->getSdrPageProperties().PutItemSet(pObj->GetMergedItemSet());
878 }
879
880 pMPage->RemoveObject(pObj->GetOrdNum());
881 SdrObject::Free(pObj);
882 }
883 }
884 }
885 }
886 if (xStbMgr)
887 xStbMgr->SetState( nImportedPages++ );
888 }
889
890 // importing slide pages
891 {
892 sal_uInt32 nOldFPos = rStCtrl.Tell();
893 PptPageKind ePageKind = m_eCurrentPageKind;
894 sal_uInt16 nPageNum = m_nCurrentPageNum;
895
896 SdPage* pHandoutPage = static_cast<SdPage*>(MakeBlancPage( false ));
897 pHandoutPage->SetPageKind( PageKind::Handout );
898 pSdrModel->InsertPage( pHandoutPage );
899
900 sal_uInt16 nPageCnt = GetPageCount();
901 if ( nPageCnt )
902 {
903 for ( sal_uInt16 nPage = 0; nPage < nPageCnt; nPage++ )
904 {
905 mePresChange = PRESCHANGE_SEMIAUTO;
906 SetPageNum( nPage );
907 SdPage* pPage = static_cast<SdPage*>(MakeBlancPage( false ));
908 PptSlidePersistEntry* pMasterPersist = nullptr;
909 if ( HasMasterPage( nPage ) ) // try to get the LayoutName from the masterpage
910 {
911 sal_uInt16 nMasterNum = GetMasterPageIndex( m_nCurrentPageNum, m_eCurrentPageKind );
912 pPage->TRG_SetMasterPage(*pSdrModel->GetMasterPage(nMasterNum));
913 PptSlidePersistList* pPageList = GetPageList( PPT_MASTERPAGE );
914 if ( pPageList && nMasterNum < pPageList->size() )
915 pMasterPersist = &(*pPageList)[ nMasterNum ];
916 pPage->SetLayoutName(static_cast<SdPage&>(pPage->TRG_GetMasterPage()).GetLayoutName());
917 }
918 pPage->SetPageKind( PageKind::Standard );
919 pSdrModel->InsertPage( pPage ); // SJ: #i29625# because of form controls, the
920 ImportPage( pPage, pMasterPersist ); // page must be inserted before importing
921 SetHeaderFooterPageSettings( pPage, pMasterPersist );
922 // CWS preseng01: pPage->SetPageKind( PageKind::Standard );
923
924 DffRecordHeader aPageHd;
925 if ( SeekToCurrentPage( &aPageHd ) )
926 {
927 bool bNewAnimationsUsed = false;
928
929 aPageHd.SeekToContent( rStCtrl );
930 auto nEndRecPos = SanitizeEndPos(rStCtrl, aPageHd.GetRecEndFilePos());
931 while ( ( rStCtrl.GetError() == ERRCODE_NONE ) && ( rStCtrl.Tell() < nEndRecPos ) )
932 {
933 DffRecordHeader aHd;
934 ReadDffRecordHeader( rStCtrl, aHd );
935 switch ( aHd.nRecType )
936 {
937 case PPT_PST_ProgTags :
938 {
939 DffRecordHeader aProgTagHd;
940 if ( SeekToContentOfProgTag( 10, rStCtrl, aPageHd, aProgTagHd ) )
941 {
942 auto nHdEndRecPos = SanitizeEndPos(rStCtrl, aProgTagHd.GetRecEndFilePos());
943 while ( ( rStCtrl.GetError() == ERRCODE_NONE ) && ( rStCtrl.Tell() < nHdEndRecPos ) )
944 {
945 DffRecordHeader aProgTagContentHd;
946 ReadDffRecordHeader( rStCtrl, aProgTagContentHd );
947 switch( aProgTagContentHd.nRecType )
948 {
949 case DFF_msofbtAnimGroup :
950 {
951 css::uno::Reference< css::drawing::XDrawPage > xPage( pPage->getUnoPage(), css::uno::UNO_QUERY );
952 ppt::AnimationImporter aImporter( this, rStCtrl );
953 bNewAnimationsUsed = aImporter.import( xPage, aProgTagContentHd ) > 0;
954 }
955 break;
956
957 case PPT_PST_HashCodeAtom : // ???
958 break;
959
960 case PPT_PST_SlideTime10Atom : // ??? don't know, this atom is always 8 bytes big
961 break; // and is appearing in nearly every l10 progtag
962 }
963 if (!aProgTagContentHd.SeekToEndOfRecord(rStCtrl))
964 break;
965 }
966 }
967 }
968 break;
969
970 case PPT_PST_HeadersFooters :
971 case PPT_PST_PPDrawing :
972 default:
973 break;
974 }
975
976 if (!aHd.SeekToEndOfRecord(rStCtrl))
977 break;
978 }
979 ImportPageEffect( pPage, bNewAnimationsUsed );
980 }
981
982 // creating the corresponding note page
983 m_eCurrentPageKind = PPT_NOTEPAGE;
984 SdPage* pNotesPage = static_cast<SdPage*>(MakeBlancPage( false ));
985 sal_uInt16 nNotesMasterNum = GetMasterPageIndex( nPage ) + 1;
986 sal_uInt32 nNotesPageId = GetNotesPageId( nPage );
987 if ( nNotesPageId )
988 {
989 nImportedPages++;
990 sal_uInt16 nNotesPageIndex = m_pNotePages->FindPage( nNotesPageId );
991 if ( nNotesPageIndex == PPTSLIDEPERSIST_ENTRY_NOTFOUND )
992 nNotesPageIndex = 0;
993 SetPageNum( nNotesPageIndex, PPT_NOTEPAGE );
994 PptSlidePersistEntry* pMasterPersist2 = nullptr;
995 if ( HasMasterPage( nNotesPageIndex, PPT_NOTEPAGE ) ) // try to get the LayoutName from the masterpage
996 {
997 pNotesPage->TRG_SetMasterPage(*pSdrModel->GetMasterPage(nNotesMasterNum));
998 PptSlidePersistList* pPageList = GetPageList( PPT_MASTERPAGE );
999 if ( pPageList && nNotesMasterNum < pPageList->size() )
1000 pMasterPersist2 = &(*pPageList)[ nNotesMasterNum ];
1001 pNotesPage->SetLayoutName( static_cast<SdPage&>(pNotesPage->TRG_GetMasterPage()).GetLayoutName() );
1002 }
1003 pNotesPage->SetPageKind( PageKind::Notes );
1004 pNotesPage->TRG_SetMasterPage(*pSdrModel->GetMasterPage(nNotesMasterNum));
1005 pSdrModel->InsertPage( pNotesPage ); // SJ: #i29625# because of form controls, the
1006 ImportPage( pNotesPage, pMasterPersist2 ); // page must be inserted before importing
1007 SetHeaderFooterPageSettings( pNotesPage, pMasterPersist2 );
1008 pNotesPage->SetAutoLayout( AUTOLAYOUT_NOTES );
1009 }
1010 else
1011 {
1012 pNotesPage->SetPageKind( PageKind::Notes );
1013 pNotesPage->TRG_SetMasterPage(*pSdrModel->GetMasterPage(nNotesMasterNum));
1014 pNotesPage->SetAutoLayout( AUTOLAYOUT_NOTES, true );
1015 pSdrModel->InsertPage( pNotesPage );
1016 SdrObject* pPageObj = pNotesPage->GetPresObj( PRESOBJ_PAGE );
1017 if ( pPageObj )
1018 static_cast<SdrPageObj*>(pPageObj)->SetReferencedPage(pSdrModel->GetPage(( nPage << 1 ) + 1));
1019 }
1020
1021 if (xStbMgr)
1022 xStbMgr->SetState( nImportedPages++ );
1023 }
1024 }
1025 else
1026 {
1027 // that can happen by document templates
1028 m_eCurrentPageKind = PPT_SLIDEPAGE;
1029 SdrPage* pPage = MakeBlancPage( false );
1030 pSdrModel->InsertPage( pPage );
1031
1032 // #i37397#, trying to set the title master for the first page
1033 sal_uInt16 nMaster, nMasterCount = pSdrModel->GetMasterPageCount();
1034 SdPage* pFoundMaster = nullptr;
1035 for ( nMaster = 1; nMaster < nMasterCount; nMaster++ )
1036 {
1037 SdPage* pMaster = static_cast<SdPage*>( pSdrModel->GetMasterPage( nMaster ) );
1038 if ( pMaster->GetPageKind() == PageKind::Standard )
1039 {
1040 SetPageNum( nMaster, PPT_MASTERPAGE );
1041 if ( !pFoundMaster )
1042 pFoundMaster = pMaster;
1043 else if ( GetSlideLayoutAtom()->eLayout == PptSlideLayout::TITLEMASTERSLIDE )
1044 pFoundMaster = pMaster;
1045 if ( GetSlideLayoutAtom()->eLayout == PptSlideLayout::TITLEMASTERSLIDE )
1046 break;
1047 }
1048 }
1049 if ( pFoundMaster )
1050 {
1051 static_cast<SdPage*>(pPage)->TRG_SetMasterPage( *pFoundMaster );
1052 static_cast<SdPage*>(pPage)->SetLayoutName( pFoundMaster->GetLayoutName() );
1053 }
1054 static_cast<SdPage*>(pPage)->SetAutoLayout( AUTOLAYOUT_TITLE, true, true );
1055
1056 m_eCurrentPageKind = PPT_NOTEPAGE;
1057 SdrPage* pNPage = MakeBlancPage( false );
1058 pSdrModel->InsertPage( pNPage );
1059 }
1060 SetPageNum( nPageNum, ePageKind );
1061 rStCtrl.Seek( nOldFPos );
1062 }
1063
1064 // create handout and note pages
1065 m_bOk = mpDoc->CreateMissingNotesAndHandoutPages();
1066 if ( m_bOk )
1067 {
1068 for ( sal_uInt16 i = 0; i < mpDoc->GetSdPageCount( PageKind::Standard ); i++ )
1069 {
1070
1071 // set AutoLayout
1072 SetPageNum( i );
1073 SdPage* pPage = mpDoc->GetSdPage( i, PageKind::Standard );
1074 AutoLayout eAutoLayout = AUTOLAYOUT_NONE;
1075 const PptSlideLayoutAtom* pSlideLayout = GetSlideLayoutAtom();
1076 if ( pSlideLayout )
1077 {
1078 switch ( pSlideLayout->eLayout ) // presentation layout for standard pages
1079 {
1080 case PptSlideLayout::TITLEANDBODYSLIDE :
1081 {
1082 eAutoLayout = AUTOLAYOUT_TITLE_CONTENT;
1083 PptPlaceholder nID1 = pSlideLayout->aPlaceholderId[ 1 ];
1084 switch ( nID1 )
1085 {
1086 case PptPlaceholder::BODY :
1087 eAutoLayout = AUTOLAYOUT_TITLE_CONTENT;
1088 break;
1089 case PptPlaceholder::TABLE :
1090 eAutoLayout = AUTOLAYOUT_TAB;
1091 break;
1092 case PptPlaceholder::ORGANISZATIONCHART :
1093 eAutoLayout = AUTOLAYOUT_ORG;
1094 break;
1095 case PptPlaceholder::GRAPH :
1096 eAutoLayout = AUTOLAYOUT_CHART;
1097 break;
1098 case PptPlaceholder::OBJECT :
1099 eAutoLayout = AUTOLAYOUT_OBJ;
1100 break;
1101 case PptPlaceholder::VERTICALTEXTBODY :
1102 eAutoLayout = AUTOLAYOUT_TITLE_VCONTENT;
1103 break;
1104 default: break;
1105 }
1106 }
1107 break;
1108
1109 case PptSlideLayout::TWOCOLUMNSANDTITLE :
1110 {
1111 eAutoLayout = AUTOLAYOUT_TITLE_2CONTENT;
1112 PptPlaceholder nID1 = pSlideLayout->aPlaceholderId[ 1 ];
1113 PptPlaceholder nID2 = pSlideLayout->aPlaceholderId[ 2 ];
1114 if ( nID1 == PptPlaceholder::BODY && nID2 == PptPlaceholder::GRAPH )
1115 eAutoLayout = AUTOLAYOUT_TEXTCHART;
1116 else if ( nID1 == PptPlaceholder::GRAPH && nID2 == PptPlaceholder::BODY )
1117 eAutoLayout = AUTOLAYOUT_CHARTTEXT;
1118 else if ( nID1 == PptPlaceholder::BODY && nID2 == PptPlaceholder::CLIPART )
1119 eAutoLayout = AUTOLAYOUT_TEXTCLIP;
1120 else if ( nID1 == PptPlaceholder::CLIPART && nID2 == PptPlaceholder::BODY )
1121 eAutoLayout = AUTOLAYOUT_CLIPTEXT;
1122 else if ( nID1 == PptPlaceholder::CLIPART && nID2 == PptPlaceholder::VERTICALTEXTBODY )
1123 eAutoLayout = AUTOLAYOUT_TITLE_2VTEXT;
1124 else if ( ( nID1 == PptPlaceholder::BODY )
1125 && ( ( nID2 == PptPlaceholder::OBJECT ) || ( nID2 == PptPlaceholder::MEDIACLIP ) ) )
1126 eAutoLayout = AUTOLAYOUT_TEXTOBJ;
1127 else if ( ( nID2 == PptPlaceholder::BODY )
1128 && ( ( nID1 == PptPlaceholder::OBJECT ) || ( nID1 == PptPlaceholder::MEDIACLIP ) ) )
1129 eAutoLayout = AUTOLAYOUT_OBJTEXT;
1130 else if ( ( nID1 == PptPlaceholder::OBJECT ) && ( nID2 == PptPlaceholder::OBJECT ) )
1131 eAutoLayout = AUTOLAYOUT_OBJ;
1132 }
1133 break;
1134
1135 case PptSlideLayout::TWOROWSANDTITLE :
1136 {
1137 eAutoLayout = AUTOLAYOUT_TITLE_2CONTENT;
1138 PptPlaceholder nID1 = pSlideLayout->aPlaceholderId[ 1 ];
1139 PptPlaceholder nID2 = pSlideLayout->aPlaceholderId[ 2 ];
1140 if ( nID1 == PptPlaceholder::BODY && nID2 == PptPlaceholder::OBJECT )
1141 eAutoLayout = AUTOLAYOUT_TEXTOVEROBJ;
1142 else if ( nID1 == PptPlaceholder::OBJECT && nID2 == PptPlaceholder::BODY )
1143 eAutoLayout = AUTOLAYOUT_TITLE_CONTENT_OVER_CONTENT;
1144 }
1145 break;
1146
1147 case PptSlideLayout::TITLESLIDE :
1148 eAutoLayout = AUTOLAYOUT_TITLE;
1149 break;
1150 case PptSlideLayout::ONLYTITLE :
1151 eAutoLayout = AUTOLAYOUT_TITLE_ONLY;
1152 break;
1153 case PptSlideLayout::RIGHTCOLUMN2ROWS :
1154 eAutoLayout = AUTOLAYOUT_TITLE_CONTENT_2CONTENT;
1155 break;
1156 case PptSlideLayout::LEFTCOLUMN2ROWS :
1157 eAutoLayout = AUTOLAYOUT_TITLE_2CONTENT_CONTENT;
1158 break;
1159 case PptSlideLayout::TOPROW2COLUMN :
1160 eAutoLayout = AUTOLAYOUT_TITLE_2CONTENT_OVER_CONTENT;
1161 break;
1162 case PptSlideLayout::FOUROBJECTS :
1163 eAutoLayout = AUTOLAYOUT_TITLE_4CONTENT;
1164 break;
1165 case PptSlideLayout::BIGOBJECT :
1166 eAutoLayout = AUTOLAYOUT_OBJ;
1167 break;
1168 case PptSlideLayout::TITLERIGHTBODYLEFT :
1169 eAutoLayout = AUTOLAYOUT_VTITLE_VCONTENT;
1170 break;
1171 case PptSlideLayout::TITLERIGHT2BODIESLEFT :
1172 eAutoLayout = AUTOLAYOUT_VTITLE_VCONTENT_OVER_VCONTENT;
1173 break;
1174
1175 case PptSlideLayout::BOTTOMROW2COLUMNS :
1176 case PptSlideLayout::BLANKSLIDE :
1177 case PptSlideLayout::MASTERSLIDE : // layout of the standard and title master page
1178 case PptSlideLayout::TITLEMASTERSLIDE :
1179 case PptSlideLayout::MASTERNOTES : // layout of the note master page
1180 case PptSlideLayout::NOTESTITLEBODY : // presentation layout for note pages
1181 case PptSlideLayout::HANDOUTLAYOUT : // presentation layout for handout
1182 eAutoLayout = AUTOLAYOUT_NONE;
1183 break;
1184 }
1185 if ( eAutoLayout != AUTOLAYOUT_NONE )
1186 pPage->SetAutoLayout( eAutoLayout );
1187 }
1188 }
1189
1190 // handout master page: auto layout
1191 SdPage* pHandoutMPage = mpDoc->GetMasterSdPage( 0, PageKind::Handout );
1192 pHandoutMPage->SetAutoLayout( AUTOLAYOUT_HANDOUT6, true, true );
1193 }
1194
1195 sal_uInt32 nSlideCount = GetPageCount();
1196 for ( sal_uInt32 i = 0; ( i < nSlideCount) && ( i < maSlideNameList.size() ); i++ )
1197 {
1198 SdPage* pPage = mpDoc->GetSdPage( i, PageKind::Standard );
1199 OUString &aName = maSlideNameList[ i ];
1200 if ( pPage )
1201 {
1202 if ( !aName.isEmpty() )
1203 pPage->SetName( aName );
1204 else
1205 aName = pPage->GetName();
1206 }
1207 }
1208 if ( mbDocumentFound )
1209 {
1210 mpDoc->SetSummationOfParagraphs();
1211 if ( pDocShell )
1212 {
1213 ::sd::FrameView* pFrameView = mpDoc->GetFrameView( 0 );
1214 if ( !pFrameView )
1215 {
1216 std::vector<std::unique_ptr<sd::FrameView>> &rViews = mpDoc->GetFrameViewList();
1217 pFrameView = new ::sd::FrameView( mpDoc );
1218 rViews.push_back( std::unique_ptr<sd::FrameView>(pFrameView) );
1219 }
1220 sal_uInt16 nSelectedPage = 0;
1221 PageKind ePageKind = PageKind::Standard;
1222 EditMode eEditMode = EditMode::Page;
1223
1224 switch ( m_aUserEditAtom.eLastViewType )
1225 {
1226 case PptViewTypeEnum::Outline:
1227 {
1228 SfxItemSet* pSet = mrMed.GetItemSet();
1229 if ( pSet )
1230 pSet->Put( SfxUInt16Item( SID_VIEW_ID, 3 ) );
1231 }
1232 break;
1233 case PptViewTypeEnum::SlideSorter:
1234 {
1235 SfxItemSet* pSet = mrMed.GetItemSet();
1236 if ( pSet )
1237 pSet->Put( SfxUInt16Item( SID_VIEW_ID, 2 ) );
1238 }
1239 break;
1240 case PptViewTypeEnum::TitleMaster:
1241 nSelectedPage = 1;
1242 [[fallthrough]];
1243 case PptViewTypeEnum::SlideMaster:
1244 {
1245 ePageKind = PageKind::Standard;
1246 eEditMode = EditMode::MasterPage;
1247 }
1248 break;
1249 case PptViewTypeEnum::NotesMaster:
1250 eEditMode = EditMode::MasterPage;
1251 [[fallthrough]];
1252 case PptViewTypeEnum::Notes:
1253 ePageKind = PageKind::Notes;
1254 break;
1255 case PptViewTypeEnum::Handout:
1256 ePageKind = PageKind::Handout;
1257 break;
1258 default :
1259 case PptViewTypeEnum::Slide:
1260 break;
1261 }
1262 pFrameView->SetPageKind( ePageKind );
1263 pFrameView->SetSelectedPage( nSelectedPage );
1264 pFrameView->SetViewShEditMode( eEditMode );
1265 }
1266 DffRecordHeader aCustomShowHeader;
1267 // read and set custom show
1268 rStCtrl.Seek( maDocHd.GetRecBegFilePos() + 8 );
1269 if ( SeekToRec( rStCtrl, PPT_PST_NamedShows, maDocHd.GetRecEndFilePos(), &aCustomShowHeader ) )
1270 {
1271 DffRecordHeader aCuHeader;
1272 while( SeekToRec( rStCtrl, PPT_PST_NamedShow, aCustomShowHeader.GetRecEndFilePos(), &aCuHeader ) )
1273 {
1274 DffRecordHeader aContent;
1275 if ( SeekToRec( rStCtrl, PPT_PST_CString, aCuHeader.GetRecEndFilePos(), &aContent ) )
1276 {
1277 OUString aCuShow;
1278 aContent.SeekToBegOfRecord( rStCtrl );
1279 if ( ReadString( aCuShow ) )
1280 {
1281 if ( SeekToRec( rStCtrl, PPT_PST_NamedShowSlides, aCuHeader.GetRecEndFilePos(), &aContent ) )
1282 {
1283 PptSlidePersistList* pPageList = GetPageList( PPT_SLIDEPAGE );
1284 const auto nRemainingSize = rStCtrl.remainingSize();
1285 sal_uInt32 nBCount = aContent.nRecLen;
1286 if (nBCount > nRemainingSize)
1287 {
1288 SAL_WARN("filter.ms", "page number data len longer than remaining stream size");
1289 nBCount = nRemainingSize;
1290 }
1291 sal_uInt32 nSCount = nBCount >> 2;
1292
1293 if ( pPageList && nSCount )
1294 {
1295 SdCustomShowList* pList = mpDoc->GetCustomShowList( true );
1296 if ( pList )
1297 {
1298 std::unique_ptr<SdCustomShow> pSdCustomShow(new SdCustomShow);
1299 pSdCustomShow->SetName( aCuShow );
1300 sal_uInt32 nFound = 0;
1301 for ( sal_uInt32 nS = 0; nS < nSCount; nS++ )
1302 {
1303 sal_uInt32 nPageNumber;
1304 rStCtrl.ReadUInt32( nPageNumber );
1305 sal_uInt16 nPage = pPageList->FindPage( nPageNumber );
1306 if ( nPage != PPTSLIDEPERSIST_ENTRY_NOTFOUND )
1307 {
1308 SdPage* pPage = mpDoc->GetSdPage( nPage, PageKind::Standard );
1309 if ( pPage )
1310 {
1311 pSdCustomShow->PagesVector().push_back( pPage );
1312 nFound++;
1313 }
1314 }
1315 }
1316 if ( nFound )
1317 pList->push_back( std::move(pSdCustomShow) );
1318 }
1319 }
1320 }
1321 }
1322 }
1323 }
1324 }
1325 // this is defaulted, maybe there is no SSDocInfoAtom
1326 OUStringBuffer aCustomShow;
1327 sal_uInt32 nFlags = 1; // Bit 0: Auto advance
1328 sal_uInt16 nStartSlide = 0;
1329
1330 // read the pres. configuration
1331 rStCtrl.Seek( maDocHd.GetRecBegFilePos() + 8 );
1332 if ( SeekToRec( rStCtrl, PPT_PST_SSDocInfoAtom, maDocHd.GetRecEndFilePos(), &aCustomShowHeader ) )
1333 {
1334 sal_uInt32 nPenColor = 0x1000000;
1335 sal_Int32 nRestartTime = 0x7fffffff;
1336 sal_Int16 nEndSlide = 0;
1337 rStCtrl.ReadUInt32( nPenColor )
1338 .ReadInt32( nRestartTime )
1339 .ReadUInt16( nStartSlide )
1340 .ReadInt16( nEndSlide );
1341
1342 sal_Unicode nChar;
1343 for ( sal_uInt32 i2 = 0; i2 < 32; i2++ )
1344 {
1345 rStCtrl.ReadUtf16( nChar );
1346 if ( nChar )
1347 aCustomShow.append( nChar );
1348 else
1349 {
1350 rStCtrl.SeekRel( ( 31 - i2 ) << 1 );
1351 break;
1352 }
1353 }
1354 rStCtrl.ReadUInt32( nFlags );
1355 }
1356 // set the current custom show
1357 if ( !aCustomShow.isEmpty() )
1358 {
1359 SdCustomShowList* pList = mpDoc->GetCustomShowList();
1360 if ( pList )
1361 {
1362 SdCustomShow* pPtr = nullptr;
1363 OUString aCustomShowStr = aCustomShow.makeStringAndClear();
1364 for( pPtr = pList->First(); pPtr; pPtr = pList->Next() )
1365 {
1366 if ( pPtr->GetName() == aCustomShowStr )
1367 break;
1368 }
1369 if ( !pPtr )
1370 pList->First();
1371 }
1372 }
1373 sd::PresentationSettings& rPresSettings = mpDoc->getPresentationSettings();
1374
1375 rPresSettings.mbManual = ( nFlags & 1 ) == 0;
1376 rPresSettings.mbAnimationAllowed = ( nFlags & 2 ) == 0;
1377 rPresSettings.mbAll = ( nFlags & 4 ) == 0;
1378 rPresSettings.mbCustomShow = ( nFlags & 8 ) != 0;
1379 rPresSettings.mbEndless = ( nFlags & 0x80 ) != 0;
1380 rPresSettings.mbFullScreen = ( nFlags & 0x10 ) == 0;
1381
1382 if ( nStartSlide && ( nStartSlide <= GetPageCount() ) )
1383 {
1384 SdPage* pPage = mpDoc->GetSdPage( nStartSlide - 1, PageKind::Standard );
1385 if ( pPage )
1386 rPresSettings.maPresPage = pPage->GetName();
1387 }
1388 }
1389
1390 xStbMgr.reset();
1391
1392 // read DocumentProperties
1393 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
1394 mpDoc->GetObjectShell()->GetModel(), uno::UNO_QUERY_THROW);
1395 uno::Reference<document::XDocumentProperties> xDocProps
1396 = xDPS->getDocumentProperties();
1397 sfx2::LoadOlePropertySet(xDocProps, &mrStorage);
1398 xDocProps->setTemplateName(OUString());
1399
1400 pSdrModel->setLock(bWasLocked);
1401 pSdrModel->EnableUndo(bSavedUndoEnabled);
1402 return m_bOk;
1403 }
1404
SetHeaderFooterPageSettings(SdPage * pPage,const PptSlidePersistEntry * pMasterPersist)1405 void ImplSdPPTImport::SetHeaderFooterPageSettings( SdPage* pPage, const PptSlidePersistEntry* pMasterPersist )
1406 {
1407 sal_uInt32 i;
1408 PptSlidePersistList* pList = GetPageList( m_eCurrentPageKind );
1409 if ( ( !pList ) || ( pList->size() <= m_nCurrentPageNum ) )
1410 return;
1411 PptSlidePersistEntry& rSlidePersist = (*pList)[ m_nCurrentPageNum ];
1412 HeaderFooterEntry* pHFE = rSlidePersist.xHeaderFooterEntry.get();
1413 if (!pHFE)
1414 return;
1415
1416 for ( i = 0; i < 4; i++ )
1417 {
1418 bool bVisible = pHFE->IsToDisplay( i );
1419 if ( ( m_eCurrentPageKind == PPT_SLIDEPAGE )
1420 && ( rSlidePersist.aSlideAtom.aLayout.eLayout == PptSlideLayout::TITLESLIDE )
1421 && ( aDocAtom.bTitlePlaceholdersOmitted ) )
1422 {
1423 bVisible = false;
1424 }
1425 if ( bVisible && pMasterPersist )
1426 {
1427 sal_uInt32 nPosition = pHFE->NeedToImportInstance( i, rSlidePersist );
1428 if ( nPosition )
1429 {
1430 ::tools::Rectangle aEmpty;
1431 bVisible = false;
1432 rStCtrl.Seek( nPosition );
1433 ProcessData aProcessData( rSlidePersist, SdPageCapsule(pPage) );
1434 SdrObject* pObj = ImportObj( rStCtrl, aProcessData, aEmpty, aEmpty, /*nCalledByGroup*/0, /*pShapeId*/nullptr );
1435 if ( pObj )
1436 pPage->NbcInsertObject( pObj, 0 );
1437 }
1438 }
1439 OUString aPlaceHolderString = pHFE->pPlaceholder[ i ];
1440
1441 sd::HeaderFooterSettings rHeaderFooterSettings( pPage->getHeaderFooterSettings() );
1442 switch( i )
1443 {
1444 case 0 :
1445 {
1446 rHeaderFooterSettings.mbDateTimeVisible = bVisible;
1447 rHeaderFooterSettings.mbDateTimeIsFixed = ( pHFE->nAtom & 0x20000 ) == 0;
1448 rHeaderFooterSettings.maDateTimeText = aPlaceHolderString;
1449 SvxDateFormat eDateFormat;
1450 SvxTimeFormat eTimeFormat;
1451 PPTFieldEntry::GetDateTime( pHFE->nAtom & 0xff, eDateFormat, eTimeFormat );
1452 rHeaderFooterSettings.meDateFormat = eDateFormat;
1453 rHeaderFooterSettings.meTimeFormat = eTimeFormat;
1454 }
1455 break;
1456 case 1 :
1457 {
1458 rHeaderFooterSettings.mbHeaderVisible = bVisible;
1459 rHeaderFooterSettings.maHeaderText = aPlaceHolderString;
1460 }
1461 break;
1462 case 2 :
1463 {
1464 rHeaderFooterSettings.mbFooterVisible = bVisible;
1465 rHeaderFooterSettings.maFooterText = aPlaceHolderString;
1466 }
1467 break;
1468 case 3 :
1469 {
1470 rHeaderFooterSettings.mbSlideNumberVisible = bVisible;
1471 }
1472 break;
1473 }
1474 pPage->setHeaderFooterSettings( rHeaderFooterSettings );
1475 }
1476 }
1477
1478 // Import of pages
1479 struct Ppt97AnimationStlSortHelper
1480 {
1481 bool operator()( const std::pair< SdrObject*, Ppt97AnimationPtr >& p1, const std::pair< SdrObject*, Ppt97AnimationPtr >& p2 );
1482 };
1483
operator ()(const std::pair<SdrObject *,Ppt97AnimationPtr> & p1,const std::pair<SdrObject *,Ppt97AnimationPtr> & p2)1484 bool Ppt97AnimationStlSortHelper::operator()( const std::pair< SdrObject*, Ppt97AnimationPtr >& p1, const std::pair< SdrObject*, Ppt97AnimationPtr >& p2 )
1485 {
1486 if( !p1.second.get() || !p2.second.get() )
1487 return p1.second.get() < p2.second.get();
1488 if( *p1.second < *p2.second )
1489 return true;
1490 if( *p1.second > *p2.second )
1491 return false;
1492 return p1.first->GetOrdNum() < p2.first->GetOrdNum();
1493 }
1494
ImportPageEffect(SdPage * pPage,const bool bNewAnimationsUsed)1495 void ImplSdPPTImport::ImportPageEffect( SdPage* pPage, const bool bNewAnimationsUsed )
1496 {
1497 sal_uLong nOldFilePos = rStCtrl.Tell();
1498
1499 // set PageKind at page (up to now only PageKind::Standard or PageKind::Notes)
1500 if ( pPage->GetPageKind() == PageKind::Standard )
1501 {
1502 PptSlidePersistList* pPersistList = GetPageList( m_eCurrentPageKind );
1503 PptSlidePersistEntry* pActualSlidePersist = ( pPersistList && ( m_nCurrentPageNum < pPersistList->size() ) )
1504 ? &(*pPersistList)[ m_nCurrentPageNum ] : nullptr;
1505
1506 if ( pActualSlidePersist && ( m_eCurrentPageKind == PPT_SLIDEPAGE ) )
1507 {
1508 if ( ! ( pActualSlidePersist->aSlideAtom.nFlags & 1 ) ) // do not follow master objects ?
1509 {
1510 if(pPage->TRG_HasMasterPage())
1511 {
1512 SdrLayerIDSet aVisibleLayers = pPage->TRG_GetMasterPageVisibleLayers();
1513 aVisibleLayers.Set(mnBackgroundObjectsLayerID, false);
1514 pPage->TRG_SetMasterPageVisibleLayers(aVisibleLayers);
1515 }
1516 }
1517 }
1518 DffRecordHeader aPageRecHd;
1519 if ( SeekToCurrentPage( &aPageRecHd ) )
1520 {
1521 sal_uLong nPageRecEnd = SanitizeEndPos(rStCtrl, aPageRecHd.GetRecEndFilePos());
1522
1523 bool bTryTwice = ( m_eCurrentPageKind == PPT_SLIDEPAGE );
1524 bool bSSSlideInfoAtom = false;
1525 while ( true )
1526 {
1527 while ( ( rStCtrl.GetError() == ERRCODE_NONE ) && ( rStCtrl.Tell() < nPageRecEnd ) )
1528 {
1529 DffRecordHeader aHd;
1530 ReadDffRecordHeader( rStCtrl, aHd );
1531 switch ( aHd.nRecType )
1532 {
1533 case PPT_PST_SSSlideInfoAtom:
1534 {
1535 bSSSlideInfoAtom = true;
1536 if ( m_eCurrentPageKind == PPT_MASTERPAGE )
1537 {
1538 if ( pActualSlidePersist )
1539 pActualSlidePersist->aPersistAtom.nReserved = aHd.GetRecBegFilePos();
1540 }
1541 else
1542 {
1543 sal_Int8 nDirection, nTransitionType, nByteDummy, nSpeed;
1544 sal_Int16 nBuildFlags;
1545 sal_Int32 nSlideTime, nSoundRef;
1546 rStCtrl.ReadInt32( nSlideTime ) // time to show (in Ticks)
1547 .ReadInt32( nSoundRef ) // Index of SoundCollection
1548 .ReadSChar( nDirection ) // direction of fade effect
1549 .ReadSChar( nTransitionType ) // fade effect
1550 .ReadInt16( nBuildFlags ) // Buildflags (s.u.)
1551 .ReadSChar( nSpeed ) // speed (slow, medium, fast)
1552 .ReadSChar( nByteDummy ).ReadSChar( nByteDummy ).ReadSChar( nByteDummy );
1553
1554 switch ( nTransitionType )
1555 {
1556 case PPT_TRANSITION_TYPE_BLINDS :
1557 {
1558 if ( nDirection == 0 )
1559 pPage->SetFadeEffect( css::presentation::FadeEffect_VERTICAL_STRIPES ); // fade vertical
1560 else if ( nDirection == 1 )
1561 pPage->SetFadeEffect( css::presentation::FadeEffect_HORIZONTAL_STRIPES ); // fade horizontal
1562 }
1563 break;
1564 case PPT_TRANSITION_TYPE_CHECKER :
1565 {
1566 if ( nDirection == 0 )
1567 pPage->SetFadeEffect( css::presentation::FadeEffect_HORIZONTAL_CHECKERBOARD ); // fade vertical with offset ??
1568 else if ( nDirection == 1 )
1569 pPage->SetFadeEffect( css::presentation::FadeEffect_VERTICAL_CHECKERBOARD ); // fade horizontal with offset ??
1570 }
1571 break;
1572 case PPT_TRANSITION_TYPE_COVER :
1573 {
1574 if ( nDirection == 0 )
1575 pPage->SetFadeEffect( css::presentation::FadeEffect_MOVE_FROM_RIGHT ); // overlay from right
1576 else if ( nDirection == 1 )
1577 pPage->SetFadeEffect( css::presentation::FadeEffect_MOVE_FROM_BOTTOM ); // overlay from bottom
1578 else if ( nDirection == 2 )
1579 pPage->SetFadeEffect( css::presentation::FadeEffect_MOVE_FROM_LEFT ); // overlay from left
1580 else if ( nDirection == 3 )
1581 pPage->SetFadeEffect( css::presentation::FadeEffect_MOVE_FROM_TOP ); // overlay from top
1582 else if ( nDirection == 4 )
1583 pPage->SetFadeEffect( css::presentation::FadeEffect_MOVE_FROM_LOWERRIGHT ); // overlay from bottom right ??
1584 else if ( nDirection == 5 )
1585 pPage->SetFadeEffect( css::presentation::FadeEffect_MOVE_FROM_LOWERLEFT ); // overlay from bottom left ??
1586 else if ( nDirection == 6 )
1587 pPage->SetFadeEffect( css::presentation::FadeEffect_MOVE_FROM_UPPERRIGHT ); // overlay from top right
1588 else if ( nDirection == 7 )
1589 pPage->SetFadeEffect( css::presentation::FadeEffect_MOVE_FROM_UPPERLEFT ); // overlay from top left ??
1590 }
1591 break;
1592 case PPT_TRANSITION_TYPE_NONE :
1593 {
1594 if ( nBuildFlags )
1595 {
1596 if ( nDirection == 0 )
1597 pPage->SetFadeEffect( css::presentation::FadeEffect_NONE ); // direct
1598 else if ( nDirection == 1 )
1599 {
1600 pPage->setTransitionType( animations::TransitionType::BARWIPE );
1601 pPage->setTransitionSubtype( animations::TransitionSubType::FADEOVERCOLOR );
1602 pPage->setTransitionFadeColor( 0 );
1603 }
1604 }
1605 else
1606 pPage->setTransitionType( 0 );
1607 }
1608 break;
1609 case PPT_TRANSITION_TYPE_DISSOLVE :
1610 pPage->SetFadeEffect(css::presentation::FadeEffect_DISSOLVE); // dissolve
1611 break;
1612 case PPT_TRANSITION_TYPE_RANDOM_BARS :
1613 {
1614 if ( nDirection == 0 )
1615 pPage->SetFadeEffect( css::presentation::FadeEffect_HORIZONTAL_LINES ); // horizontal lines
1616 else if ( nDirection == 1 )
1617 pPage->SetFadeEffect( css::presentation::FadeEffect_VERTICAL_LINES ); // vertical lines
1618 }
1619 break;
1620 case PPT_TRANSITION_TYPE_SPLIT :
1621 {
1622 if ( nDirection == 0 )
1623 pPage->SetFadeEffect( css::presentation::FadeEffect_OPEN_VERTICAL ); // open horizontal ??
1624 else if ( nDirection == 1 )
1625 pPage->SetFadeEffect( css::presentation::FadeEffect_CLOSE_VERTICAL ); // close horizontal ??
1626 else if ( nDirection == 2 )
1627 pPage->SetFadeEffect( css::presentation::FadeEffect_OPEN_HORIZONTAL ); // open vertical ??
1628 else if ( nDirection == 3 )
1629 pPage->SetFadeEffect( css::presentation::FadeEffect_CLOSE_HORIZONTAL ); // close vertical ??
1630 }
1631 break;
1632 case PPT_TRANSITION_TYPE_STRIPS :
1633 {
1634 if ( nDirection == 4 )
1635 pPage->SetFadeEffect( css::presentation::FadeEffect_FADE_FROM_LOWERRIGHT ); // diagonal to top left
1636 else if ( nDirection == 5 )
1637 pPage->SetFadeEffect( css::presentation::FadeEffect_FADE_FROM_LOWERLEFT ); // diagonal to top right
1638 else if ( nDirection == 6 )
1639 pPage->SetFadeEffect( css::presentation::FadeEffect_FADE_FROM_UPPERRIGHT ); // diagonal to bottom left
1640 else if ( nDirection == 7 )
1641 pPage->SetFadeEffect( css::presentation::FadeEffect_FADE_FROM_UPPERLEFT ); // diagonal to bottom right
1642 }
1643 break;
1644 case PPT_TRANSITION_TYPE_PULL :
1645 {
1646 if ( nDirection == 0 )
1647 pPage->SetFadeEffect( css::presentation::FadeEffect_UNCOVER_TO_LEFT ); // uncover to left
1648 else if ( nDirection == 1 )
1649 pPage->SetFadeEffect( css::presentation::FadeEffect_UNCOVER_TO_TOP ); // uncover to top
1650 else if ( nDirection == 2 )
1651 pPage->SetFadeEffect( css::presentation::FadeEffect_UNCOVER_TO_RIGHT ); // uncover to right
1652 else if ( nDirection == 3 )
1653 pPage->SetFadeEffect( css::presentation::FadeEffect_UNCOVER_TO_BOTTOM ); // uncover to bottom
1654 else if ( nDirection == 4 )
1655 pPage->SetFadeEffect( css::presentation::FadeEffect_UNCOVER_TO_UPPERLEFT ); // uncover to top left
1656 else if ( nDirection == 5 )
1657 pPage->SetFadeEffect( css::presentation::FadeEffect_UNCOVER_TO_UPPERRIGHT ); // uncover to top right
1658 else if ( nDirection == 6 )
1659 pPage->SetFadeEffect( css::presentation::FadeEffect_UNCOVER_TO_LOWERLEFT ); // uncover to bottom left
1660 else if ( nDirection == 7 )
1661 pPage->SetFadeEffect( css::presentation::FadeEffect_UNCOVER_TO_LOWERRIGHT ); // uncover to bottom right
1662 }
1663 break;
1664 case PPT_TRANSITION_TYPE_WIPE :
1665 {
1666 if ( nDirection == 0 )
1667 pPage->SetFadeEffect( css::presentation::FadeEffect_FADE_FROM_RIGHT ); // roll from right
1668 else if ( nDirection == 1 )
1669 pPage->SetFadeEffect( css::presentation::FadeEffect_FADE_FROM_BOTTOM ); // roll from bottom
1670 else if ( nDirection == 2 )
1671 pPage->SetFadeEffect( css::presentation::FadeEffect_FADE_FROM_LEFT ); // roll from left
1672 else if ( nDirection == 3 )
1673 pPage->SetFadeEffect( css::presentation::FadeEffect_FADE_FROM_TOP ); // roll from top
1674 }
1675 break;
1676 case PPT_TRANSITION_TYPE_RANDOM :
1677 pPage->SetFadeEffect( css::presentation::FadeEffect_RANDOM ); // automatic
1678 break;
1679 case PPT_TRANSITION_TYPE_FADE :
1680 {
1681 pPage->setTransitionType( animations::TransitionType::FADE );
1682 pPage->setTransitionSubtype( animations::TransitionSubType::FADEOVERCOLOR );
1683 pPage->setTransitionFadeColor( 0 );
1684 }
1685 break;
1686 case PPT_TRANSITION_TYPE_ZOOM :
1687 {
1688 if ( nDirection == 0 )
1689 pPage->SetFadeEffect( css::presentation::FadeEffect_FADE_FROM_CENTER ); // fade from center
1690 else if ( nDirection == 1 )
1691 pPage->SetFadeEffect( css::presentation::FadeEffect_FADE_TO_CENTER ); // fade from the outside
1692 }
1693 break;
1694 case PPT_TRANSITION_TYPE_DIAMOND :
1695 {
1696 pPage->setTransitionType( animations::TransitionType::IRISWIPE );
1697 pPage->setTransitionSubtype( animations::TransitionSubType::DIAMOND );
1698 }
1699 break;
1700 case PPT_TRANSITION_TYPE_PLUS :
1701 {
1702 pPage->setTransitionType( animations::TransitionType::FOURBOXWIPE );
1703 pPage->setTransitionSubtype( animations::TransitionSubType::CORNERSOUT );
1704 }
1705 break;
1706 case PPT_TRANSITION_TYPE_CIRCLE :
1707 {
1708 pPage->setTransitionType( animations::TransitionType::ELLIPSEWIPE );
1709 pPage->setTransitionSubtype( animations::TransitionSubType::CIRCLE );
1710 }
1711 break;
1712 case PPT_TRANSITION_TYPE_WEDGE :
1713 {
1714 pPage->setTransitionType( animations::TransitionType::FANWIPE );
1715 pPage->setTransitionSubtype( animations::TransitionSubType::CENTERTOP );
1716 }
1717 break;
1718 case PPT_TRANSITION_TYPE_WHEEL :
1719 {
1720 pPage->setTransitionType( animations::TransitionType::PINWHEELWIPE );
1721 sal_Int16 nSubType;
1722 switch( nDirection )
1723 {
1724 default:
1725 case 1 : nSubType = animations::TransitionSubType::ONEBLADE; break;
1726 case 2 : nSubType = animations::TransitionSubType::TWOBLADEVERTICAL; break;
1727 case 3 : nSubType = animations::TransitionSubType::THREEBLADE; break;
1728 case 4 : nSubType = animations::TransitionSubType::FOURBLADE; break;
1729 case 8 : nSubType = animations::TransitionSubType::EIGHTBLADE; break;
1730 }
1731 pPage->setTransitionSubtype( nSubType );
1732 }
1733 break;
1734 case PPT_TRANSITION_TYPE_PUSH :
1735 {
1736 pPage->setTransitionType( animations::TransitionType::PUSHWIPE );
1737 sal_Int16 nSubType;
1738 switch( nDirection )
1739 {
1740 default:
1741 case 0 : nSubType = animations::TransitionSubType::FROMRIGHT; break;
1742 case 1 : nSubType = animations::TransitionSubType::FROMBOTTOM; break;
1743 case 2 : nSubType = animations::TransitionSubType::FROMLEFT; break;
1744 case 3 : nSubType = animations::TransitionSubType::FROMTOP; break;
1745 }
1746 pPage->setTransitionSubtype( nSubType );
1747 }
1748 break;
1749 case PPT_TRANSITION_TYPE_COMB :
1750 {
1751 pPage->setTransitionType( animations::TransitionType::PUSHWIPE );
1752 pPage->setTransitionSubtype( nDirection ? animations::TransitionSubType::COMBVERTICAL : animations::TransitionSubType::COMBHORIZONTAL );
1753 }
1754 break;
1755 case PPT_TRANSITION_TYPE_NEWSFLASH :
1756 {
1757 pPage->setTransitionType( animations::TransitionType::ZOOM );
1758 pPage->setTransitionSubtype( animations::TransitionSubType::ROTATEIN );
1759 }
1760 break;
1761 case PPT_TRANSITION_TYPE_SMOOTHFADE :
1762 {
1763 pPage->setTransitionType( animations::TransitionType::FADE );
1764 pPage->setTransitionSubtype( animations::TransitionSubType::CROSSFADE );
1765 }
1766 break;
1767 }
1768
1769 if ( nSpeed == 0 )
1770 pPage->setTransitionDuration( 1.0 ); // slow
1771 else if ( nSpeed == 1 )
1772 pPage->setTransitionDuration( 0.75 ); // medium
1773 else if ( nSpeed == 2 )
1774 pPage->setTransitionDuration( 0.5 ); // fast
1775
1776 if ( nBuildFlags & 0x400 ) // slidechange by time
1777 { // time to show (in Ticks)
1778 pPage->SetPresChange( PRESCHANGE_AUTO );
1779 pPage->SetTime( nSlideTime / 1000.0 );
1780 }
1781 else
1782 pPage->SetPresChange( mePresChange );
1783
1784 if ( nBuildFlags & 4 )
1785 pPage->SetExcluded( true ); // don't show slide
1786 if ( nBuildFlags & 16 )
1787 { // slide with sound effect
1788 pPage->SetSound( true );
1789 OUString aSoundFile( ReadSound( nSoundRef ) );
1790 pPage->SetSoundFile( aSoundFile );
1791 }
1792 if ( nBuildFlags & ( 1 << 6 ) ) // Loop until next sound
1793 pPage->SetLoopSound( true );
1794 if ( nBuildFlags & ( 1 << 8 ) ) // Stop the previous sound
1795 pPage->SetStopSound( true );
1796 break;
1797 }
1798 }
1799 }
1800 if (!aHd.SeekToEndOfRecord(rStCtrl))
1801 break;
1802 }
1803 if ( bTryTwice && !bSSSlideInfoAtom )
1804 {
1805 bTryTwice = false;
1806 if ( HasMasterPage( m_nCurrentPageNum, m_eCurrentPageKind ) )
1807 {
1808 sal_uInt16 nMasterNum = GetMasterPageIndex( m_nCurrentPageNum, m_eCurrentPageKind );
1809 PptSlidePersistList* pPageList = GetPageList( PPT_MASTERPAGE );
1810 if ( pPageList && ( nMasterNum < pPageList->size() ) )
1811 {
1812 assert( !pPageList->is_null( nMasterNum ) );
1813 const PptSlidePersistEntry& rE = (*pPageList)[ nMasterNum ];
1814 sal_uInt32 nOfs = rE.aPersistAtom.nReserved;
1815 if ( nOfs )
1816 {
1817 rStCtrl.Seek( nOfs );
1818 nPageRecEnd = nOfs + 16;
1819 continue;
1820 }
1821 }
1822
1823 }
1824 }
1825 break;
1826 }
1827 }
1828 }
1829
1830 if ( !bNewAnimationsUsed )
1831 {
1832 tAnimationVector aAnimationsOnThisPage;
1833
1834 // add effects from page in correct order
1835 SdrObjListIter aSdrIter( pPage, SdrIterMode::Flat );
1836 while ( aSdrIter.IsMore() )
1837 {
1838 SdrObject* pObj = aSdrIter.Next();
1839 tAnimationMap::iterator aFound = maAnimations.find( pObj );
1840 if( aFound != maAnimations.end() )
1841 {
1842 std::pair< SdrObject*, Ppt97AnimationPtr > aPair( (*aFound).first, (*aFound).second );
1843 aAnimationsOnThisPage.push_back( aPair );
1844 }
1845 }
1846
1847 std::sort( aAnimationsOnThisPage.begin(), aAnimationsOnThisPage.end(), Ppt97AnimationStlSortHelper() );
1848
1849 for( auto& rEntry : aAnimationsOnThisPage )
1850 {
1851 Ppt97AnimationPtr pPpt97Animation = rEntry.second;
1852 if( pPpt97Animation.get() )
1853 pPpt97Animation->createAndSetCustomAnimationEffect( rEntry.first );
1854 }
1855 }
1856 rStCtrl.Seek( nOldFilePos );
1857 }
1858
1859 // import of sounds
1860
1861 // Not only the sounds are imported as string, they are also inserted to
1862 // the gallery if they are not already there.
ReadSound(sal_uInt32 nSoundRef) const1863 OUString ImplSdPPTImport::ReadSound(sal_uInt32 nSoundRef) const
1864 {
1865 OUString aRetval;
1866 sal_uInt32 nOldPos = rStCtrl.Tell();
1867 DffRecordHeader aDocHd;
1868 if ( SeekToDocument( &aDocHd ) )
1869 {
1870 sal_uInt32 nSoundLen = aDocHd.GetRecEndFilePos();
1871 DffRecordHeader aSoundBlockRecHd;
1872 if( SeekToRec( rStCtrl, PPT_PST_SoundCollection, nSoundLen, &aSoundBlockRecHd ) )
1873 {
1874 sal_uInt32 nDataLen = aSoundBlockRecHd.GetRecEndFilePos();
1875 DffRecordHeader aSoundRecHd;
1876 bool bRefStrValid = false;
1877 bool bDone = false;
1878
1879 while( !bDone && SeekToRec( rStCtrl, PPT_PST_Sound, nDataLen, &aSoundRecHd ) )
1880 {
1881 sal_uInt32 nStrLen = aSoundRecHd.GetRecEndFilePos();
1882 OUString aRefStr;
1883 sal_uInt32 nOldPos2 = rStCtrl.Tell();
1884 if ( SeekToRec( rStCtrl, PPT_PST_CString, nStrLen, nullptr, 2 ) )
1885 {
1886 if ( ReadString( aRefStr ) )
1887 bRefStrValid = true;
1888 }
1889 if ( bRefStrValid )
1890 {
1891 if ( OUString::number(nSoundRef) == aRefStr )
1892 {
1893 rStCtrl.Seek( nOldPos2 );
1894 if ( SeekToRec( rStCtrl, PPT_PST_CString, nStrLen ) )
1895 {
1896 ReadString( aRetval );
1897 bDone = true;
1898 }
1899 }
1900 }
1901 if ( bDone )
1902 {
1903 // Check if this sound file already exists.
1904 // If not, it is exported to our local sound directory.
1905 bool bSoundExists = false;
1906 ::std::vector< OUString > aSoundList;
1907
1908 GalleryExplorer::FillObjList( GALLERY_THEME_SOUNDS, aSoundList );
1909 GalleryExplorer::FillObjList( GALLERY_THEME_USERSOUNDS, aSoundList );
1910
1911 for( size_t n = 0; ( n < aSoundList.size() ) && !bSoundExists; ++n )
1912 {
1913 INetURLObject aURL( aSoundList[ n ] );
1914
1915 if (aURL.GetLastName() == aRetval)
1916 {
1917 aRetval = aSoundList[ n ];
1918 bSoundExists = true;
1919 }
1920 }
1921
1922 aSoundList.clear();
1923
1924 if ( !bSoundExists )
1925 {
1926 rStCtrl.Seek( nOldPos2 );
1927 DffRecordHeader aSoundDataRecHd;
1928 if ( SeekToRec( rStCtrl, PPT_PST_SoundData, nStrLen, &aSoundDataRecHd ) )
1929 {
1930 OUString aGalleryDir;
1931 if (utl::ConfigManager::IsFuzzing())
1932 osl_getTempDirURL(&aGalleryDir.pData);
1933 else
1934 aGalleryDir = SvtPathOptions().GetGalleryPath();
1935 // Use last token delimited by ';'. copy(lastIndexOf+1) works whether
1936 // string is empty or not and whether ';' is there or not.
1937 INetURLObject aGalleryUserSound( aGalleryDir.copy(aGalleryDir.lastIndexOf(';')+1) );
1938
1939 aGalleryUserSound.Append( aRetval );
1940 const auto nRemainingSize = rStCtrl.remainingSize();
1941 sal_uInt32 nSoundDataLen = aSoundDataRecHd.nRecLen;
1942 if (nSoundDataLen > nRemainingSize)
1943 {
1944 SAL_WARN("filter.ms", "sound data len longer than remaining stream size");
1945 nSoundDataLen = nRemainingSize;
1946 }
1947 std::vector<sal_uInt8> aBuf(nSoundDataLen);
1948
1949 rStCtrl.ReadBytes(aBuf.data(), nSoundDataLen);
1950 std::unique_ptr<SvStream> pOStm = ::utl::UcbStreamHelper::CreateStream( aGalleryUserSound.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::WRITE | StreamMode::TRUNC );
1951
1952 if( pOStm )
1953 {
1954 pOStm->WriteBytes(aBuf.data(), nSoundDataLen);
1955
1956 if( pOStm->GetError() == ERRCODE_NONE )
1957 {
1958 GalleryExplorer::InsertURL( GALLERY_THEME_USERSOUNDS, aGalleryUserSound.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
1959 aRetval = aGalleryUserSound.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1960 }
1961 }
1962 }
1963 }
1964 }
1965 if ( !bDone )
1966 {
1967 if (!aSoundRecHd.SeekToEndOfRecord(rStCtrl))
1968 break;
1969 }
1970 }
1971 }
1972 }
1973 rStCtrl.Seek( nOldPos );
1974 return aRetval;
1975 }
1976
1977 // media object import, the return value is the url to the media object
ReadMedia(sal_uInt32 nMediaRef) const1978 OUString ImplSdPPTImport::ReadMedia( sal_uInt32 nMediaRef ) const
1979 {
1980 OUString aRetVal;
1981 DffRecordHeader* pHd( const_cast<ImplSdPPTImport*>(this)->aDocRecManager.GetRecordHeader( PPT_PST_ExObjList ) );
1982 if ( pHd )
1983 {
1984 pHd->SeekToContent( rStCtrl );
1985 auto nEndRecPos = SanitizeEndPos(rStCtrl, pHd->GetRecEndFilePos());
1986 while ( ( rStCtrl.Tell() < nEndRecPos ) && aRetVal.isEmpty() )
1987 {
1988 DffRecordHeader aHdMovie;
1989 ReadDffRecordHeader( rStCtrl, aHdMovie );
1990 switch( aHdMovie.nRecType )
1991 {
1992 case PPT_PST_ExAviMovie :
1993 case PPT_PST_ExMCIMovie :
1994 {
1995 DffRecordHeader aExVideoHd;
1996 if ( SeekToRec( rStCtrl, PPT_PST_ExVideo, aHdMovie.GetRecEndFilePos(), &aExVideoHd ) )
1997 {
1998 DffRecordHeader aExMediaAtomHd;
1999 if ( SeekToRec( rStCtrl, PPT_PST_ExMediaAtom, aExVideoHd.GetRecEndFilePos(), &aExMediaAtomHd ) )
2000 {
2001 sal_uInt32 nRef;
2002 rStCtrl.ReadUInt32( nRef );
2003 if ( nRef == nMediaRef )
2004 {
2005 aExVideoHd.SeekToContent( rStCtrl );
2006 auto nHdEndRecPos = SanitizeEndPos(rStCtrl, aExVideoHd.GetRecEndFilePos());
2007 while (rStCtrl.Tell() < nHdEndRecPos)
2008 {
2009 DffRecordHeader aHd;
2010 ReadDffRecordHeader( rStCtrl, aHd );
2011 switch( aHd.nRecType )
2012 {
2013 case PPT_PST_CString :
2014 {
2015 aHd.SeekToBegOfRecord( rStCtrl );
2016 OUString aStr;
2017 if ( ReadString( aStr ) )
2018 {
2019 if( osl::FileBase::getFileURLFromSystemPath( aStr, aRetVal )
2020 == osl::FileBase::E_None )
2021 {
2022 aRetVal = INetURLObject( aRetVal ).GetMainURL( INetURLObject::DecodeMechanism::Unambiguous );
2023 }else{
2024 aRetVal = aStr;
2025 }
2026 }
2027 }
2028 break;
2029 }
2030 if (!aHd.SeekToEndOfRecord(rStCtrl))
2031 break;
2032 }
2033 break;
2034 }
2035 }
2036 }
2037 }
2038 break;
2039 }
2040 if (!aHdMovie.SeekToEndOfRecord(rStCtrl))
2041 break;
2042 }
2043 }
2044 return aRetVal;
2045 }
2046
2047 // import of objects
FillSdAnimationInfo(SdAnimationInfo * pInfo,PptInteractiveInfoAtom const * pIAtom,const OUString & aMacroName)2048 void ImplSdPPTImport::FillSdAnimationInfo( SdAnimationInfo* pInfo, PptInteractiveInfoAtom const * pIAtom, const OUString& aMacroName )
2049 {
2050 // set local information into pInfo
2051 if( pIAtom->nSoundRef )
2052 {
2053 pInfo->SetBookmark( ReadSound( pIAtom->nSoundRef ) ); // path to sound file in MS DOS notation
2054 pInfo->meClickAction = css::presentation::ClickAction_SOUND; // RunProgramAction
2055 }
2056
2057 switch ( pIAtom->nAction )
2058 {
2059
2060 case 0x02 : // RunProgramAction
2061 {
2062 pInfo->meClickAction = css::presentation::ClickAction_PROGRAM;
2063 pInfo->SetBookmark( aMacroName ); // program name in aBookmark
2064 }
2065 break;
2066 case 0x03 : // JumpAction
2067 {
2068 switch( pIAtom->nJump )
2069 {
2070 case 0x01 :
2071 pInfo->meClickAction = css::presentation::ClickAction_NEXTPAGE; // Next slide
2072 break;
2073 case 0x02 :
2074 pInfo->meClickAction = css::presentation::ClickAction_PREVPAGE; // Previous slide
2075 break;
2076 case 0x03 :
2077 pInfo->meClickAction = css::presentation::ClickAction_FIRSTPAGE; // First slide
2078 break;
2079 case 0x04 :
2080 pInfo->meClickAction = css::presentation::ClickAction_LASTPAGE; // last Slide
2081 break;
2082 case 0x05 :
2083 pInfo->meClickAction = css::presentation::ClickAction_PREVPAGE; // Last slide viewed
2084 break;
2085 case 0x06 :
2086 pInfo->meClickAction = css::presentation::ClickAction_STOPPRESENTATION; // End show
2087 break;
2088 default :
2089 pInfo->meClickAction = css::presentation::ClickAction_NONE; // 0x00: no action, else unknown
2090 break;
2091 }
2092 }
2093 break;
2094 case 0x04 :
2095 {
2096 SdHyperlinkEntry* pPtr = nullptr;
2097 for (SdHyperlinkEntry & entry : m_aHyperList) {
2098 if ( entry.nIndex == pIAtom->nExHyperlinkId ) {
2099 pPtr = &entry;
2100 break;
2101 }
2102 }
2103 if ( pPtr )
2104 {
2105 switch( pIAtom->nHyperlinkType )
2106 {
2107 case 9:
2108 case 8: // hyperlink : URL
2109 {
2110 if ( !pPtr->aTarget.isEmpty() )
2111 {
2112 ::sd::DrawDocShell* pDocShell = mpDoc->GetDocSh();
2113 SfxMedium* pMedium = pDocShell ? pDocShell->GetMedium() : nullptr;
2114 if (pMedium)
2115 {
2116 OUString aBaseURL = pMedium->GetBaseURL();
2117 OUString aBookmarkURL( pInfo->GetBookmark() );
2118 INetURLObject aURL( pPtr->aTarget );
2119 if( INetProtocol::NotValid == aURL.GetProtocol()
2120 && (osl::FileBase::getFileURLFromSystemPath(
2121 pPtr->aTarget, aBookmarkURL)
2122 != osl::FileBase::E_None) )
2123 aBookmarkURL.clear();
2124 if( aBookmarkURL.isEmpty() )
2125 aBookmarkURL = URIHelper::SmartRel2Abs( INetURLObject(aBaseURL), pPtr->aTarget, URIHelper::GetMaybeFileHdl() );
2126 pInfo->SetBookmark( aBookmarkURL );
2127 pInfo->meClickAction = css::presentation::ClickAction_PROGRAM;
2128 }
2129 }
2130 }
2131 break;
2132
2133 case 10:
2134 break;
2135
2136 case 7: // hyperlink to a page
2137 {
2138 if ( !pPtr->aConvSubString.isEmpty() )
2139 {
2140 pInfo->meClickAction = css::presentation::ClickAction_BOOKMARK;
2141 pInfo->SetBookmark( pPtr->aConvSubString );
2142 }
2143 }
2144 break;
2145 }
2146 }
2147 }
2148 break;
2149 case 0x05 : // OLEAction ( OLEVerb to use, 0==first, 1==second, .. )
2150 case 0x06 : // MediaAction
2151 case 0x07 : // CustomShowAction
2152 default : // 0x00: no action, else unknown action
2153 break;
2154 }
2155 }
2156
ApplyTextObj(PPTTextObj * pTextObj,SdrTextObj * pObj,SdPageCapsule pPageCapsule,SfxStyleSheet * pSheet,SfxStyleSheet ** ppStyleSheetAry) const2157 SdrObject* ImplSdPPTImport::ApplyTextObj( PPTTextObj* pTextObj, SdrTextObj* pObj, SdPageCapsule pPageCapsule,
2158 SfxStyleSheet* pSheet, SfxStyleSheet** ppStyleSheetAry ) const
2159 {
2160 SdPage * pPage = static_cast<SdPage *>(pPageCapsule.page);
2161 SfxStyleSheet* pStyleSheetAry[ 9 ];
2162 SdrTextObj* pText = pObj;
2163 SdrObject* pRet = pText;
2164
2165 ppStyleSheetAry = nullptr;
2166
2167 PresObjKind ePresKind = PRESOBJ_NONE;
2168 PptOEPlaceholderAtom* pPlaceHolder = pTextObj->GetOEPlaceHolderAtom();
2169 OUString aPresentationText;
2170 if ( pPlaceHolder )
2171 {
2172 switch( pPlaceHolder->nPlaceholderId )
2173 {
2174 case PptPlaceholder::MASTERNOTESSLIDEIMAGE :
2175 case PptPlaceholder::MASTERCENTEREDTITLE :
2176 case PptPlaceholder::MASTERTITLE :
2177 {
2178 ePresKind = PRESOBJ_TITLE;
2179 aPresentationText = pPage->GetPresObjText( ePresKind );
2180 }
2181 break;
2182 case PptPlaceholder::MASTERBODY :
2183 {
2184 ePresKind = PRESOBJ_OUTLINE;
2185 aPresentationText = pPage->GetPresObjText( ePresKind );
2186 }
2187 break;
2188 case PptPlaceholder::MASTERSUBTITLE :
2189 {
2190 ePresKind = PRESOBJ_TEXT;
2191 aPresentationText = pPage->GetPresObjText( ePresKind );
2192 }
2193 break;
2194 case PptPlaceholder::MASTERNOTESBODYIMAGE :
2195 {
2196 ePresKind = PRESOBJ_NOTES;
2197 aPresentationText = pPage->GetPresObjText( ePresKind );
2198 }
2199 break;
2200 case PptPlaceholder::MASTERDATE : ePresKind = PRESOBJ_DATETIME; break;
2201 case PptPlaceholder::MASTERSLIDENUMBER : ePresKind = PRESOBJ_SLIDENUMBER;break;
2202 case PptPlaceholder::MASTERFOOTER : ePresKind = PRESOBJ_FOOTER; break;
2203 case PptPlaceholder::MASTERHEADER : ePresKind = PRESOBJ_HEADER; break;
2204 default: break;
2205 }
2206 }
2207 switch ( pTextObj->GetDestinationInstance() )
2208 {
2209 case TSS_Type::PageTitle :
2210 case TSS_Type::Title :
2211 {
2212 pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_TITLE );
2213 if ( pSheet )
2214 static_cast<SdrAttrObj*>(pText)->SdrAttrObj::NbcSetStyleSheet( pSheet, true );
2215 DBG_ASSERT( pSheet, "ImplSdPPTImport::ApplyTextObj -> could not get stylesheet for titleobject (SJ)" );
2216 }
2217 break;
2218 case TSS_Type::Subtitle :
2219 {
2220 pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_TEXT );
2221 if ( pSheet )
2222 static_cast<SdrAttrObj*>(pText)->SdrAttrObj::NbcSetStyleSheet( pSheet, true );
2223 DBG_ASSERT( pSheet, "ImplSdPPTImport::ApplyTextObj -> could not get stylesheet for subtitleobject (SJ)" );
2224 }
2225 break;
2226 case TSS_Type::Body :
2227 case TSS_Type::HalfBody :
2228 case TSS_Type::QuarterBody :
2229 {
2230 for ( sal_uInt16 nLevel = 9; nLevel; nLevel-- )
2231 {
2232 OUString aName = pPage->GetLayoutName() + " " + OUString::number( nLevel );
2233 pSheet = static_cast<SfxStyleSheet*>(mpDoc->GetStyleSheetPool()->Find( aName, SfxStyleFamily::Page ));
2234 if ( pSheet )
2235 pText->StartListening( *pSheet );
2236 pStyleSheetAry[ nLevel - 1 ] = pSheet;
2237 }
2238 DBG_ASSERT( pSheet, "ImplSdPPTImport::ApplyTextObj -> could not get stylesheet for outlinerobject (SJ)" );
2239 if ( pSheet )
2240 static_cast<SdrAttrObj*>(pText)->SdrAttrObj::NbcSetStyleSheet( pSheet, true );
2241 ppStyleSheetAry = &pStyleSheetAry[ 0 ];
2242 }
2243 break;
2244 case TSS_Type::Notes :
2245 {
2246 if ( pPlaceHolder && ( ( pPlaceHolder->nPlaceholderId == PptPlaceholder::NOTESSLIDEIMAGE )
2247 || ( pPlaceHolder->nPlaceholderId == PptPlaceholder::MASTERNOTESSLIDEIMAGE ) ) )
2248 {
2249 pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_TITLE );
2250 if ( pSheet )
2251 static_cast<SdrAttrObj*>(pText)->SdrAttrObj::NbcSetStyleSheet( pSheet, true );
2252 DBG_ASSERT( pSheet, "ImplSdPPTImport::ApplyTextObj -> could not get stylesheet for titleobject (SJ)" );
2253 }
2254 else
2255 {
2256 pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_NOTES );
2257 DBG_ASSERT( pSheet, "ImplSdPPTImport::ApplyTextObj -> could not get stylesheet for notesobj (SJ)" );
2258 if ( pSheet )
2259 static_cast<SdrAttrObj*>(pText)->SdrAttrObj::NbcSetStyleSheet( pSheet, true );
2260 }
2261 }
2262 break;
2263 case TSS_Type::Unused :
2264 case TSS_Type::TextInShape :
2265 {
2266 switch( ePresKind )
2267 {
2268 case PRESOBJ_DATETIME :
2269 case PRESOBJ_SLIDENUMBER :
2270 case PRESOBJ_FOOTER :
2271 case PRESOBJ_HEADER :
2272 pSheet = static_cast<SfxStyleSheet*>(mpDoc->GetStyleSheetPool()->Find(SdResId(STR_PSEUDOSHEET_BACKGROUNDOBJECTS), SfxStyleFamily::Pseudo ));
2273 break;
2274 default :
2275 pSheet = static_cast<SfxStyleSheet*>(mpDoc->GetStyleSheetPool()->Find(SdResId(STR_STANDARD_STYLESHEET_NAME), SfxStyleFamily::Para ));
2276 }
2277 }
2278 break;
2279 default: break;
2280 }
2281
2282 pText = static_cast<SdrTextObj*>(SdrPowerPointImport::ApplyTextObj( pTextObj, pText, pPageCapsule, pSheet, ppStyleSheetAry ));
2283
2284 if ( pPlaceHolder && pPlaceHolder->nPlaceholderId != PptPlaceholder::NONE )
2285 {
2286 if ( m_eCurrentPageKind == PPT_MASTERPAGE )
2287 {
2288 bool bCreatePlaceHolder = ( pTextObj->GetInstance() != TSS_Type::Unused );
2289 bool bIsHeaderFooter = ( ePresKind == PRESOBJ_HEADER) || (ePresKind == PRESOBJ_FOOTER)
2290 || (ePresKind == PRESOBJ_DATETIME) || (ePresKind == PRESOBJ_SLIDENUMBER);
2291 if ( bCreatePlaceHolder && ( pTextObj->GetInstance() == TSS_Type::TextInShape ) )
2292 bCreatePlaceHolder = bIsHeaderFooter;
2293 if ( bCreatePlaceHolder )
2294 {
2295 if ( !bIsHeaderFooter )
2296 {
2297 pText->SetNotVisibleAsMaster( true );
2298 pText->SetEmptyPresObj( true );
2299 }
2300 pText->SetUserCall( pPage );
2301 pPage->InsertPresObj( pText, ePresKind );
2302 SdrOutliner* pOutl = nullptr;
2303 if ( pTextObj->GetInstance() == TSS_Type::Notes )
2304 pOutl = GetDrawOutliner( pText );
2305 if ( !aPresentationText.isEmpty() )
2306 pPage->SetObjText( pText, pOutl, ePresKind, aPresentationText );
2307
2308 if ( pPage->GetPageKind() != PageKind::Notes && pPage->GetPageKind() != PageKind::Handout)
2309 {
2310 SfxStyleSheet* pSheet2( pPage->GetStyleSheetForPresObj( ePresKind ) );
2311 if ( pSheet2 )
2312 {
2313 SfxItemSet& rItemSet = pSheet2->GetItemSet();
2314 rItemSet.Put( pText->GetMergedItem( SDRATTR_TEXT_LEFTDIST ) );
2315 rItemSet.Put( pText->GetMergedItem( SDRATTR_TEXT_RIGHTDIST ) );
2316 rItemSet.Put( pText->GetMergedItem( SDRATTR_TEXT_UPPERDIST ) );
2317 rItemSet.Put( pText->GetMergedItem( SDRATTR_TEXT_LOWERDIST ) );
2318 rItemSet.Put( pText->GetMergedItem( SDRATTR_TEXT_VERTADJUST ) );
2319 rItemSet.Put( pText->GetMergedItem( SDRATTR_TEXT_HORZADJUST ) );
2320 if ( pTextObj->GetInstance() == TSS_Type::Title
2321 || pTextObj->GetInstance() == TSS_Type::Subtitle)
2322 {
2323 rItemSet.Put( pText->GetMergedItemSet() );
2324 }
2325 }
2326 }
2327
2328 SfxItemSet aTempAttr( mpDoc->GetPool() );
2329 SdrMetricItem aMinHeight( makeSdrTextMinFrameHeightItem(pText->GetLogicRect().GetSize().Height()) );
2330 aTempAttr.Put( aMinHeight );
2331 SdrOnOffItem aAutoGrowHeight( makeSdrTextAutoGrowHeightItem(false) );
2332 aTempAttr.Put( aAutoGrowHeight );
2333 pText->SetMergedItemSet(aTempAttr);
2334 }
2335 else
2336 {
2337 pRet = nullptr;
2338 }
2339 }
2340 else
2341 {
2342 const PptSlideLayoutAtom* pSlideLayout = GetSlideLayoutAtom();
2343 if ( pSlideLayout || ( m_eCurrentPageKind == PPT_NOTEPAGE ) )
2344 {
2345 sal_uInt32 nPlacementId = pPlaceHolder->nPlacementId;
2346 PptPlaceholder nPlaceholderId = pPlaceHolder->nPlaceholderId;
2347 PresObjKind ePresObjKind = PRESOBJ_NONE;
2348 bool bEmptyPresObj = true;
2349 bool bVertical = false;
2350 if ( ( pTextObj->GetShapeType() == mso_sptRectangle ) || ( pTextObj->GetShapeType() == mso_sptTextBox ) )
2351 {
2352 //if a placeholder with some custom attribute,the pTextObj will keep those attr,whose text size is zero,
2353 //so sdPage should renew a PresObj to process placeholder.
2354 bEmptyPresObj = ( pTextObj->Count() == 0 ) || ( pTextObj->Count() == 1 && pTextObj->First()->GetTextSize() == 0 );
2355 switch ( nPlaceholderId )
2356 {
2357 case PptPlaceholder::NOTESBODY : ePresObjKind = PRESOBJ_NOTES; break;
2358 case PptPlaceholder::VERTICALTEXTTITLE :
2359 bVertical = true;
2360 [[fallthrough]];
2361 case PptPlaceholder::TITLE : ePresObjKind = PRESOBJ_TITLE; break;
2362 case PptPlaceholder::VERTICALTEXTBODY :
2363 bVertical = true;
2364 [[fallthrough]];
2365 case PptPlaceholder::BODY : ePresObjKind = PRESOBJ_OUTLINE; break;
2366 case PptPlaceholder::CENTEREDTITLE : ePresObjKind = PRESOBJ_TITLE; break;
2367 case PptPlaceholder::SUBTITLE : ePresObjKind = PRESOBJ_TEXT; break; // PRESOBJ_OUTLINE
2368
2369 default :
2370 {
2371 if ( pTextObj->Count() == 0 )
2372 {
2373 switch ( nPlaceholderId )
2374 {
2375 case PptPlaceholder::MEDIACLIP :
2376 case PptPlaceholder::OBJECT : ePresObjKind = PRESOBJ_OBJECT; break;
2377 case PptPlaceholder::GRAPH : ePresObjKind = PRESOBJ_CHART; break;
2378 case PptPlaceholder::TABLE : ePresObjKind = PRESOBJ_TABLE; break;
2379 case PptPlaceholder::CLIPART : ePresObjKind = PRESOBJ_GRAPHIC; break;
2380 case PptPlaceholder::ORGANISZATIONCHART : ePresObjKind = PRESOBJ_ORGCHART; break;
2381 default: break;
2382 }
2383 }
2384 };
2385 }
2386 }
2387 else if ( pTextObj->GetShapeType() == mso_sptPictureFrame )
2388 {
2389 if ( !pTextObj->Count() && dynamic_cast< const SdrGrafObj *>( pObj ) != nullptr )
2390 {
2391 bEmptyPresObj = false;
2392 switch ( nPlaceholderId )
2393 {
2394 case PptPlaceholder::MEDIACLIP :
2395 case PptPlaceholder::OBJECT : ePresObjKind = PRESOBJ_OBJECT; break;
2396 case PptPlaceholder::GRAPH : ePresObjKind = PRESOBJ_CHART; break;
2397 case PptPlaceholder::TABLE : ePresObjKind = PRESOBJ_CALC; break;
2398 case PptPlaceholder::CLIPART : ePresObjKind = PRESOBJ_GRAPHIC; break;
2399 case PptPlaceholder::ORGANISZATIONCHART : ePresObjKind = PRESOBJ_ORGCHART; break;
2400 default: break;
2401 }
2402 }
2403 }
2404 if ( ePresObjKind != PRESOBJ_NONE )
2405 {
2406 if ( !bEmptyPresObj )
2407 {
2408 pPage->InsertPresObj( pRet, ePresObjKind );
2409 }
2410 else
2411 {
2412 SdrObject* pPresObj = pPage->CreatePresObj( ePresObjKind, bVertical, pText->GetLogicRect() );
2413 pPresObj->SetUserCall( pPage );
2414
2415 SfxItemSet aSet( pSdrModel->GetItemPool() );
2416 ApplyAttributes( rStCtrl, aSet );
2417 pPresObj->SetLogicRect(pText->GetLogicRect());
2418 ApplyTextAnchorAttributes( *pTextObj, aSet );
2419 //set custom font attribute of the placeholder
2420 if ( pTextObj->Count() == 1 )
2421 {
2422 PPTParagraphObj* pPara = pTextObj->First();
2423 if ( pPara && pPara->GetTextSize() == 0 )
2424 {
2425 if ( PPTPortionObj * pPor = pPara->First() )
2426 {
2427 pPor->ApplyTo(aSet, const_cast<SdrPowerPointImport&>(static_cast<SdrPowerPointImport const &>(*this)), pTextObj->GetDestinationInstance());
2428 }
2429 }
2430 }
2431 pPresObj->SetMergedItemSet(aSet);
2432
2433 if ((m_eCurrentPageKind != PPT_NOTEPAGE) && (nPlacementId != 0xffffffff) && pPage->TRG_HasMasterPage())
2434 {
2435 SdrObject* pTitleObj = static_cast<SdPage&>(pPage->TRG_GetMasterPage()).GetPresObj( PRESOBJ_TITLE );
2436 SdrObject* pOutlineObj = static_cast<SdPage&>(pPage->TRG_GetMasterPage()).GetPresObj( PRESOBJ_OUTLINE );
2437
2438 ::tools::Rectangle aTitleRect;
2439 ::tools::Rectangle aOutlineRect;
2440 Size aOutlineSize;
2441
2442 if ( pTitleObj )
2443 aTitleRect = pTitleObj->GetLogicRect();
2444 if ( pOutlineObj )
2445 {
2446 aOutlineRect = pOutlineObj->GetLogicRect();
2447 aOutlineSize = aOutlineRect.GetSize();
2448 }
2449 ::tools::Rectangle aLogicRect( pPresObj->GetLogicRect() );
2450 Size aLogicSize( aLogicRect.GetSize() );
2451
2452 switch ( nPlacementId )
2453 {
2454 case 0 : // position in title area
2455 {
2456 if ( aLogicRect != aTitleRect )
2457 pPresObj->SetUserCall( nullptr );
2458 }
2459 break;
2460
2461 case 1:
2462 {
2463 if ( pSlideLayout->eLayout == PptSlideLayout::TITLEANDBODYSLIDE )
2464 { // position in outline area
2465 if ( aLogicRect != aOutlineRect )
2466 pPresObj->SetUserCall( nullptr );
2467 }
2468 else if ( pSlideLayout->eLayout == PptSlideLayout::TWOCOLUMNSANDTITLE )
2469 { // position in outline area left
2470 if (std::abs(aLogicRect.Left() - aOutlineRect.Left()) > MAX_USER_MOVE ||
2471 std::abs(aLogicRect.Top() - aOutlineRect.Top()) > MAX_USER_MOVE ||
2472 std::abs(aLogicRect.Bottom() - aOutlineRect.Bottom()) > MAX_USER_MOVE ||
2473 aOutlineSize.Width() == 0 ||
2474 static_cast<double>(aLogicSize.Width()) / aOutlineSize.Width() < 0.48 ||
2475 static_cast<double>(aLogicSize.Width()) / aOutlineSize.Width() > 0.5)
2476 {
2477 pPresObj->SetUserCall(nullptr);
2478 }
2479 }
2480 else if ( pSlideLayout->eLayout == PptSlideLayout::TWOROWSANDTITLE )
2481 { // position in outline area top
2482 if (std::abs(aLogicRect.Left() - aOutlineRect.Left()) > MAX_USER_MOVE ||
2483 std::abs(aLogicRect.Top() - aOutlineRect.Top()) > MAX_USER_MOVE ||
2484 std::abs(aLogicRect.Right() - aOutlineRect.Right()) > MAX_USER_MOVE)
2485 {
2486 pPresObj->SetUserCall( nullptr );
2487 }
2488 }
2489 else if (std::abs(aLogicRect.Left() - aOutlineRect.Left()) > MAX_USER_MOVE ||
2490 std::abs(aLogicRect.Top() - aOutlineRect.Top()) > MAX_USER_MOVE)
2491 { // position in outline area top left
2492 pPresObj->SetUserCall( nullptr );
2493 }
2494 }
2495 break;
2496
2497 case 2:
2498 {
2499 if ( pSlideLayout->eLayout == PptSlideLayout::TWOCOLUMNSANDTITLE )
2500 { // position in outline area right
2501 if (std::abs(aLogicRect.Right() - aOutlineRect.Right()) > MAX_USER_MOVE ||
2502 std::abs(aLogicRect.Top() - aOutlineRect.Top()) > MAX_USER_MOVE ||
2503 std::abs(aLogicRect.Bottom() - aOutlineRect.Bottom()) > MAX_USER_MOVE ||
2504 aOutlineSize.Width() == 0 ||
2505 static_cast<double>(aLogicSize.Width()) / aOutlineSize.Width() < 0.48 ||
2506 static_cast<double>(aLogicSize.Width()) / aOutlineSize.Width() > 0.5)
2507 {
2508 pPresObj->SetUserCall( nullptr );
2509 }
2510 }
2511 else if ( pSlideLayout->eLayout == PptSlideLayout::TWOROWSANDTITLE )
2512 { // position in outline area bottom
2513 if (std::abs(aLogicRect.Left() - aOutlineRect.Left()) > MAX_USER_MOVE ||
2514 std::abs(aLogicRect.Bottom() - aOutlineRect.Bottom()) > MAX_USER_MOVE ||
2515 std::abs(aLogicRect.Right() - aOutlineRect.Right()) > MAX_USER_MOVE)
2516 {
2517 pPresObj->SetUserCall( nullptr );
2518 }
2519 }
2520 else if (std::abs(aLogicRect.Right() - aOutlineRect.Right()) > MAX_USER_MOVE ||
2521 std::abs(aLogicRect.Top() - aOutlineRect.Top()) > MAX_USER_MOVE)
2522 { // position in outline area top right
2523 pPresObj->SetUserCall(nullptr);
2524 }
2525 }
2526 break;
2527
2528 case 3:
2529 { // position in outline area bottom left
2530 if (std::abs(aLogicRect.Left() - aOutlineRect.Left()) > MAX_USER_MOVE ||
2531 std::abs(aLogicRect.Bottom() - aOutlineRect.Bottom()) > MAX_USER_MOVE)
2532 {
2533 pPresObj->SetUserCall( nullptr );
2534 }
2535 }
2536 break;
2537
2538 case 4:
2539 { // position in outline area bottom right
2540 if (std::abs(aLogicRect.Right() - aOutlineRect.Right()) > MAX_USER_MOVE ||
2541 std::abs(aLogicRect.Bottom() - aOutlineRect.Bottom()) > MAX_USER_MOVE)
2542 {
2543 pObj->SetUserCall( nullptr );
2544 }
2545 }
2546 break;
2547 }
2548 }
2549 pRet = nullptr; // return zero cause this obj was already inserted by CreatePresObj
2550 }
2551 }
2552 else if ( !pTextObj->Count() )
2553 pRet = nullptr;
2554 }
2555 }
2556 }
2557 if ( pRet != pText )
2558 {
2559 SdrObject* pFree( pText );
2560 SdrObject::Free( pFree );
2561 }
2562 return pRet;
2563 }
2564
ProcessObj(SvStream & rSt,DffObjData & rObjData,SvxMSDffClientData & rData,::tools::Rectangle & rTextRect,SdrObject * pRet)2565 SdrObject* ImplSdPPTImport::ProcessObj( SvStream& rSt, DffObjData& rObjData, SvxMSDffClientData& rData, ::tools::Rectangle& rTextRect, SdrObject* pRet )
2566 {
2567 SdrObject* pObj = SdrPowerPointImport::ProcessObj( rSt, rObjData, rData, rTextRect, pRet );
2568
2569 // read animation effect of object
2570 if ( pObj )
2571 {
2572 // further setup placeholder objects
2573 if (dynamic_cast<const SdrPageObj*>(pObj))
2574 {
2575 const ProcessData& rProcessData=static_cast<const ProcessData&>(rData);
2576 if(rProcessData.pPage.page)
2577 static_cast<SdPage *>(rProcessData.pPage.page)->InsertPresObj(
2578 pObj, PRESOBJ_PAGE );
2579 }
2580
2581 DffRecordHeader aMasterShapeHd;
2582
2583 if ( maShapeRecords.SeekToContent( rSt, DFF_msofbtClientData, SEEK_FROM_CURRENT_AND_RESTART ) )
2584 {
2585 bool bInhabitanceChecked = false;
2586 bool bAnimationInfoFound = false;
2587
2588 DffRecordHeader& rHdClientData = *maShapeRecords.Current();
2589 while( true )
2590 {
2591 sal_uInt32 nClientDataLen = SanitizeEndPos(rSt, rHdClientData.GetRecEndFilePos());
2592 DffRecordHeader aHd;
2593 do
2594 {
2595 ReadDffRecordHeader( rSt, aHd );
2596 sal_uInt32 nHdRecEnd = aHd.GetRecEndFilePos();
2597 switch ( aHd.nRecType )
2598 {
2599 case PPT_PST_AnimationInfo :
2600 {
2601 DffRecordHeader aHdAnimInfoAtom;
2602 if ( SeekToRec( rSt, PPT_PST_AnimationInfoAtom, nHdRecEnd, &aHdAnimInfoAtom ) )
2603 {
2604 // read data from stream
2605 Ppt97AnimationPtr pAnimation( new Ppt97Animation( rSt ) );
2606 // store animation information
2607 if( pAnimation->HasEffect() )
2608 {
2609 // translate color to RGB
2610 pAnimation->SetDimColor( MSO_CLR_ToColor(pAnimation->GetDimColor()) );
2611 // translate sound bits to file url
2612 if( pAnimation->HasSoundEffect() )
2613 pAnimation->SetSoundFileUrl( ReadSound( pAnimation->GetSoundRef() ) );
2614
2615 bool bDontAnimateInvisibleShape = false;
2616 {
2617 SdrTextObj* pTextObj = dynamic_cast<SdrTextObj*>(pObj);
2618
2619 if( pTextObj && pTextObj->HasText() &&
2620 dynamic_cast< SdrObjGroup *>( pObj ) == nullptr &&
2621 pAnimation->HasAnimateAssociatedShape() )
2622 {
2623 const SfxItemSet& rObjItemSet = pObj->GetMergedItemSet();
2624
2625 drawing::FillStyle eFillStyle = rObjItemSet.Get(XATTR_FILLSTYLE).GetValue();
2626 drawing::LineStyle eLineStyle = rObjItemSet.Get(XATTR_LINESTYLE).GetValue();
2627
2628 if ( ( eFillStyle == drawing::FillStyle_NONE ) && ( eLineStyle == drawing::LineStyle_NONE ) )
2629 bDontAnimateInvisibleShape = true;
2630 }
2631 }
2632 if( bDontAnimateInvisibleShape )
2633 pAnimation->SetAnimateAssociatedShape(false);
2634
2635 //maybe some actions necessary to ensure that animations on master pages are played before animations on normal pages
2636 //maybe todo in future: bool bIsEffectOnMasterPage = !bInhabitanceChecked;?
2637
2638 maAnimations[pObj] = pAnimation;
2639
2640 bAnimationInfoFound = true;
2641 }
2642 }
2643 }
2644 break;
2645 case PPT_PST_InteractiveInfo:
2646 {
2647 sal_uInt32 nOldFilePos2 = rSt.Tell();
2648 OUString aMacroName;
2649
2650 if(SeekToRec( rSt, PPT_PST_CString, nHdRecEnd ) )
2651 ReadString(aMacroName);
2652
2653 rSt.Seek( nOldFilePos2 );
2654 DffRecordHeader aHdInteractiveInfoAtom;
2655 if ( SeekToRec( rSt, PPT_PST_InteractiveInfoAtom, nHdRecEnd, &aHdInteractiveInfoAtom ) )
2656 {
2657 PptInteractiveInfoAtom aInteractiveInfoAtom;
2658 ReadPptInteractiveInfoAtom( rSt, aInteractiveInfoAtom );
2659
2660 // interactive object
2661 SdAnimationInfo* pInfo = SdDrawDocument::GetShapeUserData(*pObj, true);
2662
2663 FillSdAnimationInfo( pInfo, &aInteractiveInfoAtom, aMacroName );
2664 if ( aInteractiveInfoAtom.nAction == 6 ) // Sj -> media action
2665 {
2666 rHdClientData.SeekToContent( rStCtrl );
2667 DffRecordHeader aObjRefAtomHd;
2668 if ( SeekToRec( rSt, PPT_PST_ExObjRefAtom, nHdRecEnd, &aObjRefAtomHd ) )
2669 {
2670 sal_uInt32 nRef;
2671 rSt.ReadUInt32( nRef );
2672 OUString aMediaURL( ReadMedia( nRef ) );
2673 if ( aMediaURL.isEmpty() )
2674 aMediaURL = ReadSound( nRef );
2675 if ( !aMediaURL.isEmpty() )
2676 {
2677 SdrMediaObj* pMediaObj = new SdrMediaObj(
2678 pObj->getSdrModelFromSdrObject(),
2679 pObj->GetSnapRect());
2680 pMediaObj->SetMergedItemSet( pObj->GetMergedItemSet() );
2681
2682 //--remove object from maAnimations list and add the new object instead
2683 Ppt97AnimationPtr pAnimation;
2684 {
2685 tAnimationMap::iterator aFound = maAnimations.find( pObj );
2686 if( aFound != maAnimations.end() )
2687 {
2688 pAnimation = (*aFound).second;
2689 maAnimations.erase(aFound);
2690 }
2691 maAnimations[pMediaObj] = pAnimation;
2692 }
2693
2694 SdrObject::Free( pObj );
2695 pObj = pMediaObj; // SJ: hoping that pObj is not inserted in any list
2696 pMediaObj->setURL( aMediaURL, ""/*TODO?*/ );
2697 }
2698 }
2699 }
2700 }
2701 }
2702 break;
2703 }
2704 if (!aHd.SeekToEndOfRecord(rSt))
2705 break;
2706 }
2707 while( ( rSt.GetError() == ERRCODE_NONE ) && ( rSt.Tell() < nClientDataLen ) );
2708
2709 if ( bInhabitanceChecked || bAnimationInfoFound )
2710 break;
2711 bInhabitanceChecked = true;
2712 if ( ! ( IsProperty( DFF_Prop_hspMaster ) && SeekToShape( rSt, &rData, GetPropertyValue( DFF_Prop_hspMaster, 0 ) ) ) )
2713 break;
2714 ReadDffRecordHeader( rSt, aMasterShapeHd );
2715 if ( !SeekToRec( rSt, DFF_msofbtClientData, aMasterShapeHd.GetRecEndFilePos(), &aMasterShapeHd ) )
2716 break;
2717 aMasterShapeHd.SeekToContent( rSt );
2718 rHdClientData = aMasterShapeHd;
2719 }
2720 }
2721 }
2722 return pObj;
2723 }
2724
2725 bool
ReadFormControl(tools::SvRef<SotStorage> & rSrc1,css::uno::Reference<css::form::XFormComponent> & rFormComp) const2726 ImplSdPPTImport::ReadFormControl( tools::SvRef<SotStorage>& rSrc1, css::uno::Reference< css::form::XFormComponent > & rFormComp ) const
2727 {
2728 uno::Reference< frame::XModel > xModel;
2729 if ( mpDoc->GetDocSh() )
2730 {
2731 xModel = mpDoc->GetDocSh()->GetModel();
2732 oox::ole::MSConvertOCXControls aCtrlImporter( xModel );
2733 return aCtrlImporter.ReadOCXStorage( rSrc1, rFormComp );
2734 }
2735 return false;
2736 }
2737
2738 // exported function
ImportPPT(SdDrawDocument * pDocument,SvStream & rDocStream,SotStorage & rStorage,SfxMedium & rMedium)2739 extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool ImportPPT(
2740 SdDrawDocument* pDocument, SvStream& rDocStream, SotStorage& rStorage, SfxMedium& rMedium )
2741 {
2742 std::unique_ptr<SdPPTImport> pImport( new SdPPTImport( pDocument, rDocStream, rStorage, rMedium ));
2743 bool bRet = pImport->Import();
2744 return bRet;
2745 }
2746
TestImportPPT(SvStream & rStream)2747 extern "C" SAL_DLLPUBLIC_EXPORT bool TestImportPPT(SvStream &rStream)
2748 {
2749 bool bRet = false;
2750 try
2751 {
2752 tools::SvRef<SotStorage> xStorage(new SotStorage(rStream));
2753 if (xStorage->GetError())
2754 return false;
2755
2756 tools::SvRef<SotStorageStream> xDocStream(xStorage->OpenSotStream( "PowerPoint Document", StreamMode::STD_READ));
2757 if ( !xDocStream.is() )
2758 return false;
2759
2760 SdDLL::Init();
2761
2762 SfxMedium aSrcMed("", StreamMode::STD_READ);
2763
2764 xDocStream->SetVersion(xStorage->GetVersion());
2765 xDocStream->SetCryptMaskKey(xStorage->GetKey());
2766
2767 ::sd::DrawDocShellRef xDocShRef = new ::sd::DrawDocShell(SfxObjectCreateMode::EMBEDDED, false, DocumentType::Impress);
2768 SdDrawDocument *pDoc = xDocShRef->GetDoc();
2769
2770 try
2771 {
2772 bRet = ImportPPT(pDoc, *xDocStream, *xStorage, aSrcMed);
2773 }
2774 catch (...)
2775 {
2776 }
2777
2778 xDocShRef->DoClose();
2779 }
2780 catch (...)
2781 {
2782 }
2783 return bRet;
2784 }
2785
2786 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
2787