/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pptin.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include "propread.hxx" #include #include #include #include #include #include #include #include #include #include #include #define MAX_USER_MOVE 2 #include "pptanimations.hxx" #include "pptinanimations.hxx" #include "ppt97animations.hxx" #include #include #include #include #include #include #include #include #include #include using namespace ::com::sun::star; SdPPTImport::SdPPTImport( SdDrawDocument* pDocument, SvStream& rDocStream, SotStorage& rStorage, SfxMedium& rMedium ) : maParam(rDocStream) { #ifdef DBG_UTIL std::unique_ptr pSummaryInformation(new PropRead( rStorage, "\005SummaryInformation" )); if ( pSummaryInformation->IsValid() ) { pSummaryInformation->Read(); sal_uInt8 const aPropSetGUID[ 16 ] { 0xe0, 0x85, 0x9f, 0xf2, 0xf9, 0x4f, 0x68, 0x10, 0xab, 0x91, 0x08, 0x00, 0x2b, 0x27, 0xb3, 0xd9 }; Section* pSection = const_cast(pSummaryInformation->GetSection( aPropSetGUID )); if ( pSection ) { PropItem aPropItem; if ( pSection->GetProperty( PID_COMMENTS, aPropItem ) ) { OUString aComment; aPropItem.Read( aComment ); if ( aComment.indexOf( "Applixware" ) >= 0 ) { maParam.nImportFlags |= PPT_IMPORTFLAGS_NO_TEXT_ASSERT; } } } } pSummaryInformation.reset(); #endif if (auto pCurrentUserStream = std::unique_ptr(rStorage.OpenSotStream("Current User", StreamMode::STD_READ))) { ReadPptCurrentUserAtom(*pCurrentUserStream, maParam.aCurrentUserAtom); } if( pDocument ) { // iterate over all styles SdStyleSheetPool* pStyleSheetPool = pDocument->GetSdStyleSheetPool(); std::shared_ptr aIter = std::make_shared(pStyleSheetPool, SfxStyleFamily::All); for (SfxStyleSheetBase *pSheet = aIter->First(); pSheet; pSheet = aIter->Next()) { SfxItemSet& rSet = pSheet->GetItemSet(); // if autokerning is set in style, override it, ppt has no autokerning if( rSet.GetItemState( EE_CHAR_PAIRKERNING, false ) == SfxItemState::SET ) rSet.ClearItem( EE_CHAR_PAIRKERNING ); } } pFilter.reset(new ImplSdPPTImport(pDocument, rStorage, rMedium, maParam)); } bool SdPPTImport::Import() { return pFilter->Import(); } SdPPTImport::~SdPPTImport() { } ImplSdPPTImport::ImplSdPPTImport( SdDrawDocument* pDocument, SotStorage& rStorage_, SfxMedium& rMedium, PowerPointImportParam& rParam ) : SdrPowerPointImport(rParam, rMedium.GetBaseURL()) , mrMed(rMedium) , mrStorage(rStorage_) , mbDocumentFound(false) , mnFilterOptions(0) , mpDoc(pDocument) , mePresChange(PRESCHANGE_MANUAL) , mnBackgroundObjectsLayerID(0) { if ( !m_bOk ) return; mbDocumentFound = SeekToDocument( &maDocHd ); // maDocHd = the latest DocumentHeader while ( SeekToRec( rStCtrl, PPT_PST_Document, nStreamLen, &maDocHd ) ) mbDocumentFound = true; sal_uInt32 nDggContainerOfs = 0; if ( mbDocumentFound ) { sal_uLong nOldPos = rStCtrl.Tell(); pStData = rStorage_.OpenSotStream( "Pictures", StreamMode::STD_READ ); rStCtrl.Seek( maDocHd.GetRecBegFilePos() + 8 ); sal_uLong nDocLen = maDocHd.GetRecEndFilePos(); DffRecordHeader aPPDGHd; if ( SeekToRec( rStCtrl, PPT_PST_PPDrawingGroup, nDocLen, &aPPDGHd ) ) { sal_uLong nPPDGLen = aPPDGHd.GetRecEndFilePos(); if ( SeekToRec( rStCtrl, DFF_msofbtDggContainer, nPPDGLen ) ) nDggContainerOfs = rStCtrl.Tell(); } rStCtrl.Seek( nOldPos ); } sal_uInt32 nSvxMSDffOLEConvFlags2 = 0; const SvtFilterOptions& rBasOpt = SvtFilterOptions::Get(); if ( rBasOpt.IsLoadPPointBasicCode() ) mnFilterOptions |= 1; if ( rBasOpt.IsMathType2Math() ) nSvxMSDffOLEConvFlags2 |= OLE_MATHTYPE_2_STARMATH; if ( rBasOpt.IsWinWord2Writer() ) nSvxMSDffOLEConvFlags2 |= OLE_WINWORD_2_STARWRITER; if ( rBasOpt.IsExcel2Calc() ) nSvxMSDffOLEConvFlags2 |= OLE_EXCEL_2_STARCALC; if ( rBasOpt.IsPowerPoint2Impress() ) nSvxMSDffOLEConvFlags2 |= OLE_POWERPOINT_2_STARIMPRESS; InitSvxMSDffManager( nDggContainerOfs, pStData, nSvxMSDffOLEConvFlags2 ); SetSvxMSDffSettings( SVXMSDFF_SETTINGS_CROP_BITMAPS | SVXMSDFF_SETTINGS_IMPORT_PPT ); SetModel( mpDoc, 576 ); } // Dtor ImplSdPPTImport::~ImplSdPPTImport() { delete pStData; } // Import bool ImplSdPPTImport::Import() { if ( !m_bOk ) return false; bool bWasLocked = pSdrModel->isLocked(); pSdrModel->setLock(true); const bool bSavedUndoEnabled = pSdrModel->IsUndoEnabled(); pSdrModel->EnableUndo(false); SdrOutliner& rOutl = mpDoc->GetDrawOutliner(); EEControlBits nControlWord = rOutl.GetEditEngine().GetControlWord(); nControlWord |= EEControlBits::ULSPACESUMMATION; const_cast(rOutl.GetEditEngine()).SetControlWord( nControlWord ); SdrLayerAdmin& rAdmin = mpDoc->GetLayerAdmin(); mnBackgroundObjectsLayerID = rAdmin.GetLayerID( sUNO_LayerName_background_objects ); ::sd::DrawDocShell* pDocShell = mpDoc->GetDocSh(); if ( pDocShell ) SeekOle( pDocShell, mnFilterOptions ); // hyperlinks std::unique_ptr pDInfoSec2(new PropRead( mrStorage, "\005DocumentSummaryInformation" )); if ( pDInfoSec2->IsValid() ) { PropItem aPropItem; sal_uInt32 nType, nPropSize, nPropCount; pDInfoSec2->Read(); sal_uInt8 const aPropSetGUID[ 16 ] { 0x02, 0xd5, 0xcd, 0xd5, 0x9c, 0x2e, 0x1b, 0x10, 0x93, 0x97, 0x08, 0x00, 0x2b, 0x2c, 0xf9, 0xae }; Section* pSection = const_cast(pDInfoSec2->GetSection( aPropSetGUID )); if ( pSection ) { if ( pSection->GetProperty( PID_SLIDECOUNT, aPropItem ) ) { aPropItem.ReadUInt32( nType ); if ( ( nType == VT_I4 ) || ( nType == VT_UI4 ) ) { // examine PID_HEADINGPAIR to get the correct entry for PID_DOCPARTS sal_uInt32 nSlideCount, nVecCount; aPropItem.ReadUInt32( nSlideCount ); if ( nSlideCount && pSection->GetProperty( PID_HEADINGPAIR, aPropItem ) ) { sal_uInt32 nSlideTitleIndex = 0, nSlideTitleCount = 0; OUString aUString; aPropItem.ReadUInt32( nType ) .ReadUInt32( nVecCount ); if ( ( nType == ( VT_VARIANT | VT_VECTOR ) ) && ( nVecCount ^ 1 ) ) { nVecCount >>= 1; sal_uInt32 nEntryCount = 0; for (sal_uInt32 i = 0; i < nVecCount; ++i) { if ( !aPropItem.Read( aUString, VT_EMPTY, false ) ) break; aPropItem.ReadUInt32( nType ); if ( ( nType != VT_I4 ) && ( nType != VT_UI4 ) ) break; sal_uInt32 nTemp(0); aPropItem.ReadUInt32( nTemp ); if ( aUString == "Slide Titles" || aUString == "Folientitel" ) { nSlideTitleCount = nTemp; nSlideTitleIndex = nEntryCount; } nEntryCount += nTemp; } } if ( ( nSlideCount == nSlideTitleCount ) && pSection->GetProperty( PID_DOCPARTS, aPropItem ) ) { aPropItem.ReadUInt32( nType ) .ReadUInt32( nVecCount ); bool bVecOk = ( ( nVecCount >= (nSlideTitleIndex + nSlideTitleCount) ) && ( nType == ( VT_LPSTR | VT_VECTOR ) ) ); if (bVecOk) { for (sal_uInt32 i = 0; i != nSlideTitleIndex; ++i) { sal_uInt32 nTemp(0); aPropItem.ReadUInt32(nTemp); if (!aPropItem.good()) { bVecOk = false; break; } auto nPos = aPropItem.Tell() + nTemp; if (!checkSeek(aPropItem, nPos)) { bVecOk = false; break; } } } if (bVecOk) { for (sal_uInt32 i = 0; i < nSlideTitleCount; ++i) { if (!aPropItem.Read(aUString, nType, false)) break; OUString aString( aUString ); if ( aString == "No Slide Title" ) aString.clear(); else { std::vector::const_iterator pIter = std::find(maSlideNameList.begin(),maSlideNameList.end(),aString); if (pIter != maSlideNameList.end()) aString.clear(); } maSlideNameList.push_back( aString ); } } } } } } sal_uInt8 const aUserPropSetGUID[ 16 ] { 0x05, 0xd5, 0xcd, 0xd5, 0x9c, 0x2e, 0x1b, 0x10, 0x93, 0x97, 0x08, 0x00, 0x2b, 0x2c, 0xf9, 0xae }; pSection = const_cast(pDInfoSec2->GetSection( aUserPropSetGUID )); if ( pSection ) { Dictionary aDict; pSection->GetDictionary(aDict); if (!aDict.empty()) { Dictionary::const_iterator iter = aDict.find( OUString("_PID_HLINKS") ); if ( iter != aDict.end() ) { if ( pSection->GetProperty( iter->second, aPropItem ) ) { aPropItem.Seek( STREAM_SEEK_TO_BEGIN ); aPropItem.ReadUInt32( nType ); if ( nType == VT_BLOB ) { aPropItem.ReadUInt32( nPropSize ) .ReadUInt32( nPropCount ); if ( ! ( nPropCount % 6 ) ) { sal_uInt32 i; nPropCount /= 6; // 6 properties per hyperlink for ( i = 0; i < nPropCount; i++ ) { SdHyperlinkEntry aHyperlink; aHyperlink.nIndex = 0; aPropItem.ReadUInt32( nType ); if ( nType != VT_I4 ) break; aPropItem.ReadInt32( aHyperlink.nPrivate1 ) .ReadUInt32( nType ); if ( nType != VT_I4 ) break; aPropItem.ReadInt32( aHyperlink.nPrivate2 ) .ReadUInt32( nType ); if ( nType != VT_I4 ) break; aPropItem.ReadInt32( aHyperlink.nPrivate3 ) .ReadUInt32( nType ); if ( nType != VT_I4 ) break; aPropItem.ReadInt32( aHyperlink.nInfo ); if ( !aPropItem.Read( aHyperlink.aTarget ) ) break; // Convert '\\' notation to 'smb://' INetURLObject aUrl( aHyperlink.aTarget, INetProtocol::File ); aHyperlink.aTarget = aUrl.GetMainURL( INetURLObject::DecodeMechanism::NONE ); if ( !aPropItem.Read( aHyperlink.aSubAdress ) ) break; if ( !aHyperlink.aSubAdress.isEmpty() ) // get the converted subaddress { sal_uInt32 nPageNumber = 0; OUString aString( aHyperlink.aSubAdress ); OString aStringAry[ 3 ]; size_t nTokenCount = 0; sal_Int32 nPos = 0; do { aStringAry[nTokenCount] = OUStringToOString(aString.getToken( 0, ',', nPos ), RTL_TEXTENCODING_UTF8); } while ( ++nTokenCount < SAL_N_ELEMENTS(aStringAry) && nPos >= 0 ); bool bDocInternalSubAddress = false; // first pass, searching for a SlideId for( size_t nToken = 0; nToken < nTokenCount; ++nToken ) { if (comphelper::string::isdigitAsciiString(aStringAry[nToken])) { sal_Int32 nNumber = aStringAry[ nToken ].toInt32(); if ( nNumber & ~0xff ) { PptSlidePersistList* pPageList = GetPageList( PPT_SLIDEPAGE ); if ( pPageList ) { sal_uInt16 nPage = pPageList->FindPage( nNumber ); if ( nPage != PPTSLIDEPERSIST_ENTRY_NOTFOUND ) { nPageNumber = nPage; bDocInternalSubAddress = true; break; } } } } } if ( !bDocInternalSubAddress ) { // second pass, searching for a SlideName for ( size_t nToken = 0; nToken < nTokenCount; ++nToken ) { OUString aToken(OStringToOUString(aStringAry[nToken], RTL_TEXTENCODING_UTF8)); std::vector::const_iterator pIter = std::find(maSlideNameList.begin(),maSlideNameList.end(),aToken); if (pIter != maSlideNameList.end()) { nPageNumber = pIter - maSlideNameList.begin(); bDocInternalSubAddress = true; } } } if ( !bDocInternalSubAddress ) { // third pass, searching for a slide number for ( size_t nToken = 0; nToken < nTokenCount; ++nToken ) { if (comphelper::string::isdigitAsciiString(aStringAry[nToken])) { sal_Int32 nNumber = aStringAry[ nToken ].toInt32(); if ( ( nNumber & ~0xff ) == 0 ) { nPageNumber = static_cast(nNumber) - 1; bDocInternalSubAddress = true; break; } } } } // if a document internal sub address if ( bDocInternalSubAddress ) { if ( nPageNumber < maSlideNameList.size() ) aHyperlink.aConvSubString = maSlideNameList[ nPageNumber ]; if ( aHyperlink.aConvSubString.isEmpty() ) { aHyperlink.aConvSubString = SdResId( STR_PAGE ) + " " + mpDoc->CreatePageNumValue( static_cast(nPageNumber) + 1 ); } } else { // if sub address is given but not internal, use it as it is if ( aHyperlink.aConvSubString.isEmpty() ) { aHyperlink.aConvSubString = aString; } } } m_aHyperList.push_back( aHyperlink ); } } } } } } } } } pDInfoSec2.reset(); if ( mbDocumentFound ) { rStCtrl.Seek( maDocHd.GetRecBegFilePos() + 8 ); // read hyperlist / set indices of the entries DffRecordHeader aHyperHd; if ( SeekToRec( rStCtrl, PPT_PST_ExObjList, maDocHd.GetRecEndFilePos(), &aHyperHd ) ) { sal_uInt32 nExObjHyperListLen = aHyperHd.GetRecEndFilePos(); for (SdHyperlinkEntry & entry : m_aHyperList) { DffRecordHeader aHyperE; if ( !SeekToRec( rStCtrl, PPT_PST_ExHyperlink, nExObjHyperListLen, &aHyperE ) ) break; if ( !SeekToRec( rStCtrl, PPT_PST_ExHyperlinkAtom, nExObjHyperListLen ) ) break; rStCtrl.SeekRel( 8 ); rStCtrl.ReadUInt32( entry.nIndex ); if (!aHyperE.SeekToEndOfRecord(rStCtrl)) break; } } } if (pDocShell) { Size aVisAreaSize; switch ( m_aUserEditAtom.eLastViewType ) { case PptViewTypeEnum::Notes: case PptViewTypeEnum::NotesMaster: aVisAreaSize = aDocAtom.GetNotesPageSize(); break; default : aVisAreaSize = aDocAtom.GetSlidesPageSize(); } Scale( aVisAreaSize ); pDocShell->SetVisArea( ::tools::Rectangle( Point(), aVisAreaSize ) ); } // create master pages: std::unique_ptr xStbMgr; if (!utl::ConfigManager::IsFuzzing()) { xStbMgr.reset(new SfxProgress(pDocShell, SdResId( STR_POWERPOINT_IMPORT), m_pMasterPages->size() + m_pSlidePages->size() + m_pNotePages->size())); } sal_uInt32 nImportedPages = 0; { sal_uInt16 nMasterCnt = GetPageCount( PPT_MASTERPAGE ); for ( sal_uInt16 nMasterNum = 0; nMasterNum < nMasterCnt; nMasterNum++ ) { SetPageNum( nMasterNum, PPT_MASTERPAGE ); SdPage* pPage = static_cast(MakeBlancPage( true )); if ( pPage ) { bool bNotesMaster = (*GetPageList( m_eCurrentPageKind ) )[ m_nCurrentPageNum ].bNotesMaster; bool bStarDrawFiller = (*GetPageList( m_eCurrentPageKind ) )[ m_nCurrentPageNum ].bStarDrawFiller; PageKind ePgKind = bNotesMaster ? PageKind::Notes : PageKind::Standard; bool bHandout = (*GetPageList( m_eCurrentPageKind ) )[ m_nCurrentPageNum ].bHandoutMaster; if ( bHandout ) ePgKind = PageKind::Handout; pPage->SetPageKind( ePgKind ); pSdrModel->InsertMasterPage( static_cast(pPage) ); if ( bNotesMaster && bStarDrawFiller ) pPage->SetAutoLayout( AUTOLAYOUT_NOTES, true ); if ( nMasterNum ) { std::optional< sal_Int16 > oStartNumbering; SfxStyleSheet* pSheet; if ( nMasterNum == 1 ) { // standardsheet pSheet = static_cast(mpDoc->GetStyleSheetPool()->Find(SdResId(STR_STANDARD_STYLESHEET_NAME), SfxStyleFamily::Para )); if ( pSheet ) { SfxItemSet& rItemSet = pSheet->GetItemSet(); PPTParagraphObj aParagraph( *m_pPPTStyleSheet, TSS_Type::TextInShape, 0 ); PPTPortionObj aPortion( *m_pPPTStyleSheet, TSS_Type::TextInShape, 0 ); aParagraph.AppendPortion( aPortion ); aParagraph.ApplyTo( rItemSet, oStartNumbering, static_cast(*this), TSS_Type::Unknown ); aPortion.ApplyTo( rItemSet, static_cast(*this), TSS_Type::Unknown ); } } // PSEUDO pSheet = static_cast(mpDoc->GetStyleSheetPool()->Find(SdResId(STR_PSEUDOSHEET_BACKGROUNDOBJECTS), SfxStyleFamily::Pseudo )); if ( pSheet ) { SfxItemSet& rItemSet = pSheet->GetItemSet(); PPTParagraphObj aParagraph( *m_pPPTStyleSheet, TSS_Type::TextInShape, 0 ); PPTPortionObj aPortion( *m_pPPTStyleSheet, TSS_Type::TextInShape, 0 ); aParagraph.AppendPortion( aPortion ); aParagraph.ApplyTo( rItemSet, oStartNumbering, static_cast(*this), TSS_Type::Unknown ); aPortion.ApplyTo( rItemSet, static_cast(*this), TSS_Type::Unknown ); } // create layoutstylesheets, set layoutname and stylesheet // (only on standard and not pages) OUString aLayoutName( SdResId( STR_LAYOUT_DEFAULT_NAME ) ); if ( nMasterNum > 2 ) { if ( ePgKind == PageKind::Standard ) { // standard page: create new presentation layout aLayoutName = SdResId( STR_LAYOUT_DEFAULT_TITLE_NAME ) + OUString::number( static_cast( ( nMasterNum + 1 ) / 2 - 1 ) ); static_cast( mpDoc->GetStyleSheetPool() )->CreateLayoutStyleSheets( aLayoutName ); } else // note page: use presentation layout of standard page aLayoutName = static_cast( mpDoc->GetMasterPage( nMasterNum - 1 ) )->GetName(); } pPage->SetName( aLayoutName ); aLayoutName += SD_LT_SEPARATOR STR_LAYOUT_OUTLINE; pPage->SetLayoutName( aLayoutName ); // set stylesheets if ( pPage->GetPageKind() == PageKind::Standard ) { TSS_Type nTitleInstance = TSS_Type::PageTitle; TSS_Type nOutlinerInstance = TSS_Type::Body; const PptSlideLayoutAtom* pSlideLayout = GetSlideLayoutAtom(); bool bSwapStyleSheet = pSlideLayout->eLayout == PptSlideLayout::TITLEMASTERSLIDE; if ( bSwapStyleSheet ) { nTitleInstance = TSS_Type::Title; nOutlinerInstance = TSS_Type::Subtitle; } // titlestylesheet pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_TITLE ); if ( pSheet ) { SfxItemSet& rItemSet = pSheet->GetItemSet(); PPTParagraphObj aParagraph( *m_pPPTStyleSheet, nTitleInstance, 0 ); PPTPortionObj aPortion( *m_pPPTStyleSheet, nTitleInstance, 0 ); aParagraph.AppendPortion( aPortion ); aParagraph.ApplyTo( rItemSet, oStartNumbering, static_cast(*this), TSS_Type::Unknown ); aPortion.ApplyTo( rItemSet, static_cast(*this), TSS_Type::Unknown ); } // outlinerstylesheet sal_uInt16 nLevel; PPTParagraphObj* pParagraphs[ 9 ]; for ( nLevel = 0; nLevel < 9; nLevel++ ) { OUString aName = pPage->GetLayoutName() + " " + OUString::number( nLevel + 1 ); SfxStyleSheet* pOutlineSheet = static_cast( mpDoc->GetStyleSheetPool()->Find( aName, SfxStyleFamily::Page ) ); DBG_ASSERT( pOutlineSheet, "Template for outline object not found" ); if ( pOutlineSheet ) { pParagraphs[ nLevel ] = new PPTParagraphObj( *m_pPPTStyleSheet, nOutlinerInstance, nLevel ); SfxItemSet& rItemSet = pOutlineSheet->GetItemSet(); PPTPortionObj aPortion( *m_pPPTStyleSheet, nOutlinerInstance, nLevel ); pParagraphs[ nLevel ]->AppendPortion( aPortion ); pParagraphs[ nLevel ]->ApplyTo( rItemSet, oStartNumbering, static_cast(*this), TSS_Type::Unknown ); aPortion.ApplyTo( rItemSet, static_cast(*this), TSS_Type::Unknown ); } else pParagraphs[ nLevel ] = nullptr; } for ( nLevel = 0; nLevel < 9; delete pParagraphs[ nLevel++ ] ) ; // subtitle stylesheet pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_TEXT ); if ( pSheet ) { SfxItemSet& rItemSet = pSheet->GetItemSet(); PPTParagraphObj aParagraph( *m_pPPTStyleSheet, TSS_Type::Subtitle, 0 ); PPTPortionObj aPortion( *m_pPPTStyleSheet, TSS_Type::Subtitle, 0 ); aParagraph.AppendPortion( aPortion ); aParagraph.ApplyTo( rItemSet, oStartNumbering, static_cast(*this), TSS_Type::Unknown ); aPortion.ApplyTo( rItemSet, static_cast(*this), TSS_Type::Unknown ); } } else if ( ePgKind == PageKind::Notes ) { pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_NOTES ); if ( pSheet ) { SfxItemSet& rItemSet = pSheet->GetItemSet(); PPTParagraphObj aParagraph( *m_pPPTStyleSheet, TSS_Type::Notes, 0 ); PPTPortionObj aPortion( *m_pPPTStyleSheet, TSS_Type::Notes, 0 ); aParagraph.AppendPortion( aPortion ); aParagraph.ApplyTo( rItemSet, oStartNumbering, static_cast(*this), TSS_Type::Unknown ); aPortion.ApplyTo( rItemSet, static_cast(*this), TSS_Type::Unknown ); } } } } } } for (sal_uInt16 i = 0; i < mpDoc->GetMasterPageCount(); ++i) { SdPage *const pMPage(static_cast(mpDoc->GetMasterPage(i))); if (pMPage == nullptr) break; SetPageNum( i, PPT_MASTERPAGE ); // importing master page objects PptSlidePersistList* pList = GetPageList( m_eCurrentPageKind ); PptSlidePersistEntry* pPersist = ( pList && ( m_nCurrentPageNum < pList->size() ) ) ? &(*pList)[ m_nCurrentPageNum ] : nullptr; if ( pPersist ) { if ( pPersist->bStarDrawFiller && pPersist->bNotesMaster && ( m_nCurrentPageNum > 2 ) && ( ( m_nCurrentPageNum & 1 ) == 0 ) ) { pSdrModel->DeleteMasterPage( m_nCurrentPageNum ); SdrPage* pNotesClone = static_cast(pSdrModel->GetMasterPage( 2 ))->CloneSdrPage(*pSdrModel); pSdrModel->InsertMasterPage( pNotesClone, m_nCurrentPageNum ); if ( pNotesClone ) { OUString aLayoutName( static_cast(pSdrModel->GetMasterPage( m_nCurrentPageNum - 1 ))->GetLayoutName() ); static_cast(pNotesClone)->SetPresentationLayout( aLayoutName, false, false ); static_cast(pNotesClone)->SetLayoutName( aLayoutName ); } } else if ( !pPersist->bStarDrawFiller ) { PptSlidePersistEntry* pE = pPersist; while( ( pE->aSlideAtom.nFlags & 4 ) && pE->aSlideAtom.nMasterId ) { auto nOrigMasterId = pE->aSlideAtom.nMasterId; sal_uInt16 nNextMaster = m_pMasterPages->FindPage(nOrigMasterId); if ( nNextMaster == PPTSLIDEPERSIST_ENTRY_NOTFOUND ) break; else pE = &(*pList)[ nNextMaster ]; if (pE->aSlideAtom.nMasterId == nOrigMasterId) { SAL_WARN("filter.ms", "loop in atom chain"); break; } } SdrObject* pObj = ImportPageBackgroundObject( *pMPage, pE->nBackgroundOffset ); // import background if ( pObj ) pMPage->NbcInsertObject( pObj ); bool bNewAnimationsUsed = false; ProcessData aProcessData( (*pList)[ m_nCurrentPageNum ], SdPageCapsule(pMPage) ); sal_uInt32 nOldFPos = rStCtrl.Tell(); DffRecordHeader aPageHd; if ( SeekToCurrentPage( &aPageHd ) ) { auto nEndRecPos = SanitizeEndPos(rStCtrl, aPageHd.GetRecEndFilePos()); while( ( rStCtrl.GetError() == ERRCODE_NONE ) && ( rStCtrl.Tell() < nEndRecPos ) ) { DffRecordHeader aHd; ReadDffRecordHeader( rStCtrl, aHd ); switch( aHd.nRecType ) { case PPT_PST_PPDrawing : { aHd.SeekToBegOfRecord( rStCtrl ); DffRecordHeader aPPDrawHd; if ( SeekToRec( rStCtrl, PPT_PST_PPDrawing, aHd.GetRecEndFilePos(), &aPPDrawHd ) ) { sal_uInt32 nPPDrawEnd = aPPDrawHd.GetRecEndFilePos(); DffRecordHeader aEscherF002Hd; if ( SeekToRec( rStCtrl, DFF_msofbtDgContainer, nPPDrawEnd, &aEscherF002Hd ) ) { sal_uInt32 nEscherF002End = aEscherF002Hd.GetRecEndFilePos(); DffRecordHeader aEscherObjListHd; if ( SeekToRec( rStCtrl, DFF_msofbtSpgrContainer, nEscherF002End, &aEscherObjListHd ) ) { sal_uInt32 nObjCount = 0; auto nListEndRecPos = SanitizeEndPos(rStCtrl, aEscherObjListHd.GetRecEndFilePos()); while( ( rStCtrl.GetError() == ERRCODE_NONE ) && ( rStCtrl.Tell() < nListEndRecPos ) ) { DffRecordHeader aHd2; ReadDffRecordHeader( rStCtrl, aHd2 ); if ( ( aHd2.nRecType == DFF_msofbtSpContainer ) || ( aHd2.nRecType == DFF_msofbtSpgrContainer ) ) { if ( nObjCount++ ) // skipping the first object { ::tools::Rectangle aEmpty; if (!aHd2.SeekToBegOfRecord(rStCtrl)) break; SdrObject* pImpObj = ImportObj( rStCtrl, aProcessData, aEmpty, aEmpty, /*nCalledByGroup*/0, /*pShapeId*/ nullptr ); if ( pImpObj ) { pImpObj->SetLayer( mnBackgroundObjectsLayerID ); pMPage->NbcInsertObject( pImpObj ); } } } if (!aHd2.SeekToEndOfRecord(rStCtrl)) break; } } } } } break; case PPT_PST_ProgTags : { DffRecordHeader aProgTagHd; if ( SeekToContentOfProgTag( 10, rStCtrl, aPageHd, aProgTagHd ) ) { auto nTagEndRecPos = SanitizeEndPos(rStCtrl, aProgTagHd.GetRecEndFilePos()); while ( ( rStCtrl.GetError() == ERRCODE_NONE ) && ( rStCtrl.Tell() < nTagEndRecPos ) ) { DffRecordHeader aProgTagContentHd; ReadDffRecordHeader( rStCtrl, aProgTagContentHd ); switch( aProgTagContentHd.nRecType ) { case DFF_msofbtAnimGroup : { css::uno::Reference< css::drawing::XDrawPage > xPage( pMPage->getUnoPage(), css::uno::UNO_QUERY ); ppt::AnimationImporter aImporter( this, rStCtrl ); bNewAnimationsUsed = aImporter.import( xPage, aProgTagContentHd ) > 0; } break; } if (!aProgTagContentHd.SeekToEndOfRecord(rStCtrl)) break; } } } break; } bool bSuccess = aHd.SeekToEndOfRecord(rStCtrl); if (!bSuccess) { SAL_WARN("filter.ms", "Could not seek to end of record"); break; } } } rStCtrl.Seek( nOldFPos ); ImportPageEffect( pMPage, bNewAnimationsUsed ); // background object pObj = pMPage->GetObj( 0 ); if ( pObj && pObj->GetObjIdentifier() == OBJ_RECT ) { if ( pMPage->GetPageKind() == PageKind::Standard ) { // transform data from imported background object to new form // and delete the object. It was used as container to transport // the attributes of the MasterPage background fill SfxStyleSheet* pSheet = pMPage->GetStyleSheetForMasterPageBackground(); if(pSheet) { // if we have a StyleSheet (for Masterpages), set attributes there and use it pSheet->GetItemSet().ClearItem(); pSheet->GetItemSet().Put(pObj->GetMergedItemSet()); pMPage->getSdrPageProperties().ClearItem(); pMPage->getSdrPageProperties().SetStyleSheet(pSheet); } else { // without StyleSheet, set attributes directly. This // should not be done at all and is an error (will be asserted by SdrPage) pMPage->getSdrPageProperties().ClearItem(); pMPage->getSdrPageProperties().PutItemSet(pObj->GetMergedItemSet()); } pMPage->RemoveObject(pObj->GetOrdNum()); SdrObject::Free(pObj); } } } } if (xStbMgr) xStbMgr->SetState( nImportedPages++ ); } // importing slide pages { sal_uInt32 nOldFPos = rStCtrl.Tell(); PptPageKind ePageKind = m_eCurrentPageKind; sal_uInt16 nPageNum = m_nCurrentPageNum; SdPage* pHandoutPage = static_cast(MakeBlancPage( false )); pHandoutPage->SetPageKind( PageKind::Handout ); pSdrModel->InsertPage( pHandoutPage ); sal_uInt16 nPageCnt = GetPageCount(); if ( nPageCnt ) { for ( sal_uInt16 nPage = 0; nPage < nPageCnt; nPage++ ) { mePresChange = PRESCHANGE_SEMIAUTO; SetPageNum( nPage ); SdPage* pPage = static_cast(MakeBlancPage( false )); PptSlidePersistEntry* pMasterPersist = nullptr; if ( HasMasterPage( nPage ) ) // try to get the LayoutName from the masterpage { sal_uInt16 nMasterNum = GetMasterPageIndex( m_nCurrentPageNum, m_eCurrentPageKind ); pPage->TRG_SetMasterPage(*pSdrModel->GetMasterPage(nMasterNum)); PptSlidePersistList* pPageList = GetPageList( PPT_MASTERPAGE ); if ( pPageList && nMasterNum < pPageList->size() ) pMasterPersist = &(*pPageList)[ nMasterNum ]; pPage->SetLayoutName(static_cast(pPage->TRG_GetMasterPage()).GetLayoutName()); } pPage->SetPageKind( PageKind::Standard ); pSdrModel->InsertPage( pPage ); // SJ: #i29625# because of form controls, the ImportPage( pPage, pMasterPersist ); // page must be inserted before importing SetHeaderFooterPageSettings( pPage, pMasterPersist ); // CWS preseng01: pPage->SetPageKind( PageKind::Standard ); DffRecordHeader aPageHd; if ( SeekToCurrentPage( &aPageHd ) ) { bool bNewAnimationsUsed = false; aPageHd.SeekToContent( rStCtrl ); auto nEndRecPos = SanitizeEndPos(rStCtrl, aPageHd.GetRecEndFilePos()); while ( ( rStCtrl.GetError() == ERRCODE_NONE ) && ( rStCtrl.Tell() < nEndRecPos ) ) { DffRecordHeader aHd; ReadDffRecordHeader( rStCtrl, aHd ); switch ( aHd.nRecType ) { case PPT_PST_ProgTags : { DffRecordHeader aProgTagHd; if ( SeekToContentOfProgTag( 10, rStCtrl, aPageHd, aProgTagHd ) ) { auto nHdEndRecPos = SanitizeEndPos(rStCtrl, aProgTagHd.GetRecEndFilePos()); while ( ( rStCtrl.GetError() == ERRCODE_NONE ) && ( rStCtrl.Tell() < nHdEndRecPos ) ) { DffRecordHeader aProgTagContentHd; ReadDffRecordHeader( rStCtrl, aProgTagContentHd ); switch( aProgTagContentHd.nRecType ) { case DFF_msofbtAnimGroup : { css::uno::Reference< css::drawing::XDrawPage > xPage( pPage->getUnoPage(), css::uno::UNO_QUERY ); ppt::AnimationImporter aImporter( this, rStCtrl ); bNewAnimationsUsed = aImporter.import( xPage, aProgTagContentHd ) > 0; } break; case PPT_PST_HashCodeAtom : // ??? break; case PPT_PST_SlideTime10Atom : // ??? don't know, this atom is always 8 bytes big break; // and is appearing in nearly every l10 progtag } if (!aProgTagContentHd.SeekToEndOfRecord(rStCtrl)) break; } } } break; case PPT_PST_HeadersFooters : case PPT_PST_PPDrawing : default: break; } if (!aHd.SeekToEndOfRecord(rStCtrl)) break; } ImportPageEffect( pPage, bNewAnimationsUsed ); } // creating the corresponding note page m_eCurrentPageKind = PPT_NOTEPAGE; SdPage* pNotesPage = static_cast(MakeBlancPage( false )); sal_uInt16 nNotesMasterNum = GetMasterPageIndex( nPage ) + 1; sal_uInt32 nNotesPageId = GetNotesPageId( nPage ); if ( nNotesPageId ) { nImportedPages++; sal_uInt16 nNotesPageIndex = m_pNotePages->FindPage( nNotesPageId ); if ( nNotesPageIndex == PPTSLIDEPERSIST_ENTRY_NOTFOUND ) nNotesPageIndex = 0; SetPageNum( nNotesPageIndex, PPT_NOTEPAGE ); PptSlidePersistEntry* pMasterPersist2 = nullptr; if ( HasMasterPage( nNotesPageIndex, PPT_NOTEPAGE ) ) // try to get the LayoutName from the masterpage { pNotesPage->TRG_SetMasterPage(*pSdrModel->GetMasterPage(nNotesMasterNum)); PptSlidePersistList* pPageList = GetPageList( PPT_MASTERPAGE ); if ( pPageList && nNotesMasterNum < pPageList->size() ) pMasterPersist2 = &(*pPageList)[ nNotesMasterNum ]; pNotesPage->SetLayoutName( static_cast(pNotesPage->TRG_GetMasterPage()).GetLayoutName() ); } pNotesPage->SetPageKind( PageKind::Notes ); pNotesPage->TRG_SetMasterPage(*pSdrModel->GetMasterPage(nNotesMasterNum)); pSdrModel->InsertPage( pNotesPage ); // SJ: #i29625# because of form controls, the ImportPage( pNotesPage, pMasterPersist2 ); // page must be inserted before importing SetHeaderFooterPageSettings( pNotesPage, pMasterPersist2 ); pNotesPage->SetAutoLayout( AUTOLAYOUT_NOTES ); } else { pNotesPage->SetPageKind( PageKind::Notes ); pNotesPage->TRG_SetMasterPage(*pSdrModel->GetMasterPage(nNotesMasterNum)); pNotesPage->SetAutoLayout( AUTOLAYOUT_NOTES, true ); pSdrModel->InsertPage( pNotesPage ); SdrObject* pPageObj = pNotesPage->GetPresObj( PRESOBJ_PAGE ); if ( pPageObj ) static_cast(pPageObj)->SetReferencedPage(pSdrModel->GetPage(( nPage << 1 ) + 1)); } if (xStbMgr) xStbMgr->SetState( nImportedPages++ ); } } else { // that can happen by document templates m_eCurrentPageKind = PPT_SLIDEPAGE; SdrPage* pPage = MakeBlancPage( false ); pSdrModel->InsertPage( pPage ); // #i37397#, trying to set the title master for the first page sal_uInt16 nMaster, nMasterCount = pSdrModel->GetMasterPageCount(); SdPage* pFoundMaster = nullptr; for ( nMaster = 1; nMaster < nMasterCount; nMaster++ ) { SdPage* pMaster = static_cast( pSdrModel->GetMasterPage( nMaster ) ); if ( pMaster->GetPageKind() == PageKind::Standard ) { SetPageNum( nMaster, PPT_MASTERPAGE ); if ( !pFoundMaster ) pFoundMaster = pMaster; else if ( GetSlideLayoutAtom()->eLayout == PptSlideLayout::TITLEMASTERSLIDE ) pFoundMaster = pMaster; if ( GetSlideLayoutAtom()->eLayout == PptSlideLayout::TITLEMASTERSLIDE ) break; } } if ( pFoundMaster ) { static_cast(pPage)->TRG_SetMasterPage( *pFoundMaster ); static_cast(pPage)->SetLayoutName( pFoundMaster->GetLayoutName() ); } static_cast(pPage)->SetAutoLayout( AUTOLAYOUT_TITLE, true, true ); m_eCurrentPageKind = PPT_NOTEPAGE; SdrPage* pNPage = MakeBlancPage( false ); pSdrModel->InsertPage( pNPage ); } SetPageNum( nPageNum, ePageKind ); rStCtrl.Seek( nOldFPos ); } // create handout and note pages m_bOk = mpDoc->CreateMissingNotesAndHandoutPages(); if ( m_bOk ) { for ( sal_uInt16 i = 0; i < mpDoc->GetSdPageCount( PageKind::Standard ); i++ ) { // set AutoLayout SetPageNum( i ); SdPage* pPage = mpDoc->GetSdPage( i, PageKind::Standard ); AutoLayout eAutoLayout = AUTOLAYOUT_NONE; const PptSlideLayoutAtom* pSlideLayout = GetSlideLayoutAtom(); if ( pSlideLayout ) { switch ( pSlideLayout->eLayout ) // presentation layout for standard pages { case PptSlideLayout::TITLEANDBODYSLIDE : { eAutoLayout = AUTOLAYOUT_TITLE_CONTENT; PptPlaceholder nID1 = pSlideLayout->aPlaceholderId[ 1 ]; switch ( nID1 ) { case PptPlaceholder::BODY : eAutoLayout = AUTOLAYOUT_TITLE_CONTENT; break; case PptPlaceholder::TABLE : eAutoLayout = AUTOLAYOUT_TAB; break; case PptPlaceholder::ORGANISZATIONCHART : eAutoLayout = AUTOLAYOUT_ORG; break; case PptPlaceholder::GRAPH : eAutoLayout = AUTOLAYOUT_CHART; break; case PptPlaceholder::OBJECT : eAutoLayout = AUTOLAYOUT_OBJ; break; case PptPlaceholder::VERTICALTEXTBODY : eAutoLayout = AUTOLAYOUT_TITLE_VCONTENT; break; default: break; } } break; case PptSlideLayout::TWOCOLUMNSANDTITLE : { eAutoLayout = AUTOLAYOUT_TITLE_2CONTENT; PptPlaceholder nID1 = pSlideLayout->aPlaceholderId[ 1 ]; PptPlaceholder nID2 = pSlideLayout->aPlaceholderId[ 2 ]; if ( nID1 == PptPlaceholder::BODY && nID2 == PptPlaceholder::GRAPH ) eAutoLayout = AUTOLAYOUT_TEXTCHART; else if ( nID1 == PptPlaceholder::GRAPH && nID2 == PptPlaceholder::BODY ) eAutoLayout = AUTOLAYOUT_CHARTTEXT; else if ( nID1 == PptPlaceholder::BODY && nID2 == PptPlaceholder::CLIPART ) eAutoLayout = AUTOLAYOUT_TEXTCLIP; else if ( nID1 == PptPlaceholder::CLIPART && nID2 == PptPlaceholder::BODY ) eAutoLayout = AUTOLAYOUT_CLIPTEXT; else if ( nID1 == PptPlaceholder::CLIPART && nID2 == PptPlaceholder::VERTICALTEXTBODY ) eAutoLayout = AUTOLAYOUT_TITLE_2VTEXT; else if ( ( nID1 == PptPlaceholder::BODY ) && ( ( nID2 == PptPlaceholder::OBJECT ) || ( nID2 == PptPlaceholder::MEDIACLIP ) ) ) eAutoLayout = AUTOLAYOUT_TEXTOBJ; else if ( ( nID2 == PptPlaceholder::BODY ) && ( ( nID1 == PptPlaceholder::OBJECT ) || ( nID1 == PptPlaceholder::MEDIACLIP ) ) ) eAutoLayout = AUTOLAYOUT_OBJTEXT; else if ( ( nID1 == PptPlaceholder::OBJECT ) && ( nID2 == PptPlaceholder::OBJECT ) ) eAutoLayout = AUTOLAYOUT_OBJ; } break; case PptSlideLayout::TWOROWSANDTITLE : { eAutoLayout = AUTOLAYOUT_TITLE_2CONTENT; PptPlaceholder nID1 = pSlideLayout->aPlaceholderId[ 1 ]; PptPlaceholder nID2 = pSlideLayout->aPlaceholderId[ 2 ]; if ( nID1 == PptPlaceholder::BODY && nID2 == PptPlaceholder::OBJECT ) eAutoLayout = AUTOLAYOUT_TEXTOVEROBJ; else if ( nID1 == PptPlaceholder::OBJECT && nID2 == PptPlaceholder::BODY ) eAutoLayout = AUTOLAYOUT_TITLE_CONTENT_OVER_CONTENT; } break; case PptSlideLayout::TITLESLIDE : eAutoLayout = AUTOLAYOUT_TITLE; break; case PptSlideLayout::ONLYTITLE : eAutoLayout = AUTOLAYOUT_TITLE_ONLY; break; case PptSlideLayout::RIGHTCOLUMN2ROWS : eAutoLayout = AUTOLAYOUT_TITLE_CONTENT_2CONTENT; break; case PptSlideLayout::LEFTCOLUMN2ROWS : eAutoLayout = AUTOLAYOUT_TITLE_2CONTENT_CONTENT; break; case PptSlideLayout::TOPROW2COLUMN : eAutoLayout = AUTOLAYOUT_TITLE_2CONTENT_OVER_CONTENT; break; case PptSlideLayout::FOUROBJECTS : eAutoLayout = AUTOLAYOUT_TITLE_4CONTENT; break; case PptSlideLayout::BIGOBJECT : eAutoLayout = AUTOLAYOUT_OBJ; break; case PptSlideLayout::TITLERIGHTBODYLEFT : eAutoLayout = AUTOLAYOUT_VTITLE_VCONTENT; break; case PptSlideLayout::TITLERIGHT2BODIESLEFT : eAutoLayout = AUTOLAYOUT_VTITLE_VCONTENT_OVER_VCONTENT; break; case PptSlideLayout::BOTTOMROW2COLUMNS : case PptSlideLayout::BLANKSLIDE : case PptSlideLayout::MASTERSLIDE : // layout of the standard and title master page case PptSlideLayout::TITLEMASTERSLIDE : case PptSlideLayout::MASTERNOTES : // layout of the note master page case PptSlideLayout::NOTESTITLEBODY : // presentation layout for note pages case PptSlideLayout::HANDOUTLAYOUT : // presentation layout for handout eAutoLayout = AUTOLAYOUT_NONE; break; } if ( eAutoLayout != AUTOLAYOUT_NONE ) pPage->SetAutoLayout( eAutoLayout ); } } // handout master page: auto layout SdPage* pHandoutMPage = mpDoc->GetMasterSdPage( 0, PageKind::Handout ); pHandoutMPage->SetAutoLayout( AUTOLAYOUT_HANDOUT6, true, true ); } sal_uInt32 nSlideCount = GetPageCount(); for ( sal_uInt32 i = 0; ( i < nSlideCount) && ( i < maSlideNameList.size() ); i++ ) { SdPage* pPage = mpDoc->GetSdPage( i, PageKind::Standard ); OUString &aName = maSlideNameList[ i ]; if ( pPage ) { if ( !aName.isEmpty() ) pPage->SetName( aName ); else aName = pPage->GetName(); } } if ( mbDocumentFound ) { mpDoc->SetSummationOfParagraphs(); if ( pDocShell ) { ::sd::FrameView* pFrameView = mpDoc->GetFrameView( 0 ); if ( !pFrameView ) { std::vector> &rViews = mpDoc->GetFrameViewList(); pFrameView = new ::sd::FrameView( mpDoc ); rViews.push_back( std::unique_ptr(pFrameView) ); } sal_uInt16 nSelectedPage = 0; PageKind ePageKind = PageKind::Standard; EditMode eEditMode = EditMode::Page; switch ( m_aUserEditAtom.eLastViewType ) { case PptViewTypeEnum::Outline: { SfxItemSet* pSet = mrMed.GetItemSet(); if ( pSet ) pSet->Put( SfxUInt16Item( SID_VIEW_ID, 3 ) ); } break; case PptViewTypeEnum::SlideSorter: { SfxItemSet* pSet = mrMed.GetItemSet(); if ( pSet ) pSet->Put( SfxUInt16Item( SID_VIEW_ID, 2 ) ); } break; case PptViewTypeEnum::TitleMaster: nSelectedPage = 1; [[fallthrough]]; case PptViewTypeEnum::SlideMaster: { ePageKind = PageKind::Standard; eEditMode = EditMode::MasterPage; } break; case PptViewTypeEnum::NotesMaster: eEditMode = EditMode::MasterPage; [[fallthrough]]; case PptViewTypeEnum::Notes: ePageKind = PageKind::Notes; break; case PptViewTypeEnum::Handout: ePageKind = PageKind::Handout; break; default : case PptViewTypeEnum::Slide: break; } pFrameView->SetPageKind( ePageKind ); pFrameView->SetSelectedPage( nSelectedPage ); pFrameView->SetViewShEditMode( eEditMode ); } DffRecordHeader aCustomShowHeader; // read and set custom show rStCtrl.Seek( maDocHd.GetRecBegFilePos() + 8 ); if ( SeekToRec( rStCtrl, PPT_PST_NamedShows, maDocHd.GetRecEndFilePos(), &aCustomShowHeader ) ) { DffRecordHeader aCuHeader; while( SeekToRec( rStCtrl, PPT_PST_NamedShow, aCustomShowHeader.GetRecEndFilePos(), &aCuHeader ) ) { DffRecordHeader aContent; if ( SeekToRec( rStCtrl, PPT_PST_CString, aCuHeader.GetRecEndFilePos(), &aContent ) ) { OUString aCuShow; aContent.SeekToBegOfRecord( rStCtrl ); if ( ReadString( aCuShow ) ) { if ( SeekToRec( rStCtrl, PPT_PST_NamedShowSlides, aCuHeader.GetRecEndFilePos(), &aContent ) ) { PptSlidePersistList* pPageList = GetPageList( PPT_SLIDEPAGE ); const auto nRemainingSize = rStCtrl.remainingSize(); sal_uInt32 nBCount = aContent.nRecLen; if (nBCount > nRemainingSize) { SAL_WARN("filter.ms", "page number data len longer than remaining stream size"); nBCount = nRemainingSize; } sal_uInt32 nSCount = nBCount >> 2; if ( pPageList && nSCount ) { SdCustomShowList* pList = mpDoc->GetCustomShowList( true ); if ( pList ) { std::unique_ptr pSdCustomShow(new SdCustomShow); pSdCustomShow->SetName( aCuShow ); sal_uInt32 nFound = 0; for ( sal_uInt32 nS = 0; nS < nSCount; nS++ ) { sal_uInt32 nPageNumber; rStCtrl.ReadUInt32( nPageNumber ); sal_uInt16 nPage = pPageList->FindPage( nPageNumber ); if ( nPage != PPTSLIDEPERSIST_ENTRY_NOTFOUND ) { SdPage* pPage = mpDoc->GetSdPage( nPage, PageKind::Standard ); if ( pPage ) { pSdCustomShow->PagesVector().push_back( pPage ); nFound++; } } } if ( nFound ) pList->push_back( std::move(pSdCustomShow) ); } } } } } } } // this is defaulted, maybe there is no SSDocInfoAtom OUStringBuffer aCustomShow; sal_uInt32 nFlags = 1; // Bit 0: Auto advance sal_uInt16 nStartSlide = 0; // read the pres. configuration rStCtrl.Seek( maDocHd.GetRecBegFilePos() + 8 ); if ( SeekToRec( rStCtrl, PPT_PST_SSDocInfoAtom, maDocHd.GetRecEndFilePos(), &aCustomShowHeader ) ) { sal_uInt32 nPenColor = 0x1000000; sal_Int32 nRestartTime = 0x7fffffff; sal_Int16 nEndSlide = 0; rStCtrl.ReadUInt32( nPenColor ) .ReadInt32( nRestartTime ) .ReadUInt16( nStartSlide ) .ReadInt16( nEndSlide ); sal_Unicode nChar; for ( sal_uInt32 i2 = 0; i2 < 32; i2++ ) { rStCtrl.ReadUtf16( nChar ); if ( nChar ) aCustomShow.append( nChar ); else { rStCtrl.SeekRel( ( 31 - i2 ) << 1 ); break; } } rStCtrl.ReadUInt32( nFlags ); } // set the current custom show if ( !aCustomShow.isEmpty() ) { SdCustomShowList* pList = mpDoc->GetCustomShowList(); if ( pList ) { SdCustomShow* pPtr = nullptr; OUString aCustomShowStr = aCustomShow.makeStringAndClear(); for( pPtr = pList->First(); pPtr; pPtr = pList->Next() ) { if ( pPtr->GetName() == aCustomShowStr ) break; } if ( !pPtr ) pList->First(); } } sd::PresentationSettings& rPresSettings = mpDoc->getPresentationSettings(); rPresSettings.mbManual = ( nFlags & 1 ) == 0; rPresSettings.mbAnimationAllowed = ( nFlags & 2 ) == 0; rPresSettings.mbAll = ( nFlags & 4 ) == 0; rPresSettings.mbCustomShow = ( nFlags & 8 ) != 0; rPresSettings.mbEndless = ( nFlags & 0x80 ) != 0; rPresSettings.mbFullScreen = ( nFlags & 0x10 ) == 0; if ( nStartSlide && ( nStartSlide <= GetPageCount() ) ) { SdPage* pPage = mpDoc->GetSdPage( nStartSlide - 1, PageKind::Standard ); if ( pPage ) rPresSettings.maPresPage = pPage->GetName(); } } xStbMgr.reset(); // read DocumentProperties uno::Reference xDPS( mpDoc->GetObjectShell()->GetModel(), uno::UNO_QUERY_THROW); uno::Reference xDocProps = xDPS->getDocumentProperties(); sfx2::LoadOlePropertySet(xDocProps, &mrStorage); xDocProps->setTemplateName(OUString()); pSdrModel->setLock(bWasLocked); pSdrModel->EnableUndo(bSavedUndoEnabled); return m_bOk; } void ImplSdPPTImport::SetHeaderFooterPageSettings( SdPage* pPage, const PptSlidePersistEntry* pMasterPersist ) { sal_uInt32 i; PptSlidePersistList* pList = GetPageList( m_eCurrentPageKind ); if ( ( !pList ) || ( pList->size() <= m_nCurrentPageNum ) ) return; PptSlidePersistEntry& rSlidePersist = (*pList)[ m_nCurrentPageNum ]; HeaderFooterEntry* pHFE = rSlidePersist.xHeaderFooterEntry.get(); if (!pHFE) return; for ( i = 0; i < 4; i++ ) { bool bVisible = pHFE->IsToDisplay( i ); if ( ( m_eCurrentPageKind == PPT_SLIDEPAGE ) && ( rSlidePersist.aSlideAtom.aLayout.eLayout == PptSlideLayout::TITLESLIDE ) && ( aDocAtom.bTitlePlaceholdersOmitted ) ) { bVisible = false; } if ( bVisible && pMasterPersist ) { sal_uInt32 nPosition = pHFE->NeedToImportInstance( i, rSlidePersist ); if ( nPosition ) { ::tools::Rectangle aEmpty; bVisible = false; rStCtrl.Seek( nPosition ); ProcessData aProcessData( rSlidePersist, SdPageCapsule(pPage) ); SdrObject* pObj = ImportObj( rStCtrl, aProcessData, aEmpty, aEmpty, /*nCalledByGroup*/0, /*pShapeId*/nullptr ); if ( pObj ) pPage->NbcInsertObject( pObj, 0 ); } } OUString aPlaceHolderString = pHFE->pPlaceholder[ i ]; sd::HeaderFooterSettings rHeaderFooterSettings( pPage->getHeaderFooterSettings() ); switch( i ) { case 0 : { rHeaderFooterSettings.mbDateTimeVisible = bVisible; rHeaderFooterSettings.mbDateTimeIsFixed = ( pHFE->nAtom & 0x20000 ) == 0; rHeaderFooterSettings.maDateTimeText = aPlaceHolderString; SvxDateFormat eDateFormat; SvxTimeFormat eTimeFormat; PPTFieldEntry::GetDateTime( pHFE->nAtom & 0xff, eDateFormat, eTimeFormat ); rHeaderFooterSettings.meDateFormat = eDateFormat; rHeaderFooterSettings.meTimeFormat = eTimeFormat; } break; case 1 : { rHeaderFooterSettings.mbHeaderVisible = bVisible; rHeaderFooterSettings.maHeaderText = aPlaceHolderString; } break; case 2 : { rHeaderFooterSettings.mbFooterVisible = bVisible; rHeaderFooterSettings.maFooterText = aPlaceHolderString; } break; case 3 : { rHeaderFooterSettings.mbSlideNumberVisible = bVisible; } break; } pPage->setHeaderFooterSettings( rHeaderFooterSettings ); } } namespace { // Import of pages struct Ppt97AnimationStlSortHelper { bool operator()( const std::pair< SdrObject*, Ppt97AnimationPtr >& p1, const std::pair< SdrObject*, Ppt97AnimationPtr >& p2 ); }; } bool Ppt97AnimationStlSortHelper::operator()( const std::pair< SdrObject*, Ppt97AnimationPtr >& p1, const std::pair< SdrObject*, Ppt97AnimationPtr >& p2 ) { if( !p1.second.get() || !p2.second.get() ) return p1.second.get() < p2.second.get(); if( *p1.second < *p2.second ) return true; if( *p1.second > *p2.second ) return false; return p1.first->GetOrdNum() < p2.first->GetOrdNum(); } void ImplSdPPTImport::ImportPageEffect( SdPage* pPage, const bool bNewAnimationsUsed ) { sal_uLong nOldFilePos = rStCtrl.Tell(); // set PageKind at page (up to now only PageKind::Standard or PageKind::Notes) if ( pPage->GetPageKind() == PageKind::Standard ) { PptSlidePersistList* pPersistList = GetPageList( m_eCurrentPageKind ); PptSlidePersistEntry* pActualSlidePersist = ( pPersistList && ( m_nCurrentPageNum < pPersistList->size() ) ) ? &(*pPersistList)[ m_nCurrentPageNum ] : nullptr; if ( pActualSlidePersist && ( m_eCurrentPageKind == PPT_SLIDEPAGE ) ) { if ( ! ( pActualSlidePersist->aSlideAtom.nFlags & 1 ) ) // do not follow master objects ? { if(pPage->TRG_HasMasterPage()) { SdrLayerIDSet aVisibleLayers = pPage->TRG_GetMasterPageVisibleLayers(); aVisibleLayers.Set(mnBackgroundObjectsLayerID, false); pPage->TRG_SetMasterPageVisibleLayers(aVisibleLayers); } } } DffRecordHeader aPageRecHd; if ( SeekToCurrentPage( &aPageRecHd ) ) { sal_uLong nPageRecEnd = SanitizeEndPos(rStCtrl, aPageRecHd.GetRecEndFilePos()); bool bTryTwice = ( m_eCurrentPageKind == PPT_SLIDEPAGE ); bool bSSSlideInfoAtom = false; while ( true ) { while ( ( rStCtrl.GetError() == ERRCODE_NONE ) && ( rStCtrl.Tell() < nPageRecEnd ) ) { DffRecordHeader aHd; ReadDffRecordHeader( rStCtrl, aHd ); switch ( aHd.nRecType ) { case PPT_PST_SSSlideInfoAtom: { bSSSlideInfoAtom = true; if ( m_eCurrentPageKind == PPT_MASTERPAGE ) { if ( pActualSlidePersist ) pActualSlidePersist->aPersistAtom.nReserved = aHd.GetRecBegFilePos(); } else { sal_Int8 nDirection, nTransitionType, nByteDummy, nSpeed; sal_Int16 nBuildFlags; sal_Int32 nSlideTime, nSoundRef; rStCtrl.ReadInt32( nSlideTime ) // time to show (in Ticks) .ReadInt32( nSoundRef ) // Index of SoundCollection .ReadSChar( nDirection ) // direction of fade effect .ReadSChar( nTransitionType ) // fade effect .ReadInt16( nBuildFlags ) // Buildflags (s.u.) .ReadSChar( nSpeed ) // speed (slow, medium, fast) .ReadSChar( nByteDummy ).ReadSChar( nByteDummy ).ReadSChar( nByteDummy ); switch ( nTransitionType ) { case PPT_TRANSITION_TYPE_BLINDS : { if ( nDirection == 0 ) pPage->SetFadeEffect( css::presentation::FadeEffect_VERTICAL_STRIPES ); // fade vertical else if ( nDirection == 1 ) pPage->SetFadeEffect( css::presentation::FadeEffect_HORIZONTAL_STRIPES ); // fade horizontal } break; case PPT_TRANSITION_TYPE_CHECKER : { if ( nDirection == 0 ) pPage->SetFadeEffect( css::presentation::FadeEffect_HORIZONTAL_CHECKERBOARD ); // fade vertical with offset ?? else if ( nDirection == 1 ) pPage->SetFadeEffect( css::presentation::FadeEffect_VERTICAL_CHECKERBOARD ); // fade horizontal with offset ?? } break; case PPT_TRANSITION_TYPE_COVER : { if ( nDirection == 0 ) pPage->SetFadeEffect( css::presentation::FadeEffect_MOVE_FROM_RIGHT ); // overlay from right else if ( nDirection == 1 ) pPage->SetFadeEffect( css::presentation::FadeEffect_MOVE_FROM_BOTTOM ); // overlay from bottom else if ( nDirection == 2 ) pPage->SetFadeEffect( css::presentation::FadeEffect_MOVE_FROM_LEFT ); // overlay from left else if ( nDirection == 3 ) pPage->SetFadeEffect( css::presentation::FadeEffect_MOVE_FROM_TOP ); // overlay from top else if ( nDirection == 4 ) pPage->SetFadeEffect( css::presentation::FadeEffect_MOVE_FROM_LOWERRIGHT ); // overlay from bottom right ?? else if ( nDirection == 5 ) pPage->SetFadeEffect( css::presentation::FadeEffect_MOVE_FROM_LOWERLEFT ); // overlay from bottom left ?? else if ( nDirection == 6 ) pPage->SetFadeEffect( css::presentation::FadeEffect_MOVE_FROM_UPPERRIGHT ); // overlay from top right else if ( nDirection == 7 ) pPage->SetFadeEffect( css::presentation::FadeEffect_MOVE_FROM_UPPERLEFT ); // overlay from top left ?? } break; case PPT_TRANSITION_TYPE_NONE : { if ( nBuildFlags ) { if ( nDirection == 0 ) pPage->SetFadeEffect( css::presentation::FadeEffect_NONE ); // direct else if ( nDirection == 1 ) { pPage->setTransitionType( animations::TransitionType::BARWIPE ); pPage->setTransitionSubtype( animations::TransitionSubType::FADEOVERCOLOR ); pPage->setTransitionFadeColor( 0 ); } } else pPage->setTransitionType( 0 ); } break; case PPT_TRANSITION_TYPE_DISSOLVE : pPage->SetFadeEffect(css::presentation::FadeEffect_DISSOLVE); // dissolve break; case PPT_TRANSITION_TYPE_RANDOM_BARS : { if ( nDirection == 0 ) pPage->SetFadeEffect( css::presentation::FadeEffect_HORIZONTAL_LINES ); // horizontal lines else if ( nDirection == 1 ) pPage->SetFadeEffect( css::presentation::FadeEffect_VERTICAL_LINES ); // vertical lines } break; case PPT_TRANSITION_TYPE_SPLIT : { if ( nDirection == 0 ) pPage->SetFadeEffect( css::presentation::FadeEffect_OPEN_VERTICAL ); // open horizontal ?? else if ( nDirection == 1 ) pPage->SetFadeEffect( css::presentation::FadeEffect_CLOSE_VERTICAL ); // close horizontal ?? else if ( nDirection == 2 ) pPage->SetFadeEffect( css::presentation::FadeEffect_OPEN_HORIZONTAL ); // open vertical ?? else if ( nDirection == 3 ) pPage->SetFadeEffect( css::presentation::FadeEffect_CLOSE_HORIZONTAL ); // close vertical ?? } break; case PPT_TRANSITION_TYPE_STRIPS : { if ( nDirection == 4 ) pPage->SetFadeEffect( css::presentation::FadeEffect_FADE_FROM_LOWERRIGHT ); // diagonal to top left else if ( nDirection == 5 ) pPage->SetFadeEffect( css::presentation::FadeEffect_FADE_FROM_LOWERLEFT ); // diagonal to top right else if ( nDirection == 6 ) pPage->SetFadeEffect( css::presentation::FadeEffect_FADE_FROM_UPPERRIGHT ); // diagonal to bottom left else if ( nDirection == 7 ) pPage->SetFadeEffect( css::presentation::FadeEffect_FADE_FROM_UPPERLEFT ); // diagonal to bottom right } break; case PPT_TRANSITION_TYPE_PULL : { if ( nDirection == 0 ) pPage->SetFadeEffect( css::presentation::FadeEffect_UNCOVER_TO_LEFT ); // uncover to left else if ( nDirection == 1 ) pPage->SetFadeEffect( css::presentation::FadeEffect_UNCOVER_TO_TOP ); // uncover to top else if ( nDirection == 2 ) pPage->SetFadeEffect( css::presentation::FadeEffect_UNCOVER_TO_RIGHT ); // uncover to right else if ( nDirection == 3 ) pPage->SetFadeEffect( css::presentation::FadeEffect_UNCOVER_TO_BOTTOM ); // uncover to bottom else if ( nDirection == 4 ) pPage->SetFadeEffect( css::presentation::FadeEffect_UNCOVER_TO_UPPERLEFT ); // uncover to top left else if ( nDirection == 5 ) pPage->SetFadeEffect( css::presentation::FadeEffect_UNCOVER_TO_UPPERRIGHT ); // uncover to top right else if ( nDirection == 6 ) pPage->SetFadeEffect( css::presentation::FadeEffect_UNCOVER_TO_LOWERLEFT ); // uncover to bottom left else if ( nDirection == 7 ) pPage->SetFadeEffect( css::presentation::FadeEffect_UNCOVER_TO_LOWERRIGHT ); // uncover to bottom right } break; case PPT_TRANSITION_TYPE_WIPE : { if ( nDirection == 0 ) pPage->SetFadeEffect( css::presentation::FadeEffect_FADE_FROM_RIGHT ); // roll from right else if ( nDirection == 1 ) pPage->SetFadeEffect( css::presentation::FadeEffect_FADE_FROM_BOTTOM ); // roll from bottom else if ( nDirection == 2 ) pPage->SetFadeEffect( css::presentation::FadeEffect_FADE_FROM_LEFT ); // roll from left else if ( nDirection == 3 ) pPage->SetFadeEffect( css::presentation::FadeEffect_FADE_FROM_TOP ); // roll from top } break; case PPT_TRANSITION_TYPE_RANDOM : pPage->SetFadeEffect( css::presentation::FadeEffect_RANDOM ); // automatic break; case PPT_TRANSITION_TYPE_FADE : { pPage->setTransitionType( animations::TransitionType::FADE ); pPage->setTransitionSubtype( animations::TransitionSubType::FADEOVERCOLOR ); pPage->setTransitionFadeColor( 0 ); } break; case PPT_TRANSITION_TYPE_ZOOM : { if ( nDirection == 0 ) pPage->SetFadeEffect( css::presentation::FadeEffect_FADE_FROM_CENTER ); // fade from center else if ( nDirection == 1 ) pPage->SetFadeEffect( css::presentation::FadeEffect_FADE_TO_CENTER ); // fade from the outside } break; case PPT_TRANSITION_TYPE_DIAMOND : { pPage->setTransitionType( animations::TransitionType::IRISWIPE ); pPage->setTransitionSubtype( animations::TransitionSubType::DIAMOND ); } break; case PPT_TRANSITION_TYPE_PLUS : { pPage->setTransitionType( animations::TransitionType::FOURBOXWIPE ); pPage->setTransitionSubtype( animations::TransitionSubType::CORNERSOUT ); } break; case PPT_TRANSITION_TYPE_CIRCLE : { pPage->setTransitionType( animations::TransitionType::ELLIPSEWIPE ); pPage->setTransitionSubtype( animations::TransitionSubType::CIRCLE ); } break; case PPT_TRANSITION_TYPE_WEDGE : { pPage->setTransitionType( animations::TransitionType::FANWIPE ); pPage->setTransitionSubtype( animations::TransitionSubType::CENTERTOP ); } break; case PPT_TRANSITION_TYPE_WHEEL : { pPage->setTransitionType( animations::TransitionType::PINWHEELWIPE ); sal_Int16 nSubType; switch( nDirection ) { default: case 1 : nSubType = animations::TransitionSubType::ONEBLADE; break; case 2 : nSubType = animations::TransitionSubType::TWOBLADEVERTICAL; break; case 3 : nSubType = animations::TransitionSubType::THREEBLADE; break; case 4 : nSubType = animations::TransitionSubType::FOURBLADE; break; case 8 : nSubType = animations::TransitionSubType::EIGHTBLADE; break; } pPage->setTransitionSubtype( nSubType ); } break; case PPT_TRANSITION_TYPE_PUSH : { pPage->setTransitionType( animations::TransitionType::PUSHWIPE ); sal_Int16 nSubType; switch( nDirection ) { default: case 0 : nSubType = animations::TransitionSubType::FROMRIGHT; break; case 1 : nSubType = animations::TransitionSubType::FROMBOTTOM; break; case 2 : nSubType = animations::TransitionSubType::FROMLEFT; break; case 3 : nSubType = animations::TransitionSubType::FROMTOP; break; } pPage->setTransitionSubtype( nSubType ); } break; case PPT_TRANSITION_TYPE_COMB : { pPage->setTransitionType( animations::TransitionType::PUSHWIPE ); pPage->setTransitionSubtype( nDirection ? animations::TransitionSubType::COMBVERTICAL : animations::TransitionSubType::COMBHORIZONTAL ); } break; case PPT_TRANSITION_TYPE_NEWSFLASH : { pPage->setTransitionType( animations::TransitionType::ZOOM ); pPage->setTransitionSubtype( animations::TransitionSubType::ROTATEIN ); } break; case PPT_TRANSITION_TYPE_SMOOTHFADE : { pPage->setTransitionType( animations::TransitionType::FADE ); pPage->setTransitionSubtype( animations::TransitionSubType::CROSSFADE ); } break; } if ( nSpeed == 0 ) pPage->setTransitionDuration( 1.0 ); // slow else if ( nSpeed == 1 ) pPage->setTransitionDuration( 0.75 ); // medium else if ( nSpeed == 2 ) pPage->setTransitionDuration( 0.5 ); // fast if ( nBuildFlags & 0x400 ) // slidechange by time { // time to show (in Ticks) pPage->SetPresChange( PRESCHANGE_AUTO ); pPage->SetTime( nSlideTime / 1000.0 ); } else pPage->SetPresChange( mePresChange ); if ( nBuildFlags & 4 ) pPage->SetExcluded( true ); // don't show slide if ( nBuildFlags & 16 ) { // slide with sound effect pPage->SetSound( true ); OUString aSoundFile( ReadSound( nSoundRef ) ); pPage->SetSoundFile( aSoundFile ); } if ( nBuildFlags & ( 1 << 6 ) ) // Loop until next sound pPage->SetLoopSound( true ); if ( nBuildFlags & ( 1 << 8 ) ) // Stop the previous sound pPage->SetStopSound( true ); break; } } } if (!aHd.SeekToEndOfRecord(rStCtrl)) break; } if ( bTryTwice && !bSSSlideInfoAtom ) { bTryTwice = false; if ( HasMasterPage( m_nCurrentPageNum, m_eCurrentPageKind ) ) { sal_uInt16 nMasterNum = GetMasterPageIndex( m_nCurrentPageNum, m_eCurrentPageKind ); PptSlidePersistList* pPageList = GetPageList( PPT_MASTERPAGE ); if ( pPageList && ( nMasterNum < pPageList->size() ) ) { assert( !pPageList->is_null( nMasterNum ) ); const PptSlidePersistEntry& rE = (*pPageList)[ nMasterNum ]; sal_uInt32 nOfs = rE.aPersistAtom.nReserved; if ( nOfs ) { rStCtrl.Seek( nOfs ); nPageRecEnd = nOfs + 16; continue; } } } } break; } } } if ( !bNewAnimationsUsed ) { tAnimationVector aAnimationsOnThisPage; // add effects from page in correct order SdrObjListIter aSdrIter( pPage, SdrIterMode::Flat ); while ( aSdrIter.IsMore() ) { SdrObject* pObj = aSdrIter.Next(); tAnimationMap::iterator aFound = maAnimations.find( pObj ); if( aFound != maAnimations.end() ) { std::pair< SdrObject*, Ppt97AnimationPtr > aPair( (*aFound).first, (*aFound).second ); aAnimationsOnThisPage.push_back( aPair ); } } std::sort( aAnimationsOnThisPage.begin(), aAnimationsOnThisPage.end(), Ppt97AnimationStlSortHelper() ); for( auto& rEntry : aAnimationsOnThisPage ) { Ppt97AnimationPtr pPpt97Animation = rEntry.second; if( pPpt97Animation.get() ) pPpt97Animation->createAndSetCustomAnimationEffect( rEntry.first ); } } rStCtrl.Seek( nOldFilePos ); } // import of sounds // Not only the sounds are imported as string, they are also inserted to // the gallery if they are not already there. OUString ImplSdPPTImport::ReadSound(sal_uInt32 nSoundRef) const { OUString aRetval; sal_uInt32 nOldPos = rStCtrl.Tell(); DffRecordHeader aDocHd; if ( SeekToDocument( &aDocHd ) ) { sal_uInt32 nSoundLen = aDocHd.GetRecEndFilePos(); DffRecordHeader aSoundBlockRecHd; if( SeekToRec( rStCtrl, PPT_PST_SoundCollection, nSoundLen, &aSoundBlockRecHd ) ) { sal_uInt32 nDataLen = aSoundBlockRecHd.GetRecEndFilePos(); DffRecordHeader aSoundRecHd; bool bRefStrValid = false; bool bDone = false; while( !bDone && SeekToRec( rStCtrl, PPT_PST_Sound, nDataLen, &aSoundRecHd ) ) { sal_uInt32 nStrLen = aSoundRecHd.GetRecEndFilePos(); OUString aRefStr; sal_uInt32 nOldPos2 = rStCtrl.Tell(); if ( SeekToRec( rStCtrl, PPT_PST_CString, nStrLen, nullptr, 2 ) ) { if ( ReadString( aRefStr ) ) bRefStrValid = true; } if ( bRefStrValid ) { if ( OUString::number(nSoundRef) == aRefStr ) { rStCtrl.Seek( nOldPos2 ); if ( SeekToRec( rStCtrl, PPT_PST_CString, nStrLen ) ) { ReadString( aRetval ); bDone = true; } } } if ( bDone ) { // Check if this sound file already exists. // If not, it is exported to our local sound directory. bool bSoundExists = false; ::std::vector< OUString > aSoundList; GalleryExplorer::FillObjList( GALLERY_THEME_SOUNDS, aSoundList ); GalleryExplorer::FillObjList( GALLERY_THEME_USERSOUNDS, aSoundList ); for( size_t n = 0; ( n < aSoundList.size() ) && !bSoundExists; ++n ) { INetURLObject aURL( aSoundList[ n ] ); if (aURL.GetLastName() == aRetval) { aRetval = aSoundList[ n ]; bSoundExists = true; } } aSoundList.clear(); if ( !bSoundExists ) { rStCtrl.Seek( nOldPos2 ); DffRecordHeader aSoundDataRecHd; if ( SeekToRec( rStCtrl, PPT_PST_SoundData, nStrLen, &aSoundDataRecHd ) ) { OUString aGalleryDir; if (utl::ConfigManager::IsFuzzing()) osl_getTempDirURL(&aGalleryDir.pData); else aGalleryDir = SvtPathOptions().GetGalleryPath(); // Use last token delimited by ';'. copy(lastIndexOf+1) works whether // string is empty or not and whether ';' is there or not. INetURLObject aGalleryUserSound( aGalleryDir.copy(aGalleryDir.lastIndexOf(';')+1) ); aGalleryUserSound.Append( aRetval ); const auto nRemainingSize = rStCtrl.remainingSize(); sal_uInt32 nSoundDataLen = aSoundDataRecHd.nRecLen; if (nSoundDataLen > nRemainingSize) { SAL_WARN("filter.ms", "sound data len longer than remaining stream size"); nSoundDataLen = nRemainingSize; } std::vector aBuf(nSoundDataLen); rStCtrl.ReadBytes(aBuf.data(), nSoundDataLen); std::unique_ptr pOStm = ::utl::UcbStreamHelper::CreateStream( aGalleryUserSound.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::WRITE | StreamMode::TRUNC ); if( pOStm ) { pOStm->WriteBytes(aBuf.data(), nSoundDataLen); if( pOStm->GetError() == ERRCODE_NONE ) { GalleryExplorer::InsertURL( GALLERY_THEME_USERSOUNDS, aGalleryUserSound.GetMainURL( INetURLObject::DecodeMechanism::NONE ) ); aRetval = aGalleryUserSound.GetMainURL( INetURLObject::DecodeMechanism::NONE ); } } } } } if ( !bDone ) { if (!aSoundRecHd.SeekToEndOfRecord(rStCtrl)) break; } } } } rStCtrl.Seek( nOldPos ); return aRetval; } // media object import, the return value is the url to the media object OUString ImplSdPPTImport::ReadMedia( sal_uInt32 nMediaRef ) const { OUString aRetVal; DffRecordHeader* pHd( const_cast(this)->aDocRecManager.GetRecordHeader( PPT_PST_ExObjList ) ); if ( pHd ) { pHd->SeekToContent( rStCtrl ); auto nEndRecPos = SanitizeEndPos(rStCtrl, pHd->GetRecEndFilePos()); while ( ( rStCtrl.Tell() < nEndRecPos ) && aRetVal.isEmpty() ) { DffRecordHeader aHdMovie; ReadDffRecordHeader( rStCtrl, aHdMovie ); switch( aHdMovie.nRecType ) { case PPT_PST_ExAviMovie : case PPT_PST_ExMCIMovie : { DffRecordHeader aExVideoHd; if ( SeekToRec( rStCtrl, PPT_PST_ExVideo, aHdMovie.GetRecEndFilePos(), &aExVideoHd ) ) { DffRecordHeader aExMediaAtomHd; if ( SeekToRec( rStCtrl, PPT_PST_ExMediaAtom, aExVideoHd.GetRecEndFilePos(), &aExMediaAtomHd ) ) { sal_uInt32 nRef; rStCtrl.ReadUInt32( nRef ); if ( nRef == nMediaRef ) { aExVideoHd.SeekToContent( rStCtrl ); auto nHdEndRecPos = SanitizeEndPos(rStCtrl, aExVideoHd.GetRecEndFilePos()); while (rStCtrl.Tell() < nHdEndRecPos) { DffRecordHeader aHd; ReadDffRecordHeader( rStCtrl, aHd ); switch( aHd.nRecType ) { case PPT_PST_CString : { aHd.SeekToBegOfRecord( rStCtrl ); OUString aStr; if ( ReadString( aStr ) ) { if( osl::FileBase::getFileURLFromSystemPath( aStr, aRetVal ) == osl::FileBase::E_None ) { aRetVal = INetURLObject( aRetVal ).GetMainURL( INetURLObject::DecodeMechanism::Unambiguous ); }else{ aRetVal = aStr; } } } break; } if (!aHd.SeekToEndOfRecord(rStCtrl)) break; } break; } } } } break; } if (!aHdMovie.SeekToEndOfRecord(rStCtrl)) break; } } return aRetVal; } // import of objects void ImplSdPPTImport::FillSdAnimationInfo( SdAnimationInfo* pInfo, PptInteractiveInfoAtom const * pIAtom, const OUString& aMacroName ) { // set local information into pInfo if( pIAtom->nSoundRef ) { pInfo->SetBookmark( ReadSound( pIAtom->nSoundRef ) ); // path to sound file in MS DOS notation pInfo->meClickAction = css::presentation::ClickAction_SOUND; // RunProgramAction } switch ( pIAtom->nAction ) { case 0x02 : // RunProgramAction { pInfo->meClickAction = css::presentation::ClickAction_PROGRAM; pInfo->SetBookmark( aMacroName ); // program name in aBookmark } break; case 0x03 : // JumpAction { switch( pIAtom->nJump ) { case 0x01 : pInfo->meClickAction = css::presentation::ClickAction_NEXTPAGE; // Next slide break; case 0x02 : pInfo->meClickAction = css::presentation::ClickAction_PREVPAGE; // Previous slide break; case 0x03 : pInfo->meClickAction = css::presentation::ClickAction_FIRSTPAGE; // First slide break; case 0x04 : pInfo->meClickAction = css::presentation::ClickAction_LASTPAGE; // last Slide break; case 0x05 : pInfo->meClickAction = css::presentation::ClickAction_PREVPAGE; // Last slide viewed break; case 0x06 : pInfo->meClickAction = css::presentation::ClickAction_STOPPRESENTATION; // End show break; default : pInfo->meClickAction = css::presentation::ClickAction_NONE; // 0x00: no action, else unknown break; } } break; case 0x04 : { SdHyperlinkEntry* pPtr = nullptr; for (SdHyperlinkEntry & entry : m_aHyperList) { if ( entry.nIndex == pIAtom->nExHyperlinkId ) { pPtr = &entry; break; } } if ( pPtr ) { switch( pIAtom->nHyperlinkType ) { case 9: case 8: // hyperlink : URL { if ( !pPtr->aTarget.isEmpty() ) { ::sd::DrawDocShell* pDocShell = mpDoc->GetDocSh(); SfxMedium* pMedium = pDocShell ? pDocShell->GetMedium() : nullptr; if (pMedium) { OUString aBaseURL = pMedium->GetBaseURL(); OUString aBookmarkURL( pInfo->GetBookmark() ); INetURLObject aURL( pPtr->aTarget ); if( INetProtocol::NotValid == aURL.GetProtocol() && (osl::FileBase::getFileURLFromSystemPath( pPtr->aTarget, aBookmarkURL) != osl::FileBase::E_None) ) aBookmarkURL.clear(); if( aBookmarkURL.isEmpty() ) aBookmarkURL = URIHelper::SmartRel2Abs( INetURLObject(aBaseURL), pPtr->aTarget, URIHelper::GetMaybeFileHdl() ); pInfo->SetBookmark( aBookmarkURL ); pInfo->meClickAction = css::presentation::ClickAction_PROGRAM; } } } break; case 10: break; case 7: // hyperlink to a page { if ( !pPtr->aConvSubString.isEmpty() ) { pInfo->meClickAction = css::presentation::ClickAction_BOOKMARK; pInfo->SetBookmark( pPtr->aConvSubString ); } } break; } } } break; case 0x05 : // OLEAction ( OLEVerb to use, 0==first, 1==second, .. ) case 0x06 : // MediaAction case 0x07 : // CustomShowAction default : // 0x00: no action, else unknown action break; } } SdrObject* ImplSdPPTImport::ApplyTextObj( PPTTextObj* pTextObj, SdrTextObj* pObj, SdPageCapsule pPageCapsule, SfxStyleSheet* pSheet, SfxStyleSheet** ppStyleSheetAry ) const { SdPage * pPage = static_cast(pPageCapsule.page); SfxStyleSheet* pStyleSheetAry[ 9 ]; SdrTextObj* pText = pObj; SdrObject* pRet = pText; ppStyleSheetAry = nullptr; PresObjKind ePresKind = PRESOBJ_NONE; PptOEPlaceholderAtom* pPlaceHolder = pTextObj->GetOEPlaceHolderAtom(); OUString aPresentationText; if ( pPlaceHolder ) { switch( pPlaceHolder->nPlaceholderId ) { case PptPlaceholder::MASTERNOTESSLIDEIMAGE : case PptPlaceholder::MASTERCENTEREDTITLE : case PptPlaceholder::MASTERTITLE : { ePresKind = PRESOBJ_TITLE; aPresentationText = pPage->GetPresObjText( ePresKind ); } break; case PptPlaceholder::MASTERBODY : { ePresKind = PRESOBJ_OUTLINE; aPresentationText = pPage->GetPresObjText( ePresKind ); } break; case PptPlaceholder::MASTERSUBTITLE : { ePresKind = PRESOBJ_TEXT; aPresentationText = pPage->GetPresObjText( ePresKind ); } break; case PptPlaceholder::MASTERNOTESBODYIMAGE : { ePresKind = PRESOBJ_NOTES; aPresentationText = pPage->GetPresObjText( ePresKind ); } break; case PptPlaceholder::MASTERDATE : ePresKind = PRESOBJ_DATETIME; break; case PptPlaceholder::MASTERSLIDENUMBER : ePresKind = PRESOBJ_SLIDENUMBER;break; case PptPlaceholder::MASTERFOOTER : ePresKind = PRESOBJ_FOOTER; break; case PptPlaceholder::MASTERHEADER : ePresKind = PRESOBJ_HEADER; break; default: break; } } switch ( pTextObj->GetDestinationInstance() ) { case TSS_Type::PageTitle : case TSS_Type::Title : { pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_TITLE ); if ( pSheet ) static_cast(pText)->SdrAttrObj::NbcSetStyleSheet( pSheet, true ); DBG_ASSERT( pSheet, "ImplSdPPTImport::ApplyTextObj -> could not get stylesheet for titleobject (SJ)" ); } break; case TSS_Type::Subtitle : { pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_TEXT ); if ( pSheet ) static_cast(pText)->SdrAttrObj::NbcSetStyleSheet( pSheet, true ); DBG_ASSERT( pSheet, "ImplSdPPTImport::ApplyTextObj -> could not get stylesheet for subtitleobject (SJ)" ); } break; case TSS_Type::Body : case TSS_Type::HalfBody : case TSS_Type::QuarterBody : { for ( sal_uInt16 nLevel = 9; nLevel; nLevel-- ) { OUString aName = pPage->GetLayoutName() + " " + OUString::number( nLevel ); pSheet = static_cast(mpDoc->GetStyleSheetPool()->Find( aName, SfxStyleFamily::Page )); if ( pSheet ) pText->StartListening( *pSheet ); pStyleSheetAry[ nLevel - 1 ] = pSheet; } DBG_ASSERT( pSheet, "ImplSdPPTImport::ApplyTextObj -> could not get stylesheet for outlinerobject (SJ)" ); if ( pSheet ) static_cast(pText)->SdrAttrObj::NbcSetStyleSheet( pSheet, true ); ppStyleSheetAry = &pStyleSheetAry[ 0 ]; } break; case TSS_Type::Notes : { if ( pPlaceHolder && ( ( pPlaceHolder->nPlaceholderId == PptPlaceholder::NOTESSLIDEIMAGE ) || ( pPlaceHolder->nPlaceholderId == PptPlaceholder::MASTERNOTESSLIDEIMAGE ) ) ) { pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_TITLE ); if ( pSheet ) static_cast(pText)->SdrAttrObj::NbcSetStyleSheet( pSheet, true ); DBG_ASSERT( pSheet, "ImplSdPPTImport::ApplyTextObj -> could not get stylesheet for titleobject (SJ)" ); } else { pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_NOTES ); DBG_ASSERT( pSheet, "ImplSdPPTImport::ApplyTextObj -> could not get stylesheet for notesobj (SJ)" ); if ( pSheet ) static_cast(pText)->SdrAttrObj::NbcSetStyleSheet( pSheet, true ); } } break; case TSS_Type::Unused : case TSS_Type::TextInShape : { switch( ePresKind ) { case PRESOBJ_DATETIME : case PRESOBJ_SLIDENUMBER : case PRESOBJ_FOOTER : case PRESOBJ_HEADER : pSheet = static_cast(mpDoc->GetStyleSheetPool()->Find(SdResId(STR_PSEUDOSHEET_BACKGROUNDOBJECTS), SfxStyleFamily::Pseudo )); break; default : pSheet = static_cast(mpDoc->GetStyleSheetPool()->Find(SdResId(STR_STANDARD_STYLESHEET_NAME), SfxStyleFamily::Para )); } } break; default: break; } pText = static_cast(SdrPowerPointImport::ApplyTextObj( pTextObj, pText, pPageCapsule, pSheet, ppStyleSheetAry )); if ( pPlaceHolder && pPlaceHolder->nPlaceholderId != PptPlaceholder::NONE ) { if ( m_eCurrentPageKind == PPT_MASTERPAGE ) { bool bCreatePlaceHolder = ( pTextObj->GetInstance() != TSS_Type::Unused ); bool bIsHeaderFooter = ( ePresKind == PRESOBJ_HEADER) || (ePresKind == PRESOBJ_FOOTER) || (ePresKind == PRESOBJ_DATETIME) || (ePresKind == PRESOBJ_SLIDENUMBER); if ( bCreatePlaceHolder && ( pTextObj->GetInstance() == TSS_Type::TextInShape ) ) bCreatePlaceHolder = bIsHeaderFooter; if ( bCreatePlaceHolder ) { if ( !bIsHeaderFooter ) { pText->SetNotVisibleAsMaster( true ); pText->SetEmptyPresObj( true ); } pText->SetUserCall( pPage ); pPage->InsertPresObj( pText, ePresKind ); SdrOutliner* pOutl = nullptr; if ( pTextObj->GetInstance() == TSS_Type::Notes ) pOutl = GetDrawOutliner( pText ); if ( !aPresentationText.isEmpty() ) pPage->SetObjText( pText, pOutl, ePresKind, aPresentationText ); if ( pPage->GetPageKind() != PageKind::Notes && pPage->GetPageKind() != PageKind::Handout) { SfxStyleSheet* pSheet2( pPage->GetStyleSheetForPresObj( ePresKind ) ); if ( pSheet2 ) { SfxItemSet& rItemSet = pSheet2->GetItemSet(); rItemSet.Put( pText->GetMergedItem( SDRATTR_TEXT_LEFTDIST ) ); rItemSet.Put( pText->GetMergedItem( SDRATTR_TEXT_RIGHTDIST ) ); rItemSet.Put( pText->GetMergedItem( SDRATTR_TEXT_UPPERDIST ) ); rItemSet.Put( pText->GetMergedItem( SDRATTR_TEXT_LOWERDIST ) ); rItemSet.Put( pText->GetMergedItem( SDRATTR_TEXT_VERTADJUST ) ); rItemSet.Put( pText->GetMergedItem( SDRATTR_TEXT_HORZADJUST ) ); if ( pTextObj->GetInstance() == TSS_Type::Title || pTextObj->GetInstance() == TSS_Type::Subtitle) { rItemSet.Put( pText->GetMergedItemSet() ); } } } SfxItemSet aTempAttr( mpDoc->GetPool() ); SdrMetricItem aMinHeight( makeSdrTextMinFrameHeightItem(pText->GetLogicRect().GetSize().Height()) ); aTempAttr.Put( aMinHeight ); SdrOnOffItem aAutoGrowHeight( makeSdrTextAutoGrowHeightItem(false) ); aTempAttr.Put( aAutoGrowHeight ); pText->SetMergedItemSet(aTempAttr); } else { pRet = nullptr; } } else { const PptSlideLayoutAtom* pSlideLayout = GetSlideLayoutAtom(); if ( pSlideLayout || ( m_eCurrentPageKind == PPT_NOTEPAGE ) ) { sal_uInt32 nPlacementId = pPlaceHolder->nPlacementId; PptPlaceholder nPlaceholderId = pPlaceHolder->nPlaceholderId; PresObjKind ePresObjKind = PRESOBJ_NONE; bool bEmptyPresObj = true; bool bVertical = false; if ( ( pTextObj->GetShapeType() == mso_sptRectangle ) || ( pTextObj->GetShapeType() == mso_sptTextBox ) ) { //if a placeholder with some custom attribute,the pTextObj will keep those attr,whose text size is zero, //so sdPage should renew a PresObj to process placeholder. bEmptyPresObj = ( pTextObj->Count() == 0 ) || ( pTextObj->Count() == 1 && pTextObj->First()->GetTextSize() == 0 ); switch ( nPlaceholderId ) { case PptPlaceholder::NOTESBODY : ePresObjKind = PRESOBJ_NOTES; break; case PptPlaceholder::VERTICALTEXTTITLE : bVertical = true; [[fallthrough]]; case PptPlaceholder::TITLE : ePresObjKind = PRESOBJ_TITLE; break; case PptPlaceholder::VERTICALTEXTBODY : bVertical = true; [[fallthrough]]; case PptPlaceholder::BODY : ePresObjKind = PRESOBJ_OUTLINE; break; case PptPlaceholder::CENTEREDTITLE : ePresObjKind = PRESOBJ_TITLE; break; case PptPlaceholder::SUBTITLE : ePresObjKind = PRESOBJ_TEXT; break; // PRESOBJ_OUTLINE default : { if ( pTextObj->Count() == 0 ) { switch ( nPlaceholderId ) { case PptPlaceholder::MEDIACLIP : case PptPlaceholder::OBJECT : ePresObjKind = PRESOBJ_OBJECT; break; case PptPlaceholder::GRAPH : ePresObjKind = PRESOBJ_CHART; break; case PptPlaceholder::TABLE : ePresObjKind = PRESOBJ_TABLE; break; case PptPlaceholder::CLIPART : ePresObjKind = PRESOBJ_GRAPHIC; break; case PptPlaceholder::ORGANISZATIONCHART : ePresObjKind = PRESOBJ_ORGCHART; break; default: break; } } }; } } else if ( pTextObj->GetShapeType() == mso_sptPictureFrame ) { if ( !pTextObj->Count() && dynamic_cast< const SdrGrafObj *>( pObj ) != nullptr ) { bEmptyPresObj = false; switch ( nPlaceholderId ) { case PptPlaceholder::MEDIACLIP : case PptPlaceholder::OBJECT : ePresObjKind = PRESOBJ_OBJECT; break; case PptPlaceholder::GRAPH : ePresObjKind = PRESOBJ_CHART; break; case PptPlaceholder::TABLE : ePresObjKind = PRESOBJ_CALC; break; case PptPlaceholder::CLIPART : ePresObjKind = PRESOBJ_GRAPHIC; break; case PptPlaceholder::ORGANISZATIONCHART : ePresObjKind = PRESOBJ_ORGCHART; break; default: break; } } } if ( ePresObjKind != PRESOBJ_NONE ) { if ( !bEmptyPresObj ) { pPage->InsertPresObj( pRet, ePresObjKind ); } else { SdrObject* pPresObj = pPage->CreatePresObj( ePresObjKind, bVertical, pText->GetLogicRect() ); pPresObj->SetUserCall( pPage ); SfxItemSet aSet( pSdrModel->GetItemPool() ); ApplyAttributes( rStCtrl, aSet ); pPresObj->SetLogicRect(pText->GetLogicRect()); ApplyTextAnchorAttributes( *pTextObj, aSet ); //set custom font attribute of the placeholder if ( pTextObj->Count() == 1 ) { PPTParagraphObj* pPara = pTextObj->First(); if ( pPara && pPara->GetTextSize() == 0 ) { if ( PPTPortionObj * pPor = pPara->First() ) { pPor->ApplyTo(aSet, const_cast(static_cast(*this)), pTextObj->GetDestinationInstance()); } } } pPresObj->SetMergedItemSet(aSet); if ((m_eCurrentPageKind != PPT_NOTEPAGE) && (nPlacementId != 0xffffffff) && pPage->TRG_HasMasterPage()) { SdrObject* pTitleObj = static_cast(pPage->TRG_GetMasterPage()).GetPresObj( PRESOBJ_TITLE ); SdrObject* pOutlineObj = static_cast(pPage->TRG_GetMasterPage()).GetPresObj( PRESOBJ_OUTLINE ); ::tools::Rectangle aTitleRect; ::tools::Rectangle aOutlineRect; Size aOutlineSize; if ( pTitleObj ) aTitleRect = pTitleObj->GetLogicRect(); if ( pOutlineObj ) { aOutlineRect = pOutlineObj->GetLogicRect(); aOutlineSize = aOutlineRect.GetSize(); } ::tools::Rectangle aLogicRect( pPresObj->GetLogicRect() ); Size aLogicSize( aLogicRect.GetSize() ); switch ( nPlacementId ) { case 0 : // position in title area { if ( aLogicRect != aTitleRect ) pPresObj->SetUserCall( nullptr ); } break; case 1: { if ( pSlideLayout->eLayout == PptSlideLayout::TITLEANDBODYSLIDE ) { // position in outline area if ( aLogicRect != aOutlineRect ) pPresObj->SetUserCall( nullptr ); } else if ( pSlideLayout->eLayout == PptSlideLayout::TWOCOLUMNSANDTITLE ) { // position in outline area left if (std::abs(aLogicRect.Left() - aOutlineRect.Left()) > MAX_USER_MOVE || std::abs(aLogicRect.Top() - aOutlineRect.Top()) > MAX_USER_MOVE || std::abs(aLogicRect.Bottom() - aOutlineRect.Bottom()) > MAX_USER_MOVE || aOutlineSize.Width() == 0 || static_cast(aLogicSize.Width()) / aOutlineSize.Width() < 0.48 || static_cast(aLogicSize.Width()) / aOutlineSize.Width() > 0.5) { pPresObj->SetUserCall(nullptr); } } else if ( pSlideLayout->eLayout == PptSlideLayout::TWOROWSANDTITLE ) { // position in outline area top if (std::abs(aLogicRect.Left() - aOutlineRect.Left()) > MAX_USER_MOVE || std::abs(aLogicRect.Top() - aOutlineRect.Top()) > MAX_USER_MOVE || std::abs(aLogicRect.Right() - aOutlineRect.Right()) > MAX_USER_MOVE) { pPresObj->SetUserCall( nullptr ); } } else if (std::abs(aLogicRect.Left() - aOutlineRect.Left()) > MAX_USER_MOVE || std::abs(aLogicRect.Top() - aOutlineRect.Top()) > MAX_USER_MOVE) { // position in outline area top left pPresObj->SetUserCall( nullptr ); } } break; case 2: { if ( pSlideLayout->eLayout == PptSlideLayout::TWOCOLUMNSANDTITLE ) { // position in outline area right if (std::abs(aLogicRect.Right() - aOutlineRect.Right()) > MAX_USER_MOVE || std::abs(aLogicRect.Top() - aOutlineRect.Top()) > MAX_USER_MOVE || std::abs(aLogicRect.Bottom() - aOutlineRect.Bottom()) > MAX_USER_MOVE || aOutlineSize.Width() == 0 || static_cast(aLogicSize.Width()) / aOutlineSize.Width() < 0.48 || static_cast(aLogicSize.Width()) / aOutlineSize.Width() > 0.5) { pPresObj->SetUserCall( nullptr ); } } else if ( pSlideLayout->eLayout == PptSlideLayout::TWOROWSANDTITLE ) { // position in outline area bottom if (std::abs(aLogicRect.Left() - aOutlineRect.Left()) > MAX_USER_MOVE || std::abs(aLogicRect.Bottom() - aOutlineRect.Bottom()) > MAX_USER_MOVE || std::abs(aLogicRect.Right() - aOutlineRect.Right()) > MAX_USER_MOVE) { pPresObj->SetUserCall( nullptr ); } } else if (std::abs(aLogicRect.Right() - aOutlineRect.Right()) > MAX_USER_MOVE || std::abs(aLogicRect.Top() - aOutlineRect.Top()) > MAX_USER_MOVE) { // position in outline area top right pPresObj->SetUserCall(nullptr); } } break; case 3: { // position in outline area bottom left if (std::abs(aLogicRect.Left() - aOutlineRect.Left()) > MAX_USER_MOVE || std::abs(aLogicRect.Bottom() - aOutlineRect.Bottom()) > MAX_USER_MOVE) { pPresObj->SetUserCall( nullptr ); } } break; case 4: { // position in outline area bottom right if (std::abs(aLogicRect.Right() - aOutlineRect.Right()) > MAX_USER_MOVE || std::abs(aLogicRect.Bottom() - aOutlineRect.Bottom()) > MAX_USER_MOVE) { pObj->SetUserCall( nullptr ); } } break; } } pRet = nullptr; // return zero cause this obj was already inserted by CreatePresObj } } else if ( !pTextObj->Count() ) pRet = nullptr; } } } if ( pRet != pText ) { SdrObject* pFree( pText ); SdrObject::Free( pFree ); } return pRet; } SdrObject* ImplSdPPTImport::ProcessObj( SvStream& rSt, DffObjData& rData, SvxMSDffClientData& rClientData, ::tools::Rectangle& rTextRect, SdrObject* pRet ) { SdrObject* pObj = SdrPowerPointImport::ProcessObj( rSt, rData, rClientData, rTextRect, pRet ); // read animation effect of object if ( pObj ) { // further setup placeholder objects if (dynamic_cast(pObj)) { const ProcessData& rProcessData=static_cast(rClientData); if(rProcessData.pPage.page) static_cast(rProcessData.pPage.page)->InsertPresObj( pObj, PRESOBJ_PAGE ); } DffRecordHeader aMasterShapeHd; if ( maShapeRecords.SeekToContent( rSt, DFF_msofbtClientData, SEEK_FROM_CURRENT_AND_RESTART ) ) { bool bInhabitanceChecked = false; bool bAnimationInfoFound = false; DffRecordHeader& rHdClientData = *maShapeRecords.Current(); while( true ) { sal_uInt32 nClientDataLen = SanitizeEndPos(rSt, rHdClientData.GetRecEndFilePos()); DffRecordHeader aHd; do { ReadDffRecordHeader( rSt, aHd ); sal_uInt32 nHdRecEnd = aHd.GetRecEndFilePos(); switch ( aHd.nRecType ) { case PPT_PST_AnimationInfo : { DffRecordHeader aHdAnimInfoAtom; if ( SeekToRec( rSt, PPT_PST_AnimationInfoAtom, nHdRecEnd, &aHdAnimInfoAtom ) ) { // read data from stream Ppt97AnimationPtr pAnimation = std::make_shared( rSt ); // store animation information if( pAnimation->HasEffect() ) { // translate color to RGB pAnimation->SetDimColor( MSO_CLR_ToColor(pAnimation->GetDimColor()) ); // translate sound bits to file url if( pAnimation->HasSoundEffect() ) pAnimation->SetSoundFileUrl( ReadSound( pAnimation->GetSoundRef() ) ); bool bDontAnimateInvisibleShape = false; { SdrTextObj* pTextObj = dynamic_cast(pObj); if( pTextObj && pTextObj->HasText() && dynamic_cast< SdrObjGroup *>( pObj ) == nullptr && pAnimation->HasAnimateAssociatedShape() ) { const SfxItemSet& rObjItemSet = pObj->GetMergedItemSet(); drawing::FillStyle eFillStyle = rObjItemSet.Get(XATTR_FILLSTYLE).GetValue(); drawing::LineStyle eLineStyle = rObjItemSet.Get(XATTR_LINESTYLE).GetValue(); if ( ( eFillStyle == drawing::FillStyle_NONE ) && ( eLineStyle == drawing::LineStyle_NONE ) ) bDontAnimateInvisibleShape = true; } } if( bDontAnimateInvisibleShape ) pAnimation->SetAnimateAssociatedShape(false); //maybe some actions necessary to ensure that animations on master pages are played before animations on normal pages //maybe todo in future: bool bIsEffectOnMasterPage = !bInhabitanceChecked;? maAnimations[pObj] = pAnimation; bAnimationInfoFound = true; } } } break; case PPT_PST_InteractiveInfo: { sal_uInt32 nOldFilePos2 = rSt.Tell(); OUString aMacroName; if(SeekToRec( rSt, PPT_PST_CString, nHdRecEnd ) ) ReadString(aMacroName); rSt.Seek( nOldFilePos2 ); DffRecordHeader aHdInteractiveInfoAtom; if ( SeekToRec( rSt, PPT_PST_InteractiveInfoAtom, nHdRecEnd, &aHdInteractiveInfoAtom ) ) { PptInteractiveInfoAtom aInteractiveInfoAtom; ReadPptInteractiveInfoAtom( rSt, aInteractiveInfoAtom ); // interactive object SdAnimationInfo* pInfo = SdDrawDocument::GetShapeUserData(*pObj, true); FillSdAnimationInfo( pInfo, &aInteractiveInfoAtom, aMacroName ); if ( aInteractiveInfoAtom.nAction == 6 ) // Sj -> media action { rHdClientData.SeekToContent( rStCtrl ); DffRecordHeader aObjRefAtomHd; if ( SeekToRec( rSt, PPT_PST_ExObjRefAtom, nHdRecEnd, &aObjRefAtomHd ) ) { sal_uInt32 nRef; rSt.ReadUInt32( nRef ); OUString aMediaURL( ReadMedia( nRef ) ); if ( aMediaURL.isEmpty() ) aMediaURL = ReadSound( nRef ); if ( !aMediaURL.isEmpty() ) { SdrMediaObj* pMediaObj = new SdrMediaObj( pObj->getSdrModelFromSdrObject(), pObj->GetSnapRect()); pMediaObj->SetMergedItemSet( pObj->GetMergedItemSet() ); //--remove object from maAnimations list and add the new object instead Ppt97AnimationPtr pAnimation; { tAnimationMap::iterator aFound = maAnimations.find( pObj ); if( aFound != maAnimations.end() ) { pAnimation = (*aFound).second; maAnimations.erase(aFound); } maAnimations[pMediaObj] = pAnimation; } SdrObject::Free( pObj ); pObj = pMediaObj; // SJ: hoping that pObj is not inserted in any list pMediaObj->setURL( aMediaURL, ""/*TODO?*/ ); } } } } } break; } if (!aHd.SeekToEndOfRecord(rSt)) break; } while( ( rSt.GetError() == ERRCODE_NONE ) && ( rSt.Tell() < nClientDataLen ) ); if ( bInhabitanceChecked || bAnimationInfoFound ) break; bInhabitanceChecked = true; if ( ! ( IsProperty( DFF_Prop_hspMaster ) && SeekToShape( rSt, &rClientData, GetPropertyValue( DFF_Prop_hspMaster, 0 ) ) ) ) break; ReadDffRecordHeader( rSt, aMasterShapeHd ); if ( !SeekToRec( rSt, DFF_msofbtClientData, aMasterShapeHd.GetRecEndFilePos(), &aMasterShapeHd ) ) break; aMasterShapeHd.SeekToContent( rSt ); rHdClientData = aMasterShapeHd; } } } return pObj; } bool ImplSdPPTImport::ReadFormControl( tools::SvRef& rSrc1, css::uno::Reference< css::form::XFormComponent > & rFormComp ) const { uno::Reference< frame::XModel > xModel; if ( mpDoc->GetDocSh() ) { xModel = mpDoc->GetDocSh()->GetModel(); oox::ole::MSConvertOCXControls aCtrlImporter( xModel ); return aCtrlImporter.ReadOCXStorage( rSrc1, rFormComp ); } return false; } // exported function extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool ImportPPT( SdDrawDocument* pDocument, SvStream& rDocStream, SotStorage& rStorage, SfxMedium& rMedium ) { std::unique_ptr pImport( new SdPPTImport( pDocument, rDocStream, rStorage, rMedium )); bool bRet = pImport->Import(); return bRet; } extern "C" SAL_DLLPUBLIC_EXPORT bool TestImportPPT(SvStream &rStream) { bool bRet = false; try { tools::SvRef xStorage(new SotStorage(rStream)); if (xStorage->GetError()) return false; tools::SvRef xDocStream(xStorage->OpenSotStream( "PowerPoint Document", StreamMode::STD_READ)); if ( !xDocStream.is() ) return false; SdDLL::Init(); SfxMedium aSrcMed("", StreamMode::STD_READ); xDocStream->SetVersion(xStorage->GetVersion()); xDocStream->SetCryptMaskKey(xStorage->GetKey()); ::sd::DrawDocShellRef xDocShRef = new ::sd::DrawDocShell(SfxObjectCreateMode::EMBEDDED, false, DocumentType::Impress); SdDrawDocument *pDoc = xDocShRef->GetDoc(); try { bRet = ImportPPT(pDoc, *xDocStream, *xStorage, aSrcMed); } catch (...) { } xDocShRef->DoClose(); } catch (...) { } return bRet; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */