tdf#141440 - Do not delete notes when pasting contents

Contents include cells with values, datetimes, strings, formulas, outlines, and sparklines.

Change-Id: I9acf3a33c7723300d6b85f0abe468db28de6ebcb
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151759
Tested-by: Jenkins
Reviewed-by: Andreas Heinisch <andreas.heinisch@yahoo.de>
diff --git a/sc/qa/unit/ucalc_copypaste.cxx b/sc/qa/unit/ucalc_copypaste.cxx
index 43f9272..695b5b8 100644
--- a/sc/qa/unit/ucalc_copypaste.cxx
+++ b/sc/qa/unit/ucalc_copypaste.cxx
@@ -9407,10 +9407,11 @@ CPPUNIT_TEST_FIXTURE(TestCopyPaste, testCopyPasteSkipEmpty)

    // Check the content after the paste.
    {
        // tdf#141440 - do not delete notes when pasting contents
        static const Check aChecks[] = {
            { "Clip1", COL_YELLOW, false }, { "B", COL_BLUE, true },
            { "Clip2", COL_YELLOW, false }, { "D", COL_BLUE, true },
            { "Clip3", COL_YELLOW, false },
            { "Clip1", COL_YELLOW, true }, { "B", COL_BLUE, true },
            { "Clip2", COL_YELLOW, true }, { "D", COL_BLUE, true },
            { "Clip3", COL_YELLOW, true },
        };

        bool bRes
@@ -9434,10 +9435,11 @@ CPPUNIT_TEST_FIXTURE(TestCopyPaste, testCopyPasteSkipEmpty)
    // Redo, and check the content again.
    aUndo.Redo();
    {
        // tdf#141440 - do not delete notes when pasting contents
        static const Check aChecks[] = {
            { "Clip1", COL_YELLOW, false }, { "B", COL_BLUE, true },
            { "Clip2", COL_YELLOW, false }, { "D", COL_BLUE, true },
            { "Clip3", COL_YELLOW, false },
            { "Clip1", COL_YELLOW, true }, { "B", COL_BLUE, true },
            { "Clip2", COL_YELLOW, true }, { "D", COL_BLUE, true },
            { "Clip3", COL_YELLOW, true },
        };

        bool bRes
diff --git a/sc/qa/unit/uicalc/uicalc.cxx b/sc/qa/unit/uicalc/uicalc.cxx
index d3ae6e4..a6854ae 100644
--- a/sc/qa/unit/uicalc/uicalc.cxx
+++ b/sc/qa/unit/uicalc/uicalc.cxx
@@ -1893,6 +1893,41 @@ CPPUNIT_TEST_FIXTURE(ScUiCalcTest, testTdf150219)
    CPPUNIT_ASSERT_EQUAL(OUString(""), pDoc->GetString(ScAddress(0, 0, 1)));
}

CPPUNIT_TEST_FIXTURE(ScUiCalcTest, testTdf141440)
{
    createScDoc();
    ScDocument* pDoc = getScDoc();

    // Insert a note to cell A1
    goToCell("A1");
    uno::Sequence<beans::PropertyValue> aArgs
        = comphelper::InitPropertySequence({ { "Text", uno::Any(OUString("Note in A1")) } });
    dispatchCommand(mxComponent, ".uno:InsertAnnotation", aArgs);

    // Insert a formula to cell A2
    insertStringToCell("A2", u"=1+1");
    CPPUNIT_ASSERT_EQUAL(OUString("2"), pDoc->GetString(ScAddress(0, 1, 0)));

    // Copy content of A2 to A1 using paste special command as a formula (Flags F)
    goToCell("A2");
    dispatchCommand(mxComponent, ".uno:Copy", {});
    goToCell("A1");
    aArgs = comphelper::InitPropertySequence(
        { { "Flags", uno::Any(OUString("F")) },
          { "FormulaCommand", uno::Any(sal_uInt16(ScPasteFunc::ADD)) },
          { "SkipEmptyCells", uno::Any(false) },
          { "Transpose", uno::Any(false) },
          { "AsLink", uno::Any(false) },
          { "MoveMode", uno::Any(sal_uInt16(InsCellCmd::INS_NONE)) } });
    dispatchCommand(mxComponent, ".uno:InsertContents", aArgs);

    // Check if string in cell A2 was copied to cell A1
    CPPUNIT_ASSERT_EQUAL(OUString("2"), pDoc->GetString(ScAddress(0, 0, 0)));
    // Without the fix in place, there would be no note in cell A1 after using paste special
    CPPUNIT_ASSERT_MESSAGE("There should be a note on A1", pDoc->HasNote(ScAddress(0, 0, 0)));
    CPPUNIT_ASSERT_EQUAL(OUString("Note in A1"), pDoc->GetNote(ScAddress(0, 0, 0))->GetText());
}

CPPUNIT_PLUGIN_IMPLEMENT();

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 25d0363..cab1dc3 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -2905,8 +2905,9 @@ void ScDocument::CopyFromClip(
    InsertDeleteFlags nDelFlag = InsertDeleteFlags::NONE;
    if ( (nInsFlag & (InsertDeleteFlags::CONTENTS | InsertDeleteFlags::ADDNOTES)) == (InsertDeleteFlags::NOTE | InsertDeleteFlags::ADDNOTES) )
        nDelFlag |= InsertDeleteFlags::NOTE;
    else if ( nInsFlag & InsertDeleteFlags::CONTENTS )
        nDelFlag |= InsertDeleteFlags::CONTENTS;
    // tdf#141440 - do not delete notes when pasting contents (see InsertDeleteFlags::CONTENTS)
    else if ( nInsFlag & (InsertDeleteFlags::CONTENTS & ~InsertDeleteFlags::NOTE) )
        nDelFlag |= InsertDeleteFlags::CONTENTS & ~InsertDeleteFlags::NOTE;

    if (nInsFlag & InsertDeleteFlags::ATTRIB)
        nDelFlag |= InsertDeleteFlags::ATTRIB;