/* -*- 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 <editeng/numitem.hxx>
#include <osl/file.hxx>
#include <sal/log.hxx>
#include <unotools/configmgr.hxx>
#include <unotools/ucbstreamhelper.hxx>
#include <vcl/wrkwin.hxx>
#include <svl/urihelper.hxx>
#include <svx/svxids.hrc>
#include <filter/msfilter/svdfppt.hxx>
#include <svx/svditer.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/app.hxx>
#include <svx/svdograf.hxx>
#include <svx/svdlayer.hxx>
#include <svl/style.hxx>
#include <svx/xflclit.hxx>
#include <editeng/eeitem.hxx>
#include <editeng/colritem.hxx>
#include <svl/whiter.hxx>
#include <svx/xgrad.hxx>
#include <svx/xflgrit.hxx>
#include <svx/xbtmpit.hxx>
#include <svx/xlnclit.hxx>
#include <editeng/adjustitem.hxx>
#include <editeng/editeng.hxx>
#include <editeng/bulletitem.hxx>
#include <editeng/lrspitem.hxx>
#include <editeng/lspcitem.hxx>
#include <editeng/tstpitem.hxx>
#include <sfx2/docinf.hxx>
#include <strings.hrc>
#include <strings.hxx>
#include "pptin.hxx"
#include <Outliner.hxx>
#include <drawdoc.hxx>
#include <sdpage.hxx>
#include <sdresid.hxx>
#include <pres.hxx>
#include <stlpool.hxx>
#include <anminfo.hxx>
#include <svx/gallery.hxx>
#include <tools/urlobj.hxx>
#include <svl/itempool.hxx>
#include <editeng/fhgtitem.hxx>
#include <svx/svdopage.hxx>
#include <svx/svdomedia.hxx>
#include <svx/svdogrp.hxx>
#include "propread.hxx"
#include <cusshow.hxx>
#include <xmloff/autolayout.hxx>
#include <customshowlist.hxx>
#include <sddll.hxx>
#include <DrawDocShell.hxx>
#include <FrameView.hxx>
#include <optsitem.hxx>
#include <unotools/fltrcfg.hxx>
#include <sfx2/progress.hxx>
#include <editeng/editstat.hxx>
#include <unotools/pathoptions.hxx>
#include <sfx2/docfac.hxx>
#define MAX_USER_MOVE 2
#include <animations.hxx>
#include "pptanimations.hxx"
#include "pptinanimations.hxx"
#include "ppt97animations.hxx"
#include <com/sun/star/animations/TransitionSubType.hpp>
#include <com/sun/star/animations/TransitionType.hpp>
#include <com/sun/star/document/XDocumentProperties.hpp>
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
#include <com/sun/star/drawing/LineStyle.hpp>
#include <comphelper/string.hxx>
#include <oox/ole/olehelper.hxx>
#include <oox/ppt/pptfilterhelpers.hxx>
#include <boost/optional.hpp>
#include <cassert>
#include <memory>
using namespace ::com::sun::star;
SdPPTImport::SdPPTImport( SdDrawDocument* pDocument, SvStream& rDocStream, SotStorage& rStorage, SfxMedium& rMedium )
: maParam(rDocStream)
{
#ifdef DBG_UTIL
std::unique_ptr<PropRead> 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<Section*>(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
SvStream* pCurrentUserStream = rStorage.OpenSotStream( "Current User", StreamMode::STD_READ );
if( pCurrentUserStream )
{
ReadPptCurrentUserAtom(*pCurrentUserStream, maParam.aCurrentUserAtom);
delete pCurrentUserStream;
}
if( pDocument )
{
// iterate over all styles
SdStyleSheetPool* pStyleSheetPool = pDocument->GetSdStyleSheetPool();
std::shared_ptr<SfxStyleSheetIterator> aIter =
std::make_shared<SfxStyleSheetIterator>(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)
, mnBackgroundLayerID(0)
, mnBackgroundObjectsLayerID(0)
{
if ( bOk )
{
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 nPosMerk = 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( nPosMerk );
}
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 ( !bOk )
return false;
pSdrModel->setLock(true);
const bool bSavedUndoEnabled = pSdrModel->IsUndoEnabled();
pSdrModel->EnableUndo(false);
SdrOutliner& rOutl = mpDoc->GetDrawOutliner();
EEControlBits nControlWord = rOutl.GetEditEngine().GetControlWord();
nControlWord |= EEControlBits::ULSPACESUMMATION;
nControlWord &= ~EEControlBits::ULSPACEFIRSTPARA;
const_cast<EditEngine&>(rOutl.GetEditEngine()).SetControlWord( nControlWord );
SdrLayerAdmin& rAdmin = mpDoc->GetLayerAdmin();
mnBackgroundLayerID = rAdmin.GetLayerID( SdResId( STR_LAYER_BCKGRND ) );
mnBackgroundObjectsLayerID = rAdmin.GetLayerID( SdResId( STR_LAYER_BCKGRNDOBJ ) );
::sd::DrawDocShell* pDocShell = mpDoc->GetDocSh();
if ( pDocShell )
SeekOle( pDocShell, mnFilterOptions );
// hyperlinks
std::unique_ptr<PropRead> 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<Section*>(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<OUString>::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<Section*>(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
SdHyperlinkEntry aHyperlink;
for ( i = 0; i < nPropCount; i++ )
{
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<OUString>::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<sal_uInt32>(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<sal_uInt16>(nPageNumber) + 1 ) );
}
} else {
// if sub address is given but not internal, use it as it is
if ( aHyperlink.aConvSubString.isEmpty() )
{
aHyperlink.aConvSubString = aString;
}
}
}
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 : 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;
}
}
}
Size aVisAreaSize;
switch ( 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<SfxProgress> 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<SdPage*>(MakeBlancPage( true ));
if ( pPage )
{
bool bNotesMaster = (*GetPageList( eCurrentPageKind ) )[ nCurrentPageNum ].bNotesMaster;
bool bStarDrawFiller = (*GetPageList( eCurrentPageKind ) )[ nCurrentPageNum ].bStarDrawFiller;
PageKind ePgKind = bNotesMaster ? PageKind::Notes : PageKind::Standard;
bool bHandout = (*GetPageList( eCurrentPageKind ) )[ nCurrentPageNum ].bHandoutMaster;
if ( bHandout )
ePgKind = PageKind::Handout;
pPage->SetPageKind( ePgKind );
pSdrModel->InsertMasterPage( static_cast<SdrPage*>(pPage) );
if ( bNotesMaster && bStarDrawFiller )
pPage->SetAutoLayout( AUTOLAYOUT_NOTES, true );
if ( nMasterNum )
{
boost::optional< sal_Int16 > oStartNumbering;
SfxStyleSheet* pSheet;
if ( nMasterNum == 1 )
{
// standardsheet
pSheet = static_cast<SfxStyleSheet*>(mpDoc->GetStyleSheetPool()->Find(SdResId(STR_STANDARD_STYLESHEET_NAME), SfxStyleFamily::Para ));
if ( pSheet )
{
SfxItemSet& rItemSet = pSheet->GetItemSet();
PPTParagraphObj aParagraph( *pPPTStyleSheet, TSS_Type::TextInShape, 0 );
PPTPortionObj aPortion( *pPPTStyleSheet, TSS_Type::TextInShape, 0 );
aParagraph.AppendPortion( aPortion );
aParagraph.ApplyTo( rItemSet, oStartNumbering, static_cast<SdrPowerPointImport&>(*this), TSS_Type::Unknown );
aPortion.ApplyTo( rItemSet, static_cast<SdrPowerPointImport&>(*this), TSS_Type::Unknown );
}
}
// PSEUDO
pSheet = static_cast<SfxStyleSheet*>(mpDoc->GetStyleSheetPool()->Find(SdResId(STR_PSEUDOSHEET_BACKGROUNDOBJECTS), SfxStyleFamily::Pseudo ));
if ( pSheet )
{
SfxItemSet& rItemSet = pSheet->GetItemSet();
PPTParagraphObj aParagraph( *pPPTStyleSheet, TSS_Type::TextInShape, 0 );
PPTPortionObj aPortion( *pPPTStyleSheet, TSS_Type::TextInShape, 0 );
aParagraph.AppendPortion( aPortion );
aParagraph.ApplyTo( rItemSet, oStartNumbering, static_cast<SdrPowerPointImport&>(*this), TSS_Type::Unknown );
aPortion.ApplyTo( rItemSet, static_cast<SdrPowerPointImport&>(*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 );
aLayoutName += OUString::number( static_cast<sal_Int32>( ( nMasterNum + 1 ) / 2 - 1 ) );
static_cast<SdStyleSheetPool*>( mpDoc->GetStyleSheetPool() )->CreateLayoutStyleSheets( aLayoutName );
}
else // note page: use presentation layout of standard page
aLayoutName = static_cast<SdPage*>( mpDoc->GetMasterPage( nMasterNum - 1 ) )->GetName();
}
pPage->SetName( aLayoutName );
aLayoutName += SD_LT_SEPARATOR;
aLayoutName += 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( *pPPTStyleSheet, nTitleInstance, 0 );
PPTPortionObj aPortion( *pPPTStyleSheet, nTitleInstance, 0 );
aParagraph.AppendPortion( aPortion );
aParagraph.ApplyTo( rItemSet, oStartNumbering, static_cast<SdrPowerPointImport&>(*this), TSS_Type::Unknown );
aPortion.ApplyTo( rItemSet, static_cast<SdrPowerPointImport&>(*this), TSS_Type::Unknown );
}
// outlinerstylesheet
sal_uInt16 nLevel;
PPTParagraphObj* pParagraphs[ 9 ];
for ( nLevel = 0; nLevel < 9; nLevel++ )
{
OUString aName( pPage->GetLayoutName() );
aName += " ";
aName += OUString::number( nLevel + 1 );
SfxStyleSheet* pOutlineSheet = static_cast<SfxStyleSheet*>( mpDoc->GetStyleSheetPool()->Find( aName, SfxStyleFamily::Page ) );
DBG_ASSERT( pOutlineSheet, "Template for outline object not found" );
if ( pOutlineSheet )
{
pParagraphs[ nLevel ] = new PPTParagraphObj( *pPPTStyleSheet, nOutlinerInstance, nLevel );
SfxItemSet& rItemSet = pOutlineSheet->GetItemSet();
PPTPortionObj aPortion( *pPPTStyleSheet, nOutlinerInstance, nLevel );
pParagraphs[ nLevel ]->AppendPortion( aPortion );
pParagraphs[ nLevel ]->ApplyTo( rItemSet, oStartNumbering, static_cast<SdrPowerPointImport&>(*this), TSS_Type::Unknown );
aPortion.ApplyTo( rItemSet, static_cast<SdrPowerPointImport&>(*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( *pPPTStyleSheet, TSS_Type::Subtitle, 0 );
PPTPortionObj aPortion( *pPPTStyleSheet, TSS_Type::Subtitle, 0 );
aParagraph.AppendPortion( aPortion );
aParagraph.ApplyTo( rItemSet, oStartNumbering, static_cast<SdrPowerPointImport&>(*this), TSS_Type::Unknown );
aPortion.ApplyTo( rItemSet, static_cast<SdrPowerPointImport&>(*this), TSS_Type::Unknown );
}
}
else if ( ePgKind == PageKind::Notes )
{
pSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_NOTES );
if ( pSheet )
{
SfxItemSet& rItemSet = pSheet->GetItemSet();
PPTParagraphObj aParagraph( *pPPTStyleSheet, TSS_Type::Notes, 0 );
PPTPortionObj aPortion( *pPPTStyleSheet, TSS_Type::Notes, 0 );
aParagraph.AppendPortion( aPortion );
aParagraph.ApplyTo( rItemSet, oStartNumbering, static_cast<SdrPowerPointImport&>(*this), TSS_Type::Unknown );
aPortion.ApplyTo( rItemSet, static_cast<SdrPowerPointImport&>(*this), TSS_Type::Unknown );
}
}
}
}
}
}
for (sal_uInt16 i = 0; i < mpDoc->GetMasterPageCount(); ++i)
{
SdPage *const pMPage(static_cast<SdPage*>(mpDoc->GetMasterPage(i)));
if (pMPage == nullptr)
break;
SetPageNum( i, PPT_MASTERPAGE );
// importing master page objects
PptSlidePersistList* pList = GetPageList( eCurrentPageKind );
PptSlidePersistEntry* pPersist = ( pList && ( nCurrentPageNum < pList->size() ) )
? &(*pList)[ nCurrentPageNum ] : nullptr;
if ( pPersist )
{
if ( pPersist->bStarDrawFiller && pPersist->bNotesMaster && ( nCurrentPageNum > 2 ) && ( ( nCurrentPageNum & 1 ) == 0 ) )
{
pSdrModel->DeleteMasterPage( nCurrentPageNum );
SdrPage* pNotesClone = static_cast<SdPage*>(pSdrModel->GetMasterPage( 2 ))->CloneSdrPage(*pSdrModel);
pSdrModel->InsertMasterPage( pNotesClone, nCurrentPageNum );
if ( pNotesClone )
{
OUString aLayoutName( static_cast<SdPage*>(pSdrModel->GetMasterPage( nCurrentPageNum - 1 ))->GetLayoutName() );
static_cast<SdPage*>(pNotesClone)->SetPresentationLayout( aLayoutName, false, false );
static_cast<SdPage*>(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)[ nCurrentPageNum ], SdPageCapsule(pMPage) );
sal_uInt32 nFPosMerk = 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( nFPosMerk );
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 nFPosMerk = rStCtrl.Tell();
PptPageKind ePageKind = eCurrentPageKind;
sal_uInt16 nPageNum = nCurrentPageNum;
SdPage* pHandoutPage = static_cast<SdPage*>(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<SdPage*>(MakeBlancPage( false ));
PptSlidePersistEntry* pMasterPersist = nullptr;
if ( HasMasterPage( nPage ) ) // try to get the LayoutName from the masterpage
{
sal_uInt16 nMasterNum = GetMasterPageIndex( nCurrentPageNum, eCurrentPageKind );
pPage->TRG_SetMasterPage(*pSdrModel->GetMasterPage(nMasterNum));
PptSlidePersistList* pPageList = GetPageList( PPT_MASTERPAGE );
if ( pPageList && nMasterNum < pPageList->size() )
pMasterPersist = &(*pPageList)[ nMasterNum ];
pPage->SetLayoutName(static_cast<SdPage&>(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
eCurrentPageKind = PPT_NOTEPAGE;
SdPage* pNotesPage = static_cast<SdPage*>(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<SdPage&>(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<SdrPageObj*>(pPageObj)->SetReferencedPage(pSdrModel->GetPage(( nPage << 1 ) + 1));
}
if (xStbMgr)
xStbMgr->SetState( nImportedPages++ );
}
}
else
{
// that can happen by document templates
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<SdPage*>( 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<SdPage*>(pPage)->TRG_SetMasterPage( *pFoundMaster );
static_cast<SdPage*>(pPage)->SetLayoutName( pFoundMaster->GetLayoutName() );
}
static_cast<SdPage*>(pPage)->SetAutoLayout( AUTOLAYOUT_TITLE, true, true );
eCurrentPageKind = PPT_NOTEPAGE;
SdrPage* pNPage = MakeBlancPage( false );
pSdrModel->InsertPage( pNPage );
}
SetPageNum( nPageNum, ePageKind );
rStCtrl.Seek( nFPosMerk );
}
// create handout and note pages
bOk = mpDoc->CreateMissingNotesAndHandoutPages();
if ( 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::BLANCSLIDE :
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<std::unique_ptr<sd::FrameView>> &rViews = mpDoc->GetFrameViewList();
pFrameView = new ::sd::FrameView( mpDoc );
rViews.push_back( std::unique_ptr<sd::FrameView>(pFrameView) );
}
if ( pFrameView )
{
sal_uInt16 nSelectedPage = 0;
PageKind ePageKind = PageKind::Standard;
EditMode eEditMode = EditMode::Page;
switch ( 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;
SAL_FALLTHROUGH;
case PptViewTypeEnum::SlideMaster:
{
ePageKind = PageKind::Standard;
eEditMode = EditMode::MasterPage;
}
break;
case PptViewTypeEnum::NotesMaster:
eEditMode = EditMode::MasterPage;
SAL_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 );
sal_uInt32 nSCount = aContent.nRecLen >> 2;
if ( pPageList && nSCount )
{
SdCustomShowList* pList = mpDoc->GetCustomShowList( true );
if ( pList )
{
SdCustomShow* 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( pSdCustomShow );
else
delete 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<document::XDocumentPropertiesSupplier> xDPS(
mpDoc->GetObjectShell()->GetModel(), uno::UNO_QUERY_THROW);
uno::Reference<document::XDocumentProperties> xDocProps
= xDPS->getDocumentProperties();
sfx2::LoadOlePropertySet(xDocProps, &mrStorage);
xDocProps->setTemplateName(OUString());
pSdrModel->setLock(false);
pSdrModel->EnableUndo(bSavedUndoEnabled);
return bOk;
}
void ImplSdPPTImport::SetHeaderFooterPageSettings( SdPage* pPage, const PptSlidePersistEntry* pMasterPersist )
{
sal_uInt32 i;
PptSlidePersistList* pList = GetPageList( eCurrentPageKind );
if ( ( !pList ) || ( pList->size() <= nCurrentPageNum ) )
return;
PptSlidePersistEntry& rSlidePersist = (*pList)[ nCurrentPageNum ];
HeaderFooterEntry* pHFE = rSlidePersist.xHeaderFooterEntry.get();
if (pHFE)
{
for ( i = 0; i < 4; i++ )
{
bool bVisible = pHFE->IsToDisplay( i );
if ( ( 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 );
}
}
}
// 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 true;
if( *p1.second < *p2.second )
return true;
if( *p1.second > *p2.second )
return false;
if( p1.first->GetOrdNum() < p2.first->GetOrdNum() )
return true;
return false;
}
void ImplSdPPTImport::ImportPageEffect( SdPage* pPage, const bool bNewAnimationsUsed )
{
sal_uLong nFilePosMerk = rStCtrl.Tell();
// set PageKind at page (up to now only PageKind::Standard or PageKind::Notes)
if ( pPage->GetPageKind() == PageKind::Standard )
{
PptSlidePersistList* pPersistList = GetPageList( eCurrentPageKind );
PptSlidePersistEntry* pActualSlidePersist = ( pPersistList && ( nCurrentPageNum < pPersistList->size() ) )
? &(*pPersistList)[ nCurrentPageNum ] : nullptr;
if ( pActualSlidePersist && ( 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 = ( 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 ( 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( nCurrentPageNum, eCurrentPageKind ) )
{
sal_uInt16 nMasterNum = GetMasterPageIndex( nCurrentPageNum, 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() );
tAnimationVector::iterator aIter( aAnimationsOnThisPage.begin() );
const tAnimationVector::iterator aEnd( aAnimationsOnThisPage.end() );
for( ;aIter != aEnd; ++aIter )
{
Ppt97AnimationPtr pPpt97Animation = (*aIter).second;
if( pPpt97Animation.get() )
pPpt97Animation->createAndSetCustomAnimationEffect( (*aIter).first );
}
}
rStCtrl.Seek( nFilePosMerk );
}
// 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 nPosMerk = 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 nPosMerk2 = 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( nPosMerk2 );
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.GetName() == aRetval )
{
aRetval = aSoundList[ n ];
bSoundExists = true;
}
}
aSoundList.clear();
if ( !bSoundExists )
{
rStCtrl.Seek( nPosMerk2 );
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<sal_uInt8> aBuf(nSoundDataLen);
rStCtrl.ReadBytes(aBuf.data(), nSoundDataLen);
std::unique_ptr<SvStream> 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( nPosMerk );
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<ImplSdPPTImport*>(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 : 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<SdPage *>(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<SdrAttrObj*>(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<SdrAttrObj*>(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() );
aName += " ";
aName += OUString::number( nLevel );
pSheet = static_cast<SfxStyleSheet*>(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<SdrAttrObj*>(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<SdrAttrObj*>(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<SdrAttrObj*>(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<SfxStyleSheet*>(mpDoc->GetStyleSheetPool()->Find(SdResId(STR_PSEUDOSHEET_BACKGROUNDOBJECTS), SfxStyleFamily::Pseudo ));
break;
default :
pSheet = static_cast<SfxStyleSheet*>(mpDoc->GetStyleSheetPool()->Find(SdResId(STR_STANDARD_STYLESHEET_NAME), SfxStyleFamily::Para ));
}
}
break;
default: break;
}
pText = static_cast<SdrTextObj*>(SdrPowerPointImport::ApplyTextObj( pTextObj, pText, pPageCapsule, pSheet, ppStyleSheetAry ));
if ( pPlaceHolder && pPlaceHolder->nPlaceholderId != PptPlaceholder::NONE )
{
if ( 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 || ( 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;
SAL_FALLTHROUGH;
case PptPlaceholder::TITLE : ePresObjKind = PRESOBJ_TITLE; break;
case PptPlaceholder::VERTICALTEXTBODY :
bVertical = true;
SAL_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<SdrPowerPointImport&>(static_cast<SdrPowerPointImport const &>(*this)), pTextObj->GetDestinationInstance());
}
}
}
pPresObj->SetMergedItemSet(aSet);
if ((eCurrentPageKind != PPT_NOTEPAGE) && (nPlacementId != 0xffffffff) && pPage->TRG_HasMasterPage())
{
SdrObject* pTitleObj = static_cast<SdPage&>(pPage->TRG_GetMasterPage()).GetPresObj( PRESOBJ_TITLE );
SdrObject* pOutlineObj = static_cast<SdPage&>(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<double>(aLogicSize.Width()) / aOutlineSize.Width() < 0.48 ||
static_cast<double>(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<double>(aLogicSize.Width()) / aOutlineSize.Width() < 0.48 ||
static_cast<double>(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& rObjData, SvxMSDffClientData& rData, ::tools::Rectangle& rTextRect, SdrObject* pRet )
{
SdrObject* pObj = SdrPowerPointImport::ProcessObj( rSt, rObjData, rData, rTextRect, pRet );
// read animation effect of object
if ( pObj )
{
// further setup placeholder objects
if (dynamic_cast<const SdrPageObj*>(pObj))
{
const ProcessData& rProcessData=static_cast<const ProcessData&>(rData);
if(rProcessData.pPage.page)
static_cast<SdPage *>(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( new Ppt97Animation( 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<SdrTextObj*>(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 nFilePosMerk2 = rSt.Tell();
OUString aMacroName;
if(SeekToRec( rSt, PPT_PST_CString, nHdRecEnd ) )
ReadString(aMacroName);
rSt.Seek( nFilePosMerk2 );
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, &rData, 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<SotStorage>& 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<SdPPTImport> 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<SotStorage> xStorage = tools::SvRef<SotStorage>(new SotStorage(rStream));
if (xStorage->GetError())
return false;
tools::SvRef<SotStorageStream> 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: */
↑ V1004 The 'pDocShell' pointer was used unsafely after it was verified against nullptr. Check lines: 258, 561.
↑ V668 There is no sense in testing the 'pFrameView' pointer against null, as the memory was allocated using the 'new' operator. The exception will be generated in the case of memory allocation error.