Coverage Report

Created: 2026-04-09 11:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sc/source/ui/undo/undostyl.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 <svl/itemset.hxx>
21
#include <tools/mapunit.hxx>
22
#include <utility>
23
#include <vcl/virdev.hxx>
24
#include <osl/diagnose.h>
25
26
#include <undostyl.hxx>
27
#include <docsh.hxx>
28
#include <stlpool.hxx>
29
#include <printfun.hxx>
30
#include <scmod.hxx>
31
#include <inputhdl.hxx>
32
#include <globstr.hrc>
33
#include <scresid.hxx>
34
35
//      modify style (cell or page style)
36
37
ScStyleSaveData::ScStyleSaveData()
38
0
{
39
0
}
40
41
ScStyleSaveData::ScStyleSaveData( const ScStyleSaveData& rOther ) :
42
0
    aName( rOther.aName ),
43
0
    aParent( rOther.aParent )
44
0
{
45
0
    if (rOther.moItems)
46
0
        moItems.emplace(*rOther.moItems);
47
0
}
48
49
ScStyleSaveData& ScStyleSaveData::operator=( const ScStyleSaveData& rOther )
50
0
{
51
0
    if (this != &rOther)
52
0
    {
53
0
        aName   = rOther.aName;
54
0
        aParent = rOther.aParent;
55
0
        if (rOther.moItems)
56
0
            moItems.emplace(*rOther.moItems);
57
0
        else
58
0
            moItems.reset();
59
0
    }
60
0
    return *this;
61
0
}
62
63
void ScStyleSaveData::InitFromStyle( const SfxStyleSheetBase* pSource )
64
0
{
65
0
    if ( pSource )
66
0
    {
67
0
        aName   = pSource->GetName();
68
0
        aParent = pSource->GetParent();
69
0
        moItems.emplace(const_cast<SfxStyleSheetBase*>(pSource)->GetItemSet());
70
0
    }
71
0
    else
72
0
    {
73
0
        aName.clear();
74
0
        aParent.clear();
75
0
        moItems.reset();
76
0
    }
77
0
}
78
79
ScUndoModifyStyle::ScUndoModifyStyle( ScDocShell& rShell, SfxStyleFamily eFam,
80
                    const ScStyleSaveData& rOld, const ScStyleSaveData& rNew ) :
81
0
    ScSimpleUndo( rShell ),
82
0
    eFamily( eFam ),
83
0
    aOldData( rOld ),
84
0
    aNewData( rNew )
85
0
{
86
0
}
87
88
ScUndoModifyStyle::~ScUndoModifyStyle()
89
0
{
90
0
}
91
92
OUString ScUndoModifyStyle::GetComment() const
93
0
{
94
0
    if (eFamily == SfxStyleFamily::Frame)
95
0
        return ScResId(STR_UNDO_EDITGRAPHICSTYLE);
96
0
    if (eFamily == SfxStyleFamily::Page)
97
0
        return ScResId(STR_UNDO_EDITPAGESTYLE);
98
99
0
    return ScResId(STR_UNDO_EDITCELLSTYLE);
100
0
}
101
102
static void lcl_DocStyleChanged( ScDocument* pDoc, const SfxStyleSheetBase* pStyle, bool bRemoved )
103
0
{
104
    //! move to document or docshell
105
106
0
    ScopedVclPtrInstance< VirtualDevice > pVDev;
107
0
    Point aLogic = pVDev->LogicToPixel(Point(1000,1000), MapMode(MapUnit::MapTwip));
108
0
    double nPPTX = aLogic.X() / 1000.0;
109
0
    double nPPTY = aLogic.Y() / 1000.0;
110
0
    double fZoom(1.0);
111
0
    pDoc->StyleSheetChanged( pStyle, bRemoved, pVDev, nPPTX, nPPTY, fZoom, fZoom );
112
113
0
    ScInputHandler* pHdl = ScModule::get()->GetInputHdl();
114
0
    if (pHdl)
115
0
        pHdl->ForgetLastPattern();
116
0
}
117
118
void ScUndoModifyStyle::DoChange( ScDocShell& rDocSh, const OUString& rName,
119
                                    SfxStyleFamily eStyleFamily, const ScStyleSaveData& rData )
120
0
{
121
0
    ScDocument& rDoc = rDocSh.GetDocument();
122
0
    ScStyleSheetPool* pStlPool = rDoc.GetStyleSheetPool();
123
0
    const OUString& aNewName = rData.GetName();
124
0
    bool bDelete = aNewName.isEmpty();         // no new name -> delete style
125
0
    bool bNew = ( rName.isEmpty() && !bDelete );   // creating new style
126
127
0
    SfxStyleSheetBase* pStyle = nullptr;
128
0
    if ( !rName.isEmpty() )
129
0
    {
130
        // find old style to modify
131
0
        pStyle = pStlPool->Find( rName, eStyleFamily );
132
0
        OSL_ENSURE( pStyle, "style not found" );
133
134
0
        if ( pStyle && !bDelete )
135
0
        {
136
            // set new name
137
0
            pStyle->SetName( aNewName );
138
0
        }
139
0
    }
140
0
    else if ( !bDelete )
141
0
    {
142
        // create style (with new name)
143
0
        pStyle = &pStlPool->Make( aNewName, eStyleFamily, SfxStyleSearchBits::UserDefined );
144
145
0
        if ( eStyleFamily == SfxStyleFamily::Para )
146
0
            rDoc.getCellAttributeHelper().CellStyleCreated(rDoc, aNewName);
147
0
    }
148
149
0
    if ( pStyle )
150
0
    {
151
0
        if ( bDelete )
152
0
        {
153
0
            if ( eStyleFamily == SfxStyleFamily::Para )
154
0
                lcl_DocStyleChanged( &rDoc, pStyle, true );      // TRUE: remove usage of style
155
0
            else if ( eStyleFamily == SfxStyleFamily::Page )
156
0
                rDoc.RemovePageStyleInUse( rName );
157
158
            // delete style
159
0
            pStlPool->Remove( pStyle );
160
0
        }
161
0
        else
162
0
        {
163
            // modify style
164
165
0
            const OUString& aNewParent = rData.GetParent();
166
0
            if ( aNewParent != pStyle->GetParent() )
167
0
                pStyle->SetParent( aNewParent );
168
169
0
            SfxItemSet& rStyleSet = pStyle->GetItemSet();
170
0
            const std::optional<SfxItemSet>& pNewSet = rData.GetItems();
171
0
            OSL_ENSURE( pNewSet, "no ItemSet for style" );
172
0
            if (pNewSet)
173
0
                rStyleSet.Set( *pNewSet, false );
174
175
0
            if ( eStyleFamily == SfxStyleFamily::Para )
176
0
            {
177
0
                lcl_DocStyleChanged( &rDoc, pStyle, false );     // cell styles: row heights
178
0
            }
179
0
            else if ( eStyleFamily == SfxStyleFamily::Page )
180
0
            {
181
                // page styles
182
183
0
                if ( bNew && aNewName != rName )
184
0
                    rDoc.RenamePageStyleInUse( rName, aNewName );
185
186
0
                if (pNewSet)
187
0
                    rDoc.ModifyStyleSheet( *pStyle, *pNewSet );
188
189
0
                rDocSh.PageStyleModified( aNewName, true );
190
0
            }
191
0
            else
192
0
                static_cast<SfxStyleSheet*>(pStyle)->Broadcast(SfxHint(SfxHintId::DataChanged));
193
0
        }
194
0
    }
195
196
0
    rDocSh.PostPaint( 0,0,0, rDoc.MaxCol(),rDoc.MaxRow(),MAXTAB, PaintPartFlags::Grid|PaintPartFlags::Left );
197
198
    //! undo/redo document modifications for deleted styles
199
    //! undo/redo modifications of number formatter
200
0
}
201
202
void ScUndoModifyStyle::Undo()
203
0
{
204
0
    BeginUndo();
205
0
    DoChange( rDocShell, aNewData.GetName(), eFamily, aOldData );
206
0
    EndUndo();
207
0
}
208
209
void ScUndoModifyStyle::Redo()
210
0
{
211
0
    BeginRedo();
212
0
    DoChange( rDocShell, aOldData.GetName(), eFamily, aNewData );
213
0
    EndRedo();
214
0
}
215
216
void ScUndoModifyStyle::Repeat(SfxRepeatTarget& /* rTarget */)
217
0
{
218
0
}
219
220
bool ScUndoModifyStyle::CanRepeat(SfxRepeatTarget& /* rTarget */) const
221
0
{
222
0
    return false;       // no repeat possible
223
0
}
224
225
//      apply page style
226
227
ScUndoApplyPageStyle::ApplyStyleEntry::ApplyStyleEntry( SCTAB nTab, OUString aOldStyle ) :
228
0
    mnTab( nTab ),
229
0
    maOldStyle(std::move( aOldStyle ))
230
0
{
231
0
}
232
233
ScUndoApplyPageStyle::ScUndoApplyPageStyle( ScDocShell& rDocSh, OUString aNewStyle ) :
234
0
    ScSimpleUndo( rDocSh ),
235
0
    maNewStyle(std::move( aNewStyle ))
236
0
{
237
0
}
238
239
ScUndoApplyPageStyle::~ScUndoApplyPageStyle()
240
0
{
241
0
}
242
243
void ScUndoApplyPageStyle::AddSheetAction( SCTAB nTab, const OUString& rOldStyle )
244
0
{
245
0
    maEntries.emplace_back( nTab, rOldStyle );
246
0
}
247
248
OUString ScUndoApplyPageStyle::GetComment() const
249
0
{
250
0
    return ScResId( STR_UNDO_APPLYPAGESTYLE );
251
0
}
252
253
void ScUndoApplyPageStyle::Undo()
254
0
{
255
0
    BeginUndo();
256
0
    for( const auto& rEntry : maEntries )
257
0
    {
258
0
        rDocShell.GetDocument().SetPageStyle( rEntry.mnTab, rEntry.maOldStyle );
259
0
        ScPrintFunc( rDocShell, rDocShell.GetPrinter(), rEntry.mnTab ).UpdatePages();
260
0
    }
261
0
    EndUndo();
262
0
}
263
264
void ScUndoApplyPageStyle::Redo()
265
0
{
266
0
    BeginRedo();
267
0
    for( const auto& rEntry : maEntries )
268
0
    {
269
0
        rDocShell.GetDocument().SetPageStyle( rEntry.mnTab, maNewStyle );
270
0
        ScPrintFunc( rDocShell, rDocShell.GetPrinter(), rEntry.mnTab ).UpdatePages();
271
0
    }
272
0
    EndRedo();
273
0
}
274
275
void ScUndoApplyPageStyle::Repeat(SfxRepeatTarget& /* rTarget */)
276
0
{
277
    //! set same page style to current tab
278
0
}
279
280
bool ScUndoApplyPageStyle::CanRepeat(SfxRepeatTarget& /* rTarget */) const
281
0
{
282
0
    return false;
283
0
}
284
285
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */