diff options
Diffstat (limited to 'sc/source/filter/xcl97/XclExpChangeTrack.cxx')
-rw-r--r-- | sc/source/filter/xcl97/XclExpChangeTrack.cxx | 1248 |
1 files changed, 1248 insertions, 0 deletions
diff --git a/sc/source/filter/xcl97/XclExpChangeTrack.cxx b/sc/source/filter/xcl97/XclExpChangeTrack.cxx new file mode 100644 index 000000000000..42cb37250c5c --- /dev/null +++ b/sc/source/filter/xcl97/XclExpChangeTrack.cxx @@ -0,0 +1,1248 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + +//___________________________________________________________________ + +#include <sot/storage.hxx> +#include "XclExpChangeTrack.hxx" +#include "xeformula.hxx" +#include "cell.hxx" +#include "xcl97rec.hxx" + +//___________________________________________________________________ +// local functions + +void lcl_WriteDateTime( XclExpStream& rStrm, const DateTime& rDateTime ) +{ + rStrm.SetSliceSize( 7 ); + rStrm << (sal_uInt16) rDateTime.GetYear() + << (sal_uInt8) rDateTime.GetMonth() + << (sal_uInt8) rDateTime.GetDay() + << (sal_uInt8) rDateTime.GetHour() + << (sal_uInt8) rDateTime.GetMin() + << (sal_uInt8) rDateTime.GetSec(); + rStrm.SetSliceSize( 0 ); +} + +// write string and fill rest of <nLength> with zero bytes +// <nLength> is without string header +void lcl_WriteFixedString( XclExpStream& rStrm, const XclExpString& rString, sal_Size nLength ) +{ + sal_Size nStrBytes = rString.GetBufferSize(); + DBG_ASSERT( nLength >= nStrBytes, "lcl_WriteFixedString - String too long" ); + if( rString.Len() > 0 ) + rStrm << rString; + if( nLength > nStrBytes ) + rStrm.WriteZeroBytes( nLength - nStrBytes ); +} + +inline void lcl_GenerateGUID( sal_uInt8* pGUID, sal_Bool& rValidGUID ) +{ + rtl_createUuid( pGUID, rValidGUID ? pGUID : NULL, sal_False ); + rValidGUID = sal_True; +} + +inline void lcl_WriteGUID( XclExpStream& rStrm, const sal_uInt8* pGUID ) +{ + rStrm.SetSliceSize( 16 ); + for( sal_Size nIndex = 0; nIndex < 16; nIndex++ ) + rStrm << pGUID[ nIndex ]; + rStrm.SetSliceSize( 0 ); +} + +//___________________________________________________________________ + +XclExpUserBView::XclExpUserBView( const String& rUsername, const sal_uInt8* pGUID ) : + sUsername( rUsername ) +{ + memcpy( aGUID, pGUID, 16 ); +} + +void XclExpUserBView::SaveCont( XclExpStream& rStrm ) +{ + rStrm << (sal_uInt32) 0xFF078014 + << (sal_uInt32) 0x00000001; + lcl_WriteGUID( rStrm, aGUID ); + rStrm.WriteZeroBytes( 8 ); + rStrm << (sal_uInt32) 1200 + << (sal_uInt32) 1000 + << (sal_uInt16) 1000 + << (sal_uInt16) 0x0CF7 + << (sal_uInt16) 0x0000 + << (sal_uInt16) 0x0001 + << (sal_uInt16) 0x0000; + if( sUsername.Len() > 0 ) + rStrm << sUsername; +} + +UINT16 XclExpUserBView::GetNum() const +{ + return 0x01A9; +} + +sal_Size XclExpUserBView::GetLen() const +{ + return 50 + ((sUsername.Len() > 0) ? sUsername.GetSize() : 0); +} + +//___________________________________________________________________ + +XclExpUserBViewList::XclExpUserBViewList( const ScChangeTrack& rChangeTrack ) +{ + sal_uInt8 aGUID[ 16 ]; + sal_Bool bValidGUID = sal_False; + const ScStrCollection& rStrColl = rChangeTrack.GetUserCollection(); + for( USHORT nIndex = 0; nIndex < rStrColl.GetCount(); nIndex++ ) + { + const StrData* pStrData = (const StrData*) rStrColl.At( nIndex ); + lcl_GenerateGUID( aGUID, bValidGUID ); + if( pStrData ) + List::Insert( new XclExpUserBView( pStrData->GetString(), aGUID ), LIST_APPEND ); + } +} + +XclExpUserBViewList::~XclExpUserBViewList() +{ + for( XclExpUserBView* pRec = _First(); pRec; pRec = _Next() ) + delete pRec; +} + +void XclExpUserBViewList::Save( XclExpStream& rStrm ) +{ + for( XclExpUserBView* pRec = _First(); pRec; pRec = _Next() ) + pRec->Save( rStrm ); +} + +//___________________________________________________________________ + +XclExpUsersViewBegin::XclExpUsersViewBegin( const sal_uInt8* pGUID, sal_uInt32 nTab ) : + nCurrTab( nTab ) +{ + memcpy( aGUID, pGUID, 16 ); +} + +void XclExpUsersViewBegin::SaveCont( XclExpStream& rStrm ) +{ + lcl_WriteGUID( rStrm, aGUID ); + rStrm << nCurrTab + << (sal_uInt32) 100 + << (sal_uInt32) 64 + << (sal_uInt32) 3 + << (sal_uInt32) 0x0000003C + << (sal_uInt16) 0 + << (sal_uInt16) 3 + << (sal_uInt16) 0 + << (sal_uInt16) 3 + << (double) 0 + << (double) 0 + << (sal_Int16) -1 + << (sal_Int16) -1; +} + +UINT16 XclExpUsersViewBegin::GetNum() const +{ + return 0x01AA; +} + +sal_Size XclExpUsersViewBegin::GetLen() const +{ + return 64; +} + +//___________________________________________________________________ + +void XclExpUsersViewEnd::SaveCont( XclExpStream& rStrm ) +{ + rStrm << (sal_uInt16) 0x0001; +} + +UINT16 XclExpUsersViewEnd::GetNum() const +{ + return 0x01AB; +} + +sal_Size XclExpUsersViewEnd::GetLen() const +{ + return 2; +} + +//___________________________________________________________________ + +void XclExpChTr0x0191::SaveCont( XclExpStream& rStrm ) +{ + rStrm << (sal_uInt16) 0x0000; +} + +UINT16 XclExpChTr0x0191::GetNum() const +{ + return 0x0191; +} + +sal_Size XclExpChTr0x0191::GetLen() const +{ + return 2; +} + +//___________________________________________________________________ + +void XclExpChTr0x0198::SaveCont( XclExpStream& rStrm ) +{ + rStrm << (sal_uInt16) 0x0006 + << (sal_uInt16) 0x0000; +} + +UINT16 XclExpChTr0x0198::GetNum() const +{ + return 0x0198; +} + +sal_Size XclExpChTr0x0198::GetLen() const +{ + return 4; +} + +//___________________________________________________________________ + +void XclExpChTr0x0192::SaveCont( XclExpStream& rStrm ) +{ + rStrm << sal_uInt16( 0x0022 ); + rStrm.WriteZeroBytes( 510 ); +} + +UINT16 XclExpChTr0x0192::GetNum() const +{ + return 0x0192; +} + +sal_Size XclExpChTr0x0192::GetLen() const +{ + return 512; +} + +//___________________________________________________________________ + +void XclExpChTr0x0197::SaveCont( XclExpStream& rStrm ) +{ + rStrm << (sal_uInt16) 0x0000; +} + +UINT16 XclExpChTr0x0197::GetNum() const +{ + return 0x0197; +} + +sal_Size XclExpChTr0x0197::GetLen() const +{ + return 2; +} + +//___________________________________________________________________ + +XclExpChTrEmpty::~XclExpChTrEmpty() +{ +} + +UINT16 XclExpChTrEmpty::GetNum() const +{ + return nRecNum; +} + +sal_Size XclExpChTrEmpty::GetLen() const +{ + return 0; +} + +//___________________________________________________________________ + +XclExpChTr0x0195::~XclExpChTr0x0195() +{ +} + +void XclExpChTr0x0195::SaveCont( XclExpStream& rStrm ) +{ + rStrm.WriteZeroBytes( 162 ); +} + +UINT16 XclExpChTr0x0195::GetNum() const +{ + return 0x0195; +} + +sal_Size XclExpChTr0x0195::GetLen() const +{ + return 162; +} + +//___________________________________________________________________ + +XclExpChTr0x0194::~XclExpChTr0x0194() +{ +} + +void XclExpChTr0x0194::SaveCont( XclExpStream& rStrm ) +{ + rStrm << (sal_uInt32) 0; + lcl_WriteDateTime( rStrm, aDateTime ); + rStrm << (sal_uInt8) 0; + lcl_WriteFixedString( rStrm, sUsername, 147 ); +} + +UINT16 XclExpChTr0x0194::GetNum() const +{ + return 0x0194; +} + +sal_Size XclExpChTr0x0194::GetLen() const +{ + return 162; +} + +//___________________________________________________________________ + +XclExpChTrHeader::~XclExpChTrHeader() +{ +} + +void XclExpChTrHeader::SaveCont( XclExpStream& rStrm ) +{ + rStrm << (sal_uInt16) 0x0006 + << (sal_uInt16) 0x0000 + << (sal_uInt16) 0x000D; + lcl_WriteGUID( rStrm, aGUID ); + lcl_WriteGUID( rStrm, aGUID ); + rStrm << nCount + << (sal_uInt16) 0x0001 + << (sal_uInt32) 0x00000000 + << (sal_uInt16) 0x001E; +} + +UINT16 XclExpChTrHeader::GetNum() const +{ + return 0x0196; +} + +sal_Size XclExpChTrHeader::GetLen() const +{ + return 50; +} + +//___________________________________________________________________ + +XclExpChTrInfo::~XclExpChTrInfo() +{ +} + +void XclExpChTrInfo::SaveCont( XclExpStream& rStrm ) +{ + rStrm << (sal_uInt32) 0xFFFFFFFF + << (sal_uInt32) 0x00000000 + << (sal_uInt32) 0x00000020 + << (sal_uInt16) 0xFFFF; + lcl_WriteGUID( rStrm, aGUID ); + rStrm << (sal_uInt16) 0x04B0; + lcl_WriteFixedString( rStrm, sUsername, 113 ); + lcl_WriteDateTime( rStrm, aDateTime ); + rStrm << (sal_uInt8) 0x0000 + << (sal_uInt16) 0x0002; +} + +UINT16 XclExpChTrInfo::GetNum() const +{ + return 0x0138; +} + +sal_Size XclExpChTrInfo::GetLen() const +{ + return 158; +} + +//___________________________________________________________________ + +XclExpChTrTabIdBuffer::XclExpChTrTabIdBuffer( sal_uInt16 nCount ) : + nBufSize( nCount ), + nLastId( nCount ) +{ + pBuffer = new sal_uInt16[ nBufSize ]; + memset( pBuffer, 0, sizeof(sal_uInt16) * nBufSize ); + pLast = pBuffer + nBufSize - 1; +} + +XclExpChTrTabIdBuffer::XclExpChTrTabIdBuffer( const XclExpChTrTabIdBuffer& rCopy ) : + nBufSize( rCopy.nBufSize ), + nLastId( rCopy.nLastId ) +{ + pBuffer = new sal_uInt16[ nBufSize ]; + memcpy( pBuffer, rCopy.pBuffer, sizeof(sal_uInt16) * nBufSize ); + pLast = pBuffer + nBufSize - 1; +} + +XclExpChTrTabIdBuffer::~XclExpChTrTabIdBuffer() +{ + delete[] pBuffer; +} + +void XclExpChTrTabIdBuffer::InitFill( sal_uInt16 nIndex ) +{ + DBG_ASSERT( nIndex < nLastId, "XclExpChTrTabIdBuffer::Insert - out of range" ); + + sal_uInt16 nFreeCount = 0; + for( sal_uInt16* pElem = pBuffer; pElem <= pLast; pElem++ ) + { + if( !*pElem ) + nFreeCount++; + if( nFreeCount > nIndex ) + { + *pElem = nLastId--; + return; + } + } +} + +void XclExpChTrTabIdBuffer::InitFillup() +{ + sal_uInt16 nFreeCount = 1; + for( sal_uInt16* pElem = pBuffer; pElem <= pLast; pElem++ ) + if( !*pElem ) + *pElem = nFreeCount++; + nLastId = nBufSize; +} + +sal_uInt16 XclExpChTrTabIdBuffer::GetId( sal_uInt16 nIndex ) const +{ + DBG_ASSERT( nIndex < nBufSize, "XclExpChTrTabIdBuffer::GetId - out of range" ); + return pBuffer[ nIndex ]; +} + +void XclExpChTrTabIdBuffer::Remove() +{ + DBG_ASSERT( pBuffer <= pLast, "XclExpChTrTabIdBuffer::Remove - buffer empty" ); + sal_uInt16* pElem = pBuffer; + while( (pElem <= pLast) && (*pElem != nLastId) ) + pElem++; + while( pElem < pLast ) + { + *pElem = *(pElem + 1); + pElem++; + } + pLast--; + nLastId--; +} + +//___________________________________________________________________ + +XclExpChTrTabIdBufferList::~XclExpChTrTabIdBufferList() +{ + for( XclExpChTrTabIdBuffer* pBuffer = First(); pBuffer; pBuffer = Next() ) + delete pBuffer; +} + +//___________________________________________________________________ + +XclExpChTrTabId::XclExpChTrTabId( const XclExpChTrTabIdBuffer& rBuffer ) : + nTabCount( rBuffer.GetBufferCount() ) +{ + pBuffer = new sal_uInt16[ nTabCount ]; + rBuffer.GetBufferCopy( pBuffer ); +} + +XclExpChTrTabId::~XclExpChTrTabId() +{ + Clear(); +} + +void XclExpChTrTabId::Copy( const XclExpChTrTabIdBuffer& rBuffer ) +{ + Clear(); + nTabCount = rBuffer.GetBufferCount(); + pBuffer = new sal_uInt16[ nTabCount ]; + rBuffer.GetBufferCopy( pBuffer ); +} + +void XclExpChTrTabId::SaveCont( XclExpStream& rStrm ) +{ + rStrm.EnableEncryption(); + if( pBuffer ) + for( sal_uInt16* pElem = pBuffer; pElem < (pBuffer + nTabCount); pElem++ ) + rStrm << *pElem; + else + for( sal_uInt16 nIndex = 1; nIndex <= nTabCount; nIndex++ ) + rStrm << nIndex; +} + +UINT16 XclExpChTrTabId::GetNum() const +{ + return 0x013D; +} + +sal_Size XclExpChTrTabId::GetLen() const +{ + return nTabCount << 1; +} + +//___________________________________________________________________ + +// ! does not copy additional actions +XclExpChTrAction::XclExpChTrAction( const XclExpChTrAction& rCopy ) : + ExcRecord( rCopy ), + sUsername( rCopy.sUsername ), + aDateTime( rCopy.aDateTime ), + nIndex( 0 ), + pAddAction( 0 ), + bAccepted( rCopy.bAccepted ), + rTabInfo( rCopy.rTabInfo ), + rIdBuffer( rCopy.rIdBuffer ), + nLength( rCopy.nLength ), + nOpCode( rCopy.nOpCode ), + bForceInfo( rCopy.bForceInfo ) +{ +} + +XclExpChTrAction::XclExpChTrAction( + const ScChangeAction& rAction, + const XclExpRoot& rRoot, + const XclExpChTrTabIdBuffer& rTabIdBuffer, + sal_uInt16 nNewOpCode ) : + sUsername( rAction.GetUser() ), + aDateTime( rAction.GetDateTime() ), + nIndex( 0 ), + pAddAction( NULL ), + bAccepted( rAction.IsAccepted() ), + rTabInfo( rRoot.GetTabInfo() ), + rIdBuffer( rTabIdBuffer ), + nLength( 0 ), + nOpCode( nNewOpCode ), + bForceInfo( sal_False ) +{ + aDateTime.SetSec( 0 ); + aDateTime.Set100Sec( 0 ); +} + +XclExpChTrAction::~XclExpChTrAction() +{ + if( pAddAction ) + delete pAddAction; +} + +void XclExpChTrAction::SetAddAction( XclExpChTrAction* pAction ) +{ + if( pAddAction ) + pAddAction->SetAddAction( pAction ); + else + pAddAction = pAction; +} + +void XclExpChTrAction::AddDependentContents( + const ScChangeAction& rAction, + const XclExpRoot& rRoot, + ScChangeTrack& rChangeTrack ) +{ + ScChangeActionTable aActionTable; + rChangeTrack.GetDependents( (ScChangeAction*)(&rAction), aActionTable ); + for( const ScChangeAction* pDepAction = aActionTable.First(); pDepAction; pDepAction = aActionTable.Next() ) + if( pDepAction->GetType() == SC_CAT_CONTENT ) + SetAddAction( new XclExpChTrCellContent( + *((const ScChangeActionContent*) pDepAction), rRoot, rIdBuffer ) ); +} + +void XclExpChTrAction::SetIndex( sal_uInt32& rIndex ) +{ + nIndex = rIndex++; +} + +void XclExpChTrAction::SaveCont( XclExpStream& rStrm ) +{ + DBG_ASSERT( nOpCode != EXC_CHTR_OP_UNKNOWN, "XclExpChTrAction::SaveCont - unknown action" ); + rStrm << nLength + << nIndex + << nOpCode + << (sal_uInt16)(bAccepted ? EXC_CHTR_ACCEPT : EXC_CHTR_NOTHING); + SaveActionData( rStrm ); +} + +void XclExpChTrAction::PrepareSaveAction( XclExpStream& /*rStrm*/ ) const +{ +} + +void XclExpChTrAction::CompleteSaveAction( XclExpStream& /*rStrm*/ ) const +{ +} + +void XclExpChTrAction::Save( XclExpStream& rStrm ) +{ + PrepareSaveAction( rStrm ); + ExcRecord::Save( rStrm ); + if( pAddAction ) + pAddAction->Save( rStrm ); + CompleteSaveAction( rStrm ); +} + +sal_Size XclExpChTrAction::GetLen() const +{ + return GetHeaderByteCount() + GetActionByteCount(); +} + +//___________________________________________________________________ + +XclExpChTrData::XclExpChTrData() : + pString( NULL ), + fValue( 0.0 ), + nRKValue( 0 ), + nType( EXC_CHTR_TYPE_EMPTY ), + nSize( 0 ) +{ +} + +XclExpChTrData::~XclExpChTrData() +{ + Clear(); +} + +void XclExpChTrData::Clear() +{ + DELETEZ( pString ); + mxTokArr.reset(); + maRefLog.clear(); + fValue = 0.0; + nRKValue = 0; + nType = EXC_CHTR_TYPE_EMPTY; + nSize = 0; +} + +void XclExpChTrData::WriteFormula( XclExpStream& rStrm, const XclExpChTrTabIdBuffer& rTabIdBuffer ) +{ + DBG_ASSERT( mxTokArr.is() && !mxTokArr->Empty(), "XclExpChTrData::Write - no formula" ); + rStrm << *mxTokArr; + + for( XclExpRefLog::const_iterator aIt = maRefLog.begin(), aEnd = maRefLog.end(); aIt != aEnd; ++aIt ) + { + if( aIt->mpUrl && aIt->mpFirstTab ) + { + rStrm << *aIt->mpUrl << (sal_uInt8) 0x01 << *aIt->mpFirstTab << (sal_uInt8) 0x02; + } + else + { + bool bSingleTab = aIt->mnFirstXclTab == aIt->mnLastXclTab; + rStrm.SetSliceSize( bSingleTab ? 6 : 8 ); + rStrm << (sal_uInt8) 0x01 << (sal_uInt8) 0x02 << (sal_uInt8) 0x00; + rStrm << rTabIdBuffer.GetId( aIt->mnFirstXclTab ); + if( bSingleTab ) + rStrm << (sal_uInt8) 0x02; + else + rStrm << (sal_uInt8) 0x00 << rTabIdBuffer.GetId( aIt->mnLastXclTab ); + } + } + rStrm.SetSliceSize( 0 ); + rStrm << (sal_uInt8) 0x00; +} + +void XclExpChTrData::Write( XclExpStream& rStrm, const XclExpChTrTabIdBuffer& rTabIdBuffer ) +{ + switch( nType ) + { + case EXC_CHTR_TYPE_RK: + rStrm << nRKValue; + break; + case EXC_CHTR_TYPE_DOUBLE: + rStrm << fValue; + break; + case EXC_CHTR_TYPE_STRING: + DBG_ASSERT( pString, "XclExpChTrData::Write - no string" ); + rStrm << *pString; + break; + case EXC_CHTR_TYPE_FORMULA: + WriteFormula( rStrm, rTabIdBuffer ); + break; + } +} + +//___________________________________________________________________ + +XclExpChTrCellContent::XclExpChTrCellContent( + const ScChangeActionContent& rAction, + const XclExpRoot& rRoot, + const XclExpChTrTabIdBuffer& rTabIdBuffer ) : + XclExpChTrAction( rAction, rRoot, rTabIdBuffer, EXC_CHTR_OP_CELL ), + XclExpRoot( rRoot ), + pOldData( 0 ), + pNewData( 0 ), + aPosition( rAction.GetBigRange().MakeRange().aStart ) +{ + sal_uInt32 nDummy32; + sal_uInt16 nDummy16; + GetCellData( rAction.GetOldCell(), pOldData, nDummy32, nOldLength ); + GetCellData( rAction.GetNewCell(), pNewData, nLength, nDummy16 ); +} + +XclExpChTrCellContent::~XclExpChTrCellContent() +{ + if( pOldData ) + delete pOldData; + if( pNewData ) + delete pNewData; +} + +void XclExpChTrCellContent::MakeEmptyChTrData( XclExpChTrData*& rpData ) +{ + if( rpData ) + rpData->Clear(); + else + rpData = new XclExpChTrData; +} + +void XclExpChTrCellContent::GetCellData( + const ScBaseCell* pScCell, + XclExpChTrData*& rpData, + sal_uInt32& rXclLength1, + sal_uInt16& rXclLength2 ) +{ + MakeEmptyChTrData( rpData ); + rXclLength1 = 0x0000003A; + rXclLength2 = 0x0000; + + if( !pScCell ) + { + delete rpData; + rpData = NULL; + return; + } + + switch( pScCell->GetCellType() ) + { + case CELLTYPE_VALUE: + { + rpData->fValue = ((const ScValueCell*) pScCell)->GetValue(); + if( XclTools::GetRKFromDouble( rpData->nRKValue, rpData->fValue ) ) + { + rpData->nType = EXC_CHTR_TYPE_RK; + rpData->nSize = 4; + rXclLength1 = 0x0000003E; + rXclLength2 = 0x0004; + } + else + { + rpData->nType = EXC_CHTR_TYPE_DOUBLE; + rpData->nSize = 8; + rXclLength1 = 0x00000042; + rXclLength2 = 0x0008; + } + } + break; + case CELLTYPE_STRING: + case CELLTYPE_EDIT: + { + String sCellStr; + if( pScCell->GetCellType() == CELLTYPE_STRING ) + ((const ScStringCell*) pScCell)->GetString( sCellStr ); + else + ((const ScEditCell*) pScCell)->GetString( sCellStr ); + rpData->pString = new XclExpString( sCellStr, EXC_STR_DEFAULT, 32766 ); + rpData->nType = EXC_CHTR_TYPE_STRING; + rpData->nSize = 3 + rpData->pString->GetSize(); + rXclLength1 = 64 + (sCellStr.Len() << 1); + rXclLength2 = 6 + (sal_uInt16)(sCellStr.Len() << 1); + } + break; + case CELLTYPE_FORMULA: + { + const ScFormulaCell* pFmlCell = (const ScFormulaCell*) pScCell; + const ScTokenArray* pTokenArray = pFmlCell->GetCode(); + if( pTokenArray ) + { + XclExpRefLog& rRefLog = rpData->maRefLog; + rpData->mxTokArr = GetFormulaCompiler().CreateFormula( + EXC_FMLATYPE_CELL, *pTokenArray, &pFmlCell->aPos, &rRefLog ); + rpData->nType = EXC_CHTR_TYPE_FORMULA; + sal_Size nSize = rpData->mxTokArr->GetSize() + 3; + + for( XclExpRefLog::const_iterator aIt = rRefLog.begin(), aEnd = rRefLog.end(); aIt != aEnd; ++aIt ) + { + if( aIt->mpUrl && aIt->mpFirstTab ) + nSize += aIt->mpUrl->GetSize() + aIt->mpFirstTab->GetSize() + 2; + else + nSize += (aIt->mnFirstXclTab == aIt->mnLastXclTab) ? 6 : 8; + } + rpData->nSize = ::std::min< sal_Size >( nSize, 0xFFFF ); + rXclLength1 = 0x00000052; + rXclLength2 = 0x0018; + } + } + break; + default:; + } +} + +void XclExpChTrCellContent::SaveActionData( XclExpStream& rStrm ) const +{ + WriteTabId( rStrm, aPosition.Tab() ); + rStrm << (sal_uInt16)((pOldData ? (pOldData->nType << 3) : 0x0000) | (pNewData ? pNewData->nType : 0x0000)) + << (sal_uInt16) 0x0000; + Write2DAddress( rStrm, aPosition ); + rStrm << nOldLength + << (sal_uInt32) 0x00000000; + if( pOldData ) + pOldData->Write( rStrm, rIdBuffer ); + if( pNewData ) + pNewData->Write( rStrm, rIdBuffer ); +} + +UINT16 XclExpChTrCellContent::GetNum() const +{ + return 0x013B; +} + +sal_Size XclExpChTrCellContent::GetActionByteCount() const +{ + sal_Size nLen = 16; + if( pOldData ) + nLen += pOldData->nSize; + if( pNewData ) + nLen += pNewData->nSize; + return nLen; +} + +//___________________________________________________________________ + +XclExpChTrInsert::XclExpChTrInsert( + const ScChangeAction& rAction, + const XclExpRoot& rRoot, + const XclExpChTrTabIdBuffer& rTabIdBuffer, + ScChangeTrack& rChangeTrack ) : + XclExpChTrAction( rAction, rRoot, rTabIdBuffer ), + 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_DELETE_COLS: nOpCode = EXC_CHTR_OP_DELCOL; break; + case SC_CAT_DELETE_ROWS: nOpCode = EXC_CHTR_OP_DELROW; break; + default: + DBG_ERROR( "XclExpChTrInsert::XclExpChTrInsert - unknown action" ); + } + + if( nOpCode & EXC_CHTR_OP_COLFLAG ) + { + aRange.aStart.SetRow( 0 ); + aRange.aEnd.SetRow( rRoot.GetXclMaxPos().Row() ); + } + else + { + aRange.aStart.SetCol( 0 ); + aRange.aEnd.SetCol( rRoot.GetXclMaxPos().Col() ); + } + + if( nOpCode & EXC_CHTR_OP_DELFLAG ) + { + SetAddAction( new XclExpChTr0x014A( *this ) ); + AddDependentContents( rAction, rRoot, rChangeTrack ); + } +} + +XclExpChTrInsert::~XclExpChTrInsert() +{ +} + +void XclExpChTrInsert::SaveActionData( XclExpStream& rStrm ) const +{ + WriteTabId( rStrm, aRange.aStart.Tab() ); + rStrm << (sal_uInt16) 0x0000; + Write2DRange( rStrm, aRange ); + rStrm << (sal_uInt32) 0x00000000; +} + +void XclExpChTrInsert::PrepareSaveAction( XclExpStream& rStrm ) const +{ + if( (nOpCode == EXC_CHTR_OP_DELROW) || (nOpCode == EXC_CHTR_OP_DELCOL) ) + XclExpChTrEmpty( 0x0150 ).Save( rStrm ); +} + +void XclExpChTrInsert::CompleteSaveAction( XclExpStream& rStrm ) const +{ + if( (nOpCode == EXC_CHTR_OP_DELROW) || (nOpCode == EXC_CHTR_OP_DELCOL) ) + XclExpChTrEmpty( 0x0151 ).Save( rStrm ); +} + +UINT16 XclExpChTrInsert::GetNum() const +{ + return 0x0137; +} + +sal_Size XclExpChTrInsert::GetActionByteCount() const +{ + return 16; +} + +//___________________________________________________________________ + +XclExpChTrInsertTab::XclExpChTrInsertTab( + const ScChangeAction& rAction, + const XclExpRoot& rRoot, + const XclExpChTrTabIdBuffer& rTabIdBuffer ) : + XclExpChTrAction( rAction, rRoot, rTabIdBuffer, EXC_CHTR_OP_INSTAB ), + XclExpRoot( rRoot ), + nTab( (SCTAB) rAction.GetBigRange().aStart.Tab() ) +{ + nLength = 0x0000021C; + bForceInfo = sal_True; +} + +XclExpChTrInsertTab::~XclExpChTrInsertTab() +{ +} + +void XclExpChTrInsertTab::SaveActionData( XclExpStream& rStrm ) const +{ + WriteTabId( rStrm, nTab ); + rStrm << sal_uInt32( 0 ); + lcl_WriteFixedString( rStrm, XclExpString( GetTabInfo().GetScTabName( nTab ) ), 127 ); + lcl_WriteDateTime( rStrm, GetDateTime() ); + rStrm.WriteZeroBytes( 133 ); +} + +UINT16 XclExpChTrInsertTab::GetNum() const +{ + return 0x014D; +} + +sal_Size XclExpChTrInsertTab::GetActionByteCount() const +{ + return 276; +} + +//___________________________________________________________________ + +XclExpChTrMoveRange::XclExpChTrMoveRange( + const ScChangeActionMove& rAction, + const XclExpRoot& rRoot, + const XclExpChTrTabIdBuffer& rTabIdBuffer, + ScChangeTrack& rChangeTrack ) : + XclExpChTrAction( rAction, rRoot, rTabIdBuffer, EXC_CHTR_OP_MOVE ), + aDestRange( rAction.GetBigRange().MakeRange() ) +{ + nLength = 0x00000042; + aSourceRange = aDestRange; + sal_Int32 nDCols, nDRows, nDTabs; + rAction.GetDelta( nDCols, nDRows, nDTabs ); + aSourceRange.aStart.IncRow( (SCROW) -nDRows ); + aSourceRange.aStart.IncCol( (SCCOL) -nDCols ); + aSourceRange.aStart.IncTab( (SCTAB) -nDTabs ); + aSourceRange.aEnd.IncRow( (SCROW) -nDRows ); + aSourceRange.aEnd.IncCol( (SCCOL) -nDCols ); + aSourceRange.aEnd.IncTab( (SCTAB) -nDTabs ); + AddDependentContents( rAction, rRoot, rChangeTrack ); +} + +XclExpChTrMoveRange::~XclExpChTrMoveRange() +{ +} + +void XclExpChTrMoveRange::SaveActionData( XclExpStream& rStrm ) const +{ + WriteTabId( rStrm, aDestRange.aStart.Tab() ); + Write2DRange( rStrm, aSourceRange ); + Write2DRange( rStrm, aDestRange ); + WriteTabId( rStrm, aSourceRange.aStart.Tab() ); + rStrm << (sal_uInt32) 0x00000000; +} + +void XclExpChTrMoveRange::PrepareSaveAction( XclExpStream& rStrm ) const +{ + XclExpChTrEmpty( 0x014E ).Save( rStrm ); +} + +void XclExpChTrMoveRange::CompleteSaveAction( XclExpStream& rStrm ) const +{ + XclExpChTrEmpty( 0x014F ).Save( rStrm ); +} + +UINT16 XclExpChTrMoveRange::GetNum() const +{ + return 0x0140; +} + +sal_Size XclExpChTrMoveRange::GetActionByteCount() const +{ + return 24; +} + +//___________________________________________________________________ + +XclExpChTr0x014A::XclExpChTr0x014A( const XclExpChTrInsert& rAction ) : + XclExpChTrInsert( rAction ) +{ + nLength = 0x00000026; + nOpCode = EXC_CHTR_OP_FORMAT; +} + +XclExpChTr0x014A::~XclExpChTr0x014A() +{ +} + +void XclExpChTr0x014A::SaveActionData( XclExpStream& rStrm ) const +{ + WriteTabId( rStrm, aRange.aStart.Tab() ); + rStrm << (sal_uInt16) 0x0003 + << (sal_uInt16) 0x0001; + Write2DRange( rStrm, aRange ); +} + +UINT16 XclExpChTr0x014A::GetNum() const +{ + return 0x014A; +} + +sal_Size XclExpChTr0x014A::GetActionByteCount() const +{ + return 14; +} + +//___________________________________________________________________ + +XclExpChTrActionStack::~XclExpChTrActionStack() +{ + while( XclExpChTrAction* pRec = Pop() ) + delete pRec; +} + +void XclExpChTrActionStack::Push( XclExpChTrAction* pNewRec ) +{ + DBG_ASSERT( pNewRec, "XclExpChTrActionStack::Push - NULL pointer" ); + if( pNewRec ) + Stack::Push( pNewRec ); +} + +//___________________________________________________________________ + +XclExpChTrRecordList::~XclExpChTrRecordList() +{ + for( ExcRecord* pRec = First(); pRec; pRec = Next() ) + delete pRec; +} + +void XclExpChTrRecordList::Append( ExcRecord* pNewRec ) +{ + DBG_ASSERT( pNewRec, "XclExpChTrRecordList::Append - NULL pointer" ); + if( pNewRec ) + List::Insert( pNewRec, LIST_APPEND ); +} + +void XclExpChTrRecordList::Save( XclExpStream& rStrm ) +{ + for( ExcRecord* pRec = First(); pRec; pRec = Next() ) + pRec->Save( rStrm ); +} + +//___________________________________________________________________ + +XclExpChangeTrack::XclExpChangeTrack( const XclExpRoot& rRoot ) : + XclExpRoot( rRoot ), + aRecList(), + aActionStack(), + aTabIdBufferList(), + pTabIdBuffer( NULL ), + pTempDoc( NULL ), + nNewAction( 1 ), + pHeader( NULL ), + bValidGUID( sal_False ) +{ + DBG_ASSERT( GetOldRoot().pTabId, "XclExpChangeTrack::XclExpChangeTrack - root data incomplete" ); + if( !GetOldRoot().pTabId ) + return; + + ScChangeTrack* pTempChangeTrack = CreateTempChangeTrack(); + if (!pTempChangeTrack) + return; + + pTabIdBuffer = new XclExpChTrTabIdBuffer( GetTabInfo().GetXclTabCount() ); + aTabIdBufferList.Append( pTabIdBuffer ); + + // calculate final table order (tab id list) + const ScChangeAction* pScAction; + for( pScAction = pTempChangeTrack->GetLast(); pScAction; pScAction = pScAction->GetPrev() ) + { + if( pScAction->GetType() == SC_CAT_INSERT_TABS ) + { + SCTAB nScTab = static_cast< SCTAB >( pScAction->GetBigRange().aStart.Tab() ); + pTabIdBuffer->InitFill( GetTabInfo().GetXclTab( nScTab ) ); + } + } + pTabIdBuffer->InitFillup(); + GetOldRoot().pTabId->Copy( *pTabIdBuffer ); + + // get actions in reverse order + pScAction = pTempChangeTrack->GetLast(); + while( pScAction ) + { + PushActionRecord( *pScAction ); + const ScChangeAction* pPrevAction = pScAction->GetPrev(); + pTempChangeTrack->Undo( pScAction->GetActionNumber(), pScAction->GetActionNumber() ); + pScAction = pPrevAction; + } + + // build record list + pHeader = new XclExpChTrHeader; + aRecList.Append( pHeader ); + aRecList.Append( new XclExpChTr0x0195 ); + aRecList.Append( new XclExpChTr0x0194( *pTempChangeTrack ) ); + + String sLastUsername; + DateTime aLastDateTime; + sal_uInt32 nIndex = 1; + while( XclExpChTrAction* pAction = aActionStack.Pop() ) + { + if( (nIndex == 1) || pAction->ForceInfoRecord() || + (pAction->GetUsername() != sLastUsername) || + (pAction->GetDateTime() != aLastDateTime) ) + { + lcl_GenerateGUID( aGUID, bValidGUID ); + sLastUsername = pAction->GetUsername(); + aLastDateTime = pAction->GetDateTime(); + aRecList.Append( new XclExpChTrInfo( sLastUsername, aLastDateTime, aGUID ) ); + aRecList.Append( new XclExpChTrTabId( pAction->GetTabIdBuffer() ) ); + pHeader->SetGUID( aGUID ); + } + pAction->SetIndex( nIndex ); + aRecList.Append( pAction ); + } + + pHeader->SetGUID( aGUID ); + pHeader->SetCount( nIndex - 1 ); + aRecList.Append( new ExcEof ); +} + +XclExpChangeTrack::~XclExpChangeTrack() +{ + if( pTempDoc ) + delete pTempDoc; +} + +ScChangeTrack* XclExpChangeTrack::CreateTempChangeTrack() +{ + // get original change track + ScChangeTrack* pOrigChangeTrack = GetDoc().GetChangeTrack(); + DBG_ASSERT( pOrigChangeTrack, "XclExpChangeTrack::CreateTempChangeTrack - no change track data" ); + if( !pOrigChangeTrack ) + return NULL; + + // create empty document + pTempDoc = new ScDocument; + DBG_ASSERT( pTempDoc, "XclExpChangeTrack::CreateTempChangeTrack - no temp document" ); + if( !pTempDoc ) + return NULL; + + // adjust table count + SCTAB nOrigCount = GetDoc().GetTableCount(); + String sTabName; + for( sal_Int32 nIndex = 0; nIndex < nOrigCount; nIndex++ ) + { + pTempDoc->CreateValidTabName( sTabName ); + pTempDoc->InsertTab( SC_TAB_APPEND, sTabName ); + } + DBG_ASSERT( nOrigCount == pTempDoc->GetTableCount(), + "XclExpChangeTrack::CreateTempChangeTrack - table count mismatch" ); + if( nOrigCount != pTempDoc->GetTableCount() ) + return sal_False; + + return pOrigChangeTrack->Clone(pTempDoc); +} + +void XclExpChangeTrack::PushActionRecord( const ScChangeAction& rAction ) +{ + XclExpChTrAction* pXclAction = NULL; + ScChangeTrack* pTempChangeTrack = pTempDoc->GetChangeTrack(); + switch( rAction.GetType() ) + { + case SC_CAT_CONTENT: + pXclAction = new XclExpChTrCellContent( (const ScChangeActionContent&) rAction, GetRoot(), *pTabIdBuffer ); + break; + case SC_CAT_INSERT_ROWS: + case SC_CAT_INSERT_COLS: + case SC_CAT_DELETE_ROWS: + case SC_CAT_DELETE_COLS: + if (pTempChangeTrack) + pXclAction = new XclExpChTrInsert( rAction, GetRoot(), *pTabIdBuffer, *pTempChangeTrack ); + break; + case SC_CAT_INSERT_TABS: + { + pXclAction = new XclExpChTrInsertTab( rAction, GetRoot(), *pTabIdBuffer ); + XclExpChTrTabIdBuffer* pNewBuffer = new XclExpChTrTabIdBuffer( *pTabIdBuffer ); + pNewBuffer->Remove(); + aTabIdBufferList.Append( pNewBuffer ); + pTabIdBuffer = pNewBuffer; + } + break; + case SC_CAT_MOVE: + if (pTempChangeTrack) + pXclAction = new XclExpChTrMoveRange( (const ScChangeActionMove&) rAction, GetRoot(), *pTabIdBuffer, *pTempChangeTrack ); + break; + default:; + } + if( pXclAction ) + aActionStack.Push( pXclAction ); +} + +sal_Bool XclExpChangeTrack::WriteUserNamesStream() +{ + sal_Bool bRet = sal_False; + SotStorageStreamRef xSvStrm = OpenStream( EXC_STREAM_USERNAMES ); + DBG_ASSERT( xSvStrm.Is(), "XclExpChangeTrack::WriteUserNamesStream - no stream" ); + if( xSvStrm.Is() ) + { + XclExpStream aXclStrm( *xSvStrm, GetRoot() ); + XclExpChTr0x0191().Save( aXclStrm ); + XclExpChTr0x0198().Save( aXclStrm ); + XclExpChTr0x0192().Save( aXclStrm ); + XclExpChTr0x0197().Save( aXclStrm ); + xSvStrm->Commit(); + bRet = sal_True; + } + return bRet; +} + +void XclExpChangeTrack::Write() +{ + if( !aRecList.Count() ) + return; + + if( WriteUserNamesStream() ) + { + SotStorageStreamRef xSvStrm = OpenStream( EXC_STREAM_REVLOG ); + DBG_ASSERT( xSvStrm.Is(), "XclExpChangeTrack::Write - no stream" ); + if( xSvStrm.Is() ) + { + XclExpStream aXclStrm( *xSvStrm, GetRoot(), EXC_MAXRECSIZE_BIFF8 + 8 ); + aRecList.Save( aXclStrm ); + xSvStrm->Commit(); + } + } +} + |