diff options
author | Szymon Kłos <szymon.klos@collabora.com> | 2020-05-27 16:25:10 +0200 |
---|---|---|
committer | Szymon Kłos <szymon.klos@collabora.com> | 2020-06-17 12:08:55 +0200 |
commit | b982be12281f2eaf63cb9d18a5b3362502c3a1dc (patch) | |
tree | 66df73ecbcef22ed6addc1a4c66e6002957c5238 /svx/source | |
parent | 01b47d4e73023d7f17a939c67959d959d6fad8ac (diff) |
Styles preview widget
Change-Id: Ib9723c9793244069407ceaa4935a11da08db3795
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95998
Tested-by: Jenkins
Reviewed-by: Szymon Kłos <szymon.klos@collabora.com>
Diffstat (limited to 'svx/source')
-rw-r--r-- | svx/source/inc/StylesPreviewToolBoxControl.hxx | 72 | ||||
-rw-r--r-- | svx/source/inc/StylesPreviewWindow.hxx | 123 | ||||
-rw-r--r-- | svx/source/tbxctrls/StylesPreviewToolBoxControl.cxx | 184 | ||||
-rw-r--r-- | svx/source/tbxctrls/StylesPreviewWindow.cxx | 504 |
4 files changed, 883 insertions, 0 deletions
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 |