30#include <sfx2/sfxsids.hrc>
38#include <editeng/editids.hrc>
60#include <com/sun/star/drawing/FillStyle.hpp>
61#include <com/sun/star/i18n/ScriptType.hpp>
62#include <com/sun/star/uno/Sequence.hxx>
69class StylePreviewCache
72 class JsonStylePreviewCacheClear final :
public Timer
75 JsonStylePreviewCacheClear()
76 :
Timer(
"Json Style Preview Cache clear callback")
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;
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();
102 StylePreviewCache::gJsonStylePreviewCache.clear();
103 gJsonIdleClear.Stop();
108 gJsonIdleClear.Start();
112 static void RegisterClient()
114 if (!gStylePreviewCacheClients)
115 gJsonIdleClear.Stop();
116 gStylePreviewCacheClients++;
119 static void UnregisterClient()
121 gStylePreviewCacheClients--;
122 if (!gStylePreviewCacheClients)
127std::map<OUString, VclPtr<VirtualDevice>> StylePreviewCache::gStylePreviewCache;
128std::map<OUString, OString> StylePreviewCache::gJsonStylePreviewCache;
129int StylePreviewCache::gStylePreviewCacheClients;
130StylePreviewCache::JsonStylePreviewCacheClear StylePreviewCache::gJsonIdleClear;
135 const css::uno::Reference<css::frame::XDispatchProvider>& xDispatchProvider)
137 , m_pPreviewControl(pPreviewControl)
156 : m_pPreviewControl(pPreviewControl)
176 if (rHint.
GetId() == SfxHintId::StyleSheetModified)
177 StylePreviewCache::ClearCache(
true);
183 , m_aStyleName(
std::move(aStyleName))
194 rRenderContext.
Pop();
199 if (rEvent.
GetCommand() != CommandEventId::ContextMenu)
202 std::unique_ptr<weld::Builder> xBuilder(
204 std::unique_ptr<weld::Menu> xMenu(xBuilder->weld_menu(
"menu"));
207 if (rIdent ==
"update" || rIdent ==
"edit")
209 css::uno::Sequence<css::beans::PropertyValue> aArgs(0);
211 const css::uno::Reference<css::frame::XDispatchProvider> xProvider(
m_xFrame,
212 css::uno::UNO_QUERY);
214 rIdent ==
"update" ? OUString(
".uno:StyleUpdateByExample")
215 : OUString(
".uno:EditStyle"),
226 const SfxPoolItem* pItem = pItemSet->GetItem(SID_ATTR_CHAR_COLOR);
235 const SfxPoolItem* pItem = pItemSet->GetItem(SID_ATTR_BRUSH_CHAR);
237 return static_cast<const SvxBrushItem*
>(pItem)->GetColor();
246 return static_cast<const XFillColorItem*
>(pItem)->GetColorValue();
257 return css::drawing::FillStyle_NONE;
261 std::optional<SfxItemSet>
const& pItemSet)
267 aFont.SetFontSize(aPixelFontSize);
269 const SfxPoolItem* pItem = pItemSet->GetItem(SID_ATTR_CHAR_WEIGHT);
271 aFont.SetWeight(
static_cast<const SvxWeightItem*
>(pItem)->GetWeight());
273 pItem = pItemSet->GetItem(SID_ATTR_CHAR_POSTURE);
275 aFont.SetItalic(
static_cast<const SvxPostureItem*
>(pItem)->GetPosture());
277 pItem = pItemSet->GetItem(SID_ATTR_CHAR_CONTOUR);
281 pItem = pItemSet->GetItem(SID_ATTR_CHAR_SHADOWED);
285 pItem = pItemSet->GetItem(SID_ATTR_CHAR_RELIEF);
289 pItem = pItemSet->GetItem(SID_ATTR_CHAR_UNDERLINE);
291 aFont.SetUnderline(
static_cast<const SvxUnderlineItem*
>(pItem)->GetLineStyle());
293 pItem = pItemSet->GetItem(SID_ATTR_CHAR_OVERLINE);
297 pItem = pItemSet->GetItem(SID_ATTR_CHAR_STRIKEOUT);
299 aFont.SetStrikeout(
static_cast<const SvxCrossedOutItem*
>(pItem)->GetStrikeout());
301 pItem = pItemSet->GetItem(SID_ATTR_CHAR_CASEMAP);
305 pItem = pItemSet->GetItem(SID_ATTR_CHAR_EMPHASISMARK);
327 pStyle = pPool->
Next();
347 sal_Int16 nScriptType
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;
360 if (pFontItem && pFontHeightItem)
362 Size aFontSize(0, pFontHeightItem->GetHeight());
378 case css::drawing::FillStyle_SOLID:
407 rRenderContext.
DrawRect(aContentRect);
446 weld::Builder& xBuilder, std::vector<std::pair<OUString, OUString>>&& aDefaultStyles,
447 const css::uno::Reference<css::frame::XFrame>& xFrame)
449 , m_xStylesView(xBuilder.weld_icon_view(
"stylesview"))
450 , m_aUpdateTask(*this)
451 , m_aDefaultStyles(
std::move(aDefaultStyles))
453 StylePreviewCache::RegisterClient();
461 const css::uno::Reference<css::frame::XDispatchProvider> xProvider(
m_xFrame,
462 css::uno::UNO_QUERY);
472 OUString sStyleName = rIconView.get_selected_text();
474 css::uno::Sequence<css::beans::PropertyValue> aArgs{
478 const css::uno::Reference<css::frame::XDispatchProvider> xProvider(
m_xFrame,
479 css::uno::UNO_QUERY);
485 OUString sStyleName = rIconView.get_selected_text();
487 css::uno::Sequence<css::beans::PropertyValue> aArgs{
491 const css::uno::Reference<css::frame::XDispatchProvider> xProvider(
m_xFrame,
492 css::uno::UNO_QUERY);
500 return Command(rPos);
509 StylePreviewCache::UnregisterClient();
515 catch (css::uno::Exception&)
531 for (std::vector<std::pair<OUString, OUString>>::size_type
i = 0;
i <
m_aAllStyles.size(); ++
i)
553 css::uno::Sequence<css::beans::PropertyValue> aFilterData{
558 if (aPNGWriter.
write(rBitmap))
562 OStringBuffer
aBuffer(
"data:image/png;base64,");
564 return aBuffer.makeStringAndClear();
573 if (std::get<2>(rQuery) !=
"image")
577 OUString sStyleId(m_xStylesView->get_id(rIter));
578 OUString sStyleName(m_xStylesView->get_text(rIter));
579 OString sBase64Png(GetCachedPreviewJson(std::pair<OUString, OUString>(sStyleId, sStyleName)));
580 if (sBase64Png.isEmpty())
584 rJsonWriter.
put(
"image", sBase64Png);
598 const Size aSize(100, 30);
599 pImg->SetOutputSizePixel(aSize);
602 aStyleController.
Paint(*pImg);
611 auto aJsonFound = StylePreviewCache::GetJson().find(rStyle.second);
612 if (aJsonFound != StylePreviewCache::GetJson().
end())
613 return StylePreviewCache::GetJson()[rStyle.second];
616 BitmapEx aBitmap(xDev->GetBitmapEx(
Point(0, 0), xDev->GetOutputSize()));
618 StylePreviewCache::GetJson()[rStyle.second] = sResult;
634 auto xIter = pStyleSheetPool->
CreateIterator(SfxStyleFamily::Para,
635 SfxStyleSearchBits::UserDefined);
643 pStyle = xIter->Next();
661 vcl::Window* pParent, std::vector<std::pair<OUString, OUString>>&& aDefaultStyles,
662 const css::uno::Reference<css::frame::XFrame>& xFrame)
static Color GetTextColorFromItemSet(std::optional< SfxItemSet > const &pItemSet)
static OString extractPngString(const BitmapEx &rBitmap)
IMPL_LINK(StylesPreviewWindow_Base, Selected, weld::IconView &, rIconView, void)
static css::drawing::FillStyle GetFillStyleFromItemSet(std::optional< SfxItemSet > const &pItemSet)
static SvxFont GetFontFromItems(const SvxFontItem *pFontItem, Size aPixelFontSize, std::optional< SfxItemSet > const &pItemSet)
static Color GetHighlightColorFromItemSet(std::optional< SfxItemSet > const &pItemSet)
static Color GetBackgroundColorFromItemSet(std::optional< SfxItemSet > const &pItemSet)
css::uno::Reference< css::lang::XComponent > m_xFrame
static const AllSettings & GetSettings()
static std::unique_ptr< weld::Builder > CreateBuilder(weld::Widget *pParent, const OUString &rUIFile, bool bMobile=false, sal_uInt64 nLOKWindowId=0)
CommandEventId GetCommand() const
const Point & GetMousePosPixel() const
virtual void Start(bool bStartTimer=true) override
virtual void dispose() override
static sal_Int16 getScriptType(LanguageType nLang)
void SetFont(const vcl::Font &rNewFont)
Size GetOutputSizePixel() const
void DrawRect(const tools::Rectangle &rRect)
tools::Long GetOutputHeightPixel() const
bool GetTextBoundRect(tools::Rectangle &rRect, const OUString &rStr, sal_Int32 nBase=0, sal_Int32 nIndex=0, sal_Int32 nLen=-1, sal_uLong nLayoutWidth=0, KernArraySpan aDXArray=KernArraySpan(), o3tl::span< const sal_Bool > pKashidaArray={}, const SalLayoutGlyphs *pGlyphs=nullptr) const
void SetTextColor(const Color &rColor)
SAL_WARN_UNUSED_RESULT Point LogicToPixel(const Point &rLogicPt) const
const Color & GetLineColor() const
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
void DrawText(const Point &rStartPt, const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, std::vector< tools::Rectangle > *pVector=nullptr, OUString *pDisplayText=nullptr, const SalLayoutGlyphs *pLayoutCache=nullptr)
const Color & GetFillColor() const
tools::Long AdjustY(tools::Long nVertMove)
tools::Long AdjustX(tools::Long nHorzMove)
static SalLayoutGlyphsCache * self()
const SalLayoutGlyphs * GetLayoutGlyphs(VclPtr< const OutputDevice > outputDevice, const OUString &text, const vcl::text::TextLayoutCache *layoutCache=nullptr)
void StartListening(SfxBroadcaster &rBroadcaster, DuplicateHandling eDuplicateHanding=DuplicateHandling::Unexpected)
void EndListening(SfxBroadcaster &rBroadcaster, bool bRemoveAllDuplicates=false)
virtual SfxStyleSheetBasePool * GetStyleSheetPool()
MapUnit GetMapUnit() const
static SAL_WARN_UNUSED_RESULT SfxObjectShell * Current()
SfxStyleSheetBase * First(SfxStyleFamily eFamily, SfxStyleSearchBits eMask=SfxStyleSearchBits::All)
virtual std::unique_ptr< SfxStyleSheetIterator > CreateIterator(SfxStyleFamily, SfxStyleSearchBits nMask=SfxStyleSearchBits::All)
SfxStyleSheetBase * Next()
const OUString & GetName() const
virtual std::optional< SfxItemSet > GetItemSetForPreview()
const OUString & GetStyleName() const
const OUString & GetStyleIdentifier() const
constexpr tools::Long getHeight() const
tools::Long AdjustHeight(tools::Long n)
void DrawHighlight(vcl::RenderContext &rRenderContext, Color aFontBack)
void Paint(vcl::RenderContext &rRenderContext)
void DrawText(vcl::RenderContext &rRenderContext)
StyleItemController(std::pair< OUString, OUString > aStyleName)
static void DrawContentBackground(vcl::RenderContext &rRenderContext, const tools::Rectangle &aContentRect, const Color &aColor)
void DrawEntry(vcl::RenderContext &rRenderContext)
static constexpr unsigned LEFT_MARGIN
SfxStyleFamily m_eStyleFamily
std::pair< OUString, OUString > m_aStyleName
Listener for styles creation or modification.
~StylePoolChangeListener()
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
StylesPreviewWindow_Base * m_pPreviewControl
StylePoolChangeListener(StylesPreviewWindow_Base *pPreviewControl)
SfxStyleSheetBasePool * m_pStyleSheetPool
Listener for style selection.
StyleStatusListener(StylesPreviewWindow_Base *pPreviewControl, const css::uno::Reference< css::frame::XDispatchProvider > &xDispatchProvider)
void StateChangedAtStatusListener(SfxItemState eState, const SfxPoolItem *pState) override
StylesPreviewWindow_Base * m_pPreviewControl
virtual void Invoke() override
StylesPreviewWindow_Base & m_rStylesList
StylesPreviewWindow_Base(weld::Builder &xBuilder, std::vector< std::pair< OUString, OUString > > &&aDefaultStyles, const css::uno::Reference< css::frame::XFrame > &xFrame)
std::vector< std::pair< OUString, OUString > > m_aDefaultStyles
void RequestStylesListUpdate()
StylesListUpdateTask m_aUpdateTask
OUString m_sSelectedStyle
~StylesPreviewWindow_Base()
std::unique_ptr< weld::IconView > m_xStylesView
static OString GetCachedPreviewJson(const std::pair< OUString, OUString > &rStyle)
css::uno::Reference< css::frame::XFrame > m_xFrame
std::vector< std::pair< OUString, OUString > > m_aAllStyles
bool Command(const CommandEvent &rEvent)
static VclPtr< VirtualDevice > GetCachedPreview(const std::pair< OUString, OUString > &rStyle)
void Select(const OUString &rStyleName)
rtl::Reference< StyleStatusListener > m_xStatusListener
std::unique_ptr< StylePoolChangeListener > m_pStylePoolChangeListener
~StylesPreviewWindow_Impl()
StylesPreviewWindow_Impl(vcl::Window *pParent, std::vector< std::pair< OUString, OUString > > &&aDefaultStyles, const css::uno::Reference< css::frame::XFrame > &xFrame)
const OUString & GetStyleName() const
const OUString & GetFamilyName() const
void SetCaseMap(const SvxCaseMap eNew)
static VclPtr< reference_type > Create(Arg &&... arg)
static void encode(OUStringBuffer &aStrBuffer, const css::uno::Sequence< sal_Int8 > &aPass)
void setParameters(css::uno::Sequence< css::beans::PropertyValue > const &rParameters)
bool write(const BitmapEx &rBitmap)
virtual void SetSizePixel(const Size &rNewSize)
Size get_preferred_size() const
constexpr ::Color COL_AUTO(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
STDMETHOD() Get(VARIANT *val)=0
#define LINK(Instance, Class, Member)
Sequence< sal_Int8 > aSeq
SVXCORE_DLLPUBLIC MSO_SPT Get(const OUString &)
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
constexpr OUStringLiteral first
sal_Int16 GetCaseMap(sal_Int32 nToken)
std::tuple< tools::JsonWriter &, const TreeIter &, std::string_view > json_prop_query
Reference< XFrame > xFrame
std::unique_ptr< char[]> aBuffer
constexpr TypedWhichId< XFillColorItem > XATTR_FILLCOLOR(XATTR_FILL_FIRST+1)
constexpr TypedWhichId< XFillStyleItem > XATTR_FILLSTYLE(XATTR_FILL_FIRST)