Bump version to 6.4-15
[LibreOffice.git] / sc / inc / chgtrack.hxx
blobbaa51b30419e3dcfec765dbba3d4c56dd1a797cc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #ifndef INCLUDED_SC_INC_CHGTRACK_HXX
21 #define INCLUDED_SC_INC_CHGTRACK_HXX
23 #include <map>
24 #include <memory>
25 #include <set>
26 #include <stack>
27 #include <vector>
29 #include <com/sun/star/uno/Sequence.hxx>
30 #include <tools/color.hxx>
31 #include <tools/datetime.hxx>
32 #include <tools/link.hxx>
33 #include <tools/solar.h>
34 #include <unotools/options.hxx>
35 #include <boost/optional.hpp>
36 #include "global.hxx"
37 #include "bigrange.hxx"
38 #include "scdllapi.h"
39 #include "cellvalue.hxx"
41 class ScDocument;
42 class ScFormulaCell;
43 class ScChangeAction;
44 class ScChangeTrack;
45 class ScAppOptions;
46 namespace tools { class JsonWriter; }
48 class ScActionColorChanger
50 private:
51 const ScAppOptions& rOpt;
52 const std::set<OUString>& rUsers;
53 OUString aLastUserName;
54 sal_uInt16 nLastUserIndex;
55 Color nColor;
57 public:
58 ScActionColorChanger( const ScChangeTrack& rTrack );
59 void Update( const ScChangeAction& rAction );
60 Color GetColor() const { return nColor; }
63 enum ScChangeActionType
65 SC_CAT_NONE,
66 SC_CAT_INSERT_COLS,
67 SC_CAT_INSERT_ROWS,
68 SC_CAT_INSERT_TABS,
69 SC_CAT_DELETE_COLS,
70 SC_CAT_DELETE_ROWS,
71 SC_CAT_DELETE_TABS,
72 SC_CAT_MOVE,
73 SC_CAT_CONTENT,
74 SC_CAT_REJECT
77 enum ScChangeActionState
79 SC_CAS_VIRGIN,
80 SC_CAS_ACCEPTED,
81 SC_CAS_REJECTED
84 enum ScChangeActionClipMode
86 SC_CACM_NONE,
87 SC_CACM_CUT,
88 SC_CACM_PASTE
91 /** A link/connection/dependency between change actions.
93 Upon construction inserts itself as the head of a chain / linked list,
94 respectively between existing link entries.
96 Upon destruction removes itself from the list and connects the previous and
97 next entry, if it was the first entry automatically maintaining the head
98 pointer to the list.
100 ppPrev == &previous->pNext or address of pointer to head of linked list,
101 *ppPrev == this
103 class ScChangeActionLinkEntry
105 ScChangeActionLinkEntry( const ScChangeActionLinkEntry& ) = delete;
106 ScChangeActionLinkEntry& operator=( const ScChangeActionLinkEntry& ) = delete;
108 protected:
110 ScChangeActionLinkEntry* pNext;
111 ScChangeActionLinkEntry** ppPrev;
112 ScChangeAction* const pAction;
113 ScChangeActionLinkEntry* pLink;
115 public:
117 ScChangeActionLinkEntry(
118 ScChangeActionLinkEntry** ppPrevP,
119 ScChangeAction* pActionP )
120 : pNext( *ppPrevP ),
121 ppPrev( ppPrevP ),
122 pAction( pActionP ),
123 pLink( nullptr )
125 if ( pNext )
126 pNext->ppPrev = &pNext;
127 *ppPrevP = this;
130 virtual ~ScChangeActionLinkEntry()
132 ScChangeActionLinkEntry* p = pLink;
133 UnLink();
134 Remove();
135 if ( p )
136 delete p;
139 void SetLink( ScChangeActionLinkEntry* pLinkP )
141 UnLink();
142 if ( pLinkP )
144 pLink = pLinkP;
145 pLinkP->pLink = this;
149 void UnLink()
151 if ( pLink )
153 pLink->pLink = nullptr;
154 pLink = nullptr;
158 void Remove()
160 if ( ppPrev )
162 if ( ( *ppPrev = pNext ) != nullptr )
163 pNext->ppPrev = ppPrev;
164 ppPrev = nullptr; // not inserted
168 const ScChangeActionLinkEntry* GetNext() const { return pNext; }
169 ScChangeActionLinkEntry* GetNext() { return pNext; }
170 const ScChangeAction* GetAction() const { return pAction; }
171 ScChangeAction* GetAction() { return pAction; }
174 // ScChangeActionCellListEntry
175 // this is only for the XML Export in the hxx
176 class ScChangeActionContent;
178 class SAL_DLLPUBLIC_RTTI ScChangeAction
180 friend class ScChangeTrack;
181 friend class ScChangeActionIns;
182 friend class ScChangeActionDel;
183 friend class ScChangeActionMove;
184 friend class ScChangeActionContent;
186 ScChangeAction( const ScChangeAction& ) = delete;
187 ScChangeAction& operator=( const ScChangeAction& ) = delete;
189 protected:
191 ScBigRange aBigRange; // Ins/Del/MoveTo/ContentPos
192 DateTime aDateTime; //! UTC
193 OUString aUser; // who?
194 OUString aComment; // user comment
195 ScChangeAction* pNext; // next in linked list
196 ScChangeAction* pPrev; // previous in linked list
197 ScChangeActionLinkEntry* pLinkAny; // arbitrary links
198 ScChangeActionLinkEntry* pLinkDeletedIn; // access to insert areas which were
199 // deleted or moved or rejected
200 ScChangeActionLinkEntry* pLinkDeleted; // links to deleted
201 ScChangeActionLinkEntry* pLinkDependent; // links to dependent
202 sal_uLong nAction;
203 sal_uLong nRejectAction;
204 ScChangeActionType eType;
205 ScChangeActionState eState;
207 ScChangeAction( ScChangeActionType, const ScRange& );
209 // only to be used in the XML import
210 ScChangeAction( ScChangeActionType,
211 const ScBigRange&,
212 const sal_uLong nAction,
213 const sal_uLong nRejectAction,
214 const ScChangeActionState eState,
215 const DateTime& aDateTime,
216 const OUString& aUser,
217 const OUString& aComment );
219 // only to be used in the XML import
220 ScChangeAction( ScChangeActionType, const ScBigRange&, const sal_uLong nAction);
222 OUString GetRefString(
223 const ScBigRange& rRange, const ScDocument* pDoc, bool bFlag3D = false) const;
225 void SetActionNumber( sal_uLong n ) { nAction = n; }
226 void SetRejectAction( sal_uLong n ) { nRejectAction = n; }
227 void SetUser( const OUString& r );
228 void SetType( ScChangeActionType e ) { eType = e; }
229 void SetState( ScChangeActionState e ) { eState = e; }
230 void SetRejected();
232 ScBigRange& GetBigRange() { return aBigRange; }
234 void AddLink( ScChangeAction* p, ScChangeActionLinkEntry* pL )
236 ScChangeActionLinkEntry* pLnk =
237 new ScChangeActionLinkEntry(
238 &pLinkAny, p );
239 pLnk->SetLink( pL );
242 virtual ScChangeActionLinkEntry* GetDeletedIn() const
243 { return pLinkDeletedIn; }
244 virtual ScChangeActionLinkEntry** GetDeletedInAddress()
245 { return &pLinkDeletedIn; }
246 bool RemoveDeletedIn( const ScChangeAction* );
247 void SetDeletedIn( ScChangeAction* );
249 ScChangeActionLinkEntry* AddDeleted( ScChangeAction* p )
251 return new ScChangeActionLinkEntry(&pLinkDeleted, p);
254 ScChangeActionLinkEntry* AddDependent( ScChangeAction* p )
256 return new ScChangeActionLinkEntry(&pLinkDependent, p);
259 void RemoveAllDependent();
261 void RemoveAllLinks();
263 virtual void AddContent( ScChangeActionContent* ) = 0;
264 virtual void DeleteCellEntries() = 0;
266 virtual void UpdateReference( const ScChangeTrack*,
267 UpdateRefMode, const ScBigRange&,
268 sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz );
270 void Accept();
271 virtual bool Reject(ScDocument* pDoc) = 0;
272 void RejectRestoreContents( ScChangeTrack*, SCCOL nDx, SCROW nDy );
274 // used in Reject() instead of IsRejectable()
275 bool IsInternalRejectable() const;
277 // Derived classes that hold a pointer to the
278 // ChangeTrack must return that. Otherwise NULL.
279 virtual const ScChangeTrack* GetChangeTrack() const = 0;
281 public:
282 virtual ~ScChangeAction();
284 bool IsInsertType() const;
285 bool IsDeleteType() const;
286 bool IsVirgin() const;
287 SC_DLLPUBLIC bool IsAccepted() const;
288 bool IsRejected() const;
290 // Action rejects another Action
291 bool IsRejecting() const;
293 // if action is visible in the document
294 bool IsVisible() const;
296 // if action if touchable
297 bool IsTouchable() const;
299 // if action is an entry in dialog root
300 bool IsDialogRoot() const;
302 // if an entry in a dialog shall be a drop down entry
303 bool IsDialogParent() const;
305 // if action is a delete with subdeletes (aufgeklappt = open ?)
306 bool IsMasterDelete() const;
308 // if action is acceptable/selectable/rejectable
309 bool IsClickable() const;
311 // if action is rejectable
312 bool IsRejectable() const;
314 const ScBigRange& GetBigRange() const { return aBigRange; }
315 SC_DLLPUBLIC DateTime GetDateTime() const; // local time
316 const DateTime& GetDateTimeUTC() const // UTC time
317 { return aDateTime; }
318 ScChangeActionType GetType() const { return eType; }
319 ScChangeActionState GetState() const { return eState; }
320 sal_uLong GetActionNumber() const { return nAction; }
321 sal_uLong GetRejectAction() const { return nRejectAction; }
323 ScChangeAction* GetNext() const { return pNext; }
324 ScChangeAction* GetPrev() const { return pPrev; }
326 bool IsDeletedIn() const;
327 bool IsDeletedIn( const ScChangeAction* ) const;
328 bool IsDeletedInDelType( ScChangeActionType ) const;
329 void RemoveAllDeletedIn();
331 const ScChangeActionLinkEntry* GetFirstDeletedEntry() const
332 { return pLinkDeleted; }
333 const ScChangeActionLinkEntry* GetFirstDependentEntry() const
334 { return pLinkDependent; }
335 bool HasDependent() const;
336 bool HasDeleted() const;
337 // description will be appended to string
338 // with bSplitRange only one column/row will be considered for delete
339 // (for a listing of entries)
340 virtual void GetDescription(
341 OUString& rStr, ScDocument* pDoc,
342 bool bSplitRange = false, bool bWarning = true ) const;
344 virtual void GetRefString(
345 OUString& rStr, ScDocument* pDoc, bool bFlag3D = false ) const;
347 // for DocumentMerge set old date of the other
348 // action, fetched by GetDateTimeUTC
349 void SetDateTimeUTC( const DateTime& rDT )
350 { aDateTime = rDT; }
352 const OUString& GetUser() const { return aUser;}
353 const OUString& GetComment() const { return aComment;}
355 // set user comment
356 void SetComment( const OUString& rStr );
358 // only to be used in the XML import
359 void SetDeletedInThis( sal_uLong nActionNumber,
360 const ScChangeTrack* pTrack );
361 // only to be used in the XML import
362 void AddDependent( sal_uLong nActionNumber,
363 const ScChangeTrack* pTrack );
366 // ScChangeActionIns
367 class SAL_DLLPUBLIC_RTTI ScChangeActionIns : public ScChangeAction
369 friend class ScChangeTrack;
371 bool const mbEndOfList; /// whether or not a row was auto-inserted at the bottom.
373 ScChangeActionIns( const ScDocument* pDoc, const ScRange& rRange, bool bEndOfList = false );
375 virtual void AddContent( ScChangeActionContent* ) override {}
376 virtual void DeleteCellEntries() override {}
378 virtual bool Reject(ScDocument* pDoc) override;
380 virtual const ScChangeTrack* GetChangeTrack() const override { return nullptr; }
382 public:
383 virtual ~ScChangeActionIns() override;
384 ScChangeActionIns(
385 const sal_uLong nActionNumber,
386 const ScChangeActionState eState,
387 const sal_uLong nRejectingNumber,
388 const ScBigRange& aBigRange,
389 const OUString& aUser,
390 const DateTime& aDateTime,
391 const OUString &sComment,
392 const ScChangeActionType eType,
393 bool bEndOfList = false );
395 virtual void GetDescription(
396 OUString& rStr, ScDocument* pDoc, bool bSplitRange = false, bool bWarning = true) const override;
398 SC_DLLPUBLIC bool IsEndOfList() const;
401 // ScChangeActionDel
402 class SAL_DLLPUBLIC_RTTI ScChangeActionMove;
404 class ScChangeActionDelMoveEntry final : public ScChangeActionLinkEntry
406 friend class ScChangeActionDel;
407 friend class ScChangeTrack;
409 short const nCutOffFrom;
410 short const nCutOffTo;
412 inline ScChangeActionDelMoveEntry(
413 ScChangeActionDelMoveEntry** ppPrevP,
414 ScChangeActionMove* pMove,
415 short nFrom, short nTo );
417 inline ScChangeActionMove* GetMove();
419 public:
420 const ScChangeActionDelMoveEntry* GetNext() const
422 return static_cast<const ScChangeActionDelMoveEntry*>(
423 ScChangeActionLinkEntry::GetNext());
425 inline const ScChangeActionMove* GetMove() const;
426 short GetCutOffFrom() const { return nCutOffFrom; }
427 short GetCutOffTo() const { return nCutOffTo; }
430 class ScChangeActionDel final : public ScChangeAction
432 friend class ScChangeTrack;
433 friend void ScChangeAction::Accept();
435 ScChangeTrack* pTrack;
436 std::vector<ScChangeActionContent*> mvCells;
437 ScChangeActionIns* pCutOff; // cut insert
438 short nCutOff; // +: start -: end
439 ScChangeActionDelMoveEntry* pLinkMove;
440 SCCOL nDx;
441 SCROW nDy;
443 ScChangeActionDel( const ScDocument* pDoc, const ScRange& rRange, SCCOL nDx, SCROW nDy, ScChangeTrack* );
445 virtual void AddContent( ScChangeActionContent* ) override;
446 virtual void DeleteCellEntries() override;
448 void UndoCutOffMoves();
449 void UndoCutOffInsert();
451 virtual void UpdateReference( const ScChangeTrack*,
452 UpdateRefMode, const ScBigRange&,
453 sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz ) override;
455 virtual bool Reject(ScDocument* pDoc) override;
457 virtual const ScChangeTrack* GetChangeTrack() const override { return pTrack; }
459 public:
460 ScChangeActionDel(
461 const sal_uLong nActionNumber, const ScChangeActionState eState,
462 const sal_uLong nRejectingNumber, const ScBigRange& aBigRange,
463 const OUString& aUser, const DateTime& aDateTime,
464 const OUString &sComment, const ScChangeActionType eType,
465 const SCCOLROW nD, ScChangeTrack* pTrack); // only to use in the XML import
466 // which of nDx and nDy is set is dependent on the type
467 virtual ~ScChangeActionDel() override;
469 // is the last in a row (or single)
470 bool IsBaseDelete() const;
472 // is the first in a row (or single)
473 bool IsTopDelete() const;
475 // is part of a row
476 bool IsMultiDelete() const;
478 // is col, belonging to a TabDelete
479 bool IsTabDeleteCol() const;
481 SCCOL GetDx() const { return nDx; }
482 SCROW GetDy() const { return nDy; }
483 ScBigRange GetOverAllRange() const; // BigRange + (nDx, nDy)
485 const ScChangeActionDelMoveEntry* GetFirstMoveEntry() const
486 { return pLinkMove; }
487 const ScChangeActionIns* GetCutOffInsert() const { return pCutOff; }
488 short GetCutOffCount() const { return nCutOff; }
490 virtual void GetDescription(
491 OUString& rStr, ScDocument* pDoc, bool bSplitRange = false, bool bWarning = true ) const override;
493 void SetCutOffInsert( ScChangeActionIns* p, short n )
494 { pCutOff = p; nCutOff = n; } // only to use in the XML import
495 // this should be protected, but for the XML import it is public
496 // only to use in the XML import
497 // this should be protected, but for the XML import it is public
498 ScChangeActionDelMoveEntry* AddCutOffMove(
499 ScChangeActionMove* pMove, short nFrom, short nTo );
502 // ScChangeActionMove
503 class ScChangeActionMove final : public ScChangeAction
505 friend class ScChangeTrack;
506 friend struct std::default_delete<ScChangeActionMove>; // for std::unique_ptr
507 friend class ScChangeActionDel;
509 ScBigRange aFromRange;
510 ScChangeTrack* pTrack;
511 std::vector<ScChangeActionContent*> mvCells;
512 sal_uLong nStartLastCut; // for PasteCut undo
513 sal_uLong nEndLastCut;
515 ScChangeActionMove( const ScRange& rFromRange,
516 const ScRange& rToRange,
517 ScChangeTrack* pTrackP )
518 : ScChangeAction( SC_CAT_MOVE, rToRange ),
519 aFromRange( rFromRange ),
520 pTrack( pTrackP ),
521 nStartLastCut(0),
522 nEndLastCut(0)
524 virtual ~ScChangeActionMove() override;
526 virtual void AddContent( ScChangeActionContent* ) override;
527 virtual void DeleteCellEntries() override;
529 ScBigRange& GetFromRange() { return aFromRange; }
531 void SetStartLastCut( sal_uLong nVal ) { nStartLastCut = nVal; }
532 sal_uLong GetStartLastCut() const { return nStartLastCut; }
533 void SetEndLastCut( sal_uLong nVal ) { nEndLastCut = nVal; }
534 sal_uLong GetEndLastCut() const { return nEndLastCut; }
536 virtual void UpdateReference( const ScChangeTrack*,
537 UpdateRefMode, const ScBigRange&,
538 sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz ) override;
540 virtual bool Reject(ScDocument* pDoc) override;
542 virtual const ScChangeTrack* GetChangeTrack() const override { return pTrack; }
544 protected:
545 using ScChangeAction::GetRefString;
547 public:
548 ScChangeActionMove(const sal_uLong nActionNumber,
549 const ScChangeActionState eState,
550 const sal_uLong nRejectingNumber,
551 const ScBigRange& aToBigRange,
552 const OUString& aUser,
553 const DateTime& aDateTime,
554 const OUString &sComment,
555 const ScBigRange& aFromBigRange,
556 ScChangeTrack* pTrack); // only to use in the XML import
558 const ScBigRange& GetFromRange() const { return aFromRange; }
559 SC_DLLPUBLIC void GetDelta( sal_Int32& nDx, sal_Int32& nDy, sal_Int32& nDz ) const;
561 virtual void GetDescription(
562 OUString& rStr, ScDocument* pDoc, bool bSplitRange = false,
563 bool bWarning = true ) const override;
565 virtual void GetRefString(
566 OUString& rStr, ScDocument* pDoc, bool bFlag3D = false ) const override;
569 ScChangeActionDelMoveEntry::ScChangeActionDelMoveEntry(
570 ScChangeActionDelMoveEntry** ppPrevP,
571 ScChangeActionMove* pMove,
572 short nFrom, short nTo )
573 : ScChangeActionLinkEntry(
574 reinterpret_cast<ScChangeActionLinkEntry**>(
575 ppPrevP),
576 static_cast<ScChangeAction*>(pMove) ),
577 nCutOffFrom( nFrom ),
578 nCutOffTo( nTo )
581 inline ScChangeActionMove* ScChangeActionDelMoveEntry::GetMove()
583 return static_cast<ScChangeActionMove*>(
584 ScChangeActionLinkEntry::GetAction());
587 inline const ScChangeActionMove* ScChangeActionDelMoveEntry::GetMove() const
589 return static_cast<const ScChangeActionMove*>(
590 ScChangeActionLinkEntry::GetAction());
592 // ScChangeActionContent
593 enum ScChangeActionContentCellType
595 SC_CACCT_NONE = 0,
596 SC_CACCT_NORMAL,
597 SC_CACCT_MATORG,
598 SC_CACCT_MATREF
601 class SAL_DLLPUBLIC_RTTI ScChangeActionContent : public ScChangeAction
603 friend class ScChangeTrack;
605 ScCellValue maOldCell;
606 ScCellValue maNewCell;
608 OUString maOldValue;
609 OUString maNewValue;
610 ScChangeActionContent* pNextContent; // at the same position
611 ScChangeActionContent* pPrevContent;
612 ScChangeActionContent* pNextInSlot; // in the same slot
613 ScChangeActionContent** ppPrevInSlot;
615 void InsertInSlot( ScChangeActionContent** pp )
617 if ( !ppPrevInSlot )
619 ppPrevInSlot = pp;
620 if ( ( pNextInSlot = *pp ) != nullptr )
621 pNextInSlot->ppPrevInSlot = &pNextInSlot;
622 *pp = this;
626 void RemoveFromSlot()
628 if ( ppPrevInSlot )
630 if ( ( *ppPrevInSlot = pNextInSlot ) != nullptr )
631 pNextInSlot->ppPrevInSlot = ppPrevInSlot;
632 ppPrevInSlot = nullptr; // not inserted
636 ScChangeActionContent* GetNextInSlot() { return pNextInSlot; }
638 void ClearTrack();
640 static void GetStringOfCell(
641 OUString& rStr, const ScCellValue& rCell, const ScDocument* pDoc, const ScAddress& rPos );
643 static void GetStringOfCell(
644 OUString& rStr, const ScCellValue& rCell, const ScDocument* pDoc, sal_uLong nFormat );
646 static void SetValue( OUString& rStr, ScCellValue& rCell, const ScAddress& rPos,
647 const ScCellValue& rOrgCell, const ScDocument* pFromDoc,
648 ScDocument* pToDoc );
650 static void SetValue( OUString& rStr, ScCellValue& rCell, sal_uLong nFormat,
651 const ScCellValue& rOrgCell, const ScDocument* pFromDoc,
652 ScDocument* pToDoc );
654 static void SetCell( OUString& rStr, ScCellValue& rCell, sal_uLong nFormat, const ScDocument* pDoc );
656 static bool NeedsNumberFormat( const ScCellValue& rVal );
658 void SetValueString( OUString& rValue, ScCellValue& rCell, const OUString& rStr, ScDocument* pDoc );
660 void GetValueString( OUString& rStr, const OUString& rValue, const ScCellValue& rCell,
661 const ScDocument* pDoc ) const;
663 void GetFormulaString( OUString& rStr, const ScFormulaCell* pCell ) const;
665 virtual void AddContent( ScChangeActionContent* ) override {}
666 virtual void DeleteCellEntries() override {}
668 virtual void UpdateReference( const ScChangeTrack*,
669 UpdateRefMode, const ScBigRange&,
670 sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz ) override;
672 virtual bool Reject(ScDocument* pDoc) override;
674 virtual const ScChangeTrack* GetChangeTrack() const override { return nullptr; }
676 // pRejectActions!=NULL: reject actions get
677 // stacked, no SetNewValue, no Append
678 bool Select( ScDocument*, ScChangeTrack*,
679 bool bOldest, ::std::stack<ScChangeActionContent*>* pRejectActions );
681 void PutValueToDoc(
682 const ScCellValue& rCell, const OUString& rValue, ScDocument* pDoc, SCCOL nDx, SCROW nDy ) const;
684 protected:
685 using ScChangeAction::GetRefString;
687 public:
688 ScChangeActionContent( const ScRange& rRange );
690 ScChangeActionContent(
691 const sal_uLong nActionNumber, const ScChangeActionState eState,
692 const sal_uLong nRejectingNumber, const ScBigRange& aBigRange,
693 const OUString& aUser, const DateTime& aDateTime,
694 const OUString &sComment, const ScCellValue& rOldCell,
695 const ScDocument* pDoc, const OUString& sOldValue ); // to use for XML Import
697 ScChangeActionContent(
698 const sal_uLong nActionNumber, const ScCellValue& rNewCell,
699 const ScBigRange& aBigRange, const ScDocument* pDoc,
700 const OUString& sNewValue ); // to use for XML Import of Generated Actions
702 virtual ~ScChangeActionContent() override;
704 ScChangeActionContent* GetNextContent() const { return pNextContent; }
705 ScChangeActionContent* GetPrevContent() const { return pPrevContent; }
706 ScChangeActionContent* GetTopContent() const;
707 bool IsTopContent() const { return pNextContent == nullptr; }
709 virtual ScChangeActionLinkEntry* GetDeletedIn() const override;
710 virtual ScChangeActionLinkEntry** GetDeletedInAddress() override;
712 void PutOldValueToDoc( ScDocument*,
713 SCCOL nDx, SCROW nDy ) const;
714 void PutNewValueToDoc( ScDocument*,
715 SCCOL nDx, SCROW nDy ) const;
717 void SetOldValue( const ScCellValue& rCell, const ScDocument* pFromDoc, ScDocument* pToDoc, sal_uLong nFormat );
719 void SetOldValue( const ScCellValue& rCell, const ScDocument* pFromDoc, ScDocument* pToDoc );
721 void SetNewValue( const ScCellValue& rCell, ScDocument* pDoc );
723 // Used in import filter AppendContentOnTheFly,
724 void SetOldNewCells(
725 const ScCellValue& rOldCell, sal_uLong nOldFormat,
726 const ScCellValue& rNewCell, sal_uLong nNewFormat, const ScDocument* pDoc );
728 // Use this only in the XML import,
729 // takes ownership of cell.
730 void SetNewCell(
731 const ScCellValue& rCell, const ScDocument* pDoc, const OUString& rFormatted );
733 // These functions should be protected but for
734 // the XML import they are public.
735 void SetNextContent( ScChangeActionContent* p )
736 { pNextContent = p; }
737 void SetPrevContent( ScChangeActionContent* p )
738 { pPrevContent = p; }
740 // don't use:
741 // assigns string / creates formula cell
742 void SetOldValue( const OUString& rOld, ScDocument* pDoc );
744 void GetOldString( OUString& rStr, const ScDocument* pDoc ) const;
745 void GetNewString( OUString& rStr, const ScDocument* pDoc ) const;
746 const ScCellValue& GetOldCell() const { return maOldCell;}
747 const ScCellValue& GetNewCell() const { return maNewCell;}
748 virtual void GetDescription(
749 OUString& rStr, ScDocument* pDoc, bool bSplitRange = false, bool bWarning = true ) const override;
751 virtual void GetRefString(
752 OUString& rStr, ScDocument* pDoc, bool bFlag3D = false ) const override;
754 static ScChangeActionContentCellType GetContentCellType( const ScCellValue& rCell );
755 static ScChangeActionContentCellType GetContentCellType( const ScRefCellValue& rIter );
757 // NewCell
758 bool IsMatrixOrigin() const;
759 // OldCell
760 bool IsOldMatrixReference() const;
763 // ScChangeActionReject
764 class ScChangeActionReject final : public ScChangeAction
766 friend class ScChangeTrack;
767 friend class ScChangeActionContent;
769 virtual void AddContent( ScChangeActionContent* ) override {}
770 virtual void DeleteCellEntries() override {}
772 virtual bool Reject(ScDocument* pDoc) override;
774 virtual const ScChangeTrack* GetChangeTrack() const override { return nullptr; }
776 public:
777 ScChangeActionReject(const sal_uLong nActionNumber,
778 const ScChangeActionState eState,
779 const sal_uLong nRejectingNumber,
780 const ScBigRange& aBigRange,
781 const OUString& aUser,
782 const DateTime& aDateTime,
783 const OUString &sComment); // only to use in the XML import
786 // ScChangeTrack
787 enum class ScChangeTrackMsgType
789 NONE,
790 Append, // Actions appended
791 Remove, // Actions removed
792 Change, // Actions changed
793 Parent // became a parent (and wasn't before)
796 struct ScChangeTrackMsgInfo
798 ScChangeTrackMsgType eMsgType;
799 sal_uLong nStartAction;
800 sal_uLong nEndAction;
803 // MsgQueue for notification via ModifiedLink
804 typedef std::vector<ScChangeTrackMsgInfo> ScChangeTrackMsgQueue;
805 typedef std::vector<ScChangeTrackMsgInfo> ScChangeTrackMsgStack;
806 typedef std::map<sal_uLong, ScChangeAction*> ScChangeActionMap;
808 enum ScChangeTrackMergeState
810 SC_CTMS_NONE,
811 SC_CTMS_PREPARE,
812 SC_CTMS_OWN,
813 SC_CTMS_UNDO,
814 SC_CTMS_OTHER
817 // Internally generated actions start at this value (nearly all bits set)
818 // and are decremented, to keep values in a table separated from "normal" actions.
819 #define SC_CHGTRACK_GENERATED_START (sal_uInt32(0xfffffff0))
821 class SAL_DLLPUBLIC_RTTI ScChangeTrack : public utl::ConfigurationListener
823 friend void ScChangeAction::RejectRestoreContents( ScChangeTrack*, SCCOL, SCROW );
824 friend bool ScChangeActionDel::Reject( ScDocument* pDoc );
825 friend void ScChangeActionDel::DeleteCellEntries();
826 friend void ScChangeActionMove::DeleteCellEntries();
827 friend bool ScChangeActionMove::Reject( ScDocument* pDoc );
829 static const SCROW nContentRowsPerSlot;
830 static const SCSIZE nContentSlots;
832 css::uno::Sequence< sal_Int8 > aProtectPass;
833 ScChangeActionMap aMap;
834 ScChangeActionMap aGeneratedMap;
835 ScChangeActionMap aPasteCutMap;
836 ScChangeTrackMsgQueue aMsgQueue;
837 ScChangeTrackMsgStack aMsgStackTmp;
838 ScChangeTrackMsgStack aMsgStackFinal;
839 std::set<OUString> maUserCollection;
840 OUString maUser;
841 Link<ScChangeTrack&,void> aModifiedLink;
842 ScRange aInDeleteRange;
843 DateTime aFixDateTime;
844 ScChangeAction* pFirst;
845 ScChangeAction* pLast;
846 ScChangeActionContent* pFirstGeneratedDelContent;
847 std::unique_ptr<ScChangeActionContent*[]> ppContentSlots;
848 std::unique_ptr<ScChangeActionMove> pLastCutMove;
849 ScChangeActionLinkEntry* pLinkInsertCol;
850 ScChangeActionLinkEntry* pLinkInsertRow;
851 ScChangeActionLinkEntry* pLinkInsertTab;
852 ScChangeActionLinkEntry* pLinkMove;
853 boost::optional<ScChangeTrackMsgInfo> xBlockModifyMsg;
854 ScDocument* pDoc;
855 sal_uLong nActionMax;
856 sal_uLong nGeneratedMin;
857 sal_uLong nMarkLastSaved;
858 sal_uLong nStartLastCut;
859 sal_uLong nEndLastCut;
860 sal_uLong nLastMerge;
861 ScChangeTrackMergeState eMergeState;
862 bool bInDelete:1;
863 bool bInDeleteUndo:1;
864 bool bInDeleteTop:1;
865 bool bInPasteCut:1;
866 bool bUseFixDateTime:1;
867 bool bTimeNanoSeconds:1;
869 ScChangeTrack( const ScChangeTrack& ) = delete;
870 ScChangeTrack& operator=( const ScChangeTrack& ) = delete;
872 static SCROW InitContentRowsPerSlot();
874 // true if one is ScMatrixMode::Formula and the other is
875 // not, or if both are and range differs
876 static bool IsMatrixFormulaRangeDifferent(
877 const ScCellValue& rOldCell, const ScCellValue& rNewCell );
879 void Init();
880 void DtorClear();
881 void SetInDeleteRange( const ScRange& rRange )
882 { aInDeleteRange = rRange; }
883 void SetInDelete( bool bVal )
884 { bInDelete = bVal; }
885 void SetInDeleteTop( bool bVal )
886 { bInDeleteTop = bVal; }
887 void SetInDeleteUndo( bool bVal )
888 { bInDeleteUndo = bVal; }
889 void SetInPasteCut( bool bVal )
890 { bInPasteCut = bVal; }
891 void SetMergeState( ScChangeTrackMergeState eState )
892 { eMergeState = eState; }
893 ScChangeTrackMergeState GetMergeState() const { return eMergeState; }
894 void SetLastMerge( sal_uLong nVal ) { nLastMerge = nVal; }
895 sal_uLong GetLastMerge() const { return nLastMerge; }
897 void SetLastCutMoveRange( const ScRange&, ScDocument* );
899 // create block of ModifyMsg
900 void StartBlockModify( ScChangeTrackMsgType,
901 sal_uLong nStartAction );
902 void EndBlockModify( sal_uLong nEndAction );
904 void AddDependentWithNotify( ScChangeAction* pParent,
905 ScChangeAction* pDependent );
907 void Dependencies( ScChangeAction* );
908 void UpdateReference( ScChangeAction*, bool bUndo );
909 void UpdateReference( ScChangeAction** ppFirstAction, ScChangeAction* pAct, bool bUndo );
910 void Append( ScChangeAction* pAppend, sal_uLong nAction );
911 SC_DLLPUBLIC void AppendDeleteRange( const ScRange&,
912 ScDocument* pRefDoc, SCTAB nDz,
913 sal_uLong nRejectingInsert );
914 void AppendOneDeleteRange( const ScRange& rOrgRange,
915 ScDocument* pRefDoc,
916 SCCOL nDx, SCROW nDy, SCTAB nDz,
917 sal_uLong nRejectingInsert );
918 void LookUpContents( const ScRange& rOrgRange,
919 ScDocument* pRefDoc,
920 SCCOL nDx, SCROW nDy, SCTAB nDz );
921 void Remove( ScChangeAction* );
922 void MasterLinks( ScChangeAction* );
924 // Content on top at Position
925 ScChangeActionContent* SearchContentAt( const ScBigAddress&,
926 const ScChangeAction* pButNotThis ) const;
927 void DeleteGeneratedDelContent(
928 ScChangeActionContent* );
930 ScChangeActionContent* GenerateDelContent(
931 const ScAddress& rPos, const ScCellValue& rCell, const ScDocument* pFromDoc );
933 void DeleteCellEntries(
934 std::vector<ScChangeActionContent*>&,
935 const ScChangeAction* pDeletor );
937 // Reject action and all dependent actions,
938 // Table stems from previous GetDependents,
939 // only needed for Insert and Move (MasterType),
940 // is NULL otherwise.
941 // bRecursion == called from reject with table
942 bool Reject( ScChangeAction*, ScChangeActionMap*, bool bRecursion );
944 bool IsLastAction( sal_uLong nNum ) const;
946 void ClearMsgQueue();
947 virtual void ConfigurationChanged( utl::ConfigurationBroadcaster*, ConfigurationHints ) override;
949 public:
951 static SCSIZE ComputeContentSlot( sal_Int32 nRow )
953 if ( nRow < 0 || nRow > MAXROW )
954 return nContentSlots - 1;
955 return static_cast< SCSIZE >( nRow / nContentRowsPerSlot );
958 SC_DLLPUBLIC ScChangeTrack( ScDocument* );
959 ScChangeTrack(ScDocument* pDocP, const std::set<OUString>& aTempUserCollection); // only to use in the XML import
960 SC_DLLPUBLIC virtual ~ScChangeTrack() override;
961 void Clear();
963 ScChangeActionContent* GetFirstGenerated() const { return pFirstGeneratedDelContent; }
964 ScChangeAction* GetFirst() const { return pFirst; }
965 ScChangeAction* GetLast() const { return pLast; }
966 sal_uLong GetActionMax() const { return nActionMax; }
967 bool IsGenerated( sal_uLong nAction ) const;
968 SC_DLLPUBLIC ScChangeAction* GetAction( sal_uLong nAction ) const;
969 ScChangeAction* GetGenerated( sal_uLong nGenerated ) const;
970 ScChangeAction* GetActionOrGenerated( sal_uLong nAction ) const;
971 sal_uLong GetLastSavedActionNumber() const;
972 void SetLastSavedActionNumber(sal_uLong nNew);
973 ScChangeAction* GetLastSaved() const;
974 ScChangeActionContent** GetContentSlots() const { return ppContentSlots.get(); }
976 const ScRange& GetInDeleteRange() const
977 { return aInDeleteRange; }
978 bool IsInDelete() const { return bInDelete; }
979 bool IsInDeleteTop() const { return bInDeleteTop; }
980 bool IsInDeleteUndo() const { return bInDeleteUndo; }
981 bool IsInPasteCut() const { return bInPasteCut; }
982 SC_DLLPUBLIC void SetUser( const OUString& rUser );
983 const OUString& GetUser() const { return maUser;}
984 const std::set<OUString>& GetUserCollection() const { return maUserCollection;}
985 ScDocument* GetDocument() const { return pDoc; }
986 // for import filter
987 const DateTime& GetFixDateTime() const { return aFixDateTime; }
989 // set this if the date/time set with
990 // SetFixDateTime...() shall be applied to
991 // appended actions
992 void SetUseFixDateTime( bool bVal )
993 { bUseFixDateTime = bVal; }
994 // for MergeDocument, apply original date/time as UTC
995 void SetFixDateTimeUTC( const DateTime& rDT )
996 { aFixDateTime = rDT; }
997 // for import filter, apply original date/time as local time
998 void SetFixDateTimeLocal( const DateTime& rDT )
999 { aFixDateTime = rDT; aFixDateTime.ConvertToUTC(); }
1001 void Append( ScChangeAction* );
1003 // pRefDoc may be NULL => no lookup of contents
1004 // => no generation of deleted contents
1005 SC_DLLPUBLIC void AppendDeleteRange( const ScRange&,
1006 ScDocument* pRefDoc,
1007 sal_uLong& nStartAction, sal_uLong& nEndAction,
1008 SCTAB nDz = 0 );
1009 // nDz: multi TabDel, LookUpContent must be searched
1010 // with an offset of -nDz
1012 // after new value was set in the document,
1013 // old value from RefDoc/UndoDoc
1014 void AppendContent( const ScAddress& rPos,
1015 const ScDocument* pRefDoc );
1016 // after new values were set in the document,
1017 // old values from RefDoc/UndoDoc
1018 void AppendContentRange( const ScRange& rRange,
1019 ScDocument* pRefDoc,
1020 sal_uLong& nStartAction, sal_uLong& nEndAction,
1021 ScChangeActionClipMode eMode = SC_CACM_NONE );
1022 // after new value was set in the document,
1023 // old value from pOldCell, nOldFormat,
1024 // RefDoc==NULL => Doc
1025 void AppendContent( const ScAddress& rPos, const ScCellValue& rOldCell,
1026 sal_uLong nOldFormat, ScDocument* pRefDoc = nullptr );
1027 // after new value was set in the document,
1028 // old value from pOldCell, format from Doc
1029 SC_DLLPUBLIC void AppendContent( const ScAddress& rPos, const ScCellValue& rOldCell );
1030 // after new values were set in the document,
1031 // old values from RefDoc/UndoDoc.
1032 // All contents with a cell in RefDoc
1033 void AppendContentsIfInRefDoc( ScDocument* pRefDoc,
1034 sal_uLong& nStartAction, sal_uLong& nEndAction );
1036 // Meant for import filter, creates and inserts
1037 // an unconditional content action of the two
1038 // cells without querying the document, not
1039 // even for number formats (though the number
1040 // formatter of the document may be used).
1041 // The action is returned and may be used to
1042 // set user name, description, date/time et al.
1043 // Takes ownership of the cells!
1044 SC_DLLPUBLIC ScChangeActionContent* AppendContentOnTheFly(
1045 const ScAddress& rPos, const ScCellValue& rOldCell, const ScCellValue& rNewCell,
1046 sal_uLong nOldFormat = 0, sal_uLong nNewFormat = 0 );
1048 // Only use the following two if there is no different solution! (Assign
1049 // string for NewValue or creation of a formula respectively)
1051 SC_DLLPUBLIC void AppendInsert( const ScRange& rRange, bool bEndOfList = false );
1053 // pRefDoc may be NULL => no lookup of contents
1054 // => no generation of deleted contents
1055 SC_DLLPUBLIC void AppendMove( const ScRange& rFromRange, const ScRange& rToRange,
1056 ScDocument* pRefDoc );
1058 // Cut to Clipboard
1059 void ResetLastCut()
1061 nStartLastCut = nEndLastCut = 0;
1062 pLastCutMove.reset();
1064 bool HasLastCut() const
1066 return nEndLastCut > 0 &&
1067 nStartLastCut <= nEndLastCut &&
1068 pLastCutMove;
1071 SC_DLLPUBLIC void Undo( sal_uLong nStartAction, sal_uLong nEndAction, bool bMerge = false );
1073 // adjust references for MergeDocument
1074 //! may only be used in a temporary opened document.
1075 //! the Track (?) is unclean afterwards
1076 void MergePrepare( const ScChangeAction* pFirstMerge, bool bShared );
1077 void MergeOwn( ScChangeAction* pAct, sal_uLong nFirstMerge, bool bShared );
1078 static bool MergeIgnore( const ScChangeAction&, sal_uLong nFirstMerge );
1080 // This comment was already really strange in German.
1081 // Tried to structure it a little. Hope no information got lost...
1083 // Insert dependents into table.
1084 // ScChangeAction is
1085 // - "Insert": really dependents
1086 // - "Move": dependent contents in FromRange /
1087 // deleted contents in ToRange
1088 // OR inserts in FromRange or ToRange
1089 // - "Delete": a list of deleted (what?)
1090 // OR for content, different contents at the same position
1091 // OR MatrixReferences belonging to MatrixOrigin
1093 // With bListMasterDelete (==TRUE ?) all Deletes of a row belonging
1094 // to a MasterDelete are listed (possibly it is
1095 // "all Deletes belonging...are listed in a row?)
1097 // With bAllFlat (==TRUE ?) all dependents of dependents
1098 // will be inserted flatly.
1100 SC_DLLPUBLIC void GetDependents(
1101 ScChangeAction*, ScChangeActionMap&, bool bListMasterDelete = false, bool bAllFlat = false ) const;
1103 // Reject visible action (and dependents)
1104 bool Reject( ScChangeAction*, bool bShared = false );
1106 // Accept visible action (and dependents)
1107 SC_DLLPUBLIC bool Accept( ScChangeAction* );
1109 void AcceptAll(); // all Virgins
1110 bool RejectAll(); // all Virgins
1112 // Selects a content of several contents at the same
1113 // position and accepts this one and
1114 // the older ones, rejects the more recent ones.
1115 // If bOldest==TRUE then the first OldValue
1116 // of a Virgin-Content-List will be restored.
1117 bool SelectContent( ScChangeAction*, bool bOldest = false );
1119 // If ModifiedLink is set, changes go to
1120 // ScChangeTrackMsgQueue
1121 void SetModifiedLink( const Link<ScChangeTrack&,void>& r )
1122 { aModifiedLink = r; ClearMsgQueue(); }
1123 ScChangeTrackMsgQueue& GetMsgQueue();
1125 void NotifyModified( ScChangeTrackMsgType eMsgType,
1126 sal_uLong nStartAction, sal_uLong nEndAction );
1128 sal_uLong AddLoadedGenerated( const ScCellValue& rNewCell,
1129 const ScBigRange& aBigRange, const OUString& sNewValue ); // only to use in the XML import
1130 void AppendLoaded( std::unique_ptr<ScChangeAction> pAppend ); // this is only for the XML import public, it should be protected
1131 void SetActionMax(sal_uLong nTempActionMax)
1132 { nActionMax = nTempActionMax; } // only to use in the XML import
1134 void SetProtection( const css::uno::Sequence< sal_Int8 >& rPass )
1135 { aProtectPass = rPass; }
1136 const css::uno::Sequence< sal_Int8 >& GetProtection() const
1137 { return aProtectPass; }
1138 bool IsProtected() const { return aProtectPass.hasElements(); }
1140 // If time stamps of actions of this
1141 // ChangeTrack and a second one are to be
1142 // compared including nanoseconds.
1143 void SetTimeNanoSeconds( bool bVal ) { bTimeNanoSeconds = bVal; }
1144 bool IsTimeNanoSeconds() const { return bTimeNanoSeconds; }
1146 void AppendCloned( ScChangeAction* pAppend );
1147 SC_DLLPUBLIC ScChangeTrack* Clone( ScDocument* pDocument ) const;
1148 static void MergeActionState( ScChangeAction* pAct, const ScChangeAction* pOtherAct );
1149 /// Get info about all ScChangeAction elements.
1150 void GetChangeTrackInfo(tools::JsonWriter&);
1153 #endif
1155 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */