summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
Diffstat (limited to 'sw')
-rw-r--r--sw/inc/doc.hxx4
-rw-r--r--sw/inc/ndtxt.hxx6
-rw-r--r--sw/qa/extras/mailmerge/data/tdf118845.fodt28
-rw-r--r--sw/qa/extras/mailmerge/mailmerge.cxx49
-rw-r--r--sw/source/core/doc/doc.cxx18
-rw-r--r--sw/source/core/txtnode/thints.cxx24
6 files changed, 112 insertions, 17 deletions
diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index b58286c80536..ac9cba92a09e 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -511,7 +511,9 @@ public:
::sw::DocumentFieldsManager & GetDocumentFieldsManager();
- bool FieldCanHidePara(SwFieldIds eFieldId) const;
+ // Returns 0 if the field cannot hide para, or a positive integer indicating the field type
+ // "weight" when several hiding fields' FieldHidesPara() give conflicting results
+ int FieldCanHideParaWeight(SwFieldIds eFieldId) const;
bool FieldHidesPara(const SwField& rField) const;
// IDocumentContentOperations
diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx
index 5d43ebf4898a..d314df94dbd0 100644
--- a/sw/inc/ndtxt.hxx
+++ b/sw/inc/ndtxt.hxx
@@ -704,8 +704,10 @@ public:
bool IsHiddenByParaField() const
{ return m_pSwpHints && m_pSwpHints->IsHiddenByParaField(); }
- bool FieldCanHidePara(SwFieldIds eFieldId) const
- { return GetDoc()->FieldCanHidePara(eFieldId); }
+ int FieldCanHideParaWeight(SwFieldIds eFieldId) const
+ {
+ return GetDoc()->FieldCanHideParaWeight(eFieldId);
+ }
bool FieldHidesPara(const SwField& rField) const
{ return GetDoc()->FieldHidesPara(rField); }
diff --git a/sw/qa/extras/mailmerge/data/tdf118845.fodt b/sw/qa/extras/mailmerge/data/tdf118845.fodt
new file mode 100644
index 000000000000..64a5180da718
--- /dev/null
+++ b/sw/qa/extras/mailmerge/data/tdf118845.fodt
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:settings>
+ <config:config-item-set config:name="ooo:configuration-settings">
+ <config:config-item config:name="CurrentDatabaseDataSource" config:type="string">4_v01</config:config-item>
+ <config:config-item config:name="CurrentDatabaseCommand" config:type="string">Tabelle1</config:config-item>
+ <config:config-item config:name="CurrentDatabaseCommandType" config:type="int">0</config:config-item>
+ <config:config-item config:name="EmptyDbFieldHidesPara" config:type="boolean">true</config:config-item>
+ </config:config-item-set>
+ </office:settings>
+ <office:automatic-styles>
+ <style:page-layout style:name="pm1">
+ <style:page-layout-properties fo:page-width="21cm" fo:page-height="29.7cm" style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm"/>
+ </style:page-layout>
+ </office:automatic-styles>
+ <office:master-styles>
+ <style:master-page style:name="Standard" style:page-layout-name="pm1"/>
+ </office:master-styles>
+ <office:body>
+ <office:text>
+ <text:p><text:hidden-paragraph text:condition="ooow:([4_v01.Tabelle1.Anrede] != &quot;Frau&quot; OR NOT [4_v01.Tabelle1.Nachname]) OR (![4_v01.Tabelle1.Nachname])"/><text:span text:style-name="T1">Dear Mrs. </text:span><text:span text:style-name="T1"><text:database-display text:table-name="Tabelle1" text:table-type="table" text:column-name="Nachname" text:database-name="4_v01">&lt;Nachname&gt;</text:database-display></text:span><text:span text:style-name="T1">,</text:span></text:p>
+ <text:p><text:hidden-paragraph text:condition="ooow:[4_v01.Tabelle1.Anrede] == &quot;Frau&quot; OR NOT [4_v01.Tabelle1.Nachname]"/><text:span text:style-name="T1">Dear Mr. </text:span><text:span text:style-name="T1"><text:database-display text:table-name="Tabelle1" text:table-type="table" text:column-name="Nachname" text:database-name="4_v01">&lt;Nachname&gt;</text:database-display></text:span><text:span text:style-name="T1">,</text:span></text:p>
+ <text:p><text:hidden-paragraph text:condition="ooow:[4_v01.Tabelle1.Nachname]"/><text:span text:style-name="T1">To whom it may concern,</text:span></text:p>
+ <text:p/>
+ </office:text>
+ </office:body>
+</office:document> \ No newline at end of file
diff --git a/sw/qa/extras/mailmerge/mailmerge.cxx b/sw/qa/extras/mailmerge/mailmerge.cxx
index e21f0fe44d0c..ba4c5dd401bd 100644
--- a/sw/qa/extras/mailmerge/mailmerge.cxx
+++ b/sw/qa/extras/mailmerge/mailmerge.cxx
@@ -818,5 +818,54 @@ DECLARE_FILE_MAILMERGE_TEST(testEmptyValuesNewFODT, "tdf35798-new.fodt", "5-with
}
}
+DECLARE_SHELL_MAILMERGE_TEST(testTdf118845, "tdf118845.fodt", "4_v01.ods", "Tabelle1")
+{
+ executeMailMerge();
+
+ // Both male and female greetings were shown, thus each page had 3 paragraphs
+
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxMMComponent.get());
+ CPPUNIT_ASSERT(pTextDoc);
+ sal_uInt16 nPhysPages = pTextDoc->GetDocShell()->GetWrtShell()->GetPhyPageNum();
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(7), nPhysPages); // 4 pages, each odd, and 3 blanks
+
+ uno::Reference<text::XTextDocument> xTextDocument(mxMMComponent, uno::UNO_QUERY);
+
+ int nParaCount = 0;
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ while (xParaEnum->hasMoreElements())
+ {
+ xParaEnum->nextElement();
+ nParaCount++;
+ }
+ CPPUNIT_ASSERT_EQUAL(8, nParaCount);
+
+ uno::Reference<text::XTextRange> xParagraph(getParagraphOrTable(1, xTextDocument->getText()),
+ uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("Dear Mrs. Mustermann1,"), xParagraph->getString());
+
+ xParagraph.set(getParagraphOrTable(2, xTextDocument->getText()), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString(""), xParagraph->getString());
+
+ xParagraph.set(getParagraphOrTable(3, xTextDocument->getText()), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("Dear Mr. Mustermann2,"), xParagraph->getString());
+
+ xParagraph.set(getParagraphOrTable(4, xTextDocument->getText()), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString(""), xParagraph->getString());
+
+ xParagraph.set(getParagraphOrTable(5, xTextDocument->getText()), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("Dear Mrs. Mustermann3,"), xParagraph->getString());
+
+ xParagraph.set(getParagraphOrTable(6, xTextDocument->getText()), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString(""), xParagraph->getString());
+
+ xParagraph.set(getParagraphOrTable(7, xTextDocument->getText()), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("Dear Mr. Mustermann4,"), xParagraph->getString());
+
+ xParagraph.set(getParagraphOrTable(8, xTextDocument->getText()), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString(""), xParagraph->getString());
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/doc/doc.cxx b/sw/source/core/doc/doc.cxx
index a594fe3d1a2c..c39b7989b116 100644
--- a/sw/source/core/doc/doc.cxx
+++ b/sw/source/core/doc/doc.cxx
@@ -1358,17 +1358,20 @@ bool HandleHidingField(SwFormatField& rFormatField, const SwNodes& rNodes,
}
}
-bool SwDoc::FieldCanHidePara(SwFieldIds eFieldId) const
+// The greater the returned value, the more weight has this field type on deciding the final
+// paragraph state
+int SwDoc::FieldCanHideParaWeight(SwFieldIds eFieldId) const
{
switch (eFieldId)
{
case SwFieldIds::HiddenPara:
- return true;
+ return 20;
case SwFieldIds::Database:
- return GetDocumentSettingManager().get(
- DocumentSettingId::EMPTY_DB_FIELD_HIDES_PARA);
+ return GetDocumentSettingManager().get(DocumentSettingId::EMPTY_DB_FIELD_HIDES_PARA)
+ ? 10
+ : 0;
default:
- return false;
+ return 0;
}
}
@@ -1379,7 +1382,8 @@ bool SwDoc::FieldHidesPara(const SwField& rField) const
case SwFieldIds::HiddenPara:
return static_cast<const SwHiddenParaField&>(rField).IsHidden();
case SwFieldIds::Database:
- return FieldCanHidePara(SwFieldIds::Database) && rField.ExpandField(true).isEmpty();
+ return FieldCanHideParaWeight(SwFieldIds::Database)
+ && rField.ExpandField(true).isEmpty();
default:
return false;
}
@@ -1411,7 +1415,7 @@ bool SwDoc::RemoveInvisibleContent()
std::vector<std::unique_ptr<FieldTypeGuard>> aHidingFieldTypes;
for (SwFieldType* pType : *getIDocumentFieldsAccess().GetFieldTypes())
{
- if (FieldCanHidePara(pType->Which()))
+ if (FieldCanHideParaWeight(pType->Which()))
aHidingFieldTypes.push_back(o3tl::make_unique<FieldTypeGuard>(pType));
}
for (const auto& pTypeGuard : aHidingFieldTypes)
diff --git a/sw/source/core/txtnode/thints.cxx b/sw/source/core/txtnode/thints.cxx
index bc111093273b..fb3a1d8a81a1 100644
--- a/sw/source/core/txtnode/thints.cxx
+++ b/sw/source/core/txtnode/thints.cxx
@@ -1156,7 +1156,7 @@ void SwTextNode::DestroyAttr( SwTextAttr* pAttr )
// certain fields must update the SwDoc's calculation flags
// Certain fields (like HiddenParaField) must trigger recalculation of visible flag
- if (FieldCanHidePara(pFieldType->Which()))
+ if (FieldCanHideParaWeight(pFieldType->Which()))
SetCalcHiddenParaField();
switch( pFieldType->Which() )
@@ -1466,7 +1466,8 @@ bool SwTextNode::InsertHint( SwTextAttr * const pAttr, const SetAttrMode nMode )
case RES_TXTATR_FIELD:
{
// trigger notification for relevant fields, like HiddenParaFields
- if (FieldCanHidePara(pAttr->GetFormatField().GetField()->GetTyp()->Which()))
+ if (FieldCanHideParaWeight(
+ pAttr->GetFormatField().GetField()->GetTyp()->Which()))
{
bHiddenPara = true;
}
@@ -2595,6 +2596,7 @@ bool SwpHints::CalcHiddenParaField() const
m_bCalcHiddenParaField = false;
const bool bOldHiddenByParaField = m_bHiddenByParaField;
bool bNewHiddenByParaField = false;
+ int nNewResultWeight = 0;
const size_t nSize = Count();
const SwTextAttr* pTextHt;
@@ -2605,12 +2607,20 @@ bool SwpHints::CalcHiddenParaField() const
if (RES_TXTATR_FIELD == nWhich)
{
+ // see also SwTextFrame::IsHiddenNow()
const SwFormatField& rField = pTextHt->GetFormatField();
- if (m_rParent.FieldCanHidePara(rField.GetField()->GetTyp()->Which())
- && !(bNewHiddenByParaField = m_rParent.FieldHidesPara(*rField.GetField())))
+ int nCurWeight = m_rParent.FieldCanHideParaWeight(rField.GetField()->GetTyp()->Which());
+ if (nCurWeight > nNewResultWeight)
{
- // If there's at least one field telling not to hide, so be it
- break;
+ nNewResultWeight = nCurWeight;
+ bNewHiddenByParaField = m_rParent.FieldHidesPara(*rField.GetField());
+ }
+ else if (nCurWeight == nNewResultWeight && bNewHiddenByParaField)
+ {
+ // Currently, for both supported hiding types (HiddenPara, Database), "Don't hide"
+ // takes precedence - i.e., if there's a "Don't hide" field of that weight, we only
+ // care about fields of higher weight.
+ bNewHiddenByParaField = m_rParent.FieldHidesPara(*rField.GetField());
}
}
}
@@ -3293,7 +3303,7 @@ void SwpHints::DeleteAtPos( const size_t nPos )
pTextField->ChgTextNode(nullptr);
}
else if (m_bHiddenByParaField
- && m_rParent.FieldCanHidePara(pField->GetTyp()->Which()))
+ && m_rParent.FieldCanHideParaWeight(pField->GetTyp()->Which()))
{
m_bCalcHiddenParaField = true;
}