include/xmloff/xmltoken.hxx                                            |    1 
 sc/inc/dbdata.hxx                                                      |    2 
 sc/qa/unit/PivotTableFormatsImportExport.cxx                           |   35 
++++++-
 sc/qa/unit/data/ods/tdf162262_summarybelow.ods                         |binary
 sc/qa/unit/data/xlsx/pivot-table/Pivot_Table_with_Cell_Protection.xlsx |binary
 sc/qa/unit/subsequent_export_test4.cxx                                 |   30 
++++++
 sc/source/core/data/table2.cxx                                         |   50 
----------
 sc/source/filter/excel/xepivotxml.cxx                                  |   31 
+++---
 sc/source/filter/inc/stylesbuffer.hxx                                  |   10 
+-
 sc/source/filter/oox/stylesbuffer.cxx                                  |   35 
++++++-
 sc/source/filter/oox/stylesfragment.cxx                                |    3 
 sc/source/filter/xml/XMLExportDatabaseRanges.cxx                       |    3 
 sc/source/filter/xml/xmldrani.cxx                                      |    5 +
 sc/source/filter/xml/xmldrani.hxx                                      |    2 
 schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng            |    9 +
 xmloff/source/core/xmltoken.cxx                                        |    1 
 xmloff/source/token/tokens.txt                                         |    1 
 17 files changed, 147 insertions(+), 71 deletions(-)

New commits:
commit 9be630c709e4b4c50c74e2874181e118e40c956a
Author:     Balazs Varga <balazs.varga.ext...@allotropia.de>
AuthorDate: Tue Nov 5 13:07:05 2024 +0100
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Wed Nov 27 00:31:45 2024 +0100

    Related tdf#162262 - sc: odf import/export of "Summary below data"
    
    Add new LO_EXT "summary-below" attribute for table:subtotal-rules.
    
    Follow up commit: 26c08356d1b2a963efdca570979cb04388371400
    (tdf#162262 sc add "Summary below data" option for Subtotal dialog)
    
    Change-Id: Ie7f43d3c76479cd9468552b5939de5dbb2082a02
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176058
    Tested-by: Jenkins
    Reviewed-by: Balazs Varga <balazs.varga.ext...@allotropia.de>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177378
    Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de>
    Tested-by: allotropia jenkins <jenk...@allotropia.de>

diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index 20b1398201bd..e3b54f961206 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -1924,6 +1924,7 @@ namespace xmloff::token {
         XML_SUB_VIEW_SIZE,
         XML_SUFFIX,
         XML_SUM,
+        XML_SUMMARY_BELOW,
         XML_SWISS,
         XML_SYMBOL,
         XML_SYMBOL_HEIGHT,
diff --git a/sc/inc/dbdata.hxx b/sc/inc/dbdata.hxx
index c1164b064b17..532d71528e07 100644
--- a/sc/inc/dbdata.hxx
+++ b/sc/inc/dbdata.hxx
@@ -192,7 +192,7 @@ public:
     SC_DLLPUBLIC bool       GetAdvancedQuerySource(ScRange& rSource) const;
     SC_DLLPUBLIC void       SetAdvancedQuerySource(const ScRange* pSource);
 
-    void        GetSubTotalParam(ScSubTotalParam& rSubTotalParam) const;
+    SC_DLLPUBLIC void       GetSubTotalParam(ScSubTotalParam& rSubTotalParam) 
const;
     void        SetSubTotalParam(const ScSubTotalParam& rSubTotalParam);
 
     void        GetImportParam(ScImportParam& rImportParam) const;
diff --git a/sc/qa/unit/data/ods/tdf162262_summarybelow.ods 
b/sc/qa/unit/data/ods/tdf162262_summarybelow.ods
new file mode 100644
index 000000000000..bd2eeba48d01
Binary files /dev/null and b/sc/qa/unit/data/ods/tdf162262_summarybelow.ods 
differ
diff --git a/sc/qa/unit/subsequent_export_test4.cxx 
b/sc/qa/unit/subsequent_export_test4.cxx
index 19f148f9a0f0..dc5831f79e70 100644
--- a/sc/qa/unit/subsequent_export_test4.cxx
+++ b/sc/qa/unit/subsequent_export_test4.cxx
@@ -21,6 +21,8 @@
 #include <postit.hxx>
 #include <validat.hxx>
 #include <scresid.hxx>
+#include <dbdata.hxx>
+#include <subtotalparam.hxx>
 #include <globstr.hrc>
 #include <tabprotection.hxx>
 #include <dpobject.hxx>
@@ -394,6 +396,34 @@ CPPUNIT_TEST_FIXTURE(ScExportTest4, testTdf162262)
     assertXPath(pSheet, "/x:worksheet/x:sheetPr/x:outlinePr", "summaryBelow", 
u"0"_ustr);
 }
 
+CPPUNIT_TEST_FIXTURE(ScExportTest4, testTdf162262_summarybelow)
+{
+    createScDoc("ods/tdf162262_summarybelow.ods");
+
+    ScDocument* pDoc = getScDoc();
+    ScDBCollection* pDBCollection = pDoc->GetDBCollection();
+    CPPUNIT_ASSERT(pDBCollection);
+    {
+        const ScDBData* pDBData = pDBCollection->GetDBAtArea(0, 0, 0, 1, 13);
+        CPPUNIT_ASSERT(pDBData);
+        ScSubTotalParam aParam;
+        pDBData->GetSubTotalParam(aParam);
+        CPPUNIT_ASSERT(!aParam.bSummaryBelow);
+    }
+
+    saveAndReload(u"calc8"_ustr);
+    pDoc = getScDoc();
+    pDBCollection = pDoc->GetDBCollection();
+    CPPUNIT_ASSERT(pDBCollection);
+    {
+        const ScDBData* pDBData = pDBCollection->GetDBAtArea(0, 0, 0, 1, 13);
+        CPPUNIT_ASSERT(pDBData);
+        ScSubTotalParam aParam;
+        pDBData->GetSubTotalParam(aParam);
+        CPPUNIT_ASSERT(!aParam.bSummaryBelow);
+    }
+}
+
 CPPUNIT_TEST_FIXTURE(ScExportTest4, testTdf122331)
 {
     createScDoc("ods/tdf122331.ods");
diff --git a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx 
b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
index 89ebcc27373c..7c28d5c81125 100644
--- a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
+++ b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
@@ -655,6 +655,9 @@ private:
         if (aParam.bCaseSens)
             mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, 
XML_TRUE);
 
+        if (!aParam.bSummaryBelow)
+            mrExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_SUMMARY_BELOW, 
XML_FALSE);
+
         SvXMLElementExport aElemSTRs(mrExport, XML_NAMESPACE_TABLE, 
XML_SUBTOTAL_RULES, true, true);
 
         if (aParam.bDoSort)
diff --git a/sc/source/filter/xml/xmldrani.cxx 
b/sc/source/filter/xml/xmldrani.cxx
index 5708c74d2fa3..bfa6be8c898f 100644
--- a/sc/source/filter/xml/xmldrani.cxx
+++ b/sc/source/filter/xml/xmldrani.cxx
@@ -99,6 +99,7 @@ ScXMLDatabaseRangeContext::ScXMLDatabaseRangeContext( 
ScXMLImport& rImport,
     bSubTotalsBindFormatsToContent(false),
     bSubTotalsIsCaseSensitive(false),
     bSubTotalsInsertPageBreaks(false),
+    bSubTotalsSummaryBelow(true),
     bSubTotalsSortGroups(false),
     bSubTotalsEnabledUserList(false),
     bSubTotalsAscending(true),
@@ -325,6 +326,7 @@ std::unique_ptr<ScDBData> 
ScXMLDatabaseRangeContext::ConvertToDBData(const OUStr
         aParam.bUserDef = bSubTotalsEnabledUserList;
         aParam.nUserIndex = nSubTotalsUserListIndex;
         aParam.bPagebreak = bSubTotalsInsertPageBreaks;
+        aParam.bSummaryBelow = bSubTotalsSummaryBelow;
         aParam.bCaseSens = bSubTotalsIsCaseSensitive;
         aParam.bDoSort = bSubTotalsSortGroups;
         aParam.bAscending = bSubTotalsAscending;
@@ -634,6 +636,9 @@ ScXMLSubTotalRulesContext::ScXMLSubTotalRulesContext( 
ScXMLImport& rImport,
             case XML_ELEMENT( TABLE, XML_PAGE_BREAKS_ON_GROUP_CHANGE ):
                 
pDatabaseRangeContext->SetSubTotalsInsertPageBreaks(IsXMLToken(aIter, 
XML_TRUE));
                 break;
+            case XML_ELEMENT( LO_EXT, XML_SUMMARY_BELOW ):
+                
pDatabaseRangeContext->SetSubTotalsSummaryBelow(IsXMLToken(aIter, XML_TRUE));
+                break;
         }
     }
 }
diff --git a/sc/source/filter/xml/xmldrani.hxx 
b/sc/source/filter/xml/xmldrani.hxx
index a35074117c28..4f5b951751c1 100644
--- a/sc/source/filter/xml/xmldrani.hxx
+++ b/sc/source/filter/xml/xmldrani.hxx
@@ -76,6 +76,7 @@ class ScXMLDatabaseRangeContext : public ScXMLImportContext
     bool            bSubTotalsBindFormatsToContent;
     bool            bSubTotalsIsCaseSensitive;
     bool            bSubTotalsInsertPageBreaks;
+    bool            bSubTotalsSummaryBelow;
     bool            bSubTotalsSortGroups;
     bool            bSubTotalsEnabledUserList;
     bool            bSubTotalsAscending;
@@ -106,6 +107,7 @@ public:
     void SetSubTotalsBindFormatsToContent(const bool bTemp ) { 
bSubTotalsBindFormatsToContent = bTemp; }
     void SetSubTotalsIsCaseSensitive(const bool bTemp) { 
bSubTotalsIsCaseSensitive = bTemp; }
     void SetSubTotalsInsertPageBreaks(const bool bTemp) { 
bSubTotalsInsertPageBreaks = bTemp; }
+    void SetSubTotalsSummaryBelow(const bool bTemp) { bSubTotalsSummaryBelow = 
bTemp; }
     void SetSubTotalsEnabledUserList(const bool bTemp) { 
bSubTotalsEnabledUserList = bTemp; }
     void SetSubTotalsUserListIndex(const sal_Int16 nTemp) { 
nSubTotalsUserListIndex = nTemp; }
     void SetSubTotalsAscending(const bool bTemp) { bSubTotalsAscending = 
bTemp; }
diff --git a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng 
b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
index 86f4322929c4..c9d41d0778cd 100644
--- a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
+++ b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
@@ -2727,6 +2727,15 @@ 
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.
     </rng:optional>
   </rng:define>
 
+    <!-- TODO no proposal, tdf#162262 -->
+  <rng:define name="table-subtotal-rules-attlist" combine="interleave">
+    <rng:optional>
+      <rng:attribute name="loext:summary-below">
+        <rng:ref name="boolean"/>
+      </rng:attribute>
+    </rng:optional>
+  </rng:define>
+
     <!-- TODO no proposal, 9009663d -->
   <rng:define name="chart-chart-attlist" combine="interleave">
     <rng:optional>
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index 467713fda6ec..171c38c9ac45 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -1937,6 +1937,7 @@ namespace xmloff::token {
         TOKEN( "sub-view-size",                   XML_SUB_VIEW_SIZE ),
         TOKEN( "suffix",                          XML_SUFFIX ),
         TOKEN( "sum",                             XML_SUM ),
+        TOKEN( "summary-below",                   XML_SUMMARY_BELOW ),
         TOKEN( "swiss",                           XML_SWISS ),
         TOKEN( "symbol",                          XML_SYMBOL ),
         TOKEN( "symbol-height",                   XML_SYMBOL_HEIGHT ),
diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt
index 25cdb87ed5b4..9bfe5dda2b8c 100644
--- a/xmloff/source/token/tokens.txt
+++ b/xmloff/source/token/tokens.txt
@@ -1837,6 +1837,7 @@ subtotal-rules
 sub-view-size
 suffix
 sum
+summary-below
 swiss
 symbol
 symbol-height
commit de0f01eb163b258b04fd97b6a78817afc0c7fe46
Author:     Balazs Varga <balazs.varga.ext...@allotropia.de>
AuthorDate: Thu Nov 21 00:53:28 2024 +0100
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Wed Nov 27 00:31:31 2024 +0100

    Related: tdf#160536 - ooxml import export correctly cell protection
    
    property for Pivot tables cells.
    
    Change-Id: I1bff7a27cf169fd0876e361b22b4d7017f190b40
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176897
    Tested-by: Jenkins
    Reviewed-by: Balazs Varga <balazs.varga.ext...@allotropia.de>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177233
    Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de>
    Tested-by: allotropia jenkins <jenk...@allotropia.de>

diff --git a/sc/qa/unit/PivotTableFormatsImportExport.cxx 
b/sc/qa/unit/PivotTableFormatsImportExport.cxx
index 22d56c0f11d6..437a25d5e7e6 100644
--- a/sc/qa/unit/PivotTableFormatsImportExport.cxx
+++ b/sc/qa/unit/PivotTableFormatsImportExport.cxx
@@ -57,6 +57,13 @@ Color getFontColor(ScDocument& rDoc, OUString const& 
rAddressString)
     return rItem.getColor();
 }
 
+bool getCellProtection(ScDocument& rDoc, OUString const& rAddressString)
+{
+    const ScPatternAttr* pPattern = rDoc.GetPattern(parseAddress(rDoc, 
rAddressString));
+    const ScProtectionAttr& rItem = pPattern->GetItem(ATTR_PROTECTION);
+    return rItem.GetProtection();
+}
+
 template <typename T> OUString checkNonEmptyAddresses(ScDocument& rDoc, T 
const& rArrayOfAddresses)
 {
     OUString aString;
@@ -66,7 +73,8 @@ template <typename T> OUString 
checkNonEmptyAddresses(ScDocument& rDoc, T const&
         aAddress.Parse(rAddressString, rDoc);
         const ScPatternAttr* pPattern = rDoc.GetPattern(aAddress);
         if (pPattern->GetItem(ATTR_FONT_COLOR).getColor() != COL_BLACK
-            || pPattern->GetItem(ATTR_BACKGROUND).GetColor() != 
COL_TRANSPARENT)
+            || pPattern->GetItem(ATTR_BACKGROUND).GetColor() != COL_TRANSPARENT
+            || !pPattern->GetItem(ATTR_PROTECTION).GetProtection())
         {
             aString += rAddressString + " ";
         }
@@ -416,6 +424,31 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport,
     assertTwoDataFieldColumns_WholeDataColumnSelected(*getScDoc());
 }
 
+static void assertFields_WithCellProtection(ScDocument& rDoc)
+{
+    CPPUNIT_ASSERT_EQUAL(false, getCellProtection(rDoc, u"F18"_ustr));
+    CPPUNIT_ASSERT_EQUAL(false, getCellProtection(rDoc, u"F19"_ustr));
+    CPPUNIT_ASSERT_EQUAL(false, getCellProtection(rDoc, u"F20"_ustr));
+    CPPUNIT_ASSERT_EQUAL(false, getCellProtection(rDoc, u"G18"_ustr));
+    CPPUNIT_ASSERT_EQUAL(false, getCellProtection(rDoc, u"G19"_ustr));
+    CPPUNIT_ASSERT_EQUAL(false, getCellProtection(rDoc, u"G20"_ustr));
+
+    // Make sure the other cells have the font color or background set to 
default
+    std::vector<OUString> aEmptyAddresses{
+        u"F15"_ustr, u"G15"_ustr, u"F16"_ustr, u"G16"_ustr,
+        u"F17"_ustr, u"G17"_ustr, u"G21"_ustr, u"F21"_ustr,
+    };
+    CPPUNIT_ASSERT_EQUAL(OUString(), checkNonEmptyAddresses(rDoc, 
aEmptyAddresses));
+}
+
+CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport, 
Pivot_Table_with_Cell_Protection)
+{
+    createScDoc("xlsx/pivot-table/Pivot_Table_with_Cell_Protection.xlsx");
+    assertFields_WithCellProtection(*getScDoc());
+    saveAndReload(u"Calc Office Open XML"_ustr);
+    assertFields_WithCellProtection(*getScDoc());
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git 
a/sc/qa/unit/data/xlsx/pivot-table/Pivot_Table_with_Cell_Protection.xlsx 
b/sc/qa/unit/data/xlsx/pivot-table/Pivot_Table_with_Cell_Protection.xlsx
new file mode 100644
index 000000000000..d7966a2d9e32
Binary files /dev/null and 
b/sc/qa/unit/data/xlsx/pivot-table/Pivot_Table_with_Cell_Protection.xlsx differ
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 4321a27893a5..83a880bdaf3b 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -433,20 +433,6 @@ void ScTable::DeleteArea(
                 aCol[i].DeleteArea(nRow1, nRow2, nDelFlag, bBroadcast, 
pBroadcastSpans);
         }
 
-            // Do not set protected cell in a protected table
-
-        if ( IsProtected() && (nDelFlag & InsertDeleteFlags::ATTRIB) )
-        {
-            // Do not overwrite cell protection if we are in a Pivot table 
area and its not protected
-            const ScDPObject* pDPObj = rDocument.GetDPAtArea(nTab, nCol1, 
nRow1, nCol2, nRow2);
-            if (!pDPObj || (pDPObj && 
!GetProtection()->isOptionEnabled(ScTableProtection::PIVOT_TABLES)))
-            {
-                ScPatternAttr aPattern(rDocument.getCellAttributeHelper());
-                aPattern.GetItemSet().Put(ScProtectionAttr(false));
-                ApplyPatternArea(nCol1, nRow1, nCol2, nRow2, aPattern);
-            }
-        }
-
         if( nDelFlag & InsertDeleteFlags::ATTRIB )
             mpCondFormatList->DeleteArea( nCol1, nRow1, nCol2, nRow2 );
     }
@@ -475,28 +461,6 @@ void ScTable::DeleteSelection( InsertDeleteFlags nDelFlag, 
const ScMarkData& rMa
             mpCondFormatList->DeleteArea( rRange.aStart.Col(), 
rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row() );
     }
 
-        // Do not set protected cell in a protected sheet
-
-    if ( IsProtected() && (nDelFlag & InsertDeleteFlags::ATTRIB) )
-    {
-        // Do not overwrite cell protection if we are in a Pivot table area 
and its not protected
-        const ScRange& rRange = rMark.GetArea();
-        const ScDPObject* pDPObj = rDocument.GetDPAtArea(nTab,
-            rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), 
rRange.aEnd.Row());
-        if (!pDPObj || (pDPObj && 
!GetProtection()->isOptionEnabled(ScTableProtection::PIVOT_TABLES)))
-        {
-            SfxItemSetFixed<ATTR_PATTERN_START, ATTR_PATTERN_END> 
aSet(*rDocument.GetPool());
-            aSet.Put(ScProtectionAttr(false));
-            ScItemPoolCache aCache(rDocument.getCellAttributeHelper(), aSet);
-            ApplySelectionCache(aCache, rMark);
-        }
-
-        SfxItemSetFixed<ATTR_PATTERN_START, ATTR_PATTERN_END> 
aSet(*rDocument.GetPool());
-        aSet.Put( ScProtectionAttr( false ) );
-        ScItemPoolCache aCache(rDocument.getCellAttributeHelper(), aSet );
-        ApplySelectionCache( aCache, rMark );
-    }
-
     // TODO: In the future we may want to check if the table has been
     // really modified before setting the stream invalid.
     SetStreamValid(false);
@@ -787,20 +751,6 @@ void ScTable::CopyFromClip(
                 pRowFlags->AndValue( j, ~CRFlags::ManualSize);
         }
     }
-
-    // Do not set protected cell in a protected sheet
-    if (IsProtected() && (rCxt.getInsertFlag() & InsertDeleteFlags::ATTRIB))
-    {
-        // Do not overwrite cell protection if we are in a Pivot table area 
and its not protected
-        const ScDPObject* pDPObj = rDocument.GetDPAtArea(nTab, nCol1, nRow1, 
nCol2, nRow2);
-        if (!pDPObj || (pDPObj && 
!GetProtection()->isOptionEnabled(ScTableProtection::PIVOT_TABLES)))
-        {
-            ScPatternAttr aPattern(rDocument.getCellAttributeHelper());
-            aPattern.GetItemSet().Put(ScProtectionAttr(false));
-            ApplyPatternArea(nCol1, nRow1, nCol2, nRow2, aPattern);
-        }
-    }
-
     // create deep copies for conditional formatting
     CopyConditionalFormat( nCol1, nRow1, nCol2, nRow2, nDx, nDy, pTable);
 }
diff --git a/sc/source/filter/excel/xepivotxml.cxx 
b/sc/source/filter/excel/xepivotxml.cxx
index ddccb1cd36f6..90f58aebc574 100644
--- a/sc/source/filter/excel/xepivotxml.cxx
+++ b/sc/source/filter/excel/xepivotxml.cxx
@@ -1241,25 +1241,28 @@ void 
XclExpXmlPivotTables::savePivotTableFormats(XclExpXmlStream& rStream, ScDPO
                         pAttributeList->add(XML_fieldPosition, 
OString::number(*rFormat.oFieldPosition));
                     pPivotStream->startElement(XML_pivotArea, pAttributeList);
                 }
-                pPivotStream->startElement(XML_references, XML_count, 
OString::number(rFormat.aSelections.size()));
-                for (sc::Selection const& rSelection : rFormat.getSelections())
+                if (rFormat.aSelections.size())
                 {
+                    pPivotStream->startElement(XML_references, XML_count, 
OString::number(rFormat.aSelections.size()));
+                    for (sc::Selection const& rSelection : 
rFormat.getSelections())
                     {
-                        auto pRefAttributeList = 
sax_fastparser::FastSerializerHelper::createAttrList();
-                        pRefAttributeList->add(XML_field, 
OString::number(sal_uInt32(rSelection.nField)));
-                        pRefAttributeList->add(XML_count, "1");
-                        if (!rSelection.bSelected) // default is true
-                            pRefAttributeList->add(XML_selected, "0");
-                        pPivotStream->startElement(XML_reference, 
pRefAttributeList);
-                    }
+                        {
+                            auto pRefAttributeList = 
sax_fastparser::FastSerializerHelper::createAttrList();
+                            pRefAttributeList->add(XML_field, 
OString::number(sal_uInt32(rSelection.nField)));
+                            pRefAttributeList->add(XML_count, "1");
+                            if (!rSelection.bSelected) // default is true
+                                pRefAttributeList->add(XML_selected, "0");
+                            pPivotStream->startElement(XML_reference, 
pRefAttributeList);
+                        }
 
-                    for (sal_uInt32 nIndex : rSelection.nIndices)
-                    {
-                        pPivotStream->singleElement(XML_x, XML_v, 
OString::number(nIndex));
+                        for (sal_uInt32 nIndex : rSelection.nIndices)
+                        {
+                            pPivotStream->singleElement(XML_x, XML_v, 
OString::number(nIndex));
+                        }
+                        pPivotStream->endElement(XML_reference);
                     }
-                    pPivotStream->endElement(XML_reference);
+                    pPivotStream->endElement(XML_references);
                 }
-                pPivotStream->endElement(XML_references);
                 pPivotStream->endElement(XML_pivotArea);
 
                 pPivotStream->endElement(XML_format);
diff --git a/sc/source/filter/inc/stylesbuffer.hxx 
b/sc/source/filter/inc/stylesbuffer.hxx
index ec6f5800cb66..95ec8b8806ff 100644
--- a/sc/source/filter/inc/stylesbuffer.hxx
+++ b/sc/source/filter/inc/stylesbuffer.hxx
@@ -357,11 +357,14 @@ bool operator==( const ApiProtectionData& rLeft, const 
ApiProtectionData& rRight
 class Protection : public WorkbookHelper
 {
 public:
-    explicit            Protection( const WorkbookHelper& rHelper );
+    explicit            Protection( const WorkbookHelper& rHelper, bool bDxf );
 
     /** Sets all attributes from the protection element. */
     void                importProtection( const AttributeList& rAttribs );
 
+    /** Sets the protection attributes from the passed BIFF12 DXF record data. 
*/
+    void                importDxfProtection( sal_Int32 nElement, 
SequenceInputStream& rStrm );
+
     /** Sets the protection attributes from the passed BIFF12 XF record data. 
*/
     void                setBiff12Data( sal_uInt32 nFlags );
 
@@ -375,8 +378,11 @@ public:
 private:
     ProtectionModel     maModel;            /// Protection model data.
     ApiProtectionData   maApiData;          /// Protection data converted to 
API constants.
+    bool                mbDxf;
 };
 
+typedef std::shared_ptr< Protection > ProtectionRef;
+
 /** Contains XML attributes of a single border line. */
 struct BorderLineModel
 {
@@ -667,6 +673,8 @@ public:
     BorderRef const &   createBorder( bool bAlwaysNew = true );
     /** Creates a new empty fill object. */
     FillRef const &     createFill( bool bAlwaysNew = true );
+    /** Creates a new empty protection object. */
+    ProtectionRef const & createProtection( bool bAlwaysNew = true );
 
     /** Inserts a new number format code. */
     void                importNumFmt( const AttributeList& rAttribs );
diff --git a/sc/source/filter/oox/stylesbuffer.cxx 
b/sc/source/filter/oox/stylesbuffer.cxx
index 5f64cf61addb..efdca05255e5 100644
--- a/sc/source/filter/oox/stylesbuffer.cxx
+++ b/sc/source/filter/oox/stylesbuffer.cxx
@@ -183,6 +183,8 @@ const sal_uInt16 BIFF12_DXF_FONT_HEIGHT     = 36;
 const sal_uInt16 BIFF12_DXF_FONT_SCHEME     = 37;
 const sal_uInt16 BIFF12_DXF_NUMFMT_CODE     = 38;
 const sal_uInt16 BIFF12_DXF_NUMFMT_ID       = 41;
+const sal_uInt16 BIFF12_DXF_CELL_LOCKED     = 43;
+const sal_uInt16 BIFF12_DXF_CELL_HIDDEN     = 44;
 
 // BIFF12 CELLSTYLE flags
 const sal_uInt16 BIFF12_CELLSTYLE_BUILTIN   = 0x0001;
@@ -1368,8 +1370,9 @@ bool operator==( const ApiProtectionData& rLeft, const 
ApiProtectionData& rRight
         (rLeft.maCellProt.IsPrintHidden   == rRight.maCellProt.IsPrintHidden);
 }
 
-Protection::Protection( const WorkbookHelper& rHelper ) :
-    WorkbookHelper( rHelper )
+Protection::Protection( const WorkbookHelper& rHelper, bool bDxf ) :
+    WorkbookHelper( rHelper ),
+    mbDxf( bDxf )
 {
 }
 
@@ -1379,6 +1382,23 @@ void Protection::importProtection( const AttributeList& 
rAttribs )
     maModel.mbHidden = rAttribs.getBool( XML_hidden, false );
 }
 
+void Protection::importDxfProtection( sal_Int32 nElement, SequenceInputStream& 
rStrm )
+{
+    SAL_WARN_IF( !mbDxf, "sc", "Protection::importDxfProtection - missing 
protection flag" );
+    bool bFlag = rStrm.readuInt8() != 0;
+    switch( nElement )
+    {
+        case XML_locked:
+            maModel.mbLocked = bFlag;
+        break;
+        case XML_hidden:
+            maModel.mbHidden = bFlag;
+        break;
+        default:
+            OSL_FAIL( "Protection::importDxfProtection - unexpected element 
identifier" );
+    }
+}
+
 void Protection::setBiff12Data( sal_uInt32 nFlags )
 {
     maModel.mbLocked = getFlag( nFlags, BIFF12_XF_LOCKED );
@@ -2005,7 +2025,7 @@ Xf::Xf( const WorkbookHelper& rHelper ) :
     WorkbookHelper( rHelper ),
     mnScNumFmt(0),
     maAlignment( rHelper ),
-    maProtection( rHelper ),
+    maProtection( rHelper, false ),
     meRotationRef( css::table::CellVertJustify2::STANDARD ),
     mpStyleSheet( nullptr )
 {
@@ -2341,6 +2361,13 @@ FillRef const & Dxf::createFill( bool bAlwaysNew )
     return mxFill;
 }
 
+ProtectionRef const & Dxf::createProtection( bool bAlwaysNew )
+{
+    if ( bAlwaysNew || !mxProtection )
+        mxProtection = std::make_shared<Protection>( *this, true );
+    return mxProtection;
+}
+
 void Dxf::importNumFmt( const AttributeList& rAttribs )
 {
     // don't propagate number formats defined in Dxf entries
@@ -2391,6 +2418,8 @@ void Dxf::importDxf( SequenceInputStream& rStrm )
             case BIFF12_DXF_FONT_SCHEME:        createFont( false 
)->importDxfScheme( rStrm );                          break;
             case BIFF12_DXF_NUMFMT_CODE:        aFmtCode = 
BiffHelper::readString( rStrm, false );                      break;
             case BIFF12_DXF_NUMFMT_ID:          nNumFmtId = 
rStrm.readuInt16();                                         break;
+            case BIFF12_DXF_CELL_LOCKED:        createProtection( false 
)->importDxfProtection( XML_locked, rStrm );    break;
+            case BIFF12_DXF_CELL_HIDDEN:        createProtection( false 
)->importDxfProtection( XML_hidden, rStrm );    break;
         }
         rStrm.seek( nRecEnd );
     }
diff --git a/sc/source/filter/oox/stylesfragment.cxx 
b/sc/source/filter/oox/stylesfragment.cxx
index de6312b9649c..1d20b98519ff 100644
--- a/sc/source/filter/oox/stylesfragment.cxx
+++ b/sc/source/filter/oox/stylesfragment.cxx
@@ -151,8 +151,8 @@ ContextHandlerRef DxfContext::onCreateContext( sal_Int32 
nElement, const Attribu
                 case XLS_TOKEN( numFmt ):       mxDxf->importNumFmt( rAttribs 
);        break;
 #if 0
                 case XLS_TOKEN( alignment ):    mxDxf->importAlignment( 
rAttribs );     break;
-                case XLS_TOKEN( protection ):   mxDxf->importProtection( 
rAttribs );    break;
 #endif
+                case XLS_TOKEN( protection ):   
mxDxf->createProtection()->importProtection( rAttribs ); break;
             }
         break;
 
@@ -163,6 +163,7 @@ ContextHandlerRef DxfContext::onCreateContext( sal_Int32 
nElement, const Attribu
                 case XLS_TOKEN( border ):       return new BorderContext( 
*this, mxDxf->createBorder() );
                 case XLS_TOKEN( fill ):         return new FillContext( *this, 
mxDxf->createFill() );
                 case XLS_TOKEN( numFmt ):       mxDxf->importNumFmt( rAttribs 
);     break;
+                case XLS_TOKEN( protection ):   
mxDxf->createProtection()->importProtection( rAttribs ); break;
             }
         break;
     }

Reply via email to