1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
24 #include <tools/datetime.hxx>
25 #include <chgtrack.hxx>
26 #include <document.hxx>
28 #include "xestring.hxx"
29 #include "excrecds.hxx"
30 #include "xlformula.hxx"
31 #include "xeformula.hxx"
33 class ExcXmlRecord
: public ExcRecord
36 virtual std::size_t GetLen() const override
;
37 virtual sal_uInt16
GetNum() const override
;
38 virtual void Save( XclExpStream
& rStrm
) override
;
41 // XclExpUserBView - one UserBView record for each user
43 class XclExpUserBView
: public ExcRecord
46 XclExpString sUsername
;
47 sal_uInt8 aGUID
[ 16 ];
49 virtual void SaveCont( XclExpStream
& rStrm
) override
;
52 XclExpUserBView( const OUString
& rUsername
, const sal_uInt8
* pGUID
);
54 const sal_uInt8
* GetGUID() const { return aGUID
; }
56 virtual sal_uInt16
GetNum() const override
;
57 virtual std::size_t GetLen() const override
;
60 // XclExpUserBViewList - list of UserBView records
62 class XclExpUserBViewList
: public ExcEmptyRec
65 std::vector
<XclExpUserBView
> aViews
;
69 typedef std::vector
<XclExpUserBView
>::const_iterator const_iterator
;
71 XclExpUserBViewList( const ScChangeTrack
& rChangeTrack
);
72 virtual ~XclExpUserBViewList() override
;
74 const_iterator
cbegin () { return aViews
.cbegin(); }
75 const_iterator
cend () { return aViews
.cend(); }
77 virtual void Save( XclExpStream
& rStrm
) override
;
80 // XclExpUsersViewBegin - begin of view block (one per sheet)
82 class XclExpUsersViewBegin
: public ExcRecord
85 sal_uInt8 aGUID
[ 16 ];
88 virtual void SaveCont( XclExpStream
& rStrm
) override
;
91 XclExpUsersViewBegin( const sal_uInt8
* pGUID
, sal_uInt32 nTab
);
92 virtual sal_uInt16
GetNum() const override
;
93 virtual std::size_t GetLen() const override
;
96 // XclExpUsersViewEnd - end of view block (one per sheet)
98 class XclExpUsersViewEnd
: public ExcRecord
101 virtual void SaveCont( XclExpStream
& rStrm
) override
;
104 virtual sal_uInt16
GetNum() const override
;
105 virtual std::size_t GetLen() const override
;
108 // dummy record for "User Names" stream
110 class XclExpChTr0x0191
: public ExcRecord
113 virtual void SaveCont( XclExpStream
& rStrm
) override
;
116 virtual sal_uInt16
GetNum() const override
;
117 virtual std::size_t GetLen() const override
;
120 // dummy record for "User Names" stream
122 class XclExpChTr0x0198
: public ExcRecord
125 virtual void SaveCont( XclExpStream
& rStrm
) override
;
128 virtual sal_uInt16
GetNum() const override
;
129 virtual std::size_t GetLen() const override
;
132 // dummy record for "User Names" stream
134 class XclExpChTr0x0192
: public ExcRecord
137 virtual void SaveCont( XclExpStream
& rStrm
) override
;
140 virtual sal_uInt16
GetNum() const override
;
141 virtual std::size_t GetLen() const override
;
144 // dummy record for "User Names" stream
146 class XclExpChTr0x0197
: public ExcRecord
149 virtual void SaveCont( XclExpStream
& rStrm
) override
;
152 virtual sal_uInt16
GetNum() const override
;
153 virtual std::size_t GetLen() const override
;
156 // dummy record without content
158 class XclExpChTrEmpty
: public ExcRecord
164 XclExpChTrEmpty( sal_uInt16 nNum
) : nRecNum( nNum
) {}
165 virtual ~XclExpChTrEmpty() override
;
167 virtual sal_uInt16
GetNum() const override
;
168 virtual std::size_t GetLen() const override
;
171 // dummy record for "Revision Log" stream
173 class XclExpChTr0x0195
: public ExcRecord
176 virtual void SaveCont( XclExpStream
& rStrm
) override
;
179 virtual ~XclExpChTr0x0195() override
;
181 virtual sal_uInt16
GetNum() const override
;
182 virtual std::size_t GetLen() const override
;
185 // dummy record for "Revision Log" stream
187 class XclExpChTr0x0194
: public ExcRecord
190 XclExpString sUsername
;
193 virtual void SaveCont( XclExpStream
& rStrm
) override
;
196 inline XclExpChTr0x0194( const ScChangeTrack
& rChangeTrack
);
197 virtual ~XclExpChTr0x0194() override
;
199 virtual sal_uInt16
GetNum() const override
;
200 virtual std::size_t GetLen() const override
;
203 inline XclExpChTr0x0194::XclExpChTr0x0194( const ScChangeTrack
& rChangeTrack
) :
204 sUsername( rChangeTrack
.GetUser() ),
205 aDateTime( rChangeTrack
.GetFixDateTime() )
209 // XclExpChTrHeader - header record, includes action count
211 class XclExpChTrHeader
: public ExcRecord
214 sal_uInt8 aGUID
[ 16 ];
217 virtual void SaveCont( XclExpStream
& rStrm
) override
;
220 XclExpChTrHeader() : nCount( 0 ) {}
221 virtual ~XclExpChTrHeader() override
;
223 void SetGUID( const sal_uInt8
* pGUID
) { memcpy( aGUID
, pGUID
, 16 ); }
224 void SetCount( sal_uInt32 nNew
) { nCount
= nNew
; }
226 virtual sal_uInt16
GetNum() const override
;
227 virtual std::size_t GetLen() const override
;
229 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
232 class XclExpXmlChTrHeaders
: public ExcXmlRecord
234 sal_uInt8 maGUID
[16];
236 void SetGUID( const sal_uInt8
* pGUID
);
238 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
241 class XclExpChTrTabIdBuffer
;
242 class XclExpChTrAction
;
244 class XclExpXmlChTrHeader
: public ExcXmlRecord
248 sal_uInt8 maGUID
[16];
249 sal_Int32 mnLogNumber
;
250 sal_uInt32 mnMinAction
;
251 sal_uInt32 mnMaxAction
;
253 std::vector
<sal_uInt16
> maTabBuffer
;
254 std::vector
<std::unique_ptr
<XclExpChTrAction
>> maActions
;
258 OUString aUserName
, const DateTime
& rDateTime
, const sal_uInt8
* pGUID
,
259 sal_Int32 nLogNumber
, const XclExpChTrTabIdBuffer
& rBuf
);
261 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
263 void AppendAction( std::unique_ptr
<XclExpChTrAction
> pAction
);
266 // XclExpChTrInfo - header of action group of a user
268 class XclExpChTrInfo
: public ExcRecord
271 XclExpString sUsername
;
273 sal_uInt8 aGUID
[ 16 ];
275 virtual void SaveCont( XclExpStream
& rStrm
) override
;
278 XclExpChTrInfo( const OUString
& rUsername
, const DateTime
& rDateTime
,
279 const sal_uInt8
* pGUID
);
281 virtual ~XclExpChTrInfo() override
;
283 virtual sal_uInt16
GetNum() const override
;
284 virtual std::size_t GetLen() const override
;
287 // XclExpChTrTabIdBuffer - buffer for tab id's
289 class XclExpChTrTabIdBuffer
292 std::unique_ptr
<sal_uInt16
[]>
299 XclExpChTrTabIdBuffer( sal_uInt16 nCount
);
300 XclExpChTrTabIdBuffer( const XclExpChTrTabIdBuffer
& rCopy
);
301 ~XclExpChTrTabIdBuffer();
303 void InitFill( sal_uInt16 nIndex
);
306 sal_uInt16
GetId( sal_uInt16 nIndex
) const;
309 sal_uInt16
GetBufferCount() const
310 { return static_cast< sal_uInt16
>( (pLast
- pBuffer
.get()) + 1 ); }
311 void GetBufferCopy( sal_uInt16
* pDest
) const
312 { memcpy( pDest
, pBuffer
.get(), sizeof(sal_uInt16
) * GetBufferCount() ); }
315 // XclExpChTrTabId - tab id record
317 class XclExpChTrTabId
: public ExcRecord
320 std::unique_ptr
<sal_uInt16
[]> pBuffer
;
321 sal_uInt16 nTabCount
;
323 void Clear() { pBuffer
.reset(); }
325 virtual void SaveCont( XclExpStream
& rStrm
) override
;
328 XclExpChTrTabId( sal_uInt16 nCount
) : nTabCount( nCount
) {}
329 XclExpChTrTabId( const XclExpChTrTabIdBuffer
& rBuffer
);
330 virtual ~XclExpChTrTabId() override
;
332 void Copy( const XclExpChTrTabIdBuffer
& rBuffer
);
334 virtual sal_uInt16
GetNum() const override
;
335 virtual std::size_t GetLen() const override
;
338 // XclExpChTrAction - base class for action records
340 class XclExpChTrAction
: public ExcRecord
345 sal_uInt32 nIndex
; // action number
346 std::unique_ptr
<XclExpChTrAction
>
347 pAddAction
; // additional record for this action
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_***
357 XclExpChTrAction( const XclExpChTrAction
& rCopy
);
359 void SetAddAction( XclExpChTrAction
* pAction
);
360 void AddDependentContents(
361 const ScChangeAction
& rAction
,
362 const XclExpRoot
& rRoot
,
363 const ScChangeTrack
& rChangeTrack
);
365 static inline void Write2DAddress( XclExpStream
& rStrm
, const ScAddress
& rAddress
);
366 static inline void Write2DRange( XclExpStream
& rStrm
, const ScRange
& rRange
);
367 inline sal_uInt16
GetTabId( SCTAB nTabId
) const;
368 inline void WriteTabId( XclExpStream
& rStrm
, SCTAB nTabId
) const;
370 // save header data, call SaveActionData()
371 virtual void SaveCont( XclExpStream
& rStrm
) override
;
372 static std::size_t GetHeaderByteCount() { return 12; }
374 // override to save action data without header, called by SaveCont()
375 virtual void SaveActionData( XclExpStream
& rStrm
) const = 0;
376 // override to get action size without header, called by GetLen()
377 virtual std::size_t GetActionByteCount() const = 0;
379 // do something before writing the record
380 virtual void PrepareSaveAction( XclExpStream
& rStrm
) const;
381 // do something after writing the record
382 virtual void CompleteSaveAction( XclExpStream
& rStrm
) const;
384 bool GetAccepted() const { return bAccepted
; }
388 const ScChangeAction
& rAction
,
389 const XclExpRoot
& rRoot
,
390 const XclExpChTrTabIdBuffer
& rTabIdBuffer
,
391 sal_uInt16 nNewOpCode
= EXC_CHTR_OP_UNKNOWN
);
392 virtual ~XclExpChTrAction() override
;
394 const OUString
& GetUsername() const { return sUsername
; }
395 const DateTime
& GetDateTime() const { return aDateTime
; }
396 const XclExpChTrTabIdBuffer
& GetTabIdBuffer() const { return rIdBuffer
; }
397 bool ForceInfoRecord() const { return bForceInfo
; }
399 // set own index & return new index
400 // could override to use more indexes per action
401 void SetIndex( sal_uInt32
& rIndex
);
403 virtual void Save( XclExpStream
& rStrm
) override
;
404 virtual std::size_t GetLen() const override
;
406 XclExpChTrAction
* GetAddAction() { return pAddAction
.get(); }
407 sal_uInt32
GetActionNumber() const { return nIndex
; }
410 inline void XclExpChTrAction::Write2DAddress( XclExpStream
& rStrm
, const ScAddress
& rAddress
)
412 rStrm
<< static_cast<sal_uInt16
>(rAddress
.Row())
413 << static_cast<sal_uInt16
>(rAddress
.Col());
416 inline void XclExpChTrAction::Write2DRange( XclExpStream
& rStrm
, const ScRange
& rRange
)
418 rStrm
<< static_cast<sal_uInt16
>(rRange
.aStart
.Row())
419 << static_cast<sal_uInt16
>(rRange
.aEnd
.Row())
420 << static_cast<sal_uInt16
>(rRange
.aStart
.Col())
421 << static_cast<sal_uInt16
>(rRange
.aEnd
.Col());
424 inline sal_uInt16
XclExpChTrAction::GetTabId( SCTAB nTab
) const
426 return rIdBuffer
.GetId( rTabInfo
.GetXclTab( nTab
) );
429 inline void XclExpChTrAction::WriteTabId( XclExpStream
& rStrm
, SCTAB nTab
) const
431 rStrm
<< GetTabId( nTab
);
434 // XclExpChTrData - cell content itself
436 struct XclExpChTrData
438 std::unique_ptr
<XclExpString
> pString
;
439 XclExpStringRef mpFormattedString
;
440 const ScFormulaCell
* mpFormulaCell
;
441 XclTokenArrayRef mxTokArr
;
442 XclExpRefLog maRefLog
;
454 const XclExpChTrTabIdBuffer
& rTabIdBuffer
);
457 const XclExpChTrTabIdBuffer
& rTabIdBuffer
);
460 // XclExpChTrCellContent - changed cell content
462 class XclExpChTrCellContent final
: public XclExpChTrAction
, protected XclExpRoot
464 std::unique_ptr
<XclExpChTrData
> pOldData
;
465 std::unique_ptr
<XclExpChTrData
> pNewData
;
466 sal_uInt16 nOldLength
; // this is not the record size
469 static void MakeEmptyChTrData( std::unique_ptr
<XclExpChTrData
>& rpData
);
472 const XclExpRoot
& rRoot
, const ScCellValue
& rScCell
, std::unique_ptr
<XclExpChTrData
>& rpData
,
473 sal_uInt32
& rXclLength1
, sal_uInt16
& rXclLength2
);
475 virtual void SaveActionData( XclExpStream
& rStrm
) const override
;
478 XclExpChTrCellContent(
479 const ScChangeActionContent
& rAction
,
480 const XclExpRoot
& rRoot
,
481 const XclExpChTrTabIdBuffer
& rTabIdBuffer
);
482 virtual ~XclExpChTrCellContent() override
;
484 virtual sal_uInt16
GetNum() const override
;
485 virtual std::size_t GetActionByteCount() const override
;
487 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
490 // XclExpChTrInsert - insert/delete columns/rows
492 class XclExpChTrInsert
: public XclExpChTrAction
499 XclExpChTrInsert( const XclExpChTrInsert
& rCopy
);
501 virtual void SaveActionData( XclExpStream
& rStrm
) const override
;
502 virtual void PrepareSaveAction( XclExpStream
& rStrm
) const override
;
503 virtual void CompleteSaveAction( XclExpStream
& rStrm
) const override
;
507 const ScChangeAction
& rAction
,
508 const XclExpRoot
& rRoot
,
509 const XclExpChTrTabIdBuffer
& rTabIdBuffer
,
510 const ScChangeTrack
& rChangeTrack
);
511 virtual ~XclExpChTrInsert() override
;
513 virtual sal_uInt16
GetNum() const override
;
514 virtual std::size_t GetActionByteCount() const override
;
516 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
519 // XclExpChTrInsertTab - insert table
521 class XclExpChTrInsertTab
: public XclExpChTrAction
, protected XclExpRoot
527 virtual void SaveActionData( XclExpStream
& rStrm
) const override
;
531 const ScChangeAction
& rAction
,
532 const XclExpRoot
& rRoot
,
533 const XclExpChTrTabIdBuffer
& rTabIdBuffer
);
534 virtual ~XclExpChTrInsertTab() override
;
536 virtual sal_uInt16
GetNum() const override
;
537 virtual std::size_t GetActionByteCount() const override
;
539 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
542 // XclExpChTrMoveRange - move cell range
544 class XclExpChTrMoveRange final
: public XclExpChTrAction
546 ScRange aSourceRange
;
549 virtual void SaveActionData( XclExpStream
& rStrm
) const override
;
550 virtual void PrepareSaveAction( XclExpStream
& rStrm
) const override
;
551 virtual void CompleteSaveAction( XclExpStream
& rStrm
) const override
;
555 const ScChangeActionMove
& rAction
,
556 const XclExpRoot
& rRoot
,
557 const XclExpChTrTabIdBuffer
& rTabIdBuffer
,
558 const ScChangeTrack
& rChangeTrack
);
559 virtual ~XclExpChTrMoveRange() override
;
561 virtual sal_uInt16
GetNum() const override
;
562 virtual std::size_t GetActionByteCount() const override
;
564 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
567 // XclExpChTr0x019A - additional data for delete action
569 class XclExpChTr0x014A
: public XclExpChTrInsert
572 virtual void SaveActionData( XclExpStream
& rStrm
) const override
;
575 XclExpChTr0x014A( const XclExpChTrInsert
& rAction
);
576 virtual ~XclExpChTr0x014A() override
;
578 virtual sal_uInt16
GetNum() const override
;
579 virtual std::size_t GetActionByteCount() const override
;
581 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
584 // XclExpChangeTrack - exports the "Revision Log" stream
586 class XclExpChangeTrack
: protected XclExpRoot
588 typedef std::vector
<std::unique_ptr
<ExcRecord
>> RecListType
;
589 RecListType maRecList
; // list of "Revision Log" stream records
590 std::stack
<XclExpChTrAction
*> aActionStack
;
591 XclExpChTrTabIdBuffer
* pTabIdBuffer
;
592 std::vector
<std::unique_ptr
<XclExpChTrTabIdBuffer
>>
595 ScDocumentUniquePtr xTempDoc
; // empty document
597 ScChangeTrack
* CreateTempChangeTrack();
598 void PushActionRecord( const ScChangeAction
& rAction
);
600 bool WriteUserNamesStream();
603 XclExpChangeTrack( const XclExpRoot
& rRoot
);
604 virtual ~XclExpChangeTrack() override
;
607 void WriteXml( XclExpXmlStream
& rStrm
);
610 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */