[Libreoffice-commits] core.git: 3 commits - sc/CppunitTest_sc_mark_test.mk sc/Module_sc.mk sc/qa

Markus Mohrhard markus.mohrhard at googlemail.com
Sat Mar 19 15:15:21 UTC 2016


 sc/CppunitTest_sc_mark_test.mk |  125 ++++++
 sc/Module_sc.mk                |    1 
 sc/qa/unit/mark_test.cxx       |  828 +++++++++++++++++++++++++++++++++++++++++
 sc/qa/unit/ucalc.hxx           |    2 
 sc/qa/unit/ucalc_column.cxx    |   33 +
 5 files changed, 989 insertions(+)

New commits:
commit fbc99bf76db0029b6a242f1f2d658feefd1063f4
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Sat Mar 19 16:12:33 2016 +0100

    fix previous commit
    
    Change-Id: I5f7ec7f48bbcb995609c3d3ef4f64b9e6230b395

diff --git a/sc/qa/unit/ucalc_column.cxx b/sc/qa/unit/ucalc_column.cxx
index 51e0553..6a70aef 100644
--- a/sc/qa/unit/ucalc_column.cxx
+++ b/sc/qa/unit/ucalc_column.cxx
@@ -96,11 +96,11 @@ void Test::testColumnFindEditCells()
 
 void Test::testSetFormula()
 {
+    m_pDoc->InsertTab(0, "Test");
 
     struct aInputs
     {
         const char* aName;
-        SCTAB nTab;
         SCROW nRow;
         SCCOL nCol;
         const char* aFormula1;      // Represents the formula that is input to SetFormula function.
@@ -108,21 +108,22 @@ void Test::testSetFormula()
         formula::FormulaGrammar::Grammar eGram;
 
     } aTest[] = {
-        { "Rock and Roll" ,0 ,5 , 4 , "=SUM($D$2:$F$3)"             ,"=SUM($D$2:$F$3)" , formula::FormulaGrammar::Grammar::GRAM_ENGLISH     },
-        { "Blues"         ,1 ,5 , 5 , "=A1-$C2+B$3-$F$4"            ,"=A1-$C2+B$3-$F$4", formula::FormulaGrammar::Grammar::GRAM_NATIVE      },
-        { "Acoustic"      ,2 ,6 , 6 , "=A1-$C2+B$3-$F$4"            ,"=A1-$C2+B$3-$F$4", formula::FormulaGrammar::Grammar::GRAM_NATIVE_XL_A1},
-        { "Nursery Rhymes",3 ,7 , 8 , "=[.A1]-[.$C2]+[.G$3]-[.$F$4]","=A1-$C2+G$3-$F$4", formula::FormulaGrammar::Grammar::GRAM_ODFF        }
+        { "Rock and Roll" ,5 , 4 , "=SUM($D$2:$F$3)"             ,"=SUM($D$2:$F$3)" , formula::FormulaGrammar::Grammar::GRAM_ENGLISH     },
+        { "Blues"         ,5 , 5 , "=A1-$C2+B$3-$F$4"            ,"=A1-$C2+B$3-$F$4", formula::FormulaGrammar::Grammar::GRAM_NATIVE      },
+        { "Acoustic"      ,6 , 6 , "=A1-$C2+B$3-$F$4"            ,"=A1-$C2+B$3-$F$4", formula::FormulaGrammar::Grammar::GRAM_NATIVE_XL_A1},
+        { "Nursery Rhymes",7 , 8 , "=[.A1]-[.$C2]+[.G$3]-[.$F$4]","=A1-$C2+G$3-$F$4", formula::FormulaGrammar::Grammar::GRAM_ODFF        }
     };
 
-    for(size_t i = 0 ; i < SAL_N_ELEMENTS(aTest) ;++i)
+    for(size_t i = 0; i < SAL_N_ELEMENTS(aTest); ++i)
     {
-        m_pDoc->InsertTab(aTest[i].nTab,OUString::createFromAscii(aTest[i].aName));
-        OUString aBuffer("123");
-        m_pDoc->SetFormula(ScAddress(aTest[i].nCol,aTest[i].nRow,aTest[i].nTab) , OUString::createFromAscii(aTest[i].aFormula1) ,aTest[i].eGram);
-        m_pDoc->GetFormula(aTest[i].nCol,aTest[i].nRow,aTest[i].nTab, aBuffer);
-        CPPUNIT_ASSERT_EQUAL_MESSAGE("Failed to set formula",OUString::createFromAscii(aTest[i].aFormula2),aBuffer);
+        OUString aBuffer;
+        m_pDoc->SetFormula(ScAddress(aTest[i].nCol, aTest[i].nRow, 0), OUString::createFromAscii(aTest[i].aFormula1), aTest[i].eGram);
+        m_pDoc->GetFormula(aTest[i].nCol, aTest[i].nRow, 0, aBuffer);
 
+        CPPUNIT_ASSERT_EQUAL_MESSAGE("Failed to set formula", OUString::createFromAscii(aTest[i].aFormula2), aBuffer);
     }
+
+    m_pDoc->DeleteTab(0);
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 2fd81edb9a6b89e1aa2d9c83006ad28660f85d71
Author: Jaskaran <jvsg1303 at gmail.com>
Date:   Sun Mar 13 10:27:48 2016 +0530

    tdf#70448, Test for SetFormula function
    
    Change-Id: Ie6899b90f02f8344710515af847170783a5e0d0f

diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx
index 996652c..b4efe3d 100644
--- a/sc/qa/unit/ucalc.hxx
+++ b/sc/qa/unit/ucalc.hxx
@@ -460,6 +460,7 @@ public:
     void testCopyPasteMatrixFormula();
     void testUndoDataAnchor();
     void testFormulaErrorPropagation();
+    void testSetFormula();
 
     void testTdf97369();
     void testTdf97587();
@@ -696,6 +697,7 @@ public:
     CPPUNIT_TEST(testCopyPasteMatrixFormula);
     CPPUNIT_TEST(testUndoDataAnchor);
     CPPUNIT_TEST(testFormulaErrorPropagation);
+    CPPUNIT_TEST(testSetFormula);
     CPPUNIT_TEST(testTdf97369);
     CPPUNIT_TEST(testTdf97587);
     CPPUNIT_TEST_SUITE_END();
diff --git a/sc/qa/unit/ucalc_column.cxx b/sc/qa/unit/ucalc_column.cxx
index 2aaba3b..51e0553 100644
--- a/sc/qa/unit/ucalc_column.cxx
+++ b/sc/qa/unit/ucalc_column.cxx
@@ -93,4 +93,36 @@ void Test::testColumnFindEditCells()
     m_pDoc->DeleteTab(0);
 }
 
+
+void Test::testSetFormula()
+{
+
+    struct aInputs
+    {
+        const char* aName;
+        SCTAB nTab;
+        SCROW nRow;
+        SCCOL nCol;
+        const char* aFormula1;      // Represents the formula that is input to SetFormula function.
+        const char* aFormula2;      // Represents the formula that is actually stored in the cell.
+        formula::FormulaGrammar::Grammar eGram;
+
+    } aTest[] = {
+        { "Rock and Roll" ,0 ,5 , 4 , "=SUM($D$2:$F$3)"             ,"=SUM($D$2:$F$3)" , formula::FormulaGrammar::Grammar::GRAM_ENGLISH     },
+        { "Blues"         ,1 ,5 , 5 , "=A1-$C2+B$3-$F$4"            ,"=A1-$C2+B$3-$F$4", formula::FormulaGrammar::Grammar::GRAM_NATIVE      },
+        { "Acoustic"      ,2 ,6 , 6 , "=A1-$C2+B$3-$F$4"            ,"=A1-$C2+B$3-$F$4", formula::FormulaGrammar::Grammar::GRAM_NATIVE_XL_A1},
+        { "Nursery Rhymes",3 ,7 , 8 , "=[.A1]-[.$C2]+[.G$3]-[.$F$4]","=A1-$C2+G$3-$F$4", formula::FormulaGrammar::Grammar::GRAM_ODFF        }
+    };
+
+    for(size_t i = 0 ; i < SAL_N_ELEMENTS(aTest) ;++i)
+    {
+        m_pDoc->InsertTab(aTest[i].nTab,OUString::createFromAscii(aTest[i].aName));
+        OUString aBuffer("123");
+        m_pDoc->SetFormula(ScAddress(aTest[i].nCol,aTest[i].nRow,aTest[i].nTab) , OUString::createFromAscii(aTest[i].aFormula1) ,aTest[i].eGram);
+        m_pDoc->GetFormula(aTest[i].nCol,aTest[i].nRow,aTest[i].nTab, aBuffer);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE("Failed to set formula",OUString::createFromAscii(aTest[i].aFormula2),aBuffer);
+
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 187669de1096ebbf4347ec1126eb6b693f6c5a96
Author: Dennis Francis <dennisfrancis.in at gmail.com>
Date:   Thu Mar 3 09:00:13 2016 +0530

    tdf#50916 : Unit tests for the refactored ScMarkData...
    
    ... and for the newly created ScMultiSel class
    
    Change-Id: I567d9dfa83da05de05b35e3b3949060358ea7e70

diff --git a/sc/CppunitTest_sc_mark_test.mk b/sc/CppunitTest_sc_mark_test.mk
new file mode 100644
index 0000000..641bd7e
--- /dev/null
+++ b/sc/CppunitTest_sc_mark_test.mk
@@ -0,0 +1,125 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_CppunitTest_CppunitTest,sc_mark_test))
+
+$(eval $(call gb_CppunitTest_use_externals,sc_mark_test, \
+	boost_headers \
+    icu_headers \
+    icui18n \
+    icuuc \
+	libxml2 \
+	mdds_headers \
+	orcus \
+	orcus-parser \
+))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,sc_mark_test, \
+    sc/qa/unit/mark_test \
+))
+
+$(eval $(call gb_CppunitTest_use_library_objects,sc_mark_test, \
+	scqahelper \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,sc_mark_test, \
+    basegfx \
+    comphelper \
+    cppu \
+    cppuhelper \
+    drawinglayer \
+    editeng \
+    for \
+    forui \
+    i18nlangtag \
+    msfilter \
+    oox \
+    sal \
+    salhelper \
+    sax \
+    sb \
+    sc \
+    sfx \
+    sot \
+    svl \
+    svt \
+    svx \
+    svxcore \
+	test \
+    tk \
+    tl \
+    ucbhelper \
+	unotest \
+    utl \
+    vbahelper \
+    vcl \
+    xo \
+	$(gb_UWINAPI) \
+))
+
+$(eval $(call gb_CppunitTest_set_include,sc_mark_test,\
+    -I$(SRCDIR)/sc/source/ui/inc \
+    -I$(SRCDIR)/sc/inc \
+    $$(INCLUDE) \
+))
+
+$(eval $(call gb_CppunitTest_use_api,sc_mark_test,\
+    offapi \
+    oovbaapi \
+    udkapi \
+))
+
+$(eval $(call gb_CppunitTest_use_ure,sc_mark_test))
+$(eval $(call gb_CppunitTest_use_vcl,sc_mark_test))
+
+$(eval $(call gb_CppunitTest_use_components,sc_mark_test,\
+    basic/util/sb \
+    chart2/source/chartcore \
+    chart2/source/controller/chartcontroller \
+    comphelper/util/comphelp \
+    configmgr/source/configmgr \
+    dbaccess/util/dba \
+    embeddedobj/util/embobj \
+    eventattacher/source/evtatt \
+    filter/source/config/cache/filterconfig1 \
+    forms/util/frm \
+    framework/util/fwk \
+    i18npool/util/i18npool \
+    oox/util/oox \
+    package/source/xstor/xstor \
+    package/util/package2 \
+    sax/source/expatwrap/expwrap \
+    scaddins/source/analysis/analysis \
+    scaddins/source/datefunc/date \
+    scripting/source/basprov/basprov \
+    scripting/util/scriptframe \
+    sc/util/sc \
+    sc/util/scd \
+    sc/util/scfilt \
+    $(call gb_Helper_optional,SCRIPTING, \
+	    sc/util/vbaobj) \
+    sfx2/util/sfx \
+    sot/util/sot \
+    svl/source/fsstor/fsstorage \
+    svl/util/svl \
+    svx/util/svx \
+    svx/util/svxcore \
+    toolkit/util/tk \
+    ucb/source/core/ucb1 \
+    ucb/source/ucp/file/ucpfile1 \
+    ucb/source/ucp/tdoc/ucptdoc1 \
+    unotools/util/utl \
+    unoxml/source/rdf/unordf \
+    unoxml/source/service/unoxml \
+    xmloff/util/xo \
+))
+
+$(eval $(call gb_CppunitTest_use_configuration,sc_mark_test))
+
+# vim: set noet sw=4 ts=4:
diff --git a/sc/Module_sc.mk b/sc/Module_sc.mk
index a32e4ae..4e218b2 100644
--- a/sc/Module_sc.mk
+++ b/sc/Module_sc.mk
@@ -44,6 +44,7 @@ $(eval $(call gb_Module_add_check_targets,sc,\
 		CppunitTest_sc_ucalc) \
 	CppunitTest_sc_filters_test \
 	CppunitTest_sc_rangelst_test \
+	CppunitTest_sc_mark_test \
 	CppunitTest_sc_core \
 	CppunitTest_sc_tiledrendering \
 ))
diff --git a/sc/qa/unit/mark_test.cxx b/sc/qa/unit/mark_test.cxx
new file mode 100644
index 0000000..e659de1
--- /dev/null
+++ b/sc/qa/unit/mark_test.cxx
@@ -0,0 +1,828 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/config.h>
+#include <test/bootstrapfixture.hxx>
+#include "helper/qahelper.hxx"
+
+#include "markdata.hxx"
+#include "../../source/core/data/markarr.cxx"
+#include "../../source/core/data/markmulti.cxx"
+#include "../../source/core/data/segmenttree.cxx"
+
+#include <utility>
+
+struct MarkTestData  // To represent a single rectangle part of a multiselection
+{
+    ScRange aRange;
+    bool bMark;
+
+    // Cumulative Test data follows
+    std::vector<ScAddress> aInsideAddresses;
+    std::vector<ScAddress> aOutsideAddresses;
+
+    std::vector<SCCOL> aColumnsWithFullMarks;
+    std::vector<SCCOL> aColumnsWithoutFullMarks;
+
+    std::vector<SCROW> aRowsWithFullMarks;
+    std::vector<SCROW> aRowsWithoutFullMarks;
+
+    std::vector<ScRange> aRangesWithFullMarks;
+    std::vector<ScRange> aRangesWithoutFullMarks;
+
+    // To test ScMarkData::GetNextMarked()
+    // Encoding : EndRow is the next marked row in the column = StartCol after StartRow.
+    // EndCol = 0 means search up, 1 means to search down
+    std::vector<ScRange> aNextMarked;
+
+    std::vector<SCCOL> aColumnsWithAtLeastOneMark;
+    std::vector<SCCOL> aColumnsWithoutAnyMarks;
+
+};
+
+struct MarkArrayTestData
+{
+    SCCOL nCol;
+    std::vector<std::pair<SCROW,SCROW>> aMarkedRowSegs;
+};
+
+struct MultiMarkTestData
+{
+    std::vector<MarkTestData> aMarks;
+    ScRange aSelectionCover;
+    ScRangeList aLeftEnvelope;
+    ScRangeList aRightEnvelope;
+    ScRangeList aTopEnvelope;
+    ScRangeList aBottomEnvelope;
+    std::vector<MarkArrayTestData> aMarkArrays;
+
+    // To test ScMultiSel::HasOneMark()
+    // Encoding : StartCol is the column to test, StartRow is the begining of the one mark,
+    // EndRow is the end of the one mark, EndCol is not used
+    std::vector<ScRange> aColsWithOneMark;
+    std::vector<SCCOL> aColsWithoutOneMark;
+
+    // To test ScMultiSel::IsAllMarked()
+    // Encoding StartCol is the column to be queried, [StartRow,EndRow] is the range to test.
+    std::vector<ScRange> aColsAllMarked;
+    std::vector<ScRange> aColsNotAllMarked;
+
+    // To test ScMultiSel::HasEqualRowsMarked()
+    std::vector<std::pair<SCCOL,SCCOL>> aColsWithEqualMarksList;
+    std::vector<std::pair<SCCOL,SCCOL>> aColsWithUnequalMarksList;
+};
+
+class Test : public test::BootstrapFixture
+{
+public:
+    Test()
+    {
+    }
+
+    virtual void setUp() override;
+    virtual void tearDown() override;
+
+    void testSimpleMark( const ScRange& rRange, const ScRange& rSelectionCover,
+                         const ScRangeList& rLeftEnvelope, const ScRangeList& rRightEnvelope,
+                         const ScRangeList& rTopEnvelope, const ScRangeList& rBottomEnvelope );
+    void testSimpleMark_Simple();
+    void testSimpleMark_Column();
+    void testSimpleMark_Row();
+
+    void testMultiMark( const MultiMarkTestData& rData );
+    void testMultiMark_FourRanges();
+    void testMultiMark_NegativeMarking();
+
+    CPPUNIT_TEST_SUITE(Test);
+    CPPUNIT_TEST(testSimpleMark_Simple);
+    CPPUNIT_TEST(testSimpleMark_Column);
+    CPPUNIT_TEST(testSimpleMark_Row);
+    CPPUNIT_TEST(testMultiMark_FourRanges);
+    CPPUNIT_TEST(testMultiMark_NegativeMarking);
+    CPPUNIT_TEST_SUITE_END();
+
+private:
+
+};
+
+static void lcl_GetSortedRanges( const ScRangeList& rRangeList, ScRangeList& rRangeListOut )
+{
+    rRangeListOut.RemoveAll();
+    std::vector<ScRange> aRanges;
+    size_t nSize = rRangeList.size();
+    aRanges.reserve( nSize );
+    for ( size_t nIdx = 0; nIdx < nSize; ++nIdx )
+        aRanges.push_back( *rRangeList[nIdx] );
+    std::sort( aRanges.begin(), aRanges.end() );
+    for ( size_t nIdx = 0; nIdx < nSize; ++nIdx )
+        rRangeListOut.Append( aRanges[nIdx] );
+}
+
+void Test::setUp()
+{
+    BootstrapFixture::setUp();
+    ScDLL::Init();
+}
+
+void Test::tearDown()
+{
+    BootstrapFixture::tearDown();
+}
+
+void Test::testSimpleMark( const ScRange& rRange, const ScRange& rSelectionCover,
+                           const ScRangeList& rLeftEnvelope, const ScRangeList& rRightEnvelope,
+                           const ScRangeList& rTopEnvelope, const ScRangeList& rBottomEnvelope )
+{
+    ScMarkData aMark;
+    CPPUNIT_ASSERT( !aMark.IsMarked() && !aMark.IsMultiMarked() );
+
+    aMark.SetMarkArea( rRange );
+    CPPUNIT_ASSERT( aMark.IsMarked() && !aMark.IsMultiMarked() );
+
+    ScRange aRangeResult;
+    aMark.GetMarkArea( aRangeResult );
+    CPPUNIT_ASSERT_EQUAL( rRange, aRangeResult );
+
+    SCROW nMidRow = ( ( rRange.aStart.Row() + rRange.aEnd.Row() ) / 2 );
+    SCCOL nMidCol = ( ( rRange.aStart.Col() + rRange.aEnd.Col() ) / 2 );
+    SCROW nOutRow1 = ( rRange.aEnd.Row() + 1 );
+    SCCOL nOutCol1 = ( rRange.aEnd.Col() + 1 );
+    SCROW nOutRow2 = ( rRange.aStart.Row() - 1 );
+    SCCOL nOutCol2 = ( rRange.aStart.Col() - 1 );
+
+    CPPUNIT_ASSERT( aMark.IsCellMarked( nMidCol, nMidRow ) );
+    if ( ValidCol( nOutCol1 ) && ValidRow( nOutRow1 ) )
+        CPPUNIT_ASSERT( !aMark.IsCellMarked( nOutCol1, nOutRow1 ) );
+
+    if ( ValidCol( nOutCol2 ) && ValidRow( nOutRow2 ) )
+        CPPUNIT_ASSERT( !aMark.IsCellMarked( nOutCol2, nOutRow2 ) );
+
+    if ( ValidRow( nOutRow1 ) )
+        CPPUNIT_ASSERT( !aMark.IsCellMarked( nMidCol, nOutRow1 ) );
+
+    if ( ValidCol( nOutCol1 ) )
+        CPPUNIT_ASSERT( !aMark.IsCellMarked( nOutCol1, nMidRow ) );
+
+    if ( ValidRow( nOutRow2 ) )
+        CPPUNIT_ASSERT( !aMark.IsCellMarked( nMidCol, nOutRow2 ) );
+
+    if ( ValidCol( nOutCol2 ) )
+        CPPUNIT_ASSERT( !aMark.IsCellMarked( nOutCol2, nMidRow ) );
+
+    if ( rRange.aStart.Row() == 0 && rRange.aEnd.Row() == MAXROW )
+        CPPUNIT_ASSERT( aMark.IsColumnMarked( nMidCol ) );
+    else
+        CPPUNIT_ASSERT( !aMark.IsColumnMarked( nMidCol ) );
+    if ( rRange.aStart.Col() == 0 && rRange.aEnd.Col() == MAXCOL )
+        CPPUNIT_ASSERT( aMark.IsRowMarked( nMidRow ) );
+    else
+        CPPUNIT_ASSERT( !aMark.IsRowMarked( nMidRow ) );
+
+    ScRange aSelectionCoverOutput;
+    aMark.GetSelectionCover( aSelectionCoverOutput );
+    CPPUNIT_ASSERT_EQUAL( rSelectionCover, aSelectionCoverOutput );
+    CPPUNIT_ASSERT_EQUAL( rLeftEnvelope, aMark.GetLeftEnvelope() );
+    CPPUNIT_ASSERT_EQUAL( rRightEnvelope, aMark.GetRightEnvelope() );
+    CPPUNIT_ASSERT_EQUAL( rTopEnvelope, aMark.GetTopEnvelope() );
+    CPPUNIT_ASSERT_EQUAL( rBottomEnvelope, aMark.GetBottomEnvelope() );
+}
+
+void Test::testSimpleMark_Simple()
+{
+    testSimpleMark( ScRange( 10, 15, 0, 20, 30, 0 ),                  // Simple range
+                    ScRange( 9, 14, 0, 21, 31, 0 ),                   // Cover
+                    ScRangeList( ScRange( 9, 15, 0, 9, 30, 0 ) ),     // Left envelope
+                    ScRangeList( ScRange( 21, 15, 0, 21, 30, 0 ) ),   // Right envelope
+                    ScRangeList( ScRange( 10, 14, 0, 20, 14, 0 ) ),   // Top envelope
+                    ScRangeList( ScRange( 10, 31, 0, 20, 31, 0 ) ) ); // Bottom envelope
+}
+
+void Test::testSimpleMark_Column()
+{
+    // Column 10, rows from 15 to 30
+    testSimpleMark( ScRange( 10, 15, 0, 10, 30, 0 ),                  // Simple range
+                    ScRange( 9, 14, 0, 11, 31, 0 ),                   // Cover
+                    ScRangeList( ScRange( 9, 15, 0, 9, 30, 0 ) ),     // Left envelope
+                    ScRangeList( ScRange( 11, 15, 0, 11, 30, 0 ) ),   // Right envelope
+                    ScRangeList( ScRange( 10, 14, 0, 10, 14, 0 ) ),   // Top envelope
+                    ScRangeList( ScRange( 10, 31, 0, 10, 31, 0 ) ) ); // Bottom envelope
+
+    // Full Column 10
+    testSimpleMark( ScRange( 10, 0, 0, 10, MAXROW, 0 ),                 // Simple range
+                    ScRange( 9, 0, 0, 11, MAXROW, 0 ),                  // Cover
+                    ScRangeList( ScRange( 9, 0, 0, 9, MAXROW, 0 ) ),    // Left envelope
+                    ScRangeList( ScRange( 11, 0, 0, 11, MAXROW, 0 ) ),  // Right envelope
+                    ScRangeList(),                                      // Top envelope
+                    ScRangeList());                                     // Bottom envelope
+}
+
+void Test::testSimpleMark_Row()
+{
+    // Row 15, cols from 10 to 20
+    testSimpleMark( ScRange( 10, 15, 0, 20, 15, 0 ),                  // Simple range
+                    ScRange( 9, 14, 0, 21, 16, 0 ),                   // Cover
+                    ScRangeList( ScRange( 9, 15, 0, 9, 15, 0 ) ),     // Left envelope
+                    ScRangeList( ScRange( 21, 15, 0, 21, 15, 0 ) ),   // Right envelope
+                    ScRangeList( ScRange( 10, 14, 0, 20, 14, 0 ) ),   // Top envelope
+                    ScRangeList( ScRange( 10, 16, 0, 20, 16, 0 ) ) ); // Bottom envelope
+
+    // Full Row 15
+    testSimpleMark( ScRange( 0, 15, 0, MAXCOL, 15, 0 ),                    // Simple range
+                    ScRange( 0, 14, 0, MAXCOL, 16, 0 ),                    // Cover
+                    ScRangeList(),                                         // Left envelope
+                    ScRangeList(),                                         // Right envelope
+                    ScRangeList( ScRange( 0, 14, 0, MAXCOL, 14, 0 ) ),     // Top envelope
+                    ScRangeList( ScRange( 0, 16, 0, MAXCOL, 16, 0 ) ) );   // Bottom envelope
+}
+
+void Test::testMultiMark( const MultiMarkTestData& rMarksData )
+{
+
+    ScMarkData aMark;
+    ScMultiSel aMultiSel;
+    CPPUNIT_ASSERT( !aMark.IsMarked() && !aMark.IsMultiMarked() );
+    CPPUNIT_ASSERT_EQUAL( SCCOL(0), aMultiSel.size() );
+    CPPUNIT_ASSERT( !aMultiSel.HasAnyMarks() );
+
+    for ( const auto& rAreaTestData : rMarksData.aMarks )
+    {
+        aMultiSel.SetMarkArea( rAreaTestData.aRange.aStart.Col(), rAreaTestData.aRange.aEnd.Col(),
+                               rAreaTestData.aRange.aStart.Row(), rAreaTestData.aRange.aEnd.Row(),
+                               rAreaTestData.bMark );
+        aMark.SetMultiMarkArea( rAreaTestData.aRange, rAreaTestData.bMark );
+        CPPUNIT_ASSERT( aMark.IsMultiMarked() );
+
+        for ( const auto& rMarkedAddress : rAreaTestData.aInsideAddresses )
+        {
+            CPPUNIT_ASSERT( aMultiSel.GetMark( rMarkedAddress.Col(), rMarkedAddress.Row() ) );
+            CPPUNIT_ASSERT( aMark.IsCellMarked( rMarkedAddress.Col(), rMarkedAddress.Row() ) );
+        }
+
+        for ( const auto& rUnMarkedAddress : rAreaTestData.aOutsideAddresses )
+        {
+            CPPUNIT_ASSERT( !aMark.IsCellMarked( rUnMarkedAddress.Col(), rUnMarkedAddress.Row() ) );
+            CPPUNIT_ASSERT( !aMark.IsCellMarked( rUnMarkedAddress.Col(), rUnMarkedAddress.Row() ) );
+        }
+
+        for ( const auto& rCol : rAreaTestData.aColumnsWithFullMarks )
+        {
+            CPPUNIT_ASSERT( aMark.IsColumnMarked( rCol ) );
+            CPPUNIT_ASSERT( aMultiSel.IsAllMarked( rCol, 0, MAXROW ) );
+        }
+
+        for ( const auto& rCol : rAreaTestData.aColumnsWithoutFullMarks )
+        {
+            CPPUNIT_ASSERT( !aMark.IsColumnMarked( rCol ) );
+            CPPUNIT_ASSERT( !aMultiSel.IsAllMarked( rCol, 0, MAXROW ) );
+        }
+
+        for ( const auto& rRow : rAreaTestData.aRowsWithFullMarks )
+        {
+            CPPUNIT_ASSERT( aMark.IsRowMarked( rRow ) );
+            CPPUNIT_ASSERT( aMultiSel.IsRowMarked( rRow ) );
+        }
+
+        for ( const auto& rRow : rAreaTestData.aRowsWithoutFullMarks )
+        {
+            CPPUNIT_ASSERT( !aMark.IsRowMarked( rRow ) );
+            CPPUNIT_ASSERT( !aMultiSel.IsRowMarked( rRow ) );
+        }
+
+        for ( const auto& rRange : rAreaTestData.aRangesWithFullMarks )
+        {
+            CPPUNIT_ASSERT( aMark.IsAllMarked( rRange ) );
+            SCROW nRow1 = rRange.aStart.Row(), nRow2 = rRange.aEnd.Row();
+            SCCOL nCol1 = rRange.aStart.Col(), nCol2 = rRange.aEnd.Col();
+            for ( SCROW nColIter = nCol1; nColIter <= nCol2; ++nColIter )
+                CPPUNIT_ASSERT( aMultiSel.IsAllMarked( nColIter, nRow1, nRow2 ) );
+        }
+
+        for ( const auto& rRange : rAreaTestData.aRangesWithoutFullMarks )
+            CPPUNIT_ASSERT( !aMark.IsAllMarked( rRange ) );
+
+        for ( const auto& rRange : rAreaTestData.aNextMarked )
+        {
+            SCsROW nNextRow1 = aMark.GetNextMarked( rRange.aStart.Col(), rRange.aStart.Row(), !static_cast<bool>(rRange.aEnd.Col()) );
+            CPPUNIT_ASSERT_EQUAL( rRange.aEnd.Row(), nNextRow1 );
+            SCsROW nNextRow2 = aMultiSel.GetNextMarked( rRange.aStart.Col(), rRange.aStart.Row(), !static_cast<bool>(rRange.aEnd.Col()) );
+            CPPUNIT_ASSERT_EQUAL( rRange.aEnd.Row(), nNextRow2 );
+        }
+
+        for ( const auto& rCol : rAreaTestData.aColumnsWithAtLeastOneMark )
+        {
+            CPPUNIT_ASSERT( aMark.HasMultiMarks( rCol ) );
+            CPPUNIT_ASSERT( aMultiSel.HasMarks( rCol ) );
+        }
+
+        for ( const auto& rCol : rAreaTestData.aColumnsWithoutAnyMarks )
+        {
+            CPPUNIT_ASSERT( !aMark.HasMultiMarks( rCol ) );
+            CPPUNIT_ASSERT( !aMultiSel.HasMarks( rCol ) );
+        }
+
+    }
+
+    ScRange aSelectionCoverOutput;
+    aMark.GetSelectionCover( aSelectionCoverOutput );
+    CPPUNIT_ASSERT_EQUAL( rMarksData.aSelectionCover, aSelectionCoverOutput );
+
+    ScRangeList aRangesExpected, aRangesActual;
+    lcl_GetSortedRanges( rMarksData.aLeftEnvelope, aRangesExpected );
+    lcl_GetSortedRanges( aMark.GetLeftEnvelope(), aRangesActual );
+    CPPUNIT_ASSERT_EQUAL( aRangesExpected, aRangesActual );
+    lcl_GetSortedRanges( rMarksData.aRightEnvelope, aRangesExpected );
+    lcl_GetSortedRanges( aMark.GetRightEnvelope(), aRangesActual );
+    CPPUNIT_ASSERT_EQUAL( aRangesExpected, aRangesActual );
+    lcl_GetSortedRanges( rMarksData.aTopEnvelope, aRangesExpected );
+    lcl_GetSortedRanges( aMark.GetTopEnvelope(), aRangesActual );
+    CPPUNIT_ASSERT_EQUAL( aRangesExpected, aRangesActual );
+    lcl_GetSortedRanges( rMarksData.aBottomEnvelope, aRangesExpected );
+    lcl_GetSortedRanges( aMark.GetBottomEnvelope(), aRangesActual );
+    CPPUNIT_ASSERT_EQUAL( aRangesExpected, aRangesActual );
+
+    for ( const auto& rMarkArrayTestData : rMarksData.aMarkArrays )
+    {
+        ScMarkArray aArray( aMark.GetMarkArray( rMarkArrayTestData.nCol ) );
+        std::vector<std::pair<SCROW, SCROW>> aMarkedRowSegs;
+        ScMarkArrayIter aIter( &aArray );
+        SCROW nStart, nEnd;
+        while ( aIter.Next( nStart, nEnd ) )
+            aMarkedRowSegs.push_back( std::pair<SCROW, SCROW>( nStart, nEnd ) );
+
+        CPPUNIT_ASSERT_EQUAL( rMarkArrayTestData.aMarkedRowSegs.size(), aMarkedRowSegs.size() );
+        size_t nIdx = 0;
+        for ( const auto& rPair : rMarkArrayTestData.aMarkedRowSegs )
+        {
+            CPPUNIT_ASSERT_EQUAL( rPair.first, aMarkedRowSegs[nIdx].first );
+            CPPUNIT_ASSERT_EQUAL( rPair.second, aMarkedRowSegs[nIdx].second );
+            ++nIdx;
+        }
+    }
+
+    for ( const auto& rColWithOneMark : rMarksData.aColsWithOneMark )
+    {
+        SCROW nRow1 = -1, nRow2 = -1;
+        CPPUNIT_ASSERT( aMultiSel.HasOneMark( rColWithOneMark.aStart.Col(), nRow1, nRow2 ) );
+        CPPUNIT_ASSERT_EQUAL( rColWithOneMark.aStart.Row(), nRow1 );
+        CPPUNIT_ASSERT_EQUAL( rColWithOneMark.aEnd.Row(), nRow2 );
+    }
+
+    {
+        SCROW nRow1 = -1, nRow2 = -1;
+        for ( const SCCOL& rCol : rMarksData.aColsWithoutOneMark )
+            CPPUNIT_ASSERT( !aMultiSel.HasOneMark( rCol, nRow1, nRow2 ) );
+    }
+
+    for ( const auto& rColAllMarked : rMarksData.aColsAllMarked )
+        CPPUNIT_ASSERT( aMultiSel.IsAllMarked( rColAllMarked.aStart.Col(),
+                                               rColAllMarked.aStart.Row(),
+                                               rColAllMarked.aEnd.Row() ) );
+
+    for ( const auto& rColNotAllMarked : rMarksData.aColsNotAllMarked )
+        CPPUNIT_ASSERT( !aMultiSel.IsAllMarked( rColNotAllMarked.aStart.Col(),
+                                                rColNotAllMarked.aStart.Row(),
+                                                rColNotAllMarked.aEnd.Row() ) );
+
+    for ( const auto& rColsWithEqualMarks : rMarksData.aColsWithEqualMarksList )
+        CPPUNIT_ASSERT( aMultiSel.HasEqualRowsMarked( rColsWithEqualMarks.first, rColsWithEqualMarks.second ) );
+
+    for ( const auto& rColsWithUnequalMarks : rMarksData.aColsWithUnequalMarksList )
+        CPPUNIT_ASSERT( !aMultiSel.HasEqualRowsMarked( rColsWithUnequalMarks.first, rColsWithUnequalMarks.second ) );
+
+    aMultiSel.Clear();
+    CPPUNIT_ASSERT_EQUAL( SCCOL(0), aMultiSel.size() );
+    CPPUNIT_ASSERT( !aMultiSel.HasAnyMarks() );
+}
+
+void Test::testMultiMark_FourRanges()
+{
+    MultiMarkTestData aData;
+    MarkTestData aSingle1;
+
+    // Create rectangle ( 10, 5, 20, 10 )
+    aSingle1.aRange = ScRange( 10, 5, 0, 20, 10, 0 );
+    aSingle1.bMark = true;
+
+    aSingle1.aInsideAddresses.push_back( ScAddress( 15, 6, 0 ) );
+    aSingle1.aInsideAddresses.push_back( ScAddress( 10, 5, 0 ) );
+    aSingle1.aInsideAddresses.push_back( ScAddress( 20, 5, 0 ) );
+    aSingle1.aInsideAddresses.push_back( ScAddress( 10, 10, 0 ) );
+    aSingle1.aInsideAddresses.push_back( ScAddress( 20, 10, 0 ) );
+
+    aSingle1.aOutsideAddresses.push_back( ScAddress( 15, 4, 0 ) );
+    aSingle1.aOutsideAddresses.push_back( ScAddress( 15, 11, 0 ) );
+    aSingle1.aOutsideAddresses.push_back( ScAddress( 9, 6, 0 ) );
+    aSingle1.aOutsideAddresses.push_back( ScAddress( 21, 6, 0 ) );
+    aSingle1.aOutsideAddresses.push_back( ScAddress( 26, 10, 0 ) );
+
+    aSingle1.aColumnsWithoutFullMarks.push_back( 16 );
+    aSingle1.aColumnsWithoutFullMarks.push_back( 21 );
+
+    aSingle1.aRowsWithoutFullMarks.push_back( 7 );
+    aSingle1.aRowsWithoutFullMarks.push_back( 11 );
+
+    aSingle1.aRangesWithFullMarks.push_back( ScRange( 10, 5, 0, 20, 10, 0 ) );
+    aSingle1.aRangesWithFullMarks.push_back( ScRange( 11, 6, 0, 19, 8, 0 ) );
+
+    aSingle1.aRangesWithoutFullMarks.push_back( ScRange( 9, 4, 0, 21, 11, 0 ) );
+    aSingle1.aRangesWithoutFullMarks.push_back( ScRange( 25, 7, 0, 30, 15, 0 ) );
+
+    aSingle1.aNextMarked.push_back( ScRange( 15, 1, 0, 1, 5, 0 ) ); // Search down
+    aSingle1.aNextMarked.push_back( ScRange( 15, 15, 0, 0, 10, 0 ) ); // Search up
+
+    aSingle1.aNextMarked.push_back( ScRange( 15, 15, 0, 1, MAXROWCOUNT, 0 ) ); // Search down fail
+    aSingle1.aNextMarked.push_back( ScRange( 15, 4, 0, 0, -1, 0 ) ); // Search up fail
+
+    aSingle1.aColumnsWithAtLeastOneMark.push_back( 10 );
+    aSingle1.aColumnsWithAtLeastOneMark.push_back( 15 );
+    aSingle1.aColumnsWithAtLeastOneMark.push_back( 20 );
+
+    aSingle1.aColumnsWithoutAnyMarks.push_back( 21 );
+    aSingle1.aColumnsWithoutAnyMarks.push_back( 9 );
+
+    // Create rectangle ( 25, 7, 30, 15 )
+    MarkTestData aSingle2;
+    aSingle2.aRange = ScRange( 25, 7, 0, 30, 15, 0 );
+    aSingle2.bMark = true;
+
+    aSingle2.aInsideAddresses = aSingle1.aInsideAddresses;
+    aSingle2.aInsideAddresses.push_back( ScAddress( 27, 10, 0 ) );
+    aSingle2.aInsideAddresses.push_back( ScAddress( 25, 7, 0 ) );
+    aSingle2.aInsideAddresses.push_back( ScAddress( 30, 7, 0 ) );
+    aSingle2.aInsideAddresses.push_back( ScAddress( 25, 15, 0 ) );
+    aSingle2.aInsideAddresses.push_back( ScAddress( 30, 15, 0 ) );
+
+    aSingle2.aOutsideAddresses.push_back( ScAddress( 15, 4, 0 ) );
+    aSingle2.aOutsideAddresses.push_back( ScAddress( 15, 11, 0 ) );
+    aSingle2.aOutsideAddresses.push_back( ScAddress( 9, 6, 0 ) );
+    aSingle2.aOutsideAddresses.push_back( ScAddress( 21, 6, 0 ) );
+    aSingle2.aOutsideAddresses.push_back( ScAddress( 26, 6, 0 ) );
+    aSingle2.aOutsideAddresses.push_back( ScAddress( 26, 16, 0 ) );
+    aSingle2.aOutsideAddresses.push_back( ScAddress( 24, 8, 0 ) );
+    aSingle2.aOutsideAddresses.push_back( ScAddress( 31, 11, 0 ) );
+
+    aSingle2.aColumnsWithoutFullMarks = aSingle1.aColumnsWithoutAnyMarks;
+
+    aSingle2.aRowsWithoutFullMarks = aSingle1.aRowsWithoutFullMarks;
+
+    aSingle2.aRangesWithFullMarks = aSingle1.aRangesWithFullMarks;
+    aSingle2.aRangesWithFullMarks.push_back( ScRange( 25, 7, 0, 30, 15, 0 ) );
+    aSingle2.aRangesWithFullMarks.push_back( ScRange( 26, 8, 0, 29, 14, 0 ) );
+
+    aSingle2.aRangesWithoutFullMarks.push_back( ScRange( 9, 4, 0, 21, 11, 0 ) );
+    aSingle2.aRangesWithoutFullMarks.push_back( ScRange( 24, 6, 0, 31, 16, 0 ) );
+    aSingle2.aRangesWithoutFullMarks.push_back( ScRange( 10, 5, 0, 30, 15, 0 ) );
+
+    aSingle2.aNextMarked.push_back( ScRange( 27, 16, 0, 0, 15, 0 ) );  // up ok
+    aSingle2.aNextMarked.push_back( ScRange( 27, 4, 0, 1, 7, 0 ) );  // down ok
+    aSingle2.aNextMarked.push_back( ScRange( 27, 4, 0, 0, -1, 0 ) );  // up fail
+    aSingle2.aNextMarked.push_back( ScRange( 27, 16, 0, 1, MAXROWCOUNT, 0 ) );  // down fail
+
+    aSingle2.aColumnsWithAtLeastOneMark = aSingle1.aColumnsWithAtLeastOneMark;
+    aSingle2.aColumnsWithAtLeastOneMark.push_back( 25 );
+    aSingle2.aColumnsWithAtLeastOneMark.push_back( 27 );
+    aSingle2.aColumnsWithAtLeastOneMark.push_back( 30 );
+
+    aSingle2.aColumnsWithoutAnyMarks.push_back( 9 );
+    aSingle2.aColumnsWithoutAnyMarks.push_back( 21 );
+    aSingle2.aColumnsWithoutAnyMarks.push_back( 24 );
+    aSingle2.aColumnsWithoutAnyMarks.push_back( 31 );
+
+    // Full row = 20
+    MarkTestData aSingle3;
+
+    aSingle3.aRange = ScRange( 0, 20, 0, MAXCOL, 20, 0 );
+    aSingle3.bMark = true;
+
+    aSingle3.aInsideAddresses = aSingle2.aInsideAddresses;
+    aSingle3.aInsideAddresses.push_back( ScAddress( 5, 20, 0 ) );
+    aSingle3.aInsideAddresses.push_back( ScAddress( 100, 20, 0 ) );
+
+    aSingle3.aOutsideAddresses.push_back( ScAddress( 0, 21, 0 ) );
+    aSingle3.aOutsideAddresses.push_back( ScAddress( 27, 19, 0 ) );
+
+    aSingle3.aColumnsWithoutFullMarks = aSingle2.aColumnsWithoutAnyMarks;
+
+    aSingle3.aRowsWithFullMarks.push_back( 20 );
+
+    aSingle3.aRangesWithFullMarks = aSingle2.aRangesWithFullMarks;
+    aSingle3.aRangesWithFullMarks.push_back( ScRange( 0, 20, 0, MAXCOL, 20, 0 ) );
+    aSingle3.aRangesWithFullMarks.push_back( ScRange( 15, 20, 0, 55, 20, 0 ) );
+
+    aSingle3.aNextMarked.push_back( ScRange( 15, 16, 0, 0, 10, 0 ) );  // up ok
+    aSingle3.aNextMarked.push_back( ScRange( 15, 16, 0, 1, 20, 0 ) );  // down ok
+    aSingle3.aNextMarked.push_back( ScRange( 22, 15, 0, 0, -1, 0 ) );  // up fail
+    aSingle3.aNextMarked.push_back( ScRange( 22, 25, 0, 1, MAXROWCOUNT, 0 ) );  // down fail
+
+    aSingle3.aColumnsWithAtLeastOneMark = aSingle2.aColumnsWithAtLeastOneMark;
+    aSingle3.aColumnsWithAtLeastOneMark.push_back( 39 );
+
+    // Full col = 35
+    MarkTestData aSingle4;
+
+    aSingle4.aRange = ScRange( 35, 0, 0, 35, MAXROW, 0 );
+    aSingle4.bMark = true;
+
+    aSingle4.aInsideAddresses = aSingle3.aInsideAddresses;
+    aSingle4.aInsideAddresses.push_back( ScAddress( 35, 10, 0 ) );
+    aSingle4.aInsideAddresses.push_back( ScAddress( 35, 25, 0 ) );
+
+    aSingle4.aOutsideAddresses.push_back( ScAddress( 33, 10, 0 ) );
+    aSingle4.aOutsideAddresses.push_back( ScAddress( 39, 10, 0 ) );
+    aSingle4.aOutsideAddresses.push_back( ScAddress( 33, 25, 0 ) );
+    aSingle4.aOutsideAddresses.push_back( ScAddress( 39, 25, 0 ) );
+
+    aSingle4.aColumnsWithFullMarks.push_back( 35 );
+
+    aSingle4.aRowsWithFullMarks.push_back( 20 );
+
+    aSingle4.aRangesWithFullMarks = aSingle3.aRangesWithFullMarks;
+    aSingle4.aRangesWithFullMarks.push_back( ScRange( 35, 0, 0, 35, MAXROW, 0 ) );
+    aSingle4.aRangesWithFullMarks.push_back( ScRange( 35, 10, 0, 35, 25, 0 ) );
+
+    // Add the rectangle data to aData
+    aData.aMarks.push_back( aSingle1 );
+    aData.aMarks.push_back( aSingle2 );
+    aData.aMarks.push_back( aSingle3 );
+    aData.aMarks.push_back( aSingle4 );
+
+    aData.aSelectionCover = ScRange( 0, 0, 0, MAXCOL, MAXROW, 0 );
+    aData.aLeftEnvelope.Append( ScRange( 9, 5, 0, 9, 10, 0 ) );
+    aData.aLeftEnvelope.Append( ScRange( 24, 7, 0, 24, 15, 0 ) );
+    aData.aLeftEnvelope.Append( ScRange( 34, 0, 0, 34, 19, 0 ) );
+    aData.aLeftEnvelope.Append( ScRange( 34, 21, 0, 34, MAXROW, 0 ) );
+
+    aData.aRightEnvelope.Append( ScRange( 21, 5, 0, 21, 10, 0 ) );
+    aData.aRightEnvelope.Append( ScRange( 31, 7, 0, 31, 15, 0 ) );
+    aData.aRightEnvelope.Append( ScRange( 36, 0, 0, 36, 19, 0 ) );
+    aData.aRightEnvelope.Append( ScRange( 36, 21, 0, 36, MAXROW, 0 ) );
+
+    aData.aTopEnvelope.Append( ScRange( 10, 4, 0, 20, 4, 0 ) );
+    aData.aTopEnvelope.Append( ScRange( 25, 6, 0, 30, 6, 0 ) );
+    aData.aTopEnvelope.Append( ScRange( 0, 19, 0, 34, 19, 0 ) );
+    aData.aTopEnvelope.Append( ScRange( 36, 19, 0, MAXCOL, 19, 0 ) );
+
+    aData.aBottomEnvelope.Append( ScRange( 10, 11, 0, 20, 11, 0 ) );
+    aData.aBottomEnvelope.Append( ScRange( 25, 16, 0, 30, 16, 0 ) );
+    aData.aBottomEnvelope.Append( ScRange( 0, 21, 0, 34, 21, 0 ) );
+    aData.aBottomEnvelope.Append( ScRange( 36, 21, 0, MAXCOL, 21, 0 ) );
+
+    MarkArrayTestData aMarkArrayTestData1;
+    aMarkArrayTestData1.nCol = 5;
+    aMarkArrayTestData1.aMarkedRowSegs.push_back( std::pair<SCROW, SCROW>( 20, 20 ) );
+
+    MarkArrayTestData aMarkArrayTestData2;
+    aMarkArrayTestData2.nCol = 15;
+    aMarkArrayTestData2.aMarkedRowSegs.push_back( std::pair<SCROW, SCROW>( 5, 10 ) );
+    aMarkArrayTestData2.aMarkedRowSegs.push_back( std::pair<SCROW, SCROW>( 20, 20 ) );
+
+    MarkArrayTestData aMarkArrayTestData3;
+    aMarkArrayTestData3.nCol = 22;
+    aMarkArrayTestData3.aMarkedRowSegs.push_back( std::pair<SCROW, SCROW>( 20, 20 ) );
+
+    MarkArrayTestData aMarkArrayTestData4;
+    aMarkArrayTestData4.nCol = 27;
+    aMarkArrayTestData4.aMarkedRowSegs.push_back( std::pair<SCROW, SCROW>( 7, 15 ) );
+    aMarkArrayTestData4.aMarkedRowSegs.push_back( std::pair<SCROW, SCROW>( 20, 20 ) );
+
+    MarkArrayTestData aMarkArrayTestData5;
+    aMarkArrayTestData5.nCol = 33;
+    aMarkArrayTestData5.aMarkedRowSegs.push_back( std::pair<SCROW, SCROW>( 20, 20 ) );
+
+    MarkArrayTestData aMarkArrayTestData6;
+    aMarkArrayTestData6.nCol = 35;
+    aMarkArrayTestData6.aMarkedRowSegs.push_back( std::pair<SCROW, SCROW>( 0, MAXROW ) );
+
+    MarkArrayTestData aMarkArrayTestData7;
+    aMarkArrayTestData7.nCol = 40;
+    aMarkArrayTestData7.aMarkedRowSegs.push_back( std::pair<SCROW, SCROW>( 20, 20 ) );
+
+    aData.aMarkArrays.push_back( aMarkArrayTestData1 );
+    aData.aMarkArrays.push_back( aMarkArrayTestData2 );
+    aData.aMarkArrays.push_back( aMarkArrayTestData3 );
+    aData.aMarkArrays.push_back( aMarkArrayTestData4 );
+    aData.aMarkArrays.push_back( aMarkArrayTestData5 );
+    aData.aMarkArrays.push_back( aMarkArrayTestData6 );
+    aData.aMarkArrays.push_back( aMarkArrayTestData7 );
+
+    aData.aColsWithOneMark.push_back( ScRange( 5, 20, 0, 0, 20, 0 ) );
+    aData.aColsWithOneMark.push_back( ScRange( 22, 20, 0, 0, 20, 0 ) );
+    aData.aColsWithOneMark.push_back( ScRange( 32, 20, 0, 0, 20, 0 ) );
+    aData.aColsWithOneMark.push_back( ScRange( 35, 0, 0, 0, MAXROW, 0 ) );
+    aData.aColsWithOneMark.push_back( ScRange( 50, 20, 0, 0, 20, 0 ) );
+
+    aData.aColsWithoutOneMark.push_back( 10 );
+    aData.aColsWithoutOneMark.push_back( 15 );
+    aData.aColsWithoutOneMark.push_back( 20 );
+    aData.aColsWithoutOneMark.push_back( 25 );
+    aData.aColsWithoutOneMark.push_back( 30 );
+
+    aData.aColsAllMarked.push_back( ScRange( 10, 5, 0, 0, 10, 0 ) );
+    aData.aColsAllMarked.push_back( ScRange( 15, 5, 0, 0, 10, 0 ) );
+    aData.aColsAllMarked.push_back( ScRange( 5, 20, 0, 0, 20, 0 ) );
+    aData.aColsAllMarked.push_back( ScRange( 10, 20, 0, 0, 20, 0 ) );
+    aData.aColsAllMarked.push_back( ScRange( 25, 7, 0, 0, 15, 0 ) );
+    aData.aColsAllMarked.push_back( ScRange( 30, 7, 0, 0, 15, 0 ) );
+    aData.aColsAllMarked.push_back( ScRange( 35, 0, 0, 0, MAXROW, 0 ) );
+    aData.aColsAllMarked.push_back( ScRange( 100, 20, 0, 0, 20, 0 ) );
+
+    aData.aColsNotAllMarked.push_back( ScRange( 5, 5, 0, 0, 25, 0 ) );
+    aData.aColsNotAllMarked.push_back( ScRange( 15, 5, 0, 0, 25, 0 ) );
+    aData.aColsNotAllMarked.push_back( ScRange( 22, 15, 0, 0, 25, 0 ) );
+    aData.aColsNotAllMarked.push_back( ScRange( 27, 7, 0, 0, 20, 0 ) );
+    aData.aColsNotAllMarked.push_back( ScRange( 100, 19, 0, 0, 21, 0 ) );
+
+    aData.aColsWithEqualMarksList.push_back( std::pair<SCCOL,SCCOL>( 0, 9 ) );
+    aData.aColsWithEqualMarksList.push_back( std::pair<SCCOL,SCCOL>( 10, 20 ) );
+    aData.aColsWithEqualMarksList.push_back( std::pair<SCCOL,SCCOL>( 21, 24 ) );
+    aData.aColsWithEqualMarksList.push_back( std::pair<SCCOL,SCCOL>( 25, 30 ) );
+    aData.aColsWithEqualMarksList.push_back( std::pair<SCCOL,SCCOL>( 31, 34 ) );
+    aData.aColsWithEqualMarksList.push_back( std::pair<SCCOL,SCCOL>( 36, 100 ) );
+    aData.aColsWithEqualMarksList.push_back( std::pair<SCCOL,SCCOL>( 0, 22 ) );
+    aData.aColsWithEqualMarksList.push_back( std::pair<SCCOL,SCCOL>( 0, 34 ) );
+
+    aData.aColsWithUnequalMarksList.push_back( std::pair<SCCOL,SCCOL>( 0, 10 ) );
+    aData.aColsWithUnequalMarksList.push_back( std::pair<SCCOL,SCCOL>( 0, 20 ) );
+    aData.aColsWithUnequalMarksList.push_back( std::pair<SCCOL,SCCOL>( 10, 21 ) );
+    aData.aColsWithUnequalMarksList.push_back( std::pair<SCCOL,SCCOL>( 20, 25 ) );
+    aData.aColsWithUnequalMarksList.push_back( std::pair<SCCOL,SCCOL>( 20, 30 ) );
+    aData.aColsWithUnequalMarksList.push_back( std::pair<SCCOL,SCCOL>( 24, 30 ) );
+    aData.aColsWithUnequalMarksList.push_back( std::pair<SCCOL,SCCOL>( 30, 31 ) );
+    aData.aColsWithUnequalMarksList.push_back( std::pair<SCCOL,SCCOL>( 30, 34 ) );
+    aData.aColsWithUnequalMarksList.push_back( std::pair<SCCOL,SCCOL>( 30, 35 ) );
+    aData.aColsWithUnequalMarksList.push_back( std::pair<SCCOL,SCCOL>( 35, 100 ) );
+
+    testMultiMark( aData );
+}
+
+void Test::testMultiMark_NegativeMarking()
+{
+    MultiMarkTestData aData;
+
+    // Create full row = 5
+    MarkTestData aSingle1;
+    aSingle1.aRange = ScRange( 0, 5, 0, MAXCOL, 5, 0 );
+    aSingle1.bMark = true;
+
+    // Create rectangle ( 10, 8, 25, 20 )
+    MarkTestData aSingle2;
+    aSingle2.aRange = ScRange( 10, 8, 0, 25, 20, 0 );
+    aSingle2.bMark = true;
+
+    // Create full row = 12
+    MarkTestData aSingle3;
+    aSingle3.aRange = ScRange( 0, 12, 0, MAXCOL, 12, 0 );
+    aSingle3.bMark = true;
+
+    // Create deselection rectangle ( 17, 5, 20, 5 )
+    MarkTestData aSingle4;
+    aSingle4.aRange = ScRange( 17, 5, 0, 20, 5, 0 );
+    aSingle4.bMark = false;
+
+    aSingle4.aInsideAddresses.push_back( ScAddress( 6, 5, 0 ) );
+    aSingle4.aInsideAddresses.push_back( ScAddress( 30, 5, 0 ) );
+    aSingle4.aInsideAddresses.push_back( ScAddress( 6, 12, 0 ) );
+    aSingle4.aInsideAddresses.push_back( ScAddress( 30, 12, 0 ) );
+    aSingle4.aInsideAddresses.push_back( ScAddress( 13, 14, 0 ) );
+    aSingle4.aInsideAddresses.push_back( ScAddress( 16, 12, 0 ) );
+
+    aSingle4.aOutsideAddresses.push_back( ScAddress( 5, 2, 0 ) );
+    aSingle4.aOutsideAddresses.push_back( ScAddress( 18, 5, 0 ) );
+    aSingle4.aOutsideAddresses.push_back( ScAddress( 17, 5, 0 ) );
+    aSingle4.aOutsideAddresses.push_back( ScAddress( 20, 5, 0 ) );
+    aSingle4.aOutsideAddresses.push_back( ScAddress( 18, 7, 0 ) );
+    aSingle4.aOutsideAddresses.push_back( ScAddress( 5, 10, 0 ) );
+    aSingle4.aOutsideAddresses.push_back( ScAddress( 30, 10, 0 ) );
+    aSingle4.aOutsideAddresses.push_back( ScAddress( 5, 14, 0 ) );
+    aSingle4.aOutsideAddresses.push_back( ScAddress( 30, 14, 0 ) );
+    aSingle4.aOutsideAddresses.push_back( ScAddress( 18, 25, 0 ) );
+
+    aSingle4.aRowsWithFullMarks.push_back( 12 );
+
+    aSingle4.aRowsWithoutFullMarks.push_back( 5 );
+
+    aSingle4.aRangesWithFullMarks.push_back( ScRange( 5, 5, 0, 16, 5, 0 ) );
+    aSingle4.aRangesWithFullMarks.push_back( ScRange( 21, 5, 0, 30, 5, 0 ) );
+    aSingle4.aRangesWithFullMarks.push_back( ScRange( 5, 12, 0, 9, 12, 0 ) );
+    aSingle4.aRangesWithFullMarks.push_back( ScRange( 26, 12, 0, 30, 12, 0 ) );
+    aSingle4.aRangesWithFullMarks.push_back( ScRange( 10, 8, 0, 25, 20, 0 ) );
+
+    aSingle4.aRangesWithoutFullMarks.push_back( ScRange( 10, 5, 0, 25, 5, 0 ) );
+
+    aSingle4.aNextMarked.push_back( ScRange( 18, 7, 0, 0, -1, 0 ) ); // up fail
+    aSingle4.aNextMarked.push_back( ScRange( 18, 4, 0, 1, 8, 0 ) ); // down ok
+
+    // Create deselection rectangle ( 15, 10, 18, 14 )
+    MarkTestData aSingle5;
+    aSingle5.aRange = ScRange( 15, 10, 0, 18, 14, 0 );
+    aSingle5.bMark = false;
+
+    aSingle5.aInsideAddresses.push_back( ScAddress( 6, 5, 0 ) );
+    aSingle5.aInsideAddresses.push_back( ScAddress( 30, 5, 0 ) );
+    aSingle5.aInsideAddresses.push_back( ScAddress( 6, 12, 0 ) );
+    aSingle5.aInsideAddresses.push_back( ScAddress( 30, 12, 0 ) );
+    aSingle5.aInsideAddresses.push_back( ScAddress( 13, 14, 0 ) );
+
+    aSingle5.aOutsideAddresses = aSingle4.aOutsideAddresses;
+    aSingle5.aOutsideAddresses.push_back( ScAddress( 17, 12, 0 ) );
+    aSingle5.aOutsideAddresses.push_back( ScAddress( 15, 10, 0 ) );
+    aSingle5.aOutsideAddresses.push_back( ScAddress( 18, 10, 0 ) );
+    aSingle5.aOutsideAddresses.push_back( ScAddress( 15, 14, 0 ) );
+    aSingle5.aOutsideAddresses.push_back( ScAddress( 18, 14, 0 ) );
+
+    aSingle5.aRowsWithoutFullMarks.push_back( 12 );
+    aSingle5.aRowsWithoutFullMarks.push_back( 5 );
+
+    aSingle5.aRangesWithoutFullMarks.push_back( ScRange( 10, 8, 0, 25, 20, 0 ) );
+
+    aSingle5.aNextMarked = aSingle4.aNextMarked;
+    aSingle5.aNextMarked.push_back( ScRange( 17, 12, 0, 0, 9, 0 ) ); // up ok
+    aSingle5.aNextMarked.push_back( ScRange( 17, 12, 0, 1, 15, 0 ) ); // down ok
+
+    // Add the rectangle data to aData
+    aData.aMarks.push_back( aSingle1 );
+    aData.aMarks.push_back( aSingle2 );
+    aData.aMarks.push_back( aSingle3 );
+    aData.aMarks.push_back( aSingle4 );
+    aData.aMarks.push_back( aSingle5 );
+
+    aData.aSelectionCover = ScRange( 0, 4, 0, MAXCOL, 21, 0 );
+    aData.aLeftEnvelope.Append( ScRange( 9, 8, 0, 9, 11, 0 ) );
+    aData.aLeftEnvelope.Append( ScRange( 9, 13, 0, 9, 20, 0 ) );
+    aData.aLeftEnvelope.Append( ScRange( 18, 10, 0, 18, 14, 0 ) );
+    aData.aLeftEnvelope.Append( ScRange( 20, 5, 0, 20, 5, 0 ) );
+
+    aData.aRightEnvelope.Append( ScRange( 17, 5, 0, 17, 5, 0 ) );
+    aData.aRightEnvelope.Append( ScRange( 15, 10, 0, 15, 14, 0 ) );
+    aData.aRightEnvelope.Append( ScRange( 26, 8, 0, 26, 11, 0 ) );
+    aData.aRightEnvelope.Append( ScRange( 26, 13, 0, 26, 20, 0 ) );
+
+    aData.aTopEnvelope.Append( ScRange( 0, 4, 0, 16, 4, 0 ) );
+    aData.aTopEnvelope.Append( ScRange( 21, 4, 0, MAXCOL, 4, 0 ) );
+    aData.aTopEnvelope.Append( ScRange( 10, 7, 0, 25, 7, 0 ) );
+    aData.aTopEnvelope.Append( ScRange( 0, 11, 0, 9, 11, 0 ) );
+    aData.aTopEnvelope.Append( ScRange( 26, 11, 0, MAXCOL, 11, 0 ) );
+    aData.aTopEnvelope.Append( ScRange( 15, 14, 0, 18, 14, 0 ) );
+
+    aData.aBottomEnvelope.Append( ScRange( 0, 6, 0, 16, 6, 0 ) );
+    aData.aBottomEnvelope.Append( ScRange( 21, 6, 0, MAXCOL, 6, 0 ) );
+    aData.aBottomEnvelope.Append( ScRange( 15, 10, 0, 18, 10, 0 ) );
+    aData.aBottomEnvelope.Append( ScRange( 0, 13, 0, 9, 13, 0 ) );
+    aData.aBottomEnvelope.Append( ScRange( 26, 13, 0, MAXCOL, 13, 0 ) );
+    aData.aBottomEnvelope.Append( ScRange( 10, 21, 0, 25, 21, 0 ) );
+
+    aData.aColsWithOneMark.push_back( ScRange( 19, 8, 0, 0, 20, 0 ) );
+    aData.aColsWithOneMark.push_back( ScRange( 20, 8, 0, 0, 20, 0 ) );
+
+    aData.aColsWithoutOneMark.push_back( 5 );
+    aData.aColsWithoutOneMark.push_back( 10 );
+    aData.aColsWithoutOneMark.push_back( 12 );
+    aData.aColsWithoutOneMark.push_back( 16 );
+    aData.aColsWithoutOneMark.push_back( 17 );
+    aData.aColsWithoutOneMark.push_back( 24 );
+    aData.aColsWithoutOneMark.push_back( 100 );
+
+    aData.aColsAllMarked.push_back( ScRange( 10, 8, 0, 0, 20, 0 ) );
+    aData.aColsAllMarked.push_back( ScRange( 17, 8, 0, 0, 9, 0 ) );
+    aData.aColsAllMarked.push_back( ScRange( 20, 8, 0, 0, 20, 0 ) );
+    aData.aColsAllMarked.push_back( ScRange( 100, 5, 0, 0, 5, 0 ) );
+    aData.aColsAllMarked.push_back( ScRange( 100, 12, 0, 0, 12, 0 ) );
+
+    aData.aColsNotAllMarked.push_back( ScRange( 5, 5, 0, 0, 12, 0 ) );
+    aData.aColsNotAllMarked.push_back( ScRange( 10, 5, 0, 0, 20, 0 ) );
+    aData.aColsNotAllMarked.push_back( ScRange( 15, 8, 0, 0, 20, 0 ) );
+    aData.aColsNotAllMarked.push_back( ScRange( 18, 8, 0, 0, 20, 0 ) );
+    aData.aColsNotAllMarked.push_back( ScRange( 25, 5, 0, 0, 20, 0 ) );
+
+    aData.aColsWithEqualMarksList.push_back( std::pair<SCCOL,SCCOL>( 0, 9 ) );
+    aData.aColsWithEqualMarksList.push_back( std::pair<SCCOL,SCCOL>( 10, 14 ) );
+    aData.aColsWithEqualMarksList.push_back( std::pair<SCCOL,SCCOL>( 15, 16 ) );
+    aData.aColsWithEqualMarksList.push_back( std::pair<SCCOL,SCCOL>( 17, 18 ) );
+    aData.aColsWithEqualMarksList.push_back( std::pair<SCCOL,SCCOL>( 19, 20 ) );
+    aData.aColsWithEqualMarksList.push_back( std::pair<SCCOL,SCCOL>( 21, 25 ) );
+    aData.aColsWithEqualMarksList.push_back( std::pair<SCCOL,SCCOL>( 26, 100 ) );
+    aData.aColsWithEqualMarksList.push_back( std::pair<SCCOL,SCCOL>( 0, 100 ) );
+
+    aData.aColsWithUnequalMarksList.push_back( std::pair<SCCOL,SCCOL>( 0, 10 ) );
+    aData.aColsWithUnequalMarksList.push_back( std::pair<SCCOL,SCCOL>( 10, 15 ) );
+    aData.aColsWithUnequalMarksList.push_back( std::pair<SCCOL,SCCOL>( 15, 17 ) );
+    aData.aColsWithUnequalMarksList.push_back( std::pair<SCCOL,SCCOL>( 17, 19 ) );
+    aData.aColsWithUnequalMarksList.push_back( std::pair<SCCOL,SCCOL>( 19, 21 ) );
+    aData.aColsWithUnequalMarksList.push_back( std::pair<SCCOL,SCCOL>( 21, 26 ) );
+
+    testMultiMark( aData );
+}
+
+
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Test);
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list