cool#16080: write the body the slide master holds
The master part was written from the page standing for the group of equivalent masters, so it carried that layout's placeholders and nothing else - for a deck whose first layout is a title slide, no body at all, and PowerPoint offered no Master text styles to edit. Take a type a master may hold that this page has none of from the first page of the group that has it. A layout placeholder was imported with what it inherits from the master, so the first layout with a body carries the master's own geometry, which is where PowerPoint puts the box. A deck whose first body-bearing layout states a geometry of its own hands that over instead. testTdf106867 moved its expected spid from 65 to 66: the master part writes one shape more, and shape ids are document-wide. It still names the p:pic that holds the video. Underneath is a document model difference: PowerPoint has masters that carry layouts, Impress has masters alone, so the import maps each layout to a master of its own and the export reconstructs both levels from them. Signed-off-by: Mike Kaganski <mike.kaganski@collabora.com> Change-Id: I1e6d311e5f20cd3377ce4c0c3f2dfa59ff4dfefb Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/9196 Tested-by: Jenkins CPCI <releng@collaboraoffice.com> Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com> (cherry picked from commit 73dfd24f01a6fdf5fbd7c0d48f17c027442fb870) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/210234 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
This commit is contained in:
committed by
Xisco Fauli
parent
f829102cad
commit
9b3b1373b2
@@ -1325,7 +1325,7 @@ CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest2, testTdf106867)
|
||||
"/p:sld/p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par/"
|
||||
"p:cTn/p:childTnLst/p:par/p:cTn/p:childTnLst/p:par/p:cTn/p:childTnLst/p:cmd/"
|
||||
"p:cBhvr/p:tgtEl/p:spTgt",
|
||||
"spid", u"65");
|
||||
"spid", u"66");
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest2, testTdf112280)
|
||||
|
||||
@@ -2466,6 +2466,13 @@ CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest4, testCool16080_masterKeepsItsPlaceholder
|
||||
assertXPath(pMaster, aTree + "/p:sp/p:nvSpPr/p:nvPr/p:ph[@type='dt']", 1);
|
||||
assertXPath(pMaster, aTree + "/p:sp/p:nvSpPr/p:nvPr/p:ph[@type='ftr']", 1);
|
||||
assertXPath(pMaster, aTree + "/p:sp/p:nvSpPr/p:nvPr/p:ph[@type='sldNum']", 1);
|
||||
|
||||
// The body comes from the first layout that has one, since the page standing for the group is
|
||||
// the Title Slide layout and has none. That layout inherits the master's geometry, so the
|
||||
// placeholder lands where the master put it rather than where a layout would.
|
||||
assertXPath(pMaster, aTree + "/p:sp/p:nvSpPr/p:nvPr/p:ph[@type='body']", 1);
|
||||
assertXPath(pMaster, aTree + "/p:sp[p:nvSpPr/p:nvPr/p:ph/@type='body']/p:spPr/a:xfrm/a:off",
|
||||
"y", u"1825560");
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest4, testCool16079_dateTimeField)
|
||||
|
||||
@@ -113,7 +113,7 @@ private:
|
||||
|
||||
// shapes
|
||||
void WriteShapeTree( const ::sax_fastparser::FSHelperPtr& pFS, PageType ePageType, bool bMaster,
|
||||
bool bSlideMasterPart = false );
|
||||
bool bSlideMasterPart = false, sal_uInt32 nMasterNum = 0 );
|
||||
|
||||
sal_uInt32 GetNewSlideId() { return mnSlideIdMax ++; }
|
||||
sal_uInt32 GetNewSlideMasterId() { return mnSlideMasterIdMax ++; }
|
||||
@@ -139,6 +139,8 @@ private:
|
||||
void WritePlaceholderReferenceShapes(PowerPointShapeExport& rDML, PageType ePageType);
|
||||
/** Writes the master page's content placeholders into the layout they belong on */
|
||||
void WriteLayoutContentPlaceholders(PowerPointShapeExport& rDML);
|
||||
/** Writes the placeholders a slide master holds that the page standing for it has none of */
|
||||
void WriteMasterOwnPlaceholders(PowerPointShapeExport& rDML, sal_uInt32 nMasterNum);
|
||||
|
||||
void FindEquivalentMasterPages();
|
||||
sal_uInt32 GetEquivalentMasterPage(sal_uInt32 nMasterPage);
|
||||
|
||||
@@ -2208,7 +2208,7 @@ void PowerPointExport::ImplWriteSlideMaster(sal_uInt32 nPageNum, Reference< XPro
|
||||
// every layout.
|
||||
if (aXBackgroundPropSet)
|
||||
ImplWriteBackground(pFS, aXBackgroundPropSet);
|
||||
WriteShapeTree(pFS, MASTER, true, /*bSlideMasterPart=*/true);
|
||||
WriteShapeTree(pFS, MASTER, true, /*bSlideMasterPart=*/true, nPageNum);
|
||||
|
||||
pFS->endElementNS(XML_p, XML_cSld);
|
||||
|
||||
@@ -2588,7 +2588,7 @@ void PowerPointExport::ImplWritePPTXLayoutWithContent(
|
||||
}
|
||||
|
||||
void PowerPointExport::WriteShapeTree(const FSHelperPtr& pFS, PageType ePageType, bool bMaster,
|
||||
bool bSlideMasterPart)
|
||||
bool bSlideMasterPart, sal_uInt32 nMasterNum)
|
||||
{
|
||||
PowerPointShapeExport aDML(pFS, &maShapeMap, this);
|
||||
aDML.SetMaster(bMaster);
|
||||
@@ -2650,6 +2650,8 @@ void PowerPointExport::WriteShapeTree(const FSHelperPtr& pFS, PageType ePageType
|
||||
WritePlaceholderReferenceShapes(aDML, ePageType);
|
||||
if ( ePageType == LAYOUT )
|
||||
WriteLayoutContentPlaceholders(aDML);
|
||||
if (bSlideMasterPart)
|
||||
WriteMasterOwnPlaceholders(aDML, nMasterNum);
|
||||
pFS->endElementNS(XML_p, XML_spTree);
|
||||
}
|
||||
|
||||
@@ -3282,6 +3284,41 @@ void PowerPointExport::WriteLayoutContentPlaceholders(PowerPointShapeExport& rDM
|
||||
}
|
||||
}
|
||||
|
||||
void PowerPointExport::WriteMasterOwnPlaceholders(PowerPointShapeExport& rDML,
|
||||
sal_uInt32 nMasterNum)
|
||||
{
|
||||
SdPage* pPage = SdPage::getImplementation(mXDrawPage);
|
||||
if (!pPage)
|
||||
return;
|
||||
|
||||
for (const auto& [ePlaceholder, ePresObjKind] :
|
||||
{ std::pair(Title, PresObjKind::Title), std::pair(Outliner, PresObjKind::Outline) })
|
||||
{
|
||||
assert(isPlaceholderAllowedOnSlideMaster(ePlaceholder));
|
||||
if (pPage->GetPresObj(ePresObjKind))
|
||||
continue; // the shape tree has written the page's own
|
||||
|
||||
// The pages standing for one slide master are its layouts, and a layout placeholder was
|
||||
// imported with the geometry and the formatting it inherits from the master, so the first
|
||||
// of them to carry this type carries the master's prototype of it. A layout that states
|
||||
// its own geometry gives that instead - the closest thing left to ask.
|
||||
for (sal_uInt32 i = 0; i < mnMasterPages; ++i)
|
||||
{
|
||||
if (i == mnCanvasMasterIndex
|
||||
|| (i != nMasterNum && maEquivalentMasters[i] != nMasterNum))
|
||||
continue;
|
||||
|
||||
SdPage* pOther = dynamic_cast<SdPage*>(maMastersLayouts[i].first);
|
||||
SdrObject* pObj = pOther ? pOther->GetPresObj(ePresObjKind) : nullptr;
|
||||
if (!pObj)
|
||||
continue;
|
||||
|
||||
rDML.WritePlaceholderShape(GetXShapeForSdrObject(pObj), ePlaceholder);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sal_Int32 PowerPointExport::GetOrCreatePlaceholderIndex(const css::uno::Reference<XShape> &rXShape)
|
||||
{
|
||||
// One index per shape, however many parts write it: a slide's placeholder pairs with the
|
||||
|
||||
Reference in New Issue
Block a user