Version 4.0.2.1, tag libreoffice-4.0.2.1
[LibreOffice.git] / sc / inc / chgtrack.hxx
blob83228bd9ad39fd5105058ff73eedfcac69fa4e3f
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 <unotools/options.hxx>
31 #include "global.hxx"
32 #include "bigrange.hxx"
33 #include "scdllapi.h"
35 #ifdef SC_CHGTRACK_CXX
36 // core/inc
37 #include "refupdat.hxx"
38 #endif
40 class ScBaseCell;
41 class ScDocument;
44 enum ScChangeActionType
46 SC_CAT_NONE,
47 SC_CAT_INSERT_COLS,
48 SC_CAT_INSERT_ROWS,
49 SC_CAT_INSERT_TABS,
50 SC_CAT_DELETE_COLS,
51 SC_CAT_DELETE_ROWS,
52 SC_CAT_DELETE_TABS,
53 SC_CAT_MOVE,
54 SC_CAT_CONTENT,
55 SC_CAT_REJECT
59 enum ScChangeActionState
61 SC_CAS_VIRGIN,
62 SC_CAS_ACCEPTED,
63 SC_CAS_REJECTED
67 enum ScChangeActionClipMode
69 SC_CACM_NONE,
70 SC_CACM_CUT,
71 SC_CACM_COPY,
72 SC_CACM_PASTE
75 // --- ScChangeActionLinkEntry ---------------------------------------------
77 // Inserts itself as the head of a chain (better: linked list?), or before a LinkEntry
78 // on delete: automatically remove of what is linked (German original was strange...)
79 // ppPrev == &previous->pNext oder address of pointer to head of linked list,
80 // *ppPrev == this
82 class ScChangeAction;
84 class ScChangeActionLinkEntry
86 // not implemented, prevent usage
87 ScChangeActionLinkEntry( const ScChangeActionLinkEntry& );
88 ScChangeActionLinkEntry& operator=( const ScChangeActionLinkEntry& );
90 protected:
92 ScChangeActionLinkEntry* pNext;
93 ScChangeActionLinkEntry** ppPrev;
94 ScChangeAction* pAction;
95 ScChangeActionLinkEntry* pLink;
97 public:
99 DECL_FIXEDMEMPOOL_NEWDEL( ScChangeActionLinkEntry )
101 ScChangeActionLinkEntry(
102 ScChangeActionLinkEntry** ppPrevP,
103 ScChangeAction* pActionP )
104 : pNext( *ppPrevP ),
105 ppPrev( ppPrevP ),
106 pAction( pActionP ),
107 pLink( NULL )
109 if ( pNext )
110 pNext->ppPrev = &pNext;
111 *ppPrevP = this;
114 virtual ~ScChangeActionLinkEntry()
116 ScChangeActionLinkEntry* p = pLink;
117 UnLink();
118 Remove();
119 if ( p )
120 delete p;
123 void SetLink( ScChangeActionLinkEntry* pLinkP )
125 UnLink();
126 if ( pLinkP )
128 pLink = pLinkP;
129 pLinkP->pLink = this;
133 void UnLink()
135 if ( pLink )
137 pLink->pLink = NULL;
138 pLink = NULL;
142 void Remove()
144 if ( ppPrev )
146 if ( ( *ppPrev = pNext ) != NULL )
147 pNext->ppPrev = ppPrev;
148 ppPrev = NULL; // not inserted
152 void Insert( ScChangeActionLinkEntry** ppPrevP )
154 if ( !ppPrev )
156 ppPrev = ppPrevP;
157 if ( (pNext = *ppPrevP) )
158 pNext->ppPrev = &pNext;
159 *ppPrevP = this;
163 const ScChangeActionLinkEntry* GetLink() const { return pLink; }
164 ScChangeActionLinkEntry* GetLink() { return pLink; }
165 const ScChangeActionLinkEntry* GetNext() const { return pNext; }
166 ScChangeActionLinkEntry* GetNext() { return pNext; }
167 const ScChangeAction* GetAction() const { return pAction; }
168 ScChangeAction* GetAction() { return pAction; }
171 // --- ScChangeActionCellListEntry -----------------------------------------
172 // this is only for the XML Export in the hxx
173 class ScChangeActionContent;
175 class ScChangeActionCellListEntry
177 friend class ScChangeAction;
178 friend class ScChangeActionDel;
179 friend class ScChangeActionMove;
180 friend class ScChangeTrack;
182 ScChangeActionCellListEntry* pNext;
183 ScChangeActionContent* pContent;
185 ScChangeActionCellListEntry(
186 ScChangeActionContent* pContentP,
187 ScChangeActionCellListEntry* pNextP )
188 : pNext( pNextP ),
189 pContent( pContentP )
192 public:
193 const ScChangeActionCellListEntry* GetNext() const { return pNext; } // this is only for the XML Export public
194 const ScChangeActionContent* GetContent() const { return pContent; } // this is only for the XML Export public
196 DECL_FIXEDMEMPOOL_NEWDEL( ScChangeActionCellListEntry )
199 // --- ScChangeAction -------------------------------------------------------
201 class ScChangeTrack;
202 class ScChangeActionIns;
203 class ScChangeActionDel;
204 class ScChangeActionContent;
206 class ScChangeAction
208 friend class ScChangeTrack;
209 friend class ScChangeActionIns;
210 friend class ScChangeActionDel;
211 friend class ScChangeActionMove;
212 friend class ScChangeActionContent;
214 // not implemented, prevent usage
215 ScChangeAction( const ScChangeAction& );
216 ScChangeAction& operator=( const ScChangeAction& );
218 protected:
220 ScBigRange aBigRange; // Ins/Del/MoveTo/ContentPos
221 DateTime aDateTime; //! UTC
222 rtl::OUString aUser; // who?
223 rtl::OUString aComment; // user comment
224 ScChangeAction* pNext; // next in linked list
225 ScChangeAction* pPrev; // previous in linked list
226 ScChangeActionLinkEntry* pLinkAny; // arbitrary links
227 ScChangeActionLinkEntry* pLinkDeletedIn; // access to insert areas which were
228 // deleted or moved or rejected
229 ScChangeActionLinkEntry* pLinkDeleted; // links to deleted
230 ScChangeActionLinkEntry* pLinkDependent; // links to dependent
231 sal_uLong nAction;
232 sal_uLong nRejectAction;
233 ScChangeActionType eType;
234 ScChangeActionState eState;
236 ScChangeAction( ScChangeActionType, const ScRange& );
238 // only to be used in the XML import
239 ScChangeAction( ScChangeActionType,
240 const ScBigRange&,
241 const sal_uLong nAction,
242 const sal_uLong nRejectAction,
243 const ScChangeActionState eState,
244 const DateTime& aDateTime,
245 const rtl::OUString& aUser,
246 const rtl::OUString& aComment );
248 // only to be used in the XML import
249 ScChangeAction( ScChangeActionType, const ScBigRange&, const sal_uLong nAction);
251 virtual ~ScChangeAction();
253 rtl::OUString GetRefString(
254 const ScBigRange& rRange, ScDocument* pDoc, bool bFlag3D = false) const;
256 void SetActionNumber( sal_uLong n ) { nAction = n; }
257 void SetRejectAction( sal_uLong n ) { nRejectAction = n; }
258 void SetUser( const rtl::OUString& r );
259 void SetType( ScChangeActionType e ) { eType = e; }
260 void SetState( ScChangeActionState e ) { eState = e; }
261 void SetRejected();
263 ScBigRange& GetBigRange() { return aBigRange; }
265 ScChangeActionLinkEntry* AddLink(
266 ScChangeAction* p, ScChangeActionLinkEntry* pL )
268 ScChangeActionLinkEntry* pLnk =
269 new ScChangeActionLinkEntry(
270 &pLinkAny, p );
271 pLnk->SetLink( pL );
272 return pLnk;
275 void RemoveAllAnyLinks();
277 virtual ScChangeActionLinkEntry* GetDeletedIn() const
278 { return pLinkDeletedIn; }
279 virtual ScChangeActionLinkEntry** GetDeletedInAddress()
280 { return &pLinkDeletedIn; }
281 ScChangeActionLinkEntry* AddDeletedIn( ScChangeAction* p )
283 return new ScChangeActionLinkEntry(
284 GetDeletedInAddress(), p );
287 bool RemoveDeletedIn( const ScChangeAction* );
288 void SetDeletedIn( ScChangeAction* );
290 ScChangeActionLinkEntry* AddDeleted( ScChangeAction* p )
292 return new ScChangeActionLinkEntry(&pLinkDeleted, p);
295 void RemoveAllDeleted();
297 ScChangeActionLinkEntry* AddDependent( ScChangeAction* p )
299 return new ScChangeActionLinkEntry(&pLinkDependent, p);
302 void RemoveAllDependent();
304 void RemoveAllLinks();
306 virtual void AddContent( ScChangeActionContent* ) = 0;
307 virtual void DeleteCellEntries() = 0;
309 virtual void UpdateReference( const ScChangeTrack*,
310 UpdateRefMode, const ScBigRange&,
311 sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz );
313 void Accept();
314 virtual bool Reject(ScDocument* pDoc) = 0;
315 void RejectRestoreContents( ScChangeTrack*, SCsCOL nDx, SCsROW nDy );
317 // used in Reject() instead of IsRejectable()
318 bool IsInternalRejectable() const;
320 // Derived classes that hold a pointer to the
321 // ChangeTrack must return that. Otherwise NULL.
322 virtual const ScChangeTrack* GetChangeTrack() const = 0;
324 public:
325 bool IsInsertType() const;
326 bool IsDeleteType() const;
327 bool IsVirgin() const;
328 SC_DLLPUBLIC bool IsAccepted() const;
329 bool IsRejected() const;
331 // Action rejects another Action
332 bool IsRejecting() const;
334 // if action is visible in the document
335 bool IsVisible() const;
337 // if action if touchable
338 bool IsTouchable() const;
340 // if action is an entry in dialog root
341 bool IsDialogRoot() const;
343 // if an entry in a dialog shall be a drop down entry
344 bool IsDialogParent() const;
346 // if action is a delete with subdeletes (aufgeklappt = open ?)
347 bool IsMasterDelete() const;
349 // if action is acceptable/selectable/rejectable
350 bool IsClickable() const;
352 // if action is rejectable
353 bool IsRejectable() const;
355 const ScBigRange& GetBigRange() const { return aBigRange; }
356 SC_DLLPUBLIC DateTime GetDateTime() const; // local time
357 const DateTime& GetDateTimeUTC() const // UTC time
358 { return aDateTime; }
359 ScChangeActionType GetType() const { return eType; }
360 ScChangeActionState GetState() const { return eState; }
361 sal_uLong GetActionNumber() const { return nAction; }
362 sal_uLong GetRejectAction() const { return nRejectAction; }
364 ScChangeAction* GetNext() const { return pNext; }
365 ScChangeAction* GetPrev() const { return pPrev; }
367 bool IsDeletedIn() const;
368 bool IsDeletedIn( const ScChangeAction* ) const;
369 bool IsDeletedInDelType( ScChangeActionType ) const;
370 void RemoveAllDeletedIn();
372 const ScChangeActionLinkEntry* GetFirstDeletedEntry() const
373 { return pLinkDeleted; }
374 const ScChangeActionLinkEntry* GetFirstDependentEntry() const
375 { return pLinkDependent; }
376 bool HasDependent() const;
377 bool HasDeleted() const;
378 // description will be appended to string
379 // with bSplitRange only one column/row will be considered for delete
380 // (for a listing of entries)
381 virtual void GetDescription(
382 rtl::OUString& rStr, ScDocument* pDoc,
383 bool bSplitRange = false, bool bWarning = true ) const;
385 virtual void GetRefString(
386 rtl::OUString& rStr, ScDocument* pDoc, bool bFlag3D = false ) const;
388 // for DocumentMerge set old date of the other
389 // action, fetched by GetDateTimeUTC
390 void SetDateTimeUTC( const DateTime& rDT )
391 { aDateTime = rDT; }
393 SC_DLLPUBLIC const rtl::OUString& GetUser() const;
394 const rtl::OUString& GetComment() const;
396 // set user comment
397 void SetComment( const rtl::OUString& rStr );
399 // only to be used in the XML import
400 void SetDeletedInThis( sal_uLong nActionNumber,
401 const ScChangeTrack* pTrack );
402 // only to be used in the XML import
403 void AddDependent( sal_uLong nActionNumber,
404 const ScChangeTrack* pTrack );
408 // --- ScChangeActionIns ----------------------------------------------------
410 class ScChangeActionIns : public ScChangeAction
412 friend class ScChangeTrack;
414 ScChangeActionIns( const ScRange& rRange );
415 virtual ~ScChangeActionIns();
417 virtual void AddContent( ScChangeActionContent* ) {}
418 virtual void DeleteCellEntries() {}
420 virtual bool Reject(ScDocument* pDoc);
422 virtual const ScChangeTrack* GetChangeTrack() const { return 0; }
424 public:
425 ScChangeActionIns(const sal_uLong nActionNumber,
426 const ScChangeActionState eState,
427 const sal_uLong nRejectingNumber,
428 const ScBigRange& aBigRange,
429 const rtl::OUString& aUser,
430 const DateTime& aDateTime,
431 const rtl::OUString &sComment,
432 const ScChangeActionType eType); // only to use in the XML import
434 virtual void GetDescription(
435 rtl::OUString& rStr, ScDocument* pDoc, bool bSplitRange = false, bool bWarning = true) const;
439 // --- ScChangeActionDel ----------------------------------------------------
441 class ScChangeActionMove;
443 class ScChangeActionDelMoveEntry : public ScChangeActionLinkEntry
445 friend class ScChangeActionDel;
446 friend class ScChangeTrack;
448 short nCutOffFrom;
449 short nCutOffTo;
451 ScChangeActionDelMoveEntry(
452 ScChangeActionDelMoveEntry** ppPrevP,
453 ScChangeActionMove* pMove,
454 short nFrom, short nTo )
455 : ScChangeActionLinkEntry(
456 (ScChangeActionLinkEntry**)
457 ppPrevP,
458 (ScChangeAction*) pMove ),
459 nCutOffFrom( nFrom ),
460 nCutOffTo( nTo )
463 ScChangeActionDelMoveEntry* GetNext()
465 return (ScChangeActionDelMoveEntry*)
466 ScChangeActionLinkEntry::GetNext();
468 ScChangeActionMove* GetMove()
470 return (ScChangeActionMove*)
471 ScChangeActionLinkEntry::GetAction();
474 public:
475 const ScChangeActionDelMoveEntry* GetNext() const
477 return (const ScChangeActionDelMoveEntry*)
478 ScChangeActionLinkEntry::GetNext();
480 const ScChangeActionMove* GetMove() const
482 return (const ScChangeActionMove*)
483 ScChangeActionLinkEntry::GetAction();
485 short GetCutOffFrom() const { return nCutOffFrom; }
486 short GetCutOffTo() const { return nCutOffTo; }
490 class ScChangeActionDel : public ScChangeAction
492 friend class ScChangeTrack;
493 friend void ScChangeAction::Accept();
495 ScChangeTrack* pTrack;
496 ScChangeActionCellListEntry* pFirstCell;
497 ScChangeActionIns* pCutOff; // cut insert
498 short nCutOff; // +: start -: end
499 ScChangeActionDelMoveEntry* pLinkMove;
500 SCsCOL nDx;
501 SCsROW nDy;
503 ScChangeActionDel( const ScRange& rRange, SCsCOL nDx, SCsROW nDy, ScChangeTrack* );
504 virtual ~ScChangeActionDel();
506 ScChangeActionIns* GetCutOffInsert() { return pCutOff; }
508 virtual void AddContent( ScChangeActionContent* );
509 virtual void DeleteCellEntries();
511 void UndoCutOffMoves();
512 void UndoCutOffInsert();
514 virtual void UpdateReference( const ScChangeTrack*,
515 UpdateRefMode, const ScBigRange&,
516 sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz );
518 virtual bool Reject(ScDocument* pDoc);
520 virtual const ScChangeTrack* GetChangeTrack() const { return pTrack; }
522 public:
523 ScChangeActionDel(
524 const sal_uLong nActionNumber, const ScChangeActionState eState,
525 const sal_uLong nRejectingNumber, const ScBigRange& aBigRange,
526 const rtl::OUString& aUser, const DateTime& aDateTime,
527 const rtl::OUString &sComment, const ScChangeActionType eType,
528 const SCsCOLROW nD, ScChangeTrack* pTrack); // only to use in the XML import
529 // which of nDx and nDy is set is dependend on the type
531 // is the last in a row (or single)
532 bool IsBaseDelete() const;
534 // is the first in a row (or single)
535 bool IsTopDelete() const;
537 // is part of a row
538 bool IsMultiDelete() const;
540 // is col, belonging to a TabDelete
541 bool IsTabDeleteCol() const;
543 SCsCOL GetDx() const;
544 SCsROW GetDy() const;
545 ScBigRange GetOverAllRange() const; // BigRange + (nDx, nDy)
547 const ScChangeActionCellListEntry* GetFirstCellEntry() const
548 { return pFirstCell; }
549 const ScChangeActionDelMoveEntry* GetFirstMoveEntry() const
550 { return pLinkMove; }
551 const ScChangeActionIns* GetCutOffInsert() const { return pCutOff; }
552 short GetCutOffCount() const { return nCutOff; }
554 virtual void GetDescription(
555 rtl::OUString& rStr, ScDocument* pDoc, bool bSplitRange = false, bool bWarning = true ) const;
557 void SetCutOffInsert( ScChangeActionIns* p, short n )
558 { pCutOff = p; nCutOff = n; } // only to use in the XML import
559 // this should be protected, but for the XML import it is public
560 // only to use in the XML import
561 // this should be protected, but for the XML import it is public
562 ScChangeActionDelMoveEntry* AddCutOffMove(
563 ScChangeActionMove* pMove, short nFrom, short nTo );
567 // --- ScChangeActionMove ---------------------------------------------------
569 class ScChangeActionMove : public ScChangeAction
571 friend class ScChangeTrack;
572 friend class ScChangeActionDel;
574 ScBigRange aFromRange;
575 ScChangeTrack* pTrack;
576 ScChangeActionCellListEntry* pFirstCell;
577 sal_uLong nStartLastCut; // for PasteCut undo
578 sal_uLong nEndLastCut;
580 ScChangeActionMove( const ScRange& rFromRange,
581 const ScRange& rToRange,
582 ScChangeTrack* pTrackP )
583 : ScChangeAction( SC_CAT_MOVE, rToRange ),
584 aFromRange( rFromRange ),
585 pTrack( pTrackP ),
586 pFirstCell( NULL ),
587 nStartLastCut(0),
588 nEndLastCut(0)
590 virtual ~ScChangeActionMove();
592 virtual void AddContent( ScChangeActionContent* );
593 virtual void DeleteCellEntries();
595 ScBigRange& GetFromRange() { return aFromRange; }
597 void SetStartLastCut( sal_uLong nVal ) { nStartLastCut = nVal; }
598 sal_uLong GetStartLastCut() const { return nStartLastCut; }
599 void SetEndLastCut( sal_uLong nVal ) { nEndLastCut = nVal; }
600 sal_uLong GetEndLastCut() const { return nEndLastCut; }
602 virtual void UpdateReference( const ScChangeTrack*,
603 UpdateRefMode, const ScBigRange&,
604 sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz );
606 virtual bool Reject(ScDocument* pDoc);
608 virtual const ScChangeTrack* GetChangeTrack() const { return pTrack; }
610 protected:
611 using ScChangeAction::GetRefString;
613 public:
614 ScChangeActionMove(const sal_uLong nActionNumber,
615 const ScChangeActionState eState,
616 const sal_uLong nRejectingNumber,
617 const ScBigRange& aToBigRange,
618 const rtl::OUString& aUser,
619 const DateTime& aDateTime,
620 const rtl::OUString &sComment,
621 const ScBigRange& aFromBigRange,
622 ScChangeTrack* pTrack); // only to use in the XML import
624 const ScChangeActionCellListEntry* GetFirstCellEntry() const
625 { return pFirstCell; } // only to use in the XML export
627 const ScBigRange& GetFromRange() const { return aFromRange; }
628 SC_DLLPUBLIC void GetDelta( sal_Int32& nDx, sal_Int32& nDy, sal_Int32& nDz ) const;
630 virtual void GetDescription(
631 rtl::OUString& rStr, ScDocument* pDoc, bool bSplitRange = false,
632 bool bWarning = true ) const;
634 virtual void GetRefString(
635 rtl::OUString& rStr, ScDocument* pDoc, bool bFlag3D = false ) const;
639 // --- ScChangeActionContent ------------------------------------------------
641 enum ScChangeActionContentCellType
643 SC_CACCT_NONE = 0,
644 SC_CACCT_NORMAL,
645 SC_CACCT_MATORG,
646 SC_CACCT_MATREF
649 class ScChangeActionContent : public ScChangeAction
651 friend class ScChangeTrack;
653 rtl::OUString aOldValue;
654 rtl::OUString aNewValue;
655 ScBaseCell* pOldCell;
656 ScBaseCell* pNewCell;
657 ScChangeActionContent* pNextContent; // at the same position
658 ScChangeActionContent* pPrevContent;
659 ScChangeActionContent* pNextInSlot; // in the same slot
660 ScChangeActionContent** ppPrevInSlot;
662 void InsertInSlot( ScChangeActionContent** pp )
664 if ( !ppPrevInSlot )
666 ppPrevInSlot = pp;
667 if ( ( pNextInSlot = *pp ) != NULL )
668 pNextInSlot->ppPrevInSlot = &pNextInSlot;
669 *pp = this;
673 void RemoveFromSlot()
675 if ( ppPrevInSlot )
677 if ( ( *ppPrevInSlot = pNextInSlot ) != NULL )
678 pNextInSlot->ppPrevInSlot = ppPrevInSlot;
679 ppPrevInSlot = NULL; // not inserted
683 ScChangeActionContent* GetNextInSlot() { return pNextInSlot; }
685 void ClearTrack();
687 static void GetStringOfCell( rtl::OUString& rStr, const ScBaseCell* pCell,
688 const ScDocument* pDoc, const ScAddress& rPos );
690 static void GetStringOfCell( rtl::OUString& rStr, const ScBaseCell* pCell,
691 const ScDocument* pDoc, sal_uLong nFormat );
693 static void SetValue( rtl::OUString& rStr, ScBaseCell*& pCell, const ScAddress& rPos,
694 const ScBaseCell* pOrgCell, const ScDocument* pFromDoc,
695 ScDocument* pToDoc );
697 static void SetValue( rtl::OUString& rStr, ScBaseCell*& pCell, sal_uLong nFormat,
698 const ScBaseCell* pOrgCell, const ScDocument* pFromDoc,
699 ScDocument* pToDoc );
701 static void SetCell( rtl::OUString& rStr, ScBaseCell* pCell,
702 sal_uLong nFormat, const ScDocument* pDoc );
704 static bool NeedsNumberFormat( const ScBaseCell* );
706 void SetValueString( rtl::OUString& rValue, ScBaseCell*& pCell,
707 const rtl::OUString& rStr, ScDocument* pDoc );
709 void GetValueString( rtl::OUString& rStr, const rtl::OUString& rValue,
710 const ScBaseCell* pCell ) const;
712 void GetFormulaString( rtl::OUString& rStr, const ScFormulaCell* pCell ) const;
714 virtual void AddContent( ScChangeActionContent* ) {}
715 virtual void DeleteCellEntries() {}
717 virtual void UpdateReference( const ScChangeTrack*,
718 UpdateRefMode, const ScBigRange&,
719 sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz );
721 virtual bool Reject(ScDocument* pDoc);
723 virtual const ScChangeTrack* GetChangeTrack() const { return 0; }
725 // pRejectActions!=NULL: reject actions get
726 // stacked, no SetNewValue, no Append
727 bool Select( ScDocument*, ScChangeTrack*,
728 bool bOldest, ::std::stack<ScChangeActionContent*>* pRejectActions );
730 void PutValueToDoc(
731 ScBaseCell* pCell, const rtl::OUString& rValue, ScDocument* pDoc,
732 SCsCOL nDx, SCsROW nDy ) const;
734 protected:
735 using ScChangeAction::GetRefString;
737 public:
739 DECL_FIXEDMEMPOOL_NEWDEL( ScChangeActionContent )
741 ScChangeActionContent( const ScRange& rRange )
742 : ScChangeAction( SC_CAT_CONTENT, rRange ),
743 pOldCell( NULL ),
744 pNewCell( NULL ),
745 pNextContent( NULL ),
746 pPrevContent( NULL ),
747 pNextInSlot( NULL ),
748 ppPrevInSlot( NULL )
750 ScChangeActionContent(
751 const sal_uLong nActionNumber, const ScChangeActionState eState,
752 const sal_uLong nRejectingNumber, const ScBigRange& aBigRange,
753 const rtl::OUString& aUser, const DateTime& aDateTime,
754 const rtl::OUString &sComment, ScBaseCell* pOldCell,
755 ScDocument* pDoc, const rtl::OUString& sOldValue); // to use for XML Import
757 ScChangeActionContent(
758 const sal_uLong nActionNumber, ScBaseCell* pNewCell,
759 const ScBigRange& aBigRange, ScDocument* pDoc,
760 const rtl::OUString& sNewValue); // to use for XML Import of Generated Actions
762 virtual ~ScChangeActionContent();
764 ScChangeActionContent* GetNextContent() const { return pNextContent; }
765 ScChangeActionContent* GetPrevContent() const { return pPrevContent; }
766 ScChangeActionContent* GetTopContent() const;
767 bool IsTopContent() const { return pNextContent == NULL; }
769 virtual ScChangeActionLinkEntry* GetDeletedIn() const;
770 virtual ScChangeActionLinkEntry** GetDeletedInAddress();
772 void PutOldValueToDoc( ScDocument*,
773 SCsCOL nDx, SCsROW nDy ) const;
774 void PutNewValueToDoc( ScDocument*,
775 SCsCOL nDx, SCsROW nDy ) const;
777 void SetOldValue( const ScBaseCell*,
778 const ScDocument* pFromDoc,
779 ScDocument* pToDoc,
780 sal_uLong nFormat );
781 void SetOldValue( const ScBaseCell*,
782 const ScDocument* pFromDoc,
783 ScDocument* pToDoc );
784 void SetNewValue( const ScBaseCell*, ScDocument* );
786 // Used in import filter AppendContentOnTheFly,
787 // takes ownership of cells.
788 void SetOldNewCells( ScBaseCell* pOldCell,
789 sal_uLong nOldFormat, ScBaseCell* pNewCell,
790 sal_uLong nNewFormat, ScDocument* pDoc );
792 // Use this only in the XML import,
793 // takes ownership of cell.
794 void SetNewCell(
795 ScBaseCell* pCell, ScDocument* pDoc, const rtl::OUString& rFormatted );
797 // These functions should be protected but for
798 // the XML import they are public.
799 void SetNextContent( ScChangeActionContent* p )
800 { pNextContent = p; }
801 void SetPrevContent( ScChangeActionContent* p )
802 { pPrevContent = p; }
804 // don't use:
805 // assigns string / creates forumula cell
806 void SetOldValue( const rtl::OUString& rOld, ScDocument* pDoc );
808 void GetOldString( rtl::OUString& rStr ) const;
809 void GetNewString( rtl::OUString& rStr ) const;
810 const ScBaseCell* GetOldCell() const { return pOldCell; }
811 const ScBaseCell* GetNewCell() const { return pNewCell; }
812 virtual void GetDescription(
813 rtl::OUString& rStr, ScDocument* pDoc, bool bSplitRange = false, bool bWarning = true ) const;
815 virtual void GetRefString(
816 rtl::OUString& rStr, ScDocument* pDoc, bool bFlag3D = false ) const;
818 static ScChangeActionContentCellType GetContentCellType( const ScBaseCell* );
820 // NewCell
821 bool IsMatrixOrigin() const;
822 // OldCell
823 bool IsOldMatrixReference() const;
827 // --- ScChangeActionReject -------------------------------------------------
829 class ScChangeActionReject : public ScChangeAction
831 friend class ScChangeTrack;
832 friend class ScChangeActionContent;
834 ScChangeActionReject( sal_uLong nReject ) :
835 ScChangeAction( SC_CAT_REJECT, ScRange() )
837 SetRejectAction( nReject );
838 SetState( SC_CAS_ACCEPTED );
841 virtual void AddContent( ScChangeActionContent* ) {}
842 virtual void DeleteCellEntries() {}
844 virtual bool Reject(ScDocument* pDoc);
846 virtual const ScChangeTrack* GetChangeTrack() const { return 0; }
848 public:
849 ScChangeActionReject(const sal_uLong nActionNumber,
850 const ScChangeActionState eState,
851 const sal_uLong nRejectingNumber,
852 const ScBigRange& aBigRange,
853 const rtl::OUString& aUser,
854 const DateTime& aDateTime,
855 const rtl::OUString &sComment); // only to use in the XML import
859 // --- ScChangeTrack --------------------------------------------------------
861 enum ScChangeTrackMsgType
863 SC_CTM_NONE,
864 SC_CTM_APPEND, // Actions appended
865 SC_CTM_REMOVE, // Actions removed
866 SC_CTM_CHANGE, // Actions changed
867 SC_CTM_PARENT // became a parent (and wasn't before)
870 struct ScChangeTrackMsgInfo
872 DECL_FIXEDMEMPOOL_NEWDEL( ScChangeTrackMsgInfo )
874 ScChangeTrackMsgType eMsgType;
875 sal_uLong nStartAction;
876 sal_uLong nEndAction;
879 // MsgQueue for notification via ModifiedLink
880 typedef std::deque<ScChangeTrackMsgInfo*> ScChangeTrackMsgQueue;
881 typedef std::stack<ScChangeTrackMsgInfo*> ScChangeTrackMsgStack;
882 typedef std::map<sal_uLong, ScChangeAction*> ScChangeActionMap;
884 enum ScChangeTrackMergeState
886 SC_CTMS_NONE,
887 SC_CTMS_PREPARE,
888 SC_CTMS_OWN,
889 SC_CTMS_UNDO,
890 SC_CTMS_OTHER
893 // Internally generated actions start at this value (nearly all bits set)
894 // and are decremented, to keep values in a table seperated from "normal" actions.
895 #define SC_CHGTRACK_GENERATED_START ((sal_uInt32) 0xfffffff0)
897 class ScChangeTrack : public utl::ConfigurationListener
899 friend void ScChangeAction::RejectRestoreContents( ScChangeTrack*, SCsCOL, SCsROW );
900 friend bool ScChangeActionDel::Reject( ScDocument* pDoc );
901 friend void ScChangeActionDel::DeleteCellEntries();
902 friend void ScChangeActionMove::DeleteCellEntries();
903 friend bool ScChangeActionMove::Reject( ScDocument* pDoc );
905 static const SCROW nContentRowsPerSlot;
906 static const SCSIZE nContentSlots;
908 com::sun::star::uno::Sequence< sal_Int8 > aProtectPass;
909 ScChangeActionMap aMap;
910 ScChangeActionMap aGeneratedMap;
911 ScChangeActionMap aPasteCutMap;
912 ScChangeTrackMsgQueue aMsgQueue;
913 ScChangeTrackMsgStack aMsgStackTmp;
914 ScChangeTrackMsgStack aMsgStackFinal;
915 std::set<rtl::OUString> maUserCollection;
916 rtl::OUString maUser;
917 Link aModifiedLink;
918 ScRange aInDeleteRange;
919 DateTime aFixDateTime;
920 ScChangeAction* pFirst;
921 ScChangeAction* pLast;
922 ScChangeActionContent* pFirstGeneratedDelContent;
923 ScChangeActionContent** ppContentSlots;
924 ScChangeActionMove* pLastCutMove;
925 ScChangeActionLinkEntry* pLinkInsertCol;
926 ScChangeActionLinkEntry* pLinkInsertRow;
927 ScChangeActionLinkEntry* pLinkInsertTab;
928 ScChangeActionLinkEntry* pLinkMove;
929 ScChangeTrackMsgInfo* pBlockModifyMsg;
930 ScDocument* pDoc;
931 sal_uLong nActionMax;
932 sal_uLong nGeneratedMin;
933 sal_uLong nMarkLastSaved;
934 sal_uLong nStartLastCut;
935 sal_uLong nEndLastCut;
936 sal_uLong nLastMerge;
937 ScChangeTrackMergeState eMergeState;
938 sal_uInt16 nLoadedFileFormatVersion;
939 bool bLoadSave:1;
940 bool bInDelete:1;
941 bool bInDeleteUndo:1;
942 bool bInDeleteTop:1;
943 bool bInPasteCut:1;
944 bool bUseFixDateTime:1;
945 bool bTime100thSeconds:1;
947 // not implemented, prevent usage
948 ScChangeTrack( const ScChangeTrack& );
949 ScChangeTrack& operator=( const ScChangeTrack& );
951 #ifdef SC_CHGTRACK_CXX
952 static SCROW InitContentRowsPerSlot();
954 // true if one is MM_FORMULA and the other is
955 // not, or if both are and range differs
956 static bool IsMatrixFormulaRangeDifferent(
957 const ScBaseCell* pOldCell, const ScBaseCell* pNewCell );
959 void Init();
960 void DtorClear();
961 void SetLoadSave( bool bVal ) { bLoadSave = bVal; }
962 void SetInDeleteRange( const ScRange& rRange )
963 { aInDeleteRange = rRange; }
964 void SetInDelete( bool bVal )
965 { bInDelete = bVal; }
966 void SetInDeleteTop( bool bVal )
967 { bInDeleteTop = bVal; }
968 void SetInDeleteUndo( bool bVal )
969 { bInDeleteUndo = bVal; }
970 void SetInPasteCut( bool bVal )
971 { bInPasteCut = bVal; }
972 void SetMergeState( ScChangeTrackMergeState eState )
973 { eMergeState = eState; }
974 ScChangeTrackMergeState GetMergeState() const { return eMergeState; }
975 void SetLastMerge( sal_uLong nVal ) { nLastMerge = nVal; }
976 sal_uLong GetLastMerge() const { return nLastMerge; }
978 void SetLastCutMoveRange( const ScRange&, ScDocument* );
980 // create block of ModifyMsg
981 void StartBlockModify( ScChangeTrackMsgType,
982 sal_uLong nStartAction );
983 void EndBlockModify( sal_uLong nEndAction );
985 void AddDependentWithNotify( ScChangeAction* pParent,
986 ScChangeAction* pDependent );
988 void Dependencies( ScChangeAction* );
989 void UpdateReference( ScChangeAction*, bool bUndo );
990 void UpdateReference( ScChangeAction** ppFirstAction, ScChangeAction* pAct, bool bUndo );
991 void Append( ScChangeAction* pAppend, sal_uLong nAction );
992 SC_DLLPUBLIC void AppendDeleteRange( const ScRange&,
993 ScDocument* pRefDoc, SCsTAB nDz,
994 sal_uLong nRejectingInsert );
995 void AppendOneDeleteRange( const ScRange& rOrgRange,
996 ScDocument* pRefDoc,
997 SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
998 sal_uLong nRejectingInsert );
999 void LookUpContents( const ScRange& rOrgRange,
1000 ScDocument* pRefDoc,
1001 SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
1002 void Remove( ScChangeAction* );
1003 void MasterLinks( ScChangeAction* );
1005 // Content on top an Position
1006 ScChangeActionContent* SearchContentAt( const ScBigAddress&,
1007 ScChangeAction* pButNotThis ) const;
1008 void DeleteGeneratedDelContent(
1009 ScChangeActionContent* );
1010 ScChangeActionContent* GenerateDelContent( const ScAddress&,
1011 const ScBaseCell*,
1012 const ScDocument* pFromDoc );
1013 void DeleteCellEntries(
1014 ScChangeActionCellListEntry*&,
1015 ScChangeAction* pDeletor );
1017 // Reject action and all dependent actions,
1018 // Table stems from previous GetDependents,
1019 // only needed for Insert and Move (MasterType),
1020 // is NULL otherwise.
1021 // bRecursion == called from reject with table
1022 bool Reject( ScChangeAction*, ScChangeActionMap*, bool bRecursion );
1024 #endif // SC_CHGTRACK_CXX
1026 void ClearMsgQueue();
1027 virtual void ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 );
1029 public:
1031 static SCSIZE ComputeContentSlot( sal_Int32 nRow )
1033 if ( nRow < 0 || nRow > MAXROW )
1034 return nContentSlots - 1;
1035 return static_cast< SCSIZE >( nRow / nContentRowsPerSlot );
1038 SC_DLLPUBLIC ScChangeTrack( ScDocument* );
1039 ScChangeTrack(ScDocument* pDocP, const std::set<rtl::OUString>& aTempUserCollection); // only to use in the XML import
1040 SC_DLLPUBLIC virtual ~ScChangeTrack();
1041 void Clear();
1043 ScChangeActionContent* GetFirstGenerated() const { return pFirstGeneratedDelContent; }
1044 ScChangeAction* GetFirst() const { return pFirst; }
1045 ScChangeAction* GetLast() const { return pLast; }
1046 sal_uLong GetActionMax() const { return nActionMax; }
1047 bool IsGenerated( sal_uLong nAction ) const
1048 { return nAction >= nGeneratedMin; }
1049 ScChangeAction* GetAction( sal_uLong nAction ) const
1051 ScChangeActionMap::const_iterator it = aMap.find( nAction );
1052 if( it != aMap.end() )
1053 return it->second;
1054 else
1055 return NULL;
1057 ScChangeAction* GetGenerated( sal_uLong nGenerated ) const
1059 ScChangeActionMap::const_iterator it = aGeneratedMap.find( nGenerated );
1060 if( it != aGeneratedMap.end() )
1061 return it->second;
1062 else
1063 return NULL;
1065 ScChangeAction* GetActionOrGenerated( sal_uLong nAction ) const
1067 return IsGenerated( nAction ) ?
1068 GetGenerated( nAction ) :
1069 GetAction( nAction );
1071 sal_uLong GetLastSavedActionNumber() const
1072 { return nMarkLastSaved; }
1073 void SetLastSavedActionNumber(sal_uLong nNew)
1074 { nMarkLastSaved = nNew; }
1075 ScChangeAction* GetLastSaved() const
1077 ScChangeActionMap::const_iterator it = aMap.find( nMarkLastSaved );
1078 if( it != aMap.end() )
1079 return it->second;
1080 else
1081 return NULL;
1083 ScChangeActionContent** GetContentSlots() const { return ppContentSlots; }
1085 bool IsLoadSave() const { return bLoadSave; }
1086 const ScRange& GetInDeleteRange() const
1087 { return aInDeleteRange; }
1088 bool IsInDelete() const { return bInDelete; }
1089 bool IsInDeleteTop() const { return bInDeleteTop; }
1090 bool IsInDeleteUndo() const { return bInDeleteUndo; }
1091 bool IsInPasteCut() const { return bInPasteCut; }
1092 SC_DLLPUBLIC void SetUser( const rtl::OUString& rUser );
1093 SC_DLLPUBLIC const rtl::OUString& GetUser() const;
1094 SC_DLLPUBLIC const std::set<rtl::OUString>& GetUserCollection() const;
1095 ScDocument* GetDocument() const { return pDoc; }
1096 // for import filter
1097 const DateTime& GetFixDateTime() const { return aFixDateTime; }
1099 // set this if the date/time set with
1100 // SetFixDateTime...() shall be applied to
1101 // appended actions
1102 void SetUseFixDateTime( bool bVal )
1103 { bUseFixDateTime = bVal; }
1104 // for MergeDocument, apply original date/time as UTC
1105 void SetFixDateTimeUTC( const DateTime& rDT )
1106 { aFixDateTime = rDT; }
1107 // for import filter, apply original date/time as local time
1108 void SetFixDateTimeLocal( const DateTime& rDT )
1109 { aFixDateTime = rDT; aFixDateTime.ConvertToUTC(); }
1111 void Append( ScChangeAction* );
1113 // pRefDoc may be NULL => no lookup of contents
1114 // => no generation of deleted contents
1115 SC_DLLPUBLIC void AppendDeleteRange( const ScRange&,
1116 ScDocument* pRefDoc,
1117 sal_uLong& nStartAction, sal_uLong& nEndAction,
1118 SCsTAB nDz = 0 );
1119 // nDz: multi TabDel, LookUpContent must be searched
1120 // with an offset of -nDz
1122 // after new value was set in the document,
1123 // old value from RefDoc/UndoDoc
1124 void AppendContent( const ScAddress& rPos,
1125 ScDocument* pRefDoc );
1126 // after new values were set in the document,
1127 // old values from RefDoc/UndoDoc
1128 void AppendContentRange( const ScRange& rRange,
1129 ScDocument* pRefDoc,
1130 sal_uLong& nStartAction, sal_uLong& nEndAction,
1131 ScChangeActionClipMode eMode = SC_CACM_NONE );
1132 // after new value was set in the document,
1133 // old value from pOldCell, nOldFormat,
1134 // RefDoc==NULL => Doc
1135 void AppendContent( const ScAddress& rPos,
1136 const ScBaseCell* pOldCell,
1137 sal_uLong nOldFormat, ScDocument* pRefDoc = NULL );
1138 // after new value was set in the document,
1139 // old value from pOldCell, format from Doc
1140 void AppendContent( const ScAddress& rPos,
1141 const ScBaseCell* pOldCell );
1142 // after new values were set in the document,
1143 // old values from RefDoc/UndoDoc.
1144 // All contents with a cell in RefDoc
1145 void AppendContentsIfInRefDoc( ScDocument* pRefDoc,
1146 sal_uLong& nStartAction, sal_uLong& nEndAction );
1148 // Meant for import filter, creates and inserts
1149 // an unconditional content action of the two
1150 // cells without querying the document, not
1151 // even for number formats (though the number
1152 // formatter of the document may be used).
1153 // The action is returned and may be used to
1154 // set user name, description, date/time et al.
1155 // Takes ownership of the cells!
1156 SC_DLLPUBLIC ScChangeActionContent* AppendContentOnTheFly( const ScAddress& rPos,
1157 ScBaseCell* pOldCell,
1158 ScBaseCell* pNewCell,
1159 sal_uLong nOldFormat = 0,
1160 sal_uLong nNewFormat = 0 );
1162 // Only use the following two if there is no different solution! (Assign
1163 // string for NewValue or creation of a formula respectively)
1165 SC_DLLPUBLIC void AppendInsert( const ScRange& );
1167 // pRefDoc may be NULL => no lookup of contents
1168 // => no generation of deleted contents
1169 SC_DLLPUBLIC void AppendMove( const ScRange& rFromRange, const ScRange& rToRange,
1170 ScDocument* pRefDoc );
1172 // Cut to Clipboard
1173 void ResetLastCut()
1175 nStartLastCut = nEndLastCut = 0;
1176 if ( pLastCutMove )
1178 delete pLastCutMove;
1179 pLastCutMove = NULL;
1182 bool HasLastCut() const
1184 return nEndLastCut > 0 &&
1185 nStartLastCut <= nEndLastCut &&
1186 pLastCutMove;
1189 SC_DLLPUBLIC void Undo( sal_uLong nStartAction, sal_uLong nEndAction, bool bMerge = false );
1191 // adjust references for MergeDocument
1192 //! may only be used in a temporary opened document.
1193 //! the Track (?) is unclean afterwards
1194 void MergePrepare( ScChangeAction* pFirstMerge, bool bShared = false );
1195 void MergeOwn( ScChangeAction* pAct, sal_uLong nFirstMerge, bool bShared = false );
1196 static bool MergeIgnore( const ScChangeAction&, sal_uLong nFirstMerge );
1198 // This comment was already really strange in German.
1199 // Tried to structure it a little. Hope no information got lost...
1201 // Insert dependents into table.
1202 // ScChangeAction is
1203 // - "Insert": really dependents
1204 // - "Move": dependent contents in FromRange /
1205 // deleted contents in ToRange
1206 // OR inserts in FromRange or ToRange
1207 // - "Delete": a list of deleted (what?)
1208 // OR for content, different contents at the same position
1209 // OR MatrixReferences belonging to MatrixOrigin
1211 // With bListMasterDelete (==TRUE ?) all Deletes of a row belonging
1212 // to a MasterDelete are listed (possibly it is
1213 // "all Deletes belonging...are listed in a row?)
1215 // With bAllFlat (==TRUE ?) all dependents of dependents
1216 // will be inserted flatly.
1218 SC_DLLPUBLIC void GetDependents(
1219 ScChangeAction*, ScChangeActionMap&, bool bListMasterDelete = false, bool bAllFlat = false ) const;
1221 // Reject visible action (and dependents)
1222 bool Reject( ScChangeAction*, bool bShared = false );
1224 // Accept visible action (and dependents)
1225 SC_DLLPUBLIC bool Accept( ScChangeAction* );
1227 void AcceptAll(); // all Virgins
1228 bool RejectAll(); // all Virgins
1230 // Selects a content of several contents at the same
1231 // position and accepts this one and
1232 // the older ones, rejects the more recent ones.
1233 // If bOldest==TRUE then the first OldValue
1234 // of a Virgin-Content-List will be restored.
1235 bool SelectContent( ScChangeAction*, bool bOldest = false );
1237 // If ModifiedLink is set, changes go to
1238 // ScChangeTrackMsgQueue
1239 void SetModifiedLink( const Link& r )
1240 { aModifiedLink = r; ClearMsgQueue(); }
1241 const Link& GetModifiedLink() const { return aModifiedLink; }
1242 ScChangeTrackMsgQueue& GetMsgQueue() { return aMsgQueue; }
1244 void NotifyModified( ScChangeTrackMsgType eMsgType,
1245 sal_uLong nStartAction, sal_uLong nEndAction );
1247 sal_uInt16 GetLoadedFileFormatVersion() const
1248 { return nLoadedFileFormatVersion; }
1250 sal_uLong AddLoadedGenerated(
1251 ScBaseCell* pOldCell, const ScBigRange& aBigRange, const rtl::OUString& sNewValue ); // only to use in the XML import
1252 void AppendLoaded( ScChangeAction* pAppend ); // this is only for the XML import public, it should be protected
1253 void SetActionMax(sal_uLong nTempActionMax)
1254 { nActionMax = nTempActionMax; } // only to use in the XML import
1256 void SetProtection( const com::sun::star::uno::Sequence< sal_Int8 >& rPass )
1257 { aProtectPass = rPass; }
1258 com::sun::star::uno::Sequence< sal_Int8 > GetProtection() const
1259 { return aProtectPass; }
1260 bool IsProtected() const { return aProtectPass.getLength() != 0; }
1262 // If time stamps of actions of this
1263 // ChangeTrack and a second one are to be
1264 // compared including 100th seconds.
1265 void SetTime100thSeconds( bool bVal ) { bTime100thSeconds = bVal; }
1266 bool IsTime100thSeconds() const { return bTime100thSeconds; }
1268 void AppendCloned( ScChangeAction* pAppend );
1269 SC_DLLPUBLIC ScChangeTrack* Clone( ScDocument* pDocument ) const;
1270 void MergeActionState( ScChangeAction* pAct, const ScChangeAction* pOtherAct );
1274 #endif
1277 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */