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
29 #include <tools/color.hxx>
30 #include <tools/datetime.hxx>
31 #include <tools/link.hxx>
32 #include <tools/mempool.hxx>
33 #include <unotools/options.hxx>
35 #include "bigrange.hxx"
37 #include "cellvalue.hxx"
45 class ScActionColorChanger
48 const ScAppOptions
& rOpt
;
49 const std::set
<OUString
>& rUsers
;
50 OUString aLastUserName
;
51 sal_uInt16 nLastUserIndex
;
55 ScActionColorChanger( const ScChangeTrack
& rTrack
);
56 void Update( const ScChangeAction
& rAction
);
57 Color
GetColor() const { return nColor
; }
60 enum ScChangeActionType
74 enum ScChangeActionState
81 enum ScChangeActionClipMode
88 /** A link/connection/dependency between change actions.
90 Upon construction inserts itself as the head of a chain / linked list,
91 respectively between existing link entries.
93 Upon destruction removes itself from the list and connects the previous and
94 next entry, if it was the first entry automatically maintaining the head
97 ppPrev == &previous->pNext or address of pointer to head of linked list,
100 class ScChangeActionLinkEntry
102 ScChangeActionLinkEntry( const ScChangeActionLinkEntry
& ) = delete;
103 ScChangeActionLinkEntry
& operator=( const ScChangeActionLinkEntry
& ) = delete;
107 ScChangeActionLinkEntry
* pNext
;
108 ScChangeActionLinkEntry
** ppPrev
;
109 ScChangeAction
* pAction
;
110 ScChangeActionLinkEntry
* pLink
;
114 DECL_FIXEDMEMPOOL_NEWDEL( ScChangeActionLinkEntry
)
116 ScChangeActionLinkEntry(
117 ScChangeActionLinkEntry
** ppPrevP
,
118 ScChangeAction
* pActionP
)
125 pNext
->ppPrev
= &pNext
;
129 virtual ~ScChangeActionLinkEntry()
131 ScChangeActionLinkEntry
* p
= pLink
;
138 void SetLink( ScChangeActionLinkEntry
* pLinkP
)
144 pLinkP
->pLink
= this;
152 pLink
->pLink
= nullptr;
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 ScChangeActionCellListEntry
179 friend class ScChangeAction
;
180 friend class ScChangeActionDel
;
181 friend class ScChangeActionMove
;
182 friend class ScChangeTrack
;
184 ScChangeActionCellListEntry
* pNext
;
185 ScChangeActionContent
* pContent
;
187 ScChangeActionCellListEntry(
188 ScChangeActionContent
* pContentP
,
189 ScChangeActionCellListEntry
* pNextP
)
191 pContent( pContentP
)
195 DECL_FIXEDMEMPOOL_NEWDEL( ScChangeActionCellListEntry
)
200 friend class ScChangeTrack
;
201 friend class ScChangeActionIns
;
202 friend class ScChangeActionDel
;
203 friend class ScChangeActionMove
;
204 friend class ScChangeActionContent
;
206 ScChangeAction( const ScChangeAction
& ) = delete;
207 ScChangeAction
& operator=( const ScChangeAction
& ) = delete;
211 ScBigRange aBigRange
; // Ins/Del/MoveTo/ContentPos
212 DateTime aDateTime
; //! UTC
213 OUString aUser
; // who?
214 OUString aComment
; // user comment
215 ScChangeAction
* pNext
; // next in linked list
216 ScChangeAction
* pPrev
; // previous in linked list
217 ScChangeActionLinkEntry
* pLinkAny
; // arbitrary links
218 ScChangeActionLinkEntry
* pLinkDeletedIn
; // access to insert areas which were
219 // deleted or moved or rejected
220 ScChangeActionLinkEntry
* pLinkDeleted
; // links to deleted
221 ScChangeActionLinkEntry
* pLinkDependent
; // links to dependent
223 sal_uLong nRejectAction
;
224 ScChangeActionType eType
;
225 ScChangeActionState eState
;
227 ScChangeAction( ScChangeActionType
, const ScRange
& );
229 // only to be used in the XML import
230 ScChangeAction( ScChangeActionType
,
232 const sal_uLong nAction
,
233 const sal_uLong nRejectAction
,
234 const ScChangeActionState eState
,
235 const DateTime
& aDateTime
,
236 const OUString
& aUser
,
237 const OUString
& aComment
);
239 // only to be used in the XML import
240 ScChangeAction( ScChangeActionType
, const ScBigRange
&, const sal_uLong nAction
);
242 virtual ~ScChangeAction();
244 OUString
GetRefString(
245 const ScBigRange
& rRange
, const ScDocument
* pDoc
, bool bFlag3D
= false) const;
247 void SetActionNumber( sal_uLong n
) { nAction
= n
; }
248 void SetRejectAction( sal_uLong n
) { nRejectAction
= n
; }
249 void SetUser( const OUString
& r
);
250 void SetType( ScChangeActionType e
) { eType
= e
; }
251 void SetState( ScChangeActionState e
) { eState
= e
; }
254 ScBigRange
& GetBigRange() { return aBigRange
; }
256 void AddLink( ScChangeAction
* p
, ScChangeActionLinkEntry
* pL
)
258 ScChangeActionLinkEntry
* pLnk
=
259 new ScChangeActionLinkEntry(
264 virtual ScChangeActionLinkEntry
* GetDeletedIn() const
265 { return pLinkDeletedIn
; }
266 virtual ScChangeActionLinkEntry
** GetDeletedInAddress()
267 { return &pLinkDeletedIn
; }
268 bool RemoveDeletedIn( const ScChangeAction
* );
269 void SetDeletedIn( ScChangeAction
* );
271 ScChangeActionLinkEntry
* AddDeleted( ScChangeAction
* p
)
273 return new ScChangeActionLinkEntry(&pLinkDeleted
, p
);
276 ScChangeActionLinkEntry
* AddDependent( ScChangeAction
* p
)
278 return new ScChangeActionLinkEntry(&pLinkDependent
, p
);
281 void RemoveAllDependent();
283 void RemoveAllLinks();
285 virtual void AddContent( ScChangeActionContent
* ) = 0;
286 virtual void DeleteCellEntries() = 0;
288 virtual void UpdateReference( const ScChangeTrack
*,
289 UpdateRefMode
, const ScBigRange
&,
290 sal_Int32 nDx
, sal_Int32 nDy
, sal_Int32 nDz
);
293 virtual bool Reject(ScDocument
* pDoc
) = 0;
294 void RejectRestoreContents( ScChangeTrack
*, SCCOL nDx
, SCROW nDy
);
296 // used in Reject() instead of IsRejectable()
297 bool IsInternalRejectable() const;
299 // Derived classes that hold a pointer to the
300 // ChangeTrack must return that. Otherwise NULL.
301 virtual const ScChangeTrack
* GetChangeTrack() const = 0;
304 bool IsInsertType() const;
305 bool IsDeleteType() const;
306 bool IsVirgin() const;
307 SC_DLLPUBLIC
bool IsAccepted() const;
308 bool IsRejected() const;
310 // Action rejects another Action
311 bool IsRejecting() const;
313 // if action is visible in the document
314 bool IsVisible() const;
316 // if action if touchable
317 bool IsTouchable() const;
319 // if action is an entry in dialog root
320 bool IsDialogRoot() const;
322 // if an entry in a dialog shall be a drop down entry
323 bool IsDialogParent() const;
325 // if action is a delete with subdeletes (aufgeklappt = open ?)
326 bool IsMasterDelete() const;
328 // if action is acceptable/selectable/rejectable
329 bool IsClickable() const;
331 // if action is rejectable
332 bool IsRejectable() const;
334 const ScBigRange
& GetBigRange() const { return aBigRange
; }
335 SC_DLLPUBLIC DateTime
GetDateTime() const; // local time
336 const DateTime
& GetDateTimeUTC() const // UTC time
337 { return aDateTime
; }
338 ScChangeActionType
GetType() const { return eType
; }
339 ScChangeActionState
GetState() const { return eState
; }
340 sal_uLong
GetActionNumber() const { return nAction
; }
341 sal_uLong
GetRejectAction() const { return nRejectAction
; }
343 ScChangeAction
* GetNext() const { return pNext
; }
344 ScChangeAction
* GetPrev() const { return pPrev
; }
346 bool IsDeletedIn() const;
347 bool IsDeletedIn( const ScChangeAction
* ) const;
348 bool IsDeletedInDelType( ScChangeActionType
) const;
349 void RemoveAllDeletedIn();
351 const ScChangeActionLinkEntry
* GetFirstDeletedEntry() const
352 { return pLinkDeleted
; }
353 const ScChangeActionLinkEntry
* GetFirstDependentEntry() const
354 { return pLinkDependent
; }
355 bool HasDependent() const;
356 bool HasDeleted() const;
357 // description will be appended to string
358 // with bSplitRange only one column/row will be considered for delete
359 // (for a listing of entries)
360 virtual void GetDescription(
361 OUString
& rStr
, ScDocument
* pDoc
,
362 bool bSplitRange
= false, bool bWarning
= true ) const;
364 virtual void GetRefString(
365 OUString
& rStr
, ScDocument
* pDoc
, bool bFlag3D
= false ) const;
367 // for DocumentMerge set old date of the other
368 // action, fetched by GetDateTimeUTC
369 void SetDateTimeUTC( const DateTime
& rDT
)
372 const OUString
& GetUser() const { return aUser
;}
373 const OUString
& GetComment() const { return aComment
;}
376 void SetComment( const OUString
& rStr
);
378 // only to be used in the XML import
379 void SetDeletedInThis( sal_uLong nActionNumber
,
380 const ScChangeTrack
* pTrack
);
381 // only to be used in the XML import
382 void AddDependent( sal_uLong nActionNumber
,
383 const ScChangeTrack
* pTrack
);
387 class ScChangeActionIns
: public ScChangeAction
389 friend class ScChangeTrack
;
391 bool mbEndOfList
; /// whether or not a row was auto-inserted at the bottom.
393 ScChangeActionIns( const ScRange
& rRange
, bool bEndOfList
= false );
394 virtual ~ScChangeActionIns() override
;
396 virtual void AddContent( ScChangeActionContent
* ) override
{}
397 virtual void DeleteCellEntries() override
{}
399 virtual bool Reject(ScDocument
* pDoc
) override
;
401 virtual const ScChangeTrack
* GetChangeTrack() const override
{ return nullptr; }
405 const sal_uLong nActionNumber
,
406 const ScChangeActionState eState
,
407 const sal_uLong nRejectingNumber
,
408 const ScBigRange
& aBigRange
,
409 const OUString
& aUser
,
410 const DateTime
& aDateTime
,
411 const OUString
&sComment
,
412 const ScChangeActionType eType
,
413 bool bEndOfList
= false );
415 virtual void GetDescription(
416 OUString
& rStr
, ScDocument
* pDoc
, bool bSplitRange
= false, bool bWarning
= true) const override
;
418 SC_DLLPUBLIC
bool IsEndOfList() const;
422 class ScChangeActionMove
;
424 class ScChangeActionDelMoveEntry
: public ScChangeActionLinkEntry
426 friend class ScChangeActionDel
;
427 friend class ScChangeTrack
;
432 inline ScChangeActionDelMoveEntry(
433 ScChangeActionDelMoveEntry
** ppPrevP
,
434 ScChangeActionMove
* pMove
,
435 short nFrom
, short nTo
);
437 inline ScChangeActionMove
* GetMove();
440 const ScChangeActionDelMoveEntry
* GetNext() const
442 return static_cast<const ScChangeActionDelMoveEntry
*>(
443 ScChangeActionLinkEntry::GetNext());
445 inline const ScChangeActionMove
* GetMove() const;
446 short GetCutOffFrom() const { return nCutOffFrom
; }
447 short GetCutOffTo() const { return nCutOffTo
; }
450 class ScChangeActionDel
: public ScChangeAction
452 friend class ScChangeTrack
;
453 friend void ScChangeAction::Accept();
455 ScChangeTrack
* pTrack
;
456 ScChangeActionCellListEntry
* pFirstCell
;
457 ScChangeActionIns
* pCutOff
; // cut insert
458 short nCutOff
; // +: start -: end
459 ScChangeActionDelMoveEntry
* pLinkMove
;
463 ScChangeActionDel( const ScRange
& rRange
, SCCOL nDx
, SCROW nDy
, ScChangeTrack
* );
464 virtual ~ScChangeActionDel() override
;
466 virtual void AddContent( ScChangeActionContent
* ) override
;
467 virtual void DeleteCellEntries() override
;
469 void UndoCutOffMoves();
470 void UndoCutOffInsert();
472 virtual void UpdateReference( const ScChangeTrack
*,
473 UpdateRefMode
, const ScBigRange
&,
474 sal_Int32 nDx
, sal_Int32 nDy
, sal_Int32 nDz
) override
;
476 virtual bool Reject(ScDocument
* pDoc
) override
;
478 virtual const ScChangeTrack
* GetChangeTrack() const override
{ return pTrack
; }
482 const sal_uLong nActionNumber
, const ScChangeActionState eState
,
483 const sal_uLong nRejectingNumber
, const ScBigRange
& aBigRange
,
484 const OUString
& aUser
, const DateTime
& aDateTime
,
485 const OUString
&sComment
, const ScChangeActionType eType
,
486 const SCCOLROW nD
, ScChangeTrack
* pTrack
); // only to use in the XML import
487 // which of nDx and nDy is set is dependent on the type
489 // is the last in a row (or single)
490 bool IsBaseDelete() const;
492 // is the first in a row (or single)
493 bool IsTopDelete() const;
496 bool IsMultiDelete() const;
498 // is col, belonging to a TabDelete
499 bool IsTabDeleteCol() const;
501 SCCOL
GetDx() const { return nDx
; }
502 SCROW
GetDy() const { return nDy
; }
503 ScBigRange
GetOverAllRange() const; // BigRange + (nDx, nDy)
505 const ScChangeActionDelMoveEntry
* GetFirstMoveEntry() const
506 { return pLinkMove
; }
507 const ScChangeActionIns
* GetCutOffInsert() const { return pCutOff
; }
508 short GetCutOffCount() const { return nCutOff
; }
510 virtual void GetDescription(
511 OUString
& rStr
, ScDocument
* pDoc
, bool bSplitRange
= false, bool bWarning
= true ) const override
;
513 void SetCutOffInsert( ScChangeActionIns
* p
, short n
)
514 { pCutOff
= p
; nCutOff
= n
; } // only to use in the XML import
515 // this should be protected, but for the XML import it is public
516 // only to use in the XML import
517 // this should be protected, but for the XML import it is public
518 ScChangeActionDelMoveEntry
* AddCutOffMove(
519 ScChangeActionMove
* pMove
, short nFrom
, short nTo
);
522 // ScChangeActionMove
523 class ScChangeActionMove
: public ScChangeAction
525 friend class ScChangeTrack
;
526 friend class ScChangeActionDel
;
528 ScBigRange aFromRange
;
529 ScChangeTrack
* pTrack
;
530 ScChangeActionCellListEntry
* pFirstCell
;
531 sal_uLong nStartLastCut
; // for PasteCut undo
532 sal_uLong nEndLastCut
;
534 ScChangeActionMove( const ScRange
& rFromRange
,
535 const ScRange
& rToRange
,
536 ScChangeTrack
* pTrackP
)
537 : ScChangeAction( SC_CAT_MOVE
, rToRange
),
538 aFromRange( rFromRange
),
540 pFirstCell( nullptr ),
544 virtual ~ScChangeActionMove() override
;
546 virtual void AddContent( ScChangeActionContent
* ) override
;
547 virtual void DeleteCellEntries() override
;
549 ScBigRange
& GetFromRange() { return aFromRange
; }
551 void SetStartLastCut( sal_uLong nVal
) { nStartLastCut
= nVal
; }
552 sal_uLong
GetStartLastCut() const { return nStartLastCut
; }
553 void SetEndLastCut( sal_uLong nVal
) { nEndLastCut
= nVal
; }
554 sal_uLong
GetEndLastCut() const { return nEndLastCut
; }
556 virtual void UpdateReference( const ScChangeTrack
*,
557 UpdateRefMode
, const ScBigRange
&,
558 sal_Int32 nDx
, sal_Int32 nDy
, sal_Int32 nDz
) override
;
560 virtual bool Reject(ScDocument
* pDoc
) override
;
562 virtual const ScChangeTrack
* GetChangeTrack() const override
{ return pTrack
; }
565 using ScChangeAction::GetRefString
;
568 ScChangeActionMove(const sal_uLong nActionNumber
,
569 const ScChangeActionState eState
,
570 const sal_uLong nRejectingNumber
,
571 const ScBigRange
& aToBigRange
,
572 const OUString
& aUser
,
573 const DateTime
& aDateTime
,
574 const OUString
&sComment
,
575 const ScBigRange
& aFromBigRange
,
576 ScChangeTrack
* pTrack
); // only to use in the XML import
578 const ScBigRange
& GetFromRange() const { return aFromRange
; }
579 SC_DLLPUBLIC
void GetDelta( sal_Int32
& nDx
, sal_Int32
& nDy
, sal_Int32
& nDz
) const;
581 virtual void GetDescription(
582 OUString
& rStr
, ScDocument
* pDoc
, bool bSplitRange
= false,
583 bool bWarning
= true ) const override
;
585 virtual void GetRefString(
586 OUString
& rStr
, ScDocument
* pDoc
, bool bFlag3D
= false ) const override
;
589 ScChangeActionDelMoveEntry::ScChangeActionDelMoveEntry(
590 ScChangeActionDelMoveEntry
** ppPrevP
,
591 ScChangeActionMove
* pMove
,
592 short nFrom
, short nTo
)
593 : ScChangeActionLinkEntry(
594 reinterpret_cast<ScChangeActionLinkEntry
**>(
596 static_cast<ScChangeAction
*>(pMove
) ),
597 nCutOffFrom( nFrom
),
601 inline ScChangeActionMove
* ScChangeActionDelMoveEntry::GetMove()
603 return static_cast<ScChangeActionMove
*>(
604 ScChangeActionLinkEntry::GetAction());
607 inline const ScChangeActionMove
* ScChangeActionDelMoveEntry::GetMove() const
609 return static_cast<const ScChangeActionMove
*>(
610 ScChangeActionLinkEntry::GetAction());
612 // ScChangeActionContent
613 enum ScChangeActionContentCellType
621 class ScChangeActionContent
: public ScChangeAction
623 friend class ScChangeTrack
;
625 ScCellValue maOldCell
;
626 ScCellValue maNewCell
;
630 ScChangeActionContent
* pNextContent
; // at the same position
631 ScChangeActionContent
* pPrevContent
;
632 ScChangeActionContent
* pNextInSlot
; // in the same slot
633 ScChangeActionContent
** ppPrevInSlot
;
635 void InsertInSlot( ScChangeActionContent
** pp
)
640 if ( ( pNextInSlot
= *pp
) != nullptr )
641 pNextInSlot
->ppPrevInSlot
= &pNextInSlot
;
646 void RemoveFromSlot()
650 if ( ( *ppPrevInSlot
= pNextInSlot
) != nullptr )
651 pNextInSlot
->ppPrevInSlot
= ppPrevInSlot
;
652 ppPrevInSlot
= nullptr; // not inserted
656 ScChangeActionContent
* GetNextInSlot() { return pNextInSlot
; }
660 static void GetStringOfCell(
661 OUString
& rStr
, const ScCellValue
& rCell
, const ScDocument
* pDoc
, const ScAddress
& rPos
);
663 static void GetStringOfCell(
664 OUString
& rStr
, const ScCellValue
& rCell
, const ScDocument
* pDoc
, sal_uLong nFormat
);
666 static void SetValue( OUString
& rStr
, ScCellValue
& rCell
, const ScAddress
& rPos
,
667 const ScCellValue
& rOrgCell
, const ScDocument
* pFromDoc
,
668 ScDocument
* pToDoc
);
670 static void SetValue( OUString
& rStr
, ScCellValue
& rCell
, sal_uLong nFormat
,
671 const ScCellValue
& rOrgCell
, const ScDocument
* pFromDoc
,
672 ScDocument
* pToDoc
);
674 static void SetCell( OUString
& rStr
, ScCellValue
& rCell
, sal_uLong nFormat
, const ScDocument
* pDoc
);
676 static bool NeedsNumberFormat( const ScCellValue
& rVal
);
678 void SetValueString( OUString
& rValue
, ScCellValue
& rCell
, const OUString
& rStr
, ScDocument
* pDoc
);
680 void GetValueString( OUString
& rStr
, const OUString
& rValue
, const ScCellValue
& rCell
,
681 const ScDocument
* pDoc
) const;
683 void GetFormulaString( OUString
& rStr
, const ScFormulaCell
* pCell
) const;
685 virtual void AddContent( ScChangeActionContent
* ) override
{}
686 virtual void DeleteCellEntries() override
{}
688 virtual void UpdateReference( const ScChangeTrack
*,
689 UpdateRefMode
, const ScBigRange
&,
690 sal_Int32 nDx
, sal_Int32 nDy
, sal_Int32 nDz
) override
;
692 virtual bool Reject(ScDocument
* pDoc
) override
;
694 virtual const ScChangeTrack
* GetChangeTrack() const override
{ return nullptr; }
696 // pRejectActions!=NULL: reject actions get
697 // stacked, no SetNewValue, no Append
698 bool Select( ScDocument
*, ScChangeTrack
*,
699 bool bOldest
, ::std::stack
<ScChangeActionContent
*>* pRejectActions
);
702 const ScCellValue
& rCell
, const OUString
& rValue
, ScDocument
* pDoc
, SCCOL nDx
, SCROW nDy
) const;
705 using ScChangeAction::GetRefString
;
709 DECL_FIXEDMEMPOOL_NEWDEL( ScChangeActionContent
)
711 ScChangeActionContent( const ScRange
& rRange
);
713 ScChangeActionContent(
714 const sal_uLong nActionNumber
, const ScChangeActionState eState
,
715 const sal_uLong nRejectingNumber
, const ScBigRange
& aBigRange
,
716 const OUString
& aUser
, const DateTime
& aDateTime
,
717 const OUString
&sComment
, const ScCellValue
& rOldCell
,
718 const ScDocument
* pDoc
, const OUString
& sOldValue
); // to use for XML Import
720 ScChangeActionContent(
721 const sal_uLong nActionNumber
, const ScCellValue
& rNewCell
,
722 const ScBigRange
& aBigRange
, const ScDocument
* pDoc
,
723 const OUString
& sNewValue
); // to use for XML Import of Generated Actions
725 virtual ~ScChangeActionContent() override
;
727 ScChangeActionContent
* GetNextContent() const { return pNextContent
; }
728 ScChangeActionContent
* GetPrevContent() const { return pPrevContent
; }
729 ScChangeActionContent
* GetTopContent() const;
730 bool IsTopContent() const { return pNextContent
== nullptr; }
732 virtual ScChangeActionLinkEntry
* GetDeletedIn() const override
;
733 virtual ScChangeActionLinkEntry
** GetDeletedInAddress() override
;
735 void PutOldValueToDoc( ScDocument
*,
736 SCCOL nDx
, SCROW nDy
) const;
737 void PutNewValueToDoc( ScDocument
*,
738 SCCOL nDx
, SCROW nDy
) const;
740 void SetOldValue( const ScCellValue
& rCell
, const ScDocument
* pFromDoc
, ScDocument
* pToDoc
, sal_uLong nFormat
);
742 void SetOldValue( const ScCellValue
& rCell
, const ScDocument
* pFromDoc
, ScDocument
* pToDoc
);
744 void SetNewValue( const ScCellValue
& rCell
, ScDocument
* pDoc
);
746 // Used in import filter AppendContentOnTheFly,
748 const ScCellValue
& rOldCell
, sal_uLong nOldFormat
,
749 const ScCellValue
& rNewCell
, sal_uLong nNewFormat
, const ScDocument
* pDoc
);
751 // Use this only in the XML import,
752 // takes ownership of cell.
754 const ScCellValue
& rCell
, const ScDocument
* pDoc
, const OUString
& rFormatted
);
756 // These functions should be protected but for
757 // the XML import they are public.
758 void SetNextContent( ScChangeActionContent
* p
)
759 { pNextContent
= p
; }
760 void SetPrevContent( ScChangeActionContent
* p
)
761 { pPrevContent
= p
; }
764 // assigns string / creates formula cell
765 void SetOldValue( const OUString
& rOld
, ScDocument
* pDoc
);
767 void GetOldString( OUString
& rStr
, const ScDocument
* pDoc
) const;
768 void GetNewString( OUString
& rStr
, const ScDocument
* pDoc
) const;
769 const ScCellValue
& GetOldCell() const { return maOldCell
;}
770 const ScCellValue
& GetNewCell() const { return maNewCell
;}
771 virtual void GetDescription(
772 OUString
& rStr
, ScDocument
* pDoc
, bool bSplitRange
= false, bool bWarning
= true ) const override
;
774 virtual void GetRefString(
775 OUString
& rStr
, ScDocument
* pDoc
, bool bFlag3D
= false ) const override
;
777 static ScChangeActionContentCellType
GetContentCellType( const ScCellValue
& rCell
);
778 static ScChangeActionContentCellType
GetContentCellType( const ScRefCellValue
& rIter
);
781 bool IsMatrixOrigin() const;
783 bool IsOldMatrixReference() const;
786 // ScChangeActionReject
787 class ScChangeActionReject
: public ScChangeAction
789 friend class ScChangeTrack
;
790 friend class ScChangeActionContent
;
792 virtual void AddContent( ScChangeActionContent
* ) override
{}
793 virtual void DeleteCellEntries() override
{}
795 virtual bool Reject(ScDocument
* pDoc
) override
;
797 virtual const ScChangeTrack
* GetChangeTrack() const override
{ return nullptr; }
800 ScChangeActionReject(const sal_uLong nActionNumber
,
801 const ScChangeActionState eState
,
802 const sal_uLong nRejectingNumber
,
803 const ScBigRange
& aBigRange
,
804 const OUString
& aUser
,
805 const DateTime
& aDateTime
,
806 const OUString
&sComment
); // only to use in the XML import
810 enum ScChangeTrackMsgType
813 SC_CTM_APPEND
, // Actions appended
814 SC_CTM_REMOVE
, // Actions removed
815 SC_CTM_CHANGE
, // Actions changed
816 SC_CTM_PARENT
// became a parent (and wasn't before)
819 struct ScChangeTrackMsgInfo
821 DECL_FIXEDMEMPOOL_NEWDEL( ScChangeTrackMsgInfo
)
823 ScChangeTrackMsgType eMsgType
;
824 sal_uLong nStartAction
;
825 sal_uLong nEndAction
;
828 // MsgQueue for notification via ModifiedLink
829 typedef std::deque
<ScChangeTrackMsgInfo
*> ScChangeTrackMsgQueue
;
830 typedef std::stack
<ScChangeTrackMsgInfo
*> ScChangeTrackMsgStack
;
831 typedef std::map
<sal_uLong
, ScChangeAction
*> ScChangeActionMap
;
833 enum ScChangeTrackMergeState
842 // Internally generated actions start at this value (nearly all bits set)
843 // and are decremented, to keep values in a table separated from "normal" actions.
844 #define SC_CHGTRACK_GENERATED_START (sal_uInt32(0xfffffff0))
846 class ScChangeTrack
: public utl::ConfigurationListener
848 friend void ScChangeAction::RejectRestoreContents( ScChangeTrack
*, SCCOL
, SCROW
);
849 friend bool ScChangeActionDel::Reject( ScDocument
* pDoc
);
850 friend void ScChangeActionDel::DeleteCellEntries();
851 friend void ScChangeActionMove::DeleteCellEntries();
852 friend bool ScChangeActionMove::Reject( ScDocument
* pDoc
);
854 static const SCROW nContentRowsPerSlot
;
855 static const SCSIZE nContentSlots
;
857 css::uno::Sequence
< sal_Int8
> aProtectPass
;
858 ScChangeActionMap aMap
;
859 ScChangeActionMap aGeneratedMap
;
860 ScChangeActionMap aPasteCutMap
;
861 ScChangeTrackMsgQueue aMsgQueue
;
862 ScChangeTrackMsgStack aMsgStackTmp
;
863 ScChangeTrackMsgStack aMsgStackFinal
;
864 std::set
<OUString
> maUserCollection
;
866 Link
<ScChangeTrack
&,void> aModifiedLink
;
867 ScRange aInDeleteRange
;
868 DateTime aFixDateTime
;
869 ScChangeAction
* pFirst
;
870 ScChangeAction
* pLast
;
871 ScChangeActionContent
* pFirstGeneratedDelContent
;
872 std::unique_ptr
<ScChangeActionContent
*[]> ppContentSlots
;
873 ScChangeActionMove
* pLastCutMove
;
874 ScChangeActionLinkEntry
* pLinkInsertCol
;
875 ScChangeActionLinkEntry
* pLinkInsertRow
;
876 ScChangeActionLinkEntry
* pLinkInsertTab
;
877 ScChangeActionLinkEntry
* pLinkMove
;
878 ScChangeTrackMsgInfo
* pBlockModifyMsg
;
880 sal_uLong nActionMax
;
881 sal_uLong nGeneratedMin
;
882 sal_uLong nMarkLastSaved
;
883 sal_uLong nStartLastCut
;
884 sal_uLong nEndLastCut
;
885 sal_uLong nLastMerge
;
886 ScChangeTrackMergeState eMergeState
;
888 bool bInDeleteUndo
:1;
891 bool bUseFixDateTime
:1;
892 bool bTimeNanoSeconds
:1;
894 ScChangeTrack( const ScChangeTrack
& ) = delete;
895 ScChangeTrack
& operator=( const ScChangeTrack
& ) = delete;
897 static SCROW
InitContentRowsPerSlot();
899 // true if one is ScMatrixMode::Formula and the other is
900 // not, or if both are and range differs
901 static bool IsMatrixFormulaRangeDifferent(
902 const ScCellValue
& rOldCell
, const ScCellValue
& rNewCell
);
906 void SetInDeleteRange( const ScRange
& rRange
)
907 { aInDeleteRange
= rRange
; }
908 void SetInDelete( bool bVal
)
909 { bInDelete
= bVal
; }
910 void SetInDeleteTop( bool bVal
)
911 { bInDeleteTop
= bVal
; }
912 void SetInDeleteUndo( bool bVal
)
913 { bInDeleteUndo
= bVal
; }
914 void SetInPasteCut( bool bVal
)
915 { bInPasteCut
= bVal
; }
916 void SetMergeState( ScChangeTrackMergeState eState
)
917 { eMergeState
= eState
; }
918 ScChangeTrackMergeState
GetMergeState() const { return eMergeState
; }
919 void SetLastMerge( sal_uLong nVal
) { nLastMerge
= nVal
; }
920 sal_uLong
GetLastMerge() const { return nLastMerge
; }
922 void SetLastCutMoveRange( const ScRange
&, ScDocument
* );
924 // create block of ModifyMsg
925 void StartBlockModify( ScChangeTrackMsgType
,
926 sal_uLong nStartAction
);
927 void EndBlockModify( sal_uLong nEndAction
);
929 void AddDependentWithNotify( ScChangeAction
* pParent
,
930 ScChangeAction
* pDependent
);
932 void Dependencies( ScChangeAction
* );
933 void UpdateReference( ScChangeAction
*, bool bUndo
);
934 void UpdateReference( ScChangeAction
** ppFirstAction
, ScChangeAction
* pAct
, bool bUndo
);
935 void Append( ScChangeAction
* pAppend
, sal_uLong nAction
);
936 SC_DLLPUBLIC
void AppendDeleteRange( const ScRange
&,
937 ScDocument
* pRefDoc
, SCTAB nDz
,
938 sal_uLong nRejectingInsert
);
939 void AppendOneDeleteRange( const ScRange
& rOrgRange
,
941 SCCOL nDx
, SCROW nDy
, SCTAB nDz
,
942 sal_uLong nRejectingInsert
);
943 void LookUpContents( const ScRange
& rOrgRange
,
945 SCCOL nDx
, SCROW nDy
, SCTAB nDz
);
946 void Remove( ScChangeAction
* );
947 void MasterLinks( ScChangeAction
* );
949 // Content on top an Position
950 ScChangeActionContent
* SearchContentAt( const ScBigAddress
&,
951 const ScChangeAction
* pButNotThis
) const;
952 void DeleteGeneratedDelContent(
953 ScChangeActionContent
* );
955 ScChangeActionContent
* GenerateDelContent(
956 const ScAddress
& rPos
, const ScCellValue
& rCell
, const ScDocument
* pFromDoc
);
958 void DeleteCellEntries(
959 ScChangeActionCellListEntry
*&,
960 const ScChangeAction
* pDeletor
);
962 // Reject action and all dependent actions,
963 // Table stems from previous GetDependents,
964 // only needed for Insert and Move (MasterType),
965 // is NULL otherwise.
966 // bRecursion == called from reject with table
967 bool Reject( ScChangeAction
*, ScChangeActionMap
*, bool bRecursion
);
969 bool IsLastAction( sal_uLong nNum
) const;
971 void ClearMsgQueue();
972 virtual void ConfigurationChanged( utl::ConfigurationBroadcaster
*, ConfigurationHints
) override
;
976 static SCSIZE
ComputeContentSlot( sal_Int32 nRow
)
978 if ( nRow
< 0 || nRow
> MAXROW
)
979 return nContentSlots
- 1;
980 return static_cast< SCSIZE
>( nRow
/ nContentRowsPerSlot
);
983 SC_DLLPUBLIC
ScChangeTrack( ScDocument
* );
984 ScChangeTrack(ScDocument
* pDocP
, const std::set
<OUString
>& aTempUserCollection
); // only to use in the XML import
985 SC_DLLPUBLIC
virtual ~ScChangeTrack() override
;
988 ScChangeActionContent
* GetFirstGenerated() const { return pFirstGeneratedDelContent
; }
989 ScChangeAction
* GetFirst() const { return pFirst
; }
990 ScChangeAction
* GetLast() const { return pLast
; }
991 sal_uLong
GetActionMax() const { return nActionMax
; }
992 bool IsGenerated( sal_uLong nAction
) const;
993 SC_DLLPUBLIC ScChangeAction
* GetAction( sal_uLong nAction
) const;
994 ScChangeAction
* GetGenerated( sal_uLong nGenerated
) const;
995 ScChangeAction
* GetActionOrGenerated( sal_uLong nAction
) const;
996 sal_uLong
GetLastSavedActionNumber() const;
997 void SetLastSavedActionNumber(sal_uLong nNew
);
998 ScChangeAction
* GetLastSaved() const;
999 ScChangeActionContent
** GetContentSlots() const { return ppContentSlots
.get(); }
1001 const ScRange
& GetInDeleteRange() const
1002 { return aInDeleteRange
; }
1003 bool IsInDelete() const { return bInDelete
; }
1004 bool IsInDeleteTop() const { return bInDeleteTop
; }
1005 bool IsInDeleteUndo() const { return bInDeleteUndo
; }
1006 bool IsInPasteCut() const { return bInPasteCut
; }
1007 SC_DLLPUBLIC
void SetUser( const OUString
& rUser
);
1008 const OUString
& GetUser() const { return maUser
;}
1009 const std::set
<OUString
>& GetUserCollection() const { return maUserCollection
;}
1010 ScDocument
* GetDocument() const { return pDoc
; }
1011 // for import filter
1012 const DateTime
& GetFixDateTime() const { return aFixDateTime
; }
1014 // set this if the date/time set with
1015 // SetFixDateTime...() shall be applied to
1017 void SetUseFixDateTime( bool bVal
)
1018 { bUseFixDateTime
= bVal
; }
1019 // for MergeDocument, apply original date/time as UTC
1020 void SetFixDateTimeUTC( const DateTime
& rDT
)
1021 { aFixDateTime
= rDT
; }
1022 // for import filter, apply original date/time as local time
1023 void SetFixDateTimeLocal( const DateTime
& rDT
)
1024 { aFixDateTime
= rDT
; aFixDateTime
.ConvertToUTC(); }
1026 void Append( ScChangeAction
* );
1028 // pRefDoc may be NULL => no lookup of contents
1029 // => no generation of deleted contents
1030 SC_DLLPUBLIC
void AppendDeleteRange( const ScRange
&,
1031 ScDocument
* pRefDoc
,
1032 sal_uLong
& nStartAction
, sal_uLong
& nEndAction
,
1034 // nDz: multi TabDel, LookUpContent must be searched
1035 // with an offset of -nDz
1037 // after new value was set in the document,
1038 // old value from RefDoc/UndoDoc
1039 void AppendContent( const ScAddress
& rPos
,
1040 const ScDocument
* pRefDoc
);
1041 // after new values were set in the document,
1042 // old values from RefDoc/UndoDoc
1043 void AppendContentRange( const ScRange
& rRange
,
1044 ScDocument
* pRefDoc
,
1045 sal_uLong
& nStartAction
, sal_uLong
& nEndAction
,
1046 ScChangeActionClipMode eMode
= SC_CACM_NONE
);
1047 // after new value was set in the document,
1048 // old value from pOldCell, nOldFormat,
1049 // RefDoc==NULL => Doc
1050 void AppendContent( const ScAddress
& rPos
, const ScCellValue
& rOldCell
,
1051 sal_uLong nOldFormat
, ScDocument
* pRefDoc
= nullptr );
1052 // after new value was set in the document,
1053 // old value from pOldCell, format from Doc
1054 SC_DLLPUBLIC
void AppendContent( const ScAddress
& rPos
, const ScCellValue
& rOldCell
);
1055 // after new values were set in the document,
1056 // old values from RefDoc/UndoDoc.
1057 // All contents with a cell in RefDoc
1058 void AppendContentsIfInRefDoc( ScDocument
* pRefDoc
,
1059 sal_uLong
& nStartAction
, sal_uLong
& nEndAction
);
1061 // Meant for import filter, creates and inserts
1062 // an unconditional content action of the two
1063 // cells without querying the document, not
1064 // even for number formats (though the number
1065 // formatter of the document may be used).
1066 // The action is returned and may be used to
1067 // set user name, description, date/time et al.
1068 // Takes ownership of the cells!
1069 SC_DLLPUBLIC ScChangeActionContent
* AppendContentOnTheFly(
1070 const ScAddress
& rPos
, const ScCellValue
& rOldCell
, const ScCellValue
& rNewCell
,
1071 sal_uLong nOldFormat
= 0, sal_uLong nNewFormat
= 0 );
1073 // Only use the following two if there is no different solution! (Assign
1074 // string for NewValue or creation of a formula respectively)
1076 SC_DLLPUBLIC
void AppendInsert( const ScRange
& rRange
, bool bEndOfList
= false );
1078 // pRefDoc may be NULL => no lookup of contents
1079 // => no generation of deleted contents
1080 SC_DLLPUBLIC
void AppendMove( const ScRange
& rFromRange
, const ScRange
& rToRange
,
1081 ScDocument
* pRefDoc
);
1086 nStartLastCut
= nEndLastCut
= 0;
1089 delete pLastCutMove
;
1090 pLastCutMove
= nullptr;
1093 bool HasLastCut() const
1095 return nEndLastCut
> 0 &&
1096 nStartLastCut
<= nEndLastCut
&&
1100 SC_DLLPUBLIC
void Undo( sal_uLong nStartAction
, sal_uLong nEndAction
, bool bMerge
= false );
1102 // adjust references for MergeDocument
1103 //! may only be used in a temporary opened document.
1104 //! the Track (?) is unclean afterwards
1105 void MergePrepare( const ScChangeAction
* pFirstMerge
, bool bShared
);
1106 void MergeOwn( ScChangeAction
* pAct
, sal_uLong nFirstMerge
, bool bShared
);
1107 static bool MergeIgnore( const ScChangeAction
&, sal_uLong nFirstMerge
);
1109 // This comment was already really strange in German.
1110 // Tried to structure it a little. Hope no information got lost...
1112 // Insert dependents into table.
1113 // ScChangeAction is
1114 // - "Insert": really dependents
1115 // - "Move": dependent contents in FromRange /
1116 // deleted contents in ToRange
1117 // OR inserts in FromRange or ToRange
1118 // - "Delete": a list of deleted (what?)
1119 // OR for content, different contents at the same position
1120 // OR MatrixReferences belonging to MatrixOrigin
1122 // With bListMasterDelete (==TRUE ?) all Deletes of a row belonging
1123 // to a MasterDelete are listed (possibly it is
1124 // "all Deletes belonging...are listed in a row?)
1126 // With bAllFlat (==TRUE ?) all dependents of dependents
1127 // will be inserted flatly.
1129 SC_DLLPUBLIC
void GetDependents(
1130 ScChangeAction
*, ScChangeActionMap
&, bool bListMasterDelete
= false, bool bAllFlat
= false ) const;
1132 // Reject visible action (and dependents)
1133 bool Reject( ScChangeAction
*, bool bShared
= false );
1135 // Accept visible action (and dependents)
1136 SC_DLLPUBLIC
bool Accept( ScChangeAction
* );
1138 void AcceptAll(); // all Virgins
1139 bool RejectAll(); // all Virgins
1141 // Selects a content of several contents at the same
1142 // position and accepts this one and
1143 // the older ones, rejects the more recent ones.
1144 // If bOldest==TRUE then the first OldValue
1145 // of a Virgin-Content-List will be restored.
1146 bool SelectContent( ScChangeAction
*, bool bOldest
= false );
1148 // If ModifiedLink is set, changes go to
1149 // ScChangeTrackMsgQueue
1150 void SetModifiedLink( const Link
<ScChangeTrack
&,void>& r
)
1151 { aModifiedLink
= r
; ClearMsgQueue(); }
1152 ScChangeTrackMsgQueue
& GetMsgQueue();
1154 void NotifyModified( ScChangeTrackMsgType eMsgType
,
1155 sal_uLong nStartAction
, sal_uLong nEndAction
);
1157 sal_uLong
AddLoadedGenerated( const ScCellValue
& rNewCell
,
1158 const ScBigRange
& aBigRange
, const OUString
& sNewValue
); // only to use in the XML import
1159 void AppendLoaded( ScChangeAction
* pAppend
); // this is only for the XML import public, it should be protected
1160 void SetActionMax(sal_uLong nTempActionMax
)
1161 { nActionMax
= nTempActionMax
; } // only to use in the XML import
1163 void SetProtection( const css::uno::Sequence
< sal_Int8
>& rPass
)
1164 { aProtectPass
= rPass
; }
1165 const css::uno::Sequence
< sal_Int8
>& GetProtection() const
1166 { return aProtectPass
; }
1167 bool IsProtected() const { return aProtectPass
.getLength() != 0; }
1169 // If time stamps of actions of this
1170 // ChangeTrack and a second one are to be
1171 // compared including nanoseconds.
1172 void SetTimeNanoSeconds( bool bVal
) { bTimeNanoSeconds
= bVal
; }
1173 bool IsTimeNanoSeconds() const { return bTimeNanoSeconds
; }
1175 void AppendCloned( ScChangeAction
* pAppend
);
1176 SC_DLLPUBLIC ScChangeTrack
* Clone( ScDocument
* pDocument
) const;
1177 static void MergeActionState( ScChangeAction
* pAct
, const ScChangeAction
* pOtherAct
);
1178 /// Get info about all ScChangeAction elements.
1179 OUString
GetChangeTrackInfo();
1184 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */