Show duplicate attribute
[LibreOffice.git] / sc / inc / chgtrack.hxx
blob6599d841b95ae7361e85dcf4dae2e8b5b99ba007
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 INCLUDED_SC_INC_CHGTRACK_HXX
21 #define INCLUDED_SC_INC_CHGTRACK_HXX
23 #include <deque>
24 #include <map>
25 #include <set>
26 #include <stack>
28 #include <tools/color.hxx>
29 #include <tools/datetime.hxx>
30 #include <tools/link.hxx>
31 #include <tools/mempool.hxx>
32 #include <unotools/options.hxx>
33 #include "global.hxx"
34 #include "bigrange.hxx"
35 #include "scdllapi.h"
36 #include "cellvalue.hxx"
38 class ScDocument;
39 class ScFormulaCell;
40 class ScChangeAction;
41 class ScChangeTrack;
42 class ScAppOptions;
44 class ScActionColorChanger
46 private:
47 const ScAppOptions& rOpt;
48 const std::set<OUString>& rUsers;
49 OUString aLastUserName;
50 sal_uInt16 nLastUserIndex;
51 ColorData nColor;
53 public:
54 ScActionColorChanger( const ScChangeTrack& rTrack );
55 ~ScActionColorChanger() {}
56 void Update( const ScChangeAction& rAction );
57 ColorData GetColor() const { return nColor; }
60 enum ScChangeActionType
62 SC_CAT_NONE,
63 SC_CAT_INSERT_COLS,
64 SC_CAT_INSERT_ROWS,
65 SC_CAT_INSERT_TABS,
66 SC_CAT_DELETE_COLS,
67 SC_CAT_DELETE_ROWS,
68 SC_CAT_DELETE_TABS,
69 SC_CAT_MOVE,
70 SC_CAT_CONTENT,
71 SC_CAT_REJECT
74 enum ScChangeActionState
76 SC_CAS_VIRGIN,
77 SC_CAS_ACCEPTED,
78 SC_CAS_REJECTED
81 enum ScChangeActionClipMode
83 SC_CACM_NONE,
84 SC_CACM_CUT,
85 SC_CACM_COPY,
86 SC_CACM_PASTE
89 // ScChangeActionLinkEntry
90 // Inserts itself as the head of a chain (better: linked list?), or before a LinkEntry
91 // on delete: automatically remove of what is linked (German original was strange...)
92 // ppPrev == &previous->pNext oder address of pointer to head of linked list,
93 // *ppPrev == this
95 class ScChangeAction;
97 class ScChangeActionLinkEntry
99 ScChangeActionLinkEntry( const ScChangeActionLinkEntry& ) SAL_DELETED_FUNCTION;
100 ScChangeActionLinkEntry& operator=( const ScChangeActionLinkEntry& ) SAL_DELETED_FUNCTION;
102 protected:
104 ScChangeActionLinkEntry* pNext;
105 ScChangeActionLinkEntry** ppPrev;
106 ScChangeAction* pAction;
107 ScChangeActionLinkEntry* pLink;
109 public:
111 DECL_FIXEDMEMPOOL_NEWDEL( ScChangeActionLinkEntry )
113 ScChangeActionLinkEntry(
114 ScChangeActionLinkEntry** ppPrevP,
115 ScChangeAction* pActionP )
116 : pNext( *ppPrevP ),
117 ppPrev( ppPrevP ),
118 pAction( pActionP ),
119 pLink( NULL )
121 if ( pNext )
122 pNext->ppPrev = &pNext;
123 *ppPrevP = this;
126 virtual ~ScChangeActionLinkEntry()
128 ScChangeActionLinkEntry* p = pLink;
129 UnLink();
130 Remove();
131 if ( p )
132 delete p;
135 void SetLink( ScChangeActionLinkEntry* pLinkP )
137 UnLink();
138 if ( pLinkP )
140 pLink = pLinkP;
141 pLinkP->pLink = this;
145 void UnLink()
147 if ( pLink )
149 pLink->pLink = NULL;
150 pLink = NULL;
154 void Remove()
156 if ( ppPrev )
158 if ( ( *ppPrev = pNext ) != NULL )
159 pNext->ppPrev = ppPrev;
160 ppPrev = NULL; // not inserted
164 void Insert( ScChangeActionLinkEntry** ppPrevP )
166 if ( !ppPrev )
168 ppPrev = ppPrevP;
169 if ( (pNext = *ppPrevP) )
170 pNext->ppPrev = &pNext;
171 *ppPrevP = this;
175 const ScChangeActionLinkEntry* GetLink() const { return pLink; }
176 ScChangeActionLinkEntry* GetLink() { return pLink; }
177 const ScChangeActionLinkEntry* GetNext() const { return pNext; }
178 ScChangeActionLinkEntry* GetNext() { return pNext; }
179 const ScChangeAction* GetAction() const { return pAction; }
180 ScChangeAction* GetAction() { return pAction; }
183 // ScChangeActionCellListEntry
184 // this is only for the XML Export in the hxx
185 class ScChangeActionContent;
187 class ScChangeActionCellListEntry
189 friend class ScChangeAction;
190 friend class ScChangeActionDel;
191 friend class ScChangeActionMove;
192 friend class ScChangeTrack;
194 ScChangeActionCellListEntry* pNext;
195 ScChangeActionContent* pContent;
197 ScChangeActionCellListEntry(
198 ScChangeActionContent* pContentP,
199 ScChangeActionCellListEntry* pNextP )
200 : pNext( pNextP ),
201 pContent( pContentP )
204 public:
205 const ScChangeActionCellListEntry* GetNext() const { return pNext; } // this is only for the XML Export public
206 const ScChangeActionContent* GetContent() const { return pContent; } // this is only for the XML Export public
208 DECL_FIXEDMEMPOOL_NEWDEL( ScChangeActionCellListEntry )
211 // ScChangeAction
212 class ScChangeTrack;
213 class ScChangeActionIns;
214 class ScChangeActionDel;
215 class ScChangeActionContent;
217 class ScChangeAction
219 friend class ScChangeTrack;
220 friend class ScChangeActionIns;
221 friend class ScChangeActionDel;
222 friend class ScChangeActionMove;
223 friend class ScChangeActionContent;
225 ScChangeAction( const ScChangeAction& ) SAL_DELETED_FUNCTION;
226 ScChangeAction& operator=( const ScChangeAction& ) SAL_DELETED_FUNCTION;
228 protected:
230 ScBigRange aBigRange; // Ins/Del/MoveTo/ContentPos
231 DateTime aDateTime; //! UTC
232 OUString aUser; // who?
233 OUString aComment; // user comment
234 ScChangeAction* pNext; // next in linked list
235 ScChangeAction* pPrev; // previous in linked list
236 ScChangeActionLinkEntry* pLinkAny; // arbitrary links
237 ScChangeActionLinkEntry* pLinkDeletedIn; // access to insert areas which were
238 // deleted or moved or rejected
239 ScChangeActionLinkEntry* pLinkDeleted; // links to deleted
240 ScChangeActionLinkEntry* pLinkDependent; // links to dependent
241 sal_uLong nAction;
242 sal_uLong nRejectAction;
243 ScChangeActionType eType;
244 ScChangeActionState eState;
246 ScChangeAction( ScChangeActionType, const ScRange& );
248 // only to be used in the XML import
249 ScChangeAction( ScChangeActionType,
250 const ScBigRange&,
251 const sal_uLong nAction,
252 const sal_uLong nRejectAction,
253 const ScChangeActionState eState,
254 const DateTime& aDateTime,
255 const OUString& aUser,
256 const OUString& aComment );
258 // only to be used in the XML import
259 ScChangeAction( ScChangeActionType, const ScBigRange&, const sal_uLong nAction);
261 virtual ~ScChangeAction();
263 OUString GetRefString(
264 const ScBigRange& rRange, ScDocument* pDoc, bool bFlag3D = false) const;
266 void SetActionNumber( sal_uLong n ) { nAction = n; }
267 void SetRejectAction( sal_uLong n ) { nRejectAction = n; }
268 void SetUser( const OUString& r );
269 void SetType( ScChangeActionType e ) { eType = e; }
270 void SetState( ScChangeActionState e ) { eState = e; }
271 void SetRejected();
273 ScBigRange& GetBigRange() { return aBigRange; }
275 ScChangeActionLinkEntry* AddLink(
276 ScChangeAction* p, ScChangeActionLinkEntry* pL )
278 ScChangeActionLinkEntry* pLnk =
279 new ScChangeActionLinkEntry(
280 &pLinkAny, p );
281 pLnk->SetLink( pL );
282 return pLnk;
285 void RemoveAllAnyLinks();
287 virtual ScChangeActionLinkEntry* GetDeletedIn() const
288 { return pLinkDeletedIn; }
289 virtual ScChangeActionLinkEntry** GetDeletedInAddress()
290 { return &pLinkDeletedIn; }
291 ScChangeActionLinkEntry* AddDeletedIn( ScChangeAction* p )
293 return new ScChangeActionLinkEntry(
294 GetDeletedInAddress(), p );
297 bool RemoveDeletedIn( const ScChangeAction* );
298 void SetDeletedIn( ScChangeAction* );
300 ScChangeActionLinkEntry* AddDeleted( ScChangeAction* p )
302 return new ScChangeActionLinkEntry(&pLinkDeleted, p);
305 void RemoveAllDeleted();
307 ScChangeActionLinkEntry* AddDependent( ScChangeAction* p )
309 return new ScChangeActionLinkEntry(&pLinkDependent, p);
312 void RemoveAllDependent();
314 void RemoveAllLinks();
316 virtual void AddContent( ScChangeActionContent* ) = 0;
317 virtual void DeleteCellEntries() = 0;
319 virtual void UpdateReference( const ScChangeTrack*,
320 UpdateRefMode, const ScBigRange&,
321 sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz );
323 void Accept();
324 virtual bool Reject(ScDocument* pDoc) = 0;
325 void RejectRestoreContents( ScChangeTrack*, SCsCOL nDx, SCsROW nDy );
327 // used in Reject() instead of IsRejectable()
328 bool IsInternalRejectable() const;
330 // Derived classes that hold a pointer to the
331 // ChangeTrack must return that. Otherwise NULL.
332 virtual const ScChangeTrack* GetChangeTrack() const = 0;
334 public:
335 bool IsInsertType() const;
336 bool IsDeleteType() const;
337 bool IsVirgin() const;
338 SC_DLLPUBLIC bool IsAccepted() const;
339 bool IsRejected() const;
341 // Action rejects another Action
342 bool IsRejecting() const;
344 // if action is visible in the document
345 bool IsVisible() const;
347 // if action if touchable
348 bool IsTouchable() const;
350 // if action is an entry in dialog root
351 bool IsDialogRoot() const;
353 // if an entry in a dialog shall be a drop down entry
354 bool IsDialogParent() const;
356 // if action is a delete with subdeletes (aufgeklappt = open ?)
357 bool IsMasterDelete() const;
359 // if action is acceptable/selectable/rejectable
360 bool IsClickable() const;
362 // if action is rejectable
363 bool IsRejectable() const;
365 const ScBigRange& GetBigRange() const { return aBigRange; }
366 SC_DLLPUBLIC DateTime GetDateTime() const; // local time
367 const DateTime& GetDateTimeUTC() const // UTC time
368 { return aDateTime; }
369 ScChangeActionType GetType() const { return eType; }
370 ScChangeActionState GetState() const { return eState; }
371 sal_uLong GetActionNumber() const { return nAction; }
372 sal_uLong GetRejectAction() const { return nRejectAction; }
374 ScChangeAction* GetNext() const { return pNext; }
375 ScChangeAction* GetPrev() const { return pPrev; }
377 bool IsDeletedIn() const;
378 bool IsDeletedIn( const ScChangeAction* ) const;
379 bool IsDeletedInDelType( ScChangeActionType ) const;
380 void RemoveAllDeletedIn();
382 const ScChangeActionLinkEntry* GetFirstDeletedEntry() const
383 { return pLinkDeleted; }
384 const ScChangeActionLinkEntry* GetFirstDependentEntry() const
385 { return pLinkDependent; }
386 bool HasDependent() const;
387 bool HasDeleted() const;
388 // description will be appended to string
389 // with bSplitRange only one column/row will be considered for delete
390 // (for a listing of entries)
391 virtual void GetDescription(
392 OUString& rStr, ScDocument* pDoc,
393 bool bSplitRange = false, bool bWarning = true ) const;
395 virtual void GetRefString(
396 OUString& rStr, ScDocument* pDoc, bool bFlag3D = false ) const;
398 // for DocumentMerge set old date of the other
399 // action, fetched by GetDateTimeUTC
400 void SetDateTimeUTC( const DateTime& rDT )
401 { aDateTime = rDT; }
403 const OUString& GetUser() const { return aUser;}
404 const OUString& GetComment() const { return aComment;}
406 // set user comment
407 void SetComment( const OUString& rStr );
409 // only to be used in the XML import
410 void SetDeletedInThis( sal_uLong nActionNumber,
411 const ScChangeTrack* pTrack );
412 // only to be used in the XML import
413 void AddDependent( sal_uLong nActionNumber,
414 const ScChangeTrack* pTrack );
417 // ScChangeActionIns
418 class ScChangeActionIns : public ScChangeAction
420 friend class ScChangeTrack;
422 bool mbEndOfList; /// whether or not a row was auto-inserted at the bottom.
424 ScChangeActionIns( const ScRange& rRange, bool bEndOfList = false );
425 virtual ~ScChangeActionIns();
427 virtual void AddContent( ScChangeActionContent* ) SAL_OVERRIDE {}
428 virtual void DeleteCellEntries() SAL_OVERRIDE {}
430 virtual bool Reject(ScDocument* pDoc) SAL_OVERRIDE;
432 virtual const ScChangeTrack* GetChangeTrack() const SAL_OVERRIDE { return 0; }
434 public:
435 ScChangeActionIns(
436 const sal_uLong nActionNumber,
437 const ScChangeActionState eState,
438 const sal_uLong nRejectingNumber,
439 const ScBigRange& aBigRange,
440 const OUString& aUser,
441 const DateTime& aDateTime,
442 const OUString &sComment,
443 const ScChangeActionType eType,
444 bool bEndOfList = false );
446 virtual void GetDescription(
447 OUString& rStr, ScDocument* pDoc, bool bSplitRange = false, bool bWarning = true) const SAL_OVERRIDE;
449 SC_DLLPUBLIC bool IsEndOfList() const;
452 // ScChangeActionDel
453 class ScChangeActionMove;
455 class ScChangeActionDelMoveEntry : public ScChangeActionLinkEntry
457 friend class ScChangeActionDel;
458 friend class ScChangeTrack;
460 short nCutOffFrom;
461 short nCutOffTo;
463 inline ScChangeActionDelMoveEntry(
464 ScChangeActionDelMoveEntry** ppPrevP,
465 ScChangeActionMove* pMove,
466 short nFrom, short nTo );
468 ScChangeActionDelMoveEntry* GetNext()
470 return static_cast<ScChangeActionDelMoveEntry*>(
471 ScChangeActionLinkEntry::GetNext());
473 inline ScChangeActionMove* GetMove();
475 public:
476 const ScChangeActionDelMoveEntry* GetNext() const
478 return static_cast<const ScChangeActionDelMoveEntry*>(
479 ScChangeActionLinkEntry::GetNext());
481 inline const ScChangeActionMove* GetMove() const;
482 short GetCutOffFrom() const { return nCutOffFrom; }
483 short GetCutOffTo() const { return nCutOffTo; }
486 class ScChangeActionDel : public ScChangeAction
488 friend class ScChangeTrack;
489 friend void ScChangeAction::Accept();
491 ScChangeTrack* pTrack;
492 ScChangeActionCellListEntry* pFirstCell;
493 ScChangeActionIns* pCutOff; // cut insert
494 short nCutOff; // +: start -: end
495 ScChangeActionDelMoveEntry* pLinkMove;
496 SCsCOL nDx;
497 SCsROW nDy;
499 ScChangeActionDel( const ScRange& rRange, SCsCOL nDx, SCsROW nDy, ScChangeTrack* );
500 virtual ~ScChangeActionDel();
502 ScChangeActionIns* GetCutOffInsert() { return pCutOff; }
504 virtual void AddContent( ScChangeActionContent* ) SAL_OVERRIDE;
505 virtual void DeleteCellEntries() SAL_OVERRIDE;
507 void UndoCutOffMoves();
508 void UndoCutOffInsert();
510 virtual void UpdateReference( const ScChangeTrack*,
511 UpdateRefMode, const ScBigRange&,
512 sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz ) SAL_OVERRIDE;
514 virtual bool Reject(ScDocument* pDoc) SAL_OVERRIDE;
516 virtual const ScChangeTrack* GetChangeTrack() const SAL_OVERRIDE { return pTrack; }
518 public:
519 ScChangeActionDel(
520 const sal_uLong nActionNumber, const ScChangeActionState eState,
521 const sal_uLong nRejectingNumber, const ScBigRange& aBigRange,
522 const OUString& aUser, const DateTime& aDateTime,
523 const OUString &sComment, const ScChangeActionType eType,
524 const SCsCOLROW nD, ScChangeTrack* pTrack); // only to use in the XML import
525 // which of nDx and nDy is set is dependent on the type
527 // is the last in a row (or single)
528 bool IsBaseDelete() const;
530 // is the first in a row (or single)
531 bool IsTopDelete() const;
533 // is part of a row
534 bool IsMultiDelete() const;
536 // is col, belonging to a TabDelete
537 bool IsTabDeleteCol() const;
539 SCsCOL GetDx() const { return nDx; }
540 SCsROW GetDy() const { return nDy; }
541 ScBigRange GetOverAllRange() const; // BigRange + (nDx, nDy)
543 const ScChangeActionCellListEntry* GetFirstCellEntry() const
544 { return pFirstCell; }
545 const ScChangeActionDelMoveEntry* GetFirstMoveEntry() const
546 { return pLinkMove; }
547 const ScChangeActionIns* GetCutOffInsert() const { return pCutOff; }
548 short GetCutOffCount() const { return nCutOff; }
550 virtual void GetDescription(
551 OUString& rStr, ScDocument* pDoc, bool bSplitRange = false, bool bWarning = true ) const SAL_OVERRIDE;
553 void SetCutOffInsert( ScChangeActionIns* p, short n )
554 { pCutOff = p; nCutOff = n; } // only to use in the XML import
555 // this should be protected, but for the XML import it is public
556 // only to use in the XML import
557 // this should be protected, but for the XML import it is public
558 ScChangeActionDelMoveEntry* AddCutOffMove(
559 ScChangeActionMove* pMove, short nFrom, short nTo );
562 // ScChangeActionMove
563 class ScChangeActionMove : public ScChangeAction
565 friend class ScChangeTrack;
566 friend class ScChangeActionDel;
568 ScBigRange aFromRange;
569 ScChangeTrack* pTrack;
570 ScChangeActionCellListEntry* pFirstCell;
571 sal_uLong nStartLastCut; // for PasteCut undo
572 sal_uLong nEndLastCut;
574 ScChangeActionMove( const ScRange& rFromRange,
575 const ScRange& rToRange,
576 ScChangeTrack* pTrackP )
577 : ScChangeAction( SC_CAT_MOVE, rToRange ),
578 aFromRange( rFromRange ),
579 pTrack( pTrackP ),
580 pFirstCell( NULL ),
581 nStartLastCut(0),
582 nEndLastCut(0)
584 virtual ~ScChangeActionMove();
586 virtual void AddContent( ScChangeActionContent* ) SAL_OVERRIDE;
587 virtual void DeleteCellEntries() SAL_OVERRIDE;
589 ScBigRange& GetFromRange() { return aFromRange; }
591 void SetStartLastCut( sal_uLong nVal ) { nStartLastCut = nVal; }
592 sal_uLong GetStartLastCut() const { return nStartLastCut; }
593 void SetEndLastCut( sal_uLong nVal ) { nEndLastCut = nVal; }
594 sal_uLong GetEndLastCut() const { return nEndLastCut; }
596 virtual void UpdateReference( const ScChangeTrack*,
597 UpdateRefMode, const ScBigRange&,
598 sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz ) SAL_OVERRIDE;
600 virtual bool Reject(ScDocument* pDoc) SAL_OVERRIDE;
602 virtual const ScChangeTrack* GetChangeTrack() const SAL_OVERRIDE { return pTrack; }
604 protected:
605 using ScChangeAction::GetRefString;
607 public:
608 ScChangeActionMove(const sal_uLong nActionNumber,
609 const ScChangeActionState eState,
610 const sal_uLong nRejectingNumber,
611 const ScBigRange& aToBigRange,
612 const OUString& aUser,
613 const DateTime& aDateTime,
614 const OUString &sComment,
615 const ScBigRange& aFromBigRange,
616 ScChangeTrack* pTrack); // only to use in the XML import
618 const ScChangeActionCellListEntry* GetFirstCellEntry() const
619 { return pFirstCell; } // only to use in the XML export
621 const ScBigRange& GetFromRange() const { return aFromRange; }
622 SC_DLLPUBLIC void GetDelta( sal_Int32& nDx, sal_Int32& nDy, sal_Int32& nDz ) const;
624 virtual void GetDescription(
625 OUString& rStr, ScDocument* pDoc, bool bSplitRange = false,
626 bool bWarning = true ) const SAL_OVERRIDE;
628 virtual void GetRefString(
629 OUString& rStr, ScDocument* pDoc, bool bFlag3D = false ) const SAL_OVERRIDE;
632 ScChangeActionDelMoveEntry::ScChangeActionDelMoveEntry(
633 ScChangeActionDelMoveEntry** ppPrevP,
634 ScChangeActionMove* pMove,
635 short nFrom, short nTo )
636 : ScChangeActionLinkEntry(
637 reinterpret_cast<ScChangeActionLinkEntry**>(
638 ppPrevP),
639 (ScChangeAction*) pMove ),
640 nCutOffFrom( nFrom ),
641 nCutOffTo( nTo )
644 inline ScChangeActionMove* ScChangeActionDelMoveEntry::GetMove()
646 return static_cast<ScChangeActionMove*>(
647 ScChangeActionLinkEntry::GetAction());
650 inline const ScChangeActionMove* ScChangeActionDelMoveEntry::GetMove() const
652 return static_cast<const ScChangeActionMove*>(
653 ScChangeActionLinkEntry::GetAction());
655 // ScChangeActionContent
656 enum ScChangeActionContentCellType
658 SC_CACCT_NONE = 0,
659 SC_CACCT_NORMAL,
660 SC_CACCT_MATORG,
661 SC_CACCT_MATREF
664 class ScChangeActionContent : public ScChangeAction
666 friend class ScChangeTrack;
668 ScCellValue maOldCell;
669 ScCellValue maNewCell;
671 OUString maOldValue;
672 OUString maNewValue;
673 ScChangeActionContent* pNextContent; // at the same position
674 ScChangeActionContent* pPrevContent;
675 ScChangeActionContent* pNextInSlot; // in the same slot
676 ScChangeActionContent** ppPrevInSlot;
678 void InsertInSlot( ScChangeActionContent** pp )
680 if ( !ppPrevInSlot )
682 ppPrevInSlot = pp;
683 if ( ( pNextInSlot = *pp ) != NULL )
684 pNextInSlot->ppPrevInSlot = &pNextInSlot;
685 *pp = this;
689 void RemoveFromSlot()
691 if ( ppPrevInSlot )
693 if ( ( *ppPrevInSlot = pNextInSlot ) != NULL )
694 pNextInSlot->ppPrevInSlot = ppPrevInSlot;
695 ppPrevInSlot = NULL; // not inserted
699 ScChangeActionContent* GetNextInSlot() { return pNextInSlot; }
701 void ClearTrack();
703 static void GetStringOfCell(
704 OUString& rStr, const ScCellValue& rCell, const ScDocument* pDoc, const ScAddress& rPos );
706 static void GetStringOfCell(
707 OUString& rStr, const ScCellValue& rCell, const ScDocument* pDoc, sal_uLong nFormat );
709 static void SetValue( OUString& rStr, ScCellValue& rCell, const ScAddress& rPos,
710 const ScCellValue& rOrgCell, const ScDocument* pFromDoc,
711 ScDocument* pToDoc );
713 static void SetValue( OUString& rStr, ScCellValue& rCell, sal_uLong nFormat,
714 const ScCellValue& rOrgCell, const ScDocument* pFromDoc,
715 ScDocument* pToDoc );
717 static void SetCell( OUString& rStr, ScCellValue& rCell, sal_uLong nFormat, const ScDocument* pDoc );
719 static bool NeedsNumberFormat( const ScCellValue& rVal );
721 void SetValueString( OUString& rValue, ScCellValue& rCell, const OUString& rStr, ScDocument* pDoc );
723 void GetValueString( OUString& rStr, const OUString& rValue, const ScCellValue& rCell,
724 const ScDocument* pDoc ) const;
726 void GetFormulaString( OUString& rStr, const ScFormulaCell* pCell ) const;
728 virtual void AddContent( ScChangeActionContent* ) SAL_OVERRIDE {}
729 virtual void DeleteCellEntries() SAL_OVERRIDE {}
731 virtual void UpdateReference( const ScChangeTrack*,
732 UpdateRefMode, const ScBigRange&,
733 sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz ) SAL_OVERRIDE;
735 virtual bool Reject(ScDocument* pDoc) SAL_OVERRIDE;
737 virtual const ScChangeTrack* GetChangeTrack() const SAL_OVERRIDE { return 0; }
739 // pRejectActions!=NULL: reject actions get
740 // stacked, no SetNewValue, no Append
741 bool Select( ScDocument*, ScChangeTrack*,
742 bool bOldest, ::std::stack<ScChangeActionContent*>* pRejectActions );
744 void PutValueToDoc(
745 const ScCellValue& rCell, const OUString& rValue, ScDocument* pDoc, SCsCOL nDx, SCsROW nDy ) const;
747 protected:
748 using ScChangeAction::GetRefString;
750 public:
752 DECL_FIXEDMEMPOOL_NEWDEL( ScChangeActionContent )
754 ScChangeActionContent( const ScRange& rRange );
756 ScChangeActionContent(
757 const sal_uLong nActionNumber, const ScChangeActionState eState,
758 const sal_uLong nRejectingNumber, const ScBigRange& aBigRange,
759 const OUString& aUser, const DateTime& aDateTime,
760 const OUString &sComment, const ScCellValue& rOldCell,
761 ScDocument* pDoc, const OUString& sOldValue ); // to use for XML Import
763 ScChangeActionContent(
764 const sal_uLong nActionNumber, const ScCellValue& rNewCell,
765 const ScBigRange& aBigRange, ScDocument* pDoc,
766 const OUString& sNewValue ); // to use for XML Import of Generated Actions
768 virtual ~ScChangeActionContent();
770 ScChangeActionContent* GetNextContent() const { return pNextContent; }
771 ScChangeActionContent* GetPrevContent() const { return pPrevContent; }
772 ScChangeActionContent* GetTopContent() const;
773 bool IsTopContent() const { return pNextContent == NULL; }
775 virtual ScChangeActionLinkEntry* GetDeletedIn() const SAL_OVERRIDE;
776 virtual ScChangeActionLinkEntry** GetDeletedInAddress() SAL_OVERRIDE;
778 void PutOldValueToDoc( ScDocument*,
779 SCsCOL nDx, SCsROW nDy ) const;
780 void PutNewValueToDoc( ScDocument*,
781 SCsCOL nDx, SCsROW nDy ) const;
783 void SetOldValue( const ScCellValue& rCell, const ScDocument* pFromDoc, ScDocument* pToDoc, sal_uLong nFormat );
785 void SetOldValue( const ScCellValue& rCell, const ScDocument* pFromDoc, ScDocument* pToDoc );
787 void SetNewValue( const ScCellValue& rCell, ScDocument* pDoc );
789 // Used in import filter AppendContentOnTheFly,
790 void SetOldNewCells(
791 const ScCellValue& rOldCell, sal_uLong nOldFormat,
792 const ScCellValue& rNewCell, sal_uLong nNewFormat, ScDocument* pDoc );
794 // Use this only in the XML import,
795 // takes ownership of cell.
796 void SetNewCell(
797 const ScCellValue& rCell, ScDocument* pDoc, const OUString& rFormatted );
799 // These functions should be protected but for
800 // the XML import they are public.
801 void SetNextContent( ScChangeActionContent* p )
802 { pNextContent = p; }
803 void SetPrevContent( ScChangeActionContent* p )
804 { pPrevContent = p; }
806 // don't use:
807 // assigns string / creates forumula cell
808 void SetOldValue( const OUString& rOld, ScDocument* pDoc );
810 void GetOldString( OUString& rStr, const ScDocument* pDoc ) const;
811 void GetNewString( OUString& rStr, const ScDocument* pDoc ) const;
812 const ScCellValue& GetOldCell() const { return maOldCell;}
813 const ScCellValue& GetNewCell() const { return maNewCell;}
814 virtual void GetDescription(
815 OUString& rStr, ScDocument* pDoc, bool bSplitRange = false, bool bWarning = true ) const SAL_OVERRIDE;
817 virtual void GetRefString(
818 OUString& rStr, ScDocument* pDoc, bool bFlag3D = false ) const SAL_OVERRIDE;
820 static ScChangeActionContentCellType GetContentCellType( const ScCellValue& rCell );
821 static ScChangeActionContentCellType GetContentCellType( const ScRefCellValue& rIter );
823 // NewCell
824 bool IsMatrixOrigin() const;
825 // OldCell
826 bool IsOldMatrixReference() const;
829 // ScChangeActionReject
830 class ScChangeActionReject : public ScChangeAction
832 friend class ScChangeTrack;
833 friend class ScChangeActionContent;
835 ScChangeActionReject( sal_uLong nReject ) :
836 ScChangeAction( SC_CAT_REJECT, ScRange() )
838 SetRejectAction( nReject );
839 SetState( SC_CAS_ACCEPTED );
842 virtual void AddContent( ScChangeActionContent* ) SAL_OVERRIDE {}
843 virtual void DeleteCellEntries() SAL_OVERRIDE {}
845 virtual bool Reject(ScDocument* pDoc) SAL_OVERRIDE;
847 virtual const ScChangeTrack* GetChangeTrack() const SAL_OVERRIDE { return 0; }
849 public:
850 ScChangeActionReject(const sal_uLong nActionNumber,
851 const ScChangeActionState eState,
852 const sal_uLong nRejectingNumber,
853 const ScBigRange& aBigRange,
854 const OUString& aUser,
855 const DateTime& aDateTime,
856 const OUString &sComment); // only to use in the XML import
859 // ScChangeTrack
860 enum ScChangeTrackMsgType
862 SC_CTM_NONE,
863 SC_CTM_APPEND, // Actions appended
864 SC_CTM_REMOVE, // Actions removed
865 SC_CTM_CHANGE, // Actions changed
866 SC_CTM_PARENT // became a parent (and wasn't before)
869 struct ScChangeTrackMsgInfo
871 DECL_FIXEDMEMPOOL_NEWDEL( ScChangeTrackMsgInfo )
873 ScChangeTrackMsgType eMsgType;
874 sal_uLong nStartAction;
875 sal_uLong nEndAction;
878 // MsgQueue for notification via ModifiedLink
879 typedef std::deque<ScChangeTrackMsgInfo*> ScChangeTrackMsgQueue;
880 typedef std::stack<ScChangeTrackMsgInfo*> ScChangeTrackMsgStack;
881 typedef std::map<sal_uLong, ScChangeAction*> ScChangeActionMap;
883 enum ScChangeTrackMergeState
885 SC_CTMS_NONE,
886 SC_CTMS_PREPARE,
887 SC_CTMS_OWN,
888 SC_CTMS_UNDO,
889 SC_CTMS_OTHER
892 // Internally generated actions start at this value (nearly all bits set)
893 // and are decremented, to keep values in a table separated from "normal" actions.
894 #define SC_CHGTRACK_GENERATED_START ((sal_uInt32) 0xfffffff0)
896 class ScChangeTrack : public utl::ConfigurationListener
898 friend void ScChangeAction::RejectRestoreContents( ScChangeTrack*, SCsCOL, SCsROW );
899 friend bool ScChangeActionDel::Reject( ScDocument* pDoc );
900 friend void ScChangeActionDel::DeleteCellEntries();
901 friend void ScChangeActionMove::DeleteCellEntries();
902 friend bool ScChangeActionMove::Reject( ScDocument* pDoc );
904 static const SCROW nContentRowsPerSlot;
905 static const SCSIZE nContentSlots;
907 com::sun::star::uno::Sequence< sal_Int8 > aProtectPass;
908 ScChangeActionMap aMap;
909 ScChangeActionMap aGeneratedMap;
910 ScChangeActionMap aPasteCutMap;
911 ScChangeTrackMsgQueue aMsgQueue;
912 ScChangeTrackMsgStack aMsgStackTmp;
913 ScChangeTrackMsgStack aMsgStackFinal;
914 std::set<OUString> maUserCollection;
915 OUString maUser;
916 Link aModifiedLink;
917 ScRange aInDeleteRange;
918 DateTime aFixDateTime;
919 ScChangeAction* pFirst;
920 ScChangeAction* pLast;
921 ScChangeActionContent* pFirstGeneratedDelContent;
922 ScChangeActionContent** ppContentSlots;
923 ScChangeActionMove* pLastCutMove;
924 ScChangeActionLinkEntry* pLinkInsertCol;
925 ScChangeActionLinkEntry* pLinkInsertRow;
926 ScChangeActionLinkEntry* pLinkInsertTab;
927 ScChangeActionLinkEntry* pLinkMove;
928 ScChangeTrackMsgInfo* pBlockModifyMsg;
929 ScDocument* pDoc;
930 sal_uLong nActionMax;
931 sal_uLong nGeneratedMin;
932 sal_uLong nMarkLastSaved;
933 sal_uLong nStartLastCut;
934 sal_uLong nEndLastCut;
935 sal_uLong nLastMerge;
936 ScChangeTrackMergeState eMergeState;
937 bool bLoadSave:1;
938 bool bInDelete:1;
939 bool bInDeleteUndo:1;
940 bool bInDeleteTop:1;
941 bool bInPasteCut:1;
942 bool bUseFixDateTime:1;
943 bool bTimeNanoSeconds:1;
945 ScChangeTrack( const ScChangeTrack& ) SAL_DELETED_FUNCTION;
946 ScChangeTrack& operator=( const ScChangeTrack& ) SAL_DELETED_FUNCTION;
948 static SCROW InitContentRowsPerSlot();
950 // true if one is MM_FORMULA and the other is
951 // not, or if both are and range differs
952 static bool IsMatrixFormulaRangeDifferent(
953 const ScCellValue& rOldCell, const ScCellValue& rNewCell );
955 void Init();
956 void DtorClear();
957 void SetLoadSave( bool bVal ) { bLoadSave = bVal; }
958 void SetInDeleteRange( const ScRange& rRange )
959 { aInDeleteRange = rRange; }
960 void SetInDelete( bool bVal )
961 { bInDelete = bVal; }
962 void SetInDeleteTop( bool bVal )
963 { bInDeleteTop = bVal; }
964 void SetInDeleteUndo( bool bVal )
965 { bInDeleteUndo = bVal; }
966 void SetInPasteCut( bool bVal )
967 { bInPasteCut = bVal; }
968 void SetMergeState( ScChangeTrackMergeState eState )
969 { eMergeState = eState; }
970 ScChangeTrackMergeState GetMergeState() const { return eMergeState; }
971 void SetLastMerge( sal_uLong nVal ) { nLastMerge = nVal; }
972 sal_uLong GetLastMerge() const { return nLastMerge; }
974 void SetLastCutMoveRange( const ScRange&, ScDocument* );
976 // create block of ModifyMsg
977 void StartBlockModify( ScChangeTrackMsgType,
978 sal_uLong nStartAction );
979 void EndBlockModify( sal_uLong nEndAction );
981 void AddDependentWithNotify( ScChangeAction* pParent,
982 ScChangeAction* pDependent );
984 void Dependencies( ScChangeAction* );
985 void UpdateReference( ScChangeAction*, bool bUndo );
986 void UpdateReference( ScChangeAction** ppFirstAction, ScChangeAction* pAct, bool bUndo );
987 void Append( ScChangeAction* pAppend, sal_uLong nAction );
988 SC_DLLPUBLIC void AppendDeleteRange( const ScRange&,
989 ScDocument* pRefDoc, SCsTAB nDz,
990 sal_uLong nRejectingInsert );
991 void AppendOneDeleteRange( const ScRange& rOrgRange,
992 ScDocument* pRefDoc,
993 SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
994 sal_uLong nRejectingInsert );
995 void LookUpContents( const ScRange& rOrgRange,
996 ScDocument* pRefDoc,
997 SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
998 void Remove( ScChangeAction* );
999 void MasterLinks( ScChangeAction* );
1001 // Content on top an Position
1002 ScChangeActionContent* SearchContentAt( const ScBigAddress&,
1003 ScChangeAction* pButNotThis ) const;
1004 void DeleteGeneratedDelContent(
1005 ScChangeActionContent* );
1007 ScChangeActionContent* GenerateDelContent(
1008 const ScAddress& rPos, const ScCellValue& rCell, const ScDocument* pFromDoc );
1010 void DeleteCellEntries(
1011 ScChangeActionCellListEntry*&,
1012 ScChangeAction* pDeletor );
1014 // Reject action and all dependent actions,
1015 // Table stems from previous GetDependents,
1016 // only needed for Insert and Move (MasterType),
1017 // is NULL otherwise.
1018 // bRecursion == called from reject with table
1019 bool Reject( ScChangeAction*, ScChangeActionMap*, bool bRecursion );
1021 bool IsLastAction( sal_uLong nNum ) const;
1023 void ClearMsgQueue();
1024 virtual void ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 ) SAL_OVERRIDE;
1026 public:
1028 static SCSIZE ComputeContentSlot( sal_Int32 nRow )
1030 if ( nRow < 0 || nRow > MAXROW )
1031 return nContentSlots - 1;
1032 return static_cast< SCSIZE >( nRow / nContentRowsPerSlot );
1035 SC_DLLPUBLIC ScChangeTrack( ScDocument* );
1036 ScChangeTrack(ScDocument* pDocP, const std::set<OUString>& aTempUserCollection); // only to use in the XML import
1037 SC_DLLPUBLIC virtual ~ScChangeTrack();
1038 void Clear();
1040 ScChangeActionContent* GetFirstGenerated() const { return pFirstGeneratedDelContent; }
1041 ScChangeAction* GetFirst() const { return pFirst; }
1042 ScChangeAction* GetLast() const { return pLast; }
1043 sal_uLong GetActionMax() const { return nActionMax; }
1044 bool IsGenerated( sal_uLong nAction ) const;
1045 SC_DLLPUBLIC ScChangeAction* GetAction( sal_uLong nAction ) const;
1046 ScChangeAction* GetGenerated( sal_uLong nGenerated ) const;
1047 ScChangeAction* GetActionOrGenerated( sal_uLong nAction ) const;
1048 sal_uLong GetLastSavedActionNumber() const;
1049 void SetLastSavedActionNumber(sal_uLong nNew);
1050 ScChangeAction* GetLastSaved() const;
1051 ScChangeActionContent** GetContentSlots() const { return ppContentSlots; }
1053 bool IsLoadSave() const { return bLoadSave; }
1054 const ScRange& GetInDeleteRange() const
1055 { return aInDeleteRange; }
1056 bool IsInDelete() const { return bInDelete; }
1057 bool IsInDeleteTop() const { return bInDeleteTop; }
1058 bool IsInDeleteUndo() const { return bInDeleteUndo; }
1059 bool IsInPasteCut() const { return bInPasteCut; }
1060 SC_DLLPUBLIC void SetUser( const OUString& rUser );
1061 const OUString& GetUser() const { return maUser;}
1062 const std::set<OUString>& GetUserCollection() const { return maUserCollection;}
1063 ScDocument* GetDocument() const { return pDoc; }
1064 // for import filter
1065 const DateTime& GetFixDateTime() const { return aFixDateTime; }
1067 // set this if the date/time set with
1068 // SetFixDateTime...() shall be applied to
1069 // appended actions
1070 void SetUseFixDateTime( bool bVal )
1071 { bUseFixDateTime = bVal; }
1072 // for MergeDocument, apply original date/time as UTC
1073 void SetFixDateTimeUTC( const DateTime& rDT )
1074 { aFixDateTime = rDT; }
1075 // for import filter, apply original date/time as local time
1076 void SetFixDateTimeLocal( const DateTime& rDT )
1077 { aFixDateTime = rDT; aFixDateTime.ConvertToUTC(); }
1079 void Append( ScChangeAction* );
1081 // pRefDoc may be NULL => no lookup of contents
1082 // => no generation of deleted contents
1083 SC_DLLPUBLIC void AppendDeleteRange( const ScRange&,
1084 ScDocument* pRefDoc,
1085 sal_uLong& nStartAction, sal_uLong& nEndAction,
1086 SCsTAB nDz = 0 );
1087 // nDz: multi TabDel, LookUpContent must be searched
1088 // with an offset of -nDz
1090 // after new value was set in the document,
1091 // old value from RefDoc/UndoDoc
1092 void AppendContent( const ScAddress& rPos,
1093 ScDocument* pRefDoc );
1094 // after new values were set in the document,
1095 // old values from RefDoc/UndoDoc
1096 void AppendContentRange( const ScRange& rRange,
1097 ScDocument* pRefDoc,
1098 sal_uLong& nStartAction, sal_uLong& nEndAction,
1099 ScChangeActionClipMode eMode = SC_CACM_NONE );
1100 // after new value was set in the document,
1101 // old value from pOldCell, nOldFormat,
1102 // RefDoc==NULL => Doc
1103 void AppendContent( const ScAddress& rPos, const ScCellValue& rOldCell,
1104 sal_uLong nOldFormat, ScDocument* pRefDoc = NULL );
1105 // after new value was set in the document,
1106 // old value from pOldCell, format from Doc
1107 SC_DLLPUBLIC void AppendContent( const ScAddress& rPos, const ScCellValue& rOldCell );
1108 // after new values were set in the document,
1109 // old values from RefDoc/UndoDoc.
1110 // All contents with a cell in RefDoc
1111 void AppendContentsIfInRefDoc( ScDocument* pRefDoc,
1112 sal_uLong& nStartAction, sal_uLong& nEndAction );
1114 // Meant for import filter, creates and inserts
1115 // an unconditional content action of the two
1116 // cells without querying the document, not
1117 // even for number formats (though the number
1118 // formatter of the document may be used).
1119 // The action is returned and may be used to
1120 // set user name, description, date/time et al.
1121 // Takes ownership of the cells!
1122 SC_DLLPUBLIC ScChangeActionContent* AppendContentOnTheFly(
1123 const ScAddress& rPos, const ScCellValue& rOldCell, const ScCellValue& rNewCell,
1124 sal_uLong nOldFormat = 0, sal_uLong nNewFormat = 0 );
1126 // Only use the following two if there is no different solution! (Assign
1127 // string for NewValue or creation of a formula respectively)
1129 SC_DLLPUBLIC void AppendInsert( const ScRange& rRange, bool bEndOfList = false );
1131 // pRefDoc may be NULL => no lookup of contents
1132 // => no generation of deleted contents
1133 SC_DLLPUBLIC void AppendMove( const ScRange& rFromRange, const ScRange& rToRange,
1134 ScDocument* pRefDoc );
1136 // Cut to Clipboard
1137 void ResetLastCut()
1139 nStartLastCut = nEndLastCut = 0;
1140 if ( pLastCutMove )
1142 delete pLastCutMove;
1143 pLastCutMove = NULL;
1146 bool HasLastCut() const
1148 return nEndLastCut > 0 &&
1149 nStartLastCut <= nEndLastCut &&
1150 pLastCutMove;
1153 SC_DLLPUBLIC void Undo( sal_uLong nStartAction, sal_uLong nEndAction, bool bMerge = false );
1155 // adjust references for MergeDocument
1156 //! may only be used in a temporary opened document.
1157 //! the Track (?) is unclean afterwards
1158 void MergePrepare( ScChangeAction* pFirstMerge, bool bShared = false );
1159 void MergeOwn( ScChangeAction* pAct, sal_uLong nFirstMerge, bool bShared = false );
1160 static bool MergeIgnore( const ScChangeAction&, sal_uLong nFirstMerge );
1162 // This comment was already really strange in German.
1163 // Tried to structure it a little. Hope no information got lost...
1165 // Insert dependents into table.
1166 // ScChangeAction is
1167 // - "Insert": really dependents
1168 // - "Move": dependent contents in FromRange /
1169 // deleted contents in ToRange
1170 // OR inserts in FromRange or ToRange
1171 // - "Delete": a list of deleted (what?)
1172 // OR for content, different contents at the same position
1173 // OR MatrixReferences belonging to MatrixOrigin
1175 // With bListMasterDelete (==TRUE ?) all Deletes of a row belonging
1176 // to a MasterDelete are listed (possibly it is
1177 // "all Deletes belonging...are listed in a row?)
1179 // With bAllFlat (==TRUE ?) all dependents of dependents
1180 // will be inserted flatly.
1182 SC_DLLPUBLIC void GetDependents(
1183 ScChangeAction*, ScChangeActionMap&, bool bListMasterDelete = false, bool bAllFlat = false ) const;
1185 // Reject visible action (and dependents)
1186 bool Reject( ScChangeAction*, bool bShared = false );
1188 // Accept visible action (and dependents)
1189 SC_DLLPUBLIC bool Accept( ScChangeAction* );
1191 void AcceptAll(); // all Virgins
1192 bool RejectAll(); // all Virgins
1194 // Selects a content of several contents at the same
1195 // position and accepts this one and
1196 // the older ones, rejects the more recent ones.
1197 // If bOldest==TRUE then the first OldValue
1198 // of a Virgin-Content-List will be restored.
1199 bool SelectContent( ScChangeAction*, bool bOldest = false );
1201 // If ModifiedLink is set, changes go to
1202 // ScChangeTrackMsgQueue
1203 void SetModifiedLink( const Link& r )
1204 { aModifiedLink = r; ClearMsgQueue(); }
1205 const Link& GetModifiedLink() const { return aModifiedLink; }
1206 ScChangeTrackMsgQueue& GetMsgQueue();
1208 void NotifyModified( ScChangeTrackMsgType eMsgType,
1209 sal_uLong nStartAction, sal_uLong nEndAction );
1211 sal_uLong AddLoadedGenerated(
1212 const ScCellValue& rNewCell, const ScBigRange& aBigRange, const OUString& sNewValue ); // only to use in the XML import
1213 void AppendLoaded( ScChangeAction* pAppend ); // this is only for the XML import public, it should be protected
1214 void SetActionMax(sal_uLong nTempActionMax)
1215 { nActionMax = nTempActionMax; } // only to use in the XML import
1217 void SetProtection( const com::sun::star::uno::Sequence< sal_Int8 >& rPass )
1218 { aProtectPass = rPass; }
1219 com::sun::star::uno::Sequence< sal_Int8 > GetProtection() const
1220 { return aProtectPass; }
1221 bool IsProtected() const { return aProtectPass.getLength() != 0; }
1223 // If time stamps of actions of this
1224 // ChangeTrack and a second one are to be
1225 // compared including nanoseconds.
1226 void SetTimeNanoSeconds( bool bVal ) { bTimeNanoSeconds = bVal; }
1227 bool IsTimeNanoSeconds() const { return bTimeNanoSeconds; }
1229 void AppendCloned( ScChangeAction* pAppend );
1230 SC_DLLPUBLIC ScChangeTrack* Clone( ScDocument* pDocument ) const;
1231 void MergeActionState( ScChangeAction* pAct, const ScChangeAction* pOtherAct );
1234 #endif
1236 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */