[Libreoffice-commits] core.git: sw/qa writerfilter/source
Jean-Sebastien Bevilacqua
realitix at gmail.com
Tue Mar 28 07:05:51 UTC 2017
sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx | 2
sw/qa/extras/ooxmlimport/data/105975.docx |binary
sw/qa/extras/ooxmlimport/ooxmlimport.cxx | 8 +++
writerfilter/source/dmapper/DomainMapper_Impl.cxx | 46 ++++++++++++++++++++--
writerfilter/source/dmapper/DomainMapper_Impl.hxx | 4 +
5 files changed, 55 insertions(+), 5 deletions(-)
New commits:
commit 4d5ce76d894d2335b551f8c2b29437e2049894f0
Author: Jean-Sebastien Bevilacqua <realitix at gmail.com>
Date: Thu Feb 16 10:16:50 2017 +0100
tdf#105975 Add Set field parsing (docx) in LibreOffice Writer
Introduction
------------
In MSWord, you can create a variable with `SET` field and then
reference it later in a formula. When you save your file as `docx`,
this `SET` field is registered in you file. In its current state,
LibreOffice can't parse the `SET` field in `docx` file.
Context of this fix
-------------------
This fix is entirely located in the `DomainMapper_Impl.cxx` file
because it's where the parsing is done.
How this fix works
------------------
First, we add `SET` support by adding it to the `aFields[]` variable.
Next, to handle the `SET` constant, we add a condition (swith case) in
`DomainMapper_Impl::CloseFieldCommand()` to call `handleFieldSet`.
Finally, `handleFieldSet` works like `handleFieldAsk` with small
differences.
Note
----
I have renamed `lcl_ExctractAskVariableAndHint` to
`lcl_ExctractVariableAndHint` because this function is used for both `ASK` and
`SET` fields.
Change-Id: I2bf948e26e8506ac151d1d0bc8556721bbe0392b
Reviewed-on: https://gerrit.libreoffice.org/34333
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
diff --git a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
index ec8b13621001..d473a13f73e2 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
@@ -432,7 +432,7 @@ DECLARE_OOXMLEXPORT_TEST(testFDO76163 , "fdo76163.docx")
if (!pXmlDoc)
return;
//docx file after RT is getting corrupted.
- assertXPath ( pXmlDoc, "/w:document/w:body/w:p[2]/w:hyperlink/w:r[11]/w:fldChar", "fldCharType", "end" );
+ assertXPath ( pXmlDoc, "/w:document/w:body/w:p[2]/w:hyperlink/w:r[10]/w:fldChar", "fldCharType", "end" );
}
DECLARE_OOXMLEXPORT_TEST(testFDO78659, "fdo78659.docx")
diff --git a/sw/qa/extras/ooxmlimport/data/105975.docx b/sw/qa/extras/ooxmlimport/data/105975.docx
new file mode 100644
index 000000000000..b902aa168a9a
Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/105975.docx differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index 77880b935b96..87c71b8afb6b 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -699,6 +699,14 @@ DECLARE_OOXMLIMPORT_TEST(testTdf105143, "tdf105143.docx")
CPPUNIT_ASSERT_EQUAL(OUString("6674"), aTop);
}
+DECLARE_OOXMLIMPORT_TEST(testTdf105975, "105975.docx")
+{
+ uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XNameAccess> xMasters(xTextFieldsSupplier->getTextFieldMasters());
+ // Make sure we have a variable named TEST_VAR.
+ CPPUNIT_ASSERT(xMasters->hasByName("com.sun.star.text.FieldMaster.SetExpression.TEST_VAR"));
+}
+
DECLARE_OOXMLIMPORT_TEST(testfdo76583, "fdo76583.docx")
{
// The problem was that the floating table was imported as a non-floating one.
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index c64d9de17889..6189f9f139ab 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -2367,7 +2367,7 @@ std::tuple<OUString, std::vector<OUString>, std::vector<OUString> > splitFieldCo
return std::make_tuple(sType, arguments, switches);
}
-OUString lcl_ExctractAskVariableAndHint( const OUString& rCommand, OUString& rHint )
+OUString lcl_ExctractVariableAndHint( const OUString& rCommand, OUString& rHint )
{
// the first word after "ASK " is the variable
// the text after the variable and before a '\' is the hint
@@ -2862,7 +2862,7 @@ if(!bFilled)
// {OUString("SECTION"), "", FIELD_SECTION },
// {OUString("SECTIONPAGES"), "", FIELD_SECTIONPAGES },
{OUString("SEQ"), "SetExpression", FIELD_SEQ },
-// {OUString("SET"), FIELD_SET },
+ {OUString("SET"), "SetExpression", FIELD_SET },
// {OUString("SKIPIF"),"", FIELD_SKIPIF },
// {OUString("STYLEREF"),"", FIELD_STYLEREF },
{OUString("SUBJECT"), "DocInfo.Subject", FIELD_SUBJECT },
@@ -2928,6 +2928,42 @@ const FieldConversionMap_t & lcl_GetEnhancedFieldConversion()
return aEnhancedFieldConversionMap;
}
+void DomainMapper_Impl::handleFieldSet
+ (const FieldContextPtr& pContext,
+ uno::Reference< uno::XInterface > & xFieldInterface,
+ uno::Reference< beans::XPropertySet > const& xFieldProperties)
+{
+ OUString sVariable, sHint;
+
+ sVariable = lcl_ExctractVariableAndHint(pContext->GetCommand(), sHint);
+
+ // remove surrounding "" if exists
+ if( sHint.getLength() >= 2 && sHint.startsWith("\"") )
+ {
+ sHint = sHint.trim().copy(1, sHint.getLength() - 2);
+ }
+
+ // determine field master name
+ uno::Reference< beans::XPropertySet > xMaster =
+ FindOrCreateFieldMaster
+ ("com.sun.star.text.FieldMaster.SetExpression", sVariable );
+
+ // a set field is a string
+ xMaster->setPropertyValue(getPropertyName(PROP_SUB_TYPE), uno::makeAny(text::SetVariableType::STRING));
+
+ // attach the master to the field
+ uno::Reference< text::XDependentTextField > xDependentField
+ ( xFieldInterface, uno::UNO_QUERY_THROW );
+ xDependentField->attachTextFieldMaster( xMaster );
+
+ xFieldProperties->setPropertyValue(getPropertyName(PROP_HINT), uno::makeAny( sHint ));
+ xFieldProperties->setPropertyValue(getPropertyName(PROP_CONTENT), uno::makeAny( sHint ));
+ xFieldProperties->setPropertyValue(getPropertyName(PROP_SUB_TYPE), uno::makeAny(text::SetVariableType::STRING));
+
+ // Mimic MS Word behavior (hide the SET)
+ xFieldProperties->setPropertyValue(getPropertyName(PROP_IS_VISIBLE), uno::makeAny(false));
+}
+
void DomainMapper_Impl::handleFieldAsk
(const FieldContextPtr& pContext,
uno::Reference< uno::XInterface > & xFieldInterface,
@@ -2936,7 +2972,7 @@ void DomainMapper_Impl::handleFieldAsk
//doesn the command contain a variable name?
OUString sVariable, sHint;
- sVariable = lcl_ExctractAskVariableAndHint( pContext->GetCommand(),
+ sVariable = lcl_ExctractVariableAndHint( pContext->GetCommand(),
sHint );
if(!sVariable.isEmpty())
{
@@ -4099,7 +4135,9 @@ void DomainMapper_Impl::CloseFieldCommand()
uno::makeAny(nNumberingType));
}
break;
- case FIELD_SET : break;
+ case FIELD_SET :
+ handleFieldSet(pContext, xFieldInterface, xFieldProperties);
+ break;
case FIELD_SKIPIF : break;
case FIELD_STYLEREF : break;
case FIELD_SUBJECT :
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index e3071b9abe78..f8924f1e75f4 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -651,6 +651,10 @@ public:
//collect the pieces of the command
void AppendFieldCommand(OUString& rPartOfCommand);
void handleRubyEQField( const FieldContextPtr& pContext);
+ void handleFieldSet
+ (const FieldContextPtr& pContext,
+ css::uno::Reference< css::uno::XInterface > & xFieldInterface,
+ css::uno::Reference< css::beans::XPropertySet > const& xFieldProperties);
void handleFieldAsk
(const FieldContextPtr& pContext,
css::uno::Reference< css::uno::XInterface > & xFieldInterface,
More information about the Libreoffice-commits
mailing list