tdf#100034 tdf#157318 XLSX export: fix lost named ranges associated to sheets

The original fix for tdf#100034 (see commit [1]) consisted of explicitly not exporting to XLSX named ranges that are not built-in. This has a side-effect that user-defined named ranges associated with sheets are also not exported to XLSX. Hence, if the user creates a named range linked to a sheet and saves the file to XLSX, the named range is not exported (which is the issue reported in tdf#157318).

This patch implements a new fix for tdf#100034, reverting the previous
fix. When the Print Ranges are cleared by the user, the associated named
ranges are also cleared, thus fixing the original problem.

This new fix has the advantage that user-defined named ranges linked to sheets are again exported to XLSX files.

Regression from commit 639519dc2bad058197b6ff73c9e3df622f979f97
"tdf#100034: Fix to persistently remove print-range".

References:
[1] 639519dc2bad058197b6ff73c9e3df622f979f97

Change-Id: Ic3b84365a6086e96f60b222cd6337991ac90f483
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157455
Tested-by: László Németh <nemeth@numbertext.org>
Reviewed-by: László Németh <nemeth@numbertext.org>
(cherry picked from commit e13683b9d94f34a5c38bd2376eae8daeb9e57283)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157716
Tested-by: Jenkins
Reviewed-by: Rafael Lima <rafael.palma.lima@gmail.com>
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 875c248..87defb0 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -2117,6 +2117,8 @@ public:
    SC_DLLPUBLIC void            ClearPrintRanges( SCTAB nTab );
    /** Adds a new print ranges. */
    SC_DLLPUBLIC void            AddPrintRange( SCTAB nTab, const ScRange& rNew );
    // Removes all named ranges used for print ranges in a given tab
    SC_DLLPUBLIC void            ClearPrintNamedRanges( SCTAB nTab );
    /** Marks the specified sheet to be printed completely. Deletes old print ranges on the sheet! */
    SC_DLLPUBLIC void            SetPrintEntireSheet( SCTAB nTab );
    SC_DLLPUBLIC void            SetRepeatColRange( SCTAB nTab, std::optional<ScRange> oNew );
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 0662053..780d122 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -830,6 +830,10 @@ public:
    void            ClearPrintRanges();
    /** Adds a new print ranges. */
    void            AddPrintRange( const ScRange& rNew );

    // Removes all named ranges used for print ranges
    void            ClearPrintNamedRanges();

    /** Marks the specified sheet to be printed completely. Deletes old print ranges! */
    void            SetPrintEntireSheet();

diff --git a/sc/qa/unit/data/ods/tdf157318.ods b/sc/qa/unit/data/ods/tdf157318.ods
new file mode 100644
index 0000000..6d17dc1
--- /dev/null
+++ b/sc/qa/unit/data/ods/tdf157318.ods
Binary files differ
diff --git a/sc/qa/unit/subsequent_export_test4.cxx b/sc/qa/unit/subsequent_export_test4.cxx
index 74313ef..f12d407 100644
--- a/sc/qa/unit/subsequent_export_test4.cxx
+++ b/sc/qa/unit/subsequent_export_test4.cxx
@@ -1712,8 +1712,8 @@ CPPUNIT_TEST_FIXTURE(ScExportTest4, testTdf100034)
    createScDoc("xlsx/tdf100034.xlsx");
    ScDocument* pDoc = getScDoc();

    // Clear print ranges
    pDoc->ClearPrintRanges(0);
    // Clear print ranges (Format - Print Ranges - Clear)
    dispatchCommand(mxComponent, ".uno:DeletePrintArea", {});

    // Save and load back
    saveAndReload("Calc Office Open XML");
@@ -1723,6 +1723,25 @@ CPPUNIT_TEST_FIXTURE(ScExportTest4, testTdf100034)
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(0), pDoc->GetPrintRangeCount(0));
}

CPPUNIT_TEST_FIXTURE(ScExportTest4, testTdf157318)
{
    // This document has 2 named ranges; Test1 is global; Test2 is linked to Sheet1)
    createScDoc("ods/tdf157318.ods");
    ScDocument* pDoc = getScDoc();

    // Save as XLSX and load back
    saveAndReload("Calc Office Open XML");
    pDoc = getScDoc();

    // Check if there is one global named range
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(1),
                         static_cast<sal_uInt16>(pDoc->GetRangeName()->size()));

    // Check if there is one named range in the first sheet
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(1),
                         static_cast<sal_uInt16>(pDoc->GetRangeName(0)->size()));
}

CPPUNIT_PLUGIN_IMPLEMENT();

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index a33784c..ea10dac 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -6417,6 +6417,12 @@ void ScDocument::ClearPrintRanges( SCTAB nTab )
        maTabs[nTab]->ClearPrintRanges();
}

void ScDocument::ClearPrintNamedRanges( SCTAB nTab )
{
    if (ScTable* pTable = FetchTable(nTab))
        pTable->ClearPrintNamedRanges();
}

void ScDocument::AddPrintRange( SCTAB nTab, const ScRange& rNew )
{
    if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index 5e40d9b..e3eeda7 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -2311,6 +2311,26 @@ void ScTable::ClearPrintRanges()
    InvalidatePageBreaks();     // #i117952# forget page breaks for an old print range
}

void ScTable::ClearPrintNamedRanges()
{
    // tdf#100034 Clearing print ranges also requires to remove all print named ranges
    // Iterate over all named ranges to determine which are print areas to be removed
    if (mpRangeName)
    {
        std::vector<ScRangeData*> aRangesToRemove;
        for (auto it = mpRangeName->begin(); it != mpRangeName->end(); it++)
        {
            ScRangeData* pData = it->second.get();
            if (pData->HasType(ScRangeData::Type::PrintArea))
                aRangesToRemove.push_back(pData);
        }

        // Effectively remove all named ranges that refer to print ranges
        for (auto pItem : aRangesToRemove)
            mpRangeName->erase(*pItem);
    }
}

void ScTable::AddPrintRange( const ScRange& rNew )
{
    bPrintEntireSheet = false;
diff --git a/sc/source/filter/excel/xename.cxx b/sc/source/filter/excel/xename.cxx
index 5ce4a2f..4e837a9 100644
--- a/sc/source/filter/excel/xename.cxx
+++ b/sc/source/filter/excel/xename.cxx
@@ -324,11 +324,6 @@ OUString XclExpName::GetWithDefaultRangeSeparator( const OUString& rSymbol ) con

void XclExpName::SaveXml( XclExpXmlStream& rStrm )
{
    // tdf#100034: Don't save print range if the built-in index is unknown
    // and sheet index is valid (this is a deleted range)
    if (mcBuiltIn == EXC_BUILTIN_UNKNOWN && mnScTab != SCTAB_GLOBAL)
        return;

    sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
    rWorkbook->startElement( XML_definedName,
            // OOXTODO: XML_comment, "",
diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx
index 24b3e6c..f787d1e 100644
--- a/sc/source/ui/view/viewfun2.cxx
+++ b/sc/source/ui/view/viewfun2.cxx
@@ -1062,7 +1062,10 @@ void ScViewFunc::SetPrintRanges( bool bEntireSheet, const OUString* pPrint,
        //  print ranges

        if( !bAddPrint )
        {
            rDoc.ClearPrintRanges( nTab );
            rDoc.ClearPrintNamedRanges(nTab);
        }

        if( bEntireSheet )
        {