update credits
[LibreOffice.git] / sc / inc / chgtrack.hxx
blob872f268599e03f8a294c852553fca9ee6e3b5a3c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef SC_CHGTRACK_HXX
21 #define SC_CHGTRACK_HXX
23 #include <deque>
24 #include <map>
25 #include <set>
26 #include <stack>
28 #include <tools/datetime.hxx>
29 #include <tools/mempool.hxx>
30 #include "tools/link.hxx"
31 #include <unotools/options.hxx>
32 #include "global.hxx"
33 #include "bigrange.hxx"
34 #include "scdllapi.h"
35 #include "refupdat.hxx"
36 #include "cellvalue.hxx"
38 class ScDocument;
39 class ScFormulaCell;
41 enum ScChangeActionType
43 SC_CAT_NONE,
44 SC_CAT_INSERT_COLS,
45 SC_CAT_INSERT_ROWS,
46 SC_CAT_INSERT_TABS,
47 SC_CAT_DELETE_COLS,
48 SC_CAT_DELETE_ROWS,
49 SC_CAT_DELETE_TABS,
50 SC_CAT_MOVE,
51 SC_CAT_CONTENT,
52 SC_CAT_REJECT
56 enum ScChangeActionState
58 SC_CAS_VIRGIN,
59 SC_CAS_ACCEPTED,
60 SC_CAS_REJECTED
64 enum ScChangeActionClipMode
66 SC_CACM_NONE,
67 SC_CACM_CUT,
68 SC_CACM_COPY,
69 SC_CACM_PASTE
72 // --- ScChangeActionLinkEntry ---------------------------------------------
74 // Inserts itself as the head of a chain (better: linked list?), or before a LinkEntry
75 // on delete: automatically remove of what is linked (German original was strange...)
76 // ppPrev == &previous->pNext oder address of pointer to head of linked list,
77 // *ppPrev == this
79 class ScChangeAction;
81 class ScChangeActionLinkEntry
83 // not implemented, prevent usage
84 ScChangeActionLinkEntry( const ScChangeActionLinkEntry& );
85 ScChangeActionLinkEntry& operator=( const ScChangeActionLinkEntry& );
87 protected:
89 ScChangeActionLinkEntry* pNext;
90 ScChangeActionLinkEntry** ppPrev;
91 ScChangeAction* pAction;
92 ScChangeActionLinkEntry* pLink;
94 public:
96 DECL_FIXEDMEMPOOL_NEWDEL( ScChangeActionLinkEntry )
98 ScChangeActionLinkEntry(
99 ScChangeActionLinkEntry** ppPrevP,
100 ScChangeAction* pActionP )
101 : pNext( *ppPrevP ),
102 ppPrev( ppPrevP ),
103 pAction( pActionP ),
104 pLink( NULL )
106 if ( pNext )
107 pNext->ppPrev = &pNext;
108 *ppPrevP = this;
111 virtual ~ScChangeActionLinkEntry()
113 ScChangeActionLinkEntry* p = pLink;
114 UnLink();
115 Remove();
116 if ( p )
117 delete p;
120 void SetLink( ScChangeActionLinkEntry* pLinkP )
122 UnLink();
123 if ( pLinkP )
125 pLink = pLinkP;
126 pLinkP->pLink = this;
130 void UnLink()
132 if ( pLink )
134 pLink->pLink = NULL;
135 pLink = NULL;
139 void Remove()
141 if ( ppPrev )
143 if ( ( *ppPrev = pNext ) != NULL )
144 pNext->ppPrev = ppPrev;
145 ppPrev = NULL; // not inserted
149 void Insert( ScChangeActionLinkEntry** ppPrevP )
151 if ( !ppPrev )
153 ppPrev = ppPrevP;
154 if ( (pNext = *ppPrevP) )
155 pNext->ppPrev = &pNext;
156 *ppPrevP = this;
160 const ScChangeActionLinkEntry* GetLink() const { return pLink; }
161 ScChangeActionLinkEntry* GetLink() { return pLink; }
162 const ScChangeActionLinkEntry* GetNext() const { return pNext; }
163 ScChangeActionLinkEntry* GetNext() { return pNext; }
164 const ScChangeAction* GetAction() const { return pAction; }
165 ScChangeAction* GetAction() { return pAction; }
168 // --- ScChangeActionCellListEntry -----------------------------------------
169 // this is only for the XML Export in the hxx
170 class ScChangeActionContent;
172 class ScChangeActionCellListEntry
174 friend class ScChangeAction;
175 friend class ScChangeActionDel;
176 friend class ScChangeActionMove;
177 friend class ScChangeTrack;
179 ScChangeActionCellListEntry* pNext;
180 ScChangeActionContent* pContent;
182 ScChangeActionCellListEntry(
183 ScChangeActionContent* pContentP,
184 ScChangeActionCellListEntry* pNextP )
185 : pNext( pNextP ),
186 pContent( pContentP )
189 public:
190 const ScChangeActionCellListEntry* GetNext() const { return pNext; } // this is only for the XML Export public
191 const ScChangeActionContent* GetContent() const { return pContent; } // this is only for the XML Export public
193 DECL_FIXEDMEMPOOL_NEWDEL( ScChangeActionCellListEntry )
196 // --- ScChangeAction -------------------------------------------------------
198 class ScChangeTrack;
199 class ScChangeActionIns;
200 class ScChangeActionDel;
201 class ScChangeActionContent;
203 class ScChangeAction
205 friend class ScChangeTrack;
206 friend class ScChangeActionIns;
207 friend class ScChangeActionDel;
208 friend class ScChangeActionMove;
209 friend class ScChangeActionContent;
211 // not implemented, prevent usage
212 ScChangeAction( const ScChangeAction& );
213 ScChangeAction& operator=( const ScChangeAction& );
215 protected:
217 ScBigRange aBigRange; // Ins/Del/MoveTo/ContentPos
218 DateTime aDateTime; //! UTC
219 OUString aUser; // who?
220 OUString aComment; // user comment
221 ScChangeAction* pNext; // next in linked list
222 ScChangeAction* pPrev; // previous in linked list
223 ScChangeActionLinkEntry* pLinkAny; // arbitrary links
224 ScChangeActionLinkEntry* pLinkDeletedIn; // access to insert areas which were
225 // deleted or moved or rejected
226 ScChangeActionLinkEntry* pLinkDeleted; // links to deleted
227 ScChangeActionLinkEntry* pLinkDependent; // links to dependent
228 sal_uLong nAction;
229 sal_uLong nRejectAction;
230 ScChangeActionType eType;
231 ScChangeActionState eState;
233 ScChangeAction( ScChangeActionType, const ScRange& );
235 // only to be used in the XML import
236 ScChangeAction( ScChangeActionType,
237 const ScBigRange&,
238 const sal_uLong nAction,
239 const sal_uLong nRejectAction,
240 const ScChangeActionState eState,
241 const DateTime& aDateTime,
242 const OUString& aUser,
243 const OUString& aComment );
245 // only to be used in the XML import
246 ScChangeAction( ScChangeActionType, const ScBigRange&, const sal_uLong nAction);
248 virtual ~ScChangeAction();
250 OUString GetRefString(
251 const ScBigRange& rRange, ScDocument* pDoc, bool bFlag3D = false) const;
253 void SetActionNumber( sal_uLong n ) { nAction = n; }
254 void SetRejectAction( sal_uLong n ) { nRejectAction = n; }
255 void SetUser( const OUString& r );
256 void SetType( ScChangeActionType e ) { eType = e; }
257 void SetState( ScChangeActionState e ) { eState = e; }
258 void SetRejected();
260 ScBigRange& GetBigRange() { return aBigRange; }
262 ScChangeActionLinkEntry* AddLink(
263 ScChangeAction* p, ScChangeActionLinkEntry* pL )
265 ScChangeActionLinkEntry* pLnk =
266 new ScChangeActionLinkEntry(
267 &pLinkAny, p );
268 pLnk->SetLink( pL );
269 return pLnk;
272 void RemoveAllAnyLinks();
274 virtual ScChangeActionLinkEntry* GetDeletedIn() const
275 { return pLinkDeletedIn; }
276 virtual ScChangeActionLinkEntry** GetDeletedInAddress()
277 { return &pLinkDeletedIn; }
278 ScChangeActionLinkEntry* AddDeletedIn( ScChangeAction* p )
280 return new ScChangeActionLinkEntry(
281 GetDeletedInAddress(), p );
284 bool RemoveDeletedIn( const ScChangeAction* );
285 void SetDeletedIn( ScChangeAction* );
287 ScChangeActionLinkEntry* AddDeleted( ScChangeAction* p )
289 return new ScChangeActionLinkEntry(&pLinkDeleted, p);
292 void RemoveAllDeleted();
294 ScChangeActionLinkEntry* AddDependent( ScChangeAction* p )
296 return new ScChangeActionLinkEntry(&pLinkDependent, p);
299 void RemoveAllDependent();
301 void RemoveAllLinks();
303 virtual void AddContent( ScChangeActionContent* ) = 0;
304 virtual void DeleteCellEntries() = 0;
306 virtual void UpdateReference( const ScChangeTrack*,
307 UpdateRefMode, const ScBigRange&,
308 sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz );
310 void Accept();
311 virtual bool Reject(ScDocument* pDoc) = 0;
312 void RejectRestoreContents( ScChangeTrack*, SCsCOL nDx, SCsROW nDy );
314 // used in Reject() instead of IsRejectable()
315 bool IsInternalRejectable() const;
317 // Derived classes that hold a pointer to the
318 // ChangeTrack must return that. Otherwise NULL.
319 virtual const ScChangeTrack* GetChangeTrack() const = 0;
321 public:
322 bool IsInsertType() const;
323 bool IsDeleteType() const;
324 bool IsVirgin() const;
325 SC_DLLPUBLIC bool IsAccepted() const;
326 bool IsRejected() const;
328 // Action rejects another Action
329 bool IsRejecting() const;
331 // if action is visible in the document
332 bool IsVisible() const;
334 // if action if touchable
335 bool IsTouchable() const;
337 // if action is an entry in dialog root
338 bool IsDialogRoot() const;
340 // if an entry in a dialog shall be a drop down entry
341 bool IsDialogParent() const;
343 // if action is a delete with subdeletes (aufgeklappt = open ?)
344 bool IsMasterDelete() const;
346 // if action is acceptable/selectable/rejectable
347 bool IsClickable() const;
349 // if action is rejectable
350 bool IsRejectable() const;
352 const ScBigRange& GetBigRange() const { return aBigRange; }
353 SC_DLLPUBLIC DateTime GetDateTime() const; // local time
354 const DateTime& GetDateTimeUTC() const // UTC time
355 { return aDateTime; }
356 ScChangeActionType GetType() const { return eType; }
357 ScChangeActionState GetState() const { return eState; }
358 sal_uLong GetActionNumber() const { return nAction; }
359 sal_uLong GetRejectAction() const { return nRejectAction; }
361 ScChangeAction* GetNext() const { return pNext; }
362 ScChangeAction* GetPrev() const { return pPrev; }
364 bool IsDeletedIn() const;
365 bool IsDeletedIn( const ScChangeAction* ) const;
366 bool IsDeletedInDelType( ScChangeActionType ) const;
367 void RemoveAllDeletedIn();
369 const ScChangeActionLinkEntry* GetFirstDeletedEntry() const
370 { return pLinkDeleted; }
371 const ScChangeActionLinkEntry* GetFirstDependentEntry() const
372 { return pLinkDependent; }
373 bool HasDependent() const;
374 bool HasDeleted() const;
375 // description will be appended to string
376 // with bSplitRange only one column/row will be considered for delete
377 // (for a listing of entries)
378 virtual void GetDescription(
379 OUString& rStr, ScDocument* pDoc,
380 bool bSplitRange = false, bool bWarning = true ) const;
382 virtual void GetRefString(
383 OUString& rStr, ScDocument* pDoc, bool bFlag3D = false ) const;
385 // for DocumentMerge set old date of the other
386 // action, fetched by GetDateTimeUTC
387 void SetDateTimeUTC( const DateTime& rDT )
388 { aDateTime = rDT; }
390 SC_DLLPUBLIC const OUString& GetUser() const;
391 const OUString& GetComment() const;
393 // set user comment
394 void SetComment( const OUString& rStr );
396 // only to be used in the XML import
397 void SetDeletedInThis( sal_uLong nActionNumber,
398 const ScChangeTrack* pTrack );
399 // only to be used in the XML import
400 void AddDependent( sal_uLong nActionNumber,
401 const ScChangeTrack* pTrack );
405 // --- ScChangeActionIns ----------------------------------------------------
407 class ScChangeActionIns : public ScChangeAction
409 friend class ScChangeTrack;
411 ScChangeActionIns( const ScRange& rRange );
412 virtual ~ScChangeActionIns();
414 virtual void AddContent( ScChangeActionContent* ) {}
415 virtual void DeleteCellEntries() {}
417 virtual bool Reject(ScDocument* pDoc);
419 virtual const ScChangeTrack* GetChangeTrack() const { return 0; }
421 public:
422 ScChangeActionIns(const sal_uLong nActionNumber,
423 const ScChangeActionState eState,
424 const sal_uLong nRejectingNumber,
425 const ScBigRange& aBigRange,
426 const OUString& aUser,
427 const DateTime& aDateTime,
428 const OUString &sComment,
429 const ScChangeActionType eType); // only to use in the XML import
431 virtual void GetDescription(
432 OUString& rStr, ScDocument* pDoc, bool bSplitRange = false, bool bWarning = true) const;
436 // --- ScChangeActionDel ----------------------------------------------------
438 class ScChangeActionMove;
440 class ScChangeActionDelMoveEntry : public ScChangeActionLinkEntry
442 friend class ScChangeActionDel;
443 friend class ScChangeTrack;
445 short nCutOffFrom;
446 short nCutOffTo;
448 ScChangeActionDelMoveEntry(
449 ScChangeActionDelMoveEntry** ppPrevP,
450 ScChangeActionMove* pMove,
451 short nFrom, short nTo )
452 : ScChangeActionLinkEntry(
453 (ScChangeActionLinkEntry**)
454 ppPrevP,
455 (ScChangeAction*) pMove ),
456 nCutOffFrom( nFrom ),
457 nCutOffTo( nTo )
460 ScChangeActionDelMoveEntry* GetNext()
462 return (ScChangeActionDelMoveEntry*)
463 ScChangeActionLinkEntry::GetNext();
465 ScChangeActionMove* GetMove()
467 return (ScChangeActionMove*)
468 ScChangeActionLinkEntry::GetAction();
471 public:
472 const ScChangeActionDelMoveEntry* GetNext() const
474 return (const ScChangeActionDelMoveEntry*)
475 ScChangeActionLinkEntry::GetNext();
477 const ScChangeActionMove* GetMove() const
479 return (const ScChangeActionMove*)
480 ScChangeActionLinkEntry::GetAction();
482 short GetCutOffFrom() const { return nCutOffFrom; }
483 short GetCutOffTo() const { return nCutOffTo; }
487 class ScChangeActionDel : public ScChangeAction
489 friend class ScChangeTrack;
490 friend void ScChangeAction::Accept();
492 ScChangeTrack* pTrack;
493 ScChangeActionCellListEntry* pFirstCell;
494 ScChangeActionIns* pCutOff; // cut insert
495 short nCutOff; // +: start -: end
496 ScChangeActionDelMoveEntry* pLinkMove;
497 SCsCOL nDx;
498 SCsROW nDy;
500 ScChangeActionDel( const ScRange& rRange, SCsCOL nDx, SCsROW nDy, ScChangeTrack* );
501 virtual ~ScChangeActionDel();
503 ScChangeActionIns* GetCutOffInsert() { return pCutOff; }
505 virtual void AddContent( ScChangeActionContent* );
506 virtual void DeleteCellEntries();
508 void UndoCutOffMoves();
509 void UndoCutOffInsert();
511 virtual void UpdateReference( const ScChangeTrack*,
512 UpdateRefMode, const ScBigRange&,
513 sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz );
515 virtual bool Reject(ScDocument* pDoc);
517 virtual const ScChangeTrack* GetChangeTrack() const { return pTrack; }
519 public:
520 ScChangeActionDel(
521 const sal_uLong nActionNumber, const ScChangeActionState eState,
522 const sal_uLong nRejectingNumber, const ScBigRange& aBigRange,
523 const OUString& aUser, const DateTime& aDateTime,
524 const OUString &sComment, const ScChangeActionType eType,
525 const SCsCOLROW nD, ScChangeTrack* pTrack); // only to use in the XML import
526 // which of nDx and nDy is set is dependend on the type
528 // is the last in a row (or single)
529 bool IsBaseDelete() const;
531 // is the first in a row (or single)
532 bool IsTopDelete() const;
534 // is part of a row
535 bool IsMultiDelete() const;
537 // is col, belonging to a TabDelete
538 bool IsTabDeleteCol() const;
540 SCsCOL GetDx() const;
541 SCsROW GetDy() const;
542 ScBigRange GetOverAllRange() const; // BigRange + (nDx, nDy)
544 const ScChangeActionCellListEntry* GetFirstCellEntry() const
545 { return pFirstCell; }
546 const ScChangeActionDelMoveEntry* GetFirstMoveEntry() const
547 { return pLinkMove; }
548 const ScChangeActionIns* GetCutOffInsert() const { return pCutOff; }
549 short GetCutOffCount() const { return nCutOff; }
551 virtual void GetDescription(
552 OUString& rStr, ScDocument* pDoc, bool bSplitRange = false, bool bWarning = true ) const;
554 void SetCutOffInsert( ScChangeActionIns* p, short n )
555 { pCutOff = p; nCutOff = n; } // only to use in the XML import
556 // this should be protected, but for the XML import it is public
557 // only to use in the XML import
558 // this should be protected, but for the XML import it is public
559 ScChangeActionDelMoveEntry* AddCutOffMove(
560 ScChangeActionMove* pMove, short nFrom, short nTo );
564 // --- ScChangeActionMove ---------------------------------------------------
566 class ScChangeActionMove : public ScChangeAction
568 friend class ScChangeTrack;
569 friend class ScChangeActionDel;
571 ScBigRange aFromRange;
572 ScChangeTrack* pTrack;
573 ScChangeActionCellListEntry* pFirstCell;
574 sal_uLong nStartLastCut; // for PasteCut undo
575 sal_uLong nEndLastCut;
577 ScChangeActionMove( const ScRange& rFromRange,
578 const ScRange& rToRange,
579 ScChangeTrack* pTrackP )
580 : ScChangeAction( SC_CAT_MOVE, rToRange ),
581 aFromRange( rFromRange ),
582 pTrack( pTrackP ),
583 pFirstCell( NULL ),
584 nStartLastCut(0),
585 nEndLastCut(0)
587 virtual ~ScChangeActionMove();
589 virtual void AddContent( ScChangeActionContent* );
590 virtual void DeleteCellEntries();
592 ScBigRange& GetFromRange() { return aFromRange; }
594 void SetStartLastCut( sal_uLong nVal ) { nStartLastCut = nVal; }
595 sal_uLong GetStartLastCut() const { return nStartLastCut; }
596 void SetEndLastCut( sal_uLong nVal ) { nEndLastCut = nVal; }
597 sal_uLong GetEndLastCut() const { return nEndLastCut; }
599 virtual void UpdateReference( const ScChangeTrack*,
600 UpdateRefMode, const ScBigRange&,
601 sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz );
603 virtual bool Reject(ScDocument* pDoc);
605 virtual const ScChangeTrack* GetChangeTrack() const { return pTrack; }
607 protected:
608 using ScChangeAction::GetRefString;
610 public:
611 ScChangeActionMove(const sal_uLong nActionNumber,
612 const ScChangeActionState eState,
613 const sal_uLong nRejectingNumber,
614 const ScBigRange& aToBigRange,
615 const OUString& aUser,
616 const DateTime& aDateTime,
617 const OUString &sComment,
618 const ScBigRange& aFromBigRange,
619 ScChangeTrack* pTrack); // only to use in the XML import
621 const ScChangeActionCellListEntry* GetFirstCellEntry() const
622 { return pFirstCell; } // only to use in the XML export
624 const ScBigRange& GetFromRange() const { return aFromRange; }
625 SC_DLLPUBLIC void GetDelta( sal_Int32& nDx, sal_Int32& nDy, sal_Int32& nDz ) const;
627 virtual void GetDescription(
628 OUString& rStr, ScDocument* pDoc, bool bSplitRange = false,
629 bool bWarning = true ) const;
631 virtual void GetRefString(
632 OUString& rStr, ScDocument* pDoc, bool bFlag3D = false ) const;
636 // --- ScChangeActionContent ------------------------------------------------
638 enum ScChangeActionContentCellType
640 SC_CACCT_NONE = 0,
641 SC_CACCT_NORMAL,
642 SC_CACCT_MATORG,
643 SC_CACCT_MATREF
646 class ScChangeActionContent : public ScChangeAction
648 friend class ScChangeTrack;
650 ScCellValue maOldCell;
651 ScCellValue maNewCell;
653 OUString maOldValue;
654 OUString maNewValue;
655 ScChangeActionContent* pNextContent; // at the same position
656 ScChangeActionContent* pPrevContent;
657 ScChangeActionContent* pNextInSlot; // in the same slot
658 ScChangeActionContent** ppPrevInSlot;
660 void InsertInSlot( ScChangeActionContent** pp )
662 if ( !ppPrevInSlot )
664 ppPrevInSlot = pp;
665 if ( ( pNextInSlot = *pp ) != NULL )
666 pNextInSlot->ppPrevInSlot = &pNextInSlot;
667 *pp = this;
671 void RemoveFromSlot()
673 if ( ppPrevInSlot )
675 if ( ( *ppPrevInSlot = pNextInSlot ) != NULL )
676 pNextInSlot->ppPrevInSlot = ppPrevInSlot;
677 ppPrevInSlot = NULL; // not inserted
681 ScChangeActionContent* GetNextInSlot() { return pNextInSlot; }
683 void ClearTrack();
685 static void GetStringOfCell(
686 OUString& rStr, const ScCellValue& rCell, const ScDocument* pDoc, const ScAddress& rPos );
688 static void GetStringOfCell(
689 OUString& rStr, const ScCellValue& rCell, const ScDocument* pDoc, sal_uLong nFormat );
691 static void SetValue( OUString& rStr, ScCellValue& rCell, const ScAddress& rPos,
692 const ScCellValue& rOrgCell, const ScDocument* pFromDoc,
693 ScDocument* pToDoc );
695 static void SetValue( OUString& rStr, ScCellValue& rCell, sal_uLong nFormat,
696 const ScCellValue& rOrgCell, const ScDocument* pFromDoc,
697 ScDocument* pToDoc );
699 static void SetCell( OUString& rStr, ScCellValue& rCell, sal_uLong nFormat, const ScDocument* pDoc );
701 static bool NeedsNumberFormat( const ScCellValue& rVal );
703 void SetValueString( OUString& rValue, ScCellValue& rCell, const OUString& rStr, ScDocument* pDoc );
705 void GetValueString( OUString& rStr, const OUString& rValue, const ScCellValue& rCell,
706 const ScDocument* pDoc ) const;
708 void GetFormulaString( OUString& rStr, const ScFormulaCell* pCell ) const;
710 virtual void AddContent( ScChangeActionContent* ) {}
711 virtual void DeleteCellEntries() {}
713 virtual void UpdateReference( const ScChangeTrack*,
714 UpdateRefMode, const ScBigRange&,
715 sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz );
717 virtual bool Reject(ScDocument* pDoc);
719 virtual const ScChangeTrack* GetChangeTrack() const { return 0; }
721 // pRejectActions!=NULL: reject actions get
722 // stacked, no SetNewValue, no Append
723 bool Select( ScDocument*, ScChangeTrack*,
724 bool bOldest, ::std::stack<ScChangeActionContent*>* pRejectActions );
726 void PutValueToDoc(
727 const ScCellValue& rCell, const OUString& rValue, ScDocument* pDoc, SCsCOL nDx, SCsROW nDy ) const;
729 protected:
730 using ScChangeAction::GetRefString;
732 public:
734 DECL_FIXEDMEMPOOL_NEWDEL( ScChangeActionContent )
736 ScChangeActionContent( const ScRange& rRange );
738 ScChangeActionContent(
739 const sal_uLong nActionNumber, const ScChangeActionState eState,
740 const sal_uLong nRejectingNumber, const ScBigRange& aBigRange,
741 const OUString& aUser, const DateTime& aDateTime,
742 const OUString &sComment, const ScCellValue& rOldCell,
743 ScDocument* pDoc, const OUString& sOldValue ); // to use for XML Import
745 ScChangeActionContent(
746 const sal_uLong nActionNumber, const ScCellValue& rNewCell,
747 const ScBigRange& aBigRange, ScDocument* pDoc,
748 const OUString& sNewValue ); // to use for XML Import of Generated Actions
750 virtual ~ScChangeActionContent();
752 ScChangeActionContent* GetNextContent() const { return pNextContent; }
753 ScChangeActionContent* GetPrevContent() const { return pPrevContent; }
754 ScChangeActionContent* GetTopContent() const;
755 bool IsTopContent() const { return pNextContent == NULL; }
757 virtual ScChangeActionLinkEntry* GetDeletedIn() const;
758 virtual ScChangeActionLinkEntry** GetDeletedInAddress();
760 void PutOldValueToDoc( ScDocument*,
761 SCsCOL nDx, SCsROW nDy ) const;
762 void PutNewValueToDoc( ScDocument*,
763 SCsCOL nDx, SCsROW nDy ) const;
765 void SetOldValue( const ScCellValue& rCell, const ScDocument* pFromDoc, ScDocument* pToDoc, sal_uLong nFormat );
767 void SetOldValue( const ScCellValue& rCell, const ScDocument* pFromDoc, ScDocument* pToDoc );
769 void SetNewValue( const ScCellValue& rCell, ScDocument* pDoc );
771 // Used in import filter AppendContentOnTheFly,
772 void SetOldNewCells(
773 const ScCellValue& rOldCell, sal_uLong nOldFormat,
774 const ScCellValue& rNewCell, sal_uLong nNewFormat, ScDocument* pDoc );
776 // Use this only in the XML import,
777 // takes ownership of cell.
778 void SetNewCell(
779 const ScCellValue& rCell, ScDocument* pDoc, const OUString& rFormatted );
781 // These functions should be protected but for
782 // the XML import they are public.
783 void SetNextContent( ScChangeActionContent* p )
784 { pNextContent = p; }
785 void SetPrevContent( ScChangeActionContent* p )
786 { pPrevContent = p; }
788 // don't use:
789 // assigns string / creates forumula cell
790 void SetOldValue( const OUString& rOld, ScDocument* pDoc );
792 void GetOldString( OUString& rStr, const ScDocument* pDoc ) const;
793 void GetNewString( OUString& rStr, const ScDocument* pDoc ) const;
794 SC_DLLPUBLIC const ScCellValue& GetOldCell() const;
795 SC_DLLPUBLIC const ScCellValue& GetNewCell() const;
796 virtual void GetDescription(
797 OUString& rStr, ScDocument* pDoc, bool bSplitRange = false, bool bWarning = true ) const;
799 virtual void GetRefString(
800 OUString& rStr, ScDocument* pDoc, bool bFlag3D = false ) const;
802 static ScChangeActionContentCellType GetContentCellType( const ScCellValue& rCell );
803 static ScChangeActionContentCellType GetContentCellType( const ScRefCellValue& rIter );
805 // NewCell
806 bool IsMatrixOrigin() const;
807 // OldCell
808 bool IsOldMatrixReference() const;
812 // --- ScChangeActionReject -------------------------------------------------
814 class ScChangeActionReject : public ScChangeAction
816 friend class ScChangeTrack;
817 friend class ScChangeActionContent;
819 ScChangeActionReject( sal_uLong nReject ) :
820 ScChangeAction( SC_CAT_REJECT, ScRange() )
822 SetRejectAction( nReject );
823 SetState( SC_CAS_ACCEPTED );
826 virtual void AddContent( ScChangeActionContent* ) {}
827 virtual void DeleteCellEntries() {}
829 virtual bool Reject(ScDocument* pDoc);
831 virtual const ScChangeTrack* GetChangeTrack() const { return 0; }
833 public:
834 ScChangeActionReject(const sal_uLong nActionNumber,
835 const ScChangeActionState eState,
836 const sal_uLong nRejectingNumber,
837 const ScBigRange& aBigRange,
838 const OUString& aUser,
839 const DateTime& aDateTime,
840 const OUString &sComment); // only to use in the XML import
844 // --- ScChangeTrack --------------------------------------------------------
846 enum ScChangeTrackMsgType
848 SC_CTM_NONE,
849 SC_CTM_APPEND, // Actions appended
850 SC_CTM_REMOVE, // Actions removed
851 SC_CTM_CHANGE, // Actions changed
852 SC_CTM_PARENT // became a parent (and wasn't before)
855 struct ScChangeTrackMsgInfo
857 DECL_FIXEDMEMPOOL_NEWDEL( ScChangeTrackMsgInfo )
859 ScChangeTrackMsgType eMsgType;
860 sal_uLong nStartAction;
861 sal_uLong nEndAction;
864 // MsgQueue for notification via ModifiedLink
865 typedef std::deque<ScChangeTrackMsgInfo*> ScChangeTrackMsgQueue;
866 typedef std::stack<ScChangeTrackMsgInfo*> ScChangeTrackMsgStack;
867 typedef std::map<sal_uLong, ScChangeAction*> ScChangeActionMap;
869 enum ScChangeTrackMergeState
871 SC_CTMS_NONE,
872 SC_CTMS_PREPARE,
873 SC_CTMS_OWN,
874 SC_CTMS_UNDO,
875 SC_CTMS_OTHER
878 // Internally generated actions start at this value (nearly all bits set)
879 // and are decremented, to keep values in a table separated from "normal" actions.
880 #define SC_CHGTRACK_GENERATED_START ((sal_uInt32) 0xfffffff0)
882 class ScChangeTrack : public utl::ConfigurationListener
884 friend void ScChangeAction::RejectRestoreContents( ScChangeTrack*, SCsCOL, SCsROW );
885 friend bool ScChangeActionDel::Reject( ScDocument* pDoc );
886 friend void ScChangeActionDel::DeleteCellEntries();
887 friend void ScChangeActionMove::DeleteCellEntries();
888 friend bool ScChangeActionMove::Reject( ScDocument* pDoc );
890 static const SCROW nContentRowsPerSlot;
891 static const SCSIZE nContentSlots;
893 com::sun::star::uno::Sequence< sal_Int8 > aProtectPass;
894 ScChangeActionMap aMap;
895 ScChangeActionMap aGeneratedMap;
896 ScChangeActionMap aPasteCutMap;
897 ScChangeTrackMsgQueue aMsgQueue;
898 ScChangeTrackMsgStack aMsgStackTmp;
899 ScChangeTrackMsgStack aMsgStackFinal;
900 std::set<OUString> maUserCollection;
901 OUString maUser;
902 Link aModifiedLink;
903 ScRange aInDeleteRange;
904 DateTime aFixDateTime;
905 ScChangeAction* pFirst;
906 ScChangeAction* pLast;
907 ScChangeActionContent* pFirstGeneratedDelContent;
908 ScChangeActionContent** ppContentSlots;
909 ScChangeActionMove* pLastCutMove;
910 ScChangeActionLinkEntry* pLinkInsertCol;
911 ScChangeActionLinkEntry* pLinkInsertRow;
912 ScChangeActionLinkEntry* pLinkInsertTab;
913 ScChangeActionLinkEntry* pLinkMove;
914 ScChangeTrackMsgInfo* pBlockModifyMsg;
915 ScDocument* pDoc;
916 sal_uLong nActionMax;
917 sal_uLong nGeneratedMin;
918 sal_uLong nMarkLastSaved;
919 sal_uLong nStartLastCut;
920 sal_uLong nEndLastCut;
921 sal_uLong nLastMerge;
922 ScChangeTrackMergeState eMergeState;
923 bool bLoadSave:1;
924 bool bInDelete:1;
925 bool bInDeleteUndo:1;
926 bool bInDeleteTop:1;
927 bool bInPasteCut:1;
928 bool bUseFixDateTime:1;
929 bool bTimeNanoSeconds:1;
931 // not implemented, prevent usage
932 ScChangeTrack( const ScChangeTrack& );
933 ScChangeTrack& operator=( const ScChangeTrack& );
935 static SCROW InitContentRowsPerSlot();
937 // true if one is MM_FORMULA and the other is
938 // not, or if both are and range differs
939 static bool IsMatrixFormulaRangeDifferent(
940 const ScCellValue& rOldCell, const ScCellValue& rNewCell );
942 void Init();
943 void DtorClear();
944 void SetLoadSave( bool bVal ) { bLoadSave = bVal; }
945 void SetInDeleteRange( const ScRange& rRange )
946 { aInDeleteRange = rRange; }
947 void SetInDelete( bool bVal )
948 { bInDelete = bVal; }
949 void SetInDeleteTop( bool bVal )
950 { bInDeleteTop = bVal; }
951 void SetInDeleteUndo( bool bVal )
952 { bInDeleteUndo = bVal; }
953 void SetInPasteCut( bool bVal )
954 { bInPasteCut = bVal; }
955 void SetMergeState( ScChangeTrackMergeState eState )
956 { eMergeState = eState; }
957 ScChangeTrackMergeState GetMergeState() const { return eMergeState; }
958 void SetLastMerge( sal_uLong nVal ) { nLastMerge = nVal; }
959 sal_uLong GetLastMerge() const { return nLastMerge; }
961 void SetLastCutMoveRange( const ScRange&, ScDocument* );
963 // create block of ModifyMsg
964 void StartBlockModify( ScChangeTrackMsgType,
965 sal_uLong nStartAction );
966 void EndBlockModify( sal_uLong nEndAction );
968 void AddDependentWithNotify( ScChangeAction* pParent,
969 ScChangeAction* pDependent );
971 void Dependencies( ScChangeAction* );
972 void UpdateReference( ScChangeAction*, bool bUndo );
973 void UpdateReference( ScChangeAction** ppFirstAction, ScChangeAction* pAct, bool bUndo );
974 void Append( ScChangeAction* pAppend, sal_uLong nAction );
975 SC_DLLPUBLIC void AppendDeleteRange( const ScRange&,
976 ScDocument* pRefDoc, SCsTAB nDz,
977 sal_uLong nRejectingInsert );
978 void AppendOneDeleteRange( const ScRange& rOrgRange,
979 ScDocument* pRefDoc,
980 SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
981 sal_uLong nRejectingInsert );
982 void LookUpContents( const ScRange& rOrgRange,
983 ScDocument* pRefDoc,
984 SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
985 void Remove( ScChangeAction* );
986 void MasterLinks( ScChangeAction* );
988 // Content on top an Position
989 ScChangeActionContent* SearchContentAt( const ScBigAddress&,
990 ScChangeAction* pButNotThis ) const;
991 void DeleteGeneratedDelContent(
992 ScChangeActionContent* );
994 ScChangeActionContent* GenerateDelContent(
995 const ScAddress& rPos, const ScCellValue& rCell, const ScDocument* pFromDoc );
997 void DeleteCellEntries(
998 ScChangeActionCellListEntry*&,
999 ScChangeAction* pDeletor );
1001 // Reject action and all dependent actions,
1002 // Table stems from previous GetDependents,
1003 // only needed for Insert and Move (MasterType),
1004 // is NULL otherwise.
1005 // bRecursion == called from reject with table
1006 bool Reject( ScChangeAction*, ScChangeActionMap*, bool bRecursion );
1008 void ClearMsgQueue();
1009 virtual void ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 );
1011 public:
1013 static SCSIZE ComputeContentSlot( sal_Int32 nRow )
1015 if ( nRow < 0 || nRow > MAXROW )
1016 return nContentSlots - 1;
1017 return static_cast< SCSIZE >( nRow / nContentRowsPerSlot );
1020 SC_DLLPUBLIC ScChangeTrack( ScDocument* );
1021 ScChangeTrack(ScDocument* pDocP, const std::set<OUString>& aTempUserCollection); // only to use in the XML import
1022 SC_DLLPUBLIC virtual ~ScChangeTrack();
1023 void Clear();
1025 ScChangeActionContent* GetFirstGenerated() const { return pFirstGeneratedDelContent; }
1026 ScChangeAction* GetFirst() const { return pFirst; }
1027 ScChangeAction* GetLast() const { return pLast; }
1028 sal_uLong GetActionMax() const { return nActionMax; }
1029 bool IsGenerated( sal_uLong nAction ) const
1030 { return nAction >= nGeneratedMin; }
1031 ScChangeAction* GetAction( sal_uLong nAction ) const
1033 ScChangeActionMap::const_iterator it = aMap.find( nAction );
1034 if( it != aMap.end() )
1035 return it->second;
1036 else
1037 return NULL;
1039 ScChangeAction* GetGenerated( sal_uLong nGenerated ) const
1041 ScChangeActionMap::const_iterator it = aGeneratedMap.find( nGenerated );
1042 if( it != aGeneratedMap.end() )
1043 return it->second;
1044 else
1045 return NULL;
1047 ScChangeAction* GetActionOrGenerated( sal_uLong nAction ) const
1049 return IsGenerated( nAction ) ?
1050 GetGenerated( nAction ) :
1051 GetAction( nAction );
1053 sal_uLong GetLastSavedActionNumber() const
1054 { return nMarkLastSaved; }
1055 void SetLastSavedActionNumber(sal_uLong nNew)
1056 { nMarkLastSaved = nNew; }
1057 ScChangeAction* GetLastSaved() const
1059 ScChangeActionMap::const_iterator it = aMap.find( nMarkLastSaved );
1060 if( it != aMap.end() )
1061 return it->second;
1062 else
1063 return NULL;
1065 ScChangeActionContent** GetContentSlots() const { return ppContentSlots; }
1067 bool IsLoadSave() const { return bLoadSave; }
1068 const ScRange& GetInDeleteRange() const
1069 { return aInDeleteRange; }
1070 bool IsInDelete() const { return bInDelete; }
1071 bool IsInDeleteTop() const { return bInDeleteTop; }
1072 bool IsInDeleteUndo() const { return bInDeleteUndo; }
1073 bool IsInPasteCut() const { return bInPasteCut; }
1074 SC_DLLPUBLIC void SetUser( const OUString& rUser );
1075 SC_DLLPUBLIC const OUString& GetUser() const;
1076 SC_DLLPUBLIC const std::set<OUString>& GetUserCollection() const;
1077 ScDocument* GetDocument() const { return pDoc; }
1078 // for import filter
1079 const DateTime& GetFixDateTime() const { return aFixDateTime; }
1081 // set this if the date/time set with
1082 // SetFixDateTime...() shall be applied to
1083 // appended actions
1084 void SetUseFixDateTime( bool bVal )
1085 { bUseFixDateTime = bVal; }
1086 // for MergeDocument, apply original date/time as UTC
1087 void SetFixDateTimeUTC( const DateTime& rDT )
1088 { aFixDateTime = rDT; }
1089 // for import filter, apply original date/time as local time
1090 void SetFixDateTimeLocal( const DateTime& rDT )
1091 { aFixDateTime = rDT; aFixDateTime.ConvertToUTC(); }
1093 void Append( ScChangeAction* );
1095 // pRefDoc may be NULL => no lookup of contents
1096 // => no generation of deleted contents
1097 SC_DLLPUBLIC void AppendDeleteRange( const ScRange&,
1098 ScDocument* pRefDoc,
1099 sal_uLong& nStartAction, sal_uLong& nEndAction,
1100 SCsTAB nDz = 0 );
1101 // nDz: multi TabDel, LookUpContent must be searched
1102 // with an offset of -nDz
1104 // after new value was set in the document,
1105 // old value from RefDoc/UndoDoc
1106 void AppendContent( const ScAddress& rPos,
1107 ScDocument* pRefDoc );
1108 // after new values were set in the document,
1109 // old values from RefDoc/UndoDoc
1110 void AppendContentRange( const ScRange& rRange,
1111 ScDocument* pRefDoc,
1112 sal_uLong& nStartAction, sal_uLong& nEndAction,
1113 ScChangeActionClipMode eMode = SC_CACM_NONE );
1114 // after new value was set in the document,
1115 // old value from pOldCell, nOldFormat,
1116 // RefDoc==NULL => Doc
1117 void AppendContent( const ScAddress& rPos, const ScCellValue& rOldCell,
1118 sal_uLong nOldFormat, ScDocument* pRefDoc = NULL );
1119 // after new value was set in the document,
1120 // old value from pOldCell, format from Doc
1121 void AppendContent( const ScAddress& rPos, const ScCellValue& rOldCell );
1122 // after new values were set in the document,
1123 // old values from RefDoc/UndoDoc.
1124 // All contents with a cell in RefDoc
1125 void AppendContentsIfInRefDoc( ScDocument* pRefDoc,
1126 sal_uLong& nStartAction, sal_uLong& nEndAction );
1128 // Meant for import filter, creates and inserts
1129 // an unconditional content action of the two
1130 // cells without querying the document, not
1131 // even for number formats (though the number
1132 // formatter of the document may be used).
1133 // The action is returned and may be used to
1134 // set user name, description, date/time et al.
1135 // Takes ownership of the cells!
1136 SC_DLLPUBLIC ScChangeActionContent* AppendContentOnTheFly(
1137 const ScAddress& rPos, const ScCellValue& rOldCell, const ScCellValue& rNewCell,
1138 sal_uLong nOldFormat = 0, sal_uLong nNewFormat = 0 );
1140 // Only use the following two if there is no different solution! (Assign
1141 // string for NewValue or creation of a formula respectively)
1143 SC_DLLPUBLIC void AppendInsert( const ScRange& );
1145 // pRefDoc may be NULL => no lookup of contents
1146 // => no generation of deleted contents
1147 SC_DLLPUBLIC void AppendMove( const ScRange& rFromRange, const ScRange& rToRange,
1148 ScDocument* pRefDoc );
1150 // Cut to Clipboard
1151 void ResetLastCut()
1153 nStartLastCut = nEndLastCut = 0;
1154 if ( pLastCutMove )
1156 delete pLastCutMove;
1157 pLastCutMove = NULL;
1160 bool HasLastCut() const
1162 return nEndLastCut > 0 &&
1163 nStartLastCut <= nEndLastCut &&
1164 pLastCutMove;
1167 SC_DLLPUBLIC void Undo( sal_uLong nStartAction, sal_uLong nEndAction, bool bMerge = false );
1169 // adjust references for MergeDocument
1170 //! may only be used in a temporary opened document.
1171 //! the Track (?) is unclean afterwards
1172 void MergePrepare( ScChangeAction* pFirstMerge, bool bShared = false );
1173 void MergeOwn( ScChangeAction* pAct, sal_uLong nFirstMerge, bool bShared = false );
1174 static bool MergeIgnore( const ScChangeAction&, sal_uLong nFirstMerge );
1176 // This comment was already really strange in German.
1177 // Tried to structure it a little. Hope no information got lost...
1179 // Insert dependents into table.
1180 // ScChangeAction is
1181 // - "Insert": really dependents
1182 // - "Move": dependent contents in FromRange /
1183 // deleted contents in ToRange
1184 // OR inserts in FromRange or ToRange
1185 // - "Delete": a list of deleted (what?)
1186 // OR for content, different contents at the same position
1187 // OR MatrixReferences belonging to MatrixOrigin
1189 // With bListMasterDelete (==TRUE ?) all Deletes of a row belonging
1190 // to a MasterDelete are listed (possibly it is
1191 // "all Deletes belonging...are listed in a row?)
1193 // With bAllFlat (==TRUE ?) all dependents of dependents
1194 // will be inserted flatly.
1196 SC_DLLPUBLIC void GetDependents(
1197 ScChangeAction*, ScChangeActionMap&, bool bListMasterDelete = false, bool bAllFlat = false ) const;
1199 // Reject visible action (and dependents)
1200 bool Reject( ScChangeAction*, bool bShared = false );
1202 // Accept visible action (and dependents)
1203 SC_DLLPUBLIC bool Accept( ScChangeAction* );
1205 void AcceptAll(); // all Virgins
1206 bool RejectAll(); // all Virgins
1208 // Selects a content of several contents at the same
1209 // position and accepts this one and
1210 // the older ones, rejects the more recent ones.
1211 // If bOldest==TRUE then the first OldValue
1212 // of a Virgin-Content-List will be restored.
1213 bool SelectContent( ScChangeAction*, bool bOldest = false );
1215 // If ModifiedLink is set, changes go to
1216 // ScChangeTrackMsgQueue
1217 void SetModifiedLink( const Link& r )
1218 { aModifiedLink = r; ClearMsgQueue(); }
1219 const Link& GetModifiedLink() const { return aModifiedLink; }
1220 ScChangeTrackMsgQueue& GetMsgQueue() { return aMsgQueue; }
1222 void NotifyModified( ScChangeTrackMsgType eMsgType,
1223 sal_uLong nStartAction, sal_uLong nEndAction );
1225 sal_uLong AddLoadedGenerated(
1226 const ScCellValue& rNewCell, const ScBigRange& aBigRange, const OUString& sNewValue ); // only to use in the XML import
1227 void AppendLoaded( ScChangeAction* pAppend ); // this is only for the XML import public, it should be protected
1228 void SetActionMax(sal_uLong nTempActionMax)
1229 { nActionMax = nTempActionMax; } // only to use in the XML import
1231 void SetProtection( const com::sun::star::uno::Sequence< sal_Int8 >& rPass )
1232 { aProtectPass = rPass; }
1233 com::sun::star::uno::Sequence< sal_Int8 > GetProtection() const
1234 { return aProtectPass; }
1235 bool IsProtected() const { return aProtectPass.getLength() != 0; }
1237 // If time stamps of actions of this
1238 // ChangeTrack and a second one are to be
1239 // compared including nanoseconds.
1240 void SetTimeNanoSeconds( bool bVal ) { bTimeNanoSeconds = bVal; }
1241 bool IsTimeNanoSeconds() const { return bTimeNanoSeconds; }
1243 void AppendCloned( ScChangeAction* pAppend );
1244 SC_DLLPUBLIC ScChangeTrack* Clone( ScDocument* pDocument ) const;
1245 void MergeActionState( ScChangeAction* pAct, const ScChangeAction* pOtherAct );
1249 #endif
1252 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */