tdf#170236 sw: import comment anchored inside a math formula
A Word comment whose w:commentReference sits inside <m:oMath> was lost on DOCX import: OOXMLFastContextHandlerLinear/Math buffers every child of the formula and never routes commentReference to handleComment, so comments.xml was never resolved and no annotation was created. Intercept w:commentReference in OOXMLFastContextHandlerLinear: collect its id and resolve it via the existing resolveComment() path once the formula object has been emitted (in OOXMLFastContextHandlerMath::process). The tag is never buffered into the formula, so the Starmath buffer stays balanced and formula import is unaffected. Signed-off-by: Dmitry Kulikov <dkul@altlinux.org> Change-Id: I9b0dccc79d5a7da9294b18f0cb58776a2bd8b553 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207888 Tested-by: Jenkins Reviewed-by: Dan Williams <dcbw@libreoffice.org>
This commit is contained in:
committed by
Dan Williams
parent
f2531aab9b
commit
23b745e20d
Binary file not shown.
@@ -1960,6 +1960,31 @@ CPPUNIT_TEST_FIXTURE(Test, testInlineFormulaTextMode)
|
|||||||
testFitsOnOnePage();
|
testFitsOnOnePage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CPPUNIT_TEST_FIXTURE(Test, testTdf170236CommentInFormula)
|
||||||
|
{
|
||||||
|
// tdf#170236: a w:commentReference inside an m:oMath formula was dropped on import
|
||||||
|
createSwDoc("tdf170236.docx");
|
||||||
|
uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
|
||||||
|
uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
|
||||||
|
uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
|
||||||
|
|
||||||
|
bool bFoundAnnotation = false;
|
||||||
|
while (xFields->hasMoreElements())
|
||||||
|
{
|
||||||
|
uno::Reference<lang::XServiceInfo> xServiceInfo(xFields->nextElement(), uno::UNO_QUERY);
|
||||||
|
if (xServiceInfo->supportsService(u"com.sun.star.text.textfield.Annotation"_ustr))
|
||||||
|
{
|
||||||
|
bFoundAnnotation = true;
|
||||||
|
uno::Reference<beans::XPropertySet> xPropertySet(xServiceInfo, uno::UNO_QUERY);
|
||||||
|
OUString aContent;
|
||||||
|
xPropertySet->getPropertyValue(u"Content"_ustr) >>= aContent;
|
||||||
|
CPPUNIT_ASSERT_EQUAL(u"Hello World!"_ustr, aContent);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CPPUNIT_ASSERT_MESSAGE("No annotation found in document", bFoundAnnotation);
|
||||||
|
}
|
||||||
|
|
||||||
// tests should only be added to ooxmlIMPORT *if* they fail round-tripping in ooxmlEXPORT
|
// tests should only be added to ooxmlIMPORT *if* they fail round-tripping in ooxmlEXPORT
|
||||||
|
|
||||||
} // end of anonymous namespace
|
} // end of anonymous namespace
|
||||||
|
|||||||
@@ -2492,9 +2492,18 @@ void OOXMLFastContextHandlerLinear::lcl_endFastElement(Token_t Element)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uno::Reference< xml::sax::XFastContextHandler >
|
uno::Reference< xml::sax::XFastContextHandler >
|
||||||
OOXMLFastContextHandlerLinear::lcl_createFastChildContext(Token_t,
|
OOXMLFastContextHandlerLinear::lcl_createFastChildContext(Token_t Element,
|
||||||
const uno::Reference< xml::sax::XFastAttributeList >&)
|
const uno::Reference< xml::sax::XFastAttributeList >& Attribs)
|
||||||
{
|
{
|
||||||
|
// tdf#170236: buffering a w:commentReference would feed it to Starmath, which
|
||||||
|
// drops it; capture the id instead and resolve it after the formula (process()).
|
||||||
|
if (Element == W_TOKEN(commentReference))
|
||||||
|
{
|
||||||
|
if (Attribs && Attribs->hasAttribute(W_TOKEN(id)))
|
||||||
|
m_aCommentIds.push_back(Attribs->getValue(W_TOKEN(id)).toInt32());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
uno::Reference< xml::sax::XFastContextHandler > xContextHandler;
|
uno::Reference< xml::sax::XFastContextHandler > xContextHandler;
|
||||||
xContextHandler.set( this );
|
xContextHandler.set( this );
|
||||||
return xContextHandler;
|
return xContextHandler;
|
||||||
@@ -2556,6 +2565,10 @@ void OOXMLFastContextHandlerMath::process()
|
|||||||
else
|
else
|
||||||
pProps->add(NS_ooxml::LN_starmath, pVal, OOXMLProperty::ATTRIBUTE);
|
pProps->add(NS_ooxml::LN_starmath, pVal, OOXMLProperty::ATTRIBUTE);
|
||||||
mpStream->props( pProps.get() );
|
mpStream->props( pProps.get() );
|
||||||
|
|
||||||
|
// tdf#170236: resolve now, so the anchor lands right after the emitted formula
|
||||||
|
for (sal_Int32 nCommentId : m_aCommentIds)
|
||||||
|
resolveComment(nCommentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
OOXMLFastContextHandlerCommentEx::OOXMLFastContextHandlerCommentEx(
|
OOXMLFastContextHandlerCommentEx::OOXMLFastContextHandlerCommentEx(
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
#include <cppuhelper/implbase.hxx>
|
#include <cppuhelper/implbase.hxx>
|
||||||
#include <com/sun/star/uno/XComponentContext.hpp>
|
#include <com/sun/star/uno/XComponentContext.hpp>
|
||||||
#include <com/sun/star/xml/sax/XFastContextHandler.hpp>
|
#include <com/sun/star/xml/sax/XFastContextHandler.hpp>
|
||||||
@@ -596,6 +597,9 @@ protected:
|
|||||||
// should be private, but not much point in making deep copies of it
|
// should be private, but not much point in making deep copies of it
|
||||||
oox::formulaimport::XmlStreamBuilder m_buffer;
|
oox::formulaimport::XmlStreamBuilder m_buffer;
|
||||||
|
|
||||||
|
// tdf#170236: comment ids referenced inside the formula, resolved in Math::process()
|
||||||
|
std::vector<sal_Int32> m_aCommentIds;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_depthCount;
|
int m_depthCount;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user