tdf#173194 sw: export a derived Table Heading as TH
A table cell whose first paragraph uses a style inherited from Table Heading was tagged TD, so a screen reader announces it as data rather than as a header; only the built-in style itself became TH. lcl_IsHeadlineCell compared the paragraph's own style name and stopped there. Walk the DerivedFrom() chain, the way the HTML table writer already does. Scope stays Column on every TH, so a row header still claims its column; that is a defect of its own. Signed-off-by: Mike Kaganski <mike.kaganski@collabora.com> Change-Id: I9ccbd1b3837d3edc5087162a143560e8412a846d Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/12168 Tested-by: Jenkins CPCI <releng@collaboraoffice.com> Reviewed-by: Miklos Vajna <vmiklos@collabora.com> (cherry picked from commit 270d087cad2c8327775ce204371830c34eecc0d7) (cherry picked from commit d86b837d439355e62afcdd6b771603c260bc5949) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/211049 Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org> Tested-by: Jenkins
This commit is contained in:
committed by
Xisco Fauli
parent
2859ce7e5b
commit
dfdee8ff8a
@@ -224,7 +224,7 @@ constexpr OUString aLinkString = u"Link"_ustr;
|
||||
constexpr OUStringLiteral aNoteString = u"Note";
|
||||
constexpr OUStringLiteral aAnnotString = u"Annot";
|
||||
|
||||
// returns true if first paragraph in cell frame has 'table heading' style
|
||||
// returns true if first paragraph in cell frame has 'table heading' style, or one derived from it
|
||||
bool lcl_IsHeadlineCell( const SwCellFrame& rCellFrame )
|
||||
{
|
||||
bool bRet = false;
|
||||
@@ -233,11 +233,14 @@ bool lcl_IsHeadlineCell( const SwCellFrame& rCellFrame )
|
||||
if ( pCnt && pCnt->IsTextFrame() )
|
||||
{
|
||||
SwTextNode const*const pTextNode = static_cast<const SwTextFrame*>(pCnt)->GetTextNodeForParaProps();
|
||||
const SwFormat* pTextFormat = pTextNode->GetFormatColl();
|
||||
|
||||
ProgName sStyleName;
|
||||
SwStyleNameMapper::FillProgName( pTextFormat->GetName(), sStyleName, SwGetPoolIdFromName::TxtColl );
|
||||
bRet = sStyleName.toString() == aTableHeadingName;
|
||||
for (const SwFormat* pFormat = pTextNode->GetFormatColl(); pFormat && !bRet;
|
||||
pFormat = pFormat->DerivedFrom())
|
||||
{
|
||||
ProgName sStyleName;
|
||||
SwStyleNameMapper::FillProgName(pFormat->GetName(), sStyleName,
|
||||
SwGetPoolIdFromName::TxtColl);
|
||||
bRet = sStyleName == aTableHeadingName;
|
||||
}
|
||||
}
|
||||
|
||||
// tdf#153935 wild guessing for 1st row based on table autoformat
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
|
||||
<office:meta><dc:title>Table heading style and one derived from it</dc:title></office:meta>
|
||||
<office:font-face-decls>
|
||||
<style:font-face style:name="Liberation Serif" svg:font-family="'Liberation Serif'" style:font-family-generic="roman" style:font-pitch="variable"/>
|
||||
</office:font-face-decls>
|
||||
<office:styles>
|
||||
<style:default-style style:family="paragraph">
|
||||
<style:text-properties style:font-name="Liberation Serif" fo:font-size="12pt" fo:language="en" fo:country="US" style:font-name-asian="Liberation Serif" style:font-size-asian="12pt" style:font-name-complex="Liberation Serif" style:font-size-complex="12pt"/>
|
||||
</style:default-style>
|
||||
<style:style style:name="Standard" style:family="paragraph" style:class="text"/>
|
||||
<style:style style:name="Table_20_Contents" style:display-name="Table Contents" style:family="paragraph" style:parent-style-name="Standard" style:class="extra"/>
|
||||
<style:style style:name="Table_20_Heading" style:display-name="Table Heading" style:family="paragraph" style:parent-style-name="Table_20_Contents" style:class="extra">
|
||||
<style:text-properties fo:font-weight="bold"/>
|
||||
</style:style>
|
||||
<style:style style:name="CustomTH" style:family="paragraph" style:parent-style-name="Table_20_Heading"/>
|
||||
</office:styles>
|
||||
<office:automatic-styles>
|
||||
<style:page-layout style:name="pm1">
|
||||
<style:page-layout-properties fo:page-width="21cm" fo:page-height="29.7cm" style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm" style:writing-mode="lr-tb"/>
|
||||
</style:page-layout>
|
||||
</office:automatic-styles>
|
||||
<office:master-styles>
|
||||
<style:master-page style:name="Standard" style:page-layout-name="pm1"/>
|
||||
</office:master-styles>
|
||||
<office:body>
|
||||
<office:text>
|
||||
<table:table table:name="Table1">
|
||||
<table:table-column table:number-columns-repeated="2"/>
|
||||
<table:table-row>
|
||||
<table:table-cell office:value-type="string"><text:p text:style-name="Table_20_Heading">head</text:p></table:table-cell>
|
||||
<table:table-cell office:value-type="string"><text:p text:style-name="Table_20_Contents">one</text:p></table:table-cell>
|
||||
</table:table-row>
|
||||
<table:table-row>
|
||||
<table:table-cell office:value-type="string"><text:p text:style-name="CustomTH">derived</text:p></table:table-cell>
|
||||
<table:table-cell office:value-type="string"><text:p text:style-name="Table_20_Contents">two</text:p></table:table-cell>
|
||||
</table:table-row>
|
||||
</table:table>
|
||||
</office:text>
|
||||
</office:body>
|
||||
</office:document>
|
||||
@@ -2181,6 +2181,70 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest2, testTdf149140)
|
||||
CPPUNIT_ASSERT_EQUAL(6, nTH);
|
||||
}
|
||||
|
||||
// the structure element type of a table cell that a row's kid refers to
|
||||
OString GetCellType(vcl::filter::PDFElement* pElement)
|
||||
{
|
||||
auto pRef = dynamic_cast<vcl::filter::PDFReferenceElement*>(pElement);
|
||||
CPPUNIT_ASSERT(pRef);
|
||||
auto pCell = pRef->LookupObject();
|
||||
CPPUNIT_ASSERT(pCell);
|
||||
auto pS = dynamic_cast<vcl::filter::PDFNameElement*>(pCell->Lookup("S"_ostr));
|
||||
CPPUNIT_ASSERT(pS);
|
||||
return pS->GetValue();
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(PdfExportTest2, testTdf173194)
|
||||
{
|
||||
loadFromFile(u"TableHeadingDerived.fodt");
|
||||
|
||||
uno::Sequence aFilterData{ comphelper::makePropertyValue(u"PDFUACompliance"_ustr, true) };
|
||||
save(TestFilter::PDF_WRITER,
|
||||
{ comphelper::makePropertyValue(u"FilterData"_ustr, aFilterData) });
|
||||
|
||||
SvFileStream aStream(maTempFile.GetURL(), StreamMode::READ);
|
||||
vcl::filter::PDFDocument aDocument;
|
||||
CPPUNIT_ASSERT(aDocument.Read(aStream));
|
||||
|
||||
vcl::filter::PDFObjectElement* pTableSE(nullptr);
|
||||
for (const auto& rDocElement : aDocument.GetElements())
|
||||
{
|
||||
auto pObject = dynamic_cast<vcl::filter::PDFObjectElement*>(rDocElement.get());
|
||||
if (!pObject)
|
||||
continue;
|
||||
auto pType = dynamic_cast<vcl::filter::PDFNameElement*>(pObject->Lookup("Type"_ostr));
|
||||
auto pS = dynamic_cast<vcl::filter::PDFNameElement*>(pObject->Lookup("S"_ostr));
|
||||
if (pType && pType->GetValue() == "StructElem" && pS && pS->GetValue() == "Table")
|
||||
{
|
||||
CPPUNIT_ASSERT(!pTableSE);
|
||||
pTableSE = pObject;
|
||||
}
|
||||
}
|
||||
CPPUNIT_ASSERT(pTableSE);
|
||||
|
||||
auto pRows = dynamic_cast<vcl::filter::PDFArrayElement*>(pTableSE->Lookup("K"_ostr));
|
||||
CPPUNIT_ASSERT(pRows);
|
||||
CPPUNIT_ASSERT_EQUAL(size_t(2), pRows->GetElements().size());
|
||||
|
||||
// the first column is Table Heading in row one and a style derived from it in row two,
|
||||
// so both rows read TH then TD
|
||||
for (const auto pRowElement : pRows->GetElements())
|
||||
{
|
||||
auto pRowRef = dynamic_cast<vcl::filter::PDFReferenceElement*>(pRowElement);
|
||||
CPPUNIT_ASSERT(pRowRef);
|
||||
auto pRow = pRowRef->LookupObject();
|
||||
CPPUNIT_ASSERT(pRow);
|
||||
auto pRowS = dynamic_cast<vcl::filter::PDFNameElement*>(pRow->Lookup("S"_ostr));
|
||||
CPPUNIT_ASSERT(pRowS);
|
||||
CPPUNIT_ASSERT_EQUAL("TR"_ostr, pRowS->GetValue());
|
||||
|
||||
auto pCells = dynamic_cast<vcl::filter::PDFArrayElement*>(pRow->Lookup("K"_ostr));
|
||||
CPPUNIT_ASSERT(pCells);
|
||||
CPPUNIT_ASSERT_EQUAL(size_t(2), pCells->GetElements().size());
|
||||
CPPUNIT_ASSERT_EQUAL("TH"_ostr, GetCellType(pCells->GetElement(0)));
|
||||
CPPUNIT_ASSERT_EQUAL("TD"_ostr, GetCellType(pCells->GetElement(1)));
|
||||
}
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(PdfExportTest2, testTdf153935)
|
||||
{
|
||||
// tdf#153935: PDF/A-1 + PDF/UA must still emit /Scope on TH and /Tabs on
|
||||
|
||||
Reference in New Issue
Block a user