1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: XclExpChangeTrack.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
35 //___________________________________________________________________
37 #include <sot/storage.hxx>
38 #include "XclExpChangeTrack.hxx"
39 #include "xeformula.hxx"
41 #include "xcl97rec.hxx"
43 //___________________________________________________________________
46 void lcl_WriteDateTime( XclExpStream
& rStrm
, const DateTime
& rDateTime
)
48 rStrm
.SetSliceSize( 7 );
49 rStrm
<< (sal_uInt16
) rDateTime
.GetYear()
50 << (sal_uInt8
) rDateTime
.GetMonth()
51 << (sal_uInt8
) rDateTime
.GetDay()
52 << (sal_uInt8
) rDateTime
.GetHour()
53 << (sal_uInt8
) rDateTime
.GetMin()
54 << (sal_uInt8
) rDateTime
.GetSec();
55 rStrm
.SetSliceSize( 0 );
58 // write string and fill rest of <nLength> with zero bytes
59 // <nLength> is without string header
60 void lcl_WriteFixedString( XclExpStream
& rStrm
, const XclExpString
& rString
, sal_Size nLength
)
62 sal_Size nStrBytes
= rString
.GetBufferSize();
63 DBG_ASSERT( nLength
>= nStrBytes
, "lcl_WriteFixedString - String too long" );
64 if( rString
.Len() > 0 )
66 if( nLength
> nStrBytes
)
67 rStrm
.WriteZeroBytes( nLength
- nStrBytes
);
70 inline void lcl_GenerateGUID( sal_uInt8
* pGUID
, sal_Bool
& rValidGUID
)
72 rtl_createUuid( pGUID
, rValidGUID
? pGUID
: NULL
, sal_False
);
73 rValidGUID
= sal_True
;
76 inline void lcl_WriteGUID( XclExpStream
& rStrm
, const sal_uInt8
* pGUID
)
78 rStrm
.SetSliceSize( 16 );
79 for( sal_Size nIndex
= 0; nIndex
< 16; nIndex
++ )
80 rStrm
<< pGUID
[ nIndex
];
81 rStrm
.SetSliceSize( 0 );
84 //___________________________________________________________________
86 XclExpUserBView::XclExpUserBView( const String
& rUsername
, const sal_uInt8
* pGUID
) :
87 sUsername( rUsername
)
89 memcpy( aGUID
, pGUID
, 16 );
92 void XclExpUserBView::SaveCont( XclExpStream
& rStrm
)
94 rStrm
<< (sal_uInt32
) 0xFF078014
95 << (sal_uInt32
) 0x00000001;
96 lcl_WriteGUID( rStrm
, aGUID
);
97 rStrm
.WriteZeroBytes( 8 );
98 rStrm
<< (sal_uInt32
) 1200
101 << (sal_uInt16
) 0x0CF7
102 << (sal_uInt16
) 0x0000
103 << (sal_uInt16
) 0x0001
104 << (sal_uInt16
) 0x0000;
105 if( sUsername
.Len() > 0 )
109 UINT16
XclExpUserBView::GetNum() const
114 sal_Size
XclExpUserBView::GetLen() const
116 return 50 + ((sUsername
.Len() > 0) ? sUsername
.GetSize() : 0);
119 //___________________________________________________________________
121 XclExpUserBViewList::XclExpUserBViewList( const ScChangeTrack
& rChangeTrack
)
123 sal_uInt8 aGUID
[ 16 ];
124 sal_Bool bValidGUID
= sal_False
;
125 const ScStrCollection
& rStrColl
= rChangeTrack
.GetUserCollection();
126 for( USHORT nIndex
= 0; nIndex
< rStrColl
.GetCount(); nIndex
++ )
128 const StrData
* pStrData
= (const StrData
*) rStrColl
.At( nIndex
);
129 lcl_GenerateGUID( aGUID
, bValidGUID
);
131 List::Insert( new XclExpUserBView( pStrData
->GetString(), aGUID
), LIST_APPEND
);
135 XclExpUserBViewList::~XclExpUserBViewList()
137 for( XclExpUserBView
* pRec
= _First(); pRec
; pRec
= _Next() )
141 void XclExpUserBViewList::Save( XclExpStream
& rStrm
)
143 for( XclExpUserBView
* pRec
= _First(); pRec
; pRec
= _Next() )
147 //___________________________________________________________________
149 XclExpUsersViewBegin::XclExpUsersViewBegin( const sal_uInt8
* pGUID
, sal_uInt32 nTab
) :
152 memcpy( aGUID
, pGUID
, 16 );
155 void XclExpUsersViewBegin::SaveCont( XclExpStream
& rStrm
)
157 lcl_WriteGUID( rStrm
, aGUID
);
162 << (sal_uInt32
) 0x0000003C
173 UINT16
XclExpUsersViewBegin::GetNum() const
178 sal_Size
XclExpUsersViewBegin::GetLen() const
183 //___________________________________________________________________
185 void XclExpUsersViewEnd::SaveCont( XclExpStream
& rStrm
)
187 rStrm
<< (sal_uInt16
) 0x0001;
190 UINT16
XclExpUsersViewEnd::GetNum() const
195 sal_Size
XclExpUsersViewEnd::GetLen() const
200 //___________________________________________________________________
202 void XclExpChTr0x0191::SaveCont( XclExpStream
& rStrm
)
204 rStrm
<< (sal_uInt16
) 0x0000;
207 UINT16
XclExpChTr0x0191::GetNum() const
212 sal_Size
XclExpChTr0x0191::GetLen() const
217 //___________________________________________________________________
219 void XclExpChTr0x0198::SaveCont( XclExpStream
& rStrm
)
221 rStrm
<< (sal_uInt16
) 0x0006
222 << (sal_uInt16
) 0x0000;
225 UINT16
XclExpChTr0x0198::GetNum() const
230 sal_Size
XclExpChTr0x0198::GetLen() const
235 //___________________________________________________________________
237 void XclExpChTr0x0192::SaveCont( XclExpStream
& rStrm
)
239 rStrm
<< sal_uInt16( 0x0022 );
240 rStrm
.WriteZeroBytes( 510 );
243 UINT16
XclExpChTr0x0192::GetNum() const
248 sal_Size
XclExpChTr0x0192::GetLen() const
253 //___________________________________________________________________
255 void XclExpChTr0x0197::SaveCont( XclExpStream
& rStrm
)
257 rStrm
<< (sal_uInt16
) 0x0000;
260 UINT16
XclExpChTr0x0197::GetNum() const
265 sal_Size
XclExpChTr0x0197::GetLen() const
270 //___________________________________________________________________
272 XclExpChTrEmpty::~XclExpChTrEmpty()
276 UINT16
XclExpChTrEmpty::GetNum() const
281 sal_Size
XclExpChTrEmpty::GetLen() const
286 //___________________________________________________________________
288 XclExpChTr0x0195::~XclExpChTr0x0195()
292 void XclExpChTr0x0195::SaveCont( XclExpStream
& rStrm
)
294 rStrm
.WriteZeroBytes( 162 );
297 UINT16
XclExpChTr0x0195::GetNum() const
302 sal_Size
XclExpChTr0x0195::GetLen() const
307 //___________________________________________________________________
309 XclExpChTr0x0194::~XclExpChTr0x0194()
313 void XclExpChTr0x0194::SaveCont( XclExpStream
& rStrm
)
315 rStrm
<< (sal_uInt32
) 0;
316 lcl_WriteDateTime( rStrm
, aDateTime
);
317 rStrm
<< (sal_uInt8
) 0;
318 lcl_WriteFixedString( rStrm
, sUsername
, 147 );
321 UINT16
XclExpChTr0x0194::GetNum() const
326 sal_Size
XclExpChTr0x0194::GetLen() const
331 //___________________________________________________________________
333 XclExpChTrHeader::~XclExpChTrHeader()
337 void XclExpChTrHeader::SaveCont( XclExpStream
& rStrm
)
339 rStrm
<< (sal_uInt16
) 0x0006
340 << (sal_uInt16
) 0x0000
341 << (sal_uInt16
) 0x000D;
342 lcl_WriteGUID( rStrm
, aGUID
);
343 lcl_WriteGUID( rStrm
, aGUID
);
345 << (sal_uInt16
) 0x0001
346 << (sal_uInt32
) 0x00000000
347 << (sal_uInt16
) 0x001E;
350 UINT16
XclExpChTrHeader::GetNum() const
355 sal_Size
XclExpChTrHeader::GetLen() const
360 //___________________________________________________________________
362 XclExpChTrInfo::~XclExpChTrInfo()
366 void XclExpChTrInfo::SaveCont( XclExpStream
& rStrm
)
368 rStrm
<< (sal_uInt32
) 0xFFFFFFFF
369 << (sal_uInt32
) 0x00000000
370 << (sal_uInt32
) 0x00000020
371 << (sal_uInt16
) 0xFFFF;
372 lcl_WriteGUID( rStrm
, aGUID
);
373 rStrm
<< (sal_uInt16
) 0x04B0;
374 lcl_WriteFixedString( rStrm
, sUsername
, 113 );
375 lcl_WriteDateTime( rStrm
, aDateTime
);
376 rStrm
<< (sal_uInt8
) 0x0000
377 << (sal_uInt16
) 0x0002;
380 UINT16
XclExpChTrInfo::GetNum() const
385 sal_Size
XclExpChTrInfo::GetLen() const
390 //___________________________________________________________________
392 XclExpChTrTabIdBuffer::XclExpChTrTabIdBuffer( sal_uInt16 nCount
) :
396 pBuffer
= new sal_uInt16
[ nBufSize
];
397 memset( pBuffer
, 0, sizeof(sal_uInt16
) * nBufSize
);
398 pLast
= pBuffer
+ nBufSize
- 1;
401 XclExpChTrTabIdBuffer::XclExpChTrTabIdBuffer( const XclExpChTrTabIdBuffer
& rCopy
) :
402 nBufSize( rCopy
.nBufSize
),
403 nLastId( rCopy
.nLastId
)
405 pBuffer
= new sal_uInt16
[ nBufSize
];
406 memcpy( pBuffer
, rCopy
.pBuffer
, sizeof(sal_uInt16
) * nBufSize
);
407 pLast
= pBuffer
+ nBufSize
- 1;
410 XclExpChTrTabIdBuffer::~XclExpChTrTabIdBuffer()
415 void XclExpChTrTabIdBuffer::InitFill( sal_uInt16 nIndex
)
417 DBG_ASSERT( nIndex
< nLastId
, "XclExpChTrTabIdBuffer::Insert - out of range" );
419 sal_uInt16 nFreeCount
= 0;
420 for( sal_uInt16
* pElem
= pBuffer
; pElem
<= pLast
; pElem
++ )
424 if( nFreeCount
> nIndex
)
432 void XclExpChTrTabIdBuffer::InitFillup()
434 sal_uInt16 nFreeCount
= 1;
435 for( sal_uInt16
* pElem
= pBuffer
; pElem
<= pLast
; pElem
++ )
437 *pElem
= nFreeCount
++;
441 sal_uInt16
XclExpChTrTabIdBuffer::GetId( sal_uInt16 nIndex
) const
443 DBG_ASSERT( nIndex
< nBufSize
, "XclExpChTrTabIdBuffer::GetId - out of range" );
444 return pBuffer
[ nIndex
];
447 void XclExpChTrTabIdBuffer::Remove()
449 DBG_ASSERT( pBuffer
<= pLast
, "XclExpChTrTabIdBuffer::Remove - buffer empty" );
450 sal_uInt16
* pElem
= pBuffer
;
451 while( (pElem
<= pLast
) && (*pElem
!= nLastId
) )
453 while( pElem
< pLast
)
455 *pElem
= *(pElem
+ 1);
462 //___________________________________________________________________
464 XclExpChTrTabIdBufferList::~XclExpChTrTabIdBufferList()
466 for( XclExpChTrTabIdBuffer
* pBuffer
= First(); pBuffer
; pBuffer
= Next() )
470 //___________________________________________________________________
472 XclExpChTrTabId::XclExpChTrTabId( const XclExpChTrTabIdBuffer
& rBuffer
) :
473 nTabCount( rBuffer
.GetBufferCount() )
475 pBuffer
= new sal_uInt16
[ nTabCount
];
476 rBuffer
.GetBufferCopy( pBuffer
);
479 XclExpChTrTabId::~XclExpChTrTabId()
484 void XclExpChTrTabId::Copy( const XclExpChTrTabIdBuffer
& rBuffer
)
487 nTabCount
= rBuffer
.GetBufferCount();
488 pBuffer
= new sal_uInt16
[ nTabCount
];
489 rBuffer
.GetBufferCopy( pBuffer
);
492 void XclExpChTrTabId::SaveCont( XclExpStream
& rStrm
)
494 rStrm
.EnableEncryption();
496 for( sal_uInt16
* pElem
= pBuffer
; pElem
< (pBuffer
+ nTabCount
); pElem
++ )
499 for( sal_uInt16 nIndex
= 1; nIndex
<= nTabCount
; nIndex
++ )
503 UINT16
XclExpChTrTabId::GetNum() const
508 sal_Size
XclExpChTrTabId::GetLen() const
510 return nTabCount
<< 1;
513 //___________________________________________________________________
515 // ! does not copy additional actions
516 XclExpChTrAction::XclExpChTrAction( const XclExpChTrAction
& rCopy
) :
518 sUsername( rCopy
.sUsername
),
519 aDateTime( rCopy
.aDateTime
),
522 bAccepted( rCopy
.bAccepted
),
523 rTabInfo( rCopy
.rTabInfo
),
524 rIdBuffer( rCopy
.rIdBuffer
),
525 nLength( rCopy
.nLength
),
526 nOpCode( rCopy
.nOpCode
),
527 bForceInfo( rCopy
.bForceInfo
)
531 XclExpChTrAction::XclExpChTrAction(
532 const ScChangeAction
& rAction
,
533 const XclExpRoot
& rRoot
,
534 const XclExpChTrTabIdBuffer
& rTabIdBuffer
,
535 sal_uInt16 nNewOpCode
) :
536 sUsername( rAction
.GetUser() ),
537 aDateTime( rAction
.GetDateTime() ),
540 bAccepted( rAction
.IsAccepted() ),
541 rTabInfo( rRoot
.GetTabInfo() ),
542 rIdBuffer( rTabIdBuffer
),
544 nOpCode( nNewOpCode
),
545 bForceInfo( sal_False
)
547 aDateTime
.SetSec( 0 );
548 aDateTime
.Set100Sec( 0 );
551 XclExpChTrAction::~XclExpChTrAction()
557 void XclExpChTrAction::SetAddAction( XclExpChTrAction
* pAction
)
560 pAddAction
->SetAddAction( pAction
);
562 pAddAction
= pAction
;
565 void XclExpChTrAction::AddDependentContents(
566 const ScChangeAction
& rAction
,
567 const XclExpRoot
& rRoot
,
568 ScChangeTrack
& rChangeTrack
)
570 ScChangeActionTable aActionTable
;
571 rChangeTrack
.GetDependents( (ScChangeAction
*)(&rAction
), aActionTable
);
572 for( const ScChangeAction
* pDepAction
= aActionTable
.First(); pDepAction
; pDepAction
= aActionTable
.Next() )
573 if( pDepAction
->GetType() == SC_CAT_CONTENT
)
574 SetAddAction( new XclExpChTrCellContent(
575 *((const ScChangeActionContent
*) pDepAction
), rRoot
, rIdBuffer
) );
578 void XclExpChTrAction::SetIndex( sal_uInt32
& rIndex
)
583 void XclExpChTrAction::SaveCont( XclExpStream
& rStrm
)
585 DBG_ASSERT( nOpCode
!= EXC_CHTR_OP_UNKNOWN
, "XclExpChTrAction::SaveCont - unknown action" );
589 << (sal_uInt16
)(bAccepted
? EXC_CHTR_ACCEPT
: EXC_CHTR_NOTHING
);
590 SaveActionData( rStrm
);
593 void XclExpChTrAction::PrepareSaveAction( XclExpStream
& /*rStrm*/ ) const
597 void XclExpChTrAction::CompleteSaveAction( XclExpStream
& /*rStrm*/ ) const
601 void XclExpChTrAction::Save( XclExpStream
& rStrm
)
603 PrepareSaveAction( rStrm
);
604 ExcRecord::Save( rStrm
);
606 pAddAction
->Save( rStrm
);
607 CompleteSaveAction( rStrm
);
610 sal_Size
XclExpChTrAction::GetLen() const
612 return GetHeaderByteCount() + GetActionByteCount();
615 //___________________________________________________________________
617 XclExpChTrData::XclExpChTrData() :
621 nType( EXC_CHTR_TYPE_EMPTY
),
626 XclExpChTrData::~XclExpChTrData()
631 void XclExpChTrData::Clear()
638 nType
= EXC_CHTR_TYPE_EMPTY
;
642 void XclExpChTrData::WriteFormula( XclExpStream
& rStrm
, const XclExpChTrTabIdBuffer
& rTabIdBuffer
)
644 DBG_ASSERT( mxTokArr
.is() && !mxTokArr
->Empty(), "XclExpChTrData::Write - no formula" );
647 for( XclExpRefLog::const_iterator aIt
= maRefLog
.begin(), aEnd
= maRefLog
.end(); aIt
!= aEnd
; ++aIt
)
649 if( aIt
->mpUrl
&& aIt
->mpFirstTab
)
651 rStrm
<< *aIt
->mpUrl
<< (sal_uInt8
) 0x01 << *aIt
->mpFirstTab
<< (sal_uInt8
) 0x02;
655 bool bSingleTab
= aIt
->mnFirstXclTab
== aIt
->mnLastXclTab
;
656 rStrm
.SetSliceSize( bSingleTab
? 6 : 8 );
657 rStrm
<< (sal_uInt8
) 0x01 << (sal_uInt8
) 0x02 << (sal_uInt8
) 0x00;
658 rStrm
<< rTabIdBuffer
.GetId( aIt
->mnFirstXclTab
);
660 rStrm
<< (sal_uInt8
) 0x02;
662 rStrm
<< (sal_uInt8
) 0x00 << rTabIdBuffer
.GetId( aIt
->mnLastXclTab
);
665 rStrm
.SetSliceSize( 0 );
666 rStrm
<< (sal_uInt8
) 0x00;
669 void XclExpChTrData::Write( XclExpStream
& rStrm
, const XclExpChTrTabIdBuffer
& rTabIdBuffer
)
673 case EXC_CHTR_TYPE_RK
:
676 case EXC_CHTR_TYPE_DOUBLE
:
679 case EXC_CHTR_TYPE_STRING
:
680 DBG_ASSERT( pString
, "XclExpChTrData::Write - no string" );
683 case EXC_CHTR_TYPE_FORMULA
:
684 WriteFormula( rStrm
, rTabIdBuffer
);
689 //___________________________________________________________________
691 XclExpChTrCellContent::XclExpChTrCellContent(
692 const ScChangeActionContent
& rAction
,
693 const XclExpRoot
& rRoot
,
694 const XclExpChTrTabIdBuffer
& rTabIdBuffer
) :
695 XclExpChTrAction( rAction
, rRoot
, rTabIdBuffer
, EXC_CHTR_OP_CELL
),
699 aPosition( rAction
.GetBigRange().MakeRange().aStart
)
703 GetCellData( rAction
.GetOldCell(), pOldData
, nDummy32
, nOldLength
);
704 GetCellData( rAction
.GetNewCell(), pNewData
, nLength
, nDummy16
);
707 XclExpChTrCellContent::~XclExpChTrCellContent()
715 void XclExpChTrCellContent::MakeEmptyChTrData( XclExpChTrData
*& rpData
)
720 rpData
= new XclExpChTrData
;
723 void XclExpChTrCellContent::GetCellData(
724 const ScBaseCell
* pScCell
,
725 XclExpChTrData
*& rpData
,
726 sal_uInt32
& rXclLength1
,
727 sal_uInt16
& rXclLength2
)
729 MakeEmptyChTrData( rpData
);
730 rXclLength1
= 0x0000003A;
731 rXclLength2
= 0x0000;
740 switch( pScCell
->GetCellType() )
744 rpData
->fValue
= ((const ScValueCell
*) pScCell
)->GetValue();
745 if( XclTools::GetRKFromDouble( rpData
->nRKValue
, rpData
->fValue
) )
747 rpData
->nType
= EXC_CHTR_TYPE_RK
;
749 rXclLength1
= 0x0000003E;
750 rXclLength2
= 0x0004;
754 rpData
->nType
= EXC_CHTR_TYPE_DOUBLE
;
756 rXclLength1
= 0x00000042;
757 rXclLength2
= 0x0008;
761 case CELLTYPE_STRING
:
765 if( pScCell
->GetCellType() == CELLTYPE_STRING
)
766 ((const ScStringCell
*) pScCell
)->GetString( sCellStr
);
768 ((const ScEditCell
*) pScCell
)->GetString( sCellStr
);
769 rpData
->pString
= new XclExpString( sCellStr
, EXC_STR_DEFAULT
, 32766 );
770 rpData
->nType
= EXC_CHTR_TYPE_STRING
;
771 rpData
->nSize
= 3 + rpData
->pString
->GetSize();
772 rXclLength1
= 64 + (sCellStr
.Len() << 1);
773 rXclLength2
= 6 + (sal_uInt16
)(sCellStr
.Len() << 1);
776 case CELLTYPE_FORMULA
:
778 const ScFormulaCell
* pFmlCell
= (const ScFormulaCell
*) pScCell
;
779 const ScTokenArray
* pTokenArray
= pFmlCell
->GetCode();
782 XclExpRefLog
& rRefLog
= rpData
->maRefLog
;
783 rpData
->mxTokArr
= GetFormulaCompiler().CreateFormula(
784 EXC_FMLATYPE_CELL
, *pTokenArray
, &pFmlCell
->aPos
, &rRefLog
);
785 rpData
->nType
= EXC_CHTR_TYPE_FORMULA
;
786 sal_Size nSize
= rpData
->mxTokArr
->GetSize() + 3;
788 for( XclExpRefLog::const_iterator aIt
= rRefLog
.begin(), aEnd
= rRefLog
.end(); aIt
!= aEnd
; ++aIt
)
790 if( aIt
->mpUrl
&& aIt
->mpFirstTab
)
791 nSize
+= aIt
->mpUrl
->GetSize() + aIt
->mpFirstTab
->GetSize() + 2;
793 nSize
+= (aIt
->mnFirstXclTab
== aIt
->mnLastXclTab
) ? 6 : 8;
795 rpData
->nSize
= ::std::min
< sal_Size
>( nSize
, 0xFFFF );
796 rXclLength1
= 0x00000052;
797 rXclLength2
= 0x0018;
805 void XclExpChTrCellContent::SaveActionData( XclExpStream
& rStrm
) const
807 WriteTabId( rStrm
, aPosition
.Tab() );
808 rStrm
<< (sal_uInt16
)((pOldData
? (pOldData
->nType
<< 3) : 0x0000) | (pNewData
? pNewData
->nType
: 0x0000))
809 << (sal_uInt16
) 0x0000;
810 Write2DAddress( rStrm
, aPosition
);
812 << (sal_uInt32
) 0x00000000;
814 pOldData
->Write( rStrm
, rIdBuffer
);
816 pNewData
->Write( rStrm
, rIdBuffer
);
819 UINT16
XclExpChTrCellContent::GetNum() const
824 sal_Size
XclExpChTrCellContent::GetActionByteCount() const
828 nLen
+= pOldData
->nSize
;
830 nLen
+= pNewData
->nSize
;
834 //___________________________________________________________________
836 XclExpChTrInsert::XclExpChTrInsert(
837 const ScChangeAction
& rAction
,
838 const XclExpRoot
& rRoot
,
839 const XclExpChTrTabIdBuffer
& rTabIdBuffer
,
840 ScChangeTrack
& rChangeTrack
) :
841 XclExpChTrAction( rAction
, rRoot
, rTabIdBuffer
),
842 aRange( rAction
.GetBigRange().MakeRange() )
844 nLength
= 0x00000030;
845 switch( rAction
.GetType() )
847 case SC_CAT_INSERT_COLS
: nOpCode
= EXC_CHTR_OP_INSCOL
; break;
848 case SC_CAT_INSERT_ROWS
: nOpCode
= EXC_CHTR_OP_INSROW
; break;
849 case SC_CAT_DELETE_COLS
: nOpCode
= EXC_CHTR_OP_DELCOL
; break;
850 case SC_CAT_DELETE_ROWS
: nOpCode
= EXC_CHTR_OP_DELROW
; break;
852 DBG_ERROR( "XclExpChTrInsert::XclExpChTrInsert - unknown action" );
855 if( nOpCode
& EXC_CHTR_OP_COLFLAG
)
857 aRange
.aStart
.SetRow( 0 );
858 aRange
.aEnd
.SetRow( rRoot
.GetXclMaxPos().Row() );
862 aRange
.aStart
.SetCol( 0 );
863 aRange
.aEnd
.SetCol( rRoot
.GetXclMaxPos().Col() );
866 if( nOpCode
& EXC_CHTR_OP_DELFLAG
)
868 SetAddAction( new XclExpChTr0x014A( *this ) );
869 AddDependentContents( rAction
, rRoot
, rChangeTrack
);
873 XclExpChTrInsert::~XclExpChTrInsert()
877 void XclExpChTrInsert::SaveActionData( XclExpStream
& rStrm
) const
879 WriteTabId( rStrm
, aRange
.aStart
.Tab() );
880 rStrm
<< (sal_uInt16
) 0x0000;
881 Write2DRange( rStrm
, aRange
);
882 rStrm
<< (sal_uInt32
) 0x00000000;
885 void XclExpChTrInsert::PrepareSaveAction( XclExpStream
& rStrm
) const
887 if( (nOpCode
== EXC_CHTR_OP_DELROW
) || (nOpCode
== EXC_CHTR_OP_DELCOL
) )
888 XclExpChTrEmpty( 0x0150 ).Save( rStrm
);
891 void XclExpChTrInsert::CompleteSaveAction( XclExpStream
& rStrm
) const
893 if( (nOpCode
== EXC_CHTR_OP_DELROW
) || (nOpCode
== EXC_CHTR_OP_DELCOL
) )
894 XclExpChTrEmpty( 0x0151 ).Save( rStrm
);
897 UINT16
XclExpChTrInsert::GetNum() const
902 sal_Size
XclExpChTrInsert::GetActionByteCount() const
907 //___________________________________________________________________
909 XclExpChTrInsertTab::XclExpChTrInsertTab(
910 const ScChangeAction
& rAction
,
911 const XclExpRoot
& rRoot
,
912 const XclExpChTrTabIdBuffer
& rTabIdBuffer
) :
913 XclExpChTrAction( rAction
, rRoot
, rTabIdBuffer
, EXC_CHTR_OP_INSTAB
),
915 nTab( (SCTAB
) rAction
.GetBigRange().aStart
.Tab() )
917 nLength
= 0x0000021C;
918 bForceInfo
= sal_True
;
921 XclExpChTrInsertTab::~XclExpChTrInsertTab()
925 void XclExpChTrInsertTab::SaveActionData( XclExpStream
& rStrm
) const
927 WriteTabId( rStrm
, nTab
);
928 rStrm
<< sal_uInt32( 0 );
929 lcl_WriteFixedString( rStrm
, XclExpString( GetTabInfo().GetScTabName( nTab
) ), 127 );
930 lcl_WriteDateTime( rStrm
, GetDateTime() );
931 rStrm
.WriteZeroBytes( 133 );
934 UINT16
XclExpChTrInsertTab::GetNum() const
939 sal_Size
XclExpChTrInsertTab::GetActionByteCount() const
944 //___________________________________________________________________
946 XclExpChTrMoveRange::XclExpChTrMoveRange(
947 const ScChangeActionMove
& rAction
,
948 const XclExpRoot
& rRoot
,
949 const XclExpChTrTabIdBuffer
& rTabIdBuffer
,
950 ScChangeTrack
& rChangeTrack
) :
951 XclExpChTrAction( rAction
, rRoot
, rTabIdBuffer
, EXC_CHTR_OP_MOVE
),
952 aDestRange( rAction
.GetBigRange().MakeRange() )
954 nLength
= 0x00000042;
955 aSourceRange
= aDestRange
;
956 sal_Int32 nDCols
, nDRows
, nDTabs
;
957 rAction
.GetDelta( nDCols
, nDRows
, nDTabs
);
958 aSourceRange
.aStart
.IncRow( (SCROW
) -nDRows
);
959 aSourceRange
.aStart
.IncCol( (SCCOL
) -nDCols
);
960 aSourceRange
.aStart
.IncTab( (SCTAB
) -nDTabs
);
961 aSourceRange
.aEnd
.IncRow( (SCROW
) -nDRows
);
962 aSourceRange
.aEnd
.IncCol( (SCCOL
) -nDCols
);
963 aSourceRange
.aEnd
.IncTab( (SCTAB
) -nDTabs
);
964 AddDependentContents( rAction
, rRoot
, rChangeTrack
);
967 XclExpChTrMoveRange::~XclExpChTrMoveRange()
971 void XclExpChTrMoveRange::SaveActionData( XclExpStream
& rStrm
) const
973 WriteTabId( rStrm
, aDestRange
.aStart
.Tab() );
974 Write2DRange( rStrm
, aSourceRange
);
975 Write2DRange( rStrm
, aDestRange
);
976 WriteTabId( rStrm
, aSourceRange
.aStart
.Tab() );
977 rStrm
<< (sal_uInt32
) 0x00000000;
980 void XclExpChTrMoveRange::PrepareSaveAction( XclExpStream
& rStrm
) const
982 XclExpChTrEmpty( 0x014E ).Save( rStrm
);
985 void XclExpChTrMoveRange::CompleteSaveAction( XclExpStream
& rStrm
) const
987 XclExpChTrEmpty( 0x014F ).Save( rStrm
);
990 UINT16
XclExpChTrMoveRange::GetNum() const
995 sal_Size
XclExpChTrMoveRange::GetActionByteCount() const
1000 //___________________________________________________________________
1002 XclExpChTr0x014A::XclExpChTr0x014A( const XclExpChTrInsert
& rAction
) :
1003 XclExpChTrInsert( rAction
)
1005 nLength
= 0x00000026;
1006 nOpCode
= EXC_CHTR_OP_FORMAT
;
1009 XclExpChTr0x014A::~XclExpChTr0x014A()
1013 void XclExpChTr0x014A::SaveActionData( XclExpStream
& rStrm
) const
1015 WriteTabId( rStrm
, aRange
.aStart
.Tab() );
1016 rStrm
<< (sal_uInt16
) 0x0003
1017 << (sal_uInt16
) 0x0001;
1018 Write2DRange( rStrm
, aRange
);
1021 UINT16
XclExpChTr0x014A::GetNum() const
1026 sal_Size
XclExpChTr0x014A::GetActionByteCount() const
1031 //___________________________________________________________________
1033 XclExpChTrActionStack::~XclExpChTrActionStack()
1035 while( XclExpChTrAction
* pRec
= Pop() )
1039 void XclExpChTrActionStack::Push( XclExpChTrAction
* pNewRec
)
1041 DBG_ASSERT( pNewRec
, "XclExpChTrActionStack::Push - NULL pointer" );
1043 Stack::Push( pNewRec
);
1046 //___________________________________________________________________
1048 XclExpChTrRecordList::~XclExpChTrRecordList()
1050 for( ExcRecord
* pRec
= First(); pRec
; pRec
= Next() )
1054 void XclExpChTrRecordList::Append( ExcRecord
* pNewRec
)
1056 DBG_ASSERT( pNewRec
, "XclExpChTrRecordList::Append - NULL pointer" );
1058 List::Insert( pNewRec
, LIST_APPEND
);
1061 void XclExpChTrRecordList::Save( XclExpStream
& rStrm
)
1063 for( ExcRecord
* pRec
= First(); pRec
; pRec
= Next() )
1064 pRec
->Save( rStrm
);
1067 //___________________________________________________________________
1069 XclExpChangeTrack::XclExpChangeTrack( const XclExpRoot
& rRoot
) :
1070 XclExpRoot( rRoot
),
1074 pTabIdBuffer( NULL
),
1078 bValidGUID( sal_False
)
1080 DBG_ASSERT( GetOldRoot().pTabId
, "XclExpChangeTrack::XclExpChangeTrack - root data incomplete" );
1081 if( !GetOldRoot().pTabId
)
1084 ScChangeTrack
* pTempChangeTrack
= CreateTempChangeTrack();
1085 if (!pTempChangeTrack
)
1088 pTabIdBuffer
= new XclExpChTrTabIdBuffer( GetTabInfo().GetXclTabCount() );
1089 aTabIdBufferList
.Append( pTabIdBuffer
);
1091 // calculate final table order (tab id list)
1092 const ScChangeAction
* pScAction
;
1093 for( pScAction
= pTempChangeTrack
->GetLast(); pScAction
; pScAction
= pScAction
->GetPrev() )
1095 if( pScAction
->GetType() == SC_CAT_INSERT_TABS
)
1097 SCTAB nScTab
= static_cast< SCTAB
>( pScAction
->GetBigRange().aStart
.Tab() );
1098 pTabIdBuffer
->InitFill( GetTabInfo().GetXclTab( nScTab
) );
1101 pTabIdBuffer
->InitFillup();
1102 GetOldRoot().pTabId
->Copy( *pTabIdBuffer
);
1104 // get actions in reverse order
1105 pScAction
= pTempChangeTrack
->GetLast();
1108 PushActionRecord( *pScAction
);
1109 const ScChangeAction
* pPrevAction
= pScAction
->GetPrev();
1110 pTempChangeTrack
->Undo( pScAction
->GetActionNumber(), pScAction
->GetActionNumber() );
1111 pScAction
= pPrevAction
;
1114 // build record list
1115 pHeader
= new XclExpChTrHeader
;
1116 aRecList
.Append( pHeader
);
1117 aRecList
.Append( new XclExpChTr0x0195
);
1118 aRecList
.Append( new XclExpChTr0x0194( *pTempChangeTrack
) );
1120 String sLastUsername
;
1121 DateTime aLastDateTime
;
1122 sal_uInt32 nIndex
= 1;
1123 while( XclExpChTrAction
* pAction
= aActionStack
.Pop() )
1125 if( (nIndex
== 1) || pAction
->ForceInfoRecord() ||
1126 (pAction
->GetUsername() != sLastUsername
) ||
1127 (pAction
->GetDateTime() != aLastDateTime
) )
1129 lcl_GenerateGUID( aGUID
, bValidGUID
);
1130 sLastUsername
= pAction
->GetUsername();
1131 aLastDateTime
= pAction
->GetDateTime();
1132 aRecList
.Append( new XclExpChTrInfo( sLastUsername
, aLastDateTime
, aGUID
) );
1133 aRecList
.Append( new XclExpChTrTabId( pAction
->GetTabIdBuffer() ) );
1134 pHeader
->SetGUID( aGUID
);
1136 pAction
->SetIndex( nIndex
);
1137 aRecList
.Append( pAction
);
1140 pHeader
->SetGUID( aGUID
);
1141 pHeader
->SetCount( nIndex
- 1 );
1142 aRecList
.Append( new ExcEof
);
1145 XclExpChangeTrack::~XclExpChangeTrack()
1151 ScChangeTrack
* XclExpChangeTrack::CreateTempChangeTrack()
1153 // get original change track
1154 ScChangeTrack
* pOrigChangeTrack
= GetDoc().GetChangeTrack();
1155 DBG_ASSERT( pOrigChangeTrack
, "XclExpChangeTrack::CreateTempChangeTrack - no change track data" );
1156 if( !pOrigChangeTrack
)
1159 // create empty document
1160 pTempDoc
= new ScDocument
;
1161 DBG_ASSERT( pTempDoc
, "XclExpChangeTrack::CreateTempChangeTrack - no temp document" );
1165 // adjust table count
1166 SCTAB nOrigCount
= GetDoc().GetTableCount();
1168 for( sal_Int32 nIndex
= 0; nIndex
< nOrigCount
; nIndex
++ )
1170 pTempDoc
->CreateValidTabName( sTabName
);
1171 pTempDoc
->InsertTab( SC_TAB_APPEND
, sTabName
);
1173 DBG_ASSERT( nOrigCount
== pTempDoc
->GetTableCount(),
1174 "XclExpChangeTrack::CreateTempChangeTrack - table count mismatch" );
1175 if( nOrigCount
!= pTempDoc
->GetTableCount() )
1178 return pOrigChangeTrack
->Clone(pTempDoc
);
1181 void XclExpChangeTrack::PushActionRecord( const ScChangeAction
& rAction
)
1183 XclExpChTrAction
* pXclAction
= NULL
;
1184 ScChangeTrack
* pTempChangeTrack
= pTempDoc
->GetChangeTrack();
1185 switch( rAction
.GetType() )
1187 case SC_CAT_CONTENT
:
1188 pXclAction
= new XclExpChTrCellContent( (const ScChangeActionContent
&) rAction
, GetRoot(), *pTabIdBuffer
);
1190 case SC_CAT_INSERT_ROWS
:
1191 case SC_CAT_INSERT_COLS
:
1192 case SC_CAT_DELETE_ROWS
:
1193 case SC_CAT_DELETE_COLS
:
1194 if (pTempChangeTrack
)
1195 pXclAction
= new XclExpChTrInsert( rAction
, GetRoot(), *pTabIdBuffer
, *pTempChangeTrack
);
1197 case SC_CAT_INSERT_TABS
:
1199 pXclAction
= new XclExpChTrInsertTab( rAction
, GetRoot(), *pTabIdBuffer
);
1200 XclExpChTrTabIdBuffer
* pNewBuffer
= new XclExpChTrTabIdBuffer( *pTabIdBuffer
);
1201 pNewBuffer
->Remove();
1202 aTabIdBufferList
.Append( pNewBuffer
);
1203 pTabIdBuffer
= pNewBuffer
;
1207 if (pTempChangeTrack
)
1208 pXclAction
= new XclExpChTrMoveRange( (const ScChangeActionMove
&) rAction
, GetRoot(), *pTabIdBuffer
, *pTempChangeTrack
);
1213 aActionStack
.Push( pXclAction
);
1216 sal_Bool
XclExpChangeTrack::WriteUserNamesStream()
1218 sal_Bool bRet
= sal_False
;
1219 SotStorageStreamRef xSvStrm
= OpenStream( EXC_STREAM_USERNAMES
);
1220 DBG_ASSERT( xSvStrm
.Is(), "XclExpChangeTrack::WriteUserNamesStream - no stream" );
1223 XclExpStream
aXclStrm( *xSvStrm
, GetRoot() );
1224 XclExpChTr0x0191().Save( aXclStrm
);
1225 XclExpChTr0x0198().Save( aXclStrm
);
1226 XclExpChTr0x0192().Save( aXclStrm
);
1227 XclExpChTr0x0197().Save( aXclStrm
);
1234 void XclExpChangeTrack::Write()
1236 if( !aRecList
.Count() )
1239 if( WriteUserNamesStream() )
1241 SotStorageStreamRef xSvStrm
= OpenStream( EXC_STREAM_REVLOG
);
1242 DBG_ASSERT( xSvStrm
.Is(), "XclExpChangeTrack::Write - no stream" );
1245 XclExpStream
aXclStrm( *xSvStrm
, GetRoot(), EXC_MAXRECSIZE_BIFF8
+ 8 );
1246 aRecList
.Save( aXclStrm
);