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 .
20 #ifndef INCLUDED_SC_INC_CHGTRACK_HXX
21 #define INCLUDED_SC_INC_CHGTRACK_HXX
28 #include <tools/color.hxx>
29 #include <tools/datetime.hxx>
30 #include <tools/link.hxx>
31 #include <tools/mempool.hxx>
32 #include <unotools/options.hxx>
34 #include "bigrange.hxx"
36 #include "cellvalue.hxx"
44 class ScActionColorChanger
47 const ScAppOptions
& rOpt
;
48 const std::set
<OUString
>& rUsers
;
49 OUString aLastUserName
;
50 sal_uInt16 nLastUserIndex
;
54 ScActionColorChanger( const ScChangeTrack
& rTrack
);
55 ~ScActionColorChanger() {}
56 void Update( const ScChangeAction
& rAction
);
57 ColorData
GetColor() const { return nColor
; }
60 enum ScChangeActionType
74 enum ScChangeActionState
81 enum ScChangeActionClipMode
89 // ScChangeActionLinkEntry
90 // Inserts itself as the head of a chain (better: linked list?), or before a LinkEntry
91 // on delete: automatically remove of what is linked (German original was strange...)
92 // ppPrev == &previous->pNext oder address of pointer to head of linked list,
97 class ScChangeActionLinkEntry
99 ScChangeActionLinkEntry( const ScChangeActionLinkEntry
& ) = delete;
100 ScChangeActionLinkEntry
& operator=( const ScChangeActionLinkEntry
& ) = delete;
104 ScChangeActionLinkEntry
* pNext
;
105 ScChangeActionLinkEntry
** ppPrev
;
106 ScChangeAction
* pAction
;
107 ScChangeActionLinkEntry
* pLink
;
111 DECL_FIXEDMEMPOOL_NEWDEL( ScChangeActionLinkEntry
)
113 ScChangeActionLinkEntry(
114 ScChangeActionLinkEntry
** ppPrevP
,
115 ScChangeAction
* pActionP
)
122 pNext
->ppPrev
= &pNext
;
126 virtual ~ScChangeActionLinkEntry()
128 ScChangeActionLinkEntry
* p
= pLink
;
135 void SetLink( ScChangeActionLinkEntry
* pLinkP
)
141 pLinkP
->pLink
= this;
149 pLink
->pLink
= nullptr;
158 if ( ( *ppPrev
= pNext
) != nullptr )
159 pNext
->ppPrev
= ppPrev
;
160 ppPrev
= nullptr; // not inserted
164 const ScChangeActionLinkEntry
* GetNext() const { return pNext
; }
165 ScChangeActionLinkEntry
* GetNext() { return pNext
; }
166 const ScChangeAction
* GetAction() const { return pAction
; }
167 ScChangeAction
* GetAction() { return pAction
; }
170 // ScChangeActionCellListEntry
171 // this is only for the XML Export in the hxx
172 class ScChangeActionContent
;
174 class ScChangeActionCellListEntry
176 friend class ScChangeAction
;
177 friend class ScChangeActionDel
;
178 friend class ScChangeActionMove
;
179 friend class ScChangeTrack
;
181 ScChangeActionCellListEntry
* pNext
;
182 ScChangeActionContent
* pContent
;
184 ScChangeActionCellListEntry(
185 ScChangeActionContent
* pContentP
,
186 ScChangeActionCellListEntry
* pNextP
)
188 pContent( pContentP
)
192 DECL_FIXEDMEMPOOL_NEWDEL( ScChangeActionCellListEntry
)
197 class ScChangeActionIns
;
198 class ScChangeActionDel
;
199 class ScChangeActionContent
;
203 friend class ScChangeTrack
;
204 friend class ScChangeActionIns
;
205 friend class ScChangeActionDel
;
206 friend class ScChangeActionMove
;
207 friend class ScChangeActionContent
;
209 ScChangeAction( const ScChangeAction
& ) = delete;
210 ScChangeAction
& operator=( const ScChangeAction
& ) = delete;
214 ScBigRange aBigRange
; // Ins/Del/MoveTo/ContentPos
215 DateTime aDateTime
; //! UTC
216 OUString aUser
; // who?
217 OUString aComment
; // user comment
218 ScChangeAction
* pNext
; // next in linked list
219 ScChangeAction
* pPrev
; // previous in linked list
220 ScChangeActionLinkEntry
* pLinkAny
; // arbitrary links
221 ScChangeActionLinkEntry
* pLinkDeletedIn
; // access to insert areas which were
222 // deleted or moved or rejected
223 ScChangeActionLinkEntry
* pLinkDeleted
; // links to deleted
224 ScChangeActionLinkEntry
* pLinkDependent
; // links to dependent
226 sal_uLong nRejectAction
;
227 ScChangeActionType eType
;
228 ScChangeActionState eState
;
230 ScChangeAction( ScChangeActionType
, const ScRange
& );
232 // only to be used in the XML import
233 ScChangeAction( ScChangeActionType
,
235 const sal_uLong nAction
,
236 const sal_uLong nRejectAction
,
237 const ScChangeActionState eState
,
238 const DateTime
& aDateTime
,
239 const OUString
& aUser
,
240 const OUString
& aComment
);
242 // only to be used in the XML import
243 ScChangeAction( ScChangeActionType
, const ScBigRange
&, const sal_uLong nAction
);
245 virtual ~ScChangeAction();
247 OUString
GetRefString(
248 const ScBigRange
& rRange
, ScDocument
* pDoc
, bool bFlag3D
= false) const;
250 void SetActionNumber( sal_uLong n
) { nAction
= n
; }
251 void SetRejectAction( sal_uLong n
) { nRejectAction
= n
; }
252 void SetUser( const OUString
& r
);
253 void SetType( ScChangeActionType e
) { eType
= e
; }
254 void SetState( ScChangeActionState e
) { eState
= e
; }
257 ScBigRange
& GetBigRange() { return aBigRange
; }
259 void AddLink( ScChangeAction
* p
, ScChangeActionLinkEntry
* pL
)
261 ScChangeActionLinkEntry
* pLnk
=
262 new ScChangeActionLinkEntry(
267 void RemoveAllAnyLinks();
269 virtual ScChangeActionLinkEntry
* GetDeletedIn() const
270 { return pLinkDeletedIn
; }
271 virtual ScChangeActionLinkEntry
** GetDeletedInAddress()
272 { return &pLinkDeletedIn
; }
273 ScChangeActionLinkEntry
* AddDeletedIn( ScChangeAction
* p
)
275 return new ScChangeActionLinkEntry(
276 GetDeletedInAddress(), p
);
279 bool RemoveDeletedIn( const ScChangeAction
* );
280 void SetDeletedIn( ScChangeAction
* );
282 ScChangeActionLinkEntry
* AddDeleted( ScChangeAction
* p
)
284 return new ScChangeActionLinkEntry(&pLinkDeleted
, p
);
287 void RemoveAllDeleted();
289 ScChangeActionLinkEntry
* AddDependent( ScChangeAction
* p
)
291 return new ScChangeActionLinkEntry(&pLinkDependent
, p
);
294 void RemoveAllDependent();
296 void RemoveAllLinks();
298 virtual void AddContent( ScChangeActionContent
* ) = 0;
299 virtual void DeleteCellEntries() = 0;
301 virtual void UpdateReference( const ScChangeTrack
*,
302 UpdateRefMode
, const ScBigRange
&,
303 sal_Int32 nDx
, sal_Int32 nDy
, sal_Int32 nDz
);
306 virtual bool Reject(ScDocument
* pDoc
) = 0;
307 void RejectRestoreContents( ScChangeTrack
*, SCsCOL nDx
, SCsROW nDy
);
309 // used in Reject() instead of IsRejectable()
310 bool IsInternalRejectable() const;
312 // Derived classes that hold a pointer to the
313 // ChangeTrack must return that. Otherwise NULL.
314 virtual const ScChangeTrack
* GetChangeTrack() const = 0;
317 bool IsInsertType() const;
318 bool IsDeleteType() const;
319 bool IsVirgin() const;
320 SC_DLLPUBLIC
bool IsAccepted() const;
321 bool IsRejected() const;
323 // Action rejects another Action
324 bool IsRejecting() const;
326 // if action is visible in the document
327 bool IsVisible() const;
329 // if action if touchable
330 bool IsTouchable() const;
332 // if action is an entry in dialog root
333 bool IsDialogRoot() const;
335 // if an entry in a dialog shall be a drop down entry
336 bool IsDialogParent() const;
338 // if action is a delete with subdeletes (aufgeklappt = open ?)
339 bool IsMasterDelete() const;
341 // if action is acceptable/selectable/rejectable
342 bool IsClickable() const;
344 // if action is rejectable
345 bool IsRejectable() const;
347 const ScBigRange
& GetBigRange() const { return aBigRange
; }
348 SC_DLLPUBLIC DateTime
GetDateTime() const; // local time
349 const DateTime
& GetDateTimeUTC() const // UTC time
350 { return aDateTime
; }
351 ScChangeActionType
GetType() const { return eType
; }
352 ScChangeActionState
GetState() const { return eState
; }
353 sal_uLong
GetActionNumber() const { return nAction
; }
354 sal_uLong
GetRejectAction() const { return nRejectAction
; }
356 ScChangeAction
* GetNext() const { return pNext
; }
357 ScChangeAction
* GetPrev() const { return pPrev
; }
359 bool IsDeletedIn() const;
360 bool IsDeletedIn( const ScChangeAction
* ) const;
361 bool IsDeletedInDelType( ScChangeActionType
) const;
362 void RemoveAllDeletedIn();
364 const ScChangeActionLinkEntry
* GetFirstDeletedEntry() const
365 { return pLinkDeleted
; }
366 const ScChangeActionLinkEntry
* GetFirstDependentEntry() const
367 { return pLinkDependent
; }
368 bool HasDependent() const;
369 bool HasDeleted() const;
370 // description will be appended to string
371 // with bSplitRange only one column/row will be considered for delete
372 // (for a listing of entries)
373 virtual void GetDescription(
374 OUString
& rStr
, ScDocument
* pDoc
,
375 bool bSplitRange
= false, bool bWarning
= true ) const;
377 virtual void GetRefString(
378 OUString
& rStr
, ScDocument
* pDoc
, bool bFlag3D
= false ) const;
380 // for DocumentMerge set old date of the other
381 // action, fetched by GetDateTimeUTC
382 void SetDateTimeUTC( const DateTime
& rDT
)
385 const OUString
& GetUser() const { return aUser
;}
386 const OUString
& GetComment() const { return aComment
;}
389 void SetComment( const OUString
& rStr
);
391 // only to be used in the XML import
392 void SetDeletedInThis( sal_uLong nActionNumber
,
393 const ScChangeTrack
* pTrack
);
394 // only to be used in the XML import
395 void AddDependent( sal_uLong nActionNumber
,
396 const ScChangeTrack
* pTrack
);
400 class ScChangeActionIns
: public ScChangeAction
402 friend class ScChangeTrack
;
404 bool mbEndOfList
; /// whether or not a row was auto-inserted at the bottom.
406 ScChangeActionIns( const ScRange
& rRange
, bool bEndOfList
= false );
407 virtual ~ScChangeActionIns();
409 virtual void AddContent( ScChangeActionContent
* ) override
{}
410 virtual void DeleteCellEntries() override
{}
412 virtual bool Reject(ScDocument
* pDoc
) override
;
414 virtual const ScChangeTrack
* GetChangeTrack() const override
{ return nullptr; }
418 const sal_uLong nActionNumber
,
419 const ScChangeActionState eState
,
420 const sal_uLong nRejectingNumber
,
421 const ScBigRange
& aBigRange
,
422 const OUString
& aUser
,
423 const DateTime
& aDateTime
,
424 const OUString
&sComment
,
425 const ScChangeActionType eType
,
426 bool bEndOfList
= false );
428 virtual void GetDescription(
429 OUString
& rStr
, ScDocument
* pDoc
, bool bSplitRange
= false, bool bWarning
= true) const override
;
431 SC_DLLPUBLIC
bool IsEndOfList() const;
435 class ScChangeActionMove
;
437 class ScChangeActionDelMoveEntry
: public ScChangeActionLinkEntry
439 friend class ScChangeActionDel
;
440 friend class ScChangeTrack
;
445 inline ScChangeActionDelMoveEntry(
446 ScChangeActionDelMoveEntry
** ppPrevP
,
447 ScChangeActionMove
* pMove
,
448 short nFrom
, short nTo
);
450 inline ScChangeActionMove
* GetMove();
453 const ScChangeActionDelMoveEntry
* GetNext() const
455 return static_cast<const ScChangeActionDelMoveEntry
*>(
456 ScChangeActionLinkEntry::GetNext());
458 inline const ScChangeActionMove
* GetMove() const;
459 short GetCutOffFrom() const { return nCutOffFrom
; }
460 short GetCutOffTo() const { return nCutOffTo
; }
463 class ScChangeActionDel
: public ScChangeAction
465 friend class ScChangeTrack
;
466 friend void ScChangeAction::Accept();
468 ScChangeTrack
* pTrack
;
469 ScChangeActionCellListEntry
* pFirstCell
;
470 ScChangeActionIns
* pCutOff
; // cut insert
471 short nCutOff
; // +: start -: end
472 ScChangeActionDelMoveEntry
* pLinkMove
;
476 ScChangeActionDel( const ScRange
& rRange
, SCsCOL nDx
, SCsROW nDy
, ScChangeTrack
* );
477 virtual ~ScChangeActionDel();
479 virtual void AddContent( ScChangeActionContent
* ) override
;
480 virtual void DeleteCellEntries() override
;
482 void UndoCutOffMoves();
483 void UndoCutOffInsert();
485 virtual void UpdateReference( const ScChangeTrack
*,
486 UpdateRefMode
, const ScBigRange
&,
487 sal_Int32 nDx
, sal_Int32 nDy
, sal_Int32 nDz
) override
;
489 virtual bool Reject(ScDocument
* pDoc
) override
;
491 virtual const ScChangeTrack
* GetChangeTrack() const override
{ return pTrack
; }
495 const sal_uLong nActionNumber
, const ScChangeActionState eState
,
496 const sal_uLong nRejectingNumber
, const ScBigRange
& aBigRange
,
497 const OUString
& aUser
, const DateTime
& aDateTime
,
498 const OUString
&sComment
, const ScChangeActionType eType
,
499 const SCsCOLROW nD
, ScChangeTrack
* pTrack
); // only to use in the XML import
500 // which of nDx and nDy is set is dependent on the type
502 // is the last in a row (or single)
503 bool IsBaseDelete() const;
505 // is the first in a row (or single)
506 bool IsTopDelete() const;
509 bool IsMultiDelete() const;
511 // is col, belonging to a TabDelete
512 bool IsTabDeleteCol() const;
514 SCsCOL
GetDx() const { return nDx
; }
515 SCsROW
GetDy() const { return nDy
; }
516 ScBigRange
GetOverAllRange() const; // BigRange + (nDx, nDy)
518 const ScChangeActionDelMoveEntry
* GetFirstMoveEntry() const
519 { return pLinkMove
; }
520 const ScChangeActionIns
* GetCutOffInsert() const { return pCutOff
; }
521 short GetCutOffCount() const { return nCutOff
; }
523 virtual void GetDescription(
524 OUString
& rStr
, ScDocument
* pDoc
, bool bSplitRange
= false, bool bWarning
= true ) const override
;
526 void SetCutOffInsert( ScChangeActionIns
* p
, short n
)
527 { pCutOff
= p
; nCutOff
= n
; } // only to use in the XML import
528 // this should be protected, but for the XML import it is public
529 // only to use in the XML import
530 // this should be protected, but for the XML import it is public
531 ScChangeActionDelMoveEntry
* AddCutOffMove(
532 ScChangeActionMove
* pMove
, short nFrom
, short nTo
);
535 // ScChangeActionMove
536 class ScChangeActionMove
: public ScChangeAction
538 friend class ScChangeTrack
;
539 friend class ScChangeActionDel
;
541 ScBigRange aFromRange
;
542 ScChangeTrack
* pTrack
;
543 ScChangeActionCellListEntry
* pFirstCell
;
544 sal_uLong nStartLastCut
; // for PasteCut undo
545 sal_uLong nEndLastCut
;
547 ScChangeActionMove( const ScRange
& rFromRange
,
548 const ScRange
& rToRange
,
549 ScChangeTrack
* pTrackP
)
550 : ScChangeAction( SC_CAT_MOVE
, rToRange
),
551 aFromRange( rFromRange
),
553 pFirstCell( nullptr ),
557 virtual ~ScChangeActionMove();
559 virtual void AddContent( ScChangeActionContent
* ) override
;
560 virtual void DeleteCellEntries() override
;
562 ScBigRange
& GetFromRange() { return aFromRange
; }
564 void SetStartLastCut( sal_uLong nVal
) { nStartLastCut
= nVal
; }
565 sal_uLong
GetStartLastCut() const { return nStartLastCut
; }
566 void SetEndLastCut( sal_uLong nVal
) { nEndLastCut
= nVal
; }
567 sal_uLong
GetEndLastCut() const { return nEndLastCut
; }
569 virtual void UpdateReference( const ScChangeTrack
*,
570 UpdateRefMode
, const ScBigRange
&,
571 sal_Int32 nDx
, sal_Int32 nDy
, sal_Int32 nDz
) override
;
573 virtual bool Reject(ScDocument
* pDoc
) override
;
575 virtual const ScChangeTrack
* GetChangeTrack() const override
{ return pTrack
; }
578 using ScChangeAction::GetRefString
;
581 ScChangeActionMove(const sal_uLong nActionNumber
,
582 const ScChangeActionState eState
,
583 const sal_uLong nRejectingNumber
,
584 const ScBigRange
& aToBigRange
,
585 const OUString
& aUser
,
586 const DateTime
& aDateTime
,
587 const OUString
&sComment
,
588 const ScBigRange
& aFromBigRange
,
589 ScChangeTrack
* pTrack
); // only to use in the XML import
591 const ScBigRange
& GetFromRange() const { return aFromRange
; }
592 SC_DLLPUBLIC
void GetDelta( sal_Int32
& nDx
, sal_Int32
& nDy
, sal_Int32
& nDz
) const;
594 virtual void GetDescription(
595 OUString
& rStr
, ScDocument
* pDoc
, bool bSplitRange
= false,
596 bool bWarning
= true ) const override
;
598 virtual void GetRefString(
599 OUString
& rStr
, ScDocument
* pDoc
, bool bFlag3D
= false ) const override
;
602 ScChangeActionDelMoveEntry::ScChangeActionDelMoveEntry(
603 ScChangeActionDelMoveEntry
** ppPrevP
,
604 ScChangeActionMove
* pMove
,
605 short nFrom
, short nTo
)
606 : ScChangeActionLinkEntry(
607 reinterpret_cast<ScChangeActionLinkEntry
**>(
609 static_cast<ScChangeAction
*>(pMove
) ),
610 nCutOffFrom( nFrom
),
614 inline ScChangeActionMove
* ScChangeActionDelMoveEntry::GetMove()
616 return static_cast<ScChangeActionMove
*>(
617 ScChangeActionLinkEntry::GetAction());
620 inline const ScChangeActionMove
* ScChangeActionDelMoveEntry::GetMove() const
622 return static_cast<const ScChangeActionMove
*>(
623 ScChangeActionLinkEntry::GetAction());
625 // ScChangeActionContent
626 enum ScChangeActionContentCellType
634 class ScChangeActionContent
: public ScChangeAction
636 friend class ScChangeTrack
;
638 ScCellValue maOldCell
;
639 ScCellValue maNewCell
;
643 ScChangeActionContent
* pNextContent
; // at the same position
644 ScChangeActionContent
* pPrevContent
;
645 ScChangeActionContent
* pNextInSlot
; // in the same slot
646 ScChangeActionContent
** ppPrevInSlot
;
648 void InsertInSlot( ScChangeActionContent
** pp
)
653 if ( ( pNextInSlot
= *pp
) != nullptr )
654 pNextInSlot
->ppPrevInSlot
= &pNextInSlot
;
659 void RemoveFromSlot()
663 if ( ( *ppPrevInSlot
= pNextInSlot
) != nullptr )
664 pNextInSlot
->ppPrevInSlot
= ppPrevInSlot
;
665 ppPrevInSlot
= nullptr; // not inserted
669 ScChangeActionContent
* GetNextInSlot() { return pNextInSlot
; }
673 static void GetStringOfCell(
674 OUString
& rStr
, const ScCellValue
& rCell
, const ScDocument
* pDoc
, const ScAddress
& rPos
);
676 static void GetStringOfCell(
677 OUString
& rStr
, const ScCellValue
& rCell
, const ScDocument
* pDoc
, sal_uLong nFormat
);
679 static void SetValue( OUString
& rStr
, ScCellValue
& rCell
, const ScAddress
& rPos
,
680 const ScCellValue
& rOrgCell
, const ScDocument
* pFromDoc
,
681 ScDocument
* pToDoc
);
683 static void SetValue( OUString
& rStr
, ScCellValue
& rCell
, sal_uLong nFormat
,
684 const ScCellValue
& rOrgCell
, const ScDocument
* pFromDoc
,
685 ScDocument
* pToDoc
);
687 static void SetCell( OUString
& rStr
, ScCellValue
& rCell
, sal_uLong nFormat
, const ScDocument
* pDoc
);
689 static bool NeedsNumberFormat( const ScCellValue
& rVal
);
691 void SetValueString( OUString
& rValue
, ScCellValue
& rCell
, const OUString
& rStr
, ScDocument
* pDoc
);
693 void GetValueString( OUString
& rStr
, const OUString
& rValue
, const ScCellValue
& rCell
,
694 const ScDocument
* pDoc
) const;
696 void GetFormulaString( OUString
& rStr
, const ScFormulaCell
* pCell
) const;
698 virtual void AddContent( ScChangeActionContent
* ) override
{}
699 virtual void DeleteCellEntries() override
{}
701 virtual void UpdateReference( const ScChangeTrack
*,
702 UpdateRefMode
, const ScBigRange
&,
703 sal_Int32 nDx
, sal_Int32 nDy
, sal_Int32 nDz
) override
;
705 virtual bool Reject(ScDocument
* pDoc
) override
;
707 virtual const ScChangeTrack
* GetChangeTrack() const override
{ return nullptr; }
709 // pRejectActions!=NULL: reject actions get
710 // stacked, no SetNewValue, no Append
711 bool Select( ScDocument
*, ScChangeTrack
*,
712 bool bOldest
, ::std::stack
<ScChangeActionContent
*>* pRejectActions
);
715 const ScCellValue
& rCell
, const OUString
& rValue
, ScDocument
* pDoc
, SCsCOL nDx
, SCsROW nDy
) const;
718 using ScChangeAction::GetRefString
;
722 DECL_FIXEDMEMPOOL_NEWDEL( ScChangeActionContent
)
724 ScChangeActionContent( const ScRange
& rRange
);
726 ScChangeActionContent(
727 const sal_uLong nActionNumber
, const ScChangeActionState eState
,
728 const sal_uLong nRejectingNumber
, const ScBigRange
& aBigRange
,
729 const OUString
& aUser
, const DateTime
& aDateTime
,
730 const OUString
&sComment
, const ScCellValue
& rOldCell
,
731 ScDocument
* pDoc
, const OUString
& sOldValue
); // to use for XML Import
733 ScChangeActionContent(
734 const sal_uLong nActionNumber
, const ScCellValue
& rNewCell
,
735 const ScBigRange
& aBigRange
, ScDocument
* pDoc
,
736 const OUString
& sNewValue
); // to use for XML Import of Generated Actions
738 virtual ~ScChangeActionContent();
740 ScChangeActionContent
* GetNextContent() const { return pNextContent
; }
741 ScChangeActionContent
* GetPrevContent() const { return pPrevContent
; }
742 ScChangeActionContent
* GetTopContent() const;
743 bool IsTopContent() const { return pNextContent
== nullptr; }
745 virtual ScChangeActionLinkEntry
* GetDeletedIn() const override
;
746 virtual ScChangeActionLinkEntry
** GetDeletedInAddress() override
;
748 void PutOldValueToDoc( ScDocument
*,
749 SCsCOL nDx
, SCsROW nDy
) const;
750 void PutNewValueToDoc( ScDocument
*,
751 SCsCOL nDx
, SCsROW nDy
) const;
753 void SetOldValue( const ScCellValue
& rCell
, const ScDocument
* pFromDoc
, ScDocument
* pToDoc
, sal_uLong nFormat
);
755 void SetOldValue( const ScCellValue
& rCell
, const ScDocument
* pFromDoc
, ScDocument
* pToDoc
);
757 void SetNewValue( const ScCellValue
& rCell
, ScDocument
* pDoc
);
759 // Used in import filter AppendContentOnTheFly,
761 const ScCellValue
& rOldCell
, sal_uLong nOldFormat
,
762 const ScCellValue
& rNewCell
, sal_uLong nNewFormat
, ScDocument
* pDoc
);
764 // Use this only in the XML import,
765 // takes ownership of cell.
767 const ScCellValue
& rCell
, ScDocument
* pDoc
, const OUString
& rFormatted
);
769 // These functions should be protected but for
770 // the XML import they are public.
771 void SetNextContent( ScChangeActionContent
* p
)
772 { pNextContent
= p
; }
773 void SetPrevContent( ScChangeActionContent
* p
)
774 { pPrevContent
= p
; }
777 // assigns string / creates formula cell
778 void SetOldValue( const OUString
& rOld
, ScDocument
* pDoc
);
780 void GetOldString( OUString
& rStr
, const ScDocument
* pDoc
) const;
781 void GetNewString( OUString
& rStr
, const ScDocument
* pDoc
) const;
782 const ScCellValue
& GetOldCell() const { return maOldCell
;}
783 const ScCellValue
& GetNewCell() const { return maNewCell
;}
784 virtual void GetDescription(
785 OUString
& rStr
, ScDocument
* pDoc
, bool bSplitRange
= false, bool bWarning
= true ) const override
;
787 virtual void GetRefString(
788 OUString
& rStr
, ScDocument
* pDoc
, bool bFlag3D
= false ) const override
;
790 static ScChangeActionContentCellType
GetContentCellType( const ScCellValue
& rCell
);
791 static ScChangeActionContentCellType
GetContentCellType( const ScRefCellValue
& rIter
);
794 bool IsMatrixOrigin() const;
796 bool IsOldMatrixReference() const;
799 // ScChangeActionReject
800 class ScChangeActionReject
: public ScChangeAction
802 friend class ScChangeTrack
;
803 friend class ScChangeActionContent
;
805 virtual void AddContent( ScChangeActionContent
* ) override
{}
806 virtual void DeleteCellEntries() override
{}
808 virtual bool Reject(ScDocument
* pDoc
) override
;
810 virtual const ScChangeTrack
* GetChangeTrack() const override
{ return nullptr; }
813 ScChangeActionReject(const sal_uLong nActionNumber
,
814 const ScChangeActionState eState
,
815 const sal_uLong nRejectingNumber
,
816 const ScBigRange
& aBigRange
,
817 const OUString
& aUser
,
818 const DateTime
& aDateTime
,
819 const OUString
&sComment
); // only to use in the XML import
823 enum ScChangeTrackMsgType
826 SC_CTM_APPEND
, // Actions appended
827 SC_CTM_REMOVE
, // Actions removed
828 SC_CTM_CHANGE
, // Actions changed
829 SC_CTM_PARENT
// became a parent (and wasn't before)
832 struct ScChangeTrackMsgInfo
834 DECL_FIXEDMEMPOOL_NEWDEL( ScChangeTrackMsgInfo
)
836 ScChangeTrackMsgType eMsgType
;
837 sal_uLong nStartAction
;
838 sal_uLong nEndAction
;
841 // MsgQueue for notification via ModifiedLink
842 typedef std::deque
<ScChangeTrackMsgInfo
*> ScChangeTrackMsgQueue
;
843 typedef std::stack
<ScChangeTrackMsgInfo
*> ScChangeTrackMsgStack
;
844 typedef std::map
<sal_uLong
, ScChangeAction
*> ScChangeActionMap
;
846 enum ScChangeTrackMergeState
855 // Internally generated actions start at this value (nearly all bits set)
856 // and are decremented, to keep values in a table separated from "normal" actions.
857 #define SC_CHGTRACK_GENERATED_START ((sal_uInt32) 0xfffffff0)
859 class ScChangeTrack
: public utl::ConfigurationListener
861 friend void ScChangeAction::RejectRestoreContents( ScChangeTrack
*, SCsCOL
, SCsROW
);
862 friend bool ScChangeActionDel::Reject( ScDocument
* pDoc
);
863 friend void ScChangeActionDel::DeleteCellEntries();
864 friend void ScChangeActionMove::DeleteCellEntries();
865 friend bool ScChangeActionMove::Reject( ScDocument
* pDoc
);
867 static const SCROW nContentRowsPerSlot
;
868 static const SCSIZE nContentSlots
;
870 css::uno::Sequence
< sal_Int8
> aProtectPass
;
871 ScChangeActionMap aMap
;
872 ScChangeActionMap aGeneratedMap
;
873 ScChangeActionMap aPasteCutMap
;
874 ScChangeTrackMsgQueue aMsgQueue
;
875 ScChangeTrackMsgStack aMsgStackTmp
;
876 ScChangeTrackMsgStack aMsgStackFinal
;
877 std::set
<OUString
> maUserCollection
;
879 Link
<ScChangeTrack
&,void> aModifiedLink
;
880 ScRange aInDeleteRange
;
881 DateTime aFixDateTime
;
882 ScChangeAction
* pFirst
;
883 ScChangeAction
* pLast
;
884 ScChangeActionContent
* pFirstGeneratedDelContent
;
885 ScChangeActionContent
** ppContentSlots
;
886 ScChangeActionMove
* pLastCutMove
;
887 ScChangeActionLinkEntry
* pLinkInsertCol
;
888 ScChangeActionLinkEntry
* pLinkInsertRow
;
889 ScChangeActionLinkEntry
* pLinkInsertTab
;
890 ScChangeActionLinkEntry
* pLinkMove
;
891 ScChangeTrackMsgInfo
* pBlockModifyMsg
;
893 sal_uLong nActionMax
;
894 sal_uLong nGeneratedMin
;
895 sal_uLong nMarkLastSaved
;
896 sal_uLong nStartLastCut
;
897 sal_uLong nEndLastCut
;
898 sal_uLong nLastMerge
;
899 ScChangeTrackMergeState eMergeState
;
902 bool bInDeleteUndo
:1;
905 bool bUseFixDateTime
:1;
906 bool bTimeNanoSeconds
:1;
908 ScChangeTrack( const ScChangeTrack
& ) = delete;
909 ScChangeTrack
& operator=( const ScChangeTrack
& ) = delete;
911 static SCROW
InitContentRowsPerSlot();
913 // true if one is MM_FORMULA and the other is
914 // not, or if both are and range differs
915 static bool IsMatrixFormulaRangeDifferent(
916 const ScCellValue
& rOldCell
, const ScCellValue
& rNewCell
);
920 void SetInDeleteRange( const ScRange
& rRange
)
921 { aInDeleteRange
= rRange
; }
922 void SetInDelete( bool bVal
)
923 { bInDelete
= bVal
; }
924 void SetInDeleteTop( bool bVal
)
925 { bInDeleteTop
= bVal
; }
926 void SetInDeleteUndo( bool bVal
)
927 { bInDeleteUndo
= bVal
; }
928 void SetInPasteCut( bool bVal
)
929 { bInPasteCut
= bVal
; }
930 void SetMergeState( ScChangeTrackMergeState eState
)
931 { eMergeState
= eState
; }
932 ScChangeTrackMergeState
GetMergeState() const { return eMergeState
; }
933 void SetLastMerge( sal_uLong nVal
) { nLastMerge
= nVal
; }
934 sal_uLong
GetLastMerge() const { return nLastMerge
; }
936 void SetLastCutMoveRange( const ScRange
&, ScDocument
* );
938 // create block of ModifyMsg
939 void StartBlockModify( ScChangeTrackMsgType
,
940 sal_uLong nStartAction
);
941 void EndBlockModify( sal_uLong nEndAction
);
943 void AddDependentWithNotify( ScChangeAction
* pParent
,
944 ScChangeAction
* pDependent
);
946 void Dependencies( ScChangeAction
* );
947 void UpdateReference( ScChangeAction
*, bool bUndo
);
948 void UpdateReference( ScChangeAction
** ppFirstAction
, ScChangeAction
* pAct
, bool bUndo
);
949 void Append( ScChangeAction
* pAppend
, sal_uLong nAction
);
950 SC_DLLPUBLIC
void AppendDeleteRange( const ScRange
&,
951 ScDocument
* pRefDoc
, SCsTAB nDz
,
952 sal_uLong nRejectingInsert
);
953 void AppendOneDeleteRange( const ScRange
& rOrgRange
,
955 SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
,
956 sal_uLong nRejectingInsert
);
957 void LookUpContents( const ScRange
& rOrgRange
,
959 SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
);
960 void Remove( ScChangeAction
* );
961 void MasterLinks( ScChangeAction
* );
963 // Content on top an Position
964 ScChangeActionContent
* SearchContentAt( const ScBigAddress
&,
965 ScChangeAction
* pButNotThis
) const;
966 void DeleteGeneratedDelContent(
967 ScChangeActionContent
* );
969 ScChangeActionContent
* GenerateDelContent(
970 const ScAddress
& rPos
, const ScCellValue
& rCell
, const ScDocument
* pFromDoc
);
972 void DeleteCellEntries(
973 ScChangeActionCellListEntry
*&,
974 ScChangeAction
* pDeletor
);
976 // Reject action and all dependent actions,
977 // Table stems from previous GetDependents,
978 // only needed for Insert and Move (MasterType),
979 // is NULL otherwise.
980 // bRecursion == called from reject with table
981 bool Reject( ScChangeAction
*, ScChangeActionMap
*, bool bRecursion
);
983 bool IsLastAction( sal_uLong nNum
) const;
985 void ClearMsgQueue();
986 virtual void ConfigurationChanged( utl::ConfigurationBroadcaster
*, sal_uInt32
) override
;
990 static SCSIZE
ComputeContentSlot( sal_Int32 nRow
)
992 if ( nRow
< 0 || nRow
> MAXROW
)
993 return nContentSlots
- 1;
994 return static_cast< SCSIZE
>( nRow
/ nContentRowsPerSlot
);
997 SC_DLLPUBLIC
ScChangeTrack( ScDocument
* );
998 ScChangeTrack(ScDocument
* pDocP
, const std::set
<OUString
>& aTempUserCollection
); // only to use in the XML import
999 SC_DLLPUBLIC
virtual ~ScChangeTrack();
1002 ScChangeActionContent
* GetFirstGenerated() const { return pFirstGeneratedDelContent
; }
1003 ScChangeAction
* GetFirst() const { return pFirst
; }
1004 ScChangeAction
* GetLast() const { return pLast
; }
1005 sal_uLong
GetActionMax() const { return nActionMax
; }
1006 bool IsGenerated( sal_uLong nAction
) const;
1007 SC_DLLPUBLIC ScChangeAction
* GetAction( sal_uLong nAction
) const;
1008 ScChangeAction
* GetGenerated( sal_uLong nGenerated
) const;
1009 ScChangeAction
* GetActionOrGenerated( sal_uLong nAction
) const;
1010 sal_uLong
GetLastSavedActionNumber() const;
1011 void SetLastSavedActionNumber(sal_uLong nNew
);
1012 ScChangeAction
* GetLastSaved() const;
1013 ScChangeActionContent
** GetContentSlots() const { return ppContentSlots
; }
1015 bool IsLoadSave() const { return bLoadSave
; }
1016 const ScRange
& GetInDeleteRange() const
1017 { return aInDeleteRange
; }
1018 bool IsInDelete() const { return bInDelete
; }
1019 bool IsInDeleteTop() const { return bInDeleteTop
; }
1020 bool IsInDeleteUndo() const { return bInDeleteUndo
; }
1021 bool IsInPasteCut() const { return bInPasteCut
; }
1022 SC_DLLPUBLIC
void SetUser( const OUString
& rUser
);
1023 const OUString
& GetUser() const { return maUser
;}
1024 const std::set
<OUString
>& GetUserCollection() const { return maUserCollection
;}
1025 ScDocument
* GetDocument() const { return pDoc
; }
1026 // for import filter
1027 const DateTime
& GetFixDateTime() const { return aFixDateTime
; }
1029 // set this if the date/time set with
1030 // SetFixDateTime...() shall be applied to
1032 void SetUseFixDateTime( bool bVal
)
1033 { bUseFixDateTime
= bVal
; }
1034 // for MergeDocument, apply original date/time as UTC
1035 void SetFixDateTimeUTC( const DateTime
& rDT
)
1036 { aFixDateTime
= rDT
; }
1037 // for import filter, apply original date/time as local time
1038 void SetFixDateTimeLocal( const DateTime
& rDT
)
1039 { aFixDateTime
= rDT
; aFixDateTime
.ConvertToUTC(); }
1041 void Append( ScChangeAction
* );
1043 // pRefDoc may be NULL => no lookup of contents
1044 // => no generation of deleted contents
1045 SC_DLLPUBLIC
void AppendDeleteRange( const ScRange
&,
1046 ScDocument
* pRefDoc
,
1047 sal_uLong
& nStartAction
, sal_uLong
& nEndAction
,
1049 // nDz: multi TabDel, LookUpContent must be searched
1050 // with an offset of -nDz
1052 // after new value was set in the document,
1053 // old value from RefDoc/UndoDoc
1054 void AppendContent( const ScAddress
& rPos
,
1055 ScDocument
* pRefDoc
);
1056 // after new values were set in the document,
1057 // old values from RefDoc/UndoDoc
1058 void AppendContentRange( const ScRange
& rRange
,
1059 ScDocument
* pRefDoc
,
1060 sal_uLong
& nStartAction
, sal_uLong
& nEndAction
,
1061 ScChangeActionClipMode eMode
= SC_CACM_NONE
);
1062 // after new value was set in the document,
1063 // old value from pOldCell, nOldFormat,
1064 // RefDoc==NULL => Doc
1065 void AppendContent( const ScAddress
& rPos
, const ScCellValue
& rOldCell
,
1066 sal_uLong nOldFormat
, ScDocument
* pRefDoc
= nullptr );
1067 // after new value was set in the document,
1068 // old value from pOldCell, format from Doc
1069 SC_DLLPUBLIC
void AppendContent( const ScAddress
& rPos
, const ScCellValue
& rOldCell
);
1070 // after new values were set in the document,
1071 // old values from RefDoc/UndoDoc.
1072 // All contents with a cell in RefDoc
1073 void AppendContentsIfInRefDoc( ScDocument
* pRefDoc
,
1074 sal_uLong
& nStartAction
, sal_uLong
& nEndAction
);
1076 // Meant for import filter, creates and inserts
1077 // an unconditional content action of the two
1078 // cells without querying the document, not
1079 // even for number formats (though the number
1080 // formatter of the document may be used).
1081 // The action is returned and may be used to
1082 // set user name, description, date/time et al.
1083 // Takes ownership of the cells!
1084 SC_DLLPUBLIC ScChangeActionContent
* AppendContentOnTheFly(
1085 const ScAddress
& rPos
, const ScCellValue
& rOldCell
, const ScCellValue
& rNewCell
,
1086 sal_uLong nOldFormat
= 0, sal_uLong nNewFormat
= 0 );
1088 // Only use the following two if there is no different solution! (Assign
1089 // string for NewValue or creation of a formula respectively)
1091 SC_DLLPUBLIC
void AppendInsert( const ScRange
& rRange
, bool bEndOfList
= false );
1093 // pRefDoc may be NULL => no lookup of contents
1094 // => no generation of deleted contents
1095 SC_DLLPUBLIC
void AppendMove( const ScRange
& rFromRange
, const ScRange
& rToRange
,
1096 ScDocument
* pRefDoc
);
1101 nStartLastCut
= nEndLastCut
= 0;
1104 delete pLastCutMove
;
1105 pLastCutMove
= nullptr;
1108 bool HasLastCut() const
1110 return nEndLastCut
> 0 &&
1111 nStartLastCut
<= nEndLastCut
&&
1115 SC_DLLPUBLIC
void Undo( sal_uLong nStartAction
, sal_uLong nEndAction
, bool bMerge
= false );
1117 // adjust references for MergeDocument
1118 //! may only be used in a temporary opened document.
1119 //! the Track (?) is unclean afterwards
1120 void MergePrepare( ScChangeAction
* pFirstMerge
, bool bShared
= false );
1121 void MergeOwn( ScChangeAction
* pAct
, sal_uLong nFirstMerge
, bool bShared
= false );
1122 static bool MergeIgnore( const ScChangeAction
&, sal_uLong nFirstMerge
);
1124 // This comment was already really strange in German.
1125 // Tried to structure it a little. Hope no information got lost...
1127 // Insert dependents into table.
1128 // ScChangeAction is
1129 // - "Insert": really dependents
1130 // - "Move": dependent contents in FromRange /
1131 // deleted contents in ToRange
1132 // OR inserts in FromRange or ToRange
1133 // - "Delete": a list of deleted (what?)
1134 // OR for content, different contents at the same position
1135 // OR MatrixReferences belonging to MatrixOrigin
1137 // With bListMasterDelete (==TRUE ?) all Deletes of a row belonging
1138 // to a MasterDelete are listed (possibly it is
1139 // "all Deletes belonging...are listed in a row?)
1141 // With bAllFlat (==TRUE ?) all dependents of dependents
1142 // will be inserted flatly.
1144 SC_DLLPUBLIC
void GetDependents(
1145 ScChangeAction
*, ScChangeActionMap
&, bool bListMasterDelete
= false, bool bAllFlat
= false ) const;
1147 // Reject visible action (and dependents)
1148 bool Reject( ScChangeAction
*, bool bShared
= false );
1150 // Accept visible action (and dependents)
1151 SC_DLLPUBLIC
bool Accept( ScChangeAction
* );
1153 void AcceptAll(); // all Virgins
1154 bool RejectAll(); // all Virgins
1156 // Selects a content of several contents at the same
1157 // position and accepts this one and
1158 // the older ones, rejects the more recent ones.
1159 // If bOldest==TRUE then the first OldValue
1160 // of a Virgin-Content-List will be restored.
1161 bool SelectContent( ScChangeAction
*, bool bOldest
= false );
1163 // If ModifiedLink is set, changes go to
1164 // ScChangeTrackMsgQueue
1165 void SetModifiedLink( const Link
<ScChangeTrack
&,void>& r
)
1166 { aModifiedLink
= r
; ClearMsgQueue(); }
1167 ScChangeTrackMsgQueue
& GetMsgQueue();
1169 void NotifyModified( ScChangeTrackMsgType eMsgType
,
1170 sal_uLong nStartAction
, sal_uLong nEndAction
);
1172 sal_uLong
AddLoadedGenerated( const ScCellValue
& rNewCell
,
1173 const ScBigRange
& aBigRange
, const OUString
& sNewValue
); // only to use in the XML import
1174 void AppendLoaded( ScChangeAction
* pAppend
); // this is only for the XML import public, it should be protected
1175 void SetActionMax(sal_uLong nTempActionMax
)
1176 { nActionMax
= nTempActionMax
; } // only to use in the XML import
1178 void SetProtection( const css::uno::Sequence
< sal_Int8
>& rPass
)
1179 { aProtectPass
= rPass
; }
1180 const css::uno::Sequence
< sal_Int8
>& GetProtection() const
1181 { return aProtectPass
; }
1182 bool IsProtected() const { return aProtectPass
.getLength() != 0; }
1184 // If time stamps of actions of this
1185 // ChangeTrack and a second one are to be
1186 // compared including nanoseconds.
1187 void SetTimeNanoSeconds( bool bVal
) { bTimeNanoSeconds
= bVal
; }
1188 bool IsTimeNanoSeconds() const { return bTimeNanoSeconds
; }
1190 void AppendCloned( ScChangeAction
* pAppend
);
1191 SC_DLLPUBLIC ScChangeTrack
* Clone( ScDocument
* pDocument
) const;
1192 static void MergeActionState( ScChangeAction
* pAct
, const ScChangeAction
* pOtherAct
);
1197 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */