1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 #include <sal/config.h>
13 #include "StylePresetsPanel.hxx"
15 #include <vcl/image.hxx>
16 #include <vcl/settings.hxx>
17 #include <vcl/svapp.hxx>
18 #include <vcl/virdev.hxx>
20 #include <sfx2/objsh.hxx>
21 #include <sfx2/StylePreviewRenderer.hxx>
23 #include <com/sun/star/lang/IllegalArgumentException.hpp>
25 #include <sfx2/doctempl.hxx>
27 #include <shellio.hxx>
30 #include <sfx2/docfile.hxx>
32 namespace sw::sidebar
{
36 void renderPreview(sfx2::StyleManager
* pStyleManager
, OutputDevice
& aOutputDevice
,
37 std::u16string_view sName
, sal_Int32 nHeight
, tools::Rectangle
const & aRect
)
39 SfxStyleSheetBase
* pStyleSheet
= pStyleManager
->Search(sName
, SfxStyleFamily::Para
);
43 std::unique_ptr
<sfx2::StylePreviewRenderer
> pStylePreviewRenderer
44 = pStyleManager
->CreateStylePreviewRenderer(aOutputDevice
, pStyleSheet
, nHeight
);
45 pStylePreviewRenderer
->recalculate();
46 pStylePreviewRenderer
->render(aRect
, sfx2::StylePreviewRenderer::RenderAlign::TOP
);
50 BitmapEx
GenerateStylePreview(SfxObjectShell
& rSource
, OUString
const & aName
)
52 sfx2::StyleManager
* pStyleManager
= rSource
.GetStyleManager();
54 ScopedVclPtrInstance
<VirtualDevice
> pVirtualDev(*Application::GetDefaultDevice());
56 float fScalingFactor
= pVirtualDev
->GetDPIScaleFactor();
58 sal_Int32 nMargin
= 6 * fScalingFactor
;
60 sal_Int32 nPreviewWidth
= 144 * fScalingFactor
;
62 sal_Int32 nNameHeight
= 16 * fScalingFactor
;
63 sal_Int32 nTitleHeight
= 32 * fScalingFactor
;
64 sal_Int32 nHeadingHeight
= 24 * fScalingFactor
;
65 sal_Int32 nTextBodyHeight
= 16 * fScalingFactor
;
66 sal_Int32 nBottomMargin
= 2 * fScalingFactor
;
68 sal_Int32 nNameFontSize
= 12 * fScalingFactor
;
70 sal_Int32 nPreviewHeight
= nNameHeight
+ nTitleHeight
+ nHeadingHeight
+ nTextBodyHeight
+ nBottomMargin
;
72 Size
aSize(nPreviewWidth
, nPreviewHeight
);
74 pVirtualDev
->SetOutputSizePixel(aSize
);
76 pVirtualDev
->SetLineColor(COL_LIGHTGRAY
);
77 pVirtualDev
->SetFillColor();
81 pVirtualDev
->SetFillColor(COL_LIGHTGRAY
);
82 tools::Rectangle
aNameRect(0, y
, nPreviewWidth
, nNameHeight
);
83 pVirtualDev
->DrawRect(aNameRect
);
86 aFont
.SetFontSize(Size(0, nNameFontSize
));
88 pVirtualDev
->SetFont(aFont
);
90 Size
aTextSize(pVirtualDev
->GetTextWidth(aName
), pVirtualDev
->GetTextHeight());
92 Point
aPoint((aNameRect
.GetWidth() / 2.0) - (aTextSize
.Width() / 2.0),
93 y
+ (aNameRect
.GetHeight() / 2.0) - (aTextSize
.Height() / 2.0));
95 pVirtualDev
->DrawText(aPoint
, aName
);
101 tools::Rectangle
aRenderRect(Point(nMargin
, y
), aSize
);
102 renderPreview(pStyleManager
, *pVirtualDev
, u
"Title", nTitleHeight
, aRenderRect
);
107 tools::Rectangle
aRenderRect(Point(nMargin
, y
), aSize
);
108 renderPreview(pStyleManager
, *pVirtualDev
, u
"Heading 1", nHeadingHeight
, aRenderRect
);
112 tools::Rectangle
aRenderRect(Point(nMargin
, y
), aSize
);
113 renderPreview(pStyleManager
, *pVirtualDev
, u
"Body Text", nTextBodyHeight
, aRenderRect
);
116 return pVirtualDev
->GetBitmapEx(Point(), aSize
);
119 BitmapEx
CreatePreview(OUString
const & aUrl
, OUString
const & aName
)
121 if (SfxObjectShell
* pObjectShell
= SfxObjectShell::Current())
123 SfxMedium
aMedium(aUrl
, StreamMode::STD_READWRITE
);
124 SfxObjectShellLock xTemplDoc
= SfxObjectShell::CreateObjectByFactoryName(pObjectShell
->GetFactory().GetFactoryName(), SfxObjectCreateMode::ORGANIZER
);
125 xTemplDoc
->DoInitNew();
126 if (xTemplDoc
->LoadFrom(aMedium
))
127 return GenerateStylePreview(*xTemplDoc
, aName
);
134 std::unique_ptr
<PanelLayout
> StylePresetsPanel::Create(weld::Widget
* pParent
)
136 if (pParent
== nullptr)
137 throw css::lang::IllegalArgumentException("no parent Window given to StylePresetsPanel::Create", nullptr, 0);
139 return std::make_unique
<StylePresetsPanel
>(pParent
);
142 StylePresetsPanel::StylePresetsPanel(weld::Widget
* pParent
)
143 : PanelLayout(pParent
, "StylePresetsPanel", "modules/swriter/ui/sidebarstylepresets.ui")
144 , mxValueSet(new ValueSet(nullptr))
145 , mxValueSetWin(new weld::CustomWeld(*m_xBuilder
, "valueset", *mxValueSet
))
147 mxValueSet
->SetColCount(2);
149 mxValueSet
->SetColor(Application::GetSettings().GetStyleSettings().GetFaceColor());
150 mxValueSet
->SetDoubleClickHdl(LINK(this, StylePresetsPanel
, DoubleClickHdl
));
155 void StylePresetsPanel::RefreshList()
157 SfxDocumentTemplates aTemplates
;
158 sal_uInt16 nCount
= aTemplates
.GetRegionCount();
159 for (sal_uInt16 i
= 0; i
< nCount
; ++i
)
161 OUString
aRegionName(aTemplates
.GetFullRegionName(i
));
162 if (aRegionName
== "Styles")
164 for (sal_uInt16 j
= 0; j
< aTemplates
.GetCount(i
); ++j
)
166 OUString aName
= aTemplates
.GetName(i
,j
);
167 OUString aURL
= aTemplates
.GetPath(i
,j
);
168 BitmapEx aPreview
= CreatePreview(aURL
, aName
);
169 sal_uInt16 nId
= j
+ 1;
170 mxValueSet
->InsertItem(nId
, Image(aPreview
), aName
);
171 maTemplateEntries
.push_back(std::make_unique
<TemplateEntry
>(aURL
));
172 mxValueSet
->SetItemData(nId
, maTemplateEntries
.back().get());
174 mxValueSet
->SetOptimalSize();
179 StylePresetsPanel::~StylePresetsPanel()
183 IMPL_LINK_NOARG(StylePresetsPanel
, DoubleClickHdl
, ValueSet
*, void)
185 sal_Int32 nItemId
= mxValueSet
->GetSelectedItemId();
186 TemplateEntry
* pEntry
= static_cast<TemplateEntry
*>(mxValueSet
->GetItemData(nItemId
));
188 if (SwDocShell
* pDocSh
= static_cast<SwDocShell
*>(SfxObjectShell::Current()))
190 SwgReaderOption aOption
;
191 aOption
.SetTextFormats(true);
192 aOption
.SetNumRules(true);
193 pDocSh
->LoadStylesFromFile(pEntry
->maURL
, aOption
, false);
197 void StylePresetsPanel::NotifyItemUpdate(const sal_uInt16
/*nSId*/,
198 const SfxItemState
/*eState*/,
199 const SfxPoolItem
* /*pState*/)
203 } // end of namespace ::sw::sidebar
205 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */