diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2019-05-29 17:26:57 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2019-05-30 17:43:12 +0200 |
commit | 4a504709498628378bcdf576a7e2da85d33e20a3 (patch) | |
tree | 95c85b0bcb7df1c7348492884505b22431e15ac8 | |
parent | 8a556a1509bbb04eb00bea41761f5616927ac773 (diff) |
ODT export: fix lost <text:user-field-decl> for fields in tables in headers
The problem was that XMLTextFieldExport::ExportFieldAutoStyle() assumed
that the text of a field anchor is always the toplevel XText, which is
true in case of body vs header text, but false in case header text vs
text-in-table-in-header.
So add an UNO property which exposes the parent of a table cell, this
way text in header (regardless of it's in a table or not) will have the
same XText, leading to writing the necessary <text:user-field-decl>
element for the matching <text:user-field-get> definition.
(cherry picked from commit 6bb241ccc61c6904efec95978fa17e33c0eb1df3)
Conflicts:
offapi/com/sun/star/text/CellProperties.idl
sw/inc/cmdid.h
sw/inc/unoprnms.hxx
sw/source/filter/xml/xmlfmte.cxx
Change-Id: I077b8d7e9dfae4062539894318637e266b925382
Reviewed-on: https://gerrit.libreoffice.org/73176
Tested-by: Jenkins
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
-rw-r--r-- | offapi/com/sun/star/text/CellProperties.idl | 7 | ||||
-rw-r--r-- | sw/inc/cmdid.h | 1 | ||||
-rw-r--r-- | sw/inc/unoprnms.hxx | 1 | ||||
-rw-r--r-- | sw/inc/unotbl.hxx | 1 | ||||
-rw-r--r-- | sw/qa/extras/odfexport/data/user-field-decl.odt | bin | 0 -> 8597 bytes | |||
-rw-r--r-- | sw/qa/extras/odfexport/odfexport.cxx | 8 | ||||
-rw-r--r-- | sw/source/core/unocore/unomap.cxx | 1 | ||||
-rw-r--r-- | sw/source/core/unocore/unotbl.cxx | 23 | ||||
-rw-r--r-- | sw/source/filter/xml/xmlfmte.cxx | 1 | ||||
-rw-r--r-- | xmloff/source/text/txtflde.cxx | 29 |
10 files changed, 71 insertions, 1 deletions
diff --git a/offapi/com/sun/star/text/CellProperties.idl b/offapi/com/sun/star/text/CellProperties.idl index 6144d9fc8530..f2a26fe9abd7 100644 --- a/offapi/com/sun/star/text/CellProperties.idl +++ b/offapi/com/sun/star/text/CellProperties.idl @@ -122,6 +122,13 @@ published service CellProperties */ [property] short VertOrient; + /** Parent text of this table cell. + + This might be a header text, body text, parent cell, etc. + + @since LibreOffice 6.3 + */ + [optional, readonly, property] com::sun::star::text::XText ParentText; }; diff --git a/sw/inc/cmdid.h b/sw/inc/cmdid.h index e626bbb93458..f91a1fd6489c 100644 --- a/sw/inc/cmdid.h +++ b/sw/inc/cmdid.h @@ -513,6 +513,7 @@ #define FN_UNO_FOOTER (FN_EXTRA2 + 38) #define FN_UNO_FOOTER_LEFT (FN_EXTRA2 + 39) #define FN_UNO_FOOTER_RIGHT (FN_EXTRA2 + 40) +#define FN_UNO_PARENT_TEXT (FN_EXTRA2 + 42) #define FN_UNO_FOLLOW_STYLE (FN_EXTRA2 + 59) #define FN_API_CALL (FN_EXTRA2 + 60) diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx index 24cc71cb8740..7a3aa2f95d32 100644 --- a/sw/inc/unoprnms.hxx +++ b/sw/inc/unoprnms.hxx @@ -391,6 +391,7 @@ #define UNO_NAME_FOOTER_BODY_DISTANCE "FooterBodyDistance" #define UNO_NAME_FOOTER_IS_DYNAMIC_HEIGHT "FooterIsDynamicHeight" #define UNO_NAME_FOOTER_IS_SHARED "FooterIsShared" +#define UNO_NAME_PARENT_TEXT "ParentText" #define UNO_NAME_FOOTER_HEIGHT "FooterHeight" #define UNO_NAME_FOOTER_IS_ON "FooterIsOn" diff --git a/sw/inc/unotbl.hxx b/sw/inc/unotbl.hxx index 7b06cc143e6c..d649c51f8ac7 100644 --- a/sw/inc/unotbl.hxx +++ b/sw/inc/unotbl.hxx @@ -73,6 +73,7 @@ class SwXCell final : public SwXCellBaseClass, // table position where pBox was found last size_t nFndPos; + css::uno::Reference<css::text::XText> m_xParentText; static size_t const NOTFOUND = SAL_MAX_SIZE; virtual const SwStartNode *GetStartNode() const override; diff --git a/sw/qa/extras/odfexport/data/user-field-decl.odt b/sw/qa/extras/odfexport/data/user-field-decl.odt Binary files differnew file mode 100644 index 000000000000..f037f403ec68 --- /dev/null +++ b/sw/qa/extras/odfexport/data/user-field-decl.odt diff --git a/sw/qa/extras/odfexport/odfexport.cxx b/sw/qa/extras/odfexport/odfexport.cxx index e9e458c4a243..e6dc81d274e0 100644 --- a/sw/qa/extras/odfexport/odfexport.cxx +++ b/sw/qa/extras/odfexport/odfexport.cxx @@ -150,6 +150,14 @@ DECLARE_ODFEXPORT_TEST(testTdf103567, "tdf103567.odt") CPPUNIT_ASSERT_EQUAL(sal_Int32( 408), rect.Height); } +DECLARE_ODFEXPORT_TEST(testUserFieldDecl, "user-field-decl.odt") +{ + if (xmlDocPtr pXmlDoc = parseExport("styles.xml")) + // Without the accompanying fix in place, this test would have failed with 'Expected: 2; + // Actual: 1', i.e. the in-table field had no declaration (in the header), while the + // outside-table one had the declaration. + assertXPath(pXmlDoc, "//style:header/text:user-field-decls/text:user-field-decl", 2); +} DECLARE_ODFEXPORT_TEST(testFramebackgrounds, "framebackgrounds.odt") { diff --git a/sw/source/core/unocore/unomap.cxx b/sw/source/core/unocore/unomap.cxx index aa98dbbf7ab9..9c71545d6510 100644 --- a/sw/source/core/unocore/unomap.cxx +++ b/sw/source/core/unocore/unomap.cxx @@ -213,6 +213,7 @@ const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetPropertyMapEntries(s { OUString(UNO_NAME_WRITING_MODE), RES_FRAMEDIR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0 }, { OUString(UNO_NAME_ROW_SPAN), FN_UNO_CELL_ROW_SPAN, cppu::UnoType<sal_Int32>::get(), 0, 0 }, { OUString(UNO_NAME_CELL_INTEROP_GRAB_BAG), RES_FRMATR_GRABBAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0 }, + { OUString(UNO_NAME_PARENT_TEXT), FN_UNO_PARENT_TEXT, cppu::UnoType<text::XText>::get(), PropertyAttribute::MAYBEVOID | PropertyAttribute::READONLY, 0 }, REDLINE_NODE_PROPERTIES { OUString(), 0, css::uno::Type(), 0, 0 } }; diff --git a/sw/source/core/unocore/unotbl.cxx b/sw/source/core/unocore/unotbl.cxx index 17c9819dc26a..2fc660b9a8a7 100644 --- a/sw/source/core/unocore/unotbl.cxx +++ b/sw/source/core/unocore/unotbl.cxx @@ -1098,6 +1098,29 @@ uno::Any SwXCell::getPropertyValue(const OUString& rPropertyName) return SwXText::getPropertyValue(rPropertyName); } break; + case FN_UNO_PARENT_TEXT: + { + if (!m_xParentText.is()) + { + const SwStartNode* pSttNd = pBox->GetSttNd(); + if (!pSttNd) + return uno::Any(); + + const SwTableNode* pTableNode = pSttNd->FindTableNode(); + if (!pTableNode) + return uno::Any(); + + SwPosition aPos(*pTableNode); + SwDoc* pDoc = aPos.GetDoc(); + if (!pDoc) + return uno::Any(); + + m_xParentText = sw::CreateParentXText(*pDoc, aPos); + } + + return uno::makeAny(m_xParentText); + } + break; default: { const SwAttrSet& rSet = pBox->GetFrameFormat()->GetAttrSet(); diff --git a/sw/source/filter/xml/xmlfmte.cxx b/sw/source/filter/xml/xmlfmte.cxx index 7ee76a429f9f..25d6ca8f9855 100644 --- a/sw/source/filter/xml/xmlfmte.cxx +++ b/sw/source/filter/xml/xmlfmte.cxx @@ -37,6 +37,7 @@ #include <com/sun/star/drawing/XDrawPageSupplier.hpp> #include "xmlexp.hxx" #include <SwStyleNameMapper.hxx> +#include <sal/log.hxx> using namespace ::com::sun::star::beans; using namespace ::com::sun::star::uno; diff --git a/xmloff/source/text/txtflde.cxx b/xmloff/source/text/txtflde.cxx index 959b2e75162b..e37817ae7d70 100644 --- a/xmloff/source/text/txtflde.cxx +++ b/xmloff/source/text/txtflde.cxx @@ -156,6 +156,31 @@ static sal_Char const FIELD_SERVICE_MEASURE[] = "Measure"; static sal_Char const FIELD_SERVICE_TABLE_FORMULA[] = "TableFormula"; static sal_Char const FIELD_SERVICE_DROP_DOWN[] = "DropDown"; +namespace +{ +/// Walks up the parent chain of xText and returns the topmost text. +uno::Reference<text::XText> GetToplevelText(const uno::Reference<text::XText>& xText) +{ + uno::Reference<text::XText> xRet = xText; + while (true) + { + uno::Reference<beans::XPropertySet> xPropertySet(xRet, uno::UNO_QUERY); + if (!xPropertySet.is()) + return xRet; + + if (!xPropertySet->getPropertySetInfo()->hasPropertyByName("ParentText")) + return xRet; + + uno::Reference<text::XText> xParent; + if (xPropertySet->getPropertyValue("ParentText") >>= xParent) + xRet = xParent; + else + return xRet; + } + return xRet; +} +} + SvXMLEnumStringMapEntry<FieldIdEnum> const aFieldServiceNameMapping[] = { ENUM_STRING_MAP_ENTRY( FIELD_SERVICE_SENDER, FIELD_ID_SENDER ), @@ -747,7 +772,9 @@ void XMLTextFieldExport::ExportFieldAutoStyle( Reference<XDependentTextField> xDepField(rTextField, UNO_QUERY); if (xDepField.is()) { - Reference<XText> xOurText = rTextField->getAnchor()->getText(); + // The direct parent may be just the table cell, while we want the topmost parent, e.g. + // a header text. + Reference<XText> xOurText = GetToplevelText(rTextField->getAnchor()->getText()); map<Reference<XText>, set<OUString> >::iterator aMapIter = pUsedMasters->find(xOurText); |