LibreOffice Module svx (master) 1
tbxcolorupdate.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <sfx2/sfxbasemodel.hxx>
21#include <sfx2/objsh.hxx>
22#include <svx/drawitem.hxx>
23#include <tbxcolorupdate.hxx>
24#include <svx/svxids.hrc>
25#include <svx/xdef.hxx>
26#include <svx/xlineit0.hxx>
27#include <svx/xlndsit.hxx>
28
29#include <utility>
31#include <vcl/gdimtf.hxx>
32#include <vcl/svapp.hxx>
33#include <vcl/toolbox.hxx>
34#include <vcl/virdev.hxx>
35#include <vcl/weld.hxx>
36#include <vcl/settings.hxx>
37
38#include <svx/strings.hrc>
39#include <svx/dialmgr.hxx>
40
41namespace svx
42{
43 ToolboxButtonColorUpdaterBase::ToolboxButtonColorUpdaterBase(bool bWideButton, OUString aCommandLabel,
44 OUString aCommandURL, sal_uInt16 nSlotId,
45 css::uno::Reference<css::frame::XFrame> xFrame)
46 : mbWideButton(bWideButton)
47 , mbWasHiContrastMode(Application::GetSettings().GetStyleSettings().GetHighContrastMode())
48 , mnSlotId(nSlotId)
49 , maCurColor(COL_TRANSPARENT)
50 , meImageType(vcl::ImageType::Size16)
51 , maCommandLabel(std::move(aCommandLabel))
52 , maCommandURL(std::move(aCommandURL))
53 , mxFrame(std::move(xFrame))
54 {
55 }
56
57 void ToolboxButtonColorUpdaterBase::Init(sal_uInt16 nSlotId)
58 {
59 if (mbWideButton)
60 {
62 return;
63 }
64
65 if (rtl::Reference xModel = dynamic_cast<SfxBaseModel*>(mxFrame->getController()->getModel().get()))
66 {
67 auto pDocSh = xModel->GetObjectShell();
68 StartListening(*pDocSh);
69 if (auto oColor = pDocSh->GetRecentColor(nSlotId))
70 {
71 Update(*oColor);
72 return;
73 }
74 }
75
76 switch (nSlotId)
77 {
78 case SID_ATTR_CHAR_COLOR:
79 case SID_ATTR_CHAR_COLOR2:
80 Update(NamedColor(COL_DEFAULT_FONT, SvxResId(RID_SVXSTR_COLOR_DEFAULT_FONT)));
81 break;
82 case SID_FRAME_LINECOLOR:
83 Update(NamedColor(COL_DEFAULT_FRAMELINE, SvxResId(RID_SVXSTR_COLOR_DEFAULT_FRAMELINE)));
84 break;
85 case SID_ATTR_CHAR_COLOR_BACKGROUND:
86 case SID_ATTR_CHAR_BACK_COLOR:
87 case SID_BACKGROUND_COLOR:
88 case SID_TABLE_CELL_BACKGROUND_COLOR:
89 Update(NamedColor(COL_DEFAULT_HIGHLIGHT, SvxResId(RID_SVXSTR_COLOR_DEFAULT_HIGHLIGHT)));
90 break;
91 case SID_ATTR_LINE_COLOR:
92 Update(NamedColor(COL_DEFAULT_SHAPE_STROKE, SvxResId(RID_SVXSTR_COLOR_DEFAULT_SHAPE_STROKE)));
93 break;
94 case SID_ATTR_FILL_COLOR:
95 Update(NamedColor(COL_DEFAULT_SHAPE_FILLING, SvxResId(RID_SVXSTR_COLOR_DEFAULT_SHAPE_FILLING)));
96 break;
97 default:
99 }
100 }
101
103 {
104 if (rHint.GetId() == SfxHintId::Dying)
105 {
107 }
108 else if (rHint.GetId() == SfxHintId::ColorsChanged)
109 {
110 if (auto oColor = static_cast<SfxObjectShell&>(rBC).GetRecentColor(mnSlotId))
111 Update(*oColor);
112 }
113 }
114
116 {
117 if (rtl::Reference xModel = dynamic_cast<SfxBaseModel*>(mxFrame->getController()->getModel().get()))
118 xModel->GetObjectShell()->SetRecentColor(mnSlotId, rNamedColor);
119 else if (!mbWideButton)
120 Update(rNamedColor);
121 }
122
124 sal_uInt16 nSlotId, ToolBoxItemId nTbxBtnId, ToolBox* pToolBox, bool bWideButton,
125 const OUString& rCommandLabel, const OUString& rCommandURL,
126 const css::uno::Reference<css::frame::XFrame>& rFrame)
127 : ToolboxButtonColorUpdaterBase(bWideButton, rCommandLabel, rCommandURL, nSlotId, rFrame)
128 , mnBtnId(nTbxBtnId)
129 , mpTbx(pToolBox)
130 {
131 Init(nSlotId);
132 }
133
135 {
136 mpTbx->SetQuickHelpText(mnBtnId, rText);
137 }
138
140 {
141 return mpTbx->GetQuickHelpText(mnBtnId);
142 }
143
145 {
146 GDIMetaFile* pMtf = pVirDev->GetConnectMetaFile();
147
148 assert(pMtf && "should have been set in ToolboxButtonColorUpdaterBase::Update");
149
150 pMtf->Stop();
151 pMtf->WindStart();
152
153 Graphic aGraphic(*pMtf);
154
155 mpTbx->SetItemImage(mnBtnId, Image(aGraphic.GetXGraphic()));
156 }
157
159 {
160 return VclPtr<VirtualDevice>::Create(*mpTbx->GetOutDev());
161 }
162
164 {
165 return mpTbx->GetImageSize();
166 }
167
169 {
170 if (mbWideButton)
171 return mpTbx->GetItemContentSize(mnBtnId);
172 return rImageSize;
173 }
174
176 {}
177
179 {
180 Update(rNamedColor.m_aColor);
181
182 // Also show the current color as QuickHelpText
183 OUString colorSuffix = OUString(" (%1)").replaceFirst("%1", rNamedColor.m_aName);
184 OUString colorHelpText = maCommandLabel + colorSuffix;
185 SetQuickHelpText(colorHelpText);
186 }
187
188 void ToolboxButtonColorUpdaterBase::Update(const Color& rColor, bool bForceUpdate)
189 {
190 vcl::ImageType eImageType = GetImageSize();
191
192#ifdef IOS // tdf#126966
193 eImageType = vcl::ImageType::Size32;
194#endif
195
196 const bool bSizeChanged = (meImageType != eImageType);
197 meImageType = eImageType;
198 const bool bDisplayModeChanged = (mbWasHiContrastMode != Application::GetSettings().GetStyleSettings().GetHighContrastMode());
199 Color aColor(rColor);
200
201 // !!! #109290# Workaround for SetFillColor with COL_AUTO
202 if (aColor == COL_AUTO)
203 aColor = COL_TRANSPARENT;
204
205 if ((maCurColor == aColor) && !bSizeChanged && !bDisplayModeChanged && !bForceUpdate)
206 return;
207
209 Image aImage(xImage);
210
211 Size aItemSize = GetItemSize(aImage.GetSizePixel());
212 if (!aItemSize.Width() || !aItemSize.Height())
213 return;
214
216 pVirDev->SetOutputSizePixel(aItemSize);
217 maBmpSize = aItemSize;
218
219 std::unique_ptr<GDIMetaFile> xMetaFile;
221 {
222 xMetaFile.reset(new GDIMetaFile);
223 xMetaFile->SetPrefSize(pVirDev->GetOutputSize());
224 xMetaFile->SetPrefMapMode(pVirDev->GetMapMode());
225 xMetaFile->Record(pVirDev.get());
226 pVirDev->EnableOutput(false);
227 }
228
229 if (maBmpSize.Width() == maBmpSize.Height())
230 // tdf#84985 align color bar with icon bottom edge; integer arithmetic e.g. 26 - 26/4 <> 26 * 3/4
232 else
234
235 pVirDev->Push(vcl::PushFlags::CLIPREGION);
236
237 // tdf#135121 don't include the part of the image which we will
238 // overwrite with the target color so that for the transparent color
239 // case the original background of the device is shown
241 aRegion.Exclude(maUpdRect);
242 pVirDev->SetClipRegion(aRegion);
243
244 pVirDev->DrawImage(Point(0, 0), aImage);
245
246 pVirDev->Pop();
247
248 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
249 mbWasHiContrastMode = rStyleSettings.GetHighContrastMode();
250
251 if ((COL_TRANSPARENT != aColor) && (maBmpSize.Width() == maBmpSize.Height()))
252 pVirDev->SetLineColor(aColor);
253 else
254 pVirDev->SetLineColor(rStyleSettings.GetDisableColor());
255
256 // use not only COL_TRANSPARENT for detection of transparence,
257 // but the method/way which is designed to do that
258 const bool bIsFullyTransparent(aColor.IsFullyTransparent());
259 maCurColor = aColor;
260
261 if (bIsFullyTransparent)
262 {
263 pVirDev->SetFillColor();
264 }
265 else
266 {
267 pVirDev->SetFillColor(maCurColor);
268 }
269
270 pVirDev->DrawRect(maUpdRect);
271
272 SetImage(pVirDev.get());
273 }
274
276 {
277 OUString sColorName = GetQuickHelpText();
278 // The obtained string is of format: color context (color name)
279 // Generate a substring which contains only the color name
280 sal_Int32 nStart = sColorName.indexOf('(');
281 sColorName = sColorName.copy( nStart + 1 );
282 sal_Int32 nLength = sColorName.getLength();
283 if(nLength > 0)
284 sColorName = sColorName.copy( 0, nLength - 1);
285 return sColorName;
286 }
287
288 ToolboxButtonColorUpdater::ToolboxButtonColorUpdater(sal_uInt16 nSlotId, const OUString& rTbxBtnId, weld::Toolbar* ptrTbx, bool bWideButton,
289 const OUString& rCommandLabel, const css::uno::Reference<css::frame::XFrame>& rFrame)
290 : ToolboxButtonColorUpdaterBase(bWideButton, rCommandLabel, rTbxBtnId, nSlotId, rFrame)
291 , msBtnId(rTbxBtnId)
292 , mpTbx(ptrTbx)
293 {
294 Init(nSlotId);
295 }
296
298 {
300 }
301
303 {
305 }
306
308 {
309 mpTbx->set_item_image(msBtnId, pVirDev);
310 }
311
313 {
315 }
316
318 {
319 return mpTbx->get_icon_size();
320 }
321
323 {
324 auto nWidth = rImageSize.Width();
325 if (mbWideButton)
326 nWidth = nWidth * 5;
327 return Size(nWidth, rImageSize.Height());
328 }
329
331 : m_eXLS(css::drawing::LineStyle_NONE)
332 , m_nDashStyleIndex(-1)
333 {
334 }
335
336 void ToolboxButtonLineStyleUpdater::Update(const com::sun::star::frame::FeatureStateEvent& rEvent)
337 {
338 if (rEvent.FeatureURL.Complete == ".uno:LineDash")
339 {
341
343 if (!pSh)
344 return;
345 const SvxDashListItem* pItem = pSh->GetItem( SID_DASH_LIST );
346 if (!pItem)
347 return;
348
349 XLineDashItem aDashItem;
350 aDashItem.PutValue(rEvent.State, 0);
351 const XDash& rDash = aDashItem.GetDashValue();
352
353 XDashListRef xLineStyleList = pItem->GetDashList();
354 for (tools::Long i = 0; i < xLineStyleList->Count(); ++i)
355 {
356 const XDashEntry* pEntry = xLineStyleList->GetDash(i);
357 const XDash& rEntry = pEntry->GetDash();
358 if (rDash == rEntry)
359 {
361 break;
362 }
363 }
364 }
365 else if (rEvent.FeatureURL.Complete == ".uno:XLineStyle")
366 {
367 XLineStyleItem aLineStyleItem;
368 aLineStyleItem.PutValue(rEvent.State, 0);
369
370 m_eXLS = aLineStyleItem.GetValue();
371 }
372 }
373
375 {
376 int nRet;
377 switch (m_eXLS)
378 {
379 case css::drawing::LineStyle_NONE:
380 nRet = 0;
381 break;
382 case css::drawing::LineStyle_SOLID:
383 nRet = 1;
384 break;
385 default:
386 nRet = m_nDashStyleIndex + 2;
387 break;
388 }
389 return nRet;
390 }
391}
392
393/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
bool IsFullyTransparent() const
void WindStart()
css::uno::Reference< css::graphic::XGraphic > GetXGraphic() const
Size GetSizePixel() const
GDIMetaFile * GetConnectMetaFile() const
EnumT GetValue() const
SfxHintId GetId() const
void StartListening(SfxBroadcaster &rBroadcaster, DuplicateHandling eDuplicateHanding=DuplicateHandling::Unexpected)
void EndListeningAll()
static SAL_WARN_UNUSED_RESULT SfxObjectShell * Current()
const SfxPoolItem * GetItem(sal_uInt16 nSlotId) const
constexpr tools::Long Height() const
constexpr tools::Long Width() const
bool GetHighContrastMode() const
const Color & GetDisableColor() const
const XDashListRef & GetDashList() const
Definition: drawitem.hxx:171
reference_type * get() const
static VclPtr< reference_type > Create(Arg &&... arg)
const XDash & GetDash() const
Definition: xtable.hxx:80
Definition: xdash.hxx:32
const XDash & GetDashValue() const
Definition: xlndsit.hxx:57
virtual bool PutValue(const css::uno::Any &rVal, sal_uInt8 nMemberId) override
Definition: xattr.cxx:804
virtual bool PutValue(const css::uno::Any &rVal, sal_uInt8 nMemberId) override
Definition: xattr.cxx:462
helper class to update a color in a toolbox button image
void Update(const NamedColor &rNamedColor)
virtual VclPtr< VirtualDevice > CreateVirtualDevice() const =0
ToolboxButtonColorUpdaterBase(bool bWideButton, OUString aCommandLabel, OUString aCommandURL, sal_uInt16 nSlotId, css::uno::Reference< css::frame::XFrame > xFrame)
virtual vcl::ImageType GetImageSize() const =0
void SetRecentColor(const NamedColor &rNamedColor)
virtual void SetImage(VirtualDevice *pVirDev)=0
css::uno::Reference< css::frame::XFrame > mxFrame
virtual Size GetItemSize(const Size &rImageSize) const =0
void Init(sal_uInt16 nSlotId)
void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
virtual bool RecordVirtualDevice() const =0
virtual void SetQuickHelpText(const OUString &rText)=0
virtual OUString GetQuickHelpText() const =0
virtual void SetImage(VirtualDevice *pVirDev) override
virtual vcl::ImageType GetImageSize() const override
virtual Size GetItemSize(const Size &rImageSize) const override
virtual VclPtr< VirtualDevice > CreateVirtualDevice() const override
ToolboxButtonColorUpdater(sal_uInt16 nSlotId, const OUString &rTbxBtnId, weld::Toolbar *ptrTbx, bool bWideButton, const OUString &rCommandLabel, const css::uno::Reference< css::frame::XFrame > &rFrame)
virtual void SetQuickHelpText(const OUString &rText) override
virtual OUString GetQuickHelpText() const override
void Update(const css::frame::FeatureStateEvent &rEvent)
virtual void SetImage(VirtualDevice *pVirDev) override
virtual OUString GetQuickHelpText() const override
virtual void SetQuickHelpText(const OUString &rText) override
virtual vcl::ImageType GetImageSize() const override
virtual VclPtr< VirtualDevice > CreateVirtualDevice() const override
virtual Size GetItemSize(const Size &rImageSize) const override
VclToolboxButtonColorUpdater(sal_uInt16 nSlotId, ToolBoxItemId nTbxBtnId, ToolBox *ptrTbx, bool bWideButton, const OUString &rCommandLabel, const OUString &rCommandURL, const css::uno::Reference< css::frame::XFrame > &rFrame)
void Exclude(const tools::Rectangle &rRegion)
virtual OUString get_item_tooltip_text(const OUString &rIdent) const=0
virtual vcl::ImageType get_icon_size() const=0
virtual void set_item_tooltip_text(const OUString &rIdent, const OUString &rTip)=0
virtual void set_item_image(const OUString &rIdent, const css::uno::Reference< css::graphic::XGraphic > &rIcon)=0
virtual VclPtr< VirtualDevice > create_virtual_device() const=0
constexpr ::Color COL_AUTO(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
constexpr ::Color COL_TRANSPARENT(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
OUString SvxResId(TranslateId aId)
Definition: dialmgr.cxx:24
int i
long Long
Reference< graphic::XGraphic > GetXGraphicForCommand(const OUString &rsCommandName, const Reference< frame::XFrame > &rxFrame, vcl::ImageType eImageType)
ImageType
OUString m_aName
Color m_aColor
Reference< XFrame > xFrame
Reference< XModel > xModel
#define COL_DEFAULT_SHAPE_FILLING
Definition: xdef.hxx:85
#define COL_DEFAULT_HIGHLIGHT
Definition: xdef.hxx:84
#define COL_DEFAULT_SHAPE_STROKE
Definition: xdef.hxx:86
#define COL_DEFAULT_FONT
Definition: xdef.hxx:82
#define COL_DEFAULT_FRAMELINE
Definition: xdef.hxx:83
sal_Int32 nLength