tdf#164995: only match keywords for requested locale and opcode
[LibreOffice.git] / svx / source / tbxctrls / StylesPreviewWindow.cxx
blob7b2c63931e962d72dbcff1d181ccf316819197d2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2 /*
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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <StylesPreviewWindow.hxx>
22 #include <comphelper/base64.hxx>
23 #include <comphelper/lok.hxx>
24 #include <comphelper/propertyvalue.hxx>
25 #include <utility>
26 #include <vcl/svapp.hxx>
27 #include <sfx2/objsh.hxx>
28 #include <svl/itemset.hxx>
29 #include <sfx2/tbxctrl.hxx>
30 #include <sfx2/sfxsids.hrc>
31 #include <sfx2/tplpitem.hxx>
32 #include <sfx2/viewsh.hxx>
33 #include <vcl/filter/PngImageWriter.hxx>
34 #include <vcl/glyphitemcache.hxx>
35 #include <vcl/virdev.hxx>
36 #include <vcl/settings.hxx>
38 #include <editeng/editids.hrc>
39 #include <editeng/fontitem.hxx>
40 #include <editeng/fhgtitem.hxx>
41 #include <editeng/svxfont.hxx>
42 #include <editeng/wghtitem.hxx>
43 #include <editeng/postitem.hxx>
44 #include <editeng/contouritem.hxx>
45 #include <editeng/shdditem.hxx>
46 #include <editeng/charreliefitem.hxx>
47 #include <editeng/udlnitem.hxx>
48 #include <editeng/crossedoutitem.hxx>
49 #include <editeng/colritem.hxx>
50 #include <editeng/cmapitem.hxx>
51 #include <editeng/emphasismarkitem.hxx>
52 #include <editeng/brushitem.hxx>
54 #include <i18nlangtag/mslangid.hxx>
56 #include <svx/xfillit0.hxx>
57 #include <svx/xdef.hxx>
58 #include <svx/xflclit.hxx>
60 #include <com/sun/star/drawing/FillStyle.hpp>
61 #include <com/sun/star/i18n/ScriptType.hpp>
63 #include <vcl/commandevent.hxx>
65 namespace
67 class StylePreviewCache
69 private:
70 class JsonStylePreviewCacheClear final : public Timer
72 public:
73 JsonStylePreviewCacheClear()
74 : Timer("Json Style Preview Cache clear callback")
76 // a generous 30 secs
77 SetTimeout(30000);
78 SetStatic();
80 virtual void Invoke() override { StylePreviewCache::gJsonStylePreviewCache.clear(); }
83 static std::map<OUString, VclPtr<VirtualDevice>> gStylePreviewCache;
84 static std::map<OUString, OString> gJsonStylePreviewCache;
85 static int gStylePreviewCacheClients;
86 static JsonStylePreviewCacheClear gJsonIdleClear;
88 public:
89 static std::map<OUString, VclPtr<VirtualDevice>>& Get() { return gStylePreviewCache; }
90 static std::map<OUString, OString>& GetJson() { return gJsonStylePreviewCache; }
92 static void ClearCache(bool bHard)
94 for (auto& aPreview : gStylePreviewCache)
95 aPreview.second.disposeAndClear();
97 gStylePreviewCache.clear();
98 if (bHard)
100 StylePreviewCache::gJsonStylePreviewCache.clear();
101 gJsonIdleClear.Stop();
103 else
105 // tdf#155720 don't immediately clear the json representation
106 gJsonIdleClear.Start();
110 static void RegisterClient()
112 if (!gStylePreviewCacheClients)
113 gJsonIdleClear.Stop();
114 gStylePreviewCacheClients++;
117 static void UnregisterClient()
119 gStylePreviewCacheClients--;
120 if (!gStylePreviewCacheClients)
121 ClearCache(false);
125 std::map<OUString, VclPtr<VirtualDevice>> StylePreviewCache::gStylePreviewCache;
126 std::map<OUString, OString> StylePreviewCache::gJsonStylePreviewCache;
127 int StylePreviewCache::gStylePreviewCacheClients;
128 StylePreviewCache::JsonStylePreviewCacheClear StylePreviewCache::gJsonIdleClear;
131 StyleStatusListener::StyleStatusListener(
132 StylesPreviewWindow_Base* pPreviewControl,
133 const css::uno::Reference<css::frame::XDispatchProvider>& xDispatchProvider)
134 : SfxStatusListener(xDispatchProvider, SID_STYLE_FAMILY2, u".uno:ParaStyle"_ustr)
135 , m_pPreviewControl(pPreviewControl)
137 ReBind();
140 void StyleStatusListener::StateChangedAtStatusListener(SfxItemState /*eState*/,
141 const SfxPoolItem* pState)
143 const SfxTemplateItem* pStateItem = dynamic_cast<const SfxTemplateItem*>(pState);
144 if (pStateItem)
146 if (pStateItem->GetStyleIdentifier().isEmpty())
147 m_pPreviewControl->Select(pStateItem->GetStyleName());
148 else
149 m_pPreviewControl->Select(pStateItem->GetStyleIdentifier());
153 StylePoolChangeListener::StylePoolChangeListener(StylesPreviewWindow_Base* pPreviewControl)
154 : m_pPreviewControl(pPreviewControl)
156 SfxObjectShell* pDocShell = SfxObjectShell::Current();
158 m_pStyleSheetPool = pDocShell ? pDocShell->GetStyleSheetPool() : nullptr;
160 if (m_pStyleSheetPool)
162 StartListening(*m_pStyleSheetPool);
166 StylePoolChangeListener::~StylePoolChangeListener()
168 if (m_pStyleSheetPool)
169 EndListening(*m_pStyleSheetPool);
172 void StylePoolChangeListener::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& rHint)
174 if (rHint.GetId() == SfxHintId::StyleSheetModified
175 || rHint.GetId() == SfxHintId::StyleSheetModifiedExtended)
176 StylePreviewCache::ClearCache(true);
177 m_pPreviewControl->RequestStylesListUpdate();
180 StyleItemController::StyleItemController(std::pair<OUString, OUString> aStyleName)
181 : m_eStyleFamily(SfxStyleFamily::Para)
182 , m_aStyleName(std::move(aStyleName))
186 void StyleItemController::Paint(vcl::RenderContext& rRenderContext)
188 rRenderContext.Push(vcl::PushFlags::FILLCOLOR | vcl::PushFlags::FONT
189 | vcl::PushFlags::TEXTCOLOR);
191 DrawEntry(rRenderContext);
193 rRenderContext.Pop();
196 bool StylesPreviewWindow_Base::Command(const CommandEvent& rEvent)
198 if (rEvent.GetCommand() != CommandEventId::ContextMenu)
199 return false;
201 std::unique_ptr<weld::Builder> xBuilder(
202 Application::CreateBuilder(m_xStylesView.get(), u"svx/ui/stylemenu.ui"_ustr));
203 std::unique_ptr<weld::Menu> xMenu(xBuilder->weld_menu(u"menu"_ustr));
204 OUString rIdent = xMenu->popup_at_rect(m_xStylesView.get(),
205 tools::Rectangle(rEvent.GetMousePosPixel(), Size(1, 1)));
206 if (rIdent == "update" || rIdent == "edit")
208 css::uno::Sequence<css::beans::PropertyValue> aArgs(0);
210 const css::uno::Reference<css::frame::XDispatchProvider> xProvider(m_xFrame,
211 css::uno::UNO_QUERY);
212 SfxToolBoxControl::Dispatch(
213 xProvider,
214 rIdent == "update" ? u".uno:StyleUpdateByExample"_ustr : u".uno:EditStyle"_ustr, aArgs);
216 return true;
219 return false;
222 static Color GetTextColorFromItemSet(std::optional<SfxItemSet> const& pItemSet)
224 const SfxPoolItem* pItem = pItemSet->GetItem(SID_ATTR_CHAR_COLOR);
225 if (pItem)
226 return static_cast<const SvxColorItem*>(pItem)->GetValue();
228 return COL_AUTO;
231 static Color GetHighlightColorFromItemSet(std::optional<SfxItemSet> const& pItemSet)
233 const SfxPoolItem* pItem = pItemSet->GetItem(SID_ATTR_BRUSH_CHAR);
234 if (pItem)
235 return static_cast<const SvxBrushItem*>(pItem)->GetColor();
237 return COL_AUTO;
240 static Color GetBackgroundColorFromItemSet(std::optional<SfxItemSet> const& pItemSet)
242 const SfxPoolItem* pItem = pItemSet->GetItem(XATTR_FILLCOLOR);
243 if (pItem)
244 return static_cast<const XFillColorItem*>(pItem)->GetColorValue();
246 return COL_AUTO;
249 static css::drawing::FillStyle GetFillStyleFromItemSet(std::optional<SfxItemSet> const& pItemSet)
251 const SfxPoolItem* pItem = pItemSet->GetItem(XATTR_FILLSTYLE);
252 if (pItem)
253 return static_cast<const XFillStyleItem*>(pItem)->GetValue();
255 return css::drawing::FillStyle_NONE;
258 static SvxFont GetFontFromItems(const SvxFontItem* pFontItem, Size aPixelFontSize,
259 std::optional<SfxItemSet> const& pItemSet)
261 SvxFont aFont;
263 aFont.SetFamilyName(pFontItem->GetFamilyName());
264 aFont.SetStyleName(pFontItem->GetStyleName());
265 aFont.SetFontSize(aPixelFontSize);
267 const SfxPoolItem* pItem = pItemSet->GetItem(SID_ATTR_CHAR_WEIGHT);
268 if (pItem)
269 aFont.SetWeight(static_cast<const SvxWeightItem*>(pItem)->GetWeight());
271 pItem = pItemSet->GetItem(SID_ATTR_CHAR_POSTURE);
272 if (pItem)
273 aFont.SetItalic(static_cast<const SvxPostureItem*>(pItem)->GetPosture());
275 pItem = pItemSet->GetItem(SID_ATTR_CHAR_CONTOUR);
276 if (pItem)
277 aFont.SetOutline(static_cast<const SvxContourItem*>(pItem)->GetValue());
279 pItem = pItemSet->GetItem(SID_ATTR_CHAR_SHADOWED);
280 if (pItem)
281 aFont.SetShadow(static_cast<const SvxShadowedItem*>(pItem)->GetValue());
283 pItem = pItemSet->GetItem(SID_ATTR_CHAR_RELIEF);
284 if (pItem)
285 aFont.SetRelief(static_cast<const SvxCharReliefItem*>(pItem)->GetValue());
287 pItem = pItemSet->GetItem(SID_ATTR_CHAR_UNDERLINE);
288 if (pItem)
289 aFont.SetUnderline(static_cast<const SvxUnderlineItem*>(pItem)->GetLineStyle());
291 pItem = pItemSet->GetItem(SID_ATTR_CHAR_OVERLINE);
292 if (pItem)
293 aFont.SetOverline(static_cast<const SvxOverlineItem*>(pItem)->GetValue());
295 pItem = pItemSet->GetItem(SID_ATTR_CHAR_STRIKEOUT);
296 if (pItem)
297 aFont.SetStrikeout(static_cast<const SvxCrossedOutItem*>(pItem)->GetStrikeout());
299 pItem = pItemSet->GetItem(SID_ATTR_CHAR_CASEMAP);
300 if (pItem)
301 aFont.SetCaseMap(static_cast<const SvxCaseMapItem*>(pItem)->GetCaseMap());
303 pItem = pItemSet->GetItem(SID_ATTR_CHAR_EMPHASISMARK);
304 if (pItem)
305 aFont.SetEmphasisMark(static_cast<const SvxEmphasisMarkItem*>(pItem)->GetEmphasisMark());
307 return aFont;
310 void StyleItemController::DrawEntry(vcl::RenderContext& rRenderContext)
312 SfxObjectShell* pShell = SfxObjectShell::Current();
313 if (!pShell)
314 return;
316 SfxStyleSheetBasePool* pPool = pShell->GetStyleSheetPool();
317 SfxStyleSheetBase* pStyle = nullptr;
319 if (!pPool)
320 return;
322 pStyle = pPool->First(m_eStyleFamily);
323 while (pStyle && pStyle->GetName() != m_aStyleName.first
324 && pStyle->GetName() != m_aStyleName.second)
325 pStyle = pPool->Next();
327 if (!pStyle)
328 return;
330 Size aSize(rRenderContext.GetOutputSizePixel());
331 tools::Rectangle aFullRect(Point(0, 0), aSize);
332 tools::Rectangle aContentRect(aFullRect);
334 Color aOriginalColor = rRenderContext.GetFillColor();
335 Color aOriginalLineColor = rRenderContext.GetLineColor();
337 DrawContentBackground(rRenderContext, aContentRect, aOriginalColor);
339 std::optional<SfxItemSet> const pItemSet(pStyle->GetItemSetForPreview());
340 if (!pItemSet)
341 return;
343 Color aFontHighlight = COL_AUTO;
345 sal_Int16 nScriptType
346 = MsLangId::getScriptType(Application::GetSettings().GetUILanguageTag().getLanguageType());
348 sal_uInt16 nFontSlot = SID_ATTR_CHAR_FONT;
349 if (nScriptType == css::i18n::ScriptType::ASIAN)
350 nFontSlot = SID_ATTR_CHAR_CJK_FONT;
351 else if (nScriptType == css::i18n::ScriptType::COMPLEX)
352 nFontSlot = SID_ATTR_CHAR_CTL_FONT;
354 const SvxFontItem* const pFontItem = pItemSet->GetItem<SvxFontItem>(nFontSlot);
355 const SvxFontHeightItem* const pFontHeightItem
356 = pItemSet->GetItem<SvxFontHeightItem>(SID_ATTR_CHAR_FONTHEIGHT);
358 if (pFontItem && pFontHeightItem)
360 Size aFontSize(0, pFontHeightItem->GetHeight());
361 Size aPixelSize(rRenderContext.LogicToPixel(aFontSize, MapMode(pShell->GetMapUnit())));
363 SvxFont aFont = GetFontFromItems(pFontItem, aPixelSize, pItemSet);
364 rRenderContext.SetFont(aFont);
366 Color aFontCol = GetTextColorFromItemSet(pItemSet);
367 if (aFontCol != COL_AUTO)
368 rRenderContext.SetTextColor(aFontCol);
370 aFontHighlight = GetHighlightColorFromItemSet(pItemSet);
372 css::drawing::FillStyle style = GetFillStyleFromItemSet(pItemSet);
374 switch (style)
376 case css::drawing::FillStyle_SOLID:
378 Color aBackCol = GetBackgroundColorFromItemSet(pItemSet);
379 if (aBackCol != COL_AUTO)
380 DrawContentBackground(rRenderContext, aContentRect, aBackCol);
382 break;
384 default:
385 break;
386 //TODO Draw the other background styles: gradient, hatching and bitmap
390 if (aFontHighlight != COL_AUTO)
391 DrawHighlight(rRenderContext, aFontHighlight);
393 DrawText(rRenderContext);
395 rRenderContext.SetFillColor(aOriginalColor);
396 rRenderContext.SetLineColor(aOriginalLineColor);
399 void StyleItemController::DrawContentBackground(vcl::RenderContext& rRenderContext,
400 const tools::Rectangle& aContentRect,
401 const Color& aColor)
403 rRenderContext.SetLineColor(aColor);
404 rRenderContext.SetFillColor(aColor);
405 rRenderContext.DrawRect(aContentRect);
408 void StyleItemController::DrawHighlight(vcl::RenderContext& rRenderContext, Color aFontBack)
410 tools::Rectangle aTextRect;
411 rRenderContext.GetTextBoundRect(aTextRect, m_aStyleName.second);
413 Size aSize = aTextRect.GetSize();
414 aSize.AdjustHeight(aSize.getHeight());
415 aTextRect.SetSize(aSize);
417 Point aPos(0, 0);
418 aPos.AdjustX(LEFT_MARGIN);
419 aPos.AdjustY((rRenderContext.GetOutputHeightPixel() - aTextRect.Bottom()) / 2);
420 aTextRect.SetPos(aPos);
422 rRenderContext.SetLineColor(aFontBack);
423 rRenderContext.SetFillColor(aFontBack);
425 rRenderContext.DrawRect(aTextRect);
428 void StyleItemController::DrawText(vcl::RenderContext& rRenderContext)
430 const SalLayoutGlyphs* layoutGlyphs
431 = SalLayoutGlyphsCache::self()->GetLayoutGlyphs(&rRenderContext, m_aStyleName.second);
432 tools::Rectangle aTextRect;
433 rRenderContext.GetTextBoundRect(aTextRect, m_aStyleName.second, 0, 0, -1, 0, {}, {},
434 layoutGlyphs);
436 Point aPos(0, 0);
437 aPos.AdjustX(LEFT_MARGIN);
438 aPos.AdjustY((rRenderContext.GetOutputHeightPixel() - aTextRect.Bottom()) / 2);
440 rRenderContext.DrawText(aPos, m_aStyleName.second, 0, -1, nullptr, nullptr, layoutGlyphs);
443 StylesPreviewWindow_Base::StylesPreviewWindow_Base(
444 weld::Builder& xBuilder, std::vector<std::pair<OUString, OUString>>&& aDefaultStyles,
445 const css::uno::Reference<css::frame::XFrame>& xFrame)
446 : m_xFrame(xFrame)
447 , m_xStylesView(xBuilder.weld_icon_view(u"stylesview"_ustr))
448 , m_aUpdateTask(*this)
449 , m_aDefaultStyles(std::move(aDefaultStyles))
451 StylePreviewCache::RegisterClient();
453 m_xStylesView->connect_selection_changed(LINK(this, StylesPreviewWindow_Base, Selected));
454 m_xStylesView->connect_item_activated(LINK(this, StylesPreviewWindow_Base, DoubleClick));
455 m_xStylesView->connect_command(LINK(this, StylesPreviewWindow_Base, DoCommand));
456 m_xStylesView->connect_get_image(LINK(this, StylesPreviewWindow_Base, GetPreviewImage));
458 const css::uno::Reference<css::frame::XDispatchProvider> xProvider(m_xFrame,
459 css::uno::UNO_QUERY);
460 m_xStatusListener = new StyleStatusListener(this, xProvider);
462 m_pStylePoolChangeListener.reset(new StylePoolChangeListener(this));
464 RequestStylesListUpdate();
467 IMPL_LINK(StylesPreviewWindow_Base, Selected, weld::IconView&, rIconView, void)
469 OUString sStyleName = rIconView.get_selected_text();
471 css::uno::Sequence<css::beans::PropertyValue> aArgs{
472 comphelper::makePropertyValue(u"Template"_ustr, sStyleName),
473 comphelper::makePropertyValue(u"Family"_ustr, sal_Int16(SfxStyleFamily::Para))
475 const css::uno::Reference<css::frame::XDispatchProvider> xProvider(m_xFrame,
476 css::uno::UNO_QUERY);
477 SfxToolBoxControl::Dispatch(xProvider, u".uno:StyleApply"_ustr, aArgs);
480 IMPL_LINK(StylesPreviewWindow_Base, DoubleClick, weld::IconView&, rIconView, bool)
482 OUString sStyleName = rIconView.get_selected_text();
484 css::uno::Sequence<css::beans::PropertyValue> aArgs{
485 comphelper::makePropertyValue(u"Param"_ustr, sStyleName),
486 comphelper::makePropertyValue(u"Family"_ustr, sal_Int16(SfxStyleFamily::Para))
488 const css::uno::Reference<css::frame::XDispatchProvider> xProvider(m_xFrame,
489 css::uno::UNO_QUERY);
490 SfxToolBoxControl::Dispatch(xProvider, u".uno:EditStyle"_ustr, aArgs);
492 return true;
495 IMPL_LINK(StylesPreviewWindow_Base, DoCommand, const CommandEvent&, rPos, bool)
497 return Command(rPos);
500 StylesPreviewWindow_Base::~StylesPreviewWindow_Base()
502 m_xStatusListener->UnBind();
504 m_aUpdateTask.Stop();
506 StylePreviewCache::UnregisterClient();
510 m_xStatusListener->dispose();
512 catch (css::uno::Exception&)
516 m_xStatusListener = nullptr;
519 void StylesPreviewWindow_Base::Select(const OUString& rStyleName)
521 m_sSelectedStyle = rStyleName;
523 UpdateSelection();
526 void StylesPreviewWindow_Base::UpdateSelection()
528 for (std::vector<std::pair<OUString, OUString>>::size_type i = 0; i < m_aAllStyles.size(); ++i)
530 if (m_aAllStyles[i].first == m_sSelectedStyle || m_aAllStyles[i].second == m_sSelectedStyle)
532 m_xStylesView->select(i);
533 break;
538 void StylesPreviewWindow_Base::RequestStylesListUpdate() { m_aUpdateTask.Start(); }
540 void StylesListUpdateTask::Invoke()
542 m_rStylesList.UpdateStylesList();
543 m_rStylesList.UpdateSelection();
546 static OString extractPngString(const BitmapEx& rBitmap)
548 SvMemoryStream aOStm(65535, 65535);
549 // Use fastest compression "1"
550 css::uno::Sequence<css::beans::PropertyValue> aFilterData{
551 comphelper::makePropertyValue(u"Compression"_ustr, sal_Int32(1)),
553 vcl::PngImageWriter aPNGWriter(aOStm);
554 aPNGWriter.setParameters(aFilterData);
555 if (aPNGWriter.write(rBitmap))
557 css::uno::Sequence<sal_Int8> aSeq(static_cast<sal_Int8 const*>(aOStm.GetData()),
558 aOStm.Tell());
559 OStringBuffer aBuffer("data:image/png;base64,");
560 ::comphelper::Base64::encode(aBuffer, aSeq);
561 return aBuffer.makeStringAndClear();
564 return ""_ostr;
567 // 0: OUString, 1: TreeIter, returns true if supported
568 IMPL_LINK(StylesPreviewWindow_Base, GetPreviewImage, const weld::encoded_image_query&, rQuery, bool)
570 const weld::TreeIter& rIter = std::get<1>(rQuery);
571 OUString sStyleId(m_xStylesView->get_id(rIter));
572 OUString sStyleName(m_xStylesView->get_text(rIter));
573 OString sBase64Png(GetCachedPreviewJson(std::pair<OUString, OUString>(sStyleId, sStyleName)));
574 if (sBase64Png.isEmpty())
575 return false;
577 OUString& rResult = std::get<0>(rQuery);
578 rResult = OStringToOUString(sBase64Png, RTL_TEXTENCODING_ASCII_US);
580 return true;
583 VclPtr<VirtualDevice>
584 StylesPreviewWindow_Base::GetCachedPreview(const std::pair<OUString, OUString>& rStyle)
586 auto aFound = StylePreviewCache::Get().find(rStyle.second);
587 if (aFound != StylePreviewCache::Get().end())
588 return StylePreviewCache::Get()[rStyle.second];
589 else
591 VclPtr<VirtualDevice> pImg = VclPtr<VirtualDevice>::Create();
592 const Size aSize(100, 30);
593 pImg->SetOutputSizePixel(aSize);
595 StyleItemController aStyleController(rStyle);
596 aStyleController.Paint(*pImg);
597 StylePreviewCache::Get()[rStyle.second] = pImg;
599 return pImg;
603 OString StylesPreviewWindow_Base::GetCachedPreviewJson(const std::pair<OUString, OUString>& rStyle)
605 auto aJsonFound = StylePreviewCache::GetJson().find(rStyle.second);
606 if (aJsonFound != StylePreviewCache::GetJson().end())
607 return StylePreviewCache::GetJson()[rStyle.second];
609 VclPtr<VirtualDevice> xDev = GetCachedPreview(rStyle);
610 BitmapEx aBitmap(xDev->GetBitmapEx(Point(0, 0), xDev->GetOutputSize()));
611 OString sResult = extractPngString(aBitmap);
612 StylePreviewCache::GetJson()[rStyle.second] = sResult;
613 return sResult;
616 void StylesPreviewWindow_Base::UpdateStylesList()
618 m_aAllStyles = m_aDefaultStyles;
620 SfxObjectShell* pDocShell = SfxObjectShell::Current();
621 SfxStyleSheetBasePool* pStyleSheetPool = nullptr;
623 if (pDocShell)
624 pStyleSheetPool = pDocShell->GetStyleSheetPool();
626 if (pStyleSheetPool)
628 auto xIter = pStyleSheetPool->CreateIterator(SfxStyleFamily::Para,
629 SfxStyleSearchBits::UserDefined);
631 SfxStyleSheetBase* pStyle = xIter->First();
633 while (pStyle)
635 OUString sName(pStyle->GetName());
636 m_aAllStyles.push_back(std::pair<OUString, OUString>(sName, sName));
637 pStyle = xIter->Next();
641 m_xStylesView->freeze();
642 m_xStylesView->clear();
643 // for online we can skip inserting the preview into the IconView and rely
644 // on DoJsonProperty to provide the image to clients
645 const bool bNeedInsertPreview = !comphelper::LibreOfficeKit::isActive();
646 for (const auto& rStyle : m_aAllStyles)
648 VclPtr<VirtualDevice> pImg = bNeedInsertPreview ? GetCachedPreview(rStyle) : nullptr;
649 m_xStylesView->append(rStyle.first, rStyle.second, pImg);
651 m_xStylesView->thaw();
654 StylesPreviewWindow_Impl::StylesPreviewWindow_Impl(
655 vcl::Window* pParent, std::vector<std::pair<OUString, OUString>>&& aDefaultStyles,
656 const css::uno::Reference<css::frame::XFrame>& xFrame)
657 : InterimItemWindow(pParent, u"svx/ui/stylespreview.ui"_ustr, u"ApplyStyleBox"_ustr, true,
658 reinterpret_cast<sal_uInt64>(SfxViewShell::Current()))
659 , StylesPreviewWindow_Base(*m_xBuilder, std::move(aDefaultStyles), xFrame)
661 SetOptimalSize();
664 StylesPreviewWindow_Impl::~StylesPreviewWindow_Impl() { disposeOnce(); }
666 void StylesPreviewWindow_Impl::dispose()
668 m_xStylesView.reset();
670 InterimItemWindow::dispose();
673 void StylesPreviewWindow_Impl::SetOptimalSize() { SetSizePixel(get_preferred_size()); }
675 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */