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