tdf#137621 sc: autofill bool sequences in merged cells

Fixed FillAnalyse to not discover booleans as number sequences,
rather as a pattern that can be repeated.

Co-authored-by: Tibor Nagy (NISZ)
Change-Id: I0a32e756461eb4101b77724129b745e23a658b1d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104655
Tested-by: Jenkins
Tested-by: László Németh <nemeth@numbertext.org>
Reviewed-by: László Németh <nemeth@numbertext.org>
diff --git a/sc/qa/unit/copy_paste_test.cxx b/sc/qa/unit/copy_paste_test.cxx
index 12e0b64..5420213 100644
--- a/sc/qa/unit/copy_paste_test.cxx
+++ b/sc/qa/unit/copy_paste_test.cxx
@@ -45,6 +45,7 @@ public:
    void testTdf40993_fillMergedCells();
    void testTdf43958_clickSelectOnMergedCells();
    void testTdf88782_autofillLinearNumbersInMergedCells();
    void tdf137621_autofillMergedBool();
    void tdf137205_autofillDatesInMergedCells();

    CPPUNIT_TEST_SUITE(ScCopyPasteTest);
@@ -57,6 +58,7 @@ public:
    CPPUNIT_TEST(testTdf40993_fillMergedCells);
    CPPUNIT_TEST(testTdf43958_clickSelectOnMergedCells);
    CPPUNIT_TEST(testTdf88782_autofillLinearNumbersInMergedCells);
    CPPUNIT_TEST(tdf137621_autofillMergedBool);
    CPPUNIT_TEST(tdf137205_autofillDatesInMergedCells);
    CPPUNIT_TEST_SUITE_END();

@@ -648,10 +650,12 @@ void ScCopyPasteTest::testTdf88782_autofillLinearNumbersInMergedCells()
    pView->FillAuto(FILL_TO_LEFT, 9, 30, 16, 35, 8);    //J31:Q36 -> B31:Q36

    // compare the results of fill-down with the reference stored in the test file
    // this compare the whole area blindly, for concrete test cases, check the test file
    // this compares the whole area blindly, for specific test cases, check the test file
    // the test file have instructions / explanations, so that is easy to understand
    for (int nCol = 1; nCol <= 10; nCol++) {
        for (int nRow = 8; nRow <= 27; nRow++) {
    for (int nCol = 1; nCol <= 10; nCol++)
    {
        for (int nRow = 8; nRow <= 27; nRow++)
        {
            CellType nType1 = rDoc.GetCellType(ScAddress(nCol, nRow, 0));
            CellType nType2 = rDoc.GetCellType(ScAddress(nCol + 22, nRow, 0));
            double* pValue1 = rDoc.GetValueCell(ScAddress(nCol, nRow, 0));
@@ -666,8 +670,10 @@ void ScCopyPasteTest::testTdf88782_autofillLinearNumbersInMergedCells()
    }

    // compare the results of fill-right and left with the reference stored in the test file
    for (int nCol = 1; nCol <= 24; nCol++) {
        for (int nRow = 30; nRow <= 35; nRow++) {
    for (int nCol = 1; nCol <= 24; nCol++)
    {
        for (int nRow = 30; nRow <= 35; nRow++)
        {
            CellType nType1 = rDoc.GetCellType(ScAddress(nCol, nRow, 0));
            CellType nType2 = rDoc.GetCellType(ScAddress(nCol, nRow + 16, 0));
            double* pValue1 = rDoc.GetValueCell(ScAddress(nCol, nRow, 0));
@@ -681,6 +687,39 @@ void ScCopyPasteTest::testTdf88782_autofillLinearNumbersInMergedCells()
        }
    }
}

void ScCopyPasteTest::tdf137621_autofillMergedBool()
{
    ScDocShellRef xDocSh = loadDocAndSetupModelViewController("tdf137621_autofillMergedBool.", FORMAT_ODS, true);
    ScDocument& rDoc = xDocSh->GetDocument();

    // Get the document controller
    ScTabViewShell* pView = xDocSh->GetBestViewShell(false);
    CPPUNIT_ASSERT(pView != nullptr);

    // fillauto booleans, these areas contain only merged cells
    pView->FillAuto(FILL_TO_RIGHT, 0, 4, 3, 5, 8);   //A5:D6

    // compare the results of fill-right with the reference stored in the test file
    // this compares the whole area blindly, for specific test cases, check the test file
    for (int nCol = 4; nCol <= 11; nCol++)
    {
        for (int nRow = 4; nRow <= 5; nRow++)
        {
            CellType nType1 = rDoc.GetCellType(ScAddress(nCol, nRow, 0));
            CellType nType2 = rDoc.GetCellType(ScAddress(nCol, nRow + 3, 0));
            double* pValue1 = rDoc.GetValueCell(ScAddress(nCol, nRow, 0));
            double* pValue2 = rDoc.GetValueCell(ScAddress(nCol, nRow + 3, 0));

            CPPUNIT_ASSERT_EQUAL(nType1, nType2);
            if (pValue2 != nullptr)
                CPPUNIT_ASSERT_EQUAL(*pValue1, *pValue2);   //cells with boolean value
            else
                CPPUNIT_ASSERT_EQUAL(pValue1, pValue2);     //empty cells
        }
    }
}

void ScCopyPasteTest::tdf137205_autofillDatesInMergedCells()
{
    ScDocShellRef xDocSh = loadDocAndSetupModelViewController("tdf137205_AutofillDatesInMergedCells.", FORMAT_ODS, true);
@@ -694,9 +733,11 @@ void ScCopyPasteTest::tdf137205_autofillDatesInMergedCells()
    pView->FillAuto(FILL_TO_RIGHT, 1, 5, 4, 7, 8);   //B6:E8

    // compare the results of fill-right with the reference stored in the test file
    // this compare the whole area blindly, for concrete test cases, check the test file
    for (int nCol = 5; nCol <= 12; nCol++) {
        for (int nRow = 5; nRow <= 7; nRow++) {
    // this compares the whole area blindly, for specific test cases, check the test file
    for (int nCol = 5; nCol <= 12; nCol++)
    {
        for (int nRow = 5; nRow <= 7; nRow++)
        {
            CellType nType1 = rDoc.GetCellType(ScAddress(nCol, nRow, 0));
            CellType nType2 = rDoc.GetCellType(ScAddress(nCol, nRow + 5, 0));
            double* pValue1 = rDoc.GetValueCell(ScAddress(nCol, nRow, 0));
diff --git a/sc/qa/unit/data/ods/tdf137621_autofillMergedBool.ods b/sc/qa/unit/data/ods/tdf137621_autofillMergedBool.ods
new file mode 100644
index 0000000..4f76017
--- /dev/null
+++ b/sc/qa/unit/data/ods/tdf137621_autofillMergedBool.ods
Binary files differ
diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx
index 37c4cb4..795dbf0 100644
--- a/sc/source/core/data/table4.cxx
+++ b/sc/source/core/data/table4.cxx
@@ -300,8 +300,8 @@ void ScTable::FillAnalyse( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
            CellType eCellType = aCurrCell.meType;
            if (eCellType == CELLTYPE_VALUE)
            {
                // TODO: Check / handle special cases of number formats like boolean
                bool bVal = true;
                double fVal;
                SvNumFormatType nCurrCellFormatType
                    = rDocument.GetFormatTable()->GetType(GetNumberFormat(nColCurr, nRowCurr));
                if (nCurrCellFormatType == SvNumFormatType::DATE)
@@ -382,6 +382,10 @@ void ScTable::FillAnalyse( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
                        return;
                    }
                }
                else if (nCurrCellFormatType == SvNumFormatType::LOGICAL
                         && ((fVal = aCurrCell.mfValue) == 0.0 || fVal == 1.0))
                {
                }
                else if (nValueCount >= 2)
                {
                    for (SCSIZE i = 1; i < nValueCount && bVal; i++)
@@ -397,6 +401,11 @@ void ScTable::FillAnalyse( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
                                rInc = nDiff;
                            if (!::rtl::math::approxEqual(nDiff, rInc, 13))
                                bVal = false;
                            else if ((aCurrCell.mfValue == 0.0 || aCurrCell.mfValue == 1.0)
                                     && (rDocument.GetFormatTable()->GetType(
                                             GetNumberFormat(nColCurr, nRowCurr))
                                         == SvNumFormatType::LOGICAL))
                                bVal = false;
                        }
                        else
                            bVal = false;