summaryrefslogtreecommitdiff
path: root/writerfilter/source/dmapper
diff options
context:
space:
mode:
authorJean-Sebastien Bevilacqua <realitix@gmail.com>2017-02-16 10:16:50 +0100
committerMiklos Vajna <vmiklos@collabora.co.uk>2017-03-28 07:05:30 +0000
commit4d5ce76d894d2335b551f8c2b29437e2049894f0 (patch)
tree152ac7f5dabfc7f7cb1df385dac8ed63a3afa1d1 /writerfilter/source/dmapper
parentb3549aacabffad3c4c66d901938d59e4789eef22 (diff)
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@libreoffice.org> Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Diffstat (limited to 'writerfilter/source/dmapper')
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx46
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.hxx4
2 files changed, 46 insertions, 4 deletions
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,