summaryrefslogtreecommitdiff
path: root/writerfilter
diff options
context:
space:
mode:
authorLászló Németh <nemeth@numbertext.org>2019-04-24 12:30:56 +0200
committerLászló Németh <nemeth@numbertext.org>2019-04-26 08:28:11 +0200
commit071c3309260aeae22f464d26bfa56a747f6a02cb (patch)
treea09f43b6ccbca9d61a48d6075ca23e9ac43bfd49 /writerfilter
parente1a75c1c3069efa303c480d0e50928c0761f468f (diff)
tdf#67207 DOCX mail merge: fix export/import of database fields
to support the registered databases (containing ODS, XLSX sheet or ODT text table data sources). Now database fields don't lose their database connection, and File->Print can merge mails after DOCX export/import, if the LO instance has got a registered database with the same name and table, as in saved in w:settings/w:mailMerge/w:query element of the DOCX document in the form of SELECT * FROM [databaseName].dbo.[tableName]$ query. Notes: – This fix supports only single table usage. – The exported DOCX document is editable in MSO, too, without losing the database connection in LO later. Change-Id: I97826b7ee7defd0243dbaffa0325c5b11dd2c0d1 Reviewed-on: https://gerrit.libreoffice.org/71228 Tested-by: Jenkins Reviewed-by: László Németh <nemeth@numbertext.org>
Diffstat (limited to 'writerfilter')
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx28
-rw-r--r--writerfilter/source/dmapper/PropertyIds.cxx4
-rw-r--r--writerfilter/source/dmapper/PropertyIds.hxx4
-rw-r--r--writerfilter/source/dmapper/SettingsTable.cxx29
-rw-r--r--writerfilter/source/dmapper/SettingsTable.hxx2
5 files changed, 65 insertions, 2 deletions
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 6f49eecf348e..961a88872bff 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -3080,8 +3080,15 @@ uno::Reference<beans::XPropertySet> DomainMapper_Impl::FindOrCreateFieldMaster(c
uno::Reference< beans::XPropertySet > xMaster;
OUString sFieldMasterService( OUString::createFromAscii(pFieldMasterService) );
OUStringBuffer aFieldMasterName;
+ OUString sDatabaseDataSourceName = GetSettingsTable()->GetCurrentDatabaseDataSource();
+ bool bIsMergeField = sFieldMasterService.endsWith("Database");
aFieldMasterName.appendAscii( pFieldMasterService );
aFieldMasterName.append('.');
+ if ( bIsMergeField && !sDatabaseDataSourceName.isEmpty() )
+ {
+ aFieldMasterName.append(sDatabaseDataSourceName);
+ aFieldMasterName.append('.');
+ }
aFieldMasterName.append(rFieldMasterName);
OUString sFieldMasterName = aFieldMasterName.makeStringAndClear();
if(xFieldMasterAccess->hasByName(sFieldMasterName))
@@ -3093,10 +3100,27 @@ uno::Reference<beans::XPropertySet> DomainMapper_Impl::FindOrCreateFieldMaster(c
{
//create the master
xMaster.set( m_xTextFactory->createInstance(sFieldMasterService), uno::UNO_QUERY_THROW);
- //set the master's name
- xMaster->setPropertyValue(
+ if ( !bIsMergeField || sDatabaseDataSourceName.isEmpty() )
+ {
+ //set the master's name
+ xMaster->setPropertyValue(
getPropertyName(PROP_NAME),
uno::makeAny(rFieldMasterName));
+ } else {
+ // set database data, based on the "databasename.tablename" of sDatabaseDataSourceName
+ xMaster->setPropertyValue(
+ getPropertyName(PROP_DATABASE_NAME),
+ uno::makeAny(sDatabaseDataSourceName.copy(0, sDatabaseDataSourceName.indexOf('.'))));
+ xMaster->setPropertyValue(
+ getPropertyName(PROP_COMMAND_TYPE),
+ uno::makeAny(sal_Int32(0)));
+ xMaster->setPropertyValue(
+ getPropertyName(PROP_DATATABLE_NAME),
+ uno::makeAny(sDatabaseDataSourceName.copy(sDatabaseDataSourceName.indexOf('.') + 1)));
+ xMaster->setPropertyValue(
+ getPropertyName(PROP_DATACOLUMN_NAME),
+ uno::makeAny(rFieldMasterName));
+ }
}
return xMaster;
}
diff --git a/writerfilter/source/dmapper/PropertyIds.cxx b/writerfilter/source/dmapper/PropertyIds.cxx
index e51062541d47..28b9092e96e2 100644
--- a/writerfilter/source/dmapper/PropertyIds.cxx
+++ b/writerfilter/source/dmapper/PropertyIds.cxx
@@ -350,6 +350,10 @@ OUString getPropertyName( PropertyIds eId )
case PROP_RUBY_ADJUST: sName = "RubyAdjust"; break;
case PROP_RUBY_POSITION: sName = "RubyPosition"; break;
case PROP_LAYOUT_IN_CELL: sName = "IsLayoutInCell"; break;
+ case PROP_DATABASE_NAME: sName = "DataBaseName"; break;
+ case PROP_COMMAND_TYPE: sName = "DataCommandType"; break;
+ case PROP_DATATABLE_NAME: sName = "DataTableName"; break;
+ case PROP_DATACOLUMN_NAME: sName = "DataColumnName"; break;
}
assert(sName.getLength()>0);
return sName;
diff --git a/writerfilter/source/dmapper/PropertyIds.hxx b/writerfilter/source/dmapper/PropertyIds.hxx
index 331a978d0d42..eed9dd62bb30 100644
--- a/writerfilter/source/dmapper/PropertyIds.hxx
+++ b/writerfilter/source/dmapper/PropertyIds.hxx
@@ -348,6 +348,10 @@ enum PropertyIds
,PROP_RUBY_ADJUST
,PROP_RUBY_POSITION
,PROP_LAYOUT_IN_CELL
+ ,PROP_DATABASE_NAME
+ ,PROP_COMMAND_TYPE
+ ,PROP_DATATABLE_NAME
+ ,PROP_DATACOLUMN_NAME
};
//Returns the UNO string equivalent to eId.
diff --git a/writerfilter/source/dmapper/SettingsTable.cxx b/writerfilter/source/dmapper/SettingsTable.cxx
index beae5a4942bd..76601e49eae2 100644
--- a/writerfilter/source/dmapper/SettingsTable.cxx
+++ b/writerfilter/source/dmapper/SettingsTable.cxx
@@ -256,6 +256,7 @@ struct SettingsTable_Impl
std::vector<beans::PropertyValue> m_aCompatSettings;
uno::Sequence<beans::PropertyValue> m_pCurrentCompatSetting;
+ OUString m_sCurrentDatabaseDataSource;
DocumentProtection_Impl m_DocumentProtection;
@@ -460,6 +461,29 @@ void SettingsTable::lcl_sprm(Sprm& rSprm)
case NS_ooxml::LN_CT_Settings_mirrorMargins:
m_pImpl->m_bMirrorMargin = nIntValue;
break;
+ case NS_ooxml::LN_CT_Settings_mailMerge:
+ {
+ writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
+ if (pProperties.get())
+ pProperties->resolve(*this);
+ }
+ break;
+ case NS_ooxml::LN_CT_MailMerge_query:
+ {
+ // try to get the "database.table" name from the query saved previously
+ OUString sVal = pValue->getString();
+ if ( sVal.endsWith("$") && sVal.indexOf(".dbo.") > 0 )
+ {
+ sal_Int32 nSpace = sVal.lastIndexOf(' ');
+ sal_Int32 nDbo = sVal.lastIndexOf(".dbo.");
+ if ( nSpace > 0 && nSpace < nDbo - 1 )
+ {
+ m_pImpl->m_sCurrentDatabaseDataSource = sVal.copy(nSpace + 1, nDbo - nSpace - 1) +
+ sVal.copy(nDbo + 4, sVal.getLength() - nDbo - 5);
+ }
+ }
+ }
+ break;
case NS_ooxml::LN_CT_Compat_compatSetting:
{
writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
@@ -595,6 +619,11 @@ css::uno::Sequence<css::beans::PropertyValue> SettingsTable::GetDocumentProtecti
return m_pImpl->m_DocumentProtection.toSequence();
}
+OUString SettingsTable::GetCurrentDatabaseDataSource() const
+{
+ return m_pImpl->m_sCurrentDatabaseDataSource;
+}
+
static bool lcl_isDefault(const uno::Reference<beans::XPropertyState>& xPropertyState, const OUString& rPropertyName)
{
return xPropertyState->getPropertyState(rPropertyName) == beans::PropertyState_DEFAULT_VALUE;
diff --git a/writerfilter/source/dmapper/SettingsTable.hxx b/writerfilter/source/dmapper/SettingsTable.hxx
index 7d539336f78e..8e7136989b47 100644
--- a/writerfilter/source/dmapper/SettingsTable.hxx
+++ b/writerfilter/source/dmapper/SettingsTable.hxx
@@ -88,6 +88,8 @@ class SettingsTable : public LoggedProperties, public LoggedTable
sal_Int32 GetWordCompatibilityMode() const;
+ OUString GetCurrentDatabaseDataSource() const;
+
private:
// Properties
virtual void lcl_attribute(Id Name, Value & val) override;