/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: */ |