/* -*- 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 #include #include #include #include #include #include #if defined __GNUC__ && !defined __clang__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsubobject-linkage" // automatically suppressed in the main .cxx, but not in this included one #endif #include "../../source/core/data/segmenttree.cxx" #if defined __GNUC__ && !defined __clang__ #pragma GCC diagnostic push #endif #include namespace { struct MarkTestData // To represent a single rectangle part of a multiselection { ScRange aRange; bool bMark; // Cumulative Test data follows std::vector aInsideAddresses; std::vector aOutsideAddresses; std::vector aColumnsWithFullMarks; std::vector aColumnsWithoutFullMarks; std::vector aRowsWithFullMarks; std::vector aRowsWithoutFullMarks; std::vector aRangesWithFullMarks; std::vector 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 aNextMarked; std::vector aColumnsWithAtLeastOneMark; std::vector aColumnsWithoutAnyMarks; }; struct MarkArrayTestData { SCCOL nCol; std::vector> aMarkedRowSegs; }; struct MultiMarkTestData { std::vector aMarks; ScRange aSelectionCover; ScRangeList aLeftEnvelope; ScRangeList aRightEnvelope; ScRangeList aTopEnvelope; ScRangeList aBottomEnvelope; std::vector aMarkArrays; // To test ScMultiSel::HasOneMark() // Encoding : StartCol is the column to test, StartRow is the beginning of the one mark, // EndRow is the end of the one mark, EndCol is not used std::vector aColsWithOneMark; std::vector aColsWithoutOneMark; // To test ScMultiSel::IsAllMarked() // Encoding StartCol is the column to be queried, [StartRow,EndRow] is the range to test. std::vector aColsAllMarked; std::vector aColsNotAllMarked; // To test ScMultiSel::HasEqualRowsMarked() std::vector> aColsWithEqualMarksList; std::vector> aColsWithUnequalMarksList; }; } class Test : public CppUnit::TestFixture { public: void testSimpleMark( const ScRange& rRange, const ScRange& rSelectionCover, const ScRangeList& rLeftEnvelope, const ScRangeList& rRightEnvelope, const ScRangeList& rTopEnvelope, const ScRangeList& rBottomEnvelope, const ScSheetLimits& rLimits ); void testSimpleMark_Simple(); void testSimpleMark_Column(); void testSimpleMark_Row(); void testMultiMark( const MultiMarkTestData& rData ); void testMultiMark_FourRanges(); void testMultiMark_NegativeMarking(); void testInsertTabBeforeSelected(); void testInsertTabAfterSelected(); void testDeleteTabBeforeSelected(); void testDeleteTabAfterSelected(); void testScMarkArraySearch(); void testIsAllMarked(); 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(testInsertTabBeforeSelected); CPPUNIT_TEST(testInsertTabAfterSelected); CPPUNIT_TEST(testDeleteTabBeforeSelected); CPPUNIT_TEST(testDeleteTabAfterSelected); CPPUNIT_TEST(testScMarkArraySearch); CPPUNIT_TEST(testIsAllMarked); CPPUNIT_TEST_SUITE_END(); private: void testScMarkArraySearch_check(const ScMarkArray & ar, SCROW nRow, bool expectStatus, SCSIZE nIndexExpect); }; static void lcl_GetSortedRanges( const ScRangeList& rRangeList, ScRangeList& rRangeListOut ) { rRangeListOut.RemoveAll(); std::vector 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.push_back( aRanges[nIdx] ); } void Test::testSimpleMark( const ScRange& rRange, const ScRange& rSelectionCover, const ScRangeList& rLeftEnvelope, const ScRangeList& rRightEnvelope, const ScRangeList& rTopEnvelope, const ScRangeList& rBottomEnvelope, const ScSheetLimits& rLimits ) { ScMarkData aMark(rLimits); CPPUNIT_ASSERT( !aMark.IsMarked() ); CPPUNIT_ASSERT( !aMark.IsMultiMarked() ); aMark.SetMarkArea( rRange ); CPPUNIT_ASSERT( aMark.IsMarked() ); CPPUNIT_ASSERT( !aMark.IsMultiMarked() ); CPPUNIT_ASSERT_EQUAL( rRange, aMark.GetMarkArea() ); 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, rLimits.MaxCol() ) && ValidRow( nOutRow1, rLimits.MaxRow() ) ) CPPUNIT_ASSERT( !aMark.IsCellMarked( nOutCol1, nOutRow1 ) ); if ( ValidCol( nOutCol2, rLimits.MaxCol() ) && ValidRow( nOutRow2, rLimits.MaxRow() ) ) CPPUNIT_ASSERT( !aMark.IsCellMarked( nOutCol2, nOutRow2 ) ); if ( ValidRow( nOutRow1, rLimits.MaxRow() ) ) CPPUNIT_ASSERT( !aMark.IsCellMarked( nMidCol, nOutRow1 ) ); if ( ValidCol( nOutCol1, rLimits.MaxCol() ) ) CPPUNIT_ASSERT( !aMark.IsCellMarked( nOutCol1, nMidRow ) ); if ( ValidRow( nOutRow2, rLimits.MaxRow() ) ) CPPUNIT_ASSERT( !aMark.IsCellMarked( nMidCol, nOutRow2 ) ); if ( ValidCol( nOutCol2, rLimits.MaxCol() ) ) CPPUNIT_ASSERT( !aMark.IsCellMarked( nOutCol2, nMidRow ) ); if ( rRange.aStart.Row() == 0 && rRange.aEnd.Row() == rLimits.MaxRow() ) CPPUNIT_ASSERT( aMark.IsColumnMarked( nMidCol ) ); else CPPUNIT_ASSERT( !aMark.IsColumnMarked( nMidCol ) ); if ( rRange.aStart.Col() == 0 && rRange.aEnd.Col() == rLimits.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() { ScSheetLimits limits( ScSheetLimits::CreateDefault()); 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 limits ); } void Test::testSimpleMark_Column() { ScSheetLimits limits( ScSheetLimits::CreateDefault()); // 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 limits ); // Full Column 10 testSimpleMark( ScRange( 10, 0, 0, 10, limits.MaxRow(), 0 ), // Simple range ScRange( 9, 0, 0, 11, limits.MaxRow(), 0 ), // Cover ScRangeList( ScRange( 9, 0, 0, 9, limits.MaxRow(), 0 ) ), // Left envelope ScRangeList( ScRange( 11, 0, 0, 11, limits.MaxRow(), 0 ) ), // Right envelope ScRangeList(), // Top envelope ScRangeList(), // Bottom envelope limits ); } void Test::testSimpleMark_Row() { ScSheetLimits limits( ScSheetLimits::CreateDefault()); // 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 limits ); // Full Row 15 testSimpleMark( ScRange( 0, 15, 0, limits.MaxCol(), 15, 0 ), // Simple range ScRange( 0, 14, 0, limits.MaxCol(), 16, 0 ), // Cover ScRangeList(), // Left envelope ScRangeList(), // Right envelope ScRangeList( ScRange( 0, 14, 0, limits.MaxCol(), 14, 0 ) ), // Top envelope ScRangeList( ScRange( 0, 16, 0, limits.MaxCol(), 16, 0 ) ), // Bottom envelope limits ); } void Test::testMultiMark( const MultiMarkTestData& rMarksData ) { ScSheetLimits limits( ScSheetLimits::CreateDefault()); ScMarkData aMark(limits); ScMultiSel aMultiSel(limits); CPPUNIT_ASSERT( !aMark.IsMarked() ); CPPUNIT_ASSERT( !aMark.IsMultiMarked() ); CPPUNIT_ASSERT_EQUAL( SCCOL(0), aMultiSel.GetMultiSelectionCount() ); 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, limits.MaxRow() ) ); } for ( const auto& rCol : rAreaTestData.aColumnsWithoutFullMarks ) { CPPUNIT_ASSERT( !aMark.IsColumnMarked( rCol ) ); CPPUNIT_ASSERT( !aMultiSel.IsAllMarked( rCol, 0, limits.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 ( SCCOL 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 ) { SCROW nNextRow1 = aMark.GetNextMarked( rRange.aStart.Col(), rRange.aStart.Row(), !static_cast(rRange.aEnd.Col()) ); CPPUNIT_ASSERT_EQUAL( rRange.aEnd.Row(), nNextRow1 ); SCROW nNextRow2 = aMultiSel.GetNextMarked( rRange.aStart.Col(), rRange.aStart.Row(), !static_cast(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> aMarkedRowSegs; ScMarkArrayIter aIter( &aArray ); SCROW nStart, nEnd; while ( aIter.Next( nStart, nEnd ) ) aMarkedRowSegs.emplace_back( 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.GetMultiSelectionCount() ); CPPUNIT_ASSERT( !aMultiSel.HasAnyMarks() ); } void Test::testMultiMark_FourRanges() { ScSheetLimits limits( ScSheetLimits::CreateDefault()); MultiMarkTestData aData; MarkTestData aSingle1; // Create rectangle ( 10, 5, 20, 10 ) aSingle1.aRange = ScRange( 10, 5, 0, 20, 10, 0 ); aSingle1.bMark = true; aSingle1.aInsideAddresses.emplace_back( 15, 6, 0 ); aSingle1.aInsideAddresses.emplace_back( 10, 5, 0 ); aSingle1.aInsideAddresses.emplace_back( 20, 5, 0 ); aSingle1.aInsideAddresses.emplace_back( 10, 10, 0 ); aSingle1.aInsideAddresses.emplace_back( 20, 10, 0 ); aSingle1.aOutsideAddresses.emplace_back( 15, 4, 0 ); aSingle1.aOutsideAddresses.emplace_back( 15, 11, 0 ); aSingle1.aOutsideAddresses.emplace_back( 9, 6, 0 ); aSingle1.aOutsideAddresses.emplace_back( 21, 6, 0 ); aSingle1.aOutsideAddresses.emplace_back( 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.emplace_back( 10, 5, 0, 20, 10, 0 ); aSingle1.aRangesWithFullMarks.emplace_back( 11, 6, 0, 19, 8, 0 ); aSingle1.aRangesWithoutFullMarks.emplace_back( 9, 4, 0, 21, 11, 0 ); aSingle1.aRangesWithoutFullMarks.emplace_back( 25, 7, 0, 30, 15, 0 ); aSingle1.aNextMarked.emplace_back( 15, 1, 0, 1, 5, 0 ); // Search down aSingle1.aNextMarked.emplace_back( 15, 15, 0, 0, 10, 0 ); // Search up aSingle1.aNextMarked.emplace_back( 15, 15, 0, 1, limits.GetMaxRowCount(), 0 ); // Search down fail aSingle1.aNextMarked.emplace_back( 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.emplace_back( 27, 10, 0 ); aSingle2.aInsideAddresses.emplace_back( 25, 7, 0 ); aSingle2.aInsideAddresses.emplace_back( 30, 7, 0 ); aSingle2.aInsideAddresses.emplace_back( 25, 15, 0 ); aSingle2.aInsideAddresses.emplace_back( 30, 15, 0 ); aSingle2.aOutsideAddresses.emplace_back( 15, 4, 0 ); aSingle2.aOutsideAddresses.emplace_back( 15, 11, 0 ); aSingle2.aOutsideAddresses.emplace_back( 9, 6, 0 ); aSingle2.aOutsideAddresses.emplace_back( 21, 6, 0 ); aSingle2.aOutsideAddresses.emplace_back( 26, 6, 0 ); aSingle2.aOutsideAddresses.emplace_back( 26, 16, 0 ); aSingle2.aOutsideAddresses.emplace_back( 24, 8, 0 ); aSingle2.aOutsideAddresses.emplace_back( 31, 11, 0 ); aSingle2.aColumnsWithoutFullMarks = aSingle1.aColumnsWithoutAnyMarks; aSingle2.aRowsWithoutFullMarks = aSingle1.aRowsWithoutFullMarks; aSingle2.aRangesWithFullMarks = aSingle1.aRangesWithFullMarks; aSingle2.aRangesWithFullMarks.emplace_back( 25, 7, 0, 30, 15, 0 ); aSingle2.aRangesWithFullMarks.emplace_back( 26, 8, 0, 29, 14, 0 ); aSingle2.aRangesWithoutFullMarks.emplace_back( 9, 4, 0, 21, 11, 0 ); aSingle2.aRangesWithoutFullMarks.emplace_back( 24, 6, 0, 31, 16, 0 ); aSingle2.aRangesWithoutFullMarks.emplace_back( 10, 5, 0, 30, 15, 0 ); aSingle2.aNextMarked.emplace_back( 27, 16, 0, 0, 15, 0 ); // up ok aSingle2.aNextMarked.emplace_back( 27, 4, 0, 1, 7, 0 ); // down ok aSingle2.aNextMarked.emplace_back( 27, 4, 0, 0, -1, 0 ); // up fail aSingle2.aNextMarked.emplace_back( 27, 16, 0, 1, limits.GetMaxRowCount(), 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, limits.MaxCol(), 20, 0 ); aSingle3.bMark = true; aSingle3.aInsideAddresses = aSingle2.aInsideAddresses; aSingle3.aInsideAddresses.emplace_back( 5, 20, 0 ); aSingle3.aInsideAddresses.emplace_back( 100, 20, 0 ); aSingle3.aOutsideAddresses.emplace_back( 0, 21, 0 ); aSingle3.aOutsideAddresses.emplace_back( 27, 19, 0 ); aSingle3.aColumnsWithoutFullMarks = aSingle2.aColumnsWithoutAnyMarks; aSingle3.aRowsWithFullMarks.push_back( 20 ); aSingle3.aRangesWithFullMarks = aSingle2.aRangesWithFullMarks; aSingle3.aRangesWithFullMarks.emplace_back( 0, 20, 0, limits.MaxCol(), 20, 0 ); aSingle3.aRangesWithFullMarks.emplace_back( 15, 20, 0, 55, 20, 0 ); aSingle3.aNextMarked.emplace_back( 15, 16, 0, 0, 10, 0 ); // up ok aSingle3.aNextMarked.emplace_back( 15, 16, 0, 1, 20, 0 ); // down ok aSingle3.aNextMarked.emplace_back( 22, 15, 0, 0, -1, 0 ); // up fail aSingle3.aNextMarked.emplace_back( 22, 25, 0, 1, limits.GetMaxRowCount(), 0 ); // down fail aSingle3.aColumnsWithAtLeastOneMark = aSingle2.aColumnsWithAtLeastOneMark; aSingle3.aColumnsWithAtLeastOneMark.push_back( 39 ); // Full col = 35 MarkTestData aSingle4; aSingle4.aRange = ScRange( 35, 0, 0, 35, limits.MaxRow(), 0 ); aSingle4.bMark = true; aSingle4.aInsideAddresses = aSingle3.aInsideAddresses; aSingle4.aInsideAddresses.emplace_back( 35, 10, 0 ); aSingle4.aInsideAddresses.emplace_back( 35, 25, 0 ); aSingle4.aOutsideAddresses.emplace_back( 33, 10, 0 ); aSingle4.aOutsideAddresses.emplace_back( 39, 10, 0 ); aSingle4.aOutsideAddresses.emplace_back( 33, 25, 0 ); aSingle4.aOutsideAddresses.emplace_back( 39, 25, 0 ); aSingle4.aColumnsWithFullMarks.push_back( 35 ); aSingle4.aRowsWithFullMarks.push_back( 20 ); aSingle4.aRangesWithFullMarks = aSingle3.aRangesWithFullMarks; aSingle4.aRangesWithFullMarks.emplace_back( 35, 0, 0, 35, limits.MaxRow(), 0 ); aSingle4.aRangesWithFullMarks.emplace_back( 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, limits.MaxCol(), limits.MaxRow(), 0 ); aData.aLeftEnvelope.push_back( ScRange( 9, 5, 0, 9, 10, 0 ) ); aData.aLeftEnvelope.push_back( ScRange( 24, 7, 0, 24, 15, 0 ) ); aData.aLeftEnvelope.push_back( ScRange( 34, 0, 0, 34, 19, 0 ) ); aData.aLeftEnvelope.push_back( ScRange( 34, 21, 0, 34, limits.MaxRow(), 0 ) ); aData.aRightEnvelope.push_back( ScRange( 21, 5, 0, 21, 10, 0 ) ); aData.aRightEnvelope.push_back( ScRange( 31, 7, 0, 31, 15, 0 ) ); aData.aRightEnvelope.push_back( ScRange( 36, 0, 0, 36, 19, 0 ) ); aData.aRightEnvelope.push_back( ScRange( 36, 21, 0, 36, limits.MaxRow(), 0 ) ); aData.aTopEnvelope.push_back( ScRange( 10, 4, 0, 20, 4, 0 ) ); aData.aTopEnvelope.push_back( ScRange( 25, 6, 0, 30, 6, 0 ) ); aData.aTopEnvelope.push_back( ScRange( 0, 19, 0, 34, 19, 0 ) ); aData.aTopEnvelope.push_back( ScRange( 36, 19, 0, limits.MaxCol(), 19, 0 ) ); aData.aBottomEnvelope.push_back( ScRange( 10, 11, 0, 20, 11, 0 ) ); aData.aBottomEnvelope.push_back( ScRange( 25, 16, 0, 30, 16, 0 ) ); aData.aBottomEnvelope.push_back( ScRange( 0, 21, 0, 34, 21, 0 ) ); aData.aBottomEnvelope.push_back( ScRange( 36, 21, 0, limits.MaxCol(), 21, 0 ) ); MarkArrayTestData aMarkArrayTestData1; aMarkArrayTestData1.nCol = 5; aMarkArrayTestData1.aMarkedRowSegs.emplace_back( 20, 20 ); MarkArrayTestData aMarkArrayTestData2; aMarkArrayTestData2.nCol = 15; aMarkArrayTestData2.aMarkedRowSegs.emplace_back( 5, 10 ); aMarkArrayTestData2.aMarkedRowSegs.emplace_back( 20, 20 ); MarkArrayTestData aMarkArrayTestData3; aMarkArrayTestData3.nCol = 22; aMarkArrayTestData3.aMarkedRowSegs.emplace_back( 20, 20 ); MarkArrayTestData aMarkArrayTestData4; aMarkArrayTestData4.nCol = 27; aMarkArrayTestData4.aMarkedRowSegs.emplace_back( 7, 15 ); aMarkArrayTestData4.aMarkedRowSegs.emplace_back( 20, 20 ); MarkArrayTestData aMarkArrayTestData5; aMarkArrayTestData5.nCol = 33; aMarkArrayTestData5.aMarkedRowSegs.emplace_back( 20, 20 ); MarkArrayTestData aMarkArrayTestData6; aMarkArrayTestData6.nCol = 35; aMarkArrayTestData6.aMarkedRowSegs.emplace_back( 0, limits.MaxRow() ); MarkArrayTestData aMarkArrayTestData7; aMarkArrayTestData7.nCol = 40; aMarkArrayTestData7.aMarkedRowSegs.emplace_back( 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.emplace_back( 5, 20, 0, 0, 20, 0 ); aData.aColsWithOneMark.emplace_back( 22, 20, 0, 0, 20, 0 ); aData.aColsWithOneMark.emplace_back( 32, 20, 0, 0, 20, 0 ); aData.aColsWithOneMark.emplace_back( 35, 0, 0, 0, limits.MaxRow(), 0 ); aData.aColsWithOneMark.emplace_back( 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.emplace_back( 10, 5, 0, 0, 10, 0 ); aData.aColsAllMarked.emplace_back( 15, 5, 0, 0, 10, 0 ); aData.aColsAllMarked.emplace_back( 5, 20, 0, 0, 20, 0 ); aData.aColsAllMarked.emplace_back( 10, 20, 0, 0, 20, 0 ); aData.aColsAllMarked.emplace_back( 25, 7, 0, 0, 15, 0 ); aData.aColsAllMarked.emplace_back( 30, 7, 0, 0, 15, 0 ); aData.aColsAllMarked.emplace_back( 35, 0, 0, 0, limits.MaxRow(), 0 ); aData.aColsAllMarked.emplace_back( 100, 20, 0, 0, 20, 0 ); aData.aColsNotAllMarked.emplace_back( 5, 5, 0, 0, 25, 0 ); aData.aColsNotAllMarked.emplace_back( 15, 5, 0, 0, 25, 0 ); aData.aColsNotAllMarked.emplace_back( 22, 15, 0, 0, 25, 0 ); aData.aColsNotAllMarked.emplace_back( 27, 7, 0, 0, 20, 0 ); aData.aColsNotAllMarked.emplace_back( 100, 19, 0, 0, 21, 0 ); aData.aColsWithEqualMarksList.emplace_back( 0, 9 ); aData.aColsWithEqualMarksList.emplace_back( 10, 20 ); aData.aColsWithEqualMarksList.emplace_back( 21, 24 ); aData.aColsWithEqualMarksList.emplace_back( 25, 30 ); aData.aColsWithEqualMarksList.emplace_back( 31, 34 ); aData.aColsWithEqualMarksList.emplace_back( 36, 100 ); aData.aColsWithEqualMarksList.emplace_back( 0, 22 ); aData.aColsWithEqualMarksList.emplace_back( 0, 34 ); aData.aColsWithUnequalMarksList.emplace_back( 0, 10 ); aData.aColsWithUnequalMarksList.emplace_back( 0, 20 ); aData.aColsWithUnequalMarksList.emplace_back( 10, 21 ); aData.aColsWithUnequalMarksList.emplace_back( 20, 25 ); aData.aColsWithUnequalMarksList.emplace_back( 20, 30 ); aData.aColsWithUnequalMarksList.emplace_back( 24, 30 ); aData.aColsWithUnequalMarksList.emplace_back( 30, 31 ); aData.aColsWithUnequalMarksList.emplace_back( 30, 34 ); aData.aColsWithUnequalMarksList.emplace_back( 30, 35 ); aData.aColsWithUnequalMarksList.emplace_back( 35, 100 ); testMultiMark( aData ); } void Test::testMultiMark_NegativeMarking() { ScSheetLimits limits( ScSheetLimits::CreateDefault()); MultiMarkTestData aData; // Create full row = 5 MarkTestData aSingle1; aSingle1.aRange = ScRange( 0, 5, 0, limits.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, limits.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.emplace_back( 6, 5, 0 ); aSingle4.aInsideAddresses.emplace_back( 30, 5, 0 ); aSingle4.aInsideAddresses.emplace_back( 6, 12, 0 ); aSingle4.aInsideAddresses.emplace_back( 30, 12, 0 ); aSingle4.aInsideAddresses.emplace_back( 13, 14, 0 ); aSingle4.aInsideAddresses.emplace_back( 16, 12, 0 ); aSingle4.aOutsideAddresses.emplace_back( 5, 2, 0 ); aSingle4.aOutsideAddresses.emplace_back( 18, 5, 0 ); aSingle4.aOutsideAddresses.emplace_back( 17, 5, 0 ); aSingle4.aOutsideAddresses.emplace_back( 20, 5, 0 ); aSingle4.aOutsideAddresses.emplace_back( 18, 7, 0 ); aSingle4.aOutsideAddresses.emplace_back( 5, 10, 0 ); aSingle4.aOutsideAddresses.emplace_back( 30, 10, 0 ); aSingle4.aOutsideAddresses.emplace_back( 5, 14, 0 ); aSingle4.aOutsideAddresses.emplace_back( 30, 14, 0 ); aSingle4.aOutsideAddresses.emplace_back( 18, 25, 0 ); aSingle4.aRowsWithFullMarks.push_back( 12 ); aSingle4.aRowsWithoutFullMarks.push_back( 5 ); aSingle4.aRangesWithFullMarks.emplace_back( 5, 5, 0, 16, 5, 0 ); aSingle4.aRangesWithFullMarks.emplace_back( 21, 5, 0, 30, 5, 0 ); aSingle4.aRangesWithFullMarks.emplace_back( 5, 12, 0, 9, 12, 0 ); aSingle4.aRangesWithFullMarks.emplace_back( 26, 12, 0, 30, 12, 0 ); aSingle4.aRangesWithFullMarks.emplace_back( 10, 8, 0, 25, 20, 0 ); aSingle4.aRangesWithoutFullMarks.emplace_back( 10, 5, 0, 25, 5, 0 ); aSingle4.aNextMarked.emplace_back( 18, 7, 0, 0, -1, 0 ); // up fail aSingle4.aNextMarked.emplace_back( 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.emplace_back( 6, 5, 0 ); aSingle5.aInsideAddresses.emplace_back( 30, 5, 0 ); aSingle5.aInsideAddresses.emplace_back( 6, 12, 0 ); aSingle5.aInsideAddresses.emplace_back( 30, 12, 0 ); aSingle5.aInsideAddresses.emplace_back( 13, 14, 0 ); aSingle5.aOutsideAddresses = aSingle4.aOutsideAddresses; aSingle5.aOutsideAddresses.emplace_back( 17, 12, 0 ); aSingle5.aOutsideAddresses.emplace_back( 15, 10, 0 ); aSingle5.aOutsideAddresses.emplace_back( 18, 10, 0 ); aSingle5.aOutsideAddresses.emplace_back( 15, 14, 0 ); aSingle5.aOutsideAddresses.emplace_back( 18, 14, 0 ); aSingle5.aRowsWithoutFullMarks.push_back( 12 ); aSingle5.aRowsWithoutFullMarks.push_back( 5 ); aSingle5.aRangesWithoutFullMarks.emplace_back( 10, 8, 0, 25, 20, 0 ); aSingle5.aNextMarked = aSingle4.aNextMarked; aSingle5.aNextMarked.emplace_back( 17, 12, 0, 0, 9, 0 ); // up ok aSingle5.aNextMarked.emplace_back( 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, limits.MaxCol(), 21, 0 ); aData.aLeftEnvelope.push_back( ScRange( 9, 8, 0, 9, 11, 0 ) ); aData.aLeftEnvelope.push_back( ScRange( 9, 13, 0, 9, 20, 0 ) ); aData.aLeftEnvelope.push_back( ScRange( 18, 10, 0, 18, 14, 0 ) ); aData.aLeftEnvelope.push_back( ScRange( 20, 5, 0, 20, 5, 0 ) ); aData.aRightEnvelope.push_back( ScRange( 17, 5, 0, 17, 5, 0 ) ); aData.aRightEnvelope.push_back( ScRange( 15, 10, 0, 15, 14, 0 ) ); aData.aRightEnvelope.push_back( ScRange( 26, 8, 0, 26, 11, 0 ) ); aData.aRightEnvelope.push_back( ScRange( 26, 13, 0, 26, 20, 0 ) ); aData.aTopEnvelope.push_back( ScRange( 0, 4, 0, 16, 4, 0 ) ); aData.aTopEnvelope.push_back( ScRange( 21, 4, 0, limits.MaxCol(), 4, 0 ) ); aData.aTopEnvelope.push_back( ScRange( 10, 7, 0, 25, 7, 0 ) ); aData.aTopEnvelope.push_back( ScRange( 0, 11, 0, 9, 11, 0 ) ); aData.aTopEnvelope.push_back( ScRange( 26, 11, 0, limits.MaxCol(), 11, 0 ) ); aData.aTopEnvelope.push_back( ScRange( 15, 14, 0, 18, 14, 0 ) ); aData.aBottomEnvelope.push_back( ScRange( 0, 6, 0, 16, 6, 0 ) ); aData.aBottomEnvelope.push_back( ScRange( 21, 6, 0, limits.MaxCol(), 6, 0 ) ); aData.aBottomEnvelope.push_back( ScRange( 15, 10, 0, 18, 10, 0 ) ); aData.aBottomEnvelope.push_back( ScRange( 0, 13, 0, 9, 13, 0 ) ); aData.aBottomEnvelope.push_back( ScRange( 26, 13, 0, limits.MaxCol(), 13, 0 ) ); aData.aBottomEnvelope.push_back( ScRange( 10, 21, 0, 25, 21, 0 ) ); aData.aColsWithOneMark.emplace_back( 19, 8, 0, 0, 20, 0 ); aData.aColsWithOneMark.emplace_back( 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.emplace_back( 10, 8, 0, 0, 20, 0 ); aData.aColsAllMarked.emplace_back( 17, 8, 0, 0, 9, 0 ); aData.aColsAllMarked.emplace_back( 20, 8, 0, 0, 20, 0 ); aData.aColsAllMarked.emplace_back( 100, 5, 0, 0, 5, 0 ); aData.aColsAllMarked.emplace_back( 100, 12, 0, 0, 12, 0 ); aData.aColsNotAllMarked.emplace_back( 5, 5, 0, 0, 12, 0 ); aData.aColsNotAllMarked.emplace_back( 10, 5, 0, 0, 20, 0 ); aData.aColsNotAllMarked.emplace_back( 15, 8, 0, 0, 20, 0 ); aData.aColsNotAllMarked.emplace_back( 18, 8, 0, 0, 20, 0 ); aData.aColsNotAllMarked.emplace_back( 25, 5, 0, 0, 20, 0 ); aData.aColsWithEqualMarksList.emplace_back( 0, 9 ); aData.aColsWithEqualMarksList.emplace_back( 10, 14 ); aData.aColsWithEqualMarksList.emplace_back( 15, 16 ); aData.aColsWithEqualMarksList.emplace_back( 17, 18 ); aData.aColsWithEqualMarksList.emplace_back( 19, 20 ); aData.aColsWithEqualMarksList.emplace_back( 21, 25 ); aData.aColsWithEqualMarksList.emplace_back( 26, 100 ); aData.aColsWithEqualMarksList.emplace_back( 0, 100 ); aData.aColsWithUnequalMarksList.emplace_back( 0, 10 ); aData.aColsWithUnequalMarksList.emplace_back( 10, 15 ); aData.aColsWithUnequalMarksList.emplace_back( 15, 17 ); aData.aColsWithUnequalMarksList.emplace_back( 17, 19 ); aData.aColsWithUnequalMarksList.emplace_back( 19, 21 ); aData.aColsWithUnequalMarksList.emplace_back( 21, 26 ); testMultiMark( aData ); } void Test::testInsertTabBeforeSelected() { ScMarkData aMark(ScSheetLimits::CreateDefault()); aMark.SelectOneTable(0); aMark.InsertTab(0); CPPUNIT_ASSERT_EQUAL(SCTAB(1), aMark.GetSelectCount()); CPPUNIT_ASSERT_EQUAL(SCTAB(1), aMark.GetFirstSelected()); } void Test::testInsertTabAfterSelected() { ScMarkData aMark(ScSheetLimits::CreateDefault()); aMark.SelectOneTable(0); aMark.InsertTab(1); CPPUNIT_ASSERT_EQUAL(SCTAB(1), aMark.GetSelectCount()); CPPUNIT_ASSERT_EQUAL(SCTAB(0), aMark.GetFirstSelected()); } void Test::testDeleteTabBeforeSelected() { ScMarkData aMark(ScSheetLimits::CreateDefault()); aMark.SelectOneTable(1); aMark.DeleteTab(0); CPPUNIT_ASSERT_EQUAL(SCTAB(1), aMark.GetSelectCount()); CPPUNIT_ASSERT_EQUAL(SCTAB(0), aMark.GetFirstSelected()); } void Test::testDeleteTabAfterSelected() { ScMarkData aMark(ScSheetLimits::CreateDefault()); aMark.SelectOneTable(0); aMark.DeleteTab(1); CPPUNIT_ASSERT_EQUAL(SCTAB(1), aMark.GetSelectCount()); CPPUNIT_ASSERT_EQUAL(SCTAB(0), aMark.GetFirstSelected()); } void Test::testScMarkArraySearch_check(const ScMarkArray & ar, SCROW nRow, bool expectStatus, SCSIZE nIndexExpect) { SCSIZE nIndex = 0; bool status = ar.Search(nRow, nIndex); CPPUNIT_ASSERT_EQUAL(expectStatus, status); CPPUNIT_ASSERT_EQUAL(nIndexExpect, nIndex); } void Test::testScMarkArraySearch() { ScSheetLimits limits( ScSheetLimits::CreateDefault()); // empty { ScMarkArray ar(limits); testScMarkArraySearch_check(ar, -1, true, 0); testScMarkArraySearch_check(ar, 100, true, 0); } // one range { ScMarkArray ar(limits); ar.SetMarkArea(10, 20, true); // 0-9,10-20,21+ testScMarkArraySearch_check(ar, -100, true, 0); testScMarkArraySearch_check(ar, -1, true, 0); testScMarkArraySearch_check(ar, 0, true, 0); testScMarkArraySearch_check(ar, 5, true, 0); testScMarkArraySearch_check(ar, 9, true, 0); testScMarkArraySearch_check(ar, 10, true, 1); testScMarkArraySearch_check(ar, 11, true, 1); testScMarkArraySearch_check(ar, 19, true, 1); testScMarkArraySearch_check(ar, 20, true, 1); testScMarkArraySearch_check(ar, 21, true, 2); testScMarkArraySearch_check(ar, 22, true, 2); } // three ranges { ScMarkArray ar(limits); ar.SetMarkArea(10, 20, true); ar.SetMarkArea(21, 30, true); ar.SetMarkArea(50, 100, true); // 0-9,10-30,31-49,50-100,101+ testScMarkArraySearch_check(ar, -100, true, 0); testScMarkArraySearch_check(ar, -1, true, 0); testScMarkArraySearch_check(ar, 5, true, 0); testScMarkArraySearch_check(ar, 15, true, 1); testScMarkArraySearch_check(ar, 25, true, 1); testScMarkArraySearch_check(ar, 35, true, 2); testScMarkArraySearch_check(ar, 55, true, 3); testScMarkArraySearch_check(ar, 20, true, 1); testScMarkArraySearch_check(ar, 21, true, 1); } // three single-row ranges { ScMarkArray ar(limits); ar.SetMarkArea(4, 4, true); ar.SetMarkArea(6, 6, true); ar.SetMarkArea(8, 8, true); testScMarkArraySearch_check(ar, -100, true, 0); testScMarkArraySearch_check(ar, -1, true, 0); testScMarkArraySearch_check(ar, 3, true, 0); testScMarkArraySearch_check(ar, 4, true, 1); testScMarkArraySearch_check(ar, 5, true, 2); testScMarkArraySearch_check(ar, 6, true, 3); testScMarkArraySearch_check(ar, 7, true, 4); testScMarkArraySearch_check(ar, 8, true, 5); testScMarkArraySearch_check(ar, 9, true, 6); testScMarkArraySearch_check(ar, 10, true, 6); } // one range { ScMarkArray ar(limits); ar.SetMarkArea(10, limits.MaxRow(), true); // 0-10,11+ testScMarkArraySearch_check(ar, -100, true, 0); testScMarkArraySearch_check(ar, -1, true, 0); testScMarkArraySearch_check(ar, 0, true, 0); testScMarkArraySearch_check(ar, 5, true, 0); testScMarkArraySearch_check(ar, 9, true, 0); testScMarkArraySearch_check(ar, 10, true, 1); testScMarkArraySearch_check(ar, 11, true, 1); testScMarkArraySearch_check(ar, 12, true, 1); testScMarkArraySearch_check(ar, 200, true, 1); testScMarkArraySearch_check(ar, limits.MaxRow(), true, 1); } } void Test::testIsAllMarked() { ScSheetLimits limits( ScSheetLimits::CreateDefault()); ScMarkData mark(limits); ScRange range1( ScAddress( 5, 10, 0 ), ScAddress( 15, 20, 0 )); ScRange range2( ScAddress( 2, 2, 0 ), ScAddress( 25, 30, 0 )); CPPUNIT_ASSERT( !mark.IsAllMarked( range1 )); CPPUNIT_ASSERT( !mark.IsAllMarked( range2 )); mark.MarkToMulti(); CPPUNIT_ASSERT( !mark.IsAllMarked( range1 )); CPPUNIT_ASSERT( !mark.IsAllMarked( range2 )); mark.ResetMark(); mark.SetMarkArea( range1 ); CPPUNIT_ASSERT( mark.IsAllMarked( range1 )); CPPUNIT_ASSERT( !mark.IsAllMarked( range2 )); mark.MarkToMulti(); CPPUNIT_ASSERT( mark.IsAllMarked( range1 )); CPPUNIT_ASSERT( !mark.IsAllMarked( range2 )); mark.ResetMark(); mark.SetMarkArea( range2 ); CPPUNIT_ASSERT( mark.IsAllMarked( range1 )); CPPUNIT_ASSERT( mark.IsAllMarked( range2 )); mark.MarkToMulti(); CPPUNIT_ASSERT( mark.IsAllMarked( range1 )); CPPUNIT_ASSERT( mark.IsAllMarked( range2 )); } CPPUNIT_TEST_SUITE_REGISTRATION(Test); CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ private/jmux/broken-static-win LibreOffice 核心代码仓库文档基金会
summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2024-04-29svx: prefix members of SdrLayerAdminMiklos Vajna
See tdf#94879 for motivation. Change-Id: I8ea80a3f2121c5c29168aa185e6278d924874c72 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166815 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
2024-03-24reduce symbol visibility in svxNoel Grandin
Change-Id: I19b7518f0ec1207ba95158f70d286ab115456466 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165224 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2024-03-18svx: prefix members of SdrLayerMiklos Vajna
See tdf#94879 for motivation. Change-Id: I35c1b90b472a27b34a3ca31cd81cd1fa65b24843 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164963 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
2022-07-21clang-tidy modernize-pass-by-value in svxNoel Grandin
Change-Id: Iedd87d321f4d161574df87629fdd6c7714ff31c5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137248 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2021-09-11clang:optin.performance.Padding in svx,editengNoel Grandin
Excessive padding in 'struct svx::SpellPortion' (18 padding bytes, where 2 is optimal). Excessive padding in 'class SvxNumRule' (11 padding bytes, where 3 is optimal). Excessive padding in 'struct SpellInfo' (10 padding bytes, where 2 is optimal). Excessive padding in 'struct ImpEditEngine::LineAreaInfo' (14 padding bytes, where 6 is optimal). Excessive padding in 'class ImpChainLinkProperties' (5 padding bytes, where 1 is optimal). Excessive padding in 'class TextChainFlow' (20 padding bytes, where 4 is optimal). Excessive padding in 'class SdrObjList' (13 padding bytes, where 5 is optimal). Excessive padding in 'class SdrLayer' (12 padding bytes, where 4 is optimal). Change-Id: I17b1c40bfe553c7635dc6177845dc92956cd0fae Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121942 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2021-06-19loplugin:finalclassesNoel Grandin
improve the plugin to detect more cases. I only apply the new final changes to classes in /include here. Which reveals that RoadmapWizard::getPageController( TabPage* _pCurrentPage ) will always return nullptr Also needed to sprinkle some SAL_DLLPUBLIC_TEMPLATE around to workaround Visual Studio linking problems. Change-Id: Iadb7d46a9e0e73dabce562375ca013c0fea6690c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117365 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2020-03-13Revert "loplugin:constfields in svx"Noel Grandin
This reverts commit 1a6397030381a45f27ab7a2a02e6e6d0f9987c84. Change-Id: Iaa706bb4ea3144ef57ab359b982400abc589b97e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/90454 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2020-02-02tdf#128302: Split SVXCORE_DLLPUBLIC from SVX_DLLPUBLICStephan Bergmann
Using SVX_DLLPUBLIC for both Library_svxcore and Library_svx had started to cause failures with clang-cl on Windows now, presumably due to devirtualization: > linectrl.o : error LNK2001: unresolved external symbol "protected: virtual void __cdecl SvxMetricField::DataChanged(class DataChangedEvent const &)" (?DataChanged@SvxMetricField@@MEAAXAEBVDataChangedEvent@@@Z) > linectrl.o : error LNK2001: unresolved external symbol "protected: virtual bool __cdecl SvxMetricField::PreNotify(class NotifyEvent &)" (?PreNotify@SvxMetricField@@MEAA_NAEAVNotifyEvent@@@Z) > linectrl.o : error LNK2001: unresolved external symbol "protected: virtual bool __cdecl SvxMetricField::EventNotify(class NotifyEvent &)" (?EventNotify@SvxMetricField@@MEAA_NAEAVNotifyEvent@@@Z) > linectrl.o : error LNK2001: unresolved external symbol "protected: virtual void __cdecl SvxMetricField::Modify(void)" (?Modify@SvxMetricField@@MEAAXXZ) > linectrl.o : error LNK2001: unresolved external symbol "private: virtual bool __cdecl SvxFillAttrBox::PreNotify(class NotifyEvent &)" (?PreNotify@SvxFillAttrBox@@EEAA_NAEAVNotifyEvent@@@Z) > linectrl.o : error LNK2001: unresolved external symbol "private: virtual bool __cdecl SvxFillAttrBox::EventNotify(class NotifyEvent &)" (?EventNotify@SvxFillAttrBox@@EEAA_NAEAVNotifyEvent@@@Z) > C:\lo-clang\core\instdir\program\svxcorelo.dll : fatal error LNK1120: 6 unresolved externals Replacing certain uses of SVX_DLLPUBLIC with the newly introduced SVXCORE_DLLPUBLIC (include/svx/svxdllapi.h) has been done on Linux as follows: > git grep -w --line-number -e SVX_DLLPUBLIC --and --not -e '#define SVX_DLLPUBLIC' >LINES to produce a file LINES containing all 640 uses. (Conveniently, all uses happen to be on different lines.) Manually create a file TOKENS with 640 corresponding lines, each containing the (class or function) name that is made SVX_DLLPUBLIC by in the corresponding line in LINES. Then > nm -D --def instdir/program/libsvxcorelo.so | grep -ivw '[vw]' | c++filt >SVXCORESYMS > nm -D --def instdir/program/libsvxlo.so | grep -ivw '[vw]' | c++filt >SVXSYMS > n=$(cat TOKENS | wc -l) > for ((i=1;i<="$n";++i)); do > tok=$(head -n "$i" TOKENS | tail -1) > printf @ > grep -Fw "$tok" SVXCORESYMS >/dev/null && printf svxcore > printf @ > grep -Fw "$tok" SVXSYMS >/dev/null && printf svx > printf '@ ' > head -n "$i" LINES | tail -1 > done to generate 640 output lines detailing for each SVX_DLLPUBLIC name occurrene whether it is mentioned in exports from neither (@@@), only from svx (@@svx@), only from svxcore (@svxcore@@), or from both libraries (@svxcore@svx@). The numbers that gives is 10 @@@ 180 @@svx@ 424 @svxcore@@ 26 @svxcore@svx@ The 10 @@@ ask for follow-up clean up, but most of them are just left as SVX_DLLPUBLIC for now. The exceptions are sxv::ITextProvider (include/svx/itextprovider.hxx) and SdrCustomShapeGeometryItem::PropertyPairHash (include/svx/sdasitm.hxx, where PropertyPairHash is a member struct of SVXCORE_DLLPUBLIC SdrCustomShapeGeometryItem). Keeping them as SVX_DLLPUBLIC would cause "unresolved externals" errors when linking Library_svxcore on Windows. The 180 @@svx@ are fine to keep as-is, and the 424 @svxcore@@ need rewriting. The 26 @svxcore@svx@ needed manual inspection to decide (in some cases, the chosen name in TOKENS was a too generic function name like Fill, in other cases it was the name of a class exported from one library but also mentioned in the arguments of a function exported from the other). And for sdr::table::SdrTableObj the class itself is defined in svxcore while the static member functions ExportAsRTF and ImportAsRTF are defined in svx. But MSVC does not allow to mark the class as SVXCORE_DLLPUBLIC and the two static member functions as SVX_DLLPLUBIC, so move the two functions out of the class. (There appears to be no real necessity that they were static member functions in the first place; they don't even need to be friends of the class. Nevertheless, this mixture of functionality from svxcore and svx in include/svx/svdotable.hxx may ask for follow-up clean up, one way or another.) All the output lines that need rewriting (all the @svxcore@@ ones, and the manually picked subset of @@@ and @svxcore@svx@ ones) are copied into a new file CHANGE (containing 451 lines). Then > sed -E -e 's|^@.*@.*@ ([^:]+):([0-9]+):.*$|sed -i -e "\2 s/SVX_DLLPUBLIC/SVXCORE_DLLPUBLIC/" \1|' <CHANGE >COMMANDS > . COMMANDS to do the changes. Change-Id: If9b6dd1c9e9ba2eb883dbdac4385d28c6fc8a203 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87794 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
2019-08-20Fix typosAndrea Gelmini
Change-Id: I88f788b6d8f9363e2f7b5447f6f0b0203f0834f0 Reviewed-on: https://gerrit.libreoffice.org/77758 Tested-by: Jenkins Reviewed-by: Julien Nabet <serval2412@yahoo.fr>
2019-06-18loplugin:passstuffbyrefNoel Grandin
Change-Id: Icb7c22cf4ac95eab54d04e79312fb471ca27bceb Reviewed-on: https://gerrit.libreoffice.org/74246 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2019-06-11tdf#42949 Fix IWYU warnings in include/svx/[sS][v-Z]*Gabor Kelemen
Found with bin/find-unneeded-includes Only removal proposals are dealt with here. Change-Id: Ie2a4122d67d2d40732e6fd00b584f33edd802c5b Reviewed-on: https://gerrit.libreoffice.org/73476 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
2019-01-23loplugin:constparams in svxNoel Grandin
Change-Id: Ie37288e4b9f064e309df81830f3a07507525bc55 Reviewed-on: https://gerrit.libreoffice.org/66771 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2018-10-30Remove now unused mbUserDefinedLayer from SdrLayerRegina Henschel
Commit 'Special methods NewStandardLayer and SetStandardLayer not needed' has removed the last user of mbUserDefinedLayer. Change-Id: Id4d4fbbfa9b1425225181ea6b0750a4205683902 Reviewed-on: https://gerrit.libreoffice.org/62506 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
2018-10-23Special methods NewStandardLayer and SetStandardLayer not neededRegina Henschel
The method SetStandardLayer() is only used once, in method SdrLayerAdmin::NewStandardLayer(). This method is only used once, in OReportDefinition::init(). The difference between a layer 'Standard' and other layers is only in mbUserDefinedLayer. But this difference is no where evaluated. Therefore an ordinary layer is sufficient. The layer name is neither stored nor used in the UI, thus translation is not needed. A layer name must be set, but in this case it is not used in code, thus handle it same as for layer 'back'. Change-Id: Ifd4400d432d3b4702e950d3a717ed13d4075c279 Reviewed-on: https://gerrit.libreoffice.org/62144 Tested-by: Jenkins Reviewed-by: Regina Henschel <rb.henschel@t-online.de>
2018-10-18convert SdrLayer::nType to boolNoel Grandin
since it is being used as a bool. Also rename it to something more readable Change-Id: I89acc47251770c94fa321b742b0fb9327024055f Reviewed-on: https://gerrit.libreoffice.org/61909 Reviewed-by: Regina Henschel <rb.henschel@t-online.de> Tested-by: Jenkins
2018-10-08loplugin:constfields in svxNoel Grandin
Change-Id: I643e8686e015ca85dd96221f1c93038f4fddf27b Reviewed-on: https://gerrit.libreoffice.org/61182 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2018-10-03loplugin:useuniqueptr in SdrLayerAdminNoel Grandin
Change-Id: I0f9c5b471b6db799b2194096f5d40c8adeb027d7 Reviewed-on: https://gerrit.libreoffice.org/61119 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2018-09-12tdf#119392 write bitfield in <draw:layer-set> orderRegina Henschel
The view uses the SdrLayerIDSet bitfield in layer ID order. But file format knows no layer IDs and on loading the bitfield is interpreted in the layer order given by <draw:layer-set> element. Therefore reorder the bits on saving according <draw:layer-set>, which is order in SdrLayerAdmin. Change-Id: Id349dc7f42338e35ca8cc3b6409d061213b01691 Reviewed-on: https://gerrit.libreoffice.org/60178 Tested-by: Jenkins Reviewed-by: Regina Henschel <rb.henschel@t-online.de>
2018-09-11loplugin:unusedmethodsNoel Grandin
Change-Id: I34009aabf0befb346470b5c0d96ad8fc476b7c4e Reviewed-on: https://gerrit.libreoffice.org/60300 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2018-09-02Fix typoAndrea Gelmini
Change-Id: I3947c13a595f94ea56d01dc5c3db5e634e737342 Reviewed-on: https://gerrit.libreoffice.org/59902 Reviewed-by: Julien Nabet <serval2412@yahoo.fr> Tested-by: Jenkins
2018-08-27tdf#101242 Support draw:display and draw:protect attributes of ODFRegina Henschel
LibreOffice writes the properties visible, printable and locked of layers into items in the subfile settings.xml and handles them as properties of the view. ODF handles them as property of the layer. To become more ODF conform as a first step these properties are now read and written. They are used to initialize the view in case they are missing in settings.xml, which is the case for foreign documents. The ODF properties are written in addition to the items in settings.xml, so that older versions will notice no difference with such documents. SdModelTestBase is changed to handle odg as Draw document. Change-Id: I190ecc51fc6ee91ec4b96d06bb216ce517bdfcfe Reviewed-on: https://gerrit.libreoffice.org/59269 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
2018-04-10loplugin:unusedmethodsNoel Grandin
Change-Id: I6f976ba8f792d2cee34859e9258798351eed8b1d Reviewed-on: https://gerrit.libreoffice.org/52636 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2017-05-12convert SdrLayerId to strong_intNoel Grandin
Also - rename SetOfByte to SdrLayerIDSet - add asserts in SdrLayerAdmin::GetUniqueLayerID so that we don't allocate overlapping SdrLayerID values - add a new constant SDRLAYERPOS_NOTFOUND to be returned from SdrLayerAdmin::GetLayerPos Change-Id: I3bb3489f9338e3d02c4040bcbd811744699941c8 Reviewed-on: https://gerrit.libreoffice.org/37467 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>