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 .
28 #include <com/sun/star/uno/Sequence.hxx>
29 #include <tools/color.hxx>
30 #include <tools/datetime.hxx>
31 #include <tools/link.hxx>
32 #include <tools/solar.h>
33 #include <unotools/options.hxx>
36 #include "bigrange.hxx"
38 #include "cellvalue.hxx"
45 namespace tools
{ class JsonWriter
; }
47 class ScActionColorChanger
50 const ScAppOptions
& rOpt
;
51 const std::set
<OUString
>& rUsers
;
52 OUString aLastUserName
;
53 sal_uInt16 nLastUserIndex
;
57 ScActionColorChanger( const ScChangeTrack
& rTrack
);
58 void Update( const ScChangeAction
& rAction
);
59 Color
GetColor() const { return nColor
; }
62 enum ScChangeActionType
76 enum ScChangeActionState
83 enum ScChangeActionClipMode
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
99 ppPrev == &previous->pNext or address of pointer to head of linked list,
102 class ScChangeActionLinkEntry
104 ScChangeActionLinkEntry( const ScChangeActionLinkEntry
& ) = delete;
105 ScChangeActionLinkEntry
& operator=( const ScChangeActionLinkEntry
& ) = delete;
107 ScChangeActionLinkEntry
* pNext
;
108 ScChangeActionLinkEntry
** ppPrev
;
109 ScChangeAction
* pAction
;
110 ScChangeActionLinkEntry
* pLink
;
114 ScChangeActionLinkEntry(
115 ScChangeActionLinkEntry
** ppPrevP
,
116 ScChangeAction
* pActionP
)
123 pNext
->ppPrev
= &pNext
;
127 virtual ~ScChangeActionLinkEntry()
129 ScChangeActionLinkEntry
* p
= pLink
;
136 void SetLink( ScChangeActionLinkEntry
* pLinkP
)
142 pLinkP
->pLink
= this;
150 pLink
->pLink
= nullptr;
159 if ( ( *ppPrev
= pNext
) != nullptr )
160 pNext
->ppPrev
= ppPrev
;
161 ppPrev
= nullptr; // not inserted
165 const ScChangeActionLinkEntry
* GetNext() const { return pNext
; }
166 ScChangeActionLinkEntry
* GetNext() { return pNext
; }
167 const ScChangeAction
* GetAction() const { return pAction
; }
168 ScChangeAction
* GetAction() { return pAction
; }
171 // ScChangeActionCellListEntry
172 // this is only for the XML Export in the hxx
173 class ScChangeActionContent
;
175 class SAL_DLLPUBLIC_RTTI ScChangeAction
177 friend class ScChangeTrack
;
178 friend class ScChangeActionIns
;
179 friend class ScChangeActionDel
;
180 friend class ScChangeActionMove
;
181 friend class ScChangeActionContent
;
183 ScChangeAction( const ScChangeAction
& ) = delete;
184 ScChangeAction
& operator=( const ScChangeAction
& ) = delete;
188 ScBigRange aBigRange
; // Ins/Del/MoveTo/ContentPos
189 DateTime aDateTime
; //! UTC
190 OUString aUser
; // who?
191 OUString aComment
; // user comment
192 ScChangeAction
* pNext
; // next in linked list
193 ScChangeAction
* pPrev
; // previous in linked list
194 ScChangeActionLinkEntry
* pLinkAny
; // arbitrary links
195 ScChangeActionLinkEntry
* pLinkDeletedIn
; // access to insert areas which were
196 // deleted or moved or rejected
197 ScChangeActionLinkEntry
* pLinkDeleted
; // links to deleted
198 ScChangeActionLinkEntry
* pLinkDependent
; // links to dependent
200 sal_uLong nRejectAction
;
201 ScChangeActionType eType
;
202 ScChangeActionState eState
;
204 ScChangeAction( ScChangeActionType
, const ScRange
& );
206 // only to be used in the XML import
207 ScChangeAction( ScChangeActionType
,
209 const sal_uLong nAction
,
210 const sal_uLong nRejectAction
,
211 const ScChangeActionState eState
,
212 const DateTime
& aDateTime
,
216 // only to be used in the XML import
217 ScChangeAction( ScChangeActionType
, ScBigRange
, const sal_uLong nAction
);
219 OUString
GetRefString(
220 const ScBigRange
& rRange
, const ScDocument
& rDoc
, bool bFlag3D
= false) const;
222 void SetActionNumber( sal_uLong n
) { nAction
= n
; }
223 void SetRejectAction( sal_uLong n
) { nRejectAction
= n
; }
224 void SetUser( const OUString
& r
);
225 void SetType( ScChangeActionType e
) { eType
= e
; }
226 void SetState( ScChangeActionState e
) { eState
= e
; }
229 ScBigRange
& GetBigRange() { return aBigRange
; }
231 void AddLink( ScChangeAction
* p
, ScChangeActionLinkEntry
* pL
)
233 ScChangeActionLinkEntry
* pLnk
=
234 new ScChangeActionLinkEntry(
239 virtual ScChangeActionLinkEntry
* GetDeletedIn() const
240 { return pLinkDeletedIn
; }
241 virtual ScChangeActionLinkEntry
** GetDeletedInAddress()
242 { return &pLinkDeletedIn
; }
243 bool RemoveDeletedIn( const ScChangeAction
* );
244 void SetDeletedIn( ScChangeAction
* );
246 ScChangeActionLinkEntry
* AddDeleted( ScChangeAction
* p
)
248 return new ScChangeActionLinkEntry(&pLinkDeleted
, p
);
251 ScChangeActionLinkEntry
* AddDependent( ScChangeAction
* p
)
253 return new ScChangeActionLinkEntry(&pLinkDependent
, p
);
256 void RemoveAllDependent();
258 void RemoveAllLinks();
260 virtual void AddContent( ScChangeActionContent
* ) = 0;
261 virtual void DeleteCellEntries() = 0;
263 virtual void UpdateReference( const ScChangeTrack
*,
264 UpdateRefMode
, const ScBigRange
&,
265 sal_Int32 nDx
, sal_Int32 nDy
, sal_Int32 nDz
);
268 virtual bool Reject(ScDocument
& rDoc
) = 0;
269 void RejectRestoreContents( ScChangeTrack
*, SCCOL nDx
, SCROW nDy
);
271 // used in Reject() instead of IsRejectable()
272 bool IsInternalRejectable() const;
274 // Derived classes that hold a pointer to the
275 // ChangeTrack must return that. Otherwise NULL.
276 virtual const ScChangeTrack
* GetChangeTrack() const = 0;
279 virtual ~ScChangeAction();
281 bool IsInsertType() const;
282 bool IsDeleteType() const;
283 bool IsVirgin() const;
284 SC_DLLPUBLIC
bool IsAccepted() const;
285 bool IsRejected() const;
287 // Action rejects another Action
288 bool IsRejecting() const;
290 // if action is visible in the document
291 bool IsVisible() const;
293 // if action if touchable
294 bool IsTouchable() const;
296 // if action is an entry in dialog root
297 bool IsDialogRoot() const;
299 // if an entry in a dialog shall be a drop down entry
300 bool IsDialogParent() const;
302 // if action is a delete with subdeletes (aufgeklappt = open ?)
303 bool IsMasterDelete() const;
305 // if action is acceptable/selectable/rejectable
306 bool IsClickable() const;
308 // if action is rejectable
309 bool IsRejectable() const;
311 const ScBigRange
& GetBigRange() const { return aBigRange
; }
312 SC_DLLPUBLIC DateTime
GetDateTime() const; // local time
313 const DateTime
& GetDateTimeUTC() const // UTC time
314 { return aDateTime
; }
315 ScChangeActionType
GetType() const { return eType
; }
316 ScChangeActionState
GetState() const { return eState
; }
317 sal_uLong
GetActionNumber() const { return nAction
; }
318 sal_uLong
GetRejectAction() const { return nRejectAction
; }
320 ScChangeAction
* GetNext() const { return pNext
; }
321 ScChangeAction
* GetPrev() const { return pPrev
; }
323 bool IsDeletedIn() const;
324 bool IsDeletedIn( const ScChangeAction
* ) const;
325 bool IsDeletedInDelType( ScChangeActionType
) const;
326 void RemoveAllDeletedIn();
328 const ScChangeActionLinkEntry
* GetFirstDeletedEntry() const
329 { return pLinkDeleted
; }
330 const ScChangeActionLinkEntry
* GetFirstDependentEntry() const
331 { return pLinkDependent
; }
332 bool HasDependent() const;
333 bool HasDeleted() const;
334 // description will be appended to string
335 // with bSplitRange only one column/row will be considered for delete
336 // (for a listing of entries)
337 virtual OUString
GetDescription(
338 ScDocument
& rDoc
, bool bSplitRange
= false, bool bWarning
= true ) const;
340 virtual OUString
GetRefString( ScDocument
& rDoc
, bool bFlag3D
= false ) const;
342 // for DocumentMerge set old date of the other
343 // action, fetched by GetDateTimeUTC
344 void SetDateTimeUTC( const DateTime
& rDT
)
347 const OUString
& GetUser() const { return aUser
;}
348 const OUString
& GetComment() const { return aComment
;}
351 void SetComment( const OUString
& rStr
);
353 // only to be used in the XML import
354 void SetDeletedInThis( sal_uLong nActionNumber
,
355 const ScChangeTrack
* pTrack
);
356 // only to be used in the XML import
357 void AddDependent( sal_uLong nActionNumber
,
358 const ScChangeTrack
* pTrack
);
362 class SAL_DLLPUBLIC_RTTI ScChangeActionIns final
: public ScChangeAction
364 friend class ScChangeTrack
;
366 bool mbEndOfList
; /// whether or not a row was auto-inserted at the bottom.
368 ScChangeActionIns( const ScDocument
* pDoc
, const ScRange
& rRange
, bool bEndOfList
= false );
370 virtual void AddContent( ScChangeActionContent
* ) override
{}
371 virtual void DeleteCellEntries() override
{}
373 virtual bool Reject(ScDocument
& rDoc
) override
;
375 virtual const ScChangeTrack
* GetChangeTrack() const override
{ return nullptr; }
378 virtual ~ScChangeActionIns() override
;
380 const sal_uLong nActionNumber
,
381 const ScChangeActionState eState
,
382 const sal_uLong nRejectingNumber
,
383 const ScBigRange
& aBigRange
,
384 const OUString
& aUser
,
385 const DateTime
& aDateTime
,
386 const OUString
&sComment
,
387 const ScChangeActionType eType
,
388 bool bEndOfList
= false );
390 virtual OUString
GetDescription(
391 ScDocument
& rDoc
, bool bSplitRange
= false, bool bWarning
= true) const override
;
393 SC_DLLPUBLIC
bool IsEndOfList() const;
397 class SAL_DLLPUBLIC_RTTI ScChangeActionMove
;
399 class ScChangeActionDelMoveEntry final
: public ScChangeActionLinkEntry
401 friend class ScChangeActionDel
;
402 friend class ScChangeTrack
;
407 inline ScChangeActionDelMoveEntry(
408 ScChangeActionDelMoveEntry
** ppPrevP
,
409 ScChangeActionMove
* pMove
,
410 short nFrom
, short nTo
);
412 inline ScChangeActionMove
* GetMove();
415 const ScChangeActionDelMoveEntry
* GetNext() const
417 return static_cast<const ScChangeActionDelMoveEntry
*>(
418 ScChangeActionLinkEntry::GetNext());
420 inline const ScChangeActionMove
* GetMove() const;
421 short GetCutOffFrom() const { return nCutOffFrom
; }
422 short GetCutOffTo() const { return nCutOffTo
; }
425 class ScChangeActionDel final
: public ScChangeAction
427 friend class ScChangeTrack
;
428 friend void ScChangeAction::Accept();
430 ScChangeTrack
* pTrack
;
431 std::vector
<ScChangeActionContent
*> mvCells
;
432 ScChangeActionIns
* pCutOff
; // cut insert
433 short nCutOff
; // +: start -: end
434 ScChangeActionDelMoveEntry
* pLinkMove
;
438 ScChangeActionDel( const ScDocument
* pDoc
, const ScRange
& rRange
, SCCOL nDx
, SCROW nDy
, ScChangeTrack
* );
440 virtual void AddContent( ScChangeActionContent
* ) override
;
441 virtual void DeleteCellEntries() override
;
443 void UndoCutOffMoves();
444 void UndoCutOffInsert();
446 virtual void UpdateReference( const ScChangeTrack
*,
447 UpdateRefMode
, const ScBigRange
&,
448 sal_Int32 nDx
, sal_Int32 nDy
, sal_Int32 nDz
) override
;
450 virtual bool Reject(ScDocument
& rDoc
) override
;
452 virtual const ScChangeTrack
* GetChangeTrack() const override
{ return pTrack
; }
456 const sal_uLong nActionNumber
, const ScChangeActionState eState
,
457 const sal_uLong nRejectingNumber
, const ScBigRange
& aBigRange
,
458 const OUString
& aUser
, const DateTime
& aDateTime
,
459 const OUString
&sComment
, const ScChangeActionType eType
,
460 const SCCOLROW nD
, ScChangeTrack
* pTrack
); // only to use in the XML import
461 // which of nDx and nDy is set is dependent on the type
462 virtual ~ScChangeActionDel() override
;
464 // is the last in a row (or single)
465 bool IsBaseDelete() const;
467 // is the first in a row (or single)
468 bool IsTopDelete() const;
471 bool IsMultiDelete() const;
473 // is col, belonging to a TabDelete
474 bool IsTabDeleteCol() const;
476 SCCOL
GetDx() const { return nDx
; }
477 SCROW
GetDy() const { return nDy
; }
478 ScBigRange
GetOverAllRange() const; // BigRange + (nDx, nDy)
480 const ScChangeActionDelMoveEntry
* GetFirstMoveEntry() const
481 { return pLinkMove
; }
482 const ScChangeActionIns
* GetCutOffInsert() const { return pCutOff
; }
483 short GetCutOffCount() const { return nCutOff
; }
485 virtual OUString
GetDescription(
486 ScDocument
& rDoc
, bool bSplitRange
= false, bool bWarning
= true ) const override
;
488 void SetCutOffInsert( ScChangeActionIns
* p
, short n
)
489 { pCutOff
= p
; nCutOff
= n
; } // only to use in the XML import
490 // this should be protected, but for the XML import it is public
491 // only to use in the XML import
492 // this should be protected, but for the XML import it is public
493 ScChangeActionDelMoveEntry
* AddCutOffMove(
494 ScChangeActionMove
* pMove
, short nFrom
, short nTo
);
497 // ScChangeActionMove
498 class ScChangeActionMove final
: public ScChangeAction
500 friend class ScChangeTrack
;
501 friend struct std::default_delete
<ScChangeActionMove
>; // for std::unique_ptr
502 friend class ScChangeActionDel
;
504 ScBigRange aFromRange
;
505 ScChangeTrack
* pTrack
;
506 std::vector
<ScChangeActionContent
*> mvCells
;
507 sal_uLong nStartLastCut
; // for PasteCut undo
508 sal_uLong nEndLastCut
;
510 ScChangeActionMove( const ScRange
& rFromRange
,
511 const ScRange
& rToRange
,
512 ScChangeTrack
* pTrackP
)
513 : ScChangeAction( SC_CAT_MOVE
, rToRange
),
514 aFromRange( rFromRange
),
519 virtual ~ScChangeActionMove() override
;
521 virtual void AddContent( ScChangeActionContent
* ) override
;
522 virtual void DeleteCellEntries() override
;
524 ScBigRange
& GetFromRange() { return aFromRange
; }
526 void SetStartLastCut( sal_uLong nVal
) { nStartLastCut
= nVal
; }
527 sal_uLong
GetStartLastCut() const { return nStartLastCut
; }
528 void SetEndLastCut( sal_uLong nVal
) { nEndLastCut
= nVal
; }
529 sal_uLong
GetEndLastCut() const { return nEndLastCut
; }
531 virtual void UpdateReference( const ScChangeTrack
*,
532 UpdateRefMode
, const ScBigRange
&,
533 sal_Int32 nDx
, sal_Int32 nDy
, sal_Int32 nDz
) override
;
535 virtual bool Reject(ScDocument
& rDoc
) override
;
537 virtual const ScChangeTrack
* GetChangeTrack() const override
{ return pTrack
; }
540 using ScChangeAction::GetRefString
;
543 ScChangeActionMove(const sal_uLong nActionNumber
,
544 const ScChangeActionState eState
,
545 const sal_uLong nRejectingNumber
,
546 const ScBigRange
& aToBigRange
,
547 const OUString
& aUser
,
548 const DateTime
& aDateTime
,
549 const OUString
&sComment
,
550 ScBigRange aFromBigRange
,
551 ScChangeTrack
* pTrack
); // only to use in the XML import
553 const ScBigRange
& GetFromRange() const { return aFromRange
; }
554 SC_DLLPUBLIC
void GetDelta( sal_Int32
& nDx
, sal_Int32
& nDy
, sal_Int32
& nDz
) const;
556 virtual OUString
GetDescription(
557 ScDocument
& rDoc
, bool bSplitRange
= false, bool bWarning
= true ) const override
;
559 virtual OUString
GetRefString( ScDocument
& rDoc
, bool bFlag3D
= false ) const override
;
562 ScChangeActionDelMoveEntry::ScChangeActionDelMoveEntry(
563 ScChangeActionDelMoveEntry
** ppPrevP
,
564 ScChangeActionMove
* pMove
,
565 short nFrom
, short nTo
)
566 : ScChangeActionLinkEntry(
567 reinterpret_cast<ScChangeActionLinkEntry
**>(
569 static_cast<ScChangeAction
*>(pMove
) ),
570 nCutOffFrom( nFrom
),
574 inline ScChangeActionMove
* ScChangeActionDelMoveEntry::GetMove()
576 return static_cast<ScChangeActionMove
*>(
577 ScChangeActionLinkEntry::GetAction());
580 inline const ScChangeActionMove
* ScChangeActionDelMoveEntry::GetMove() const
582 return static_cast<const ScChangeActionMove
*>(
583 ScChangeActionLinkEntry::GetAction());
585 // ScChangeActionContent
586 enum ScChangeActionContentCellType
594 class SAL_DLLPUBLIC_RTTI ScChangeActionContent final
: public ScChangeAction
596 friend class ScChangeTrack
;
598 ScCellValue maOldCell
;
599 ScCellValue maNewCell
;
603 ScChangeActionContent
* pNextContent
; // at the same position
604 ScChangeActionContent
* pPrevContent
;
605 ScChangeActionContent
* pNextInSlot
; // in the same slot
606 ScChangeActionContent
** ppPrevInSlot
;
608 void InsertInSlot( ScChangeActionContent
** pp
)
613 if ( ( pNextInSlot
= *pp
) != nullptr )
614 pNextInSlot
->ppPrevInSlot
= &pNextInSlot
;
619 void RemoveFromSlot()
623 if ( ( *ppPrevInSlot
= pNextInSlot
) != nullptr )
624 pNextInSlot
->ppPrevInSlot
= ppPrevInSlot
;
625 ppPrevInSlot
= nullptr; // not inserted
629 ScChangeActionContent
* GetNextInSlot() { return pNextInSlot
; }
633 static OUString
GetStringOfCell(
634 const ScCellValue
& rCell
, const ScDocument
* pDoc
, const ScAddress
& rPos
);
636 static OUString
GetStringOfCell(
637 const ScCellValue
& rCell
, const ScDocument
* pDoc
, sal_uLong nFormat
);
639 static void SetValue( OUString
& rStr
, ScCellValue
& rCell
, const ScAddress
& rPos
,
640 const ScCellValue
& rOrgCell
, const ScDocument
* pFromDoc
,
641 ScDocument
* pToDoc
);
643 static void SetValue( OUString
& rStr
, ScCellValue
& rCell
, sal_uLong nFormat
,
644 const ScCellValue
& rOrgCell
, const ScDocument
* pFromDoc
,
645 ScDocument
* pToDoc
);
647 static void SetCell( OUString
& rStr
, ScCellValue
& rCell
, sal_uLong nFormat
, const ScDocument
* pDoc
);
649 static bool NeedsNumberFormat( const ScCellValue
& rVal
);
651 void SetValueString( OUString
& rValue
, ScCellValue
& rCell
, const OUString
& rStr
, ScDocument
* pDoc
);
653 OUString
GetValueString( const OUString
& rValue
, const ScCellValue
& rCell
,
654 const ScDocument
* pDoc
) const;
656 OUString
GetFormulaString( const ScFormulaCell
* pCell
) const;
658 virtual void AddContent( ScChangeActionContent
* ) override
{}
659 virtual void DeleteCellEntries() override
{}
661 virtual void UpdateReference( const ScChangeTrack
*,
662 UpdateRefMode
, const ScBigRange
&,
663 sal_Int32 nDx
, sal_Int32 nDy
, sal_Int32 nDz
) override
;
665 virtual bool Reject(ScDocument
& rDoc
) override
;
667 virtual const ScChangeTrack
* GetChangeTrack() const override
{ return nullptr; }
669 // pRejectActions!=NULL: reject actions get
670 // stacked, no SetNewValue, no Append
671 bool Select( ScDocument
&, ScChangeTrack
*,
672 bool bOldest
, ::std::stack
<ScChangeActionContent
*>* pRejectActions
);
675 const ScCellValue
& rCell
, const OUString
& rValue
, ScDocument
* pDoc
, SCCOL nDx
, SCROW nDy
) const;
678 using ScChangeAction::GetRefString
;
681 ScChangeActionContent( const ScRange
& rRange
);
683 ScChangeActionContent(
684 const sal_uLong nActionNumber
, const ScChangeActionState eState
,
685 const sal_uLong nRejectingNumber
, const ScBigRange
& aBigRange
,
686 const OUString
& aUser
, const DateTime
& aDateTime
,
687 const OUString
&sComment
, ScCellValue aOldCell
,
688 const ScDocument
* pDoc
, const OUString
& sOldValue
); // to use for XML Import
690 ScChangeActionContent(
691 const sal_uLong nActionNumber
, ScCellValue aNewCell
,
692 const ScBigRange
& aBigRange
, const ScDocument
* pDoc
,
693 const OUString
& sNewValue
); // to use for XML Import of Generated Actions
695 virtual ~ScChangeActionContent() override
;
697 ScChangeActionContent
* GetNextContent() const { return pNextContent
; }
698 ScChangeActionContent
* GetPrevContent() const { return pPrevContent
; }
699 ScChangeActionContent
* GetTopContent() const;
700 bool IsTopContent() const { return pNextContent
== nullptr; }
702 virtual ScChangeActionLinkEntry
* GetDeletedIn() const override
;
703 virtual ScChangeActionLinkEntry
** GetDeletedInAddress() override
;
705 void PutOldValueToDoc( ScDocument
*,
706 SCCOL nDx
, SCROW nDy
) const;
707 void PutNewValueToDoc( ScDocument
*,
708 SCCOL nDx
, SCROW nDy
) const;
710 void SetOldValue( const ScCellValue
& rCell
, const ScDocument
* pFromDoc
, ScDocument
* pToDoc
, sal_uLong nFormat
);
712 void SetOldValue( const ScCellValue
& rCell
, const ScDocument
* pFromDoc
, ScDocument
* pToDoc
);
714 void SetNewValue( const ScCellValue
& rCell
, ScDocument
* pDoc
);
716 // Used in import filter AppendContentOnTheFly,
718 const ScCellValue
& rOldCell
, sal_uLong nOldFormat
,
719 const ScCellValue
& rNewCell
, sal_uLong nNewFormat
, const ScDocument
* pDoc
);
721 // Use this only in the XML import,
722 // takes ownership of cell.
724 const ScCellValue
& rCell
, const ScDocument
* pDoc
, const OUString
& rFormatted
);
726 // These functions should be protected but for
727 // the XML import they are public.
728 void SetNextContent( ScChangeActionContent
* p
)
729 { pNextContent
= p
; }
730 void SetPrevContent( ScChangeActionContent
* p
)
731 { pPrevContent
= p
; }
734 // assigns string / creates formula cell
735 void SetOldValue( const OUString
& rOld
, ScDocument
* pDoc
);
737 OUString
GetOldString( const ScDocument
* pDoc
) const;
738 OUString
GetNewString( const ScDocument
* pDoc
) const;
739 const ScCellValue
& GetOldCell() const { return maOldCell
;}
740 const ScCellValue
& GetNewCell() const { return maNewCell
;}
741 virtual OUString
GetDescription(
742 ScDocument
& rDoc
, bool bSplitRange
= false, bool bWarning
= true ) const override
;
744 virtual OUString
GetRefString( ScDocument
& rDoc
, bool bFlag3D
= false ) const override
;
746 static ScChangeActionContentCellType
GetContentCellType( const ScCellValue
& rCell
);
747 static ScChangeActionContentCellType
GetContentCellType( const ScRefCellValue
& rIter
);
750 bool IsMatrixOrigin() const;
752 bool IsOldMatrixReference() const;
755 // ScChangeActionReject
756 class ScChangeActionReject final
: public ScChangeAction
758 friend class ScChangeTrack
;
759 friend class ScChangeActionContent
;
761 virtual void AddContent( ScChangeActionContent
* ) override
{}
762 virtual void DeleteCellEntries() override
{}
764 virtual bool Reject(ScDocument
& rDoc
) override
;
766 virtual const ScChangeTrack
* GetChangeTrack() const override
{ return nullptr; }
769 ScChangeActionReject(const sal_uLong nActionNumber
,
770 const ScChangeActionState eState
,
771 const sal_uLong nRejectingNumber
,
772 const ScBigRange
& aBigRange
,
773 const OUString
& aUser
,
774 const DateTime
& aDateTime
,
775 const OUString
&sComment
); // only to use in the XML import
779 enum class ScChangeTrackMsgType
782 Append
, // Actions appended
783 Remove
, // Actions removed
784 Change
, // Actions changed
785 Parent
// became a parent (and wasn't before)
788 struct ScChangeTrackMsgInfo
790 ScChangeTrackMsgType eMsgType
;
791 sal_uLong nStartAction
;
792 sal_uLong nEndAction
;
795 // MsgQueue for notification via ModifiedLink
796 typedef std::vector
<ScChangeTrackMsgInfo
> ScChangeTrackMsgQueue
;
797 typedef std::vector
<ScChangeTrackMsgInfo
> ScChangeTrackMsgStack
;
798 typedef std::map
<sal_uLong
, ScChangeAction
*> ScChangeActionMap
;
800 enum ScChangeTrackMergeState
809 // Internally generated actions start at this value (nearly all bits set)
810 // and are decremented, to keep values in a table separated from "normal" actions.
811 #define SC_CHGTRACK_GENERATED_START (sal_uInt32(0xfffffff0))
813 class SAL_DLLPUBLIC_RTTI ScChangeTrack final
: public utl::ConfigurationListener
815 friend void ScChangeAction::RejectRestoreContents( ScChangeTrack
*, SCCOL
, SCROW
);
816 friend bool ScChangeActionDel::Reject( ScDocument
& pDoc
);
817 friend void ScChangeActionDel::DeleteCellEntries();
818 friend void ScChangeActionMove::DeleteCellEntries();
819 friend bool ScChangeActionMove::Reject( ScDocument
& pDoc
);
821 SCROW mnContentRowsPerSlot
;
822 SCSIZE mnContentSlots
;
824 css::uno::Sequence
< sal_Int8
> aProtectPass
;
825 ScChangeActionMap aMap
;
826 ScChangeActionMap aGeneratedMap
;
827 ScChangeActionMap aPasteCutMap
;
828 ScChangeTrackMsgQueue aMsgQueue
;
829 ScChangeTrackMsgStack aMsgStackTmp
;
830 ScChangeTrackMsgStack aMsgStackFinal
;
831 std::set
<OUString
> maUserCollection
;
833 Link
<ScChangeTrack
&,void> aModifiedLink
;
834 ScRange aInDeleteRange
;
835 DateTime aFixDateTime
;
836 ScChangeAction
* pFirst
;
837 ScChangeAction
* pLast
;
838 ScChangeActionContent
* pFirstGeneratedDelContent
;
839 std::unique_ptr
<ScChangeActionContent
*[]> ppContentSlots
;
840 std::unique_ptr
<ScChangeActionMove
> pLastCutMove
;
841 ScChangeActionLinkEntry
* pLinkInsertCol
;
842 ScChangeActionLinkEntry
* pLinkInsertRow
;
843 ScChangeActionLinkEntry
* pLinkInsertTab
;
844 ScChangeActionLinkEntry
* pLinkMove
;
845 std::optional
<ScChangeTrackMsgInfo
> xBlockModifyMsg
;
847 sal_uLong nActionMax
;
848 sal_uLong nGeneratedMin
;
849 sal_uLong nMarkLastSaved
;
850 sal_uLong nStartLastCut
;
851 sal_uLong nEndLastCut
;
852 sal_uLong nLastMerge
;
853 ScChangeTrackMergeState eMergeState
;
855 bool bInDeleteUndo
:1;
858 bool bUseFixDateTime
:1;
859 bool bTimeNanoSeconds
:1;
861 ScChangeTrack( const ScChangeTrack
& ) = delete;
862 ScChangeTrack
& operator=( const ScChangeTrack
& ) = delete;
864 SCROW
InitContentRowsPerSlot();
866 // true if one is ScMatrixMode::Formula and the other is
867 // not, or if both are and range differs
868 static bool IsMatrixFormulaRangeDifferent(
869 const ScCellValue
& rOldCell
, const ScCellValue
& rNewCell
);
873 void SetInDeleteRange( const ScRange
& rRange
)
874 { aInDeleteRange
= rRange
; }
875 void SetInDelete( bool bVal
)
876 { bInDelete
= bVal
; }
877 void SetInDeleteTop( bool bVal
)
878 { bInDeleteTop
= bVal
; }
879 void SetInDeleteUndo( bool bVal
)
880 { bInDeleteUndo
= bVal
; }
881 void SetInPasteCut( bool bVal
)
882 { bInPasteCut
= bVal
; }
883 void SetMergeState( ScChangeTrackMergeState eState
)
884 { eMergeState
= eState
; }
885 ScChangeTrackMergeState
GetMergeState() const { return eMergeState
; }
886 void SetLastMerge( sal_uLong nVal
) { nLastMerge
= nVal
; }
887 sal_uLong
GetLastMerge() const { return nLastMerge
; }
889 void SetLastCutMoveRange( const ScRange
&, ScDocument
* );
891 // create block of ModifyMsg
892 void StartBlockModify( ScChangeTrackMsgType
,
893 sal_uLong nStartAction
);
894 void EndBlockModify( sal_uLong nEndAction
);
896 void AddDependentWithNotify( ScChangeAction
* pParent
,
897 ScChangeAction
* pDependent
);
899 void Dependencies( ScChangeAction
* );
900 void UpdateReference( ScChangeAction
*, bool bUndo
);
901 void UpdateReference( ScChangeAction
** ppFirstAction
, ScChangeAction
* pAct
, bool bUndo
);
902 void Append( ScChangeAction
* pAppend
, sal_uLong nAction
);
903 SC_DLLPUBLIC
void AppendDeleteRange( const ScRange
&,
904 ScDocument
* pRefDoc
, SCTAB nDz
,
905 sal_uLong nRejectingInsert
);
906 void AppendOneDeleteRange( const ScRange
& rOrgRange
,
908 SCCOL nDx
, SCROW nDy
, SCTAB nDz
,
909 sal_uLong nRejectingInsert
);
910 void LookUpContents( const ScRange
& rOrgRange
,
912 SCCOL nDx
, SCROW nDy
, SCTAB nDz
);
913 void Remove( ScChangeAction
* );
914 void MasterLinks( ScChangeAction
* );
916 // Content on top at Position
917 ScChangeActionContent
* SearchContentAt( const ScBigAddress
&,
918 const ScChangeAction
* pButNotThis
) const;
919 void DeleteGeneratedDelContent(
920 ScChangeActionContent
* );
922 ScChangeActionContent
* GenerateDelContent(
923 const ScAddress
& rPos
, const ScCellValue
& rCell
, const ScDocument
* pFromDoc
);
925 void DeleteCellEntries(
926 std::vector
<ScChangeActionContent
*>&,
927 const ScChangeAction
* pDeletor
);
929 // Reject action and all dependent actions,
930 // Table stems from previous GetDependents,
931 // only needed for Insert and Move (MasterType),
932 // is NULL otherwise.
933 // bRecursion == called from reject with table
934 bool Reject( ScChangeAction
*, ScChangeActionMap
*, bool bRecursion
);
936 bool IsLastAction( sal_uLong nNum
) const;
938 void ClearMsgQueue();
939 virtual void ConfigurationChanged( utl::ConfigurationBroadcaster
*, ConfigurationHints
) override
;
943 SCSIZE
ComputeContentSlot( sal_Int32 nRow
) const;
945 SC_DLLPUBLIC
ScChangeTrack( ScDocument
& );
946 ScChangeTrack(ScDocument
& rDocP
, std::set
<OUString
>&& aTempUserCollection
); // only to use in the XML import
947 SC_DLLPUBLIC
virtual ~ScChangeTrack() override
;
950 ScChangeActionContent
* GetFirstGenerated() const { return pFirstGeneratedDelContent
; }
951 ScChangeAction
* GetFirst() const { return pFirst
; }
952 ScChangeAction
* GetLast() const { return pLast
; }
953 sal_uLong
GetActionMax() const { return nActionMax
; }
954 bool IsGenerated( sal_uLong nAction
) const;
955 SC_DLLPUBLIC ScChangeAction
* GetAction( sal_uLong nAction
) const;
956 ScChangeAction
* GetGenerated( sal_uLong nGenerated
) const;
957 ScChangeAction
* GetActionOrGenerated( sal_uLong nAction
) const;
958 sal_uLong
GetLastSavedActionNumber() const;
959 void SetLastSavedActionNumber(sal_uLong nNew
);
960 ScChangeAction
* GetLastSaved() const;
961 ScChangeActionContent
** GetContentSlots() const { return ppContentSlots
.get(); }
963 const ScRange
& GetInDeleteRange() const
964 { return aInDeleteRange
; }
965 bool IsInDelete() const { return bInDelete
; }
966 bool IsInDeleteTop() const { return bInDeleteTop
; }
967 bool IsInDeleteUndo() const { return bInDeleteUndo
; }
968 bool IsInPasteCut() const { return bInPasteCut
; }
969 SC_DLLPUBLIC
void SetUser( const OUString
& rUser
);
970 const OUString
& GetUser() const { return maUser
;}
971 const std::set
<OUString
>& GetUserCollection() const { return maUserCollection
;}
972 ScDocument
& GetDocument() const { return rDoc
; }
974 const DateTime
& GetFixDateTime() const { return aFixDateTime
; }
976 // set this if the date/time set with
977 // SetFixDateTime...() shall be applied to
979 void SetUseFixDateTime( bool bVal
)
980 { bUseFixDateTime
= bVal
; }
981 // for MergeDocument, apply original date/time as UTC
982 void SetFixDateTimeUTC( const DateTime
& rDT
)
983 { aFixDateTime
= rDT
; }
984 // for import filter, apply original date/time as local time
985 void SetFixDateTimeLocal( const DateTime
& rDT
)
986 { aFixDateTime
= rDT
; aFixDateTime
.ConvertToUTC(); }
988 void Append( ScChangeAction
* );
990 // pRefDoc may be NULL => no lookup of contents
991 // => no generation of deleted contents
992 SC_DLLPUBLIC
void AppendDeleteRange( const ScRange
&,
994 sal_uLong
& nStartAction
, sal_uLong
& nEndAction
,
996 // nDz: multi TabDel, LookUpContent must be searched
997 // with an offset of -nDz
999 // after new value was set in the document,
1000 // old value from RefDoc/UndoDoc
1001 void AppendContent( const ScAddress
& rPos
,
1002 const ScDocument
* pRefDoc
);
1003 // after new values were set in the document,
1004 // old values from RefDoc/UndoDoc
1005 void AppendContentRange( const ScRange
& rRange
,
1006 ScDocument
* pRefDoc
,
1007 sal_uLong
& nStartAction
, sal_uLong
& nEndAction
,
1008 ScChangeActionClipMode eMode
= SC_CACM_NONE
);
1009 // after new value was set in the document,
1010 // old value from pOldCell, nOldFormat,
1011 // RefDoc==NULL => Doc
1012 void AppendContent( const ScAddress
& rPos
, const ScCellValue
& rOldCell
,
1013 sal_uLong nOldFormat
, ScDocument
* pRefDoc
= nullptr );
1014 // after new value was set in the document,
1015 // old value from pOldCell, format from Doc
1016 SC_DLLPUBLIC
void AppendContent( const ScAddress
& rPos
, const ScCellValue
& rOldCell
);
1017 // after new values were set in the document,
1018 // old values from RefDoc/UndoDoc.
1019 // All contents with a cell in RefDoc
1020 void AppendContentsIfInRefDoc( ScDocument
& rRefDoc
,
1021 sal_uLong
& nStartAction
, sal_uLong
& nEndAction
);
1023 // Meant for import filter, creates and inserts
1024 // an unconditional content action of the two
1025 // cells without querying the document, not
1026 // even for number formats (though the number
1027 // formatter of the document may be used).
1028 // The action is returned and may be used to
1029 // set user name, description, date/time et al.
1030 // Takes ownership of the cells!
1031 SC_DLLPUBLIC ScChangeActionContent
* AppendContentOnTheFly(
1032 const ScAddress
& rPos
, const ScCellValue
& rOldCell
, const ScCellValue
& rNewCell
,
1033 sal_uLong nOldFormat
= 0, sal_uLong nNewFormat
= 0 );
1035 // Only use the following two if there is no different solution! (Assign
1036 // string for NewValue or creation of a formula respectively)
1038 SC_DLLPUBLIC
void AppendInsert( const ScRange
& rRange
, bool bEndOfList
= false );
1040 // pRefDoc may be NULL => no lookup of contents
1041 // => no generation of deleted contents
1042 SC_DLLPUBLIC
void AppendMove( const ScRange
& rFromRange
, const ScRange
& rToRange
,
1043 ScDocument
* pRefDoc
);
1048 nStartLastCut
= nEndLastCut
= 0;
1049 pLastCutMove
.reset();
1051 bool HasLastCut() const
1053 return nEndLastCut
> 0 &&
1054 nStartLastCut
<= nEndLastCut
&&
1058 SC_DLLPUBLIC
void Undo( sal_uLong nStartAction
, sal_uLong nEndAction
, bool bMerge
= false );
1060 // adjust references for MergeDocument
1061 //! may only be used in a temporary opened document.
1062 //! the Track (?) is unclean afterwards
1063 void MergePrepare( const ScChangeAction
* pFirstMerge
, bool bShared
);
1064 void MergeOwn( ScChangeAction
* pAct
, sal_uLong nFirstMerge
, bool bShared
);
1065 static bool MergeIgnore( const ScChangeAction
&, sal_uLong nFirstMerge
);
1067 // This comment was already really strange in German.
1068 // Tried to structure it a little. Hope no information got lost...
1070 // Insert dependents into table.
1071 // ScChangeAction is
1072 // - "Insert": really dependents
1073 // - "Move": dependent contents in FromRange /
1074 // deleted contents in ToRange
1075 // OR inserts in FromRange or ToRange
1076 // - "Delete": a list of deleted (what?)
1077 // OR for content, different contents at the same position
1078 // OR MatrixReferences belonging to MatrixOrigin
1080 // With bListMasterDelete (==TRUE ?) all Deletes of a row belonging
1081 // to a MasterDelete are listed (possibly it is
1082 // "all Deletes belonging...are listed in a row?)
1084 // With bAllFlat (==TRUE ?) all dependents of dependents
1085 // will be inserted flatly.
1087 SC_DLLPUBLIC
void GetDependents(
1088 ScChangeAction
*, ScChangeActionMap
&, bool bListMasterDelete
= false, bool bAllFlat
= false ) const;
1090 // Reject visible action (and dependents)
1091 bool Reject( ScChangeAction
*, bool bShared
= false );
1093 // Accept visible action (and dependents)
1094 SC_DLLPUBLIC
bool Accept( ScChangeAction
* );
1096 void AcceptAll(); // all Virgins
1097 bool RejectAll(); // all Virgins
1099 // Selects a content of several contents at the same
1100 // position and accepts this one and
1101 // the older ones, rejects the more recent ones.
1102 // If bOldest==TRUE then the first OldValue
1103 // of a Virgin-Content-List will be restored.
1104 bool SelectContent( ScChangeAction
*, bool bOldest
= false );
1106 // If ModifiedLink is set, changes go to
1107 // ScChangeTrackMsgQueue
1108 void SetModifiedLink( const Link
<ScChangeTrack
&,void>& r
)
1109 { aModifiedLink
= r
; ClearMsgQueue(); }
1110 ScChangeTrackMsgQueue
& GetMsgQueue();
1112 void NotifyModified( ScChangeTrackMsgType eMsgType
,
1113 sal_uLong nStartAction
, sal_uLong nEndAction
);
1115 sal_uLong
AddLoadedGenerated( const ScCellValue
& rNewCell
,
1116 const ScBigRange
& aBigRange
, const OUString
& sNewValue
); // only to use in the XML import
1117 void AppendLoaded( std::unique_ptr
<ScChangeAction
> pAppend
); // this is only for the XML import public, it should be protected
1118 void SetActionMax(sal_uLong nTempActionMax
)
1119 { nActionMax
= nTempActionMax
; } // only to use in the XML import
1121 void SetProtection( const css::uno::Sequence
< sal_Int8
>& rPass
)
1122 { aProtectPass
= rPass
; }
1123 const css::uno::Sequence
< sal_Int8
>& GetProtection() const
1124 { return aProtectPass
; }
1125 bool IsProtected() const { return aProtectPass
.hasElements(); }
1127 // If time stamps of actions of this
1128 // ChangeTrack and a second one are to be
1129 // compared including nanoseconds.
1130 void SetTimeNanoSeconds( bool bVal
) { bTimeNanoSeconds
= bVal
; }
1131 bool IsTimeNanoSeconds() const { return bTimeNanoSeconds
; }
1133 void AppendCloned( ScChangeAction
* pAppend
);
1134 SC_DLLPUBLIC ScChangeTrack
* Clone( ScDocument
* pDocument
) const;
1135 static void MergeActionState( ScChangeAction
* pAct
, const ScChangeAction
* pOtherAct
);
1136 /// Get info about all ScChangeAction elements.
1137 void GetChangeTrackInfo(tools::JsonWriter
&);
1140 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */