cid#1607171 Data race condition
[LibreOffice.git] / sc / source / ui / undo / undostyl.cxx
blob99bfb2f68d62f17ba64c646219e93ab4c7f72baf
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <svl/itemset.hxx>
21 #include <utility>
22 #include <vcl/virdev.hxx>
23 #include <osl/diagnose.h>
25 #include <undostyl.hxx>
26 #include <docsh.hxx>
27 #include <stlpool.hxx>
28 #include <printfun.hxx>
29 #include <scmod.hxx>
30 #include <inputhdl.hxx>
31 #include <globstr.hrc>
32 #include <scresid.hxx>
34 // modify style (cell or page style)
36 ScStyleSaveData::ScStyleSaveData()
40 ScStyleSaveData::ScStyleSaveData( const ScStyleSaveData& rOther ) :
41 aName( rOther.aName ),
42 aParent( rOther.aParent )
44 if (rOther.moItems)
45 moItems.emplace(*rOther.moItems);
48 ScStyleSaveData& ScStyleSaveData::operator=( const ScStyleSaveData& rOther )
50 if (this != &rOther)
52 aName = rOther.aName;
53 aParent = rOther.aParent;
54 if (rOther.moItems)
55 moItems.emplace(*rOther.moItems);
56 else
57 moItems.reset();
59 return *this;
62 void ScStyleSaveData::InitFromStyle( const SfxStyleSheetBase* pSource )
64 if ( pSource )
66 aName = pSource->GetName();
67 aParent = pSource->GetParent();
68 moItems.emplace(const_cast<SfxStyleSheetBase*>(pSource)->GetItemSet());
70 else
72 aName.clear();
73 aParent.clear();
74 moItems.reset();
78 ScUndoModifyStyle::ScUndoModifyStyle( ScDocShell* pDocSh, SfxStyleFamily eFam,
79 const ScStyleSaveData& rOld, const ScStyleSaveData& rNew ) :
80 ScSimpleUndo( pDocSh ),
81 eFamily( eFam ),
82 aOldData( rOld ),
83 aNewData( rNew )
87 ScUndoModifyStyle::~ScUndoModifyStyle()
91 OUString ScUndoModifyStyle::GetComment() const
93 if (eFamily == SfxStyleFamily::Frame)
94 return ScResId(STR_UNDO_EDITGRAPHICSTYLE);
95 if (eFamily == SfxStyleFamily::Page)
96 return ScResId(STR_UNDO_EDITPAGESTYLE);
98 return ScResId(STR_UNDO_EDITCELLSTYLE);
101 static void lcl_DocStyleChanged( ScDocument* pDoc, const SfxStyleSheetBase* pStyle, bool bRemoved )
103 //! move to document or docshell
105 ScopedVclPtrInstance< VirtualDevice > pVDev;
106 Point aLogic = pVDev->LogicToPixel(Point(1000,1000), MapMode(MapUnit::MapTwip));
107 double nPPTX = aLogic.X() / 1000.0;
108 double nPPTY = aLogic.Y() / 1000.0;
109 Fraction aZoom(1,1);
110 pDoc->StyleSheetChanged( pStyle, bRemoved, pVDev, nPPTX, nPPTY, aZoom, aZoom );
112 ScInputHandler* pHdl = ScModule::get()->GetInputHdl();
113 if (pHdl)
114 pHdl->ForgetLastPattern();
117 void ScUndoModifyStyle::DoChange( ScDocShell* pDocSh, const OUString& rName,
118 SfxStyleFamily eStyleFamily, const ScStyleSaveData& rData )
120 ScDocument& rDoc = pDocSh->GetDocument();
121 ScStyleSheetPool* pStlPool = rDoc.GetStyleSheetPool();
122 const OUString& aNewName = rData.GetName();
123 bool bDelete = aNewName.isEmpty(); // no new name -> delete style
124 bool bNew = ( rName.isEmpty() && !bDelete ); // creating new style
126 SfxStyleSheetBase* pStyle = nullptr;
127 if ( !rName.isEmpty() )
129 // find old style to modify
130 pStyle = pStlPool->Find( rName, eStyleFamily );
131 OSL_ENSURE( pStyle, "style not found" );
133 if ( pStyle && !bDelete )
135 // set new name
136 pStyle->SetName( aNewName );
139 else if ( !bDelete )
141 // create style (with new name)
142 pStyle = &pStlPool->Make( aNewName, eStyleFamily, SfxStyleSearchBits::UserDefined );
144 if ( eStyleFamily == SfxStyleFamily::Para )
145 rDoc.getCellAttributeHelper().CellStyleCreated(rDoc, aNewName);
148 if ( pStyle )
150 if ( bDelete )
152 if ( eStyleFamily == SfxStyleFamily::Para )
153 lcl_DocStyleChanged( &rDoc, pStyle, true ); // TRUE: remove usage of style
154 else if ( eStyleFamily == SfxStyleFamily::Page )
155 rDoc.RemovePageStyleInUse( rName );
157 // delete style
158 pStlPool->Remove( pStyle );
160 else
162 // modify style
164 const OUString& aNewParent = rData.GetParent();
165 if ( aNewParent != pStyle->GetParent() )
166 pStyle->SetParent( aNewParent );
168 SfxItemSet& rStyleSet = pStyle->GetItemSet();
169 const std::optional<SfxItemSet>& pNewSet = rData.GetItems();
170 OSL_ENSURE( pNewSet, "no ItemSet for style" );
171 if (pNewSet)
172 rStyleSet.Set( *pNewSet, false );
174 if ( eStyleFamily == SfxStyleFamily::Para )
176 lcl_DocStyleChanged( &rDoc, pStyle, false ); // cell styles: row heights
178 else if ( eStyleFamily == SfxStyleFamily::Page )
180 // page styles
182 if ( bNew && aNewName != rName )
183 rDoc.RenamePageStyleInUse( rName, aNewName );
185 if (pNewSet)
186 rDoc.ModifyStyleSheet( *pStyle, *pNewSet );
188 pDocSh->PageStyleModified( aNewName, true );
190 else
191 static_cast<SfxStyleSheet*>(pStyle)->Broadcast(SfxHint(SfxHintId::DataChanged));
195 pDocSh->PostPaint( 0,0,0, rDoc.MaxCol(),rDoc.MaxRow(),MAXTAB, PaintPartFlags::Grid|PaintPartFlags::Left );
197 //! undo/redo document modifications for deleted styles
198 //! undo/redo modifications of number formatter
201 void ScUndoModifyStyle::Undo()
203 BeginUndo();
204 DoChange( pDocShell, aNewData.GetName(), eFamily, aOldData );
205 EndUndo();
208 void ScUndoModifyStyle::Redo()
210 BeginRedo();
211 DoChange( pDocShell, aOldData.GetName(), eFamily, aNewData );
212 EndRedo();
215 void ScUndoModifyStyle::Repeat(SfxRepeatTarget& /* rTarget */)
219 bool ScUndoModifyStyle::CanRepeat(SfxRepeatTarget& /* rTarget */) const
221 return false; // no repeat possible
224 // apply page style
226 ScUndoApplyPageStyle::ApplyStyleEntry::ApplyStyleEntry( SCTAB nTab, OUString aOldStyle ) :
227 mnTab( nTab ),
228 maOldStyle(std::move( aOldStyle ))
232 ScUndoApplyPageStyle::ScUndoApplyPageStyle( ScDocShell* pDocSh, OUString aNewStyle ) :
233 ScSimpleUndo( pDocSh ),
234 maNewStyle(std::move( aNewStyle ))
238 ScUndoApplyPageStyle::~ScUndoApplyPageStyle()
242 void ScUndoApplyPageStyle::AddSheetAction( SCTAB nTab, const OUString& rOldStyle )
244 maEntries.emplace_back( nTab, rOldStyle );
247 OUString ScUndoApplyPageStyle::GetComment() const
249 return ScResId( STR_UNDO_APPLYPAGESTYLE );
252 void ScUndoApplyPageStyle::Undo()
254 BeginUndo();
255 for( const auto& rEntry : maEntries )
257 pDocShell->GetDocument().SetPageStyle( rEntry.mnTab, rEntry.maOldStyle );
258 ScPrintFunc( pDocShell, pDocShell->GetPrinter(), rEntry.mnTab ).UpdatePages();
260 EndUndo();
263 void ScUndoApplyPageStyle::Redo()
265 BeginRedo();
266 for( const auto& rEntry : maEntries )
268 pDocShell->GetDocument().SetPageStyle( rEntry.mnTab, maNewStyle );
269 ScPrintFunc( pDocShell, pDocShell->GetPrinter(), rEntry.mnTab ).UpdatePages();
271 EndRedo();
274 void ScUndoApplyPageStyle::Repeat(SfxRepeatTarget& /* rTarget */)
276 //! set same page style to current tab
279 bool ScUndoApplyPageStyle::CanRepeat(SfxRepeatTarget& /* rTarget */) const
281 return false;
284 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */