summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw/Library_sw.mk1
-rw-r--r--sw/inc/swtypes.hxx6
-rw-r--r--sw/source/core/inc/ThemeColorChanger.hxx33
-rw-r--r--sw/source/core/inc/UndoAttribute.hxx2
-rw-r--r--sw/source/core/model/ThemeColorChanger.cxx271
-rw-r--r--sw/source/core/undo/unattr.cxx21
-rw-r--r--sw/source/uibase/sidebar/ThemePanel.cxx44
7 files changed, 331 insertions, 47 deletions
diff --git a/sw/Library_sw.mk b/sw/Library_sw.mk
index 478136e50f54..fa2ca1663512 100644
--- a/sw/Library_sw.mk
+++ b/sw/Library_sw.mk
@@ -366,6 +366,7 @@ $(eval $(call gb_Library_add_exception_objects,sw,\
sw/source/core/layout/wsfrm \
sw/source/core/model/ModelTraverser \
sw/source/core/model/SearchResultLocator \
+ sw/source/core/model/ThemeColorChanger \
sw/source/core/objectpositioning/anchoredobjectposition \
sw/source/core/objectpositioning/ascharanchoredobjectposition \
sw/source/core/objectpositioning/environmentofanchoredobject \
diff --git a/sw/inc/swtypes.hxx b/sw/inc/swtypes.hxx
index 96c0fb5008c3..b3cdfa531074 100644
--- a/sw/inc/swtypes.hxx
+++ b/sw/inc/swtypes.hxx
@@ -143,17 +143,19 @@ enum class SetAttrMode
NOHINTADJUST = 0x0008, // No merging of ranges.
NOFORMATATTR = 0x0010, // Do not change into format attribute.
APICALL = 0x0020, // Called from API (all UI related
- // functionality will be disabled).
+ // functionality will be disabled).
/// Force hint expand (only matters for hints with CH_TXTATR).
FORCEHINTEXPAND = 0x0040,
/// The inserted item is a copy -- intended for use in ndtxt.cxx.
IS_COPY = 0x0080,
/// for Undo, translated to SwInsertFlags::NOHINTEXPAND
NOHINTEXPAND = 0x0100,
+ /// don't change the cursor position
+ NO_CURSOR_CHANGE = 0x0200
};
namespace o3tl
{
- template<> struct typed_flags<SetAttrMode> : is_typed_flags<SetAttrMode, 0x1ff> {};
+ template<> struct typed_flags<SetAttrMode> : is_typed_flags<SetAttrMode, 0x3ff> {};
}
namespace sw {
diff --git a/sw/source/core/inc/ThemeColorChanger.hxx b/sw/source/core/inc/ThemeColorChanger.hxx
new file mode 100644
index 000000000000..0698126da3e9
--- /dev/null
+++ b/sw/source/core/inc/ThemeColorChanger.hxx
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+#pragma once
+
+#include <docsh.hxx>
+#include <svx/ColorSets.hxx>
+
+namespace sw
+{
+class ThemeColorChanger
+{
+private:
+ SwDocShell* mpDocSh;
+
+public:
+ ThemeColorChanger(SwDocShell* pDocSh)
+ : mpDocSh(pDocSh)
+ {
+ }
+
+ void apply(svx::ColorSet const& rColorSet);
+};
+
+} // end sw namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/inc/UndoAttribute.hxx b/sw/source/core/inc/UndoAttribute.hxx
index c3cf4925d95a..e3c40b7f0e87 100644
--- a/sw/source/core/inc/UndoAttribute.hxx
+++ b/sw/source/core/inc/UndoAttribute.hxx
@@ -45,7 +45,7 @@ class SwUndoAttr final : public SwUndo, private SwUndRng
OUString m_aChrFormatName;
void RemoveIdx( SwDoc& rDoc );
-
+ void redoAttribute(SwPaM& rPam, sw::UndoRedoContext& rContext);
public:
SwUndoAttr( const SwPaM&, SfxItemSet, const SetAttrMode nFlags );
SwUndoAttr( const SwPaM&, const SfxPoolItem&, const SetAttrMode nFlags );
diff --git a/sw/source/core/model/ThemeColorChanger.cxx b/sw/source/core/model/ThemeColorChanger.cxx
new file mode 100644
index 000000000000..ff59c474748b
--- /dev/null
+++ b/sw/source/core/model/ThemeColorChanger.cxx
@@ -0,0 +1,271 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#include <ThemeColorChanger.hxx>
+#include <ModelTraverser.hxx>
+#include <txtftn.hxx>
+#include <txtfrm.hxx>
+#include <docstyle.hxx>
+#include <drawdoc.hxx>
+#include <ndnotxt.hxx>
+#include <ndtxt.hxx>
+#include <format.hxx>
+#include <charatr.hxx>
+#include <DocumentContentOperationsManager.hxx>
+#include <IDocumentUndoRedo.hxx>
+
+#include <sal/config.h>
+#include <svx/svdpage.hxx>
+#include <svx/svditer.hxx>
+#include <docmodel/uno/UnoThemeColor.hxx>
+#include <editeng/unoprnms.hxx>
+#include <com/sun/star/text/XTextRange.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+namespace sw
+{
+namespace
+{
+/** Handler for ModelTraverser that recalculates and updates the theme colors.
+ *
+ * It checks all the SdrObjects and updates fill, line and text theme colors.
+ * For writer nodes it checks all the text nodes and updates the direct
+ * formatting in all hints.
+ *
+ */
+class ThemeColorHandler : public sw::ModelTraverseHandler
+{
+ SwDoc& mrDocument;
+ svx::ColorSet const& mrColorSet;
+
+public:
+ ThemeColorHandler(SwDoc& rDocument, svx::ColorSet const& rColorSet)
+ : mrDocument(rDocument)
+ , mrColorSet(rColorSet)
+ {
+ }
+
+ /// Updates hints for a text node
+ void updateHints(SwTextNode* pTextNode)
+ {
+ if (!pTextNode->HasHints())
+ return;
+
+ SwpHints& rHints = pTextNode->GetSwpHints();
+ for (size_t i = 0; i < rHints.Count(); ++i)
+ {
+ const SwTextAttr* pTextAttr = rHints.Get(i);
+ if (pTextAttr->Which() == RES_TXTATR_AUTOFMT)
+ {
+ SwFormatAutoFormat const& rAutoFormatPool(pTextAttr->GetAutoFormat());
+ std::shared_ptr<SfxItemSet> pStyleHandle(rAutoFormatPool.GetStyleHandle());
+ if (const SvxColorItem* pItem = pStyleHandle->GetItemIfSet(RES_CHRATR_COLOR))
+ {
+ model::ThemeColor const& rThemeColor = pItem->GetThemeColor();
+ auto eThemeType = rThemeColor.getType();
+ if (eThemeType != model::ThemeColorType::Unknown)
+ {
+ Color aNewColor = mrColorSet.resolveColor(rThemeColor);
+ auto pNew = pItem->Clone();
+ pNew->SetValue(aNewColor);
+
+ SwPaM aPam(*pTextNode, pTextAttr->GetStart(), *pTextNode,
+ pTextAttr->GetAnyEnd());
+ mrDocument.GetDocumentContentOperationsManager().InsertPoolItem(
+ aPam, *pNew, SetAttrMode::APICALL | SetAttrMode::NO_CURSOR_CHANGE);
+ }
+ }
+ }
+ }
+ }
+
+ void handleNode(SwNode* pNode) override
+ {
+ if (!pNode->IsTextNode())
+ return;
+
+ updateHints(pNode->GetTextNode());
+ }
+
+ /// Updates text portion property colors
+ void updateTextPortionColorSet(const uno::Reference<beans::XPropertySet>& xPortion)
+ {
+ if (!xPortion->getPropertySetInfo()->hasPropertyByName(
+ UNO_NAME_EDIT_CHAR_COLOR_THEME_REFERENCE))
+ return;
+
+ uno::Reference<util::XThemeColor> xThemeColor;
+ xPortion->getPropertyValue(UNO_NAME_EDIT_CHAR_COLOR_THEME_REFERENCE) >>= xThemeColor;
+ if (!xThemeColor.is())
+ return;
+
+ model::ThemeColor aThemeColor;
+ model::theme::setFromXThemeColor(aThemeColor, xThemeColor);
+
+ if (aThemeColor.getType() == model::ThemeColorType::Unknown)
+ return;
+
+ Color aColor = mrColorSet.resolveColor(aThemeColor);
+ xPortion->setPropertyValue(UNO_NAME_EDIT_CHAR_COLOR,
+ uno::Any(static_cast<sal_Int32>(aColor)));
+ }
+
+ /// Updates the fill property colors
+ void updateFillColorSet(const uno::Reference<beans::XPropertySet>& xShape)
+ {
+ if (!xShape->getPropertySetInfo()->hasPropertyByName(UNO_NAME_FILLCOLOR_THEME_REFERENCE))
+ return;
+
+ uno::Reference<util::XThemeColor> xThemeColor;
+ xShape->getPropertyValue(UNO_NAME_FILLCOLOR_THEME_REFERENCE) >>= xThemeColor;
+ if (!xThemeColor.is())
+ return;
+
+ model::ThemeColor aThemeColor;
+ model::theme::setFromXThemeColor(aThemeColor, xThemeColor);
+
+ if (aThemeColor.getType() == model::ThemeColorType::Unknown)
+ return;
+
+ Color aColor = mrColorSet.resolveColor(aThemeColor);
+ xShape->setPropertyValue(UNO_NAME_FILLCOLOR, uno::Any(static_cast<sal_Int32>(aColor)));
+ }
+
+ /// Updates the line property colors
+ void updateLineColorSet(const uno::Reference<beans::XPropertySet>& xShape)
+ {
+ if (!xShape->getPropertySetInfo()->hasPropertyByName(UNO_NAME_LINECOLOR_THEME_REFERENCE))
+ return;
+
+ uno::Reference<util::XThemeColor> xThemeColor;
+ xShape->getPropertyValue(UNO_NAME_LINECOLOR_THEME_REFERENCE) >>= xThemeColor;
+ if (!xThemeColor.is())
+ return;
+
+ model::ThemeColor aThemeColor;
+ model::theme::setFromXThemeColor(aThemeColor, xThemeColor);
+
+ if (aThemeColor.getType() == model::ThemeColorType::Unknown)
+ return;
+
+ Color aColor = mrColorSet.resolveColor(aThemeColor);
+ xShape->setPropertyValue(UNO_NAME_LINECOLOR, uno::Any(static_cast<sal_Int32>(aColor)));
+ }
+
+ /// Updates properties of the SdrObject
+ void updateSdrObject(SdrObject* pObject)
+ {
+ uno::Reference<drawing::XShape> xShape = pObject->getUnoShape();
+ uno::Reference<text::XTextRange> xShapeText(xShape, uno::UNO_QUERY);
+ if (xShapeText.is())
+ {
+ // E.g. group shapes have no text.
+ uno::Reference<container::XEnumerationAccess> xText(xShapeText->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParagraphs = xText->createEnumeration();
+ while (xParagraphs->hasMoreElements())
+ {
+ uno::Reference<container::XEnumerationAccess> xParagraph(xParagraphs->nextElement(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xPortions = xParagraph->createEnumeration();
+ while (xPortions->hasMoreElements())
+ {
+ uno::Reference<beans::XPropertySet> xPortion(xPortions->nextElement(),
+ uno::UNO_QUERY);
+ updateTextPortionColorSet(xPortion);
+ }
+ }
+ }
+
+ uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
+ updateFillColorSet(xShapeProps);
+ updateLineColorSet(xShapeProps);
+ }
+
+ void handleSdrObject(SdrObject* pObject) override
+ {
+ // update current object
+ updateSdrObject(pObject);
+
+ // update child objects
+ SdrObjList* pList = pObject->GetSubList();
+ if (pList)
+ {
+ SdrObjListIter aIter(pList, SdrIterMode::DeepWithGroups);
+ while (aIter.IsMore())
+ {
+ updateSdrObject(aIter.Next());
+ }
+ }
+ }
+};
+
+void changeColor(SwFormat* pFormat, svx::ColorSet const& rColorSet, SwDoc* pDocument)
+{
+ const SwAttrSet& rAttrSet = pFormat->GetAttrSet();
+ std::unique_ptr<SfxItemSet> pNewSet = rAttrSet.Clone();
+
+ SvxColorItem aColorItem(rAttrSet.GetColor());
+ model::ThemeColor const& rThemeColor = aColorItem.GetThemeColor();
+ auto eThemeType = rThemeColor.getType();
+ if (eThemeType != model::ThemeColorType::Unknown)
+ {
+ Color aColor = rColorSet.getColor(eThemeType);
+ aColor = rThemeColor.applyTransformations(aColor);
+ aColorItem.SetValue(aColor);
+ pNewSet->Put(aColorItem);
+ pDocument->ChgFormat(*pFormat, *pNewSet);
+ }
+}
+
+} // end anonymous namespace
+
+void ThemeColorChanger::apply(svx::ColorSet const& rColorSet)
+{
+ SwDoc* pDocument = mpDocSh->GetDoc();
+ pDocument->GetIDocumentUndoRedo().StartUndo(SwUndoId::EMPTY, nullptr);
+
+ SfxStyleSheetBasePool* pPool = mpDocSh->GetStyleSheetPool();
+ SwDocStyleSheet* pStyle;
+
+ // Paragraph style color change
+ pStyle = static_cast<SwDocStyleSheet*>(pPool->First(SfxStyleFamily::Para));
+ while (pStyle)
+ {
+ SwTextFormatColl* pTextFormatCollection = pStyle->GetCollection();
+ if (pTextFormatCollection)
+ changeColor(pTextFormatCollection, rColorSet, pDocument);
+ pStyle = static_cast<SwDocStyleSheet*>(pPool->Next());
+ }
+
+ // Character style color change
+ pStyle = static_cast<SwDocStyleSheet*>(pPool->First(SfxStyleFamily::Char));
+ while (pStyle)
+ {
+ SwCharFormat* pCharFormat = pStyle->GetCharFormat();
+ if (pCharFormat)
+ changeColor(pCharFormat, rColorSet, pDocument);
+ pStyle = static_cast<SwDocStyleSheet*>(pPool->Next());
+ }
+
+ // Direct format change
+ auto pHandler = std::make_shared<ThemeColorHandler>(*pDocument, rColorSet);
+ sw::ModelTraverser aModelTraverser(pDocument);
+ aModelTraverser.addNodeHandler(pHandler);
+ aModelTraverser.traverse();
+
+ pDocument->GetIDocumentUndoRedo().EndUndo(SwUndoId::EMPTY, nullptr);
+}
+
+} // end sw namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/undo/unattr.cxx b/sw/source/core/undo/unattr.cxx
index d8dc236c92e2..60df048d22b3 100644
--- a/sw/source/core/undo/unattr.cxx
+++ b/sw/source/core/undo/unattr.cxx
@@ -770,7 +770,8 @@ void SwUndoAttr::UndoImpl(::sw::UndoRedoContext & rContext)
m_pHistory->SetTmpEnd( m_pHistory->Count() );
// set cursor onto Undo area
- AddUndoRedoPaM(rContext);
+ if (!(m_nInsertFlags & SetAttrMode::NO_CURSOR_CHANGE))
+ AddUndoRedoPaM(rContext);
}
void SwUndoAttr::RepeatImpl(::sw::RepeatContext & rContext)
@@ -787,10 +788,9 @@ void SwUndoAttr::RepeatImpl(::sw::RepeatContext & rContext)
}
}
-void SwUndoAttr::RedoImpl(::sw::UndoRedoContext & rContext)
+void SwUndoAttr::redoAttribute(SwPaM& rPam, sw::UndoRedoContext & rContext)
{
SwDoc & rDoc = rContext.GetDoc();
- SwPaM & rPam = AddUndoRedoPaM(rContext);
// Restore pointer to char format from name
if (!m_aChrFormatName.isEmpty())
@@ -826,6 +826,21 @@ void SwUndoAttr::RedoImpl(::sw::UndoRedoContext & rContext)
}
}
+void SwUndoAttr::RedoImpl(sw::UndoRedoContext & rContext)
+{
+ if (m_nInsertFlags & SetAttrMode::NO_CURSOR_CHANGE)
+ {
+ SwPaM aPam(rContext.GetDoc().GetNodes().GetEndOfContent());
+ SetPaM(aPam, false);
+ redoAttribute(aPam, rContext);
+ }
+ else
+ {
+ SwPaM& rPam = AddUndoRedoPaM(rContext);
+ redoAttribute(rPam, rContext);
+ }
+}
+
void SwUndoAttr::RemoveIdx( SwDoc& rDoc )
{
if ( SfxItemState::SET != m_AttrSet.GetItemState( RES_TXTATR_FTN, false ))
diff --git a/sw/source/uibase/sidebar/ThemePanel.cxx b/sw/source/uibase/sidebar/ThemePanel.cxx
index 5c1f9238dc43..76fd5e59870b 100644
--- a/sw/source/uibase/sidebar/ThemePanel.cxx
+++ b/sw/source/uibase/sidebar/ThemePanel.cxx
@@ -13,55 +13,16 @@
#include <doc.hxx>
#include <docsh.hxx>
-#include <docstyle.hxx>
#include <drawdoc.hxx>
-#include <ndnotxt.hxx>
-#include <ndtxt.hxx>
-#include <fmtcol.hxx>
-#include <format.hxx>
-#include <charatr.hxx>
#include <IDocumentDrawModelAccess.hxx>
+#include <ThemeColorChanger.hxx>
#include <vcl/settings.hxx>
#include <vcl/svapp.hxx>
#include <svx/svdpage.hxx>
#include <svx/ColorSets.hxx>
#include <svx/dialog/ThemeColorValueSet.hxx>
-#include <sfx2/objsh.hxx>
-#include <editeng/colritem.hxx>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
-namespace
-{
-
-void changeColor(SwTextFormatColl* pCollection, svx::ColorSet const& rColorSet)
-{
- SvxColorItem aColorItem(pCollection->GetColor());
- model::ThemeColor const& rThemeColor = aColorItem.GetThemeColor();
- auto eThemeType = rThemeColor.getType();
- if (eThemeType != model::ThemeColorType::Unknown)
- {
- Color aColor = rColorSet.getColor(eThemeType);
- aColor = rThemeColor.applyTransformations(aColor);
- aColorItem.SetValue(aColor);
- pCollection->SetFormatAttr(aColorItem);
- }
-}
-
-void applyTheme(SfxStyleSheetBasePool* pPool, svx::ColorSet const& rColorSet)
-{
- SwDocStyleSheet* pStyle;
-
- pStyle = static_cast<SwDocStyleSheet*>(pPool->First(SfxStyleFamily::Para));
- while (pStyle)
- {
- SwTextFormatColl* pCollection = pStyle->GetCollection();
- changeColor(pCollection, rColorSet);
- pStyle = static_cast<SwDocStyleSheet*>(pPool->Next());
- }
-}
-
-} // end anonymous namespace
-
namespace sw::sidebar
{
@@ -147,7 +108,8 @@ void ThemePanel::DoubleClickHdl()
svx::ColorSet const& rColorSet = maColorSets.getColorSet(nIndex);
- applyTheme(pDocSh->GetStyleSheetPool(), rColorSet);
+ ThemeColorChanger aChanger(pDocSh);
+ aChanger.apply(rColorSet);
}
void ThemePanel::NotifyItemUpdate(const sal_uInt16 /*nSId*/,