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 <unotools/securityoptions.hxx>
26 #include <chgtrack.hxx>
27 #include <document.hxx>
29 #include "xestring.hxx"
30 #include "excrecds.hxx"
31 #include "xlformula.hxx"
33 #include "xeformula.hxx"
35 class ExcXmlRecord
: public ExcRecord
38 virtual std::size_t GetLen() const override
;
39 virtual sal_uInt16
GetNum() const override
;
40 virtual void Save( XclExpStream
& rStrm
) override
;
43 // XclExpUserBView - one UserBView record for each user
45 class XclExpUserBView
: public ExcRecord
48 XclExpString sUsername
;
49 sal_uInt8 aGUID
[ 16 ];
51 virtual void SaveCont( XclExpStream
& rStrm
) override
;
54 XclExpUserBView( const OUString
& rUsername
, const sal_uInt8
* pGUID
);
56 const sal_uInt8
* GetGUID() const { return aGUID
; }
58 virtual sal_uInt16
GetNum() const override
;
59 virtual std::size_t GetLen() const override
;
62 // XclExpUserBViewList - list of UserBView records
64 class XclExpUserBViewList
: public ExcEmptyRec
67 std::vector
<XclExpUserBView
> aViews
;
71 typedef std::vector
<XclExpUserBView
>::const_iterator const_iterator
;
73 XclExpUserBViewList( const ScChangeTrack
& rChangeTrack
);
74 virtual ~XclExpUserBViewList() override
;
76 const_iterator
cbegin () { return aViews
.cbegin(); }
77 const_iterator
cend () { return aViews
.cend(); }
79 virtual void Save( XclExpStream
& rStrm
) override
;
82 // XclExpUsersViewBegin - begin of view block (one per sheet)
84 class XclExpUsersViewBegin
: public ExcRecord
87 sal_uInt8 aGUID
[ 16 ];
90 virtual void SaveCont( XclExpStream
& rStrm
) override
;
93 XclExpUsersViewBegin( const sal_uInt8
* pGUID
, sal_uInt32 nTab
);
94 virtual sal_uInt16
GetNum() const override
;
95 virtual std::size_t GetLen() const override
;
98 // XclExpUsersViewEnd - end of view block (one per sheet)
100 class XclExpUsersViewEnd
: public ExcRecord
103 virtual void SaveCont( XclExpStream
& rStrm
) override
;
106 virtual sal_uInt16
GetNum() const override
;
107 virtual std::size_t GetLen() const override
;
110 // dummy record for "User Names" stream
112 class XclExpChTr0x0191
: public ExcRecord
115 virtual void SaveCont( XclExpStream
& rStrm
) override
;
118 virtual sal_uInt16
GetNum() const override
;
119 virtual std::size_t GetLen() const override
;
122 // dummy record for "User Names" stream
124 class XclExpChTr0x0198
: public ExcRecord
127 virtual void SaveCont( XclExpStream
& rStrm
) override
;
130 virtual sal_uInt16
GetNum() const override
;
131 virtual std::size_t GetLen() const override
;
134 // dummy record for "User Names" stream
136 class XclExpChTr0x0192
: public ExcRecord
139 virtual void SaveCont( XclExpStream
& rStrm
) override
;
142 virtual sal_uInt16
GetNum() const override
;
143 virtual std::size_t GetLen() const override
;
146 // dummy record for "User Names" stream
148 class XclExpChTr0x0197
: public ExcRecord
151 virtual void SaveCont( XclExpStream
& rStrm
) override
;
154 virtual sal_uInt16
GetNum() const override
;
155 virtual std::size_t GetLen() const override
;
158 // dummy record without content
160 class XclExpChTrEmpty
: public ExcRecord
166 XclExpChTrEmpty( sal_uInt16 nNum
) : nRecNum( nNum
) {}
167 virtual ~XclExpChTrEmpty() override
;
169 virtual sal_uInt16
GetNum() const override
;
170 virtual std::size_t GetLen() const override
;
173 // dummy record for "Revision Log" stream
175 class XclExpChTr0x0195
: public ExcRecord
178 virtual void SaveCont( XclExpStream
& rStrm
) override
;
181 virtual ~XclExpChTr0x0195() override
;
183 virtual sal_uInt16
GetNum() const override
;
184 virtual std::size_t GetLen() const override
;
187 // dummy record for "Revision Log" stream
189 class XclExpChTr0x0194
: public ExcRecord
192 XclExpString sUsername
;
195 virtual void SaveCont( XclExpStream
& rStrm
) override
;
198 inline XclExpChTr0x0194( const ScChangeTrack
& rChangeTrack
);
199 virtual ~XclExpChTr0x0194() override
;
201 virtual sal_uInt16
GetNum() const override
;
202 virtual std::size_t GetLen() const override
;
205 inline XclExpChTr0x0194::XclExpChTr0x0194( const ScChangeTrack
& rChangeTrack
) :
206 sUsername( rChangeTrack
.GetUser() ),
207 aDateTime( rChangeTrack
.GetFixDateTime() )
211 // XclExpChTrHeader - header record, includes action count
213 class XclExpChTrHeader
: public ExcRecord
216 sal_uInt8 aGUID
[ 16 ];
219 virtual void SaveCont( XclExpStream
& rStrm
) override
;
222 XclExpChTrHeader() : nCount( 0 ) {}
223 virtual ~XclExpChTrHeader() override
;
225 void SetGUID( const sal_uInt8
* pGUID
) { memcpy( aGUID
, pGUID
, 16 ); }
226 void SetCount( sal_uInt32 nNew
) { nCount
= nNew
; }
228 virtual sal_uInt16
GetNum() const override
;
229 virtual std::size_t GetLen() const override
;
231 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
234 class XclExpXmlChTrHeaders
: public ExcXmlRecord
236 sal_uInt8 maGUID
[16];
238 void SetGUID( const sal_uInt8
* pGUID
);
240 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
243 class XclExpChTrTabIdBuffer
;
244 class XclExpChTrAction
;
246 class XclExpXmlChTrHeader
: public ExcXmlRecord
250 sal_uInt8 maGUID
[16];
251 sal_Int32 mnLogNumber
;
252 sal_uInt32 mnMinAction
;
253 sal_uInt32 mnMaxAction
;
255 std::vector
<sal_uInt16
> maTabBuffer
;
256 std::vector
<std::unique_ptr
<XclExpChTrAction
>> maActions
;
260 OUString aUserName
, const DateTime
& rDateTime
, const sal_uInt8
* pGUID
,
261 sal_Int32 nLogNumber
, const XclExpChTrTabIdBuffer
& rBuf
);
263 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
265 void AppendAction( std::unique_ptr
<XclExpChTrAction
> pAction
);
268 /// map authors to remove personal info
269 std::unique_ptr
<SvtSecurityMapPersonalInfo
> mpAuthorIDs
;
272 // XclExpChTrInfo - header of action group of a user
274 class XclExpChTrInfo
: public ExcRecord
277 XclExpString sUsername
;
279 sal_uInt8 aGUID
[ 16 ];
281 virtual void SaveCont( XclExpStream
& rStrm
) override
;
284 XclExpChTrInfo( const OUString
& rUsername
, const DateTime
& rDateTime
,
285 const sal_uInt8
* pGUID
);
287 virtual ~XclExpChTrInfo() override
;
289 virtual sal_uInt16
GetNum() const override
;
290 virtual std::size_t GetLen() const override
;
293 // XclExpChTrTabIdBuffer - buffer for tab id's
295 class XclExpChTrTabIdBuffer
298 std::unique_ptr
<sal_uInt16
[]>
305 XclExpChTrTabIdBuffer( sal_uInt16 nCount
);
306 XclExpChTrTabIdBuffer( const XclExpChTrTabIdBuffer
& rCopy
);
307 ~XclExpChTrTabIdBuffer();
309 void InitFill( sal_uInt16 nIndex
);
312 sal_uInt16
GetId( sal_uInt16 nIndex
) const;
313 bool HasId( sal_uInt16 nIndex
) const;
316 sal_uInt16
GetBufferCount() const
317 { return static_cast< sal_uInt16
>( (pLast
- pBuffer
.get()) + 1 ); }
318 void GetBufferCopy( sal_uInt16
* pDest
) const
319 { memcpy( pDest
, pBuffer
.get(), sizeof(sal_uInt16
) * GetBufferCount() ); }
322 // XclExpChTrTabId - tab id record
324 class XclExpChTrTabId
: public ExcRecord
327 std::unique_ptr
<sal_uInt16
[]> pBuffer
;
328 sal_uInt16 nTabCount
;
330 void Clear() { pBuffer
.reset(); }
332 virtual void SaveCont( XclExpStream
& rStrm
) override
;
335 XclExpChTrTabId( sal_uInt16 nCount
) : nTabCount( nCount
) {}
336 XclExpChTrTabId( const XclExpChTrTabIdBuffer
& rBuffer
);
337 virtual ~XclExpChTrTabId() override
;
339 void Copy( const XclExpChTrTabIdBuffer
& rBuffer
);
341 virtual sal_uInt16
GetNum() const override
;
342 virtual std::size_t GetLen() const override
;
345 // XclExpChTrAction - base class for action records
347 class XclExpChTrAction
: public ExcRecord
352 sal_uInt32 nIndex
; // action number
353 std::unique_ptr
<XclExpChTrAction
>
354 pAddAction
; // additional record for this action
358 const XclExpTabInfo
& rTabInfo
; // for table num export (sc num -> xcl num)
359 const XclExpChTrTabIdBuffer
& rIdBuffer
; // for table num export (xcl num -> tab id)
360 sal_uInt32 nLength
; // this is not the record size
361 sal_uInt16 nOpCode
; // EXC_CHTR_OP_***
364 XclExpChTrAction( const XclExpChTrAction
& rCopy
);
366 void SetAddAction( XclExpChTrAction
* pAction
);
367 void AddDependentContents(
368 const ScChangeAction
& rAction
,
369 const XclExpRoot
& rRoot
,
370 const ScChangeTrack
& rChangeTrack
);
372 static inline void Write2DAddress( XclExpStream
& rStrm
, const ScAddress
& rAddress
);
373 static inline void Write2DRange( XclExpStream
& rStrm
, const ScRange
& rRange
);
374 inline sal_uInt16
GetTabId( SCTAB nTabId
) const;
375 inline bool IsDeletedTab( SCTAB nTab
) const;
376 inline void WriteTabId( XclExpStream
& rStrm
, SCTAB nTabId
) const;
378 // save header data, call SaveActionData()
379 virtual void SaveCont( XclExpStream
& rStrm
) override
;
380 static std::size_t GetHeaderByteCount() { return 12; }
382 // override to save action data without header, called by SaveCont()
383 virtual void SaveActionData( XclExpStream
& rStrm
) const = 0;
384 // override to get action size without header, called by GetLen()
385 virtual std::size_t GetActionByteCount() const = 0;
387 // true if export would attempt to get the tab id of an unknown tab
388 virtual bool UsesDeletedTab() const = 0;
390 // do something before writing the record
391 virtual void PrepareSaveAction( XclExpStream
& rStrm
) const;
392 // do something after writing the record
393 virtual void CompleteSaveAction( XclExpStream
& rStrm
) const;
395 bool GetAccepted() const { return bAccepted
; }
399 const ScChangeAction
& rAction
,
400 const XclExpRoot
& rRoot
,
401 const XclExpChTrTabIdBuffer
& rTabIdBuffer
,
402 sal_uInt16 nNewOpCode
= EXC_CHTR_OP_UNKNOWN
);
403 virtual ~XclExpChTrAction() override
;
405 const OUString
& GetUsername() const { return sUsername
; }
406 const DateTime
& GetDateTime() const { return aDateTime
; }
407 const XclExpChTrTabIdBuffer
& GetTabIdBuffer() const { return rIdBuffer
; }
408 bool ForceInfoRecord() const { return bForceInfo
; }
410 // set own index & return new index
411 // could override to use more indexes per action
412 void SetIndex( sal_uInt32
& rIndex
);
414 virtual void Save( XclExpStream
& rStrm
) override
;
415 virtual std::size_t GetLen() const override
;
417 XclExpChTrAction
* GetAddAction() { return pAddAction
.get(); }
418 sal_uInt32
GetActionNumber() const { return nIndex
; }
421 inline void XclExpChTrAction::Write2DAddress( XclExpStream
& rStrm
, const ScAddress
& rAddress
)
423 rStrm
<< static_cast<sal_uInt16
>(rAddress
.Row())
424 << static_cast<sal_uInt16
>(rAddress
.Col());
427 inline void XclExpChTrAction::Write2DRange( XclExpStream
& rStrm
, const ScRange
& rRange
)
429 rStrm
<< static_cast<sal_uInt16
>(rRange
.aStart
.Row())
430 << static_cast<sal_uInt16
>(rRange
.aEnd
.Row())
431 << static_cast<sal_uInt16
>(rRange
.aStart
.Col())
432 << static_cast<sal_uInt16
>(rRange
.aEnd
.Col());
435 inline bool XclExpChTrAction::IsDeletedTab(SCTAB nTab
) const
437 return rTabInfo
.GetXclTab(nTab
) == EXC_TAB_DELETED
;
440 inline sal_uInt16
XclExpChTrAction::GetTabId( SCTAB nTab
) const
442 return rIdBuffer
.GetId( rTabInfo
.GetXclTab( nTab
) );
445 inline void XclExpChTrAction::WriteTabId( XclExpStream
& rStrm
, SCTAB nTab
) const
447 rStrm
<< GetTabId( nTab
);
450 // XclExpChTrData - cell content itself
452 struct XclExpChTrData
454 std::unique_ptr
<XclExpString
> pString
;
455 XclExpStringRef mpFormattedString
;
456 const ScFormulaCell
* mpFormulaCell
;
457 XclTokenArrayRef mxTokArr
;
458 XclExpRefLog maRefLog
;
470 const XclExpChTrTabIdBuffer
& rTabIdBuffer
);
473 const XclExpChTrTabIdBuffer
& rTabIdBuffer
);
475 bool UsesDeletedTab(const XclExpChTrTabIdBuffer
& rTabIdBuffer
) const;
478 // XclExpChTrCellContent - changed cell content
480 class XclExpChTrCellContent final
: public XclExpChTrAction
, protected XclExpRoot
482 std::unique_ptr
<XclExpChTrData
> pOldData
;
483 std::unique_ptr
<XclExpChTrData
> pNewData
;
484 sal_uInt16 nOldLength
; // this is not the record size
487 static void MakeEmptyChTrData( std::unique_ptr
<XclExpChTrData
>& rpData
);
490 const XclExpRoot
& rRoot
, const ScCellValue
& rScCell
, std::unique_ptr
<XclExpChTrData
>& rpData
,
491 sal_uInt32
& rXclLength1
, sal_uInt16
& rXclLength2
);
493 virtual bool UsesDeletedTab() const override
;
495 virtual void SaveActionData( XclExpStream
& rStrm
) const override
;
498 XclExpChTrCellContent(
499 const ScChangeActionContent
& rAction
,
500 const XclExpRoot
& rRoot
,
501 const XclExpChTrTabIdBuffer
& rTabIdBuffer
);
502 virtual ~XclExpChTrCellContent() override
;
504 virtual sal_uInt16
GetNum() const override
;
505 virtual std::size_t GetActionByteCount() const override
;
507 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
510 // XclExpChTrInsert - insert/delete columns/rows
512 class XclExpChTrInsert
: public XclExpChTrAction
519 XclExpChTrInsert( const XclExpChTrInsert
& rCopy
);
521 virtual bool UsesDeletedTab() const override
;
523 virtual void SaveActionData( XclExpStream
& rStrm
) const override
;
524 virtual void PrepareSaveAction( XclExpStream
& rStrm
) const override
;
525 virtual void CompleteSaveAction( XclExpStream
& rStrm
) const override
;
529 const ScChangeAction
& rAction
,
530 const XclExpRoot
& rRoot
,
531 const XclExpChTrTabIdBuffer
& rTabIdBuffer
,
532 const ScChangeTrack
& rChangeTrack
);
533 virtual ~XclExpChTrInsert() override
;
535 virtual sal_uInt16
GetNum() const override
;
536 virtual std::size_t GetActionByteCount() const override
;
538 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
541 // XclExpChTrInsertTab - insert table
543 class XclExpChTrInsertTab
: public XclExpChTrAction
, protected XclExpRoot
550 virtual bool UsesDeletedTab() const override
;
552 virtual void SaveActionData( XclExpStream
& rStrm
) const override
;
556 const ScChangeAction
& rAction
,
557 const XclExpRoot
& rRoot
,
558 const XclExpChTrTabIdBuffer
& rTabIdBuffer
);
559 virtual ~XclExpChTrInsertTab() override
;
561 virtual sal_uInt16
GetNum() const override
;
562 virtual std::size_t GetActionByteCount() const override
;
564 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
567 // XclExpChTrMoveRange - move cell range
569 class XclExpChTrMoveRange final
: public XclExpChTrAction
571 ScRange aSourceRange
;
574 virtual bool UsesDeletedTab() const override
;
576 virtual void SaveActionData( XclExpStream
& rStrm
) const override
;
577 virtual void PrepareSaveAction( XclExpStream
& rStrm
) const override
;
578 virtual void CompleteSaveAction( XclExpStream
& rStrm
) const override
;
582 const ScChangeActionMove
& rAction
,
583 const XclExpRoot
& rRoot
,
584 const XclExpChTrTabIdBuffer
& rTabIdBuffer
,
585 const ScChangeTrack
& rChangeTrack
);
586 virtual ~XclExpChTrMoveRange() override
;
588 virtual sal_uInt16
GetNum() const override
;
589 virtual std::size_t GetActionByteCount() const override
;
591 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
594 // XclExpChTr0x019A - additional data for delete action
596 class XclExpChTr0x014A
: public XclExpChTrInsert
599 virtual void SaveActionData( XclExpStream
& rStrm
) const override
;
602 XclExpChTr0x014A( const XclExpChTrInsert
& rAction
);
603 virtual ~XclExpChTr0x014A() override
;
605 virtual sal_uInt16
GetNum() const override
;
606 virtual std::size_t GetActionByteCount() const override
;
608 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
611 // XclExpChangeTrack - exports the "Revision Log" stream
613 class XclExpChangeTrack
: protected XclExpRoot
615 typedef std::vector
<std::unique_ptr
<ExcRecord
>> RecListType
;
616 RecListType maRecList
; // list of "Revision Log" stream records
617 std::stack
<XclExpChTrAction
*> aActionStack
;
618 XclExpChTrTabIdBuffer
* pTabIdBuffer
;
619 std::vector
<std::unique_ptr
<XclExpChTrTabIdBuffer
>>
622 ScDocumentUniquePtr xTempDoc
; // empty document
624 ScChangeTrack
* CreateTempChangeTrack();
625 void PushActionRecord( const ScChangeAction
& rAction
);
627 bool WriteUserNamesStream();
630 XclExpChangeTrack( const XclExpRoot
& rRoot
);
631 virtual ~XclExpChangeTrack() override
;
634 void WriteXml( XclExpXmlStream
& rStrm
);
637 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */