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