From 48d2dca48d75fef67e3caa61d80f074fdbeb9984 Mon Sep 17 00:00:00 2001 From: Tomaž Vajngerl Date: Tue, 26 May 2015 18:49:29 +0900 Subject: Show previews of style presets in sidebar Change-Id: I0e3d6f00a79bc33e1db1329df217e7e867dfd511 --- include/sfx2/StylePreviewRenderer.hxx | 14 ++- include/svx/CommonStylePreviewRenderer.hxx | 2 +- svx/source/styles/CommonStylePreviewRenderer.cxx | 18 +++- sw/source/uibase/sidebar/StylePresetsPanel.cxx | 120 +++++++++++++++++++++-- sw/source/uibase/sidebar/StylePresetsPanel.hxx | 10 +- sw/uiconfig/swriter/ui/sidebarstylepresets.ui | 11 +++ 6 files changed, 159 insertions(+), 16 deletions(-) diff --git a/include/sfx2/StylePreviewRenderer.hxx b/include/sfx2/StylePreviewRenderer.hxx index bc77e20792d1..1fc980409e99 100644 --- a/include/sfx2/StylePreviewRenderer.hxx +++ b/include/sfx2/StylePreviewRenderer.hxx @@ -26,8 +26,14 @@ protected: OutputDevice& mrOutputDev; SfxStyleSheetBase* mpStyle; long mnMaxHeight; + OUString msRenderText; public: + enum class RenderAlign + { + TOP, CENTER, BOTTOM + }; + StylePreviewRenderer(const SfxObjectShell& rShell, OutputDevice& rOutputDev, SfxStyleSheetBase* pStyle, @@ -36,14 +42,20 @@ public: , mrOutputDev(rOutputDev) , mpStyle(pStyle) , mnMaxHeight(nMaxHeight) + , msRenderText() {} virtual ~StylePreviewRenderer() {} + void setRenderText(OUString& rRenderText) + { + msRenderText = rRenderText; + } + virtual bool recalculate() = 0; virtual Size getRenderSize() = 0; - virtual bool render(const Rectangle& aRectangle) = 0; + virtual bool render(const Rectangle& aRectangle, RenderAlign eRenderAlign = RenderAlign::CENTER) = 0; }; } // end namespace sfx2 diff --git a/include/svx/CommonStylePreviewRenderer.hxx b/include/svx/CommonStylePreviewRenderer.hxx index 1e7d54e0c6ae..49717b574854 100644 --- a/include/svx/CommonStylePreviewRenderer.hxx +++ b/include/svx/CommonStylePreviewRenderer.hxx @@ -35,7 +35,7 @@ public: virtual bool recalculate() SAL_OVERRIDE; virtual Size getRenderSize() SAL_OVERRIDE; - virtual bool render(const Rectangle& aRectangle) SAL_OVERRIDE; + virtual bool render(const Rectangle& aRectangle, RenderAlign eRenderAlign = RenderAlign::CENTER) SAL_OVERRIDE; }; } // end namespace svx diff --git a/svx/source/styles/CommonStylePreviewRenderer.cxx b/svx/source/styles/CommonStylePreviewRenderer.cxx index ab1271ac8fe0..2d9ac3f5dd10 100644 --- a/svx/source/styles/CommonStylePreviewRenderer.cxx +++ b/svx/source/styles/CommonStylePreviewRenderer.cxx @@ -174,8 +174,10 @@ Size CommonStylePreviewRenderer::getRenderSize() return maPixelSize; } -bool CommonStylePreviewRenderer::render(const Rectangle& aRectangle) +bool CommonStylePreviewRenderer::render(const Rectangle& aRectangle, RenderAlign eRenderAlign) { + const OUString& rText = msRenderText.isEmpty() ? maStyleName : msRenderText; + // setup the device & draw vcl::Font aOldFont(mrOutputDev.GetFont()); Color aOldColor(mrOutputDev.GetTextColor()); @@ -192,10 +194,18 @@ bool CommonStylePreviewRenderer::render(const Rectangle& aRectangle) mrOutputDev.SetTextColor(maFontColor); Point aFontDrawPosition = aRectangle.TopLeft(); - if (aRectangle.GetHeight() > maPixelSize.Height()) - aFontDrawPosition.Y() += ( aRectangle.GetHeight() - maPixelSize.Height() ) / 2; + if (eRenderAlign == RenderAlign::CENTER) + { + if (aRectangle.GetHeight() > maPixelSize.Height()) + aFontDrawPosition.Y() += (aRectangle.GetHeight() - maPixelSize.Height()) / 2; + } + else if (eRenderAlign == RenderAlign::BOTTOM) + { + if (aRectangle.GetHeight() > maPixelSize.Height()) + aFontDrawPosition.Y() += aRectangle.GetHeight() - maPixelSize.Height(); + } - mrOutputDev.DrawText(aFontDrawPosition, maStyleName); + mrOutputDev.DrawText(aFontDrawPosition, rText); mrOutputDev.SetFillColor(aOldFillColor); mrOutputDev.SetTextColor(aOldColor); diff --git a/sw/source/uibase/sidebar/StylePresetsPanel.cxx b/sw/source/uibase/sidebar/StylePresetsPanel.cxx index 7a4dbfc2933a..957f0508b008 100644 --- a/sw/source/uibase/sidebar/StylePresetsPanel.cxx +++ b/sw/source/uibase/sidebar/StylePresetsPanel.cxx @@ -63,14 +63,18 @@ StylePresetsPanel::StylePresetsPanel(vcl::Window* pParent, : PanelLayout(pParent, "StylePresetsPanel", "modules/swriter/ui/sidebarstylepresets.ui", rxFrame) , mpBindings(pBindings) { + get(mpValueSet, "valueset"); - get(mpListBox, "listbox"); + mpValueSet->SetColCount(2); - mpListBox->SetDoubleClickHdl(LINK(this, StylePresetsPanel, DoubleClickHdl)); + mpValueSet->SetDoubleClickHdl(LINK(this, StylePresetsPanel, DoubleClickHdl)); + RefreshList(); +} +void StylePresetsPanel::RefreshList() +{ SfxDocumentTemplates aTemplates; - sal_uInt16 nCount = aTemplates.GetRegionCount(); for (sal_uInt16 i = 0; i < nCount; ++i) { @@ -81,14 +85,112 @@ StylePresetsPanel::StylePresetsPanel(vcl::Window* pParent, { OUString aName = aTemplates.GetName(i,j); OUString aURL = aTemplates.GetPath(i,j); - sal_Int32 nIndex = mpListBox->InsertEntry(aName); + BitmapEx aPreview = CreatePreview(aURL, aName); + mpValueSet->InsertItem(j, Image(aPreview), aName); maTemplateEntries.push_back(std::unique_ptr(new TemplateEntry(aName, aURL))); - mpListBox->SetEntryData(nIndex, maTemplateEntries.back().get()); + mpValueSet->SetItemData(j, maTemplateEntries.back().get()); } } } } +BitmapEx StylePresetsPanel::CreatePreview(OUString& aUrl, OUString& aName) +{ + SfxMedium aMedium(aUrl, STREAM_STD_READWRITE); + SfxObjectShell* pObjectShell = SfxObjectShell::Current(); + SfxObjectShellLock xTemplDoc = pObjectShell->CreateObjectByFactoryName(pObjectShell->GetFactory().GetFactoryName(), SfxObjectCreateMode::ORGANIZER); + xTemplDoc->DoInitNew(0); + if (xTemplDoc->LoadFrom(aMedium)) + { + return GenerateStylePreview(*xTemplDoc, aName); + } + return BitmapEx(); +} + +void renderPreview(sfx2::StyleManager* pStyleManager, OutputDevice& aOutputDevice, + OUString sName, sal_Int32 nHeight, Rectangle& aRect) +{ + sfx2::StylePreviewRenderer* pStylePreviewRenderer; + + SfxStyleSheetBase* pStyleSheet = pStyleManager->Search(sName, SFX_STYLE_FAMILY_PARA); + + if (pStyleSheet) + { + pStylePreviewRenderer = pStyleManager->CreateStylePreviewRenderer(aOutputDevice, pStyleSheet, nHeight); + pStylePreviewRenderer->recalculate(); + pStylePreviewRenderer->render(aRect, sfx2::StylePreviewRenderer::RenderAlign::TOP); + } +} + +BitmapEx StylePresetsPanel::GenerateStylePreview(SfxObjectShell& rSource, OUString& aName) +{ + sfx2::StyleManager* pStyleManager = rSource.GetStyleManager(); + + ScopedVclPtrInstance pVirtualDev(*Application::GetDefaultDevice()); + + sal_Int32 nScalingFactor = pVirtualDev->GetDPIScaleFactor(); + + sal_Int32 nMargin = 6 * nScalingFactor; + + sal_Int32 nPreviewWidth = 144 * nScalingFactor; + + sal_Int32 nNameHeight = 16 * nScalingFactor; + sal_Int32 nTitleHeight = 32 * nScalingFactor; + sal_Int32 nHeadingHeight = 24 * nScalingFactor; + sal_Int32 nTextBodyHeight = 16 * nScalingFactor; + sal_Int32 nBottomMargin = 2 * nScalingFactor; + + sal_Int32 nNameFontSize = 12 * nScalingFactor; + + sal_Int32 nPreviewHeight = nNameHeight + nTitleHeight + nHeadingHeight + nTextBodyHeight + nBottomMargin; + + Size aSize(nPreviewWidth, nPreviewHeight); + + pVirtualDev->SetOutputSizePixel(aSize); + + pVirtualDev->SetLineColor(COL_LIGHTGRAY); + pVirtualDev->SetFillColor(); + + long y = 0; + { + pVirtualDev->SetFillColor(COL_LIGHTGRAY); + Rectangle aNameRect(0, y, nPreviewWidth, nNameHeight); + pVirtualDev->DrawRect(aNameRect); + + vcl::Font aFont; + aFont.SetSize(Size(0, nNameFontSize)); + + pVirtualDev->SetFont(aFont); + + Size aTextSize(pVirtualDev->GetTextWidth(aName), pVirtualDev->GetTextHeight()); + + Point aPoint((aNameRect.GetWidth() / 2.0) - (aTextSize.Width() / 2.0), + y + (aNameRect.GetHeight() / 2.0) - (aTextSize.Height() / 2.0)); + + pVirtualDev->DrawText(aPoint, aName); + + y += nNameHeight; + } + + { + Rectangle aRenderRect(Point(nMargin, y), aSize); + renderPreview(pStyleManager, *pVirtualDev.get(), "Title", nTitleHeight, aRenderRect); + y += nTitleHeight; + } + + { + Rectangle aRenderRect(Point(nMargin, y), aSize); + renderPreview(pStyleManager, *pVirtualDev.get(), "Heading 1", nHeadingHeight, aRenderRect); + y += nHeadingHeight; + } + { + Rectangle aRenderRect(Point(nMargin, y), aSize); + renderPreview(pStyleManager, *pVirtualDev.get(), "Text Body", nTextBodyHeight, aRenderRect); + } + + return pVirtualDev->GetBitmapEx(Point(), aSize); +} + StylePresetsPanel::~StylePresetsPanel() { disposeOnce(); @@ -96,15 +198,15 @@ StylePresetsPanel::~StylePresetsPanel() void StylePresetsPanel::dispose() { - mpListBox.disposeAndClear(); + mpValueSet.disposeAndClear(); PanelLayout::dispose(); } IMPL_LINK_NOARG(StylePresetsPanel, DoubleClickHdl) { - sal_Int32 nIndex = mpListBox->GetSelectEntryPos(); - TemplateEntry* pEntry = static_cast(mpListBox->GetEntryData(nIndex)); + sal_Int32 nItemId = mpValueSet->GetSelectItemId(); + TemplateEntry* pEntry = static_cast(mpValueSet->GetItemData(nItemId)); SwDocShell* pDocSh = static_cast(SfxObjectShell::Current()); if (pDocSh) @@ -115,7 +217,7 @@ IMPL_LINK_NOARG(StylePresetsPanel, DoubleClickHdl) pDocSh->LoadStylesFromFile(pEntry->maURL, aOption, false); } - return 1; + return 0; } void StylePresetsPanel::NotifyItemUpdate(const sal_uInt16 /*nSId*/, diff --git a/sw/source/uibase/sidebar/StylePresetsPanel.hxx b/sw/source/uibase/sidebar/StylePresetsPanel.hxx index dd2a7c7be8b6..fd51cf416e20 100644 --- a/sw/source/uibase/sidebar/StylePresetsPanel.hxx +++ b/sw/source/uibase/sidebar/StylePresetsPanel.hxx @@ -19,6 +19,8 @@ #include +#include + #include #include #include @@ -32,6 +34,8 @@ #include #include +#include + #include #include "docstyle.hxx" @@ -64,6 +68,10 @@ private: OUString maURL; }; + void RefreshList(); + BitmapEx CreatePreview(OUString& aUrl, OUString& aName); + BitmapEx GenerateStylePreview(SfxObjectShell& rSource, OUString& aName); + StylePresetsPanel(vcl::Window* pParent, const css::uno::Reference& rxFrame, SfxBindings* pBindings); @@ -73,7 +81,7 @@ private: SfxBindings* mpBindings; - VclPtr mpListBox; + VclPtr mpValueSet; std::vector> maTemplateEntries; diff --git a/sw/uiconfig/swriter/ui/sidebarstylepresets.ui b/sw/uiconfig/swriter/ui/sidebarstylepresets.ui index 071e9e57ec29..fc64564fea38 100644 --- a/sw/uiconfig/swriter/ui/sidebarstylepresets.ui +++ b/sw/uiconfig/swriter/ui/sidebarstylepresets.ui @@ -2,6 +2,7 @@ + True False @@ -31,6 +32,16 @@ 0 + + + True + False + + + 0 + 1 + + -- cgit v1.2.3