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 <erack@redhat.com>
Tested-by: Jenkins
Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116039
diff --git a/sc/source/ui/inc/viewdata.hxx b/sc/source/ui/inc/viewdata.hxx
index 4026c17..6e11410 100644
--- a/sc/source/ui/inc/viewdata.hxx
+++ b/sc/source/ui/inc/viewdata.hxx
@@ -480,7 +480,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 cd46db5..fc24d18 100644
--- a/sc/source/ui/view/cellsh.cxx
+++ b/sc/source/ui/view/cellsh.cxx
@@ -223,7 +223,7 @@ void ScCellShell::GetBlockState( SfxItemSet& rSet )
            case SID_PASTE_ONLY_TEXT:
            case SID_PASTE_ONLY_FORMULA:
            case SID_PASTE_TEXTIMPORT_DIALOG:
                bDisable = GetViewData()->SelectionForbidsCellFill();
                bDisable = GetViewData()->SelectionForbidsPaste();
                break;

            case FID_INS_ROW:
@@ -543,12 +543,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;
@@ -566,12 +565,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 2d30a35..40ed99d 100644
--- a/sc/source/ui/view/viewdata.cxx
+++ b/sc/source/ui/view/viewdata.cxx
@@ -55,6 +55,8 @@
#include <markdata.hxx>
#include <ViewSettingsSequenceDefines.hxx>
#include <gridwin.hxx>
#include <transobj.hxx>
#include <clipparam.hxx>
#include <comphelper/flagguard.hxx>
#include <comphelper/lok.hxx>
#include <comphelper/processfactory.hxx>
@@ -1255,6 +1257,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 af9e50a..bb73a9c 100644
--- a/sc/source/ui/view/viewfun3.cxx
+++ b/sc/source/ui/view/viewfun3.cxx
@@ -884,7 +884,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