Coverage Report

Created: 2026-07-10 11:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sc/source/ui/operation/ReplacePivotTableOperation.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
10
#include <operation/ReplacePivotTableOperation.hxx>
11
#include <operation/PivotTableOperationCommon.hxx>
12
13
#include <vcl/svapp.hxx>
14
#include <vcl/vclenum.hxx>
15
#include <vcl/weld/MessageDialog.hxx>
16
#include <vcl/weld/WaitObject.hxx>
17
#include <vcl/weld/Window.hxx>
18
#include <osl/diagnose.h>
19
20
#include <dpsave.hxx>
21
#include <undodat.hxx>
22
#include <scresid.hxx>
23
#include <hints.hxx>
24
25
namespace sc
26
{
27
ReplacePivotTableOperation::ReplacePivotTableOperation(ScDocShell& rDocShell, ScDPObject* pDPObject,
28
                                                       ScDPObject const* pNewDPObject, bool bRecord,
29
                                                       bool bApi, bool bAllowMove)
30
0
    : PivotTableOperation(OperationType::PivotTableReplace, rDocShell, bRecord, bApi)
31
0
    , mpDPObject(pDPObject)
32
0
    , mpNewDPObject(pNewDPObject)
33
0
    , mbAllowMove(bAllowMove)
34
0
{
35
0
}
36
37
bool ReplacePivotTableOperation::runImplementation()
38
0
{
39
0
    assert(mpDPObject);
40
0
    assert(mpNewDPObject);
41
0
    assert(mpDPObject != mpNewDPObject);
42
43
0
    ScDocShellModificator aModificator(mrDocShell);
44
0
    weld::WaitObject aWait(ScDocShell::GetActiveDialogParent());
45
46
    // Resolve to the default view's DPObject when called from a sheet view
47
0
    ScDPObject* pDPObject = findDefaultViewDPObject(*mpDPObject);
48
0
    if (!pDPObject)
49
0
        pDPObject = mpDPObject;
50
51
0
    ScRangeList aRanges;
52
0
    aRanges.push_back(pDPObject->GetOutRange());
53
0
    aRanges.push_back(ScRange(
54
0
        convertAddress(mpNewDPObject->GetOutRange()
55
0
                           .aStart))); // at least one cell in the output position must be editable.
56
57
0
    if (!sc::pivot::isEditable(mrDocShell, aRanges, mbApi))
58
0
        return false;
59
60
0
    ScDocumentUniquePtr pOldUndoDoc;
61
0
    ScDocumentUniquePtr pNewUndoDoc;
62
63
0
    ScDPObject aUndoDPObject(*pDPObject); // for undo or revert on failure
64
65
0
    ScDocument& rDoc = mrDocShell.GetDocument();
66
0
    if (mbRecord && !rDoc.IsUndoEnabled())
67
0
        mbRecord = false;
68
69
0
    if (mbRecord)
70
0
        sc::pivot::createUndoDoc(pOldUndoDoc, rDoc, pDPObject->GetOutRange());
71
72
0
    mpNewDPObject->WriteSourceDataTo(*pDPObject); // copy source data
73
74
0
    ScDPSaveData* pData = mpNewDPObject->GetSaveData();
75
0
    OSL_ENSURE(pData, "no SaveData from living DPObject");
76
0
    if (pData)
77
0
        pDPObject->SetSaveData(*pData); // copy SaveData
78
79
0
    pDPObject->SetAllowMove(mbAllowMove);
80
0
    pDPObject->ReloadGroupTableData();
81
0
    pDPObject->SyncAllDimensionMembers();
82
0
    pDPObject->InvalidateData(); // before getting the new output area
83
84
    //  make sure the table has a name (not set by dialog)
85
0
    if (pDPObject->GetName().isEmpty())
86
0
        pDPObject->SetName(rDoc.GetDPCollection()->CreateNewName());
87
88
0
    ScRange aNewOut;
89
0
    if (!sc::pivot::checkNewOutputRange(*pDPObject, mrDocShell, aNewOut, mbApi))
90
0
    {
91
0
        *pDPObject = aUndoDPObject;
92
0
        return false;
93
0
    }
94
95
0
    if (mbRecord)
96
0
        sc::pivot::createUndoDoc(pNewUndoDoc, rDoc, aNewOut);
97
98
    // Use spill checking output if the destination range has non-empty cells,
99
    // write #SPILL! into the origin cell instead of overwriting.
100
    // Skip the spill check during XML import
101
0
    pDPObject->Output(aNewOut.aStart, !rDoc.IsImportingXML());
102
0
    mrDocShell.PostPaintGridAll();
103
104
0
    if (mbRecord)
105
0
    {
106
0
        mrDocShell.GetUndoManager()->AddUndoAction(std::make_unique<ScUndoDataPilot>(
107
0
            mrDocShell, std::move(pOldUndoDoc), std::move(pNewUndoDoc), &aUndoDPObject, pDPObject,
108
0
            mbAllowMove));
109
0
    }
110
111
0
    syncSheetViews();
112
113
    // notify API objects
114
0
    rDoc.BroadcastUno(ScDataPilotModifiedHint(pDPObject->GetName()));
115
0
    aModificator.SetDocumentModified();
116
117
0
    return true;
118
0
}
119
}
120
121
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */