Version 7.1.7.1, tag libreoffice-7.1.7.1
[LibreOffice.git] / svx / source / tbxctrls / tbxcolorupdate.cxx
blobcfacba152071a73066f5139594277ae35614707c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <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>
28 #include <vcl/commandinfoprovider.hxx>
29 #include <vcl/svapp.hxx>
30 #include <vcl/toolbox.hxx>
31 #include <vcl/virdev.hxx>
32 #include <vcl/weld.hxx>
33 #include <vcl/settings.hxx>
35 #include <svx/strings.hrc>
36 #include <svx/dialmgr.hxx>
38 namespace svx
40 ToolboxButtonColorUpdaterBase::ToolboxButtonColorUpdaterBase(bool bWideButton, const OUString& rCommandLabel,
41 const OUString& rCommandURL,
42 const css::uno::Reference<css::frame::XFrame>& rFrame)
43 : mbWideButton(bWideButton)
44 , mbWasHiContrastMode(Application::GetSettings().GetStyleSettings().GetHighContrastMode())
45 , maCurColor(COL_TRANSPARENT)
46 , meImageType(vcl::ImageType::Size16)
47 , maCommandLabel(rCommandLabel)
48 , maCommandURL(rCommandURL)
49 , mxFrame(rFrame)
53 void ToolboxButtonColorUpdaterBase::Init(sal_uInt16 nSlotId)
55 switch (nSlotId)
57 case SID_ATTR_CHAR_COLOR:
58 case SID_ATTR_CHAR_COLOR2:
59 Update(NamedColor(COL_DEFAULT_FONT, SvxResId(RID_SVXSTR_COLOR_DEFAULT_FONT)));
60 break;
61 case SID_FRAME_LINECOLOR:
62 Update(NamedColor(COL_DEFAULT_FRAMELINE, SvxResId(RID_SVXSTR_COLOR_DEFAULT_FRAMELINE)));
63 break;
64 case SID_ATTR_CHAR_COLOR_BACKGROUND:
65 case SID_ATTR_CHAR_BACK_COLOR:
66 case SID_BACKGROUND_COLOR:
67 case SID_TABLE_CELL_BACKGROUND_COLOR:
68 Update(NamedColor(COL_DEFAULT_HIGHLIGHT, SvxResId(RID_SVXSTR_COLOR_DEFAULT_HIGHLIGHT)));
69 break;
70 case SID_ATTR_LINE_COLOR:
71 Update(NamedColor(COL_DEFAULT_SHAPE_STROKE, SvxResId(RID_SVXSTR_COLOR_DEFAULT_SHAPE_STROKE)));
72 break;
73 case SID_ATTR_FILL_COLOR:
74 Update(NamedColor(COL_DEFAULT_SHAPE_FILLING, SvxResId(RID_SVXSTR_COLOR_DEFAULT_SHAPE_FILLING)));
75 break;
76 default:
77 Update(COL_TRANSPARENT);
81 VclToolboxButtonColorUpdater::VclToolboxButtonColorUpdater(
82 sal_uInt16 nSlotId, sal_uInt16 nTbxBtnId, ToolBox* pToolBox, bool bWideButton,
83 const OUString& rCommandLabel, const OUString& rCommandURL,
84 const css::uno::Reference<css::frame::XFrame>& rFrame)
85 : ToolboxButtonColorUpdaterBase(bWideButton, rCommandLabel, rCommandURL, rFrame)
86 , mnBtnId(nTbxBtnId)
87 , mpTbx(pToolBox)
89 Init(nSlotId);
92 void VclToolboxButtonColorUpdater::SetQuickHelpText(const OUString& rText)
94 mpTbx->SetQuickHelpText(mnBtnId, rText);
97 OUString VclToolboxButtonColorUpdater::GetQuickHelpText() const
99 return mpTbx->GetQuickHelpText(mnBtnId);
102 void VclToolboxButtonColorUpdater::SetImage(VirtualDevice* pVirDev)
104 mpTbx->SetItemImage(mnBtnId, Image(pVirDev->GetBitmapEx(Point(0,0), maBmpSize)));
107 VclPtr<VirtualDevice> VclToolboxButtonColorUpdater::CreateVirtualDevice() const
109 auto xRet = VclPtr<VirtualDevice>::Create(*mpTbx,
110 DeviceFormat::DEFAULT, DeviceFormat::DEFAULT);
111 xRet->SetBackground(mpTbx->GetControlBackground());
112 return xRet;
115 vcl::ImageType VclToolboxButtonColorUpdater::GetImageSize() const
117 return mpTbx->GetImageSize();
120 Size VclToolboxButtonColorUpdater::GetItemSize(const Size& rImageSize) const
122 if (mbWideButton)
123 return mpTbx->GetItemContentSize(mnBtnId);
124 return rImageSize;
127 ToolboxButtonColorUpdaterBase::~ToolboxButtonColorUpdaterBase()
130 void ToolboxButtonColorUpdaterBase::Update(const NamedColor &rNamedColor)
132 Update(rNamedColor.first);
133 if (!mbWideButton)
135 // Also show the current color as QuickHelpText
136 OUString colorSuffix = OUString(" (%1)").replaceFirst("%1", rNamedColor.second);
137 OUString colorHelpText = maCommandLabel + colorSuffix;
139 SetQuickHelpText(colorHelpText);
143 void ToolboxButtonColorUpdaterBase::Update(const Color& rColor, bool bForceUpdate)
145 vcl::ImageType eImageType = GetImageSize();
147 #ifdef IOS // tdf#126966
148 eImageType = vcl::ImageType::Size32;
149 #endif
151 const bool bSizeChanged = (meImageType != eImageType);
152 meImageType = eImageType;
153 const bool bDisplayModeChanged = (mbWasHiContrastMode != Application::GetSettings().GetStyleSettings().GetHighContrastMode());
154 Color aColor(rColor);
156 // !!! #109290# Workaround for SetFillColor with COL_AUTO
157 if (aColor == COL_AUTO)
158 aColor = COL_TRANSPARENT;
160 if ((maCurColor == aColor) && !bSizeChanged && !bDisplayModeChanged && !bForceUpdate)
161 return;
163 auto xImage = vcl::CommandInfoProvider::GetXGraphicForCommand(maCommandURL, mxFrame, meImageType);
164 Image aImage(xImage);
166 Size aItemSize = GetItemSize(aImage.GetSizePixel());
167 if (!aItemSize.Width() || !aItemSize.Height())
168 return;
170 ScopedVclPtr<VirtualDevice> pVirDev(CreateVirtualDevice());
171 pVirDev->SetOutputSizePixel(aItemSize);
172 maBmpSize = aItemSize;
174 if (maBmpSize.Width() == maBmpSize.Height())
175 // tdf#84985 align color bar with icon bottom edge; integer arithmetic e.g. 26 - 26/4 <> 26 * 3/4
176 maUpdRect = tools::Rectangle(Point( 0, maBmpSize.Height() - maBmpSize.Height() / 4), Size(maBmpSize.Width(), maBmpSize.Height() / 4));
177 else
178 maUpdRect = tools::Rectangle(Point( maBmpSize.Height() + 2, 2), Point(maBmpSize.Width() - 3, maBmpSize.Height() - 3));
180 pVirDev->Push(PushFlags::CLIPREGION);
182 // tdf#135121 don't include the part of the image which we will
183 // overwrite with the target color so that for the transparent color
184 // case the original background of the device is shown
185 vcl::Region aRegion(tools::Rectangle(Point(0, 0), maBmpSize));
186 aRegion.Exclude(maUpdRect);
187 pVirDev->SetClipRegion(aRegion);
189 pVirDev->DrawImage(Point(0, 0), aImage);
191 pVirDev->Pop();
193 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
194 mbWasHiContrastMode = rStyleSettings.GetHighContrastMode();
196 if ((COL_TRANSPARENT != aColor) && (maBmpSize.Width() == maBmpSize.Height()))
197 pVirDev->SetLineColor(aColor);
198 else
199 pVirDev->SetLineColor(rStyleSettings.GetDisableColor());
201 // use not only COL_TRANSPARENT for detection of transparence,
202 // but the method/way which is designed to do that
203 const bool bIsTransparent(0xff == aColor.GetTransparency());
204 maCurColor = aColor;
206 if (bIsTransparent)
208 pVirDev->SetFillColor();
210 else
212 pVirDev->SetFillColor(maCurColor);
215 pVirDev->DrawRect(maUpdRect);
217 SetImage(pVirDev.get());
220 OUString ToolboxButtonColorUpdaterBase::GetCurrentColorName() const
222 OUString sColorName = GetQuickHelpText();
223 // The obtained string is of format: color context (color name)
224 // Generate a substring which contains only the color name
225 sal_Int32 nStart = sColorName.indexOf('(');
226 sColorName = sColorName.copy( nStart + 1 );
227 sal_Int32 nLength = sColorName.getLength();
228 if(nLength > 0)
229 sColorName = sColorName.copy( 0, nLength - 1);
230 return sColorName;
233 ToolboxButtonColorUpdater::ToolboxButtonColorUpdater(sal_uInt16 nSlotId, const OString& rTbxBtnId, weld::Toolbar* ptrTbx, bool bWideButton,
234 const OUString& rCommandLabel, const css::uno::Reference<css::frame::XFrame>& rFrame)
235 : ToolboxButtonColorUpdaterBase(bWideButton, rCommandLabel, OUString::fromUtf8(rTbxBtnId), rFrame)
236 , msBtnId(rTbxBtnId)
237 , mpTbx(ptrTbx)
239 Init(nSlotId);
242 void ToolboxButtonColorUpdater::SetQuickHelpText(const OUString& rText)
244 mpTbx->set_item_tooltip_text(msBtnId, rText);
247 OUString ToolboxButtonColorUpdater::GetQuickHelpText() const
249 return mpTbx->get_item_tooltip_text(msBtnId);
252 void ToolboxButtonColorUpdater::SetImage(VirtualDevice* pVirDev)
254 mpTbx->set_item_image(msBtnId, pVirDev);
257 VclPtr<VirtualDevice> ToolboxButtonColorUpdater::CreateVirtualDevice() const
259 return mpTbx->create_virtual_device();
262 vcl::ImageType ToolboxButtonColorUpdater::GetImageSize() const
264 return mpTbx->get_icon_size();
267 Size ToolboxButtonColorUpdater::GetItemSize(const Size& rImageSize) const
269 auto nWidth = rImageSize.Width();
270 if (mbWideButton)
271 nWidth = nWidth * 5;
272 return Size(nWidth, rImageSize.Height());
275 ToolboxButtonLineStyleUpdater::ToolboxButtonLineStyleUpdater()
276 : m_eXLS(css::drawing::LineStyle_NONE)
277 , m_nDashStyleIndex(-1)
281 void ToolboxButtonLineStyleUpdater::Update(const com::sun::star::frame::FeatureStateEvent& rEvent)
283 if (rEvent.FeatureURL.Complete == ".uno:LineDash")
285 m_nDashStyleIndex = -1;
287 SfxObjectShell* pSh = SfxObjectShell::Current();
288 if (!pSh)
289 return;
290 const SvxDashListItem* pItem = pSh->GetItem( SID_DASH_LIST );
291 if (!pItem)
292 return;
294 XLineDashItem aDashItem;
295 aDashItem.PutValue(rEvent.State, 0);
296 const XDash& rDash = aDashItem.GetDashValue();
298 XDashListRef xLineStyleList = pItem->GetDashList();
299 for (tools::Long i = 0; i < xLineStyleList->Count(); ++i)
301 const XDashEntry* pEntry = xLineStyleList->GetDash(i);
302 const XDash& rEntry = pEntry->GetDash();
303 if (rDash == rEntry)
305 m_nDashStyleIndex = i;
306 break;
310 else if (rEvent.FeatureURL.Complete == ".uno:XLineStyle")
312 XLineStyleItem aLineStyleItem;
313 aLineStyleItem.PutValue(rEvent.State, 0);
315 m_eXLS = aLineStyleItem.GetValue();
319 int ToolboxButtonLineStyleUpdater::GetStyleIndex() const
321 int nRet;
322 switch (m_eXLS)
324 case css::drawing::LineStyle_NONE:
325 nRet = 0;
326 break;
327 case css::drawing::LineStyle_SOLID:
328 nRet = 1;
329 break;
330 default:
331 nRet = m_nDashStyleIndex + 2;
332 break;
334 return nRet;
338 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */