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