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 #ifndef SC_XCLEXPCHANGETRACK_HXX
25 #define SC_XCLEXPCHANGETRACK_HXX
26 
27 #include <tools/debug.hxx>
28 #include <tools/datetime.hxx>
29 #include <rtl/uuid.h>
30 #include "bigrange.hxx"
31 #include "chgtrack.hxx"
32 #include "xelink.hxx"
33 #include "ftools.hxx"
34 #include "excrecds.hxx"
35 
36 //___________________________________________________________________
37 
38 class ScBaseCell;
39 
40 //___________________________________________________________________
41 // XclExpUserBView - one UserBView record for each user
42 
43 class XclExpUserBView : public ExcRecord
44 {
45 private:
46     XclExpString                sUsername;
47 	sal_uInt8					aGUID[ 16 ];
48 
49 	virtual void				SaveCont( XclExpStream& rStrm );
50 
51 public:
52 								XclExpUserBView( const String& rUsername, const sal_uInt8* pGUID );
53 
GetGUID() const54 	inline const sal_uInt8*		GetGUID() const { return aGUID; }
55 
56 	virtual sal_uInt16				GetNum() const;
57     virtual sal_Size            GetLen() const;
58 };
59 
60 //___________________________________________________________________
61 // XclExpUserBViewList - list of UserBView records
62 
63 class XclExpUserBViewList : public ExcEmptyRec, private List
64 {
65 private:
_First()66 	inline XclExpUserBView*		_First()	{ return (XclExpUserBView*) List::First(); }
_Next()67 	inline XclExpUserBView*		_Next()		{ return (XclExpUserBView*) List::Next(); }
68 
69 public:
70 								XclExpUserBViewList( const ScChangeTrack& rChangeTrack );
71 	virtual						~XclExpUserBViewList();
72 
First()73 	inline const XclExpUserBView* First()	{ return (const XclExpUserBView*) List::First(); }
Next()74 	inline const XclExpUserBView* Next()	{ return (const XclExpUserBView*) List::Next(); }
75 
76 	virtual void				Save( XclExpStream& rStrm );
77 };
78 
79 //___________________________________________________________________
80 // XclExpUsersViewBegin - begin of view block (one per sheet)
81 
82 class XclExpUsersViewBegin : public ExcRecord
83 {
84 private:
85 	sal_uInt8					aGUID[ 16 ];
86 	sal_uInt32					nCurrTab;
87 
88 	virtual void				SaveCont( XclExpStream& rStrm );
89 
90 public:
91 								XclExpUsersViewBegin( const sal_uInt8* pGUID, sal_uInt32 nTab );
92 	virtual sal_uInt16				GetNum() const;
93     virtual sal_Size            GetLen() const;
94 };
95 
96 //___________________________________________________________________
97 // XclExpUsersViewEnd - end of view block (one per sheet)
98 
99 class XclExpUsersViewEnd : public ExcRecord
100 {
101 private:
102 	virtual void				SaveCont( XclExpStream& rStrm );
103 
104 public:
105 	virtual sal_uInt16				GetNum() const;
106     virtual sal_Size            GetLen() const;
107 };
108 
109 //___________________________________________________________________
110 // dummy record for "User Names" stream
111 
112 class XclExpChTr0x0191 : public ExcRecord
113 {
114 private:
115 	virtual void				SaveCont( XclExpStream& rStrm );
116 
117 public:
118 	virtual sal_uInt16				GetNum() const;
119     virtual sal_Size            GetLen() const;
120 };
121 
122 //___________________________________________________________________
123 // dummy record for "User Names" stream
124 
125 class XclExpChTr0x0198 : public ExcRecord
126 {
127 private:
128 	virtual void				SaveCont( XclExpStream& rStrm );
129 
130 public:
131 	virtual sal_uInt16				GetNum() const;
132     virtual sal_Size            GetLen() const;
133 };
134 
135 //___________________________________________________________________
136 // dummy record for "User Names" stream
137 
138 class XclExpChTr0x0192 : public ExcRecord
139 {
140 private:
141 	virtual void				SaveCont( XclExpStream& rStrm );
142 
143 public:
144 	virtual sal_uInt16				GetNum() const;
145     virtual sal_Size            GetLen() const;
146 };
147 
148 //___________________________________________________________________
149 // dummy record for "User Names" stream
150 
151 class XclExpChTr0x0197 : public ExcRecord
152 {
153 private:
154 	virtual void				SaveCont( XclExpStream& rStrm );
155 
156 public:
157 	virtual sal_uInt16				GetNum() const;
158     virtual sal_Size            GetLen() const;
159 };
160 
161 //___________________________________________________________________
162 // dummy record without content
163 
164 class XclExpChTrEmpty : public ExcRecord
165 {
166 private:
167 	sal_uInt16						nRecNum;
168 
169 public:
XclExpChTrEmpty(sal_uInt16 nNum)170 	inline						XclExpChTrEmpty( sal_uInt16 nNum ) : nRecNum( nNum ) {}
171 	virtual						~XclExpChTrEmpty();
172 
173 	virtual sal_uInt16				GetNum() const;
174     virtual sal_Size            GetLen() const;
175 };
176 
177 //___________________________________________________________________
178 // dummy record for "Revision Log" stream
179 
180 class XclExpChTr0x0195 : public ExcRecord
181 {
182 private:
183 	virtual void				SaveCont( XclExpStream& rStrm );
184 
185 public:
186 	virtual						~XclExpChTr0x0195();
187 
188 	virtual sal_uInt16				GetNum() const;
189     virtual sal_Size            GetLen() const;
190 };
191 
192 //___________________________________________________________________
193 // dummy record for "Revision Log" stream
194 
195 class XclExpChTr0x0194 : public ExcRecord
196 {
197 private:
198     XclExpString                sUsername;
199 	DateTime					aDateTime;
200 
201 	virtual void				SaveCont( XclExpStream& rStrm );
202 
203 public:
204 	inline						XclExpChTr0x0194( const ScChangeTrack& rChangeTrack );
205 	virtual						~XclExpChTr0x0194();
206 
207 	virtual sal_uInt16				GetNum() const;
208     virtual sal_Size            GetLen() const;
209 };
210 
XclExpChTr0x0194(const ScChangeTrack & rChangeTrack)211 inline XclExpChTr0x0194::XclExpChTr0x0194( const ScChangeTrack& rChangeTrack ) :
212 	sUsername( rChangeTrack.GetUser() ),
213 	aDateTime( rChangeTrack.GetFixDateTime() )
214 {
215 }
216 
217 //___________________________________________________________________
218 // XclExpChTrHeader - header record, includes action count
219 
220 class XclExpChTrHeader : public ExcRecord
221 {
222 private:
223 	sal_uInt8					aGUID[ 16 ];
224 	sal_uInt32					nCount;
225 
226 	virtual void				SaveCont( XclExpStream& rStrm );
227 
228 public:
XclExpChTrHeader()229 	inline						XclExpChTrHeader() : nCount( 0 ) {}
230 	virtual						~XclExpChTrHeader();
231 
SetGUID(const sal_uInt8 * pGUID)232 	inline void					SetGUID( const sal_uInt8* pGUID )	{ memcpy( aGUID, pGUID, 16 ); }
SetCount(sal_uInt32 nNew)233 	inline void					SetCount( sal_uInt32 nNew )			{ nCount = nNew; }
234 
235 	virtual sal_uInt16				GetNum() const;
236     virtual sal_Size            GetLen() const;
237 };
238 
239 //___________________________________________________________________
240 // XclExpChTrInfo - header of action group of a user
241 
242 class XclExpChTrInfo : public ExcRecord
243 {
244 private:
245     XclExpString                sUsername;
246 	DateTime					aDateTime;
247 	sal_uInt8					aGUID[ 16 ];
248 
249 	virtual void				SaveCont( XclExpStream& rStrm );
250 
251 public:
252 	inline						XclExpChTrInfo(
253 									const String& rUsername,
254 									const DateTime& rDateTime,
255 									const sal_uInt8* pGUID );
256 	virtual						~XclExpChTrInfo();
257 
258 	virtual sal_uInt16				GetNum() const;
259     virtual sal_Size            GetLen() const;
260 };
261 
XclExpChTrInfo(const String & rUsername,const DateTime & rDateTime,const sal_uInt8 * pGUID)262 inline XclExpChTrInfo::XclExpChTrInfo( const String& rUsername, const DateTime& rDateTime, const sal_uInt8* pGUID ) :
263 	sUsername( rUsername ),
264 	aDateTime( rDateTime )
265 {
266 	memcpy( aGUID, pGUID, 16 );
267 }
268 
269 //___________________________________________________________________
270 // XclExpChTrTabIdBuffer - buffer for tab id's
271 
272 class XclExpChTrTabIdBuffer
273 {
274 private:
275 	sal_uInt16*					pBuffer;
276 	sal_uInt16*					pLast;
277 	sal_uInt16					nBufSize;
278 	sal_uInt16					nLastId;
279 
280 public:
281 								XclExpChTrTabIdBuffer( sal_uInt16 nCount );
282 								XclExpChTrTabIdBuffer( const XclExpChTrTabIdBuffer& rCopy );
283 								~XclExpChTrTabIdBuffer();
284 
285 	void						InitFill( sal_uInt16 nIndex );
286 	void						InitFillup();
287 
288 	sal_uInt16					GetId( sal_uInt16 nIndex ) const;
289 	void						Remove();
290 
GetBufferCount() const291 	inline sal_uInt16			GetBufferCount() const
292                                     { return static_cast< sal_uInt16 >( (pLast - pBuffer) + 1 ); }
GetBufferCopy(sal_uInt16 * pDest) const293 	inline void					GetBufferCopy( sal_uInt16* pDest ) const
294 									{ memcpy( pDest, pBuffer, sizeof(sal_uInt16) * GetBufferCount() ); }
295 };
296 
297 //___________________________________________________________________
298 // XclExpChTrTabIdBufferList
299 
300 class XclExpChTrTabIdBufferList : private List
301 {
302 private:
First()303 	inline XclExpChTrTabIdBuffer* First()	{ return (XclExpChTrTabIdBuffer*) List::First(); }
Next()304 	inline XclExpChTrTabIdBuffer* Next()	{ return (XclExpChTrTabIdBuffer*) List::Next(); }
305 
306 public:
307 	virtual						~XclExpChTrTabIdBufferList();
308 
Append(XclExpChTrTabIdBuffer * pNew)309 	inline void					Append( XclExpChTrTabIdBuffer* pNew )
310 									{ List::Insert( pNew, LIST_APPEND ); }
311 };
312 
313 //___________________________________________________________________
314 // XclExpChTrTabId - tab id record
315 
316 class XclExpChTrTabId : public ExcRecord
317 {
318 private:
319 	sal_uInt16*					pBuffer;
320 	sal_uInt16					nTabCount;
321 
Clear()322 	inline void					Clear() { if( pBuffer ) delete[] pBuffer; pBuffer = NULL; }
323 
324 	virtual void				SaveCont( XclExpStream& rStrm );
325 
326 public:
XclExpChTrTabId(sal_uInt16 nCount)327 	inline						XclExpChTrTabId( sal_uInt16 nCount ) :
328 									pBuffer( NULL ), nTabCount( nCount ) {}
329 								XclExpChTrTabId( const XclExpChTrTabIdBuffer& rBuffer );
330 	virtual						~XclExpChTrTabId();
331 
332 	void						Copy( const XclExpChTrTabIdBuffer& rBuffer );
333 
334 	virtual sal_uInt16				GetNum() const;
335     virtual sal_Size            GetLen() const;
336 };
337 
338 //___________________________________________________________________
339 // XclExpChTrAction - base class for action records
340 
341 class XclExpChTrAction : public ExcRecord
342 {
343 private:
344 	String						sUsername;
345 	DateTime					aDateTime;
346 	sal_uInt32					nIndex;			// action number
347 	XclExpChTrAction*			pAddAction;		// additional record for this action
348 	sal_Bool					bAccepted;
349 
350 protected:
351     const XclExpTabInfo&        rTabInfo;       // for table num export (sc num -> xcl num)
352 	const XclExpChTrTabIdBuffer& rIdBuffer;		// for table num export (xcl num -> tab id)
353 	sal_uInt32					nLength;		// this is not the record size
354 	sal_uInt16					nOpCode;		// EXC_CHTR_OP_***
355 	sal_Bool					bForceInfo;
356 
357 								XclExpChTrAction( const XclExpChTrAction& rCopy );
358 
359 	void						SetAddAction( XclExpChTrAction* pAction );
360 	void						AddDependentContents(
361 									const ScChangeAction& rAction,
362                                     const XclExpRoot& rRoot,
363 									ScChangeTrack& rChangeTrack );
364 
365 	inline void					Write2DAddress( XclExpStream& rStrm, const ScAddress& rAddress ) const;
366 	inline void					Write2DRange( XclExpStream& rStrm, const ScRange& rRange ) const;
367 	inline void					WriteTabId( XclExpStream& rStrm, SCTAB nTabId ) const;
368 
369 								// save header data, call SaveActionData()
370 	virtual void				SaveCont( XclExpStream& rStrm );
GetHeaderByteCount() const371     inline sal_Size             GetHeaderByteCount() const  { return 12; }
372 
373 								// overload to save action data without header, called by SaveCont()
374 	virtual void				SaveActionData( XclExpStream& rStrm ) const = 0;
375 								// overload to get action size without header, called by GetLen()
376     virtual sal_Size            GetActionByteCount() const = 0;
377 
378 								// do something before writing the record
379 	virtual void				PrepareSaveAction( XclExpStream& rStrm ) const;
380 								// do something after writing the record
381 	virtual void				CompleteSaveAction( XclExpStream& rStrm ) const;
382 
383 public:
384 								XclExpChTrAction(
385 									const ScChangeAction& rAction,
386                                     const XclExpRoot& rRoot,
387 									const XclExpChTrTabIdBuffer& rTabIdBuffer,
388 									sal_uInt16 nNewOpCode = EXC_CHTR_OP_UNKNOWN );
389 	virtual						~XclExpChTrAction();
390 
GetUsername() const391 	inline const String&		GetUsername() const				{ return sUsername; }
GetDateTime() const392 	inline const DateTime&		GetDateTime() const				{ return aDateTime; }
GetTabIdBuffer() const393 	inline const XclExpChTrTabIdBuffer& GetTabIdBuffer() const	{ return rIdBuffer; }
ForceInfoRecord() const394 	inline sal_Bool				ForceInfoRecord() const			{ return bForceInfo; }
395 
396 								// set own index & return new index
397 								// could be overloaded to use more indexes per action
398 	virtual void				SetIndex( sal_uInt32& rIndex );
399 
400 	virtual void				Save( XclExpStream& rStrm );
401     virtual sal_Size            GetLen() const;
402 };
403 
Write2DAddress(XclExpStream & rStrm,const ScAddress & rAddress) const404 inline void XclExpChTrAction::Write2DAddress( XclExpStream& rStrm, const ScAddress& rAddress ) const
405 {
406 	rStrm	<< (sal_uInt16)	rAddress.Row()
407 			<< (sal_uInt16)	rAddress.Col();
408 }
409 
Write2DRange(XclExpStream & rStrm,const ScRange & rRange) const410 inline void XclExpChTrAction::Write2DRange( XclExpStream& rStrm, const ScRange& rRange ) const
411 {
412 	rStrm	<< (sal_uInt16)	rRange.aStart.Row()
413 			<< (sal_uInt16)	rRange.aEnd.Row()
414 			<< (sal_uInt16)	rRange.aStart.Col()
415 			<< (sal_uInt16)	rRange.aEnd.Col();
416 }
417 
WriteTabId(XclExpStream & rStrm,SCTAB nTab) const418 inline void XclExpChTrAction::WriteTabId( XclExpStream& rStrm, SCTAB nTab ) const
419 {
420     rStrm << rIdBuffer.GetId( rTabInfo.GetXclTab( nTab ) );
421 }
422 
423 //___________________________________________________________________
424 // XclExpChTrData - cell content itself
425 
426 struct XclExpChTrData
427 {
428     XclExpString*               pString;
429     XclTokenArrayRef            mxTokArr;
430     XclExpRefLog                maRefLog;
431 	double						fValue;
432 	sal_Int32					nRKValue;
433 	sal_uInt16					nType;
434     sal_Size                    nSize;
435 
436                                 XclExpChTrData();
437                                 ~XclExpChTrData();
438 	void						Clear();
439 
440 	void						WriteFormula(
441 									XclExpStream& rStrm,
442 									const XclExpChTrTabIdBuffer& rTabIdBuffer );
443 	void						Write(
444 									XclExpStream& rStrm,
445 									const XclExpChTrTabIdBuffer& rTabIdBuffer );
446 };
447 
448 //___________________________________________________________________
449 // XclExpChTrCellContent - changed cell content
450 
451 class XclExpChTrCellContent : public XclExpChTrAction, protected XclExpRoot
452 {
453 private:
454 	XclExpChTrData*				pOldData;
455 	XclExpChTrData*				pNewData;
456 	sal_uInt16					nOldLength;		// this is not the record size
457 
458 	void						MakeEmptyChTrData( XclExpChTrData*& rpData );
459 
460 protected:
461 	ScAddress					aPosition;
462 
463 	void						GetCellData(
464 									const ScBaseCell* pScCell,
465 									XclExpChTrData*& rpData,
466 									sal_uInt32& rXclLength1,
467 									sal_uInt16& rXclLength2 );
468 
469 	virtual void				SaveActionData( XclExpStream& rStrm ) const;
470 
471 public:
472 								XclExpChTrCellContent(
473 									const ScChangeActionContent& rAction,
474                                     const XclExpRoot& rRoot,
475 									const XclExpChTrTabIdBuffer& rTabIdBuffer );
476 	virtual						~XclExpChTrCellContent();
477 
478 	virtual sal_uInt16				GetNum() const;
479     virtual sal_Size            GetActionByteCount() const;
480 };
481 
482 //___________________________________________________________________
483 // XclExpChTrInsert - insert/delete columns/rows
484 
485 class XclExpChTrInsert : public XclExpChTrAction
486 {
487 protected:
488 	ScRange						aRange;
489 
XclExpChTrInsert(const XclExpChTrInsert & rCopy)490 								XclExpChTrInsert( const XclExpChTrInsert& rCopy ) :
491 									XclExpChTrAction( rCopy ), aRange( rCopy.aRange ) {}
492 
493 	virtual void				SaveActionData( XclExpStream& rStrm ) const;
494 	virtual void				PrepareSaveAction( XclExpStream& rStrm ) const;
495 	virtual void				CompleteSaveAction( XclExpStream& rStrm ) const;
496 
497 public:
498 								XclExpChTrInsert(
499 									const ScChangeAction& rAction,
500                                     const XclExpRoot& rRoot,
501 									const XclExpChTrTabIdBuffer& rTabIdBuffer,
502 									ScChangeTrack& rChangeTrack );
503 	virtual						~XclExpChTrInsert();
504 
505 	virtual sal_uInt16				GetNum() const;
506     virtual sal_Size            GetActionByteCount() const;
507 };
508 
509 //___________________________________________________________________
510 // XclExpChTrInsertTab - insert table
511 
512 class XclExpChTrInsertTab : public XclExpChTrAction, protected XclExpRoot
513 {
514 private:
515 	SCTAB					nTab;
516 
517 protected:
518 	virtual void				SaveActionData( XclExpStream& rStrm ) const;
519 
520 public:
521 								XclExpChTrInsertTab(
522 									const ScChangeAction& rAction,
523                                     const XclExpRoot& rRoot,
524 									const XclExpChTrTabIdBuffer& rTabIdBuffer );
525 	virtual						~XclExpChTrInsertTab();
526 
527 	virtual sal_uInt16				GetNum() const;
528     virtual sal_Size            GetActionByteCount() const;
529 };
530 
531 //___________________________________________________________________
532 // XclExpChTrMoveRange - move cell range
533 
534 class XclExpChTrMoveRange : public XclExpChTrAction
535 {
536 protected:
537 	ScRange						aSourceRange;
538 	ScRange						aDestRange;
539 
540 	virtual void				SaveActionData( XclExpStream& rStrm ) const;
541 	virtual void				PrepareSaveAction( XclExpStream& rStrm ) const;
542 	virtual void				CompleteSaveAction( XclExpStream& rStrm ) const;
543 
544 public:
545 								XclExpChTrMoveRange(
546 									const ScChangeActionMove& rAction,
547                                     const XclExpRoot& rRoot,
548 									const XclExpChTrTabIdBuffer& rTabIdBuffer,
549 									ScChangeTrack& rChangeTrack );
550 	virtual						~XclExpChTrMoveRange();
551 
552 	virtual sal_uInt16				GetNum() const;
553     virtual sal_Size            GetActionByteCount() const;
554 };
555 
556 //___________________________________________________________________
557 // XclExpChTr0x019A - additional data for delete action
558 
559 class XclExpChTr0x014A : public XclExpChTrInsert
560 {
561 protected:
562 	virtual void				SaveActionData( XclExpStream& rStrm ) const;
563 
564 public:
565 								XclExpChTr0x014A( const XclExpChTrInsert& rAction );
566 	virtual						~XclExpChTr0x014A();
567 
568 	virtual sal_uInt16				GetNum() const;
569     virtual sal_Size            GetActionByteCount() const;
570 };
571 
572 //___________________________________________________________________
573 // XclExpChTrActionStack - temporary action stack
574 
575 class XclExpChTrActionStack : private Stack
576 {
577 public:
578 	virtual						~XclExpChTrActionStack();
579 
580 	void						Push( XclExpChTrAction* pNewRec );
Pop()581 	inline XclExpChTrAction*	Pop()	{ return (XclExpChTrAction*) Stack::Pop(); }
582 
583 private:
584     using                       Stack::Push;
585 };
586 
587 //___________________________________________________________________
588 // XclExpChTrRecordList - list of "Revision Log" stream records
589 
590 class XclExpChTrRecordList : private List
591 {
592 private:
First()593 	inline ExcRecord*			First()	{ return (ExcRecord*) List::First(); }
Next()594 	inline ExcRecord*			Next()	{ return (ExcRecord*) List::Next(); }
595 
596 public:
597 	virtual						~XclExpChTrRecordList();
598 
599     using                       List::Count;
600 	void						Append( ExcRecord* pNewRec );
601 	void						Save( XclExpStream& rStrm );
602 };
603 
604 //___________________________________________________________________
605 // XclExpChangeTrack - exports the "Revision Log" stream
606 
607 class XclExpChangeTrack : protected XclExpRoot
608 {
609 private:
610 	XclExpChTrRecordList		aRecList;
611 	XclExpChTrActionStack		aActionStack;
612 	XclExpChTrTabIdBufferList	aTabIdBufferList;
613 	XclExpChTrTabIdBuffer*		pTabIdBuffer;
614 
615 	ScDocument*					pTempDoc;			// empty document
616 
617 	sal_uInt32					nNewAction;			// action number, 1-based
618 	XclExpChTrHeader*			pHeader;			// header record for last GUID
619 	sal_uInt8					aGUID[ 16 ];		// GUID for action info records
620 	sal_Bool					bValidGUID;
621 
622 	ScChangeTrack*			    CreateTempChangeTrack();
623 	void						PushActionRecord( const ScChangeAction& rAction );
624 
625 	sal_Bool					WriteUserNamesStream();
626 
627 public:
628                                 XclExpChangeTrack( const XclExpRoot& rRoot );
629 								~XclExpChangeTrack();
630 
631 	void						Write();
632 };
633 
634 //___________________________________________________________________
635 
636 #endif
637 
638