summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Stahl <michael.stahl@allotropia.de>2022-05-20 20:56:56 +0200
committerCaolán McNamara <caolanm@redhat.com>2022-05-24 12:37:18 +0200
commit30c171ab3dc07a0a8423775619631f6ad514f916 (patch)
treef2ce57b073500ba8e24e87790ac71a5ce2cf6f56
parenttdf#149231 Fix crash on print preview of master (diff)
downloadcore-30c171ab3dc07a0a8423775619631f6ad514f916.tar.gz
core-30c171ab3dc07a0a8423775619631f6ad514f916.zip
sw: copy grab bags in mail merge
Otherwise formatting may get lost when the result is stored as DOCX. Change-Id: I62cbeb1fc9f120dd9c424daf5dc0471686715537 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134694 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.stahl@allotropia.de> (cherry picked from commit 123d3a9301c90925c23cfb4806d7b0be01b975d6) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134762 Reviewed-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r--sw/qa/extras/mailmerge/data/grabbagtest.docxbin0 -> 11920 bytes
-rw-r--r--sw/qa/extras/mailmerge/data/onecell.xlsxbin0 -> 4846 bytes
-rw-r--r--sw/qa/extras/mailmerge/mailmerge.cxx92
-rw-r--r--sw/source/core/doc/docnew.cxx9
-rw-r--r--sw/source/ui/dbui/mmresultdialogs.cxx8
-rw-r--r--writerfilter/source/dmapper/DomainMapper.cxx2
6 files changed, 98 insertions, 13 deletions
diff --git a/sw/qa/extras/mailmerge/data/grabbagtest.docx b/sw/qa/extras/mailmerge/data/grabbagtest.docx
new file mode 100644
index 000000000000..4b40f1fb4e94
--- /dev/null
+++ b/sw/qa/extras/mailmerge/data/grabbagtest.docx
Binary files differ
diff --git a/sw/qa/extras/mailmerge/data/onecell.xlsx b/sw/qa/extras/mailmerge/data/onecell.xlsx
new file mode 100644
index 000000000000..972f6b3c5fc5
--- /dev/null
+++ b/sw/qa/extras/mailmerge/data/onecell.xlsx
Binary files differ
diff --git a/sw/qa/extras/mailmerge/mailmerge.cxx b/sw/qa/extras/mailmerge/mailmerge.cxx
index e1fee48d74da..663d04f0afbe 100644
--- a/sw/qa/extras/mailmerge/mailmerge.cxx
+++ b/sw/qa/extras/mailmerge/mailmerge.cxx
@@ -16,7 +16,9 @@
#include <com/sun/star/text/MailMergeType.hpp>
#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/table/TableBorder.hpp>
#include <com/sun/star/text/TextContentAnchorType.hpp>
+#include <com/sun/star/text/XTextTable.hpp>
#include <com/sun/star/sdbc/XRowSet.hpp>
#include <com/sun/star/sdbcx/XRowLocate.hpp>
#include <com/sun/star/task/XJob.hpp>
@@ -77,7 +79,7 @@ public:
* calling executeMailMerge() after modifying the job arguments.
*/
void executeMailMergeTest( const char* filename, const char* datasource, const char* tablename,
- bool file, int selection, const char* column )
+ char const*const filter, int selection, const char* column )
{
maMMtestFilename = filename;
header();
@@ -89,7 +91,7 @@ public:
const OUString aURI( m_directories.getURLFromSrc(mpTestDocumentPath) + OUString::createFromAscii(datasource) );
const OUString aPrefix = column ? OUString::createFromAscii( column ) : "LOMM_";
const OUString aDBName = registerDBsource( aURI, aWorkDir );
- initMailMergeJobAndArgs( filename, tablename, aDBName, aPrefix, aWorkDir, file, selection, column != nullptr );
+ initMailMergeJobAndArgs( filename, tablename, aDBName, aPrefix, aWorkDir, filter, selection, column != nullptr );
verify();
finish();
@@ -138,7 +140,8 @@ public:
}
void initMailMergeJobAndArgs( const char* filename, const char* tablename, const OUString &aDBName,
- const OUString &aPrefix, const OUString &aWorkDir, bool file, int nDataSets,
+ const OUString &aPrefix, const OUString &aWorkDir,
+ char const*const filter, int nDataSets,
const bool bPrefixIsColumn )
{
uno::Reference< task::XJob > xJob( getMultiServiceFactory()->createInstance( "com.sun.star.text.MailMerge" ), uno::UNO_QUERY_THROW );
@@ -146,13 +149,16 @@ public:
mMMargs.reserve( 15 );
- mMMargs.emplace_back( UNO_NAME_OUTPUT_TYPE, uno::Any( file ? text::MailMergeType::FILE : text::MailMergeType::SHELL ) );
+ mMMargs.emplace_back( UNO_NAME_OUTPUT_TYPE, uno::Any( filter ? text::MailMergeType::FILE : text::MailMergeType::SHELL ) );
mMMargs.emplace_back( UNO_NAME_DOCUMENT_URL, uno::Any(
( OUString( m_directories.getURLFromSrc(mpTestDocumentPath) + OUString::createFromAscii(filename)) ) ) );
mMMargs.emplace_back( UNO_NAME_DATA_SOURCE_NAME, uno::Any( aDBName ) );
mMMargs.emplace_back( UNO_NAME_OUTPUT_URL, uno::Any( aWorkDir ) );
- if (file)
+ if (filter)
+ {
mMMargs.emplace_back( UNO_NAME_FILE_NAME_PREFIX, uno::Any( aPrefix ) );
+ mMMargs.emplace_back(UNO_NAME_SAVE_FILTER, uno::Any(OUString::createFromAscii(filter)));
+ }
if (bPrefixIsColumn)
mMMargs.emplace_back( UNO_NAME_FILE_NAME_FROM_COLUMN, uno::Any( true ) );
@@ -256,7 +262,7 @@ public:
/**
Loads number-th document from mail merge. Requires file output from mail merge.
*/
- void loadMailMergeDocument( int number )
+ void loadMailMergeDocument(int number, char const*const ext = ".odt")
{
OUString name;
if (!msMailMergeOutputPrefix.isEmpty())
@@ -268,7 +274,7 @@ public:
aURLObj.SetSmartURL( msMailMergeDocumentURL );
name = aURLObj.GetBase();
}
- name += OUString::number( number ) + ".odt";
+ name += OUString::number(number) + OStringToOUString(std::string_view(ext, strlen(ext)), RTL_TEXTENCODING_ASCII_US);
loadMailMergeDocument( name );
}
@@ -298,7 +304,7 @@ protected:
const char* maMMtestFilename;
};
-#define DECLARE_MAILMERGE_TEST(TestName, filename, datasource, tablename, file, BaseClass, selection, column) \
+#define DECLARE_MAILMERGE_TEST(TestName, filename, datasource, tablename, filter, BaseClass, selection, column) \
class TestName : public BaseClass { \
protected: \
virtual OUString getTestName() override { return #TestName; } \
@@ -308,7 +314,7 @@ protected:
CPPUNIT_TEST_SUITE_END(); \
\
void MailMerge() { \
- executeMailMergeTest(filename, datasource, tablename, file, selection, column); \
+ executeMailMergeTest(filename, datasource, tablename, filter, selection, column); \
} \
void verify() override; \
}; \
@@ -317,17 +323,17 @@ protected:
// Will generate the resulting document in mxMMDocument.
#define DECLARE_SHELL_MAILMERGE_TEST(TestName, filename, datasource, tablename) \
- DECLARE_MAILMERGE_TEST(TestName, filename, datasource, tablename, false, MMTest, 0, nullptr)
+ DECLARE_MAILMERGE_TEST(TestName, filename, datasource, tablename, nullptr, MMTest, 0, nullptr)
// Will generate documents as files, use loadMailMergeDocument().
#define DECLARE_FILE_MAILMERGE_TEST(TestName, filename, datasource, tablename) \
- DECLARE_MAILMERGE_TEST(TestName, filename, datasource, tablename, true, MMTest, 0, nullptr)
+ DECLARE_MAILMERGE_TEST(TestName, filename, datasource, tablename, "writer8", MMTest, 0, nullptr)
#define DECLARE_SHELL_MAILMERGE_TEST_SELECTION(TestName, filename, datasource, tablename, selection) \
- DECLARE_MAILMERGE_TEST(TestName, filename, datasource, tablename, false, MMTest, selection, nullptr)
+ DECLARE_MAILMERGE_TEST(TestName, filename, datasource, tablename, nullptr, MMTest, selection, nullptr)
#define DECLARE_FILE_MAILMERGE_TEST_COLUMN(TestName, filename, datasource, tablename, column) \
- DECLARE_MAILMERGE_TEST(TestName, filename, datasource, tablename, true, MMTest, 0, column)
+ DECLARE_MAILMERGE_TEST(TestName, filename, datasource, tablename, "writer8", MMTest, 0, column)
int MMTest::documentStartPageNumber( int document ) const
{ // See documentStartPageNumber() .
@@ -1292,5 +1298,65 @@ DECLARE_SHELL_MAILMERGE_TEST(testTdf128148, "tdf128148.odt", "4_v01.ods", "Tabel
}
}
+namespace com::sun::star::table {
+
+static std::ostream& operator<<(std::ostream& rStream, table::BorderLine const& rLine)
+{
+ rStream << "BorderLine(" << rLine.Color << "," << rLine.InnerLineWidth << "," << rLine.OuterLineWidth << "," << rLine.LineDistance << ")";
+ return rStream;
+}
+
+static std::ostream& operator<<(std::ostream& rStream, table::TableBorder const& rBorder)
+{
+ rStream << "TableBorder(\n "
+ << rBorder.TopLine << "," << static_cast<bool>(rBorder.IsTopLineValid) << ",\n "
+ << rBorder.BottomLine << "," << static_cast<bool>(rBorder.IsBottomLineValid) << ",\n "
+ << rBorder.LeftLine << "," << static_cast<bool>(rBorder.IsLeftLineValid) << ",\n "
+ << rBorder.RightLine << "," << static_cast<bool>(rBorder.IsRightLineValid) << ",\n "
+ << rBorder.HorizontalLine << "," << static_cast<bool>(rBorder.IsHorizontalLineValid) << ",\n "
+ << rBorder.VerticalLine << "," << static_cast<bool>(rBorder.IsVerticalLineValid) << ",\n "
+ << rBorder.Distance << "," << static_cast<bool>(rBorder.IsDistanceValid) << ")";
+ return rStream;
+}
+
+}
+
+DECLARE_MAILMERGE_TEST(testGrabBag, "grabbagtest.docx", "onecell.xlsx", "Sheet1", "MS Word 2007 XML", MMTest, 0, nullptr)
+{
+ executeMailMerge(true);
+
+ loadMailMergeDocument(0, ".docx");
+
+ SwXTextDocument *const pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ CPPUNIT_ASSERT(pTextDoc);
+
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), pTextDoc->GetDocShell()->GetWrtShell()->GetPhyPageNum());
+
+ // check grabbag
+ uno::Reference<beans::XPropertySet> const xModel(
+ mxComponent, uno::UNO_QUERY_THROW);
+ uno::Sequence<beans::PropertyValue> aInteropGrabBag;
+ pTextDoc->getPropertyValue("InteropGrabBag") >>= aInteropGrabBag;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(13), aInteropGrabBag.getLength());
+
+ // check table border - comes from table style "Tabellenraster"
+ uno::Reference<text::XTextTable> const xTable(getParagraphOrTable(1, pTextDoc->getText()), uno::UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertySet> const xTableProps(xTable, uno::UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_EQUAL(table::TableBorder(
+ table::BorderLine(util::Color(0), 0, 18, 0), true,
+ table::BorderLine(util::Color(0), 0, 18, 0), true,
+ table::BorderLine(util::Color(0), 0, 18, 0), true,
+ table::BorderLine(util::Color(0), 0, 18, 0), true,
+ table::BorderLine(util::Color(0), 0, 18, 0), true,
+ table::BorderLine(util::Color(0), 0, 0, 0), true,
+ sal_Int16(191), true),
+ getProperty<table::TableBorder>(xTableProps, "TableBorder"));
+
+ // check font is Arial - comes from theme (wrong result was "" - nothing)
+ uno::Reference<text::XText> const xCell(xTable->getCellByName("A1"), uno::UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertySet> const xParaA1(getParagraphOrTable(1, xCell->getText()), uno::UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_EQUAL(OUString("Arial"), getProperty<OUString>(xParaA1, "CharFontName"));
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index 667cb4283207..7aa134edf841 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -29,6 +29,7 @@
#include <doc.hxx>
#include <proofreadingiterator.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/text/XFlatParagraphIteratorProvider.hpp>
#include <com/sun/star/linguistic2/XProofreadingIterator.hpp>
#include <com/sun/star/frame/XModel.hpp>
@@ -909,6 +910,14 @@ SfxObjectShell* SwDoc::CreateCopy( bool bCallInitNew, bool bEmpty ) const
xRet->ReplaceStyles(*this);
+ uno::Reference<beans::XPropertySet> const xThisSet(
+ GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertySet> const xRetSet(
+ pRetShell->GetBaseModel(), uno::UNO_QUERY_THROW);
+ uno::Sequence<beans::PropertyValue> aInteropGrabBag;
+ xThisSet->getPropertyValue("InteropGrabBag") >>= aInteropGrabBag;
+ xRetSet->setPropertyValue("InteropGrabBag", uno::Any(aInteropGrabBag));
+
if( !bEmpty )
{
#ifdef DBG_UTIL
diff --git a/sw/source/ui/dbui/mmresultdialogs.cxx b/sw/source/ui/dbui/mmresultdialogs.cxx
index e801329df5a6..0699b93e3638 100644
--- a/sw/source/ui/dbui/mmresultdialogs.cxx
+++ b/sw/source/ui/dbui/mmresultdialogs.cxx
@@ -685,6 +685,14 @@ IMPL_LINK_NOARG(SwMMResultSaveDialog, SaveOutputHdl_Impl, weld::Button&, void)
pTempView->GetDocShell()->GetDoc()->ReplaceDefaults( *pTargetView->GetDocShell()->GetDoc());
pTempView->GetDocShell()->GetDoc()->ReplaceDocumentProperties( *pTargetView->GetDocShell()->GetDoc(), true );
+ uno::Reference<beans::XPropertySet> const xThisSet(
+ pTargetView->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertySet> const xRetSet(
+ pTempView->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW);
+ uno::Sequence<beans::PropertyValue> aInteropGrabBag;
+ xThisSet->getPropertyValue("InteropGrabBag") >>= aInteropGrabBag;
+ xRetSet->setPropertyValue("InteropGrabBag", uno::Any(aInteropGrabBag));
+
pTargetView->GetWrtShell().PastePages(
pTempView->GetWrtShell(), documentStartPageNumber(xConfigItem.get(), nDoc, false),
documentEndPageNumber(xConfigItem.get(), nDoc, false));
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index acb8f8cae102..99fb28fda05f 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -378,6 +378,8 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "asciiTheme", ThemeTable::getStringForTheme(nIntValue));
if (m_pImpl->GetTopContext())
{
+ // note: overwrite Fonts_ascii with Fonts_asciiTheme *even if*
+ // theme font is empty - this is apparently what Word 2013 does
uno::Any aPropValue = uno::makeAny( m_pImpl->GetThemeTable()->getFontNameForTheme( nIntValue ) );
m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME, aPropValue );
m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_FONT_NAME_ASCII, aPropValue, true, CHAR_GRAB_BAG );