Add a comment about possible use of standard functions, when/if available
[LibreOffice.git] / svx / source / tbxctrls / StylesPreviewWindow.cxx
blobfafeaf71cedddb8be243bfce7ae7b3f2030e334b
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>
62 #include <com/sun/star/uno/Sequence.hxx>
64 #include <vcl/commandevent.hxx>
65 #include <tools/json_writer.hxx>
67 namespace
69 class StylePreviewCache
71 private:
72 class JsonStylePreviewCacheClear final : public Timer
74 public:
75 JsonStylePreviewCacheClear()
76 : Timer("Json Style Preview Cache clear callback")
78 // a generous 30 secs
79 SetTimeout(30000);
80 SetStatic();
82 virtual void Invoke() override { StylePreviewCache::gJsonStylePreviewCache.clear(); }
85 static std::map<OUString, VclPtr<VirtualDevice>> gStylePreviewCache;
86 static std::map<OUString, OString> gJsonStylePreviewCache;
87 static int gStylePreviewCacheClients;
88 static JsonStylePreviewCacheClear gJsonIdleClear;
90 public:
91 static std::map<OUString, VclPtr<VirtualDevice>>& Get() { return gStylePreviewCache; }
92 static std::map<OUString, OString>& GetJson() { return gJsonStylePreviewCache; }
94 static void ClearCache(bool bHard)
96 for (auto& aPreview : gStylePreviewCache)
97 aPreview.second.disposeAndClear();
99 gStylePreviewCache.clear();
100 if (bHard)
102 StylePreviewCache::gJsonStylePreviewCache.clear();
103 gJsonIdleClear.Stop();
105 else
107 // tdf#155720 don't immediately clear the json representation
108 gJsonIdleClear.Start();
112 static void RegisterClient()
114 if (!gStylePreviewCacheClients)
115 gJsonIdleClear.Stop();
116 gStylePreviewCacheClients++;
119 static void UnregisterClient()
121 gStylePreviewCacheClients--;
122 if (!gStylePreviewCacheClients)
123 ClearCache(false);
127 std::map<OUString, VclPtr<VirtualDevice>> StylePreviewCache::gStylePreviewCache;
128 std::map<OUString, OString> StylePreviewCache::gJsonStylePreviewCache;
129 int StylePreviewCache::gStylePreviewCacheClients;
130 StylePreviewCache::JsonStylePreviewCacheClear StylePreviewCache::gJsonIdleClear;
133 StyleStatusListener::StyleStatusListener(
134 StylesPreviewWindow_Base* pPreviewControl,
135 const css::uno::Reference<css::frame::XDispatchProvider>& xDispatchProvider)
136 : SfxStatusListener(xDispatchProvider, SID_STYLE_FAMILY2, u".uno:ParaStyle"_ustr)
137 , m_pPreviewControl(pPreviewControl)
139 ReBind();
142 void StyleStatusListener::StateChangedAtStatusListener(SfxItemState /*eState*/,
143 const SfxPoolItem* pState)
145 const SfxTemplateItem* pStateItem = dynamic_cast<const SfxTemplateItem*>(pState);
146 if (pStateItem)
148 if (pStateItem->GetStyleIdentifier().isEmpty())
149 m_pPreviewControl->Select(pStateItem->GetStyleName());
150 else
151 m_pPreviewControl->Select(pStateItem->GetStyleIdentifier());
155 StylePoolChangeListener::StylePoolChangeListener(StylesPreviewWindow_Base* pPreviewControl)
156 : m_pPreviewControl(pPreviewControl)
158 SfxObjectShell* pDocShell = SfxObjectShell::Current();
160 m_pStyleSheetPool = pDocShell ? pDocShell->GetStyleSheetPool() : nullptr;
162 if (m_pStyleSheetPool)
164 StartListening(*m_pStyleSheetPool);
168 StylePoolChangeListener::~StylePoolChangeListener()
170 if (m_pStyleSheetPool)
171 EndListening(*m_pStyleSheetPool);
174 void StylePoolChangeListener::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& rHint)
176 if (rHint.GetId() == SfxHintId::StyleSheetModified
177 || rHint.GetId() == SfxHintId::StyleSheetModifiedExtended)
178 StylePreviewCache::ClearCache(true);
179 m_pPreviewControl->RequestStylesListUpdate();
182 StyleItemController::StyleItemController(std::pair<OUString, OUString> aStyleName)
183 : m_eStyleFamily(SfxStyleFamily::Para)
184 , m_aStyleName(std::move(aStyleName))
188 void StyleItemController::Paint(vcl::RenderContext& rRenderContext)
190 rRenderContext.Push(vcl::PushFlags::FILLCOLOR | vcl::PushFlags::FONT
191 | vcl::PushFlags::TEXTCOLOR);
193 DrawEntry(rRenderContext);
195 rRenderContext.Pop();
198 bool StylesPreviewWindow_Base::Command(const CommandEvent& rEvent)
200 if (rEvent.GetCommand() != CommandEventId::ContextMenu)
201 return false;
203 std::unique_ptr<weld::Builder> xBuilder(
204 Application::CreateBuilder(m_xStylesView.get(), u"svx/ui/stylemenu.ui"_ustr));
205 std::unique_ptr<weld::Menu> xMenu(xBuilder->weld_menu(u"menu"_ustr));
206 OUString rIdent = xMenu->popup_at_rect(m_xStylesView.get(),
207 tools::Rectangle(rEvent.GetMousePosPixel(), Size(1, 1)));
208 if (rIdent == "update" || rIdent == "edit")
210 css::uno::Sequence<css::beans::PropertyValue> aArgs(0);
212 const css::uno::Reference<css::frame::XDispatchProvider> xProvider(m_xFrame,
213 css::uno::UNO_QUERY);
214 SfxToolBoxControl::Dispatch(
215 xProvider,
216 rIdent == "update" ? u".uno:StyleUpdateByExample"_ustr : u".uno:EditStyle"_ustr, aArgs);
218 return true;
221 return false;
224 static Color GetTextColorFromItemSet(std::optional<SfxItemSet> const& pItemSet)
226 const SfxPoolItem* pItem = pItemSet->GetItem(SID_ATTR_CHAR_COLOR);
227 if (pItem)
228 return static_cast<const SvxColorItem*>(pItem)->GetValue();
230 return COL_AUTO;
233 static Color GetHighlightColorFromItemSet(std::optional<SfxItemSet> const& pItemSet)
235 const SfxPoolItem* pItem = pItemSet->GetItem(SID_ATTR_BRUSH_CHAR);
236 if (pItem)
237 return static_cast<const SvxBrushItem*>(pItem)->GetColor();
239 return COL_AUTO;
242 static Color GetBackgroundColorFromItemSet(std::optional<SfxItemSet> const& pItemSet)
244 const SfxPoolItem* pItem = pItemSet->GetItem(XATTR_FILLCOLOR);
245 if (pItem)
246 return static_cast<const XFillColorItem*>(pItem)->GetColorValue();
248 return COL_AUTO;
251 static css::drawing::FillStyle GetFillStyleFromItemSet(std::optional<SfxItemSet> const& pItemSet)
253 const SfxPoolItem* pItem = pItemSet->GetItem(XATTR_FILLSTYLE);
254 if (pItem)
255 return static_cast<const XFillStyleItem*>(pItem)->GetValue();
257 return css::drawing::FillStyle_NONE;
260 static SvxFont GetFontFromItems(const SvxFontItem* pFontItem, Size aPixelFontSize,
261 std::optional<SfxItemSet> const& pItemSet)
263 SvxFont aFont;
265 aFont.SetFamilyName(pFontItem->GetFamilyName());
266 aFont.SetStyleName(pFontItem->GetStyleName());
267 aFont.SetFontSize(aPixelFontSize);
269 const SfxPoolItem* pItem = pItemSet->GetItem(SID_ATTR_CHAR_WEIGHT);
270 if (pItem)
271 aFont.SetWeight(static_cast<const SvxWeightItem*>(pItem)->GetWeight());
273 pItem = pItemSet->GetItem(SID_ATTR_CHAR_POSTURE);
274 if (pItem)
275 aFont.SetItalic(static_cast<const SvxPostureItem*>(pItem)->GetPosture());
277 pItem = pItemSet->GetItem(SID_ATTR_CHAR_CONTOUR);
278 if (pItem)
279 aFont.SetOutline(static_cast<const SvxContourItem*>(pItem)->GetValue());
281 pItem = pItemSet->GetItem(SID_ATTR_CHAR_SHADOWED);
282 if (pItem)
283 aFont.SetShadow(static_cast<const SvxShadowedItem*>(pItem)->GetValue());
285 pItem = pItemSet->GetItem(SID_ATTR_CHAR_RELIEF);
286 if (pItem)
287 aFont.SetRelief(static_cast<const SvxCharReliefItem*>(pItem)->GetValue());
289 pItem = pItemSet->GetItem(SID_ATTR_CHAR_UNDERLINE);
290 if (pItem)
291 aFont.SetUnderline(static_cast<const SvxUnderlineItem*>(pItem)->GetLineStyle());
293 pItem = pItemSet->GetItem(SID_ATTR_CHAR_OVERLINE);
294 if (pItem)
295 aFont.SetOverline(static_cast<const SvxOverlineItem*>(pItem)->GetValue());
297 pItem = pItemSet->GetItem(SID_ATTR_CHAR_STRIKEOUT);
298 if (pItem)
299 aFont.SetStrikeout(static_cast<const SvxCrossedOutItem*>(pItem)->GetStrikeout());
301 pItem = pItemSet->GetItem(SID_ATTR_CHAR_CASEMAP);
302 if (pItem)
303 aFont.SetCaseMap(static_cast<const SvxCaseMapItem*>(pItem)->GetCaseMap());
305 pItem = pItemSet->GetItem(SID_ATTR_CHAR_EMPHASISMARK);
306 if (pItem)
307 aFont.SetEmphasisMark(static_cast<const SvxEmphasisMarkItem*>(pItem)->GetEmphasisMark());
309 return aFont;
312 void StyleItemController::DrawEntry(vcl::RenderContext& rRenderContext)
314 SfxObjectShell* pShell = SfxObjectShell::Current();
315 if (!pShell)
316 return;
318 SfxStyleSheetBasePool* pPool = pShell->GetStyleSheetPool();
319 SfxStyleSheetBase* pStyle = nullptr;
321 if (!pPool)
322 return;
324 pStyle = pPool->First(m_eStyleFamily);
325 while (pStyle && pStyle->GetName() != m_aStyleName.first
326 && pStyle->GetName() != m_aStyleName.second)
327 pStyle = pPool->Next();
329 if (!pStyle)
330 return;
332 Size aSize(rRenderContext.GetOutputSizePixel());
333 tools::Rectangle aFullRect(Point(0, 0), aSize);
334 tools::Rectangle aContentRect(aFullRect);
336 Color aOriginalColor = rRenderContext.GetFillColor();
337 Color aOriginalLineColor = rRenderContext.GetLineColor();
339 DrawContentBackground(rRenderContext, aContentRect, aOriginalColor);
341 std::optional<SfxItemSet> const pItemSet(pStyle->GetItemSetForPreview());
342 if (!pItemSet)
343 return;
345 Color aFontHighlight = COL_AUTO;
347 sal_Int16 nScriptType
348 = MsLangId::getScriptType(Application::GetSettings().GetUILanguageTag().getLanguageType());
350 sal_uInt16 nFontSlot = SID_ATTR_CHAR_FONT;
351 if (nScriptType == css::i18n::ScriptType::ASIAN)
352 nFontSlot = SID_ATTR_CHAR_CJK_FONT;
353 else if (nScriptType == css::i18n::ScriptType::COMPLEX)
354 nFontSlot = SID_ATTR_CHAR_CTL_FONT;
356 const SvxFontItem* const pFontItem = pItemSet->GetItem<SvxFontItem>(nFontSlot);
357 const SvxFontHeightItem* const pFontHeightItem
358 = pItemSet->GetItem<SvxFontHeightItem>(SID_ATTR_CHAR_FONTHEIGHT);
360 if (pFontItem && pFontHeightItem)
362 Size aFontSize(0, pFontHeightItem->GetHeight());
363 Size aPixelSize(rRenderContext.LogicToPixel(aFontSize, MapMode(pShell->GetMapUnit())));
365 SvxFont aFont = GetFontFromItems(pFontItem, aPixelSize, pItemSet);
366 rRenderContext.SetFont(aFont);
368 Color aFontCol = GetTextColorFromItemSet(pItemSet);
369 if (aFontCol != COL_AUTO)
370 rRenderContext.SetTextColor(aFontCol);
372 aFontHighlight = GetHighlightColorFromItemSet(pItemSet);
374 css::drawing::FillStyle style = GetFillStyleFromItemSet(pItemSet);
376 switch (style)
378 case css::drawing::FillStyle_SOLID:
380 Color aBackCol = GetBackgroundColorFromItemSet(pItemSet);
381 if (aBackCol != COL_AUTO)
382 DrawContentBackground(rRenderContext, aContentRect, aBackCol);
384 break;
386 default:
387 break;
388 //TODO Draw the other background styles: gradient, hatching and bitmap
392 if (aFontHighlight != COL_AUTO)
393 DrawHighlight(rRenderContext, aFontHighlight);
395 DrawText(rRenderContext);
397 rRenderContext.SetFillColor(aOriginalColor);
398 rRenderContext.SetLineColor(aOriginalLineColor);
401 void StyleItemController::DrawContentBackground(vcl::RenderContext& rRenderContext,
402 const tools::Rectangle& aContentRect,
403 const Color& aColor)
405 rRenderContext.SetLineColor(aColor);
406 rRenderContext.SetFillColor(aColor);
407 rRenderContext.DrawRect(aContentRect);
410 void StyleItemController::DrawHighlight(vcl::RenderContext& rRenderContext, Color aFontBack)
412 tools::Rectangle aTextRect;
413 rRenderContext.GetTextBoundRect(aTextRect, m_aStyleName.second);
415 Size aSize = aTextRect.GetSize();
416 aSize.AdjustHeight(aSize.getHeight());
417 aTextRect.SetSize(aSize);
419 Point aPos(0, 0);
420 aPos.AdjustX(LEFT_MARGIN);
421 aPos.AdjustY((rRenderContext.GetOutputHeightPixel() - aTextRect.Bottom()) / 2);
422 aTextRect.SetPos(aPos);
424 rRenderContext.SetLineColor(aFontBack);
425 rRenderContext.SetFillColor(aFontBack);
427 rRenderContext.DrawRect(aTextRect);
430 void StyleItemController::DrawText(vcl::RenderContext& rRenderContext)
432 const SalLayoutGlyphs* layoutGlyphs
433 = SalLayoutGlyphsCache::self()->GetLayoutGlyphs(&rRenderContext, m_aStyleName.second);
434 tools::Rectangle aTextRect;
435 rRenderContext.GetTextBoundRect(aTextRect, m_aStyleName.second, 0, 0, -1, 0, {}, {},
436 layoutGlyphs);
438 Point aPos(0, 0);
439 aPos.AdjustX(LEFT_MARGIN);
440 aPos.AdjustY((rRenderContext.GetOutputHeightPixel() - aTextRect.Bottom()) / 2);
442 rRenderContext.DrawText(aPos, m_aStyleName.second, 0, -1, nullptr, nullptr, layoutGlyphs);
445 StylesPreviewWindow_Base::StylesPreviewWindow_Base(
446 weld::Builder& xBuilder, std::vector<std::pair<OUString, OUString>>&& aDefaultStyles,
447 const css::uno::Reference<css::frame::XFrame>& xFrame)
448 : m_xFrame(xFrame)
449 , m_xStylesView(xBuilder.weld_icon_view(u"stylesview"_ustr))
450 , m_aUpdateTask(*this)
451 , m_aDefaultStyles(std::move(aDefaultStyles))
453 StylePreviewCache::RegisterClient();
455 m_xStylesView->connect_selection_changed(LINK(this, StylesPreviewWindow_Base, Selected));
456 m_xStylesView->connect_item_activated(LINK(this, StylesPreviewWindow_Base, DoubleClick));
457 m_xStylesView->connect_command(LINK(this, StylesPreviewWindow_Base, DoCommand));
458 m_xStylesView->connect_get_image(LINK(this, StylesPreviewWindow_Base, GetPreviewImage));
460 const css::uno::Reference<css::frame::XDispatchProvider> xProvider(m_xFrame,
461 css::uno::UNO_QUERY);
462 m_xStatusListener = new StyleStatusListener(this, xProvider);
464 m_pStylePoolChangeListener.reset(new StylePoolChangeListener(this));
466 RequestStylesListUpdate();
469 IMPL_LINK(StylesPreviewWindow_Base, Selected, weld::IconView&, rIconView, void)
471 OUString sStyleName = rIconView.get_selected_text();
473 css::uno::Sequence<css::beans::PropertyValue> aArgs{
474 comphelper::makePropertyValue(u"Template"_ustr, sStyleName),
475 comphelper::makePropertyValue(u"Family"_ustr, sal_Int16(SfxStyleFamily::Para))
477 const css::uno::Reference<css::frame::XDispatchProvider> xProvider(m_xFrame,
478 css::uno::UNO_QUERY);
479 SfxToolBoxControl::Dispatch(xProvider, u".uno:StyleApply"_ustr, aArgs);
482 IMPL_LINK(StylesPreviewWindow_Base, DoubleClick, weld::IconView&, rIconView, bool)
484 OUString sStyleName = rIconView.get_selected_text();
486 css::uno::Sequence<css::beans::PropertyValue> aArgs{
487 comphelper::makePropertyValue(u"Param"_ustr, sStyleName),
488 comphelper::makePropertyValue(u"Family"_ustr, sal_Int16(SfxStyleFamily::Para))
490 const css::uno::Reference<css::frame::XDispatchProvider> xProvider(m_xFrame,
491 css::uno::UNO_QUERY);
492 SfxToolBoxControl::Dispatch(xProvider, u".uno:EditStyle"_ustr, aArgs);
494 return true;
497 IMPL_LINK(StylesPreviewWindow_Base, DoCommand, const CommandEvent&, rPos, bool)
499 return Command(rPos);
502 StylesPreviewWindow_Base::~StylesPreviewWindow_Base()
504 m_xStatusListener->UnBind();
506 m_aUpdateTask.Stop();
508 StylePreviewCache::UnregisterClient();
512 m_xStatusListener->dispose();
514 catch (css::uno::Exception&)
518 m_xStatusListener = nullptr;
521 void StylesPreviewWindow_Base::Select(const OUString& rStyleName)
523 m_sSelectedStyle = rStyleName;
525 UpdateSelection();
528 void StylesPreviewWindow_Base::UpdateSelection()
530 for (std::vector<std::pair<OUString, OUString>>::size_type i = 0; i < m_aAllStyles.size(); ++i)
532 if (m_aAllStyles[i].first == m_sSelectedStyle || m_aAllStyles[i].second == m_sSelectedStyle)
534 m_xStylesView->select(i);
535 break;
540 void StylesPreviewWindow_Base::RequestStylesListUpdate() { m_aUpdateTask.Start(); }
542 void StylesListUpdateTask::Invoke()
544 m_rStylesList.UpdateStylesList();
545 m_rStylesList.UpdateSelection();
548 static OString extractPngString(const BitmapEx& rBitmap)
550 SvMemoryStream aOStm(65535, 65535);
551 // Use fastest compression "1"
552 css::uno::Sequence<css::beans::PropertyValue> aFilterData{
553 comphelper::makePropertyValue(u"Compression"_ustr, sal_Int32(1)),
555 vcl::PngImageWriter aPNGWriter(aOStm);
556 aPNGWriter.setParameters(aFilterData);
557 if (aPNGWriter.write(rBitmap))
559 css::uno::Sequence<sal_Int8> aSeq(static_cast<sal_Int8 const*>(aOStm.GetData()),
560 aOStm.Tell());
561 OStringBuffer aBuffer("data:image/png;base64,");
562 ::comphelper::Base64::encode(aBuffer, aSeq);
563 return aBuffer.makeStringAndClear();
566 return ""_ostr;
569 // 0: OUString, 1: TreeIter, returns true if supported
570 IMPL_LINK(StylesPreviewWindow_Base, GetPreviewImage, const weld::encoded_image_query&, rQuery, bool)
572 const weld::TreeIter& rIter = std::get<1>(rQuery);
573 OUString sStyleId(m_xStylesView->get_id(rIter));
574 OUString sStyleName(m_xStylesView->get_text(rIter));
575 OString sBase64Png(GetCachedPreviewJson(std::pair<OUString, OUString>(sStyleId, sStyleName)));
576 if (sBase64Png.isEmpty())
577 return false;
579 OUString& rResult = std::get<0>(rQuery);
580 rResult = OStringToOUString(sBase64Png, RTL_TEXTENCODING_ASCII_US);
582 return true;
585 VclPtr<VirtualDevice>
586 StylesPreviewWindow_Base::GetCachedPreview(const std::pair<OUString, OUString>& rStyle)
588 auto aFound = StylePreviewCache::Get().find(rStyle.second);
589 if (aFound != StylePreviewCache::Get().end())
590 return StylePreviewCache::Get()[rStyle.second];
591 else
593 VclPtr<VirtualDevice> pImg = VclPtr<VirtualDevice>::Create();
594 const Size aSize(100, 30);
595 pImg->SetOutputSizePixel(aSize);
597 StyleItemController aStyleController(rStyle);
598 aStyleController.Paint(*pImg);
599 StylePreviewCache::Get()[rStyle.second] = pImg;
601 return pImg;
605 OString StylesPreviewWindow_Base::GetCachedPreviewJson(const std::pair<OUString, OUString>& rStyle)
607 auto aJsonFound = StylePreviewCache::GetJson().find(rStyle.second);
608 if (aJsonFound != StylePreviewCache::GetJson().end())
609 return StylePreviewCache::GetJson()[rStyle.second];
611 VclPtr<VirtualDevice> xDev = GetCachedPreview(rStyle);
612 BitmapEx aBitmap(xDev->GetBitmapEx(Point(0, 0), xDev->GetOutputSize()));
613 OString sResult = extractPngString(aBitmap);
614 StylePreviewCache::GetJson()[rStyle.second] = sResult;
615 return sResult;
618 void StylesPreviewWindow_Base::UpdateStylesList()
620 m_aAllStyles = m_aDefaultStyles;
622 SfxObjectShell* pDocShell = SfxObjectShell::Current();
623 SfxStyleSheetBasePool* pStyleSheetPool = nullptr;
625 if (pDocShell)
626 pStyleSheetPool = pDocShell->GetStyleSheetPool();
628 if (pStyleSheetPool)
630 auto xIter = pStyleSheetPool->CreateIterator(SfxStyleFamily::Para,
631 SfxStyleSearchBits::UserDefined);
633 SfxStyleSheetBase* pStyle = xIter->First();
635 while (pStyle)
637 OUString sName(pStyle->GetName());
638 m_aAllStyles.push_back(std::pair<OUString, OUString>(sName, sName));
639 pStyle = xIter->Next();
643 m_xStylesView->freeze();
644 m_xStylesView->clear();
645 // for online we can skip inserting the preview into the IconView and rely
646 // on DoJsonProperty to provide the image to clients
647 const bool bNeedInsertPreview = !comphelper::LibreOfficeKit::isActive();
648 for (const auto& rStyle : m_aAllStyles)
650 VclPtr<VirtualDevice> pImg = bNeedInsertPreview ? GetCachedPreview(rStyle) : nullptr;
651 m_xStylesView->append(rStyle.first, rStyle.second, pImg);
653 m_xStylesView->thaw();
656 StylesPreviewWindow_Impl::StylesPreviewWindow_Impl(
657 vcl::Window* pParent, std::vector<std::pair<OUString, OUString>>&& aDefaultStyles,
658 const css::uno::Reference<css::frame::XFrame>& xFrame)
659 : InterimItemWindow(pParent, u"svx/ui/stylespreview.ui"_ustr, u"ApplyStyleBox"_ustr, true,
660 reinterpret_cast<sal_uInt64>(SfxViewShell::Current()))
661 , StylesPreviewWindow_Base(*m_xBuilder, std::move(aDefaultStyles), xFrame)
663 SetOptimalSize();
666 StylesPreviewWindow_Impl::~StylesPreviewWindow_Impl() { disposeOnce(); }
668 void StylesPreviewWindow_Impl::dispose()
670 m_xStylesView.reset();
672 InterimItemWindow::dispose();
675 void StylesPreviewWindow_Impl::SetOptimalSize() { SetSizePixel(get_preferred_size()); }
677 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */