diff options
-rw-r--r-- | sc/inc/userdat.hxx | 2 | ||||
-rw-r--r-- | sc/qa/unit/data/ods/legacycellanchoredrotatedclippedshape.ods | bin | 0 -> 8338 bytes | |||
-rw-r--r-- | sc/qa/unit/data/ods/legacycellanchoredrotatedhiddenshape.ods | bin | 0 -> 8333 bytes | |||
-rw-r--r-- | sc/qa/unit/data/ods/legacycellanchoredrotatedshape.ods | bin | 0 -> 7917 bytes | |||
-rw-r--r-- | sc/qa/unit/filters-test.cxx | 114 | ||||
-rw-r--r-- | sc/qa/unit/helper/qahelper.hxx | 5 | ||||
-rw-r--r-- | sc/qa/unit/ucalc.cxx | 83 |
7 files changed, 202 insertions, 2 deletions
diff --git a/sc/inc/userdat.hxx b/sc/inc/userdat.hxx index 29f09b5caffe..537e3ae99d17 100644 --- a/sc/inc/userdat.hxx +++ b/sc/inc/userdat.hxx @@ -48,7 +48,7 @@ public: //------------------------------------------------------------------------- -class ScDrawObjData : public SdrObjUserData +class SC_DLLPUBLIC ScDrawObjData : public SdrObjUserData { public: enum Type { CellNote, ValidationCircle, DetectiveArrow, DrawingObject }; diff --git a/sc/qa/unit/data/ods/legacycellanchoredrotatedclippedshape.ods b/sc/qa/unit/data/ods/legacycellanchoredrotatedclippedshape.ods Binary files differnew file mode 100644 index 000000000000..45cf2ccf11ad --- /dev/null +++ b/sc/qa/unit/data/ods/legacycellanchoredrotatedclippedshape.ods diff --git a/sc/qa/unit/data/ods/legacycellanchoredrotatedhiddenshape.ods b/sc/qa/unit/data/ods/legacycellanchoredrotatedhiddenshape.ods Binary files differnew file mode 100644 index 000000000000..48b1e74a983b --- /dev/null +++ b/sc/qa/unit/data/ods/legacycellanchoredrotatedhiddenshape.ods diff --git a/sc/qa/unit/data/ods/legacycellanchoredrotatedshape.ods b/sc/qa/unit/data/ods/legacycellanchoredrotatedshape.ods Binary files differnew file mode 100644 index 000000000000..271eab5af19c --- /dev/null +++ b/sc/qa/unit/data/ods/legacycellanchoredrotatedshape.ods diff --git a/sc/qa/unit/filters-test.cxx b/sc/qa/unit/filters-test.cxx index 0f7d8903a652..19ad9fb0568e 100644 --- a/sc/qa/unit/filters-test.cxx +++ b/sc/qa/unit/filters-test.cxx @@ -51,6 +51,9 @@ #include "scitems.hxx" #include "document.hxx" #include "cellform.hxx" +#include "drwlayer.hxx" +#include "userdat.hxx" +#include <svx/svdpage.hxx> using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -81,7 +84,6 @@ public: void testContentXLS(); void testContentXLSX(); void testContentLotus123(); - #if TEST_BUG_FILES //goes recursively through all files in this dir and tries to open them void testDir(osl::Directory& rDir, sal_Int32 nType); @@ -90,6 +92,7 @@ public: void testBugFilesXLS(); void testBugFilesXLSX(); #endif + void testLegacyCellAnchoredRotatedShape(); CPPUNIT_TEST_SUITE(ScFiltersTest); CPPUNIT_TEST(testCVEs); @@ -98,6 +101,7 @@ public: CPPUNIT_TEST(testContentXLS); CPPUNIT_TEST(testContentXLSX); CPPUNIT_TEST(testContentLotus123); + CPPUNIT_TEST(testLegacyCellAnchoredRotatedShape); #if TEST_BUG_FILES CPPUNIT_TEST(testBugFiles); @@ -331,6 +335,114 @@ void ScFiltersTest::testContentLotus123() testContentImpl(pDoc, LOTUS123); xDocSh->DoClose(); } +void impl_testLegacyCellAnchoredRotatedShape( ScDocument* pDoc, Rectangle& aRect, ScDrawObjData& aAnchor ) +{ + const long TOLERANCE = 30; //30 hmm + ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); + CPPUNIT_ASSERT_MESSAGE("No drawing layer.", pDrawLayer); + SdrPage* pPage = pDrawLayer->GetPage(0); + CPPUNIT_ASSERT_MESSAGE("No page instance for the 1st sheet.", pPage); + CPPUNIT_ASSERT_EQUAL( sal_uIntPtr(1), pPage->GetObjCount() ); + + SdrObject* pObj = pPage->GetObj(0); + const Rectangle& aSnap = pObj->GetSnapRect(); + printf("expected height %ld actual %ld\n", aRect.GetHeight(), aSnap.GetHeight() ); + CPPUNIT_ASSERT_EQUAL( true, testEqualsWithTolerance( aRect.GetHeight(), aSnap.GetHeight(), TOLERANCE ) ); + printf("expected width %ld actual %ld\n", aRect.GetWidth(), aSnap.GetWidth() ); + CPPUNIT_ASSERT_EQUAL( true, testEqualsWithTolerance( aRect.GetWidth(), aSnap.GetWidth(), TOLERANCE ) ); + printf("expected left %ld actual %ld\n", aRect.Left(), aSnap.Left() ); + CPPUNIT_ASSERT_EQUAL( true, testEqualsWithTolerance( aRect.Left(), aSnap.Left(), TOLERANCE ) ); + printf("expected right %ld actual %ld\n", aRect.Top(), aSnap.Top() ); + CPPUNIT_ASSERT_EQUAL( true, testEqualsWithTolerance( aRect.Top(), aSnap.Top(), TOLERANCE ) ); + + + ScDrawObjData* pData = ScDrawLayer::GetObjData( pObj ); + printf("expected startrow %d actual %d\n", aAnchor.maStart.Row(), pData->maStart.Row() ); + CPPUNIT_ASSERT_EQUAL( aAnchor.maStart.Row(), pData->maStart.Row() ); + printf("expected startcol %d actual %d\n", aAnchor.maStart.Col(), pData->maStart.Col() ); + CPPUNIT_ASSERT_EQUAL( aAnchor.maStart.Col(), pData->maStart.Col() ); + printf("expected endrow %d actual %d\n", aAnchor.maEnd.Row(), pData->maEnd.Row() ); + CPPUNIT_ASSERT_EQUAL( aAnchor.maEnd.Row(), pData->maEnd.Row() ); + printf("expected endcol %d actual %d\n", aAnchor.maEnd.Col(), pData->maEnd.Col() ); + CPPUNIT_ASSERT_EQUAL( aAnchor.maEnd.Col(), pData->maEnd.Col() ); +} + +void ScFiltersTest::testLegacyCellAnchoredRotatedShape() +{ + { + // This example doc contains cell anchored shape that is rotated, the + // rotated shape is in fact cliped by the sheet boundries ( and thus + // is a good edge case test to see if we import it still correctly ) + ScDocShellRef xDocSh = loadDoc("legacycellanchoredrotatedclippedshape.", ODS); + + ScDocument* pDoc = xDocSh->GetDocument(); + CPPUNIT_ASSERT(pDoc); + // ensure the imported legacy rotated shape is in the expected position + Rectangle aRect( 6000, -2000, 8000, 4000 ); + // ensure the imported ( and converted ) anchor ( note we internally now store the anchor in + // terms of the rotated shape ) is more or less contains the correct info + ScDrawObjData aAnchor; + aAnchor.maStart.SetRow( 0 ); + aAnchor.maStart.SetCol( 5 ); + aAnchor.maEnd.SetRow( 3 ); + aAnchor.maEnd.SetCol( 7 ); + impl_testLegacyCellAnchoredRotatedShape( pDoc, aRect, aAnchor ); + // test save and reload + // for some reason having this test in subsequent_export-test.cxx causes + // a core dump in editeng ( so moved to here ) + xDocSh = saveAndReload( &(*xDocSh), ODS); + pDoc = xDocSh->GetDocument(); + CPPUNIT_ASSERT(pDoc); + impl_testLegacyCellAnchoredRotatedShape( pDoc, aRect, aAnchor ); + } +#if 0 // #FIXME, this is failing and is a regression + { + // This example doc contains cell anchored shape that is rotated, the + // rotated shape is in fact clipped by the sheet boundries, additionally + // the shape is completely hidden because the rows the shape occupies + // are hidden + ScDocShellRef xDocSh = loadDoc("legacycellanchoredrotatedhiddenshape.", ODS); + ScDocument* pDoc = xDocSh->GetDocument(); + CPPUNIT_ASSERT(pDoc); + // ensure the imported legacy rotated shape is in the expected position + Rectangle aRect( 6000, -2000, 8000, 4000 ); + // ensure the imported ( and converted ) anchor ( note we internally now store the anchor in + // terms of the rotated shape ) is more or less contains the correct info + ScDrawObjData aAnchor; + aAnchor.maStart.SetRow( 0 ); + aAnchor.maStart.SetCol( 5 ); + aAnchor.maEnd.SetRow( 3 ); + aAnchor.maEnd.SetCol( 7 ); + pDoc->ShowRows(0, 9, 0, true); // show relavent rows + impl_testLegacyCellAnchoredRotatedShape( pDoc, aRect, aAnchor ); + xDocSh->DoClose(); + } +#endif + { + // This example doc contains cell anchored shape that is rotated + ScDocShellRef xDocSh = loadDoc("legacycellanchoredrotatedshape.", ODS); + + ScDocument* pDoc = xDocSh->GetDocument(); + CPPUNIT_ASSERT(pDoc); + // ensure the imported legacy rotated shape is in the expected position + Rectangle aRect( 6000, 3000, 8000, 9000 ); + // ensure the imported ( and converted ) anchor ( note we internally now store the anchor in + // terms of the rotated shape ) is more or less contains the correct info + + ScDrawObjData aAnchor; + aAnchor.maStart.SetRow( 3 ); + aAnchor.maStart.SetCol( 6 ); + aAnchor.maEnd.SetRow( 9 ); + aAnchor.maEnd.SetCol( 7 ); + // test import + impl_testLegacyCellAnchoredRotatedShape( pDoc, aRect, aAnchor ); + // test save and reload + xDocSh = saveAndReload( &(*xDocSh), ODS); + pDoc = xDocSh->GetDocument(); + CPPUNIT_ASSERT(pDoc); + impl_testLegacyCellAnchoredRotatedShape( pDoc, aRect, aAnchor ); + } +} ScFiltersTest::ScFiltersTest() : ScBootstrapFixture( "/sc/qa/unit/data" ) diff --git a/sc/qa/unit/helper/qahelper.hxx b/sc/qa/unit/helper/qahelper.hxx index b09a61e2991e..94d761abcaf5 100644 --- a/sc/qa/unit/helper/qahelper.hxx +++ b/sc/qa/unit/helper/qahelper.hxx @@ -58,6 +58,11 @@ #define HTML 4 #define LOTUS123 5 +bool testEqualsWithTolerance( long nVal1, long nVal2, long nTol ) +{ + return ( labs( nVal1 - nVal2 ) <= nTol ); +} + struct FileFormat { const char* pName; const char* pFilterName; const char* pTypeName; unsigned int nFormatType; }; diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index 58fde7aae2d6..0c795c88834b 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -261,6 +261,7 @@ public: void testShiftCells(); void testDeleteRow(); void testDeleteCol(); + void testAnchoredRotatedShape(); CPPUNIT_TEST_SUITE(Test); CPPUNIT_TEST(testCollator); @@ -321,6 +322,7 @@ public: CPPUNIT_TEST(testShiftCells); CPPUNIT_TEST(testDeleteRow); CPPUNIT_TEST(testDeleteCol); + CPPUNIT_TEST(testAnchoredRotatedShape); CPPUNIT_TEST_SUITE_END(); private: @@ -5942,6 +5944,87 @@ void Test::testDeleteCol() pDoc->DeleteTab(0); } +void Test::testAnchoredRotatedShape() +{ + OUString aTabName("TestTab"); + m_pDoc->InsertTab(0, aTabName); + SCROW nRow1, nRow2; + bool bHidden = m_pDoc->RowHidden(0, 0, &nRow1, &nRow2); + CPPUNIT_ASSERT_MESSAGE("new sheet should have all rows visible", !bHidden && nRow1 == 0 && nRow2 == MAXROW); + + m_pDoc->InitDrawLayer(); + ScDrawLayer *pDrawLayer = m_pDoc->GetDrawLayer(); + CPPUNIT_ASSERT_MESSAGE("must have a draw layer", pDrawLayer != NULL); + SdrPage* pPage = pDrawLayer->GetPage(0); + CPPUNIT_ASSERT_MESSAGE("must have a draw page", pPage != NULL); + m_pDoc->SetRowHeightRange( 0, MAXROW, 0, sc::HMMToTwips( 1000 ) ); + const long TOLERANCE = 30; //30 hmm + for ( SCCOL nCol = 0; nCol < MAXCOL; ++nCol ) + m_pDoc->SetColWidth( nCol, 0, sc::HMMToTwips( 1000 ) ); + { + //Add a rect + Rectangle aRect( 4000, 5000, 10000, 7000 ); + + Rectangle aRotRect( 6000, 3000, 8000, 9000 ); + SdrRectObj *pObj = new SdrRectObj(aRect); + pPage->InsertObject(pObj); + Point aRef1(pObj->GetSnapRect().Center()); + int nAngle = 9000; //90 deg. + double nSin=sin(nAngle*nPi180); + double nCos=cos(nAngle*nPi180); + pObj->Rotate(aRef1,nAngle,nSin,nCos); + + ScDrawLayer::SetCellAnchoredFromPosition(*pObj, *m_pDoc, 0); + + Rectangle aSnap = pObj->GetSnapRect(); + printf("expected height %ld actual %ld\n", aRotRect.GetHeight(), aSnap.GetHeight() ); + CPPUNIT_ASSERT_EQUAL( true, testEqualsWithTolerance( aRotRect.GetHeight(), aSnap.GetHeight(), TOLERANCE ) ); + printf("expected width %ld actual %ld\n", aRotRect.GetWidth(), aSnap.GetWidth() ); + CPPUNIT_ASSERT_EQUAL( true, testEqualsWithTolerance( aRotRect.GetWidth(), aSnap.GetWidth(), TOLERANCE ) ); + printf("expected left %ld actual %ld\n", aRotRect.Left(), aSnap.Left() ); + CPPUNIT_ASSERT_EQUAL( true, testEqualsWithTolerance( aRotRect.Left(), aSnap.Left(), TOLERANCE ) ); + printf("expected right %ld actual %ld\n", aRotRect.Top(), aSnap.Top() ); + CPPUNIT_ASSERT_EQUAL( true, testEqualsWithTolerance( aRotRect.Top(), aSnap.Top(), TOLERANCE ) ); + + ScDrawObjData aAnchor; + ScDrawObjData* pData = ScDrawLayer::GetObjData( pObj ); + + aAnchor.maStart = pData->maStart; + aAnchor.maEnd = pData->maEnd; + + m_pDoc->SetDrawPageSize(0); + + // increase row 5 by 2000 hmm + m_pDoc->SetRowHeight( 5, 0, sc::HMMToTwips( 3000 ) ); + // increase col 6 by 1000 hmm + m_pDoc->SetColWidth( 6, 0, sc::HMMToTwips( 2000 ) ); + + aRotRect.setWidth( aRotRect.GetWidth() + 1000 ); + aRotRect.setHeight( aRotRect.GetHeight() + 2000 ); + + m_pDoc->SetDrawPageSize(0); + + aSnap = pObj->GetSnapRect(); + + printf("expected new height %ld actual %ld\n", aRotRect.GetHeight(), aSnap.GetHeight() ); + // ensure that width and height have been adjusted accordingly + CPPUNIT_ASSERT_EQUAL( true, testEqualsWithTolerance( aRotRect.GetHeight(), aSnap.GetHeight(), TOLERANCE ) ); + printf("expected new width %ld %ld\n", aRotRect.GetWidth(), aSnap.GetWidth() ); + CPPUNIT_ASSERT_EQUAL( true, testEqualsWithTolerance( aRotRect.GetWidth(), aSnap.GetWidth(), TOLERANCE ) ); + + // ensure that anchor start and end addresses haven't changed + printf("expected startrow %d actual %d\n", aAnchor.maStart.Row(), pData->maStart.Row() ); + CPPUNIT_ASSERT_EQUAL( aAnchor.maStart.Row(), pData->maStart.Row() ); // start row 0 + printf("expected startcol %d actual %d\n", aAnchor.maStart.Col(), pData->maStart.Col() ); + CPPUNIT_ASSERT_EQUAL( aAnchor.maStart.Col(), pData->maStart.Col() ); // start column 5 + printf("expected endrow %d actual %d\n", aAnchor.maEnd.Row(), pData->maEnd.Row() ); + CPPUNIT_ASSERT_EQUAL( aAnchor.maEnd.Row(), pData->maEnd.Row() ); // end row 3 + printf("expected endcol %d actual %d\n", aAnchor.maEnd.Col(), pData->maEnd.Col() ); + CPPUNIT_ASSERT_EQUAL( aAnchor.maEnd.Col(), pData->maEnd.Col() ); // end col 7 + } + m_pDoc->DeleteTab(0); +} + CPPUNIT_TEST_SUITE_REGISTRATION(Test); } |