LibreOffice Module sc (master) 1
CellAppearancePropertyPanel.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
21#include <sc.hrc>
22#include <bitmaps.hlst>
23#include <sfx2/bindings.hxx>
24#include <sfx2/weldutils.hxx>
27#include <editeng/boxitem.hxx>
28#include <editeng/lineitem.hxx>
29#include <vcl/svapp.hxx>
30#include <vcl/settings.hxx>
31#include <vcl/virdev.hxx>
32#include <com/sun/star/lang/IllegalArgumentException.hpp>
35
36using namespace css;
37using namespace css::uno;
38
39constexpr OUStringLiteral SETBORDERSTYLE = u"SetBorderStyle";
40constexpr OUStringLiteral LINESTYLE = u"LineStyle";
41
42// namespace open
43
44namespace sc::sidebar {
45
47 weld::Widget* pParent,
48 const css::uno::Reference<css::frame::XFrame>& rxFrame,
49 SfxBindings* pBindings)
50: PanelLayout(pParent, "CellAppearancePropertyPanel", "modules/scalc/ui/sidebarcellappearance.ui"),
51
52 mxTBCellBorder(m_xBuilder->weld_toolbar("cellbordertype")),
53 mxTBCellBackground(m_xBuilder->weld_toolbar("cellbackgroundcolor")),
54 mxBackColorDispatch(new ToolbarUnoDispatcher(*mxTBCellBackground, *m_xBuilder, rxFrame)),
55 mxTBLineStyle(m_xBuilder->weld_toolbar("borderlinestyle")),
56 mxTBLineColor(m_xBuilder->weld_toolbar("borderlinecolor")),
57 mxLineColorDispatch(new ToolbarUnoDispatcher(*mxTBLineColor, *m_xBuilder, rxFrame)),
58
59 mbCellBorderPopoverCreated(false),
60 mbLinePopoverCreated(false),
61
62 maLineStyleControl(SID_FRAME_LINESTYLE, *pBindings, *this),
63 maBorderOuterControl(SID_ATTR_BORDER_OUTER, *pBindings, *this),
64 maBorderInnerControl(SID_ATTR_BORDER_INNER, *pBindings, *this),
65 maGridShowControl(FID_TAB_TOGGLE_GRID, *pBindings, *this),
66 maBorderTLBRControl(SID_ATTR_BORDER_DIAG_TLBR, *pBindings, *this),
67 maBorderBLTRControl(SID_ATTR_BORDER_DIAG_BLTR, *pBindings, *this),
68
69 maIMGCellBorder(StockImage::Yes, RID_BMP_CELL_BORDER),
70 msIMGCellBorder(RID_BMP_CELL_BORDER),
71 msIMGLineStyle1(RID_BMP_LINE_STYLE1),
72 msIMGLineStyle2(RID_BMP_LINE_STYLE2),
73 msIMGLineStyle3(RID_BMP_LINE_STYLE3),
74 msIMGLineStyle4(RID_BMP_LINE_STYLE4),
75 msIMGLineStyle5(RID_BMP_LINE_STYLE5),
76 msIMGLineStyle6(RID_BMP_LINE_STYLE6),
77 msIMGLineStyle7(RID_BMP_LINE_STYLE7),
78 msIMGLineStyle8(RID_BMP_LINE_STYLE8),
79 msIMGLineStyle9(RID_BMP_LINE_STYLE9),
80
81 mnInWidth(0),
82 mnOutWidth(0),
83 mnDistance(0),
84 mnDiagTLBRInWidth(0),
85 mnDiagTLBROutWidth(0),
86 mnDiagTLBRDistance(0),
87 mnDiagBLTRInWidth(0),
88 mnDiagBLTROutWidth(0),
89 mnDiagBLTRDistance(0),
90 mbBorderStyleAvailable(true),
91 mbLeft(false),
92 mbRight(false),
93 mbTop(false),
94 mbBottom(false),
95 mbVer(false),
96 mbHor(false),
97 mbOuterBorder(false),
98 mbInnerBorder(false),
99 mbDiagTLBR(false),
100 mbDiagBLTR(false),
101 mpBindings(pBindings)
102{
103 Initialize();
104}
105
107{
109 mxTBCellBorder.reset();
110 mxBackColorDispatch.reset();
111 mxTBCellBackground.reset();
113 mxTBLineStyle.reset();
114 mxLineColorDispatch.reset();
115 mxTBLineColor.reset();
116
123}
124
126{
127 mxTBCellBorder->set_item_icon_name(SETBORDERSTYLE, msIMGCellBorder);
129 mxTBCellBorder->set_item_popover(SETBORDERSTYLE, mxCellBorderPopoverContainer->getTopLevel());
130 mxTBCellBorder->connect_clicked(LINK(this, CellAppearancePropertyPanel, TbxCellBorderSelectHdl));
131 mxTBCellBorder->connect_menu_toggled(LINK(this, CellAppearancePropertyPanel, TbxCellBorderMenuHdl));
132
133 mxTBLineStyle->set_item_icon_name(LINESTYLE, msIMGLineStyle1);
135 mxTBLineStyle->set_item_popover(LINESTYLE, mxLinePopoverContainer->getTopLevel());
136 mxTBLineStyle->connect_clicked(LINK(this, CellAppearancePropertyPanel, TbxLineStyleSelectHdl));
137 mxTBLineStyle->connect_menu_toggled(LINK(this, CellAppearancePropertyPanel, TbxLineStyleMenuHdl));
138 mxTBLineStyle->set_sensitive(false);
139
140 mxTBLineColor->set_sensitive(false);
141}
142
143IMPL_LINK_NOARG(CellAppearancePropertyPanel, TbxCellBorderSelectHdl, const OUString&, void)
144{
145 mxTBCellBorder->set_menu_item_active(SETBORDERSTYLE, !mxTBCellBorder->get_menu_item_active(SETBORDERSTYLE));
146}
147
148IMPL_LINK_NOARG(CellAppearancePropertyPanel, TbxCellBorderMenuHdl, const OUString&, void)
149{
150 if (!mxTBCellBorder->get_menu_item_active(SETBORDERSTYLE))
151 return;
152 if (!mbCellBorderPopoverCreated)
153 {
154 mxCellBorderPopoverContainer->setPopover(std::make_unique<CellBorderStylePopup>(mxTBCellBorder.get(), SETBORDERSTYLE, GetBindings()->GetDispatcher()));
155 mbCellBorderPopoverCreated = true;
156 }
157 mxCellBorderPopoverContainer->getPopover()->GrabFocus();
158}
159
160IMPL_LINK_NOARG(CellAppearancePropertyPanel, TbxLineStyleSelectHdl, const OUString&, void)
161{
162 mxTBLineStyle->set_menu_item_active(LINESTYLE, !mxTBLineStyle->get_menu_item_active(LINESTYLE));
163}
164
165IMPL_LINK_NOARG(CellAppearancePropertyPanel, TbxLineStyleMenuHdl, const OUString&, void)
166{
167 if (!mxTBLineStyle->get_menu_item_active(LINESTYLE))
168 return;
169 if (!mbLinePopoverCreated)
170 {
171 mxLinePopoverContainer->setPopover(std::make_unique<CellLineStylePopup>(mxTBLineStyle.get(), LINESTYLE, GetBindings()->GetDispatcher()));
172 mbLinePopoverCreated = true;
173 }
174 auto pPopup = static_cast<CellLineStylePopup*>(mxLinePopoverContainer->getPopover());
175 pPopup->SetLineStyleSelect(mnOutWidth, mnInWidth, mnDistance);
176 pPopup->GrabFocus();
177}
178
179std::unique_ptr<PanelLayout> CellAppearancePropertyPanel::Create (
180 weld::Widget* pParent,
181 const css::uno::Reference<css::frame::XFrame>& rxFrame,
182 SfxBindings* pBindings)
183{
184 if (pParent == nullptr)
185 throw lang::IllegalArgumentException("no parent Window given to CellAppearancePropertyPanel::Create", nullptr, 0);
186 if ( ! rxFrame.is())
187 throw lang::IllegalArgumentException("no XFrame given to CellAppearancePropertyPanel::Create", nullptr, 1);
188 if (pBindings == nullptr)
189 throw lang::IllegalArgumentException("no SfxBindings given to CellAppearancePropertyPanel::Create", nullptr, 2);
190
191 return std::make_unique<CellAppearancePropertyPanel>(pParent, rxFrame, pBindings);
192}
193
195{
196 if (maContext == rContext)
197 {
198 // Nothing to do.
199 return;
200 }
201
202 maContext = rContext;
203}
204
206 sal_uInt16 nSID,
207 SfxItemState eState,
208 const SfxPoolItem* pState)
209{
210 switch(nSID)
211 {
212 case SID_FRAME_LINESTYLE:
214 if( eState == SfxItemState::DONTCARE )
215 {
217 mnInWidth = 0;
218 mnOutWidth = 0;
219 mnDistance = 0;
220 }
221 else if(eState >= SfxItemState::DEFAULT)
222 {
223 const SvxLineItem* pSvxLineItem = dynamic_cast< const SvxLineItem* >(pState);
224 if(pSvxLineItem)
225 {
226 const editeng::SvxBorderLine* pLineItem = pSvxLineItem->GetLine();
227 mnInWidth = pLineItem->GetInWidth();
228 mnOutWidth = pLineItem->GetOutWidth();
229 mnDistance = pLineItem->GetDistance();
230 mbBorderStyleAvailable = !(mnInWidth == 0 && mnOutWidth == 0 && mnDistance == 0);
231 }
232 }
233 SetStyleIcon();
234 break;
235 case SID_ATTR_BORDER_OUTER:
236 if(eState >= SfxItemState::DEFAULT)
237 {
238 const SvxBoxItem* pBoxItem = dynamic_cast< const SvxBoxItem* >(pState);
239
240 if(pBoxItem)
241 {
242 mbLeft=false;
243 mbRight=false;
244 mbTop=false;
245 mbBottom=false;
246
247 if(pBoxItem->GetLeft())
248 mbLeft = true;
249
250 if(pBoxItem->GetRight())
251 mbRight = true;
252
253 if(pBoxItem->GetTop())
254 mbTop = true;
255
256 if(pBoxItem->GetBottom())
257 mbBottom = true;
258
261 else
263
264 if(mbLeft || mbRight || mbTop || mbBottom)
265 mbOuterBorder = true;
266 else
267 mbOuterBorder = false;
268
270 }
271 }
272 break;
273 case SID_ATTR_BORDER_INNER:
274 if(eState >= SfxItemState::DEFAULT)
275 {
276 const SvxBoxInfoItem* pBoxInfoItem = dynamic_cast< const SvxBoxInfoItem* >(pState);
277 if(pBoxInfoItem)
278 {
279 bool bLeft(false), bRight(false), bTop(false), bBottom(false);
280
281 mbVer = false;
282 mbHor = false;
283
284 if(!pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::VERT ) || pBoxInfoItem->GetVert())
285 mbVer = true;
286
287 if(!pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::HORI ) || pBoxInfoItem->GetHori())
288 mbHor = true;
289
290 if(!pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::LEFT ) || mbLeft)
291 bLeft = true;
292
293 if(!pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::RIGHT ) || mbRight)
294 bRight = true;
295
296 if(!pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::TOP ) || mbTop)
297 bTop = true;
298
299 if(!pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::BOTTOM ) || mbBottom)
300 bBottom = true;
301
303 UpdateCellBorder(bTop, bBottom, bLeft, bRight, mbVer, mbHor, mbDiagTLBR, mbDiagBLTR);
304 else
305 UpdateCellBorder(bTop, bBottom, bRight, bLeft, mbVer, mbHor, mbDiagTLBR, mbDiagBLTR);
306
307 if(mbVer || mbHor || bLeft || bRight || bTop || bBottom)
308 mbInnerBorder = true;
309 else
310 mbInnerBorder = false;
311
313 }
314 }
315 break;
316 case SID_ATTR_BORDER_DIAG_TLBR:
317 mbDiagTLBR = false;
318 if( eState == SfxItemState::DONTCARE )
319 {
320 mbDiagTLBR = true;
322 }
323 else if(eState >= SfxItemState::DEFAULT)
324 {
325 const SvxLineItem* pItem = dynamic_cast< const SvxLineItem* >(pState);
326 if(pItem)
327 {
328 const editeng::SvxBorderLine* aLine = pItem->GetLine();
329 if(aLine)
330 {
331 mnDiagTLBRInWidth = aLine->GetInWidth();
334
336 }
337 }
338 }
341 break;
342 case SID_ATTR_BORDER_DIAG_BLTR:
343 mbDiagBLTR = false;
344 if( eState == SfxItemState::DONTCARE )
345 {
346 mbDiagBLTR = true;
348 }
349 else if(eState >= SfxItemState::DEFAULT)
350 {
351 const SvxLineItem* pItem = dynamic_cast< const SvxLineItem* >(pState);
352 if(pItem)
353 {
354 const editeng::SvxBorderLine* aLine = pItem->GetLine();
355
356 if(aLine)
357 {
358 mnDiagBLTRInWidth = aLine->GetInWidth();
361
363 }
364 }
365 }
368 break;
369 }
370}
371
373{
374 //FIXME: update for new line border possibilities
376 mxTBLineStyle->set_item_icon_name(LINESTYLE, msIMGLineStyle1);
377 else if(mnOutWidth == SvxBorderLineWidth::Medium && mnInWidth == 0 && mnDistance == 0) //2
378 mxTBLineStyle->set_item_icon_name(LINESTYLE, msIMGLineStyle2);
379 else if(mnOutWidth == SvxBorderLineWidth::Thick && mnInWidth == 0 && mnDistance == 0) //3
380 mxTBLineStyle->set_item_icon_name(LINESTYLE, msIMGLineStyle3);
381 else if(mnOutWidth == SvxBorderLineWidth::ExtraThick && mnInWidth == 0 && mnDistance == 0) //4
382 mxTBLineStyle->set_item_icon_name(LINESTYLE, msIMGLineStyle4);
384 mxTBLineStyle->set_item_icon_name(LINESTYLE, msIMGLineStyle5);
386 mxTBLineStyle->set_item_icon_name(LINESTYLE, msIMGLineStyle6);
388 mxTBLineStyle->set_item_icon_name(LINESTYLE, msIMGLineStyle7);
390 mxTBLineStyle->set_item_icon_name(LINESTYLE, msIMGLineStyle8);
392 mxTBLineStyle->set_item_icon_name(LINESTYLE, msIMGLineStyle9);
393 else
394 mxTBLineStyle->set_item_icon_name(LINESTYLE, msIMGLineStyle1);
395}
396
398{
400 {
401 mxTBLineColor->set_sensitive(true);
402 mxTBLineStyle->set_sensitive(true);
403
404 //set line style state
406 {
407 }
409 {
413 }
415 {
419 }
421 {
423 {
427 }
428 else
429 {
430 mnInWidth = 0;
431 mnOutWidth = 0;
432 mnDistance = 0;
433 }
434 }
436 {
438 {
439 mnInWidth = 0;
440 mnOutWidth = 0;
441 mnDistance = 0;
442 }
443 }
445 {
447 {
448 mnInWidth = 0;
449 mnOutWidth = 0;
450 mnDistance = 0;
451 }
452 }
453 else
454 {
455 mnInWidth = 0;
456 mnOutWidth = 0;
457 mnDistance = 0;
458 }
459 SetStyleIcon();
460 }
461 else
462 {
463 mxTBLineColor->set_sensitive(false);
464 mxTBLineStyle->set_sensitive(false);
465 }
466}
467
468void CellAppearancePropertyPanel::UpdateCellBorder(bool bTop, bool bBot, bool bLeft, bool bRight,
469 bool bVer, bool bHor, bool bTLBR, bool bBLTR)
470{
471 const Size aBmpSize = maIMGCellBorder.GetBitmapEx().GetSizePixel();
472
473 if (aBmpSize.Width() == 43 && aBmpSize.Height() == 43)
474 {
475 ScopedVclPtr<VirtualDevice> pVirDev(mxTBCellBorder->create_virtual_device());
476 pVirDev->SetOutputSizePixel(aBmpSize);
477 pVirDev->SetLineColor( ::Application::GetSettings().GetStyleSettings().GetFieldTextColor() ) ;
478 pVirDev->SetFillColor(COL_BLACK);
479 pVirDev->DrawImage(Point(0, 0), maIMGCellBorder);
480 Point aTL(2, 1), aTR(42,1), aBL(2, 41), aBR(42, 41), aHL(2,21), aHR(42, 21), aVT(22,1), aVB(22, 41);
481 if(bLeft)
482 pVirDev->DrawLine( aTL,aBL );
483 if(bRight)
484 pVirDev->DrawLine( aTR,aBR );
485 if(bTop)
486 pVirDev->DrawLine( aTL,aTR );
487 if(bBot)
488 pVirDev->DrawLine( aBL,aBR );
489 if(bVer)
490 pVirDev->DrawLine( aVT,aVB );
491 if(bHor)
492 pVirDev->DrawLine( aHL,aHR );
493 if(bTLBR)
494 pVirDev->DrawLine( aTL,aBR );
495 if(bBLTR)
496 pVirDev->DrawLine( aBL,aTR );
497 mxTBCellBorder->set_item_image(SETBORDERSTYLE, pVirDev);
498 }
499 else
500 mxTBCellBorder->set_item_icon_name(SETBORDERSTYLE, msIMGCellBorder);
501}
502// namespace close
503
504} // end of namespace ::sc::sidebar
505
506/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr OUStringLiteral LINESTYLE
constexpr OUStringLiteral SETBORDERSTYLE
static bool GetLayoutRTL()
static const AllSettings & GetSettings()
const Size & GetSizePixel() const
BitmapEx GetBitmapEx() const
virtual void dispose()
constexpr tools::Long Height() const
constexpr tools::Long Width() const
static const sal_Int16 ExtraThick
static const sal_Int16 Thin
static const sal_Int16 Medium
static const sal_Int16 Hairline
static const sal_Int16 Thick
bool IsValid(SvxBoxInfoItemValidFlags nValid) const
const editeng::SvxBorderLine * GetHori() const
const editeng::SvxBorderLine * GetVert() const
const editeng::SvxBorderLine * GetTop() const
const editeng::SvxBorderLine * GetRight() const
const editeng::SvxBorderLine * GetLeft() const
const editeng::SvxBorderLine * GetBottom() const
const editeng::SvxBorderLine * GetLine() const
sal_uInt16 GetDistance() const
sal_uInt16 GetOutWidth() const
sal_uInt16 GetInWidth() const
virtual void NotifyItemUpdate(const sal_uInt16 nSId, const SfxItemState eState, const SfxPoolItem *pState) override
std::unique_ptr< ToolbarPopupContainer > mxCellBorderPopoverContainer
std::unique_ptr< ToolbarUnoDispatcher > mxLineColorDispatch
std::unique_ptr< ToolbarUnoDispatcher > mxBackColorDispatch
virtual void HandleContextChange(const vcl::EnumContext &rContext) override
static std::unique_ptr< PanelLayout > Create(weld::Widget *pParent, const css::uno::Reference< css::frame::XFrame > &rxFrame, SfxBindings *pBindings)
::sfx2::sidebar::ControllerItem maBorderInnerControl
void UpdateCellBorder(bool bTop, bool bBot, bool bLeft, bool bRight, bool bVer, bool bHor, bool bTLBR, bool bBLTR)
std::unique_ptr< weld::Toolbar > mxTBCellBackground
std::unique_ptr< ToolbarPopupContainer > mxLinePopoverContainer
CellAppearancePropertyPanel(weld::Widget *pParent, const css::uno::Reference< css::frame::XFrame > &rxFrame, SfxBindings *pBindings)
::sfx2::sidebar::ControllerItem maBorderOuterControl
void SetLineStyleSelect(sal_uInt16 out, sal_uInt16 in, sal_uInt16 dis)
constexpr ::Color COL_BLACK(0x00, 0x00, 0x00)
virtual SfxBindings & GetBindings() override
float u
StockImage
Yes
SfxDispatcher * GetDispatcher()
IMPL_LINK_NOARG(AlignmentPropertyPanel, AngleModifiedHdl, weld::MetricSpinButton &, void)
SfxItemState