From 388360bb0731c9b5046a2004e799cbaebcd2aaed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCl=C5=9Fah=20K=C3=B6se?= Date: Tue, 15 Sep 2026 16:31:22 +0300 Subject: [PATCH] cool#16218 writerfilter: apply the table alignment a table style sets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A table that took its alignment only from the w:jc of its table style imported left aligned. TablePropertiesHandler keeps the alignment in TablePropertyMap's setValue() channel, which only another TablePropertyMap copies. The style path hands the properties to the plain PropertyMap of the style entry, so the value was dropped there, and endTableGetTableStyle() then wrote the left default over the style. Store the alignment as a plain property as well, for the whole table part of a style only, and start from it in endTableGetTableStyle() so direct formatting and the floating table frame properties still win. Signed-off-by: Gülşah Köse Change-Id: I31ca48f77ba3388e950ff8edcd0d61a71055c853 Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/12632 Reviewed-by: Mike Kaganski Tested-by: Jenkins CPCI (cherry picked from commit b04ae23b97badfc8b617a9c2b8a492cfab754657) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/211103 Tested-by: Jenkins Reviewed-by: Xisco Fauli --- .../ooxmlexport/data/table-style-jc.docx | Bin 0 -> 1957 bytes sw/qa/extras/ooxmlexport/ooxmlexport27.cxx | 28 ++++++++++++++++++ .../dmapper/DomainMapperTableHandler.cxx | 10 ++++++- .../dmapper/TblStylePrHandler.cxx | 15 ++++++++++ 4 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 sw/qa/extras/ooxmlexport/data/table-style-jc.docx diff --git a/sw/qa/extras/ooxmlexport/data/table-style-jc.docx b/sw/qa/extras/ooxmlexport/data/table-style-jc.docx new file mode 100644 index 0000000000000000000000000000000000000000..22ddb3d93c07140aca9eedbe11c94edcf4dd6c56 GIT binary patch literal 1957 zcmWIWW@Zs#U|`^2FwEAE&8yh(|2L4Q$Hc%O45Xu-^Ycnl^Gf1FDhpDJWA!R>bJkAW z?RVHfr0u(1>(i}XG7)zupV?jY8j4e$FV~BiwYQ zgKq_&U~S;92{KQLe40BJ+)H#QylZ0a#5(`tbFK5Td$Q#>w9h^J=3~IR>581Xg=PCC z(x*KUSZvBwbn)oD*ZEUkxvcR1^kU&fmnd;&adFPgpNt<&sn*n=+~f9*OVhqtTkoUb zBr&TMbG1+Y`aX->+WEe8>+?T%#DW7nLgwAM`D=}ZLEYc$e5WS6{`xQK{a!pyrha#H zEmHt6thj)o!T=5{Fat`k0qOXn)SO~{kQzjIT6s!0Yy`?_Gcqu6!`0}4RQ8^?<~wA- z!}ehB@{T>1xA1T*Tox-36duASpqeLj(Pm1Ed%iy#TbG1H?*D%}=65fjdD5qtl`eTD zm6c^}K~VJ32S#(usuc_iwST_RF^Vv7x-NEBGJW1Bzd2j_Rg}$)W(0j=_gXyT!iNZ} zelveJaUTDjJY7|K>tYn|hF$Gz^Jl&_)wAlP!k0~KMmlo;H{P|#YIIl6W6S+j_(*$V zs+@=#8^5^9)c0jGBNya4hwE=U%8lFitU#ZY=NF}*d0yI``I|V<<9C3GNf4$aB|o_| z7nq_zN$G5mt^Z*IfxEx8b>3fTWL&tyv)yZhl15V58}Fni`Zt$l{zWBOr0n3_#pquL!=^y{S+S)7WQCQJiosg0ikMCd8%%@!H zEN3vy*T(`N2#37zO8x^^FByene9-hEnrGI!sfPl_M#oBZQ9=1 zQ*!3WET1Da_j2-yqs3CD6BgPO#$IIJ*2?hdgf#Dz)Dzlvk3}>(=O37T@$sHdXVe*f zuly!3WzH$S&j(-TAMt;~<;m@?W2oJ6zbbXX{6kJFZ$IFP>byTg&{*%x#q@KN4p|-4 zIiUCPv1e)Rt~)&oYlO8!ooD~+bPQq@=;S$d%--tAwX2Eo*^&8n45&%yeu;w9U0~?# z0fr<$EEJ1NDsxhcL18$z?;tQc^0d9L?mAIE?GWR_tham~9(M$K*iQ&uF7ukBWu{$Q zJ;~`IlhdQL=f6MyzWw%oQ+T?MjZ4;pqUc7aO&58un0~0)v3m#O(WDcS@|@B$CMMp` zD+@krRGl*Qzwq^7=DjB(vd?Zio=_p}zT`|?5|`VjSyr}3pBxj>HG2N*!Pn5x*w+bc zO=Y?v!MdMk@ON5Pwd}bSK22gC*O{iLshszAv*k@>5#DuplCEru(@G2J|Grn*ueF}O zXurg0&Ks%C-fI&69{u`!;{QxrzF2*GYuy+83qy?d|6C)yeRetSBnQe&;3S7F*UgNM z+p`|1Kn56OGN=lXlOHr2p5{7aAi#Q|cE8e@d&^1{m3(&#E{t9&FEHsP^JgXDqyP3Y znv2Ek*uzu&&gb&pHHrQ`TPoBS=xHasm~y>)Hp`v1)9*NXCY3}+yAI|#ceq;;qW@M6MMiemU z1vb#P3_xEqY-t3suoT}A18|pOAZ-i`0t|m0b%5r;LKoFi^imC^17c|aTn{*K@mU5c zG#~(EnHI2&fEFRBcA*y{AT1EPd|_IU;}ku7&~pz$`($RQjflL2&$*xk2LT}G&SgPM leyEN{PkJnge%)#&gsAWAkm;gw(w3`3` literal 0 HcmV?d00001 diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport27.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport27.cxx index 0f95241d4078..0f659a284115 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport27.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport27.cxx @@ -13,9 +13,11 @@ #include #include #include +#include #include #include #include +#include #include #include @@ -257,6 +259,32 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf146973_rtlDateLocale) assertXPathNoAttribute(pXmlDoc, "(//w:r[w:instrText])[1]/w:rPr/w:lang", "val"); } +CPPUNIT_TEST_FIXTURE(Test, testTableAlignmentFromTableStyle) +{ + // The first table takes its alignment from the w:jc of its table style, the second one + // overrides the w:jc of its style with a direct one. + auto verify = [this]() { + uno::Reference xSupplier(mxComponent, uno::UNO_QUERY_THROW); + uno::Reference xTables = xSupplier->getTextTables(); + + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 2 + // - Actual : 7 + // i.e. the table was left aligned, the w:jc of the table style having been dropped. + CPPUNIT_ASSERT_EQUAL( + text::HoriOrientation::CENTER, + getProperty(xTables->getByName(u"Table1"_ustr), u"HoriOrient"_ustr)); + CPPUNIT_ASSERT_EQUAL( + text::HoriOrientation::LEFT_AND_WIDTH, + getProperty(xTables->getByName(u"Table2"_ustr), u"HoriOrient"_ustr)); + }; + + createSwDoc("table-style-jc.docx"); + verify(); + saveAndReload(TestFilter::DOCX); + verify(); +} + } // end of anonymous namespace CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/writerfilter/dmapper/DomainMapperTableHandler.cxx b/sw/source/writerfilter/dmapper/DomainMapperTableHandler.cxx index 7b21d26c650c..49aff0f5c16e 100644 --- a/sw/source/writerfilter/dmapper/DomainMapperTableHandler.cxx +++ b/sw/source/writerfilter/dmapper/DomainMapperTableHandler.cxx @@ -676,7 +676,15 @@ TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo } sal_Int32 nHoriOrient = text::HoriOrientation::LEFT_AND_WIDTH; - // Fetch Horizontal Orientation in rFrameProperties if not set in m_aTableProperties + // The table style carries the alignment as a plain property. + if (const std::optional oStyleHoriOrient + = m_aTableProperties->getProperty(PROP_HORI_ORIENT)) + { + sal_Int16 nStyleHoriOrient{}; + if (oStyleHoriOrient->second >>= nStyleHoriOrient) + nHoriOrient = nStyleHoriOrient; + } + // Direct formatting wins over it, then Horizontal Orientation in rFrameProperties. if ( !m_aTableProperties->getValue( TablePropertyMap::HORI_ORIENT, nHoriOrient ) ) lcl_extractHoriOrient( rFrameProperties, nHoriOrient ); m_aTableProperties->Insert( PROP_HORI_ORIENT, uno::Any( sal_Int16(nHoriOrient) ) ); diff --git a/sw/source/writerfilter/dmapper/TblStylePrHandler.cxx b/sw/source/writerfilter/dmapper/TblStylePrHandler.cxx index 3ad0375381af..1b6ec15cde1b 100644 --- a/sw/source/writerfilter/dmapper/TblStylePrHandler.cxx +++ b/sw/source/writerfilter/dmapper/TblStylePrHandler.cxx @@ -22,6 +22,7 @@ #include "CellMarginHandler.hxx" #include "PropertyMap.hxx" #include "MeasureHandler.hxx" +#include "ConversionHelper.hxx" #include #include @@ -161,6 +162,20 @@ void TblStylePrHandler::lcl_sprm(Sprm & rSprm) } } break; + case NS_ooxml::LN_CT_TrPrBase_jc: + case NS_ooxml::LN_CT_TblPrBase_jc: + { + // Table alignment: keep it as a property, the TablePropertyMap value that + // TablePropertiesHandler sets does not survive the copy into a style entry. + // Whole table only, the conditional formats (w:tblStylePr) feed cells. + if ( m_nType == TblStyleType::Unknown || m_nType == TblStyleType::WholeTable ) + { + const Value* pValue = rSprm.getValue(); + m_pProperties->Insert( PROP_HORI_ORIENT, uno::Any( + ConversionHelper::convertTableJustification( pValue ? pValue->getInt() : 0 ) ) ); + } + } + break; case NS_ooxml::LN_CT_TrPrBase_tblHeader: { m_pProperties->Insert( PROP_HEADER_ROW_COUNT, uno::Any(sal_Int32(1)));