tdf#104816 sw: if non-section content, let all sections hide.
[LibreOffice.git] / sc / inc / chgtrack.hxx
blob65f049ad163feee0f133e70eccfe6b06d40c0deb
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;
47 class ScActionColorChanger
49 private:
50 const ScAppOptions& rOpt;
51 const std::set<OUString>& rUsers;
52 OUString aLastUserName;
53 sal_uInt16 nLastUserIndex;
54 Color nColor;
56 public:
57 ScActionColorChanger( const ScChangeTrack& rTrack );
58 void Update( const ScChangeAction& rAction );
59 Color GetColor() const { return nColor; }
62 enum ScChangeActionType
64 SC_CAT_NONE,
65 SC_CAT_INSERT_COLS,
66 SC_CAT_INSERT_ROWS,
67 SC_CAT_INSERT_TABS,
68 SC_CAT_DELETE_COLS,
69 SC_CAT_DELETE_ROWS,
70 SC_CAT_DELETE_TABS,
71 SC_CAT_MOVE,
72 SC_CAT_CONTENT,
73 SC_CAT_REJECT
76 enum ScChangeActionState
78 SC_CAS_VIRGIN,
79 SC_CAS_ACCEPTED,
80 SC_CAS_REJECTED
83 enum ScChangeActionClipMode
85 SC_CACM_NONE,
86 SC_CACM_CUT,
87 SC_CACM_PASTE
90 /** A link/connection/dependency between change actions.
92 Upon construction inserts itself as the head of a chain / linked list,
93 respectively between existing link entries.
95 Upon destruction removes itself from the list and connects the previous and
96 next entry, if it was the first entry automatically maintaining the head
97 pointer to the list.
99 ppPrev == &previous->pNext or address of pointer to head of linked list,
100 *ppPrev == this
102 class ScChangeActionLinkEntry
104 ScChangeActionLinkEntry( const ScChangeActionLinkEntry& ) = delete;
105 ScChangeActionLinkEntry& operator=( const ScChangeActionLinkEntry& ) = delete;
107 protected:
109 ScChangeActionLinkEntry* pNext;
110 ScChangeActionLinkEntry** ppPrev;
111 ScChangeAction* const pAction;
112 ScChangeActionLinkEntry* pLink;
114 public:
116 ScChangeActionLinkEntry(
117 ScChangeActionLinkEntry** ppPrevP,
118 ScChangeAction* pActionP )
119 : pNext( *ppPrevP ),
120 ppPrev( ppPrevP ),
121 pAction( pActionP ),
122 pLink( nullptr )
124 if ( pNext )
125 pNext->ppPrev = &pNext;
126 *ppPrevP = this;
129 virtual ~ScChangeActionLinkEntry()
131 ScChangeActionLinkEntry* p = pLink;
132 UnLink();
133 Remove();
134 if ( p )
135 delete p;
138 void SetLink( ScChangeActionLinkEntry* pLinkP )
140 UnLink();
141 if ( pLinkP )
143 pLink = pLinkP;
144 pLinkP->pLink = this;
148 void UnLink()
150 if ( pLink )
152 pLink->pLink = nullptr;
153 pLink = nullptr;
157 void Remove()
159 if ( ppPrev )
161 if ( ( *ppPrev = pNext ) != nullptr )
162 pNext->ppPrev = ppPrev;
163 ppPrev = nullptr; // not inserted
167 const ScChangeActionLinkEntry* GetNext() const { return pNext; }
168 ScChangeActionLinkEntry* GetNext() { return pNext; }
169 const ScChangeAction* GetAction() const { return pAction; }
170 ScChangeAction* GetAction() { return pAction; }
173 // ScChangeActionCellListEntry
174 // this is only for the XML Export in the hxx
175 class ScChangeActionContent;
177 class ScChangeAction
179 friend class ScChangeTrack;
180 friend class ScChangeActionIns;
181 friend class ScChangeActionDel;
182 friend class ScChangeActionMove;
183 friend class ScChangeActionContent;
185 ScChangeAction( const ScChangeAction& ) = delete;
186 ScChangeAction& operator=( const ScChangeAction& ) = delete;
188 protected:
190 ScBigRange aBigRange; // Ins/Del/MoveTo/ContentPos
191 DateTime aDateTime; //! UTC
192 OUString aUser; // who?
193 OUString aComment; // user comment
194 ScChangeAction* pNext; // next in linked list
195 ScChangeAction* pPrev; // previous in linked list
196 ScChangeActionLinkEntry* pLinkAny; // arbitrary links
197 ScChangeActionLinkEntry* pLinkDeletedIn; // access to insert areas which were
198 // deleted or moved or rejected
199 ScChangeActionLinkEntry* pLinkDeleted; // links to deleted
200 ScChangeActionLinkEntry* pLinkDependent; // links to dependent
201 sal_uLong nAction;
202 sal_uLong nRejectAction;
203 ScChangeActionType eType;
204 ScChangeActionState eState;
206 ScChangeAction( ScChangeActionType, const ScRange& );
208 // only to be used in the XML import
209 ScChangeAction( ScChangeActionType,
210 const ScBigRange&,
211 const sal_uLong nAction,
212 const sal_uLong nRejectAction,
213 const ScChangeActionState eState,
214 const DateTime& aDateTime,
215 const OUString& aUser,
216 const OUString& aComment );
218 // only to be used in the XML import
219 ScChangeAction( ScChangeActionType, const ScBigRange&, const sal_uLong nAction);
221 OUString GetRefString(
222 const ScBigRange& rRange, const ScDocument* pDoc, bool bFlag3D = false) const;
224 void SetActionNumber( sal_uLong n ) { nAction = n; }
225 void SetRejectAction( sal_uLong n ) { nRejectAction = n; }
226 void SetUser( const OUString& r );
227 void SetType( ScChangeActionType e ) { eType = e; }
228 void SetState( ScChangeActionState e ) { eState = e; }
229 void SetRejected();
231 ScBigRange& GetBigRange() { return aBigRange; }
233 void AddLink( ScChangeAction* p, ScChangeActionLinkEntry* pL )
235 ScChangeActionLinkEntry* pLnk =
236 new ScChangeActionLinkEntry(
237 &pLinkAny, p );
238 pLnk->SetLink( pL );
241 virtual ScChangeActionLinkEntry* GetDeletedIn() const
242 { return pLinkDeletedIn; }
243 virtual ScChangeActionLinkEntry** GetDeletedInAddress()
244 { return &pLinkDeletedIn; }
245 bool RemoveDeletedIn( const ScChangeAction* );
246 void SetDeletedIn( ScChangeAction* );
248 ScChangeActionLinkEntry* AddDeleted( ScChangeAction* p )
250 return new ScChangeActionLinkEntry(&pLinkDeleted, p);
253 ScChangeActionLinkEntry* AddDependent( ScChangeAction* p )
255 return new ScChangeActionLinkEntry(&pLinkDependent, p);
258 void RemoveAllDependent();
260 void RemoveAllLinks();
262 virtual void AddContent( ScChangeActionContent* ) = 0;
263 virtual void DeleteCellEntries() = 0;
265 virtual void UpdateReference( const ScChangeTrack*,
266 UpdateRefMode, const ScBigRange&,
267 sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz );
269 void Accept();
270 virtual bool Reject(ScDocument* pDoc) = 0;
271 void RejectRestoreContents( ScChangeTrack*, SCCOL nDx, SCROW nDy );
273 // used in Reject() instead of IsRejectable()
274 bool IsInternalRejectable() const;
276 // Derived classes that hold a pointer to the
277 // ChangeTrack must return that. Otherwise NULL.
278 virtual const ScChangeTrack* GetChangeTrack() const = 0;
280 public:
281 virtual ~ScChangeAction();
283 bool IsInsertType() const;
284 bool IsDeleteType() const;
285 bool IsVirgin() const;
286 SC_DLLPUBLIC bool IsAccepted() const;
287 bool IsRejected() const;
289 // Action rejects another Action
290 bool IsRejecting() const;
292 // if action is visible in the document
293 bool IsVisible() const;
295 // if action if touchable
296 bool IsTouchable() const;
298 // if action is an entry in dialog root
299 bool IsDialogRoot() const;
301 // if an entry in a dialog shall be a drop down entry
302 bool IsDialogParent() const;
304 // if action is a delete with subdeletes (aufgeklappt = open ?)
305 bool IsMasterDelete() const;
307 // if action is acceptable/selectable/rejectable
308 bool IsClickable() const;
310 // if action is rejectable
311 bool IsRejectable() const;
313 const ScBigRange& GetBigRange() const { return aBigRange; }
314 SC_DLLPUBLIC DateTime GetDateTime() const; // local time
315 const DateTime& GetDateTimeUTC() const // UTC time
316 { return aDateTime; }
317 ScChangeActionType GetType() const { return eType; }
318 ScChangeActionState GetState() const { return eState; }
319 sal_uLong GetActionNumber() const { return nAction; }
320 sal_uLong GetRejectAction() const { return nRejectAction; }
322 ScChangeAction* GetNext() const { return pNext; }
323 ScChangeAction* GetPrev() const { return pPrev; }
325 bool IsDeletedIn() const;
326 bool IsDeletedIn( const ScChangeAction* ) const;
327 bool IsDeletedInDelType( ScChangeActionType ) const;
328 void RemoveAllDeletedIn();
330 const ScChangeActionLinkEntry* GetFirstDeletedEntry() const
331 { return pLinkDeleted; }
332 const ScChangeActionLinkEntry* GetFirstDependentEntry() const
333 { return pLinkDependent; }
334 bool HasDependent() const;
335 bool HasDeleted() const;
336 // description will be appended to string
337 // with bSplitRange only one column/row will be considered for delete
338 // (for a listing of entries)
339 virtual void GetDescription(
340 OUString& rStr, ScDocument* pDoc,
341 bool bSplitRange = false, bool bWarning = true ) const;
343 virtual void GetRefString(
344 OUString& rStr, ScDocument* pDoc, bool bFlag3D = false ) const;
346 // for DocumentMerge set old date of the other
347 // action, fetched by GetDateTimeUTC
348 void SetDateTimeUTC( const DateTime& rDT )
349 { aDateTime = rDT; }
351 const OUString& GetUser() const { return aUser;}
352 const OUString& GetComment() const { return aComment;}
354 // set user comment
355 void SetComment( const OUString& rStr );
357 // only to be used in the XML import
358 void SetDeletedInThis( sal_uLong nActionNumber,
359 const ScChangeTrack* pTrack );
360 // only to be used in the XML import
361 void AddDependent( sal_uLong nActionNumber,
362 const ScChangeTrack* pTrack );
365 // ScChangeActionIns
366 class ScChangeActionIns : public ScChangeAction
368 friend class ScChangeTrack;
370 bool const mbEndOfList; /// whether or not a row was auto-inserted at the bottom.
372 ScChangeActionIns( const ScRange& rRange, bool bEndOfList = false );
374 virtual void AddContent( ScChangeActionContent* ) override {}
375 virtual void DeleteCellEntries() override {}
377 virtual bool Reject(ScDocument* pDoc) override;
379 virtual const ScChangeTrack* GetChangeTrack() const override { return nullptr; }
381 public:
382 virtual ~ScChangeActionIns() override;
383 ScChangeActionIns(
384 const sal_uLong nActionNumber,
385 const ScChangeActionState eState,
386 const sal_uLong nRejectingNumber,
387 const ScBigRange& aBigRange,
388 const OUString& aUser,
389 const DateTime& aDateTime,
390 const OUString &sComment,
391 const ScChangeActionType eType,
392 bool bEndOfList = false );
394 virtual void GetDescription(
395 OUString& rStr, ScDocument* pDoc, bool bSplitRange = false, bool bWarning = true) const override;
397 SC_DLLPUBLIC bool IsEndOfList() const;
400 // ScChangeActionDel
401 class ScChangeActionMove;
403 class ScChangeActionDelMoveEntry : public ScChangeActionLinkEntry
405 friend class ScChangeActionDel;
406 friend class ScChangeTrack;
408 short const nCutOffFrom;
409 short const nCutOffTo;
411 inline ScChangeActionDelMoveEntry(
412 ScChangeActionDelMoveEntry** ppPrevP,
413 ScChangeActionMove* pMove,
414 short nFrom, short nTo );
416 inline ScChangeActionMove* GetMove();
418 public:
419 const ScChangeActionDelMoveEntry* GetNext() const
421 return static_cast<const ScChangeActionDelMoveEntry*>(
422 ScChangeActionLinkEntry::GetNext());
424 inline const ScChangeActionMove* GetMove() const;
425 short GetCutOffFrom() const { return nCutOffFrom; }
426 short GetCutOffTo() const { return nCutOffTo; }
429 class ScChangeActionDel : public ScChangeAction
431 friend class ScChangeTrack;
432 friend void ScChangeAction::Accept();
434 ScChangeTrack* pTrack;
435 std::vector<ScChangeActionContent*> mvCells;
436 ScChangeActionIns* pCutOff; // cut insert
437 short nCutOff; // +: start -: end
438 ScChangeActionDelMoveEntry* pLinkMove;
439 SCCOL nDx;
440 SCROW nDy;
442 ScChangeActionDel( const ScRange& rRange, SCCOL nDx, SCROW nDy, ScChangeTrack* );
444 virtual void AddContent( ScChangeActionContent* ) override;
445 virtual void DeleteCellEntries() override;
447 void UndoCutOffMoves();
448 void UndoCutOffInsert();
450 virtual void UpdateReference( const ScChangeTrack*,
451 UpdateRefMode, const ScBigRange&,
452 sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz ) override;
454 virtual bool Reject(ScDocument* pDoc) override;
456 virtual const ScChangeTrack* GetChangeTrack() const override { return pTrack; }
458 public:
459 ScChangeActionDel(
460 const sal_uLong nActionNumber, const ScChangeActionState eState,
461 const sal_uLong nRejectingNumber, const ScBigRange& aBigRange,
462 const OUString& aUser, const DateTime& aDateTime,
463 const OUString &sComment, const ScChangeActionType eType,
464 const SCCOLROW nD, ScChangeTrack* pTrack); // only to use in the XML import
465 // which of nDx and nDy is set is dependent on the type
466 virtual ~ScChangeActionDel() override;
468 // is the last in a row (or single)
469 bool IsBaseDelete() const;
471 // is the first in a row (or single)
472 bool IsTopDelete() const;
474 // is part of a row
475 bool IsMultiDelete() const;
477 // is col, belonging to a TabDelete
478 bool IsTabDeleteCol() const;
480 SCCOL GetDx() const { return nDx; }
481 SCROW GetDy() const { return nDy; }
482 ScBigRange GetOverAllRange() const; // BigRange + (nDx, nDy)
484 const ScChangeActionDelMoveEntry* GetFirstMoveEntry() const
485 { return pLinkMove; }
486 const ScChangeActionIns* GetCutOffInsert() const { return pCutOff; }
487 short GetCutOffCount() const { return nCutOff; }
489 virtual void GetDescription(
490 OUString& rStr, ScDocument* pDoc, bool bSplitRange = false, bool bWarning = true ) const override;
492 void SetCutOffInsert( ScChangeActionIns* p, short n )
493 { pCutOff = p; nCutOff = n; } // only to use in the XML import
494 // this should be protected, but for the XML import it is public
495 // only to use in the XML import
496 // this should be protected, but for the XML import it is public
497 ScChangeActionDelMoveEntry* AddCutOffMove(
498 ScChangeActionMove* pMove, short nFrom, short nTo );
501 // ScChangeActionMove
502 class ScChangeActionMove : public ScChangeAction
504 friend class ScChangeTrack;
505 friend struct std::default_delete<ScChangeActionMove>; // for std::unique_ptr
506 friend class ScChangeActionDel;
508 ScBigRange aFromRange;
509 ScChangeTrack* pTrack;
510 std::vector<ScChangeActionContent*> mvCells;
511 sal_uLong nStartLastCut; // for PasteCut undo
512 sal_uLong nEndLastCut;
514 ScChangeActionMove( const ScRange& rFromRange,
515 const ScRange& rToRange,
516 ScChangeTrack* pTrackP )
517 : ScChangeAction( SC_CAT_MOVE, rToRange ),
518 aFromRange( rFromRange ),
519 pTrack( pTrackP ),
520 nStartLastCut(0),
521 nEndLastCut(0)
523 virtual ~ScChangeActionMove() override;
525 virtual void AddContent( ScChangeActionContent* ) override;
526 virtual void DeleteCellEntries() override;
528 ScBigRange& GetFromRange() { return aFromRange; }
530 void SetStartLastCut( sal_uLong nVal ) { nStartLastCut = nVal; }
531 sal_uLong GetStartLastCut() const { return nStartLastCut; }
532 void SetEndLastCut( sal_uLong nVal ) { nEndLastCut = nVal; }
533 sal_uLong GetEndLastCut() const { return nEndLastCut; }
535 virtual void UpdateReference( const ScChangeTrack*,
536 UpdateRefMode, const ScBigRange&,
537 sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz ) override;
539 virtual bool Reject(ScDocument* pDoc) override;
541 virtual const ScChangeTrack* GetChangeTrack() const override { return pTrack; }
543 protected:
544 using ScChangeAction::GetRefString;
546 public:
547 ScChangeActionMove(const sal_uLong nActionNumber,
548 const ScChangeActionState eState,
549 const sal_uLong nRejectingNumber,
550 const ScBigRange& aToBigRange,
551 const OUString& aUser,
552 const DateTime& aDateTime,
553 const OUString &sComment,
554 const ScBigRange& aFromBigRange,
555 ScChangeTrack* pTrack); // only to use in the XML import
557 const ScBigRange& GetFromRange() const { return aFromRange; }
558 SC_DLLPUBLIC void GetDelta( sal_Int32& nDx, sal_Int32& nDy, sal_Int32& nDz ) const;
560 virtual void GetDescription(
561 OUString& rStr, ScDocument* pDoc, bool bSplitRange = false,
562 bool bWarning = true ) const override;
564 virtual void GetRefString(
565 OUString& rStr, ScDocument* pDoc, bool bFlag3D = false ) const override;
568 ScChangeActionDelMoveEntry::ScChangeActionDelMoveEntry(
569 ScChangeActionDelMoveEntry** ppPrevP,
570 ScChangeActionMove* pMove,
571 short nFrom, short nTo )
572 : ScChangeActionLinkEntry(
573 reinterpret_cast<ScChangeActionLinkEntry**>(
574 ppPrevP),
575 static_cast<ScChangeAction*>(pMove) ),
576 nCutOffFrom( nFrom ),
577 nCutOffTo( nTo )
580 inline ScChangeActionMove* ScChangeActionDelMoveEntry::GetMove()
582 return static_cast<ScChangeActionMove*>(
583 ScChangeActionLinkEntry::GetAction());
586 inline const ScChangeActionMove* ScChangeActionDelMoveEntry::GetMove() const
588 return static_cast<const ScChangeActionMove*>(
589 ScChangeActionLinkEntry::GetAction());
591 // ScChangeActionContent
592 enum ScChangeActionContentCellType
594 SC_CACCT_NONE = 0,
595 SC_CACCT_NORMAL,
596 SC_CACCT_MATORG,
597 SC_CACCT_MATREF
600 class ScChangeActionContent : public ScChangeAction
602 friend class ScChangeTrack;
604 ScCellValue maOldCell;
605 ScCellValue maNewCell;
607 OUString maOldValue;
608 OUString maNewValue;
609 ScChangeActionContent* pNextContent; // at the same position
610 ScChangeActionContent* pPrevContent;
611 ScChangeActionContent* pNextInSlot; // in the same slot
612 ScChangeActionContent** ppPrevInSlot;
614 void InsertInSlot( ScChangeActionContent** pp )
616 if ( !ppPrevInSlot )
618 ppPrevInSlot = pp;
619 if ( ( pNextInSlot = *pp ) != nullptr )
620 pNextInSlot->ppPrevInSlot = &pNextInSlot;
621 *pp = this;
625 void RemoveFromSlot()
627 if ( ppPrevInSlot )
629 if ( ( *ppPrevInSlot = pNextInSlot ) != nullptr )
630 pNextInSlot->ppPrevInSlot = ppPrevInSlot;
631 ppPrevInSlot = nullptr; // not inserted
635 ScChangeActionContent* GetNextInSlot() { return pNextInSlot; }
637 void ClearTrack();
639 static void GetStringOfCell(
640 OUString& rStr, const ScCellValue& rCell, const ScDocument* pDoc, const ScAddress& rPos );
642 static void GetStringOfCell(
643 OUString& rStr, const ScCellValue& rCell, const ScDocument* pDoc, sal_uLong nFormat );
645 static void SetValue( OUString& rStr, ScCellValue& rCell, const ScAddress& rPos,
646 const ScCellValue& rOrgCell, const ScDocument* pFromDoc,
647 ScDocument* pToDoc );
649 static void SetValue( OUString& rStr, ScCellValue& rCell, sal_uLong nFormat,
650 const ScCellValue& rOrgCell, const ScDocument* pFromDoc,
651 ScDocument* pToDoc );
653 static void SetCell( OUString& rStr, ScCellValue& rCell, sal_uLong nFormat, const ScDocument* pDoc );
655 static bool NeedsNumberFormat( const ScCellValue& rVal );
657 void SetValueString( OUString& rValue, ScCellValue& rCell, const OUString& rStr, ScDocument* pDoc );
659 void GetValueString( OUString& rStr, const OUString& rValue, const ScCellValue& rCell,
660 const ScDocument* pDoc ) const;
662 void GetFormulaString( OUString& rStr, const ScFormulaCell* pCell ) const;
664 virtual void AddContent( ScChangeActionContent* ) override {}
665 virtual void DeleteCellEntries() override {}
667 virtual void UpdateReference( const ScChangeTrack*,
668 UpdateRefMode, const ScBigRange&,
669 sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz ) override;
671 virtual bool Reject(ScDocument* pDoc) override;
673 virtual const ScChangeTrack* GetChangeTrack() const override { return nullptr; }
675 // pRejectActions!=NULL: reject actions get
676 // stacked, no SetNewValue, no Append
677 bool Select( ScDocument*, ScChangeTrack*,
678 bool bOldest, ::std::stack<ScChangeActionContent*>* pRejectActions );
680 void PutValueToDoc(
681 const ScCellValue& rCell, const OUString& rValue, ScDocument* pDoc, SCCOL nDx, SCROW nDy ) const;
683 protected:
684 using ScChangeAction::GetRefString;
686 public:
687 ScChangeActionContent( const ScRange& rRange );
689 ScChangeActionContent(
690 const sal_uLong nActionNumber, const ScChangeActionState eState,
691 const sal_uLong nRejectingNumber, const ScBigRange& aBigRange,
692 const OUString& aUser, const DateTime& aDateTime,
693 const OUString &sComment, const ScCellValue& rOldCell,
694 const ScDocument* pDoc, const OUString& sOldValue ); // to use for XML Import
696 ScChangeActionContent(
697 const sal_uLong nActionNumber, const ScCellValue& rNewCell,
698 const ScBigRange& aBigRange, const ScDocument* pDoc,
699 const OUString& sNewValue ); // to use for XML Import of Generated Actions
701 virtual ~ScChangeActionContent() override;
703 ScChangeActionContent* GetNextContent() const { return pNextContent; }
704 ScChangeActionContent* GetPrevContent() const { return pPrevContent; }
705 ScChangeActionContent* GetTopContent() const;
706 bool IsTopContent() const { return pNextContent == nullptr; }
708 virtual ScChangeActionLinkEntry* GetDeletedIn() const override;
709 virtual ScChangeActionLinkEntry** GetDeletedInAddress() override;
711 void PutOldValueToDoc( ScDocument*,
712 SCCOL nDx, SCROW nDy ) const;
713 void PutNewValueToDoc( ScDocument*,
714 SCCOL nDx, SCROW nDy ) const;
716 void SetOldValue( const ScCellValue& rCell, const ScDocument* pFromDoc, ScDocument* pToDoc, sal_uLong nFormat );
718 void SetOldValue( const ScCellValue& rCell, const ScDocument* pFromDoc, ScDocument* pToDoc );
720 void SetNewValue( const ScCellValue& rCell, ScDocument* pDoc );
722 // Used in import filter AppendContentOnTheFly,
723 void SetOldNewCells(
724 const ScCellValue& rOldCell, sal_uLong nOldFormat,
725 const ScCellValue& rNewCell, sal_uLong nNewFormat, const ScDocument* pDoc );
727 // Use this only in the XML import,
728 // takes ownership of cell.
729 void SetNewCell(
730 const ScCellValue& rCell, const ScDocument* pDoc, const OUString& rFormatted );
732 // These functions should be protected but for
733 // the XML import they are public.
734 void SetNextContent( ScChangeActionContent* p )
735 { pNextContent = p; }
736 void SetPrevContent( ScChangeActionContent* p )
737 { pPrevContent = p; }
739 // don't use:
740 // assigns string / creates formula cell
741 void SetOldValue( const OUString& rOld, ScDocument* pDoc );
743 void GetOldString( OUString& rStr, const ScDocument* pDoc ) const;
744 void GetNewString( OUString& rStr, const ScDocument* pDoc ) const;
745 const ScCellValue& GetOldCell() const { return maOldCell;}
746 const ScCellValue& GetNewCell() const { return maNewCell;}
747 virtual void GetDescription(
748 OUString& rStr, ScDocument* pDoc, bool bSplitRange = false, bool bWarning = true ) const override;
750 virtual void GetRefString(
751 OUString& rStr, ScDocument* pDoc, bool bFlag3D = false ) const override;
753 static ScChangeActionContentCellType GetContentCellType( const ScCellValue& rCell );
754 static ScChangeActionContentCellType GetContentCellType( const ScRefCellValue& rIter );
756 // NewCell
757 bool IsMatrixOrigin() const;
758 // OldCell
759 bool IsOldMatrixReference() const;
762 // ScChangeActionReject
763 class ScChangeActionReject : public ScChangeAction
765 friend class ScChangeTrack;
766 friend class ScChangeActionContent;
768 virtual void AddContent( ScChangeActionContent* ) override {}
769 virtual void DeleteCellEntries() override {}
771 virtual bool Reject(ScDocument* pDoc) override;
773 virtual const ScChangeTrack* GetChangeTrack() const override { return nullptr; }
775 public:
776 ScChangeActionReject(const sal_uLong nActionNumber,
777 const ScChangeActionState eState,
778 const sal_uLong nRejectingNumber,
779 const ScBigRange& aBigRange,
780 const OUString& aUser,
781 const DateTime& aDateTime,
782 const OUString &sComment); // only to use in the XML import
785 // ScChangeTrack
786 enum class ScChangeTrackMsgType
788 NONE,
789 Append, // Actions appended
790 Remove, // Actions removed
791 Change, // Actions changed
792 Parent // became a parent (and wasn't before)
795 struct ScChangeTrackMsgInfo
797 ScChangeTrackMsgType eMsgType;
798 sal_uLong nStartAction;
799 sal_uLong nEndAction;
802 // MsgQueue for notification via ModifiedLink
803 typedef std::vector<ScChangeTrackMsgInfo> ScChangeTrackMsgQueue;
804 typedef std::vector<ScChangeTrackMsgInfo> ScChangeTrackMsgStack;
805 typedef std::map<sal_uLong, ScChangeAction*> ScChangeActionMap;
807 enum ScChangeTrackMergeState
809 SC_CTMS_NONE,
810 SC_CTMS_PREPARE,
811 SC_CTMS_OWN,
812 SC_CTMS_UNDO,
813 SC_CTMS_OTHER
816 // Internally generated actions start at this value (nearly all bits set)
817 // and are decremented, to keep values in a table separated from "normal" actions.
818 #define SC_CHGTRACK_GENERATED_START (sal_uInt32(0xfffffff0))
820 class ScChangeTrack : public utl::ConfigurationListener
822 friend void ScChangeAction::RejectRestoreContents( ScChangeTrack*, SCCOL, SCROW );
823 friend bool ScChangeActionDel::Reject( ScDocument* pDoc );
824 friend void ScChangeActionDel::DeleteCellEntries();
825 friend void ScChangeActionMove::DeleteCellEntries();
826 friend bool ScChangeActionMove::Reject( ScDocument* pDoc );
828 static const SCROW nContentRowsPerSlot;
829 static const SCSIZE nContentSlots;
831 css::uno::Sequence< sal_Int8 > aProtectPass;
832 ScChangeActionMap aMap;
833 ScChangeActionMap aGeneratedMap;
834 ScChangeActionMap aPasteCutMap;
835 ScChangeTrackMsgQueue aMsgQueue;
836 ScChangeTrackMsgStack aMsgStackTmp;
837 ScChangeTrackMsgStack aMsgStackFinal;
838 std::set<OUString> maUserCollection;
839 OUString maUser;
840 Link<ScChangeTrack&,void> aModifiedLink;
841 ScRange aInDeleteRange;
842 DateTime aFixDateTime;
843 ScChangeAction* pFirst;
844 ScChangeAction* pLast;
845 ScChangeActionContent* pFirstGeneratedDelContent;
846 std::unique_ptr<ScChangeActionContent*[]> ppContentSlots;
847 std::unique_ptr<ScChangeActionMove> pLastCutMove;
848 ScChangeActionLinkEntry* pLinkInsertCol;
849 ScChangeActionLinkEntry* pLinkInsertRow;
850 ScChangeActionLinkEntry* pLinkInsertTab;
851 ScChangeActionLinkEntry* pLinkMove;
852 boost::optional<ScChangeTrackMsgInfo> xBlockModifyMsg;
853 ScDocument* pDoc;
854 sal_uLong nActionMax;
855 sal_uLong nGeneratedMin;
856 sal_uLong nMarkLastSaved;
857 sal_uLong nStartLastCut;
858 sal_uLong nEndLastCut;
859 sal_uLong nLastMerge;
860 ScChangeTrackMergeState eMergeState;
861 bool bInDelete:1;
862 bool bInDeleteUndo:1;
863 bool bInDeleteTop:1;
864 bool bInPasteCut:1;
865 bool bUseFixDateTime:1;
866 bool bTimeNanoSeconds:1;
868 ScChangeTrack( const ScChangeTrack& ) = delete;
869 ScChangeTrack& operator=( const ScChangeTrack& ) = delete;
871 static SCROW InitContentRowsPerSlot();
873 // true if one is ScMatrixMode::Formula and the other is
874 // not, or if both are and range differs
875 static bool IsMatrixFormulaRangeDifferent(
876 const ScCellValue& rOldCell, const ScCellValue& rNewCell );
878 void Init();
879 void DtorClear();
880 void SetInDeleteRange( const ScRange& rRange )
881 { aInDeleteRange = rRange; }
882 void SetInDelete( bool bVal )
883 { bInDelete = bVal; }
884 void SetInDeleteTop( bool bVal )
885 { bInDeleteTop = bVal; }
886 void SetInDeleteUndo( bool bVal )
887 { bInDeleteUndo = bVal; }
888 void SetInPasteCut( bool bVal )
889 { bInPasteCut = bVal; }
890 void SetMergeState( ScChangeTrackMergeState eState )
891 { eMergeState = eState; }
892 ScChangeTrackMergeState GetMergeState() const { return eMergeState; }
893 void SetLastMerge( sal_uLong nVal ) { nLastMerge = nVal; }
894 sal_uLong GetLastMerge() const { return nLastMerge; }
896 void SetLastCutMoveRange( const ScRange&, ScDocument* );
898 // create block of ModifyMsg
899 void StartBlockModify( ScChangeTrackMsgType,
900 sal_uLong nStartAction );
901 void EndBlockModify( sal_uLong nEndAction );
903 void AddDependentWithNotify( ScChangeAction* pParent,
904 ScChangeAction* pDependent );
906 void Dependencies( ScChangeAction* );
907 void UpdateReference( ScChangeAction*, bool bUndo );
908 void UpdateReference( ScChangeAction** ppFirstAction, ScChangeAction* pAct, bool bUndo );
909 void Append( ScChangeAction* pAppend, sal_uLong nAction );
910 SC_DLLPUBLIC void AppendDeleteRange( const ScRange&,
911 ScDocument* pRefDoc, SCTAB nDz,
912 sal_uLong nRejectingInsert );
913 void AppendOneDeleteRange( const ScRange& rOrgRange,
914 ScDocument* pRefDoc,
915 SCCOL nDx, SCROW nDy, SCTAB nDz,
916 sal_uLong nRejectingInsert );
917 void LookUpContents( const ScRange& rOrgRange,
918 ScDocument* pRefDoc,
919 SCCOL nDx, SCROW nDy, SCTAB nDz );
920 void Remove( ScChangeAction* );
921 void MasterLinks( ScChangeAction* );
923 // Content on top an Position
924 ScChangeActionContent* SearchContentAt( const ScBigAddress&,
925 const ScChangeAction* pButNotThis ) const;
926 void DeleteGeneratedDelContent(
927 ScChangeActionContent* );
929 ScChangeActionContent* GenerateDelContent(
930 const ScAddress& rPos, const ScCellValue& rCell, const ScDocument* pFromDoc );
932 void DeleteCellEntries(
933 std::vector<ScChangeActionContent*>&,
934 const ScChangeAction* pDeletor );
936 // Reject action and all dependent actions,
937 // Table stems from previous GetDependents,
938 // only needed for Insert and Move (MasterType),
939 // is NULL otherwise.
940 // bRecursion == called from reject with table
941 bool Reject( ScChangeAction*, ScChangeActionMap*, bool bRecursion );
943 bool IsLastAction( sal_uLong nNum ) const;
945 void ClearMsgQueue();
946 virtual void ConfigurationChanged( utl::ConfigurationBroadcaster*, ConfigurationHints ) override;
948 public:
950 static SCSIZE ComputeContentSlot( sal_Int32 nRow )
952 if ( nRow < 0 || nRow > MAXROW )
953 return nContentSlots - 1;
954 return static_cast< SCSIZE >( nRow / nContentRowsPerSlot );
957 SC_DLLPUBLIC ScChangeTrack( ScDocument* );
958 ScChangeTrack(ScDocument* pDocP, const std::set<OUString>& aTempUserCollection); // only to use in the XML import
959 SC_DLLPUBLIC virtual ~ScChangeTrack() override;
960 void Clear();
962 ScChangeActionContent* GetFirstGenerated() const { return pFirstGeneratedDelContent; }
963 ScChangeAction* GetFirst() const { return pFirst; }
964 ScChangeAction* GetLast() const { return pLast; }
965 sal_uLong GetActionMax() const { return nActionMax; }
966 bool IsGenerated( sal_uLong nAction ) const;
967 SC_DLLPUBLIC ScChangeAction* GetAction( sal_uLong nAction ) const;
968 ScChangeAction* GetGenerated( sal_uLong nGenerated ) const;
969 ScChangeAction* GetActionOrGenerated( sal_uLong nAction ) const;
970 sal_uLong GetLastSavedActionNumber() const;
971 void SetLastSavedActionNumber(sal_uLong nNew);
972 ScChangeAction* GetLastSaved() const;
973 ScChangeActionContent** GetContentSlots() const { return ppContentSlots.get(); }
975 const ScRange& GetInDeleteRange() const
976 { return aInDeleteRange; }
977 bool IsInDelete() const { return bInDelete; }
978 bool IsInDeleteTop() const { return bInDeleteTop; }
979 bool IsInDeleteUndo() const { return bInDeleteUndo; }
980 bool IsInPasteCut() const { return bInPasteCut; }
981 SC_DLLPUBLIC void SetUser( const OUString& rUser );
982 const OUString& GetUser() const { return maUser;}
983 const std::set<OUString>& GetUserCollection() const { return maUserCollection;}
984 ScDocument* GetDocument() const { return pDoc; }
985 // for import filter
986 const DateTime& GetFixDateTime() const { return aFixDateTime; }
988 // set this if the date/time set with
989 // SetFixDateTime...() shall be applied to
990 // appended actions
991 void SetUseFixDateTime( bool bVal )
992 { bUseFixDateTime = bVal; }
993 // for MergeDocument, apply original date/time as UTC
994 void SetFixDateTimeUTC( const DateTime& rDT )
995 { aFixDateTime = rDT; }
996 // for import filter, apply original date/time as local time
997 void SetFixDateTimeLocal( const DateTime& rDT )
998 { aFixDateTime = rDT; aFixDateTime.ConvertToUTC(); }
1000 void Append( ScChangeAction* );
1002 // pRefDoc may be NULL => no lookup of contents
1003 // => no generation of deleted contents
1004 SC_DLLPUBLIC void AppendDeleteRange( const ScRange&,
1005 ScDocument* pRefDoc,
1006 sal_uLong& nStartAction, sal_uLong& nEndAction,
1007 SCTAB nDz = 0 );
1008 // nDz: multi TabDel, LookUpContent must be searched
1009 // with an offset of -nDz
1011 // after new value was set in the document,
1012 // old value from RefDoc/UndoDoc
1013 void AppendContent( const ScAddress& rPos,
1014 const ScDocument* pRefDoc );
1015 // after new values were set in the document,
1016 // old values from RefDoc/UndoDoc
1017 void AppendContentRange( const ScRange& rRange,
1018 ScDocument* pRefDoc,
1019 sal_uLong& nStartAction, sal_uLong& nEndAction,
1020 ScChangeActionClipMode eMode = SC_CACM_NONE );
1021 // after new value was set in the document,
1022 // old value from pOldCell, nOldFormat,
1023 // RefDoc==NULL => Doc
1024 void AppendContent( const ScAddress& rPos, const ScCellValue& rOldCell,
1025 sal_uLong nOldFormat, ScDocument* pRefDoc = nullptr );
1026 // after new value was set in the document,
1027 // old value from pOldCell, format from Doc
1028 SC_DLLPUBLIC void AppendContent( const ScAddress& rPos, const ScCellValue& rOldCell );
1029 // after new values were set in the document,
1030 // old values from RefDoc/UndoDoc.
1031 // All contents with a cell in RefDoc
1032 void AppendContentsIfInRefDoc( ScDocument* pRefDoc,
1033 sal_uLong& nStartAction, sal_uLong& nEndAction );
1035 // Meant for import filter, creates and inserts
1036 // an unconditional content action of the two
1037 // cells without querying the document, not
1038 // even for number formats (though the number
1039 // formatter of the document may be used).
1040 // The action is returned and may be used to
1041 // set user name, description, date/time et al.
1042 // Takes ownership of the cells!
1043 SC_DLLPUBLIC ScChangeActionContent* AppendContentOnTheFly(
1044 const ScAddress& rPos, const ScCellValue& rOldCell, const ScCellValue& rNewCell,
1045 sal_uLong nOldFormat = 0, sal_uLong nNewFormat = 0 );
1047 // Only use the following two if there is no different solution! (Assign
1048 // string for NewValue or creation of a formula respectively)
1050 SC_DLLPUBLIC void AppendInsert( const ScRange& rRange, bool bEndOfList = false );
1052 // pRefDoc may be NULL => no lookup of contents
1053 // => no generation of deleted contents
1054 SC_DLLPUBLIC void AppendMove( const ScRange& rFromRange, const ScRange& rToRange,
1055 ScDocument* pRefDoc );
1057 // Cut to Clipboard
1058 void ResetLastCut()
1060 nStartLastCut = nEndLastCut = 0;
1061 pLastCutMove.reset();
1063 bool HasLastCut() const
1065 return nEndLastCut > 0 &&
1066 nStartLastCut <= nEndLastCut &&
1067 pLastCutMove;
1070 SC_DLLPUBLIC void Undo( sal_uLong nStartAction, sal_uLong nEndAction, bool bMerge = false );
1072 // adjust references for MergeDocument
1073 //! may only be used in a temporary opened document.
1074 //! the Track (?) is unclean afterwards
1075 void MergePrepare( const ScChangeAction* pFirstMerge, bool bShared );
1076 void MergeOwn( ScChangeAction* pAct, sal_uLong nFirstMerge, bool bShared );
1077 static bool MergeIgnore( const ScChangeAction&, sal_uLong nFirstMerge );
1079 // This comment was already really strange in German.
1080 // Tried to structure it a little. Hope no information got lost...
1082 // Insert dependents into table.
1083 // ScChangeAction is
1084 // - "Insert": really dependents
1085 // - "Move": dependent contents in FromRange /
1086 // deleted contents in ToRange
1087 // OR inserts in FromRange or ToRange
1088 // - "Delete": a list of deleted (what?)
1089 // OR for content, different contents at the same position
1090 // OR MatrixReferences belonging to MatrixOrigin
1092 // With bListMasterDelete (==TRUE ?) all Deletes of a row belonging
1093 // to a MasterDelete are listed (possibly it is
1094 // "all Deletes belonging...are listed in a row?)
1096 // With bAllFlat (==TRUE ?) all dependents of dependents
1097 // will be inserted flatly.
1099 SC_DLLPUBLIC void GetDependents(
1100 ScChangeAction*, ScChangeActionMap&, bool bListMasterDelete = false, bool bAllFlat = false ) const;
1102 // Reject visible action (and dependents)
1103 bool Reject( ScChangeAction*, bool bShared = false );
1105 // Accept visible action (and dependents)
1106 SC_DLLPUBLIC bool Accept( ScChangeAction* );
1108 void AcceptAll(); // all Virgins
1109 bool RejectAll(); // all Virgins
1111 // Selects a content of several contents at the same
1112 // position and accepts this one and
1113 // the older ones, rejects the more recent ones.
1114 // If bOldest==TRUE then the first OldValue
1115 // of a Virgin-Content-List will be restored.
1116 bool SelectContent( ScChangeAction*, bool bOldest = false );
1118 // If ModifiedLink is set, changes go to
1119 // ScChangeTrackMsgQueue
1120 void SetModifiedLink( const Link<ScChangeTrack&,void>& r )
1121 { aModifiedLink = r; ClearMsgQueue(); }
1122 ScChangeTrackMsgQueue& GetMsgQueue();
1124 void NotifyModified( ScChangeTrackMsgType eMsgType,
1125 sal_uLong nStartAction, sal_uLong nEndAction );
1127 sal_uLong AddLoadedGenerated( const ScCellValue& rNewCell,
1128 const ScBigRange& aBigRange, const OUString& sNewValue ); // only to use in the XML import
1129 void AppendLoaded( std::unique_ptr<ScChangeAction> pAppend ); // this is only for the XML import public, it should be protected
1130 void SetActionMax(sal_uLong nTempActionMax)
1131 { nActionMax = nTempActionMax; } // only to use in the XML import
1133 void SetProtection( const css::uno::Sequence< sal_Int8 >& rPass )
1134 { aProtectPass = rPass; }
1135 const css::uno::Sequence< sal_Int8 >& GetProtection() const
1136 { return aProtectPass; }
1137 bool IsProtected() const { return aProtectPass.getLength() != 0; }
1139 // If time stamps of actions of this
1140 // ChangeTrack and a second one are to be
1141 // compared including nanoseconds.
1142 void SetTimeNanoSeconds( bool bVal ) { bTimeNanoSeconds = bVal; }
1143 bool IsTimeNanoSeconds() const { return bTimeNanoSeconds; }
1145 void AppendCloned( ScChangeAction* pAppend );
1146 SC_DLLPUBLIC ScChangeTrack* Clone( ScDocument* pDocument ) const;
1147 static void MergeActionState( ScChangeAction* pAct, const ScChangeAction* pOtherAct );
1148 /// Get info about all ScChangeAction elements.
1149 OUString GetChangeTrackInfo();
1152 #endif
1154 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */