diff options
author | Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk> | 2015-04-22 12:32:06 +0900 |
---|---|---|
committer | Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk> | 2015-04-22 12:41:15 +0900 |
commit | 7e20c37c4c60d485736261b60089acdc7dc4b886 (patch) | |
tree | 62ee875fb20b325e14a5d910993c92e0100f464e /sw | |
parent | 25d200bf448735f063ce1e3ca9f762d39892eafd (diff) |
Theme panel to change color/fonts of current styles
In a theme panel the user can change / replace the styles font
and colors used in some predefined style elements (for example
Heading). This is "fake" theme support and not the same thing that
MSO uses, but it still can be useful for the users to change the
appearance of the document. This is the initial commit of the work
and will be much extended. Currently it is only available when
experimental mode is enabled.
Change-Id: I8d34ce87d21975ec6020ac45ecaebb0701b63b2a
Diffstat (limited to 'sw')
-rw-r--r-- | sw/Library_sw.mk | 1 | ||||
-rw-r--r-- | sw/UIConfig_swriter.mk | 1 | ||||
-rw-r--r-- | sw/source/uibase/sidebar/SwPanelFactory.cxx | 7 | ||||
-rw-r--r-- | sw/source/uibase/sidebar/ThemePanel.cxx | 476 | ||||
-rw-r--r-- | sw/source/uibase/sidebar/ThemePanel.hxx | 79 | ||||
-rw-r--r-- | sw/uiconfig/swriter/ui/sidebartheme.ui | 94 |
6 files changed, 658 insertions, 0 deletions
diff --git a/sw/Library_sw.mk b/sw/Library_sw.mk index 76ddb5c89f8e..ea8368719f7b 100644 --- a/sw/Library_sw.mk +++ b/sw/Library_sw.mk @@ -682,6 +682,7 @@ $(eval $(call gb_Library_add_exception_objects,sw,\ sw/source/uibase/sidebar/PageColumnControl \ sw/source/uibase/sidebar/PagePropertyPanel \ sw/source/uibase/sidebar/WrapPropertyPanel \ + sw/source/uibase/sidebar/ThemePanel \ sw/source/uibase/sidebar/SwPanelFactory \ sw/source/uibase/smartmenu/stmenu \ sw/source/uibase/table/chartins \ diff --git a/sw/UIConfig_swriter.mk b/sw/UIConfig_swriter.mk index 762d3ffe0c33..9d5c8738d5fa 100644 --- a/sw/UIConfig_swriter.mk +++ b/sw/UIConfig_swriter.mk @@ -206,6 +206,7 @@ $(eval $(call gb_UIConfig_add_uifiles,modules/swriter,\ sw/uiconfig/swriter/ui/sidebarpage \ sw/uiconfig/swriter/ui/sidebarwrap \ sw/uiconfig/swriter/ui/sidebarstylepresets \ + sw/uiconfig/swriter/ui/sidebartheme \ sw/uiconfig/swriter/ui/sortdialog \ sw/uiconfig/swriter/ui/splittable \ sw/uiconfig/swriter/ui/statisticsinfopage \ diff --git a/sw/source/uibase/sidebar/SwPanelFactory.cxx b/sw/source/uibase/sidebar/SwPanelFactory.cxx index e2e04f7a84ed..ea66e3b91ece 100644 --- a/sw/source/uibase/sidebar/SwPanelFactory.cxx +++ b/sw/source/uibase/sidebar/SwPanelFactory.cxx @@ -19,6 +19,7 @@ #include <com/sun/star/ui/XUIElementFactory.hpp> +#include <ThemePanel.hxx> #include <StylePresetsPanel.hxx> #include <PagePropertyPanel.hxx> #include <WrapPropertyPanel.hxx> @@ -160,6 +161,12 @@ Reference<ui::XUIElement> SAL_CALL SwPanelFactory::createUIElement ( xElement = sfx2::sidebar::SidebarPanelBase::Create( rsResourceURL, xFrame, pPanel, ui::LayoutSize(-1,-1,-1)); } + else if (rsResourceURL.endsWith("/ThemePanel")) + { + sw::sidebar::ThemePanel* pPanel = sw::sidebar::ThemePanel::Create(pParentWindow, xFrame, pBindings); + xElement = sfx2::sidebar::SidebarPanelBase::Create( + rsResourceURL, xFrame, pPanel, ui::LayoutSize(-1,-1,-1)); + } return xElement; } diff --git a/sw/source/uibase/sidebar/ThemePanel.cxx b/sw/source/uibase/sidebar/ThemePanel.cxx new file mode 100644 index 000000000000..9f86ff37db03 --- /dev/null +++ b/sw/source/uibase/sidebar/ThemePanel.cxx @@ -0,0 +1,476 @@ +/* -*- 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 <sal/config.h> + +#include "ThemePanel.hxx" + +#include <swtypes.hxx> +#include <cmdid.h> + +#include <svl/intitem.hxx> +#include <svx/svxids.hrc> +#include <svx/dlgutil.hxx> +#include <svx/rulritem.hxx> + +#include <sfx2/sidebar/ControlFactory.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/bindings.hxx> +#include <sfx2/viewsh.hxx> +#include <sfx2/objsh.hxx> + +#include <com/sun/star/frame/XController.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/frame/DocumentTemplates.hpp> +#include <com/sun/star/frame/XDocumentTemplates.hpp> +#include <com/sun/star/document/XUndoManagerSupplier.hpp> + +#include <editeng/fontitem.hxx> +#include <editeng/boxitem.hxx> +#include <editeng/borderline.hxx> +#include "charatr.hxx" +#include "charfmt.hxx" +#include "docstyle.hxx" +#include "fmtcol.hxx" +#include "format.hxx" + +namespace +{ + +class FontSet +{ +public: + OUString maName; + OUString msMonoFont; + OUString msHeadingFont; + OUString msBaseFont; +}; + +class ColorSet +{ +public: + OUString maName; + Color maColors[10]; + + Color getBackgroundColor1() + { + return maColors[0]; + } + Color getTextColor1() + { + return maColors[1]; + } + Color getBackgroundColor2() + { + return maColors[2]; + } + Color getTextColor2() + { + return maColors[3]; + } + Color getAccent1() + { + return maColors[4]; + } + Color getAccent2() + { + return maColors[5]; + } + Color getAccent3() + { + return maColors[6]; + } + Color getAccent4() + { + return maColors[7]; + } + Color getAccent5() + { + return maColors[8]; + } + Color getAccent6() + { + return maColors[9]; + } +}; + +class ColorVariable +{ +public: + long mnIndex; + Color maColor; + + ColorVariable() + {} + + ColorVariable(Color aColor) + : mnIndex(-1) + , maColor(aColor) + {} + + ColorVariable(long nIndex) + : mnIndex(nIndex) + , maColor() + {} + +}; + +class StyleRedefinition +{ + ColorVariable maVariable; + +public: + OUString maElementName; + +public: + StyleRedefinition(OUString aElementName) + : maElementName(aElementName) + {} + + void setColorVariable(ColorVariable aVariable) + { + maVariable = aVariable; + } + + Color getColor(ColorSet& rColorSet) + { + if (maVariable.mnIndex > -1) + { + return rColorSet.maColors[maVariable.mnIndex]; + } + else + { + return maVariable.maColor; + } + } +}; + +class StyleSet +{ + OUString maName; + std::vector<StyleRedefinition> maStyles; + +public: + StyleSet(OUString aName) + : maName(aName) + , maStyles() + {} + + void add(StyleRedefinition aRedefinition) + { + maStyles.push_back(aRedefinition); + } + + StyleRedefinition* get(OUString aString) + { + for (size_t i = 0; i < maStyles.size(); i++) + { + if (maStyles[i].maElementName == aString) + { + return &maStyles[i]; + } + } + return nullptr; + } +}; + +StyleSet setupThemes() +{ + StyleSet aSet("Default"); + + StyleRedefinition aRedefinition("Heading"); + aRedefinition.setColorVariable(ColorVariable(0)); + aSet.add(aRedefinition); + + return aSet; +} + +void changeFont(SwFmt* pFormat, SwDocStyleSheet* pStyle, FontSet& rFontSet) +{ + bool bChanged = false; + + if (pFormat->GetAttrSet().GetItem(RES_CHRATR_FONT, false) == nullptr) + { + return; + } + + SvxFontItem aFontItem(static_cast<const SvxFontItem&>(pFormat->GetFont(false))); + + FontPitch ePitch = aFontItem.GetPitch(); + + if (ePitch == PITCH_FIXED) + { + aFontItem.SetFamilyName(rFontSet.msMonoFont); + bChanged = true; + } + else if (ePitch == PITCH_VARIABLE) + { + if (pStyle->GetName() == "Heading") + { + aFontItem.SetFamilyName(rFontSet.msHeadingFont); + bChanged = true; + } + else + { + aFontItem.SetFamilyName(rFontSet.msBaseFont); + bChanged = true; + } + } + + if (bChanged) + { + pFormat->SetFmtAttr(aFontItem); + } +} + +/*void changeBorder(SwTxtFmtColl* 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->SetFmtAttr(aBoxItem); + } +}*/ + +void changeColor(SwTxtFmtColl* pCollection, ColorSet& rColorSet, StyleRedefinition* pRedefinition) +{ + Color aColor = pRedefinition->getColor(rColorSet); + + SvxColorItem aColorItem(pCollection->GetColor()); + aColorItem.SetValue(aColor); + pCollection->SetFmtAttr(aColorItem); +} + +std::vector<FontSet> initFontSets() +{ + std::vector<FontSet> aFontSets; + { + FontSet aFontSet; + aFontSet.maName = "LibreOffice"; + aFontSet.msHeadingFont = "Liberation Sans"; + aFontSet.msBaseFont = "Liberation Serif"; + aFontSet.msMonoFont = "Liberation Mono"; + aFontSets.push_back(aFontSet); + } + { + FontSet aFontSet; + aFontSet.maName = "LibreOffice 2"; + aFontSet.msHeadingFont = "DejaVu Sans"; + aFontSet.msBaseFont = "DejaVu Serif"; + aFontSet.msMonoFont = "DejaVu Sans Mono"; + aFontSets.push_back(aFontSet); + } + { + FontSet aFontSet; + aFontSet.maName = "LibreOffice Modern"; + aFontSet.msHeadingFont = "Caladea"; + aFontSet.msBaseFont = "Carlito"; + aFontSet.msMonoFont = "Source Code Pro"; + aFontSets.push_back(aFontSet); + } + { + FontSet aFontSet; + aFontSet.maName = "LibreOffice Modern 2"; + aFontSet.msHeadingFont = "Source Sans Pro"; + aFontSet.msBaseFont = "Source Sans Pro"; + aFontSet.msMonoFont = "Source Code Pro"; + aFontSets.push_back(aFontSet); + } + { + FontSet aFontSet; + aFontSet.maName = "LibreOffice 3"; + aFontSet.msHeadingFont = "Linux Biolinum"; + aFontSet.msBaseFont = "Linux Libertine"; + aFontSet.msMonoFont = "Liberation Mono"; + aFontSets.push_back(aFontSet); + } + { + FontSet aFontSet; + aFontSet.maName = "LibreOffice 4"; + aFontSet.msHeadingFont = "OpenSans"; + aFontSet.msBaseFont = "OpenSans"; + aFontSet.msMonoFont = "Liberation Mono"; + aFontSets.push_back(aFontSet); + } + return aFontSets; +} + +FontSet getFontSet(OUString& rFontVariant, std::vector<FontSet>& aFontSets) +{ + for (size_t i = 0; i < aFontSets.size(); ++i) + { + if (aFontSets[i].maName == rFontVariant) + return aFontSets[i]; + } + return aFontSets[0]; +} + +std::vector<ColorSet> initColorSets() +{ + std::vector<ColorSet> aColorSets; + { + ColorSet aColorSet; + aColorSet.maName = "Default"; + aColorSet.maColors[0] = Color(0x00, 0x00, 0x00); + aColorSets.push_back(aColorSet); + } + { + ColorSet aColorSet; + aColorSet.maName = "Red"; + aColorSet.maColors[0] = Color(0xa4, 0x00, 0x00); + aColorSets.push_back(aColorSet); + } + { + ColorSet aColorSet; + aColorSet.maName = "Green"; + aColorSet.maColors[0] = Color(0x00, 0xa4, 0x00); + aColorSets.push_back(aColorSet); + } + { + ColorSet aColorSet; + aColorSet.maName = "Blue"; + aColorSet.maColors[0] = Color(0x00, 0x00, 0xa4); + aColorSets.push_back(aColorSet); + } + + return aColorSets; +} + +ColorSet getColorSet(OUString& rColorVariant, std::vector<ColorSet>& aColorSets) +{ + for (size_t i = 0; i < aColorSets.size(); ++i) + { + if (aColorSets[i].maName == rColorVariant) + return aColorSets[i]; + } + return aColorSets[0]; +} + +void applyTheme(SfxStyleSheetBasePool* pPool, OUString sFontSetName, OUString sColorSetName, StyleSet& rStyleSet) +{ + SwDocStyleSheet* pStyle; + + std::vector<FontSet> aFontSets = initFontSets(); + FontSet aFontSet = getFontSet(sFontSetName, aFontSets); + + std::vector<ColorSet> aColorSets = initColorSets(); + ColorSet aColorSet = getColorSet(sColorSetName, aColorSets); + + pPool->SetSearchMask(SFX_STYLE_FAMILY_PARA, SFXSTYLEBIT_ALL); + pStyle = static_cast<SwDocStyleSheet*>(pPool->First()); + + while (pStyle) + { + SwTxtFmtColl* 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()); + } + + pPool->SetSearchMask(SFX_STYLE_FAMILY_CHAR, SFXSTYLEBIT_ALL); + pStyle = static_cast<SwDocStyleSheet*>(pPool->First()); + + while (pStyle) + { + SwCharFmt* pCharFormat = pStyle->GetCharFmt(); + + changeFont(static_cast<SwFmt*>(pCharFormat), pStyle, aFontSet); + + pStyle = static_cast<SwDocStyleSheet*>(pPool->Next()); + } +} + +} // end anonymous namespace + +namespace sw { namespace sidebar { + +ThemePanel* ThemePanel::Create (vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings) +{ + if (pParent == NULL) + throw css::lang::IllegalArgumentException("no parent Window given to PagePropertyPanel::Create", NULL, 0); + if (!rxFrame.is()) + throw css::lang::IllegalArgumentException("no XFrame given to PagePropertyPanel::Create", NULL, 1); + if (pBindings == NULL) + throw css::lang::IllegalArgumentException("no SfxBindings given to PagePropertyPanel::Create", NULL, 2); + + return new ThemePanel(pParent, rxFrame, pBindings); +} + +ThemePanel::ThemePanel(vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings) + : PanelLayout(pParent, "ThemePanel", "modules/swriter/ui/sidebartheme.ui", rxFrame) + , mpBindings(pBindings) +{ + get(mpListBoxFonts, "listbox_fonts"); + get(mpListBoxColors, "listbox_colors"); + get(mpApplyButton, "apply"); + + mpApplyButton->SetClickHdl(LINK(this, ThemePanel, ClickHdl)); + mpListBoxFonts->SetDoubleClickHdl(LINK(this, ThemePanel, ClickHdl)); + mpListBoxColors->SetDoubleClickHdl(LINK(this, ThemePanel, ClickHdl)); + + std::vector<FontSet> aFontSets = initFontSets(); + for (size_t i = 0; i < aFontSets.size(); ++i) + { + mpListBoxFonts->InsertEntry(aFontSets[i].maName); + } + + std::vector<ColorSet> aColorSets = initColorSets(); + for (size_t i = 0; i < aColorSets.size(); ++i) + { + mpListBoxColors->InsertEntry(aColorSets[i].maName); + } +} + +ThemePanel::~ThemePanel() +{ +} + +IMPL_LINK_NOARG(ThemePanel, ClickHdl) +{ + SwDocShell* pDocSh = static_cast<SwDocShell*>(SfxObjectShell::Current()); + if (pDocSh) + { + OUString sEntryFonts = mpListBoxFonts->GetSelectEntry(); + OUString sEntryColors = mpListBoxColors->GetSelectEntry(); + + StyleSet aStyleSet = setupThemes(); + + applyTheme(pDocSh->GetStyleSheetPool(), sEntryFonts, sEntryColors, aStyleSet); + } + return 1; +} + +void ThemePanel::NotifyItemUpdate(const sal_uInt16 /*nSId*/, + const SfxItemState /*eState*/, + const SfxPoolItem* /*pState*/, + const bool /*bIsEnabled*/) +{ +} + +}} // end of namespace ::sw::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/uibase/sidebar/ThemePanel.hxx b/sw/source/uibase/sidebar/ThemePanel.hxx new file mode 100644 index 000000000000..ed5c19df39f3 --- /dev/null +++ b/sw/source/uibase/sidebar/ThemePanel.hxx @@ -0,0 +1,79 @@ +/* -*- 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/. + * + */ + +#ifndef INCLUDED_SW_SOURCE_UIBASE_SIDEBAR_THEMEPANEL_HXX +#define INCLUDED_SW_SOURCE_UIBASE_SIDEBAR_THEMEPANEL_HXX + +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/document/XUndoManager.hpp> + +#include <svx/sidebar/Popup.hxx> +#include <svx/sidebar/PanelLayout.hxx> + +#include <sfx2/sidebar/ControllerItem.hxx> + +#include <svx/pageitem.hxx> +#include <svx/rulritem.hxx> +#include <editeng/sizeitem.hxx> + +#include <vcl/ctrl.hxx> +#include <vcl/fixed.hxx> +#include <vcl/button.hxx> +#include <vcl/toolbox.hxx> +#include <vcl/lstbox.hxx> +#include <vcl/field.hxx> +#include <svl/intitem.hxx> +#include <svl/lstner.hxx> + +#include <svx/fntctrl.hxx> + +#include "docsh.hxx" + +namespace sw { namespace sidebar { + +class ThemePanel : public PanelLayout, + public sfx2::sidebar::ControllerItem::ItemUpdateReceiverInterface +{ +public: + static ThemePanel* Create(vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings); + + virtual void NotifyItemUpdate(const sal_uInt16 nSId, + const SfxItemState eState, + const SfxPoolItem* pState, + const bool bIsEnabled) SAL_OVERRIDE; + + SfxBindings* GetBindings() const + { + return mpBindings; + } + +private: + ThemePanel(vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings); + + virtual ~ThemePanel(); + + SfxBindings* mpBindings; + + ListBox* mpListBoxFonts; + ListBox* mpListBoxColors; + PushButton* mpApplyButton; + + DECL_LINK(ClickHdl, void*); +}; + +}} // end of namespace sw::sidebar + +#endif // INCLUDED_SW_SOURCE_UIBASE_SIDEBAR_THEMEPANEL_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/uiconfig/swriter/ui/sidebartheme.ui b/sw/uiconfig/swriter/ui/sidebartheme.ui new file mode 100644 index 000000000000..b422773d6e27 --- /dev/null +++ b/sw/uiconfig/swriter/ui/sidebartheme.ui @@ -0,0 +1,94 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.18.3 --> +<interface> + <requires lib="gtk+" version="3.0"/> + <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> + <child> + <object class="GtkAlignment" id="alignment1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkGrid" id="grid1"> + <property name="visible">True</property> + <property name="can_focus">False</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="xalign">0</property> + <property name="label" translatable="yes">Fonts</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkTreeView" id="listbox_fonts"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hexpand">True</property> + <child internal-child="selection"> + <object class="GtkTreeSelection" id="treeview-selection1"/> + </child> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="GtkTreeView" id="listbox_colors"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hexpand">True</property> + <child internal-child="selection"> + <object class="GtkTreeSelection" id="treeview-selection2"/> + </child> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">3</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label2"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Colors</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">gtk-apply</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">4</property> + </packing> + </child> + </object> + </child> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + </object> +</interface> |