Coverage Report

Created: 2026-02-14 09:37

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
ScUndoDBTable::ScUndoDBTable(ScDocShell& rNewDocShell, const OUString& rNewTable, bool bIns,
751
                             std::unique_ptr<ScDBCollection> pNewUndoColl,
752
                             std::unique_ptr<ScDBCollection> pNewRedoColl ) :
753
0
    ScSimpleUndo( rNewDocShell ),
754
0
    aTableName( rNewTable ),
755
0
    bInsert( bIns ),
756
0
    pUndoColl( std::move(pNewUndoColl) ),
757
0
    pRedoColl( std::move(pNewRedoColl) )
758
0
{
759
0
}
760
761
ScUndoDBTable::~ScUndoDBTable()
762
0
{
763
0
}
764
765
OUString ScUndoDBTable::GetComment() const
766
0
{   // "Insert/Delete tables";
767
0
    return bInsert ? ScResId(STR_UNDO_DBADDTABLE) : ScResId(STR_UNDO_DBREMTABLE);
768
0
}
769
770
void ScUndoDBTable::Undo()
771
0
{
772
0
    BeginUndo();
773
0
    DoChange(true);
774
0
    SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScDbAreasChanged ) );
775
0
    EndUndo();
776
0
}
777
778
void ScUndoDBTable::Redo()
779
0
{
780
0
    BeginRedo();
781
0
    DoChange(false);
782
0
    SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScDbAreasChanged ) );
783
0
    EndRedo();
784
0
}
785
786
void ScUndoDBTable::Repeat(SfxRepeatTarget& /* rTarget */)
787
0
{
788
0
}
789
790
bool ScUndoDBTable::CanRepeat(SfxRepeatTarget& /* rTarget */) const
791
0
{
792
0
    return false;    // is not possible
793
0
}
794
795
void ScUndoDBTable::DoChange(const bool bUndo)
796
0
{
797
0
    ScDBCollection* pWorkRefData = bUndo ? pUndoColl.get() : pRedoColl.get();
798
799
0
    ScDocument& rDoc = rDocShell.GetDocument();
800
0
    bool bOldAutoCalc = rDoc.GetAutoCalc();
801
0
    rDoc.SetAutoCalc(false); // Avoid unnecessary calculations
802
0
    rDoc.PreprocessDBDataUpdate();
803
0
    rDoc.SetDBCollection(std::unique_ptr<ScDBCollection>(new ScDBCollection(*pWorkRefData)), true);
804
0
    rDoc.CompileHybridFormula();
805
0
    rDoc.SetAutoCalc(bOldAutoCalc);
806
807
0
    pWorkRefData = !bInsert ? pUndoColl.get() : pRedoColl.get();
808
0
    if (const ScDBData* pDBData = pWorkRefData->getNamedDBs().findByUpperName(
809
0
            ScGlobal::getCharClass().uppercase(aTableName)))
810
0
    {
811
0
        ScRange aRange;
812
0
        pDBData->GetArea(aRange);
813
0
        if (!aRange.IsValid())
814
0
            return;
815
816
0
        if (pDBData->HasAutoFilter())
817
0
        {
818
0
            const bool bApply = (bInsert != bUndo);
819
0
            auto func = bApply ? &ScDocument::ApplyFlagsTab : &ScDocument::RemoveFlagsTab;
820
0
            (rDoc.*func)(aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(),
821
0
                         aRange.aStart.Row(), aRange.aStart.Tab(), ScMF::Auto);
822
0
        }
823
824
0
        if (ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell())
825
0
        {
826
0
            SCTAB nTab = aRange.aStart.Tab();
827
0
            SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
828
0
            if (nVisTab != nTab)
829
0
                pViewShell->SetTabNo(nTab);
830
831
0
            rDocShell.PostPaint(ScRange(0, 0, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab),
832
0
                                 PaintPartFlags::Grid | PaintPartFlags::Left | PaintPartFlags::Top
833
0
                                     | PaintPartFlags::Size);
834
0
        }
835
0
    }
836
0
}
837
838
ScUndoTableTotals::ScUndoTableTotals(ScDocShell& rNewDocShell, SCTAB nNewTab,
839
                                     const ScSubTotalParam& rNewParam, SCROW nNewEndY,
840
                                     ScDocumentUniquePtr pNewUndoDoc,
841
                                     std::unique_ptr<ScDBCollection> pNewUndoDB,
842
                                     std::unique_ptr<ScDBCollection> pNewRedoDB)
843
0
    : ScDBFuncUndo(rNewDocShell, ScRange(rNewParam.nCol1, rNewParam.nRow1, nNewTab,
844
0
                                         rNewParam.nCol2, rNewParam.nRow2, nNewTab))
845
0
    , nTab(nNewTab)
846
0
    , aParam(rNewParam)
847
0
    , nNewEndRow(nNewEndY)
848
0
    , xUndoDoc(std::move(pNewUndoDoc))
849
0
    , xUndoDB(std::move(pNewUndoDB))
850
0
    , xRedoDB(std::move(pNewRedoDB))
851
0
{
852
0
}
853
854
OUString ScUndoTableTotals::GetComment() const
855
0
{   // "Total Rows in Table Style"
856
0
    return ScResId( STR_UNDO_TABLETOTALS );
857
0
}
858
859
void ScUndoTableTotals::Undo()
860
0
{
861
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
862
0
    if (!pViewShell)
863
0
        return;
864
865
0
    BeginUndo();
866
867
0
    ScDocument& rDoc = rDocShell.GetDocument();
868
869
0
    if (nNewEndRow > aParam.nRow2)
870
0
    {
871
0
        rDoc.DeleteRow( aParam.nCol1, nTab, aParam.nCol2, nTab, nNewEndRow, static_cast<SCSIZE>(1) );
872
0
    }
873
874
0
    rDoc.DeleteAreaTab( aParam.nCol1, aParam.nRow1+1, aParam.nCol2, aParam.nRow2, nTab, InsertDeleteFlags::ALL );
875
876
0
    xUndoDoc->CopyToDocument(aParam.nCol1, aParam.nRow1 + 1, nTab, aParam.nCol2, aParam.nRow2, nTab,
877
0
                                                            InsertDeleteFlags::NONE, false, rDoc);
878
0
    xUndoDoc->UndoToDocument(aParam.nCol1, aParam.nRow1 + 1, nTab, aParam.nCol2, aParam.nRow2, nTab,
879
0
                                                            InsertDeleteFlags::ALL, false, rDoc);
880
881
0
    if (xUndoDB)
882
0
        rDoc.SetDBCollection(std::unique_ptr<ScDBCollection>(new ScDBCollection(*xUndoDB)), true);
883
884
0
    SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
885
0
    if ( nVisTab != nTab )
886
0
        pViewShell->SetTabNo( nTab );
887
888
0
    rDocShell.PostPaint(0,0,nTab,rDoc.MaxCol(),rDoc.MaxRow(),nTab,PaintPartFlags::Grid|PaintPartFlags::Left|PaintPartFlags::Top|PaintPartFlags::Size);
889
0
    rDocShell.PostDataChanged();
890
891
0
    EndUndo();
892
0
}
893
894
void ScUndoTableTotals::Redo()
895
0
{
896
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
897
0
    if (!pViewShell)
898
0
        return;
899
900
0
    BeginRedo();
901
902
0
    SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
903
0
    if ( nVisTab != nTab )
904
0
        pViewShell->SetTabNo( nTab );
905
906
0
    const ScDBData* pDBData = nullptr;
907
0
    if (xRedoDB)
908
0
    {
909
0
        if (aParam.bReplace && !aParam.bRemoveOnly)
910
0
            pDBData = xRedoDB->GetDBAtArea(nTab, aParam.nCol1, aParam.nRow1, aParam.nCol2, nNewEndRow);
911
0
        else
912
0
            pDBData = xRedoDB->GetDBAtArea(nTab, aParam.nCol1, aParam.nRow1, aParam.nCol2, aParam.nRow2);
913
0
    }
914
0
    if (pDBData)
915
0
        pViewShell->DoTableSubTotals(*pDBData, aParam, false);
916
917
0
    EndRedo();
918
0
}
919
920
0
void ScUndoTableTotals::Repeat(SfxRepeatTarget& /* rTarget */) {
921
0
}
922
923
bool ScUndoTableTotals::CanRepeat(SfxRepeatTarget& /* rTarget */) const
924
0
{
925
0
    return false;
926
0
}
927
928
ScUndoQuery::ScUndoQuery( ScDocShell& rNewDocShell, SCTAB nNewTab, const ScQueryParam& rParam,
929
                            ScDocumentUniquePtr pNewUndoDoc, std::unique_ptr<ScDBCollection> pNewUndoDB,
930
                            const ScRange* pOld, bool bSize, const ScRange* pAdvSrc ) :
931
0
    ScDBFuncUndo( rNewDocShell, ScRange( rParam.nCol1, rParam.nRow1, nNewTab,
932
0
                                         rParam.nCol2, rParam.nRow2, nNewTab ) ),
933
0
    nTab( nNewTab ),
934
0
    aQueryParam( rParam ),
935
0
    xUndoDoc( std::move(pNewUndoDoc) ),
936
0
    xUndoDB( std::move(pNewUndoDB) ),
937
0
    bIsAdvanced( false ),
938
0
    bDestArea( false ),
939
0
    bDoSize( bSize )
940
0
{
941
0
    if ( pOld )
942
0
    {
943
0
        bDestArea = true;
944
0
        aOldDest = *pOld;
945
0
    }
946
0
    if ( pAdvSrc )
947
0
    {
948
0
        bIsAdvanced = true;
949
0
        aAdvSource = *pAdvSrc;
950
0
    }
951
952
0
    pDrawUndo = GetSdrUndoAction( &rDocShell.GetDocument() );
953
0
}
954
955
ScUndoQuery::~ScUndoQuery()
956
0
{
957
0
    pDrawUndo.reset();
958
0
}
959
960
OUString ScUndoQuery::GetComment() const
961
0
{   // "Filter";
962
0
    return ScResId( STR_UNDO_QUERY );
963
0
}
964
965
void ScUndoQuery::Undo()
966
0
{
967
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
968
0
    if (!pViewShell)
969
0
        return;
970
971
0
    if (ScTabViewShell::isAnyEditViewInRange(pViewShell, /*bColumns*/ false, aQueryParam.nRow1, aQueryParam.nRow2))
972
0
        return;
973
974
0
    BeginUndo();
975
976
0
    ScDocument& rDoc = rDocShell.GetDocument();
977
978
0
    bool bCopy = !aQueryParam.bInplace;
979
0
    SCCOL nDestEndCol = 0;
980
0
    SCROW nDestEndRow = 0;
981
0
    if (bCopy)
982
0
    {
983
0
        nDestEndCol = aQueryParam.nDestCol + ( aQueryParam.nCol2-aQueryParam.nCol1 );
984
0
        nDestEndRow = aQueryParam.nDestRow + ( aQueryParam.nRow2-aQueryParam.nRow1 );
985
986
0
        ScDBData* pData = rDoc.GetDBAtCursor( aQueryParam.nDestCol, aQueryParam.nDestRow,
987
0
                                                aQueryParam.nDestTab, ScDBDataPortion::TOP_LEFT );
988
0
        if (pData)
989
0
        {
990
0
            ScRange aNewDest;
991
0
            pData->GetArea( aNewDest );
992
0
            nDestEndCol = aNewDest.aEnd.Col();
993
0
            nDestEndRow = aNewDest.aEnd.Row();
994
0
        }
995
996
0
        if ( bDoSize && bDestArea )
997
0
        {
998
            //  aDestRange is the old range
999
0
            rDoc.FitBlock( ScRange(
1000
0
                                aQueryParam.nDestCol, aQueryParam.nDestRow, aQueryParam.nDestTab,
1001
0
                                nDestEndCol, nDestEndRow, aQueryParam.nDestTab ),
1002
0
                            aOldDest );
1003
0
        }
1004
1005
0
        ScUndoUtil::MarkSimpleBlock( rDocShell,
1006
0
                                    aQueryParam.nDestCol, aQueryParam.nDestRow, aQueryParam.nDestTab,
1007
0
                                    nDestEndCol, nDestEndRow, aQueryParam.nDestTab );
1008
0
        rDoc.DeleteAreaTab( aQueryParam.nDestCol, aQueryParam.nDestRow,
1009
0
                            nDestEndCol, nDestEndRow, aQueryParam.nDestTab, InsertDeleteFlags::ALL );
1010
1011
0
        pViewShell->DoneBlockMode();
1012
1013
0
        xUndoDoc->CopyToDocument(aQueryParam.nDestCol, aQueryParam.nDestRow, aQueryParam.nDestTab,
1014
0
                                 nDestEndCol, nDestEndRow, aQueryParam.nDestTab,
1015
0
                                 InsertDeleteFlags::ALL, false, rDoc);
1016
        //  Attributes are always copied (#49287#)
1017
1018
        // rest of the old range
1019
0
        if ( bDestArea && !bDoSize )
1020
0
        {
1021
0
            rDoc.DeleteAreaTab( aOldDest, InsertDeleteFlags::ALL );
1022
0
            xUndoDoc->CopyToDocument(aOldDest, InsertDeleteFlags::ALL, false, rDoc);
1023
0
        }
1024
0
    }
1025
0
    else
1026
0
        xUndoDoc->CopyToDocument(0, aQueryParam.nRow1, nTab, rDoc.MaxCol(), aQueryParam.nRow2, nTab,
1027
0
                                 InsertDeleteFlags::NONE, false, rDoc);
1028
1029
0
    if (xUndoDB)
1030
0
        rDoc.SetDBCollection(std::unique_ptr<ScDBCollection>(new ScDBCollection(*xUndoDB )), true);
1031
1032
0
    if (!bCopy)
1033
0
    {
1034
0
        rDoc.InvalidatePageBreaks(nTab);
1035
0
        rDoc.UpdatePageBreaks( nTab );
1036
0
    }
1037
1038
0
    ScRange aDirtyRange( 0 , aQueryParam.nRow1, nTab,
1039
0
        rDoc.MaxCol(), aQueryParam.nRow2, nTab );
1040
0
    rDoc.SetDirty( aDirtyRange, true );
1041
1042
0
    DoSdrUndoAction( pDrawUndo.get(), &rDoc );
1043
1044
0
    SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
1045
0
    if ( nVisTab != nTab )
1046
0
        pViewShell->SetTabNo( nTab );
1047
1048
1049
    // invalidate cache positions and update cursor and selection
1050
0
    pViewShell->OnLOKShowHideColRow(/*bColumns*/ false, aQueryParam.nRow1 - 1);
1051
0
    ScTabViewShell::notifyAllViewsHeaderInvalidation(pViewShell, ROW_HEADER, nTab);
1052
0
    ScTabViewShell::notifyAllViewsSheetGeomInvalidation(
1053
0
            pViewShell,
1054
0
            false /* bColumns */, true /* bRows */,
1055
0
            false /* bSizes*/, true /* bHidden */, true /* bFiltered */,
1056
0
            false /* bGroups */, nTab);
1057
1058
    //  Paint
1059
1060
0
    if (bCopy)
1061
0
    {
1062
0
        SCCOL nEndX = nDestEndCol;
1063
0
        SCROW nEndY = nDestEndRow;
1064
0
        if (bDestArea)
1065
0
        {
1066
0
            if ( aOldDest.aEnd.Col() > nEndX )
1067
0
                nEndX = aOldDest.aEnd.Col();
1068
0
            if ( aOldDest.aEnd.Row() > nEndY )
1069
0
                nEndY = aOldDest.aEnd.Row();
1070
0
        }
1071
0
        if (bDoSize)
1072
0
            nEndY = rDoc.MaxRow();
1073
0
        rDocShell.PostPaint( aQueryParam.nDestCol, aQueryParam.nDestRow, aQueryParam.nDestTab,
1074
0
                                    nEndX, nEndY, aQueryParam.nDestTab, PaintPartFlags::Grid );
1075
0
    }
1076
0
    else
1077
0
        rDocShell.PostPaint( 0, aQueryParam.nRow1, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab,
1078
0
                                                    PaintPartFlags::Grid | PaintPartFlags::Left );
1079
0
    rDocShell.PostDataChanged();
1080
1081
0
    EndUndo();
1082
0
}
1083
1084
void ScUndoQuery::Redo()
1085
0
{
1086
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1087
0
    if (!pViewShell)
1088
0
        return;
1089
1090
0
    BeginRedo();
1091
1092
0
    SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
1093
0
    if ( nVisTab != nTab )
1094
0
        pViewShell->SetTabNo( nTab );
1095
1096
0
    if ( bIsAdvanced )
1097
0
        pViewShell->Query( aQueryParam, &aAdvSource, false );
1098
0
    else
1099
0
        pViewShell->Query( aQueryParam, nullptr, false );
1100
1101
0
    EndRedo();
1102
0
}
1103
1104
void ScUndoQuery::Repeat(SfxRepeatTarget& /* rTarget */)
1105
0
{
1106
0
}
1107
1108
bool ScUndoQuery::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1109
0
{
1110
0
    return false;    // does not work due to column numbers
1111
0
}
1112
1113
//      Show or hide AutoFilter buttons (doesn't include filter settings)
1114
1115
ScUndoAutoFilter::ScUndoAutoFilter( ScDocShell& rNewDocShell, const ScRange& rRange,
1116
                                    OUString aName, bool bSet ) :
1117
0
    ScDBFuncUndo( rNewDocShell, rRange ),
1118
0
    aDBName(std::move( aName )),
1119
0
    bFilterSet( bSet )
1120
0
{
1121
0
}
1122
1123
ScUndoAutoFilter::~ScUndoAutoFilter()
1124
0
{
1125
0
}
1126
1127
OUString ScUndoAutoFilter::GetComment() const
1128
0
{
1129
0
    return ScResId( STR_UNDO_QUERY );    // same as ScUndoQuery
1130
0
}
1131
1132
void ScUndoAutoFilter::DoChange( bool bUndo )
1133
0
{
1134
0
    bool bNewFilter = bUndo ? !bFilterSet : bFilterSet;
1135
1136
0
    ScDocument& rDoc = rDocShell.GetDocument();
1137
0
    ScDBData* pDBData=nullptr;
1138
0
    if (aDBName == STR_DB_LOCAL_NONAME)
1139
0
    {
1140
0
        SCTAB nTab = aOriginalRange.aStart.Tab();
1141
0
        pDBData = rDoc.GetAnonymousDBData(nTab);
1142
0
    }
1143
0
    else
1144
0
    {
1145
0
        ScDBCollection* pColl = rDoc.GetDBCollection();
1146
0
        pDBData = pColl->getNamedDBs().findByUpperName(ScGlobal::getCharClass().uppercase(aDBName));
1147
0
    }
1148
1149
0
    if ( !pDBData )
1150
0
        return;
1151
1152
0
    pDBData->SetAutoFilter( bNewFilter );
1153
1154
0
    SCCOL nRangeX1;
1155
0
    SCROW nRangeY1;
1156
0
    SCCOL nRangeX2;
1157
0
    SCROW nRangeY2;
1158
0
    SCTAB nRangeTab;
1159
0
    pDBData->GetArea( nRangeTab, nRangeX1, nRangeY1, nRangeX2, nRangeY2 );
1160
1161
0
    if ( bNewFilter )
1162
0
        rDoc.ApplyFlagsTab( nRangeX1, nRangeY1, nRangeX2, nRangeY1, nRangeTab, ScMF::Auto );
1163
0
    else
1164
0
        rDoc.RemoveFlagsTab( nRangeX1, nRangeY1, nRangeX2, nRangeY1, nRangeTab, ScMF::Auto );
1165
1166
0
    rDocShell.PostPaint( nRangeX1, nRangeY1, nRangeTab, nRangeX2, nRangeY1, nRangeTab, PaintPartFlags::Grid );
1167
0
}
1168
1169
void ScUndoAutoFilter::Undo()
1170
0
{
1171
0
    BeginUndo();
1172
0
    DoChange( true );
1173
0
    EndUndo();
1174
0
}
1175
1176
void ScUndoAutoFilter::Redo()
1177
0
{
1178
0
    BeginRedo();
1179
0
    DoChange( false );
1180
0
    EndRedo();
1181
0
}
1182
1183
void ScUndoAutoFilter::Repeat(SfxRepeatTarget& /* rTarget */)
1184
0
{
1185
0
}
1186
1187
bool ScUndoAutoFilter::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1188
0
{
1189
0
    return false;
1190
0
}
1191
1192
// change database sections (dialog)
1193
ScUndoDBData::ScUndoDBData( ScDocShell& rNewDocShell, const OUString& rNewUndoName,
1194
                            std::unique_ptr<ScDBCollection> pNewUndoColl, const OUString& rNewRedoName,
1195
                            std::unique_ptr<ScDBCollection> pNewRedoColl ) :
1196
0
    ScSimpleUndo( rNewDocShell ),
1197
0
    aUndoName( rNewUndoName ),
1198
0
    pUndoColl( std::move(pNewUndoColl) ),
1199
0
    aRedoName( rNewRedoName ),
1200
0
    pRedoColl( std::move(pNewRedoColl) )
1201
0
{
1202
0
}
1203
1204
ScUndoDBData::~ScUndoDBData()
1205
0
{
1206
0
}
1207
1208
OUString ScUndoDBData::GetComment() const
1209
0
{   // "Change database range";
1210
0
    return ScResId( STR_UNDO_DBDATA );
1211
0
}
1212
1213
void ScUndoDBData::Undo()
1214
0
{
1215
0
    BeginUndo();
1216
0
    DoChange(true);
1217
0
    SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScDbAreasChanged ) );
1218
0
    EndUndo();
1219
0
}
1220
1221
void ScUndoDBData::Redo()
1222
0
{
1223
0
    BeginRedo();
1224
0
    DoChange(false);
1225
0
    SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScDbAreasChanged ) );
1226
0
    EndRedo();
1227
0
}
1228
1229
void ScUndoDBData::Repeat(SfxRepeatTarget& /* rTarget */)
1230
0
{
1231
0
}
1232
1233
bool ScUndoDBData::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1234
0
{
1235
0
    return false;    // is not possible
1236
0
}
1237
1238
void ScUndoDBData::DoChange( const bool bUndo )
1239
0
{
1240
0
    ScDBCollection* pWorkRefData = bUndo ? pUndoColl.get() : pRedoColl.get();
1241
0
    ScDBCollection* pOldRefData = bUndo ? pRedoColl.get() : pUndoColl.get();
1242
1243
0
    ScDocument& rDoc = rDocShell.GetDocument();
1244
0
    bool bOldAutoCalc = rDoc.GetAutoCalc();
1245
0
    rDoc.SetAutoCalc(false); // Avoid unnecessary calculations
1246
0
    rDoc.PreprocessDBDataUpdate();
1247
0
    rDoc.SetDBCollection(std::unique_ptr<ScDBCollection>(new ScDBCollection(*pWorkRefData)), true);
1248
0
    rDoc.CompileHybridFormula();
1249
0
    rDoc.SetAutoCalc(bOldAutoCalc);
1250
1251
0
    const OUString& rWorkName = bUndo ? aUndoName : aRedoName;
1252
0
    const OUString& rOldName = bUndo ? aRedoName : aUndoName;
1253
1254
0
    if (const ScDBData* pDBData = pWorkRefData->getNamedDBs().findByUpperName(
1255
0
            ScGlobal::getCharClass().uppercase(rWorkName)))
1256
0
    {
1257
0
        ScRange aOldRange;
1258
0
        if (const ScDBData* pOldDBData = pOldRefData->getNamedDBs().findByUpperName(
1259
0
                ScGlobal::getCharClass().uppercase(rOldName)))
1260
0
        {
1261
0
            ScRange aNewRange;
1262
0
            pOldDBData->GetArea(aOldRange);
1263
0
            pDBData->GetArea(aNewRange);
1264
0
            bool bAreaChanged = (aOldRange != aNewRange);
1265
0
            bool bOldAutoFilter = pOldDBData->HasAutoFilter();
1266
0
            bool bNewAutoFilter = pDBData->HasAutoFilter();
1267
1268
0
            if (bAreaChanged || bOldAutoFilter != bNewAutoFilter)
1269
0
            {
1270
0
                if (bAreaChanged)
1271
0
                    rDoc.CompileDBFormula();
1272
0
                if (bOldAutoFilter && !bNewAutoFilter)
1273
0
                {
1274
0
                    rDoc.RemoveFlagsTab(aOldRange.aStart.Col(), aOldRange.aStart.Row(),
1275
0
                                        aOldRange.aEnd.Col(), aOldRange.aEnd.Row(),
1276
0
                                        aOldRange.aStart.Tab(), ScMF::Auto);
1277
0
                }
1278
0
                else if (bOldAutoFilter && bNewAutoFilter)
1279
0
                {
1280
0
                    rDoc.RemoveFlagsTab(aOldRange.aStart.Col(), aOldRange.aStart.Row(),
1281
0
                                        aOldRange.aEnd.Col(), aOldRange.aEnd.Row(),
1282
0
                                        aOldRange.aStart.Tab(), ScMF::Auto);
1283
0
                    rDoc.ApplyFlagsTab(aNewRange.aStart.Col(), aNewRange.aStart.Row(),
1284
0
                                       aNewRange.aEnd.Col(), aNewRange.aStart.Row(),
1285
0
                                       aNewRange.aStart.Tab(), ScMF::Auto);
1286
0
                }
1287
0
                else if (!bOldAutoFilter && bNewAutoFilter)
1288
0
                {
1289
0
                    rDoc.ApplyFlagsTab(aNewRange.aStart.Col(), aNewRange.aStart.Row(),
1290
0
                                       aNewRange.aEnd.Col(), aNewRange.aStart.Row(),
1291
0
                                       aNewRange.aStart.Tab(), ScMF::Auto);
1292
0
                }
1293
0
            }
1294
0
        }
1295
1296
0
        if (pDBData->GetTableStyleInfo())
1297
0
        {
1298
0
            ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1299
0
            if (pViewShell && aOldRange.IsValid())
1300
0
            {
1301
0
                SCTAB nTab = aOldRange.aStart.Tab();
1302
0
                SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
1303
0
                if (nVisTab != nTab)
1304
0
                    pViewShell->SetTabNo(nTab);
1305
1306
0
                rDocShell.PostPaint(ScRange(0, 0, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab),
1307
0
                                     PaintPartFlags::Grid | PaintPartFlags::Left | PaintPartFlags::Top | PaintPartFlags::Size);
1308
0
            }
1309
0
        }
1310
0
    }
1311
0
}
1312
1313
ScUndoImportData::ScUndoImportData( ScDocShell& rNewDocShell, SCTAB nNewTab,
1314
                                const ScImportParam& rParam, SCCOL nNewEndX, SCROW nNewEndY,
1315
                                SCCOL nNewFormula,
1316
                                ScDocumentUniquePtr pNewUndoDoc, ScDocumentUniquePtr pNewRedoDoc,
1317
                                std::unique_ptr<ScDBData> pNewUndoData, std::unique_ptr<ScDBData> pNewRedoData ) :
1318
0
    ScSimpleUndo( rNewDocShell ),
1319
0
    nTab( nNewTab ),
1320
0
    aImportParam( rParam ),
1321
0
    nEndCol( nNewEndX ),
1322
0
    nEndRow( nNewEndY ),
1323
0
    xUndoDoc(std::move(pNewUndoDoc)),
1324
0
    xRedoDoc(std::move(pNewRedoDoc)),
1325
0
    xUndoDBData(std::move(pNewUndoData)),
1326
0
    xRedoDBData(std::move(pNewRedoData)),
1327
0
    nFormulaCols( nNewFormula ),
1328
0
    bRedoFilled( false )
1329
0
{
1330
    // redo doc doesn't contain imported data (but everything else)
1331
0
}
1332
1333
OUString ScUndoImportData::GetComment() const
1334
0
{
1335
0
    return ScResId( STR_UNDO_IMPORTDATA );
1336
0
}
1337
1338
void ScUndoImportData::Undo()
1339
0
{
1340
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1341
0
    if (!pViewShell)
1342
0
        return;
1343
1344
0
    BeginUndo();
1345
1346
0
    ScDocument& rDoc = rDocShell.GetDocument();
1347
1348
0
    ScUndoUtil::MarkSimpleBlock( rDocShell, aImportParam.nCol1,aImportParam.nRow1,nTab,
1349
0
                                                        nEndCol,nEndRow,nTab );
1350
1351
0
    SCTAB nTable;
1352
0
    SCCOL nCol1, nCol2;
1353
0
    SCROW nRow1, nRow2;
1354
0
    ScDBData* pCurrentData = nullptr;
1355
0
    if (xUndoDBData && xRedoDBData)
1356
0
    {
1357
0
        xRedoDBData->GetArea( nTable, nCol1, nRow1, nCol2, nRow2 );
1358
0
        pCurrentData = ScUndoUtil::GetOldDBData(xRedoDBData.get(), &rDoc, nTab,
1359
0
                                                nCol1, nRow1, nCol2, nRow2);
1360
1361
0
        if ( !bRedoFilled )
1362
0
        {
1363
            //  read redo data from document at first undo
1364
            //  imported data is deleted later anyway,
1365
            //  so now delete each column after copying to save memory (#41216#)
1366
1367
0
            bool bOldAutoCalc = rDoc.GetAutoCalc();
1368
0
            rDoc.SetAutoCalc( false );             // outside of the loop
1369
0
            for (SCCOL nCopyCol = nCol1; nCopyCol <= nCol2; nCopyCol++)
1370
0
            {
1371
0
                rDoc.CopyToDocument(nCopyCol,nRow1,nTab, nCopyCol,nRow2,nTab,
1372
0
                                    InsertDeleteFlags::CONTENTS & ~InsertDeleteFlags::NOTE, false, *xRedoDoc);
1373
0
                rDoc.DeleteAreaTab(nCopyCol, nRow1, nCopyCol, nRow2, nTab, InsertDeleteFlags::CONTENTS & ~InsertDeleteFlags::NOTE);
1374
0
            }
1375
0
            rDoc.SetAutoCalc( bOldAutoCalc );
1376
0
            bRedoFilled = true;
1377
0
        }
1378
0
    }
1379
0
    bool bMoveCells = xUndoDBData && xRedoDBData &&
1380
0
                        xRedoDBData->IsDoSize();        // the same in old and new
1381
0
    if (bMoveCells)
1382
0
    {
1383
        //  Undo: first delete the new data, then FitBlock backwards
1384
1385
0
        ScRange aOld, aNew;
1386
0
        xUndoDBData->GetArea(aOld);
1387
0
        xRedoDBData->GetArea(aNew);
1388
1389
0
        rDoc.DeleteAreaTab( aNew.aStart.Col(), aNew.aStart.Row(),
1390
0
                                aNew.aEnd.Col(), aNew.aEnd.Row(), nTab, InsertDeleteFlags::ALL & ~InsertDeleteFlags::NOTE );
1391
1392
0
        aOld.aEnd.SetCol( aOld.aEnd.Col() + nFormulaCols );     // FitBlock also for formulas
1393
0
        aNew.aEnd.SetCol( aNew.aEnd.Col() + nFormulaCols );
1394
0
        rDoc.FitBlock( aNew, aOld, false );                    // backwards
1395
0
    }
1396
0
    else
1397
0
        rDoc.DeleteAreaTab( aImportParam.nCol1,aImportParam.nRow1,
1398
0
                                nEndCol,nEndRow, nTab, InsertDeleteFlags::ALL & ~InsertDeleteFlags::NOTE );
1399
1400
0
    xUndoDoc->CopyToDocument(aImportParam.nCol1,aImportParam.nRow1,nTab,
1401
0
                             nEndCol+nFormulaCols,nEndRow,nTab,
1402
0
                             InsertDeleteFlags::ALL & ~InsertDeleteFlags::NOTE, false, rDoc);
1403
1404
0
    if (pCurrentData)
1405
0
    {
1406
0
        *pCurrentData = *xUndoDBData;
1407
1408
0
        xUndoDBData->GetArea(nTable, nCol1, nRow1, nCol2, nRow2);
1409
0
        ScUndoUtil::MarkSimpleBlock( rDocShell, nCol1, nRow1, nTable, nCol2, nRow2, nTable );
1410
0
    }
1411
1412
0
    SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
1413
0
    if ( nVisTab != nTab )
1414
0
        pViewShell->SetTabNo( nTab );
1415
1416
0
    if (bMoveCells)
1417
0
        rDocShell.PostPaint( 0,0,nTab, rDoc.MaxCol(),rDoc.MaxRow(),nTab, PaintPartFlags::Grid );
1418
0
    else
1419
0
        rDocShell.PostPaint( aImportParam.nCol1,aImportParam.nRow1,nTab,
1420
0
                                nEndCol,nEndRow,nTab, PaintPartFlags::Grid );
1421
0
    rDocShell.PostDataChanged();
1422
1423
0
    EndUndo();
1424
0
}
1425
1426
void ScUndoImportData::Redo()
1427
0
{
1428
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1429
0
    if (!pViewShell)
1430
0
        return;
1431
1432
0
    BeginRedo();
1433
1434
0
    ScDocument& rDoc = rDocShell.GetDocument();
1435
1436
0
    ScUndoUtil::MarkSimpleBlock( rDocShell, aImportParam.nCol1,aImportParam.nRow1,nTab,
1437
0
                                                        nEndCol,nEndRow,nTab );
1438
1439
0
    SCTAB nTable;
1440
0
    SCCOL nCol1, nCol2;
1441
0
    SCROW nRow1, nRow2;
1442
0
    ScDBData* pCurrentData = nullptr;
1443
0
    if (xUndoDBData && xRedoDBData)
1444
0
    {
1445
0
        xUndoDBData->GetArea( nTable, nCol1, nRow1, nCol2, nRow2 );
1446
0
        pCurrentData = ScUndoUtil::GetOldDBData(xUndoDBData.get(), &rDoc, nTab,
1447
0
                                                nCol1, nRow1, nCol2, nRow2);
1448
0
    }
1449
0
    bool bMoveCells = xUndoDBData && xRedoDBData &&
1450
0
                        xRedoDBData->IsDoSize();        // the same in old and new
1451
0
    if (bMoveCells)
1452
0
    {
1453
        //  Redo: FitBlock, then delete data (needed for CopyToDocument)
1454
1455
0
        ScRange aOld, aNew;
1456
0
        xUndoDBData->GetArea(aOld);
1457
0
        xRedoDBData->GetArea(aNew);
1458
1459
0
        aOld.aEnd.SetCol( aOld.aEnd.Col() + nFormulaCols );     // FitBlock also for formulas
1460
0
        aNew.aEnd.SetCol( aNew.aEnd.Col() + nFormulaCols );
1461
0
        rDoc.FitBlock( aOld, aNew );
1462
1463
0
        rDoc.DeleteAreaTab( aNew.aStart.Col(), aNew.aStart.Row(),
1464
0
                                aNew.aEnd.Col(), aNew.aEnd.Row(), nTab, InsertDeleteFlags::ALL & ~InsertDeleteFlags::NOTE );
1465
1466
0
        xRedoDoc->CopyToDocument(aNew, InsertDeleteFlags::ALL & ~InsertDeleteFlags::NOTE, false, rDoc);        // including formulas
1467
0
    }
1468
0
    else
1469
0
    {
1470
0
        rDoc.DeleteAreaTab( aImportParam.nCol1,aImportParam.nRow1,
1471
0
                                nEndCol,nEndRow, nTab, InsertDeleteFlags::ALL & ~InsertDeleteFlags::NOTE );
1472
0
        xRedoDoc->CopyToDocument(aImportParam.nCol1,aImportParam.nRow1,nTab,
1473
0
                                 nEndCol,nEndRow,nTab, InsertDeleteFlags::ALL & ~InsertDeleteFlags::NOTE, false, rDoc);
1474
0
    }
1475
1476
0
    if (pCurrentData)
1477
0
    {
1478
0
        *pCurrentData = *xRedoDBData;
1479
1480
0
        xRedoDBData->GetArea(nTable, nCol1, nRow1, nCol2, nRow2);
1481
0
        ScUndoUtil::MarkSimpleBlock( rDocShell, nCol1, nRow1, nTable, nCol2, nRow2, nTable );
1482
0
    }
1483
1484
0
    SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
1485
0
    if ( nVisTab != nTab )
1486
0
        pViewShell->SetTabNo( nTab );
1487
1488
0
    if (bMoveCells)
1489
0
        rDocShell.PostPaint( 0,0,nTab, rDoc.MaxCol(),rDoc.MaxRow(),nTab, PaintPartFlags::Grid );
1490
0
    else
1491
0
        rDocShell.PostPaint( aImportParam.nCol1,aImportParam.nRow1,nTab,
1492
0
                                nEndCol,nEndRow,nTab, PaintPartFlags::Grid );
1493
0
    rDocShell.PostDataChanged();
1494
1495
0
    EndRedo();
1496
0
}
1497
1498
void ScUndoImportData::Repeat(SfxRepeatTarget& rTarget)
1499
0
{
1500
0
    if (auto pViewTarget = dynamic_cast<ScTabViewTarget*>( &rTarget))
1501
0
    {
1502
0
        ScTabViewShell& rViewShell = pViewTarget->GetViewShell();
1503
1504
0
        ScImportParam aNewParam(aImportParam);
1505
0
        if (ScDBData* pDBData = rViewShell.GetDBData())
1506
0
        {
1507
0
            SCTAB nDummy;
1508
0
            pDBData->GetArea( nDummy, aNewParam.nCol1,aNewParam.nRow1, aNewParam.nCol2,aNewParam.nRow2 );
1509
0
        }
1510
1511
0
        rViewShell.ImportData( aNewParam );
1512
0
    }
1513
0
}
1514
1515
bool ScUndoImportData::CanRepeat(SfxRepeatTarget& rTarget) const
1516
0
{
1517
    //  Repeat only for import using a database range, then xUndoDBData is set
1518
1519
0
    if (xUndoDBData)
1520
0
        return dynamic_cast<const ScTabViewTarget*>( &rTarget) !=  nullptr;
1521
0
    else
1522
0
        return false;       // Address book
1523
0
}
1524
1525
ScUndoRepeatDB::ScUndoRepeatDB( ScDocShell& rNewDocShell, SCTAB nNewTab,
1526
                                SCCOL nStartX, SCROW nStartY, SCCOL nEndX, SCROW nEndY,
1527
                                SCROW nResultEndRow, SCCOL nCurX, SCROW nCurY,
1528
                                ScDocumentUniquePtr pNewUndoDoc, std::unique_ptr<ScOutlineTable> pNewUndoTab,
1529
                                std::unique_ptr<ScRangeName> pNewUndoRange, std::unique_ptr<ScDBCollection> pNewUndoDB,
1530
                                const ScRange* pOldQ, const ScRange* pNewQ ) :
1531
0
    ScSimpleUndo( rNewDocShell ),
1532
0
    aBlockStart( nStartX,nStartY,nNewTab ),
1533
0
    aBlockEnd( nEndX,nEndY,nNewTab ),
1534
0
    nNewEndRow( nResultEndRow ),
1535
0
    aCursorPos( nCurX,nCurY,nNewTab ),
1536
0
    xUndoDoc(std::move(pNewUndoDoc)),
1537
0
    xUndoTable(std::move(pNewUndoTab)),
1538
0
    xUndoRange(std::move(pNewUndoRange)),
1539
0
    xUndoDB(std::move(pNewUndoDB)),
1540
0
    bQuerySize( false )
1541
0
{
1542
0
    if ( pOldQ && pNewQ )
1543
0
    {
1544
0
        aOldQuery = *pOldQ;
1545
0
        aNewQuery = *pNewQ;
1546
0
        bQuerySize = true;
1547
0
    }
1548
0
}
1549
1550
OUString ScUndoRepeatDB::GetComment() const
1551
0
{
1552
0
    return ScResId( STR_UNDO_REPEATDB );
1553
0
}
1554
1555
void ScUndoRepeatDB::Undo()
1556
0
{
1557
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1558
0
    if (!pViewShell)
1559
0
        return;
1560
1561
0
    BeginUndo();
1562
1563
0
    ScDocument& rDoc = rDocShell.GetDocument();
1564
0
    SCTAB nTab = aBlockStart.Tab();
1565
1566
0
    if (bQuerySize)
1567
0
    {
1568
0
        rDoc.FitBlock( aNewQuery, aOldQuery, false );
1569
1570
0
        if ( aNewQuery.aEnd.Col() == aOldQuery.aEnd.Col() )
1571
0
        {
1572
0
            SCCOL nFormulaCols = 0;
1573
0
            SCCOL nCol = aOldQuery.aEnd.Col() + 1;
1574
0
            SCROW nRow = aOldQuery.aStart.Row() + 1;        // test the header
1575
0
            while ( nCol <= rDoc.MaxCol() &&
1576
0
                    rDoc.GetCellType(ScAddress( nCol, nRow, nTab )) == CELLTYPE_FORMULA )
1577
0
            {
1578
0
                ++nCol;
1579
0
                ++nFormulaCols;
1580
0
            }
1581
1582
0
            if ( nFormulaCols > 0 )
1583
0
            {
1584
0
                ScRange aOldForm = aOldQuery;
1585
0
                aOldForm.aStart.SetCol( aOldQuery.aEnd.Col() + 1 );
1586
0
                aOldForm.aEnd.SetCol( aOldQuery.aEnd.Col() + nFormulaCols );
1587
0
                ScRange aNewForm = aOldForm;
1588
0
                aNewForm.aEnd.SetRow( aNewQuery.aEnd.Row() );
1589
0
                rDoc.FitBlock( aNewForm, aOldForm, false );
1590
0
            }
1591
0
        }
1592
0
    }
1593
1594
    // TODO Data from Filter in other range are still missing!
1595
1596
0
    if (nNewEndRow > aBlockEnd.Row())
1597
0
    {
1598
0
        rDoc.DeleteRow( 0,nTab, rDoc.MaxCol(),nTab, aBlockEnd.Row()+1, static_cast<SCSIZE>(nNewEndRow-aBlockEnd.Row()) );
1599
0
    }
1600
0
    else if (nNewEndRow < aBlockEnd.Row())
1601
0
    {
1602
0
        rDoc.InsertRow( 0,nTab, rDoc.MaxCol(),nTab, nNewEndRow+1, static_cast<SCSIZE>(nNewEndRow-aBlockEnd.Row()) );
1603
0
    }
1604
1605
    // Original Outline table
1606
0
    rDoc.SetOutlineTable(nTab, xUndoTable.get());
1607
1608
    // Original column/row status
1609
0
    if (xUndoTable)
1610
0
    {
1611
0
        SCCOLROW nStartCol;
1612
0
        SCCOLROW nStartRow;
1613
0
        SCCOLROW nEndCol;
1614
0
        SCCOLROW nEndRow;
1615
0
        xUndoTable->GetColArray().GetRange(nStartCol, nEndCol);
1616
0
        xUndoTable->GetRowArray().GetRange(nStartRow, nEndRow);
1617
1618
0
        xUndoDoc->CopyToDocument(static_cast<SCCOL>(nStartCol), 0, nTab,
1619
0
                                 static_cast<SCCOL>(nEndCol), rDoc.MaxRow(), nTab, InsertDeleteFlags::NONE, false,
1620
0
                                 rDoc);
1621
0
        xUndoDoc->CopyToDocument(0, nStartRow, nTab, rDoc.MaxCol(), nEndRow, nTab, InsertDeleteFlags::NONE, false, rDoc);
1622
1623
0
        pViewShell->UpdateScrollBars();
1624
0
    }
1625
1626
    //  Original data and references
1627
0
    ScUndoUtil::MarkSimpleBlock( rDocShell, 0, aBlockStart.Row(), nTab,
1628
0
                                            rDoc.MaxCol(), aBlockEnd.Row(), nTab );
1629
0
    rDoc.DeleteAreaTab( 0, aBlockStart.Row(),
1630
0
                            rDoc.MaxCol(), aBlockEnd.Row(), nTab, InsertDeleteFlags::ALL );
1631
1632
0
    xUndoDoc->CopyToDocument(0, aBlockStart.Row(), nTab, rDoc.MaxCol(), aBlockEnd.Row(), nTab,
1633
0
                             InsertDeleteFlags::NONE, false, rDoc);            // Flags
1634
0
    xUndoDoc->UndoToDocument(0, aBlockStart.Row(), nTab, rDoc.MaxCol(), aBlockEnd.Row(), nTab,
1635
0
                             InsertDeleteFlags::ALL, false, rDoc);
1636
1637
0
    ScUndoUtil::MarkSimpleBlock( rDocShell, aBlockStart.Col(),aBlockStart.Row(),nTab,
1638
0
                                            aBlockEnd.Col(),aBlockEnd.Row(),nTab );
1639
1640
0
    if (xUndoRange)
1641
0
        rDoc.SetRangeName(std::unique_ptr<ScRangeName>(new ScRangeName(*xUndoRange)));
1642
0
    if (xUndoDB)
1643
0
        rDoc.SetDBCollection(std::unique_ptr<ScDBCollection>(new ScDBCollection(*xUndoDB)), true);
1644
1645
0
    ScTabViewShell::notifyAllViewsSheetGeomInvalidation(pViewShell, false /* bColumns */, true /* bRows */,
1646
0
            false /* bSizes*/, true /* bHidden */, true /* bFiltered */,
1647
0
            false /* bGroups */, nTab);
1648
1649
0
    SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
1650
0
    if ( nVisTab != nTab )
1651
0
        pViewShell->SetTabNo( nTab );
1652
1653
0
    rDocShell.PostPaint(0,0,nTab,rDoc.MaxCol(),rDoc.MaxRow(),nTab,PaintPartFlags::Grid|PaintPartFlags::Left|PaintPartFlags::Top|PaintPartFlags::Size);
1654
0
    rDocShell.PostDataChanged();
1655
1656
0
    EndUndo();
1657
0
}
1658
1659
void ScUndoRepeatDB::Redo()
1660
0
{
1661
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1662
0
    if (!pViewShell)
1663
0
        return;
1664
1665
0
    BeginRedo();
1666
1667
0
    SCTAB nTab = aBlockStart.Tab();
1668
1669
0
    SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber();
1670
0
    if ( nVisTab != nTab )
1671
0
        pViewShell->SetTabNo( nTab );
1672
1673
0
    ScUndoUtil::MarkSimpleBlock( rDocShell, aBlockStart.Col(),aBlockStart.Row(),nTab,
1674
0
                                            aBlockEnd.Col(),aBlockEnd.Row(),nTab );
1675
0
    pViewShell->SetCursor( aCursorPos.Col(), aCursorPos.Row() );
1676
1677
0
    pViewShell->RepeatDB( false );
1678
1679
0
    EndRedo();
1680
0
}
1681
1682
void ScUndoRepeatDB::Repeat(SfxRepeatTarget& rTarget)
1683
0
{
1684
0
    if (auto pViewTarget = dynamic_cast<ScTabViewTarget*>( &rTarget))
1685
0
        pViewTarget->GetViewShell().RepeatDB();
1686
0
}
1687
1688
bool ScUndoRepeatDB::CanRepeat(SfxRepeatTarget& rTarget) const
1689
0
{
1690
0
    return dynamic_cast<const ScTabViewTarget*>( &rTarget) !=  nullptr;
1691
0
}
1692
1693
ScUndoDataPilot::ScUndoDataPilot( ScDocShell& rNewDocShell,
1694
                            ScDocumentUniquePtr pOldDoc, ScDocumentUniquePtr pNewDoc,
1695
                            const ScDPObject* pOldObj, const ScDPObject* pNewObj, bool bMove )
1696
0
    : ScSimpleUndo(rNewDocShell)
1697
0
    , xOldUndoDoc(std::move(pOldDoc))
1698
0
    , xNewUndoDoc(std::move(pNewDoc))
1699
0
    , bAllowMove( bMove)
1700
0
{
1701
0
    if (pOldObj)
1702
0
        xOldDPObject.reset(new ScDPObject(*pOldObj));
1703
0
    if (pNewObj)
1704
0
        xNewDPObject.reset(new ScDPObject(*pNewObj));
1705
0
}
1706
1707
OUString ScUndoDataPilot::GetComment() const
1708
0
{
1709
0
    TranslateId pResId;
1710
0
    if (xOldUndoDoc && xNewUndoDoc)
1711
0
        pResId = STR_UNDO_PIVOT_MODIFY;
1712
0
    else if (xNewUndoDoc)
1713
0
        pResId = STR_UNDO_PIVOT_NEW;
1714
0
    else
1715
0
        pResId = STR_UNDO_PIVOT_DELETE;
1716
1717
0
    return ScResId(pResId);
1718
0
}
1719
1720
void ScUndoDataPilot::Undo()
1721
0
{
1722
0
    BeginUndo();
1723
1724
0
    ScDocument& rDoc = rDocShell.GetDocument();
1725
1726
0
    ScRange aOldRange;
1727
0
    ScRange aNewRange;
1728
1729
0
    if (xNewDPObject && xNewUndoDoc)
1730
0
    {
1731
0
        aNewRange = xNewDPObject->GetOutRange();
1732
0
        rDoc.DeleteAreaTab( aNewRange, InsertDeleteFlags::ALL );
1733
0
        xNewUndoDoc->CopyToDocument(aNewRange, InsertDeleteFlags::ALL, false, rDoc);
1734
0
    }
1735
0
    if (xOldDPObject && xOldUndoDoc)
1736
0
    {
1737
0
        aOldRange = xOldDPObject->GetOutRange();
1738
0
        rDoc.DeleteAreaTab(aOldRange, InsertDeleteFlags::ALL);
1739
0
        xOldUndoDoc->CopyToDocument(aOldRange, InsertDeleteFlags::ALL, false, rDoc);
1740
0
    }
1741
1742
    //  update objects in collection
1743
0
    if (xNewDPObject)
1744
0
    {
1745
        //  find updated object
1746
        //! find by name!
1747
1748
0
        ScDPObject* pDocObj = rDoc.GetDPAtCursor(
1749
0
                            aNewRange.aStart.Col(), aNewRange.aStart.Row(), aNewRange.aStart.Tab() );
1750
0
        OSL_ENSURE(pDocObj, "DPObject not found");
1751
0
        if (pDocObj)
1752
0
        {
1753
0
            if (xOldDPObject)
1754
0
            {
1755
                //  restore old settings
1756
0
                *pDocObj = *xOldDPObject;
1757
0
            }
1758
0
            else
1759
0
            {
1760
                //  delete inserted object
1761
0
                rDoc.GetDPCollection()->FreeTable(pDocObj);
1762
0
            }
1763
0
        }
1764
0
    }
1765
0
    else if (xOldDPObject)
1766
0
    {
1767
        //  re-insert deleted object
1768
0
        rDoc.GetDPCollection()->InsertNewTable(std::make_unique<ScDPObject>(*xOldDPObject));
1769
0
    }
1770
1771
0
    if (xNewUndoDoc)
1772
0
        rDocShell.PostPaint(aNewRange, PaintPartFlags::Grid, SC_PF_LINES);
1773
0
    if (xOldUndoDoc)
1774
0
        rDocShell.PostPaint(aOldRange, PaintPartFlags::Grid, SC_PF_LINES);
1775
0
    rDocShell.PostDataChanged();
1776
1777
0
    if (xNewDPObject)
1778
0
    {
1779
        // notify API objects
1780
0
        rDoc.BroadcastUno(ScDataPilotModifiedHint(xNewDPObject->GetName()));
1781
0
    }
1782
1783
0
    EndUndo();
1784
0
}
1785
1786
void ScUndoDataPilot::Redo()
1787
0
{
1788
0
    BeginRedo();
1789
1790
    //! copy output data instead of repeating the change,
1791
    //! in case external data have changed!
1792
1793
0
    ScDocument& rDoc = rDocShell.GetDocument();
1794
1795
0
    ScDPObject* pSourceObj = nullptr;
1796
0
    if (xOldDPObject)
1797
0
    {
1798
        //  find object to modify
1799
        //! find by name!
1800
1801
0
        ScRange aOldRange = xOldDPObject->GetOutRange();
1802
0
        pSourceObj = rDoc.GetDPAtCursor(
1803
0
                        aOldRange.aStart.Col(), aOldRange.aStart.Row(), aOldRange.aStart.Tab() );
1804
0
        OSL_ENSURE(pSourceObj, "DPObject not found");
1805
0
    }
1806
1807
0
    ScDBDocFunc aFunc( rDocShell );
1808
0
    aFunc.DataPilotUpdate(pSourceObj, xNewDPObject.get(), false, false, bAllowMove);    // no new undo action
1809
1810
0
    EndRedo();
1811
0
}
1812
1813
void ScUndoDataPilot::Repeat(SfxRepeatTarget& /* rTarget */)
1814
0
{
1815
    //! allow deletion
1816
0
}
1817
1818
bool ScUndoDataPilot::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1819
0
{
1820
    //! allow deletion
1821
0
    return false;
1822
0
}
1823
1824
ScUndoConsolidate::ScUndoConsolidate( ScDocShell& rNewDocShell, const ScArea& rArea,
1825
                    const ScConsolidateParam& rPar, ScDocumentUniquePtr pNewUndoDoc,
1826
                    bool bReference, SCROW nInsCount, std::unique_ptr<ScOutlineTable> pTab,
1827
                    std::unique_ptr<ScDBData> pData )
1828
0
    : ScSimpleUndo(rNewDocShell)
1829
0
    , aDestArea(rArea)
1830
0
    , xUndoDoc(std::move(pNewUndoDoc))
1831
0
    , aParam(rPar)
1832
0
    , bInsRef(bReference)
1833
0
    , nInsertCount(nInsCount)
1834
0
    , xUndoTab(std::move(pTab))
1835
0
    , xUndoData(std::move(pData))
1836
0
{
1837
0
}
1838
1839
OUString ScUndoConsolidate::GetComment() const
1840
0
{
1841
0
    return ScResId( STR_UNDO_CONSOLIDATE );
1842
0
}
1843
1844
void ScUndoConsolidate::Undo()
1845
0
{
1846
0
    BeginUndo();
1847
1848
0
    ScDocument& rDoc = rDocShell.GetDocument();
1849
0
    SCTAB nTab = aDestArea.nTab;
1850
1851
0
    ScRange aOldRange;
1852
0
    if (xUndoData)
1853
0
        xUndoData->GetArea(aOldRange);
1854
1855
0
    if (bInsRef)
1856
0
    {
1857
0
        rDoc.DeleteRow( 0,nTab, rDoc.MaxCol(),nTab, aDestArea.nRowStart, nInsertCount );
1858
0
        rDoc.SetOutlineTable(nTab, xUndoTab.get());
1859
1860
        // Row status
1861
0
        xUndoDoc->CopyToDocument(0, 0, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab, InsertDeleteFlags::NONE, false, rDoc);
1862
1863
        // Data and references
1864
0
        rDoc.DeleteAreaTab( 0,aDestArea.nRowStart, rDoc.MaxCol(),aDestArea.nRowEnd, nTab, InsertDeleteFlags::ALL );
1865
0
        xUndoDoc->UndoToDocument(0, aDestArea.nRowStart, nTab,
1866
0
                                 rDoc.MaxCol(), aDestArea.nRowEnd, nTab,
1867
0
                                 InsertDeleteFlags::ALL, false, rDoc);
1868
1869
        // Original range
1870
0
        if (xUndoData)
1871
0
        {
1872
0
            rDoc.DeleteAreaTab(aOldRange, InsertDeleteFlags::ALL);
1873
0
            xUndoDoc->CopyToDocument(aOldRange, InsertDeleteFlags::ALL, false, rDoc);
1874
0
        }
1875
1876
0
        rDocShell.PostPaint( 0,aDestArea.nRowStart,nTab, rDoc.MaxCol(),rDoc.MaxRow(),nTab,
1877
0
                                PaintPartFlags::Grid | PaintPartFlags::Left | PaintPartFlags::Size );
1878
0
    }
1879
0
    else
1880
0
    {
1881
0
        rDoc.DeleteAreaTab( aDestArea.nColStart,aDestArea.nRowStart,
1882
0
                                aDestArea.nColEnd,aDestArea.nRowEnd, nTab, InsertDeleteFlags::ALL );
1883
0
        xUndoDoc->CopyToDocument(aDestArea.nColStart, aDestArea.nRowStart, nTab,
1884
0
                                 aDestArea.nColEnd, aDestArea.nRowEnd, nTab,
1885
0
                                 InsertDeleteFlags::ALL, false, rDoc);
1886
1887
        //  Original range
1888
0
        if (xUndoData)
1889
0
        {
1890
0
            rDoc.DeleteAreaTab(aOldRange, InsertDeleteFlags::ALL);
1891
0
            xUndoDoc->CopyToDocument(aOldRange, InsertDeleteFlags::ALL, false, rDoc);
1892
0
        }
1893
1894
0
        SCCOL nEndX = aDestArea.nColEnd;
1895
0
        SCROW nEndY = aDestArea.nRowEnd;
1896
0
        if (xUndoData)
1897
0
        {
1898
0
            if ( aOldRange.aEnd.Col() > nEndX )
1899
0
                nEndX = aOldRange.aEnd.Col();
1900
0
            if ( aOldRange.aEnd.Row() > nEndY )
1901
0
                nEndY = aOldRange.aEnd.Row();
1902
0
        }
1903
0
        rDocShell.PostPaint( aDestArea.nColStart, aDestArea.nRowStart, nTab,
1904
0
                                    nEndX, nEndY, nTab, PaintPartFlags::Grid );
1905
0
    }
1906
1907
    // Adjust Database range again
1908
0
    if (xUndoData)
1909
0
    {
1910
0
        ScDBCollection* pColl = rDoc.GetDBCollection();
1911
0
        if (pColl)
1912
0
        {
1913
0
            ScDBData* pDocData = pColl->getNamedDBs().findByUpperName(xUndoData->GetUpperName());
1914
0
            if (pDocData)
1915
0
                *pDocData = *xUndoData;
1916
0
        }
1917
0
    }
1918
1919
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1920
0
    if (pViewShell)
1921
0
    {
1922
0
        SCTAB nViewTab = pViewShell->GetViewData().GetTabNumber();
1923
0
        if ( nViewTab != nTab )
1924
0
            pViewShell->SetTabNo( nTab );
1925
0
    }
1926
1927
0
    EndUndo();
1928
0
}
1929
1930
void ScUndoConsolidate::Redo()
1931
0
{
1932
0
    BeginRedo();
1933
1934
0
    rDocShell.DoConsolidate( aParam, false );
1935
1936
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1937
0
    if (pViewShell)
1938
0
    {
1939
0
        SCTAB nViewTab = pViewShell->GetViewData().GetTabNumber();
1940
0
        if ( nViewTab != aParam.nTab )
1941
0
            pViewShell->SetTabNo( aParam.nTab );
1942
0
    }
1943
1944
0
    EndRedo();
1945
0
}
1946
1947
void ScUndoConsolidate::Repeat(SfxRepeatTarget& /* rTarget */)
1948
0
{
1949
0
}
1950
1951
bool ScUndoConsolidate::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1952
0
{
1953
0
    return false;
1954
0
}
1955
1956
// Change source data of Chart
1957
void ScUndoChartData::Init()
1958
0
{
1959
0
    ScDocument& rDoc = rDocShell.GetDocument();
1960
0
    aOldRangeListRef = new ScRangeList;
1961
0
    rDoc.GetOldChartParameters( aChartName, *aOldRangeListRef, bOldColHeaders, bOldRowHeaders );
1962
0
}
1963
1964
ScUndoChartData::ScUndoChartData( ScDocShell& rNewDocShell, OUString aName,
1965
                                    const ScRange& rNew, bool bColHdr, bool bRowHdr,
1966
                                    bool bAdd ) :
1967
0
    ScSimpleUndo( rNewDocShell ),
1968
0
    aChartName(std::move( aName )),
1969
0
    bOldColHeaders(false),
1970
0
    bOldRowHeaders(false),
1971
0
    bNewColHeaders( bColHdr ),
1972
0
    bNewRowHeaders( bRowHdr ),
1973
0
    bAddRange( bAdd )
1974
0
{
1975
0
    aNewRangeListRef = new ScRangeList;
1976
0
    aNewRangeListRef->push_back( rNew );
1977
1978
0
    Init();
1979
0
}
1980
1981
ScUndoChartData::ScUndoChartData( ScDocShell& rNewDocShell, OUString aName,
1982
                                    ScRangeListRef xNew, bool bColHdr, bool bRowHdr,
1983
                                    bool bAdd ) :
1984
0
    ScSimpleUndo( rNewDocShell ),
1985
0
    aChartName(std::move( aName )),
1986
0
    bOldColHeaders(false),
1987
0
    bOldRowHeaders(false),
1988
0
    aNewRangeListRef(std::move( xNew )),
1989
0
    bNewColHeaders( bColHdr ),
1990
0
    bNewRowHeaders( bRowHdr ),
1991
0
    bAddRange( bAdd )
1992
0
{
1993
0
    Init();
1994
0
}
1995
1996
ScUndoChartData::~ScUndoChartData()
1997
0
{
1998
0
}
1999
2000
OUString ScUndoChartData::GetComment() const
2001
0
{
2002
0
    return ScResId( STR_UNDO_CHARTDATA );
2003
0
}
2004
2005
void ScUndoChartData::Undo()
2006
0
{
2007
0
    BeginUndo();
2008
2009
0
    rDocShell.GetDocument().UpdateChartArea( aChartName, aOldRangeListRef,
2010
0
                                bOldColHeaders, bOldRowHeaders, false );
2011
2012
0
    EndUndo();
2013
0
}
2014
2015
void ScUndoChartData::Redo()
2016
0
{
2017
0
    BeginRedo();
2018
2019
0
    rDocShell.GetDocument().UpdateChartArea( aChartName, aNewRangeListRef,
2020
0
                                bNewColHeaders, bNewRowHeaders, bAddRange );
2021
2022
0
    EndRedo();
2023
0
}
2024
2025
void ScUndoChartData::Repeat(SfxRepeatTarget& /* rTarget */)
2026
0
{
2027
0
}
2028
2029
bool ScUndoChartData::CanRepeat(SfxRepeatTarget& /* rTarget */) const
2030
0
{
2031
0
    return false;
2032
0
}
2033
2034
ScUndoDataForm::ScUndoDataForm( ScDocShell& rNewDocShell,
2035
                                SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
2036
                                SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
2037
                                const ScMarkData& rMark,
2038
                                ScDocumentUniquePtr pNewUndoDoc, ScDocumentUniquePtr pNewRedoDoc,
2039
                                std::unique_ptr<ScRefUndoData> pRefData )
2040
0
    : ScBlockUndo(rNewDocShell, ScRange( nStartX, nStartY, nStartZ, nEndX, nEndY, nEndZ ), SC_UNDO_SIMPLE)
2041
0
    , mxMarkData(new ScMarkData(rMark))
2042
0
    , xUndoDoc(std::move(pNewUndoDoc))
2043
0
    , xRedoDoc(std::move(pNewRedoDoc))
2044
0
    , xRefUndoData(std::move(pRefData))
2045
0
    , bRedoFilled(false)
2046
0
{
2047
    //      pFill1,pFill2,pFill3 are there so the ctor calls for simple paste (without cutting)
2048
    //      don't have to be changed and branched for 641.
2049
    //      They can be removed later.
2050
2051
0
    if (!mxMarkData->IsMarked())                            // no cell marked:
2052
0
        mxMarkData->SetMarkArea(aBlockRange);   //  mark paste block
2053
2054
0
    if (xRefUndoData)
2055
0
        xRefUndoData->DeleteUnchanged(rDocShell.GetDocument());
2056
0
}
2057
2058
OUString ScUndoDataForm::GetComment() const
2059
0
{
2060
0
    return ScResId( STR_UNDO_PASTE );
2061
0
}
2062
2063
void ScUndoDataForm::Undo()
2064
0
{
2065
0
    BeginUndo();
2066
0
    DoChange( true );
2067
0
    ShowTable( aBlockRange );
2068
0
    EndUndo();
2069
0
    SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScAreaLinksChanged ) );
2070
0
}
2071
2072
void ScUndoDataForm::Redo()
2073
0
{
2074
0
    BeginRedo();
2075
0
    ScDocument& rDoc = rDocShell.GetDocument();
2076
0
    EnableDrawAdjust( &rDoc, false );                                //! include in ScBlockUndo?
2077
0
    DoChange( false );
2078
0
    EnableDrawAdjust( &rDoc, true );                                 //! include in ScBlockUndo?
2079
0
    EndRedo();
2080
0
    SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScAreaLinksChanged ) );
2081
0
}
2082
2083
void ScUndoDataForm::Repeat(SfxRepeatTarget& /*rTarget*/)
2084
0
{
2085
0
}
2086
2087
bool ScUndoDataForm::CanRepeat(SfxRepeatTarget& rTarget) const
2088
0
{
2089
0
    return (dynamic_cast<const ScTabViewTarget*>( &rTarget) !=  nullptr);
2090
0
}
2091
2092
void ScUndoDataForm::DoChange( const bool bUndo )
2093
0
{
2094
0
    ScDocument& rDoc = rDocShell.GetDocument();
2095
2096
    //      RefUndoData for redo is created before first undo
2097
    //      (with DeleteUnchanged after the DoUndo call)
2098
0
    bool bCreateRedoData = (bUndo && xRefUndoData && !xRefRedoData);
2099
0
    if (bCreateRedoData)
2100
0
        xRefRedoData.reset(new ScRefUndoData(rDoc));
2101
2102
0
    ScRefUndoData* pWorkRefData = bUndo ? xRefUndoData.get() : xRefRedoData.get();
2103
2104
0
    bool bPaintAll = false;
2105
2106
0
    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
2107
2108
0
    SCTAB nTabCount = rDoc.GetTableCount();
2109
0
    if ( bUndo && !bRedoFilled )
2110
0
    {
2111
0
        if (!xRedoDoc)
2112
0
        {
2113
0
            bool bColInfo = ( aBlockRange.aStart.Row()==0 && aBlockRange.aEnd.Row()==rDoc.MaxRow() );
2114
0
            bool bRowInfo = ( aBlockRange.aStart.Col()==0 && aBlockRange.aEnd.Col()==rDoc.MaxCol() );
2115
2116
0
            xRedoDoc.reset(new ScDocument(SCDOCMODE_UNDO));
2117
0
            xRedoDoc->InitUndoSelected(rDoc, *mxMarkData, bColInfo, bRowInfo);
2118
0
        }
2119
        //  read "redo" data from the document in the first undo
2120
            //  all sheets - CopyToDocument skips those that don't exist in pRedoDoc
2121
0
        ScRange aCopyRange = aBlockRange;
2122
0
        aCopyRange.aStart.SetTab(0);
2123
0
        aCopyRange.aEnd.SetTab(nTabCount-1);
2124
0
        rDoc.CopyToDocument(aCopyRange, InsertDeleteFlags::VALUE, false, *xRedoDoc);
2125
0
        bRedoFilled = true;
2126
0
    }
2127
2128
0
    sal_uInt16 nExtFlags = 0;
2129
0
    rDocShell.UpdatePaintExt( nExtFlags, aBlockRange );
2130
2131
0
    for ( sal_uInt16 i=0; i <= ( aBlockRange.aEnd.Col() - aBlockRange.aStart.Col() ); i++ )
2132
0
    {
2133
0
        OUString aOldString = xUndoDoc->GetString(
2134
0
            aBlockRange.aStart.Col()+i, aBlockRange.aStart.Row(), aBlockRange.aStart.Tab());
2135
0
        rDoc.SetString( aBlockRange.aStart.Col()+i , aBlockRange.aStart.Row() , aBlockRange.aStart.Tab() , aOldString );
2136
0
    }
2137
2138
0
    if (pWorkRefData)
2139
0
    {
2140
0
        pWorkRefData->DoUndo( rDoc, true );             // TRUE = bSetChartRangeLists for SetChartListenerCollection
2141
0
        if ( rDoc.RefreshAutoFilter( 0,0, rDoc.MaxCol(),rDoc.MaxRow(), aBlockRange.aStart.Tab() ) )
2142
0
            bPaintAll = true;
2143
0
    }
2144
2145
0
    if (bCreateRedoData && xRefRedoData)
2146
0
        xRefRedoData->DeleteUnchanged(rDoc);
2147
2148
0
    if ( bUndo )
2149
0
    {
2150
0
        ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
2151
0
        if ( pChangeTrack )
2152
0
            pChangeTrack->Undo( 0, 0 );
2153
0
    }
2154
2155
0
    ScRange aDrawRange( aBlockRange );
2156
0
    rDoc.ExtendMerge( aDrawRange, true );      // only needed for single sheet (text/rtf etc.)
2157
0
    PaintPartFlags nPaint = PaintPartFlags::Grid;
2158
0
    if (bPaintAll)
2159
0
    {
2160
0
        aDrawRange.aStart.SetCol(0);
2161
0
        aDrawRange.aStart.SetRow(0);
2162
0
        aDrawRange.aEnd.SetCol(rDoc.MaxCol());
2163
0
        aDrawRange.aEnd.SetRow(rDoc.MaxRow());
2164
0
        nPaint |= PaintPartFlags::Top | PaintPartFlags::Left;
2165
0
        if (pViewShell)
2166
0
            pViewShell->AdjustBlockHeight(false);
2167
0
    }
2168
0
    else
2169
0
    {
2170
0
        if ( aBlockRange.aStart.Row() == 0 && aBlockRange.aEnd.Row() == rDoc.MaxRow() )        // whole column
2171
0
        {
2172
0
            nPaint |= PaintPartFlags::Top;
2173
0
            aDrawRange.aEnd.SetCol(rDoc.MaxCol());
2174
0
        }
2175
0
        if ( aBlockRange.aStart.Col() == 0 && aBlockRange.aEnd.Col() == rDoc.MaxCol() )        // whole row
2176
0
        {
2177
0
            nPaint |= PaintPartFlags::Left;
2178
0
            aDrawRange.aEnd.SetRow(rDoc.MaxRow());
2179
0
        }
2180
0
        if (pViewShell && pViewShell->AdjustBlockHeight(false))
2181
0
        {
2182
0
            aDrawRange.aStart.SetCol(0);
2183
0
            aDrawRange.aStart.SetRow(0);
2184
0
            aDrawRange.aEnd.SetCol(rDoc.MaxCol());
2185
0
            aDrawRange.aEnd.SetRow(rDoc.MaxRow());
2186
0
            nPaint |= PaintPartFlags::Left;
2187
0
        }
2188
0
        rDocShell.UpdatePaintExt( nExtFlags, aDrawRange );
2189
0
    }
2190
2191
0
    if ( !bUndo )                               //      draw redo after updating row heights
2192
0
        RedoSdrUndoAction( pDrawUndo.get() );   //!     include in ScBlockUndo?
2193
2194
0
    rDocShell.PostPaint( aDrawRange, nPaint, nExtFlags );
2195
2196
0
    rDocShell.PostDataChanged();
2197
0
    if (pViewShell)
2198
0
        pViewShell->CellContentChanged();
2199
0
}
2200
2201
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */