summaryrefslogtreecommitdiff
path: root/sc/source/ui
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2017-05-11 18:07:56 -0400
committerKohei Yoshida <libreoffice@kohei.us>2017-05-17 05:16:44 +0200
commit034be10413ed4915090678ad4f1d48596cf5e206 (patch)
tree5227cc4aae303272338e8fc25225fc48914168d0 /sc/source/ui
parent296c2296f5565556eea9fab51563050f28bbcafc (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>
Diffstat (limited to 'sc/source/ui')
-rw-r--r--sc/source/ui/docshell/docfunc.cxx46
-rw-r--r--sc/source/ui/docshell/editable.cxx22
-rw-r--r--sc/source/ui/inc/editable.hxx14
-rw-r--r--sc/source/ui/inc/protectiondlg.hxx4
-rw-r--r--sc/source/ui/miscdlgs/protectiondlg.cxx24
-rw-r--r--sc/source/ui/view/cellsh.cxx26
6 files changed, 130 insertions, 6 deletions
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();