tdf#43535: support additional sheet protection options.
New options are:
* insert columns.
* insert rows.
* delete columns.
* delete rows.
Change-Id: I076b0d01bee0fff0623e2f1137c09938a6110939
Reviewed-on: https://gerrit.libreoffice.org/37695
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Kohei Yoshida <libreoffice@kohei.us>
diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index 9ab65ab..d746ae7 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -605,6 +605,8 @@ namespace xmloff { namespace token {
XML_DEFAULT_STYLE_NAME,
XML_DEGREE,
XML_DELAY,
XML_DELETE_COLUMNS,
XML_DELETE_ROWS,
XML_DELETION,
XML_DELETIONS,
XML_DENOMALIGN,
@@ -1037,6 +1039,8 @@ namespace xmloff { namespace token {
XML_INFORMATION,
XML_INITIAL_CREATOR,
XML_INPROCEEDINGS,
XML_INSERT_COLUMNS,
XML_INSERT_ROWS,
XML_INSERTION,
XML_INSERTION_CUT_OFF,
XML_INSERTION_POSITION,
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 2c0f131..87c8995 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -791,6 +791,9 @@ 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;
SC_DLLPUBLIC bool GetMatrixFormulaRange( const ScAddress& rCellPos, ScRange& rMatrix );
bool IsEmbedded() const { return bIsEmbedded;}
diff --git a/sc/inc/global.hxx b/sc/inc/global.hxx
index 1c67775..7219b9b 100644
--- a/sc/inc/global.hxx
+++ b/sc/inc/global.hxx
@@ -428,6 +428,21 @@ enum ScDBObject
ScDbQuery
};
namespace sc {
enum class ColRowEditAction
{
Unknown,
InsertColumnsBefore,
InsertColumnsAfter,
InsertRowsBefore,
InsertRowsAfter,
DeleteColumns,
DeleteRows
};
}
struct ScImportParam
{
SCCOL nCol1;
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 87ba9c6..c5941b0 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -350,6 +350,8 @@ public:
void SetProtection(const ScTableProtection* pProtect);
ScTableProtection* GetProtection();
bool IsEditActionAllowed( sc::ColRowEditAction eAction, SCCOLROW nStart, SCCOLROW nEnd ) const;
Size GetPageSize() const;
void SetPageSize( const Size& rSize );
void SetRepeatArea( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCROW nEndRow );
diff --git a/sc/source/core/data/document10.cxx b/sc/source/core/data/document10.cxx
index 1617290..1273a17 100644
--- a/sc/source/core/data/document10.cxx
+++ b/sc/source/core/data/document10.cxx
@@ -881,4 +881,27 @@ bool ScDocument::CopyAdjustRangeName( SCTAB& rSheet, sal_uInt16& rIndex, ScRange
return true;
}
bool ScDocument::IsEditActionAllowed(
sc::ColRowEditAction eAction, SCTAB nTab, SCCOLROW nStart, SCCOLROW nEnd ) const
{
const ScTable* pTab = FetchTable(nTab);
if (!pTab)
return false;
return pTab->IsEditActionAllowed(eAction, nStart, nEnd);
}
bool ScDocument::IsEditActionAllowed(
sc::ColRowEditAction eAction, const ScMarkData& rMark, SCCOLROW nStart, SCCOLROW nEnd ) const
{
ScMarkData::const_iterator it = rMark.begin(), itEnd = rMark.end();
for (; it != itEnd; ++it)
{
if (!IsEditActionAllowed(eAction, *it, nStart, nEnd))
return false;
}
return true;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/table7.cxx b/sc/source/core/data/table7.cxx
index 051e57b..723a3d6 100644
--- a/sc/source/core/data/table7.cxx
+++ b/sc/source/core/data/table7.cxx
@@ -16,6 +16,7 @@
#include <sharedformula.hxx>
#include <cellvalues.hxx>
#include "olinetab.hxx"
#include <tabprotection.hxx>
bool ScTable::IsMerged( SCCOL nCol, SCROW nRow ) const
{
@@ -310,6 +311,87 @@ void ScTable::SetNeedsListeningGroup( SCCOL nCol, SCROW nRow )
aCol[nCol].SetNeedsListeningGroup(nRow);
}
bool ScTable::IsEditActionAllowed(
sc::ColRowEditAction eAction, SCCOLROW nStart, SCCOLROW nEnd ) const
{
if (!IsProtected())
{
SCCOL nCol1 = 0, nCol2 = MAXCOL;
SCROW nRow1 = 0, nRow2 = MAXROW;
switch (eAction)
{
case sc::ColRowEditAction::InsertColumnsBefore:
case sc::ColRowEditAction::InsertColumnsAfter:
case sc::ColRowEditAction::DeleteColumns:
{
nCol1 = nStart;
nCol2 = nEnd;
break;
}
case sc::ColRowEditAction::InsertRowsBefore:
case sc::ColRowEditAction::InsertRowsAfter:
case sc::ColRowEditAction::DeleteRows:
{
nRow1 = nStart;
nRow2 = nEnd;
break;
}
default:
;
}
return IsBlockEditable(nCol1, nRow1, nCol2, nRow2, nullptr);
}
if (IsScenario())
// TODO: I don't even know what this scenario thingie is. Perhaps we
// should check it against the scenario ranges?
return false;
assert(pTabProtection);
switch (eAction)
{
case sc::ColRowEditAction::InsertColumnsBefore:
case sc::ColRowEditAction::InsertColumnsAfter:
{
// TODO: improve the matrix range handling for the insert-before action.
if (HasBlockMatrixFragment(nStart, 0, nEnd, MAXROW))
return false;
return pTabProtection->isOptionEnabled(ScTableProtection::INSERT_COLUMNS);
}
case sc::ColRowEditAction::InsertRowsBefore:
case sc::ColRowEditAction::InsertRowsAfter:
{
// TODO: improve the matrix range handling for the insert-before action.
if (HasBlockMatrixFragment(0, nStart, MAXCOL, nEnd))
return false;
return pTabProtection->isOptionEnabled(ScTableProtection::INSERT_ROWS);
}
case sc::ColRowEditAction::DeleteColumns:
{
if (!pTabProtection->isOptionEnabled(ScTableProtection::DELETE_COLUMNS))
return false;
return !HasAttrib(nStart, 0, nEnd, MAXROW, HasAttrFlags::Protected);
}
case sc::ColRowEditAction::DeleteRows:
{
if (!pTabProtection->isOptionEnabled(ScTableProtection::DELETE_ROWS))
return false;
return !HasAttrib(0, nStart, MAXCOL, nEnd, HasAttrFlags::Protected);
}
default:
;
}
return false;
}
void ScTable::finalizeOutlineImport()
{
if (pOutlineTable && pRowFlags)
diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx
index f84eaea..d7e4ef5 100644
--- a/sc/source/filter/xml/xmlexprt.cxx
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -2894,6 +2894,16 @@ void ScXMLExport::WriteTable(sal_Int32 nTable, const uno::Reference<sheet::XSpre
if (pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS))
AddAttribute(XML_NAMESPACE_LO_EXT, XML_SELECT_UNPROTECTED_CELLS, XML_TRUE);
if (pProtect->isOptionEnabled(ScTableProtection::INSERT_COLUMNS))
AddAttribute(XML_NAMESPACE_LO_EXT, XML_INSERT_COLUMNS, XML_TRUE);
if (pProtect->isOptionEnabled(ScTableProtection::INSERT_ROWS))
AddAttribute(XML_NAMESPACE_LO_EXT, XML_INSERT_ROWS, XML_TRUE);
if (pProtect->isOptionEnabled(ScTableProtection::DELETE_COLUMNS))
AddAttribute(XML_NAMESPACE_LO_EXT, XML_DELETE_COLUMNS, XML_TRUE);
if (pProtect->isOptionEnabled(ScTableProtection::DELETE_ROWS))
AddAttribute(XML_NAMESPACE_LO_EXT, XML_DELETE_ROWS, XML_TRUE);
OUString aElemName = GetNamespaceMap().GetQNameByKey(
XML_NAMESPACE_LO_EXT, GetXMLToken(XML_TABLE_PROTECTION));
diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx
index c8f94d7..d035e9e 100644
--- a/sc/source/filter/xml/xmlimprt.cxx
+++ b/sc/source/filter/xml/xmlimprt.cxx
@@ -903,6 +903,10 @@ const SvXMLTokenMap& ScXMLImport::GetTableProtectionAttrTokenMap()
{ XML_NAMESPACE_LO_EXT, XML_SELECT_PROTECTED_CELLS, XML_TOK_TABLE_SELECT_PROTECTED_CELLS_EXT },
{ XML_NAMESPACE_OFFICE_EXT, XML_SELECT_UNPROTECTED_CELLS, XML_TOK_TABLE_SELECT_UNPROTECTED_CELLS_EXT },
{ XML_NAMESPACE_LO_EXT, XML_SELECT_UNPROTECTED_CELLS, XML_TOK_TABLE_SELECT_UNPROTECTED_CELLS_EXT },
{ XML_NAMESPACE_LO_EXT, XML_INSERT_COLUMNS, XML_TOK_TABLE_INSERT_COLUMNS_EXT, },
{ XML_NAMESPACE_LO_EXT, XML_INSERT_ROWS, XML_TOK_TABLE_INSERT_ROWS_EXT, },
{ XML_NAMESPACE_LO_EXT, XML_DELETE_COLUMNS, XML_TOK_TABLE_DELETE_COLUMNS_EXT, },
{ XML_NAMESPACE_LO_EXT, XML_DELETE_ROWS, XML_TOK_TABLE_DELETE_ROWS_EXT, },
XML_TOKEN_MAP_END
};
pTableProtectionElemTokenMap = new SvXMLTokenMap(aTableProtectionTokenMap);
diff --git a/sc/source/filter/xml/xmlimprt.hxx b/sc/source/filter/xml/xmlimprt.hxx
index 02c2ccf..84dd944 100644
--- a/sc/source/filter/xml/xmlimprt.hxx
+++ b/sc/source/filter/xml/xmlimprt.hxx
@@ -247,7 +247,11 @@ enum ScXMLTokenProtectionTokens
XML_TOK_TABLE_SELECT_PROTECTED_CELLS,
XML_TOK_TABLE_SELECT_UNPROTECTED_CELLS,
XML_TOK_TABLE_SELECT_PROTECTED_CELLS_EXT,
XML_TOK_TABLE_SELECT_UNPROTECTED_CELLS_EXT
XML_TOK_TABLE_SELECT_UNPROTECTED_CELLS_EXT,
XML_TOK_TABLE_INSERT_COLUMNS_EXT,
XML_TOK_TABLE_INSERT_ROWS_EXT,
XML_TOK_TABLE_DELETE_COLUMNS_EXT,
XML_TOK_TABLE_DELETE_ROWS_EXT,
};
enum ScXMLTableRowsTokens
diff --git a/sc/source/filter/xml/xmlsubti.cxx b/sc/source/filter/xml/xmlsubti.cxx
index c44ac7e..5933724 100644
--- a/sc/source/filter/xml/xmlsubti.cxx
+++ b/sc/source/filter/xml/xmlsubti.cxx
@@ -51,7 +51,11 @@ ScXMLTabProtectionData::ScXMLTabProtectionData() :
meHash2(PASSHASH_UNSPECIFIED),
mbProtected(false),
mbSelectProtectedCells(true),
mbSelectUnprotectedCells(true)
mbSelectUnprotectedCells(true),
mbInsertColumns(false),
mbInsertRows(false),
mbDeleteColumns(false),
mbDeleteRows(false)
{
}
@@ -203,6 +207,10 @@ void ScMyTables::DeleteTable()
pProtect->setPasswordHash(aHash, maProtectionData.meHash1, maProtectionData.meHash2);
pProtect->setOption(ScTableProtection::SELECT_LOCKED_CELLS, maProtectionData.mbSelectProtectedCells);
pProtect->setOption(ScTableProtection::SELECT_UNLOCKED_CELLS, maProtectionData.mbSelectUnprotectedCells);
pProtect->setOption(ScTableProtection::INSERT_COLUMNS, maProtectionData.mbInsertColumns);
pProtect->setOption(ScTableProtection::INSERT_ROWS, maProtectionData.mbInsertRows);
pProtect->setOption(ScTableProtection::DELETE_COLUMNS, maProtectionData.mbDeleteColumns);
pProtect->setOption(ScTableProtection::DELETE_ROWS, maProtectionData.mbDeleteRows);
rImport.GetDocument()->SetTabProtection(maCurrentCellPos.Tab(), pProtect.get());
}
}
diff --git a/sc/source/filter/xml/xmlsubti.hxx b/sc/source/filter/xml/xmlsubti.hxx
index 48f7a92..fc1be16 100644
--- a/sc/source/filter/xml/xmlsubti.hxx
+++ b/sc/source/filter/xml/xmlsubti.hxx
@@ -40,6 +40,10 @@ struct ScXMLTabProtectionData
bool mbProtected;
bool mbSelectProtectedCells;
bool mbSelectUnprotectedCells;
bool mbInsertColumns;
bool mbInsertRows;
bool mbDeleteColumns;
bool mbDeleteRows;
ScXMLTabProtectionData();
};
diff --git a/sc/source/filter/xml/xmltabi.cxx b/sc/source/filter/xml/xmltabi.cxx
index 3c1a89c..793416b 100644
--- a/sc/source/filter/xml/xmltabi.cxx
+++ b/sc/source/filter/xml/xmltabi.cxx
@@ -442,6 +442,10 @@ ScXMLTableProtectionContext::ScXMLTableProtectionContext(
const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetTableProtectionAttrTokenMap();
bool bSelectProtectedCells = false;
bool bSelectUnprotectedCells = false;
bool bInsertColumns = false;
bool bInsertRows = false;
bool bDeleteColumns = false;
bool bDeleteRows = false;
sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
@@ -459,11 +463,23 @@ ScXMLTableProtectionContext::ScXMLTableProtectionContext(
case XML_TOK_TABLE_SELECT_PROTECTED_CELLS:
case XML_TOK_TABLE_SELECT_PROTECTED_CELLS_EXT:
bSelectProtectedCells = IsXMLToken(aValue, XML_TRUE);
break;
break;
case XML_TOK_TABLE_SELECT_UNPROTECTED_CELLS:
case XML_TOK_TABLE_SELECT_UNPROTECTED_CELLS_EXT:
bSelectUnprotectedCells = IsXMLToken(aValue, XML_TRUE);
break;
break;
case XML_TOK_TABLE_INSERT_COLUMNS_EXT:
bInsertColumns = IsXMLToken(aValue, XML_TRUE);
break;
case XML_TOK_TABLE_INSERT_ROWS_EXT:
bInsertRows = IsXMLToken(aValue, XML_TRUE);
break;
case XML_TOK_TABLE_DELETE_COLUMNS_EXT:
bDeleteColumns = IsXMLToken(aValue, XML_TRUE);
break;
case XML_TOK_TABLE_DELETE_ROWS_EXT:
bDeleteRows = IsXMLToken(aValue, XML_TRUE);
break;
default:
SAL_WARN("sc", "unknown attribute: " << aAttrName);
}
@@ -472,6 +488,10 @@ ScXMLTableProtectionContext::ScXMLTableProtectionContext(
ScXMLTabProtectionData& rProtectData = GetScImport().GetTables().GetCurrentProtectionData();
rProtectData.mbSelectProtectedCells = bSelectProtectedCells;
rProtectData.mbSelectUnprotectedCells = bSelectUnprotectedCells;
rProtectData.mbInsertColumns = bInsertColumns;
rProtectData.mbInsertRows = bInsertRows;
rProtectData.mbDeleteColumns = bDeleteColumns;
rProtectData.mbDeleteRows = bDeleteRows;
}
ScXMLTableProtectionContext::~ScXMLTableProtectionContext()
diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx
index 5e686ca..13d4baa 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -1761,7 +1761,32 @@ bool ScDocFunc::InsertCells( const ScRange& rRange, const ScMarkData* pTabMark,
SCCOL nEditTestEndCol = (eCmd==INS_INSCOLS_BEFORE || eCmd==INS_INSCOLS_AFTER) ? MAXCOL : nMergeTestEndCol;
SCROW nEditTestEndRow = (eCmd==INS_INSROWS_BEFORE || eCmd==INS_INSROWS_AFTER) ? MAXROW : nMergeTestEndRow;
ScEditableTester aTester( &rDoc, nMergeTestStartCol, nMergeTestStartRow, nEditTestEndCol, nEditTestEndRow, aMark );
ScEditableTester aTester;
switch (eCmd)
{
case INS_INSCOLS_BEFORE:
aTester = ScEditableTester(
rDoc, sc::ColRowEditAction::InsertColumnsBefore, nMergeTestStartCol, nMergeTestEndCol, aMark);
break;
case INS_INSCOLS_AFTER:
aTester = ScEditableTester(
rDoc, sc::ColRowEditAction::InsertColumnsAfter, nMergeTestStartCol, nMergeTestEndCol, aMark);
break;
case INS_INSROWS_BEFORE:
aTester = ScEditableTester(
rDoc, sc::ColRowEditAction::InsertRowsBefore, nMergeTestStartRow, nMergeTestEndRow, aMark);
break;
case INS_INSROWS_AFTER:
aTester = ScEditableTester(
rDoc, sc::ColRowEditAction::InsertRowsAfter, nMergeTestStartRow, nMergeTestEndRow, aMark);
break;
default:
aTester = ScEditableTester(
&rDoc, nMergeTestStartCol, nMergeTestStartRow, nEditTestEndCol, nEditTestEndRow, aMark);
}
if (!aTester.IsEditable())
{
if (!bApi)
@@ -2217,7 +2242,24 @@ bool ScDocFunc::DeleteCells( const ScRange& rRange, const ScMarkData* pTabMark,
SCROW nEditTestEndY = nUndoEndRow;
if ( eCmd==DEL_DELROWS || eCmd==DEL_CELLSUP )
nEditTestEndY = MAXROW;
ScEditableTester aTester( &rDoc, nUndoStartCol, nUndoStartRow, nEditTestEndX, nEditTestEndY, aMark );
ScEditableTester aTester;
switch (eCmd)
{
case DEL_DELCOLS:
aTester = ScEditableTester(
rDoc, sc::ColRowEditAction::DeleteColumns, nUndoStartCol, nUndoEndCol, aMark);
break;
case DEL_DELROWS:
aTester = ScEditableTester(
rDoc, sc::ColRowEditAction::DeleteRows, nUndoStartRow, nUndoEndRow, aMark);
break;
default:
aTester = ScEditableTester(
&rDoc, nUndoStartCol, nUndoStartRow, nEditTestEndX, nEditTestEndY, aMark);
}
if (!aTester.IsEditable())
{
if (!bApi)
diff --git a/sc/source/ui/docshell/editable.cxx b/sc/source/ui/docshell/editable.cxx
index 05d4f19..2a06c82 100644
--- a/sc/source/ui/docshell/editable.cxx
+++ b/sc/source/ui/docshell/editable.cxx
@@ -73,6 +73,13 @@ ScEditableTester::ScEditableTester( ScViewFunc* pView ) :
}
}
ScEditableTester::ScEditableTester(
const ScDocument& rDoc, sc::ColRowEditAction eAction, SCCOLROW nStart, SCCOLROW nEnd, const ScMarkData& rMark ) :
ScEditableTester()
{
TestBlockForAction(rDoc, eAction, nStart, nEnd, rMark);
}
void ScEditableTester::TestBlock( ScDocument* pDoc, SCTAB nTab,
SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
{
@@ -124,6 +131,21 @@ void ScEditableTester::TestSelection( ScDocument* pDoc, const ScMarkData& rMark
}
}
void ScEditableTester::TestBlockForAction(
const ScDocument& rDoc, sc::ColRowEditAction eAction, SCCOLROW nStart, SCCOLROW nEnd,
const ScMarkData& rMark )
{
mbOnlyMatrix = false;
for (ScMarkData::const_iterator it = rMark.begin(), itEnd = rMark.end(); it != itEnd; ++it)
{
if (!mbIsEditable)
return;
mbIsEditable = rDoc.IsEditActionAllowed(eAction, *it, nStart, nEnd);
}
}
sal_uInt16 ScEditableTester::GetMessageId() const
{
if (mbIsEditable)
diff --git a/sc/source/ui/inc/editable.hxx b/sc/source/ui/inc/editable.hxx
index 10a0303..e47e2d4 100644
--- a/sc/source/ui/inc/editable.hxx
+++ b/sc/source/ui/inc/editable.hxx
@@ -27,6 +27,12 @@ class ScViewFunc;
class ScMarkData;
class ScRange;
namespace sc {
enum class ColRowEditAction;
}
class ScEditableTester
{
bool mbIsEditable;
@@ -53,6 +59,10 @@ public:
// calls TestView
ScEditableTester( ScViewFunc* pView );
ScEditableTester(
const ScDocument& rDoc, sc::ColRowEditAction eAction, SCCOLROW nStart, SCCOLROW nEnd,
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( ScDocument* pDoc, SCTAB nTab,
@@ -63,6 +73,10 @@ public:
void TestRange( ScDocument* pDoc, const ScRange& rRange );
void TestSelection( ScDocument* pDoc, const ScMarkData& rMark );
void TestBlockForAction(
const ScDocument& rDoc, sc::ColRowEditAction eAction, SCCOLROW nStart, SCCOLROW nEnd,
const ScMarkData& rMark );
bool IsEditable() const { return mbIsEditable; }
bool IsFormatEditable() const { return mbIsEditable || mbOnlyMatrix; }
sal_uInt16 GetMessageId() const;
diff --git a/sc/source/ui/inc/protectiondlg.hxx b/sc/source/ui/inc/protectiondlg.hxx
index 752fee0..351a733 100644
--- a/sc/source/ui/inc/protectiondlg.hxx
+++ b/sc/source/ui/inc/protectiondlg.hxx
@@ -62,6 +62,10 @@ private:
OUString m_aSelectLockedCells;
OUString m_aSelectUnlockedCells;
OUString m_aInsertColumns;
OUString m_aInsertRows;
OUString m_aDeleteColumns;
OUString m_aDeleteRows;
DECL_LINK( OKHdl, Button*, void );
DECL_LINK( CheckBoxHdl, Button*, void );
diff --git a/sc/source/ui/miscdlgs/protectiondlg.cxx b/sc/source/ui/miscdlgs/protectiondlg.cxx
index ddfd337a..082aec5a 100644
--- a/sc/source/ui/miscdlgs/protectiondlg.cxx
+++ b/sc/source/ui/miscdlgs/protectiondlg.cxx
@@ -23,13 +23,21 @@
#include <sal/macros.h>
#include <vcl/msgbox.hxx>
#include <vector>
namespace {
// The order must match that of the list box.
static const ScTableProtection::Option aOptions[] = {
const std::vector<ScTableProtection::Option> aOptions = {
ScTableProtection::SELECT_LOCKED_CELLS,
ScTableProtection::SELECT_UNLOCKED_CELLS,
ScTableProtection::INSERT_COLUMNS,
ScTableProtection::INSERT_ROWS,
ScTableProtection::DELETE_COLUMNS,
ScTableProtection::DELETE_ROWS,
};
static const sal_uInt16 nOptionCount = SAL_N_ELEMENTS(aOptions);
}
ScTableProtectionDlg::ScTableProtectionDlg(vcl::Window* pParent)
: ModalDialog( pParent, "ProtectSheetDialog", "modules/scalc/ui/protectsheetdlg.ui" )
@@ -44,6 +52,10 @@ ScTableProtectionDlg::ScTableProtectionDlg(vcl::Window* pParent)
m_aSelectLockedCells = get<FixedText>("protected")->GetText();
m_aSelectUnlockedCells = get<FixedText>("unprotected")->GetText();
m_aInsertColumns = get<FixedText>("insert-columns")->GetText();
m_aInsertRows = get<FixedText>("insert-rows")->GetText();
m_aDeleteColumns = get<FixedText>("delete-columns")->GetText();
m_aDeleteRows = get<FixedText>("delete-rows")->GetText();
Init();
}
@@ -67,7 +79,7 @@ void ScTableProtectionDlg::dispose()
void ScTableProtectionDlg::SetDialogData(const ScTableProtection& rData)
{
for (sal_uInt16 i = 0; i < nOptionCount; ++i)
for (size_t i = 0; i < aOptions.size(); ++i)
m_pOptionsListBox->CheckEntryPos(i, rData.isOptionEnabled(aOptions[i]));
}
@@ -78,7 +90,7 @@ void ScTableProtectionDlg::WriteData(ScTableProtection& rData) const
// We assume that the two password texts match.
rData.setPassword(m_pPassword1Edit->GetText());
for (sal_uInt16 i = 0; i < nOptionCount; ++i)
for (size_t i = 0; i < aOptions.size(); ++i)
rData.setOption(aOptions[i], m_pOptionsListBox->IsChecked(i));
}
@@ -97,6 +109,10 @@ void ScTableProtectionDlg::Init()
m_pOptionsListBox->InsertEntry(m_aSelectLockedCells);
m_pOptionsListBox->InsertEntry(m_aSelectUnlockedCells);
m_pOptionsListBox->InsertEntry(m_aInsertColumns);
m_pOptionsListBox->InsertEntry(m_aInsertRows);
m_pOptionsListBox->InsertEntry(m_aDeleteColumns);
m_pOptionsListBox->InsertEntry(m_aDeleteRows);
m_pOptionsListBox->CheckEntryPos(0);
m_pOptionsListBox->CheckEntryPos(1);
diff --git a/sc/source/ui/view/cellsh.cxx b/sc/source/ui/view/cellsh.cxx
index 79d356e..52785f4 100644
--- a/sc/source/ui/view/cellsh.cxx
+++ b/sc/source/ui/view/cellsh.cxx
@@ -231,6 +231,19 @@ void ScCellShell::GetBlockState( SfxItemSet& rSet )
case FID_INS_ROW:
case FID_INS_ROWS_BEFORE: // insert rows
case FID_INS_ROWS_AFTER:
{
sc::ColRowEditAction eAction = sc::ColRowEditAction::InsertRowsBefore;
if (nWhich == FID_INS_ROWS_AFTER)
eAction = sc::ColRowEditAction::InsertRowsAfter;
bDisable = (!bSimpleArea) || GetViewData()->SimpleColMarked();
if (!bEditable && nCol1 == 0 && nCol2 == MAXCOL)
{
// See if row insertions are allowed.
bEditable = pDoc->IsEditActionAllowed(eAction, rMark, nRow1, nRow2);
}
break;
}
case FID_INS_CELLSDOWN:
case SID_ROW_OPERATIONS:
bDisable = (!bSimpleArea) || GetViewData()->SimpleColMarked();
@@ -239,6 +252,19 @@ void ScCellShell::GetBlockState( SfxItemSet& rSet )
case FID_INS_COLUMN:
case FID_INS_COLUMNS_BEFORE: // insert columns
case FID_INS_COLUMNS_AFTER:
{
sc::ColRowEditAction eAction = sc::ColRowEditAction::InsertColumnsBefore;
if (nWhich == FID_INS_COLUMNS_AFTER)
eAction = sc::ColRowEditAction::InsertColumnsAfter;
bDisable = (!bSimpleArea) || GetViewData()->SimpleRowMarked();
if (!bEditable && nRow1 == 0 && nRow2 == MAXROW)
{
// See if row insertions are allowed.
bEditable = pDoc->IsEditActionAllowed(eAction, rMark, nCol1, nCol2);
}
break;
}
case FID_INS_CELLSRIGHT:
case SID_COLUMN_OPERATIONS:
bDisable = (!bSimpleArea) || GetViewData()->SimpleRowMarked();
diff --git a/sc/uiconfig/scalc/ui/protectsheetdlg.ui b/sc/uiconfig/scalc/ui/protectsheetdlg.ui
index 63f35c1..0b520b9 100644
--- a/sc/uiconfig/scalc/ui/protectsheetdlg.ui
+++ b/sc/uiconfig/scalc/ui/protectsheetdlg.ui
@@ -248,6 +248,54 @@
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="insert-columns">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Insert columns</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="insert-rows">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Insert rows</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="delete-columns">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Delete columns</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="delete-rows">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Delete rows</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index c22e321..a7d242b 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -606,6 +606,8 @@ namespace xmloff { namespace token {
TOKEN( "default-style-name", XML_DEFAULT_STYLE_NAME ),
TOKEN( "degree", XML_DEGREE ),
TOKEN( "delay", XML_DELAY ),
TOKEN( "delete-columns", XML_DELETE_COLUMNS ),
TOKEN( "delete-rows", XML_DELETE_ROWS ),
TOKEN( "deletion", XML_DELETION ),
TOKEN( "deletions", XML_DELETIONS ),
TOKEN( "denomalign" , XML_DENOMALIGN ),
@@ -1039,6 +1041,8 @@ namespace xmloff { namespace token {
TOKEN( "information", XML_INFORMATION ),
TOKEN( "initial-creator", XML_INITIAL_CREATOR ),
TOKEN( "inproceedings", XML_INPROCEEDINGS ),
TOKEN( "insert-columns", XML_INSERT_COLUMNS ),
TOKEN( "insert-rows", XML_INSERT_ROWS ),
TOKEN( "insertion", XML_INSERTION ),
TOKEN( "insertion-cut-off", XML_INSERTION_CUT_OFF ),
TOKEN( "insertion-position", XML_INSERTION_POSITION ),
diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt
index 7038673..e874670 100644
--- a/xmloff/source/token/tokens.txt
+++ b/xmloff/source/token/tokens.txt
@@ -529,6 +529,8 @@ default-style
default-style-name
degree
delay
delete-columns
delete-rows
deletion
deletions
denomalign
@@ -957,6 +959,8 @@ index-title-template
information
initial-creator
inproceedings
insert-columns
insert-rows
insertion
insertion-cut-off
insertion-position