tdf#123057 Correct page count in mail merge if sections are hidden

Remove of invisible content has influence on page count and
therefore on fields for page count. So straight after removing
invisible content in the mail merge process, the layout has to
be updated before fields are converted to text.

Reviewed-on: https://gerrit.libreoffice.org/67343
Tested-by: Jenkins
Reviewed-by: Michael Stahl <Michael.Stahl@cib.de>
(cherry picked from commit b42b3acd043e3d464e2751ff17b0fda462ed62bd)

Change-Id: If43f9921b6797c7ceb112860cda4baf4978c36bc
Reviewed-on: https://gerrit.libreoffice.org/68317
Tested-by: Jenkins
Reviewed-by: Michael Stahl <Michael.Stahl@cib.de>
diff --git a/sw/qa/extras/mailmerge/data/db_pagecounttest.ods b/sw/qa/extras/mailmerge/data/db_pagecounttest.ods
new file mode 100644
index 0000000..4b9f90e
--- /dev/null
+++ b/sw/qa/extras/mailmerge/data/db_pagecounttest.ods
Binary files differ
diff --git a/sw/qa/extras/mailmerge/data/pagecounttest.ott b/sw/qa/extras/mailmerge/data/pagecounttest.ott
new file mode 100644
index 0000000..d7f6341
--- /dev/null
+++ b/sw/qa/extras/mailmerge/data/pagecounttest.ott
Binary files differ
diff --git a/sw/qa/extras/mailmerge/mailmerge.cxx b/sw/qa/extras/mailmerge/mailmerge.cxx
index fe50e89..38b9c58 100644
--- a/sw/qa/extras/mailmerge/mailmerge.cxx
+++ b/sw/qa/extras/mailmerge/mailmerge.cxx
@@ -1014,5 +1014,74 @@ DECLARE_SHELL_MAILMERGE_TEST(testTdf121168, "section_ps.odt", "4_v01.ods", "Tabe
    }
}

DECLARE_FILE_MAILMERGE_TEST(testTdf123057_file, "pagecounttest.ott", "db_pagecounttest.ods", "Sheet1")
{
    executeMailMerge(true);

    for (int doc = 0; doc < 4; ++doc)
    {
        loadMailMergeDocument(doc);

        // get document properties
        uno::Reference<text::XTextSectionsSupplier> xSectionsSupplier(mxComponent, uno::UNO_QUERY_THROW);
        uno::Reference<container::XIndexAccess> xSections(xSectionsSupplier->getTextSections(), uno::UNO_QUERY_THROW);

        CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xSections->getCount());
        uno::Reference<beans::XPropertySet> xSect0(xSections->getByIndex(0), uno::UNO_QUERY_THROW);
        uno::Reference<beans::XPropertySet> xSect1(xSections->getByIndex(1), uno::UNO_QUERY_THROW);

        OUString sFieldPageCount;
        uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
        uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
        uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());

        if (xFields.is())
        {
            while (xFields->hasMoreElements())
            {
                uno::Any aField = xFields->nextElement();
                uno::Reference<lang::XServiceInfo> xServiceInfo(aField, uno::UNO_QUERY);
                if (xServiceInfo->supportsService("com.sun.star.text.textfield.PageCount"))
                {
                    uno::Reference<text::XTextContent> xField(aField, uno::UNO_QUERY);
                    sFieldPageCount = xField->getAnchor()->getString();
                }
            }
        }

        switch (doc)
        {
        case 0:
            // both sections visible, page num is 2
            CPPUNIT_ASSERT_EQUAL(2, getPages());
            CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xSect0, "IsCurrentlyVisible"));
            CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xSect1, "IsCurrentlyVisible"));
            CPPUNIT_ASSERT_EQUAL(OUString("2"), sFieldPageCount);
            break;
        case 1:
            // second section hidden, page num is 1
            CPPUNIT_ASSERT_EQUAL(1, getPages());
            CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xSect0, "IsCurrentlyVisible"));
            CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xSect1, "IsCurrentlyVisible"));
            CPPUNIT_ASSERT_EQUAL(OUString("1"), sFieldPageCount);
            break;
        case 2:
            // first section hidden, page num is 1
            CPPUNIT_ASSERT_EQUAL(1, getPages());
            CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xSect0, "IsCurrentlyVisible"));
            CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xSect1, "IsCurrentlyVisible"));
            CPPUNIT_ASSERT_EQUAL(OUString("1"), sFieldPageCount);
            break;
        case 3:
            // both sections hidden, page num is 1
            CPPUNIT_ASSERT_EQUAL(1, getPages());
            CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xSect0, "IsCurrentlyVisible"));
            CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xSect1, "IsCurrentlyVisible"));
            CPPUNIT_ASSERT_EQUAL(OUString("1"), sFieldPageCount);
            break;
        }
    }
}

CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index 0a00dcc..f9a05ad 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -1501,6 +1501,9 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
                // prepare working copy and target to append

                pWorkDoc->RemoveInvisibleContent();
                // remove of invisible content has influence on page count and so on fields for page count,
                // therefore layout has to be updated before fields are converted to text
                pWorkShell->CalcLayout();
                pWorkShell->ConvertFieldsToText();
                pWorkShell->SetNumberingRestart();
                if( bSynchronizedDoc )
@@ -1516,8 +1519,6 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
                    ++targetDocPageCount; // Docs always start on odd pages (so offset must be even).
                SwNodeIndex appendedDocStart = pTargetDoc->AppendDoc( *pWorkDoc,
                    nStartingPageNo, !bWorkDocInitialized, targetDocPageCount, nDocNo);
                // ensure layout is up to date in order to get correct page count
                pWorkShell->CalcLayout();
                targetDocPageCount += pWorkShell->GetPageCnt();

                if ( (nMaxDumpDocs < 0) || (nDocNo <= nMaxDumpDocs) )