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>
25 #include <svtools/toolbarmenu.hxx>
26 #include <editeng/borderline.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>
33 #include "CellLineStyleControl.hxx"
35 
36 using namespace css;
37 using namespace css::uno;
38 
39 constexpr OStringLiteral SETBORDERSTYLE = "SetBorderStyle";
40 constexpr OStringLiteral LINESTYLE = "LineStyle";
41 
42 // namespace open
43 
44 namespace sc::sidebar {
45 
46 CellAppearancePropertyPanel::CellAppearancePropertyPanel(
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();
112  mxLinePopoverContainer.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 
143 IMPL_LINK_NOARG(CellAppearancePropertyPanel, TbxCellBorderSelectHdl, const OString&, void)
144 {
145  mxTBCellBorder->set_menu_item_active(SETBORDERSTYLE, !mxTBCellBorder->get_menu_item_active(SETBORDERSTYLE));
146 }
147 
148 IMPL_LINK_NOARG(CellAppearancePropertyPanel, TbxCellBorderMenuHdl, const OString&, 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 
160 IMPL_LINK_NOARG(CellAppearancePropertyPanel, TbxLineStyleSelectHdl, const OString&, void)
161 {
162  mxTBLineStyle->set_menu_item_active(LINESTYLE, !mxTBLineStyle->get_menu_item_active(LINESTYLE));
163 }
164 
165 IMPL_LINK_NOARG(CellAppearancePropertyPanel, TbxLineStyleMenuHdl, const OString&, 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 
179 std::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:
213  mbBorderStyleAvailable = false;
214  if( eState == SfxItemState::DONTCARE )
215  {
216  mbBorderStyleAvailable = true;
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();
332  mnDiagTLBROutWidth = aLine->GetOutWidth();
333  mnDiagTLBRDistance = aLine->GetDistance();
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();
359  mnDiagBLTROutWidth = aLine->GetOutWidth();
360  mnDiagBLTRDistance = aLine->GetDistance();
361 
363  }
364  }
365  }
368  break;
369  }
370 }
371 
373 {
374  //FIXME: update for new line border possibilities
375  if(mnOutWidth == DEF_LINE_WIDTH_0 && mnInWidth == 0 && mnDistance == 0) //1
376  mxTBLineStyle->set_item_icon_name(LINESTYLE, msIMGLineStyle1);
377  else if(mnOutWidth == DEF_LINE_WIDTH_2 && mnInWidth == 0 && mnDistance == 0) //2
378  mxTBLineStyle->set_item_icon_name(LINESTYLE, msIMGLineStyle2);
379  else if(mnOutWidth == DEF_LINE_WIDTH_3 && mnInWidth == 0 && mnDistance == 0) //3
380  mxTBLineStyle->set_item_icon_name(LINESTYLE, msIMGLineStyle3);
381  else if(mnOutWidth == DEF_LINE_WIDTH_4 && 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  }
408  else if( !mbBorderStyleAvailable && mbDiagTLBR && !mbDiagBLTR )
409  {
413  }
414  else if ( !mbBorderStyleAvailable && !mbDiagTLBR && mbDiagBLTR )
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 
468 void 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 OStringLiteral LINESTYLE
static const AllSettings & GetSettings()
const editeng::SvxBorderLine * GetVert() const
std::unique_ptr< ToolbarUnoDispatcher > mxLineColorDispatch
::sfx2::sidebar::ControllerItem maBorderOuterControl
const editeng::SvxBorderLine * GetRight() const
#define DEF_LINE_WIDTH_1
constexpr tools::Long Width() const
sal_uInt16 GetOutWidth() const
virtual void NotifyItemUpdate(const sal_uInt16 nSId, const SfxItemState eState, const SfxPoolItem *pState) override
void UpdateCellBorder(bool bTop, bool bBot, bool bLeft, bool bRight, bool bVer, bool bHor, bool bTLBR, bool bBLTR)
const editeng::SvxBorderLine * GetHori() const
const editeng::SvxBorderLine * GetTop() const
std::unique_ptr< ToolbarUnoDispatcher > mxBackColorDispatch
#define DEF_LINE_WIDTH_3
virtual void HandleContextChange(const vcl::EnumContext &rContext) override
::sfx2::sidebar::ControllerItem maBorderInnerControl
const editeng::SvxBorderLine * GetLeft() const
virtual void dispose()
std::unique_ptr< ToolbarPopupContainer > mxLinePopoverContainer
constexpr OStringLiteral SETBORDERSTYLE
static bool GetLayoutRTL()
#define DEF_LINE_WIDTH_4
sal_uInt16 GetDistance() const
bool IsValid(SvxBoxInfoItemValidFlags nValid) const
StockImage
static std::unique_ptr< PanelLayout > Create(weld::Widget *pParent, const css::uno::Reference< css::frame::XFrame > &rxFrame, SfxBindings *pBindings)
const editeng::SvxBorderLine * GetLine() const
SfxItemState
constexpr tools::Long Height() const
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BLACK
BitmapEx GetBitmapEx() const
#define DEF_LINE_WIDTH_2
void SetLineStyleSelect(sal_uInt16 out, sal_uInt16 in, sal_uInt16 dis)
IMPL_LINK_NOARG(AlignmentPropertyPanel, AngleModifiedHdl, weld::MetricSpinButton &, void)
std::unique_ptr< ToolbarPopupContainer > mxCellBorderPopoverContainer
#define DEF_LINE_WIDTH_0
const Size & GetSizePixel() const
sal_uInt16 GetInWidth() const
std::unique_ptr< weld::Toolbar > mxTBCellBackground
const editeng::SvxBorderLine * GetBottom() const