sc/inc/chgtrack.hxx | 72 ++---- sc/qa/unit/data/xls/track-changes/simple-cell-changes.xls |binary sc/qa/unit/subsequent_export-test.cxx | 162 +++++++++++++- sc/source/core/tool/chgtrack.cxx | 100 +++++++- sc/source/filter/inc/XclExpChangeTrack.hxx | 5 sc/source/filter/inc/XclImpChangeTrack.hxx | 2 sc/source/filter/xcl97/XclExpChangeTrack.cxx | 17 + sc/source/filter/xcl97/XclImpChangeTrack.cxx | 11 8 files changed, 292 insertions(+), 77 deletions(-)
New commits: commit adf0d7b1fb8eed88f4fcd6d31662ae6f59d00812 Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Mon Jul 14 15:24:19 2014 -0400 Preserve the "end of list" flag for xls round-tripping. This "end of list" flag determines whether the row insertion was an automatic insertion at the bottom. Calc doesn't use this at the moment but Excel uses it to differentiate a normal row insertion from an automatic one. Change-Id: I6b28669d816c54d1dc1e4c106918ba688415788d diff --git a/sc/inc/chgtrack.hxx b/sc/inc/chgtrack.hxx index b2b6cf9..59b4058 100644 --- a/sc/inc/chgtrack.hxx +++ b/sc/inc/chgtrack.hxx @@ -421,7 +421,9 @@ class ScChangeActionIns : public ScChangeAction { friend class ScChangeTrack; - ScChangeActionIns( const ScRange& rRange ); + bool mbEndOfList; /// whether or not a row was auto-inserted at the bottom. + + ScChangeActionIns( const ScRange& rRange, bool bEndOfList = false ); virtual ~ScChangeActionIns(); virtual void AddContent( ScChangeActionContent* ) SAL_OVERRIDE {} @@ -432,17 +434,21 @@ class ScChangeActionIns : public ScChangeAction virtual const ScChangeTrack* GetChangeTrack() const SAL_OVERRIDE { return 0; } public: - ScChangeActionIns(const sal_uLong nActionNumber, - const ScChangeActionState eState, - const sal_uLong nRejectingNumber, - const ScBigRange& aBigRange, - const OUString& aUser, - const DateTime& aDateTime, - const OUString &sComment, - const ScChangeActionType eType); // only to use in the XML import + ScChangeActionIns( + const sal_uLong nActionNumber, + const ScChangeActionState eState, + const sal_uLong nRejectingNumber, + const ScBigRange& aBigRange, + const OUString& aUser, + const DateTime& aDateTime, + const OUString &sComment, + const ScChangeActionType eType, + bool bEndOfList = false ); virtual void GetDescription( OUString& rStr, ScDocument* pDoc, bool bSplitRange = false, bool bWarning = true) const SAL_OVERRIDE; + + SC_DLLPUBLIC bool IsEndOfList() const; }; // ScChangeActionDel @@ -1113,7 +1119,7 @@ public: // Only use the following two if there is no different solution! (Assign // string for NewValue or creation of a formula respectively) - SC_DLLPUBLIC void AppendInsert( const ScRange& ); + SC_DLLPUBLIC void AppendInsert( const ScRange& rRange, bool bEndOfList = false ); // pRefDoc may be NULL => no lookup of contents // => no generation of deleted contents diff --git a/sc/source/core/tool/chgtrack.cxx b/sc/source/core/tool/chgtrack.cxx index 4b57b71..a18d0d3 100644 --- a/sc/source/core/tool/chgtrack.cxx +++ b/sc/source/core/tool/chgtrack.cxx @@ -652,8 +652,9 @@ void ScChangeAction::AddDependent( sal_uLong nActionNumber, } // ScChangeActionIns -ScChangeActionIns::ScChangeActionIns( const ScRange& rRange ) - : ScChangeAction( SC_CAT_NONE, rRange ) +ScChangeActionIns::ScChangeActionIns( const ScRange& rRange, bool bEndOfList ) : + ScChangeAction(SC_CAT_NONE, rRange), + mbEndOfList(bEndOfList) { if ( rRange.aStart.Col() == 0 && rRange.aEnd.Col() == MAXCOL ) { @@ -684,8 +685,10 @@ ScChangeActionIns::ScChangeActionIns( const sal_uLong nActionNumber, const ScChangeActionState eStateP, const sal_uLong nRejectingNumber, const ScBigRange& aBigRangeP, const OUString& aUserP, const DateTime& aDateTimeP, - const OUString& sComment, const ScChangeActionType eTypeP) : - ScChangeAction(eTypeP, aBigRangeP, nActionNumber, nRejectingNumber, eStateP, aDateTimeP, aUserP, sComment) + const OUString& sComment, const ScChangeActionType eTypeP, + bool bEndOfList ) : + ScChangeAction(eTypeP, aBigRangeP, nActionNumber, nRejectingNumber, eStateP, aDateTimeP, aUserP, sComment), + mbEndOfList(bEndOfList) { } @@ -728,6 +731,11 @@ void ScChangeActionIns::GetDescription( } } +bool ScChangeActionIns::IsEndOfList() const +{ + return mbEndOfList; +} + bool ScChangeActionIns::Reject( ScDocument* pDoc ) { if ( !aBigRange.IsValid( pDoc ) ) @@ -2848,9 +2856,9 @@ ScChangeActionContent* ScChangeTrack::AppendContentOnTheFly( return pAct; } -void ScChangeTrack::AppendInsert( const ScRange& rRange ) +void ScChangeTrack::AppendInsert( const ScRange& rRange, bool bEndOfList ) { - ScChangeActionIns* pAct = new ScChangeActionIns( rRange ); + ScChangeActionIns* pAct = new ScChangeActionIns(rRange, bEndOfList); Append( pAct ); } @@ -4477,18 +4485,20 @@ ScChangeTrack* ScChangeTrack::Clone( ScDocument* pDocument ) const case SC_CAT_INSERT_COLS: case SC_CAT_INSERT_ROWS: case SC_CAT_INSERT_TABS: - { - pClonedAction = new ScChangeActionIns( - pAction->GetActionNumber(), - pAction->GetState(), - pAction->GetRejectAction(), - pAction->GetBigRange(), - pAction->GetUser(), - pAction->GetDateTimeUTC(), - pAction->GetComment(), - pAction->GetType() ); - } - break; + { + bool bEndOfList = static_cast<const ScChangeActionIns*>(pAction)->IsEndOfList(); + pClonedAction = new ScChangeActionIns( + pAction->GetActionNumber(), + pAction->GetState(), + pAction->GetRejectAction(), + pAction->GetBigRange(), + pAction->GetUser(), + pAction->GetDateTimeUTC(), + pAction->GetComment(), + pAction->GetType(), + bEndOfList ); + } + break; case SC_CAT_DELETE_COLS: case SC_CAT_DELETE_ROWS: case SC_CAT_DELETE_TABS: diff --git a/sc/source/filter/inc/XclExpChangeTrack.hxx b/sc/source/filter/inc/XclExpChangeTrack.hxx index 18b0409..2bfa1bb 100644 --- a/sc/source/filter/inc/XclExpChangeTrack.hxx +++ b/sc/source/filter/inc/XclExpChangeTrack.hxx @@ -472,11 +472,12 @@ public: class XclExpChTrInsert : public XclExpChTrAction { + bool mbEndOfList; + protected: ScRange aRange; - XclExpChTrInsert( const XclExpChTrInsert& rCopy ) : - XclExpChTrAction( rCopy ), aRange( rCopy.aRange ) {} + XclExpChTrInsert( const XclExpChTrInsert& rCopy ); virtual void SaveActionData( XclExpStream& rStrm ) const SAL_OVERRIDE; virtual void PrepareSaveAction( XclExpStream& rStrm ) const SAL_OVERRIDE; diff --git a/sc/source/filter/inc/XclImpChangeTrack.hxx b/sc/source/filter/inc/XclImpChangeTrack.hxx index 0d1dc70..ac589b9 100644 --- a/sc/source/filter/inc/XclImpChangeTrack.hxx +++ b/sc/source/filter/inc/XclImpChangeTrack.hxx @@ -65,7 +65,7 @@ private: void DoAcceptRejectAction( ScChangeAction* pAction ); void DoAcceptRejectAction( sal_uInt32 nFirst, sal_uInt32 nLast ); - void DoInsertRange( const ScRange& rRange ); + void DoInsertRange( const ScRange& rRange, bool bEndOfList ); void DoDeleteRange( const ScRange& rRange ); inline sal_uInt8 LookAtuInt8(); diff --git a/sc/source/filter/xcl97/XclExpChangeTrack.cxx b/sc/source/filter/xcl97/XclExpChangeTrack.cxx index bb47f2a..a307382 100644 --- a/sc/source/filter/xcl97/XclExpChangeTrack.cxx +++ b/sc/source/filter/xcl97/XclExpChangeTrack.cxx @@ -992,19 +992,31 @@ void XclExpChTrCellContent::SaveXml( XclExpXmlStream& rRevisionLogStrm ) pStream->endElement( XML_rcc ); } +XclExpChTrInsert::XclExpChTrInsert( const XclExpChTrInsert& rCopy ) : + XclExpChTrAction(rCopy), + mbEndOfList(rCopy.mbEndOfList), + aRange(rCopy.aRange) {} + XclExpChTrInsert::XclExpChTrInsert( const ScChangeAction& rAction, const XclExpRoot& rRoot, const XclExpChTrTabIdBuffer& rTabIdBuffer, ScChangeTrack& rChangeTrack ) : XclExpChTrAction( rAction, rRoot, rTabIdBuffer ), + mbEndOfList(false), aRange( rAction.GetBigRange().MakeRange() ) { nLength = 0x00000030; switch( rAction.GetType() ) { case SC_CAT_INSERT_COLS: nOpCode = EXC_CHTR_OP_INSCOL; break; - case SC_CAT_INSERT_ROWS: nOpCode = EXC_CHTR_OP_INSROW; break; + case SC_CAT_INSERT_ROWS: + { + const ScChangeActionIns& rIns = static_cast<const ScChangeActionIns&>(rAction); + mbEndOfList = rIns.IsEndOfList(); + nOpCode = EXC_CHTR_OP_INSROW; + } + break; case SC_CAT_DELETE_COLS: nOpCode = EXC_CHTR_OP_DELCOL; break; case SC_CAT_DELETE_ROWS: nOpCode = EXC_CHTR_OP_DELROW; break; default: @@ -1036,7 +1048,8 @@ XclExpChTrInsert::~XclExpChTrInsert() void XclExpChTrInsert::SaveActionData( XclExpStream& rStrm ) const { WriteTabId( rStrm, aRange.aStart.Tab() ); - rStrm << (sal_uInt16) 0x0000; + sal_uInt16 nFlagVal = mbEndOfList ? 0x0001 : 0x0000; + rStrm << nFlagVal; Write2DRange( rStrm, aRange ); rStrm << (sal_uInt32) 0x00000000; } diff --git a/sc/source/filter/xcl97/XclImpChangeTrack.cxx b/sc/source/filter/xcl97/XclImpChangeTrack.cxx index b6e4180..f453208 100644 --- a/sc/source/filter/xcl97/XclImpChangeTrack.cxx +++ b/sc/source/filter/xcl97/XclImpChangeTrack.cxx @@ -93,10 +93,10 @@ void XclImpChangeTrack::DoAcceptRejectAction( sal_uInt32 nFirst, sal_uInt32 nLas DoAcceptRejectAction( pChangeTrack->GetAction( nIndex ) ); } -void XclImpChangeTrack::DoInsertRange( const ScRange& rRange ) +void XclImpChangeTrack::DoInsertRange( const ScRange& rRange, bool bEndOfList ) { sal_uInt32 nFirst = pChangeTrack->GetActionMax() + 1; - pChangeTrack->AppendInsert( rRange ); + pChangeTrack->AppendInsert(rRange, bEndOfList); sal_uInt32 nLast = pChangeTrack->GetActionMax(); DoAcceptRejectAction( nFirst, nLast ); } @@ -297,7 +297,8 @@ void XclImpChangeTrack::ReadChTrInsert() ScRange aRange; aRange.aStart.SetTab( ReadTabNum() ); aRange.aEnd.SetTab( aRange.aStart.Tab() ); - pStrm->Ignore( 2 ); + sal_uInt16 nFlags = pStrm->ReaduInt16(); + bool bEndOfList = (nFlags & 0x0001); // row auto-inserted at the bottom. Read2DRange( aRange ); if( aRecHeader.nOpCode & EXC_CHTR_OP_COLFLAG ) @@ -314,7 +315,7 @@ void XclImpChangeTrack::ReadChTrInsert() if( aRecHeader.nOpCode & EXC_CHTR_OP_DELFLAG ) DoDeleteRange( aRange ); else - DoInsertRange( aRange ); + DoInsertRange(aRange, bEndOfList); } } } @@ -426,7 +427,7 @@ void XclImpChangeTrack::ReadChTrInsertTab() if( pStrm->IsValid() ) { nTabIdCount++; - DoInsertRange( ScRange( 0, 0, nTab, MAXCOL, MAXROW, nTab ) ); + DoInsertRange(ScRange(0, 0, nTab, MAXCOL, MAXROW, nTab), false); } } } commit d873fd9fa28a26c6f2b177d26dbbc76c9bd827a3 Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Mon Jul 14 12:58:43 2014 -0400 Move this header to the source file. refupdat.hxx is under the ui directory. Not everyone has access to it. Change-Id: I3f60761e1105946ed5bd6bddb339ee9a9e7705ad diff --git a/sc/inc/chgtrack.hxx b/sc/inc/chgtrack.hxx index 94a94f3..b2b6cf9 100644 --- a/sc/inc/chgtrack.hxx +++ b/sc/inc/chgtrack.hxx @@ -33,7 +33,6 @@ #include "global.hxx" #include "bigrange.hxx" #include "scdllapi.h" -#include "refupdat.hxx" #include "cellvalue.hxx" class ScDocument; diff --git a/sc/source/core/tool/chgtrack.cxx b/sc/source/core/tool/chgtrack.cxx index 3abdc45..4b57b71 100644 --- a/sc/source/core/tool/chgtrack.cxx +++ b/sc/source/core/tool/chgtrack.cxx @@ -33,6 +33,7 @@ #include "editutil.hxx" #include "tokenarray.hxx" #include "refupdatecontext.hxx" +#include <refupdat.hxx> #include <tools/shl.hxx> #include <tools/rtti.hxx> commit 953d606b99017195249823c30c2bf19c83f10a44 Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Mon Jul 14 12:29:15 2014 -0400 Make these non inline. Change-Id: Ieb54e895f334361978cfc22956ab65687fb74adf diff --git a/sc/inc/chgtrack.hxx b/sc/inc/chgtrack.hxx index dc5f36c..94a94f3 100644 --- a/sc/inc/chgtrack.hxx +++ b/sc/inc/chgtrack.hxx @@ -1029,42 +1029,13 @@ public: ScChangeAction* GetFirst() const { return pFirst; } ScChangeAction* GetLast() const { return pLast; } sal_uLong GetActionMax() const { return nActionMax; } - bool IsGenerated( sal_uLong nAction ) const - { return nAction >= nGeneratedMin; } - ScChangeAction* GetAction( sal_uLong nAction ) const - { - ScChangeActionMap::const_iterator it = aMap.find( nAction ); - if( it != aMap.end() ) - return it->second; - else - return NULL; - } - ScChangeAction* GetGenerated( sal_uLong nGenerated ) const - { - ScChangeActionMap::const_iterator it = aGeneratedMap.find( nGenerated ); - if( it != aGeneratedMap.end() ) - return it->second; - else - return NULL; - } - ScChangeAction* GetActionOrGenerated( sal_uLong nAction ) const - { - return IsGenerated( nAction ) ? - GetGenerated( nAction ) : - GetAction( nAction ); - } - sal_uLong GetLastSavedActionNumber() const - { return nMarkLastSaved; } - void SetLastSavedActionNumber(sal_uLong nNew) - { nMarkLastSaved = nNew; } - ScChangeAction* GetLastSaved() const - { - ScChangeActionMap::const_iterator it = aMap.find( nMarkLastSaved ); - if( it != aMap.end() ) - return it->second; - else - return NULL; - } + bool IsGenerated( sal_uLong nAction ) const; + SC_DLLPUBLIC ScChangeAction* GetAction( sal_uLong nAction ) const; + ScChangeAction* GetGenerated( sal_uLong nGenerated ) const; + ScChangeAction* GetActionOrGenerated( sal_uLong nAction ) const; + sal_uLong GetLastSavedActionNumber() const; + void SetLastSavedActionNumber(sal_uLong nNew); + ScChangeAction* GetLastSaved() const; ScChangeActionContent** GetContentSlots() const { return ppContentSlots; } bool IsLoadSave() const { return bLoadSave; } @@ -1220,7 +1191,7 @@ public: void SetModifiedLink( const Link& r ) { aModifiedLink = r; ClearMsgQueue(); } const Link& GetModifiedLink() const { return aModifiedLink; } - ScChangeTrackMsgQueue& GetMsgQueue() { return aMsgQueue; } + ScChangeTrackMsgQueue& GetMsgQueue(); void NotifyModified( ScChangeTrackMsgType eMsgType, sal_uLong nStartAction, sal_uLong nEndAction ); diff --git a/sc/source/core/tool/chgtrack.cxx b/sc/source/core/tool/chgtrack.cxx index 8f1691d..3abdc45 100644 --- a/sc/source/core/tool/chgtrack.cxx +++ b/sc/source/core/tool/chgtrack.cxx @@ -2196,6 +2196,54 @@ void ScChangeTrack::Clear() Init(); } +bool ScChangeTrack::IsGenerated( sal_uLong nAction ) const +{ + return nAction >= nGeneratedMin; +} + +ScChangeAction* ScChangeTrack::GetAction( sal_uLong nAction ) const +{ + ScChangeActionMap::const_iterator it = aMap.find( nAction ); + if( it != aMap.end() ) + return it->second; + else + return NULL; +} + +ScChangeAction* ScChangeTrack::GetGenerated( sal_uLong nGenerated ) const +{ + ScChangeActionMap::const_iterator it = aGeneratedMap.find( nGenerated ); + if( it != aGeneratedMap.end() ) + return it->second; + else + return NULL; +} + +ScChangeAction* ScChangeTrack::GetActionOrGenerated( sal_uLong nAction ) const +{ + return IsGenerated( nAction ) ? + GetGenerated( nAction ) : + GetAction( nAction ); +} +sal_uLong ScChangeTrack::GetLastSavedActionNumber() const +{ + return nMarkLastSaved; +} + +void ScChangeTrack::SetLastSavedActionNumber(sal_uLong nNew) +{ + nMarkLastSaved = nNew; +} + +ScChangeAction* ScChangeTrack::GetLastSaved() const +{ + ScChangeActionMap::const_iterator it = aMap.find( nMarkLastSaved ); + if( it != aMap.end() ) + return it->second; + else + return NULL; +} + void ScChangeTrack::ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 ) { if ( !pDoc->IsInDtorClear() ) @@ -2282,6 +2330,11 @@ void ScChangeTrack::EndBlockModify( sal_uLong nEndAction ) } } +ScChangeTrackMsgQueue& ScChangeTrack::GetMsgQueue() +{ + return aMsgQueue; +} + void ScChangeTrack::NotifyModified( ScChangeTrackMsgType eMsgType, sal_uLong nStartAction, sal_uLong nEndAction ) { commit b63b6c63fdba944331ba4fcd6fe9a459c563d696 Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Fri Jul 11 18:40:43 2014 -0400 Write test for change track round-tripping for xls file format. Change-Id: I127879c4f1b6d3605ff800c3f3aa3929a098fead diff --git a/sc/qa/unit/data/xls/track-changes/simple-cell-changes.xls b/sc/qa/unit/data/xls/track-changes/simple-cell-changes.xls new file mode 100755 index 0000000..8def117 Binary files /dev/null and b/sc/qa/unit/data/xls/track-changes/simple-cell-changes.xls differ diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx index 9fa0bc2..103b962 100644 --- a/sc/qa/unit/subsequent_export-test.cxx +++ b/sc/qa/unit/subsequent_export-test.cxx @@ -33,6 +33,7 @@ #include "cellvalue.hxx" #include <postit.hxx> #include <tokenstringcontext.hxx> +#include <chgtrack.hxx> #include <svx/svdoole2.hxx> #include "tabprotection.hxx" @@ -92,7 +93,7 @@ public: void testCellBordersXLS(); void testCellBordersXLSX(); - + void testTrackChangesSimpleXLS(); void testSheetTabColorsXLSX(); void testSharedFormulaExportXLS(); @@ -131,6 +132,7 @@ public: CPPUNIT_TEST(testSheetProtectionXLSX); CPPUNIT_TEST(testCellBordersXLS); CPPUNIT_TEST(testCellBordersXLSX); + CPPUNIT_TEST(testTrackChangesSimpleXLS); CPPUNIT_TEST(testSheetTabColorsXLSX); CPPUNIT_TEST(testSharedFormulaExportXLS); CPPUNIT_TEST(testSharedFormulaExportXLSX); @@ -1305,6 +1307,164 @@ void ScExportTest::testCellBordersXLSX() testExcelCellBorders(XLSX); } +OUString toString( const ScBigRange& rRange ) +{ + OUStringBuffer aBuf; + aBuf.appendAscii("(columns:"); + aBuf.append(rRange.aStart.Col()); + aBuf.append('-'); + aBuf.append(rRange.aEnd.Col()); + aBuf.appendAscii(";rows:"); + aBuf.append(rRange.aStart.Row()); + aBuf.append('-'); + aBuf.append(rRange.aEnd.Row()); + aBuf.appendAscii(";sheets:"); + aBuf.append(rRange.aStart.Tab()); + aBuf.append('-'); + aBuf.append(rRange.aEnd.Tab()); + aBuf.append(')'); + + return aBuf.makeStringAndClear(); +} + +void ScExportTest::testTrackChangesSimpleXLS() +{ + struct CheckItem + { + sal_uLong mnActionId; + ScChangeActionType meType; + + sal_Int32 mnStartCol; + sal_Int32 mnStartRow; + sal_Int32 mnStartTab; + sal_Int32 mnEndCol; + sal_Int32 mnEndRow; + sal_Int32 mnEndTab; + + bool mbRowInsertedAtBottom; + }; + + struct + { + bool checkRange( ScChangeActionType eType, const ScBigRange& rExpected, const ScBigRange& rActual ) + { + ScBigRange aExpected(rExpected), aActual(rActual); + + switch (eType) + { + case SC_CAT_INSERT_ROWS: + { + // Ignore columns. + aExpected.aStart.SetCol(0); + aExpected.aEnd.SetCol(0); + aActual.aStart.SetCol(0); + aActual.aEnd.SetCol(0); + } + break; + default: + ; + } + + return aExpected == aActual; + } + + bool check( ScDocument& rDoc ) + { + CheckItem aChecks[] = + { + { 1, SC_CAT_CONTENT , 1, 1, 0, 1, 1, 0, false }, + { 2, SC_CAT_INSERT_ROWS , 0, 2, 0, 0, 2, 0, true }, + { 3, SC_CAT_CONTENT , 1, 2, 0, 1, 2, 0, false }, + { 4, SC_CAT_INSERT_ROWS , 0, 3, 0, 0, 3, 0, true }, + { 5, SC_CAT_CONTENT , 1, 3, 0, 1, 3, 0, false }, + { 6, SC_CAT_INSERT_ROWS , 0, 4, 0, 0, 4, 0, true }, + { 7, SC_CAT_CONTENT , 1, 4, 0, 1, 4, 0, false }, + { 8, SC_CAT_INSERT_ROWS , 0, 5, 0, 0, 5, 0, true }, + { 9, SC_CAT_CONTENT , 1, 5, 0, 1, 5, 0, false }, + { 10, SC_CAT_INSERT_ROWS , 0, 6, 0, 0, 6, 0, true }, + { 11, SC_CAT_CONTENT , 1, 6, 0, 1, 6, 0, false }, + { 12, SC_CAT_INSERT_ROWS , 0, 7, 0, 0, 7, 0, true }, + { 13, SC_CAT_CONTENT , 1, 7, 0, 1, 7, 0, false }, + }; + + ScChangeTrack* pCT = rDoc.GetChangeTrack(); + if (!pCT) + { + cerr << "Change track instance doesn't exist." << endl; + return false; + } + + sal_uLong nActionMax = pCT->GetActionMax(); + if (nActionMax != 13) + { + cerr << "Unexpected highest action ID value." << endl; + return false; + } + + for (size_t i = 0, n = SAL_N_ELEMENTS(aChecks); i < n; ++i) + { + sal_uInt16 nActId = aChecks[i].mnActionId; + const ScChangeAction* pAction = pCT->GetAction(nActId); + if (!pAction) + { + cerr << "No action for action number " << nActId << " found." << endl; + return false; + } + + if (pAction->GetType() != aChecks[i].meType) + { + cerr << "Unexpected action type for action number " << nActId << "." << endl; + return false; + } + + const ScBigRange& rRange = pAction->GetBigRange(); + ScBigRange aCheck(aChecks[i].mnStartCol, aChecks[i].mnStartRow, aChecks[i].mnStartTab, + aChecks[i].mnEndCol, aChecks[i].mnEndRow, aChecks[i].mnEndTab); + + if (!checkRange(pAction->GetType(), aCheck, rRange)) + { + cerr << "Unexpected range for action number " << nActId + << ": expected=" << toString(aCheck) << " actual=" << toString(rRange) << endl; + return false; + } + + switch (pAction->GetType()) + { + case SC_CAT_INSERT_ROWS: + { + const ScChangeActionIns* p = static_cast<const ScChangeActionIns*>(pAction); + if (p->IsEndOfList() != aChecks[i].mbRowInsertedAtBottom) + { + cerr << "Unexpected end-of-list flag for action number " << nActId << "." << endl; + return false; + } + } + break; + default: + ; + } + } + + return true; + } + + } aTest; + + ScDocShellRef xDocSh = loadDoc("track-changes/simple-cell-changes.", XLS); + CPPUNIT_ASSERT(xDocSh.Is()); + ScDocument* pDoc = &xDocSh->GetDocument(); + bool bGood = aTest.check(*pDoc); + CPPUNIT_ASSERT_MESSAGE("Initial check failed.", bGood); + + ScDocShellRef xDocSh2 = saveAndReload(xDocSh, XLS); + xDocSh->DoClose(); + pDoc = &xDocSh2->GetDocument(); + bGood = aTest.check(*pDoc); + CPPUNIT_ASSERT_MESSAGE("Check after reload failed.", bGood); + + xDocSh2->DoClose(); +} + void ScExportTest::testSheetTabColorsXLSX() { struct _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits