LibreOffice Module sc (master) 1
ThemeColorChanger.cxx
Go to the documentation of this file.
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
11#include <ThemeColorChanger.hxx>
12
13#include <sal/config.h>
14
17#include <editeng/colritem.hxx>
18#include <editeng/brushitem.hxx>
19#include <editeng/boxitem.hxx>
21#include <svx/svditer.hxx>
22
23#include <undodraw.hxx>
24#include <stlpool.hxx>
25#include <stlsheet.hxx>
26#include <scitems.hxx>
27#include <scresid.hxx>
28#include <globstr.hrc>
29#include <document.hxx>
30#include <address.hxx>
31#include <dociter.hxx>
32#include <tabvwsh.hxx>
33#include <undostyl.hxx>
34#include <undoblk.hxx>
35
37
38namespace sc
39{
41 : m_rDocShell(rDocShell)
42{
43}
44
46
47namespace
48{
49bool changeBorderLine(editeng::SvxBorderLine* pBorderLine, model::ColorSet const& rColorSet)
50{
51 if (!pBorderLine)
52 return false;
53
54 model::ComplexColor const& rComplexColor = pBorderLine->getComplexColor();
55 if (rComplexColor.meType == model::ColorType::Scheme)
56 {
57 auto eThemeType = rComplexColor.meSchemeType;
58
59 if (eThemeType != model::ThemeColorType::Unknown)
60 {
61 Color aColor = rColorSet.resolveColor(rComplexColor);
62 pBorderLine->SetColor(aColor);
63 return true;
64 }
65 }
66 return false;
67}
68
69bool changeCellItems(SfxItemSet& rItemSet, model::ColorSet const& rColorSet)
70{
71 const SfxPoolItem* pItem = nullptr;
72 bool bChanged = false;
73 if (rItemSet.HasItem(ATTR_FONT_COLOR, &pItem))
74 {
75 auto const* pColorItem = static_cast<const SvxColorItem*>(pItem);
76 model::ComplexColor const& rComplexColor = pColorItem->getComplexColor();
77 if (rComplexColor.meType == model::ColorType::Scheme)
78 {
79 auto eThemeType = rComplexColor.meSchemeType;
80 if (eThemeType != model::ThemeColorType::Unknown)
81 {
82 Color aColor = rColorSet.getColor(eThemeType);
83 aColor = rComplexColor.applyTransformations(aColor);
84
85 SvxColorItem aColorItem(*pColorItem);
86 aColorItem.setColor(aColor);
87 rItemSet.Put(aColorItem);
88 bChanged = true;
89 }
90 }
91 }
92 if (rItemSet.HasItem(ATTR_BACKGROUND, &pItem))
93 {
94 auto const* pBrushItem = static_cast<const SvxBrushItem*>(pItem);
95 model::ComplexColor const& rComplexColor = pBrushItem->getComplexColor();
96 if (rComplexColor.meType == model::ColorType::Scheme)
97 {
98 auto eThemeType = rComplexColor.meSchemeType;
99 if (eThemeType != model::ThemeColorType::Unknown)
100 {
101 Color aColor = rColorSet.getColor(eThemeType);
102 aColor = rComplexColor.applyTransformations(aColor);
103
104 SvxBrushItem aNewBrushItem(*pBrushItem);
105 aNewBrushItem.SetColor(aColor);
106 rItemSet.Put(aNewBrushItem);
107 bChanged = true;
108 }
109 }
110 }
111 if (rItemSet.HasItem(ATTR_BORDER, &pItem))
112 {
113 auto const* pBoxItem = static_cast<const SvxBoxItem*>(pItem);
114 SvxBoxItem rNewItem(*pBoxItem);
115 bool bLineChanged = false;
116
117 bLineChanged = changeBorderLine(rNewItem.GetBottom(), rColorSet) || bChanged;
118 bLineChanged = changeBorderLine(rNewItem.GetTop(), rColorSet) || bChanged;
119 bLineChanged = changeBorderLine(rNewItem.GetLeft(), rColorSet) || bChanged;
120 bLineChanged = changeBorderLine(rNewItem.GetRight(), rColorSet) || bChanged;
121
122 if (bLineChanged)
123 {
124 rItemSet.Put(rNewItem);
125 bChanged = true;
126 }
127 }
128 return bChanged;
129}
130
131bool changeStyles(ScDocShell& rDocShell, std::shared_ptr<model::ColorSet> const& pColorSet)
132{
133 ScDocument& rDocument = rDocShell.GetDocument();
134 ScStyleSheetPool* pPool = rDocument.GetStyleSheetPool();
135 ScStyleSheet* pStyle = nullptr;
136 bool bChanged = false;
137
138 // Paragraph style color change
139 pStyle = static_cast<ScStyleSheet*>(pPool->First(SfxStyleFamily::Para));
140 while (pStyle)
141 {
142 ScStyleSaveData aOldData;
143 aOldData.InitFromStyle(pStyle);
144
145 auto rItemSet = pStyle->GetItemSet();
146 if (changeCellItems(rItemSet, *pColorSet))
147 {
148 if (rDocument.IsUndoEnabled())
149 {
150 ScStyleSaveData aNewData;
151 aNewData.InitFromStyle(pStyle);
152 rDocShell.GetUndoManager()->AddUndoAction(std::make_unique<ScUndoModifyStyle>(
153 &rDocShell, SfxStyleFamily::Para, aOldData, aNewData));
154 }
155 static_cast<SfxStyleSheet*>(pStyle)->Broadcast(SfxHint(SfxHintId::DataChanged));
156 bChanged = true;
157 }
158
159 pStyle = static_cast<ScStyleSheet*>(pPool->Next());
160 }
161
162 return bChanged;
163}
164
165bool changeSheets(ScDocShell& rDocShell, ScDrawLayer* pModel,
166 std::shared_ptr<model::ColorSet> const& pColorSet)
167{
168 ScDocument& rDocument = rDocShell.GetDocument();
169 bool bChanged = false;
170
171 for (SCTAB nTab = 0; nTab < rDocument.GetTableCount(); nTab++)
172 {
173 // Change Cell / Text attributes
174 {
175 ScDocAttrIterator aAttributeIterator(rDocument, nTab, 0, 0, rDocument.MaxCol(),
176 rDocument.MaxRow());
177 SCCOL nCol = 0;
178 SCROW nRow1 = 0;
179 SCROW nRow2 = 0;
180
181 while (const ScPatternAttr* pPattern = aAttributeIterator.GetNext(nCol, nRow1, nRow2))
182 {
183 if (!pPattern || !pPattern->IsVisible())
184 continue;
185
186 ScPatternAttr aNewPattern(*pPattern);
187 auto& rItemSet = aNewPattern.GetItemSet();
188 bool bItemChanged = changeCellItems(rItemSet, *pColorSet);
189 bChanged = bChanged || bItemChanged;
190
191 if (bItemChanged && rDocument.IsUndoEnabled())
192 {
193 ScRange aRange(nCol, nRow1, nTab, nCol, nRow2, nTab);
194 ScMarkData aMark(rDocument.GetSheetLimits());
195 aMark.SetMarkArea(aRange);
196
198 pUndoDoc->InitUndo(rDocument, nTab, nTab);
199 pUndoDoc->AddUndoTab(nTab, nTab);
200
201 aMark.MarkToMulti();
202
203 rDocument.CopyToDocument(aRange, InsertDeleteFlags::ATTRIB, true, *pUndoDoc,
204 &aMark);
205
206 auto pUndo = std::make_unique<ScUndoSelectionAttr>(
207 &rDocShell, aMark, aRange.aStart.Col(), aRange.aStart.Row(),
208 aRange.aStart.Tab(), aRange.aEnd.Col(), aRange.aEnd.Row(),
209 aRange.aEnd.Tab(), std::move(pUndoDoc), true, &aNewPattern);
210
211 ScEditDataArray* pDataArray = pUndo->GetDataArray();
212
213 rDocument.ApplySelectionPattern(aNewPattern, aMark, pDataArray);
214
215 rDocShell.GetUndoManager()->AddUndoAction(std::move(pUndo));
216 }
217 }
218 }
219
220 // Change all SdrObjects
221 {
222 pModel->BeginCalcUndo(true);
223
224 SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
225 SdrObjListIter aIter(pPage, SdrIterMode::DeepNoGroups);
226 SdrObject* pObject = aIter.Next();
227 while (pObject)
228 {
229 svx::theme::updateSdrObject(*pColorSet, pObject);
230 pObject = aIter.Next();
231 }
232
233 std::unique_ptr<SdrUndoGroup> pUndo = pModel->GetCalcUndo();
234
235 if (pUndo)
236 {
237 bChanged = true;
238 pUndo->SetComment("Hi!");
239 auto pUndoDraw = std::make_unique<ScUndoDraw>(std::move(pUndo), &rDocShell);
240 rDocShell.GetUndoManager()->AddUndoAction(std::move(pUndoDraw));
241 }
242 }
243 }
244
245 return bChanged;
246}
247
248void changeTheTheme(ScDocShell& rDocShell, std::shared_ptr<model::ColorSet> const& pColorSet)
249{
250 ScDocument& rDocument = rDocShell.GetDocument();
251 ScDrawLayer* pModel = rDocument.GetDrawLayer();
252 SdrPage* pPage = pModel->GetPage(0);
253
254 auto pTheme = pPage->getSdrPageProperties().GetTheme();
255 if (!pTheme)
256 {
257 pTheme = std::make_shared<model::Theme>("Office");
258 pPage->getSdrPageProperties().SetTheme(pTheme);
259 }
260
261 std::shared_ptr<model::ColorSet> pNewColorSet = pColorSet;
262 std::shared_ptr<model::ColorSet> pOldColorSet = pTheme->getColorSet();
263 pTheme->setColorSet(pNewColorSet);
264
265 if (rDocument.IsUndoEnabled())
266 {
267 auto pUndoThemeChange
268 = std::make_unique<sc::UndoThemeChange>(rDocShell, pOldColorSet, pNewColorSet);
269 rDocShell.GetUndoManager()->AddUndoAction(std::move(pUndoThemeChange));
270 }
271}
272
273} // end anonymous ns
274
275void ThemeColorChanger::apply(std::shared_ptr<model::ColorSet> const& pColorSet)
276{
278
280 ScDocument& rDocument = m_rDocShell.GetDocument();
281 auto pUndoManager = m_rDocShell.GetUndoManager();
282
283 const bool bUndo(rDocument.IsUndoEnabled());
284
285 ViewShellId nViewShellId(-1);
287 nViewShellId = pViewSh->GetViewShellId();
288
289 if (bUndo)
290 {
291 OUString aUndo = ScResId(STR_UNDO_THEME_COLOR_CHANGE);
292 pUndoManager->EnterListAction(aUndo, aUndo, 0, nViewShellId);
293 }
294
295 bool bChanged = false;
296 bChanged = changeStyles(m_rDocShell, pColorSet) || bChanged;
297 bChanged = changeSheets(m_rDocShell, rDocument.GetDrawLayer(), pColorSet) || bChanged;
298
299 changeTheTheme(m_rDocShell, pColorSet);
300
301 if (bUndo)
302 {
303 pUndoManager->LeaveListAction();
304 }
305
307 aModificator.SetDocumentModified();
308}
309
310} // end sw namespace
311
312/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Create before modifications of the document and destroy thereafter.
Definition: docsh.hxx:455
void SetDocumentModified()
Definition: docsh.cxx:3315
const ScDocument & GetDocument() const
Definition: docsh.hxx:219
ScDrawLayer * MakeDrawLayer()
Definition: docsh2.cxx:169
void SetDrawModified()
SetDrawModified - without Formula update.
Definition: docsh.cxx:3046
virtual SfxUndoManager * GetUndoManager() override
Definition: docsh.cxx:2968
ScSheetLimits & GetSheetLimits() const
Definition: document.hxx:898
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:892
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:893
SC_DLLPUBLIC ScDrawLayer * GetDrawLayer()
Definition: document.hxx:1084
SC_DLLPUBLIC void ApplySelectionPattern(const ScPatternAttr &rAttr, const ScMarkData &rMark, ScEditDataArray *pDataArray=nullptr, bool *pIsChanged=nullptr)
Definition: document.cxx:5864
void CopyToDocument(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, InsertDeleteFlags nFlags, bool bMarked, ScDocument &rDestDoc, const ScMarkData *pMarks=nullptr, bool bColRowFlags=true)
Definition: document.cxx:2041
SC_DLLPUBLIC ScStyleSheetPool * GetStyleSheetPool() const
Definition: document.cxx:6055
bool IsUndoEnabled() const
Definition: document.hxx:1595
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:297
void BeginCalcUndo(bool bDisableTextEditUsesCommonUndoManager)
Definition: drwlayer.cxx:1514
std::unique_ptr< SdrUndoGroup > GetCalcUndo()
Definition: drwlayer.cxx:1521
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
Definition: markdata.hxx:43
void InitFromStyle(const SfxStyleSheetBase *pSource)
Definition: undostyl.cxx:63
virtual SC_DLLPUBLIC SfxItemSet & GetItemSet() override
Definition: stlsheet.cxx:133
static ScTabViewShell * GetActiveViewShell()
Definition: tabvwsh4.cxx:1076
const SdrPage * GetPage(sal_uInt16 nPgNum) const
std::shared_ptr< model::Theme > const & GetTheme() const
void SetTheme(std::shared_ptr< model::Theme > const &pTheme)
SdrPageProperties & getSdrPageProperties()
bool HasItem(sal_uInt16 nWhich, const SfxPoolItem **ppItem=nullptr) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
SfxStyleSheetBase * First(SfxStyleFamily eFamily, SfxStyleSearchBits eMask=SfxStyleSearchBits::All)
SfxStyleSheetBase * Next()
virtual void AddUndoAction(std::unique_ptr< SfxUndoAction > pAction, bool bTryMerg=false)
void SetColor(const Color &rColor)
model::ComplexColor const & getComplexColor() const
Color getColor(model::ThemeColorType eType) const
Color resolveColor(model::ComplexColor const &rComplexColor) const
ThemeColorType meSchemeType
Color applyTransformations(Color const &rColor) const
virtual ~ThemeColorChanger() override
void apply(std::shared_ptr< model::ColorSet > const &pColorSet) override
ThemeColorChanger(ScDocShell &rDocShell)
std::unique_ptr< ScDocument, o3tl::default_delete< ScDocument > > ScDocumentUniquePtr
Definition: document.hxx:2720
@ SCDOCMODE_UNDO
Definition: document.hxx:258
EmbeddedObjectRef * pObject
@ ATTRIB
Internal use only (d&d undo): do not delete caption objects of cell notes.
CAUTION! The following defines must be in the same namespace as the respective type.
Definition: broadcast.cxx:15
void updateSdrObject(model::ColorSet const &rColorSet, SdrObject *pObject)
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
constexpr TypedWhichId< SvxColorItem > ATTR_FONT_COLOR(109)
constexpr TypedWhichId< SvxBrushItem > ATTR_BACKGROUND(148)
constexpr TypedWhichId< SvxBoxItem > ATTR_BORDER(150)
sal_Int16 SCTAB
Definition: types.hxx:22
sal_Int16 SCCOL
Definition: types.hxx:21
sal_Int32 SCROW
Definition: types.hxx:17