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 71 const WhichRangesContainer SvxBorderTabPage::pRanges( 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 97 static void lcl_SetDecimalDigitsTo1(weld::MetricSpinButton& rField) 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 147 ShadowControlsWrapper::ShadowControlsWrapper(ValueSet& rVsPos, weld::MetricSpinButton& rMfSize, ColorListBox& rLbColor) 148 : mrVsPos(rVsPos) 149 , mrMfSize(rMfSize) 150 , mrLbColor(rLbColor) 151 { 152 } 153 154 SvxShadowItem ShadowControlsWrapper::GetControlValue(const SvxShadowItem& rItem) const 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 184 if (mrMfSize.get_value_changed_from_saved()) 185 aItem.SetWidth(mrMfSize.denormalize(mrMfSize.get_value(FieldUnit::TWIP))); 186 if (!mrLbColor.IsNoSelection()) 187 aItem.SetColor(mrLbColor.GetSelectEntryColor()); 188 return aItem; 189 } 190 191 void ShadowControlsWrapper::SetControlValue(const SvxShadowItem& rItem) 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: 211 mrVsPos.SetNoSelection(); 212 break; 213 } 214 mrVsPos.SaveValue(); 215 mrMfSize.set_value(mrMfSize.normalize(rItem.GetWidth()), FieldUnit::TWIP); 216 mrMfSize.save_value(); 217 mrLbColor.SelectEntry(rItem.GetColor()); 218 mrLbColor.SaveValue(); 219 } 220 221 bool ShadowControlsWrapper::get_value_changed_from_saved() const 222 { 223 return mrVsPos.IsValueChangedFromSaved() || 224 mrMfSize.get_value_changed_from_saved() || 225 mrLbColor.IsValueChangedFromSaved(); 226 } 227 228 void ShadowControlsWrapper::SetControlDontKnow() 229 { 230 mrVsPos.SetNoSelection(); 231 mrMfSize.set_text(""); 232 mrLbColor.SetNoSelection(); 233 } 234 235 MarginControlsWrapper::MarginControlsWrapper(weld::MetricSpinButton& rMfLeft, weld::MetricSpinButton& rMfRight, 236 weld::MetricSpinButton& rMfTop, weld::MetricSpinButton& rMfBottom) 237 : mrLeftWrp(rMfLeft) 238 , mrRightWrp(rMfRight) 239 , mrTopWrp(rMfTop) 240 , mrBottomWrp(rMfBottom) 241 { 242 } 243 244 SvxMarginItem MarginControlsWrapper::GetControlValue(const SvxMarginItem &rItem) const 245 { 246 SvxMarginItem aItem(rItem); 247 if (mrLeftWrp.get_sensitive()) 248 aItem.SetLeftMargin(mrLeftWrp.denormalize(mrLeftWrp.get_value(FieldUnit::TWIP))); 249 if (mrRightWrp.get_sensitive()) 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))); 253 if (mrBottomWrp.get_sensitive()) 254 aItem.SetBottomMargin(mrBottomWrp.denormalize(mrBottomWrp.get_value(FieldUnit::TWIP))); 255 return aItem; 256 } 257 258 bool MarginControlsWrapper::get_value_changed_from_saved() const 259 { 260 return mrLeftWrp.get_value_changed_from_saved() || 261 mrRightWrp.get_value_changed_from_saved() || 262 mrTopWrp.get_value_changed_from_saved() || 263 mrBottomWrp.get_value_changed_from_saved(); 264 } 265 266 void MarginControlsWrapper::SetControlValue(const SvxMarginItem& rItem) 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); 272 mrLeftWrp.save_value(); 273 mrRightWrp.save_value(); 274 mrTopWrp.save_value(); 275 mrBottomWrp.save_value(); 276 } 277 278 void MarginControlsWrapper::SetControlDontKnow() 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 287 SvxBorderTabPage::SvxBorderTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs) 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 { 342 if (comphelper::LibreOfficeKit::isActive()) 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 { 389 if (comphelper::LibreOfficeKit::isActive()) 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 577 SfxObjectShell* pDocSh = SfxObjectShell::Current(); 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 597 SvxBorderTabPage::~SvxBorderTabPage() 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 626 bool SvxBorderTabPage::IsBorderLineStyleAllowed( SvxBorderLineStyle nStyle ) const 627 { 628 if (maUsedBorderStyles.empty()) 629 // All border styles are allowed. 630 return true; 631 632 return maUsedBorderStyles.count(nStyle) > 0; 633 } 634 635 void SvxBorderTabPage::Reset( const SfxItemSet* rSet ) 636 { 637 SfxItemPool* pPool = rSet->GetPool(); 638 639 if (m_aFrameSel.IsBorderEnabled(svx::FrameBorderType::TLBR)) 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 645 m_aFrameSel.SetBorderDontCare(svx::FrameBorderType::TLBR); 646 } 647 648 if (m_aFrameSel.IsBorderEnabled(svx::FrameBorderType::BLTR)) 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 654 m_aFrameSel.SetBorderDontCare(svx::FrameBorderType::BLTR); 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) 680 m_xMergeAdjacentBordersCB->set_state(TRISTATE_INDET); 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) 688 m_xMergeWithNextCB->set_state(TRISTATE_INDET); 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: 783 m_aFrameSel.HideAllBorders(); 784 } 785 786 if( !m_aFrameSel.IsAnyBorderVisible() ) 787 m_aFrameSel.DeselectAllBorders(); 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); 818 auto nTextColor = Application::GetSettings().GetStyleSettings().GetWindowTextColor(); 819 m_xLbLineStyle->SetColor(nTextColor); 820 821 // Select all visible lines, if they are all equal. 822 if( bWidthEq && bColorEq ) 823 m_aFrameSel.SelectAllVisibleBorders(); 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 882 mbRemoveAdjacentCellBorders = false; 883 m_xRemoveAdjacentCellBordersCB->set_active(false); 884 m_xRemoveAdjacentCellBordersCB->set_sensitive(false); 885 } 886 887 void SvxBorderTabPage::ChangesApplied() 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 897 DeactivateRC SvxBorderTabPage::DeactivatePage( SfxItemSet* _pSet ) 898 { 899 if ( _pSet ) 900 FillItemSet( _pSet ); 901 902 return DeactivateRC::LeavePage; 903 } 904 905 bool SvxBorderTabPage::FillItemSet( SfxItemSet* rCoreAttrs ) 906 { 907 bool bAttrsChanged = false; 908 909 SfxItemPool* pPool = rCoreAttrs->GetPool(); 910 911 if (m_aFrameSel.IsBorderEnabled(svx::FrameBorderType::TLBR) && 912 m_aFrameSel.GetFrameBorderState(svx::FrameBorderType::TLBR) != svx::FrameBorderState::DontCare) 913 { 914 if (const SfxPoolItem* pOldItem = GetOldItem(*rCoreAttrs, SID_ATTR_BORDER_DIAG_TLBR)) 915 { 916 SvxLineItem aLineItem(*static_cast<const SvxLineItem*>(pOldItem)); 917 aLineItem.SetLine(m_aFrameSel.GetFrameBorderStyle(svx::FrameBorderType::TLBR)); 918 rCoreAttrs->Put(aLineItem); 919 bAttrsChanged = true; 920 } 921 } 922 923 if (m_aFrameSel.IsBorderEnabled(svx::FrameBorderType::BLTR) && 924 m_aFrameSel.GetFrameBorderState(svx::FrameBorderType::BLTR) != svx::FrameBorderState::DontCare) 925 { 926 if (const SfxPoolItem* pOldItem = GetOldItem(*rCoreAttrs, SID_ATTR_BORDER_DIAG_BLTR)) 927 { 928 SvxLineItem aLineItem(*static_cast<const SvxLineItem*>(pOldItem)); 929 aLineItem.SetLine(m_aFrameSel.GetFrameBorderStyle(svx::FrameBorderType::BLTR)); 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 1019 aBoxItem.SetRemoveAdjacentCellBorder( mbRemoveAdjacentCellBorders ); 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 ); 1084 aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::HORI, m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Horizontal ) != 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 1130 void SvxBorderTabPage::HideShadowControls() 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 1157 IMPL_LINK_NOARG(SvxBorderTabPage, SelPreHdl_Impl, ValueSet*, void) 1158 { 1159 const svx::FrameBorderState SHOW = svx::FrameBorderState::Show; 1160 const svx::FrameBorderState HIDE = svx::FrameBorderState::Hide; 1161 const svx::FrameBorderState DONT = svx::FrameBorderState::DontCare; 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 { 1199 svx::FrameBorderType eBorder = svx::GetFrameBorderTypeFromIndex( nBorder ); 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 1227 IMPL_LINK_NOARG(SvxBorderTabPage, SelSdwHdl_Impl, ValueSet*, void) 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 1252 IMPL_LINK_NOARG(SvxBorderTabPage, ModifyWidthMFHdl_Impl, weld::MetricSpinButton&, void) 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 1265 IMPL_LINK_NOARG(SvxBorderTabPage, SelStyleHdl_Impl, SvtLineListBox&, void) 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 1305 { IID_PRE_CELL_NONE, IID_PRE_CELL_ALL, IID_PRE_CELL_LR, IID_PRE_CELL_TB, IID_PRE_CELL_L }, 1306 // simple cell with diagonal frame borders 1307 { IID_PRE_CELL_NONE, IID_PRE_CELL_ALL, IID_PRE_CELL_LR, IID_PRE_CELL_TB, IID_PRE_CELL_DIAG }, 1308 // with horizontal inner frame border 1309 { IID_PRE_HOR_NONE, IID_PRE_HOR_OUTER, IID_PRE_HOR_HOR, IID_PRE_HOR_ALL, IID_PRE_HOR_OUTER2 }, 1310 // with vertical inner frame border 1311 { IID_PRE_VER_NONE, IID_PRE_VER_OUTER, IID_PRE_VER_VER, IID_PRE_VER_ALL, IID_PRE_VER_OUTER2 }, 1312 // with horizontal and vertical inner frame borders 1313 { IID_PRE_TABLE_NONE, IID_PRE_TABLE_OUTER, IID_PRE_TABLE_OUTERH, IID_PRE_TABLE_ALL, IID_PRE_TABLE_OUTER2 } 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 1365 void SvxBorderTabPage::FillPresetVS() 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 1385 void SvxBorderTabPage::FillShadowVS() 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 1410 void SvxBorderTabPage::FillValueSets() 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 1443 void SvxBorderTabPage::FillLineListBox_Impl() 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 1501 IMPL_LINK_NOARG(SvxBorderTabPage, LinesChanged_Impl, LinkParamNone*, void) 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 1581 void SvxBorderTabPage::UpdateRemoveAdjCellBorderCB( sal_uInt16 nPreset ) 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 { 1624 mbRemoveAdjacentCellBorders = false; 1625 m_xRemoveAdjacentCellBordersCB->set_active(false); 1626 } 1627 } 1628 1629 void SvxBorderTabPage::PageCreated(const SfxAllItemSet& aSet) 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 ) 1652 HideShadowControls(); 1653 } 1654 1655 void SvxBorderTabPage::SetTableMode() 1656 { 1657 nSWMode = SwBorderModes::TABLE; 1658 } 1659 1660 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 1661
