summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/vcl/customweld.hxx1
-rw-r--r--officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu11
-rw-r--r--officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu8
-rwxr-xr-xsolenv/bin/native-code.py1
-rw-r--r--svx/Library_svxcore.mk2
-rw-r--r--svx/UIConfig_svx.mk1
-rw-r--r--svx/source/inc/StylesPreviewToolBoxControl.hxx72
-rw-r--r--svx/source/inc/StylesPreviewWindow.hxx123
-rw-r--r--svx/source/tbxctrls/StylesPreviewToolBoxControl.cxx184
-rw-r--r--svx/source/tbxctrls/StylesPreviewWindow.cxx504
-rw-r--r--svx/uiconfig/ui/stylespreview.ui142
-rw-r--r--svx/util/svxcore.component4
12 files changed, 1053 insertions, 0 deletions
diff --git a/include/vcl/customweld.hxx b/include/vcl/customweld.hxx
index 85829f35d6ff..3e6835b8f864 100644
--- a/include/vcl/customweld.hxx
+++ b/include/vcl/customweld.hxx
@@ -154,6 +154,7 @@ public:
void set_grid_left_attach(int nAttach) { m_xDrawingArea->set_grid_left_attach(nAttach); }
int get_grid_left_attach() const { return m_xDrawingArea->get_grid_left_attach(); }
void set_help_id(const OString& rHelpId) { m_xDrawingArea->set_help_id(rHelpId); }
+ void set_tooltip_text(const OUString& rTip) { m_xDrawingArea->set_tooltip_text(rTip); }
};
}
#endif
diff --git a/officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu b/officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu
index 48ed82b932aa..c18e2d1fb44a 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu
@@ -1712,6 +1712,17 @@
<value>com.sun.star.comp.svx.StyleToolBoxControl</value>
</prop>
</node>
+ <node oor:name="StylesPreviewToolBox" oor:op="replace">
+ <prop oor:name="Command">
+ <value>.uno:StylesPreview</value>
+ </prop>
+ <prop oor:name="Module">
+ <value/>
+ </prop>
+ <prop oor:name="Controller">
+ <value>com.sun.star.comp.svx.StylesPreviewToolBoxControl</value>
+ </prop>
+ </node>
<node oor:name="OpenToolbarController" oor:op="replace">
<prop oor:name="Command">
<value>.uno:Open</value>
diff --git a/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu b/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu
index 7c4898dfa272..8735fb5eb8a2 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu
@@ -3028,6 +3028,14 @@
<value>1</value>
</prop>
</node>
+ <node oor:name=".uno:StylesPreview" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="en-US">Styles Preview</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
<node oor:name=".uno:AddDateField" oor:op="replace">
<prop oor:name="Label" oor:type="xs:string">
<value xml:lang="en-US">Date Field</value>
diff --git a/solenv/bin/native-code.py b/solenv/bin/native-code.py
index 908d50787754..661d64894c37 100755
--- a/solenv/bin/native-code.py
+++ b/solenv/bin/native-code.py
@@ -257,6 +257,7 @@ core_constructor_list = [
"com_sun_star_comp_Svx_GraphicExportHelper_get_implementation",
"com_sun_star_comp_Svx_GraphicImportHelper_get_implementation",
"com_sun_star_comp_svx_StyleToolBoxControl_get_implementation",
+ "com_sun_star_comp_svx_StylesPreviewToolBoxControl_get_implementation",
# toolkit/util/tk.component
"stardiv_Toolkit_StdTabController_get_implementation",
"stardiv_Toolkit_UnoButtonControl_get_implementation",
diff --git a/svx/Library_svxcore.mk b/svx/Library_svxcore.mk
index 430b35e9299c..7ed0705102be 100644
--- a/svx/Library_svxcore.mk
+++ b/svx/Library_svxcore.mk
@@ -376,6 +376,8 @@ $(eval $(call gb_Library_add_exception_objects,svxcore,\
svx/source/tbxctrls/tbxcolorupdate \
svx/source/tbxctrls/SvxColorValueSet \
svx/source/tbxctrls/SvxPresetListBox \
+ svx/source/tbxctrls/StylesPreviewToolBoxControl \
+ svx/source/tbxctrls/StylesPreviewWindow \
svx/source/toolbars/extrusionbar \
svx/source/toolbars/fontworkbar \
svx/source/unodraw/gluepts \
diff --git a/svx/UIConfig_svx.mk b/svx/UIConfig_svx.mk
index fdc7d1b3bc52..f7f02ad2f126 100644
--- a/svx/UIConfig_svx.mk
+++ b/svx/UIConfig_svx.mk
@@ -132,6 +132,7 @@ $(eval $(call gb_UIConfig_add_uifiles,svx,\
svx/uiconfig/ui/stylemenu \
svx/uiconfig/ui/surfacewindow \
svx/uiconfig/ui/tablewindow \
+ svx/uiconfig/ui/stylespreview \
svx/uiconfig/ui/textcharacterspacingcontrol \
svx/uiconfig/ui/textcontrolchardialog \
svx/uiconfig/ui/textcontrolparadialog \
diff --git a/svx/source/inc/StylesPreviewToolBoxControl.hxx b/svx/source/inc/StylesPreviewToolBoxControl.hxx
new file mode 100644
index 000000000000..ad449ab24313
--- /dev/null
+++ b/svx/source/inc/StylesPreviewToolBoxControl.hxx
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_SVX_SOURCE_INC_STYLES_PREVIEW_TOOLBOX_CONTROL_HXX
+#define INCLUDED_SVX_SOURCE_INC_STYLES_PREVIEW_TOOLBOX_CONTROL_HXX
+
+#include <svx/svxdllapi.h>
+#include <sfx2/tbxctrl.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include "StylesPreviewWindow.hxx"
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+
+class SVXCORE_DLLPUBLIC StylesPreviewToolBoxControl final
+ : public cppu::ImplInheritanceHelper<svt::ToolboxController, css::lang::XServiceInfo>
+{
+ VclPtr<StylesPreviewWindow_Impl> m_xVclBox;
+ std::unique_ptr<StylesPreviewWindow_Base> m_xWeldBox;
+ StylesPreviewWindow_Base* m_pBox;
+
+ css::uno::Reference<css::frame::XDispatchProvider> m_xDispatchProvider;
+
+ std::vector<OUString> m_aDefaultStyles;
+
+public:
+ StylesPreviewToolBoxControl();
+ virtual ~StylesPreviewToolBoxControl() override;
+
+ // XStatusListener
+ virtual void SAL_CALL statusChanged(const css::frame::FeatureStateEvent& rEvent) override;
+
+ // XToolbarController
+ virtual css::uno::Reference<css::awt::XWindow>
+ SAL_CALL createItemWindow(const css::uno::Reference<css::awt::XWindow>& rParent) override;
+
+ // XInitialization
+ virtual void SAL_CALL initialize(const css::uno::Sequence<css::uno::Any>& aArguments) override;
+
+ // XComponent
+ virtual void SAL_CALL dispose() override;
+
+ // XUpdatable
+ virtual void SAL_CALL update() override;
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+ virtual sal_Bool SAL_CALL supportsService(const OUString& rServiceName) override;
+ virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
+
+private:
+ void InitializeStyles(const css::uno::Reference<css::frame::XModel>& xModel);
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ \ No newline at end of file
diff --git a/svx/source/inc/StylesPreviewWindow.hxx b/svx/source/inc/StylesPreviewWindow.hxx
new file mode 100644
index 000000000000..5ae857210c6f
--- /dev/null
+++ b/svx/source/inc/StylesPreviewWindow.hxx
@@ -0,0 +1,123 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_SVX_SOURCE_INC_STYLES_PREVIEW_WINDOW_HXX
+#define INCLUDED_SVX_SOURCE_INC_STYLES_PREVIEW_WINDOW_HXX
+
+#include <vcl/InterimItemWindow.hxx>
+#include <vcl/customweld.hxx>
+#include <svl/style.hxx>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <sfx2/sfxstatuslistener.hxx>
+
+class StylesPreviewWindow_Base;
+
+class StyleStatusListener : public SfxStatusListener
+{
+ StylesPreviewWindow_Base* m_pPreviewControl;
+
+public:
+ StyleStatusListener(StylesPreviewWindow_Base* pPreviewControl,
+ css::uno::Reference<css::frame::XDispatchProvider>& xDispatchProvider);
+
+ void StateChanged(SfxItemState eState, const SfxPoolItem* pState) override;
+};
+
+class StyleItemController : public weld::CustomWidgetController
+{
+ static constexpr unsigned LEFT_MARGIN = 8;
+
+ SfxStyleFamily m_eStyleFamily;
+ OUString m_aStyleName;
+ bool m_bSelected;
+ css::uno::Reference<css::frame::XDispatchProvider> m_xDispatchProvider;
+
+public:
+ StyleItemController(const OUString& aStyleName,
+ css::uno::Reference<css::frame::XDispatchProvider>& xDispatchProvider);
+
+ void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override;
+
+ bool MouseButtonDown(const MouseEvent&) override;
+
+ void SetStyle(const OUString& sStyleName);
+
+ void Select(bool bSelect);
+
+private:
+ void DrawEntry(vcl::RenderContext& rRenderContext);
+ void DrawText(vcl::RenderContext& rRenderContext);
+ void DrawHighlight(vcl::RenderContext& rRenderContext, Color aFontBack);
+ static void DrawSelection(vcl::RenderContext& rRenderContext);
+ static void DrawContentBackground(vcl::RenderContext& rRenderContext,
+ tools::Rectangle& aContentRect, Color& aColor);
+};
+
+class StylesPreviewWindow_Base
+{
+protected:
+ static constexpr unsigned STYLES_COUNT = 4;
+
+ std::unique_ptr<StyleItemController> m_xStyleControllers[STYLES_COUNT];
+ std::unique_ptr<weld::CustomWeld> m_xStyleControllersWeld[STYLES_COUNT];
+
+ StyleStatusListener* m_pStatusListener;
+ css::uno::Reference<css::lang::XComponent> m_xStatusListener;
+
+ std::unique_ptr<weld::Toolbar> m_xUp;
+ std::unique_ptr<weld::Toolbar> m_xDown;
+
+ std::vector<OUString> m_aDefaultStyles;
+ std::vector<OUString> m_aAllStyles;
+
+ unsigned m_nStyleIterator;
+ OUString m_sSelectedStyle;
+
+ DECL_LINK(GoUp, const OString&, void);
+ DECL_LINK(GoDown, const OString&, void);
+
+public:
+ StylesPreviewWindow_Base(weld::Builder& xBuilder, std::vector<OUString>& aDefaultStyles,
+ css::uno::Reference<css::frame::XDispatchProvider>& xDispatchProvider);
+ ~StylesPreviewWindow_Base();
+
+ void Select(const OUString& rStyleName);
+
+private:
+ void Update();
+ void UpdateStylesList();
+ void MakeCurrentStyleVisible();
+ OUString GetVisibleStyle(unsigned nPosition);
+};
+
+class StylesPreviewWindow_Impl : public InterimItemWindow, public StylesPreviewWindow_Base
+{
+public:
+ StylesPreviewWindow_Impl(vcl::Window* pParent, std::vector<OUString>& aDefaultStyles,
+ css::uno::Reference<css::frame::XDispatchProvider>& xDispatchProvider);
+ ~StylesPreviewWindow_Impl();
+
+ void dispose();
+
+ void SetOptimalSize();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ \ No newline at end of file
diff --git a/svx/source/tbxctrls/StylesPreviewToolBoxControl.cxx b/svx/source/tbxctrls/StylesPreviewToolBoxControl.cxx
new file mode 100644
index 000000000000..0a95aa5397e5
--- /dev/null
+++ b/svx/source/tbxctrls/StylesPreviewToolBoxControl.cxx
@@ -0,0 +1,184 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <StylesPreviewToolBoxControl.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <vcl/svapp.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+StylesPreviewToolBoxControl::StylesPreviewToolBoxControl() {}
+
+StylesPreviewToolBoxControl::~StylesPreviewToolBoxControl() {}
+
+void SAL_CALL
+StylesPreviewToolBoxControl::initialize(const css::uno::Sequence<css::uno::Any>& rArguments)
+{
+ svt::ToolboxController::initialize(rArguments);
+
+ if (m_xFrame.is())
+ {
+ InitializeStyles(m_xFrame->getController()->getModel());
+
+ m_xDispatchProvider = css::uno::Reference<css::frame::XDispatchProvider>(
+ m_xFrame->getController(), css::uno::UNO_QUERY);
+ }
+}
+
+void SAL_CALL StylesPreviewToolBoxControl::dispose()
+{
+ svt::ToolboxController::dispose();
+
+ SolarMutexGuard aSolarMutexGuard;
+ m_xVclBox.disposeAndClear();
+ m_xWeldBox.reset();
+ m_pBox = nullptr;
+}
+
+void StylesPreviewToolBoxControl::InitializeStyles(
+ const css::uno::Reference<css::frame::XModel>& xModel)
+{
+ m_aDefaultStyles.clear();
+
+ //now convert the default style names to the localized names
+ try
+ {
+ css::uno::Reference<css::style::XStyleFamiliesSupplier> xStylesSupplier(
+ xModel, css::uno::UNO_QUERY_THROW);
+ css::uno::Reference<css::lang::XServiceInfo> xServices(xModel, css::uno::UNO_QUERY_THROW);
+ if (xServices->supportsService("com.sun.star.text.TextDocument"))
+ {
+ css::uno::Reference<css::container::XNameAccess> xParaStyles;
+ xStylesSupplier->getStyleFamilies()->getByName("ParagraphStyles") >>= xParaStyles;
+ static const std::vector<OUString> aWriterStyles
+ = { "Standard", "Text body", "Title", "Subtitle",
+ "Heading 1", "Heading 2", "Heading 3", "Quotations" };
+ for (const OUString& aStyle : aWriterStyles)
+ {
+ try
+ {
+ css::uno::Reference<css::beans::XPropertySet> xStyle;
+ xParaStyles->getByName(aStyle) >>= xStyle;
+ OUString sName;
+ xStyle->getPropertyValue("DisplayName") >>= sName;
+ if (!sName.isEmpty())
+ m_aDefaultStyles.push_back(sName);
+ }
+ catch (const css::uno::Exception&)
+ {
+ }
+ }
+ }
+ else if (xServices->supportsService("com.sun.star.sheet.SpreadsheetDocument"))
+ {
+ static const char* aCalcStyles[] = { "Default", "Heading1", "Result", "Result2" };
+ css::uno::Reference<css::container::XNameAccess> xCellStyles;
+ xStylesSupplier->getStyleFamilies()->getByName("CellStyles") >>= xCellStyles;
+ for (const char* pCalcStyle : aCalcStyles)
+ {
+ try
+ {
+ const OUString sStyleName(OUString::createFromAscii(pCalcStyle));
+ if (xCellStyles->hasByName(sStyleName))
+ {
+ css::uno::Reference<css::beans::XPropertySet> xStyle(
+ xCellStyles->getByName(sStyleName), css::uno::UNO_QUERY_THROW);
+ OUString sName;
+ xStyle->getPropertyValue("DisplayName") >>= sName;
+ if (!sName.isEmpty())
+ m_aDefaultStyles.push_back(sName);
+ }
+ }
+ catch (const css::uno::Exception&)
+ {
+ }
+ }
+ }
+ }
+ catch (const css::uno::Exception&)
+ {
+ OSL_FAIL("error while initializing style names");
+ }
+}
+
+void SAL_CALL StylesPreviewToolBoxControl::update() {}
+
+void StylesPreviewToolBoxControl::statusChanged(const css::frame::FeatureStateEvent& /*rEvent*/) {}
+
+css::uno::Reference<css::awt::XWindow>
+StylesPreviewToolBoxControl::createItemWindow(const css::uno::Reference<css::awt::XWindow>& rParent)
+{
+ css::uno::Reference<css::awt::XWindow> xItemWindow;
+
+ /* TODO
+ if (m_pBuilder)
+ {
+ SolarMutexGuard aSolarMutexGuard;
+
+ std::unique_ptr<weld::Container> xWidget(*m_pBuilder);
+
+ xItemWindow
+ = css::uno::Reference<css::awt::XWindow>(new weld::TransportAsXWindow(xWidget.get()));
+
+ m_xWeldBox.reset(new StylesPreviewWindow_Base(std::move(xWidget)));
+ m_pBox = m_xWeldBox.get();
+ }
+ else
+ */
+ {
+ VclPtr<vcl::Window> pParent = VCLUnoHelper::GetWindow(rParent);
+ if (pParent)
+ {
+ SolarMutexGuard aSolarMutexGuard;
+
+ m_xVclBox = VclPtr<StylesPreviewWindow_Impl>::Create(pParent, m_aDefaultStyles,
+ m_xDispatchProvider);
+ m_pBox = m_xVclBox.get();
+ xItemWindow = VCLUnoHelper::GetInterface(m_xVclBox);
+ }
+ }
+
+ return xItemWindow;
+}
+
+OUString StylesPreviewToolBoxControl::getImplementationName()
+{
+ return "com.sun.star.comp.svx.StylesPreviewToolBoxControl";
+}
+
+sal_Bool StylesPreviewToolBoxControl::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+css::uno::Sequence<OUString> StylesPreviewToolBoxControl::getSupportedServiceNames()
+{
+ return { "com.sun.star.frame.ToolbarController" };
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+com_sun_star_comp_svx_StylesPreviewToolBoxControl_get_implementation(
+ css::uno::XComponentContext*, css::uno::Sequence<css::uno::Any> const&)
+{
+ return cppu::acquire(new StylesPreviewToolBoxControl());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ \ No newline at end of file
diff --git a/svx/source/tbxctrls/StylesPreviewWindow.cxx b/svx/source/tbxctrls/StylesPreviewWindow.cxx
new file mode 100644
index 000000000000..5f4749d2a53a
--- /dev/null
+++ b/svx/source/tbxctrls/StylesPreviewWindow.cxx
@@ -0,0 +1,504 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <StylesPreviewWindow.hxx>
+
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <sfx2/objsh.hxx>
+#include <svl/itemset.hxx>
+#include <sfx2/tbxctrl.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <sfx2/tplpitem.hxx>
+
+#include <editeng/editids.hrc>
+#include <editeng/fontitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/svxfont.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/contouritem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/charreliefitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/crossedoutitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/cmapitem.hxx>
+#include <editeng/emphasismarkitem.hxx>
+#include <editeng/brushitem.hxx>
+
+#include <svx/xfillit0.hxx>
+#include <svx/svddef.hxx>
+#include <svx/xflclit.hxx>
+
+#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <cppuhelper/weak.hxx>
+
+#include <sal/log.hxx>
+
+StyleStatusListener::StyleStatusListener(
+ StylesPreviewWindow_Base* pPreviewControl,
+ css::uno::Reference<css::frame::XDispatchProvider>& xDispatchProvider)
+ : SfxStatusListener(xDispatchProvider, SID_STYLE_FAMILY2, ".uno:ParaStyle")
+ , m_pPreviewControl(pPreviewControl)
+{
+ ReBind();
+}
+
+void StyleStatusListener::StateChanged(SfxItemState /*eState*/, const SfxPoolItem* pState)
+{
+ const SfxTemplateItem* pStateItem = dynamic_cast<const SfxTemplateItem*>(pState);
+ m_pPreviewControl->Select(pStateItem->GetStyleName());
+}
+
+StyleItemController::StyleItemController(
+ const OUString& aStyleName,
+ css::uno::Reference<css::frame::XDispatchProvider>& xDispatchProvider)
+ : m_eStyleFamily(SfxStyleFamily::Para)
+ , m_aStyleName(aStyleName)
+ , m_bSelected(false)
+ , m_xDispatchProvider(xDispatchProvider)
+{
+}
+
+void StyleItemController::Paint(vcl::RenderContext& rRenderContext,
+ const tools::Rectangle& /*rRect*/)
+{
+ rRenderContext.Push(PushFlags::FILLCOLOR | PushFlags::FONT | PushFlags::TEXTCOLOR);
+
+ DrawEntry(rRenderContext);
+
+ rRenderContext.Pop();
+}
+
+void StyleItemController::SetStyle(const OUString& sStyleName)
+{
+ m_aStyleName = sStyleName;
+ Invalidate();
+}
+
+void StyleItemController::Select(bool bSelect)
+{
+ m_bSelected = bSelect;
+ Invalidate();
+}
+
+bool StyleItemController::MouseButtonDown(const MouseEvent&)
+{
+ css::uno::Sequence<css::beans::PropertyValue> aArgs(2);
+ aArgs[0].Value <<= m_aStyleName;
+ aArgs[1].Name = "Family";
+ aArgs[1].Value <<= sal_Int16(m_eStyleFamily);
+
+ aArgs[0].Name = "Template";
+ SfxToolBoxControl::Dispatch(m_xDispatchProvider, ".uno:StyleApply", aArgs);
+
+ return false;
+}
+
+static Color GetTextColorFromItemSet(std::unique_ptr<const SfxItemSet> const& pItemSet)
+{
+ const SfxPoolItem* pItem = pItemSet->GetItem(SID_ATTR_CHAR_COLOR);
+ if (pItem)
+ return static_cast<const SvxColorItem*>(pItem)->GetValue();
+
+ return COL_AUTO;
+}
+
+static Color GetHighlightColorFromItemSet(std::unique_ptr<const SfxItemSet> const& pItemSet)
+{
+ const SfxPoolItem* pItem = pItemSet->GetItem(SID_ATTR_BRUSH_CHAR);
+ if (pItem)
+ return static_cast<const SvxBrushItem*>(pItem)->GetColor();
+
+ return COL_AUTO;
+}
+
+static Color GetBackgroundColorFromItemSet(std::unique_ptr<const SfxItemSet> const& pItemSet)
+{
+ const SfxPoolItem* pItem = pItemSet->GetItem(XATTR_FILLCOLOR);
+ if (pItem)
+ return static_cast<const XFillColorItem*>(pItem)->GetColorValue();
+
+ return COL_AUTO;
+}
+
+static css::drawing::FillStyle
+GetFillStyleFromItemSet(std::unique_ptr<const SfxItemSet> const& pItemSet)
+{
+ const SfxPoolItem* pItem = pItemSet->GetItem(XATTR_FILLSTYLE);
+ if (pItem)
+ return static_cast<const XFillStyleItem*>(pItem)->GetValue();
+
+ return css::drawing::FillStyle_NONE;
+}
+
+static SvxFont GetFontFromItems(const SvxFontItem* pFontItem, Size aPixelFontSize,
+ std::unique_ptr<const SfxItemSet> const& pItemSet)
+{
+ SvxFont aFont;
+
+ aFont.SetFamilyName(pFontItem->GetFamilyName());
+ aFont.SetStyleName(pFontItem->GetStyleName());
+ aFont.SetFontSize(aPixelFontSize);
+
+ const SfxPoolItem* pItem = pItemSet->GetItem(SID_ATTR_CHAR_WEIGHT);
+ if (pItem)
+ aFont.SetWeight(static_cast<const SvxWeightItem*>(pItem)->GetWeight());
+
+ pItem = pItemSet->GetItem(SID_ATTR_CHAR_POSTURE);
+ if (pItem)
+ aFont.SetItalic(static_cast<const SvxPostureItem*>(pItem)->GetPosture());
+
+ pItem = pItemSet->GetItem(SID_ATTR_CHAR_CONTOUR);
+ if (pItem)
+ aFont.SetOutline(static_cast<const SvxContourItem*>(pItem)->GetValue());
+
+ pItem = pItemSet->GetItem(SID_ATTR_CHAR_SHADOWED);
+ if (pItem)
+ aFont.SetShadow(static_cast<const SvxShadowedItem*>(pItem)->GetValue());
+
+ pItem = pItemSet->GetItem(SID_ATTR_CHAR_RELIEF);
+ if (pItem)
+ aFont.SetRelief(static_cast<const SvxCharReliefItem*>(pItem)->GetValue());
+
+ pItem = pItemSet->GetItem(SID_ATTR_CHAR_UNDERLINE);
+ if (pItem)
+ aFont.SetUnderline(static_cast<const SvxUnderlineItem*>(pItem)->GetLineStyle());
+
+ pItem = pItemSet->GetItem(SID_ATTR_CHAR_OVERLINE);
+ if (pItem)
+ aFont.SetOverline(static_cast<const SvxOverlineItem*>(pItem)->GetValue());
+
+ pItem = pItemSet->GetItem(SID_ATTR_CHAR_STRIKEOUT);
+ if (pItem)
+ aFont.SetStrikeout(static_cast<const SvxCrossedOutItem*>(pItem)->GetStrikeout());
+
+ pItem = pItemSet->GetItem(SID_ATTR_CHAR_CASEMAP);
+ if (pItem)
+ aFont.SetCaseMap(static_cast<const SvxCaseMapItem*>(pItem)->GetCaseMap());
+
+ pItem = pItemSet->GetItem(SID_ATTR_CHAR_EMPHASISMARK);
+ if (pItem)
+ aFont.SetEmphasisMark(static_cast<const SvxEmphasisMarkItem*>(pItem)->GetEmphasisMark());
+
+ return aFont;
+}
+
+void StyleItemController::DrawEntry(vcl::RenderContext& rRenderContext)
+{
+ SfxObjectShell* pShell = SfxObjectShell::Current();
+ SfxStyleSheetBasePool* pPool = pShell->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyle = nullptr;
+
+ if (pPool)
+ {
+ pStyle = pPool->First(m_eStyleFamily);
+ while (pStyle && pStyle->GetName() != m_aStyleName)
+ pStyle = pPool->Next();
+
+ if (!pStyle)
+ return;
+
+ Size aSize(rRenderContext.GetOutputSizePixel());
+ tools::Rectangle aFullRect(Point(0, 0), aSize);
+ aSize = Size(aSize.getWidth() - 6, aSize.getHeight() - 6);
+ tools::Rectangle aContentRect(aFullRect);
+
+ Color aOriginalColor = rRenderContext.GetFillColor();
+ Color aOriginalLineColor = rRenderContext.GetLineColor();
+ vcl::Region aOriginalClipRegion(aFullRect);
+
+ if (m_bSelected)
+ {
+ aContentRect = tools::Rectangle(Point(3, 3), aSize);
+ DrawSelection(rRenderContext);
+ }
+
+ DrawContentBackground(rRenderContext, aContentRect, aOriginalColor);
+
+ vcl::Region aClipRegion(aContentRect);
+ rRenderContext.SetClipRegion(aClipRegion);
+
+ std::unique_ptr<const SfxItemSet> const pItemSet(pStyle->GetItemSetForPreview());
+ if (!pItemSet)
+ return;
+
+ Color aFontHighlight = COL_AUTO;
+
+ const SvxFontItem* const pFontItem = pItemSet->GetItem<SvxFontItem>(SID_ATTR_CHAR_FONT);
+ const SvxFontHeightItem* const pFontHeightItem
+ = pItemSet->GetItem<SvxFontHeightItem>(SID_ATTR_CHAR_FONTHEIGHT);
+
+ if (pFontItem && pFontHeightItem)
+ {
+ Size aFontSize(0, pFontHeightItem->GetHeight());
+ Size aPixelSize(rRenderContext.LogicToPixel(aFontSize, MapMode(pShell->GetMapUnit())));
+
+ SvxFont aFont = GetFontFromItems(pFontItem, aPixelSize, pItemSet);
+ rRenderContext.SetFont(aFont);
+
+ Color aFontCol = GetTextColorFromItemSet(pItemSet);
+ if (aFontCol != COL_AUTO)
+ rRenderContext.SetTextColor(aFontCol);
+
+ aFontHighlight = GetHighlightColorFromItemSet(pItemSet);
+
+ css::drawing::FillStyle style = GetFillStyleFromItemSet(pItemSet);
+
+ switch (style)
+ {
+ case css::drawing::FillStyle_SOLID:
+ {
+ Color aBackCol = GetBackgroundColorFromItemSet(pItemSet);
+ if (aBackCol != COL_AUTO)
+ DrawContentBackground(rRenderContext, aContentRect, aBackCol);
+ }
+ break;
+
+ default:
+ break;
+ //TODO Draw the other background styles: gradient, hatching and bitmap
+ }
+ }
+
+ if (aFontHighlight != COL_AUTO)
+ DrawHighlight(rRenderContext, aFontHighlight);
+
+ DrawText(rRenderContext);
+
+ rRenderContext.SetFillColor(aOriginalColor);
+ rRenderContext.SetLineColor(aOriginalLineColor);
+ rRenderContext.SetClipRegion(aOriginalClipRegion);
+ }
+}
+
+void StyleItemController::DrawContentBackground(vcl::RenderContext& rRenderContext,
+ tools::Rectangle& aContentRect, Color& aColor)
+{
+ rRenderContext.SetLineColor(aColor);
+ rRenderContext.SetFillColor(aColor);
+ rRenderContext.DrawRect(aContentRect);
+}
+
+void StyleItemController::DrawSelection(vcl::RenderContext& rRenderContext)
+{
+ Size aSize(rRenderContext.GetOutputSizePixel());
+ tools::Rectangle aFullRect(Point(0, 0), aSize);
+
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+
+ rRenderContext.SetLineColor(rStyleSettings.GetActiveBorderColor());
+ rRenderContext.SetFillColor(rStyleSettings.GetActiveBorderColor());
+
+ rRenderContext.DrawRect(aFullRect);
+}
+
+void StyleItemController::DrawHighlight(vcl::RenderContext& rRenderContext, Color aFontBack)
+{
+ tools::Rectangle aTextRect;
+ rRenderContext.GetTextBoundRect(aTextRect, m_aStyleName);
+
+ Size aSize = aTextRect.GetSize();
+ aSize.AdjustHeight(aSize.getHeight());
+ aTextRect.SetSize(aSize);
+
+ Point aPos(0, 0);
+ aPos.AdjustX(LEFT_MARGIN);
+ aPos.AdjustY((rRenderContext.GetOutputHeightPixel() - aTextRect.Bottom()) / 2);
+ aTextRect.SetPos(aPos);
+
+ rRenderContext.SetLineColor(aFontBack);
+ rRenderContext.SetFillColor(aFontBack);
+
+ rRenderContext.DrawRect(aTextRect);
+}
+
+void StyleItemController::DrawText(vcl::RenderContext& rRenderContext)
+{
+ tools::Rectangle aTextRect;
+ rRenderContext.GetTextBoundRect(aTextRect, m_aStyleName);
+
+ Point aPos(0, 0);
+ aPos.AdjustX(LEFT_MARGIN);
+ aPos.AdjustY((rRenderContext.GetOutputHeightPixel() - aTextRect.Bottom()) / 2);
+
+ rRenderContext.DrawText(aPos, m_aStyleName);
+}
+
+StylesPreviewWindow_Base::StylesPreviewWindow_Base(
+ weld::Builder& xBuilder, std::vector<OUString>& aDefaultStyles,
+ css::uno::Reference<css::frame::XDispatchProvider>& xDispatchProvider)
+ : m_xUp(xBuilder.weld_toolbar("uptoolbar"))
+ , m_xDown(xBuilder.weld_toolbar("downtoolbar"))
+ , m_aDefaultStyles(aDefaultStyles)
+ , m_nStyleIterator(0)
+{
+ for (unsigned int i = 0; i < STYLES_COUNT; i++)
+ {
+ m_xStyleControllers[i].reset(new StyleItemController(aDefaultStyles[i], xDispatchProvider));
+
+ OUString sIdOUString = "style" + OUString::number(i + 1);
+ OString sId = OUStringToOString(sIdOUString, RTL_TEXTENCODING_ASCII_US);
+
+ m_xStyleControllersWeld[i].reset(
+ new weld::CustomWeld(xBuilder, sId, *m_xStyleControllers[i]));
+ m_xStyleControllersWeld[i]->set_size_request(100, 60);
+ }
+
+ m_xUp->connect_clicked(LINK(this, StylesPreviewWindow_Base, GoUp));
+ m_xDown->connect_clicked(LINK(this, StylesPreviewWindow_Base, GoDown));
+
+ m_pStatusListener = new StyleStatusListener(this, xDispatchProvider);
+ m_xStatusListener.set(static_cast<cppu::OWeakObject*>(m_pStatusListener), css::uno::UNO_QUERY);
+}
+
+StylesPreviewWindow_Base::~StylesPreviewWindow_Base()
+{
+ m_pStatusListener->UnBind();
+
+ try
+ {
+ m_xStatusListener->dispose();
+ }
+ catch (css::uno::Exception&)
+ {
+ }
+
+ m_pStatusListener = nullptr;
+}
+
+OUString StylesPreviewWindow_Base::GetVisibleStyle(unsigned nPosition)
+{
+ if (nPosition >= STYLES_COUNT || !m_aAllStyles.size())
+ return "";
+
+ return m_aAllStyles[(m_nStyleIterator + nPosition) % m_aAllStyles.size()];
+}
+
+void StylesPreviewWindow_Base::Select(const OUString& rStyleName)
+{
+ m_sSelectedStyle = rStyleName;
+
+ UpdateStylesList();
+ MakeCurrentStyleVisible();
+ Update();
+}
+
+void StylesPreviewWindow_Base::MakeCurrentStyleVisible()
+{
+ if (m_aAllStyles.size())
+ {
+ unsigned nNewIterator = m_nStyleIterator;
+ auto aFound = std::find(m_aAllStyles.begin(), m_aAllStyles.end(), m_sSelectedStyle);
+ if (aFound != m_aAllStyles.end())
+ nNewIterator = aFound - m_aAllStyles.begin();
+
+ bool bIsAlreadyVisible
+ = nNewIterator >= m_nStyleIterator % m_aAllStyles.size()
+ && nNewIterator < m_nStyleIterator % m_aAllStyles.size() + STYLES_COUNT;
+ if (!bIsAlreadyVisible)
+ m_nStyleIterator = nNewIterator;
+ }
+}
+
+void StylesPreviewWindow_Base::Update()
+{
+ UpdateStylesList();
+
+ for (unsigned int i = 0; i < STYLES_COUNT; i++)
+ {
+ OUString sStyleName = GetVisibleStyle(i);
+ m_xStyleControllers[i]->SetStyle(sStyleName);
+ m_xStyleControllersWeld[i]->set_tooltip_text(sStyleName);
+
+ if (sStyleName == m_sSelectedStyle)
+ m_xStyleControllers[i]->Select(true);
+ else
+ m_xStyleControllers[i]->Select(false);
+ }
+}
+
+void StylesPreviewWindow_Base::UpdateStylesList()
+{
+ m_aAllStyles = m_aDefaultStyles;
+
+ SfxObjectShell* pDocShell = SfxObjectShell::Current();
+ const SfxStyleFamily eFamily = SfxStyleFamily::Para;
+ SfxStyleSheetBasePool* pStyleSheetPool = nullptr;
+
+ if (pDocShell)
+ pStyleSheetPool = pDocShell->GetStyleSheetPool();
+
+ if (pStyleSheetPool)
+ {
+ auto xIter = pStyleSheetPool->CreateIterator(eFamily, SfxStyleSearchBits::UserDefined);
+
+ SfxStyleSheetBase* pStyle = xIter->First();
+
+ while (pStyle)
+ {
+ m_aAllStyles.push_back(pStyle->GetName());
+ pStyle = xIter->Next();
+ }
+ }
+}
+
+IMPL_LINK(StylesPreviewWindow_Base, GoUp, const OString&, /*rItem*/, void)
+{
+ if (m_nStyleIterator == 0)
+ m_nStyleIterator = m_aAllStyles.size();
+ else
+ m_nStyleIterator--;
+
+ Update();
+}
+
+IMPL_LINK(StylesPreviewWindow_Base, GoDown, const OString&, /*rItem*/, void)
+{
+ m_nStyleIterator++;
+ Update();
+}
+
+StylesPreviewWindow_Impl::StylesPreviewWindow_Impl(
+ vcl::Window* pParent, std::vector<OUString>& aDefaultStyles,
+ css::uno::Reference<css::frame::XDispatchProvider>& xDispatchProvider)
+ : InterimItemWindow(pParent, "svx/ui/stylespreview.ui", "ApplyStyleBox")
+ , StylesPreviewWindow_Base(*m_xBuilder, aDefaultStyles, xDispatchProvider)
+{
+ SetOptimalSize();
+}
+
+StylesPreviewWindow_Impl::~StylesPreviewWindow_Impl() { disposeOnce(); }
+
+void StylesPreviewWindow_Impl::dispose()
+{
+ m_xUp.reset();
+ m_xDown.reset();
+
+ for (unsigned int i = 0; i < STYLES_COUNT; i++)
+ m_xStyleControllersWeld[i].reset();
+
+ InterimItemWindow::dispose();
+}
+
+void StylesPreviewWindow_Impl::SetOptimalSize() { SetSizePixel(get_preferred_size()); }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ \ No newline at end of file
diff --git a/svx/uiconfig/ui/stylespreview.ui b/svx/uiconfig/ui/stylespreview.ui
new file mode 100644
index 000000000000..e714c31a3f37
--- /dev/null
+++ b/svx/uiconfig/ui/stylespreview.ui
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.4 -->
+<interface domain="svx">
+ <requires lib="gtk+" version="3.18"/>
+ <object class="GtkBox" id="ApplyStyleBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">3</property>
+ <child>
+ <object class="GtkBox" id="stylescontainer">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkDrawingArea" id="style1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="style2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="style3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="style4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkToolbar" id="uptoolbar">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="toolbar_style">icons</property>
+ <child>
+ <object class="GtkToolButton" id="up">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="stylespreview|up">Previous</property>
+ <property name="use_underline">True</property>
+ <property name="icon_name">cmd/lc_prevrecord.png</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolbar" id="downtoolbar">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="toolbar_style">icons</property>
+ <child>
+ <object class="GtkToolButton" id="down">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="stylespreview|down">Next</property>
+ <property name="use_underline">True</property>
+ <property name="icon_name">cmd/lc_nextrecord.png</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/svx/util/svxcore.component b/svx/util/svxcore.component
index f5a81131fac9..b36a8d71bcb4 100644
--- a/svx/util/svxcore.component
+++ b/svx/util/svxcore.component
@@ -88,4 +88,8 @@
constructor="com_sun_star_comp_graphic_PrimitiveFactory2D_get_implementation">
<service name="com.sun.star.graphic.PrimitiveFactory2D"/>
</implementation>
+ <implementation name="com.sun.star.comp.svx.StylesPreviewToolBoxControl"
+ constructor="com_sun_star_comp_svx_StylesPreviewToolBoxControl_get_implementation">
+ <service name="com.sun.star.frame.ToolbarController"/>
+ </implementation>
</component>