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/objsh.hxx>
21#include <svx/drawitem.hxx>
22#include <tbxcolorupdate.hxx>
23#include <svx/svxids.hrc>
24#include <svx/xdef.hxx>
25#include <svx/xlineit0.hxx>
26#include <svx/xlndsit.hxx>
27
28#include <utility>
30#include <vcl/gdimtf.hxx>
31#include <vcl/svapp.hxx>
32#include <vcl/toolbox.hxx>
33#include <vcl/virdev.hxx>
34#include <vcl/weld.hxx>
35#include <vcl/settings.hxx>
36
37#include <svx/strings.hrc>
38#include <svx/dialmgr.hxx>
39
40namespace svx
41{
42 ToolboxButtonColorUpdaterBase::ToolboxButtonColorUpdaterBase(bool bWideButton, OUString aCommandLabel,
43 OUString aCommandURL,
44 css::uno::Reference<css::frame::XFrame> xFrame)
45 : mbWideButton(bWideButton)
46 , mbWasHiContrastMode(Application::GetSettings().GetStyleSettings().GetHighContrastMode())
47 , maCurColor(COL_TRANSPARENT)
48 , meImageType(vcl::ImageType::Size16)
49 , maCommandLabel(std::move(aCommandLabel))
50 , maCommandURL(std::move(aCommandURL))
51 , mxFrame(std::move(xFrame))
52 {
53 }
54
55 void ToolboxButtonColorUpdaterBase::Init(sal_uInt16 nSlotId)
56 {
57 switch (nSlotId)
58 {
59 case SID_ATTR_CHAR_COLOR:
60 case SID_ATTR_CHAR_COLOR2:
61 Update(NamedColor(COL_DEFAULT_FONT, SvxResId(RID_SVXSTR_COLOR_DEFAULT_FONT)));
62 break;
63 case SID_FRAME_LINECOLOR:
64 Update(NamedColor(COL_DEFAULT_FRAMELINE, SvxResId(RID_SVXSTR_COLOR_DEFAULT_FRAMELINE)));
65 break;
66 case SID_ATTR_CHAR_COLOR_BACKGROUND:
67 case SID_ATTR_CHAR_BACK_COLOR:
68 case SID_BACKGROUND_COLOR:
69 case SID_TABLE_CELL_BACKGROUND_COLOR:
70 Update(NamedColor(COL_DEFAULT_HIGHLIGHT, SvxResId(RID_SVXSTR_COLOR_DEFAULT_HIGHLIGHT)));
71 break;
72 case SID_ATTR_LINE_COLOR:
73 Update(NamedColor(COL_DEFAULT_SHAPE_STROKE, SvxResId(RID_SVXSTR_COLOR_DEFAULT_SHAPE_STROKE)));
74 break;
75 case SID_ATTR_FILL_COLOR:
76 Update(NamedColor(COL_DEFAULT_SHAPE_FILLING, SvxResId(RID_SVXSTR_COLOR_DEFAULT_SHAPE_FILLING)));
77 break;
78 default:
80 }
81 }
82
84 sal_uInt16 nSlotId, ToolBoxItemId nTbxBtnId, ToolBox* pToolBox, bool bWideButton,
85 const OUString& rCommandLabel, const OUString& rCommandURL,
86 const css::uno::Reference<css::frame::XFrame>& rFrame)
87 : ToolboxButtonColorUpdaterBase(bWideButton, rCommandLabel, rCommandURL, rFrame)
88 , mnBtnId(nTbxBtnId)
89 , mpTbx(pToolBox)
90 {
91 Init(nSlotId);
92 }
93
95 {
96 mpTbx->SetQuickHelpText(mnBtnId, rText);
97 }
98
100 {
101 return mpTbx->GetQuickHelpText(mnBtnId);
102 }
103
105 {
106 GDIMetaFile* pMtf = pVirDev->GetConnectMetaFile();
107
108 assert(pMtf && "should have been set in ToolboxButtonColorUpdaterBase::Update");
109
110 pMtf->Stop();
111 pMtf->WindStart();
112
113 Graphic aGraphic(*pMtf);
114
115 mpTbx->SetItemImage(mnBtnId, Image(aGraphic.GetXGraphic()));
116 }
117
119 {
120 return VclPtr<VirtualDevice>::Create(*mpTbx->GetOutDev());
121 }
122
124 {
125 return mpTbx->GetImageSize();
126 }
127
129 {
130 if (mbWideButton)
131 return mpTbx->GetItemContentSize(mnBtnId);
132 return rImageSize;
133 }
134
136 {}
137
139 {
140 Update(rNamedColor.first);
141 if (!mbWideButton)
142 {
143 // Also show the current color as QuickHelpText
144 OUString colorSuffix = OUString(" (%1)").replaceFirst("%1", rNamedColor.second);
145 OUString colorHelpText = maCommandLabel + colorSuffix;
146
147 SetQuickHelpText(colorHelpText);
148 }
149 }
150
151 void ToolboxButtonColorUpdaterBase::Update(const Color& rColor, bool bForceUpdate)
152 {
153 vcl::ImageType eImageType = GetImageSize();
154
155#ifdef IOS // tdf#126966
156 eImageType = vcl::ImageType::Size32;
157#endif
158
159 const bool bSizeChanged = (meImageType != eImageType);
160 meImageType = eImageType;
161 const bool bDisplayModeChanged = (mbWasHiContrastMode != Application::GetSettings().GetStyleSettings().GetHighContrastMode());
162 Color aColor(rColor);
163
164 // !!! #109290# Workaround for SetFillColor with COL_AUTO
165 if (aColor == COL_AUTO)
166 aColor = COL_TRANSPARENT;
167
168 if ((maCurColor == aColor) && !bSizeChanged && !bDisplayModeChanged && !bForceUpdate)
169 return;
170
172 Image aImage(xImage);
173
174 Size aItemSize = GetItemSize(aImage.GetSizePixel());
175 if (!aItemSize.Width() || !aItemSize.Height())
176 return;
177
179 pVirDev->SetOutputSizePixel(aItemSize);
180 maBmpSize = aItemSize;
181
182 std::unique_ptr<GDIMetaFile> xMetaFile;
184 {
185 xMetaFile.reset(new GDIMetaFile);
186 xMetaFile->SetPrefSize(pVirDev->GetOutputSize());
187 xMetaFile->SetPrefMapMode(pVirDev->GetMapMode());
188 xMetaFile->Record(pVirDev.get());
189 pVirDev->EnableOutput(false);
190 }
191
192 if (maBmpSize.Width() == maBmpSize.Height())
193 // tdf#84985 align color bar with icon bottom edge; integer arithmetic e.g. 26 - 26/4 <> 26 * 3/4
195 else
197
198 pVirDev->Push(vcl::PushFlags::CLIPREGION);
199
200 // tdf#135121 don't include the part of the image which we will
201 // overwrite with the target color so that for the transparent color
202 // case the original background of the device is shown
204 aRegion.Exclude(maUpdRect);
205 pVirDev->SetClipRegion(aRegion);
206
207 pVirDev->DrawImage(Point(0, 0), aImage);
208
209 pVirDev->Pop();
210
211 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
212 mbWasHiContrastMode = rStyleSettings.GetHighContrastMode();
213
214 if ((COL_TRANSPARENT != aColor) && (maBmpSize.Width() == maBmpSize.Height()))
215 pVirDev->SetLineColor(aColor);
216 else
217 pVirDev->SetLineColor(rStyleSettings.GetDisableColor());
218
219 // use not only COL_TRANSPARENT for detection of transparence,
220 // but the method/way which is designed to do that
221 const bool bIsFullyTransparent(aColor.IsFullyTransparent());
222 maCurColor = aColor;
223
224 if (bIsFullyTransparent)
225 {
226 pVirDev->SetFillColor();
227 }
228 else
229 {
230 pVirDev->SetFillColor(maCurColor);
231 }
232
233 pVirDev->DrawRect(maUpdRect);
234
235 SetImage(pVirDev.get());
236 }
237
239 {
240 OUString sColorName = GetQuickHelpText();
241 // The obtained string is of format: color context (color name)
242 // Generate a substring which contains only the color name
243 sal_Int32 nStart = sColorName.indexOf('(');
244 sColorName = sColorName.copy( nStart + 1 );
245 sal_Int32 nLength = sColorName.getLength();
246 if(nLength > 0)
247 sColorName = sColorName.copy( 0, nLength - 1);
248 return sColorName;
249 }
250
251 ToolboxButtonColorUpdater::ToolboxButtonColorUpdater(sal_uInt16 nSlotId, const OString& rTbxBtnId, weld::Toolbar* ptrTbx, bool bWideButton,
252 const OUString& rCommandLabel, const css::uno::Reference<css::frame::XFrame>& rFrame)
253 : ToolboxButtonColorUpdaterBase(bWideButton, rCommandLabel, OUString::fromUtf8(rTbxBtnId), rFrame)
254 , msBtnId(rTbxBtnId)
255 , mpTbx(ptrTbx)
256 {
257 Init(nSlotId);
258 }
259
261 {
263 }
264
266 {
268 }
269
271 {
272 mpTbx->set_item_image(msBtnId, pVirDev);
273 }
274
276 {
278 }
279
281 {
282 return mpTbx->get_icon_size();
283 }
284
286 {
287 auto nWidth = rImageSize.Width();
288 if (mbWideButton)
289 nWidth = nWidth * 5;
290 return Size(nWidth, rImageSize.Height());
291 }
292
294 : m_eXLS(css::drawing::LineStyle_NONE)
295 , m_nDashStyleIndex(-1)
296 {
297 }
298
299 void ToolboxButtonLineStyleUpdater::Update(const com::sun::star::frame::FeatureStateEvent& rEvent)
300 {
301 if (rEvent.FeatureURL.Complete == ".uno:LineDash")
302 {
304
306 if (!pSh)
307 return;
308 const SvxDashListItem* pItem = pSh->GetItem( SID_DASH_LIST );
309 if (!pItem)
310 return;
311
312 XLineDashItem aDashItem;
313 aDashItem.PutValue(rEvent.State, 0);
314 const XDash& rDash = aDashItem.GetDashValue();
315
316 XDashListRef xLineStyleList = pItem->GetDashList();
317 for (tools::Long i = 0; i < xLineStyleList->Count(); ++i)
318 {
319 const XDashEntry* pEntry = xLineStyleList->GetDash(i);
320 const XDash& rEntry = pEntry->GetDash();
321 if (rDash == rEntry)
322 {
324 break;
325 }
326 }
327 }
328 else if (rEvent.FeatureURL.Complete == ".uno:XLineStyle")
329 {
330 XLineStyleItem aLineStyleItem;
331 aLineStyleItem.PutValue(rEvent.State, 0);
332
333 m_eXLS = aLineStyleItem.GetValue();
334 }
335 }
336
338 {
339 int nRet;
340 switch (m_eXLS)
341 {
342 case css::drawing::LineStyle_NONE:
343 nRet = 0;
344 break;
345 case css::drawing::LineStyle_SOLID:
346 nRet = 1;
347 break;
348 default:
349 nRet = m_nDashStyleIndex + 2;
350 break;
351 }
352 return nRet;
353 }
354}
355
356/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::pair< Color, OUString > NamedColor
Definition: Palette.hxx:30
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
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:751
virtual bool PutValue(const css::uno::Any &rVal, sal_uInt8 nMemberId) override
Definition: xattr.cxx:409
helper class to update a color in a toolbox button image
void Update(const NamedColor &rNamedColor)
virtual VclPtr< VirtualDevice > CreateVirtualDevice() const =0
virtual vcl::ImageType GetImageSize() const =0
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)
virtual bool RecordVirtualDevice() const =0
virtual void SetQuickHelpText(const OUString &rText)=0
virtual OUString GetQuickHelpText() const =0
ToolboxButtonColorUpdaterBase(bool bWideButton, OUString aCommandLabel, OUString aCommandURL, css::uno::Reference< css::frame::XFrame > xFrame)
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 OString &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 OString &rIdent) const=0
virtual vcl::ImageType get_icon_size() const=0
virtual void set_item_tooltip_text(const OString &rIdent, const OUString &rTip)=0
virtual void set_item_image(const OString &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
Reference< XFrame > xFrame
#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