include/sfx2/sfxsids.hrc | 1 include/svl/itemset.hxx | 17 include/svx/dialog/ThemeColorValueSet.hxx | 38 include/svx/dialog/ThemeDialog.hxx | 42 include/svx/theme/IThemeColorChanger.hxx | 26 officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu | 8 svx/Library_svx.mk | 2 svx/UIConfig_svx.mk | 1 svx/sdi/svx.sdi | 17 svx/source/dialog/ThemeColorValueSet.cxx | 98 ++ svx/source/dialog/ThemeDialog.cxx | 64 + svx/uiconfig/ui/themedialog.ui | 127 +++ sw/Library_sw.mk | 1 sw/inc/swtypes.hxx | 6 sw/sdi/_basesh.sdi | 7 sw/source/core/inc/ThemeColorChanger.hxx | 36 sw/source/core/inc/UndoAttribute.hxx | 2 sw/source/core/model/ThemeColorChanger.cxx | 274 ++++++ sw/source/core/undo/unattr.cxx | 21 sw/source/uibase/shells/basesh.cxx | 26 sw/source/uibase/sidebar/ThemePanel.cxx | 421 ---------- sw/source/uibase/sidebar/ThemePanel.hxx | 7 sw/uiconfig/sglobal/menubar/menubar.xml | 1 sw/uiconfig/swriter/menubar/menubar.xml | 1 sw/uiconfig/swriter/ui/sidebartheme.ui | 164 +-- 25 files changed, 874 insertions(+), 534 deletions(-)
New commits: commit 36b9e335fffbad88b956ad4a07d3fdac7fe856ee Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Tue Jan 10 20:21:31 2023 +0900 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Wed Jan 18 12:58:56 2023 +0000 ThemeDialog added which allows to change the theme used by the doc. ThemeDialog is a common dialog that can be used to select the theme used by the document. Currently it only implements colors but in the future also the fonts and formats (for shapes) will be adde. The IThemeColorChanger interface is used by the dialog to change the actual color values inside the document. For the writer the existing ThemeColorChanger is now implementing the interface. The dialog is accessible in Writer at Format -> Theme... in the main menu. Change-Id: I23c7dc9668cdc5427f36d604a76c433d6dbef497 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145264 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> (cherry picked from commit d4e4a2b96a787b4f99d68d7a417c37c97b47c170) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145695 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/include/sfx2/sfxsids.hrc b/include/sfx2/sfxsids.hrc index d202087d95e5..8a6023dd7b4f 100644 --- a/include/sfx2/sfxsids.hrc +++ b/include/sfx2/sfxsids.hrc @@ -452,6 +452,7 @@ class SvxSearchItem; #define SID_ACCESSIBILITY_CHECK (SID_SFX_START + 812) #define SID_ASYNCHRON (SID_SFX_START + 813) #define SID_ACCESSIBILITY_CHECK_ONLINE (SID_SFX_START + 814) +#define SID_THEME_DIALOG (SID_SFX_START + 815) // default-ids for configuration #define SID_CONFIG (SID_SFX_START + 904) diff --git a/include/svx/dialog/ThemeDialog.hxx b/include/svx/dialog/ThemeDialog.hxx new file mode 100644 index 000000000000..968c54af9e98 --- /dev/null +++ b/include/svx/dialog/ThemeDialog.hxx @@ -0,0 +1,42 @@ +/* -*- 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 <svx/svxdllapi.h> +#include <vcl/weld.hxx> +#include <svx/ColorSets.hxx> +#include <svx/svdpage.hxx> +#include <svx/theme/IThemeColorChanger.hxx> +#include <svx/dialog/ThemeColorValueSet.hxx> + +namespace svx +{ +class SVX_DLLPUBLIC ThemeDialog final : public weld::GenericDialogController +{ +private: + svx::Theme* mpTheme; + svx::ColorSets maColorSets; + std::shared_ptr<IThemeColorChanger> mpChanger; + + std::unique_ptr<svx::ThemeColorValueSet> mxValueSetThemeColors; + std::unique_ptr<weld::CustomWeld> mxValueSetThemeColorsWindow; + +public: + ThemeDialog(weld::Window* pParent, svx::Theme* pTheme, + std::shared_ptr<IThemeColorChanger> const& pChanger); + virtual ~ThemeDialog() override; + + DECL_LINK(DoubleClickValueSetHdl, ValueSet*, void); + void DoubleClickHdl(); +}; + +} // end svx namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/svx/theme/IThemeColorChanger.hxx b/include/svx/theme/IThemeColorChanger.hxx new file mode 100644 index 000000000000..5f90f273ee37 --- /dev/null +++ b/include/svx/theme/IThemeColorChanger.hxx @@ -0,0 +1,26 @@ +/* -*- 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 <svx/svxdllapi.h> +#include <svx/ColorSets.hxx> + +namespace svx +{ +class SVX_DLLPUBLIC IThemeColorChanger +{ +public: + virtual ~IThemeColorChanger() = default; + virtual void apply(svx::ColorSet const& rColorSet) = 0; +}; + +} // end svx namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu b/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu index f25abc61048e..2cf8e73d304c 100644 --- a/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu +++ b/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu @@ -7397,6 +7397,14 @@ bit 3 (0x8): #define UICOMMANDDESCRIPTION_PROPERTIES_TOGGLEBUTTON 8 <value>1</value> </prop> </node> + <node oor:name=".uno:ThemeDialog" oor:op="replace"> + <prop oor:name="Label" oor:type="xs:string"> + <value xml:lang="en-US">Theme...</value> + </prop> + <prop oor:name="Properties" oor:type="xs:int"> + <value>1</value> + </prop> + </node> <node oor:name=".uno:SidebarDeck.PropertyDeck" oor:op="replace"> <prop oor:name="Label" oor:type="xs:string"> <value xml:lang="en-US">Open the Properties Deck</value> diff --git a/svx/Library_svx.mk b/svx/Library_svx.mk index 79bc39776e75..0e93d3179f80 100644 --- a/svx/Library_svx.mk +++ b/svx/Library_svx.mk @@ -158,6 +158,7 @@ $(eval $(call gb_Library_add_exception_objects,svx,\ svx/source/dialog/swframeexample \ svx/source/dialog/swframeposstrings \ svx/source/dialog/ThemeColorValueSet \ + svx/source/dialog/ThemeDialog \ svx/source/dialog/txencbox \ svx/source/dialog/txenctab \ svx/source/dialog/weldeditview \ diff --git a/svx/UIConfig_svx.mk b/svx/UIConfig_svx.mk index 33bc1797f20f..9f12a4819b53 100644 --- a/svx/UIConfig_svx.mk +++ b/svx/UIConfig_svx.mk @@ -142,6 +142,7 @@ $(eval $(call gb_UIConfig_add_uifiles,svx,\ svx/uiconfig/ui/textcontrolchardialog \ svx/uiconfig/ui/textcontrolparadialog \ svx/uiconfig/ui/textunderlinecontrol \ + svx/uiconfig/ui/themedialog \ svx/uiconfig/ui/toolbarpopover \ svx/uiconfig/ui/xmlsecstatmenu \ svx/uiconfig/ui/xformspage \ diff --git a/svx/sdi/svx.sdi b/svx/sdi/svx.sdi index 42a43e3fa1ea..0fa54c98eb89 100644 --- a/svx/sdi/svx.sdi +++ b/svx/sdi/svx.sdi @@ -12459,6 +12459,23 @@ SfxVoidItem GraphicSizeCheck SID_GRAPHIC_SIZE_CHECK GroupId = SfxGroupId::Modify; ] +SfxVoidItem ThemeDialog SID_THEME_DIALOG +() +[ + AutoUpdate = FALSE, + FastCall = FALSE, + ReadOnlyDoc = TRUE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + + AccelConfig = FALSE, + MenuConfig = FALSE, + ToolBoxConfig = FALSE, + GroupId = SfxGroupId::Modify; +] + SfxVoidItem AccessibilityCheck SID_ACCESSIBILITY_CHECK () [ diff --git a/svx/source/dialog/ThemeDialog.cxx b/svx/source/dialog/ThemeDialog.cxx new file mode 100644 index 000000000000..4991ca7b4b78 --- /dev/null +++ b/svx/source/dialog/ThemeDialog.cxx @@ -0,0 +1,64 @@ +/* -*- 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 <svx/dialog/ThemeDialog.hxx> +#include <docmodel/theme/ThemeColor.hxx> +#include <vcl/svapp.hxx> +#include <vcl/settings.hxx> + +namespace svx +{ +ThemeDialog::ThemeDialog(weld::Window* pParent, svx::Theme* pTheme, + std::shared_ptr<IThemeColorChanger> const& pChanger) + : GenericDialogController(pParent, "svx/ui/themedialog.ui", "ThemeDialog") + , mpTheme(pTheme) + , mpChanger(pChanger) + , mxValueSetThemeColors(new svx::ThemeColorValueSet) + , mxValueSetThemeColorsWindow( + new weld::CustomWeld(*m_xBuilder, "valueset_theme_colors", *mxValueSetThemeColors)) +{ + mxValueSetThemeColors->SetColCount(2); + mxValueSetThemeColors->SetLineCount(6); + mxValueSetThemeColors->SetColor(Application::GetSettings().GetStyleSettings().GetFaceColor()); + mxValueSetThemeColors->SetDoubleClickHdl(LINK(this, ThemeDialog, DoubleClickValueSetHdl)); + + maColorSets.init(); + maColorSets.insert(*mpTheme->GetColorSet()); + + for (auto const& rColorSet : maColorSets.getColorSets()) + { + mxValueSetThemeColors->insert(rColorSet); + } + + mxValueSetThemeColors->SetOptimalSize(); + + if (!maColorSets.getColorSets().empty()) + mxValueSetThemeColors->SelectItem(1); // ItemId 1, position 0 +} + +ThemeDialog::~ThemeDialog() = default; + +IMPL_LINK_NOARG(ThemeDialog, DoubleClickValueSetHdl, ValueSet*, void) { DoubleClickHdl(); } + +void ThemeDialog::DoubleClickHdl() +{ + sal_uInt32 nItemId = mxValueSetThemeColors->GetSelectedItemId(); + if (!nItemId) + return; + + sal_uInt32 nIndex = nItemId - 1; + + svx::ColorSet const& rColorSet = maColorSets.getColorSet(nIndex); + + mpChanger->apply(rColorSet); +} + +} // end svx namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/uiconfig/ui/themedialog.ui b/svx/uiconfig/ui/themedialog.ui new file mode 100644 index 000000000000..78d226d15ad3 --- /dev/null +++ b/svx/uiconfig/ui/themedialog.ui @@ -0,0 +1,127 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.40.0 --> +<interface domain="svx"> + <requires lib="gtk+" version="3.20"/> + <object class="GtkDialog" id="ThemeDialog"> + <property name="width-request">640</property> + <property name="height-request">480</property> + <property name="can-focus">False</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="border-width">6</property> + <property name="title" translatable="yes" context="themedialog|Title">Theme</property> + <property name="type-hint">dialog</property> + <child internal-child="vbox"> + <object class="GtkBox" id="dialogBox1"> + <property name="can-focus">False</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="orientation">vertical</property> + <property name="spacing">12</property> + <child internal-child="action_area"> + <object class="GtkButtonBox" id="dialogButtons"> + <property name="can-focus">False</property> + <property name="layout-style">end</property> + <child> + <object class="GtkButton" id="help"> + <property name="label" translatable="yes" context="stock">_Help</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="use-underline">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="ok"> + <property name="label" translatable="yes" context="stock">_OK</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="can-default">True</property> + <property name="has-default">True</property> + <property name="receives-default">True</property> + <property name="use-underline">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkButton" id="cancel"> + <property name="label" translatable="yes" context="stock">_Cancel</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="use-underline">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack-type">end</property> + <property name="position">0</property> + </packing> + </child> + <child> + <!-- n-columns=1 n-rows=1 --> + <object class="GtkGrid"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <child> + <object class="GtkScrolledWindow" id="scroll_window"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="hexpand">False</property> + <property name="vexpand">False</property> + <property name="hscrollbar-policy">never</property> + <property name="vscrollbar-policy">never</property> + <property name="shadow-type">in</property> + <child> + <object class="GtkViewport"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <child> + <object class="GtkDrawingArea" id="valueset_theme_colors"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + </object> + </child> + </object> + </child> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">0</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + </object> + </child> + <action-widgets> + <action-widget response="-11">help</action-widget> + <action-widget response="-5">ok</action-widget> + <action-widget response="-6">cancel</action-widget> + </action-widgets> + </object> +</interface> diff --git a/sw/sdi/_basesh.sdi b/sw/sdi/_basesh.sdi index 5ac4cb001eb3..a1468ffac8b1 100644 --- a/sw/sdi/_basesh.sdi +++ b/sw/sdi/_basesh.sdi @@ -617,4 +617,11 @@ interface BaseTextSelection StateMethod = GetState; DisableFlags="SfxDisableFlags::SwOnProtectedCursor"; ] + + SID_THEME_DIALOG + [ + ExecMethod = ExecDlg; + StateMethod = GetState; + DisableFlags="SfxDisableFlags::SwOnProtectedCursor"; + ] } diff --git a/sw/source/core/inc/ThemeColorChanger.hxx b/sw/source/core/inc/ThemeColorChanger.hxx index 0698126da3e9..d4ba7a9fcad5 100644 --- a/sw/source/core/inc/ThemeColorChanger.hxx +++ b/sw/source/core/inc/ThemeColorChanger.hxx @@ -11,10 +11,11 @@ #include <docsh.hxx> #include <svx/ColorSets.hxx> +#include <svx/theme/IThemeColorChanger.hxx> namespace sw { -class ThemeColorChanger +class ThemeColorChanger : public svx::IThemeColorChanger { private: SwDocShell* mpDocSh; @@ -25,7 +26,9 @@ public: { } - void apply(svx::ColorSet const& rColorSet); + virtual ~ThemeColorChanger() override; + + void apply(svx::ColorSet const& rColorSet) override; }; } // end sw namespace diff --git a/sw/source/core/model/ThemeColorChanger.cxx b/sw/source/core/model/ThemeColorChanger.cxx index 7cc88c4cac83..ee0eb9aa37de 100644 --- a/sw/source/core/model/ThemeColorChanger.cxx +++ b/sw/source/core/model/ThemeColorChanger.cxx @@ -230,6 +230,8 @@ void changeColor(SwFormat* pFormat, svx::ColorSet const& rColorSet, SwDoc* pDocu } // end anonymous namespace +ThemeColorChanger::~ThemeColorChanger() {} + void ThemeColorChanger::apply(svx::ColorSet const& rColorSet) { SwDoc* pDocument = mpDocSh->GetDoc(); diff --git a/sw/source/uibase/shells/basesh.cxx b/sw/source/uibase/shells/basesh.cxx index 3591baf3fee9..b05afd9a92e0 100644 --- a/sw/source/uibase/shells/basesh.cxx +++ b/sw/source/uibase/shells/basesh.cxx @@ -79,8 +79,11 @@ #include <strings.hrc> #include <unotxdoc.hxx> #include <doc.hxx> +#include <drawdoc.hxx> #include <IDocumentSettingAccess.hxx> +#include <IDocumentDrawModelAccess.hxx> #include <IDocumentUndoRedo.hxx> +#include <ThemeColorChanger.hxx> #include <swabstdlg.hxx> #include <modcfg.hxx> #include <svx/fmshell.hxx> @@ -93,6 +96,7 @@ #include <memory> #include <svx/unobrushitemhelper.hxx> +#include <svx/dialog/ThemeDialog.hxx> #include <comphelper/scopeguard.hxx> #include <comphelper/lok.hxx> #include <osl/diagnose.h> @@ -2202,6 +2206,10 @@ void SwBaseShell::GetState( SfxItemSet &rSet ) rSet.DisableItem(nWhich); } break; + case SID_THEME_DIALOG: + { + } + break; } nWhich = aIter.NextWhich(); } @@ -3033,6 +3041,24 @@ void SwBaseShell::ExecDlg(SfxRequest &rReq) } break; + case SID_THEME_DIALOG: + { + auto* pDocument = rSh.GetDoc(); + auto* pDocumentShell = pDocument->GetDocShell(); + if (pDocumentShell) + { + SdrPage* pPage = pDocument->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0); + svx::Theme* pTheme = pPage->getSdrPageProperties().GetTheme(); + if (pTheme) + { + std::shared_ptr<svx::IThemeColorChanger> pChanger(new sw::ThemeColorChanger(pDocumentShell)); + auto pDialog = std::make_shared<svx::ThemeDialog>(pMDI, pTheme, pChanger); + weld::DialogController::runAsync(pDialog, [](int) {}); + } + } + } + break; + default:OSL_FAIL("wrong Dispatcher (basesh.cxx)"); } if(!bDone) diff --git a/sw/uiconfig/sglobal/menubar/menubar.xml b/sw/uiconfig/sglobal/menubar/menubar.xml index 21be2c0ce1c5..2b3a47bd8633 100644 --- a/sw/uiconfig/sglobal/menubar/menubar.xml +++ b/sw/uiconfig/sglobal/menubar/menubar.xml @@ -443,6 +443,7 @@ <menu:menuitem menu:id=".uno:FontDialog"/> <menu:menuitem menu:id=".uno:ParagraphDialog"/> <menu:menuitem menu:id=".uno:OutlineBullet"/> + <menu:menuitem menu:id=".uno:ThemeDialog"/> <menu:menuseparator/> <menu:menuitem menu:id=".uno:PageDialog"/> <menu:menuitem menu:id=".uno:TitlePageDialog" menu:style="text"/> diff --git a/sw/uiconfig/swriter/menubar/menubar.xml b/sw/uiconfig/swriter/menubar/menubar.xml index 9b5129e8890d..96406c02ce32 100644 --- a/sw/uiconfig/swriter/menubar/menubar.xml +++ b/sw/uiconfig/swriter/menubar/menubar.xml @@ -454,6 +454,7 @@ </menu:menupopup> </menu:menu> <menu:menuitem menu:id=".uno:OutlineBullet"/> + <menu:menuitem menu:id=".uno:ThemeDialog"/> <menu:menuseparator/> <menu:menuitem menu:id=".uno:PageDialog"/> <menu:menuitem menu:id=".uno:TitlePageDialog"/> commit 9eb7ca0059c912c16c994bda0ca16494a3121c8f Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Fri Jan 6 17:28:49 2023 +0900 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Wed Jan 18 12:58:50 2023 +0000 sw: add ThemeColorChanger that sweeps the model and changes colors The ThemeColorChanger responisiblity is to recalculate and change all the theme colors in the model. This includes styles and direct formatting changes. It uses ModelTraverser for direct formatting changes as it already implements traversing through nodes. The ThemeColorChanger replaces the code to change the colors in ThemePanel. Also modify undo/redo for changing of attributes to not move the cursor and selection when undoing and redoing (new flag NO_CURSOR_CHANGE), as in this case it is very distrcting. Change-Id: Ida1912bd0697307daad9244d474862830ab2686f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145263 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> (cherry picked from commit 1af58b5acec4a2de095d86feef05ac4aed3edb8f) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145694 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/include/svl/itemset.hxx b/include/svl/itemset.hxx index 5ce13bb1f4c8..cf26d10a0e99 100644 --- a/include/svl/itemset.hxx +++ b/include/svl/itemset.hxx @@ -145,6 +145,23 @@ public: bool bSrchInParent = true, const SfxPoolItem **ppItem = nullptr ) const; + template <class T> + SfxItemState GetItemState( TypedWhichId<T> nWhich, + bool bSrchInParent = true, + const T **ppItem = nullptr ) const + { return GetItemState(sal_uInt16(nWhich), bSrchInParent, reinterpret_cast<SfxPoolItem const**>(ppItem)); } + + /// Templatized version of GetItemState() to directly return the correct type. + template<class T> + const T * GetItemIfSet( TypedWhichId<T> nWhich, + bool bSrchInParent = true ) const + { + const SfxPoolItem * pItem = nullptr; + if( SfxItemState::SET == GetItemState(sal_uInt16(nWhich), bSrchInParent, &pItem) ) + return static_cast<const T*>(pItem); + return nullptr; + } + bool HasItem(sal_uInt16 nWhich, const SfxPoolItem** ppItem = nullptr) const; void DisableItem(sal_uInt16 nWhich); diff --git a/sw/Library_sw.mk b/sw/Library_sw.mk index 999c2e7a0419..df31cb18d150 100644 --- a/sw/Library_sw.mk +++ b/sw/Library_sw.mk @@ -359,6 +359,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 d6de8697ab5d..02bd3704f773 100644 --- a/sw/inc/swtypes.hxx +++ b/sw/inc/swtypes.hxx @@ -144,17 +144,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> {}; } constexpr bool SW_ISPRINTABLE(sal_Unicode c) { return c >= ' ' && 127 != c; } 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 ffe4c4f3206d..3ac09d7f9c06 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&, const 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..7cc88c4cac83 --- /dev/null +++ b/sw/source/core/model/ThemeColorChanger.cxx @@ -0,0 +1,272 @@ +/* -*- 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 <pam.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 bb2cdcaa34bb..13977d5479f3 100644 --- a/sw/source/core/undo/unattr.cxx +++ b/sw/source/core/undo/unattr.cxx @@ -776,7 +776,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) @@ -793,10 +794,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()) @@ -832,6 +832,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 86846b50286d..7f2dd73fdbf2 100644 --- a/sw/source/uibase/sidebar/ThemePanel.cxx +++ b/sw/source/uibase/sidebar/ThemePanel.cxx @@ -27,55 +27,16 @@ #include <charfmt.hxx> #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 { @@ -161,7 +122,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*/, commit 424855cc772d9759e1846f2460390eb91f4e7370 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Thu Jan 5 23:58:50 2023 +0900 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Wed Jan 18 12:58:43 2023 +0000 sw: rework ThemePanel, theme color ValueSet drawing as custom draw Rework the ThemePanel to only work with theme colors, as fonts are uing an old mock implemntation of themes. To do this properly it is needed to remove the implementation for now. The theme colors entries were rendered as a bitmap and then shown in the ValueSet. This has the problem that it doesn't look sharp on a HiDPI screen, so replace that with a ThemeColorValueSet, which uses custom draw to render the theme color entries directly. The ThemeColorValueSet was added to th svx component as it will be used in other components as well. Change-Id: I1a727ef4cf4be4e215db57ac33f571f43aaddc15 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145087 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> (cherry picked from commit 8bc22ed6899bcbafc3020f0af6c939019506a5fd) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145693 Tested-by: Tomaž Vajngerl <qui...@gmail.com> diff --git a/include/svx/dialog/ThemeColorValueSet.hxx b/include/svx/dialog/ThemeColorValueSet.hxx new file mode 100644 index 000000000000..4b70ed0f56db --- /dev/null +++ b/include/svx/dialog/ThemeColorValueSet.hxx @@ -0,0 +1,38 @@ +/* -*- 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 <svx/svxdllapi.h> +#include <sal/config.h> +#include <svtools/valueset.hxx> +#include <svx/ColorSets.hxx> + +namespace svx +{ +class SVX_DLLPUBLIC ThemeColorValueSet final : public ValueSet +{ + std::vector<std::reference_wrapper<const svx::ColorSet>> maColorSets; + +public: + ThemeColorValueSet() + : ValueSet(nullptr) + { + } + + void SetDrawingArea(weld::DrawingArea* pDrawingArea) override; + void UserDraw(const UserDrawEvent& rUserDrawEvent) override; + void StyleUpdated() override; + + void insert(svx::ColorSet const& rColorSet); +}; + +} // end svx namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/Library_svx.mk b/svx/Library_svx.mk index 3a54b129ebb9..79bc39776e75 100644 --- a/svx/Library_svx.mk +++ b/svx/Library_svx.mk @@ -157,6 +157,7 @@ $(eval $(call gb_Library_add_exception_objects,svx,\ svx/source/dialog/svxruler \ svx/source/dialog/swframeexample \ svx/source/dialog/swframeposstrings \ + svx/source/dialog/ThemeColorValueSet \ svx/source/dialog/txencbox \ svx/source/dialog/txenctab \ svx/source/dialog/weldeditview \ diff --git a/svx/source/dialog/ThemeColorValueSet.cxx b/svx/source/dialog/ThemeColorValueSet.cxx new file mode 100644 index 000000000000..02297a9eb51e --- /dev/null +++ b/svx/source/dialog/ThemeColorValueSet.cxx @@ -0,0 +1,98 @@ +/* -*- 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 <svx/dialog/ThemeColorValueSet.hxx> +#include <docmodel/uno/UnoThemeColor.hxx> +#include <vcl/event.hxx> + +namespace svx +{ +constexpr tools::Long BORDER = 3; +constexpr tools::Long SIZE = 14; +constexpr tools::Long LABEL_HEIGHT = 16; +constexpr tools::Long LABEL_TEXT_HEIGHT = 14; +constexpr tools::Long constElementNumber = 8; + +void ThemeColorValueSet::insert(svx::ColorSet const& rColorSet) +{ + maColorSets.push_back(std::cref(rColorSet)); + InsertItem(maColorSets.size()); +} + +void ThemeColorValueSet::SetDrawingArea(weld::DrawingArea* pDrawingArea) +{ + ValueSet::SetDrawingArea(pDrawingArea); + SetStyle(WB_TABSTOP | WB_ITEMBORDER | WB_DOUBLEBORDER); + Size aSize(BORDER * 7 + SIZE * 6 + BORDER * 2, BORDER * 3 + SIZE * 2 + LABEL_HEIGHT); + SetItemWidth(aSize.Width()); + SetItemHeight(aSize.Height()); +} + +void ThemeColorValueSet::UserDraw(const UserDrawEvent& rUserDrawEvent) +{ + vcl::RenderContext* pDev = rUserDrawEvent.GetRenderContext(); + tools::Rectangle aRect = rUserDrawEvent.GetRect(); + const Point aPosition = aRect.TopLeft(); + const sal_uInt16 nItemId = rUserDrawEvent.GetItemId(); + svx::ColorSet const& rColorSet = maColorSets[nItemId - 1]; + + Size aSize = aRect.GetSize(); + Size aMin(BORDER * 7 + SIZE * constElementNumber / 2 + BORDER * 2, + BORDER * 3 + SIZE * 2 + LABEL_HEIGHT); + tools::Long startX = (aSize.Width() / 2.0) - (aMin.Width() / 2.0); + tools::Long x = BORDER; + tools::Long y1 = BORDER + LABEL_HEIGHT; + tools::Long y2 = y1 + SIZE + BORDER; + + pDev->SetLineColor(COL_LIGHTGRAY); + pDev->SetFillColor(COL_LIGHTGRAY); + tools::Rectangle aNameRect(aPosition, Size(aSize.Width(), LABEL_HEIGHT)); + pDev->DrawRect(aNameRect); + + vcl::Font aFont; + OUString aName = rColorSet.getName(); + aFont.SetFontHeight(LABEL_TEXT_HEIGHT); + pDev->SetFont(aFont); + + Size aTextSize(pDev->GetTextWidth(aName), pDev->GetTextHeight()); + + Point aPoint(aPosition.X() + (aNameRect.GetWidth() / 2.0) - (aTextSize.Width() / 2.0), + aPosition.Y() + (aNameRect.GetHeight() / 2.0) - (aTextSize.Height() / 2.0)); + + pDev->DrawText(aPoint, aName); + + pDev->SetLineColor(COL_LIGHTGRAY); + pDev->SetFillColor(); + + for (sal_uInt32 i = 2; i < 10; i += 2) + { + pDev->SetFillColor(rColorSet.getColor(model::convertToThemeColorType(i))); + pDev->DrawRect(tools::Rectangle(Point(aPosition.X() + x + startX, aPosition.Y() + y1), + Size(SIZE, SIZE))); + + pDev->SetFillColor(rColorSet.getColor(model::convertToThemeColorType(i + 1))); + pDev->DrawRect(tools::Rectangle(Point(aPosition.X() + x + startX, aPosition.Y() + y2), + Size(SIZE, SIZE))); + + x += SIZE + BORDER; + if (i == 2 || i == 8) + x += BORDER; + } +} + +void ThemeColorValueSet::StyleUpdated() +{ + SetFormat(); + Invalidate(); + ValueSet::StyleUpdated(); +} + +} // end svx namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/uibase/sidebar/ThemePanel.cxx b/sw/source/uibase/sidebar/ThemePanel.cxx index e6a7f339cc2c..86846b50286d 100644 --- a/sw/source/uibase/sidebar/ThemePanel.cxx +++ b/sw/source/uibase/sidebar/ThemePanel.cxx @@ -8,6 +8,7 @@ * */ +#include "ThemePanel.hxx" #include <sal/config.h> #include "ThemePanel.hxx" @@ -24,202 +25,29 @@ #include <vcl/virdev.hxx> #include <charatr.hxx> #include <charfmt.hxx> +#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 <svx/ColorSets.hxx> -#include <doc.hxx> +#include <charatr.hxx> #include <IDocumentDrawModelAccess.hxx> +#include <vcl/settings.hxx> +#include <vcl/svapp.hxx> #include <svx/svdpage.hxx> -#include <drawdoc.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 { -class FontSet -{ -public: - OUString maName; - OUString msMonoFont; - OUString msHeadingFont; - OUString msBaseFont; -}; - -class ColorVariable -{ -public: - tools::Long mnIndex; - sal_Int16 mnTintShade; - - ColorVariable() - : mnIndex(-1) - , mnTintShade() - {} - - ColorVariable(tools::Long nIndex, sal_Int16 nTintShade) - : mnIndex(nIndex) - , mnTintShade(nTintShade) - {} -}; - -class StyleRedefinition -{ - ColorVariable maVariable; - -public: - OUString maElementName; - -public: - explicit StyleRedefinition(const OUString& aElementName) - : maElementName(aElementName) - {} - - void setColorVariable(ColorVariable aVariable) - { - maVariable = aVariable; - } -}; - -class StyleSet -{ - std::vector<StyleRedefinition> maStyles; - -public: - explicit StyleSet() - {} - - void add(StyleRedefinition const & aRedefinition) - { - maStyles.push_back(aRedefinition); - } - - StyleRedefinition* get(std::u16string_view aString) - { - for (StyleRedefinition & rStyle : maStyles) - { - if (rStyle.maElementName == aString) - { - return &rStyle; - } - } - return nullptr; - } -}; - -StyleSet setupThemes() -{ - StyleSet aSet; - - { - StyleRedefinition aRedefinition("Heading 1"); - aRedefinition.setColorVariable(ColorVariable(10, -1000)); - aSet.add(aRedefinition); - } - - { - StyleRedefinition aRedefinition("Heading 2"); - aRedefinition.setColorVariable(ColorVariable(7, -500)); - aSet.add(aRedefinition); - } - - { - StyleRedefinition aRedefinition("Heading 3"); - aRedefinition.setColorVariable(ColorVariable(5, 0)); - aSet.add(aRedefinition); - } - - { - StyleRedefinition aRedefinition("Heading 4"); - aRedefinition.setColorVariable(ColorVariable(6, -1000)); - aSet.add(aRedefinition); - } - - { - StyleRedefinition aRedefinition("Heading 5"); - aRedefinition.setColorVariable(ColorVariable(4, -1500)); - aSet.add(aRedefinition); - } - - { - StyleRedefinition aRedefinition("Heading 6"); - aRedefinition.setColorVariable(ColorVariable(3, -2500)); - aSet.add(aRedefinition); - } - - { - StyleRedefinition aRedefinition("Heading 7"); - aRedefinition.setColorVariable(ColorVariable(3, -2500)); - aSet.add(aRedefinition); - } - - { - StyleRedefinition aRedefinition("Heading 8"); - aRedefinition.setColorVariable(ColorVariable(2, 0)); - aSet.add(aRedefinition); - } - - { - StyleRedefinition aRedefinition("Heading 9"); - aRedefinition.setColorVariable(ColorVariable(2, 0)); - aSet.add(aRedefinition); - } - - { - StyleRedefinition aRedefinition("Heading 10"); - aRedefinition.setColorVariable(ColorVariable(0, 0)); - aSet.add(aRedefinition); - } - - return aSet; -} - -void changeFont(SwFormat* pFormat, SwDocStyleSheet const * pStyle, FontSet const & rFontSet) -{ - if (pStyle->GetName() != "Default Style" && pFormat->GetAttrSet().GetItem(RES_CHRATR_FONT, false) == nullptr) - { - return; - } - - SvxFontItem aFontItem(pFormat->GetFont(false)); - - FontPitch ePitch = aFontItem.GetPitch(); - - if (ePitch == PITCH_FIXED) - { - aFontItem.SetFamilyName(rFontSet.msMonoFont); - } - else - { - if (pStyle->GetName() == "Heading") - { - aFontItem.SetFamilyName(rFontSet.msHeadingFont); - } - else - { - aFontItem.SetFamilyName(rFontSet.msBaseFont); - } - } - - pFormat->SetFormatAttr(aFontItem); -} - -/*void changeBorder(SwTextFormatColl* pCollection, SwDocStyleSheet* pStyle, StyleSet& rStyleSet) -{ - if (pStyle->GetName() == "Heading") - { - SvxBoxItem aBoxItem(pCollection->GetBox()); - editeng::SvxBorderLine aBorderLine; - aBorderLine.SetWidth(40); //20 = 1pt - aBorderLine.SetColor(rColorSet.mBaseColors[0]); - aBoxItem.SetLine(&aBorderLine, SvxBoxItemLine::BOTTOM); - - pCollection->SetFormatAttr(aBoxItem); - } -}*/ - -void changeColor(SwTextFormatColl* pCollection, svx::ColorSet const& rColorSet, StyleRedefinition* /*pRedefinition*/) +void changeColor(SwTextFormatColl* pCollection, svx::ColorSet const& rColorSet) { SvxColorItem aColorItem(pCollection->GetColor()); model::ThemeColor const& rThemeColor = aColorItem.GetThemeColor(); @@ -233,189 +61,23 @@ void changeColor(SwTextFormatColl* pCollection, svx::ColorSet const& rColorSet, } } -std::vector<FontSet> initFontSets() -{ - std::vector<FontSet> aFontSets; - { - FontSet aFontSet; - aFontSet.maName = "Liberation Family"; - aFontSet.msHeadingFont = "Liberation Sans"; - aFontSet.msBaseFont = "Liberation Serif"; - aFontSet.msMonoFont = "Liberation Mono"; - aFontSets.push_back(aFontSet); - } - { - FontSet aFontSet; - aFontSet.maName = "DejaVu Family"; - aFontSet.msHeadingFont = "DejaVu Sans"; - aFontSet.msBaseFont = "DejaVu Serif"; - aFontSet.msMonoFont = "DejaVu Sans Mono"; - aFontSets.push_back(aFontSet); - } - { - FontSet aFontSet; - aFontSet.maName = "Croscore Modern"; - aFontSet.msHeadingFont = "Caladea"; - aFontSet.msBaseFont = "Carlito"; - aFontSet.msMonoFont = "Liberation Mono"; - aFontSets.push_back(aFontSet); - } - { - FontSet aFontSet; - aFontSet.maName = "Carlito"; - aFontSet.msHeadingFont = "Carlito"; - aFontSet.msBaseFont = "Carlito"; - aFontSet.msMonoFont = "Liberation Mono"; - aFontSets.push_back(aFontSet); - } - { - FontSet aFontSet; - aFontSet.maName = "Source Sans Family"; - aFontSet.msHeadingFont = "Source Sans Pro"; - aFontSet.msBaseFont = "Source Sans Pro"; - aFontSet.msMonoFont = "Source Code Pro"; - aFontSets.push_back(aFontSet); - } - { - FontSet aFontSet; - aFontSet.maName = "Source Sans Family 2"; - aFontSet.msHeadingFont = "Source Sans Pro"; - aFontSet.msBaseFont = "Source Sans Pro Light"; - aFontSet.msMonoFont = "Source Code Pro"; - aFontSets.push_back(aFontSet); - } - { - FontSet aFontSet; - aFontSet.maName = "Libertine Family"; - aFontSet.msHeadingFont = "Linux Biolinum G"; - aFontSet.msBaseFont = "Linux Libertine G"; - aFontSet.msMonoFont = "Liberation Mono"; - aFontSets.push_back(aFontSet); - } - { - FontSet aFontSet; - aFontSet.maName = "Open Sans"; - aFontSet.msHeadingFont = "Open Sans"; - aFontSet.msBaseFont = "Open Sans"; - aFontSet.msMonoFont = "Droid Sans Mono"; - aFontSets.push_back(aFontSet); - } - { - FontSet aFontSet; - aFontSet.maName = "Droid Sans"; - aFontSet.msHeadingFont = "Droid Sans"; - aFontSet.msBaseFont = "Droid Sans"; - aFontSet.msMonoFont = "Droid Sans Mono"; - aFontSets.push_back(aFontSet); - } - return aFontSets; -} - -FontSet getFontSet(std::u16string_view rFontVariant, std::vector<FontSet>& aFontSets) -{ - for (const FontSet & rFontSet : aFontSets) - { - if (rFontSet.maName == rFontVariant) - return rFontSet; - } - return aFontSets[0]; -} - -void applyTheme(SfxStyleSheetBasePool* pPool, std::u16string_view sFontSetName, std::u16string_view sColorSetName, - StyleSet& rStyleSet, svx::ColorSets& rColorSets) +void applyTheme(SfxStyleSheetBasePool* pPool, svx::ColorSet const& rColorSet) { SwDocStyleSheet* pStyle; - std::vector<FontSet> aFontSets = initFontSets(); - FontSet aFontSet = getFontSet(sFontSetName, aFontSets); - - svx::ColorSet aColorSet = rColorSets.getColorSet(sColorSetName); - pStyle = static_cast<SwDocStyleSheet*>(pPool->First(SfxStyleFamily::Para)); while (pStyle) { SwTextFormatColl* pCollection = pStyle->GetCollection(); - - changeFont(pCollection, pStyle, aFontSet); - - StyleRedefinition* pRedefinition = rStyleSet.get(pStyle->GetName()); - - if (pRedefinition) - { - changeColor(pCollection, aColorSet, pRedefinition); - } - - pStyle = static_cast<SwDocStyleSheet*>(pPool->Next()); - } - - pStyle = static_cast<SwDocStyleSheet*>(pPool->First(SfxStyleFamily::Char)); - while (pStyle) - { - SwCharFormat* pCharFormat = pStyle->GetCharFormat(); - - changeFont(static_cast<SwFormat*>(pCharFormat), pStyle, aFontSet); - + changeColor(pCollection, rColorSet); pStyle = static_cast<SwDocStyleSheet*>(pPool->Next()); } } -BitmapEx GenerateColorPreview(const svx::ColorSet& rColorSet) -{ - ScopedVclPtrInstance<VirtualDevice> pVirtualDev(*Application::GetDefaultDevice()); - float fScaleFactor = pVirtualDev->GetDPIScaleFactor(); - tools::Long BORDER = 3 * fScaleFactor; - tools::Long SIZE = 14 * fScaleFactor; - tools::Long LABEL_HEIGHT = 16 * fScaleFactor; - tools::Long LABEL_TEXT_HEIGHT = 14 * fScaleFactor; - - Size aSize(BORDER * 7 + SIZE * 6 + BORDER * 2, BORDER * 3 + SIZE * 2 + LABEL_HEIGHT); - pVirtualDev->SetOutputSizePixel(aSize); - pVirtualDev->SetBackground(Wallpaper(Application::GetSettings().GetStyleSettings().GetFaceColor())); - pVirtualDev->Erase(); - - tools::Long x = BORDER; - tools::Long y1 = BORDER + LABEL_HEIGHT; - tools::Long y2 = y1 + SIZE + BORDER; - - pVirtualDev->SetLineColor(COL_LIGHTGRAY); - pVirtualDev->SetFillColor(COL_LIGHTGRAY); - tools::Rectangle aNameRect(Point(0, 0), Size(aSize.Width(), LABEL_HEIGHT)); - pVirtualDev->DrawRect(aNameRect); - - vcl::Font aFont; - OUString aName = rColorSet.getName(); - aFont.SetFontHeight(LABEL_TEXT_HEIGHT); - pVirtualDev->SetFont(aFont); - - Size aTextSize(pVirtualDev->GetTextWidth(aName), pVirtualDev->GetTextHeight()); - - Point aPoint((aNameRect.GetWidth() / 2.0) - (aTextSize.Width() / 2.0), - (aNameRect.GetHeight() / 2.0) - (aTextSize.Height() / 2.0)); - - pVirtualDev->DrawText(aPoint, aName); - - pVirtualDev->SetLineColor(COL_LIGHTGRAY); - pVirtualDev->SetFillColor(); - - for (sal_uInt32 i = 0; i < 12; i += 2) - { - pVirtualDev->SetFillColor(rColorSet.getColor(model::convertToThemeColorType(i))); - pVirtualDev->DrawRect(tools::Rectangle(x, y1, x + SIZE, y1 + SIZE)); - - pVirtualDev->SetFillColor(rColorSet.getColor(model::convertToThemeColorType(i + 1))); - pVirtualDev->DrawRect(tools::Rectangle(x, y2, x + SIZE, y2 + SIZE)); - - x += SIZE + BORDER; - if (i == 2 || i == 8) - x += BORDER; - } - - return pVirtualDev->GetBitmapEx(Point(), aSize); -} - } // end anonymous namespace -namespace sw::sidebar { +namespace sw::sidebar +{ std::unique_ptr<PanelLayout> ThemePanel::Create(weld::Widget* pParent) { @@ -427,8 +89,7 @@ std::unique_ptr<PanelLayout> ThemePanel::Create(weld::Widget* pParent) ThemePanel::ThemePanel(weld::Widget* pParent) : PanelLayout(pParent, "ThemePanel", "modules/swriter/ui/sidebartheme.ui") - , mxListBoxFonts(m_xBuilder->weld_tree_view("listbox_fonts")) - , mxValueSetColors(new ValueSet(nullptr)) + , mxValueSetColors(new svx::ThemeColorValueSet) , mxValueSetColorsWin(new weld::CustomWeld(*m_xBuilder, "valueset_colors", *mxValueSetColors)) , mxApplyButton(m_xBuilder->weld_button("apply")) { @@ -437,14 +98,8 @@ ThemePanel::ThemePanel(weld::Widget* pParent) mxValueSetColors->SetColor(Application::GetSettings().GetStyleSettings().GetFaceColor()); mxApplyButton->connect_clicked(LINK(this, ThemePanel, ClickHdl)); - mxListBoxFonts->connect_row_activated(LINK(this, ThemePanel, DoubleClickHdl)); mxValueSetColors->SetDoubleClickHdl(LINK(this, ThemePanel, DoubleClickValueSetHdl)); - std::vector<FontSet> aFontSets = initFontSets(); - for (const FontSet & rFontSet : aFontSets) - mxListBoxFonts->append_text(rFontSet.maName); - mxListBoxFonts->set_size_request(-1, mxListBoxFonts->get_height_rows(aFontSets.size())); - maColorSets.init(); SwDocShell* pDocSh = static_cast<SwDocShell*>(SfxObjectShell::Current()); @@ -461,12 +116,7 @@ ThemePanel::ThemePanel(weld::Widget* pParent) for (size_t i = 0; i < aColorSets.size(); ++i) { const svx::ColorSet& rColorSet = aColorSets[i]; - - const OUString& aName = rColorSet.getName(); - BitmapEx aPreview = GenerateColorPreview(rColorSet); - - sal_uInt16 nId = i + 1; - mxValueSetColors->InsertItem(nId, Image(aPreview), aName); + mxValueSetColors->insert(rColorSet); } mxValueSetColors->SetOptimalSize(); @@ -477,7 +127,6 @@ ThemePanel::ThemePanel(weld::Widget* pParent) ThemePanel::~ThemePanel() { - mxListBoxFonts.reset(); mxValueSetColorsWin.reset(); mxValueSetColors.reset(); mxApplyButton.reset(); @@ -508,13 +157,11 @@ void ThemePanel::DoubleClickHdl() sal_uInt32 nItemId = mxValueSetColors->GetSelectedItemId(); if (!nItemId) return; - OUString sEntryFonts = mxListBoxFonts->get_selected_text(); sal_uInt32 nIndex = nItemId - 1; - OUString sEntryColors = maColorSets.getColorSet(nIndex).getName(); - StyleSet aStyleSet = setupThemes(); + svx::ColorSet const& rColorSet = maColorSets.getColorSet(nIndex); - applyTheme(pDocSh->GetStyleSheetPool(), sEntryFonts, sEntryColors, aStyleSet, maColorSets); + applyTheme(pDocSh->GetStyleSheetPool(), rColorSet); } void ThemePanel::NotifyItemUpdate(const sal_uInt16 /*nSId*/, diff --git a/sw/source/uibase/sidebar/ThemePanel.hxx b/sw/source/uibase/sidebar/ThemePanel.hxx index 14af479e664a..848d022ee0c6 100644 --- a/sw/source/uibase/sidebar/ThemePanel.hxx +++ b/sw/source/uibase/sidebar/ThemePanel.hxx @@ -15,7 +15,10 @@ #include <svtools/valueset.hxx> #include <svx/ColorSets.hxx> -namespace sw::sidebar { +namespace svx { class ThemeColorValueSet; } + +namespace sw::sidebar +{ class ThemePanel : public PanelLayout, public sfx2::sidebar::ControllerItem::ItemUpdateReceiverInterface @@ -36,7 +39,7 @@ public: private: std::unique_ptr<weld::TreeView> mxListBoxFonts; - std::unique_ptr<ValueSet> mxValueSetColors; + std::unique_ptr<svx::ThemeColorValueSet> mxValueSetColors; std::unique_ptr<weld::CustomWeld> mxValueSetColorsWin; std::unique_ptr<weld::Button> mxApplyButton; diff --git a/sw/uiconfig/swriter/ui/sidebartheme.ui b/sw/uiconfig/swriter/ui/sidebartheme.ui index fd436e149e43..4af29d4d7b64 100644 --- a/sw/uiconfig/swriter/ui/sidebartheme.ui +++ b/sw/uiconfig/swriter/ui/sidebartheme.ui @@ -1,144 +1,68 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.22.1 --> +<!-- Generated with glade 3.40.0 --> <interface domain="sw"> <requires lib="gtk+" version="3.20"/> - <object class="GtkTreeStore" id="liststore1"> - <columns> - <!-- column-name text --> - <column type="gchararray"/> - <!-- column-name id --> - <column type="gchararray"/> - </columns> - </object> - <!-- n-columns=1 n-rows=1 --> + <!-- n-columns=1 n-rows=3 --> <object class="GtkGrid" id="ThemePanel"> <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="row_spacing">6</property> - <property name="column_spacing">6</property> + <property name="can-focus">True</property> + <property name="row-spacing">6</property> + <property name="column-spacing">6</property> <child> - <!-- n-columns=1 n-rows=1 --> - <object class="GtkGrid" id="grid1"> + <object class="GtkLabel" id="label2"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="sidebartheme|label2">Colors</property> + <property name="use-underline">True</property> + <property name="mnemonic-widget">valueset_colors</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="apply"> + <property name="label" translatable="yes" context="stock">_Apply</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="use-underline">True</property> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">2</property> + </packing> + </child> + <child> + <object class="GtkScrolledWindow" id="valuesetwin"> + <property name="visible">True</property> + <property name="can-focus">True</property> <property name="hexpand">True</property> <property name="vexpand">True</property> - <property name="row_spacing">6</property> - <property name="column_spacing">6</property> - <child> - <object class="GtkLabel" id="label1"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes" context="sidebartheme|label1">Fonts</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">listbox_fonts</property> - <property name="xalign">0</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">0</property> - </packing> - </child> + <property name="hscrollbar-policy">never</property> + <property name="vscrollbar-policy">never</property> + <property name="shadow-type">in</property> <child> - <object class="GtkScrolledWindow"> + <object class="GtkViewport"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hexpand">True</property> - <property name="vexpand">True</property> - <property name="shadow_type">in</property> + <property name="can-focus">False</property> <child> - <object class="GtkTreeView" id="listbox_fonts"> + <object class="GtkDrawingArea" id="valueset_colors"> <property name="visible">True</property> - <property name="can_focus">True</property> + <property name="can-focus">True</property> + <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property> <property name="hexpand">True</property> <property name="vexpand">True</property> - <property name="model">liststore1</property> - <property name="headers_visible">False</property> - <property name="headers_clickable">False</property> - <property name="search_column">0</property> - <property name="show_expanders">False</property> - <child internal-child="selection"> - <object class="GtkTreeSelection"/> - </child> - <child> - <object class="GtkTreeViewColumn" id="treeviewcolumn1"> - <child> - <object class="GtkCellRendererText" id="cellrenderertext1"/> - <attributes> - <attribute name="text">0</attribute> - </attributes> - </child> - </object> - </child> - </object> - </child> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label2"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes" context="sidebartheme|label2">Colors</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">valueset_colors</property> - <property name="xalign">0</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">2</property> - </packing> - </child> - <child> - <object class="GtkButton" id="apply"> - <property name="label" translatable="yes" context="stock">_Apply</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="use-underline">True</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">4</property> - </packing> - </child> - <child> - <object class="GtkScrolledWindow" id="valuesetwin"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hexpand">True</property> - <property name="vexpand">True</property> - <property name="hscrollbar_policy">never</property> - <property name="vscrollbar_policy">never</property> - <property name="shadow_type">in</property> - <child> - <object class="GtkViewport"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <child> - <object class="GtkDrawingArea" id="valueset_colors"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property> - <property name="hexpand">True</property> - <property name="vexpand">True</property> - </object> - </child> </object> </child> </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">3</property> - </packing> </child> </object> <packing> - <property name="left_attach">0</property> - <property name="top_attach">0</property> + <property name="left-attach">0</property> + <property name="top-attach">1</property> </packing> </child> </object>