LibreOffice Module cui (master)  1
border.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 <sal/config.h>
21 
22 #include <sfx2/objsh.hxx>
23 #include <svx/strings.hrc>
24 #include <svx/svxids.hrc>
25 
26 #include <strings.hrc>
27 #include <bitmaps.hlst>
28 
29 #include <editeng/boxitem.hxx>
30 #include <editeng/lineitem.hxx>
31 #include <border.hxx>
32 #include <svx/dlgutil.hxx>
33 #include <dialmgr.hxx>
34 #include <sfx2/htmlmode.hxx>
35 #include <vcl/fieldvalues.hxx>
36 #include <vcl/settings.hxx>
37 #include <vcl/svapp.hxx>
38 #include <svx/dialmgr.hxx>
39 #include <svx/flagsdef.hxx>
40 #include <svl/grabbagitem.hxx>
41 #include <svl/intitem.hxx>
42 #include <svl/ilstitem.hxx>
43 #include <svl/int64item.hxx>
44 #include <sal/macros.h>
45 #include <com/sun/star/lang/XServiceInfo.hpp>
46 #include <comphelper/lok.hxx>
47 #include <svtools/unitconv.hxx>
48 
49 using namespace ::editeng;
50 using ::com::sun::star::uno::Reference;
51 using ::com::sun::star::lang::XServiceInfo;
52 using ::com::sun::star::uno::UNO_QUERY;
53 
54 
55 /*
56  * [Description:]
57  * TabPage for setting the border attributes.
58  * Needs
59  * a SvxShadowItem: shadow
60  * a SvxBoxItem: lines left, right, top, bottom,
61  * a SvxBoxInfo: lines vertical, horizontal, distance, flags
62  *
63  * Lines can have three conditions:
64  * 1. Show ( -> valid values )
65  * 2. Hide ( -> NULL-Pointer )
66  * 3. DontCare ( -> special Valid-Flags in the InfoItem )
67  */
68 
69 // static ----------------------------------------------------------------
70 
72  svl::Items<
73  SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_SHADOW,
74  SID_ATTR_ALIGN_MARGIN, SID_ATTR_ALIGN_MARGIN,
75  SID_ATTR_BORDER_CONNECT, SID_ATTR_BORDER_CONNECT,
76  SID_SW_COLLAPSING_BORDERS, SID_SW_COLLAPSING_BORDERS,
77  SID_ATTR_BORDER_DIAG_TLBR, SID_ATTR_BORDER_DIAG_BLTR>);
78 
79 namespace
80 {
81 int lcl_twipsToPt(sal_Int64 nTwips)
82 {
83  return vcl::ConvertDoubleValue(nTwips, 0, FieldUnit::TWIP, MapUnit::MapPoint) * 100;
84 }
85 }
86 
87 const std::vector<int> SvxBorderTabPage::m_aLineWidths = {
88  lcl_twipsToPt(SvxBorderLineWidth::Hairline),
89  lcl_twipsToPt(SvxBorderLineWidth::VeryThin),
90  lcl_twipsToPt(SvxBorderLineWidth::Thin),
91  lcl_twipsToPt(SvxBorderLineWidth::Medium),
92  lcl_twipsToPt(SvxBorderLineWidth::Thick),
93  lcl_twipsToPt(SvxBorderLineWidth::ExtraThick),
94  -1
95 };
96 
98 {
99  auto nMin = rField.denormalize(rField.get_min(FieldUnit::TWIP));
100  rField.set_digits(1);
101  rField.set_min(rField.normalize(nMin), FieldUnit::TWIP);
102 }
103 
104 // returns in pt
105 static sal_Int64 lcl_GetMinLineWidth(SvxBorderLineStyle aStyle)
106 {
107  switch (aStyle)
108  {
109  case SvxBorderLineStyle::NONE:
110  return 0;
111 
112  case SvxBorderLineStyle::SOLID:
113  case SvxBorderLineStyle::DOTTED:
114  case SvxBorderLineStyle::DASHED:
115  case SvxBorderLineStyle::FINE_DASHED:
116  case SvxBorderLineStyle::DASH_DOT:
117  case SvxBorderLineStyle::DASH_DOT_DOT:
118  return 15;
119 
120  // Double lines
121  case SvxBorderLineStyle::DOUBLE: return 15;
122  case SvxBorderLineStyle::DOUBLE_THIN: return 15;
123  case SvxBorderLineStyle::THINTHICK_SMALLGAP: return 20;
124  case SvxBorderLineStyle::THINTHICK_MEDIUMGAP: return 15;
125  case SvxBorderLineStyle::THINTHICK_LARGEGAP: return 15;
126  case SvxBorderLineStyle::THICKTHIN_SMALLGAP: return 20;
127  case SvxBorderLineStyle::THICKTHIN_MEDIUMGAP: return 15;
128  case SvxBorderLineStyle::THICKTHIN_LARGEGAP: return 15;
129 
130  case SvxBorderLineStyle::EMBOSSED: return 15;
131  case SvxBorderLineStyle::ENGRAVED: return 15;
132 
133  case SvxBorderLineStyle::OUTSET: return 10;
134  case SvxBorderLineStyle::INSET: return 10;
135 
136  default:
137  return 15;
138  }
139 }
140 
141 // number of preset images to show
142 const sal_uInt16 BORDER_PRESET_COUNT = 5;
143 
144 // number of shadow images to show
145 const sal_uInt16 BORDER_SHADOW_COUNT = 5;
146 
148  : mrVsPos(rVsPos)
149  , mrMfSize(rMfSize)
150  , mrLbColor(rLbColor)
151 {
152 }
153 
155 {
156  SvxShadowItem aItem(rItem);
157  if (!mrVsPos.IsNoSelection())
158  {
159  switch (mrVsPos.GetSelectedItemId())
160  {
161  case 1:
162  aItem.SetLocation(SvxShadowLocation::NONE);
163  break;
164  case 2:
165  aItem.SetLocation(SvxShadowLocation::BottomRight);
166  break;
167  case 3:
168  aItem.SetLocation(SvxShadowLocation::TopRight);
169  break;
170  case 4:
171  aItem.SetLocation(SvxShadowLocation::BottomLeft);
172  break;
173  case 5:
174  aItem.SetLocation(SvxShadowLocation::TopLeft);
175  break;
176  default:
177  aItem.SetLocation(SvxShadowLocation::NONE);
178  break;
179  }
180  }
181  // Default value was saved; so don't change the aItem's width if the control
182  // has not changed its value, to avoid round-trip errors (like twip->cm->twip)
183  // E.g., initial 100 twip will become 0.18 cm, which will return as 102 twip
185  aItem.SetWidth(mrMfSize.denormalize(mrMfSize.get_value(FieldUnit::TWIP)));
186  if (!mrLbColor.IsNoSelection())
188  return aItem;
189 }
190 
192 {
193  switch (rItem.GetLocation())
194  {
195  case SvxShadowLocation::NONE:
196  mrVsPos.SelectItem(1);
197  break;
198  case SvxShadowLocation::BottomRight:
199  mrVsPos.SelectItem(2);
200  break;
201  case SvxShadowLocation::TopRight:
202  mrVsPos.SelectItem(3);
203  break;
204  case SvxShadowLocation::BottomLeft:
205  mrVsPos.SelectItem(4);
206  break;
207  case SvxShadowLocation::TopLeft:
208  mrVsPos.SelectItem(5);
209  break;
210  default:
212  break;
213  }
214  mrVsPos.SaveValue();
215  mrMfSize.set_value(mrMfSize.normalize(rItem.GetWidth()), FieldUnit::TWIP);
217  mrLbColor.SelectEntry(rItem.GetColor());
219 }
220 
222 {
223  return mrVsPos.IsValueChangedFromSaved() ||
226 }
227 
229 {
231  mrMfSize.set_text("");
233 }
234 
237  : mrLeftWrp(rMfLeft)
238  , mrRightWrp(rMfRight)
239  , mrTopWrp(rMfTop)
240  , mrBottomWrp(rMfBottom)
241 {
242 }
243 
245 {
246  SvxMarginItem aItem(rItem);
247  if (mrLeftWrp.get_sensitive())
248  aItem.SetLeftMargin(mrLeftWrp.denormalize(mrLeftWrp.get_value(FieldUnit::TWIP)));
250  aItem.SetRightMargin(mrRightWrp.denormalize(mrRightWrp.get_value(FieldUnit::TWIP)));
251  if (mrTopWrp.get_sensitive())
252  aItem.SetTopMargin(mrTopWrp.denormalize(mrTopWrp.get_value(FieldUnit::TWIP)));
255  return aItem;
256 }
257 
259 {
264 }
265 
267 {
268  mrLeftWrp.set_value(mrLeftWrp.normalize(rItem.GetLeftMargin()), FieldUnit::TWIP);
269  mrRightWrp.set_value(mrRightWrp.normalize(rItem.GetRightMargin()), FieldUnit::TWIP);
270  mrTopWrp.set_value(mrTopWrp.normalize(rItem.GetTopMargin()), FieldUnit::TWIP);
271  mrBottomWrp.set_value(mrBottomWrp.normalize(rItem.GetBottomMargin()), FieldUnit::TWIP);
276 }
277 
279 {
280  const OUString sEmpty;
281  mrLeftWrp.set_text(sEmpty);
282  mrRightWrp.set_text(sEmpty);
283  mrTopWrp.set_text(sEmpty);
284  mrBottomWrp.set_text(sEmpty);
285 }
286 
288  : SfxTabPage(pPage, pController, "cui/ui/borderpage.ui", "BorderPage", &rCoreAttrs)
289  , nMinValue(0)
290  , nSWMode(SwBorderModes::NONE)
291  , mnBoxSlot(SID_ATTR_BORDER_OUTER)
292  , mnShadowSlot(SID_ATTR_BORDER_SHADOW)
293  , mbHorEnabled(false)
294  , mbVerEnabled(false)
295  , mbTLBREnabled(false)
296  , mbBLTREnabled(false)
297  , mbUseMarginItem(false)
298  , mbLeftModified(false)
299  , mbRightModified(false)
300  , mbTopModified(false)
301  , mbBottomModified(false)
302  , mbSync(true)
303  , mbRemoveAdjacentCellBorders(false)
304  , bIsCalcDoc(false)
305  , m_xWndPresets(new ValueSet(nullptr))
306  , m_xWndPresetsWin(new weld::CustomWeld(*m_xBuilder, "presets", *m_xWndPresets))
307  , m_xUserDefFT(m_xBuilder->weld_label("userdefft"))
308  , m_xFrameSelWin(new weld::CustomWeld(*m_xBuilder, "framesel", m_aFrameSel))
309  , m_xLbLineStyle(new SvtLineListBox(m_xBuilder->weld_menu_button("linestylelb")))
310  , m_xLbLineColor(new ColorListBox(m_xBuilder->weld_menu_button("linecolorlb"),
311  [this]{ return GetDialogController()->getDialog(); }))
312  , m_xLineWidthLB(m_xBuilder->weld_combo_box("linewidthlb"))
313  , m_xLineWidthMF(m_xBuilder->weld_metric_spin_button("linewidthmf", FieldUnit::POINT))
314  , m_xSpacingFrame(m_xBuilder->weld_container("spacing"))
315  , m_xLeftFT(m_xBuilder->weld_label("leftft"))
316  , m_xLeftMF(m_xBuilder->weld_metric_spin_button("leftmf", FieldUnit::MM))
317  , m_xRightFT(m_xBuilder->weld_label("rightft"))
318  , m_xRightMF(m_xBuilder->weld_metric_spin_button("rightmf", FieldUnit::MM))
319  , m_xTopFT(m_xBuilder->weld_label("topft"))
320  , m_xTopMF(m_xBuilder->weld_metric_spin_button("topmf", FieldUnit::MM))
321  , m_xBottomFT(m_xBuilder->weld_label("bottomft"))
322  , m_xBottomMF(m_xBuilder->weld_metric_spin_button("bottommf", FieldUnit::MM))
323  , m_xSynchronizeCB(m_xBuilder->weld_check_button("sync"))
324  , m_xShadowFrame(m_xBuilder->weld_container("shadow"))
325  , m_xWndShadows(new ValueSet(nullptr))
326  , m_xWndShadowsWin(new weld::CustomWeld(*m_xBuilder, "shadows", *m_xWndShadows))
327  , m_xFtShadowSize(m_xBuilder->weld_label("distanceft"))
328  , m_xEdShadowSize(m_xBuilder->weld_metric_spin_button("distancemf", FieldUnit::MM))
329  , m_xFtShadowColor(m_xBuilder->weld_label("shadowcolorft"))
330  , m_xLbShadowColor(new ColorListBox(m_xBuilder->weld_menu_button("shadowcolorlb"),
331  [this]{ return GetDialogController()->getDialog(); }))
332  , m_xPropertiesFrame(m_xBuilder->weld_container("properties"))
333  , m_xMergeWithNextCB(m_xBuilder->weld_check_button("mergewithnext"))
334  , m_xMergeAdjacentBordersCB(m_xBuilder->weld_check_button("mergeadjacent"))
335  , m_xRemoveAdjacentCellBordersCB(m_xBuilder->weld_check_button("rmadjcellborders"))
336  , m_xRemoveAdjacentCellBordersFT(m_xBuilder->weld_label("rmadjcellbordersft"))
337 {
338  static std::vector<OUString> aBorderImageIds;
339 
340  if (aBorderImageIds.empty())
341  {
343  {
344  aBorderImageIds.insert(aBorderImageIds.end(), {
345  RID_SVXBMP_CELL_NONE_32,
346  RID_SVXBMP_CELL_ALL_32,
347  RID_SVXBMP_CELL_LR_32,
348  RID_SVXBMP_CELL_TB_32,
349  RID_SVXBMP_CELL_L_32,
350  RID_SVXBMP_CELL_DIAG_32
351  });
352  }
353  else
354  {
355  aBorderImageIds.insert(aBorderImageIds.end(), {
356  RID_SVXBMP_CELL_NONE,
357  RID_SVXBMP_CELL_ALL,
358  RID_SVXBMP_CELL_LR,
359  RID_SVXBMP_CELL_TB,
360  RID_SVXBMP_CELL_L,
361  RID_SVXBMP_CELL_DIAG
362  });
363  }
364  aBorderImageIds.insert(aBorderImageIds.end(), {
365  RID_SVXBMP_HOR_NONE,
366  RID_SVXBMP_HOR_OUTER,
367  RID_SVXBMP_HOR_HOR,
368  RID_SVXBMP_HOR_ALL,
369  RID_SVXBMP_HOR_OUTER2,
370  RID_SVXBMP_VER_NONE,
371  RID_SVXBMP_VER_OUTER,
372  RID_SVXBMP_VER_VER,
373  RID_SVXBMP_VER_ALL,
374  RID_SVXBMP_VER_OUTER2,
375  RID_SVXBMP_TABLE_NONE,
376  RID_SVXBMP_TABLE_OUTER,
377  RID_SVXBMP_TABLE_OUTERH,
378  RID_SVXBMP_TABLE_ALL,
379  RID_SVXBMP_TABLE_OUTER2
380  });
381  }
382 
383  for (auto const & rImageId : aBorderImageIds)
384  m_aBorderImgVec.emplace_back(StockImage::Yes, rImageId);
385 
386  static std::vector<OUString> aShadowImageIds;
387  if (aShadowImageIds.empty())
388  {
390  {
391  aShadowImageIds.insert(aShadowImageIds.end(), {
392  RID_SVXBMP_SHADOWNONE_32,
393  RID_SVXBMP_SHADOW_BOT_RIGHT_32,
394  RID_SVXBMP_SHADOW_TOP_RIGHT_32,
395  RID_SVXBMP_SHADOW_BOT_LEFT_32,
396  RID_SVXBMP_SHADOW_TOP_LEFT_32
397  });
398  }
399  else
400  {
401  aShadowImageIds.insert(aShadowImageIds.end(), {
402  RID_SVXBMP_SHADOWNONE,
403  RID_SVXBMP_SHADOW_BOT_RIGHT,
404  RID_SVXBMP_SHADOW_TOP_RIGHT,
405  RID_SVXBMP_SHADOW_BOT_LEFT,
406  RID_SVXBMP_SHADOW_TOP_LEFT
407  });
408  }
409  }
410 
411  for (auto const & rImageId : aShadowImageIds)
412  m_aShadowImgVec.emplace_back(StockImage::Yes, rImageId);
413 
414  assert(m_aShadowImgVec.size() == BORDER_SHADOW_COUNT);
415 
416  // this page needs ExchangeSupport
417  SetExchangeSupport();
418 
419  /* Use SvxMarginItem instead of margins from SvxBoxItem, if present.
420  -> Remember this state in mbUseMarginItem, because other special handling
421  is needed across various functions... */
422  mbUseMarginItem = rCoreAttrs.GetItemState(GetWhich(SID_ATTR_ALIGN_MARGIN)) != SfxItemState::UNKNOWN;
423 
424  if (const SfxIntegerListItem* p = rCoreAttrs.GetItemIfSet(SID_ATTR_BORDER_STYLES))
425  {
426  std::vector<sal_Int32> aUsedStyles = p->GetList();
427  for (int aUsedStyle : aUsedStyles)
428  maUsedBorderStyles.insert(static_cast<SvxBorderLineStyle>(aUsedStyle));
429  }
430 
431  if (const SfxInt64Item* p = rCoreAttrs.GetItemIfSet(SID_ATTR_BORDER_DEFAULT_WIDTH))
432  {
433  // The caller specifies default line width. Honor it.
434  SetLineWidth(p->GetValue());
435  }
436 
437  // set metric
438  FieldUnit eFUnit = GetModuleFieldUnit( rCoreAttrs );
439 
440  if( mbUseMarginItem )
441  {
442  // copied from SvxAlignmentTabPage
443  switch ( eFUnit )
444  {
445  // #103396# the default value (1pt) can't be accurately represented in
446  // inches or pica with two decimals, so point is used instead.
447  case FieldUnit::PICA:
448  case FieldUnit::INCH:
449  case FieldUnit::FOOT:
450  case FieldUnit::MILE:
451  eFUnit = FieldUnit::POINT;
452  break;
453 
454  case FieldUnit::CM:
455  case FieldUnit::M:
456  case FieldUnit::KM:
457  eFUnit = FieldUnit::MM;
458  break;
459  default: ;//prevent warning
460  }
461  }
462  else
463  {
464  switch ( eFUnit )
465  {
466  case FieldUnit::M:
467  case FieldUnit::KM:
468  eFUnit = FieldUnit::MM;
469  break;
470  default: ; //prevent warning
471  }
472  }
473 
474  SetFieldUnit(*m_xEdShadowSize, eFUnit);
475 
476  sal_uInt16 nWhich = GetWhich( SID_ATTR_BORDER_INNER, false );
477  bool bIsDontCare = true;
478 
479  if ( rCoreAttrs.GetItemState( nWhich ) >= SfxItemState::DEFAULT )
480  {
481  // paragraph or table
482  const SvxBoxInfoItem* pBoxInfo =
483  static_cast<const SvxBoxInfoItem*>(&( rCoreAttrs.Get( nWhich ) ));
484 
485  mbHorEnabled = pBoxInfo->IsHorEnabled();
486  mbVerEnabled = pBoxInfo->IsVerEnabled();
487  mbTLBREnabled = rCoreAttrs.GetItemState(GetWhich(SID_ATTR_BORDER_DIAG_TLBR)) != SfxItemState::UNKNOWN;
488  mbBLTREnabled = rCoreAttrs.GetItemState(GetWhich(SID_ATTR_BORDER_DIAG_BLTR)) != SfxItemState::UNKNOWN;
489 
490  if(pBoxInfo->IsDist())
491  {
492  SetFieldUnit(*m_xLeftMF, eFUnit);
493  SetFieldUnit(*m_xRightMF, eFUnit);
494  SetFieldUnit(*m_xTopMF, eFUnit);
495  SetFieldUnit(*m_xBottomMF, eFUnit);
496  m_xSynchronizeCB->connect_toggled(LINK(this, SvxBorderTabPage, SyncHdl_Impl));
497  m_xLeftMF->connect_value_changed(LINK(this, SvxBorderTabPage, ModifyDistanceHdl_Impl));
498  m_xRightMF->connect_value_changed(LINK(this, SvxBorderTabPage, ModifyDistanceHdl_Impl));
499  m_xTopMF->connect_value_changed(LINK(this, SvxBorderTabPage, ModifyDistanceHdl_Impl));
500  m_xBottomMF->connect_value_changed(LINK(this, SvxBorderTabPage, ModifyDistanceHdl_Impl));
501  }
502  else
503  {
504  m_xSpacingFrame->hide();
505  }
506  bIsDontCare = !pBoxInfo->IsValid( SvxBoxInfoItemValidFlags::DISABLE );
507  }
508  if(!mbUseMarginItem && eFUnit == FieldUnit::MM && MapUnit::MapTwip == rCoreAttrs.GetPool()->GetMetric( GetWhich( SID_ATTR_BORDER_INNER ) ))
509  {
510  //#i91548# changing the number of decimal digits changes the minimum values, too
511  lcl_SetDecimalDigitsTo1(*m_xLeftMF);
512  lcl_SetDecimalDigitsTo1(*m_xRightMF);
513  lcl_SetDecimalDigitsTo1(*m_xTopMF);
514  lcl_SetDecimalDigitsTo1(*m_xBottomMF);
515  lcl_SetDecimalDigitsTo1(*m_xEdShadowSize);
516  }
517 
518  FrameSelFlags nFlags = FrameSelFlags::Outer;
519  if( mbHorEnabled )
520  nFlags |= FrameSelFlags::InnerHorizontal;
521  if( mbVerEnabled )
522  nFlags |= FrameSelFlags::InnerVertical;
523  if( mbTLBREnabled )
524  nFlags |= FrameSelFlags::DiagonalTLBR;
525  if( mbBLTREnabled )
526  nFlags |= FrameSelFlags::DiagonalBLTR;
527  if( bIsDontCare )
528  nFlags |= FrameSelFlags::DontCare;
529  m_aFrameSel.Initialize( nFlags );
530 
531  m_aFrameSel.SetSelectHdl(LINK(this, SvxBorderTabPage, LinesChanged_Impl));
532  m_xLbLineStyle->SetSelectHdl( LINK( this, SvxBorderTabPage, SelStyleHdl_Impl ) );
533  m_xLbLineColor->SetSelectHdl( LINK( this, SvxBorderTabPage, SelColHdl_Impl ) );
534  m_xLineWidthLB->connect_changed(LINK(this, SvxBorderTabPage, ModifyWidthLBHdl_Impl));
535  m_xLineWidthMF->connect_value_changed(LINK(this, SvxBorderTabPage, ModifyWidthMFHdl_Impl));
536  m_xWndPresets->SetSelectHdl( LINK( this, SvxBorderTabPage, SelPreHdl_Impl ) );
537  m_xWndShadows->SetSelectHdl( LINK( this, SvxBorderTabPage, SelSdwHdl_Impl ) );
538 
539  FillValueSets();
540  FillLineListBox_Impl();
541 
542  // Reapply line width: probably one of predefined values should be selected
543  SetLineWidth(m_xLineWidthMF->get_value(FieldUnit::NONE));
544 
545  // connections
546  const SfxPoolItem* pItem = nullptr;
547  if (rCoreAttrs.HasItem(GetWhich(SID_ATTR_PARA_GRABBAG), &pItem))
548  {
549  const SfxGrabBagItem* pGrabBag = static_cast<const SfxGrabBagItem*>(pItem);
550  auto it = pGrabBag->GetGrabBag().find("DialogUseCharAttr");
551  if (it != pGrabBag->GetGrabBag().end())
552  {
553  bool bDialogUseCharAttr = false;
554  it->second >>= bDialogUseCharAttr;
555  if (bDialogUseCharAttr)
556  {
557  mnShadowSlot = SID_ATTR_CHAR_SHADOW;
558  mnBoxSlot = SID_ATTR_CHAR_BOX;
559  }
560  }
561  }
562 
563  bool bSupportsShadow = !SfxItemPool::IsSlot(GetWhich(mnShadowSlot));
564  if( bSupportsShadow )
565  m_xShadowControls.reset(new ShadowControlsWrapper(*m_xWndShadows, *m_xEdShadowSize, *m_xLbShadowColor));
566  else
567  HideShadowControls();
568 
569  if (mbUseMarginItem)
570  m_xMarginControls.reset(new MarginControlsWrapper(*m_xLeftMF, *m_xRightMF, *m_xTopMF, *m_xBottomMF));
571 
572  // checkbox "Merge with next paragraph" only visible for Writer dialog format.paragraph
573  m_xMergeWithNextCB->hide();
574  // checkbox "Merge adjacent line styles" only visible for Writer dialog format.table
575  m_xMergeAdjacentBordersCB->hide();
576 
578  if (pDocSh)
579  {
580  Reference< XServiceInfo > xSI( pDocSh->GetModel(), UNO_QUERY );
581  if ( xSI.is() )
582  bIsCalcDoc = xSI->supportsService("com.sun.star.sheet.SpreadsheetDocument");
583  }
584  if( bIsCalcDoc )
585  {
586  m_xRemoveAdjacentCellBordersCB->connect_toggled(LINK(this, SvxBorderTabPage, RemoveAdjacentCellBorderHdl_Impl));
587  m_xRemoveAdjacentCellBordersCB->show();
588  m_xRemoveAdjacentCellBordersCB->set_sensitive(false);
589  }
590  else
591  {
592  m_xRemoveAdjacentCellBordersCB->hide();
593  m_xRemoveAdjacentCellBordersFT->hide();
594  }
595 }
596 
598 {
599  m_xLbShadowColor.reset();
600  m_xWndShadowsWin.reset();
601  m_xWndShadows.reset();
602  m_xLbLineColor.reset();
603  m_xLbLineStyle.reset();
604  m_xFrameSelWin.reset();
605  m_xWndPresetsWin.reset();
606  m_xWndPresets.reset();
607 }
608 
609 std::unique_ptr<SfxTabPage> SvxBorderTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
610  const SfxItemSet* rAttrSet )
611 {
612  return std::make_unique<SvxBorderTabPage>(pPage, pController, *rAttrSet);
613 }
614 
615 void SvxBorderTabPage::ResetFrameLine_Impl( svx::FrameBorderType eBorder, const SvxBorderLine* pCoreLine, bool bValid )
616 {
617  if( m_aFrameSel.IsBorderEnabled( eBorder ) )
618  {
619  if( bValid )
620  m_aFrameSel.ShowBorder( eBorder, pCoreLine );
621  else
622  m_aFrameSel.SetBorderDontCare( eBorder );
623  }
624 }
625 
627 {
628  if (maUsedBorderStyles.empty())
629  // All border styles are allowed.
630  return true;
631 
632  return maUsedBorderStyles.count(nStyle) > 0;
633 }
634 
636 {
637  SfxItemPool* pPool = rSet->GetPool();
638 
640  {
641  sal_uInt16 nBorderDiagId = pPool->GetWhich(SID_ATTR_BORDER_DIAG_TLBR);
642  if (const SvxLineItem* pLineItem = static_cast<const SvxLineItem*>(rSet->GetItem(nBorderDiagId)))
643  m_aFrameSel.ShowBorder(svx::FrameBorderType::TLBR, pLineItem->GetLine());
644  else
646  }
647 
649  {
650  sal_uInt16 nBorderDiagId = pPool->GetWhich(SID_ATTR_BORDER_DIAG_BLTR);
651  if (const SvxLineItem* pLineItem = static_cast<const SvxLineItem*>(rSet->GetItem(nBorderDiagId)))
652  m_aFrameSel.ShowBorder(svx::FrameBorderType::BLTR, pLineItem->GetLine());
653  else
655  }
656 
657  if (m_xShadowControls)
658  {
659  sal_uInt16 nShadowId = pPool->GetWhich(mnShadowSlot);
660  const SfxPoolItem* pItem = rSet->GetItem(nShadowId);
661  if (pItem)
662  m_xShadowControls->SetControlValue(*static_cast<const SvxShadowItem*>(pItem));
663  else
664  m_xShadowControls->SetControlDontKnow();
665  }
666 
667  if (m_xMarginControls)
668  {
669  sal_uInt16 nAlignMarginId = pPool->GetWhich(SID_ATTR_ALIGN_MARGIN);
670  const SfxPoolItem* pItem = rSet->GetItem(nAlignMarginId);
671  if (pItem)
672  m_xMarginControls->SetControlValue(*static_cast<const SvxMarginItem*>(pItem));
673  else
674  m_xMarginControls->SetControlDontKnow();
675  }
676 
677  sal_uInt16 nMergeAdjacentBordersId = pPool->GetWhich(SID_SW_COLLAPSING_BORDERS);
678  const SfxBoolItem *pMergeAdjacentBorders = static_cast<const SfxBoolItem*>(rSet->GetItem(nMergeAdjacentBordersId));
679  if (!pMergeAdjacentBorders)
681  else
682  m_xMergeAdjacentBordersCB->set_active(pMergeAdjacentBorders->GetValue());
683  m_xMergeAdjacentBordersCB->save_state();
684 
685  sal_uInt16 nMergeWithNextId = pPool->GetWhich(SID_ATTR_BORDER_CONNECT);
686  const SfxBoolItem *pMergeWithNext = static_cast<const SfxBoolItem*>(rSet->GetItem(nMergeWithNextId));
687  if (!pMergeWithNext)
689  else
690  m_xMergeWithNextCB->set_active(pMergeWithNext->GetValue());
691  m_xMergeWithNextCB->save_state();
692 
693  const SvxBoxItem* pBoxItem;
694  const SvxBoxInfoItem* pBoxInfoItem;
695  sal_uInt16 nWhichBox = GetWhich(mnBoxSlot);
696  MapUnit eCoreUnit;
697 
698  pBoxItem = static_cast<const SvxBoxItem*>(GetItem( *rSet, mnBoxSlot ));
699 
700  pBoxInfoItem = GetItem( *rSet, SID_ATTR_BORDER_INNER, false );
701 
702  eCoreUnit = pPool->GetMetric( nWhichBox );
703 
704  if ( pBoxItem && pBoxInfoItem ) // -> Don't Care
705  {
706  ResetFrameLine_Impl( svx::FrameBorderType::Left, pBoxItem->GetLeft(), pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::LEFT ) );
707  ResetFrameLine_Impl( svx::FrameBorderType::Right, pBoxItem->GetRight(), pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::RIGHT ) );
708  ResetFrameLine_Impl( svx::FrameBorderType::Top, pBoxItem->GetTop(), pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::TOP ) );
709  ResetFrameLine_Impl( svx::FrameBorderType::Bottom, pBoxItem->GetBottom(), pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::BOTTOM ) );
710  ResetFrameLine_Impl( svx::FrameBorderType::Vertical, pBoxInfoItem->GetVert(), pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::VERT ) );
711  ResetFrameLine_Impl( svx::FrameBorderType::Horizontal, pBoxInfoItem->GetHori(), pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::HORI ) );
712 
713 
714  // distance inside
715 
716  if( !mbUseMarginItem )
717  {
718  if (m_xLeftMF->get_visible())
719  {
720  SetMetricValue(*m_xLeftMF, pBoxInfoItem->GetDefDist(), eCoreUnit);
721  SetMetricValue(*m_xRightMF, pBoxInfoItem->GetDefDist(), eCoreUnit);
722  SetMetricValue(*m_xTopMF, pBoxInfoItem->GetDefDist(), eCoreUnit);
723  SetMetricValue(*m_xBottomMF, pBoxInfoItem->GetDefDist(), eCoreUnit);
724 
725  nMinValue = m_xLeftMF->get_value(FieldUnit::NONE);
726 
727  if ( pBoxInfoItem->IsDist() )
728  {
729  if( rSet->GetItemState( nWhichBox ) >= SfxItemState::DEFAULT )
730  {
731  bool bIsAnyBorderVisible = m_aFrameSel.IsAnyBorderVisible();
732  if( !bIsAnyBorderVisible || !pBoxInfoItem->IsMinDist() )
733  {
734  m_xLeftMF->set_min(0, FieldUnit::NONE);
735  m_xRightMF->set_min(0, FieldUnit::NONE);
736  m_xTopMF->set_min(0, FieldUnit::NONE);
737  m_xBottomMF->set_min(0, FieldUnit::NONE);
738  }
739  tools::Long nLeftDist = pBoxItem->GetDistance( SvxBoxItemLine::LEFT);
740  SetMetricValue(*m_xLeftMF, nLeftDist, eCoreUnit);
741  tools::Long nRightDist = pBoxItem->GetDistance( SvxBoxItemLine::RIGHT);
742  SetMetricValue(*m_xRightMF, nRightDist, eCoreUnit);
743  tools::Long nTopDist = pBoxItem->GetDistance( SvxBoxItemLine::TOP);
744  SetMetricValue( *m_xTopMF, nTopDist, eCoreUnit );
745  tools::Long nBottomDist = pBoxItem->GetDistance( SvxBoxItemLine::BOTTOM);
746  SetMetricValue( *m_xBottomMF, nBottomDist, eCoreUnit );
747 
748  // if the distance is set with no active border line
749  // or it is null with an active border line
750  // no automatic changes should be made
751  const tools::Long nDefDist = bIsAnyBorderVisible ? pBoxInfoItem->GetDefDist() : 0;
752  bool bDiffDist = (nDefDist != nLeftDist ||
753  nDefDist != nRightDist ||
754  nDefDist != nTopDist ||
755  nDefDist != nBottomDist);
756  if ((pBoxItem->GetSmallestDistance() || bIsAnyBorderVisible) && bDiffDist )
757  {
758  mbLeftModified = true;
759  mbRightModified = true;
760  mbTopModified = true;
761  mbBottomModified = true;
762  }
763  }
764  else
765  {
766  // #106224# different margins -> do not fill the edits
767  m_xLeftMF->set_text( OUString() );
768  m_xRightMF->set_text( OUString() );
769  m_xTopMF->set_text( OUString() );
770  m_xBottomMF->set_text( OUString() );
771  }
772  }
773  m_xLeftMF->save_value();
774  m_xRightMF->save_value();
775  m_xTopMF->save_value();
776  m_xBottomMF->save_value();
777  }
778  }
779  }
780  else
781  {
782  // avoid ResetFrameLine-calls:
784  }
785 
788 
789  // depict line (color) in controllers if unambiguous:
790 
791  {
792  // Do all visible lines show the same line widths?
793  tools::Long nWidth;
794  SvxBorderLineStyle nStyle;
795  bool bWidthEq = m_aFrameSel.GetVisibleWidth( nWidth, nStyle );
796  if( bWidthEq )
797  {
798  // Determine the width first as some styles can be missing depending on it
799  sal_Int64 nWidthPt = static_cast<sal_Int64>(vcl::ConvertDoubleValue(
800  sal_Int64( nWidth ), m_xLineWidthMF->get_digits(),
801  MapUnit::MapTwip, FieldUnit::POINT ));
802  SetLineWidth(nWidthPt);
803  m_xLbLineStyle->SetWidth(nWidth);
804 
805  // then set the style
806  m_xLbLineStyle->SelectEntry( nStyle );
807  }
808  else
809  m_xLbLineStyle->SelectEntry(SvxBorderLineStyle::SOLID);
810 
811  // Do all visible lines show the same line color?
812  Color aColor;
813  bool bColorEq = m_aFrameSel.GetVisibleColor( aColor );
814  if( !bColorEq )
815  aColor = COL_BLACK;
816 
817  m_xLbLineColor->SelectEntry(aColor);
819  m_xLbLineStyle->SetColor(nTextColor);
820 
821  // Select all visible lines, if they are all equal.
822  if( bWidthEq && bColorEq )
824 
825  // set the current style and color (caches style in control even if nothing is selected)
826  SelStyleHdl_Impl(*m_xLbLineStyle);
827  SelColHdl_Impl(*m_xLbLineColor);
828  }
829 
830  bool bEnable = m_xWndShadows->GetSelectedItemId() > 1 ;
831  m_xFtShadowSize->set_sensitive(bEnable);
832  m_xEdShadowSize->set_sensitive(bEnable);
833  m_xFtShadowColor->set_sensitive(bEnable);
834  m_xLbShadowColor->set_sensitive(bEnable);
835 
836  m_xWndPresets->SetNoSelection();
837 
838  // - no line - should not be selected
839 
840  if (m_xLbLineStyle->GetSelectEntryStyle() == SvxBorderLineStyle::NONE)
841  {
842  m_xLbLineStyle->SelectEntry(SvxBorderLineStyle::SOLID);
843  SelStyleHdl_Impl(*m_xLbLineStyle);
844  }
845 
846  const SfxUInt16Item* pHtmlModeItem = rSet->GetItemIfSet(SID_HTML_MODE, false);
847  if(!pHtmlModeItem)
848  {
849  if (SfxObjectShell* pShell = SfxObjectShell::Current())
850  pHtmlModeItem = pShell->GetItem(SID_HTML_MODE);
851  }
852  if(pHtmlModeItem)
853  {
854  sal_uInt16 nHtmlMode = pHtmlModeItem->GetValue();
855  if(nHtmlMode & HTMLMODE_ON)
856  {
857  // there are no shadows in Html-mode and only complete borders
858  m_xShadowFrame->set_sensitive(false);
859 
860  if( !(nSWMode & SwBorderModes::TABLE) )
861  {
862  m_xUserDefFT->set_sensitive(false);
863  m_xFrameSelWin->set_sensitive(false);
864  m_xWndPresets->RemoveItem(3);
865  m_xWndPresets->RemoveItem(4);
866  m_xWndPresets->RemoveItem(5);
867  }
868  }
869  }
870 
871  LinesChanged_Impl( nullptr );
872  if (m_xLeftMF->get_value(FieldUnit::NONE) == m_xRightMF->get_value(FieldUnit::NONE) &&
873  m_xTopMF->get_value(FieldUnit::NONE) == m_xBottomMF->get_value(FieldUnit::NONE) &&
874  m_xTopMF->get_value(FieldUnit::NONE) == m_xLeftMF->get_value(FieldUnit::NONE))
875  {
876  mbSync = true;
877  }
878  else
879  mbSync = false;
880  m_xSynchronizeCB->set_active(mbSync);
881 
883  m_xRemoveAdjacentCellBordersCB->set_active(false);
884  m_xRemoveAdjacentCellBordersCB->set_sensitive(false);
885 }
886 
888 {
889  m_xLeftMF->save_value();
890  m_xRightMF->save_value();
891  m_xTopMF->save_value();
892  m_xBottomMF->save_value();
893  m_xMergeWithNextCB->save_state();
894  m_xMergeAdjacentBordersCB->save_state();
895 }
896 
898 {
899  if ( _pSet )
900  FillItemSet( _pSet );
901 
902  return DeactivateRC::LeavePage;
903 }
904 
906 {
907  bool bAttrsChanged = false;
908 
909  SfxItemPool* pPool = rCoreAttrs->GetPool();
910 
913  {
914  if (const SfxPoolItem* pOldItem = GetOldItem(*rCoreAttrs, SID_ATTR_BORDER_DIAG_TLBR))
915  {
916  SvxLineItem aLineItem(*static_cast<const SvxLineItem*>(pOldItem));
918  rCoreAttrs->Put(aLineItem);
919  bAttrsChanged = true;
920  }
921  }
922 
925  {
926  if (const SfxPoolItem* pOldItem = GetOldItem(*rCoreAttrs, SID_ATTR_BORDER_DIAG_BLTR))
927  {
928  SvxLineItem aLineItem(*static_cast<const SvxLineItem*>(pOldItem));
930  rCoreAttrs->Put(aLineItem);
931  bAttrsChanged = true;
932  }
933  }
934 
935  if (m_xShadowControls && m_xShadowControls->get_value_changed_from_saved())
936  {
937  if (const SfxPoolItem* pOldItem = GetOldItem(*rCoreAttrs, mnShadowSlot))
938  {
939  const SvxShadowItem& rOldShadowItem = *static_cast<const SvxShadowItem*>(pOldItem);
940  rCoreAttrs->Put(m_xShadowControls->GetControlValue(rOldShadowItem));
941  bAttrsChanged = true;
942  }
943  }
944 
945  if (m_xMarginControls && m_xMarginControls->get_value_changed_from_saved())
946  {
947  if (const SfxPoolItem* pOldItem = GetOldItem(*rCoreAttrs, SID_ATTR_ALIGN_MARGIN))
948  {
949  const SvxMarginItem& rOldMarginItem = *static_cast<const SvxMarginItem*>(pOldItem);
950  rCoreAttrs->Put(m_xMarginControls->GetControlValue(rOldMarginItem));
951  bAttrsChanged = true;
952  }
953  }
954 
955  if (m_xMergeAdjacentBordersCB->get_state_changed_from_saved())
956  {
957  auto nState = m_xMergeAdjacentBordersCB->get_state();
958  if (nState == TRISTATE_INDET)
959  {
960  sal_uInt16 nMergeAdjacentBordersId = pPool->GetWhich(SID_SW_COLLAPSING_BORDERS);
961  rCoreAttrs->ClearItem(nMergeAdjacentBordersId);
962  }
963  else
964  {
965  if (const SfxPoolItem* pOldItem = GetOldItem(*rCoreAttrs, SID_SW_COLLAPSING_BORDERS))
966  {
967  std::unique_ptr<SfxBoolItem> xNewItem(static_cast<SfxBoolItem*>(pOldItem->Clone()));
968  xNewItem->SetValue(static_cast<bool>(nState));
969  rCoreAttrs->Put(std::move(xNewItem));
970  }
971  }
972  bAttrsChanged = true;
973  }
974 
975  if (m_xMergeWithNextCB->get_state_changed_from_saved())
976  {
977  auto nState = m_xMergeWithNextCB->get_state();
978  if (nState == TRISTATE_INDET)
979  {
980  sal_uInt16 nMergeWithNextId = pPool->GetWhich(SID_ATTR_BORDER_CONNECT);
981  rCoreAttrs->ClearItem(nMergeWithNextId);
982  }
983  else
984  {
985  if (const SfxPoolItem* pOldItem = GetOldItem(*rCoreAttrs, SID_ATTR_BORDER_CONNECT))
986  {
987  std::unique_ptr<SfxBoolItem> xNewItem(static_cast<SfxBoolItem*>(pOldItem->Clone()));
988  xNewItem->SetValue(static_cast<bool>(nState));
989  rCoreAttrs->Put(std::move(xNewItem));
990  }
991  }
992  bAttrsChanged = true;
993  }
994 
995  bool bPut = true;
996  sal_uInt16 nBoxWhich = GetWhich( mnBoxSlot );
997  sal_uInt16 nBoxInfoWhich = pPool->GetWhich( SID_ATTR_BORDER_INNER, false );
998  const SfxItemSet& rOldSet = GetItemSet();
999  SvxBoxItem aBoxItem ( nBoxWhich );
1000  SvxBoxInfoItem aBoxInfoItem ( nBoxInfoWhich );
1001  const SvxBoxItem* pOldBoxItem = static_cast<const SvxBoxItem*>(GetOldItem( *rCoreAttrs, mnBoxSlot ));
1002 
1003  MapUnit eCoreUnit = rOldSet.GetPool()->GetMetric( nBoxWhich );
1004 
1005 
1006  // outer border:
1007 
1008  std::pair<svx::FrameBorderType,SvxBoxItemLine> eTypes1[] = {
1009  { svx::FrameBorderType::Top,SvxBoxItemLine::TOP },
1010  { svx::FrameBorderType::Bottom,SvxBoxItemLine::BOTTOM },
1011  { svx::FrameBorderType::Left,SvxBoxItemLine::LEFT },
1012  { svx::FrameBorderType::Right,SvxBoxItemLine::RIGHT },
1013  };
1014 
1015  for (std::pair<svx::FrameBorderType,SvxBoxItemLine> const & i : eTypes1)
1016  aBoxItem.SetLine( m_aFrameSel.GetFrameBorderStyle( i.first ), i.second );
1017 
1018 
1020  // border hor/ver and TableFlag
1021 
1022  std::pair<svx::FrameBorderType,SvxBoxInfoItemLine> eTypes2[] = {
1023  { svx::FrameBorderType::Horizontal,SvxBoxInfoItemLine::HORI },
1024  { svx::FrameBorderType::Vertical,SvxBoxInfoItemLine::VERT }
1025  };
1026  for (std::pair<svx::FrameBorderType,SvxBoxInfoItemLine> const & j : eTypes2)
1027  aBoxInfoItem.SetLine( m_aFrameSel.GetFrameBorderStyle( j.first ), j.second );
1028 
1029  aBoxInfoItem.EnableHor( mbHorEnabled );
1030  aBoxInfoItem.EnableVer( mbVerEnabled );
1031 
1032 
1033  // inner distance
1034 
1035  if (m_xLeftMF->get_visible())
1036  {
1037  // #i40405# enable distance controls for next dialog call
1038  aBoxInfoItem.SetDist( true );
1039 
1040  if( !mbUseMarginItem )
1041  {
1042  // #106224# all edits empty: do nothing
1043  if( !m_xLeftMF->get_text().isEmpty() || !m_xRightMF->get_text().isEmpty() ||
1044  !m_xTopMF->get_text().isEmpty() || !m_xBottomMF->get_text().isEmpty() )
1045  {
1046  const SvxBoxInfoItem* pOldBoxInfoItem = GetOldItem( *rCoreAttrs, SID_ATTR_BORDER_INNER );
1047  if (
1048  !pOldBoxItem ||
1049  m_xLeftMF->get_value_changed_from_saved() ||
1050  m_xRightMF->get_value_changed_from_saved() ||
1051  m_xTopMF->get_value_changed_from_saved() ||
1052  m_xBottomMF->get_value_changed_from_saved() ||
1053  nMinValue == m_xLeftMF->get_value(FieldUnit::NONE) ||
1054  nMinValue == m_xRightMF->get_value(FieldUnit::NONE) ||
1055  nMinValue == m_xTopMF->get_value(FieldUnit::NONE) ||
1056  nMinValue == m_xBottomMF->get_value(FieldUnit::NONE) ||
1057  (pOldBoxInfoItem && !pOldBoxInfoItem->IsValid(SvxBoxInfoItemValidFlags::DISTANCE))
1058  )
1059  {
1060  aBoxItem.SetDistance( static_cast<sal_uInt16>(GetCoreValue(*m_xLeftMF, eCoreUnit )), SvxBoxItemLine::LEFT );
1061  aBoxItem.SetDistance( static_cast<sal_uInt16>(GetCoreValue(*m_xRightMF, eCoreUnit )), SvxBoxItemLine::RIGHT );
1062  aBoxItem.SetDistance( static_cast<sal_uInt16>(GetCoreValue(*m_xTopMF, eCoreUnit )), SvxBoxItemLine::TOP );
1063  aBoxItem.SetDistance( static_cast<sal_uInt16>(GetCoreValue(*m_xBottomMF, eCoreUnit )), SvxBoxItemLine::BOTTOM);
1064  }
1065  else
1066  {
1067  aBoxItem.SetDistance(pOldBoxItem->GetDistance(SvxBoxItemLine::LEFT ), SvxBoxItemLine::LEFT);
1068  aBoxItem.SetDistance(pOldBoxItem->GetDistance(SvxBoxItemLine::RIGHT), SvxBoxItemLine::RIGHT);
1069  aBoxItem.SetDistance(pOldBoxItem->GetDistance(SvxBoxItemLine::TOP ), SvxBoxItemLine::TOP);
1070  aBoxItem.SetDistance(pOldBoxItem->GetDistance(SvxBoxItemLine::BOTTOM), SvxBoxItemLine::BOTTOM);
1071  }
1072  aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::DISTANCE );
1073  }
1074  }
1075  }
1076 
1077 
1078  // note Don't Care Status in the Info-Item:
1079 
1080  aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::TOP, m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Top ) != svx::FrameBorderState::DontCare );
1081  aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::BOTTOM, m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Bottom ) != svx::FrameBorderState::DontCare );
1082  aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::LEFT, m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Left ) != svx::FrameBorderState::DontCare );
1083  aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::RIGHT, m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Right ) != svx::FrameBorderState::DontCare );
1085  aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::VERT, m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Vertical ) != svx::FrameBorderState::DontCare );
1086 
1087 
1088  // Put or Clear of the border?
1089 
1090  bPut = true;
1091 
1092  if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nBoxWhich, false ))
1093  {
1094  bPut = aBoxItem != static_cast<const SvxBoxItem&>(rOldSet.Get(nBoxWhich));
1095  }
1096  if( SfxItemState::DEFAULT == rOldSet.GetItemState( nBoxInfoWhich, false ) )
1097  {
1098  const SvxBoxInfoItem& rOldBoxInfo = static_cast<const SvxBoxInfoItem&>(
1099  rOldSet.Get(nBoxInfoWhich));
1100 
1101  aBoxInfoItem.SetMinDist( rOldBoxInfo.IsMinDist() );
1102  aBoxInfoItem.SetDefDist( rOldBoxInfo.GetDefDist() );
1103  bPut |= (aBoxInfoItem != rOldBoxInfo );
1104  }
1105 
1106  if ( bPut )
1107  {
1108  if ( !pOldBoxItem || *pOldBoxItem != aBoxItem )
1109  {
1110  rCoreAttrs->Put( aBoxItem );
1111  bAttrsChanged = true;
1112  }
1113  const SfxPoolItem* pOld = GetOldItem( *rCoreAttrs, SID_ATTR_BORDER_INNER, false );
1114 
1115  if ( !pOld || *static_cast<const SvxBoxInfoItem*>(pOld) != aBoxInfoItem )
1116  {
1117  rCoreAttrs->Put( aBoxInfoItem );
1118  bAttrsChanged = true;
1119  }
1120  }
1121  else
1122  {
1123  rCoreAttrs->ClearItem( nBoxWhich );
1124  rCoreAttrs->ClearItem( nBoxInfoWhich );
1125  }
1126 
1127  return bAttrsChanged;
1128 }
1129 
1131 {
1132  m_xShadowFrame->hide();
1133 }
1134 
1135 #define IID_PRE_CELL_NONE 1
1136 #define IID_PRE_CELL_ALL 2
1137 #define IID_PRE_CELL_LR 3
1138 #define IID_PRE_CELL_TB 4
1139 #define IID_PRE_CELL_L 5
1140 #define IID_PRE_CELL_DIAG 6
1141 #define IID_PRE_HOR_NONE 7
1142 #define IID_PRE_HOR_OUTER 8
1143 #define IID_PRE_HOR_HOR 9
1144 #define IID_PRE_HOR_ALL 10
1145 #define IID_PRE_HOR_OUTER2 11
1146 #define IID_PRE_VER_NONE 12
1147 #define IID_PRE_VER_OUTER 13
1148 #define IID_PRE_VER_VER 14
1149 #define IID_PRE_VER_ALL 15
1150 #define IID_PRE_VER_OUTER2 16
1151 #define IID_PRE_TABLE_NONE 17
1152 #define IID_PRE_TABLE_OUTER 18
1153 #define IID_PRE_TABLE_OUTERH 19
1154 #define IID_PRE_TABLE_ALL 20
1155 #define IID_PRE_TABLE_OUTER2 21
1156 
1158 {
1162 
1163  static const svx::FrameBorderState ppeStates[][ svx::FRAMEBORDERTYPE_COUNT ] =
1164  { /* Left Right Top Bot Hor Ver TLBR BLTR */
1165 /* ---------------------+--------------------------------------------------- */
1166 /* IID_PRE_CELL_NONE */ { HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE },
1167 /* IID_PRE_CELL_ALL */ { SHOW, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE, HIDE },
1168 /* IID_PRE_CELL_LR */ { SHOW, SHOW, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE },
1169 /* IID_PRE_CELL_TB */ { HIDE, HIDE, SHOW, SHOW, HIDE, HIDE, HIDE, HIDE },
1170 /* IID_PRE_CELL_L */ { SHOW, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE },
1171 /* IID_PRE_CELL_DIAG */ { HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, SHOW, SHOW },
1172 /* IID_PRE_HOR_NONE */ { HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE },
1173 /* IID_PRE_HOR_OUTER */ { SHOW, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE, HIDE },
1174 /* IID_PRE_HOR_HOR */ { HIDE, HIDE, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE },
1175 /* IID_PRE_HOR_ALL */ { SHOW, SHOW, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE },
1176 /* IID_PRE_HOR_OUTER2 */ { SHOW, SHOW, SHOW, SHOW, DONT, HIDE, HIDE, HIDE },
1177 /* IID_PRE_VER_NONE */ { HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE },
1178 /* IID_PRE_VER_OUTER */ { SHOW, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE, HIDE },
1179 /* IID_PRE_VER_VER */ { SHOW, SHOW, HIDE, HIDE, HIDE, SHOW, HIDE, HIDE },
1180 /* IID_PRE_VER_ALL */ { SHOW, SHOW, SHOW, SHOW, HIDE, SHOW, HIDE, HIDE },
1181 /* IID_PRE_VER_OUTER2 */ { SHOW, SHOW, SHOW, SHOW, HIDE, DONT, HIDE, HIDE },
1182 /* IID_PRE_TABLE_NONE */ { HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE },
1183 /* IID_PRE_TABLE_OUTER */ { SHOW, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE, HIDE },
1184 /* IID_PRE_TABLE_OUTERH */ { SHOW, SHOW, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE },
1185 /* IID_PRE_TABLE_ALL */ { SHOW, SHOW, SHOW, SHOW, SHOW, SHOW, HIDE, HIDE },
1186 /* IID_PRE_TABLE_OUTER2 */ { SHOW, SHOW, SHOW, SHOW, DONT, DONT, HIDE, HIDE }
1187  };
1188 
1189  // first hide and deselect all frame borders
1190  m_aFrameSel.HideAllBorders();
1191  m_aFrameSel.DeselectAllBorders();
1192 
1193  // Using image ID to find correct line in table above.
1194  sal_uInt16 nLine = GetPresetImageId( m_xWndPresets->GetSelectedItemId() ) - 1;
1195 
1196  // Apply all styles from the table
1197  for( int nBorder = 0; nBorder < svx::FRAMEBORDERTYPE_COUNT; ++nBorder )
1198  {
1200  switch( ppeStates[ nLine ][ nBorder ] )
1201  {
1202  case SHOW: m_aFrameSel.SelectBorder( eBorder ); break;
1203  case HIDE: /* nothing to do */ break;
1204  case DONT: m_aFrameSel.SetBorderDontCare( eBorder ); break;
1205  }
1206  }
1207 
1208  // Show all lines that have been selected above
1209  if( m_aFrameSel.IsAnyBorderSelected() )
1210  {
1211  // any visible style, but "no-line" in line list box? -> use hair-line
1212  if (m_xLbLineStyle->GetSelectEntryStyle() == SvxBorderLineStyle::NONE)
1213  m_xLbLineStyle->SelectEntry(SvxBorderLineStyle::SOLID);
1214 
1215  // set current style to all previously selected lines
1216  SelStyleHdl_Impl(*m_xLbLineStyle);
1217  SelColHdl_Impl(*m_xLbLineColor);
1218  }
1219 
1220  // Presets ValueSet does not show a selection (used as push buttons).
1221  m_xWndPresets->SetNoSelection();
1222 
1223  LinesChanged_Impl( nullptr );
1224  UpdateRemoveAdjCellBorderCB( nLine + 1 );
1225 }
1226 
1228 {
1229  bool bEnable = m_xWndShadows->GetSelectedItemId() > 1;
1230  m_xFtShadowSize->set_sensitive(bEnable);
1231  m_xEdShadowSize->set_sensitive(bEnable);
1232  m_xFtShadowColor->set_sensitive(bEnable);
1233  m_xLbShadowColor->set_sensitive(bEnable);
1234 }
1235 
1236 IMPL_LINK(SvxBorderTabPage, SelColHdl_Impl, ColorListBox&, rColorBox, void)
1237 {
1238  Color aColor = rColorBox.GetSelectEntryColor();
1239  m_aFrameSel.SetColorToSelection(aColor);
1240 }
1241 
1242 IMPL_LINK_NOARG(SvxBorderTabPage, ModifyWidthLBHdl_Impl, weld::ComboBox&, void)
1243 {
1244  sal_Int32 nPos = m_xLineWidthLB->get_active();
1245 
1246  SetLineWidth(m_aLineWidths[nPos]);
1247 
1248  // Call the spinner handler to trigger all related modifications
1249  ModifyWidthMFHdl_Impl(*m_xLineWidthMF);
1250 }
1251 
1253 {
1254  sal_Int64 nVal = m_xLineWidthMF->get_value(FieldUnit::NONE);
1255  nVal = static_cast<sal_Int64>(vcl::ConvertDoubleValue(
1256  nVal,
1257  m_xLineWidthMF->get_digits(),
1258  FieldUnit::POINT, MapUnit::MapTwip ));
1259  m_xLbLineStyle->SetWidth( nVal );
1260 
1261  m_aFrameSel.SetStyleToSelection( nVal,
1262  m_xLbLineStyle->GetSelectEntryStyle() );
1263 }
1264 
1266 {
1267  sal_Int64 nOldWidth = m_xLineWidthMF->get_value(FieldUnit::NONE);
1268  nOldWidth = static_cast<sal_Int64>(vcl::ConvertDoubleValue(
1269  nOldWidth,
1270  m_xLineWidthMF->get_digits(),
1271  FieldUnit::POINT,
1272  MapUnit::MapTwip));
1273 
1274  const sal_Int64 nOldMinWidth = lcl_GetMinLineWidth(m_aFrameSel.getCurrentStyleLineStyle());
1275  const sal_Int64 nNewMinWidth = lcl_GetMinLineWidth(m_xLbLineStyle->GetSelectEntryStyle());
1276 
1277  // auto change line-width if it doesn't correspond to minimal value
1278  // let's change only in case when user has not changed the line-width into some custom value
1279  const sal_Int64 nNewWidth = (nOldMinWidth == nOldWidth)? nNewMinWidth : nOldWidth;
1280 
1281  // set value inside edit box
1282  if (nOldWidth != nNewWidth)
1283  {
1284  const sal_Int64 nNewWidthPt = static_cast<sal_Int64>(vcl::ConvertDoubleValue(
1285  nNewWidth,
1286  m_xLineWidthMF->get_digits(),
1287  MapUnit::MapTwip,
1288  FieldUnit::POINT));
1289  SetLineWidth(nNewWidthPt);
1290  }
1291 
1292  // set value inside style box
1293  m_aFrameSel.SetStyleToSelection( nNewWidth,
1294  m_xLbLineStyle->GetSelectEntryStyle() );
1295 }
1296 
1297 
1298 // ValueSet handling
1299 sal_uInt16 SvxBorderTabPage::GetPresetImageId( sal_uInt16 nValueSetIdx ) const
1300 {
1301  // table with all sets of predefined border styles
1302  static const sal_uInt16 ppnImgIds[][ BORDER_PRESET_COUNT ] =
1303  {
1304  // simple cell without diagonal frame borders
1306  // simple cell with diagonal frame borders
1308  // with horizontal inner frame border
1310  // with vertical inner frame border
1312  // with horizontal and vertical inner frame borders
1314  };
1315 
1316  // find correct set of presets
1317  int nLine = 0;
1318  if( !mbHorEnabled && !mbVerEnabled )
1319  nLine = (mbTLBREnabled || mbBLTREnabled) ? 1 : 0;
1320  else if( mbHorEnabled && !mbVerEnabled )
1321  nLine = 2;
1322  else if( !mbHorEnabled && mbVerEnabled )
1323  nLine = 3;
1324  else
1325  nLine = 4;
1326 
1327  DBG_ASSERT( (1 <= nValueSetIdx) && (nValueSetIdx <= BORDER_PRESET_COUNT),
1328  "SvxBorderTabPage::GetPresetImageId - wrong index" );
1329  return ppnImgIds[ nLine ][ nValueSetIdx - 1 ];
1330 }
1331 
1332 TranslateId SvxBorderTabPage::GetPresetStringId( sal_uInt16 nValueSetIdx ) const
1333 {
1334  // string resource IDs for each image (in order of the IID_PRE_* image IDs)
1335  static const TranslateId pnStrIds[] =
1336  {
1337  RID_SVXSTR_TABLE_PRESET_NONE,
1338  RID_SVXSTR_PARA_PRESET_ALL,
1339  RID_SVXSTR_PARA_PRESET_LEFTRIGHT,
1340  RID_SVXSTR_PARA_PRESET_TOPBOTTOM,
1341  RID_SVXSTR_PARA_PRESET_ONLYLEFT,
1342  RID_SVXSTR_PARA_PRESET_DIAGONAL,
1343 
1344  RID_SVXSTR_TABLE_PRESET_NONE,
1345  RID_SVXSTR_TABLE_PRESET_ONLYOUTER,
1346  RID_SVXSTR_HOR_PRESET_ONLYHOR,
1347  RID_SVXSTR_TABLE_PRESET_OUTERALL,
1348  RID_SVXSTR_TABLE_PRESET_OUTERINNER,
1349 
1350  RID_SVXSTR_TABLE_PRESET_NONE,
1351  RID_SVXSTR_TABLE_PRESET_ONLYOUTER,
1352  RID_SVXSTR_VER_PRESET_ONLYVER,
1353  RID_SVXSTR_TABLE_PRESET_OUTERALL,
1354  RID_SVXSTR_TABLE_PRESET_OUTERINNER,
1355 
1356  RID_SVXSTR_TABLE_PRESET_NONE,
1357  RID_SVXSTR_TABLE_PRESET_ONLYOUTER,
1358  RID_SVXSTR_TABLE_PRESET_OUTERHORI,
1359  RID_SVXSTR_TABLE_PRESET_OUTERALL,
1360  RID_SVXSTR_TABLE_PRESET_OUTERINNER
1361  };
1362  return pnStrIds[ GetPresetImageId( nValueSetIdx ) - 1 ];
1363 }
1364 
1366 {
1367  // basic initialization of the ValueSet
1368  m_xWndPresets->SetStyle( m_xWndPresets->GetStyle() | WB_ITEMBORDER | WB_DOUBLEBORDER );
1369  m_xWndPresets->SetColCount( BORDER_PRESET_COUNT );
1370 
1371  // insert images and help texts
1372  for( sal_uInt16 nVSIdx = 1; nVSIdx <= BORDER_PRESET_COUNT; ++nVSIdx )
1373  {
1374  m_xWndPresets->InsertItem( nVSIdx );
1375  m_xWndPresets->SetItemImage(nVSIdx, m_aBorderImgVec[GetPresetImageId(nVSIdx) - 1]);
1376  m_xWndPresets->SetItemText( nVSIdx, SvxResId( GetPresetStringId( nVSIdx ) ) );
1377  }
1378 
1379  // show the control
1380  m_xWndPresets->SetNoSelection();
1381  m_xWndPresets->SetOptimalSize();
1382  m_xWndPresets->Show();
1383 }
1384 
1386 {
1387  // basic initialization of the ValueSet
1388  m_xWndShadows->SetStyle( m_xWndShadows->GetStyle() | WB_ITEMBORDER | WB_DOUBLEBORDER );
1389  m_xWndShadows->SetColCount( BORDER_SHADOW_COUNT );
1390 
1391  // string resource IDs for each image
1392  static const TranslateId pnStrIds[ BORDER_SHADOW_COUNT ] =
1393  { RID_CUISTR_SHADOW_STYLE_NONE, RID_CUISTR_SHADOW_STYLE_BOTTOMRIGHT, RID_CUISTR_SHADOW_STYLE_TOPRIGHT, RID_CUISTR_SHADOW_STYLE_BOTTOMLEFT, RID_CUISTR_SHADOW_STYLE_TOPLEFT };
1394 
1395  // insert images and help texts
1396  for( sal_uInt16 nVSIdx = 1; nVSIdx <= BORDER_SHADOW_COUNT; ++nVSIdx )
1397  {
1398  m_xWndShadows->InsertItem( nVSIdx );
1399  m_xWndShadows->SetItemImage(nVSIdx, m_aShadowImgVec[nVSIdx-1]);
1400  m_xWndShadows->SetItemText( nVSIdx, CuiResId( pnStrIds[ nVSIdx - 1 ] ) );
1401  }
1402 
1403  // show the control
1404  m_xWndShadows->SelectItem( 1 );
1405  m_xWndShadows->SetOptimalSize();
1406  m_xWndShadows->Show();
1407 }
1408 
1409 
1411 {
1412  FillPresetVS();
1413  FillShadowVS();
1414 }
1415 
1416 void SvxBorderTabPage::SetLineWidth( sal_Int64 nWidth )
1417 {
1418  if ( nWidth >= 0 )
1419  m_xLineWidthMF->set_value( nWidth, FieldUnit::POINT );
1420 
1421  auto it = std::find_if( m_aLineWidths.begin(), m_aLineWidths.end(),
1422  [nWidth](const int val) -> bool { return val == nWidth; } );
1423 
1424  if ( it != m_aLineWidths.end() && *it >= 0 )
1425  {
1426  // Select predefined value in combobox
1427  m_xLineWidthMF->hide();
1428  m_xLineWidthLB->set_active(std::distance(m_aLineWidths.begin(), it));
1429  }
1430  else
1431  {
1432  // This is not one of predefined values. Show spinner
1433  m_xLineWidthLB->set_active(m_aLineWidths.size()-1);
1434  m_xLineWidthMF->show();
1435  }
1436 }
1437 
1438 static Color lcl_mediumColor( Color aMain, Color /*aDefault*/ )
1439 {
1440  return SvxBorderLine::threeDMediumColor( aMain );
1441 }
1442 
1444 {
1445  using namespace ::com::sun::star::table::BorderLineStyle;
1446 
1447  static struct {
1448  SvxBorderLineStyle mnStyle;
1449  SvtLineListBox::ColorFunc mpColor1Fn;
1450  SvtLineListBox::ColorFunc mpColor2Fn;
1451  SvtLineListBox::ColorDistFunc mpColorDistFn;
1452  } const aLines[] = {
1453  // Simple lines
1454  { SvxBorderLineStyle::SOLID, &sameColor, &sameColor, &sameDistColor },
1455  { SvxBorderLineStyle::DOTTED, &sameColor, &sameColor, &sameDistColor },
1456  { SvxBorderLineStyle::DASHED, &sameColor, &sameColor, &sameDistColor },
1457  { SvxBorderLineStyle::FINE_DASHED, &sameColor, &sameColor, &sameDistColor },
1458  { SvxBorderLineStyle::DASH_DOT, &sameColor, &sameColor, &sameDistColor },
1459  { SvxBorderLineStyle::DASH_DOT_DOT, &sameColor, &sameColor, &sameDistColor },
1460 
1461  // Double lines
1462  { SvxBorderLineStyle::DOUBLE, &sameColor, &sameColor, &sameDistColor },
1463  { SvxBorderLineStyle::DOUBLE_THIN, &sameColor, &sameColor, &sameDistColor },
1464  { SvxBorderLineStyle::THINTHICK_SMALLGAP, &sameColor, &sameColor, &sameDistColor },
1465  { SvxBorderLineStyle::THINTHICK_MEDIUMGAP, &sameColor, &sameColor, &sameDistColor },
1466  { SvxBorderLineStyle::THINTHICK_LARGEGAP, &sameColor, &sameColor, &sameDistColor },
1467  { SvxBorderLineStyle::THICKTHIN_SMALLGAP, &sameColor, &sameColor, &sameDistColor },
1468  { SvxBorderLineStyle::THICKTHIN_MEDIUMGAP, &sameColor, &sameColor, &sameDistColor },
1469  { SvxBorderLineStyle::THICKTHIN_LARGEGAP, &sameColor, &sameColor, &sameDistColor },
1470 
1471  { SvxBorderLineStyle::EMBOSSED, &SvxBorderLine::threeDLightColor, &SvxBorderLine::threeDDarkColor, &lcl_mediumColor },
1472  { SvxBorderLineStyle::ENGRAVED, &SvxBorderLine::threeDDarkColor, &SvxBorderLine::threeDLightColor, &lcl_mediumColor },
1473 
1474  { SvxBorderLineStyle::OUTSET, &SvxBorderLine::lightColor, &SvxBorderLine::darkColor, &sameDistColor },
1475  { SvxBorderLineStyle::INSET, &SvxBorderLine::darkColor, &SvxBorderLine::lightColor, &sameDistColor }
1476  };
1477 
1478  m_xLbLineStyle->SetSourceUnit( FieldUnit::TWIP );
1479 
1480  for (size_t i = 0; i < std::size(aLines); ++i)
1481  {
1482  if (!IsBorderLineStyleAllowed(aLines[i].mnStyle))
1483  continue;
1484 
1485  m_xLbLineStyle->InsertEntry(
1486  SvxBorderLine::getWidthImpl(aLines[i].mnStyle),
1487  aLines[i].mnStyle,
1488  lcl_GetMinLineWidth(aLines[i].mnStyle),
1489  aLines[i].mpColor1Fn,
1490  aLines[i].mpColor2Fn,
1491  aLines[i].mpColorDistFn);
1492  }
1493 
1494  sal_Int64 nVal = m_xLineWidthMF->get_value(FieldUnit::NONE);
1495  nVal = static_cast<sal_Int64>(vcl::ConvertDoubleValue(nVal, m_xLineWidthMF->get_digits(),
1496  m_xLineWidthMF->get_unit(), MapUnit::MapTwip));
1497  m_xLbLineStyle->SetWidth( nVal );
1498 }
1499 
1500 
1502 {
1503  if (!mbUseMarginItem && m_xLeftMF->get_visible())
1504  {
1505  bool bLineSet = m_aFrameSel.IsAnyBorderVisible();
1506  bool bSpaceModified = mbLeftModified ||
1507  mbRightModified ||
1508  mbTopModified ||
1509  mbBottomModified;
1510 
1511  if(bLineSet)
1512  {
1513  if(!bSpaceModified)
1514  {
1515  m_xLeftMF->set_value(nMinValue, FieldUnit::NONE);
1516  m_xRightMF->set_value(nMinValue, FieldUnit::NONE);
1517  m_xTopMF->set_value(nMinValue, FieldUnit::NONE);
1518  m_xBottomMF->set_value(nMinValue, FieldUnit::NONE);
1519  }
1520  }
1521  else
1522  {
1523  m_xLeftMF->set_min(0, FieldUnit::NONE);
1524  m_xRightMF->set_min(0, FieldUnit::NONE);
1525  m_xTopMF->set_min(0, FieldUnit::NONE);
1526  m_xBottomMF->set_min(0, FieldUnit::NONE);
1527  }
1528  // for tables everything is allowed
1529  SvxBoxInfoItemValidFlags nValid = SvxBoxInfoItemValidFlags::TOP|SvxBoxInfoItemValidFlags::BOTTOM|SvxBoxInfoItemValidFlags::LEFT|SvxBoxInfoItemValidFlags::RIGHT;
1530 
1531  m_xLeftFT->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::LEFT) );
1532  m_xRightFT->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::RIGHT) );
1533  m_xTopFT->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::TOP) );
1534  m_xBottomFT->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::BOTTOM) );
1535  m_xLeftMF->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::LEFT) );
1536  m_xRightMF->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::RIGHT) );
1537  m_xTopMF->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::TOP) );
1538  m_xBottomMF->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::BOTTOM) );
1539  m_xSynchronizeCB->set_sensitive(m_xRightMF->get_sensitive() || m_xTopMF->get_sensitive() ||
1540  m_xBottomMF->get_sensitive() || m_xLeftMF->get_sensitive());
1541  }
1542  UpdateRemoveAdjCellBorderCB( SAL_MAX_UINT16 );
1543 }
1544 
1545 
1546 IMPL_LINK( SvxBorderTabPage, ModifyDistanceHdl_Impl, weld::MetricSpinButton&, rField, void)
1547 {
1548  if (&rField == m_xLeftMF.get())
1549  mbLeftModified = true;
1550  else if (&rField == m_xRightMF.get())
1551  mbRightModified = true;
1552  else if (&rField == m_xTopMF.get())
1553  mbTopModified = true;
1554  else if (&rField == m_xBottomMF.get())
1555  mbBottomModified = true;
1556 
1557  if (mbSync)
1558  {
1559  const auto nVal = rField.get_value(FieldUnit::NONE);
1560  if (&rField != m_xLeftMF.get())
1561  m_xLeftMF->set_value(nVal, FieldUnit::NONE);
1562  if (&rField != m_xRightMF.get())
1563  m_xRightMF->set_value(nVal, FieldUnit::NONE);
1564  if (&rField != m_xTopMF.get())
1565  m_xTopMF->set_value(nVal, FieldUnit::NONE);
1566  if (&rField != m_xBottomMF.get())
1567  m_xBottomMF->set_value(nVal, FieldUnit::NONE);
1568  }
1569 }
1570 
1571 IMPL_LINK( SvxBorderTabPage, SyncHdl_Impl, weld::Toggleable&, rBox, void)
1572 {
1573  mbSync = rBox.get_active();
1574 }
1575 
1576 IMPL_LINK( SvxBorderTabPage, RemoveAdjacentCellBorderHdl_Impl, weld::Toggleable&, rBox, void)
1577 {
1578  mbRemoveAdjacentCellBorders = rBox.get_active();
1579 }
1580 
1582 {
1583  if( !bIsCalcDoc )
1584  return;
1585  const SfxItemSet& rOldSet = GetItemSet();
1586  const SvxBoxInfoItem* pOldBoxInfoItem = GetOldItem( rOldSet, SID_ATTR_BORDER_INNER );
1587  const SvxBoxItem* pOldBoxItem = static_cast<const SvxBoxItem*>(GetOldItem( rOldSet, mnBoxSlot ));
1588  if( !pOldBoxInfoItem || !pOldBoxItem )
1589  return;
1590  std::pair<svx::FrameBorderType, SvxBoxInfoItemValidFlags> eTypes1[] = {
1591  { svx::FrameBorderType::Top,SvxBoxInfoItemValidFlags::TOP },
1592  { svx::FrameBorderType::Bottom,SvxBoxInfoItemValidFlags::BOTTOM },
1593  { svx::FrameBorderType::Left,SvxBoxInfoItemValidFlags::LEFT },
1594  { svx::FrameBorderType::Right,SvxBoxInfoItemValidFlags::RIGHT },
1595  };
1596  SvxBoxItemLine const eTypes2[] = {
1597  SvxBoxItemLine::TOP,
1598  SvxBoxItemLine::BOTTOM,
1599  SvxBoxItemLine::LEFT,
1600  SvxBoxItemLine::RIGHT,
1601  };
1602 
1603  // Check if current selection involves deletion of at least one border
1604  bool bBorderDeletionReq = false;
1605  for ( size_t i=0; i < std::size( eTypes1 ); ++i )
1606  {
1607  if( pOldBoxItem->GetLine( eTypes2[i] ) || !( pOldBoxInfoItem->IsValid( eTypes1[i].second ) ) )
1608  {
1609  if( m_aFrameSel.GetFrameBorderState( eTypes1[i].first ) == svx::FrameBorderState::Hide )
1610  {
1611  bBorderDeletionReq = true;
1612  break;
1613  }
1614  }
1615  }
1616 
1617  if( !bBorderDeletionReq && ( nPreset == IID_PRE_CELL_NONE || nPreset == IID_PRE_TABLE_NONE ) )
1618  bBorderDeletionReq = true;
1619 
1620  m_xRemoveAdjacentCellBordersCB->set_sensitive(bBorderDeletionReq);
1621 
1622  if( !bBorderDeletionReq )
1623  {
1625  m_xRemoveAdjacentCellBordersCB->set_active(false);
1626  }
1627 }
1628 
1630 {
1631  const SfxUInt16Item* pSWModeItem = aSet.GetItem<SfxUInt16Item>(SID_SWMODE_TYPE, false);
1632  const SfxUInt32Item* pFlagItem = aSet.GetItem<SfxUInt32Item>(SID_FLAG_TYPE, false);
1633  if (pSWModeItem)
1634  {
1635  nSWMode = static_cast<SwBorderModes>(pSWModeItem->GetValue());
1636  // #i43593#
1637  // show checkbox <m_xMergeWithNextCB> for format.paragraph
1638  if ( nSWMode == SwBorderModes::PARA )
1639  {
1640  m_xMergeWithNextCB->show();
1641  m_xPropertiesFrame->show();
1642  }
1643  // show checkbox <m_xMergeAdjacentBordersCB> for format.paragraph
1644  else if ( nSWMode == SwBorderModes::TABLE )
1645  {
1646  m_xMergeAdjacentBordersCB->show();
1647  m_xPropertiesFrame->show();
1648  }
1649  }
1650  if (pFlagItem)
1651  if ( ( pFlagItem->GetValue() & SVX_HIDESHADOWCTL ) == SVX_HIDESHADOWCTL )
1653 }
1654 
1656 {
1657  nSWMode = SwBorderModes::TABLE;
1658 }
1659 
1660 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define IID_PRE_HOR_NONE
Definition: border.cxx:1141
sal_uInt16 mnShadowSlot
Definition: border.hxx:106
sal_Int64 get_min(FieldUnit eValueUnit) const
bool GetValue() const
virtual ~SvxBorderTabPage() override
Definition: border.cxx:597
#define IID_PRE_VER_VER
Definition: border.cxx:1148
bool mbHorEnabled
true = Inner horizontal border enabled.
Definition: border.hxx:108
std::unique_ptr< ValueSet > m_xWndShadows
Definition: border.hxx:147
void SetFieldUnit(weld::MetricSpinButton &rField, FieldUnit eUnit, bool bAll)
std::unique_ptr< ShadowControlsWrapper > m_xShadowControls
Definition: border.hxx:160
FrameBorderType GetFrameBorderTypeFromIndex(size_t nIndex)
bool mbUseMarginItem
Definition: border.hxx:112
FieldUnit
static const sal_Int16 VeryThin
static Color lcl_mediumColor(Color aMain, Color)
Definition: border.cxx:1438
void SetMetricValue(weld::MetricSpinButton &rField, sal_Int64 nCoreValue, MapUnit eUnit)
static const WhichRangesContainer pRanges
Definition: border.hxx:79
const T * GetItemIfSet(TypedWhichId< T > nWhich, bool bSrchInParent=true) const
bool get_value_changed_from_saved() const
Definition: border.cxx:258
void SetLeftMargin(sal_Int16 nLeft)
void SetDefDist(sal_uInt16 nNew)
std::unique_ptr< weld::CheckButton > m_xMergeWithNextCB
Definition: border.hxx:155
void set_value(sal_Int64 nValue, FieldUnit eValueUnit)
bool mbLeftModified
Definition: border.hxx:113
static constexpr auto Items
bool IsNoSelection() const
weld::MetricSpinButton & mrRightWrp
Definition: border.hxx:72
tools::Long nMinValue
minimum distance
Definition: border.hxx:103
bool mbRemoveAdjacentCellBorders
Definition: border.hxx:118
void SetMinDist(bool bNew)
void set_digits(unsigned int digits)
void SetLineWidth(sal_Int64 nWidth)
Definition: border.cxx:1416
#define IID_PRE_TABLE_OUTERH
Definition: border.cxx:1153
Color(* ColorFunc)(Color)
long Long
bool IsHorEnabled() const
void SetColor(const Color &rNew)
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
const editeng::SvxBorderLine * GetVert() const
css::uno::Reference< css::frame::XModel3 > GetModel() const
sal_uInt16 GetValue() const
virtual void ChangesApplied() override
Definition: border.cxx:887
sal_uInt16 GetDistance(SvxBoxItemLine nLine) const
#define IID_PRE_HOR_OUTER
Definition: border.cxx:1142
sal_uInt16 GetPresetImageId(sal_uInt16 nValueSetIdx) const
Definition: border.cxx:1299
ValueSet & mrVsPos
Definition: border.hxx:53
virtual void Reset(const SfxItemSet *) override
Definition: border.cxx:635
sal_uInt16 GetDefDist() const
bool mbBottomModified
Definition: border.hxx:116
static std::unique_ptr< SfxTabPage > Create(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet *rAttrSet)
Definition: border.cxx:609
std::unique_ptr< ColorListBox > m_xLbLineColor
Definition: border.hxx:131
sal_uInt16 GetSelectedItemId() const
static SfxObjectShell * Current()
sal_Int16 GetRightMargin() const
virtual void PageCreated(const SfxAllItemSet &aSet) override
Definition: border.cxx:1629
void SetLine(const editeng::SvxBorderLine *pNew)
SvxBorderTabPage(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet &rCoreAttrs)
Definition: border.cxx:287
const editeng::SvxBorderLine * GetRight() const
sal_uInt16 mnBoxSlot
Definition: border.hxx:105
std::vector< Image > m_aShadowImgVec
Definition: border.hxx:100
void ResetFrameLine_Impl(svx::FrameBorderType eBorder, const editeng::SvxBorderLine *pCurLine, bool bValid)
share for individual Frame-/Core-Line
Definition: border.cxx:615
std::unique_ptr< weld::Container > m_xShadowFrame
Definition: border.hxx:146
static const SfxPoolItem * GetItem(const SfxItemSet &rSet, sal_uInt16 nSlot, bool bDeep=true)
IMPL_LINK_NOARG(SvxBorderTabPage, SelPreHdl_Impl, ValueSet *, void)
Definition: border.cxx:1157
std::unique_ptr< weld::CheckButton > m_xSynchronizeCB
Definition: border.hxx:144
FieldUnit GetModuleFieldUnit(const SfxItemSet &rSet)
NONE
std::unique_ptr< weld::CustomWeld > m_xWndShadowsWin
Definition: border.hxx:148
void SetControlDontKnow()
Definition: border.cxx:228
virtual MapUnit GetMetric(sal_uInt16 nWhich) const
void SaveValue()
SvxBorderLineStyle
IMPL_LINK(SvxBorderTabPage, SelColHdl_Impl, ColorListBox &, rColorBox, void)
Definition: border.cxx:1236
bool IsNoSelection() const
void SetNoSelection()
SvxShadowLocation GetLocation() const
FrameBorderState
#define SAL_MAX_UINT16
SvxBoxInfoItemValidFlags
std::unique_ptr< weld::CustomWeld > m_xFrameSelWin
Definition: border.hxx:128
#define WB_ITEMBORDER
const OUString sEmpty
static const sal_Int16 Medium
OUString SvxResId(TranslateId aId)
bool get_value_changed_from_saved() const
Definition: border.cxx:221
std::unique_ptr< weld::Label > m_xFtShadowColor
Definition: border.hxx:151
bool mbBLTREnabled
true = Bottom-left to top-right border enabled.
Definition: border.hxx:111
enum SvxBorderLineStyle sal_Int16 typedef::std::vector< FontMetric > ImplFontList Color sameColor(Color rMain)
bool IsAnyBorderVisible() const
bool IsMinDist() const
std::unique_ptr< weld::Container > m_xPropertiesFrame
properties - "Merge with next paragraph" in Writer
Definition: border.hxx:154
sal_Int64 denormalize(sal_Int64 nValue) const
const editeng::SvxBorderLine * GetLine(SvxBoxItemLine nLine) const
void EnableHor(bool bEnable)
std::unique_ptr< weld::MetricSpinButton > m_xBottomMF
Definition: border.hxx:143
TRISTATE_INDET
std::unique_ptr< weld::MetricSpinButton > m_xRightMF
Definition: border.hxx:139
#define IID_PRE_TABLE_NONE
Definition: border.cxx:1151
static sal_Int64 lcl_GetMinLineWidth(SvxBorderLineStyle aStyle)
Definition: border.cxx:105
std::vector< Image > m_aBorderImgVec
Definition: border.hxx:101
const SfxItemSet & GetItemSet() const
void set_text(const OUString &rText)
void FillShadowVS()
Definition: border.cxx:1385
Color(* ColorDistFunc)(Color, Color)
std::unique_ptr< weld::CheckButton > m_xRemoveAdjacentCellBordersCB
Definition: border.hxx:158
#define IID_PRE_VER_NONE
Definition: border.cxx:1146
void SetTopMargin(sal_Int16 nTop)
virtual DeactivateRC DeactivatePage(SfxItemSet *pSet) override
Definition: border.cxx:897
OUString CuiResId(TranslateId aKey)
Definition: cuiresmgr.cxx:23
weld::MetricSpinButton & mrLeftWrp
Definition: border.hxx:71
const editeng::SvxBorderLine * GetHori() const
const SfxPoolItem * GetOldItem(const SfxItemSet &rSet, sal_uInt16 nSlot, bool bDeep=true)
void SelectEntry(const NamedColor &rColor)
void SetRemoveAdjacentCellBorder(bool bSet)
const Color & GetColor() const
std::set< SvxBorderLineStyle > maUsedBorderStyles
Definition: border.hxx:121
SwBorderModes nSWMode
table, textframe, paragraph
Definition: border.hxx:104
const editeng::SvxBorderLine * GetTop() const
#define IID_PRE_CELL_ALL
Definition: border.cxx:1136
sal_uInt16 ClearItem(sal_uInt16 nWhich=0)
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
const editeng::SvxBorderLine * GetLeft() const
#define DBG_ASSERT(sCon, aError)
int i
weld::MetricSpinButton & mrBottomWrp
Definition: border.hxx:74
std::unique_ptr< weld::MetricSpinButton > m_xEdShadowSize
Definition: border.hxx:150
bool GetVisibleWidth(tools::Long &rnWidth, SvxBorderLineStyle &rnStyle) const
const sal_uInt16 BORDER_PRESET_COUNT
Definition: border.cxx:142
void SetRightMargin(sal_Int16 nRight)
bool IsBorderLineStyleAllowed(SvxBorderLineStyle nStyle) const
Definition: border.cxx:626
TranslateId GetPresetStringId(sal_uInt16 nValueSetIdx) const
Definition: border.cxx:1332
bool IsValueChangedFromSaved() const
std::unique_ptr< ColorListBox > m_xLbShadowColor
Definition: border.hxx:152
std::unique_ptr< weld::MetricSpinButton > m_xTopMF
Definition: border.hxx:141
Color sameDistColor(Color, Color rDefault)
bool mbVerEnabled
true = Inner vertical border enabled.
Definition: border.hxx:109
bool mbTopModified
Definition: border.hxx:115
bool IsBorderEnabled(FrameBorderType eBorder) const
HTMLMODE_ON
weld::MetricSpinButton & mrTopWrp
Definition: border.hxx:73
void SetLine(const editeng::SvxBorderLine *pNew, SvxBoxInfoItemLine nLine)
void FillValueSets()
Definition: border.cxx:1410
bool IsValueChangedFromSaved() const
#define IID_PRE_HOR_ALL
Definition: border.cxx:1144
FrameBorderType
const std::map< OUString, css::uno::Any > & GetGrabBag() const
#define IID_PRE_CELL_TB
Definition: border.cxx:1138
virtual bool FillItemSet(SfxItemSet *rCoreAttrs) override
Definition: border.cxx:905
void set_min(sal_Int64 min, FieldUnit eValueUnit)
std::unique_ptr< weld::ComboBox > m_xLineWidthLB
Definition: border.hxx:132
#define IID_PRE_HOR_OUTER2
Definition: border.cxx:1145
void SetControlValue(const SvxMarginItem &rItem)
Definition: border.cxx:266
void SetBottomMargin(sal_Int16 nBottom)
#define IID_PRE_VER_OUTER2
Definition: border.cxx:1150
void SetDistance(sal_uInt16 nNew, SvxBoxItemLine nLine)
const editeng::SvxBorderLine * GetFrameBorderStyle(FrameBorderType eBorder) const
SvxShadowItem GetControlValue(const SvxShadowItem &rItem) const
Definition: border.cxx:154
bool get_sensitive() const
#define IID_PRE_VER_OUTER
Definition: border.cxx:1147
bool get_value_changed_from_saved() const
bool mbRightModified
Definition: border.hxx:114
SfxItemPool * GetPool() const
sal_Int16 GetBottomMargin() const
static bool IsSlot(sal_uInt16 nId)
void EnableVer(bool bEnable)
sal_Int64 get_value(FieldUnit eDestUnit) const
std::unique_ptr< weld::MetricSpinButton > m_xLeftMF
Definition: border.hxx:137
bool GetVisibleColor(Color &rColor) const
void SaveValue()
SvxMarginItem GetControlValue(const SvxMarginItem &rItem) const
Definition: border.cxx:244
bool IsValid(SvxBoxInfoItemValidFlags nValid) const
void SelectItem(sal_uInt16 nItemId)
tools::Long const nBorder
#define IID_PRE_TABLE_OUTER
Definition: border.cxx:1152
void SelectAllVisibleBorders()
FrameSelFlags
void ShowBorder(FrameBorderType eBorder, const editeng::SvxBorderLine *pStyle)
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
#define IID_PRE_CELL_L
Definition: border.cxx:1139
std::unique_ptr< weld::Label > m_xFtShadowSize
Definition: border.hxx:149
static const std::vector< int > m_aLineWidths
Definition: border.hxx:80
MarginControlsWrapper(weld::MetricSpinButton &rMfLeft, weld::MetricSpinButton &rMfRight, weld::MetricSpinButton &rMfTop, weld::MetricSpinButton &rMfBottom)
Definition: border.cxx:235
svx::FrameSelector m_aFrameSel
Definition: border.hxx:124
std::unique_ptr< weld::CustomWeld > m_xWndPresetsWin
Definition: border.hxx:126
void SetTableMode()
Definition: border.cxx:1655
static const sal_Int16 Hairline
Color const & GetSelectEntryColor() const
std::unique_ptr< ValueSet > m_xWndPresets
Definition: border.hxx:125
std::unique_ptr< SvtLineListBox > m_xLbLineStyle
Definition: border.hxx:130
#define IID_PRE_CELL_NONE
Definition: border.cxx:1135
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
sal_uInt16 GetWhich(sal_uInt16 nSlot, bool bDeep=true) const
ShadowControlsWrapper(ValueSet &rVsPos, weld::MetricSpinButton &rMfSize, ColorListBox &rLbColor)
Definition: border.cxx:147
void SetNoSelection()
void SetWidth(sal_uInt16 nNew)
sal_Int64 GetCoreValue(const weld::MetricSpinButton &rField, MapUnit eUnit)
#define GetWhich(nSlot)
static const sal_Int16 Thin
static const sal_Int16 ExtraThick
void SetLocation(SvxShadowLocation eNew)
#define SVX_HIDESHADOWCTL
bool mbTLBREnabled
true = Top-left to bottom-right border enabled.
Definition: border.hxx:110
SvxBoxItemLine
const int FRAMEBORDERTYPE_COUNT
sal_Int16 GetLeftMargin() const
const sal_uInt16 BORDER_SHADOW_COUNT
Definition: border.cxx:145
void * p
ColorListBox & mrLbColor
Definition: border.hxx:55
#define IID_PRE_TABLE_OUTER2
Definition: border.cxx:1155
SfxOkDialogController * GetDialogController() const
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BLACK
std::unique_ptr< weld::Label > m_xUserDefFT
Definition: border.hxx:127
std::unique_ptr< weld::MetricSpinButton > m_xLineWidthMF
Definition: border.hxx:133
void HideShadowControls()
Definition: border.cxx:1130
void SetControlValue(const SvxShadowItem &rItem)
Definition: border.cxx:191
DeactivateRC
SwBorderModes
void SetValid(SvxBoxInfoItemValidFlags nValid, bool bValid=true)
void FillLineListBox_Impl()
Definition: border.cxx:1443
FrameBorderState GetFrameBorderState(FrameBorderType eBorder) const
sal_Int64 normalize(sal_Int64 nValue) const
#define WB_DOUBLEBORDER
MapUnit
double ConvertDoubleValue(double nValue, sal_Int64 mnBaseValue, sal_uInt16 nDecDigits, FieldUnit eInUnit, FieldUnit eOutUnit)
void FillPresetVS()
Definition: border.cxx:1365
#define IID_PRE_CELL_DIAG
Definition: border.cxx:1140
#define IID_PRE_CELL_LR
Definition: border.cxx:1137
#define IID_PRE_TABLE_ALL
Definition: border.cxx:1154
std::unique_ptr< MarginControlsWrapper > m_xMarginControls
Definition: border.hxx:161
void SetBorderDontCare(FrameBorderType eBorder)
#define IID_PRE_VER_ALL
Definition: border.cxx:1149
std::unique_ptr< weld::CheckButton > m_xMergeAdjacentBordersCB
Definition: border.hxx:157
sal_uInt16 GetSmallestDistance() const
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
void UpdateRemoveAdjCellBorderCB(sal_uInt16 nPreset)
Definition: border.cxx:1581
#define IID_PRE_HOR_HOR
Definition: border.cxx:1143
sal_Int32 nState
weld::MetricSpinButton & mrMfSize
Definition: border.hxx:54
static const sal_Int16 Thick
const editeng::SvxBorderLine * GetBottom() const
bool IsDist() const
const Color & GetWindowTextColor() const
void SetControlDontKnow()
Definition: border.cxx:278
sal_uInt16 nPos
sal_uInt16 GetWhich(sal_uInt16 nSlot, bool bDeep=true) const
void SetDist(bool bNew)
bool IsVerEnabled() const
bool m_bDetectedRangeSegmentation false
sal_uInt16 GetWidth() const
void SetLine(const editeng::SvxBorderLine *pNew, SvxBoxItemLine nLine)
sal_Int16 GetTopMargin() const
static void lcl_SetDecimalDigitsTo1(weld::MetricSpinButton &rField)
Definition: border.cxx:97