diff options
author | Kohei Yoshida <kohei.yoshida@collabora.com> | 2017-05-11 18:07:56 -0400 |
---|---|---|
committer | Kohei Yoshida <libreoffice@kohei.us> | 2017-05-17 05:16:44 +0200 |
commit | 034be10413ed4915090678ad4f1d48596cf5e206 (patch) | |
tree | 5227cc4aae303272338e8fc25225fc48914168d0 | |
parent | 296c2296f5565556eea9fab51563050f28bbcafc (diff) |
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>
-rw-r--r-- | include/xmloff/xmltoken.hxx | 4 | ||||
-rw-r--r-- | sc/inc/document.hxx | 3 | ||||
-rw-r--r-- | sc/inc/global.hxx | 15 | ||||
-rw-r--r-- | sc/inc/table.hxx | 2 | ||||
-rw-r--r-- | sc/source/core/data/document10.cxx | 23 | ||||
-rw-r--r-- | sc/source/core/data/table7.cxx | 82 | ||||
-rw-r--r-- | sc/source/filter/xml/xmlexprt.cxx | 10 | ||||
-rw-r--r-- | sc/source/filter/xml/xmlimprt.cxx | 4 | ||||
-rw-r--r-- | sc/source/filter/xml/xmlimprt.hxx | 6 | ||||
-rw-r--r-- | sc/source/filter/xml/xmlsubti.cxx | 10 | ||||
-rw-r--r-- | sc/source/filter/xml/xmlsubti.hxx | 4 | ||||
-rw-r--r-- | sc/source/filter/xml/xmltabi.cxx | 24 | ||||
-rw-r--r-- | sc/source/ui/docshell/docfunc.cxx | 46 | ||||
-rw-r--r-- | sc/source/ui/docshell/editable.cxx | 22 | ||||
-rw-r--r-- | sc/source/ui/inc/editable.hxx | 14 | ||||
-rw-r--r-- | sc/source/ui/inc/protectiondlg.hxx | 4 | ||||
-rw-r--r-- | sc/source/ui/miscdlgs/protectiondlg.cxx | 24 | ||||
-rw-r--r-- | sc/source/ui/view/cellsh.cxx | 26 | ||||
-rw-r--r-- | sc/uiconfig/scalc/ui/protectsheetdlg.ui | 48 | ||||
-rw-r--r-- | xmloff/source/core/xmltoken.cxx | 4 | ||||
-rw-r--r-- | xmloff/source/token/tokens.txt | 4 |
21 files changed, 369 insertions, 10 deletions
diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx index 9ab65abfd195..d746ae78c5d0 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 2c0f1318fc63..87c89958acf2 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 1c67775099cb..7219b9bd2a04 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 87ba9c6df206..c5941b0a085f 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 161729063e4b..1273a17bc87f 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 051e57bc7609..723a3d64c3fb 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 f84eaea6488d..d7e4ef5b8ce6 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 c8f94d7c4096..d035e9e1cab9 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 02c2ccfb3504..84dd944fd941 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 c44ac7e5c25e..593372406e91 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 48f7a92fbbd6..fc1be1654401 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 3c1a89cac4da..793416ba0e93 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 5e686ca56a90..13d4baa795e8 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 05d4f19ebc89..2a06c82dc322 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 10a03032c5ac..e47e2d473060 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 752fee048706..351a733e31d0 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 ddfd337a220b..082aec5a87c6 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 79d356e1a86f..52785f4fc883 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 63f35c1f5dfa..0b520b9752ae 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 c22e32173314..a7d242b366dd 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 70386737e4ed..e874670378bb 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 |