From fddef05ea72db3450f95570a17511350cc46016b Mon Sep 17 00:00:00 2001 From: Eike Rathke Date: Mon, 24 May 2021 01:29:19 +0200 Subject: Resolves: tdf#134675 Allow unrestricted pastes of same size in one dimension So copy-paste of for example one entire column onto more than 23 columns is possible as that does not create multiple repetitions. Change-Id: I2b035afa1c04522db55569396a36b1bac57c590c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116031 Reviewed-by: Eike Rathke Tested-by: Jenkins --- sc/source/ui/inc/viewdata.hxx | 10 +++++++- sc/source/ui/view/cellsh.cxx | 14 +++++++----- sc/source/ui/view/viewdata.cxx | 52 ++++++++++++++++++++++++++++++++++++++++++ sc/source/ui/view/viewfun3.cxx | 2 +- 4 files changed, 70 insertions(+), 8 deletions(-) diff --git a/sc/source/ui/inc/viewdata.hxx b/sc/source/ui/inc/viewdata.hxx index 957fd47a9b35..b63b10f0a195 100644 --- a/sc/source/ui/inc/viewdata.hxx +++ b/sc/source/ui/inc/viewdata.hxx @@ -479,7 +479,15 @@ public: bool IsMultiMarked() const; - /** Disallow cell fill (Paste,Fill,...) on Ctrl+A all + /** Disallow Paste on Ctrl+A all selected or another high + amount of selected cells that is not the same size in + one direction as the clipboard source. + To prevent DOOM. + */ + bool SelectionForbidsPaste( ScDocument* pClipDoc = nullptr ); + bool SelectionForbidsPaste( SCCOL nSrcCols, SCROW nSrcRows ); + + /** Disallow cell fill (Fill,Enter,...) on Ctrl+A all selected or another high amount of selected cells. We'd go DOOM. */ diff --git a/sc/source/ui/view/cellsh.cxx b/sc/source/ui/view/cellsh.cxx index 9bf5286c8d7c..233e59b32ec5 100644 --- a/sc/source/ui/view/cellsh.cxx +++ b/sc/source/ui/view/cellsh.cxx @@ -225,7 +225,7 @@ void ScCellShell::GetBlockState( SfxItemSet& rSet ) case SID_PASTE_TRANSPOSED: case SID_PASTE_AS_LINK: case SID_PASTE_TEXTIMPORT_DIALOG: - bDisable = GetViewData().SelectionForbidsCellFill(); + bDisable = GetViewData().SelectionForbidsPaste(); break; case FID_INS_ROW: @@ -548,12 +548,11 @@ bool checkDestRanges(ScViewData& rViewData) return false; } - if (rViewData.SelectionForbidsCellFill()) - return false; - // Multiple destination ranges. - ScDocument& rDoc = rViewData.GetDocument(); + // Same as ScViewData::SelectionForbidsPaste() in + // sc/source/ui/view/viewdata.cxx but different return details. + vcl::Window* pWin = rViewData.GetActiveWin(); if (!pWin) return false; @@ -571,12 +570,15 @@ bool checkDestRanges(ScViewData& rViewData) SCROW nRowSize = aSrcRange.aEnd.Row() - aSrcRange.aStart.Row() + 1; SCCOL nColSize = aSrcRange.aEnd.Col() - aSrcRange.aStart.Col() + 1; + if (rViewData.SelectionForbidsPaste( nColSize, nRowSize)) + return false; + ScMarkData aMark = rViewData.GetMarkData(); ScRangeList aRanges; aMark.MarkToSimple(); aMark.FillRangeListWithMarks(&aRanges, false); - return ScClipUtil::CheckDestRanges(rDoc, nColSize, nRowSize, aMark, aRanges); + return ScClipUtil::CheckDestRanges(rViewData.GetDocument(), nColSize, nRowSize, aMark, aRanges); } } diff --git a/sc/source/ui/view/viewdata.cxx b/sc/source/ui/view/viewdata.cxx index 233ea9206e2e..5c66b48c6c72 100644 --- a/sc/source/ui/view/viewdata.cxx +++ b/sc/source/ui/view/viewdata.cxx @@ -56,6 +56,8 @@ #include #include #include +#include +#include #include #include #include @@ -1256,6 +1258,56 @@ bool ScViewData::IsMultiMarked() const return (eType & SC_MARK_SIMPLE) != SC_MARK_SIMPLE; } +bool ScViewData::SelectionForbidsPaste( ScDocument* pClipDoc ) +{ + if (!pClipDoc) + { + // Same as checkDestRanges() in sc/source/ui/view/cellsh.cxx but + // different return details. + + vcl::Window* pWin = GetActiveWin(); + if (!pWin) + // No window doesn't mean paste would be forbidden. + return false; + + const ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard(ScTabViewShell::GetClipData(pWin)); + if (!pOwnClip) + // Foreign content does not get repeatedly replicated. + return false; + + pClipDoc = pOwnClip->GetDocument(); + if (!pClipDoc) + // No clipdoc doesn't mean paste would be forbidden. + return false; + } + + const ScRange aSrcRange = pClipDoc->GetClipParam().getWholeRange(); + const SCROW nRowSize = aSrcRange.aEnd.Row() - aSrcRange.aStart.Row() + 1; + const SCCOL nColSize = aSrcRange.aEnd.Col() - aSrcRange.aStart.Col() + 1; + + return SelectionForbidsPaste( nColSize, nRowSize); +} + +bool ScViewData::SelectionForbidsPaste( SCCOL nSrcCols, SCROW nSrcRows ) +{ + ScRange aSelRange( ScAddress::UNINITIALIZED ); + ScMarkType eMarkType = GetSimpleArea( aSelRange); + + if (eMarkType == SC_MARK_MULTI) + // Not because of DOOM. + return false; + + if (aSelRange.aEnd.Row() - aSelRange.aStart.Row() + 1 == nSrcRows) + // This also covers entire col(s) copied to be pasted on entire cols. + return false; + + if (aSelRange.aEnd.Col() - aSelRange.aStart.Col() + 1 == nSrcCols) + // This also covers entire row(s) copied to be pasted on entire rows. + return false; + + return SelectionFillDOOM( aSelRange); +} + bool ScViewData::SelectionForbidsCellFill() { ScRange aSelRange( ScAddress::UNINITIALIZED ); diff --git a/sc/source/ui/view/viewfun3.cxx b/sc/source/ui/view/viewfun3.cxx index 476e92cd7443..5f5cb8ac4b36 100644 --- a/sc/source/ui/view/viewfun3.cxx +++ b/sc/source/ui/view/viewfun3.cxx @@ -885,7 +885,7 @@ bool ScViewFunc::PasteFromClip( InsertDeleteFlags nFlags, ScDocument* pClipDoc, return false; } - if (GetViewData().SelectionForbidsCellFill()) + if (GetViewData().SelectionForbidsPaste(pClipDoc)) return false; // undo: save all or no content -- cgit