Coverage Report

Created: 2025-07-07 10:01

/src/libreoffice/sc/inc/chgtrack.hxx
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
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/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
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 .
18
 */
19
20
#pragma once
21
22
#include <map>
23
#include <memory>
24
#include <set>
25
#include <stack>
26
#include <vector>
27
28
#include <com/sun/star/uno/Sequence.hxx>
29
#include <tools/color.hxx>
30
#include <tools/datetime.hxx>
31
#include <tools/link.hxx>
32
#include <tools/solar.h>
33
#include <unotools/options.hxx>
34
#include <optional>
35
#include "global.hxx"
36
#include "bigrange.hxx"
37
#include "scdllapi.h"
38
#include "cellvalue.hxx"
39
40
class ScDocument;
41
class ScFormulaCell;
42
class ScChangeAction;
43
class ScChangeTrack;
44
class ScAppOptions;
45
namespace tools { class JsonWriter; }
46
47
class ScActionColorChanger
48
{
49
private:
50
    const ScAppOptions&     rOpt;
51
    const std::set<OUString>& rUsers;
52
    OUString                aLastUserName;
53
    sal_uInt16              nLastUserIndex;
54
    Color                   nColor;
55
56
public:
57
    ScActionColorChanger( const ScChangeTrack& rTrack );
58
    void        Update( const ScChangeAction& rAction );
59
0
    Color       GetColor() const { return nColor; }
60
};
61
62
enum ScChangeActionType
63
{
64
    SC_CAT_NONE,
65
    SC_CAT_INSERT_COLS,
66
    SC_CAT_INSERT_ROWS,
67
    SC_CAT_INSERT_TABS,
68
    SC_CAT_DELETE_COLS,
69
    SC_CAT_DELETE_ROWS,
70
    SC_CAT_DELETE_TABS,
71
    SC_CAT_MOVE,
72
    SC_CAT_CONTENT,
73
    SC_CAT_REJECT
74
};
75
76
enum ScChangeActionState
77
{
78
    SC_CAS_VIRGIN,
79
    SC_CAS_ACCEPTED,
80
    SC_CAS_REJECTED
81
};
82
83
enum ScChangeActionClipMode
84
{
85
    SC_CACM_NONE,
86
    SC_CACM_CUT,
87
    SC_CACM_PASTE
88
};
89
90
/** A link/connection/dependency between change actions.
91
92
    Upon construction inserts itself as the head of a chain / linked list,
93
    respectively between existing link entries.
94
95
    Upon destruction removes itself from the list and connects the previous and
96
    next entry, if it was the first entry automatically maintaining the head
97
    pointer to the list.
98
99
    ppPrev == &previous->pNext or address of pointer to head of linked list,
100
    *ppPrev == this
101
 */
102
class ScChangeActionLinkEntry
103
{
104
    ScChangeActionLinkEntry( const ScChangeActionLinkEntry& ) = delete;
105
    ScChangeActionLinkEntry& operator=( const ScChangeActionLinkEntry& ) = delete;
106
107
    ScChangeActionLinkEntry*    pNext;
108
    ScChangeActionLinkEntry**   ppPrev;
109
    ScChangeAction*             pAction;
110
    ScChangeActionLinkEntry*    pLink;
111
112
public:
113
114
    ScChangeActionLinkEntry(
115
            ScChangeActionLinkEntry** ppPrevP,
116
            ScChangeAction* pActionP )
117
0
        :   pNext( *ppPrevP ),
118
0
            ppPrev( ppPrevP ),
119
0
            pAction( pActionP ),
120
0
            pLink( nullptr )
121
0
        {
122
0
            if ( pNext )
123
0
                pNext->ppPrev = &pNext;
124
0
            *ppPrevP = this;
125
0
        }
126
127
    virtual ~ScChangeActionLinkEntry()
128
0
    {
129
0
        ScChangeActionLinkEntry* p = pLink;
130
0
        UnLink();
131
0
        Remove();
132
0
        if ( p )
133
0
            delete p;
134
0
    }
135
136
    void SetLink( ScChangeActionLinkEntry* pLinkP )
137
0
    {
138
0
        UnLink();
139
0
        if ( pLinkP )
140
0
        {
141
0
            pLink = pLinkP;
142
0
            pLinkP->pLink = this;
143
0
        }
144
0
    }
145
146
    void UnLink()
147
0
    {
148
0
        if ( pLink )
149
0
        {
150
0
            pLink->pLink = nullptr;
151
0
            pLink = nullptr;
152
0
        }
153
0
    }
154
155
    void Remove()
156
0
    {
157
0
        if ( ppPrev )
158
0
        {
159
0
            if ( ( *ppPrev = pNext ) != nullptr )
160
0
                pNext->ppPrev = ppPrev;
161
0
            ppPrev = nullptr;  // not inserted
162
0
        }
163
0
    }
164
165
0
    const ScChangeActionLinkEntry*  GetNext() const     { return pNext; }
166
0
    ScChangeActionLinkEntry*        GetNext()           { return pNext; }
167
0
    const ScChangeAction*           GetAction() const   { return pAction; }
168
0
    ScChangeAction*                 GetAction()         { return pAction; }
169
};
170
171
// ScChangeActionCellListEntry
172
// this is only for the XML Export in the hxx
173
class ScChangeActionContent;
174
175
class SAL_DLLPUBLIC_RTTI ScChangeAction
176
{
177
    friend class ScChangeTrack;
178
    friend class ScChangeActionIns;
179
    friend class ScChangeActionDel;
180
    friend class ScChangeActionMove;
181
    friend class ScChangeActionContent;
182
183
    ScChangeAction( const ScChangeAction& ) = delete;
184
    ScChangeAction& operator=( const ScChangeAction& ) = delete;
185
186
protected:
187
188
    ScBigRange          aBigRange;          // Ins/Del/MoveTo/ContentPos
189
    DateTime            aDateTime;          //! UTC
190
    OUString       aUser;              // who?
191
    OUString       aComment;           // user comment
192
    ScChangeAction*     pNext;              // next in linked list
193
    ScChangeAction*     pPrev;              // previous in linked list
194
    ScChangeActionLinkEntry*    pLinkAny;   // arbitrary links
195
    ScChangeActionLinkEntry*    pLinkDeletedIn; // access to insert areas which were
196
                                            // deleted or moved or rejected
197
    ScChangeActionLinkEntry*    pLinkDeleted;   // links to deleted
198
    ScChangeActionLinkEntry*    pLinkDependent; // links to dependent
199
    sal_uLong               nAction;
200
    sal_uLong               nRejectAction;
201
    ScChangeActionType  eType;
202
    ScChangeActionState eState;
203
204
    ScChangeAction( ScChangeActionType, const ScRange& );
205
206
    // only to be used in the XML import
207
    ScChangeAction( ScChangeActionType,
208
                    ScBigRange ,
209
                    const sal_uLong nAction,
210
                    const sal_uLong nRejectAction,
211
                    const ScChangeActionState eState,
212
                    const DateTime& aDateTime,
213
                    OUString aUser,
214
                    OUString aComment );
215
216
    // only to be used in the XML import
217
    ScChangeAction( ScChangeActionType, ScBigRange , const sal_uLong nAction);
218
219
    OUString GetRefString(
220
        const ScBigRange& rRange, const ScDocument& rDoc, bool bFlag3D = false) const;
221
222
113
    void SetActionNumber( sal_uLong n ) { nAction = n; }
223
0
    void SetRejectAction( sal_uLong n ) { nRejectAction = n; }
224
    void SetUser( const OUString& r );
225
0
    void SetType( ScChangeActionType e ) { eType = e; }
226
0
    void SetState( ScChangeActionState e ) { eState = e; }
227
    void SetRejected();
228
229
295
    ScBigRange& GetBigRange() { return aBigRange; }
230
231
    void AddLink( ScChangeAction* p, ScChangeActionLinkEntry* pL )
232
0
    {
233
0
        ScChangeActionLinkEntry* pLnk =
234
0
            new ScChangeActionLinkEntry(
235
0
            &pLinkAny, p );
236
0
        pLnk->SetLink( pL );
237
0
    }
238
239
    virtual ScChangeActionLinkEntry*    GetDeletedIn() const
240
0
                                            { return pLinkDeletedIn; }
241
    virtual ScChangeActionLinkEntry**   GetDeletedInAddress()
242
0
                                            { return &pLinkDeletedIn; }
243
    bool RemoveDeletedIn( const ScChangeAction* );
244
    void SetDeletedIn( ScChangeAction* );
245
246
    ScChangeActionLinkEntry* AddDeleted( ScChangeAction* p )
247
0
    {
248
0
        return new ScChangeActionLinkEntry(&pLinkDeleted, p);
249
0
    }
250
251
    ScChangeActionLinkEntry* AddDependent( ScChangeAction* p )
252
0
    {
253
0
        return new ScChangeActionLinkEntry(&pLinkDependent, p);
254
0
    }
255
256
    void                RemoveAllDependent();
257
258
    void                RemoveAllLinks();
259
260
    virtual void AddContent( ScChangeActionContent* ) = 0;
261
    virtual void DeleteCellEntries() = 0;
262
263
    virtual void UpdateReference( const ScChangeTrack*,
264
                     UpdateRefMode, const ScBigRange&,
265
                     sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz );
266
267
    void Accept();
268
    virtual bool Reject(ScDocument& rDoc) = 0;
269
    void RejectRestoreContents( ScChangeTrack*, SCCOL nDx, SCROW nDy );
270
271
    // used in Reject() instead of IsRejectable()
272
    bool IsInternalRejectable() const;
273
274
    // Derived classes that hold a pointer to the
275
    // ChangeTrack must return that. Otherwise NULL.
276
    virtual const ScChangeTrack* GetChangeTrack() const = 0;
277
278
public:
279
    virtual ~ScChangeAction();
280
281
    bool IsInsertType() const;
282
    bool IsDeleteType() const;
283
    bool IsVirgin() const;
284
    SC_DLLPUBLIC bool IsAccepted() const;
285
    bool IsRejected() const;
286
287
    // Action rejects another Action
288
    bool IsRejecting() const;
289
290
    // if action is visible in the document
291
    bool IsVisible() const;
292
293
    // if action if touchable
294
    bool IsTouchable() const;
295
296
    // if action is an entry in dialog root
297
    bool IsDialogRoot() const;
298
299
    // if an entry in a dialog shall be a drop down entry
300
    bool IsDialogParent() const;
301
302
    // if action is a delete with subdeletes (aufgeklappt = open ?)
303
    bool IsMasterDelete() const;
304
305
    // if action is acceptable/selectable/rejectable
306
    bool IsClickable() const;
307
308
    // if action is rejectable
309
    bool IsRejectable() const;
310
311
0
    const ScBigRange& GetBigRange() const { return aBigRange; }
312
    SC_DLLPUBLIC DateTime GetDateTime() const;        // local time
313
    const DateTime&     GetDateTimeUTC() const      // UTC time
314
0
                            { return aDateTime; }
315
423
    ScChangeActionType  GetType() const { return eType; }
316
0
    ScChangeActionState GetState() const { return eState; }
317
113
    sal_uLong               GetActionNumber() const { return nAction; }
318
0
    sal_uLong               GetRejectAction() const { return nRejectAction; }
319
320
113
    ScChangeAction*     GetNext() const { return pNext; }
321
0
    ScChangeAction*     GetPrev() const { return pPrev; }
322
323
    bool IsDeletedIn() const;
324
    bool IsDeletedIn( const ScChangeAction* ) const;
325
    bool IsDeletedInDelType( ScChangeActionType ) const;
326
    void RemoveAllDeletedIn();
327
328
    const ScChangeActionLinkEntry* GetFirstDeletedEntry() const
329
0
                            { return pLinkDeleted; }
330
    const ScChangeActionLinkEntry* GetFirstDependentEntry() const
331
0
                            { return pLinkDependent; }
332
    bool HasDependent() const;
333
    bool HasDeleted() const;
334
                                // description will be appended to string
335
                                // with bSplitRange only one column/row will be considered for delete
336
                                // (for a listing of entries)
337
    virtual OUString GetDescription(
338
        ScDocument& rDoc, bool bSplitRange = false, bool bWarning = true ) const;
339
340
    virtual OUString GetRefString( ScDocument& rDoc, bool bFlag3D = false ) const;
341
342
                        // for DocumentMerge set old date of the other
343
                        // action, fetched by GetDateTimeUTC
344
    void                SetDateTimeUTC( const DateTime& rDT )
345
113
                            { aDateTime = rDT; }
346
347
0
    const OUString& GetUser() const { return aUser;}
348
0
    const OUString& GetComment() const { return aComment;}
349
350
    // set user comment
351
    void SetComment( const OUString& rStr );
352
353
                        // only to be used in the XML import
354
    void                SetDeletedInThis( sal_uLong nActionNumber,
355
                                const ScChangeTrack* pTrack );
356
                        // only to be used in the XML import
357
    void                AddDependent( sal_uLong nActionNumber,
358
                                const ScChangeTrack* pTrack );
359
};
360
361
//  ScChangeActionIns
362
class SAL_DLLPUBLIC_RTTI ScChangeActionIns final : public ScChangeAction
363
{
364
    friend class ScChangeTrack;
365
366
    bool mbEndOfList; /// whether or not a row was auto-inserted at the bottom.
367
368
    ScChangeActionIns( const ScDocument* pDoc, const ScRange& rRange, bool bEndOfList = false );
369
370
0
    virtual void                AddContent( ScChangeActionContent* ) override {}
371
0
    virtual void                DeleteCellEntries() override {}
372
373
    virtual bool Reject(ScDocument& rDoc) override;
374
375
0
    virtual const ScChangeTrack*    GetChangeTrack() const override { return nullptr; }
376
377
public:
378
    virtual                     ~ScChangeActionIns() override;
379
    ScChangeActionIns(
380
        const sal_uLong nActionNumber,
381
        const ScChangeActionState eState,
382
        const sal_uLong nRejectingNumber,
383
        const ScBigRange& aBigRange,
384
        const OUString& aUser,
385
        const DateTime& aDateTime,
386
        const OUString &sComment,
387
        const ScChangeActionType eType,
388
        bool bEndOfList = false );
389
390
    virtual OUString GetDescription(
391
        ScDocument& rDoc, bool bSplitRange = false, bool bWarning = true) const override;
392
393
    SC_DLLPUBLIC bool IsEndOfList() const;
394
};
395
396
//  ScChangeActionDel
397
class SAL_DLLPUBLIC_RTTI ScChangeActionMove;
398
399
class ScChangeActionDelMoveEntry final : public ScChangeActionLinkEntry
400
{
401
    friend class ScChangeActionDel;
402
    friend class ScChangeTrack;
403
404
    short               nCutOffFrom;
405
    short               nCutOffTo;
406
407
    inline ScChangeActionDelMoveEntry(
408
        ScChangeActionDelMoveEntry** ppPrevP,
409
        ScChangeActionMove* pMove,
410
        short nFrom, short nTo );
411
412
    inline ScChangeActionMove* GetMove();
413
414
public:
415
    const ScChangeActionDelMoveEntry*   GetNext() const
416
0
                            {
417
0
                                return static_cast<const ScChangeActionDelMoveEntry*>(
418
0
                                    ScChangeActionLinkEntry::GetNext());
419
0
                            }
420
    inline const ScChangeActionMove*   GetMove() const;
421
0
    short               GetCutOffFrom() const { return nCutOffFrom; }
422
0
    short               GetCutOffTo() const { return nCutOffTo; }
423
};
424
425
class ScChangeActionDel final : public ScChangeAction
426
{
427
    friend class ScChangeTrack;
428
    friend void ScChangeAction::Accept();
429
430
    ScChangeTrack*      pTrack;
431
    std::vector<ScChangeActionContent*> mvCells;
432
    ScChangeActionIns*  pCutOff;        // cut insert
433
    short               nCutOff;        // +: start  -: end
434
    ScChangeActionDelMoveEntry* pLinkMove;
435
    SCCOL               nDx;
436
    SCROW               nDy;
437
438
    ScChangeActionDel( const ScDocument* pDoc, const ScRange& rRange, SCCOL nDx, SCROW nDy, ScChangeTrack* );
439
440
    virtual void                AddContent( ScChangeActionContent* ) override;
441
    virtual void                DeleteCellEntries() override;
442
443
            void                UndoCutOffMoves();
444
            void                UndoCutOffInsert();
445
446
    virtual void                UpdateReference( const ScChangeTrack*,
447
                                    UpdateRefMode, const ScBigRange&,
448
                                    sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz ) override;
449
450
    virtual bool Reject(ScDocument& rDoc) override;
451
452
0
    virtual const ScChangeTrack*    GetChangeTrack() const override { return pTrack; }
453
454
public:
455
    ScChangeActionDel(
456
        const sal_uLong nActionNumber, const ScChangeActionState eState,
457
        const sal_uLong nRejectingNumber, const ScBigRange& aBigRange,
458
        const OUString& aUser, const DateTime& aDateTime,
459
        const OUString &sComment, const ScChangeActionType eType,
460
        const SCCOLROW nD, ScChangeTrack* pTrack); // only to use in the XML import
461
                                            // which of nDx and nDy is set is dependent on the type
462
    virtual ~ScChangeActionDel() override;
463
464
    // is the last in a row (or single)
465
    bool IsBaseDelete() const;
466
467
    // is the first in a row (or single)
468
    bool IsTopDelete() const;
469
470
    // is part of a row
471
    bool IsMultiDelete() const;
472
473
    // is col, belonging to a TabDelete
474
    bool IsTabDeleteCol() const;
475
476
0
    SCCOL GetDx() const { return nDx; }
477
0
    SCROW GetDy() const { return nDy; }
478
    ScBigRange          GetOverAllRange() const;    // BigRange + (nDx, nDy)
479
480
    const ScChangeActionDelMoveEntry* GetFirstMoveEntry() const
481
0
                            { return pLinkMove; }
482
0
    const ScChangeActionIns*    GetCutOffInsert() const { return pCutOff; }
483
0
    short               GetCutOffCount() const { return nCutOff; }
484
485
    virtual OUString GetDescription(
486
        ScDocument& rDoc, bool bSplitRange = false, bool bWarning = true ) const override;
487
488
    void                SetCutOffInsert( ScChangeActionIns* p, short n )
489
0
                            { pCutOff = p; nCutOff = n; }   // only to use in the XML import
490
                                                                    // this should be protected, but for the XML import it is public
491
    // only to use in the XML import
492
    // this should be protected, but for the XML import it is public
493
    ScChangeActionDelMoveEntry* AddCutOffMove(
494
        ScChangeActionMove* pMove, short nFrom, short nTo );
495
};
496
497
//  ScChangeActionMove
498
class ScChangeActionMove final : public ScChangeAction
499
{
500
    friend class ScChangeTrack;
501
    friend struct std::default_delete<ScChangeActionMove>; // for std::unique_ptr
502
    friend class ScChangeActionDel;
503
504
    ScBigRange          aFromRange;
505
    ScChangeTrack*      pTrack;
506
    std::vector<ScChangeActionContent*> mvCells;
507
    sal_uLong               nStartLastCut;  // for PasteCut undo
508
    sal_uLong               nEndLastCut;
509
510
    ScChangeActionMove( const ScRange& rFromRange,
511
        const ScRange& rToRange,
512
        ScChangeTrack* pTrackP )
513
0
        : ScChangeAction( SC_CAT_MOVE, rToRange ),
514
0
            aFromRange( rFromRange ),
515
0
            pTrack( pTrackP ),
516
0
            nStartLastCut(0),
517
0
            nEndLastCut(0)
518
0
        {}
519
    virtual ~ScChangeActionMove() override;
520
521
    virtual void                AddContent( ScChangeActionContent* ) override;
522
    virtual void                DeleteCellEntries() override;
523
524
0
            ScBigRange&         GetFromRange() { return aFromRange; }
525
526
0
            void                SetStartLastCut( sal_uLong nVal ) { nStartLastCut = nVal; }
527
0
            sal_uLong               GetStartLastCut() const { return nStartLastCut; }
528
0
            void                SetEndLastCut( sal_uLong nVal ) { nEndLastCut = nVal; }
529
0
            sal_uLong               GetEndLastCut() const { return nEndLastCut; }
530
531
    virtual void                UpdateReference( const ScChangeTrack*,
532
                                    UpdateRefMode, const ScBigRange&,
533
                                    sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz ) override;
534
535
    virtual bool Reject(ScDocument& rDoc) override;
536
537
0
    virtual const ScChangeTrack*    GetChangeTrack() const override { return pTrack; }
538
539
protected:
540
    using ScChangeAction::GetRefString;
541
542
public:
543
    ScChangeActionMove(const sal_uLong nActionNumber,
544
                    const ScChangeActionState eState,
545
                    const sal_uLong nRejectingNumber,
546
                    const ScBigRange& aToBigRange,
547
                    const OUString& aUser,
548
                    const DateTime& aDateTime,
549
                    const OUString &sComment,
550
                    ScBigRange aFromBigRange,
551
                    ScChangeTrack* pTrack); // only to use in the XML import
552
553
0
    const ScBigRange&   GetFromRange() const { return aFromRange; }
554
    SC_DLLPUBLIC        void                GetDelta( sal_Int32& nDx, sal_Int32& nDy, sal_Int32& nDz ) const;
555
556
    virtual OUString GetDescription(
557
        ScDocument& rDoc, bool bSplitRange = false, bool bWarning = true ) const override;
558
559
    virtual OUString GetRefString( ScDocument& rDoc, bool bFlag3D = false ) const override;
560
};
561
562
ScChangeActionDelMoveEntry::ScChangeActionDelMoveEntry(
563
    ScChangeActionDelMoveEntry** ppPrevP,
564
    ScChangeActionMove* pMove,
565
    short nFrom, short nTo )
566
0
    :   ScChangeActionLinkEntry(
567
0
            reinterpret_cast<ScChangeActionLinkEntry**>(
568
0
                ppPrevP),
569
0
            static_cast<ScChangeAction*>(pMove) ),
570
0
        nCutOffFrom( nFrom ),
571
0
        nCutOffTo( nTo )
572
0
{}
573
574
inline ScChangeActionMove* ScChangeActionDelMoveEntry::GetMove()
575
0
                           {
576
0
                               return static_cast<ScChangeActionMove*>(
577
0
                                   ScChangeActionLinkEntry::GetAction());
578
0
                           }
579
580
inline const ScChangeActionMove* ScChangeActionDelMoveEntry::GetMove() const
581
0
                          {
582
0
                              return static_cast<const ScChangeActionMove*>(
583
0
                                  ScChangeActionLinkEntry::GetAction());
584
0
                          }
585
//  ScChangeActionContent
586
enum ScChangeActionContentCellType
587
{
588
    SC_CACCT_NONE = 0,
589
    SC_CACCT_NORMAL,
590
    SC_CACCT_MATORG,
591
    SC_CACCT_MATREF
592
};
593
594
class SAL_DLLPUBLIC_RTTI ScChangeActionContent final : public ScChangeAction
595
{
596
    friend class ScChangeTrack;
597
598
    ScCellValue maOldCell;
599
    ScCellValue maNewCell;
600
601
    OUString maOldValue;
602
    OUString maNewValue;
603
    ScChangeActionContent*  pNextContent;   // at the same position
604
    ScChangeActionContent*  pPrevContent;
605
    ScChangeActionContent*  pNextInSlot;    // in the same slot
606
    ScChangeActionContent** ppPrevInSlot;
607
608
    void InsertInSlot( ScChangeActionContent** pp )
609
113
    {
610
113
        if ( !ppPrevInSlot )
611
113
        {
612
113
            ppPrevInSlot = pp;
613
113
            if ( ( pNextInSlot = *pp ) != nullptr )
614
84
                pNextInSlot->ppPrevInSlot = &pNextInSlot;
615
113
            *pp = this;
616
113
        }
617
113
    }
618
619
    void RemoveFromSlot()
620
113
    {
621
113
        if ( ppPrevInSlot )
622
113
        {
623
113
            if ( ( *ppPrevInSlot = pNextInSlot ) != nullptr )
624
0
                pNextInSlot->ppPrevInSlot = ppPrevInSlot;
625
113
            ppPrevInSlot = nullptr;    // not inserted
626
113
        }
627
113
    }
628
629
56
    ScChangeActionContent*  GetNextInSlot() { return pNextInSlot; }
630
631
    void ClearTrack();
632
633
    static OUString GetStringOfCell(
634
        const ScCellValue& rCell, const ScDocument& rDoc, const ScAddress& rPos );
635
636
    static OUString GetStringOfCell(
637
        const ScCellValue& rCell, const ScDocument& rDoc, sal_uLong nFormat );
638
639
    static void SetValue( OUString& rStr, ScCellValue& rCell, const ScAddress& rPos,
640
                          const ScCellValue& rOrgCell, const ScDocument* pFromDoc,
641
                          ScDocument* pToDoc );
642
643
    static void SetValue( OUString& rStr, ScCellValue& rCell, sal_uLong nFormat,
644
                          const ScCellValue& rOrgCell, const ScDocument* pFromDoc,
645
                          ScDocument* pToDoc );
646
647
    static void SetCell( OUString& rStr, const ScCellValue& rCell, sal_uLong nFormat, const ScDocument& rDoc );
648
649
    static bool NeedsNumberFormat( const ScCellValue& rVal );
650
651
    void SetValueString( OUString& rValue, ScCellValue& rCell, const OUString& rStr, ScDocument* pDoc );
652
653
    OUString GetValueString( const OUString& rValue, const ScCellValue& rCell,
654
                             const ScDocument& rDoc ) const;
655
656
    OUString GetFormulaString( const ScFormulaCell* pCell ) const;
657
658
0
    virtual void                AddContent( ScChangeActionContent* ) override {}
659
0
    virtual void                DeleteCellEntries() override {}
660
661
    virtual void                UpdateReference( const ScChangeTrack*,
662
                                    UpdateRefMode, const ScBigRange&,
663
                                    sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz ) override;
664
665
    virtual bool Reject(ScDocument& rDoc) override;
666
667
0
    virtual const ScChangeTrack*    GetChangeTrack() const override { return nullptr; }
668
669
    // pRejectActions!=NULL: reject actions get
670
    // stacked, no SetNewValue, no Append
671
    bool Select( ScDocument&, ScChangeTrack*,
672
                 bool bOldest, ::std::stack<ScChangeActionContent*>* pRejectActions );
673
674
    void PutValueToDoc(
675
        const ScCellValue& rCell, const OUString& rValue, ScDocument* pDoc, SCCOL nDx, SCROW nDy ) const;
676
677
protected:
678
    using ScChangeAction::GetRefString;
679
680
public:
681
    ScChangeActionContent( const ScRange& rRange );
682
683
    ScChangeActionContent(
684
        const sal_uLong nActionNumber,  const ScChangeActionState eState,
685
        const sal_uLong nRejectingNumber, const ScBigRange& aBigRange,
686
        const OUString& aUser, const DateTime& aDateTime,
687
        const OUString &sComment, ScCellValue aOldCell,
688
        const ScDocument& rDoc, const OUString& sOldValue ); // to use for XML Import
689
690
    ScChangeActionContent(
691
        const sal_uLong nActionNumber, ScCellValue aNewCell,
692
        const ScBigRange& aBigRange, const ScDocument& rDoc,
693
        const OUString& sNewValue ); // to use for XML Import of Generated Actions
694
695
    virtual ~ScChangeActionContent() override;
696
697
84
    ScChangeActionContent*  GetNextContent() const { return pNextContent; }
698
84
    ScChangeActionContent*  GetPrevContent() const { return pPrevContent; }
699
    ScChangeActionContent*  GetTopContent() const;
700
0
    bool IsTopContent() const { return pNextContent == nullptr; }
701
702
    virtual ScChangeActionLinkEntry*    GetDeletedIn() const override;
703
    virtual ScChangeActionLinkEntry**   GetDeletedInAddress() override;
704
705
    void                PutOldValueToDoc( ScDocument*,
706
                            SCCOL nDx, SCROW nDy ) const;
707
    void                PutNewValueToDoc( ScDocument*,
708
                            SCCOL nDx, SCROW nDy ) const;
709
710
    void SetOldValue( const ScCellValue& rCell, const ScDocument* pFromDoc, ScDocument* pToDoc, sal_uLong nFormat );
711
712
    void SetOldValue( const ScCellValue& rCell, const ScDocument* pFromDoc, ScDocument* pToDoc );
713
714
    void SetNewValue( const ScCellValue& rCell, ScDocument* pDoc );
715
716
    // Used in import filter AppendContentOnTheFly,
717
    void SetOldNewCells(
718
        const ScCellValue& rOldCell, sal_uLong nOldFormat,
719
        const ScCellValue& rNewCell, sal_uLong nNewFormat, const ScDocument& rDoc );
720
721
    // Use this only in the XML import,
722
    // takes ownership of cell.
723
    void SetNewCell(
724
        const ScCellValue& rCell, const ScDocument& rDoc, const OUString& rFormatted );
725
726
                        // These functions should be protected but for
727
                        // the XML import they are public.
728
    void                SetNextContent( ScChangeActionContent* p )
729
42
                            { pNextContent = p; }
730
    void                SetPrevContent( ScChangeActionContent* p )
731
42
                            { pPrevContent = p; }
732
733
    // don't use:
734
    // assigns string / creates formula cell
735
    void SetOldValue( const OUString& rOld, ScDocument* pDoc );
736
737
    OUString GetOldString( const ScDocument& rDoc ) const;
738
    OUString GetNewString( const ScDocument& rDoc ) const;
739
0
    const ScCellValue& GetOldCell() const { return maOldCell;}
740
84
    const ScCellValue& GetNewCell() const { return maNewCell;}
741
    virtual OUString GetDescription(
742
        ScDocument& rDoc, bool bSplitRange = false, bool bWarning = true ) const override;
743
744
    virtual OUString GetRefString( ScDocument& rDoc, bool bFlag3D = false ) const override;
745
746
    static ScChangeActionContentCellType GetContentCellType( const ScCellValue& rCell );
747
    static ScChangeActionContentCellType GetContentCellType( const ScRefCellValue& rIter );
748
749
    // NewCell
750
    bool IsMatrixOrigin() const;
751
    // OldCell
752
    bool IsOldMatrixReference() const;
753
};
754
755
//  ScChangeActionReject
756
class ScChangeActionReject final : public ScChangeAction
757
{
758
    friend class ScChangeTrack;
759
    friend class ScChangeActionContent;
760
761
0
    virtual void AddContent( ScChangeActionContent* ) override {}
762
0
    virtual void DeleteCellEntries() override {}
763
764
    virtual bool Reject(ScDocument& rDoc) override;
765
766
0
    virtual const ScChangeTrack* GetChangeTrack() const override { return nullptr; }
767
768
public:
769
    ScChangeActionReject(const sal_uLong nActionNumber,
770
                    const ScChangeActionState eState,
771
                    const sal_uLong nRejectingNumber,
772
                    const ScBigRange& aBigRange,
773
                    const OUString& aUser,
774
                    const DateTime& aDateTime,
775
                    const OUString &sComment); // only to use in the XML import
776
};
777
778
//  ScChangeTrack
779
enum class ScChangeTrackMsgType
780
{
781
    NONE,
782
    Append,      // Actions appended
783
    Remove,      // Actions removed
784
    Change,      // Actions changed
785
    Parent       // became a parent (and wasn't before)
786
};
787
788
struct ScChangeTrackMsgInfo
789
{
790
    ScChangeTrackMsgType    eMsgType;
791
    sal_uLong                   nStartAction;
792
    sal_uLong                   nEndAction;
793
};
794
795
// MsgQueue for notification via ModifiedLink
796
typedef std::vector<ScChangeTrackMsgInfo> ScChangeTrackMsgQueue;
797
typedef std::vector<ScChangeTrackMsgInfo> ScChangeTrackMsgStack;
798
typedef std::map<sal_uLong, ScChangeAction*> ScChangeActionMap;
799
800
enum ScChangeTrackMergeState
801
{
802
    SC_CTMS_NONE,
803
    SC_CTMS_PREPARE,
804
    SC_CTMS_OWN,
805
    SC_CTMS_UNDO,
806
    SC_CTMS_OTHER
807
};
808
809
// Internally generated actions start at this value (nearly all bits set)
810
// and are decremented, to keep values in a table separated from "normal" actions.
811
36
#define SC_CHGTRACK_GENERATED_START (sal_uInt32(0xfffffff0))
812
813
class SAL_DLLPUBLIC_RTTI ScChangeTrack final : public utl::ConfigurationListener
814
{
815
    friend void ScChangeAction::RejectRestoreContents( ScChangeTrack*, SCCOL, SCROW );
816
    friend bool ScChangeActionDel::Reject( ScDocument& pDoc );
817
    friend void ScChangeActionDel::DeleteCellEntries();
818
    friend void ScChangeActionMove::DeleteCellEntries();
819
    friend bool ScChangeActionMove::Reject( ScDocument& pDoc );
820
821
    SCROW               mnContentRowsPerSlot;
822
    SCSIZE              mnContentSlots;
823
824
    css::uno::Sequence< sal_Int8 >   aProtectPass;
825
    ScChangeActionMap   aMap;
826
    ScChangeActionMap   aGeneratedMap;
827
    ScChangeActionMap   aPasteCutMap;
828
    ScChangeTrackMsgQueue   aMsgQueue;
829
    ScChangeTrackMsgStack   aMsgStackTmp;
830
    ScChangeTrackMsgStack   aMsgStackFinal;
831
    std::set<OUString> maUserCollection;
832
    OUString maUser;
833
    Link<ScChangeTrack&,void> aModifiedLink;
834
    ScRange             aInDeleteRange;
835
    DateTime            aFixDateTime;
836
    ScChangeAction*     pFirst;
837
    ScChangeAction*     pLast;
838
    ScChangeActionContent*  pFirstGeneratedDelContent;
839
    std::unique_ptr<ScChangeActionContent*[]> ppContentSlots;
840
    std::unique_ptr<ScChangeActionMove> pLastCutMove;
841
    ScChangeActionLinkEntry*    pLinkInsertCol;
842
    ScChangeActionLinkEntry*    pLinkInsertRow;
843
    ScChangeActionLinkEntry*    pLinkInsertTab;
844
    ScChangeActionLinkEntry*    pLinkMove;
845
    std::optional<ScChangeTrackMsgInfo> xBlockModifyMsg;
846
    ScDocument&             rDoc;
847
    sal_uLong               nActionMax;
848
    sal_uLong               nGeneratedMin;
849
    sal_uLong               nMarkLastSaved;
850
    sal_uLong               nStartLastCut;
851
    sal_uLong               nEndLastCut;
852
    sal_uLong               nLastMerge;
853
    ScChangeTrackMergeState eMergeState;
854
    bool bInDelete:1;
855
    bool bInDeleteUndo:1;
856
    bool bInDeleteTop:1;
857
    bool bInPasteCut:1;
858
    bool bUseFixDateTime:1;
859
    bool bTimeNanoSeconds:1;
860
861
    ScChangeTrack( const ScChangeTrack& ) = delete;
862
    ScChangeTrack& operator=( const ScChangeTrack& ) = delete;
863
864
    SCROW               InitContentRowsPerSlot();
865
866
    // true if one is ScMatrixMode::Formula and the other is
867
    // not, or if both are and range differs
868
    static bool IsMatrixFormulaRangeDifferent(
869
        const ScCellValue& rOldCell, const ScCellValue& rNewCell );
870
871
    void                Init();
872
    void                DtorClear();
873
    void                SetInDeleteRange( const ScRange& rRange )
874
0
                            { aInDeleteRange = rRange; }
875
    void                SetInDelete( bool bVal )
876
0
                            { bInDelete = bVal; }
877
    void                SetInDeleteTop( bool bVal )
878
0
                            { bInDeleteTop = bVal; }
879
    void                SetInDeleteUndo( bool bVal )
880
0
                            { bInDeleteUndo = bVal; }
881
    void                SetInPasteCut( bool bVal )
882
0
                            { bInPasteCut = bVal; }
883
    void                SetMergeState( ScChangeTrackMergeState eState )
884
0
                            { eMergeState = eState; }
885
0
    ScChangeTrackMergeState GetMergeState() const { return eMergeState; }
886
0
    void                SetLastMerge( sal_uLong nVal ) { nLastMerge = nVal; }
887
0
    sal_uLong               GetLastMerge() const { return nLastMerge; }
888
889
    void                SetLastCutMoveRange( const ScRange&, ScDocument& );
890
891
                        // create block of ModifyMsg
892
    void                StartBlockModify( ScChangeTrackMsgType,
893
                            sal_uLong nStartAction );
894
    void                EndBlockModify( sal_uLong nEndAction );
895
896
    void                AddDependentWithNotify( ScChangeAction* pParent,
897
                            ScChangeAction* pDependent );
898
899
    void                Dependencies( ScChangeAction* );
900
    void UpdateReference( ScChangeAction*, bool bUndo );
901
    void UpdateReference( ScChangeAction** ppFirstAction, ScChangeAction* pAct, bool bUndo );
902
    void                Append( ScChangeAction* pAppend, sal_uLong nAction );
903
    SC_DLLPUBLIC        void                AppendDeleteRange( const ScRange&,
904
                                    ScDocument* pRefDoc, SCTAB nDz,
905
                                    sal_uLong nRejectingInsert );
906
    void                AppendOneDeleteRange( const ScRange& rOrgRange,
907
                            ScDocument* pRefDoc,
908
                            SCCOL nDx, SCROW nDy, SCTAB nDz,
909
                            sal_uLong nRejectingInsert );
910
    void                LookUpContents( const ScRange& rOrgRange,
911
                            ScDocument* pRefDoc,
912
                            SCCOL nDx, SCROW nDy, SCTAB nDz );
913
    void                Remove( ScChangeAction* );
914
    void                MasterLinks( ScChangeAction* );
915
916
                                // Content on top at Position
917
    ScChangeActionContent*  SearchContentAt( const ScBigAddress&,
918
                                    const ScChangeAction* pButNotThis ) const;
919
    void                DeleteGeneratedDelContent(
920
                                    ScChangeActionContent* );
921
922
    ScChangeActionContent* GenerateDelContent(
923
        const ScAddress& rPos, const ScCellValue& rCell, const ScDocument* pFromDoc );
924
925
    void                DeleteCellEntries(
926
                                    std::vector<ScChangeActionContent*>&,
927
                                    const ScChangeAction* pDeletor );
928
929
                                // Reject action and all dependent actions,
930
                                // Table stems from previous GetDependents,
931
                                // only needed for Insert and Move (MasterType),
932
                                // is NULL otherwise.
933
                                // bRecursion == called from reject with table
934
    bool Reject( ScChangeAction*, ScChangeActionMap*, bool bRecursion );
935
936
    bool IsLastAction( sal_uLong nNum ) const;
937
938
            void                ClearMsgQueue();
939
    virtual void                ConfigurationChanged( utl::ConfigurationBroadcaster*, ConfigurationHints ) override;
940
941
public:
942
943
    SCSIZE              ComputeContentSlot( sal_Int32 nRow ) const;
944
945
    SC_DLLPUBLIC ScChangeTrack( ScDocument& );
946
    ScChangeTrack(ScDocument& rDocP, std::set<OUString>&& aTempUserCollection); // only to use in the XML import
947
    SC_DLLPUBLIC virtual ~ScChangeTrack() override;
948
    void Clear();
949
950
0
    ScChangeActionContent*  GetFirstGenerated() const { return pFirstGeneratedDelContent; }
951
36
    ScChangeAction*     GetFirst() const { return pFirst; }
952
0
    ScChangeAction*     GetLast() const { return pLast; }
953
0
    sal_uLong               GetActionMax() const { return nActionMax; }
954
    bool IsGenerated( sal_uLong nAction ) const;
955
    SC_DLLPUBLIC ScChangeAction* GetAction( sal_uLong nAction ) const;
956
    ScChangeAction* GetGenerated( sal_uLong nGenerated ) const;
957
    ScChangeAction* GetActionOrGenerated( sal_uLong nAction ) const;
958
    sal_uLong GetLastSavedActionNumber() const;
959
    void SetLastSavedActionNumber(sal_uLong nNew);
960
    ScChangeAction* GetLastSaved() const;
961
0
    ScChangeActionContent** GetContentSlots() const { return ppContentSlots.get(); }
962
963
    const ScRange&      GetInDeleteRange() const
964
0
                            { return aInDeleteRange; }
965
0
    bool IsInDelete() const { return bInDelete; }
966
0
    bool IsInDeleteTop() const { return bInDeleteTop; }
967
0
    bool IsInDeleteUndo() const { return bInDeleteUndo; }
968
0
    bool IsInPasteCut() const { return bInPasteCut; }
969
    void CreateAuthorName();
970
    SC_DLLPUBLIC void SetUser( const OUString& rUser );
971
36
    const OUString& GetUser() const { return maUser;}
972
0
    const std::set<OUString>& GetUserCollection() const { return maUserCollection;}
973
36
    ScDocument&         GetDocument() const { return rDoc; }
974
                        // for import filter
975
0
    const DateTime&     GetFixDateTime() const { return aFixDateTime; }
976
977
                        // set this if the date/time set with
978
                        // SetFixDateTime...() shall be applied to
979
                        // appended actions
980
    void                SetUseFixDateTime( bool bVal )
981
72
                            { bUseFixDateTime = bVal; }
982
                        // for MergeDocument, apply original date/time as UTC
983
    void                SetFixDateTimeUTC( const DateTime& rDT )
984
0
                            { aFixDateTime = rDT; }
985
                        // for import filter, apply original date/time as local time
986
    void                SetFixDateTimeLocal( const DateTime& rDT )
987
178
                            { aFixDateTime = rDT; aFixDateTime.ConvertToUTC(); }
988
989
    void                Append( ScChangeAction* );
990
991
                                // pRefDoc may be NULL => no lookup of contents
992
                                // => no generation of deleted contents
993
    SC_DLLPUBLIC void AppendDeleteRange( const ScRange&,
994
                                    ScDocument* pRefDoc,
995
                                    sal_uLong& nStartAction, sal_uLong& nEndAction,
996
                                    SCTAB nDz = 0 );
997
                                    // nDz: multi TabDel, LookUpContent must be searched
998
                                    // with an offset of -nDz
999
1000
                        // after new value was set in the document,
1001
                        // old value from RefDoc/UndoDoc
1002
    void                AppendContent( const ScAddress& rPos,
1003
                            const ScDocument& rRefDoc );
1004
                        // after new values were set in the document,
1005
                        // old values from RefDoc/UndoDoc
1006
    void                AppendContentRange( const ScRange& rRange,
1007
                            ScDocument& rRefDoc,
1008
                            sal_uLong& nStartAction, sal_uLong& nEndAction,
1009
                            ScChangeActionClipMode eMode = SC_CACM_NONE );
1010
                        // after new value was set in the document,
1011
                        // old value from pOldCell, nOldFormat,
1012
                        // RefDoc==NULL => Doc
1013
    void AppendContent( const ScAddress& rPos, const ScCellValue& rOldCell,
1014
                        sal_uLong nOldFormat, ScDocument* pRefDoc = nullptr );
1015
                        // after new value was set in the document,
1016
                        // old value from pOldCell, format from Doc
1017
    SC_DLLPUBLIC void AppendContent( const ScAddress& rPos, const ScCellValue& rOldCell );
1018
                        // after new values were set in the document,
1019
                        // old values from RefDoc/UndoDoc.
1020
                        // All contents with a cell in RefDoc
1021
    void                AppendContentsIfInRefDoc( ScDocument& rRefDoc,
1022
                            sal_uLong& nStartAction, sal_uLong& nEndAction );
1023
1024
                        // Meant for import filter, creates and inserts
1025
                        // an unconditional content action of the two
1026
                        // cells without querying the document, not
1027
                        // even for number formats (though the number
1028
                        // formatter of the document may be used).
1029
                        // The action is returned and may be used to
1030
                        // set user name, description, date/time et al.
1031
                        // Takes ownership of the cells!
1032
    SC_DLLPUBLIC ScChangeActionContent* AppendContentOnTheFly(
1033
        const ScAddress& rPos, const ScCellValue& rOldCell, const ScCellValue& rNewCell,
1034
        sal_uLong nOldFormat = 0, sal_uLong nNewFormat = 0 );
1035
1036
    // Only use the following two if there is no different solution! (Assign
1037
    // string for NewValue or creation of a formula respectively)
1038
1039
    SC_DLLPUBLIC void AppendInsert( const ScRange& rRange, bool bEndOfList = false );
1040
1041
                                // pRefDoc may be NULL => no lookup of contents
1042
                                // => no generation of deleted contents
1043
    SC_DLLPUBLIC void AppendMove( const ScRange& rFromRange, const ScRange& rToRange,
1044
                                  ScDocument* pRefDoc );
1045
1046
                                // Cut to Clipboard
1047
    void ResetLastCut()
1048
0
    {
1049
0
        nStartLastCut = nEndLastCut = 0;
1050
0
        pLastCutMove.reset();
1051
0
    }
1052
    bool HasLastCut() const
1053
0
    {
1054
0
        return nEndLastCut > 0 &&
1055
0
            nStartLastCut <= nEndLastCut &&
1056
0
            pLastCutMove;
1057
0
    }
1058
1059
    SC_DLLPUBLIC void Undo( sal_uLong nStartAction, sal_uLong nEndAction, bool bMerge = false );
1060
1061
                        // adjust references for MergeDocument
1062
                        //! may only be used in a temporary opened document.
1063
                        //! the Track (?) is unclean afterwards
1064
    void                MergePrepare( const ScChangeAction* pFirstMerge, bool bShared );
1065
    void                MergeOwn( ScChangeAction* pAct, sal_uLong nFirstMerge, bool bShared );
1066
    static bool MergeIgnore( const ScChangeAction&, sal_uLong nFirstMerge );
1067
1068
                                // This comment was already really strange in German.
1069
                                // Tried to structure it a little. Hope no information got lost...
1070
                                //
1071
                                // Insert dependents into table.
1072
                                // ScChangeAction is
1073
                                // - "Insert": really dependents
1074
                                // - "Move": dependent contents in FromRange /
1075
                                //           deleted contents in ToRange
1076
                                //      OR   inserts in FromRange or ToRange
1077
                                // - "Delete": a list of deleted (what?)
1078
                                //      OR     for content, different contents at the same position
1079
                                //      OR     MatrixReferences belonging to MatrixOrigin
1080
1081
                                // With bListMasterDelete (==TRUE ?) all Deletes of a row belonging
1082
                                // to a MasterDelete are listed (possibly it is
1083
                                // "all Deletes belonging...are listed in a row?)
1084
1085
                                // With bAllFlat (==TRUE ?) all dependents of dependents
1086
                                // will be inserted flatly.
1087
1088
    SC_DLLPUBLIC void GetDependents(
1089
        ScChangeAction*, ScChangeActionMap&, bool bListMasterDelete = false, bool bAllFlat = false ) const;
1090
1091
    // Reject visible action (and dependents)
1092
    bool Reject( ScChangeAction*, bool bShared = false );
1093
1094
    // Accept visible action (and dependents)
1095
    SC_DLLPUBLIC bool Accept( ScChangeAction* );
1096
1097
    void                AcceptAll();    // all Virgins
1098
    bool                RejectAll();    // all Virgins
1099
1100
    // Selects a content of several contents at the same
1101
    // position and accepts this one and
1102
    // the older ones, rejects the more recent ones.
1103
    // If bOldest==TRUE then the first OldValue
1104
    // of a Virgin-Content-List will be restored.
1105
    bool SelectContent( ScChangeAction*, bool bOldest = false );
1106
1107
                        // If ModifiedLink is set, changes go to
1108
                        // ScChangeTrackMsgQueue
1109
    void                SetModifiedLink( const Link<ScChangeTrack&,void>& r )
1110
0
                            { aModifiedLink = r; ClearMsgQueue(); }
1111
    ScChangeTrackMsgQueue& GetMsgQueue();
1112
1113
    void                NotifyModified( ScChangeTrackMsgType eMsgType,
1114
                            sal_uLong nStartAction, sal_uLong nEndAction );
1115
1116
    sal_uLong           AddLoadedGenerated( const ScCellValue& rNewCell,
1117
                            const ScBigRange& aBigRange, const OUString& sNewValue ); // only to use in the XML import
1118
    void                AppendLoaded( std::unique_ptr<ScChangeAction> pAppend ); // this is only for the XML import public, it should be protected
1119
    void                SetActionMax(sal_uLong nTempActionMax)
1120
0
                            { nActionMax = nTempActionMax; } // only to use in the XML import
1121
1122
    void                SetProtection( const css::uno::Sequence< sal_Int8 >& rPass )
1123
0
                            { aProtectPass = rPass; }
1124
    const css::uno::Sequence< sal_Int8 >& GetProtection() const
1125
0
                                    { return aProtectPass; }
1126
0
    bool IsProtected() const { return aProtectPass.hasElements(); }
1127
1128
                                // If time stamps of actions of this
1129
                                // ChangeTrack and a second one are to be
1130
                                // compared including nanoseconds.
1131
0
    void SetTimeNanoSeconds( bool bVal ) { bTimeNanoSeconds = bVal; }
1132
0
    bool IsTimeNanoSeconds() const { return bTimeNanoSeconds; }
1133
1134
    void AppendCloned( ScChangeAction* pAppend );
1135
    SC_DLLPUBLIC ScChangeTrack* Clone( ScDocument& rDocument ) const;
1136
    static void MergeActionState( ScChangeAction* pAct, const ScChangeAction* pOtherAct );
1137
    /// Get info about all ScChangeAction elements.
1138
    void GetChangeTrackInfo(tools::JsonWriter&);
1139
};
1140
1141
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */