Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / inc / chgtrack.hxx
blob5fdb50b8109ce63b0e4bb5128092e503721d733e
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
55 enum ScChangeActionState
57 SC_CAS_VIRGIN,
58 SC_CAS_ACCEPTED,
59 SC_CAS_REJECTED
62 enum ScChangeActionClipMode
64 SC_CACM_NONE,
65 SC_CACM_CUT,
66 SC_CACM_COPY,
67 SC_CACM_PASTE
70 // ScChangeActionLinkEntry
71 // Inserts itself as the head of a chain (better: linked list?), or before a LinkEntry
72 // on delete: automatically remove of what is linked (German original was strange...)
73 // ppPrev == &previous->pNext oder address of pointer to head of linked list,
74 // *ppPrev == this
76 class ScChangeAction;
78 class ScChangeActionLinkEntry
80 // not implemented, prevent usage
81 ScChangeActionLinkEntry( const ScChangeActionLinkEntry& );
82 ScChangeActionLinkEntry& operator=( const ScChangeActionLinkEntry& );
84 protected:
86 ScChangeActionLinkEntry* pNext;
87 ScChangeActionLinkEntry** ppPrev;
88 ScChangeAction* pAction;
89 ScChangeActionLinkEntry* pLink;
91 public:
93 DECL_FIXEDMEMPOOL_NEWDEL( ScChangeActionLinkEntry )
95 ScChangeActionLinkEntry(
96 ScChangeActionLinkEntry** ppPrevP,
97 ScChangeAction* pActionP )
98 : pNext( *ppPrevP ),
99 ppPrev( ppPrevP ),
100 pAction( pActionP ),
101 pLink( NULL )
103 if ( pNext )
104 pNext->ppPrev = &pNext;
105 *ppPrevP = this;
108 virtual ~ScChangeActionLinkEntry()
110 ScChangeActionLinkEntry* p = pLink;
111 UnLink();
112 Remove();
113 if ( p )
114 delete p;
117 void SetLink( ScChangeActionLinkEntry* pLinkP )
119 UnLink();
120 if ( pLinkP )
122 pLink = pLinkP;
123 pLinkP->pLink = this;
127 void UnLink()
129 if ( pLink )
131 pLink->pLink = NULL;
132 pLink = NULL;
136 void Remove()
138 if ( ppPrev )
140 if ( ( *ppPrev = pNext ) != NULL )
141 pNext->ppPrev = ppPrev;
142 ppPrev = NULL; // not inserted
146 void Insert( ScChangeActionLinkEntry** ppPrevP )
148 if ( !ppPrev )
150 ppPrev = ppPrevP;
151 if ( (pNext = *ppPrevP) )
152 pNext->ppPrev = &pNext;
153 *ppPrevP = this;
157 const ScChangeActionLinkEntry* GetLink() const { return pLink; }
158 ScChangeActionLinkEntry* GetLink() { return pLink; }
159 const ScChangeActionLinkEntry* GetNext() const { return pNext; }
160 ScChangeActionLinkEntry* GetNext() { return pNext; }
161 const ScChangeAction* GetAction() const { return pAction; }
162 ScChangeAction* GetAction() { return pAction; }
165 // ScChangeActionCellListEntry
166 // this is only for the XML Export in the hxx
167 class ScChangeActionContent;
169 class ScChangeActionCellListEntry
171 friend class ScChangeAction;
172 friend class ScChangeActionDel;
173 friend class ScChangeActionMove;
174 friend class ScChangeTrack;
176 ScChangeActionCellListEntry* pNext;
177 ScChangeActionContent* pContent;
179 ScChangeActionCellListEntry(
180 ScChangeActionContent* pContentP,
181 ScChangeActionCellListEntry* pNextP )
182 : pNext( pNextP ),
183 pContent( pContentP )
186 public:
187 const ScChangeActionCellListEntry* GetNext() const { return pNext; } // this is only for the XML Export public
188 const ScChangeActionContent* GetContent() const { return pContent; } // this is only for the XML Export public
190 DECL_FIXEDMEMPOOL_NEWDEL( ScChangeActionCellListEntry )
193 // ScChangeAction
194 class ScChangeTrack;
195 class ScChangeActionIns;
196 class ScChangeActionDel;
197 class ScChangeActionContent;
199 class ScChangeAction
201 friend class ScChangeTrack;
202 friend class ScChangeActionIns;
203 friend class ScChangeActionDel;
204 friend class ScChangeActionMove;
205 friend class ScChangeActionContent;
207 // not implemented, prevent usage
208 ScChangeAction( const ScChangeAction& );
209 ScChangeAction& operator=( const ScChangeAction& );
211 protected:
213 ScBigRange aBigRange; // Ins/Del/MoveTo/ContentPos
214 DateTime aDateTime; //! UTC
215 OUString aUser; // who?
216 OUString aComment; // user comment
217 ScChangeAction* pNext; // next in linked list
218 ScChangeAction* pPrev; // previous in linked list
219 ScChangeActionLinkEntry* pLinkAny; // arbitrary links
220 ScChangeActionLinkEntry* pLinkDeletedIn; // access to insert areas which were
221 // deleted or moved or rejected
222 ScChangeActionLinkEntry* pLinkDeleted; // links to deleted
223 ScChangeActionLinkEntry* pLinkDependent; // links to dependent
224 sal_uLong nAction;
225 sal_uLong nRejectAction;
226 ScChangeActionType eType;
227 ScChangeActionState eState;
229 ScChangeAction( ScChangeActionType, const ScRange& );
231 // only to be used in the XML import
232 ScChangeAction( ScChangeActionType,
233 const ScBigRange&,
234 const sal_uLong nAction,
235 const sal_uLong nRejectAction,
236 const ScChangeActionState eState,
237 const DateTime& aDateTime,
238 const OUString& aUser,
239 const OUString& aComment );
241 // only to be used in the XML import
242 ScChangeAction( ScChangeActionType, const ScBigRange&, const sal_uLong nAction);
244 virtual ~ScChangeAction();
246 OUString GetRefString(
247 const ScBigRange& rRange, ScDocument* pDoc, bool bFlag3D = false) const;
249 void SetActionNumber( sal_uLong n ) { nAction = n; }
250 void SetRejectAction( sal_uLong n ) { nRejectAction = n; }
251 void SetUser( const OUString& r );
252 void SetType( ScChangeActionType e ) { eType = e; }
253 void SetState( ScChangeActionState e ) { eState = e; }
254 void SetRejected();
256 ScBigRange& GetBigRange() { return aBigRange; }
258 ScChangeActionLinkEntry* AddLink(
259 ScChangeAction* p, ScChangeActionLinkEntry* pL )
261 ScChangeActionLinkEntry* pLnk =
262 new ScChangeActionLinkEntry(
263 &pLinkAny, p );
264 pLnk->SetLink( pL );
265 return pLnk;
268 void RemoveAllAnyLinks();
270 virtual ScChangeActionLinkEntry* GetDeletedIn() const
271 { return pLinkDeletedIn; }
272 virtual ScChangeActionLinkEntry** GetDeletedInAddress()
273 { return &pLinkDeletedIn; }
274 ScChangeActionLinkEntry* AddDeletedIn( ScChangeAction* p )
276 return new ScChangeActionLinkEntry(
277 GetDeletedInAddress(), p );
280 bool RemoveDeletedIn( const ScChangeAction* );
281 void SetDeletedIn( ScChangeAction* );
283 ScChangeActionLinkEntry* AddDeleted( ScChangeAction* p )
285 return new ScChangeActionLinkEntry(&pLinkDeleted, p);
288 void RemoveAllDeleted();
290 ScChangeActionLinkEntry* AddDependent( ScChangeAction* p )
292 return new ScChangeActionLinkEntry(&pLinkDependent, p);
295 void RemoveAllDependent();
297 void RemoveAllLinks();
299 virtual void AddContent( ScChangeActionContent* ) = 0;
300 virtual void DeleteCellEntries() = 0;
302 virtual void UpdateReference( const ScChangeTrack*,
303 UpdateRefMode, const ScBigRange&,
304 sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz );
306 void Accept();
307 virtual bool Reject(ScDocument* pDoc) = 0;
308 void RejectRestoreContents( ScChangeTrack*, SCsCOL nDx, SCsROW nDy );
310 // used in Reject() instead of IsRejectable()
311 bool IsInternalRejectable() const;
313 // Derived classes that hold a pointer to the
314 // ChangeTrack must return that. Otherwise NULL.
315 virtual const ScChangeTrack* GetChangeTrack() const = 0;
317 public:
318 bool IsInsertType() const;
319 bool IsDeleteType() const;
320 bool IsVirgin() const;
321 SC_DLLPUBLIC bool IsAccepted() const;
322 bool IsRejected() const;
324 // Action rejects another Action
325 bool IsRejecting() const;
327 // if action is visible in the document
328 bool IsVisible() const;
330 // if action if touchable
331 bool IsTouchable() const;
333 // if action is an entry in dialog root
334 bool IsDialogRoot() const;
336 // if an entry in a dialog shall be a drop down entry
337 bool IsDialogParent() const;
339 // if action is a delete with subdeletes (aufgeklappt = open ?)
340 bool IsMasterDelete() const;
342 // if action is acceptable/selectable/rejectable
343 bool IsClickable() const;
345 // if action is rejectable
346 bool IsRejectable() const;
348 const ScBigRange& GetBigRange() const { return aBigRange; }
349 SC_DLLPUBLIC DateTime GetDateTime() const; // local time
350 const DateTime& GetDateTimeUTC() const // UTC time
351 { return aDateTime; }
352 ScChangeActionType GetType() const { return eType; }
353 ScChangeActionState GetState() const { return eState; }
354 sal_uLong GetActionNumber() const { return nAction; }
355 sal_uLong GetRejectAction() const { return nRejectAction; }
357 ScChangeAction* GetNext() const { return pNext; }
358 ScChangeAction* GetPrev() const { return pPrev; }
360 bool IsDeletedIn() const;
361 bool IsDeletedIn( const ScChangeAction* ) const;
362 bool IsDeletedInDelType( ScChangeActionType ) const;
363 void RemoveAllDeletedIn();
365 const ScChangeActionLinkEntry* GetFirstDeletedEntry() const
366 { return pLinkDeleted; }
367 const ScChangeActionLinkEntry* GetFirstDependentEntry() const
368 { return pLinkDependent; }
369 bool HasDependent() const;
370 bool HasDeleted() const;
371 // description will be appended to string
372 // with bSplitRange only one column/row will be considered for delete
373 // (for a listing of entries)
374 virtual void GetDescription(
375 OUString& rStr, ScDocument* pDoc,
376 bool bSplitRange = false, bool bWarning = true ) const;
378 virtual void GetRefString(
379 OUString& rStr, ScDocument* pDoc, bool bFlag3D = false ) const;
381 // for DocumentMerge set old date of the other
382 // action, fetched by GetDateTimeUTC
383 void SetDateTimeUTC( const DateTime& rDT )
384 { aDateTime = rDT; }
386 SC_DLLPUBLIC const OUString& GetUser() const;
387 const OUString& GetComment() const;
389 // set user comment
390 void SetComment( const OUString& rStr );
392 // only to be used in the XML import
393 void SetDeletedInThis( sal_uLong nActionNumber,
394 const ScChangeTrack* pTrack );
395 // only to be used in the XML import
396 void AddDependent( sal_uLong nActionNumber,
397 const ScChangeTrack* pTrack );
400 // ScChangeActionIns
401 class ScChangeActionIns : public ScChangeAction
403 friend class ScChangeTrack;
405 ScChangeActionIns( const ScRange& rRange );
406 virtual ~ScChangeActionIns();
408 virtual void AddContent( ScChangeActionContent* ) {}
409 virtual void DeleteCellEntries() {}
411 virtual bool Reject(ScDocument* pDoc);
413 virtual const ScChangeTrack* GetChangeTrack() const { return 0; }
415 public:
416 ScChangeActionIns(const sal_uLong nActionNumber,
417 const ScChangeActionState eState,
418 const sal_uLong nRejectingNumber,
419 const ScBigRange& aBigRange,
420 const OUString& aUser,
421 const DateTime& aDateTime,
422 const OUString &sComment,
423 const ScChangeActionType eType); // only to use in the XML import
425 virtual void GetDescription(
426 OUString& rStr, ScDocument* pDoc, bool bSplitRange = false, bool bWarning = true) const;
429 // ScChangeActionDel
430 class ScChangeActionMove;
432 class ScChangeActionDelMoveEntry : public ScChangeActionLinkEntry
434 friend class ScChangeActionDel;
435 friend class ScChangeTrack;
437 short nCutOffFrom;
438 short nCutOffTo;
440 ScChangeActionDelMoveEntry(
441 ScChangeActionDelMoveEntry** ppPrevP,
442 ScChangeActionMove* pMove,
443 short nFrom, short nTo )
444 : ScChangeActionLinkEntry(
445 (ScChangeActionLinkEntry**)
446 ppPrevP,
447 (ScChangeAction*) pMove ),
448 nCutOffFrom( nFrom ),
449 nCutOffTo( nTo )
452 ScChangeActionDelMoveEntry* GetNext()
454 return (ScChangeActionDelMoveEntry*)
455 ScChangeActionLinkEntry::GetNext();
457 ScChangeActionMove* GetMove()
459 return (ScChangeActionMove*)
460 ScChangeActionLinkEntry::GetAction();
463 public:
464 const ScChangeActionDelMoveEntry* GetNext() const
466 return (const ScChangeActionDelMoveEntry*)
467 ScChangeActionLinkEntry::GetNext();
469 const ScChangeActionMove* GetMove() const
471 return (const ScChangeActionMove*)
472 ScChangeActionLinkEntry::GetAction();
474 short GetCutOffFrom() const { return nCutOffFrom; }
475 short GetCutOffTo() const { return nCutOffTo; }
478 class ScChangeActionDel : public ScChangeAction
480 friend class ScChangeTrack;
481 friend void ScChangeAction::Accept();
483 ScChangeTrack* pTrack;
484 ScChangeActionCellListEntry* pFirstCell;
485 ScChangeActionIns* pCutOff; // cut insert
486 short nCutOff; // +: start -: end
487 ScChangeActionDelMoveEntry* pLinkMove;
488 SCsCOL nDx;
489 SCsROW nDy;
491 ScChangeActionDel( const ScRange& rRange, SCsCOL nDx, SCsROW nDy, ScChangeTrack* );
492 virtual ~ScChangeActionDel();
494 ScChangeActionIns* GetCutOffInsert() { return pCutOff; }
496 virtual void AddContent( ScChangeActionContent* );
497 virtual void DeleteCellEntries();
499 void UndoCutOffMoves();
500 void UndoCutOffInsert();
502 virtual void UpdateReference( const ScChangeTrack*,
503 UpdateRefMode, const ScBigRange&,
504 sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz );
506 virtual bool Reject(ScDocument* pDoc);
508 virtual const ScChangeTrack* GetChangeTrack() const { return pTrack; }
510 public:
511 ScChangeActionDel(
512 const sal_uLong nActionNumber, const ScChangeActionState eState,
513 const sal_uLong nRejectingNumber, const ScBigRange& aBigRange,
514 const OUString& aUser, const DateTime& aDateTime,
515 const OUString &sComment, const ScChangeActionType eType,
516 const SCsCOLROW nD, ScChangeTrack* pTrack); // only to use in the XML import
517 // which of nDx and nDy is set is dependend on the type
519 // is the last in a row (or single)
520 bool IsBaseDelete() const;
522 // is the first in a row (or single)
523 bool IsTopDelete() const;
525 // is part of a row
526 bool IsMultiDelete() const;
528 // is col, belonging to a TabDelete
529 bool IsTabDeleteCol() const;
531 SCsCOL GetDx() const;
532 SCsROW GetDy() const;
533 ScBigRange GetOverAllRange() const; // BigRange + (nDx, nDy)
535 const ScChangeActionCellListEntry* GetFirstCellEntry() const
536 { return pFirstCell; }
537 const ScChangeActionDelMoveEntry* GetFirstMoveEntry() const
538 { return pLinkMove; }
539 const ScChangeActionIns* GetCutOffInsert() const { return pCutOff; }
540 short GetCutOffCount() const { return nCutOff; }
542 virtual void GetDescription(
543 OUString& rStr, ScDocument* pDoc, bool bSplitRange = false, bool bWarning = true ) const;
545 void SetCutOffInsert( ScChangeActionIns* p, short n )
546 { pCutOff = p; nCutOff = n; } // only to use in the XML import
547 // this should be protected, but for the XML import it is public
548 // only to use in the XML import
549 // this should be protected, but for the XML import it is public
550 ScChangeActionDelMoveEntry* AddCutOffMove(
551 ScChangeActionMove* pMove, short nFrom, short nTo );
554 // ScChangeActionMove
555 class ScChangeActionMove : public ScChangeAction
557 friend class ScChangeTrack;
558 friend class ScChangeActionDel;
560 ScBigRange aFromRange;
561 ScChangeTrack* pTrack;
562 ScChangeActionCellListEntry* pFirstCell;
563 sal_uLong nStartLastCut; // for PasteCut undo
564 sal_uLong nEndLastCut;
566 ScChangeActionMove( const ScRange& rFromRange,
567 const ScRange& rToRange,
568 ScChangeTrack* pTrackP )
569 : ScChangeAction( SC_CAT_MOVE, rToRange ),
570 aFromRange( rFromRange ),
571 pTrack( pTrackP ),
572 pFirstCell( NULL ),
573 nStartLastCut(0),
574 nEndLastCut(0)
576 virtual ~ScChangeActionMove();
578 virtual void AddContent( ScChangeActionContent* );
579 virtual void DeleteCellEntries();
581 ScBigRange& GetFromRange() { return aFromRange; }
583 void SetStartLastCut( sal_uLong nVal ) { nStartLastCut = nVal; }
584 sal_uLong GetStartLastCut() const { return nStartLastCut; }
585 void SetEndLastCut( sal_uLong nVal ) { nEndLastCut = nVal; }
586 sal_uLong GetEndLastCut() const { return nEndLastCut; }
588 virtual void UpdateReference( const ScChangeTrack*,
589 UpdateRefMode, const ScBigRange&,
590 sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz );
592 virtual bool Reject(ScDocument* pDoc);
594 virtual const ScChangeTrack* GetChangeTrack() const { return pTrack; }
596 protected:
597 using ScChangeAction::GetRefString;
599 public:
600 ScChangeActionMove(const sal_uLong nActionNumber,
601 const ScChangeActionState eState,
602 const sal_uLong nRejectingNumber,
603 const ScBigRange& aToBigRange,
604 const OUString& aUser,
605 const DateTime& aDateTime,
606 const OUString &sComment,
607 const ScBigRange& aFromBigRange,
608 ScChangeTrack* pTrack); // only to use in the XML import
610 const ScChangeActionCellListEntry* GetFirstCellEntry() const
611 { return pFirstCell; } // only to use in the XML export
613 const ScBigRange& GetFromRange() const { return aFromRange; }
614 SC_DLLPUBLIC void GetDelta( sal_Int32& nDx, sal_Int32& nDy, sal_Int32& nDz ) const;
616 virtual void GetDescription(
617 OUString& rStr, ScDocument* pDoc, bool bSplitRange = false,
618 bool bWarning = true ) const;
620 virtual void GetRefString(
621 OUString& rStr, ScDocument* pDoc, bool bFlag3D = false ) const;
624 // ScChangeActionContent
625 enum ScChangeActionContentCellType
627 SC_CACCT_NONE = 0,
628 SC_CACCT_NORMAL,
629 SC_CACCT_MATORG,
630 SC_CACCT_MATREF
633 class ScChangeActionContent : public ScChangeAction
635 friend class ScChangeTrack;
637 ScCellValue maOldCell;
638 ScCellValue maNewCell;
640 OUString maOldValue;
641 OUString maNewValue;
642 ScChangeActionContent* pNextContent; // at the same position
643 ScChangeActionContent* pPrevContent;
644 ScChangeActionContent* pNextInSlot; // in the same slot
645 ScChangeActionContent** ppPrevInSlot;
647 void InsertInSlot( ScChangeActionContent** pp )
649 if ( !ppPrevInSlot )
651 ppPrevInSlot = pp;
652 if ( ( pNextInSlot = *pp ) != NULL )
653 pNextInSlot->ppPrevInSlot = &pNextInSlot;
654 *pp = this;
658 void RemoveFromSlot()
660 if ( ppPrevInSlot )
662 if ( ( *ppPrevInSlot = pNextInSlot ) != NULL )
663 pNextInSlot->ppPrevInSlot = ppPrevInSlot;
664 ppPrevInSlot = NULL; // not inserted
668 ScChangeActionContent* GetNextInSlot() { return pNextInSlot; }
670 void ClearTrack();
672 static void GetStringOfCell(
673 OUString& rStr, const ScCellValue& rCell, const ScDocument* pDoc, const ScAddress& rPos );
675 static void GetStringOfCell(
676 OUString& rStr, const ScCellValue& rCell, const ScDocument* pDoc, sal_uLong nFormat );
678 static void SetValue( OUString& rStr, ScCellValue& rCell, const ScAddress& rPos,
679 const ScCellValue& rOrgCell, const ScDocument* pFromDoc,
680 ScDocument* pToDoc );
682 static void SetValue( OUString& rStr, ScCellValue& rCell, sal_uLong nFormat,
683 const ScCellValue& rOrgCell, const ScDocument* pFromDoc,
684 ScDocument* pToDoc );
686 static void SetCell( OUString& rStr, ScCellValue& rCell, sal_uLong nFormat, const ScDocument* pDoc );
688 static bool NeedsNumberFormat( const ScCellValue& rVal );
690 void SetValueString( OUString& rValue, ScCellValue& rCell, const OUString& rStr, ScDocument* pDoc );
692 void GetValueString( OUString& rStr, const OUString& rValue, const ScCellValue& rCell,
693 const ScDocument* pDoc ) const;
695 void GetFormulaString( OUString& rStr, const ScFormulaCell* pCell ) const;
697 virtual void AddContent( ScChangeActionContent* ) {}
698 virtual void DeleteCellEntries() {}
700 virtual void UpdateReference( const ScChangeTrack*,
701 UpdateRefMode, const ScBigRange&,
702 sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz );
704 virtual bool Reject(ScDocument* pDoc);
706 virtual const ScChangeTrack* GetChangeTrack() const { return 0; }
708 // pRejectActions!=NULL: reject actions get
709 // stacked, no SetNewValue, no Append
710 bool Select( ScDocument*, ScChangeTrack*,
711 bool bOldest, ::std::stack<ScChangeActionContent*>* pRejectActions );
713 void PutValueToDoc(
714 const ScCellValue& rCell, const OUString& rValue, ScDocument* pDoc, SCsCOL nDx, SCsROW nDy ) const;
716 protected:
717 using ScChangeAction::GetRefString;
719 public:
721 DECL_FIXEDMEMPOOL_NEWDEL( ScChangeActionContent )
723 ScChangeActionContent( const ScRange& rRange );
725 ScChangeActionContent(
726 const sal_uLong nActionNumber, const ScChangeActionState eState,
727 const sal_uLong nRejectingNumber, const ScBigRange& aBigRange,
728 const OUString& aUser, const DateTime& aDateTime,
729 const OUString &sComment, const ScCellValue& rOldCell,
730 ScDocument* pDoc, const OUString& sOldValue ); // to use for XML Import
732 ScChangeActionContent(
733 const sal_uLong nActionNumber, const ScCellValue& rNewCell,
734 const ScBigRange& aBigRange, ScDocument* pDoc,
735 const OUString& sNewValue ); // to use for XML Import of Generated Actions
737 virtual ~ScChangeActionContent();
739 ScChangeActionContent* GetNextContent() const { return pNextContent; }
740 ScChangeActionContent* GetPrevContent() const { return pPrevContent; }
741 ScChangeActionContent* GetTopContent() const;
742 bool IsTopContent() const { return pNextContent == NULL; }
744 virtual ScChangeActionLinkEntry* GetDeletedIn() const;
745 virtual ScChangeActionLinkEntry** GetDeletedInAddress();
747 void PutOldValueToDoc( ScDocument*,
748 SCsCOL nDx, SCsROW nDy ) const;
749 void PutNewValueToDoc( ScDocument*,
750 SCsCOL nDx, SCsROW nDy ) const;
752 void SetOldValue( const ScCellValue& rCell, const ScDocument* pFromDoc, ScDocument* pToDoc, sal_uLong nFormat );
754 void SetOldValue( const ScCellValue& rCell, const ScDocument* pFromDoc, ScDocument* pToDoc );
756 void SetNewValue( const ScCellValue& rCell, ScDocument* pDoc );
758 // Used in import filter AppendContentOnTheFly,
759 void SetOldNewCells(
760 const ScCellValue& rOldCell, sal_uLong nOldFormat,
761 const ScCellValue& rNewCell, sal_uLong nNewFormat, ScDocument* pDoc );
763 // Use this only in the XML import,
764 // takes ownership of cell.
765 void SetNewCell(
766 const ScCellValue& rCell, ScDocument* pDoc, const OUString& rFormatted );
768 // These functions should be protected but for
769 // the XML import they are public.
770 void SetNextContent( ScChangeActionContent* p )
771 { pNextContent = p; }
772 void SetPrevContent( ScChangeActionContent* p )
773 { pPrevContent = p; }
775 // don't use:
776 // assigns string / creates forumula cell
777 void SetOldValue( const OUString& rOld, ScDocument* pDoc );
779 void GetOldString( OUString& rStr, const ScDocument* pDoc ) const;
780 void GetNewString( OUString& rStr, const ScDocument* pDoc ) const;
781 SC_DLLPUBLIC const ScCellValue& GetOldCell() const;
782 SC_DLLPUBLIC const ScCellValue& GetNewCell() const;
783 virtual void GetDescription(
784 OUString& rStr, ScDocument* pDoc, bool bSplitRange = false, bool bWarning = true ) const;
786 virtual void GetRefString(
787 OUString& rStr, ScDocument* pDoc, bool bFlag3D = false ) const;
789 static ScChangeActionContentCellType GetContentCellType( const ScCellValue& rCell );
790 static ScChangeActionContentCellType GetContentCellType( const ScRefCellValue& rIter );
792 // NewCell
793 bool IsMatrixOrigin() const;
794 // OldCell
795 bool IsOldMatrixReference() const;
798 // ScChangeActionReject
799 class ScChangeActionReject : public ScChangeAction
801 friend class ScChangeTrack;
802 friend class ScChangeActionContent;
804 ScChangeActionReject( sal_uLong nReject ) :
805 ScChangeAction( SC_CAT_REJECT, ScRange() )
807 SetRejectAction( nReject );
808 SetState( SC_CAS_ACCEPTED );
811 virtual void AddContent( ScChangeActionContent* ) {}
812 virtual void DeleteCellEntries() {}
814 virtual bool Reject(ScDocument* pDoc);
816 virtual const ScChangeTrack* GetChangeTrack() const { return 0; }
818 public:
819 ScChangeActionReject(const sal_uLong nActionNumber,
820 const ScChangeActionState eState,
821 const sal_uLong nRejectingNumber,
822 const ScBigRange& aBigRange,
823 const OUString& aUser,
824 const DateTime& aDateTime,
825 const OUString &sComment); // only to use in the XML import
828 // ScChangeTrack
829 enum ScChangeTrackMsgType
831 SC_CTM_NONE,
832 SC_CTM_APPEND, // Actions appended
833 SC_CTM_REMOVE, // Actions removed
834 SC_CTM_CHANGE, // Actions changed
835 SC_CTM_PARENT // became a parent (and wasn't before)
838 struct ScChangeTrackMsgInfo
840 DECL_FIXEDMEMPOOL_NEWDEL( ScChangeTrackMsgInfo )
842 ScChangeTrackMsgType eMsgType;
843 sal_uLong nStartAction;
844 sal_uLong nEndAction;
847 // MsgQueue for notification via ModifiedLink
848 typedef std::deque<ScChangeTrackMsgInfo*> ScChangeTrackMsgQueue;
849 typedef std::stack<ScChangeTrackMsgInfo*> ScChangeTrackMsgStack;
850 typedef std::map<sal_uLong, ScChangeAction*> ScChangeActionMap;
852 enum ScChangeTrackMergeState
854 SC_CTMS_NONE,
855 SC_CTMS_PREPARE,
856 SC_CTMS_OWN,
857 SC_CTMS_UNDO,
858 SC_CTMS_OTHER
861 // Internally generated actions start at this value (nearly all bits set)
862 // and are decremented, to keep values in a table separated from "normal" actions.
863 #define SC_CHGTRACK_GENERATED_START ((sal_uInt32) 0xfffffff0)
865 class ScChangeTrack : public utl::ConfigurationListener
867 friend void ScChangeAction::RejectRestoreContents( ScChangeTrack*, SCsCOL, SCsROW );
868 friend bool ScChangeActionDel::Reject( ScDocument* pDoc );
869 friend void ScChangeActionDel::DeleteCellEntries();
870 friend void ScChangeActionMove::DeleteCellEntries();
871 friend bool ScChangeActionMove::Reject( ScDocument* pDoc );
873 static const SCROW nContentRowsPerSlot;
874 static const SCSIZE nContentSlots;
876 com::sun::star::uno::Sequence< sal_Int8 > aProtectPass;
877 ScChangeActionMap aMap;
878 ScChangeActionMap aGeneratedMap;
879 ScChangeActionMap aPasteCutMap;
880 ScChangeTrackMsgQueue aMsgQueue;
881 ScChangeTrackMsgStack aMsgStackTmp;
882 ScChangeTrackMsgStack aMsgStackFinal;
883 std::set<OUString> maUserCollection;
884 OUString maUser;
885 Link aModifiedLink;
886 ScRange aInDeleteRange;
887 DateTime aFixDateTime;
888 ScChangeAction* pFirst;
889 ScChangeAction* pLast;
890 ScChangeActionContent* pFirstGeneratedDelContent;
891 ScChangeActionContent** ppContentSlots;
892 ScChangeActionMove* pLastCutMove;
893 ScChangeActionLinkEntry* pLinkInsertCol;
894 ScChangeActionLinkEntry* pLinkInsertRow;
895 ScChangeActionLinkEntry* pLinkInsertTab;
896 ScChangeActionLinkEntry* pLinkMove;
897 ScChangeTrackMsgInfo* pBlockModifyMsg;
898 ScDocument* pDoc;
899 sal_uLong nActionMax;
900 sal_uLong nGeneratedMin;
901 sal_uLong nMarkLastSaved;
902 sal_uLong nStartLastCut;
903 sal_uLong nEndLastCut;
904 sal_uLong nLastMerge;
905 ScChangeTrackMergeState eMergeState;
906 bool bLoadSave:1;
907 bool bInDelete:1;
908 bool bInDeleteUndo:1;
909 bool bInDeleteTop:1;
910 bool bInPasteCut:1;
911 bool bUseFixDateTime:1;
912 bool bTimeNanoSeconds:1;
914 // not implemented, prevent usage
915 ScChangeTrack( const ScChangeTrack& );
916 ScChangeTrack& operator=( const ScChangeTrack& );
918 static SCROW InitContentRowsPerSlot();
920 // true if one is MM_FORMULA and the other is
921 // not, or if both are and range differs
922 static bool IsMatrixFormulaRangeDifferent(
923 const ScCellValue& rOldCell, const ScCellValue& rNewCell );
925 void Init();
926 void DtorClear();
927 void SetLoadSave( bool bVal ) { bLoadSave = bVal; }
928 void SetInDeleteRange( const ScRange& rRange )
929 { aInDeleteRange = rRange; }
930 void SetInDelete( bool bVal )
931 { bInDelete = bVal; }
932 void SetInDeleteTop( bool bVal )
933 { bInDeleteTop = bVal; }
934 void SetInDeleteUndo( bool bVal )
935 { bInDeleteUndo = bVal; }
936 void SetInPasteCut( bool bVal )
937 { bInPasteCut = bVal; }
938 void SetMergeState( ScChangeTrackMergeState eState )
939 { eMergeState = eState; }
940 ScChangeTrackMergeState GetMergeState() const { return eMergeState; }
941 void SetLastMerge( sal_uLong nVal ) { nLastMerge = nVal; }
942 sal_uLong GetLastMerge() const { return nLastMerge; }
944 void SetLastCutMoveRange( const ScRange&, ScDocument* );
946 // create block of ModifyMsg
947 void StartBlockModify( ScChangeTrackMsgType,
948 sal_uLong nStartAction );
949 void EndBlockModify( sal_uLong nEndAction );
951 void AddDependentWithNotify( ScChangeAction* pParent,
952 ScChangeAction* pDependent );
954 void Dependencies( ScChangeAction* );
955 void UpdateReference( ScChangeAction*, bool bUndo );
956 void UpdateReference( ScChangeAction** ppFirstAction, ScChangeAction* pAct, bool bUndo );
957 void Append( ScChangeAction* pAppend, sal_uLong nAction );
958 SC_DLLPUBLIC void AppendDeleteRange( const ScRange&,
959 ScDocument* pRefDoc, SCsTAB nDz,
960 sal_uLong nRejectingInsert );
961 void AppendOneDeleteRange( const ScRange& rOrgRange,
962 ScDocument* pRefDoc,
963 SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
964 sal_uLong nRejectingInsert );
965 void LookUpContents( const ScRange& rOrgRange,
966 ScDocument* pRefDoc,
967 SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
968 void Remove( ScChangeAction* );
969 void MasterLinks( ScChangeAction* );
971 // Content on top an Position
972 ScChangeActionContent* SearchContentAt( const ScBigAddress&,
973 ScChangeAction* pButNotThis ) const;
974 void DeleteGeneratedDelContent(
975 ScChangeActionContent* );
977 ScChangeActionContent* GenerateDelContent(
978 const ScAddress& rPos, const ScCellValue& rCell, const ScDocument* pFromDoc );
980 void DeleteCellEntries(
981 ScChangeActionCellListEntry*&,
982 ScChangeAction* pDeletor );
984 // Reject action and all dependent actions,
985 // Table stems from previous GetDependents,
986 // only needed for Insert and Move (MasterType),
987 // is NULL otherwise.
988 // bRecursion == called from reject with table
989 bool Reject( ScChangeAction*, ScChangeActionMap*, bool bRecursion );
991 void ClearMsgQueue();
992 virtual void ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 );
994 public:
996 static SCSIZE ComputeContentSlot( sal_Int32 nRow )
998 if ( nRow < 0 || nRow > MAXROW )
999 return nContentSlots - 1;
1000 return static_cast< SCSIZE >( nRow / nContentRowsPerSlot );
1003 SC_DLLPUBLIC ScChangeTrack( ScDocument* );
1004 ScChangeTrack(ScDocument* pDocP, const std::set<OUString>& aTempUserCollection); // only to use in the XML import
1005 SC_DLLPUBLIC virtual ~ScChangeTrack();
1006 void Clear();
1008 ScChangeActionContent* GetFirstGenerated() const { return pFirstGeneratedDelContent; }
1009 ScChangeAction* GetFirst() const { return pFirst; }
1010 ScChangeAction* GetLast() const { return pLast; }
1011 sal_uLong GetActionMax() const { return nActionMax; }
1012 bool IsGenerated( sal_uLong nAction ) const
1013 { return nAction >= nGeneratedMin; }
1014 ScChangeAction* GetAction( sal_uLong nAction ) const
1016 ScChangeActionMap::const_iterator it = aMap.find( nAction );
1017 if( it != aMap.end() )
1018 return it->second;
1019 else
1020 return NULL;
1022 ScChangeAction* GetGenerated( sal_uLong nGenerated ) const
1024 ScChangeActionMap::const_iterator it = aGeneratedMap.find( nGenerated );
1025 if( it != aGeneratedMap.end() )
1026 return it->second;
1027 else
1028 return NULL;
1030 ScChangeAction* GetActionOrGenerated( sal_uLong nAction ) const
1032 return IsGenerated( nAction ) ?
1033 GetGenerated( nAction ) :
1034 GetAction( nAction );
1036 sal_uLong GetLastSavedActionNumber() const
1037 { return nMarkLastSaved; }
1038 void SetLastSavedActionNumber(sal_uLong nNew)
1039 { nMarkLastSaved = nNew; }
1040 ScChangeAction* GetLastSaved() const
1042 ScChangeActionMap::const_iterator it = aMap.find( nMarkLastSaved );
1043 if( it != aMap.end() )
1044 return it->second;
1045 else
1046 return NULL;
1048 ScChangeActionContent** GetContentSlots() const { return ppContentSlots; }
1050 bool IsLoadSave() const { return bLoadSave; }
1051 const ScRange& GetInDeleteRange() const
1052 { return aInDeleteRange; }
1053 bool IsInDelete() const { return bInDelete; }
1054 bool IsInDeleteTop() const { return bInDeleteTop; }
1055 bool IsInDeleteUndo() const { return bInDeleteUndo; }
1056 bool IsInPasteCut() const { return bInPasteCut; }
1057 SC_DLLPUBLIC void SetUser( const OUString& rUser );
1058 SC_DLLPUBLIC const OUString& GetUser() const;
1059 SC_DLLPUBLIC const std::set<OUString>& GetUserCollection() const;
1060 ScDocument* GetDocument() const { return pDoc; }
1061 // for import filter
1062 const DateTime& GetFixDateTime() const { return aFixDateTime; }
1064 // set this if the date/time set with
1065 // SetFixDateTime...() shall be applied to
1066 // appended actions
1067 void SetUseFixDateTime( bool bVal )
1068 { bUseFixDateTime = bVal; }
1069 // for MergeDocument, apply original date/time as UTC
1070 void SetFixDateTimeUTC( const DateTime& rDT )
1071 { aFixDateTime = rDT; }
1072 // for import filter, apply original date/time as local time
1073 void SetFixDateTimeLocal( const DateTime& rDT )
1074 { aFixDateTime = rDT; aFixDateTime.ConvertToUTC(); }
1076 void Append( ScChangeAction* );
1078 // pRefDoc may be NULL => no lookup of contents
1079 // => no generation of deleted contents
1080 SC_DLLPUBLIC void AppendDeleteRange( const ScRange&,
1081 ScDocument* pRefDoc,
1082 sal_uLong& nStartAction, sal_uLong& nEndAction,
1083 SCsTAB nDz = 0 );
1084 // nDz: multi TabDel, LookUpContent must be searched
1085 // with an offset of -nDz
1087 // after new value was set in the document,
1088 // old value from RefDoc/UndoDoc
1089 void AppendContent( const ScAddress& rPos,
1090 ScDocument* pRefDoc );
1091 // after new values were set in the document,
1092 // old values from RefDoc/UndoDoc
1093 void AppendContentRange( const ScRange& rRange,
1094 ScDocument* pRefDoc,
1095 sal_uLong& nStartAction, sal_uLong& nEndAction,
1096 ScChangeActionClipMode eMode = SC_CACM_NONE );
1097 // after new value was set in the document,
1098 // old value from pOldCell, nOldFormat,
1099 // RefDoc==NULL => Doc
1100 void AppendContent( const ScAddress& rPos, const ScCellValue& rOldCell,
1101 sal_uLong nOldFormat, ScDocument* pRefDoc = NULL );
1102 // after new value was set in the document,
1103 // old value from pOldCell, format from Doc
1104 void AppendContent( const ScAddress& rPos, const ScCellValue& rOldCell );
1105 // after new values were set in the document,
1106 // old values from RefDoc/UndoDoc.
1107 // All contents with a cell in RefDoc
1108 void AppendContentsIfInRefDoc( ScDocument* pRefDoc,
1109 sal_uLong& nStartAction, sal_uLong& nEndAction );
1111 // Meant for import filter, creates and inserts
1112 // an unconditional content action of the two
1113 // cells without querying the document, not
1114 // even for number formats (though the number
1115 // formatter of the document may be used).
1116 // The action is returned and may be used to
1117 // set user name, description, date/time et al.
1118 // Takes ownership of the cells!
1119 SC_DLLPUBLIC ScChangeActionContent* AppendContentOnTheFly(
1120 const ScAddress& rPos, const ScCellValue& rOldCell, const ScCellValue& rNewCell,
1121 sal_uLong nOldFormat = 0, sal_uLong nNewFormat = 0 );
1123 // Only use the following two if there is no different solution! (Assign
1124 // string for NewValue or creation of a formula respectively)
1126 SC_DLLPUBLIC void AppendInsert( const ScRange& );
1128 // pRefDoc may be NULL => no lookup of contents
1129 // => no generation of deleted contents
1130 SC_DLLPUBLIC void AppendMove( const ScRange& rFromRange, const ScRange& rToRange,
1131 ScDocument* pRefDoc );
1133 // Cut to Clipboard
1134 void ResetLastCut()
1136 nStartLastCut = nEndLastCut = 0;
1137 if ( pLastCutMove )
1139 delete pLastCutMove;
1140 pLastCutMove = NULL;
1143 bool HasLastCut() const
1145 return nEndLastCut > 0 &&
1146 nStartLastCut <= nEndLastCut &&
1147 pLastCutMove;
1150 SC_DLLPUBLIC void Undo( sal_uLong nStartAction, sal_uLong nEndAction, bool bMerge = false );
1152 // adjust references for MergeDocument
1153 //! may only be used in a temporary opened document.
1154 //! the Track (?) is unclean afterwards
1155 void MergePrepare( ScChangeAction* pFirstMerge, bool bShared = false );
1156 void MergeOwn( ScChangeAction* pAct, sal_uLong nFirstMerge, bool bShared = false );
1157 static bool MergeIgnore( const ScChangeAction&, sal_uLong nFirstMerge );
1159 // This comment was already really strange in German.
1160 // Tried to structure it a little. Hope no information got lost...
1162 // Insert dependents into table.
1163 // ScChangeAction is
1164 // - "Insert": really dependents
1165 // - "Move": dependent contents in FromRange /
1166 // deleted contents in ToRange
1167 // OR inserts in FromRange or ToRange
1168 // - "Delete": a list of deleted (what?)
1169 // OR for content, different contents at the same position
1170 // OR MatrixReferences belonging to MatrixOrigin
1172 // With bListMasterDelete (==TRUE ?) all Deletes of a row belonging
1173 // to a MasterDelete are listed (possibly it is
1174 // "all Deletes belonging...are listed in a row?)
1176 // With bAllFlat (==TRUE ?) all dependents of dependents
1177 // will be inserted flatly.
1179 SC_DLLPUBLIC void GetDependents(
1180 ScChangeAction*, ScChangeActionMap&, bool bListMasterDelete = false, bool bAllFlat = false ) const;
1182 // Reject visible action (and dependents)
1183 bool Reject( ScChangeAction*, bool bShared = false );
1185 // Accept visible action (and dependents)
1186 SC_DLLPUBLIC bool Accept( ScChangeAction* );
1188 void AcceptAll(); // all Virgins
1189 bool RejectAll(); // all Virgins
1191 // Selects a content of several contents at the same
1192 // position and accepts this one and
1193 // the older ones, rejects the more recent ones.
1194 // If bOldest==TRUE then the first OldValue
1195 // of a Virgin-Content-List will be restored.
1196 bool SelectContent( ScChangeAction*, bool bOldest = false );
1198 // If ModifiedLink is set, changes go to
1199 // ScChangeTrackMsgQueue
1200 void SetModifiedLink( const Link& r )
1201 { aModifiedLink = r; ClearMsgQueue(); }
1202 const Link& GetModifiedLink() const { return aModifiedLink; }
1203 ScChangeTrackMsgQueue& GetMsgQueue() { return aMsgQueue; }
1205 void NotifyModified( ScChangeTrackMsgType eMsgType,
1206 sal_uLong nStartAction, sal_uLong nEndAction );
1208 sal_uLong AddLoadedGenerated(
1209 const ScCellValue& rNewCell, const ScBigRange& aBigRange, const OUString& sNewValue ); // only to use in the XML import
1210 void AppendLoaded( ScChangeAction* pAppend ); // this is only for the XML import public, it should be protected
1211 void SetActionMax(sal_uLong nTempActionMax)
1212 { nActionMax = nTempActionMax; } // only to use in the XML import
1214 void SetProtection( const com::sun::star::uno::Sequence< sal_Int8 >& rPass )
1215 { aProtectPass = rPass; }
1216 com::sun::star::uno::Sequence< sal_Int8 > GetProtection() const
1217 { return aProtectPass; }
1218 bool IsProtected() const { return aProtectPass.getLength() != 0; }
1220 // If time stamps of actions of this
1221 // ChangeTrack and a second one are to be
1222 // compared including nanoseconds.
1223 void SetTimeNanoSeconds( bool bVal ) { bTimeNanoSeconds = bVal; }
1224 bool IsTimeNanoSeconds() const { return bTimeNanoSeconds; }
1226 void AppendCloned( ScChangeAction* pAppend );
1227 SC_DLLPUBLIC ScChangeTrack* Clone( ScDocument* pDocument ) const;
1228 void MergeActionState( ScChangeAction* pAct, const ScChangeAction* pOtherAct );
1231 #endif
1233 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */