LibreOffice Module sw (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#include <ModelTraverser.hxx>
13#include <txtftn.hxx>
14#include <txtfrm.hxx>
15#include <docstyle.hxx>
16#include <drawdoc.hxx>
17#include <ndnotxt.hxx>
18#include <ndtxt.hxx>
19#include <format.hxx>
20#include <charatr.hxx>
23#include <IDocumentUndoRedo.hxx>
24
25#include <sal/config.h>
26#include <svx/svdpage.hxx>
27#include <svx/svditer.hxx>
29#include <editeng/unoprnms.hxx>
30#include <com/sun/star/text/XTextRange.hpp>
31#include <com/sun/star/container/XEnumerationAccess.hpp>
32#include <com/sun/star/container/XEnumeration.hpp>
33#include <com/sun/star/beans/XPropertySet.hpp>
34
35namespace sw
36{
37namespace
38{
46class ThemeColorHandler : public sw::ModelTraverseHandler
47{
48 SwDoc& mrDocument;
49 model::ColorSet const& mrColorSet;
50
51public:
52 ThemeColorHandler(SwDoc& rDocument, model::ColorSet const& rColorSet)
53 : mrDocument(rDocument)
54 , mrColorSet(rColorSet)
55 {
56 }
57
59 void updateHints(SwTextNode* pTextNode)
60 {
61 if (!pTextNode->HasHints())
62 return;
63
64 SwpHints& rHints = pTextNode->GetSwpHints();
65 for (size_t i = 0; i < rHints.Count(); ++i)
66 {
67 const SwTextAttr* pTextAttr = rHints.Get(i);
68 if (pTextAttr->Which() == RES_TXTATR_AUTOFMT)
69 {
70 SwFormatAutoFormat const& rAutoFormatPool(pTextAttr->GetAutoFormat());
71 std::shared_ptr<SfxItemSet> pStyleHandle(rAutoFormatPool.GetStyleHandle());
72 if (const SvxColorItem* pItem = pStyleHandle->GetItemIfSet(RES_CHRATR_COLOR))
73 {
74 model::ThemeColor const& rThemeColor = pItem->GetThemeColor();
75 auto eThemeType = rThemeColor.getType();
76 if (eThemeType != model::ThemeColorType::Unknown)
77 {
78 Color aNewColor = mrColorSet.resolveColor(rThemeColor);
79 auto pNew = pItem->Clone();
80 pNew->SetValue(aNewColor);
81
82 SwPaM aPam(*pTextNode, pTextAttr->GetStart(), *pTextNode,
83 pTextAttr->GetAnyEnd());
86 }
87 }
88 }
89 }
90 }
91
92 void handleNode(SwNode* pNode) override
93 {
94 if (!pNode->IsTextNode())
95 return;
96
97 updateHints(pNode->GetTextNode());
98 }
99
100 void handleSdrObject(SdrObject* pObject) override
101 {
102 // update current object
103 svx::theme::updateSdrObject(mrColorSet, pObject);
104
105 // update child objects
106 SdrObjList* pList = pObject->GetSubList();
107 if (pList)
108 {
109 SdrObjListIter aIter(pList, SdrIterMode::DeepWithGroups);
110 while (aIter.IsMore())
111 {
112 svx::theme::updateSdrObject(mrColorSet, aIter.Next());
113 }
114 }
115 }
116};
117
118void changeColor(SwFormat* pFormat, model::ColorSet const& rColorSet, SwDoc* pDocument)
119{
120 const SwAttrSet& rAttrSet = pFormat->GetAttrSet();
121 std::unique_ptr<SfxItemSet> pNewSet = rAttrSet.Clone();
122
123 SvxColorItem aColorItem(rAttrSet.GetColor());
124 model::ThemeColor const& rThemeColor = aColorItem.GetThemeColor();
125 auto eThemeType = rThemeColor.getType();
126 if (eThemeType != model::ThemeColorType::Unknown)
127 {
128 Color aColor = rColorSet.getColor(eThemeType);
129 aColor = rThemeColor.applyTransformations(aColor);
130 aColorItem.SetValue(aColor);
131 pNewSet->Put(aColorItem);
132 pDocument->ChgFormat(*pFormat, *pNewSet);
133 }
134}
135
136} // end anonymous namespace
137
139 : mpDocSh(pDocSh)
140{
141}
142
144
146{
147 SwDoc* pDocument = mpDocSh->GetDoc();
148 if (!pDocument)
149 return;
150
151 pDocument->GetIDocumentUndoRedo().StartUndo(SwUndoId::EMPTY, nullptr);
152
153 SdrPage* pPage = pDocument->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
154 model::Theme* pTheme = pPage->getSdrPageProperties().GetTheme().get();
155 if (pTheme)
156 {
157 pTheme->SetColorSet(std::make_unique<model::ColorSet>(rColorSet));
158 }
159 else
160 {
161 pPage->getSdrPageProperties().SetTheme(std::make_unique<model::Theme>("Office"));
162 pTheme = pPage->getSdrPageProperties().GetTheme().get();
163 pTheme->SetColorSet(std::make_unique<model::ColorSet>(rColorSet));
164 }
165
167 SwDocStyleSheet* pStyle;
168
169 // Paragraph style color change
170 pStyle = static_cast<SwDocStyleSheet*>(pPool->First(SfxStyleFamily::Para));
171 while (pStyle)
172 {
173 SwTextFormatColl* pTextFormatCollection = pStyle->GetCollection();
174 if (pTextFormatCollection)
175 changeColor(pTextFormatCollection, rColorSet, pDocument);
176 pStyle = static_cast<SwDocStyleSheet*>(pPool->Next());
177 }
178
179 // Character style color change
180 pStyle = static_cast<SwDocStyleSheet*>(pPool->First(SfxStyleFamily::Char));
181 while (pStyle)
182 {
183 SwCharFormat* pCharFormat = pStyle->GetCharFormat();
184 if (pCharFormat)
185 changeColor(pCharFormat, rColorSet, pDocument);
186 pStyle = static_cast<SwDocStyleSheet*>(pPool->Next());
187 }
188
189 // Direct format change
190 auto pHandler = std::make_shared<ThemeColorHandler>(*pDocument, rColorSet);
191 sw::ModelTraverser aModelTraverser(pDocument);
192 aModelTraverser.addNodeHandler(pHandler);
193 aModelTraverser.traverse();
194
195 pDocument->GetIDocumentUndoRedo().EndUndo(SwUndoId::EMPTY, nullptr);
196}
197
198} // end sw namespace
199
200/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual const SwDrawModel * GetDrawModel() const =0
Draw Model and id accessors.
const SdrPage * GetPage(sal_uInt16 nPgNum) const
void SetTheme(std::unique_ptr< model::Theme > pTheme)
std::unique_ptr< model::Theme > const & GetTheme() const
SdrPageProperties & getSdrPageProperties()
SfxStyleSheetBase * First(SfxStyleFamily eFamily, SfxStyleSearchBits eMask=SfxStyleSearchBits::All)
SfxStyleSheetBase * Next()
const SvxColorItem & GetColor(bool=true) const
Definition: charatr.hxx:89
virtual std::unique_ptr< SfxItemSet > Clone(bool bItems=true, SfxItemPool *pToPool=nullptr) const override
Definition: swatrset.cxx:111
Represents the style of a text portion.
Definition: charfmt.hxx:27
virtual SfxStyleSheetBasePool * GetStyleSheetPool() override
For Style PI.
Definition: docsh.cxx:1154
SwDoc * GetDoc()
returns Doc. But be careful!
Definition: docsh.hxx:204
SwCharFormat * GetCharFormat()
Definition: docstyle.cxx:2190
SwTextFormatColl * GetCollection()
Definition: docstyle.cxx:2197
Definition: doc.hxx:195
void ChgFormat(SwFormat &rFormat, const SfxItemSet &rSet)
Definition: docfmt.cxx:1871
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:152
::sw::DocumentContentOperationsManager const & GetDocumentContentOperationsManager() const
Definition: doc.cxx:333
IDocumentDrawModelAccess const & getIDocumentDrawModelAccess() const
Definition: doc.cxx:163
Base class for various Writer styles.
Definition: format.hxx:47
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:136
Base class of the Writer document model elements.
Definition: node.hxx:98
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:903
bool IsTextNode() const
Definition: node.hxx:687
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:187
A wrapper around SfxPoolItem to store the start position of (usually) a text portion,...
Definition: txatbase.hxx:44
sal_Int32 GetAnyEnd() const
end (if available), else start
Definition: txatbase.hxx:161
sal_Int32 GetStart() const
Definition: txatbase.hxx:88
const SwFormatAutoFormat & GetAutoFormat() const
Definition: txatbase.hxx:193
sal_uInt16 Which() const
Definition: txatbase.hxx:116
Represents the style of a paragraph.
Definition: fmtcol.hxx:61
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:112
bool HasHints() const
Definition: ndtxt.hxx:254
SwpHints & GetSwpHints()
getters for SwpHints
Definition: ndtxt.hxx:869
An SwTextAttr container, stores all directly formatted text portions for a text node.
Definition: ndhints.hxx:68
SwTextAttr * Get(size_t nPos) const
Definition: ndhints.hxx:144
size_t Count() const
Definition: ndhints.hxx:142
Color getColor(model::ThemeColorType eType) const
Color resolveColor(model::ThemeColor const &rThemeColor) const
Color applyTransformations(Color const &rColor) const
ThemeColorType getType() const
void SetColorSet(std::unique_ptr< ColorSet > pColorSet)
bool InsertPoolItem(const SwPaM &rRg, const SfxPoolItem &, const SetAttrMode nFlags=SetAttrMode::DEFAULT, SwRootFrame const *pLayout=nullptr, SwTextAttr **ppNewTextAttr=nullptr) override
Insert an attribute.
void addNodeHandler(std::shared_ptr< ModelTraverseHandler > pHandler)
void apply(model::ColorSet const &rColorSet) override
ThemeColorChanger(SwDocShell *pDocSh)
virtual ~ThemeColorChanger() override
EmbeddedObjectRef * pObject
constexpr TypedWhichId< SwFormatAutoFormat > RES_TXTATR_AUTOFMT(50)
constexpr TypedWhichId< SvxColorItem > RES_CHRATR_COLOR(3)
int i
void updateSdrObject(model::ColorSet const &rColorSet, SdrObject *pObject)
Dialog to specify the properties of date form field.
@ NO_CURSOR_CHANGE
don't change the cursor position