include/xmloff/xmltoken.hxx                                 |    2 
 sc/inc/document.hxx                                         |    7 
 sc/inc/global.hxx                                           |    5 
 sc/inc/table.hxx                                            |    3 
 sc/qa/unit/data/xlsx/tdfSheetProts.xlsx                     |binary
 sc/qa/unit/subsequent_export_test4.cxx                      |   52 +++
 sc/qa/unit/ucalc_pivottable.cxx                             |   27 ++
 sc/source/core/data/documen3.cxx                            |   14 +
 sc/source/core/data/document10.cxx                          |    9 
 sc/source/core/data/table2.cxx                              |   38 ++
 sc/source/core/data/table7.cxx                              |   51 ++-
 sc/source/filter/oox/pivottablebuffer.cxx                   |    3 
 sc/source/filter/xml/xmlexprt.cxx                           |    5 
 sc/source/filter/xml/xmlsubti.cxx                           |    6 
 sc/source/filter/xml/xmlsubti.hxx                           |    2 
 sc/source/filter/xml/xmltabi.cxx                            |   10 
 sc/source/ui/docshell/dbdocfun.cxx                          |   34 +-
 sc/source/ui/docshell/docfunc.cxx                           |   16 -
 sc/source/ui/docshell/editable.cxx                          |   43 ++-
 sc/source/ui/docshell/impex.cxx                             |    2 
 sc/source/ui/inc/editable.hxx                               |   21 -
 sc/source/ui/inc/protectiondlg.hxx                          |    4 
 sc/source/ui/miscdlgs/protectiondlg.cxx                     |    8 
 sc/source/ui/view/cellsh.cxx                                |   12 
 sc/source/ui/view/cellsh2.cxx                               |   63 +++-
 sc/source/ui/view/gridwin.cxx                               |   20 +
 sc/source/ui/view/pivotsh.cxx                               |   14 -
 sc/uiconfig/scalc/ui/protectsheetdlg.ui                     |  160 ++++++------
 schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng |   10 
 xmloff/source/core/xmltoken.cxx                             |    2 
 xmloff/source/token/tokens.txt                              |    2 
 31 files changed, 469 insertions(+), 176 deletions(-)

New commits:
commit 83910246044c1e05a3b50e25d21ac6a31566cc38
Author:     Balazs Varga <[email protected]>
AuthorDate: Wed Nov 6 21:33:46 2024 +0100
Commit:     Balazs Varga <[email protected]>
CommitDate: Thu Nov 14 23:53:24 2024 +0100

    tdf#160404 tdf#160535 tdf#160536 - sc improve sheet protection
    
    tdf#160404: Fix FILEOPEN XLSX Pivot table is not imported if sheet
    protection has Pivot table editing enabled
    - Import correctly the pivot tables, even if the tab protection is not
    allowing to use them.
    
    tdf#160535: Support sheet protection option: Use AutoFilter
    - Add new option for tab protection to enable/disable to use autofilter
    on the sheet. Import/export correctly to odf/ooxml.
    Add new ext-odf attribute: XML_USE_AUTOFILTER
    
    tdf#160536: Support sheet protection option: Use PivotTable&PivotChart
    - Add new option for tab protection to enable/disable to use Pivot table
    on the sheet. Import/export correctly to odf/ooxml.
    Add new ext-odf attribute: XML_USE_PIVOT
    
    Change-Id: I5d34e3608aed1a3d004ec553f6125b6428e9c05e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176274
    Tested-by: Jenkins
    Reviewed-by: Balazs Varga <[email protected]>

diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index cd61d4d3c065..574beaced5e5 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -2095,6 +2095,7 @@ namespace xmloff::token {
         XML_UPRIGHT,
         XML_URL,
         XML_USE,
+        XML_USE_AUTOFILTER,
         XML_USE_CAPTION,
         XML_USE_CELL_PROTECTION,
         XML_USE_CHART_OBJECTS,
@@ -2112,6 +2113,7 @@ namespace xmloff::token {
         XML_USE_OPTIMAL_COLUMN_WIDTH,
         XML_USE_OPTIMAL_ROW_HEIGHT,
         XML_USE_OTHER_OBJECTS,
+        XML_USE_PIVOT,
         XML_USE_SPREADSHEET_OBJECTS,
         XML_USE_STYLES,
         XML_USE_TABLES,
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 7caa75d7db1e..9f9a79eb024f 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -934,6 +934,7 @@ public:
     SC_DLLPUBLIC bool                  HasPivotTable() const;
     SC_DLLPUBLIC ScDPCollection*       GetDPCollection();
     SC_DLLPUBLIC const ScDPCollection* GetDPCollection() const;
+    SC_DLLPUBLIC const ScDPObject*     GetDPAtArea(SCTAB nTab, SCCOL nCol1, 
SCROW nRow1, SCCOL nCol2, SCROW nRow2) const;
     SC_DLLPUBLIC ScDPObject*           GetDPAtCursor(SCCOL nCol, SCROW nRow, 
SCTAB nTab) const;
     SC_DLLPUBLIC ScDPObject*           GetDPAtCursor(ScAddress const& 
rAddress) const
     {
@@ -1040,8 +1041,10 @@ public:
                                                     SCCOL nEndCol, SCROW 
nEndRow,
                                                     const ScMarkData& rMark ) 
const;
 
-    bool IsEditActionAllowed( sc::ColRowEditAction eAction, SCTAB nTab, 
SCCOLROW nStart, SCCOLROW nEnd ) const;
-    bool IsEditActionAllowed( sc::ColRowEditAction eAction, const ScMarkData& 
rMark, SCCOLROW nStart, SCCOLROW nEnd ) const;
+    bool            IsEditActionAllowed( sc::EditAction eAction, SCTAB nTab, 
SCCOL nStartCol, SCROW nStartRow,
+                                         SCCOL nEndCol, SCROW nEndRow ) const;
+    bool            IsEditActionAllowed( sc::EditAction eAction, const 
ScMarkData& rMark, SCCOL nStartCol,
+                                         SCROW nStartRow, SCCOL nEndCol, SCROW 
nEndRow ) const;
 
     SC_DLLPUBLIC bool GetMatrixFormulaRange( const ScAddress& rCellPos, 
ScRange& rMatrix );
 
diff --git a/sc/inc/global.hxx b/sc/inc/global.hxx
index 79d24030179b..616930567210 100644
--- a/sc/inc/global.hxx
+++ b/sc/inc/global.hxx
@@ -425,7 +425,7 @@ enum ScDBObject
 
 namespace sc {
 
-enum class ColRowEditAction
+enum class EditAction
 {
     Unknown,
     InsertColumnsBefore,
@@ -433,7 +433,8 @@ enum class ColRowEditAction
     InsertRowsBefore,
     InsertRowsAfter,
     DeleteColumns,
-    DeleteRows
+    DeleteRows,
+    UpdatePivotTable
 };
 
 }
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index c1dfb716b595..5f36e5d9d5c7 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -409,7 +409,8 @@ public:
     const ScTableProtection* GetProtection() const;
     void            GetUnprotectedCells( ScRangeList& rRangeList ) const;
 
-    bool IsEditActionAllowed( sc::ColRowEditAction eAction, SCCOLROW nStart, 
SCCOLROW nEnd ) const;
+    bool            IsEditActionAllowed( sc::EditAction eAction, SCCOL 
nStartCol, SCROW nStartRow,
+                                         SCCOL nEndCol, SCROW nEndRow ) const;
 
     Size            GetPageSize() const;
     void            SetPageSize( const Size& rSize );
diff --git a/sc/qa/unit/data/xlsx/tdfSheetProts.xlsx 
b/sc/qa/unit/data/xlsx/tdfSheetProts.xlsx
new file mode 100644
index 000000000000..ffd9fe127840
Binary files /dev/null and b/sc/qa/unit/data/xlsx/tdfSheetProts.xlsx differ
diff --git a/sc/qa/unit/subsequent_export_test4.cxx 
b/sc/qa/unit/subsequent_export_test4.cxx
index ae856010b110..fae430bbe6f1 100644
--- a/sc/qa/unit/subsequent_export_test4.cxx
+++ b/sc/qa/unit/subsequent_export_test4.cxx
@@ -24,6 +24,8 @@
 #include <dbdata.hxx>
 #include <subtotalparam.hxx>
 #include <globstr.hrc>
+#include <tabprotection.hxx>
+#include <dpobject.hxx>
 
 #include <editeng/wghtitem.hxx>
 #include <editeng/postitem.hxx>
@@ -2061,6 +2063,56 @@ CPPUNIT_TEST_FIXTURE(ScExportTest4, testNotesAuthor)
     pBatch->commit();
 }
 
+CPPUNIT_TEST_FIXTURE(ScExportTest4, testSheetProtections)
+{
+    auto verify = [this]() {
+        ScDocument* pDoc = getScDoc();
+
+        // 1. tab autofilter allowed, pivot tables not allowed
+        const ScTableProtection* pTab1Protect = pDoc->GetTabProtection(0);
+        CPPUNIT_ASSERT(pTab1Protect);
+        
CPPUNIT_ASSERT(pTab1Protect->isOptionEnabled(ScTableProtection::AUTOFILTER));
+        
CPPUNIT_ASSERT(!pTab1Protect->isOptionEnabled(ScTableProtection::PIVOT_TABLES));
+
+        // 2. tab autofilter NOT allowed, pivot tables allowed
+        const ScTableProtection* pTab2Protect = pDoc->GetTabProtection(1);
+        CPPUNIT_ASSERT(pTab2Protect);
+        
CPPUNIT_ASSERT(!pTab2Protect->isOptionEnabled(ScTableProtection::AUTOFILTER));
+        
CPPUNIT_ASSERT(pTab2Protect->isOptionEnabled(ScTableProtection::PIVOT_TABLES));
+
+        // check we have pivot table
+        ScDPObject* pDPObj1 = pDoc->GetDPAtCursor(0, 0, 1);
+        CPPUNIT_ASSERT(pDPObj1);
+        CPPUNIT_ASSERT(!pDPObj1->GetName().isEmpty());
+
+        // 3. tab autofilter NOT allowed, pivot tables not allowed
+        const ScTableProtection* pTab3Protect = pDoc->GetTabProtection(2);
+        CPPUNIT_ASSERT(pTab3Protect);
+        
CPPUNIT_ASSERT(!pTab3Protect->isOptionEnabled(ScTableProtection::AUTOFILTER));
+        
CPPUNIT_ASSERT(!pTab3Protect->isOptionEnabled(ScTableProtection::PIVOT_TABLES));
+
+        // 4. tab autofilter allowed, pivot tables not allowed
+        const ScTableProtection* pTab4Protect = pDoc->GetTabProtection(3);
+        CPPUNIT_ASSERT(pTab4Protect);
+        
CPPUNIT_ASSERT(pTab4Protect->isOptionEnabled(ScTableProtection::AUTOFILTER));
+        
CPPUNIT_ASSERT(!pTab4Protect->isOptionEnabled(ScTableProtection::PIVOT_TABLES));
+
+        // check we have pivot table
+        ScDPObject* pDPObj2 = pDoc->GetDPAtCursor(0, 0, 3);
+        CPPUNIT_ASSERT(pDPObj2);
+        CPPUNIT_ASSERT(!pDPObj2->GetName().isEmpty());
+    };
+
+    createScDoc("xlsx/tdfSheetProts.xlsx");
+    verify();
+
+    saveAndReload(u"Calc Office Open XML"_ustr);
+    verify();
+
+    saveAndReload(u"calc8"_ustr);
+    verify();
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/qa/unit/ucalc_pivottable.cxx b/sc/qa/unit/ucalc_pivottable.cxx
index 594d7a7e1265..9517826423bf 100644
--- a/sc/qa/unit/ucalc_pivottable.cxx
+++ b/sc/qa/unit/ucalc_pivottable.cxx
@@ -17,6 +17,7 @@
 #include <stringutil.hxx>
 #include <dbdocfun.hxx>
 #include <generalfunction.hxx>
+#include <tabprotection.hxx>
 
 #include <formula/errorcodes.hxx>
 #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
@@ -2115,6 +2116,32 @@ CPPUNIT_TEST_FIXTURE(TestPivottable, 
testPivotTableDocFunc)
         CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
     }
 
+    // Start: Test Pivot table with tab protection
+    ScTableProtection aProtect;
+    aProtect.setProtected(true);
+    m_pDoc->SetTabProtection(1, &aProtect);
+
+    bSuccess = aFunc.RemovePivotTable(*pDPObject, false, true);
+    CPPUNIT_ASSERT_MESSAGE("Pivot table should not be allowed to remove.", 
!bSuccess);
+
+    bSuccess = aFunc.UpdatePivotTable(*pDPObject, false, true);
+    CPPUNIT_ASSERT_MESSAGE("Pivot table should not be allowed to update.", 
!bSuccess);
+
+    // Allow pivot table usage
+    aProtect.setOption(ScTableProtection::PIVOT_TABLES, true);
+    m_pDoc->SetTabProtection(1, &aProtect);
+
+    bSuccess = aFunc.RemovePivotTable(*pDPObject, false, true);
+    CPPUNIT_ASSERT_MESSAGE("Pivot table should not be allowed to remove.", 
!bSuccess);
+
+    bSuccess = aFunc.UpdatePivotTable(*pDPObject, false, true);
+    CPPUNIT_ASSERT_MESSAGE("Pivot table should be allowed to update.", 
bSuccess);
+
+    aProtect.setProtected(false);
+    aProtect.setOption(ScTableProtection::PIVOT_TABLES, false);
+    m_pDoc->SetTabProtection(1, &aProtect);
+    // End: Test Pivot table with tab protection
+
     // Remove this pivot table output. This should also clear the pivot cache
     // it was referencing.
     bSuccess = aFunc.RemovePivotTable(*pDPObject, false, true);
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index 1ef2b40530d5..788f16a135d9 100644
--- a/sc/source/core/data/documen3.cxx
+++ b/sc/source/core/data/documen3.cxx
@@ -379,6 +379,20 @@ const ScDPCollection* ScDocument::GetDPCollection() const
     return pDPCollection.get();
 }
 
+const ScDPObject* ScDocument::GetDPAtArea(SCTAB nTab, SCCOL nCol1, SCROW 
nRow1, SCCOL nCol2, SCROW nRow2) const
+{
+    if (!pDPCollection)
+        return nullptr;
+
+    sal_uInt16 nCount = pDPCollection->GetCount();
+    ScRange aRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab);
+    for (sal_uInt16 i = 0; i < nCount; i++)
+        if ((*pDPCollection)[i].GetOutRange() == aRange)
+            return &(*pDPCollection)[i];
+
+    return nullptr;
+}
+
 ScDPObject* ScDocument::GetDPAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab) const
 {
     if (!pDPCollection)
diff --git a/sc/source/core/data/document10.cxx 
b/sc/source/core/data/document10.cxx
index 74716ce93dd7..4c6527304a7e 100644
--- a/sc/source/core/data/document10.cxx
+++ b/sc/source/core/data/document10.cxx
@@ -961,20 +961,21 @@ bool ScDocument::CopyAdjustRangeName( SCTAB& rSheet, 
sal_uInt16& rIndex, ScRange
 }
 
 bool ScDocument::IsEditActionAllowed(
-    sc::ColRowEditAction eAction, SCTAB nTab, SCCOLROW nStart, SCCOLROW nEnd ) 
const
+    sc::EditAction eAction, SCTAB nTab, SCCOL nStartCol, SCROW nStartRow, 
SCCOL nEndCol, SCROW nEndRow ) const
 {
     const ScTable* pTab = FetchTable(nTab);
     if (!pTab)
         return false;
 
-    return pTab->IsEditActionAllowed(eAction, nStart, nEnd);
+    return pTab->IsEditActionAllowed(eAction, nStartCol, nStartRow, nEndCol, 
nEndRow);
 }
 
 bool ScDocument::IsEditActionAllowed(
-    sc::ColRowEditAction eAction, const ScMarkData& rMark, SCCOLROW nStart, 
SCCOLROW nEnd ) const
+    sc::EditAction eAction, const ScMarkData& rMark, SCCOL nStartCol, SCROW 
nStartRow, SCCOL nEndCol, SCROW nEndRow ) const
 {
     return std::all_of(rMark.begin(), rMark.end(),
-        [this, &eAction, &nStart, &nEnd](const SCTAB& rTab) { return 
IsEditActionAllowed(eAction, rTab, nStart, nEnd); });
+        [this, &eAction, &nStartCol, &nStartRow, &nEndCol, &nEndRow](const 
SCTAB& rTab)
+        { return IsEditActionAllowed(eAction, rTab, nStartCol, nStartRow, 
nEndCol, nEndRow); });
 }
 
 std::optional<sc::ColumnIterator> ScDocument::GetColumnIterator( SCTAB nTab, 
SCCOL nCol, SCROW nRow1, SCROW nRow2 ) const
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 933b9a37930e..4321a27893a5 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -52,6 +52,7 @@
 #include <compressedarray.hxx>
 #include <refdata.hxx>
 #include <docsh.hxx>
+#include <dpobject.hxx>
 
 #include <scitems.hxx>
 #include <editeng/boxitem.hxx>
@@ -436,9 +437,14 @@ void ScTable::DeleteArea(
 
         if ( IsProtected() && (nDelFlag & InsertDeleteFlags::ATTRIB) )
         {
-            ScPatternAttr aPattern(rDocument.getCellAttributeHelper());
-            aPattern.GetItemSet().Put( ScProtectionAttr( false ) );
-            ApplyPatternArea( nCol1, nRow1, nCol2, nRow2, aPattern );
+            // 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 )
@@ -473,6 +479,18 @@ void ScTable::DeleteSelection( InsertDeleteFlags nDelFlag, 
const ScMarkData& rMa
 
     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 );
@@ -773,9 +791,14 @@ void ScTable::CopyFromClip(
     // Do not set protected cell in a protected sheet
     if (IsProtected() && (rCxt.getInsertFlag() & InsertDeleteFlags::ATTRIB))
     {
-        ScPatternAttr aPattern(rDocument.getCellAttributeHelper());
-        aPattern.GetItemSet().Put( ScProtectionAttr( false ) );
-        ApplyPatternArea( nCol1, nRow1, nCol2, nRow2, aPattern );
+        // 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
@@ -2709,8 +2732,7 @@ bool ScTable::IsBlockEditable( SCCOL nCol1, SCROW nRow1, 
SCCOL nCol2,
         if (!bIsEditable)
         {
             // An enhanced protection permission may override the attribute.
-            if (pTabProtection)
-                bIsEditable = pTabProtection->isBlockEditable( ScRange( nCol1, 
nRow1, nTab, nCol2, nRow2, nTab));
+            bIsEditable = pTabProtection->isBlockEditable( ScRange( nCol1, 
nRow1, nTab, nCol2, nRow2, nTab));
         }
         if (bIsEditable)
         {
diff --git a/sc/source/core/data/table7.cxx b/sc/source/core/data/table7.cxx
index b1aab8dc2052..c41dcf9464a1 100644
--- a/sc/source/core/data/table7.cxx
+++ b/sc/source/core/data/table7.cxx
@@ -339,8 +339,8 @@ void ScTable::SetNeedsListeningGroup( SCCOL nCol, SCROW 
nRow )
     CreateColumnIfNotExists(nCol).SetNeedsListeningGroup(nRow);
 }
 
-bool ScTable::IsEditActionAllowed(
-    sc::ColRowEditAction eAction, SCCOLROW nStart, SCCOLROW nEnd ) const
+bool ScTable::IsEditActionAllowed( sc::EditAction eAction, SCCOL nStartCol, 
SCROW nStartRow,
+    SCCOL nEndCol, SCROW nEndRow ) const
 {
     if (!IsProtected())
     {
@@ -349,20 +349,20 @@ bool ScTable::IsEditActionAllowed(
 
         switch (eAction)
         {
-            case sc::ColRowEditAction::InsertColumnsBefore:
-            case sc::ColRowEditAction::InsertColumnsAfter:
-            case sc::ColRowEditAction::DeleteColumns:
+            case sc::EditAction::InsertColumnsBefore:
+            case sc::EditAction::InsertColumnsAfter:
+            case sc::EditAction::DeleteColumns:
             {
-                nCol1 = nStart;
-                nCol2 = nEnd;
+                nCol1 = nStartCol;
+                nCol2 = nEndCol;
                 break;
             }
-            case sc::ColRowEditAction::InsertRowsBefore:
-            case sc::ColRowEditAction::InsertRowsAfter:
-            case sc::ColRowEditAction::DeleteRows:
+            case sc::EditAction::InsertRowsBefore:
+            case sc::EditAction::InsertRowsAfter:
+            case sc::EditAction::DeleteRows:
             {
-                nRow1 = nStart;
-                nRow2 = nEnd;
+                nRow1 = nStartRow;
+                nRow2 = nEndRow;
                 break;
             }
             default:
@@ -381,37 +381,44 @@ bool ScTable::IsEditActionAllowed(
 
     switch (eAction)
     {
-        case sc::ColRowEditAction::InsertColumnsBefore:
-        case sc::ColRowEditAction::InsertColumnsAfter:
+        case sc::EditAction::InsertColumnsBefore:
+        case sc::EditAction::InsertColumnsAfter:
         {
             // TODO: improve the matrix range handling for the insert-before 
action.
-            if (HasBlockMatrixFragment(nStart, 0, nEnd, rDocument.MaxRow()))
+            if (HasBlockMatrixFragment(nStartCol, nStartRow, nEndCol, nEndRow))
                 return false;
 
             return 
pTabProtection->isOptionEnabled(ScTableProtection::INSERT_COLUMNS);
         }
-        case sc::ColRowEditAction::InsertRowsBefore:
-        case sc::ColRowEditAction::InsertRowsAfter:
+        case sc::EditAction::InsertRowsBefore:
+        case sc::EditAction::InsertRowsAfter:
         {
             // TODO: improve the matrix range handling for the insert-before 
action.
-            if (HasBlockMatrixFragment(0, nStart, rDocument.MaxCol(), nEnd))
+            if (HasBlockMatrixFragment(nStartCol, nStartRow, nEndCol, nEndRow))
                 return false;
 
             return 
pTabProtection->isOptionEnabled(ScTableProtection::INSERT_ROWS);
         }
-        case sc::ColRowEditAction::DeleteColumns:
+        case sc::EditAction::DeleteColumns:
         {
             if 
(!pTabProtection->isOptionEnabled(ScTableProtection::DELETE_COLUMNS))
                 return false;
 
-            return !HasAttrib(nStart, 0, nEnd, rDocument.MaxRow(), 
HasAttrFlags::Protected);
+            return !HasAttrib(nStartCol, nStartRow, nEndCol, nEndRow, 
HasAttrFlags::Protected);
         }
-        case sc::ColRowEditAction::DeleteRows:
+        case sc::EditAction::DeleteRows:
         {
             if 
(!pTabProtection->isOptionEnabled(ScTableProtection::DELETE_ROWS))
                 return false;
 
-            return !HasAttrib(0, nStart, rDocument.MaxCol(), nEnd, 
HasAttrFlags::Protected);
+            return !HasAttrib(nStartCol, nStartRow, nEndCol, nEndRow, 
HasAttrFlags::Protected);
+        }
+        case sc::EditAction::UpdatePivotTable:
+        {
+            if 
(pTabProtection->isOptionEnabled(ScTableProtection::PIVOT_TABLES))
+                return true;
+
+            return !HasAttrib(nStartCol, nStartRow, nEndCol, nEndRow, 
HasAttrFlags::Protected);
         }
         default:
             ;
diff --git a/sc/source/filter/oox/pivottablebuffer.cxx 
b/sc/source/filter/oox/pivottablebuffer.cxx
index 249176cf2b7b..f128e27afd0e 100644
--- a/sc/source/filter/oox/pivottablebuffer.cxx
+++ b/sc/source/filter/oox/pivottablebuffer.cxx
@@ -1355,7 +1355,10 @@ void PivotTable::finalizeImport()
         mpDPObject->PutInteropGrabBag(std::move(maInteropGrabBag));
 
         // insert the DataPilot table into the sheet
+        ScDocument& rDoc = getDocImport().getDoc();
+        rDoc.SetImportingXML(true);
         xDPTables->insertNewByName( maDefModel.maName, aPos, mxDPDescriptor );
+        rDoc.SetImportingXML(false);
     }
     catch( Exception& )
     {
diff --git a/sc/source/filter/xml/xmlexprt.cxx 
b/sc/source/filter/xml/xmlexprt.cxx
index 19722fe6bbd8..2ca445ba2a1f 100644
--- a/sc/source/filter/xml/xmlexprt.cxx
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -2907,6 +2907,11 @@ void ScXMLExport::WriteTable(sal_Int32 nTable, const 
uno::Reference<sheet::XSpre
         if (pProtect->isOptionEnabled(ScTableProtection::DELETE_ROWS))
             AddAttribute(XML_NAMESPACE_LO_EXT, XML_DELETE_ROWS, XML_TRUE);
 
+        if (pProtect->isOptionEnabled(ScTableProtection::AUTOFILTER))
+            AddAttribute(XML_NAMESPACE_LO_EXT, XML_USE_AUTOFILTER, XML_TRUE);
+        if (pProtect->isOptionEnabled(ScTableProtection::PIVOT_TABLES))
+            AddAttribute(XML_NAMESPACE_LO_EXT, XML_USE_PIVOT, XML_TRUE);
+
         OUString aElemName = GetNamespaceMap().GetQNameByKey(
             XML_NAMESPACE_LO_EXT, GetXMLToken(XML_TABLE_PROTECTION));
 
diff --git a/sc/source/filter/xml/xmlsubti.cxx 
b/sc/source/filter/xml/xmlsubti.cxx
index 0d865721b930..02cd36264ccb 100644
--- a/sc/source/filter/xml/xmlsubti.cxx
+++ b/sc/source/filter/xml/xmlsubti.cxx
@@ -49,7 +49,9 @@ ScXMLTabProtectionData::ScXMLTabProtectionData() :
     mbInsertColumns(false),
     mbInsertRows(false),
     mbDeleteColumns(false),
-    mbDeleteRows(false)
+    mbDeleteRows(false),
+    mbUseAutoFilter(false),
+    mbUsePivot(false)
 {
 }
 
@@ -208,6 +210,8 @@ void ScMyTables::DeleteTable()
     aProtect.setOption(ScTableProtection::INSERT_ROWS,    
maProtectionData.mbInsertRows);
     aProtect.setOption(ScTableProtection::DELETE_COLUMNS, 
maProtectionData.mbDeleteColumns);
     aProtect.setOption(ScTableProtection::DELETE_ROWS,    
maProtectionData.mbDeleteRows);
+    aProtect.setOption(ScTableProtection::AUTOFILTER,     
maProtectionData.mbUseAutoFilter);
+    aProtect.setOption(ScTableProtection::PIVOT_TABLES,   
maProtectionData.mbUsePivot);
     rImport.GetDocument()->SetTabProtection(maCurrentCellPos.Tab(), &aProtect);
 }
 
diff --git a/sc/source/filter/xml/xmlsubti.hxx 
b/sc/source/filter/xml/xmlsubti.hxx
index 49e148b3db16..b5ccc4261600 100644
--- a/sc/source/filter/xml/xmlsubti.hxx
+++ b/sc/source/filter/xml/xmlsubti.hxx
@@ -42,6 +42,8 @@ struct ScXMLTabProtectionData
     bool            mbInsertRows;
     bool            mbDeleteColumns;
     bool            mbDeleteRows;
+    bool            mbUseAutoFilter;
+    bool            mbUsePivot;
 
     ScXMLTabProtectionData();
 };
diff --git a/sc/source/filter/xml/xmltabi.cxx b/sc/source/filter/xml/xmltabi.cxx
index af4ba33d3c6f..5010c70b5e11 100644
--- a/sc/source/filter/xml/xmltabi.cxx
+++ b/sc/source/filter/xml/xmltabi.cxx
@@ -417,6 +417,8 @@ ScXMLTableProtectionContext::ScXMLTableProtectionContext(
     bool bInsertRows = false;
     bool bDeleteColumns = false;
     bool bDeleteRows = false;
+    bool bUseAutoFilter = false;
+    bool bUsePivot = false;
 
     if ( rAttrList.is() )
     {
@@ -447,6 +449,12 @@ ScXMLTableProtectionContext::ScXMLTableProtectionContext(
             case XML_ELEMENT( LO_EXT, XML_DELETE_ROWS ):
                 bDeleteRows = IsXMLToken(aIter, XML_TRUE);
                 break;
+            case XML_ELEMENT( LO_EXT, XML_USE_AUTOFILTER ):
+                bUseAutoFilter = IsXMLToken(aIter, XML_TRUE);
+                break;
+            case XML_ELEMENT( LO_EXT, XML_USE_PIVOT ):
+                bUsePivot = IsXMLToken(aIter, XML_TRUE);
+                break;
             default:
                 XMLOFF_WARN_UNKNOWN("sc", aIter);
             }
@@ -460,6 +468,8 @@ ScXMLTableProtectionContext::ScXMLTableProtectionContext(
     rProtectData.mbInsertRows = bInsertRows;
     rProtectData.mbDeleteColumns = bDeleteColumns;
     rProtectData.mbDeleteRows = bDeleteRows;
+    rProtectData.mbUseAutoFilter = bUseAutoFilter;
+    rProtectData.mbUsePivot = bUsePivot;
 }
 
 ScXMLTableProtectionContext::~ScXMLTableProtectionContext()
diff --git a/sc/source/ui/docshell/dbdocfun.cxx 
b/sc/source/ui/docshell/dbdocfun.cxx
index cb7ffe31e9e0..1ded38ed6eda 100644
--- a/sc/source/ui/docshell/dbdocfun.cxx
+++ b/sc/source/ui/docshell/dbdocfun.cxx
@@ -1213,7 +1213,8 @@ bool lcl_EmptyExcept( ScDocument& rDoc, const ScRange& 
rRange, const ScRange& rE
     return true;        // nothing found - empty
 }
 
-bool isEditable(ScDocShell& rDocShell, const ScRangeList& rRanges, bool bApi)
+bool isEditable(ScDocShell& rDocShell, const ScRangeList& rRanges, bool bApi,
+    sc::EditAction eAction = sc::EditAction::Unknown)
 {
     ScDocument& rDoc = rDocShell.GetDocument();
     if (!rDocShell.IsEditable() || rDoc.GetChangeTrack())
@@ -1228,7 +1229,7 @@ bool isEditable(ScDocShell& rDocShell, const ScRangeList& 
rRanges, bool bApi)
     for (size_t i = 0, n = rRanges.size(); i < n; ++i)
     {
         const ScRange & r = rRanges[i];
-        ScEditableTester aTester(rDoc, r);
+        ScEditableTester aTester(rDoc, r, eAction);
         if (!aTester.IsEditable())
         {
             if (!bApi)
@@ -1249,7 +1250,8 @@ void createUndoDoc(ScDocumentUniquePtr& pUndoDoc, 
ScDocument& rDoc, const ScRang
     rDoc.CopyToDocument(rRange, InsertDeleteFlags::ALL, false, *pUndoDoc);
 }
 
-bool checkNewOutputRange(ScDPObject& rDPObj, ScDocShell& rDocShell, ScRange& 
rNewOut, bool bApi)
+bool checkNewOutputRange(ScDPObject& rDPObj, ScDocShell& rDocShell, ScRange& 
rNewOut, bool bApi,
+    sc::EditAction eAction = sc::EditAction::Unknown)
 {
     ScDocument& rDoc = rDocShell.GetDocument();
 
@@ -1279,14 +1281,17 @@ bool checkNewOutputRange(ScDPObject& rDPObj, 
ScDocShell& rDocShell, ScRange& rNe
         return false;
     }
 
-    ScEditableTester aTester(rDoc, rNewOut);
-    if (!aTester.IsEditable())
+    if (!rDoc.IsImportingXML())
     {
-        //  destination area isn't editable
-        if (!bApi)
-            rDocShell.ErrorMessage(aTester.GetMessageId());
+        ScEditableTester aTester(rDoc, rNewOut, eAction);
+        if (!aTester.IsEditable())
+        {
+            //  destination area isn't editable
+            if (!bApi)
+                rDocShell.ErrorMessage(aTester.GetMessageId());
 
-        return false;
+            return false;
+        }
     }
 
     return true;
@@ -1484,12 +1489,12 @@ bool ScDBDocFunc::CreatePivotTable(const ScDPObject& 
rDPObj, bool bRecord, bool
     weld::WaitObject aWait(ScDocShell::GetActiveDialogParent());
 
     // At least one cell in the output range should be editable. Check in 
advance.
-    if (!isEditable(rDocShell, ScRange(rDPObj.GetOutRange().aStart), bApi))
+    ScDocument& rDoc = rDocShell.GetDocument();
+    if (!rDoc.IsImportingXML() && !isEditable(rDocShell, 
ScRange(rDPObj.GetOutRange().aStart), bApi))
         return false;
 
     ScDocumentUniquePtr pNewUndoDoc;
 
-    ScDocument& rDoc = rDocShell.GetDocument();
     if (bRecord && !rDoc.IsUndoEnabled())
         bRecord = false;
 
@@ -1537,8 +1542,9 @@ bool ScDBDocFunc::CreatePivotTable(const ScDPObject& 
rDPObj, bool bRecord, bool
         return false;
     }
 
+    if (!rDoc.IsImportingXML())
     {
-        ScEditableTester aTester(rDoc, aNewOut);
+        ScEditableTester aTester(rDoc, aNewOut, sc::EditAction::Unknown);
         if (!aTester.IsEditable())
         {
             //  destination area isn't editable
@@ -1594,7 +1600,7 @@ bool ScDBDocFunc::UpdatePivotTable(ScDPObject& rDPObj, 
bool bRecord, bool bApi)
     ScDocShellModificator aModificator( rDocShell );
     weld::WaitObject aWait( ScDocShell::GetActiveDialogParent() );
 
-    if (!isEditable(rDocShell, rDPObj.GetOutRange(), bApi))
+    if (!isEditable(rDocShell, rDPObj.GetOutRange(), bApi, 
sc::EditAction::UpdatePivotTable))
         return false;
 
     ScDocumentUniquePtr pOldUndoDoc;
@@ -1621,7 +1627,7 @@ bool ScDBDocFunc::UpdatePivotTable(ScDPObject& rDPObj, 
bool bRecord, bool bApi)
         rDPObj.SetName( rDoc.GetDPCollection()->CreateNewName() );
 
     ScRange aNewOut;
-    if (!checkNewOutputRange(rDPObj, rDocShell, aNewOut, bApi))
+    if (!checkNewOutputRange(rDPObj, rDocShell, aNewOut, bApi, 
sc::EditAction::UpdatePivotTable))
     {
         rDPObj = aUndoDPObj;
         return false;
diff --git a/sc/source/ui/docshell/docfunc.cxx 
b/sc/source/ui/docshell/docfunc.cxx
index 0b16439f29cf..dccbb6d224e7 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -1904,19 +1904,19 @@ bool ScDocFunc::InsertCells( const ScRange& rRange, 
const ScMarkData* pTabMark,
     {
         case INS_INSCOLS_BEFORE:
             aTester = ScEditableTester(
-                rDoc, sc::ColRowEditAction::InsertColumnsBefore, 
nMergeTestStartCol, nMergeTestEndCol, aMark);
+                rDoc, sc::EditAction::InsertColumnsBefore, nMergeTestStartCol, 
0, nMergeTestEndCol, rDoc.MaxRow(), aMark);
             break;
         case INS_INSCOLS_AFTER:
             aTester = ScEditableTester(
-                rDoc, sc::ColRowEditAction::InsertColumnsAfter, 
nMergeTestStartCol, nMergeTestEndCol, aMark);
+                rDoc, sc::EditAction::InsertColumnsAfter, nMergeTestStartCol, 
0, nMergeTestEndCol, rDoc.MaxRow(), aMark);
             break;
         case INS_INSROWS_BEFORE:
             aTester = ScEditableTester(
-                rDoc, sc::ColRowEditAction::InsertRowsBefore, 
nMergeTestStartRow, nMergeTestEndRow, aMark);
+                rDoc, sc::EditAction::InsertRowsBefore, 0, nMergeTestStartRow, 
rDoc.MaxCol(), nMergeTestEndRow, aMark);
             break;
         case INS_INSROWS_AFTER:
             aTester = ScEditableTester(
-                rDoc, sc::ColRowEditAction::InsertRowsAfter, 
nMergeTestStartRow, nMergeTestEndRow, aMark);
+                rDoc, sc::EditAction::InsertRowsAfter, 0, nMergeTestStartRow, 
rDoc.MaxCol(), nMergeTestEndRow, aMark);
             break;
         default:
             aTester = ScEditableTester(
@@ -2406,11 +2406,11 @@ bool ScDocFunc::DeleteCells( const ScRange& rRange, 
const ScMarkData* pTabMark,
     {
         case DelCellCmd::Cols:
             aTester = ScEditableTester(
-                rDoc, sc::ColRowEditAction::DeleteColumns, nUndoStartCol, 
nUndoEndCol, aMark);
+                rDoc, sc::EditAction::DeleteColumns, nUndoStartCol, 0, 
nUndoEndCol, rDoc.MaxRow(), aMark);
             break;
         case DelCellCmd::Rows:
             aTester = ScEditableTester(
-                rDoc, sc::ColRowEditAction::DeleteRows, nUndoStartRow, 
nUndoEndRow, aMark);
+                rDoc, sc::EditAction::DeleteRows, 0, nUndoStartRow, 
rDoc.MaxCol(), nUndoEndRow, aMark);
             break;
         default:
             aTester = ScEditableTester(
@@ -4890,7 +4890,7 @@ bool ScDocFunc::FillAuto( ScRange& rRange, const 
ScMarkData* pTabMark, FillDir e
     //!     Source range can be protected !!!
     //!     but can't contain matrix fragments !!!
 
-    ScEditableTester aTester( rDoc, aDestArea );
+    ScEditableTester aTester( rDoc, aDestArea, sc::EditAction::Unknown );
     if ( !aTester.IsEditable() )
     {
         if (!bApi)
@@ -5743,7 +5743,7 @@ void ScDocFunc::ConvertFormulaToValue( const ScRange& 
rRange, bool bInteraction
     if (!rDoc.IsUndoEnabled())
         bRecord = false;
 
-    ScEditableTester aTester(rDoc, rRange);
+    ScEditableTester aTester(rDoc, rRange, sc::EditAction::Unknown);
     if (!aTester.IsEditable())
     {
         if (bInteraction)
diff --git a/sc/source/ui/docshell/editable.cxx 
b/sc/source/ui/docshell/editable.cxx
index 86bbb9f2e004..357897470aa1 100644
--- a/sc/source/ui/docshell/editable.cxx
+++ b/sc/source/ui/docshell/editable.cxx
@@ -45,11 +45,14 @@ ScEditableTester::ScEditableTester( const ScDocument& rDoc,
     TestSelectedBlock( rDoc, nStartCol, nStartRow, nEndCol, nEndRow, rMark );
 }
 
-ScEditableTester::ScEditableTester( const ScDocument& rDoc, const ScRange& 
rRange ) :
+ScEditableTester::ScEditableTester( const ScDocument& rDoc, const ScRange& 
rRange, sc::EditAction eAction ) :
     mbIsEditable(true),
     mbOnlyMatrix(true)
 {
-    TestRange( rDoc, rRange );
+    if (eAction == sc::EditAction::Unknown)
+        TestRange(rDoc, rRange);
+    else
+        TestRangeForAction( rDoc, rRange, eAction );
 }
 
 ScEditableTester::ScEditableTester( const ScDocument& rDoc, const ScMarkData& 
rMark ) :
@@ -73,10 +76,11 @@ ScEditableTester::ScEditableTester( ScViewFunc* pView ) :
 }
 
 ScEditableTester::ScEditableTester(
-    const ScDocument& rDoc, sc::ColRowEditAction eAction, SCCOLROW nStart, 
SCCOLROW nEnd, const ScMarkData& rMark ) :
+    const ScDocument& rDoc, sc::EditAction eAction, SCCOL nStartCol, SCROW 
nStartRow,
+    SCCOL nEndCol, SCROW nEndRow, const ScMarkData& rMark ) :
     ScEditableTester()
 {
-    TestBlockForAction(rDoc, eAction, nStart, nEnd, rMark);
+    TestBlockForAction(rDoc, eAction, nStartCol, nStartRow, nEndCol, nEndRow, 
rMark);
 }
 
 void ScEditableTester::TestBlock( const ScDocument& rDoc, SCTAB nTab,
@@ -85,7 +89,7 @@ void ScEditableTester::TestBlock( const ScDocument& rDoc, 
SCTAB nTab,
     if (mbIsEditable || mbOnlyMatrix)
     {
         bool bThisMatrix;
-        if (!rDoc.IsBlockEditable( nTab, nStartCol, nStartRow, nEndCol, 
nEndRow, &bThisMatrix, bNoMatrixAtAll))
+        if (!rDoc.IsBlockEditable( nTab, nStartCol, nStartRow, nEndCol, 
nEndRow, &bThisMatrix, bNoMatrixAtAll ))
         {
             mbIsEditable = false;
             if ( !bThisMatrix )
@@ -94,6 +98,15 @@ void ScEditableTester::TestBlock( const ScDocument& rDoc, 
SCTAB nTab,
     }
 }
 
+void ScEditableTester::TestBlockForAction( const ScDocument& rDoc, SCTAB nTab,
+        SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, 
sc::EditAction eAction )
+{
+    if (mbIsEditable || mbOnlyMatrix)
+    {
+        mbIsEditable = rDoc.IsEditActionAllowed(eAction, nTab, nStartCol, 
nStartRow, nEndCol, nEndRow);
+    }
+}
+
 void ScEditableTester::TestSelectedBlock( const ScDocument& rDoc,
                         SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW 
nEndRow,
                         const ScMarkData& rMark )
@@ -108,7 +121,7 @@ void ScEditableTester::TestSelectedBlock( const ScDocument& 
rDoc,
     }
 }
 
-void ScEditableTester::TestRange(  const ScDocument& rDoc, const ScRange& 
rRange )
+void ScEditableTester::TestRange( const ScDocument& rDoc, const ScRange& 
rRange )
 {
     SCCOL nStartCol = rRange.aStart.Col();
     SCROW nStartRow = rRange.aStart.Row();
@@ -120,6 +133,18 @@ void ScEditableTester::TestRange(  const ScDocument& rDoc, 
const ScRange& rRange
         TestBlock( rDoc, nTab, nStartCol, nStartRow, nEndCol, nEndRow, false );
 }
 
+void ScEditableTester::TestRangeForAction(const ScDocument& rDoc, const 
ScRange& rRange, sc::EditAction eAction)
+{
+    SCCOL nStartCol = rRange.aStart.Col();
+    SCROW nStartRow = rRange.aStart.Row();
+    SCTAB nStartTab = rRange.aStart.Tab();
+    SCCOL nEndCol = rRange.aEnd.Col();
+    SCROW nEndRow = rRange.aEnd.Row();
+    SCTAB nEndTab = rRange.aEnd.Tab();
+    for (SCTAB nTab = nStartTab; nTab <= nEndTab; nTab++)
+        TestBlockForAction(rDoc, nTab, nStartCol, nStartRow, nEndCol, nEndRow, 
eAction);
+}
+
 void ScEditableTester::TestSelection( const ScDocument& rDoc, const 
ScMarkData& rMark )
 {
     if (mbIsEditable || mbOnlyMatrix)
@@ -135,8 +160,8 @@ void ScEditableTester::TestSelection( const ScDocument& 
rDoc, const ScMarkData&
 }
 
 void ScEditableTester::TestBlockForAction(
-    const ScDocument& rDoc, sc::ColRowEditAction eAction, SCCOLROW nStart, 
SCCOLROW nEnd,
-    const ScMarkData& rMark )
+    const ScDocument& rDoc, sc::EditAction eAction, SCCOL nStartCol, SCROW 
nStartRow,
+    SCCOL nEndCol, SCROW nEndRow, const ScMarkData& rMark )
 {
     mbOnlyMatrix = false;
 
@@ -145,7 +170,7 @@ void ScEditableTester::TestBlockForAction(
         if (!mbIsEditable)
             return;
 
-        mbIsEditable = rDoc.IsEditActionAllowed(eAction, rTab, nStart, nEnd);
+        mbIsEditable = rDoc.IsEditActionAllowed(eAction, rTab, nStartCol, 
nStartRow, nEndCol, nEndRow);
     }
 }
 
diff --git a/sc/source/ui/docshell/impex.cxx b/sc/source/ui/docshell/impex.cxx
index 5bb6fb343ca4..b7a27b5b6711 100644
--- a/sc/source/ui/docshell/impex.cxx
+++ b/sc/source/ui/docshell/impex.cxx
@@ -230,7 +230,7 @@ bool ScImportExport::StartPaste()
 {
     if ( !bAll )
     {
-        ScEditableTester aTester( rDoc, aRange );
+        ScEditableTester aTester( rDoc, aRange, sc::EditAction::Unknown );
         if ( !aTester.IsEditable() )
         {
             std::unique_ptr<weld::MessageDialog> 
xInfoBox(Application::CreateMessageDialog(ScDocShell::GetActiveDialogParent(),
diff --git a/sc/source/ui/inc/editable.hxx b/sc/source/ui/inc/editable.hxx
index 1c229a1b11ef..c5deab9ae699 100644
--- a/sc/source/ui/inc/editable.hxx
+++ b/sc/source/ui/inc/editable.hxx
@@ -28,7 +28,7 @@ class ScMarkData;
 
 namespace sc {
 
-enum class ColRowEditAction;
+enum class EditAction;
 
 }
 
@@ -54,7 +54,7 @@ public:
                         const ScMarkData& rMark );
 
             // calls TestRange
-            ScEditableTester( const ScDocument& rDoc, const ScRange& rRange );
+            ScEditableTester( const ScDocument& rDoc, const ScRange& rRange, 
sc::EditAction eAction );
 
             // calls TestSelection
             ScEditableTester( const ScDocument& rDoc, const ScMarkData& rMark 
);
@@ -62,24 +62,29 @@ public:
             // calls TestView
             ScEditableTester( ScViewFunc* pView );
 
-    ScEditableTester(
-        const ScDocument& rDoc, sc::ColRowEditAction eAction, SCCOLROW nStart, 
SCCOLROW nEnd,
-        const ScMarkData& rMark );
+            ScEditableTester(
+                const ScDocument& rDoc, sc::EditAction eAction, SCCOL 
nStartCol,
+                SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const 
ScMarkData& rMark );
 
             // Several calls to the Test... methods check if *all* of the 
ranges
             // are editable. For several independent checks, Reset() has to be 
used.
     void    TestBlock( const ScDocument& rDoc, SCTAB nTab,
                         SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW 
nEndRow,
                         bool bNoMatrixAtAll = false );
+    void    TestBlockForAction( const ScDocument& rDoc, SCTAB nTab,
+                        SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW 
nEndRow,
+                        sc::EditAction eAction );
     void    TestSelectedBlock( const ScDocument& rDoc,
                         SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW 
nEndRow,
                         const ScMarkData& rMark );
     void    TestRange( const ScDocument& rDoc, const ScRange& rRange );
+    void    TestRangeForAction( const ScDocument& rDoc, const ScRange& rRange,
+                       sc::EditAction eAction );
     void    TestSelection( const ScDocument& rDoc, const ScMarkData& rMark );
 
-    void TestBlockForAction(
-        const ScDocument& rDoc, sc::ColRowEditAction eAction, SCCOLROW nStart, 
SCCOLROW nEnd,
-        const ScMarkData& rMark );
+    void    TestBlockForAction(
+                        const ScDocument& rDoc, sc::EditAction eAction, SCCOL 
nStartCol, SCROW nStartRow,
+                        SCCOL nEndCol, SCROW nEndRow, const ScMarkData& rMark 
);
 
     bool IsEditable() const { return mbIsEditable; }
     bool IsFormatEditable() const { return mbIsEditable || mbOnlyMatrix; }
diff --git a/sc/source/ui/inc/protectiondlg.hxx 
b/sc/source/ui/inc/protectiondlg.hxx
index e59fb3accf77..4ad633cbd6d5 100644
--- a/sc/source/ui/inc/protectiondlg.hxx
+++ b/sc/source/ui/inc/protectiondlg.hxx
@@ -45,6 +45,8 @@ private:
     OUString m_aInsertRows;
     OUString m_aDeleteColumns;
     OUString m_aDeleteRows;
+    OUString m_aAutoFilter;
+    OUString m_aPivot;
 
     std::unique_ptr<weld::CheckButton> m_xBtnProtect;
     std::unique_ptr<weld::Container> m_xPasswords;
@@ -60,6 +62,8 @@ private:
     std::unique_ptr<weld::Label> m_xInsertRows;
     std::unique_ptr<weld::Label> m_xDeleteColumns;
     std::unique_ptr<weld::Label> m_xDeleteRows;
+    std::unique_ptr<weld::Label> m_xAutoFilter;
+    std::unique_ptr<weld::Label> m_xPivot;
 
     void InsertEntry(const OUString& rTxt);
 
diff --git a/sc/source/ui/miscdlgs/protectiondlg.cxx 
b/sc/source/ui/miscdlgs/protectiondlg.cxx
index f96cc72c0346..041f50dfa0db 100644
--- a/sc/source/ui/miscdlgs/protectiondlg.cxx
+++ b/sc/source/ui/miscdlgs/protectiondlg.cxx
@@ -33,6 +33,8 @@ const std::vector<ScTableProtection::Option> aOptions = {
     ScTableProtection::INSERT_ROWS,
     ScTableProtection::DELETE_COLUMNS,
     ScTableProtection::DELETE_ROWS,
+    ScTableProtection::AUTOFILTER,
+    ScTableProtection::PIVOT_TABLES,
 };
 
 }
@@ -53,6 +55,8 @@ ScTableProtectionDlg::ScTableProtectionDlg(weld::Window* 
pParent)
     , m_xInsertRows(m_xBuilder->weld_label(u"insert-rows"_ustr))
     , m_xDeleteColumns(m_xBuilder->weld_label(u"delete-columns"_ustr))
     , m_xDeleteRows(m_xBuilder->weld_label(u"delete-rows"_ustr))
+    , m_xAutoFilter(m_xBuilder->weld_label(u"useautofilter"_ustr))
+    , m_xPivot(m_xBuilder->weld_label(u"usepivot"_ustr))
 {
     m_aSelectLockedCells = m_xProtected->get_label();
     m_aSelectUnlockedCells = m_xUnprotected->get_label();
@@ -60,6 +64,8 @@ ScTableProtectionDlg::ScTableProtectionDlg(weld::Window* 
pParent)
     m_aInsertRows = m_xInsertRows->get_label();
     m_aDeleteColumns = m_xDeleteColumns->get_label();
     m_aDeleteRows = m_xDeleteRows->get_label();
+    m_aAutoFilter = m_xAutoFilter->get_label();
+    m_aPivot = m_xPivot->get_label();
 
     m_xOptionsListBox->enable_toggle_buttons(weld::ColumnToggleType::Check);
 
@@ -114,6 +120,8 @@ void ScTableProtectionDlg::Init()
     InsertEntry(m_aInsertRows);
     InsertEntry(m_aDeleteColumns);
     InsertEntry(m_aDeleteRows);
+    InsertEntry(m_aAutoFilter);
+    InsertEntry(m_aPivot);
 
     m_xOptionsListBox->set_toggle(0, TRISTATE_TRUE);
     m_xOptionsListBox->set_toggle(1, TRISTATE_TRUE);
diff --git a/sc/source/ui/view/cellsh.cxx b/sc/source/ui/view/cellsh.cxx
index f1ff35b5a379..f18c6ceb30e5 100644
--- a/sc/source/ui/view/cellsh.cxx
+++ b/sc/source/ui/view/cellsh.cxx
@@ -256,15 +256,15 @@ void ScCellShell::GetBlockState( SfxItemSet& rSet )
             case FID_INS_ROWS_BEFORE:           // insert rows
             case FID_INS_ROWS_AFTER:
             {
-                sc::ColRowEditAction eAction = 
sc::ColRowEditAction::InsertRowsBefore;
+                sc::EditAction eAction = sc::EditAction::InsertRowsBefore;
                 if (nWhich == FID_INS_ROWS_AFTER)
-                    eAction = sc::ColRowEditAction::InsertRowsAfter;
+                    eAction = sc::EditAction::InsertRowsAfter;
 
                 bDisable = (!bSimpleArea) || GetViewData().SimpleColMarked();
                 if (!bEditable && nCol1 == 0 && nCol2 == rDoc.MaxCol())
                 {
                     // See if row insertions are allowed.
-                    bEditable = rDoc.IsEditActionAllowed(eAction, rMark, 
nRow1, nRow2);
+                    bEditable = rDoc.IsEditActionAllowed(eAction, rMark, 
nCol1, nRow1, nCol2, nRow2);
                 }
                 break;
             }
@@ -276,16 +276,16 @@ void ScCellShell::GetBlockState( SfxItemSet& rSet )
             case FID_INS_COLUMNS_BEFORE:        // insert columns
             case FID_INS_COLUMNS_AFTER:
             {
-                sc::ColRowEditAction eAction = 
sc::ColRowEditAction::InsertColumnsBefore;
+                sc::EditAction eAction = sc::EditAction::InsertColumnsBefore;
                 if (nWhich == FID_INS_COLUMNS_AFTER)
-                    eAction = sc::ColRowEditAction::InsertColumnsAfter;
+                    eAction = sc::EditAction::InsertColumnsAfter;
 
                 bDisable = (!bSimpleArea && eMarkType != 
SC_MARK_SIMPLE_FILTERED)
                            || GetViewData().SimpleRowMarked();
                 if (!bEditable && nRow1 == 0 && nRow2 == rDoc.MaxRow())
                 {
                     // See if row insertions are allowed.
-                    bEditable = rDoc.IsEditActionAllowed(eAction, rMark, 
nCol1, nCol2);
+                    bEditable = rDoc.IsEditActionAllowed(eAction, rMark, 
nCol1, nRow1, nCol2, nRow2);
                 }
                 break;
             }
diff --git a/sc/source/ui/view/cellsh2.cxx b/sc/source/ui/view/cellsh2.cxx
index bb7c4cf831b3..1a3aa891ffde 100644
--- a/sc/source/ui/view/cellsh2.cxx
+++ b/sc/source/ui/view/cellsh2.cxx
@@ -1116,11 +1116,19 @@ void ScCellShell::GetDBState( SfxItemSet& rSet )
             case SID_FILTER:
             case SID_SPECIAL_FILTER:
                 {
-                    ScRange aDummy;
-                    ScMarkType eMarkType = GetViewData().GetSimpleArea( 
aDummy);
-                    if (eMarkType != SC_MARK_SIMPLE && eMarkType != 
SC_MARK_SIMPLE_FILTERED)
+                    const ScTableProtection* pTabProt = 
rDoc.GetTabProtection(nTab);
+                    if (pTabProt && pTabProt->isProtected() && 
!pTabProt->isOptionEnabled(ScTableProtection::AUTOFILTER))
                     {
-                        rSet.DisableItem( nWhich );
+                        rSet.DisableItem(nWhich);
+                    }
+                    else
+                    {
+                        ScRange aDummy;
+                        ScMarkType eMarkType = 
GetViewData().GetSimpleArea(aDummy);
+                        if (eMarkType != SC_MARK_SIMPLE && eMarkType != 
SC_MARK_SIMPLE_FILTERED)
+                        {
+                            rSet.DisableItem(nWhich);
+                        }
                     }
                 }
                 break;
@@ -1139,6 +1147,17 @@ void ScCellShell::GetDBState( SfxItemSet& rSet )
                     {
                         rSet.DisableItem( nWhich );
                     }
+                    else
+                    {
+                        if (nWhich == SID_OPENDLG_PIVOTTABLE)
+                        {
+                            const ScTableProtection* pTabProt = 
rDoc.GetTabProtection(nTab);
+                            if (pTabProt && pTabProt->isProtected() && 
!pTabProt->isOptionEnabled(ScTableProtection::PIVOT_TABLES))
+                            {
+                                rSet.DisableItem(nWhich);
+                            }
+                        }
+                    }
                 }
                 break;
 
@@ -1174,29 +1193,37 @@ void ScCellShell::GetDBState( SfxItemSet& rSet )
             case SID_AUTO_FILTER:
             case SID_AUTOFILTER_HIDE:
                 {
-                    if (!bAutoFilterTested)
+                    const ScTableProtection* pTabProt = 
rDoc.GetTabProtection(nTab);
+                    if (pTabProt && pTabProt->isProtected() && 
!pTabProt->isOptionEnabled(ScTableProtection::AUTOFILTER))
                     {
-                        bAutoFilter = rDoc.HasAutoFilter( nPosX, nPosY, nTab );
-                        bAutoFilterTested = true;
+                        rSet.DisableItem(nWhich);
                     }
-                    if ( nWhich == SID_AUTO_FILTER )
+                    else
                     {
-                        ScRange aDummy;
-                        ScMarkType eMarkType = GetViewData().GetSimpleArea( 
aDummy);
-                        if (eMarkType != SC_MARK_SIMPLE && eMarkType != 
SC_MARK_SIMPLE_FILTERED)
+                        if (!bAutoFilterTested)
                         {
-                            rSet.DisableItem( nWhich );
+                            bAutoFilter = rDoc.HasAutoFilter(nPosX, nPosY, 
nTab);
+                            bAutoFilterTested = true;
                         }
-                        else if (rDoc.GetDPAtBlock(aDummy))
+                        if (nWhich == SID_AUTO_FILTER)
                         {
-                            rSet.DisableItem( nWhich );
+                            ScRange aDummy;
+                            ScMarkType eMarkType = 
GetViewData().GetSimpleArea(aDummy);
+                            if (eMarkType != SC_MARK_SIMPLE && eMarkType != 
SC_MARK_SIMPLE_FILTERED)
+                            {
+                                rSet.DisableItem(nWhich);
+                            }
+                            else if (rDoc.GetDPAtBlock(aDummy))
+                            {
+                                rSet.DisableItem(nWhich);
+                            }
+                            else
+                                rSet.Put(SfxBoolItem(nWhich, bAutoFilter));
                         }
                         else
-                            rSet.Put( SfxBoolItem( nWhich, bAutoFilter ) );
+                            if (!bAutoFilter)
+                                rSet.DisableItem(nWhich);
                     }
-                    else
-                        if (!bAutoFilter)
-                            rSet.DisableItem( nWhich );
                 }
                 break;
 
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index fa75d629a871..81c8a67e0ad6 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -2070,9 +2070,20 @@ void ScGridWindow::HandleMouseButtonDown( const 
MouseEvent& rMEvt, MouseEventSta
         SCROW nRealPosY;
         mrViewData.GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nRealPosX, 
nRealPosY, false );//the real row/col
 
+        bool bAutoFilterDisable = false;
+        bool bPivotDisable = false;
+
+        if (rDoc.IsTabProtected(nTab))
+        {
+            const ScTableProtection* pTabProtection = 
rDoc.GetTabProtection(nTab);
+            bAutoFilterDisable = pTabProtection && 
!pTabProtection->isOptionEnabled(ScTableProtection::AUTOFILTER);//autofilter
+            bPivotDisable = pTabProtection && 
!pTabProtection->isOptionEnabled(ScTableProtection::PIVOT_TABLES);//pivot
+        }
+
         // show in the merged cells the filter of the first cell (nPosX 
instead of nRealPosX)
         const ScMergeFlagAttr* pRealPosAttr = rDoc.GetAttr(nPosX, nRealPosY, 
nTab, ATTR_MERGE_FLAG);
-        if( pRealPosAttr->HasAutoFilter() )
+
+        if (!bAutoFilterDisable && pRealPosAttr->HasAutoFilter())
         {
             SC_MOD()->InputEnterHandler();
             if (DoAutoFilterButton(nPosX, nRealPosY, rMEvt))
@@ -2080,7 +2091,7 @@ void ScGridWindow::HandleMouseButtonDown( const 
MouseEvent& rMEvt, MouseEventSta
         }
 
         const ScMergeFlagAttr* pAttr = rDoc.GetAttr(nPosX, nPosY, nTab, 
ATTR_MERGE_FLAG);
-        if (pAttr->HasAutoFilter())
+        if (!bAutoFilterDisable && pAttr->HasAutoFilter())
         {
             if (DoAutoFilterButton(nPosX, nPosY, rMEvt))
             {
@@ -2089,7 +2100,8 @@ void ScGridWindow::HandleMouseButtonDown( const 
MouseEvent& rMEvt, MouseEventSta
             }
         }
 
-        if (pAttr->HasPivotButton() || pAttr->HasPivotPopupButton() || 
pAttr->HasPivotMultiFieldPopupButton())
+        if (!bPivotDisable && (pAttr->HasPivotButton() || 
pAttr->HasPivotPopupButton() ||
+            pAttr->HasPivotMultiFieldPopupButton()))
         {
             DoPushPivotButton(nPosX, nPosY, rMEvt, pAttr->HasPivotButton(),
                 pAttr->HasPivotPopupButton(), 
pAttr->HasPivotMultiFieldPopupButton());
@@ -2097,7 +2109,7 @@ void ScGridWindow::HandleMouseButtonDown( const 
MouseEvent& rMEvt, MouseEventSta
             return;
         }
 
-        if (pAttr->HasPivotToggle())
+        if (!bPivotDisable && pAttr->HasPivotToggle())
         {
             DoPushPivotToggle(nPosX, nPosY, rMEvt);
             rState.mbActivatePart = false;
diff --git a/sc/source/ui/view/pivotsh.cxx b/sc/source/ui/view/pivotsh.cxx
index 019e4da8f34e..40c6425a4025 100644
--- a/sc/source/ui/view/pivotsh.cxx
+++ b/sc/source/ui/view/pivotsh.cxx
@@ -128,6 +128,18 @@ void ScPivotShell::GetState( SfxItemSet& rSet )
     ScDocShell* pDocSh = pViewShell->GetViewData().GetDocShell();
     ScDocument& rDoc = pDocSh->GetDocument();
     bool bDisable = pDocSh->IsReadOnly() || rDoc.GetChangeTrack();
+    bool bFilterDisable = bDisable;
+    if (!bDisable)
+    {
+        SCCOL nTab = pViewShell->GetViewData().GetTabNo();
+        const ScTableProtection* pTabProt = rDoc.GetTabProtection(nTab);
+        if (pTabProt && pTabProt->isProtected())
+        {
+            bDisable = true;
+            if (!pTabProt->isOptionEnabled(ScTableProtection::PIVOT_TABLES))
+                bFilterDisable = true;
+        }
+    }
 
     SfxWhichIter aIter(rSet);
     sal_uInt16 nWhich = aIter.FirstWhich();
@@ -148,7 +160,7 @@ void ScPivotShell::GetState( SfxItemSet& rSet )
             case SID_DP_FILTER:
             {
                 ScDPObject* pDPObj = GetCurrDPObject();
-                if( bDisable || !pDPObj || !pDPObj->IsSheetData() )
+                if( bFilterDisable || !pDPObj || !pDPObj->IsSheetData() )
                     rSet.DisableItem( nWhich );
             }
             break;
diff --git a/sc/uiconfig/scalc/ui/protectsheetdlg.ui 
b/sc/uiconfig/scalc/ui/protectsheetdlg.ui
index 83f1a1af012a..20835b596783 100644
--- a/sc/uiconfig/scalc/ui/protectsheetdlg.ui
+++ b/sc/uiconfig/scalc/ui/protectsheetdlg.ui
@@ -17,30 +17,30 @@
     </columns>
   </object>
   <object class="GtkDialog" id="ProtectSheetDialog">
-    <property name="can_focus">False</property>
-    <property name="border_width">6</property>
+    <property name="can-focus">False</property>
+    <property name="border-width">6</property>
     <property name="title" translatable="yes" 
context="protectsheetdlg|ProtectSheetDialog">Protect Sheet</property>
     <property name="modal">True</property>
-    <property name="default_width">0</property>
-    <property name="default_height">0</property>
-    <property name="type_hint">dialog</property>
+    <property name="default-width">0</property>
+    <property name="default-height">0</property>
+    <property name="type-hint">dialog</property>
     <child internal-child="vbox">
       <object class="GtkBox" id="dialog-vbox1">
-        <property name="can_focus">False</property>
+        <property name="can-focus">False</property>
         <property name="orientation">vertical</property>
         <property name="spacing">12</property>
         <child internal-child="action_area">
           <object class="GtkButtonBox" id="dialog-action_area1">
-            <property name="can_focus">False</property>
-            <property name="layout_style">end</property>
+            <property name="can-focus">False</property>
+            <property name="layout-style">end</property>
             <child>
               <object class="GtkButton" id="ok">
                 <property name="label" translatable="yes" 
context="stock">_OK</property>
                 <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="can_default">True</property>
-                <property name="has_default">True</property>
-                <property name="receives_default">True</property>
+                <property name="can-focus">True</property>
+                <property name="can-default">True</property>
+                <property name="has-default">True</property>
+                <property name="receives-default">True</property>
                 <property name="use-underline">True</property>
               </object>
               <packing>
@@ -53,8 +53,8 @@
               <object class="GtkButton" id="cancel">
                 <property name="label" translatable="yes" 
context="stock">_Cancel</property>
                 <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
+                <property name="can-focus">True</property>
+                <property name="receives-default">True</property>
                 <property name="use-underline">True</property>
               </object>
               <packing>
@@ -67,8 +67,8 @@
               <object class="GtkButton" id="help">
                 <property name="label" translatable="yes" 
context="stock">_Help</property>
                 <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
+                <property name="can-focus">True</property>
+                <property name="receives-default">True</property>
                 <property name="use-underline">True</property>
               </object>
               <packing>
@@ -82,14 +82,14 @@
           <packing>
             <property name="expand">False</property>
             <property name="fill">True</property>
-            <property name="pack_type">end</property>
+            <property name="pack-type">end</property>
             <property name="position">0</property>
           </packing>
         </child>
         <child>
           <object class="GtkBox" id="box1">
             <property name="visible">True</property>
-            <property name="can_focus">False</property>
+            <property name="can-focus">False</property>
             <property name="hexpand">True</property>
             <property name="vexpand">True</property>
             <property name="orientation">vertical</property>
@@ -97,7 +97,7 @@
             <child>
               <object class="GtkBox" id="box2">
                 <property name="visible">True</property>
-                <property name="can_focus">False</property>
+                <property name="can-focus">False</property>
                 <property name="hexpand">True</property>
                 <property name="orientation">vertical</property>
                 <property name="spacing">6</property>
@@ -105,10 +105,10 @@
                   <object class="GtkCheckButton" id="protect">
                     <property name="label" translatable="yes" 
context="protectsheetdlg|protect">P_rotect this sheet and the contents of 
protected cells</property>
                     <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="use_underline">True</property>
-                    <property name="draw_indicator">True</property>
+                    <property name="can-focus">True</property>
+                    <property name="receives-default">False</property>
+                    <property name="use-underline">True</property>
+                    <property name="draw-indicator">True</property>
                   </object>
                   <packing>
                     <property name="expand">False</property>
@@ -120,33 +120,33 @@
                   <!-- n-columns=2 n-rows=3 -->
                   <object class="GtkGrid" id="passwords">
                     <property name="visible">True</property>
-                    <property name="can_focus">False</property>
+                    <property name="can-focus">False</property>
                     <property name="hexpand">True</property>
-                    <property name="row_spacing">6</property>
-                    <property name="column_spacing">6</property>
+                    <property name="row-spacing">6</property>
+                    <property name="column-spacing">6</property>
                     <child>
                       <object class="GtkLabel" id="label1">
                         <property name="visible">True</property>
-                        <property name="can_focus">False</property>
+                        <property name="can-focus">False</property>
                         <property name="halign">end</property>
                         <property name="label" translatable="yes" 
context="protectsheetdlg|label1">_Password:</property>
-                        <property name="use_underline">True</property>
-                        <property name="mnemonic_widget">password1</property>
+                        <property name="use-underline">True</property>
+                        <property name="mnemonic-widget">password1</property>
                         <property name="xalign">1</property>
                       </object>
                       <packing>
-                        <property name="left_attach">0</property>
-                        <property name="top_attach">0</property>
+                        <property name="left-attach">0</property>
+                        <property name="top-attach">0</property>
                       </packing>
                     </child>
                     <child>
                       <object class="GtkLabel" id="label2">
                         <property name="visible">True</property>
-                        <property name="can_focus">False</property>
+                        <property name="can-focus">False</property>
                         <property name="halign">end</property>
                         <property name="label" translatable="yes" 
context="protectsheetdlg|label2">_Confirm:</property>
-                        <property name="use_underline">True</property>
-                        <property name="mnemonic_widget">password2</property>
+                        <property name="use-underline">True</property>
+                        <property name="mnemonic-widget">password2</property>
                         <property name="xalign">1</property>
                       </object>
                       <packing>
@@ -157,29 +157,29 @@
                     <child>
                       <object class="GtkEntry" id="password1">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
+                        <property name="can-focus">True</property>
                         <property name="hexpand">True</property>
                         <property name="visibility">False</property>
-                        <property name="activates_default">True</property>
-                        <property name="width_chars">24</property>
+                        <property name="activates-default">True</property>
+                        <property name="width-chars">24</property>
                         <property name="truncate-multiline">True</property>
-                        <property name="input_purpose">password</property>
+                        <property name="input-purpose">password</property>
                       </object>
                       <packing>
-                        <property name="left_attach">1</property>
-                        <property name="top_attach">0</property>
+                        <property name="left-attach">1</property>
+                        <property name="top-attach">0</property>
                       </packing>
                     </child>
                     <child>
                       <object class="GtkEntry" id="password2">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
+                        <property name="can-focus">True</property>
                         <property name="hexpand">True</property>
                         <property name="visibility">False</property>
-                        <property name="activates_default">True</property>
-                        <property name="width_chars">24</property>
+                        <property name="activates-default">True</property>
+                        <property name="width-chars">24</property>
                         <property name="truncate-multiline">True</property>
-                        <property name="input_purpose">password</property>
+                        <property name="input-purpose">password</property>
                       </object>
                       <packing>
                         <property name="left-attach">1</property>
@@ -190,6 +190,11 @@
                       <object class="GtkLevelBar" id="passwordbar">
                         <property name="visible">True</property>
                         <property name="can-focus">False</property>
+                        <child internal-child="accessible">
+                          <object class="AtkObject" id="passwordbar-atkobject">
+                            <property name="AtkObject::accessible-description" 
translatable="yes" context="protectsheetdlg|extended_tip|passwordbar">Measure 
of password strength</property>
+                          </object>
+                        </child>
                       </object>
                       <packing>
                         <property name="left-attach">1</property>
@@ -216,7 +221,7 @@
             <child>
               <object class="GtkBox" id="options">
                 <property name="visible">True</property>
-                <property name="can_focus">False</property>
+                <property name="can-focus">False</property>
                 <property name="hexpand">True</property>
                 <property name="vexpand">True</property>
                 <property name="orientation">vertical</property>
@@ -224,10 +229,10 @@
                 <child>
                   <object class="GtkLabel" id="label4">
                     <property name="visible">True</property>
-                    <property name="can_focus">False</property>
+                    <property name="can-focus">False</property>
                     <property name="label" translatable="yes" 
context="protectsheetdlg|label4">Allow all users of this sheet to:</property>
-                    <property name="use_underline">True</property>
-                    <property name="mnemonic_widget">checklist</property>
+                    <property name="use-underline">True</property>
+                    <property name="mnemonic-widget">checklist</property>
                     <property name="xalign">0</property>
                   </object>
                   <packing>
@@ -239,23 +244,23 @@
                 <child>
                   <object class="GtkScrolledWindow">
                     <property name="visible">True</property>
-                    <property name="can_focus">True</property>
+                    <property name="can-focus">True</property>
                     <property name="hexpand">True</property>
                     <property name="vexpand">True</property>
-                    <property name="hscrollbar_policy">never</property>
-                    <property name="vscrollbar_policy">never</property>
-                    <property name="shadow_type">in</property>
+                    <property name="hscrollbar-policy">never</property>
+                    <property name="vscrollbar-policy">never</property>
+                    <property name="shadow-type">in</property>
                     <child>
                       <object class="GtkTreeView" id="checklist">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">True</property>
+                        <property name="can-focus">True</property>
+                        <property name="receives-default">True</property>
                         <property name="hexpand">True</property>
                         <property name="vexpand">True</property>
                         <property name="model">liststore1</property>
-                        <property name="headers_visible">False</property>
-                        <property name="search_column">0</property>
-                        <property name="show_expanders">False</property>
+                        <property name="headers-visible">False</property>
+                        <property name="search-column">0</property>
+                        <property name="show-expanders">False</property>
                         <child internal-child="selection">
                           <object class="GtkTreeSelection" id="Macro Library 
List-selection2"/>
                         </child>
@@ -297,12 +302,12 @@
                 </child>
                 <child>
                   <object class="GtkBox" id="box4">
-                    <property name="can_focus">False</property>
+                    <property name="can-focus">False</property>
                     <property name="homogeneous">True</property>
                     <child>
                       <object class="GtkLabel" id="protected">
                         <property name="visible">True</property>
-                        <property name="can_focus">False</property>
+                        <property name="can-focus">False</property>
                         <property name="label" translatable="yes" 
context="protectsheetdlg|protected">Select protected cells</property>
                       </object>
                       <packing>
@@ -314,7 +319,7 @@
                     <child>
                       <object class="GtkLabel" id="delete-columns">
                         <property name="visible">True</property>
-                        <property name="can_focus">False</property>
+                        <property name="can-focus">False</property>
                         <property name="label" translatable="yes" 
context="protectsheetdlg|delete-columns">Delete columns</property>
                       </object>
                       <packing>
@@ -326,7 +331,7 @@
                     <child>
                       <object class="GtkLabel" id="delete-rows">
                         <property name="visible">True</property>
-                        <property name="can_focus">False</property>
+                        <property name="can-focus">False</property>
                         <property name="label" translatable="yes" 
context="protectsheetdlg|delete-rows">Delete rows</property>
                       </object>
                       <packing>
@@ -338,7 +343,7 @@
                     <child>
                       <object class="GtkLabel" id="insert-columns">
                         <property name="visible">True</property>
-                        <property name="can_focus">False</property>
+                        <property name="can-focus">False</property>
                         <property name="label" translatable="yes" 
context="protectsheetdlg|insert-columns">Insert columns</property>
                       </object>
                       <packing>
@@ -350,7 +355,7 @@
                     <child>
                       <object class="GtkLabel" id="insert-rows">
                         <property name="visible">True</property>
-                        <property name="can_focus">False</property>
+                        <property name="can-focus">False</property>
                         <property name="label" translatable="yes" 
context="protectsheetdlg|insert-rows">Insert rows</property>
                       </object>
                       <packing>
@@ -362,7 +367,7 @@
                     <child>
                       <object class="GtkLabel" id="unprotected">
                         <property name="visible">True</property>
-                        <property name="can_focus">False</property>
+                        <property name="can-focus">False</property>
                         <property name="label" translatable="yes" 
context="protectsheetdlg|unprotected">Select unprotected cells</property>
                       </object>
                       <packing>
@@ -371,6 +376,30 @@
                         <property name="position">1</property>
                       </packing>
                     </child>
+                    <child>
+                      <object class="GtkLabel" id="useautofilter">
+                        <property name="visible">True</property>
+                        <property name="can-focus">False</property>
+                        <property name="label" translatable="yes" 
context="protectsheetdlg|delete-columns">Use AutoFilter</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">6</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="usepivot">
+                        <property name="visible">True</property>
+                        <property name="can-focus">False</property>
+                        <property name="label" translatable="yes" 
context="protectsheetdlg|delete-columns">Use Pivot Table and Pivot 
Chart</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">7</property>
+                      </packing>
+                    </child>
                   </object>
                   <packing>
                     <property name="expand">False</property>
@@ -399,9 +428,6 @@
       <action-widget response="-6">cancel</action-widget>
       <action-widget response="-11">help</action-widget>
     </action-widgets>
-    <child type="titlebar">
-      <placeholder/>
-    </child>
     <child internal-child="accessible">
       <object class="AtkObject" id="ProtectSheetDialog-atkobject">
         <property name="AtkObject::accessible-description" translatable="yes" 
context="protectsheetdlg|extended_tip|ProtectSheetDialog">Protects the cells in 
the current sheet from being modified.</property>
diff --git a/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng 
b/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng
index 749c6daa3bfc..7ae65dc531ee 100644
--- a/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng
+++ b/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng
@@ -2809,6 +2809,16 @@ 
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.
           <rng:ref name="boolean"/>
         </rng:attribute>
       </rng:optional>
+      <rng:optional>
+        <rng:attribute name="loext:use-autofilter">
+          <rng:ref name="boolean"/>
+        </rng:attribute>
+      </rng:optional>
+      <rng:optional>
+        <rng:attribute name="loext:use-pivot">
+          <rng:ref name="boolean"/>
+        </rng:attribute>
+      </rng:optional>
     </rng:element>
   </rng:define>
   <rng:define name="office-spreadsheet-attlist" combine="interleave">
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index 7b6e4a269602..9c6ba7833a75 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -2108,6 +2108,7 @@ namespace xmloff::token {
         TOKEN( "upright",                         XML_UPRIGHT ),
         TOKEN( "url",                             XML_URL ),
         TOKEN( "use",                             XML_USE ),
+        TOKEN( "use-autofilter",                  XML_USE_AUTOFILTER),
         TOKEN( "use-caption",                     XML_USE_CAPTION ),
         TOKEN( "use-cell-protection",             XML_USE_CELL_PROTECTION ),
         TOKEN( "use-chart-objects",               XML_USE_CHART_OBJECTS ),
@@ -2125,6 +2126,7 @@ namespace xmloff::token {
         TOKEN( "use-optimal-column-width",        XML_USE_OPTIMAL_COLUMN_WIDTH 
),
         TOKEN( "use-optimal-row-height",          XML_USE_OPTIMAL_ROW_HEIGHT ),
         TOKEN( "use-other-objects",               XML_USE_OTHER_OBJECTS ),
+        TOKEN( "use-pivot",                       XML_USE_PIVOT),
         TOKEN( "use-spreadsheet-objects",         XML_USE_SPREADSHEET_OBJECTS 
),
         TOKEN( "use-styles",                      XML_USE_STYLES ),
         TOKEN( "use-tables",                      XML_USE_TABLES ),
diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt
index 05a6dd1be01d..8752dd63723d 100644
--- a/xmloff/source/token/tokens.txt
+++ b/xmloff/source/token/tokens.txt
@@ -2008,6 +2008,7 @@ uplimit
 upright
 url
 use
+use-autofilter
 use-caption
 use-cell-protection
 use-chart-objects
@@ -2025,6 +2026,7 @@ use-objects
 use-optimal-column-width
 use-optimal-row-height
 use-other-objects
+use-pivot
 use-spreadsheet-objects
 use-styles
 use-tables

Reply via email to