Coverage Report

Created: 2025-12-08 09:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sc/source/ui/undo/undodat.cxx
Line
Count
Source
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
#include <sfx2/app.hxx>
21
#include <svx/svdundo.hxx>
22
#include <unotools/charclass.hxx>
23
#include <osl/diagnose.h>
24
25
#include <undodat.hxx>
26
#include <undoutil.hxx>
27
#include <undoolk.hxx>
28
#include <document.hxx>
29
#include <docsh.hxx>
30
#include <tabvwsh.hxx>
31
#include <olinetab.hxx>
32
#include <dbdata.hxx>
33
#include <rangenam.hxx>
34
#include <globstr.hrc>
35
#include <scresid.hxx>
36
#include <global.hxx>
37
#include <globalnames.hxx>
38
#include <target.hxx>
39
#include <dbdocfun.hxx>
40
#include <olinefun.hxx>
41
#include <dpobject.hxx>
42
#include <attrib.hxx>
43
#include <hints.hxx>
44
#include <chgtrack.hxx>
45
#include <refundo.hxx>
46
#include <markdata.hxx>
47
#include <utility>
48
49
// Show or hide outline groups
50
51
ScUndoDoOutline::ScUndoDoOutline( ScDocShell& rNewDocShell,
52
                            SCCOLROW nNewStart, SCCOLROW nNewEnd, SCTAB nNewTab,
53
                            ScDocumentUniquePtr pNewUndoDoc, bool bNewColumns,
54
                            sal_uInt16 nNewLevel, sal_uInt16 nNewEntry, bool bNewShow ) :
55
0
    ScSimpleUndo( rNewDocShell ),
56
0
    nStart( nNewStart ),
57
0
    nEnd( nNewEnd ),
58
0
    nTab( nNewTab ),
59
0
    pUndoDoc( std::move(pNewUndoDoc) ),
60
0
    bColumns( bNewColumns ),
61
0
    nLevel( nNewLevel ),
62
0
    nEntry( nNewEntry ),
63
0
    bShow( bNewShow )
64
0
{
65
0
}
66
67
ScUndoDoOutline::~ScUndoDoOutline()
68
0
{
69
0
}
70
71
OUString ScUndoDoOutline::GetComment() const
72
0
{   // Show outline" "Hide outline"
73
0
    return bShow ?
74
0
        ScResId( STR_UNDO_DOOUTLINE ) :
75
0
        ScResId( STR_UNDO_REDOOUTLINE );
76
0
}
77
78
void ScUndoDoOutline::Undo()
79
0
{
80
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
81
0
    if (!pViewShell)
82
0
        return;
83
84
0
    BeginUndo();
85
86
0
    ScDocument& rDoc = rDocShell.GetDocument();
87
88
    // sheet has to be switched over (#46952#)!
89
90
0
    SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
91
0
    if ( nVisTab != nTab )
92
0
        pViewShell->SetTabNo( nTab );
93
94
    // perform the inverse function
95
96
0
    if (bShow)
97
0
        pViewShell->HideOutline( bColumns, nLevel, nEntry, false, false );
98
0
    else
99
0
        pViewShell->ShowOutline( bColumns, nLevel, nEntry, false, false );
100
101
    //  Original column/row status
102
0
    if (bColumns)
103
0
        pUndoDoc->CopyToDocument(static_cast<SCCOL>(nStart), 0, nTab,
104
0
                                 static_cast<SCCOL>(nEnd), rDoc.MaxRow(), nTab, InsertDeleteFlags::NONE, false, rDoc);
105
0
    else
106
0
        pUndoDoc->CopyToDocument(0, nStart, nTab, rDoc.MaxCol(), nEnd, nTab, InsertDeleteFlags::NONE, false, rDoc);
107
108
0
    ScTabViewShell::notifyAllViewsSheetGeomInvalidation(pViewShell, bColumns, !bColumns,
109
0
            false /* bSizes*/, true /* bHidden */, true /* bFiltered */,
110
0
            true /* bGroups */, nTab);
111
0
    pViewShell->UpdateScrollBars();
112
113
0
    rDocShell.PostPaint(0,0,nTab,rDoc.MaxCol(),rDoc.MaxRow(),nTab,PaintPartFlags::Grid|PaintPartFlags::Left|PaintPartFlags::Top);
114
115
0
    EndUndo();
116
0
}
117
118
void ScUndoDoOutline::Redo()
119
0
{
120
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
121
0
    if (!pViewShell)
122
0
        return;
123
124
0
    BeginRedo();
125
126
    // sheet has to be switched over (#46952#)!
127
128
0
    SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
129
0
    if ( nVisTab != nTab )
130
0
        pViewShell->SetTabNo( nTab );
131
132
0
    if (bShow)
133
0
        pViewShell->ShowOutline( bColumns, nLevel, nEntry, false );
134
0
    else
135
0
        pViewShell->HideOutline( bColumns, nLevel, nEntry, false );
136
137
0
    EndRedo();
138
0
}
139
140
void ScUndoDoOutline::Repeat(SfxRepeatTarget& /* rTarget */)
141
0
{
142
0
}
143
144
bool ScUndoDoOutline::CanRepeat(SfxRepeatTarget& /* rTarget */) const
145
0
{
146
0
    return false;                       // is not possible
147
0
}
148
149
/** Make or delete outline groups */
150
ScUndoMakeOutline::ScUndoMakeOutline( ScDocShell& rNewDocShell,
151
                            SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
152
                            SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
153
                            std::unique_ptr<ScOutlineTable> pNewUndoTab, bool bNewColumns, bool bNewMake ) :
154
0
    ScSimpleUndo( rNewDocShell ),
155
0
    aBlockStart( nStartX, nStartY, nStartZ ),
156
0
    aBlockEnd( nEndX, nEndY, nEndZ ),
157
0
    pUndoTable( std::move(pNewUndoTab) ),
158
0
    bColumns( bNewColumns ),
159
0
    bMake( bNewMake )
160
0
{
161
0
}
162
163
ScUndoMakeOutline::~ScUndoMakeOutline()
164
0
{
165
0
}
166
167
OUString ScUndoMakeOutline::GetComment() const
168
0
{   // "Grouping" "Undo grouping"
169
0
    return bMake ?
170
0
        ScResId( STR_UNDO_MAKEOUTLINE ) :
171
0
        ScResId( STR_UNDO_REMAKEOUTLINE );
172
0
}
173
174
void ScUndoMakeOutline::Undo()
175
0
{
176
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
177
0
    if (!pViewShell)
178
0
        return;
179
180
0
    BeginUndo();
181
182
0
    ScDocument& rDoc = rDocShell.GetDocument();
183
0
    SCTAB nTab = aBlockStart.Tab();
184
185
0
    ScUndoUtil::MarkSimpleBlock( rDocShell, aBlockStart, aBlockEnd );
186
187
0
    rDoc.SetOutlineTable( nTab, pUndoTable.get() );
188
189
0
    SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
190
0
    if ( nVisTab != nTab )
191
0
        pViewShell->SetTabNo( nTab );
192
193
0
    rDocShell.PostPaint(0,0,nTab,rDoc.MaxCol(),rDoc.MaxRow(),nTab,PaintPartFlags::Grid|PaintPartFlags::Left|PaintPartFlags::Top|PaintPartFlags::Size);
194
195
0
    ScTabViewShell::notifyAllViewsHeaderInvalidation( pViewShell, bColumns ? COLUMN_HEADER : ROW_HEADER, nTab );
196
0
    ScTabViewShell::notifyAllViewsSheetGeomInvalidation(
197
0
            pViewShell,
198
0
            bColumns /* bColumns */, !bColumns /* bRows */,
199
0
            false /* bSizes*/, true /* bHidden */, true /* bFiltered */,
200
0
            true /* bGroups */, nTab);
201
202
0
    EndUndo();
203
0
}
204
205
void ScUndoMakeOutline::Redo()
206
0
{
207
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
208
0
    if (!pViewShell)
209
0
        return;
210
211
0
    BeginRedo();
212
213
0
    ScDocument& rDoc = rDocShell.GetDocument();
214
215
0
    ScUndoUtil::MarkSimpleBlock( rDocShell, aBlockStart, aBlockEnd );
216
217
0
    if (bMake)
218
0
        pViewShell->MakeOutline( bColumns, false );
219
0
    else
220
0
        pViewShell->RemoveOutline( bColumns, false );
221
222
0
    rDocShell.PostPaint(0,0,aBlockStart.Tab(),rDoc.MaxCol(),rDoc.MaxRow(),aBlockEnd.Tab(),PaintPartFlags::Grid);
223
224
0
    EndRedo();
225
0
}
226
227
void ScUndoMakeOutline::Repeat(SfxRepeatTarget& rTarget)
228
0
{
229
0
    if (auto pViewTarget = dynamic_cast<ScTabViewTarget*>( &rTarget))
230
0
    {
231
0
        ScTabViewShell& rViewShell = pViewTarget->GetViewShell();
232
233
0
        if (bMake)
234
0
            rViewShell.MakeOutline( bColumns );
235
0
        else
236
0
            rViewShell.RemoveOutline( bColumns );
237
0
    }
238
0
}
239
240
bool ScUndoMakeOutline::CanRepeat(SfxRepeatTarget& rTarget) const
241
0
{
242
0
    return dynamic_cast<const ScTabViewTarget*>( &rTarget) !=  nullptr;
243
0
}
244
245
ScUndoOutlineLevel::ScUndoOutlineLevel( ScDocShell& rNewDocShell,
246
                        SCCOLROW nNewStart, SCCOLROW nNewEnd, SCTAB nNewTab,
247
                        ScDocumentUniquePtr pNewUndoDoc, std::unique_ptr<ScOutlineTable> pNewUndoTab,
248
                        bool bNewColumns, sal_uInt16 nNewLevel )
249
0
    : ScSimpleUndo(rNewDocShell)
250
0
    , nStart(nNewStart)
251
0
    , nEnd(nNewEnd)
252
0
    , nTab(nNewTab)
253
0
    , xUndoDoc(std::move(pNewUndoDoc))
254
0
    , xUndoTable(std::move(pNewUndoTab))
255
0
    , bColumns(bNewColumns)
256
0
    , nLevel(nNewLevel)
257
0
{
258
0
}
259
260
OUString ScUndoOutlineLevel::GetComment() const
261
0
{   // "Select outline level"
262
0
    return ScResId( STR_UNDO_OUTLINELEVEL );
263
0
}
264
265
void ScUndoOutlineLevel::Undo()
266
0
{
267
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
268
0
    if (!pViewShell)
269
0
        return;
270
271
0
    BeginUndo();
272
273
0
    ScDocument& rDoc = rDocShell.GetDocument();
274
275
    //  Original Outline table
276
277
0
    rDoc.SetOutlineTable(nTab, xUndoTable.get());
278
279
    //  Original column/row status
280
281
0
    if (bColumns)
282
0
        xUndoDoc->CopyToDocument(static_cast<SCCOL>(nStart), 0, nTab,
283
0
                                 static_cast<SCCOL>(nEnd), rDoc.MaxRow(), nTab, InsertDeleteFlags::NONE, false, rDoc);
284
0
    else
285
0
        xUndoDoc->CopyToDocument(0, nStart, nTab, rDoc.MaxCol(), nEnd, nTab, InsertDeleteFlags::NONE, false, rDoc);
286
287
0
    rDoc.UpdatePageBreaks( nTab );
288
289
0
    ScTabViewShell::notifyAllViewsSheetGeomInvalidation(pViewShell, bColumns, !bColumns,
290
0
            false /* bSizes*/, true /* bHidden */, true /* bFiltered */,
291
0
            true /* bGroups */, nTab);
292
0
    pViewShell->UpdateScrollBars();
293
294
0
    SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
295
0
    if ( nVisTab != nTab )
296
0
        pViewShell->SetTabNo( nTab );
297
298
0
    rDocShell.PostPaint(0,0,nTab,rDoc.MaxCol(),rDoc.MaxRow(),nTab,PaintPartFlags::Grid|PaintPartFlags::Left|PaintPartFlags::Top);
299
300
0
    EndUndo();
301
0
}
302
303
void ScUndoOutlineLevel::Redo()
304
0
{
305
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
306
0
    if (!pViewShell)
307
0
        return;
308
309
0
    BeginRedo();
310
311
    // sheet has to be switched on or off before this (#46952#) !!!
312
313
0
    SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
314
0
    if ( nVisTab != nTab )
315
0
        pViewShell->SetTabNo( nTab );
316
317
0
    pViewShell->SelectLevel( bColumns, nLevel, false );
318
319
0
    EndRedo();
320
0
}
321
322
void ScUndoOutlineLevel::Repeat(SfxRepeatTarget& rTarget)
323
0
{
324
0
    if (auto pViewTarget = dynamic_cast<ScTabViewTarget*>( &rTarget))
325
0
        pViewTarget->GetViewShell().SelectLevel( bColumns, nLevel );
326
0
}
327
328
bool ScUndoOutlineLevel::CanRepeat(SfxRepeatTarget& rTarget) const
329
0
{
330
0
    return dynamic_cast<const ScTabViewTarget*>( &rTarget) !=  nullptr;
331
0
}
332
333
/** show/hide outline over block marks */
334
ScUndoOutlineBlock::ScUndoOutlineBlock( ScDocShell& rNewDocShell,
335
                        SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
336
                        SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
337
                        ScDocumentUniquePtr pNewUndoDoc, std::unique_ptr<ScOutlineTable> pNewUndoTab, bool bNewShow ) :
338
0
    ScSimpleUndo( rNewDocShell ),
339
0
    aBlockStart( nStartX, nStartY, nStartZ ),
340
0
    aBlockEnd( nEndX, nEndY, nEndZ ),
341
0
    xUndoDoc(std::move(pNewUndoDoc)),
342
0
    xUndoTable(std::move(pNewUndoTab)),
343
0
    bShow( bNewShow )
344
0
{
345
0
}
346
347
OUString ScUndoOutlineBlock::GetComment() const
348
0
{   // "Show outline" "Hide outline"
349
0
    return bShow ?
350
0
        ScResId( STR_UNDO_DOOUTLINEBLK ) :
351
0
        ScResId( STR_UNDO_REDOOUTLINEBLK );
352
0
}
353
354
void ScUndoOutlineBlock::Undo()
355
0
{
356
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
357
0
    if (!pViewShell)
358
0
        return;
359
360
0
    BeginUndo();
361
362
0
    ScDocument& rDoc = rDocShell.GetDocument();
363
0
    SCTAB nTab = aBlockStart.Tab();
364
365
    //  Original Outline table
366
0
    rDoc.SetOutlineTable(nTab, xUndoTable.get());
367
368
    //  Original column/row status
369
0
    SCCOLROW    nStartCol = aBlockStart.Col();
370
0
    SCCOLROW    nEndCol = aBlockEnd.Col();
371
0
    SCCOLROW    nStartRow = aBlockStart.Row();
372
0
    SCCOLROW    nEndRow = aBlockEnd.Row();
373
374
0
    if (!bShow)
375
0
    {                               // Size of the hidden blocks
376
0
        size_t nLevel;
377
0
        xUndoTable->GetColArray().FindTouchedLevel(nStartCol, nEndCol, nLevel);
378
0
        xUndoTable->GetColArray().ExtendBlock(nLevel, nStartCol, nEndCol);
379
0
        xUndoTable->GetRowArray().FindTouchedLevel(nStartRow, nEndRow, nLevel);
380
0
        xUndoTable->GetRowArray().ExtendBlock(nLevel, nStartRow, nEndRow);
381
0
    }
382
383
0
    xUndoDoc->CopyToDocument(static_cast<SCCOL>(nStartCol), 0, nTab,
384
0
                             static_cast<SCCOL>(nEndCol), rDoc.MaxRow(), nTab, InsertDeleteFlags::NONE, false, rDoc);
385
0
    xUndoDoc->CopyToDocument(0, nStartRow, nTab, rDoc.MaxCol(), nEndRow, nTab, InsertDeleteFlags::NONE, false, rDoc);
386
387
0
    rDoc.UpdatePageBreaks( nTab );
388
389
0
    ScTabViewShell::notifyAllViewsSheetGeomInvalidation(pViewShell, true /* bColumns */, true /* bRows */,
390
0
            false /* bSizes*/, true /* bHidden */, true /* bFiltered */,
391
0
            true /* bGroups */, nTab);
392
0
    pViewShell->UpdateScrollBars();
393
394
0
    SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
395
0
    if ( nVisTab != nTab )
396
0
        pViewShell->SetTabNo( nTab );
397
398
0
    rDocShell.PostPaint(0,0,nTab,rDoc.MaxCol(),rDoc.MaxRow(),nTab,PaintPartFlags::Grid|PaintPartFlags::Left|PaintPartFlags::Top);
399
400
401
0
    pViewShell->OnLOKShowHideColRow(/*columns: */ true, nStartCol - 1);
402
0
    pViewShell->OnLOKShowHideColRow(/*columns: */ false, nStartRow - 1);
403
404
0
    EndUndo();
405
0
}
406
407
void ScUndoOutlineBlock::Redo()
408
0
{
409
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
410
0
    if (!pViewShell)
411
0
        return;
412
413
0
    BeginRedo();
414
415
0
    ScUndoUtil::MarkSimpleBlock( rDocShell, aBlockStart, aBlockEnd );
416
0
    if (bShow)
417
0
        pViewShell->ShowMarkedOutlines( false );
418
0
    else
419
0
        pViewShell->HideMarkedOutlines( false );
420
421
0
    EndRedo();
422
0
}
423
424
void ScUndoOutlineBlock::Repeat(SfxRepeatTarget& rTarget)
425
0
{
426
0
    if (auto pViewTarget = dynamic_cast<ScTabViewTarget*>( &rTarget))
427
0
    {
428
0
        ScTabViewShell& rViewShell = pViewTarget->GetViewShell();
429
430
0
        if (bShow)
431
0
            rViewShell.ShowMarkedOutlines();
432
0
        else
433
0
            rViewShell.HideMarkedOutlines();
434
0
    }
435
0
}
436
437
bool ScUndoOutlineBlock::CanRepeat(SfxRepeatTarget& rTarget) const
438
0
{
439
0
    return dynamic_cast<const ScTabViewTarget*>( &rTarget) !=  nullptr;
440
0
}
441
442
ScUndoRemoveAllOutlines::ScUndoRemoveAllOutlines(ScDocShell& rNewDocShell,
443
                                    SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
444
                                    SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
445
                                    ScDocumentUniquePtr pNewUndoDoc, std::unique_ptr<ScOutlineTable> pNewUndoTab)
446
0
    : ScSimpleUndo(rNewDocShell)
447
0
    , aBlockStart(nStartX, nStartY, nStartZ)
448
0
    , aBlockEnd(nEndX, nEndY, nEndZ)
449
0
    , xUndoDoc(std::move(pNewUndoDoc))
450
0
    , xUndoTable(std::move(pNewUndoTab))
451
0
{
452
0
}
453
454
OUString ScUndoRemoveAllOutlines::GetComment() const
455
0
{   // "Remove outlines"
456
0
    return ScResId( STR_UNDO_REMOVEALLOTLNS );
457
0
}
458
459
void ScUndoRemoveAllOutlines::Undo()
460
0
{
461
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
462
0
    if (!pViewShell)
463
0
        return;
464
465
0
    BeginUndo();
466
467
0
    ScDocument& rDoc = rDocShell.GetDocument();
468
0
    SCTAB nTab = aBlockStart.Tab();
469
470
    //  Original Outline table
471
0
    rDoc.SetOutlineTable(nTab, xUndoTable.get());
472
473
    //  Original column/row status
474
0
    SCCOL   nStartCol = aBlockStart.Col();
475
0
    SCCOL   nEndCol = aBlockEnd.Col();
476
0
    SCROW   nStartRow = aBlockStart.Row();
477
0
    SCROW   nEndRow = aBlockEnd.Row();
478
479
0
    xUndoDoc->CopyToDocument(nStartCol, 0, nTab, nEndCol, rDoc.MaxRow(), nTab, InsertDeleteFlags::NONE, false, rDoc);
480
0
    xUndoDoc->CopyToDocument(0, nStartRow, nTab, rDoc.MaxCol(), nEndRow, nTab, InsertDeleteFlags::NONE, false, rDoc);
481
482
0
    rDoc.UpdatePageBreaks( nTab );
483
484
0
    pViewShell->UpdateScrollBars();
485
486
0
    SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
487
0
    if ( nVisTab != nTab )
488
0
        pViewShell->SetTabNo( nTab );
489
490
0
    rDocShell.PostPaint(0,0,nTab,rDoc.MaxCol(),rDoc.MaxRow(),nTab,PaintPartFlags::Grid|PaintPartFlags::Left|PaintPartFlags::Top|PaintPartFlags::Size);
491
492
0
    ScTabViewShell::notifyAllViewsHeaderInvalidation(pViewShell, BOTH_HEADERS, nTab);
493
0
    ScTabViewShell::notifyAllViewsSheetGeomInvalidation(
494
0
            pViewShell,
495
0
            true /* bColumns */, true /* bRows */,
496
0
            false /* bSizes*/, true /* bHidden */, true /* bFiltered */,
497
0
            true /* bGroups */, nTab);
498
499
0
    EndUndo();
500
0
}
501
502
void ScUndoRemoveAllOutlines::Redo()
503
0
{
504
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
505
0
    if (!pViewShell)
506
0
        return;
507
508
0
    BeginRedo();
509
510
    // sheet has to be switched over (#46952#)!
511
512
0
    SCTAB nTab = aBlockStart.Tab();
513
0
    SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
514
0
    if ( nVisTab != nTab )
515
0
        pViewShell->SetTabNo( nTab );
516
517
0
    pViewShell->RemoveAllOutlines( false );
518
519
0
    EndRedo();
520
0
}
521
522
void ScUndoRemoveAllOutlines::Repeat(SfxRepeatTarget& rTarget)
523
0
{
524
0
    if (auto pViewTarget = dynamic_cast<ScTabViewTarget*>( &rTarget))
525
0
        pViewTarget->GetViewShell().RemoveAllOutlines();
526
0
}
527
528
bool ScUndoRemoveAllOutlines::CanRepeat(SfxRepeatTarget& rTarget) const
529
0
{
530
0
    return dynamic_cast<const ScTabViewTarget*>( &rTarget) !=  nullptr;
531
0
}
532
533
ScUndoAutoOutline::ScUndoAutoOutline(ScDocShell& rNewDocShell,
534
                                     SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
535
                                     SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
536
                                     ScDocumentUniquePtr pNewUndoDoc, std::unique_ptr<ScOutlineTable> pNewUndoTab)
537
0
    : ScSimpleUndo(rNewDocShell)
538
0
    , aBlockStart(nStartX, nStartY, nStartZ)
539
0
    , aBlockEnd(nEndX, nEndY, nEndZ)
540
0
    , xUndoDoc(std::move(pNewUndoDoc))
541
0
    , xUndoTable(std::move(pNewUndoTab))
542
0
{
543
0
}
544
545
OUString ScUndoAutoOutline::GetComment() const
546
0
{
547
0
    return ScResId( STR_UNDO_AUTOOUTLINE );
548
0
}
549
550
void ScUndoAutoOutline::Undo()
551
0
{
552
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
553
0
    if (!pViewShell)
554
0
        return;
555
556
0
    BeginUndo();
557
558
0
    ScDocument& rDoc = rDocShell.GetDocument();
559
0
    SCTAB nTab = aBlockStart.Tab();
560
561
    // Original outline table
562
0
    rDoc.SetOutlineTable(nTab, xUndoTable.get());
563
564
    // Original column/row status
565
0
    if (xUndoDoc && xUndoTable)
566
0
    {
567
0
        SCCOLROW nStartCol;
568
0
        SCCOLROW nStartRow;
569
0
        SCCOLROW nEndCol;
570
0
        SCCOLROW nEndRow;
571
0
        xUndoTable->GetColArray().GetRange(nStartCol, nEndCol);
572
0
        xUndoTable->GetRowArray().GetRange(nStartRow, nEndRow);
573
574
0
        xUndoDoc->CopyToDocument(static_cast<SCCOL>(nStartCol), 0, nTab,
575
0
                                 static_cast<SCCOL>(nEndCol), rDoc.MaxRow(), nTab, InsertDeleteFlags::NONE, false,
576
0
                                 rDoc);
577
0
        xUndoDoc->CopyToDocument(0, nStartRow, nTab, rDoc.MaxCol(), nEndRow, nTab, InsertDeleteFlags::NONE, false, rDoc);
578
579
0
        pViewShell->UpdateScrollBars();
580
0
    }
581
582
0
    SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
583
0
    if ( nVisTab != nTab )
584
0
        pViewShell->SetTabNo( nTab );
585
586
0
    rDocShell.PostPaint(0,0,nTab,rDoc.MaxCol(),rDoc.MaxRow(),nTab,PaintPartFlags::Grid|PaintPartFlags::Left|PaintPartFlags::Top|PaintPartFlags::Size);
587
588
0
    EndUndo();
589
0
}
590
591
void ScUndoAutoOutline::Redo()
592
0
{
593
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
594
0
    if (!pViewShell)
595
0
        return;
596
597
0
    BeginRedo();
598
599
0
    SCTAB nTab = aBlockStart.Tab();
600
    // sheet has to be switched on or off before this (#46952#) !!!
601
602
0
    SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
603
0
    if ( nVisTab != nTab )
604
0
        pViewShell->SetTabNo( nTab );
605
606
0
    ScRange aRange( aBlockStart.Col(), aBlockStart.Row(), nTab,
607
0
                    aBlockEnd.Col(),   aBlockEnd.Row(),   nTab );
608
0
    ScOutlineDocFunc aFunc( rDocShell );
609
0
    aFunc.AutoOutline( aRange, false );
610
611
    //  Select in View
612
    //  If it was called with a multi selection,
613
    //  then this is now the enclosing range...
614
615
0
    pViewShell->MarkRange( aRange );
616
617
0
    EndRedo();
618
0
}
619
620
void ScUndoAutoOutline::Repeat(SfxRepeatTarget& rTarget)
621
0
{
622
0
    if (auto pViewTarget = dynamic_cast<ScTabViewTarget*>( &rTarget))
623
0
        pViewTarget->GetViewShell().AutoOutline();
624
0
}
625
626
bool ScUndoAutoOutline::CanRepeat(SfxRepeatTarget& rTarget) const
627
0
{
628
0
    return dynamic_cast<const ScTabViewTarget*>( &rTarget) !=  nullptr;
629
0
}
630
631
ScUndoSubTotals::ScUndoSubTotals(ScDocShell& rNewDocShell, SCTAB nNewTab,
632
                                 const ScSubTotalParam& rNewParam, SCROW nNewEndY,
633
                                 ScDocumentUniquePtr pNewUndoDoc, std::unique_ptr<ScOutlineTable> pNewUndoTab,
634
                                 std::unique_ptr<ScRangeName> pNewUndoRange, std::unique_ptr<ScDBCollection> pNewUndoDB)
635
0
    : ScDBFuncUndo(rNewDocShell, ScRange(rNewParam.nCol1, rNewParam.nRow1, nNewTab,
636
0
                                         rNewParam.nCol2, rNewParam.nRow2, nNewTab))
637
0
    , nTab(nNewTab)
638
0
    , aParam(rNewParam)
639
0
    , nNewEndRow(nNewEndY)
640
0
    , xUndoDoc(std::move(pNewUndoDoc))
641
0
    , xUndoTable(std::move(pNewUndoTab))
642
0
    , xUndoRange(std::move(pNewUndoRange))
643
0
    , xUndoDB(std::move(pNewUndoDB))
644
0
{
645
0
}
646
647
OUString ScUndoSubTotals::GetComment() const
648
0
{   // "Subtotals"
649
0
    return ScResId( STR_UNDO_SUBTOTALS );
650
0
}
651
652
void ScUndoSubTotals::Undo()
653
0
{
654
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
655
0
    if (!pViewShell)
656
0
        return;
657
658
0
    BeginUndo();
659
660
0
    ScDocument& rDoc = rDocShell.GetDocument();
661
662
0
    if (nNewEndRow > aParam.nRow2)
663
0
    {
664
0
        rDoc.DeleteRow( 0,nTab, rDoc.MaxCol(),nTab, aParam.nRow2+1, static_cast<SCSIZE>(nNewEndRow-aParam.nRow2) );
665
0
    }
666
0
    else if (nNewEndRow < aParam.nRow2)
667
0
    {
668
0
        rDoc.InsertRow( 0,nTab, rDoc.MaxCol(),nTab, nNewEndRow+1, static_cast<SCSIZE>(aParam.nRow2-nNewEndRow) );
669
0
    }
670
671
    // Original Outline table
672
0
    rDoc.SetOutlineTable(nTab, xUndoTable.get());
673
674
    // Original column/row status
675
0
    if (xUndoTable)
676
0
    {
677
0
        SCCOLROW nStartCol;
678
0
        SCCOLROW nStartRow;
679
0
        SCCOLROW nEndCol;
680
0
        SCCOLROW nEndRow;
681
0
        xUndoTable->GetColArray().GetRange(nStartCol, nEndCol);
682
0
        xUndoTable->GetRowArray().GetRange(nStartRow, nEndRow);
683
684
0
        xUndoDoc->CopyToDocument(static_cast<SCCOL>(nStartCol), 0, nTab,
685
0
                                 static_cast<SCCOL>(nEndCol), rDoc.MaxRow(), nTab, InsertDeleteFlags::NONE, false,
686
0
                                 rDoc);
687
0
        xUndoDoc->CopyToDocument(0, nStartRow, nTab, rDoc.MaxCol(), nEndRow, nTab, InsertDeleteFlags::NONE, false, rDoc);
688
689
0
        pViewShell->UpdateScrollBars();
690
0
    }
691
692
    //  Original data and references
693
694
0
    ScUndoUtil::MarkSimpleBlock( rDocShell, 0, aParam.nRow1+1, nTab,
695
0
                                            rDoc.MaxCol(), aParam.nRow2, nTab );
696
697
0
    rDoc.DeleteAreaTab( 0,aParam.nRow1+1, rDoc.MaxCol(),aParam.nRow2, nTab, InsertDeleteFlags::ALL );
698
699
0
    xUndoDoc->CopyToDocument(0, aParam.nRow1+1, nTab, rDoc.MaxCol(), aParam.nRow2, nTab,
700
0
                                                            InsertDeleteFlags::NONE, false, rDoc);    // Flags
701
0
    xUndoDoc->UndoToDocument(0, aParam.nRow1+1, nTab, rDoc.MaxCol(), aParam.nRow2, nTab,
702
0
                                                            InsertDeleteFlags::ALL, false, rDoc);
703
704
0
    ScUndoUtil::MarkSimpleBlock( rDocShell, aParam.nCol1,aParam.nRow1,nTab,
705
0
                                            aParam.nCol2,aParam.nRow2,nTab );
706
707
0
    if (xUndoRange)
708
0
        rDoc.SetRangeName(std::unique_ptr<ScRangeName>(new ScRangeName(*xUndoRange)));
709
0
    if (xUndoDB)
710
0
        rDoc.SetDBCollection(std::unique_ptr<ScDBCollection>(new ScDBCollection(*xUndoDB)), true);
711
712
0
    SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
713
0
    if ( nVisTab != nTab )
714
0
        pViewShell->SetTabNo( nTab );
715
716
0
    rDocShell.PostPaint(0,0,nTab,rDoc.MaxCol(),rDoc.MaxRow(),nTab,PaintPartFlags::Grid|PaintPartFlags::Left|PaintPartFlags::Top|PaintPartFlags::Size);
717
0
    rDocShell.PostDataChanged();
718
719
0
    EndUndo();
720
0
}
721
722
void ScUndoSubTotals::Redo()
723
0
{
724
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
725
0
    if (!pViewShell)
726
0
        return;
727
728
0
    BeginRedo();
729
730
0
    SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
731
0
    if ( nVisTab != nTab )
732
0
        pViewShell->SetTabNo( nTab );
733
734
0
    ScUndoUtil::MarkSimpleBlock( rDocShell, aParam.nCol1,aParam.nRow1,nTab,
735
0
                                            aParam.nCol2,aParam.nRow2,nTab );
736
0
    pViewShell->DoSubTotals( aParam, false );
737
738
0
    EndRedo();
739
0
}
740
741
void ScUndoSubTotals::Repeat(SfxRepeatTarget& /* rTarget */)
742
0
{
743
0
}
744
745
bool ScUndoSubTotals::CanRepeat(SfxRepeatTarget& /* rTarget */) const
746
0
{
747
0
    return false;     // is not possible due to column numbers
748
0
}
749
750
ScUndoQuery::ScUndoQuery( ScDocShell& rNewDocShell, SCTAB nNewTab, const ScQueryParam& rParam,
751
                            ScDocumentUniquePtr pNewUndoDoc, std::unique_ptr<ScDBCollection> pNewUndoDB,
752
                            const ScRange* pOld, bool bSize, const ScRange* pAdvSrc ) :
753
0
    ScDBFuncUndo( rNewDocShell, ScRange( rParam.nCol1, rParam.nRow1, nNewTab,
754
0
                                         rParam.nCol2, rParam.nRow2, nNewTab ) ),
755
0
    nTab( nNewTab ),
756
0
    aQueryParam( rParam ),
757
0
    xUndoDoc( std::move(pNewUndoDoc) ),
758
0
    xUndoDB( std::move(pNewUndoDB) ),
759
0
    bIsAdvanced( false ),
760
0
    bDestArea( false ),
761
0
    bDoSize( bSize )
762
0
{
763
0
    if ( pOld )
764
0
    {
765
0
        bDestArea = true;
766
0
        aOldDest = *pOld;
767
0
    }
768
0
    if ( pAdvSrc )
769
0
    {
770
0
        bIsAdvanced = true;
771
0
        aAdvSource = *pAdvSrc;
772
0
    }
773
774
0
    pDrawUndo = GetSdrUndoAction( &rDocShell.GetDocument() );
775
0
}
776
777
ScUndoQuery::~ScUndoQuery()
778
0
{
779
0
    pDrawUndo.reset();
780
0
}
781
782
OUString ScUndoQuery::GetComment() const
783
0
{   // "Filter";
784
0
    return ScResId( STR_UNDO_QUERY );
785
0
}
786
787
void ScUndoQuery::Undo()
788
0
{
789
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
790
0
    if (!pViewShell)
791
0
        return;
792
793
0
    if (ScTabViewShell::isAnyEditViewInRange(pViewShell, /*bColumns*/ false, aQueryParam.nRow1, aQueryParam.nRow2))
794
0
        return;
795
796
0
    BeginUndo();
797
798
0
    ScDocument& rDoc = rDocShell.GetDocument();
799
800
0
    bool bCopy = !aQueryParam.bInplace;
801
0
    SCCOL nDestEndCol = 0;
802
0
    SCROW nDestEndRow = 0;
803
0
    if (bCopy)
804
0
    {
805
0
        nDestEndCol = aQueryParam.nDestCol + ( aQueryParam.nCol2-aQueryParam.nCol1 );
806
0
        nDestEndRow = aQueryParam.nDestRow + ( aQueryParam.nRow2-aQueryParam.nRow1 );
807
808
0
        ScDBData* pData = rDoc.GetDBAtCursor( aQueryParam.nDestCol, aQueryParam.nDestRow,
809
0
                                                aQueryParam.nDestTab, ScDBDataPortion::TOP_LEFT );
810
0
        if (pData)
811
0
        {
812
0
            ScRange aNewDest;
813
0
            pData->GetArea( aNewDest );
814
0
            nDestEndCol = aNewDest.aEnd.Col();
815
0
            nDestEndRow = aNewDest.aEnd.Row();
816
0
        }
817
818
0
        if ( bDoSize && bDestArea )
819
0
        {
820
            //  aDestRange is the old range
821
0
            rDoc.FitBlock( ScRange(
822
0
                                aQueryParam.nDestCol, aQueryParam.nDestRow, aQueryParam.nDestTab,
823
0
                                nDestEndCol, nDestEndRow, aQueryParam.nDestTab ),
824
0
                            aOldDest );
825
0
        }
826
827
0
        ScUndoUtil::MarkSimpleBlock( rDocShell,
828
0
                                    aQueryParam.nDestCol, aQueryParam.nDestRow, aQueryParam.nDestTab,
829
0
                                    nDestEndCol, nDestEndRow, aQueryParam.nDestTab );
830
0
        rDoc.DeleteAreaTab( aQueryParam.nDestCol, aQueryParam.nDestRow,
831
0
                            nDestEndCol, nDestEndRow, aQueryParam.nDestTab, InsertDeleteFlags::ALL );
832
833
0
        pViewShell->DoneBlockMode();
834
835
0
        xUndoDoc->CopyToDocument(aQueryParam.nDestCol, aQueryParam.nDestRow, aQueryParam.nDestTab,
836
0
                                 nDestEndCol, nDestEndRow, aQueryParam.nDestTab,
837
0
                                 InsertDeleteFlags::ALL, false, rDoc);
838
        //  Attributes are always copied (#49287#)
839
840
        // rest of the old range
841
0
        if ( bDestArea && !bDoSize )
842
0
        {
843
0
            rDoc.DeleteAreaTab( aOldDest, InsertDeleteFlags::ALL );
844
0
            xUndoDoc->CopyToDocument(aOldDest, InsertDeleteFlags::ALL, false, rDoc);
845
0
        }
846
0
    }
847
0
    else
848
0
        xUndoDoc->CopyToDocument(0, aQueryParam.nRow1, nTab, rDoc.MaxCol(), aQueryParam.nRow2, nTab,
849
0
                                 InsertDeleteFlags::NONE, false, rDoc);
850
851
0
    if (xUndoDB)
852
0
        rDoc.SetDBCollection(std::unique_ptr<ScDBCollection>(new ScDBCollection(*xUndoDB )), true);
853
854
0
    if (!bCopy)
855
0
    {
856
0
        rDoc.InvalidatePageBreaks(nTab);
857
0
        rDoc.UpdatePageBreaks( nTab );
858
0
    }
859
860
0
    ScRange aDirtyRange( 0 , aQueryParam.nRow1, nTab,
861
0
        rDoc.MaxCol(), aQueryParam.nRow2, nTab );
862
0
    rDoc.SetDirty( aDirtyRange, true );
863
864
0
    DoSdrUndoAction( pDrawUndo.get(), &rDoc );
865
866
0
    SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
867
0
    if ( nVisTab != nTab )
868
0
        pViewShell->SetTabNo( nTab );
869
870
871
    // invalidate cache positions and update cursor and selection
872
0
    pViewShell->OnLOKShowHideColRow(/*bColumns*/ false, aQueryParam.nRow1 - 1);
873
0
    ScTabViewShell::notifyAllViewsHeaderInvalidation(pViewShell, ROW_HEADER, nTab);
874
0
    ScTabViewShell::notifyAllViewsSheetGeomInvalidation(
875
0
            pViewShell,
876
0
            false /* bColumns */, true /* bRows */,
877
0
            false /* bSizes*/, true /* bHidden */, true /* bFiltered */,
878
0
            false /* bGroups */, nTab);
879
880
    //  Paint
881
882
0
    if (bCopy)
883
0
    {
884
0
        SCCOL nEndX = nDestEndCol;
885
0
        SCROW nEndY = nDestEndRow;
886
0
        if (bDestArea)
887
0
        {
888
0
            if ( aOldDest.aEnd.Col() > nEndX )
889
0
                nEndX = aOldDest.aEnd.Col();
890
0
            if ( aOldDest.aEnd.Row() > nEndY )
891
0
                nEndY = aOldDest.aEnd.Row();
892
0
        }
893
0
        if (bDoSize)
894
0
            nEndY = rDoc.MaxRow();
895
0
        rDocShell.PostPaint( aQueryParam.nDestCol, aQueryParam.nDestRow, aQueryParam.nDestTab,
896
0
                                    nEndX, nEndY, aQueryParam.nDestTab, PaintPartFlags::Grid );
897
0
    }
898
0
    else
899
0
        rDocShell.PostPaint( 0, aQueryParam.nRow1, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab,
900
0
                                                    PaintPartFlags::Grid | PaintPartFlags::Left );
901
0
    rDocShell.PostDataChanged();
902
903
0
    EndUndo();
904
0
}
905
906
void ScUndoQuery::Redo()
907
0
{
908
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
909
0
    if (!pViewShell)
910
0
        return;
911
912
0
    BeginRedo();
913
914
0
    SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
915
0
    if ( nVisTab != nTab )
916
0
        pViewShell->SetTabNo( nTab );
917
918
0
    if ( bIsAdvanced )
919
0
        pViewShell->Query( aQueryParam, &aAdvSource, false );
920
0
    else
921
0
        pViewShell->Query( aQueryParam, nullptr, false );
922
923
0
    EndRedo();
924
0
}
925
926
void ScUndoQuery::Repeat(SfxRepeatTarget& /* rTarget */)
927
0
{
928
0
}
929
930
bool ScUndoQuery::CanRepeat(SfxRepeatTarget& /* rTarget */) const
931
0
{
932
0
    return false;    // does not work due to column numbers
933
0
}
934
935
//      Show or hide AutoFilter buttons (doesn't include filter settings)
936
937
ScUndoAutoFilter::ScUndoAutoFilter( ScDocShell& rNewDocShell, const ScRange& rRange,
938
                                    OUString aName, bool bSet ) :
939
0
    ScDBFuncUndo( rNewDocShell, rRange ),
940
0
    aDBName(std::move( aName )),
941
0
    bFilterSet( bSet )
942
0
{
943
0
}
944
945
ScUndoAutoFilter::~ScUndoAutoFilter()
946
0
{
947
0
}
948
949
OUString ScUndoAutoFilter::GetComment() const
950
0
{
951
0
    return ScResId( STR_UNDO_QUERY );    // same as ScUndoQuery
952
0
}
953
954
void ScUndoAutoFilter::DoChange( bool bUndo )
955
0
{
956
0
    bool bNewFilter = bUndo ? !bFilterSet : bFilterSet;
957
958
0
    ScDocument& rDoc = rDocShell.GetDocument();
959
0
    ScDBData* pDBData=nullptr;
960
0
    if (aDBName == STR_DB_LOCAL_NONAME)
961
0
    {
962
0
        SCTAB nTab = aOriginalRange.aStart.Tab();
963
0
        pDBData = rDoc.GetAnonymousDBData(nTab);
964
0
    }
965
0
    else
966
0
    {
967
0
        ScDBCollection* pColl = rDoc.GetDBCollection();
968
0
        pDBData = pColl->getNamedDBs().findByUpperName(ScGlobal::getCharClass().uppercase(aDBName));
969
0
    }
970
971
0
    if ( !pDBData )
972
0
        return;
973
974
0
    pDBData->SetAutoFilter( bNewFilter );
975
976
0
    SCCOL nRangeX1;
977
0
    SCROW nRangeY1;
978
0
    SCCOL nRangeX2;
979
0
    SCROW nRangeY2;
980
0
    SCTAB nRangeTab;
981
0
    pDBData->GetArea( nRangeTab, nRangeX1, nRangeY1, nRangeX2, nRangeY2 );
982
983
0
    if ( bNewFilter )
984
0
        rDoc.ApplyFlagsTab( nRangeX1, nRangeY1, nRangeX2, nRangeY1, nRangeTab, ScMF::Auto );
985
0
    else
986
0
        rDoc.RemoveFlagsTab( nRangeX1, nRangeY1, nRangeX2, nRangeY1, nRangeTab, ScMF::Auto );
987
988
0
    rDocShell.PostPaint( nRangeX1, nRangeY1, nRangeTab, nRangeX2, nRangeY1, nRangeTab, PaintPartFlags::Grid );
989
0
}
990
991
void ScUndoAutoFilter::Undo()
992
0
{
993
0
    BeginUndo();
994
0
    DoChange( true );
995
0
    EndUndo();
996
0
}
997
998
void ScUndoAutoFilter::Redo()
999
0
{
1000
0
    BeginRedo();
1001
0
    DoChange( false );
1002
0
    EndRedo();
1003
0
}
1004
1005
void ScUndoAutoFilter::Repeat(SfxRepeatTarget& /* rTarget */)
1006
0
{
1007
0
}
1008
1009
bool ScUndoAutoFilter::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1010
0
{
1011
0
    return false;
1012
0
}
1013
1014
// change database sections (dialog)
1015
ScUndoDBData::ScUndoDBData( ScDocShell& rNewDocShell,
1016
                            std::unique_ptr<ScDBCollection> pNewUndoColl,
1017
                            std::unique_ptr<ScDBCollection> pNewRedoColl ) :
1018
0
    ScSimpleUndo( rNewDocShell ),
1019
0
    pUndoColl( std::move(pNewUndoColl) ),
1020
0
    pRedoColl( std::move(pNewRedoColl) )
1021
0
{
1022
0
}
1023
1024
ScUndoDBData::~ScUndoDBData()
1025
0
{
1026
0
}
1027
1028
OUString ScUndoDBData::GetComment() const
1029
0
{   // "Change database range";
1030
0
    return ScResId( STR_UNDO_DBDATA );
1031
0
}
1032
1033
void ScUndoDBData::Undo()
1034
0
{
1035
0
    BeginUndo();
1036
1037
0
    ScDocument& rDoc = rDocShell.GetDocument();
1038
1039
0
    bool bOldAutoCalc = rDoc.GetAutoCalc();
1040
0
    rDoc.SetAutoCalc( false );         // Avoid unnecessary calculations
1041
0
    rDoc.PreprocessDBDataUpdate();
1042
0
    rDoc.SetDBCollection( std::unique_ptr<ScDBCollection>(new ScDBCollection(*pUndoColl)), true );
1043
0
    rDoc.CompileHybridFormula();
1044
0
    rDoc.SetAutoCalc( bOldAutoCalc );
1045
1046
0
    SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScDbAreasChanged ) );
1047
1048
0
    EndUndo();
1049
0
}
1050
1051
void ScUndoDBData::Redo()
1052
0
{
1053
0
    BeginRedo();
1054
1055
0
    ScDocument& rDoc = rDocShell.GetDocument();
1056
1057
0
    bool bOldAutoCalc = rDoc.GetAutoCalc();
1058
0
    rDoc.SetAutoCalc( false );         // Avoid unnecessary calculations
1059
0
    rDoc.PreprocessDBDataUpdate();
1060
0
    rDoc.SetDBCollection( std::unique_ptr<ScDBCollection>(new ScDBCollection(*pRedoColl)), true );
1061
0
    rDoc.CompileHybridFormula();
1062
0
    rDoc.SetAutoCalc( bOldAutoCalc );
1063
1064
0
    SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScDbAreasChanged ) );
1065
1066
0
    EndRedo();
1067
0
}
1068
1069
void ScUndoDBData::Repeat(SfxRepeatTarget& /* rTarget */)
1070
0
{
1071
0
}
1072
1073
bool ScUndoDBData::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1074
0
{
1075
0
    return false;    // is not possible
1076
0
}
1077
1078
ScUndoImportData::ScUndoImportData( ScDocShell& rNewDocShell, SCTAB nNewTab,
1079
                                const ScImportParam& rParam, SCCOL nNewEndX, SCROW nNewEndY,
1080
                                SCCOL nNewFormula,
1081
                                ScDocumentUniquePtr pNewUndoDoc, ScDocumentUniquePtr pNewRedoDoc,
1082
                                std::unique_ptr<ScDBData> pNewUndoData, std::unique_ptr<ScDBData> pNewRedoData ) :
1083
0
    ScSimpleUndo( rNewDocShell ),
1084
0
    nTab( nNewTab ),
1085
0
    aImportParam( rParam ),
1086
0
    nEndCol( nNewEndX ),
1087
0
    nEndRow( nNewEndY ),
1088
0
    xUndoDoc(std::move(pNewUndoDoc)),
1089
0
    xRedoDoc(std::move(pNewRedoDoc)),
1090
0
    xUndoDBData(std::move(pNewUndoData)),
1091
0
    xRedoDBData(std::move(pNewRedoData)),
1092
0
    nFormulaCols( nNewFormula ),
1093
0
    bRedoFilled( false )
1094
0
{
1095
    // redo doc doesn't contain imported data (but everything else)
1096
0
}
1097
1098
OUString ScUndoImportData::GetComment() const
1099
0
{
1100
0
    return ScResId( STR_UNDO_IMPORTDATA );
1101
0
}
1102
1103
void ScUndoImportData::Undo()
1104
0
{
1105
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1106
0
    if (!pViewShell)
1107
0
        return;
1108
1109
0
    BeginUndo();
1110
1111
0
    ScDocument& rDoc = rDocShell.GetDocument();
1112
1113
0
    ScUndoUtil::MarkSimpleBlock( rDocShell, aImportParam.nCol1,aImportParam.nRow1,nTab,
1114
0
                                                        nEndCol,nEndRow,nTab );
1115
1116
0
    SCTAB nTable;
1117
0
    SCCOL nCol1, nCol2;
1118
0
    SCROW nRow1, nRow2;
1119
0
    ScDBData* pCurrentData = nullptr;
1120
0
    if (xUndoDBData && xRedoDBData)
1121
0
    {
1122
0
        xRedoDBData->GetArea( nTable, nCol1, nRow1, nCol2, nRow2 );
1123
0
        pCurrentData = ScUndoUtil::GetOldDBData(xRedoDBData.get(), &rDoc, nTab,
1124
0
                                                nCol1, nRow1, nCol2, nRow2);
1125
1126
0
        if ( !bRedoFilled )
1127
0
        {
1128
            //  read redo data from document at first undo
1129
            //  imported data is deleted later anyway,
1130
            //  so now delete each column after copying to save memory (#41216#)
1131
1132
0
            bool bOldAutoCalc = rDoc.GetAutoCalc();
1133
0
            rDoc.SetAutoCalc( false );             // outside of the loop
1134
0
            for (SCCOL nCopyCol = nCol1; nCopyCol <= nCol2; nCopyCol++)
1135
0
            {
1136
0
                rDoc.CopyToDocument(nCopyCol,nRow1,nTab, nCopyCol,nRow2,nTab,
1137
0
                                    InsertDeleteFlags::CONTENTS & ~InsertDeleteFlags::NOTE, false, *xRedoDoc);
1138
0
                rDoc.DeleteAreaTab(nCopyCol, nRow1, nCopyCol, nRow2, nTab, InsertDeleteFlags::CONTENTS & ~InsertDeleteFlags::NOTE);
1139
0
            }
1140
0
            rDoc.SetAutoCalc( bOldAutoCalc );
1141
0
            bRedoFilled = true;
1142
0
        }
1143
0
    }
1144
0
    bool bMoveCells = xUndoDBData && xRedoDBData &&
1145
0
                        xRedoDBData->IsDoSize();        // the same in old and new
1146
0
    if (bMoveCells)
1147
0
    {
1148
        //  Undo: first delete the new data, then FitBlock backwards
1149
1150
0
        ScRange aOld, aNew;
1151
0
        xUndoDBData->GetArea(aOld);
1152
0
        xRedoDBData->GetArea(aNew);
1153
1154
0
        rDoc.DeleteAreaTab( aNew.aStart.Col(), aNew.aStart.Row(),
1155
0
                                aNew.aEnd.Col(), aNew.aEnd.Row(), nTab, InsertDeleteFlags::ALL & ~InsertDeleteFlags::NOTE );
1156
1157
0
        aOld.aEnd.SetCol( aOld.aEnd.Col() + nFormulaCols );     // FitBlock also for formulas
1158
0
        aNew.aEnd.SetCol( aNew.aEnd.Col() + nFormulaCols );
1159
0
        rDoc.FitBlock( aNew, aOld, false );                    // backwards
1160
0
    }
1161
0
    else
1162
0
        rDoc.DeleteAreaTab( aImportParam.nCol1,aImportParam.nRow1,
1163
0
                                nEndCol,nEndRow, nTab, InsertDeleteFlags::ALL & ~InsertDeleteFlags::NOTE );
1164
1165
0
    xUndoDoc->CopyToDocument(aImportParam.nCol1,aImportParam.nRow1,nTab,
1166
0
                             nEndCol+nFormulaCols,nEndRow,nTab,
1167
0
                             InsertDeleteFlags::ALL & ~InsertDeleteFlags::NOTE, false, rDoc);
1168
1169
0
    if (pCurrentData)
1170
0
    {
1171
0
        *pCurrentData = *xUndoDBData;
1172
1173
0
        xUndoDBData->GetArea(nTable, nCol1, nRow1, nCol2, nRow2);
1174
0
        ScUndoUtil::MarkSimpleBlock( rDocShell, nCol1, nRow1, nTable, nCol2, nRow2, nTable );
1175
0
    }
1176
1177
0
    SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
1178
0
    if ( nVisTab != nTab )
1179
0
        pViewShell->SetTabNo( nTab );
1180
1181
0
    if (bMoveCells)
1182
0
        rDocShell.PostPaint( 0,0,nTab, rDoc.MaxCol(),rDoc.MaxRow(),nTab, PaintPartFlags::Grid );
1183
0
    else
1184
0
        rDocShell.PostPaint( aImportParam.nCol1,aImportParam.nRow1,nTab,
1185
0
                                nEndCol,nEndRow,nTab, PaintPartFlags::Grid );
1186
0
    rDocShell.PostDataChanged();
1187
1188
0
    EndUndo();
1189
0
}
1190
1191
void ScUndoImportData::Redo()
1192
0
{
1193
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1194
0
    if (!pViewShell)
1195
0
        return;
1196
1197
0
    BeginRedo();
1198
1199
0
    ScDocument& rDoc = rDocShell.GetDocument();
1200
1201
0
    ScUndoUtil::MarkSimpleBlock( rDocShell, aImportParam.nCol1,aImportParam.nRow1,nTab,
1202
0
                                                        nEndCol,nEndRow,nTab );
1203
1204
0
    SCTAB nTable;
1205
0
    SCCOL nCol1, nCol2;
1206
0
    SCROW nRow1, nRow2;
1207
0
    ScDBData* pCurrentData = nullptr;
1208
0
    if (xUndoDBData && xRedoDBData)
1209
0
    {
1210
0
        xUndoDBData->GetArea( nTable, nCol1, nRow1, nCol2, nRow2 );
1211
0
        pCurrentData = ScUndoUtil::GetOldDBData(xUndoDBData.get(), &rDoc, nTab,
1212
0
                                                nCol1, nRow1, nCol2, nRow2);
1213
0
    }
1214
0
    bool bMoveCells = xUndoDBData && xRedoDBData &&
1215
0
                        xRedoDBData->IsDoSize();        // the same in old and new
1216
0
    if (bMoveCells)
1217
0
    {
1218
        //  Redo: FitBlock, then delete data (needed for CopyToDocument)
1219
1220
0
        ScRange aOld, aNew;
1221
0
        xUndoDBData->GetArea(aOld);
1222
0
        xRedoDBData->GetArea(aNew);
1223
1224
0
        aOld.aEnd.SetCol( aOld.aEnd.Col() + nFormulaCols );     // FitBlock also for formulas
1225
0
        aNew.aEnd.SetCol( aNew.aEnd.Col() + nFormulaCols );
1226
0
        rDoc.FitBlock( aOld, aNew );
1227
1228
0
        rDoc.DeleteAreaTab( aNew.aStart.Col(), aNew.aStart.Row(),
1229
0
                                aNew.aEnd.Col(), aNew.aEnd.Row(), nTab, InsertDeleteFlags::ALL & ~InsertDeleteFlags::NOTE );
1230
1231
0
        xRedoDoc->CopyToDocument(aNew, InsertDeleteFlags::ALL & ~InsertDeleteFlags::NOTE, false, rDoc);        // including formulas
1232
0
    }
1233
0
    else
1234
0
    {
1235
0
        rDoc.DeleteAreaTab( aImportParam.nCol1,aImportParam.nRow1,
1236
0
                                nEndCol,nEndRow, nTab, InsertDeleteFlags::ALL & ~InsertDeleteFlags::NOTE );
1237
0
        xRedoDoc->CopyToDocument(aImportParam.nCol1,aImportParam.nRow1,nTab,
1238
0
                                 nEndCol,nEndRow,nTab, InsertDeleteFlags::ALL & ~InsertDeleteFlags::NOTE, false, rDoc);
1239
0
    }
1240
1241
0
    if (pCurrentData)
1242
0
    {
1243
0
        *pCurrentData = *xRedoDBData;
1244
1245
0
        xRedoDBData->GetArea(nTable, nCol1, nRow1, nCol2, nRow2);
1246
0
        ScUndoUtil::MarkSimpleBlock( rDocShell, nCol1, nRow1, nTable, nCol2, nRow2, nTable );
1247
0
    }
1248
1249
0
    SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
1250
0
    if ( nVisTab != nTab )
1251
0
        pViewShell->SetTabNo( nTab );
1252
1253
0
    if (bMoveCells)
1254
0
        rDocShell.PostPaint( 0,0,nTab, rDoc.MaxCol(),rDoc.MaxRow(),nTab, PaintPartFlags::Grid );
1255
0
    else
1256
0
        rDocShell.PostPaint( aImportParam.nCol1,aImportParam.nRow1,nTab,
1257
0
                                nEndCol,nEndRow,nTab, PaintPartFlags::Grid );
1258
0
    rDocShell.PostDataChanged();
1259
1260
0
    EndRedo();
1261
0
}
1262
1263
void ScUndoImportData::Repeat(SfxRepeatTarget& rTarget)
1264
0
{
1265
0
    if (auto pViewTarget = dynamic_cast<ScTabViewTarget*>( &rTarget))
1266
0
    {
1267
0
        ScTabViewShell& rViewShell = pViewTarget->GetViewShell();
1268
1269
0
        ScImportParam aNewParam(aImportParam);
1270
0
        if (ScDBData* pDBData = rViewShell.GetDBData())
1271
0
        {
1272
0
            SCTAB nDummy;
1273
0
            pDBData->GetArea( nDummy, aNewParam.nCol1,aNewParam.nRow1, aNewParam.nCol2,aNewParam.nRow2 );
1274
0
        }
1275
1276
0
        rViewShell.ImportData( aNewParam );
1277
0
    }
1278
0
}
1279
1280
bool ScUndoImportData::CanRepeat(SfxRepeatTarget& rTarget) const
1281
0
{
1282
    //  Repeat only for import using a database range, then xUndoDBData is set
1283
1284
0
    if (xUndoDBData)
1285
0
        return dynamic_cast<const ScTabViewTarget*>( &rTarget) !=  nullptr;
1286
0
    else
1287
0
        return false;       // Address book
1288
0
}
1289
1290
ScUndoRepeatDB::ScUndoRepeatDB( ScDocShell& rNewDocShell, SCTAB nNewTab,
1291
                                SCCOL nStartX, SCROW nStartY, SCCOL nEndX, SCROW nEndY,
1292
                                SCROW nResultEndRow, SCCOL nCurX, SCROW nCurY,
1293
                                ScDocumentUniquePtr pNewUndoDoc, std::unique_ptr<ScOutlineTable> pNewUndoTab,
1294
                                std::unique_ptr<ScRangeName> pNewUndoRange, std::unique_ptr<ScDBCollection> pNewUndoDB,
1295
                                const ScRange* pOldQ, const ScRange* pNewQ ) :
1296
0
    ScSimpleUndo( rNewDocShell ),
1297
0
    aBlockStart( nStartX,nStartY,nNewTab ),
1298
0
    aBlockEnd( nEndX,nEndY,nNewTab ),
1299
0
    nNewEndRow( nResultEndRow ),
1300
0
    aCursorPos( nCurX,nCurY,nNewTab ),
1301
0
    xUndoDoc(std::move(pNewUndoDoc)),
1302
0
    xUndoTable(std::move(pNewUndoTab)),
1303
0
    xUndoRange(std::move(pNewUndoRange)),
1304
0
    xUndoDB(std::move(pNewUndoDB)),
1305
0
    bQuerySize( false )
1306
0
{
1307
0
    if ( pOldQ && pNewQ )
1308
0
    {
1309
0
        aOldQuery = *pOldQ;
1310
0
        aNewQuery = *pNewQ;
1311
0
        bQuerySize = true;
1312
0
    }
1313
0
}
1314
1315
OUString ScUndoRepeatDB::GetComment() const
1316
0
{
1317
0
    return ScResId( STR_UNDO_REPEATDB );
1318
0
}
1319
1320
void ScUndoRepeatDB::Undo()
1321
0
{
1322
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1323
0
    if (!pViewShell)
1324
0
        return;
1325
1326
0
    BeginUndo();
1327
1328
0
    ScDocument& rDoc = rDocShell.GetDocument();
1329
0
    SCTAB nTab = aBlockStart.Tab();
1330
1331
0
    if (bQuerySize)
1332
0
    {
1333
0
        rDoc.FitBlock( aNewQuery, aOldQuery, false );
1334
1335
0
        if ( aNewQuery.aEnd.Col() == aOldQuery.aEnd.Col() )
1336
0
        {
1337
0
            SCCOL nFormulaCols = 0;
1338
0
            SCCOL nCol = aOldQuery.aEnd.Col() + 1;
1339
0
            SCROW nRow = aOldQuery.aStart.Row() + 1;        // test the header
1340
0
            while ( nCol <= rDoc.MaxCol() &&
1341
0
                    rDoc.GetCellType(ScAddress( nCol, nRow, nTab )) == CELLTYPE_FORMULA )
1342
0
            {
1343
0
                ++nCol;
1344
0
                ++nFormulaCols;
1345
0
            }
1346
1347
0
            if ( nFormulaCols > 0 )
1348
0
            {
1349
0
                ScRange aOldForm = aOldQuery;
1350
0
                aOldForm.aStart.SetCol( aOldQuery.aEnd.Col() + 1 );
1351
0
                aOldForm.aEnd.SetCol( aOldQuery.aEnd.Col() + nFormulaCols );
1352
0
                ScRange aNewForm = aOldForm;
1353
0
                aNewForm.aEnd.SetRow( aNewQuery.aEnd.Row() );
1354
0
                rDoc.FitBlock( aNewForm, aOldForm, false );
1355
0
            }
1356
0
        }
1357
0
    }
1358
1359
    // TODO Data from Filter in other range are still missing!
1360
1361
0
    if (nNewEndRow > aBlockEnd.Row())
1362
0
    {
1363
0
        rDoc.DeleteRow( 0,nTab, rDoc.MaxCol(),nTab, aBlockEnd.Row()+1, static_cast<SCSIZE>(nNewEndRow-aBlockEnd.Row()) );
1364
0
    }
1365
0
    else if (nNewEndRow < aBlockEnd.Row())
1366
0
    {
1367
0
        rDoc.InsertRow( 0,nTab, rDoc.MaxCol(),nTab, nNewEndRow+1, static_cast<SCSIZE>(nNewEndRow-aBlockEnd.Row()) );
1368
0
    }
1369
1370
    // Original Outline table
1371
0
    rDoc.SetOutlineTable(nTab, xUndoTable.get());
1372
1373
    // Original column/row status
1374
0
    if (xUndoTable)
1375
0
    {
1376
0
        SCCOLROW nStartCol;
1377
0
        SCCOLROW nStartRow;
1378
0
        SCCOLROW nEndCol;
1379
0
        SCCOLROW nEndRow;
1380
0
        xUndoTable->GetColArray().GetRange(nStartCol, nEndCol);
1381
0
        xUndoTable->GetRowArray().GetRange(nStartRow, nEndRow);
1382
1383
0
        xUndoDoc->CopyToDocument(static_cast<SCCOL>(nStartCol), 0, nTab,
1384
0
                                 static_cast<SCCOL>(nEndCol), rDoc.MaxRow(), nTab, InsertDeleteFlags::NONE, false,
1385
0
                                 rDoc);
1386
0
        xUndoDoc->CopyToDocument(0, nStartRow, nTab, rDoc.MaxCol(), nEndRow, nTab, InsertDeleteFlags::NONE, false, rDoc);
1387
1388
0
        pViewShell->UpdateScrollBars();
1389
0
    }
1390
1391
    //  Original data and references
1392
0
    ScUndoUtil::MarkSimpleBlock( rDocShell, 0, aBlockStart.Row(), nTab,
1393
0
                                            rDoc.MaxCol(), aBlockEnd.Row(), nTab );
1394
0
    rDoc.DeleteAreaTab( 0, aBlockStart.Row(),
1395
0
                            rDoc.MaxCol(), aBlockEnd.Row(), nTab, InsertDeleteFlags::ALL );
1396
1397
0
    xUndoDoc->CopyToDocument(0, aBlockStart.Row(), nTab, rDoc.MaxCol(), aBlockEnd.Row(), nTab,
1398
0
                             InsertDeleteFlags::NONE, false, rDoc);            // Flags
1399
0
    xUndoDoc->UndoToDocument(0, aBlockStart.Row(), nTab, rDoc.MaxCol(), aBlockEnd.Row(), nTab,
1400
0
                             InsertDeleteFlags::ALL, false, rDoc);
1401
1402
0
    ScUndoUtil::MarkSimpleBlock( rDocShell, aBlockStart.Col(),aBlockStart.Row(),nTab,
1403
0
                                            aBlockEnd.Col(),aBlockEnd.Row(),nTab );
1404
1405
0
    if (xUndoRange)
1406
0
        rDoc.SetRangeName(std::unique_ptr<ScRangeName>(new ScRangeName(*xUndoRange)));
1407
0
    if (xUndoDB)
1408
0
        rDoc.SetDBCollection(std::unique_ptr<ScDBCollection>(new ScDBCollection(*xUndoDB)), true);
1409
1410
0
    ScTabViewShell::notifyAllViewsSheetGeomInvalidation(pViewShell, false /* bColumns */, true /* bRows */,
1411
0
            false /* bSizes*/, true /* bHidden */, true /* bFiltered */,
1412
0
            false /* bGroups */, nTab);
1413
1414
0
    SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
1415
0
    if ( nVisTab != nTab )
1416
0
        pViewShell->SetTabNo( nTab );
1417
1418
0
    rDocShell.PostPaint(0,0,nTab,rDoc.MaxCol(),rDoc.MaxRow(),nTab,PaintPartFlags::Grid|PaintPartFlags::Left|PaintPartFlags::Top|PaintPartFlags::Size);
1419
0
    rDocShell.PostDataChanged();
1420
1421
0
    EndUndo();
1422
0
}
1423
1424
void ScUndoRepeatDB::Redo()
1425
0
{
1426
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1427
0
    if (!pViewShell)
1428
0
        return;
1429
1430
0
    BeginRedo();
1431
1432
0
    SCTAB nTab = aBlockStart.Tab();
1433
1434
0
    SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
1435
0
    if ( nVisTab != nTab )
1436
0
        pViewShell->SetTabNo( nTab );
1437
1438
0
    ScUndoUtil::MarkSimpleBlock( rDocShell, aBlockStart.Col(),aBlockStart.Row(),nTab,
1439
0
                                            aBlockEnd.Col(),aBlockEnd.Row(),nTab );
1440
0
    pViewShell->SetCursor( aCursorPos.Col(), aCursorPos.Row() );
1441
1442
0
    pViewShell->RepeatDB( false );
1443
1444
0
    EndRedo();
1445
0
}
1446
1447
void ScUndoRepeatDB::Repeat(SfxRepeatTarget& rTarget)
1448
0
{
1449
0
    if (auto pViewTarget = dynamic_cast<ScTabViewTarget*>( &rTarget))
1450
0
        pViewTarget->GetViewShell().RepeatDB();
1451
0
}
1452
1453
bool ScUndoRepeatDB::CanRepeat(SfxRepeatTarget& rTarget) const
1454
0
{
1455
0
    return dynamic_cast<const ScTabViewTarget*>( &rTarget) !=  nullptr;
1456
0
}
1457
1458
ScUndoDataPilot::ScUndoDataPilot( ScDocShell& rNewDocShell,
1459
                            ScDocumentUniquePtr pOldDoc, ScDocumentUniquePtr pNewDoc,
1460
                            const ScDPObject* pOldObj, const ScDPObject* pNewObj, bool bMove )
1461
0
    : ScSimpleUndo(rNewDocShell)
1462
0
    , xOldUndoDoc(std::move(pOldDoc))
1463
0
    , xNewUndoDoc(std::move(pNewDoc))
1464
0
    , bAllowMove( bMove)
1465
0
{
1466
0
    if (pOldObj)
1467
0
        xOldDPObject.reset(new ScDPObject(*pOldObj));
1468
0
    if (pNewObj)
1469
0
        xNewDPObject.reset(new ScDPObject(*pNewObj));
1470
0
}
1471
1472
OUString ScUndoDataPilot::GetComment() const
1473
0
{
1474
0
    TranslateId pResId;
1475
0
    if (xOldUndoDoc && xNewUndoDoc)
1476
0
        pResId = STR_UNDO_PIVOT_MODIFY;
1477
0
    else if (xNewUndoDoc)
1478
0
        pResId = STR_UNDO_PIVOT_NEW;
1479
0
    else
1480
0
        pResId = STR_UNDO_PIVOT_DELETE;
1481
1482
0
    return ScResId(pResId);
1483
0
}
1484
1485
void ScUndoDataPilot::Undo()
1486
0
{
1487
0
    BeginUndo();
1488
1489
0
    ScDocument& rDoc = rDocShell.GetDocument();
1490
1491
0
    ScRange aOldRange;
1492
0
    ScRange aNewRange;
1493
1494
0
    if (xNewDPObject && xNewUndoDoc)
1495
0
    {
1496
0
        aNewRange = xNewDPObject->GetOutRange();
1497
0
        rDoc.DeleteAreaTab( aNewRange, InsertDeleteFlags::ALL );
1498
0
        xNewUndoDoc->CopyToDocument(aNewRange, InsertDeleteFlags::ALL, false, rDoc);
1499
0
    }
1500
0
    if (xOldDPObject && xOldUndoDoc)
1501
0
    {
1502
0
        aOldRange = xOldDPObject->GetOutRange();
1503
0
        rDoc.DeleteAreaTab(aOldRange, InsertDeleteFlags::ALL);
1504
0
        xOldUndoDoc->CopyToDocument(aOldRange, InsertDeleteFlags::ALL, false, rDoc);
1505
0
    }
1506
1507
    //  update objects in collection
1508
0
    if (xNewDPObject)
1509
0
    {
1510
        //  find updated object
1511
        //! find by name!
1512
1513
0
        ScDPObject* pDocObj = rDoc.GetDPAtCursor(
1514
0
                            aNewRange.aStart.Col(), aNewRange.aStart.Row(), aNewRange.aStart.Tab() );
1515
0
        OSL_ENSURE(pDocObj, "DPObject not found");
1516
0
        if (pDocObj)
1517
0
        {
1518
0
            if (xOldDPObject)
1519
0
            {
1520
                //  restore old settings
1521
0
                *pDocObj = *xOldDPObject;
1522
0
            }
1523
0
            else
1524
0
            {
1525
                //  delete inserted object
1526
0
                rDoc.GetDPCollection()->FreeTable(pDocObj);
1527
0
            }
1528
0
        }
1529
0
    }
1530
0
    else if (xOldDPObject)
1531
0
    {
1532
        //  re-insert deleted object
1533
0
        rDoc.GetDPCollection()->InsertNewTable(std::make_unique<ScDPObject>(*xOldDPObject));
1534
0
    }
1535
1536
0
    if (xNewUndoDoc)
1537
0
        rDocShell.PostPaint(aNewRange, PaintPartFlags::Grid, SC_PF_LINES);
1538
0
    if (xOldUndoDoc)
1539
0
        rDocShell.PostPaint(aOldRange, PaintPartFlags::Grid, SC_PF_LINES);
1540
0
    rDocShell.PostDataChanged();
1541
1542
0
    if (xNewDPObject)
1543
0
    {
1544
        // notify API objects
1545
0
        rDoc.BroadcastUno(ScDataPilotModifiedHint(xNewDPObject->GetName()));
1546
0
    }
1547
1548
0
    EndUndo();
1549
0
}
1550
1551
void ScUndoDataPilot::Redo()
1552
0
{
1553
0
    BeginRedo();
1554
1555
    //! copy output data instead of repeating the change,
1556
    //! in case external data have changed!
1557
1558
0
    ScDocument& rDoc = rDocShell.GetDocument();
1559
1560
0
    ScDPObject* pSourceObj = nullptr;
1561
0
    if (xOldDPObject)
1562
0
    {
1563
        //  find object to modify
1564
        //! find by name!
1565
1566
0
        ScRange aOldRange = xOldDPObject->GetOutRange();
1567
0
        pSourceObj = rDoc.GetDPAtCursor(
1568
0
                        aOldRange.aStart.Col(), aOldRange.aStart.Row(), aOldRange.aStart.Tab() );
1569
0
        OSL_ENSURE(pSourceObj, "DPObject not found");
1570
0
    }
1571
1572
0
    ScDBDocFunc aFunc( rDocShell );
1573
0
    aFunc.DataPilotUpdate(pSourceObj, xNewDPObject.get(), false, false, bAllowMove);    // no new undo action
1574
1575
0
    EndRedo();
1576
0
}
1577
1578
void ScUndoDataPilot::Repeat(SfxRepeatTarget& /* rTarget */)
1579
0
{
1580
    //! allow deletion
1581
0
}
1582
1583
bool ScUndoDataPilot::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1584
0
{
1585
    //! allow deletion
1586
0
    return false;
1587
0
}
1588
1589
ScUndoConsolidate::ScUndoConsolidate( ScDocShell& rNewDocShell, const ScArea& rArea,
1590
                    const ScConsolidateParam& rPar, ScDocumentUniquePtr pNewUndoDoc,
1591
                    bool bReference, SCROW nInsCount, std::unique_ptr<ScOutlineTable> pTab,
1592
                    std::unique_ptr<ScDBData> pData )
1593
0
    : ScSimpleUndo(rNewDocShell)
1594
0
    , aDestArea(rArea)
1595
0
    , xUndoDoc(std::move(pNewUndoDoc))
1596
0
    , aParam(rPar)
1597
0
    , bInsRef(bReference)
1598
0
    , nInsertCount(nInsCount)
1599
0
    , xUndoTab(std::move(pTab))
1600
0
    , xUndoData(std::move(pData))
1601
0
{
1602
0
}
1603
1604
OUString ScUndoConsolidate::GetComment() const
1605
0
{
1606
0
    return ScResId( STR_UNDO_CONSOLIDATE );
1607
0
}
1608
1609
void ScUndoConsolidate::Undo()
1610
0
{
1611
0
    BeginUndo();
1612
1613
0
    ScDocument& rDoc = rDocShell.GetDocument();
1614
0
    SCTAB nTab = aDestArea.nTab;
1615
1616
0
    ScRange aOldRange;
1617
0
    if (xUndoData)
1618
0
        xUndoData->GetArea(aOldRange);
1619
1620
0
    if (bInsRef)
1621
0
    {
1622
0
        rDoc.DeleteRow( 0,nTab, rDoc.MaxCol(),nTab, aDestArea.nRowStart, nInsertCount );
1623
0
        rDoc.SetOutlineTable(nTab, xUndoTab.get());
1624
1625
        // Row status
1626
0
        xUndoDoc->CopyToDocument(0, 0, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab, InsertDeleteFlags::NONE, false, rDoc);
1627
1628
        // Data and references
1629
0
        rDoc.DeleteAreaTab( 0,aDestArea.nRowStart, rDoc.MaxCol(),aDestArea.nRowEnd, nTab, InsertDeleteFlags::ALL );
1630
0
        xUndoDoc->UndoToDocument(0, aDestArea.nRowStart, nTab,
1631
0
                                 rDoc.MaxCol(), aDestArea.nRowEnd, nTab,
1632
0
                                 InsertDeleteFlags::ALL, false, rDoc);
1633
1634
        // Original range
1635
0
        if (xUndoData)
1636
0
        {
1637
0
            rDoc.DeleteAreaTab(aOldRange, InsertDeleteFlags::ALL);
1638
0
            xUndoDoc->CopyToDocument(aOldRange, InsertDeleteFlags::ALL, false, rDoc);
1639
0
        }
1640
1641
0
        rDocShell.PostPaint( 0,aDestArea.nRowStart,nTab, rDoc.MaxCol(),rDoc.MaxRow(),nTab,
1642
0
                                PaintPartFlags::Grid | PaintPartFlags::Left | PaintPartFlags::Size );
1643
0
    }
1644
0
    else
1645
0
    {
1646
0
        rDoc.DeleteAreaTab( aDestArea.nColStart,aDestArea.nRowStart,
1647
0
                                aDestArea.nColEnd,aDestArea.nRowEnd, nTab, InsertDeleteFlags::ALL );
1648
0
        xUndoDoc->CopyToDocument(aDestArea.nColStart, aDestArea.nRowStart, nTab,
1649
0
                                 aDestArea.nColEnd, aDestArea.nRowEnd, nTab,
1650
0
                                 InsertDeleteFlags::ALL, false, rDoc);
1651
1652
        //  Original range
1653
0
        if (xUndoData)
1654
0
        {
1655
0
            rDoc.DeleteAreaTab(aOldRange, InsertDeleteFlags::ALL);
1656
0
            xUndoDoc->CopyToDocument(aOldRange, InsertDeleteFlags::ALL, false, rDoc);
1657
0
        }
1658
1659
0
        SCCOL nEndX = aDestArea.nColEnd;
1660
0
        SCROW nEndY = aDestArea.nRowEnd;
1661
0
        if (xUndoData)
1662
0
        {
1663
0
            if ( aOldRange.aEnd.Col() > nEndX )
1664
0
                nEndX = aOldRange.aEnd.Col();
1665
0
            if ( aOldRange.aEnd.Row() > nEndY )
1666
0
                nEndY = aOldRange.aEnd.Row();
1667
0
        }
1668
0
        rDocShell.PostPaint( aDestArea.nColStart, aDestArea.nRowStart, nTab,
1669
0
                                    nEndX, nEndY, nTab, PaintPartFlags::Grid );
1670
0
    }
1671
1672
    // Adjust Database range again
1673
0
    if (xUndoData)
1674
0
    {
1675
0
        ScDBCollection* pColl = rDoc.GetDBCollection();
1676
0
        if (pColl)
1677
0
        {
1678
0
            ScDBData* pDocData = pColl->getNamedDBs().findByUpperName(xUndoData->GetUpperName());
1679
0
            if (pDocData)
1680
0
                *pDocData = *xUndoData;
1681
0
        }
1682
0
    }
1683
1684
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1685
0
    if (pViewShell)
1686
0
    {
1687
0
        SCTAB nViewTab = pViewShell->GetViewData().GetTabNumber();
1688
0
        if ( nViewTab != nTab )
1689
0
            pViewShell->SetTabNo( nTab );
1690
0
    }
1691
1692
0
    EndUndo();
1693
0
}
1694
1695
void ScUndoConsolidate::Redo()
1696
0
{
1697
0
    BeginRedo();
1698
1699
0
    rDocShell.DoConsolidate( aParam, false );
1700
1701
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1702
0
    if (pViewShell)
1703
0
    {
1704
0
        SCTAB nViewTab = pViewShell->GetViewData().GetTabNumber();
1705
0
        if ( nViewTab != aParam.nTab )
1706
0
            pViewShell->SetTabNo( aParam.nTab );
1707
0
    }
1708
1709
0
    EndRedo();
1710
0
}
1711
1712
void ScUndoConsolidate::Repeat(SfxRepeatTarget& /* rTarget */)
1713
0
{
1714
0
}
1715
1716
bool ScUndoConsolidate::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1717
0
{
1718
0
    return false;
1719
0
}
1720
1721
// Change source data of Chart
1722
void ScUndoChartData::Init()
1723
0
{
1724
0
    ScDocument& rDoc = rDocShell.GetDocument();
1725
0
    aOldRangeListRef = new ScRangeList;
1726
0
    rDoc.GetOldChartParameters( aChartName, *aOldRangeListRef, bOldColHeaders, bOldRowHeaders );
1727
0
}
1728
1729
ScUndoChartData::ScUndoChartData( ScDocShell& rNewDocShell, OUString aName,
1730
                                    const ScRange& rNew, bool bColHdr, bool bRowHdr,
1731
                                    bool bAdd ) :
1732
0
    ScSimpleUndo( rNewDocShell ),
1733
0
    aChartName(std::move( aName )),
1734
0
    bOldColHeaders(false),
1735
0
    bOldRowHeaders(false),
1736
0
    bNewColHeaders( bColHdr ),
1737
0
    bNewRowHeaders( bRowHdr ),
1738
0
    bAddRange( bAdd )
1739
0
{
1740
0
    aNewRangeListRef = new ScRangeList;
1741
0
    aNewRangeListRef->push_back( rNew );
1742
1743
0
    Init();
1744
0
}
1745
1746
ScUndoChartData::ScUndoChartData( ScDocShell& rNewDocShell, OUString aName,
1747
                                    ScRangeListRef xNew, bool bColHdr, bool bRowHdr,
1748
                                    bool bAdd ) :
1749
0
    ScSimpleUndo( rNewDocShell ),
1750
0
    aChartName(std::move( aName )),
1751
0
    bOldColHeaders(false),
1752
0
    bOldRowHeaders(false),
1753
0
    aNewRangeListRef(std::move( xNew )),
1754
0
    bNewColHeaders( bColHdr ),
1755
0
    bNewRowHeaders( bRowHdr ),
1756
0
    bAddRange( bAdd )
1757
0
{
1758
0
    Init();
1759
0
}
1760
1761
ScUndoChartData::~ScUndoChartData()
1762
0
{
1763
0
}
1764
1765
OUString ScUndoChartData::GetComment() const
1766
0
{
1767
0
    return ScResId( STR_UNDO_CHARTDATA );
1768
0
}
1769
1770
void ScUndoChartData::Undo()
1771
0
{
1772
0
    BeginUndo();
1773
1774
0
    rDocShell.GetDocument().UpdateChartArea( aChartName, aOldRangeListRef,
1775
0
                                bOldColHeaders, bOldRowHeaders, false );
1776
1777
0
    EndUndo();
1778
0
}
1779
1780
void ScUndoChartData::Redo()
1781
0
{
1782
0
    BeginRedo();
1783
1784
0
    rDocShell.GetDocument().UpdateChartArea( aChartName, aNewRangeListRef,
1785
0
                                bNewColHeaders, bNewRowHeaders, bAddRange );
1786
1787
0
    EndRedo();
1788
0
}
1789
1790
void ScUndoChartData::Repeat(SfxRepeatTarget& /* rTarget */)
1791
0
{
1792
0
}
1793
1794
bool ScUndoChartData::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1795
0
{
1796
0
    return false;
1797
0
}
1798
1799
ScUndoDataForm::ScUndoDataForm( ScDocShell& rNewDocShell,
1800
                                SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
1801
                                SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
1802
                                const ScMarkData& rMark,
1803
                                ScDocumentUniquePtr pNewUndoDoc, ScDocumentUniquePtr pNewRedoDoc,
1804
                                std::unique_ptr<ScRefUndoData> pRefData )
1805
0
    : ScBlockUndo(rNewDocShell, ScRange( nStartX, nStartY, nStartZ, nEndX, nEndY, nEndZ ), SC_UNDO_SIMPLE)
1806
0
    , mxMarkData(new ScMarkData(rMark))
1807
0
    , xUndoDoc(std::move(pNewUndoDoc))
1808
0
    , xRedoDoc(std::move(pNewRedoDoc))
1809
0
    , xRefUndoData(std::move(pRefData))
1810
0
    , bRedoFilled(false)
1811
0
{
1812
    //      pFill1,pFill2,pFill3 are there so the ctor calls for simple paste (without cutting)
1813
    //      don't have to be changed and branched for 641.
1814
    //      They can be removed later.
1815
1816
0
    if (!mxMarkData->IsMarked())                            // no cell marked:
1817
0
        mxMarkData->SetMarkArea(aBlockRange);   //  mark paste block
1818
1819
0
    if (xRefUndoData)
1820
0
        xRefUndoData->DeleteUnchanged(rDocShell.GetDocument());
1821
0
}
1822
1823
OUString ScUndoDataForm::GetComment() const
1824
0
{
1825
0
    return ScResId( STR_UNDO_PASTE );
1826
0
}
1827
1828
void ScUndoDataForm::Undo()
1829
0
{
1830
0
    BeginUndo();
1831
0
    DoChange( true );
1832
0
    ShowTable( aBlockRange );
1833
0
    EndUndo();
1834
0
    SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScAreaLinksChanged ) );
1835
0
}
1836
1837
void ScUndoDataForm::Redo()
1838
0
{
1839
0
    BeginRedo();
1840
0
    ScDocument& rDoc = rDocShell.GetDocument();
1841
0
    EnableDrawAdjust( &rDoc, false );                                //! include in ScBlockUndo?
1842
0
    DoChange( false );
1843
0
    EnableDrawAdjust( &rDoc, true );                                 //! include in ScBlockUndo?
1844
0
    EndRedo();
1845
0
    SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScAreaLinksChanged ) );
1846
0
}
1847
1848
void ScUndoDataForm::Repeat(SfxRepeatTarget& /*rTarget*/)
1849
0
{
1850
0
}
1851
1852
bool ScUndoDataForm::CanRepeat(SfxRepeatTarget& rTarget) const
1853
0
{
1854
0
    return (dynamic_cast<const ScTabViewTarget*>( &rTarget) !=  nullptr);
1855
0
}
1856
1857
void ScUndoDataForm::DoChange( const bool bUndo )
1858
0
{
1859
0
    ScDocument& rDoc = rDocShell.GetDocument();
1860
1861
    //      RefUndoData for redo is created before first undo
1862
    //      (with DeleteUnchanged after the DoUndo call)
1863
0
    bool bCreateRedoData = (bUndo && xRefUndoData && !xRefRedoData);
1864
0
    if (bCreateRedoData)
1865
0
        xRefRedoData.reset(new ScRefUndoData(rDoc));
1866
1867
0
    ScRefUndoData* pWorkRefData = bUndo ? xRefUndoData.get() : xRefRedoData.get();
1868
1869
0
    bool bPaintAll = false;
1870
1871
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1872
1873
0
    SCTAB nTabCount = rDoc.GetTableCount();
1874
0
    if ( bUndo && !bRedoFilled )
1875
0
    {
1876
0
        if (!xRedoDoc)
1877
0
        {
1878
0
            bool bColInfo = ( aBlockRange.aStart.Row()==0 && aBlockRange.aEnd.Row()==rDoc.MaxRow() );
1879
0
            bool bRowInfo = ( aBlockRange.aStart.Col()==0 && aBlockRange.aEnd.Col()==rDoc.MaxCol() );
1880
1881
0
            xRedoDoc.reset(new ScDocument(SCDOCMODE_UNDO));
1882
0
            xRedoDoc->InitUndoSelected(rDoc, *mxMarkData, bColInfo, bRowInfo);
1883
0
        }
1884
        //  read "redo" data from the document in the first undo
1885
            //  all sheets - CopyToDocument skips those that don't exist in pRedoDoc
1886
0
        ScRange aCopyRange = aBlockRange;
1887
0
        aCopyRange.aStart.SetTab(0);
1888
0
        aCopyRange.aEnd.SetTab(nTabCount-1);
1889
0
        rDoc.CopyToDocument(aCopyRange, InsertDeleteFlags::VALUE, false, *xRedoDoc);
1890
0
        bRedoFilled = true;
1891
0
    }
1892
1893
0
    sal_uInt16 nExtFlags = 0;
1894
0
    rDocShell.UpdatePaintExt( nExtFlags, aBlockRange );
1895
1896
0
    for ( sal_uInt16 i=0; i <= ( aBlockRange.aEnd.Col() - aBlockRange.aStart.Col() ); i++ )
1897
0
    {
1898
0
        OUString aOldString = xUndoDoc->GetString(
1899
0
            aBlockRange.aStart.Col()+i, aBlockRange.aStart.Row(), aBlockRange.aStart.Tab());
1900
0
        rDoc.SetString( aBlockRange.aStart.Col()+i , aBlockRange.aStart.Row() , aBlockRange.aStart.Tab() , aOldString );
1901
0
    }
1902
1903
0
    if (pWorkRefData)
1904
0
    {
1905
0
        pWorkRefData->DoUndo( rDoc, true );             // TRUE = bSetChartRangeLists for SetChartListenerCollection
1906
0
        if ( rDoc.RefreshAutoFilter( 0,0, rDoc.MaxCol(),rDoc.MaxRow(), aBlockRange.aStart.Tab() ) )
1907
0
            bPaintAll = true;
1908
0
    }
1909
1910
0
    if (bCreateRedoData && xRefRedoData)
1911
0
        xRefRedoData->DeleteUnchanged(rDoc);
1912
1913
0
    if ( bUndo )
1914
0
    {
1915
0
        ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
1916
0
        if ( pChangeTrack )
1917
0
            pChangeTrack->Undo( 0, 0 );
1918
0
    }
1919
1920
0
    ScRange aDrawRange( aBlockRange );
1921
0
    rDoc.ExtendMerge( aDrawRange, true );      // only needed for single sheet (text/rtf etc.)
1922
0
    PaintPartFlags nPaint = PaintPartFlags::Grid;
1923
0
    if (bPaintAll)
1924
0
    {
1925
0
        aDrawRange.aStart.SetCol(0);
1926
0
        aDrawRange.aStart.SetRow(0);
1927
0
        aDrawRange.aEnd.SetCol(rDoc.MaxCol());
1928
0
        aDrawRange.aEnd.SetRow(rDoc.MaxRow());
1929
0
        nPaint |= PaintPartFlags::Top | PaintPartFlags::Left;
1930
0
        if (pViewShell)
1931
0
            pViewShell->AdjustBlockHeight(false);
1932
0
    }
1933
0
    else
1934
0
    {
1935
0
        if ( aBlockRange.aStart.Row() == 0 && aBlockRange.aEnd.Row() == rDoc.MaxRow() )        // whole column
1936
0
        {
1937
0
            nPaint |= PaintPartFlags::Top;
1938
0
            aDrawRange.aEnd.SetCol(rDoc.MaxCol());
1939
0
        }
1940
0
        if ( aBlockRange.aStart.Col() == 0 && aBlockRange.aEnd.Col() == rDoc.MaxCol() )        // whole row
1941
0
        {
1942
0
            nPaint |= PaintPartFlags::Left;
1943
0
            aDrawRange.aEnd.SetRow(rDoc.MaxRow());
1944
0
        }
1945
0
        if (pViewShell && pViewShell->AdjustBlockHeight(false))
1946
0
        {
1947
0
            aDrawRange.aStart.SetCol(0);
1948
0
            aDrawRange.aStart.SetRow(0);
1949
0
            aDrawRange.aEnd.SetCol(rDoc.MaxCol());
1950
0
            aDrawRange.aEnd.SetRow(rDoc.MaxRow());
1951
0
            nPaint |= PaintPartFlags::Left;
1952
0
        }
1953
0
        rDocShell.UpdatePaintExt( nExtFlags, aDrawRange );
1954
0
    }
1955
1956
0
    if ( !bUndo )                               //      draw redo after updating row heights
1957
0
        RedoSdrUndoAction( pDrawUndo.get() );   //!     include in ScBlockUndo?
1958
1959
0
    rDocShell.PostPaint( aDrawRange, nPaint, nExtFlags );
1960
1961
0
    rDocShell.PostDataChanged();
1962
0
    if (pViewShell)
1963
0
        pViewShell->CellContentChanged();
1964
0
}
1965
1966
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */