tdf#166401: keep a placeholder's prompt in ODF
Commit 67ba6ccd5a (tdf#140912, tdf#159219:
fix import of graphic placeholder with custom prompt, 2024-01-17) left
the prompt out of ODF for want of a representation, so a reload replaced
an authored one with our own localized default. It now travels as a
coext:placeholder-prompt attribute beside presentation:placeholder, on
draw:frame and draw:page-thumbnail, written when saving with extensions
and added to the extended schema so the round trip validates. It is
also listed in the Collabora ODF extensions notes.
Signed-off-by: Mike Kaganski <mike.kaganski@collabora.com>
Change-Id: I12b51ff2bc103e5c26e94558802064919c7289dd
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/9070
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
(cherry picked from commit 6b1b6331ada0cc948e880eb83db5506f8bf1aa9c)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/210297
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
This commit is contained in:
committed by
Xisco Fauli
parent
6a4ef93a54
commit
64fe896867
@@ -1566,6 +1566,7 @@ namespace xmloff::token {
|
||||
XML_PHYSICS_ANIMATION_BOUNCINESS,
|
||||
XML_PIE_OFFSET,
|
||||
XML_PLACEHOLDER,
|
||||
XML_PLACEHOLDER_PROMPT,
|
||||
XML_PLACEHOLDER_TYPE,
|
||||
XML_PLACING,
|
||||
XML_PLAIN_NUMBER,
|
||||
|
||||
@@ -2469,6 +2469,14 @@ xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.
|
||||
</rng:attribute>
|
||||
</rng:optional>
|
||||
</rng:define>
|
||||
<!-- The prompt an empty placeholder shows, when the document authors one of its own. -->
|
||||
<rng:define name="presentation-shape-attlist" combine="interleave">
|
||||
<rng:optional>
|
||||
<rng:attribute name="loext:placeholder-prompt">
|
||||
<rng:ref name="string"/>
|
||||
</rng:attribute>
|
||||
</rng:optional>
|
||||
</rng:define>
|
||||
<rng:define name="loext-columns-and-groups">
|
||||
<rng:oneOrMore>
|
||||
<rng:choice>
|
||||
|
||||
@@ -353,6 +353,39 @@ CPPUNIT_TEST_FIXTURE(SdExportTest2, testAnimationSoundExternalImportPPTX)
|
||||
CPPUNIT_ASSERT(xmloff::getSoundAllowed(xAudio->getSource()));
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(SdExportTest2, testPlaceholderPromptODFRoundTrip)
|
||||
{
|
||||
// Given one layout whose picture placeholder authored a prompt, and another whose authored
|
||||
// none - a slide layout arrives as a master page, so that is where to look for them:
|
||||
createSdImpressDoc("pptx/picture-placeholder-custom-prompt.pptx");
|
||||
saveAndReload(TestFilter::ODP);
|
||||
|
||||
auto xMPs = mxComponent.queryThrow<drawing::XMasterPagesSupplier>()->getMasterPages();
|
||||
OUString aPrompt;
|
||||
sal_Int32 nPrompts = 0;
|
||||
for (sal_Int32 nPage = 0; nPage < xMPs->getCount(); ++nPage)
|
||||
{
|
||||
auto xShapes = xMPs->getByIndex(nPage).queryThrow<drawing::XShapes>();
|
||||
for (sal_Int32 nShape = 0; nShape < xShapes->getCount(); ++nShape)
|
||||
{
|
||||
auto xProps = xShapes->getByIndex(nShape).queryThrow<beans::XPropertySet>();
|
||||
OUString aShapePrompt;
|
||||
if (xProps->getPropertySetInfo()->hasPropertyByName(u"CustomPromptText"_ustr)
|
||||
&& (xProps->getPropertyValue(u"CustomPromptText"_ustr) >>= aShapePrompt)
|
||||
&& !aShapePrompt.isEmpty())
|
||||
{
|
||||
aPrompt = aShapePrompt;
|
||||
++nPrompts;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The authored prompt survives ODF, which has no representation of its own for one. Without
|
||||
// the accompanying fix nothing carried it, and the reload showed a localized default instead.
|
||||
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), nPrompts);
|
||||
CPPUNIT_ASSERT_EQUAL(u"Custom prompt to insert an image"_ustr, aPrompt);
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(SdExportTest2, testAnimationSoundEmbeddedImportPPTX)
|
||||
{
|
||||
// A PPTX animation sound embedded in the package becomes package content,
|
||||
|
||||
@@ -1578,6 +1578,7 @@ namespace xmloff::token {
|
||||
TOKEN( "bounciness", XML_PHYSICS_ANIMATION_BOUNCINESS ),
|
||||
TOKEN( "pie-offset", XML_PIE_OFFSET ),
|
||||
TOKEN( "placeholder", XML_PLACEHOLDER ),
|
||||
TOKEN( "placeholder-prompt", XML_PLACEHOLDER_PROMPT ),
|
||||
TOKEN( "placeholder-type", XML_PLACEHOLDER_TYPE ),
|
||||
TOKEN( "placing", XML_PLACING ),
|
||||
TOKEN( "plain-number", XML_PLAIN_NUMBER ),
|
||||
|
||||
@@ -1735,6 +1735,17 @@ bool XMLShapeExport::ImpExportPresentationAttributes( const uno::Reference< bean
|
||||
if(!bTemp)
|
||||
mrExport.AddAttribute(XML_NAMESPACE_PRESENTATION, XML_USER_TRANSFORMED, XML_TRUE);
|
||||
}
|
||||
|
||||
// ODF has no representation for the prompt an empty placeholder shows, so an authored one
|
||||
// travels as an extension; otherwise a reload replaces it with our own localized default.
|
||||
if (xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(u"CustomPromptText"_ustr)
|
||||
&& (mrExport.getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED))
|
||||
{
|
||||
OUString aPrompt;
|
||||
xPropSet->getPropertyValue(u"CustomPromptText"_ustr) >>= aPrompt;
|
||||
if (!aPrompt.isEmpty())
|
||||
mrExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_PLACEHOLDER_PROMPT, aPrompt);
|
||||
}
|
||||
}
|
||||
|
||||
return bIsEmpty;
|
||||
|
||||
@@ -355,6 +355,14 @@ void SdXMLShapeContext::endFastElement(sal_Int32 )
|
||||
GetImport().GetTextImport()->PopListContext();
|
||||
}
|
||||
|
||||
// Applied once the text is in, because setting it is what makes an empty placeholder show it.
|
||||
if (!maPlaceholderPrompt.isEmpty())
|
||||
{
|
||||
auto xProp = mxShape.query<beans::XPropertySet>();
|
||||
if (xProp && xProp->getPropertySetInfo()->hasPropertyByName(u"CustomPromptText"_ustr))
|
||||
xProp->setPropertyValue(u"CustomPromptText"_ustr, uno::Any(maPlaceholderPrompt));
|
||||
}
|
||||
|
||||
if( !msHyperlink.isEmpty() ) try
|
||||
{
|
||||
uno::Reference< beans::XPropertySet > xProp( mxShape, uno::UNO_QUERY );
|
||||
@@ -853,6 +861,9 @@ bool SdXMLShapeContext::processAttribute( const sax_fastparser::FastAttributeLis
|
||||
case XML_ELEMENT(PRESENTATION, XML_CLASS):
|
||||
maPresentationClass = aIter.toString();
|
||||
break;
|
||||
case XML_ELEMENT(LO_EXT, XML_PLACEHOLDER_PROMPT):
|
||||
maPlaceholderPrompt = aIter.toString();
|
||||
break;
|
||||
case XML_ELEMENT(PRESENTATION, XML_STYLE_NAME):
|
||||
maDrawStyleName = aIter.toString();
|
||||
mnStyleFamily = XmlStyleFamily::SD_PRESENTATION_ID;
|
||||
|
||||
@@ -55,6 +55,7 @@ protected:
|
||||
OUString maDrawStyleName;
|
||||
OUString maTextStyleName;
|
||||
OUString maPresentationClass;
|
||||
OUString maPlaceholderPrompt;
|
||||
OUString maShapeName;
|
||||
OUString maThumbnailURL;
|
||||
|
||||
|
||||
@@ -1477,6 +1477,7 @@ density
|
||||
bounciness
|
||||
pie-offset
|
||||
placeholder
|
||||
placeholder-prompt
|
||||
placeholder-type
|
||||
placing
|
||||
plain-number
|
||||
|
||||
Reference in New Issue
Block a user