xref: /AOO41X/main/sc/source/filter/xcl97/XclExpChangeTrack.cxx (revision ca62e2c2083b5d0995f1245bad6c2edfb455fbec)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26 
27 
28 //___________________________________________________________________
29 
30 #include <sot/storage.hxx>
31 #include "XclExpChangeTrack.hxx"
32 #include "xeformula.hxx"
33 #include "cell.hxx"
34 #include "xcl97rec.hxx"
35 
36 //___________________________________________________________________
37 // local functions
38 
lcl_WriteDateTime(XclExpStream & rStrm,const DateTime & rDateTime)39 void lcl_WriteDateTime( XclExpStream& rStrm, const DateTime& rDateTime )
40 {
41     rStrm.SetSliceSize( 7 );
42     rStrm   << (sal_uInt16) rDateTime.GetYear()
43             << (sal_uInt8)  rDateTime.GetMonth()
44             << (sal_uInt8)  rDateTime.GetDay()
45             << (sal_uInt8)  rDateTime.GetHour()
46             << (sal_uInt8)  rDateTime.GetMin()
47             << (sal_uInt8)  rDateTime.GetSec();
48     rStrm.SetSliceSize( 0 );
49 }
50 
51 // write string and fill rest of <nLength> with zero bytes
52 // <nLength> is without string header
lcl_WriteFixedString(XclExpStream & rStrm,const XclExpString & rString,sal_Size nLength)53 void lcl_WriteFixedString( XclExpStream& rStrm, const XclExpString& rString, sal_Size nLength )
54 {
55     sal_Size nStrBytes = rString.GetBufferSize();
56     DBG_ASSERT( nLength >= nStrBytes, "lcl_WriteFixedString - String too long" );
57     if( rString.Len() > 0 )
58         rStrm << rString;
59     if( nLength > nStrBytes )
60         rStrm.WriteZeroBytes( nLength - nStrBytes );
61 }
62 
lcl_GenerateGUID(sal_uInt8 * pGUID,sal_Bool & rValidGUID)63 inline void lcl_GenerateGUID( sal_uInt8* pGUID, sal_Bool& rValidGUID )
64 {
65     rtl_createUuid( pGUID, rValidGUID ? pGUID : NULL, sal_False );
66     rValidGUID = sal_True;
67 }
68 
lcl_WriteGUID(XclExpStream & rStrm,const sal_uInt8 * pGUID)69 inline void lcl_WriteGUID( XclExpStream& rStrm, const sal_uInt8* pGUID )
70 {
71     rStrm.SetSliceSize( 16 );
72     for( sal_Size nIndex = 0; nIndex < 16; nIndex++ )
73         rStrm << pGUID[ nIndex ];
74     rStrm.SetSliceSize( 0 );
75 }
76 
77 //___________________________________________________________________
78 
XclExpUserBView(const String & rUsername,const sal_uInt8 * pGUID)79 XclExpUserBView::XclExpUserBView( const String& rUsername, const sal_uInt8* pGUID ) :
80     sUsername( rUsername )
81 {
82     memcpy( aGUID, pGUID, 16 );
83 }
84 
SaveCont(XclExpStream & rStrm)85 void XclExpUserBView::SaveCont( XclExpStream& rStrm )
86 {
87     rStrm   << (sal_uInt32) 0xFF078014
88             << (sal_uInt32) 0x00000001;
89     lcl_WriteGUID( rStrm, aGUID );
90     rStrm.WriteZeroBytes( 8 );
91     rStrm   << (sal_uInt32) 1200
92             << (sal_uInt32) 1000
93             << (sal_uInt16) 1000
94             << (sal_uInt16) 0x0CF7
95             << (sal_uInt16) 0x0000
96             << (sal_uInt16) 0x0001
97             << (sal_uInt16) 0x0000;
98     if( sUsername.Len() > 0 )
99         rStrm << sUsername;
100 }
101 
GetNum() const102 sal_uInt16 XclExpUserBView::GetNum() const
103 {
104     return 0x01A9;
105 }
106 
GetLen() const107 sal_Size XclExpUserBView::GetLen() const
108 {
109     return 50 + ((sUsername.Len() > 0) ? sUsername.GetSize() : 0);
110 }
111 
112 //___________________________________________________________________
113 
XclExpUserBViewList(const ScChangeTrack & rChangeTrack)114 XclExpUserBViewList::XclExpUserBViewList( const ScChangeTrack& rChangeTrack )
115 {
116     sal_uInt8 aGUID[ 16 ];
117     sal_Bool bValidGUID = sal_False;
118     const ScStrCollection& rStrColl = rChangeTrack.GetUserCollection();
119     for( sal_uInt16 nIndex = 0; nIndex < rStrColl.GetCount(); nIndex++ )
120     {
121         const StrData* pStrData = (const StrData*) rStrColl.At( nIndex );
122         lcl_GenerateGUID( aGUID, bValidGUID );
123         if( pStrData )
124             List::Insert( new XclExpUserBView( pStrData->GetString(), aGUID ), LIST_APPEND );
125     }
126 }
127 
~XclExpUserBViewList()128 XclExpUserBViewList::~XclExpUserBViewList()
129 {
130     for( XclExpUserBView* pRec = _First(); pRec; pRec = _Next() )
131         delete pRec;
132 }
133 
Save(XclExpStream & rStrm)134 void XclExpUserBViewList::Save( XclExpStream& rStrm )
135 {
136     for( XclExpUserBView* pRec = _First(); pRec; pRec = _Next() )
137         pRec->Save( rStrm );
138 }
139 
140 //___________________________________________________________________
141 
XclExpUsersViewBegin(const sal_uInt8 * pGUID,sal_uInt32 nTab)142 XclExpUsersViewBegin::XclExpUsersViewBegin( const sal_uInt8* pGUID, sal_uInt32 nTab ) :
143     nCurrTab( nTab )
144 {
145     memcpy( aGUID, pGUID, 16 );
146 }
147 
SaveCont(XclExpStream & rStrm)148 void XclExpUsersViewBegin::SaveCont( XclExpStream& rStrm )
149 {
150     lcl_WriteGUID( rStrm, aGUID );
151     rStrm   << nCurrTab
152             << (sal_uInt32) 100
153             << (sal_uInt32) 64
154             << (sal_uInt32) 3
155             << (sal_uInt32) 0x0000003C
156             << (sal_uInt16) 0
157             << (sal_uInt16) 3
158             << (sal_uInt16) 0
159             << (sal_uInt16) 3
160             << (double)     0
161             << (double)     0
162             << (sal_Int16)  -1
163             << (sal_Int16)  -1;
164 }
165 
GetNum() const166 sal_uInt16 XclExpUsersViewBegin::GetNum() const
167 {
168     return 0x01AA;
169 }
170 
GetLen() const171 sal_Size XclExpUsersViewBegin::GetLen() const
172 {
173     return 64;
174 }
175 
176 //___________________________________________________________________
177 
SaveCont(XclExpStream & rStrm)178 void XclExpUsersViewEnd::SaveCont( XclExpStream& rStrm )
179 {
180     rStrm << (sal_uInt16) 0x0001;
181 }
182 
GetNum() const183 sal_uInt16 XclExpUsersViewEnd::GetNum() const
184 {
185     return 0x01AB;
186 }
187 
GetLen() const188 sal_Size XclExpUsersViewEnd::GetLen() const
189 {
190     return 2;
191 }
192 
193 //___________________________________________________________________
194 
SaveCont(XclExpStream & rStrm)195 void XclExpChTr0x0191::SaveCont( XclExpStream& rStrm )
196 {
197     rStrm << (sal_uInt16) 0x0000;
198 }
199 
GetNum() const200 sal_uInt16 XclExpChTr0x0191::GetNum() const
201 {
202     return 0x0191;
203 }
204 
GetLen() const205 sal_Size XclExpChTr0x0191::GetLen() const
206 {
207     return 2;
208 }
209 
210 //___________________________________________________________________
211 
SaveCont(XclExpStream & rStrm)212 void XclExpChTr0x0198::SaveCont( XclExpStream& rStrm )
213 {
214     rStrm   << (sal_uInt16) 0x0006
215             << (sal_uInt16) 0x0000;
216 }
217 
GetNum() const218 sal_uInt16 XclExpChTr0x0198::GetNum() const
219 {
220     return 0x0198;
221 }
222 
GetLen() const223 sal_Size XclExpChTr0x0198::GetLen() const
224 {
225     return 4;
226 }
227 
228 //___________________________________________________________________
229 
SaveCont(XclExpStream & rStrm)230 void XclExpChTr0x0192::SaveCont( XclExpStream& rStrm )
231 {
232     rStrm << sal_uInt16( 0x0022 );
233     rStrm.WriteZeroBytes( 510 );
234 }
235 
GetNum() const236 sal_uInt16 XclExpChTr0x0192::GetNum() const
237 {
238     return 0x0192;
239 }
240 
GetLen() const241 sal_Size XclExpChTr0x0192::GetLen() const
242 {
243     return 512;
244 }
245 
246 //___________________________________________________________________
247 
SaveCont(XclExpStream & rStrm)248 void XclExpChTr0x0197::SaveCont( XclExpStream& rStrm )
249 {
250     rStrm << (sal_uInt16) 0x0000;
251 }
252 
GetNum() const253 sal_uInt16 XclExpChTr0x0197::GetNum() const
254 {
255     return 0x0197;
256 }
257 
GetLen() const258 sal_Size XclExpChTr0x0197::GetLen() const
259 {
260     return 2;
261 }
262 
263 //___________________________________________________________________
264 
~XclExpChTrEmpty()265 XclExpChTrEmpty::~XclExpChTrEmpty()
266 {
267 }
268 
GetNum() const269 sal_uInt16 XclExpChTrEmpty::GetNum() const
270 {
271     return nRecNum;
272 }
273 
GetLen() const274 sal_Size XclExpChTrEmpty::GetLen() const
275 {
276     return 0;
277 }
278 
279 //___________________________________________________________________
280 
~XclExpChTr0x0195()281 XclExpChTr0x0195::~XclExpChTr0x0195()
282 {
283 }
284 
SaveCont(XclExpStream & rStrm)285 void XclExpChTr0x0195::SaveCont( XclExpStream& rStrm )
286 {
287     rStrm.WriteZeroBytes( 162 );
288 }
289 
GetNum() const290 sal_uInt16 XclExpChTr0x0195::GetNum() const
291 {
292     return 0x0195;
293 }
294 
GetLen() const295 sal_Size XclExpChTr0x0195::GetLen() const
296 {
297     return 162;
298 }
299 
300 //___________________________________________________________________
301 
~XclExpChTr0x0194()302 XclExpChTr0x0194::~XclExpChTr0x0194()
303 {
304 }
305 
SaveCont(XclExpStream & rStrm)306 void XclExpChTr0x0194::SaveCont( XclExpStream& rStrm )
307 {
308     rStrm << (sal_uInt32) 0;
309     lcl_WriteDateTime( rStrm, aDateTime );
310     rStrm << (sal_uInt8) 0;
311     lcl_WriteFixedString( rStrm, sUsername, 147 );
312 }
313 
GetNum() const314 sal_uInt16 XclExpChTr0x0194::GetNum() const
315 {
316     return 0x0194;
317 }
318 
GetLen() const319 sal_Size XclExpChTr0x0194::GetLen() const
320 {
321     return 162;
322 }
323 
324 //___________________________________________________________________
325 
~XclExpChTrHeader()326 XclExpChTrHeader::~XclExpChTrHeader()
327 {
328 }
329 
SaveCont(XclExpStream & rStrm)330 void XclExpChTrHeader::SaveCont( XclExpStream& rStrm )
331 {
332     rStrm   << (sal_uInt16) 0x0006
333             << (sal_uInt16) 0x0000
334             << (sal_uInt16) 0x000D;
335     lcl_WriteGUID( rStrm, aGUID );
336     lcl_WriteGUID( rStrm, aGUID );
337     rStrm   << nCount
338             << (sal_uInt16) 0x0001
339             << (sal_uInt32) 0x00000000
340             << (sal_uInt16) 0x001E;
341 }
342 
GetNum() const343 sal_uInt16 XclExpChTrHeader::GetNum() const
344 {
345     return 0x0196;
346 }
347 
GetLen() const348 sal_Size XclExpChTrHeader::GetLen() const
349 {
350     return 50;
351 }
352 
353 //___________________________________________________________________
354 
~XclExpChTrInfo()355 XclExpChTrInfo::~XclExpChTrInfo()
356 {
357 }
358 
SaveCont(XclExpStream & rStrm)359 void XclExpChTrInfo::SaveCont( XclExpStream& rStrm )
360 {
361     rStrm   << (sal_uInt32) 0xFFFFFFFF
362             << (sal_uInt32) 0x00000000
363             << (sal_uInt32) 0x00000020
364             << (sal_uInt16) 0xFFFF;
365     lcl_WriteGUID( rStrm, aGUID );
366     rStrm   << (sal_uInt16) 0x04B0;
367     lcl_WriteFixedString( rStrm, sUsername, 113 );
368     lcl_WriteDateTime( rStrm, aDateTime );
369     rStrm   << (sal_uInt8)  0x0000
370             << (sal_uInt16) 0x0002;
371 }
372 
GetNum() const373 sal_uInt16 XclExpChTrInfo::GetNum() const
374 {
375     return 0x0138;
376 }
377 
GetLen() const378 sal_Size XclExpChTrInfo::GetLen() const
379 {
380     return 158;
381 }
382 
383 //___________________________________________________________________
384 
XclExpChTrTabIdBuffer(sal_uInt16 nCount)385 XclExpChTrTabIdBuffer::XclExpChTrTabIdBuffer( sal_uInt16 nCount ) :
386     nBufSize( nCount ),
387     nLastId( nCount )
388 {
389     pBuffer = new sal_uInt16[ nBufSize ];
390     memset( pBuffer, 0, sizeof(sal_uInt16) * nBufSize );
391     pLast = pBuffer + nBufSize - 1;
392 }
393 
XclExpChTrTabIdBuffer(const XclExpChTrTabIdBuffer & rCopy)394 XclExpChTrTabIdBuffer::XclExpChTrTabIdBuffer( const XclExpChTrTabIdBuffer& rCopy ) :
395     nBufSize( rCopy.nBufSize ),
396     nLastId( rCopy.nLastId )
397 {
398     pBuffer = new sal_uInt16[ nBufSize ];
399     memcpy( pBuffer, rCopy.pBuffer, sizeof(sal_uInt16) * nBufSize );
400     pLast = pBuffer + nBufSize - 1;
401 }
402 
~XclExpChTrTabIdBuffer()403 XclExpChTrTabIdBuffer::~XclExpChTrTabIdBuffer()
404 {
405     delete[] pBuffer;
406 }
407 
InitFill(sal_uInt16 nIndex)408 void XclExpChTrTabIdBuffer::InitFill( sal_uInt16 nIndex )
409 {
410     DBG_ASSERT( nIndex < nLastId, "XclExpChTrTabIdBuffer::Insert - out of range" );
411 
412     sal_uInt16 nFreeCount = 0;
413     for( sal_uInt16* pElem = pBuffer; pElem <= pLast; pElem++ )
414     {
415         if( !*pElem )
416             nFreeCount++;
417         if( nFreeCount > nIndex )
418         {
419             *pElem = nLastId--;
420             return;
421         }
422     }
423 }
424 
InitFillup()425 void XclExpChTrTabIdBuffer::InitFillup()
426 {
427     sal_uInt16 nFreeCount = 1;
428     for( sal_uInt16* pElem = pBuffer; pElem <= pLast; pElem++ )
429         if( !*pElem )
430             *pElem = nFreeCount++;
431     nLastId = nBufSize;
432 }
433 
GetId(sal_uInt16 nIndex) const434 sal_uInt16 XclExpChTrTabIdBuffer::GetId( sal_uInt16 nIndex ) const
435 {
436     DBG_ASSERT( nIndex < nBufSize, "XclExpChTrTabIdBuffer::GetId - out of range" );
437     return pBuffer[ nIndex ];
438 }
439 
Remove()440 void XclExpChTrTabIdBuffer::Remove()
441 {
442     DBG_ASSERT( pBuffer <= pLast, "XclExpChTrTabIdBuffer::Remove - buffer empty" );
443     sal_uInt16* pElem = pBuffer;
444     while( (pElem <= pLast) && (*pElem != nLastId) )
445         pElem++;
446     while( pElem < pLast )
447     {
448         *pElem = *(pElem + 1);
449         pElem++;
450     }
451     pLast--;
452     nLastId--;
453 }
454 
455 //___________________________________________________________________
456 
~XclExpChTrTabIdBufferList()457 XclExpChTrTabIdBufferList::~XclExpChTrTabIdBufferList()
458 {
459     for( XclExpChTrTabIdBuffer* pBuffer = First(); pBuffer; pBuffer = Next() )
460         delete pBuffer;
461 }
462 
463 //___________________________________________________________________
464 
XclExpChTrTabId(const XclExpChTrTabIdBuffer & rBuffer)465 XclExpChTrTabId::XclExpChTrTabId( const XclExpChTrTabIdBuffer& rBuffer ) :
466     nTabCount( rBuffer.GetBufferCount() )
467 {
468     pBuffer = new sal_uInt16[ nTabCount ];
469     rBuffer.GetBufferCopy( pBuffer );
470 }
471 
~XclExpChTrTabId()472 XclExpChTrTabId::~XclExpChTrTabId()
473 {
474     Clear();
475 }
476 
Copy(const XclExpChTrTabIdBuffer & rBuffer)477 void XclExpChTrTabId::Copy( const XclExpChTrTabIdBuffer& rBuffer )
478 {
479     Clear();
480     nTabCount = rBuffer.GetBufferCount();
481     pBuffer = new sal_uInt16[ nTabCount ];
482     rBuffer.GetBufferCopy( pBuffer );
483 }
484 
SaveCont(XclExpStream & rStrm)485 void XclExpChTrTabId::SaveCont( XclExpStream& rStrm )
486 {
487     rStrm.EnableEncryption();
488     if( pBuffer )
489         for( sal_uInt16* pElem = pBuffer; pElem < (pBuffer + nTabCount); pElem++ )
490             rStrm << *pElem;
491     else
492         for( sal_uInt16 nIndex = 1; nIndex <= nTabCount; nIndex++ )
493             rStrm << nIndex;
494 }
495 
GetNum() const496 sal_uInt16 XclExpChTrTabId::GetNum() const
497 {
498     return 0x013D;
499 }
500 
GetLen() const501 sal_Size XclExpChTrTabId::GetLen() const
502 {
503     return nTabCount << 1;
504 }
505 
506 //___________________________________________________________________
507 
508 // ! does not copy additional actions
XclExpChTrAction(const XclExpChTrAction & rCopy)509 XclExpChTrAction::XclExpChTrAction( const XclExpChTrAction& rCopy ) :
510     ExcRecord( rCopy ),
511     sUsername( rCopy.sUsername ),
512     aDateTime( rCopy.aDateTime ),
513     nIndex( 0 ),
514     pAddAction( 0 ),
515     bAccepted( rCopy.bAccepted ),
516     rTabInfo( rCopy.rTabInfo ),
517     rIdBuffer( rCopy.rIdBuffer ),
518     nLength( rCopy.nLength ),
519     nOpCode( rCopy.nOpCode ),
520     bForceInfo( rCopy.bForceInfo )
521 {
522 }
523 
XclExpChTrAction(const ScChangeAction & rAction,const XclExpRoot & rRoot,const XclExpChTrTabIdBuffer & rTabIdBuffer,sal_uInt16 nNewOpCode)524 XclExpChTrAction::XclExpChTrAction(
525         const ScChangeAction& rAction,
526         const XclExpRoot& rRoot,
527         const XclExpChTrTabIdBuffer& rTabIdBuffer,
528         sal_uInt16 nNewOpCode ) :
529     sUsername( rAction.GetUser() ),
530     aDateTime( rAction.GetDateTime() ),
531     nIndex( 0 ),
532     pAddAction( NULL ),
533     bAccepted( rAction.IsAccepted() ),
534     rTabInfo( rRoot.GetTabInfo() ),
535     rIdBuffer( rTabIdBuffer ),
536     nLength( 0 ),
537     nOpCode( nNewOpCode ),
538     bForceInfo( sal_False )
539 {
540     aDateTime.SetSec( 0 );
541     aDateTime.Set100Sec( 0 );
542 }
543 
~XclExpChTrAction()544 XclExpChTrAction::~XclExpChTrAction()
545 {
546     if( pAddAction )
547         delete pAddAction;
548 }
549 
SetAddAction(XclExpChTrAction * pAction)550 void XclExpChTrAction::SetAddAction( XclExpChTrAction* pAction )
551 {
552     if( pAddAction )
553         pAddAction->SetAddAction( pAction );
554     else
555         pAddAction = pAction;
556 }
557 
AddDependentContents(const ScChangeAction & rAction,const XclExpRoot & rRoot,ScChangeTrack & rChangeTrack)558 void XclExpChTrAction::AddDependentContents(
559         const ScChangeAction& rAction,
560         const XclExpRoot& rRoot,
561         ScChangeTrack& rChangeTrack )
562 {
563     ScChangeActionTable aActionTable;
564     rChangeTrack.GetDependents( (ScChangeAction*)(&rAction), aActionTable );
565     for( const ScChangeAction* pDepAction = aActionTable.First(); pDepAction; pDepAction = aActionTable.Next() )
566         if( pDepAction->GetType() == SC_CAT_CONTENT )
567             SetAddAction( new XclExpChTrCellContent(
568                 *((const ScChangeActionContent*) pDepAction), rRoot, rIdBuffer ) );
569 }
570 
SetIndex(sal_uInt32 & rIndex)571 void XclExpChTrAction::SetIndex( sal_uInt32& rIndex )
572 {
573     nIndex = rIndex++;
574 }
575 
SaveCont(XclExpStream & rStrm)576 void XclExpChTrAction::SaveCont( XclExpStream& rStrm )
577 {
578     DBG_ASSERT( nOpCode != EXC_CHTR_OP_UNKNOWN, "XclExpChTrAction::SaveCont - unknown action" );
579     rStrm   << nLength
580             << nIndex
581             << nOpCode
582             << (sal_uInt16)(bAccepted ? EXC_CHTR_ACCEPT : EXC_CHTR_NOTHING);
583     SaveActionData( rStrm );
584 }
585 
PrepareSaveAction(XclExpStream &) const586 void XclExpChTrAction::PrepareSaveAction( XclExpStream& /*rStrm*/ ) const
587 {
588 }
589 
CompleteSaveAction(XclExpStream &) const590 void XclExpChTrAction::CompleteSaveAction( XclExpStream& /*rStrm*/ ) const
591 {
592 }
593 
Save(XclExpStream & rStrm)594 void XclExpChTrAction::Save( XclExpStream& rStrm )
595 {
596     PrepareSaveAction( rStrm );
597     ExcRecord::Save( rStrm );
598     if( pAddAction )
599         pAddAction->Save( rStrm );
600     CompleteSaveAction( rStrm );
601 }
602 
GetLen() const603 sal_Size XclExpChTrAction::GetLen() const
604 {
605     return GetHeaderByteCount() + GetActionByteCount();
606 }
607 
608 //___________________________________________________________________
609 
XclExpChTrData()610 XclExpChTrData::XclExpChTrData() :
611     pString( NULL ),
612     fValue( 0.0 ),
613     nRKValue( 0 ),
614     nType( EXC_CHTR_TYPE_EMPTY ),
615     nSize( 0 )
616 {
617 }
618 
~XclExpChTrData()619 XclExpChTrData::~XclExpChTrData()
620 {
621     Clear();
622 }
623 
Clear()624 void XclExpChTrData::Clear()
625 {
626     DELETEZ( pString );
627     mxTokArr.reset();
628     maRefLog.clear();
629     fValue = 0.0;
630     nRKValue = 0;
631     nType = EXC_CHTR_TYPE_EMPTY;
632     nSize = 0;
633 }
634 
WriteFormula(XclExpStream & rStrm,const XclExpChTrTabIdBuffer & rTabIdBuffer)635 void XclExpChTrData::WriteFormula( XclExpStream& rStrm, const XclExpChTrTabIdBuffer& rTabIdBuffer )
636 {
637     DBG_ASSERT( mxTokArr.is() && !mxTokArr->Empty(), "XclExpChTrData::Write - no formula" );
638     rStrm << *mxTokArr;
639 
640     for( XclExpRefLog::const_iterator aIt = maRefLog.begin(), aEnd = maRefLog.end(); aIt != aEnd; ++aIt )
641     {
642         if( aIt->mpUrl && aIt->mpFirstTab )
643         {
644             rStrm << *aIt->mpUrl << (sal_uInt8) 0x01 << *aIt->mpFirstTab << (sal_uInt8) 0x02;
645         }
646         else
647         {
648             bool bSingleTab = aIt->mnFirstXclTab == aIt->mnLastXclTab;
649             rStrm.SetSliceSize( bSingleTab ? 6 : 8 );
650             rStrm << (sal_uInt8) 0x01 << (sal_uInt8) 0x02 << (sal_uInt8) 0x00;
651             rStrm << rTabIdBuffer.GetId( aIt->mnFirstXclTab );
652             if( bSingleTab )
653                 rStrm << (sal_uInt8) 0x02;
654             else
655                 rStrm << (sal_uInt8) 0x00 << rTabIdBuffer.GetId( aIt->mnLastXclTab );
656         }
657     }
658     rStrm.SetSliceSize( 0 );
659     rStrm << (sal_uInt8) 0x00;
660 }
661 
Write(XclExpStream & rStrm,const XclExpChTrTabIdBuffer & rTabIdBuffer)662 void XclExpChTrData::Write( XclExpStream& rStrm, const XclExpChTrTabIdBuffer& rTabIdBuffer )
663 {
664     switch( nType )
665     {
666         case EXC_CHTR_TYPE_RK:
667             rStrm << nRKValue;
668         break;
669         case EXC_CHTR_TYPE_DOUBLE:
670             rStrm << fValue;
671         break;
672         case EXC_CHTR_TYPE_STRING:
673             DBG_ASSERT( pString, "XclExpChTrData::Write - no string" );
674             rStrm << *pString;
675         break;
676         case EXC_CHTR_TYPE_FORMULA:
677             WriteFormula( rStrm, rTabIdBuffer );
678         break;
679     }
680 }
681 
682 //___________________________________________________________________
683 
XclExpChTrCellContent(const ScChangeActionContent & rAction,const XclExpRoot & rRoot,const XclExpChTrTabIdBuffer & rTabIdBuffer)684 XclExpChTrCellContent::XclExpChTrCellContent(
685         const ScChangeActionContent& rAction,
686         const XclExpRoot& rRoot,
687         const XclExpChTrTabIdBuffer& rTabIdBuffer ) :
688     XclExpChTrAction( rAction, rRoot, rTabIdBuffer, EXC_CHTR_OP_CELL ),
689     XclExpRoot( rRoot ),
690     pOldData( 0 ),
691     pNewData( 0 ),
692     aPosition( rAction.GetBigRange().MakeRange().aStart )
693 {
694     sal_uInt32 nDummy32;
695     sal_uInt16 nDummy16;
696     GetCellData( rAction.GetOldCell(), pOldData, nDummy32, nOldLength );
697     GetCellData( rAction.GetNewCell(), pNewData, nLength, nDummy16 );
698 }
699 
~XclExpChTrCellContent()700 XclExpChTrCellContent::~XclExpChTrCellContent()
701 {
702     if( pOldData )
703         delete pOldData;
704     if( pNewData )
705         delete pNewData;
706 }
707 
MakeEmptyChTrData(XclExpChTrData * & rpData)708 void XclExpChTrCellContent::MakeEmptyChTrData( XclExpChTrData*& rpData )
709 {
710     if( rpData )
711         rpData->Clear();
712     else
713         rpData = new XclExpChTrData;
714 }
715 
GetCellData(const ScBaseCell * pScCell,XclExpChTrData * & rpData,sal_uInt32 & rXclLength1,sal_uInt16 & rXclLength2)716 void XclExpChTrCellContent::GetCellData(
717         const ScBaseCell* pScCell,
718         XclExpChTrData*& rpData,
719         sal_uInt32& rXclLength1,
720         sal_uInt16& rXclLength2 )
721 {
722     MakeEmptyChTrData( rpData );
723     rXclLength1 = 0x0000003A;
724     rXclLength2 = 0x0000;
725 
726     if( !pScCell )
727     {
728         delete rpData;
729         rpData = NULL;
730         return;
731     }
732 
733     switch( pScCell->GetCellType() )
734     {
735         case CELLTYPE_VALUE:
736         {
737             rpData->fValue = ((const ScValueCell*) pScCell)->GetValue();
738             if( XclTools::GetRKFromDouble( rpData->nRKValue, rpData->fValue ) )
739             {
740                 rpData->nType = EXC_CHTR_TYPE_RK;
741                 rpData->nSize = 4;
742                 rXclLength1 = 0x0000003E;
743                 rXclLength2 = 0x0004;
744             }
745             else
746             {
747                 rpData->nType = EXC_CHTR_TYPE_DOUBLE;
748                 rpData->nSize = 8;
749                 rXclLength1 = 0x00000042;
750                 rXclLength2 = 0x0008;
751             }
752         }
753         break;
754         case CELLTYPE_STRING:
755         case CELLTYPE_EDIT:
756         {
757             String sCellStr;
758             if( pScCell->GetCellType() == CELLTYPE_STRING )
759                 ((const ScStringCell*) pScCell)->GetString( sCellStr );
760             else
761                 ((const ScEditCell*) pScCell)->GetString( sCellStr );
762             rpData->pString = new XclExpString( sCellStr, EXC_STR_DEFAULT, 32766 );
763             rpData->nType = EXC_CHTR_TYPE_STRING;
764             rpData->nSize = 3 + rpData->pString->GetSize();
765             rXclLength1 = 64 + (sCellStr.Len() << 1);
766             rXclLength2 = 6 + (sal_uInt16)(sCellStr.Len() << 1);
767         }
768         break;
769         case CELLTYPE_FORMULA:
770         {
771             const ScFormulaCell* pFmlCell = (const ScFormulaCell*) pScCell;
772             const ScTokenArray* pTokenArray = pFmlCell->GetCode();
773             if( pTokenArray )
774             {
775                 XclExpRefLog& rRefLog = rpData->maRefLog;
776                 rpData->mxTokArr = GetFormulaCompiler().CreateFormula(
777                     EXC_FMLATYPE_CELL, *pTokenArray, &pFmlCell->aPos, &rRefLog );
778                 rpData->nType = EXC_CHTR_TYPE_FORMULA;
779                 sal_Size nSize = rpData->mxTokArr->GetSize() + 3;
780 
781                 for( XclExpRefLog::const_iterator aIt = rRefLog.begin(), aEnd = rRefLog.end(); aIt != aEnd; ++aIt )
782                 {
783                     if( aIt->mpUrl && aIt->mpFirstTab )
784                         nSize += aIt->mpUrl->GetSize() + aIt->mpFirstTab->GetSize() + 2;
785                     else
786                         nSize += (aIt->mnFirstXclTab == aIt->mnLastXclTab) ? 6 : 8;
787                 }
788                 rpData->nSize = ::std::min< sal_Size >( nSize, 0xFFFF );
789                 rXclLength1 = 0x00000052;
790                 rXclLength2 = 0x0018;
791             }
792         }
793         break;
794         default:;
795     }
796 }
797 
SaveActionData(XclExpStream & rStrm) const798 void XclExpChTrCellContent::SaveActionData( XclExpStream& rStrm ) const
799 {
800     WriteTabId( rStrm, aPosition.Tab() );
801     rStrm   << (sal_uInt16)((pOldData ? (pOldData->nType << 3) : 0x0000) | (pNewData ? pNewData->nType : 0x0000))
802             << (sal_uInt16) 0x0000;
803     Write2DAddress( rStrm, aPosition );
804     rStrm   << nOldLength
805             << (sal_uInt32) 0x00000000;
806     if( pOldData )
807         pOldData->Write( rStrm, rIdBuffer );
808     if( pNewData )
809         pNewData->Write( rStrm, rIdBuffer );
810 }
811 
GetNum() const812 sal_uInt16 XclExpChTrCellContent::GetNum() const
813 {
814     return 0x013B;
815 }
816 
GetActionByteCount() const817 sal_Size XclExpChTrCellContent::GetActionByteCount() const
818 {
819     sal_Size nLen = 16;
820     if( pOldData )
821         nLen += pOldData->nSize;
822     if( pNewData )
823         nLen += pNewData->nSize;
824     return nLen;
825 }
826 
827 //___________________________________________________________________
828 
XclExpChTrInsert(const ScChangeAction & rAction,const XclExpRoot & rRoot,const XclExpChTrTabIdBuffer & rTabIdBuffer,ScChangeTrack & rChangeTrack)829 XclExpChTrInsert::XclExpChTrInsert(
830         const ScChangeAction& rAction,
831         const XclExpRoot& rRoot,
832         const XclExpChTrTabIdBuffer& rTabIdBuffer,
833         ScChangeTrack& rChangeTrack ) :
834     XclExpChTrAction( rAction, rRoot, rTabIdBuffer ),
835     aRange( rAction.GetBigRange().MakeRange() )
836 {
837     nLength = 0x00000030;
838     switch( rAction.GetType() )
839     {
840         case SC_CAT_INSERT_COLS:    nOpCode = EXC_CHTR_OP_INSCOL;   break;
841         case SC_CAT_INSERT_ROWS:    nOpCode = EXC_CHTR_OP_INSROW;   break;
842         case SC_CAT_DELETE_COLS:    nOpCode = EXC_CHTR_OP_DELCOL;   break;
843         case SC_CAT_DELETE_ROWS:    nOpCode = EXC_CHTR_OP_DELROW;   break;
844         default:
845             DBG_ERROR( "XclExpChTrInsert::XclExpChTrInsert - unknown action" );
846     }
847 
848     if( nOpCode & EXC_CHTR_OP_COLFLAG )
849     {
850         aRange.aStart.SetRow( 0 );
851         aRange.aEnd.SetRow( rRoot.GetXclMaxPos().Row() );
852     }
853     else
854     {
855         aRange.aStart.SetCol( 0 );
856         aRange.aEnd.SetCol( rRoot.GetXclMaxPos().Col() );
857     }
858 
859     if( nOpCode & EXC_CHTR_OP_DELFLAG )
860     {
861         SetAddAction( new XclExpChTr0x014A( *this ) );
862         AddDependentContents( rAction, rRoot, rChangeTrack );
863     }
864 }
865 
~XclExpChTrInsert()866 XclExpChTrInsert::~XclExpChTrInsert()
867 {
868 }
869 
SaveActionData(XclExpStream & rStrm) const870 void XclExpChTrInsert::SaveActionData( XclExpStream& rStrm ) const
871 {
872     WriteTabId( rStrm, aRange.aStart.Tab() );
873     rStrm   << (sal_uInt16) 0x0000;
874     Write2DRange( rStrm, aRange );
875     rStrm   << (sal_uInt32) 0x00000000;
876 }
877 
PrepareSaveAction(XclExpStream & rStrm) const878 void XclExpChTrInsert::PrepareSaveAction( XclExpStream& rStrm ) const
879 {
880     if( (nOpCode == EXC_CHTR_OP_DELROW) || (nOpCode == EXC_CHTR_OP_DELCOL) )
881         XclExpChTrEmpty( 0x0150 ).Save( rStrm );
882 }
883 
CompleteSaveAction(XclExpStream & rStrm) const884 void XclExpChTrInsert::CompleteSaveAction( XclExpStream& rStrm ) const
885 {
886     if( (nOpCode == EXC_CHTR_OP_DELROW) || (nOpCode == EXC_CHTR_OP_DELCOL) )
887         XclExpChTrEmpty( 0x0151 ).Save( rStrm );
888 }
889 
GetNum() const890 sal_uInt16 XclExpChTrInsert::GetNum() const
891 {
892     return 0x0137;
893 }
894 
GetActionByteCount() const895 sal_Size XclExpChTrInsert::GetActionByteCount() const
896 {
897     return 16;
898 }
899 
900 //___________________________________________________________________
901 
XclExpChTrInsertTab(const ScChangeAction & rAction,const XclExpRoot & rRoot,const XclExpChTrTabIdBuffer & rTabIdBuffer)902 XclExpChTrInsertTab::XclExpChTrInsertTab(
903         const ScChangeAction& rAction,
904         const XclExpRoot& rRoot,
905         const XclExpChTrTabIdBuffer& rTabIdBuffer ) :
906     XclExpChTrAction( rAction, rRoot, rTabIdBuffer, EXC_CHTR_OP_INSTAB ),
907     XclExpRoot( rRoot ),
908     nTab( (SCTAB) rAction.GetBigRange().aStart.Tab() )
909 {
910     nLength = 0x0000021C;
911     bForceInfo = sal_True;
912 }
913 
~XclExpChTrInsertTab()914 XclExpChTrInsertTab::~XclExpChTrInsertTab()
915 {
916 }
917 
SaveActionData(XclExpStream & rStrm) const918 void XclExpChTrInsertTab::SaveActionData( XclExpStream& rStrm ) const
919 {
920     WriteTabId( rStrm, nTab );
921     rStrm << sal_uInt32( 0 );
922     lcl_WriteFixedString( rStrm, XclExpString( GetTabInfo().GetScTabName( nTab ) ), 127 );
923     lcl_WriteDateTime( rStrm, GetDateTime() );
924     rStrm.WriteZeroBytes( 133 );
925 }
926 
GetNum() const927 sal_uInt16 XclExpChTrInsertTab::GetNum() const
928 {
929     return 0x014D;
930 }
931 
GetActionByteCount() const932 sal_Size XclExpChTrInsertTab::GetActionByteCount() const
933 {
934     return 276;
935 }
936 
937 //___________________________________________________________________
938 
XclExpChTrMoveRange(const ScChangeActionMove & rAction,const XclExpRoot & rRoot,const XclExpChTrTabIdBuffer & rTabIdBuffer,ScChangeTrack & rChangeTrack)939 XclExpChTrMoveRange::XclExpChTrMoveRange(
940         const ScChangeActionMove& rAction,
941         const XclExpRoot& rRoot,
942         const XclExpChTrTabIdBuffer& rTabIdBuffer,
943         ScChangeTrack& rChangeTrack ) :
944     XclExpChTrAction( rAction, rRoot, rTabIdBuffer, EXC_CHTR_OP_MOVE ),
945     aDestRange( rAction.GetBigRange().MakeRange() )
946 {
947     nLength = 0x00000042;
948     aSourceRange = aDestRange;
949     sal_Int32 nDCols, nDRows, nDTabs;
950     rAction.GetDelta( nDCols, nDRows, nDTabs );
951     aSourceRange.aStart.IncRow( (SCROW) -nDRows );
952     aSourceRange.aStart.IncCol( (SCCOL) -nDCols );
953     aSourceRange.aStart.IncTab( (SCTAB) -nDTabs );
954     aSourceRange.aEnd.IncRow( (SCROW) -nDRows );
955     aSourceRange.aEnd.IncCol( (SCCOL) -nDCols );
956     aSourceRange.aEnd.IncTab( (SCTAB) -nDTabs );
957     AddDependentContents( rAction, rRoot, rChangeTrack );
958 }
959 
~XclExpChTrMoveRange()960 XclExpChTrMoveRange::~XclExpChTrMoveRange()
961 {
962 }
963 
SaveActionData(XclExpStream & rStrm) const964 void XclExpChTrMoveRange::SaveActionData( XclExpStream& rStrm ) const
965 {
966     WriteTabId( rStrm, aDestRange.aStart.Tab() );
967     Write2DRange( rStrm, aSourceRange );
968     Write2DRange( rStrm, aDestRange );
969     WriteTabId( rStrm, aSourceRange.aStart.Tab() );
970     rStrm << (sal_uInt32) 0x00000000;
971 }
972 
PrepareSaveAction(XclExpStream & rStrm) const973 void XclExpChTrMoveRange::PrepareSaveAction( XclExpStream& rStrm ) const
974 {
975     XclExpChTrEmpty( 0x014E ).Save( rStrm );
976 }
977 
CompleteSaveAction(XclExpStream & rStrm) const978 void XclExpChTrMoveRange::CompleteSaveAction( XclExpStream& rStrm ) const
979 {
980     XclExpChTrEmpty( 0x014F ).Save( rStrm );
981 }
982 
GetNum() const983 sal_uInt16 XclExpChTrMoveRange::GetNum() const
984 {
985     return 0x0140;
986 }
987 
GetActionByteCount() const988 sal_Size XclExpChTrMoveRange::GetActionByteCount() const
989 {
990     return 24;
991 }
992 
993 //___________________________________________________________________
994 
XclExpChTr0x014A(const XclExpChTrInsert & rAction)995 XclExpChTr0x014A::XclExpChTr0x014A( const XclExpChTrInsert& rAction ) :
996     XclExpChTrInsert( rAction )
997 {
998     nLength = 0x00000026;
999     nOpCode = EXC_CHTR_OP_FORMAT;
1000 }
1001 
~XclExpChTr0x014A()1002 XclExpChTr0x014A::~XclExpChTr0x014A()
1003 {
1004 }
1005 
SaveActionData(XclExpStream & rStrm) const1006 void XclExpChTr0x014A::SaveActionData( XclExpStream& rStrm ) const
1007 {
1008     WriteTabId( rStrm, aRange.aStart.Tab() );
1009     rStrm   << (sal_uInt16) 0x0003
1010             << (sal_uInt16) 0x0001;
1011     Write2DRange( rStrm, aRange );
1012 }
1013 
GetNum() const1014 sal_uInt16 XclExpChTr0x014A::GetNum() const
1015 {
1016     return 0x014A;
1017 }
1018 
GetActionByteCount() const1019 sal_Size XclExpChTr0x014A::GetActionByteCount() const
1020 {
1021     return 14;
1022 }
1023 
1024 //___________________________________________________________________
1025 
~XclExpChTrActionStack()1026 XclExpChTrActionStack::~XclExpChTrActionStack()
1027 {
1028     while( XclExpChTrAction* pRec = Pop() )
1029         delete pRec;
1030 }
1031 
Push(XclExpChTrAction * pNewRec)1032 void XclExpChTrActionStack::Push( XclExpChTrAction* pNewRec )
1033 {
1034     DBG_ASSERT( pNewRec, "XclExpChTrActionStack::Push - NULL pointer" );
1035     if( pNewRec )
1036         Stack::Push( pNewRec );
1037 }
1038 
1039 //___________________________________________________________________
1040 
~XclExpChTrRecordList()1041 XclExpChTrRecordList::~XclExpChTrRecordList()
1042 {
1043     for( ExcRecord* pRec = First(); pRec; pRec = Next() )
1044         delete pRec;
1045 }
1046 
Append(ExcRecord * pNewRec)1047 void XclExpChTrRecordList::Append( ExcRecord* pNewRec )
1048 {
1049     DBG_ASSERT( pNewRec, "XclExpChTrRecordList::Append - NULL pointer" );
1050     if( pNewRec )
1051         List::Insert( pNewRec, LIST_APPEND );
1052 }
1053 
Save(XclExpStream & rStrm)1054 void XclExpChTrRecordList::Save( XclExpStream& rStrm )
1055 {
1056     for( ExcRecord* pRec = First(); pRec; pRec = Next() )
1057         pRec->Save( rStrm );
1058 }
1059 
1060 //___________________________________________________________________
1061 
XclExpChangeTrack(const XclExpRoot & rRoot)1062 XclExpChangeTrack::XclExpChangeTrack( const XclExpRoot& rRoot ) :
1063     XclExpRoot( rRoot ),
1064     aRecList(),
1065     aActionStack(),
1066     aTabIdBufferList(),
1067     pTabIdBuffer( NULL ),
1068     pTempDoc( NULL ),
1069     nNewAction( 1 ),
1070     pHeader( NULL ),
1071     bValidGUID( sal_False )
1072 {
1073     DBG_ASSERT( GetOldRoot().pTabId, "XclExpChangeTrack::XclExpChangeTrack - root data incomplete" );
1074     if( !GetOldRoot().pTabId )
1075         return;
1076 
1077     ScChangeTrack* pTempChangeTrack = CreateTempChangeTrack();
1078     if (!pTempChangeTrack)
1079         return;
1080 
1081     pTabIdBuffer = new XclExpChTrTabIdBuffer( GetTabInfo().GetXclTabCount() );
1082     aTabIdBufferList.Append( pTabIdBuffer );
1083 
1084     // calculate final table order (tab id list)
1085     const ScChangeAction* pScAction;
1086     for( pScAction = pTempChangeTrack->GetLast(); pScAction; pScAction = pScAction->GetPrev() )
1087     {
1088         if( pScAction->GetType() == SC_CAT_INSERT_TABS )
1089         {
1090             SCTAB nScTab = static_cast< SCTAB >( pScAction->GetBigRange().aStart.Tab() );
1091             pTabIdBuffer->InitFill( GetTabInfo().GetXclTab( nScTab ) );
1092         }
1093     }
1094     pTabIdBuffer->InitFillup();
1095     GetOldRoot().pTabId->Copy( *pTabIdBuffer );
1096 
1097     // get actions in reverse order
1098     pScAction = pTempChangeTrack->GetLast();
1099     while( pScAction )
1100     {
1101         PushActionRecord( *pScAction );
1102         const ScChangeAction* pPrevAction = pScAction->GetPrev();
1103         pTempChangeTrack->Undo( pScAction->GetActionNumber(), pScAction->GetActionNumber() );
1104         pScAction = pPrevAction;
1105     }
1106 
1107     // build record list
1108     pHeader = new XclExpChTrHeader;
1109     aRecList.Append( pHeader );
1110     aRecList.Append( new XclExpChTr0x0195 );
1111     aRecList.Append( new XclExpChTr0x0194( *pTempChangeTrack ) );
1112 
1113     String sLastUsername;
1114     DateTime aLastDateTime;
1115     sal_uInt32 nIndex = 1;
1116     while( XclExpChTrAction* pAction = aActionStack.Pop() )
1117     {
1118         if( (nIndex == 1) || pAction->ForceInfoRecord() ||
1119             (pAction->GetUsername() != sLastUsername) ||
1120             (pAction->GetDateTime() != aLastDateTime) )
1121         {
1122             lcl_GenerateGUID( aGUID, bValidGUID );
1123             sLastUsername = pAction->GetUsername();
1124             aLastDateTime = pAction->GetDateTime();
1125             aRecList.Append( new XclExpChTrInfo( sLastUsername, aLastDateTime, aGUID ) );
1126             aRecList.Append( new XclExpChTrTabId( pAction->GetTabIdBuffer() ) );
1127             pHeader->SetGUID( aGUID );
1128         }
1129         pAction->SetIndex( nIndex );
1130         aRecList.Append( pAction );
1131     }
1132 
1133     pHeader->SetGUID( aGUID );
1134     pHeader->SetCount( nIndex - 1 );
1135     aRecList.Append( new ExcEof );
1136 }
1137 
~XclExpChangeTrack()1138 XclExpChangeTrack::~XclExpChangeTrack()
1139 {
1140     if( pTempDoc )
1141         delete pTempDoc;
1142 }
1143 
CreateTempChangeTrack()1144 ScChangeTrack* XclExpChangeTrack::CreateTempChangeTrack()
1145 {
1146     // get original change track
1147     ScChangeTrack* pOrigChangeTrack = GetDoc().GetChangeTrack();
1148     DBG_ASSERT( pOrigChangeTrack, "XclExpChangeTrack::CreateTempChangeTrack - no change track data" );
1149     if( !pOrigChangeTrack )
1150         return NULL;
1151 
1152     // create empty document
1153     pTempDoc = new ScDocument;
1154     DBG_ASSERT( pTempDoc, "XclExpChangeTrack::CreateTempChangeTrack - no temp document" );
1155     if( !pTempDoc )
1156         return NULL;
1157 
1158     // adjust table count
1159     SCTAB nOrigCount = GetDoc().GetTableCount();
1160     String sTabName;
1161     for( sal_Int32 nIndex = 0; nIndex < nOrigCount; nIndex++ )
1162     {
1163         pTempDoc->CreateValidTabName( sTabName );
1164         pTempDoc->InsertTab( SC_TAB_APPEND, sTabName );
1165     }
1166     DBG_ASSERT( nOrigCount == pTempDoc->GetTableCount(),
1167         "XclExpChangeTrack::CreateTempChangeTrack - table count mismatch" );
1168     if( nOrigCount != pTempDoc->GetTableCount() )
1169         return NULL;
1170 
1171     return pOrigChangeTrack->Clone(pTempDoc);
1172 }
1173 
PushActionRecord(const ScChangeAction & rAction)1174 void XclExpChangeTrack::PushActionRecord( const ScChangeAction& rAction )
1175 {
1176     XclExpChTrAction* pXclAction = NULL;
1177     ScChangeTrack* pTempChangeTrack = pTempDoc->GetChangeTrack();
1178     switch( rAction.GetType() )
1179     {
1180         case SC_CAT_CONTENT:
1181             pXclAction = new XclExpChTrCellContent( (const ScChangeActionContent&) rAction, GetRoot(), *pTabIdBuffer );
1182         break;
1183         case SC_CAT_INSERT_ROWS:
1184         case SC_CAT_INSERT_COLS:
1185         case SC_CAT_DELETE_ROWS:
1186         case SC_CAT_DELETE_COLS:
1187             if (pTempChangeTrack)
1188                 pXclAction = new XclExpChTrInsert( rAction, GetRoot(), *pTabIdBuffer, *pTempChangeTrack );
1189         break;
1190         case SC_CAT_INSERT_TABS:
1191         {
1192             pXclAction = new XclExpChTrInsertTab( rAction, GetRoot(), *pTabIdBuffer );
1193             XclExpChTrTabIdBuffer* pNewBuffer = new XclExpChTrTabIdBuffer( *pTabIdBuffer );
1194             pNewBuffer->Remove();
1195             aTabIdBufferList.Append( pNewBuffer );
1196             pTabIdBuffer = pNewBuffer;
1197         }
1198         break;
1199         case SC_CAT_MOVE:
1200             if (pTempChangeTrack)
1201                 pXclAction = new XclExpChTrMoveRange( (const ScChangeActionMove&) rAction, GetRoot(), *pTabIdBuffer, *pTempChangeTrack );
1202         break;
1203         default:;
1204     }
1205     if( pXclAction )
1206         aActionStack.Push( pXclAction );
1207 }
1208 
WriteUserNamesStream()1209 sal_Bool XclExpChangeTrack::WriteUserNamesStream()
1210 {
1211     sal_Bool bRet = sal_False;
1212     SotStorageStreamRef xSvStrm = OpenStream( EXC_STREAM_USERNAMES );
1213     DBG_ASSERT( xSvStrm.Is(), "XclExpChangeTrack::WriteUserNamesStream - no stream" );
1214     if( xSvStrm.Is() )
1215     {
1216         XclExpStream aXclStrm( *xSvStrm, GetRoot() );
1217         XclExpChTr0x0191().Save( aXclStrm );
1218         XclExpChTr0x0198().Save( aXclStrm );
1219         XclExpChTr0x0192().Save( aXclStrm );
1220         XclExpChTr0x0197().Save( aXclStrm );
1221         xSvStrm->Commit();
1222         bRet = sal_True;
1223     }
1224     return bRet;
1225 }
1226 
Write()1227 void XclExpChangeTrack::Write()
1228 {
1229     if( !aRecList.Count() )
1230         return;
1231 
1232     if( WriteUserNamesStream() )
1233     {
1234         SotStorageStreamRef xSvStrm = OpenStream( EXC_STREAM_REVLOG );
1235         DBG_ASSERT( xSvStrm.Is(), "XclExpChangeTrack::Write - no stream" );
1236         if( xSvStrm.Is() )
1237         {
1238             XclExpStream aXclStrm( *xSvStrm, GetRoot(), EXC_MAXRECSIZE_BIFF8 + 8 );
1239             aRecList.Save( aXclStrm );
1240             xSvStrm->Commit();
1241         }
1242     }
1243 }
1244 
1245