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 <com/sun/star/text/VertOrientation.hpp> 21 22 #include <numpages.hxx> 23 #include <dialmgr.hxx> 24 #include <tools/mapunit.hxx> 25 #include <i18nlangtag/languagetag.hxx> 26 #include <i18nlangtag/mslangid.hxx> 27 #include <editeng/numitem.hxx> 28 #include <svl/eitem.hxx> 29 #include <vcl/svapp.hxx> 30 #include <svx/colorbox.hxx> 31 #include <svx/dlgutil.hxx> 32 #include <svx/strarray.hxx> 33 #include <svx/gallery.hxx> 34 #include <editeng/brushitem.hxx> 35 #include <svl/intitem.hxx> 36 #include <sfx2/objsh.hxx> 37 #include <vcl/graph.hxx> 38 #include <vcl/settings.hxx> 39 #include <cui/cuicharmap.hxx> 40 #include <editeng/flstitem.hxx> 41 #include <svx/numvset.hxx> 42 #include <sfx2/htmlmode.hxx> 43 #include <unotools/pathoptions.hxx> 44 #include <svtools/ctrltool.hxx> 45 #include <svtools/unitconv.hxx> 46 #include <com/sun/star/style/NumberingType.hpp> 47 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 48 #include <com/sun/star/container/XIndexAccess.hpp> 49 #include <com/sun/star/text/XDefaultNumberingProvider.hpp> 50 #include <com/sun/star/text/XNumberingFormatter.hpp> 51 #include <com/sun/star/beans/PropertyValue.hpp> 52 #include <comphelper/processfactory.hxx> 53 #include <comphelper/propertyvalue.hxx> 54 #include <svx/svxids.hrc> 55 #include <o3tl/string_view.hxx> 56 57 #include <algorithm> 58 #include <memory> 59 #include <vector> 60 #include <sfx2/opengrf.hxx> 61 62 #include <strings.hrc> 63 #include <svl/stritem.hxx> 64 #include <svl/slstitm.hxx> 65 #include <sfx2/filedlghelper.hxx> 66 #include <unotools/ucbstreamhelper.hxx> 67 #include <com/sun/star/ucb/SimpleFileAccess.hpp> 68 #include <sal/log.hxx> 69 #include <vcl/cvtgrf.hxx> 70 #include <vcl/graphicfilter.hxx> 71 #include <svx/SvxNumOptionsTabPageHelper.hxx> 72 #include <tools/urlobj.hxx> 73 #include <o3tl/temporary.hxx> 74 #include <osl/diagnose.h> 75 76 using namespace css; 77 using namespace css::uno; 78 using namespace css::beans; 79 using namespace css::lang; 80 using namespace css::text; 81 using namespace css::container; 82 using namespace css::style; 83 84 #define SHOW_NUMBERING 0 85 #define SHOW_BULLET 1 86 #define SHOW_BITMAP 2 87 88 #define MAX_BMP_WIDTH 16 89 #define MAX_BMP_HEIGHT 16 90 #define SEARCHPATH_DELIMITER u';' 91 #define SEARCHFILENAME_DELIMITER u'/' 92 93 static bool bLastRelative = false; 94 95 static SvxNumSettings_Impl* lcl_CreateNumSettingsPtr(const Sequence<PropertyValue>& rLevelProps) 96 { 97 const PropertyValue* pValues = rLevelProps.getConstArray(); 98 SvxNumSettings_Impl* pNew = new SvxNumSettings_Impl; 99 for(sal_Int32 j = 0; j < rLevelProps.getLength(); j++) 100 { 101 if ( pValues[j].Name == "NumberingType" ) 102 { 103 sal_Int16 nTmp; 104 if (pValues[j].Value >>= nTmp) 105 pNew->nNumberType = static_cast<SvxNumType>(nTmp); 106 } 107 else if ( pValues[j].Name == "Prefix" ) 108 pValues[j].Value >>= pNew->sPrefix; 109 else if ( pValues[j].Name == "Suffix" ) 110 pValues[j].Value >>= pNew->sSuffix; 111 else if ( pValues[j].Name == "ParentNumbering" ) 112 pValues[j].Value >>= pNew->nParentNumbering; 113 else if ( pValues[j].Name == "BulletChar" ) 114 pValues[j].Value >>= pNew->sBulletChar; 115 else if ( pValues[j].Name == "BulletFontName" ) 116 pValues[j].Value >>= pNew->sBulletFont; 117 } 118 return pNew; 119 } 120 121 // the selection of bullets from the OpenSymbol 122 const sal_Unicode aBulletTypes[] = 123 { 124 0x2022, 125 0x25cf, 126 0xe00c, 127 0xe00a, 128 0x2794, 129 0x27a2, 130 0x2717, 131 0x2714 132 }; 133 134 // Is one of the masked formats set? 135 static bool lcl_IsNumFmtSet(SvxNumRule const * pNum, sal_uInt16 nLevelMask) 136 { 137 bool bRet = false; 138 sal_uInt16 nMask = 1; 139 for( sal_uInt16 i = 0; i < SVX_MAX_NUM && !bRet; i++ ) 140 { 141 if(nLevelMask & nMask) 142 bRet |= nullptr != pNum->Get( i ); 143 nMask <<= 1 ; 144 } 145 return bRet; 146 } 147 148 static const vcl::Font& lcl_GetDefaultBulletFont() 149 { 150 static vcl::Font aDefBulletFont = []() 151 { 152 vcl::Font tmp("OpenSymbol", "", Size(0, 14)); 153 tmp.SetCharSet( RTL_TEXTENCODING_SYMBOL ); 154 tmp.SetFamily( FAMILY_DONTKNOW ); 155 tmp.SetPitch( PITCH_DONTKNOW ); 156 tmp.SetWeight( WEIGHT_DONTKNOW ); 157 tmp.SetTransparent( true ); 158 return tmp; 159 }(); 160 return aDefBulletFont; 161 } 162 163 SvxSingleNumPickTabPage::SvxSingleNumPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet) 164 : SfxTabPage(pPage, pController, "cui/ui/picknumberingpage.ui", "PickNumberingPage", &rSet) 165 , nActNumLvl(SAL_MAX_UINT16) 166 , bModified(false) 167 , bPreset(false) 168 , nNumItemId(SID_ATTR_NUMBERING_RULE) 169 , m_xExamplesVS(new SvxNumValueSet(m_xBuilder->weld_scrolled_window("valuesetwin", true))) 170 , m_xExamplesVSWin(new weld::CustomWeld(*m_xBuilder, "valueset", *m_xExamplesVS)) 171 { 172 SetExchangeSupport(); 173 m_xExamplesVS->init(NumberingPageType::SINGLENUM); 174 m_xExamplesVS->SetSelectHdl(LINK(this, SvxSingleNumPickTabPage, NumSelectHdl_Impl)); 175 m_xExamplesVS->SetDoubleClickHdl(LINK(this, SvxSingleNumPickTabPage, DoubleClickHdl_Impl)); 176 177 Reference<XDefaultNumberingProvider> xDefNum = SvxNumOptionsTabPageHelper::GetNumberingProvider(); 178 if(!xDefNum.is()) 179 return; 180 181 Sequence< Sequence< PropertyValue > > aNumberings; 182 const Locale& rLocale = Application::GetSettings().GetLanguageTag().getLocale(); 183 try 184 { 185 aNumberings = 186 xDefNum->getDefaultContinuousNumberingLevels( rLocale ); 187 188 189 sal_Int32 nLength = std::min<sal_Int32>(aNumberings.getLength(), NUM_VALUSET_COUNT); 190 191 const Sequence<PropertyValue>* pValuesArr = aNumberings.getConstArray(); 192 for(sal_Int32 i = 0; i < nLength; i++) 193 { 194 SvxNumSettings_Impl* pNew = lcl_CreateNumSettingsPtr(pValuesArr[i]); 195 aNumSettingsArr.push_back(std::unique_ptr<SvxNumSettings_Impl>(pNew)); 196 } 197 } 198 catch(const Exception&) 199 { 200 } 201 Reference<XNumberingFormatter> xFormat(xDefNum, UNO_QUERY); 202 m_xExamplesVS->SetNumberingSettings(aNumberings, xFormat, rLocale); 203 } 204 205 SvxSingleNumPickTabPage::~SvxSingleNumPickTabPage() 206 { 207 m_xExamplesVSWin.reset(); 208 m_xExamplesVS.reset(); 209 } 210 211 std::unique_ptr<SfxTabPage> SvxSingleNumPickTabPage::Create(weld::Container* pPage, weld::DialogController* pController, 212 const SfxItemSet* rAttrSet) 213 { 214 return std::make_unique<SvxSingleNumPickTabPage>(pPage, pController, *rAttrSet); 215 } 216 217 bool SvxSingleNumPickTabPage::FillItemSet( SfxItemSet* rSet ) 218 { 219 if( (bPreset || bModified) && pSaveNum) 220 { 221 *pSaveNum = *pActNum; 222 rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId )); 223 rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, bPreset)); 224 } 225 226 return bModified; 227 } 228 229 void SvxSingleNumPickTabPage::ActivatePage(const SfxItemSet& rSet) 230 { 231 bPreset = false; 232 bool bIsPreset = false; 233 const SfxItemSet* pExampleSet = GetDialogExampleSet(); 234 if(pExampleSet) 235 { 236 if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false)) 237 bIsPreset = pPresetItem->GetValue(); 238 if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false)) 239 nActNumLvl = pLevelItem->GetValue(); 240 } 241 if(const SvxNumBulletItem* pNumItem = rSet.GetItemIfSet(nNumItemId, false)) 242 { 243 pSaveNum.reset( new SvxNumRule(pNumItem->GetNumRule()) ); 244 } 245 if(pActNum && *pSaveNum != *pActNum) 246 { 247 *pActNum = *pSaveNum; 248 m_xExamplesVS->SetNoSelection(); 249 } 250 251 if(pActNum && (!lcl_IsNumFmtSet(pActNum.get(), nActNumLvl) || bIsPreset)) 252 { 253 m_xExamplesVS->SelectItem(1); 254 NumSelectHdl_Impl(m_xExamplesVS.get()); 255 bPreset = true; 256 } 257 bPreset |= bIsPreset; 258 259 bModified = false; 260 } 261 262 DeactivateRC SvxSingleNumPickTabPage::DeactivatePage(SfxItemSet *_pSet) 263 { 264 if(_pSet) 265 FillItemSet(_pSet); 266 return DeactivateRC::LeavePage; 267 } 268 269 void SvxSingleNumPickTabPage::Reset( const SfxItemSet* rSet ) 270 { 271 const SfxPoolItem* pItem; 272 273 // in Draw the item exists as WhichId, in Writer only as SlotId 274 SfxItemState eState = rSet->GetItemState(SID_ATTR_NUMBERING_RULE, false, &pItem); 275 if(eState != SfxItemState::SET) 276 { 277 nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE); 278 eState = rSet->GetItemState(nNumItemId, false, &pItem); 279 280 if( eState != SfxItemState::SET ) 281 { 282 pItem = & rSet->Get( nNumItemId ); 283 eState = SfxItemState::SET; 284 } 285 } 286 DBG_ASSERT(eState == SfxItemState::SET, "no item found!"); 287 pSaveNum.reset( new SvxNumRule(static_cast<const SvxNumBulletItem*>(pItem)->GetNumRule()) ); 288 289 if(!pActNum) 290 pActNum.reset( new SvxNumRule(*pSaveNum) ); 291 else if(*pSaveNum != *pActNum) 292 *pActNum = *pSaveNum; 293 } 294 295 IMPL_LINK_NOARG(SvxSingleNumPickTabPage, NumSelectHdl_Impl, ValueSet*, void) 296 { 297 if(!pActNum) 298 return; 299 300 bPreset = false; 301 bModified = true; 302 sal_uInt16 nIdx = m_xExamplesVS->GetSelectedItemId() - 1; 303 DBG_ASSERT(aNumSettingsArr.size() > nIdx, "wrong index"); 304 if(aNumSettingsArr.size() <= nIdx) 305 return; 306 SvxNumSettings_Impl* _pSet = aNumSettingsArr[nIdx].get(); 307 SvxNumType eNewType = _pSet->nNumberType; 308 const sal_Unicode cLocalPrefix = !_pSet->sPrefix.isEmpty() ? _pSet->sPrefix[0] : 0; 309 const sal_Unicode cLocalSuffix = !_pSet->sSuffix.isEmpty() ? _pSet->sSuffix[0] : 0; 310 311 sal_uInt16 nMask = 1; 312 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) 313 { 314 if(nActNumLvl & nMask) 315 { 316 SvxNumberFormat aFmt(pActNum->GetLevel(i)); 317 aFmt.SetNumberingType(eNewType); 318 aFmt.SetListFormat(cLocalPrefix == ' ' ? "" : _pSet->sPrefix, 319 cLocalSuffix == ' ' ? "" : _pSet->sSuffix, i); 320 aFmt.SetCharFormatName(""); 321 aFmt.SetBulletRelSize(100); 322 pActNum->SetLevel(i, aFmt); 323 } 324 nMask <<= 1; 325 } 326 } 327 328 IMPL_LINK_NOARG(SvxSingleNumPickTabPage, DoubleClickHdl_Impl, ValueSet*, void) 329 { 330 NumSelectHdl_Impl(m_xExamplesVS.get()); 331 weld::Button& rOk = GetDialogController()->GetOKButton(); 332 rOk.clicked(); 333 } 334 335 SvxBulletPickTabPage::SvxBulletPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet) 336 : SfxTabPage(pPage, pController, "cui/ui/pickbulletpage.ui", "PickBulletPage", &rSet) 337 , nActNumLvl(SAL_MAX_UINT16) 338 , bModified(false) 339 , bPreset(false) 340 , nNumItemId(SID_ATTR_NUMBERING_RULE) 341 , m_xExamplesVS(new SvxNumValueSet(m_xBuilder->weld_scrolled_window("valuesetwin", true))) 342 , m_xExamplesVSWin(new weld::CustomWeld(*m_xBuilder, "valueset", *m_xExamplesVS)) 343 { 344 SetExchangeSupport(); 345 m_xExamplesVS->init(NumberingPageType::BULLET); 346 m_xExamplesVS->SetSelectHdl(LINK(this, SvxBulletPickTabPage, NumSelectHdl_Impl)); 347 m_xExamplesVS->SetDoubleClickHdl(LINK(this, SvxBulletPickTabPage, DoubleClickHdl_Impl)); 348 } 349 350 SvxBulletPickTabPage::~SvxBulletPickTabPage() 351 { 352 m_xExamplesVSWin.reset(); 353 m_xExamplesVS.reset(); 354 } 355 356 std::unique_ptr<SfxTabPage> SvxBulletPickTabPage::Create(weld::Container* pPage, weld::DialogController* pController, 357 const SfxItemSet* rAttrSet) 358 { 359 return std::make_unique<SvxBulletPickTabPage>(pPage, pController, *rAttrSet); 360 } 361 362 bool SvxBulletPickTabPage::FillItemSet( SfxItemSet* rSet ) 363 { 364 if( (bPreset || bModified) && pActNum) 365 { 366 *pSaveNum = *pActNum; 367 rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId )); 368 rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, bPreset)); 369 } 370 return bModified; 371 } 372 373 void SvxBulletPickTabPage::ActivatePage(const SfxItemSet& rSet) 374 { 375 bPreset = false; 376 bool bIsPreset = false; 377 const SfxItemSet* pExampleSet = GetDialogExampleSet(); 378 if(pExampleSet) 379 { 380 if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false)) 381 bIsPreset = pPresetItem->GetValue(); 382 if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false)) 383 nActNumLvl = pLevelItem->GetValue(); 384 } 385 if(const SvxNumBulletItem* pBulletItem = rSet.GetItemIfSet(nNumItemId, false)) 386 { 387 pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) ); 388 } 389 if(pActNum && *pSaveNum != *pActNum) 390 { 391 *pActNum = *pSaveNum; 392 m_xExamplesVS->SetNoSelection(); 393 } 394 395 if(pActNum && (!lcl_IsNumFmtSet(pActNum.get(), nActNumLvl) || bIsPreset)) 396 { 397 m_xExamplesVS->SelectItem(1); 398 NumSelectHdl_Impl(m_xExamplesVS.get()); 399 bPreset = true; 400 } 401 bPreset |= bIsPreset; 402 bModified = false; 403 } 404 405 DeactivateRC SvxBulletPickTabPage::DeactivatePage(SfxItemSet *_pSet) 406 { 407 if(_pSet) 408 FillItemSet(_pSet); 409 return DeactivateRC::LeavePage; 410 } 411 412 void SvxBulletPickTabPage::Reset( const SfxItemSet* rSet ) 413 { 414 // in Draw the item exists as WhichId, in Writer only as SlotId 415 const SvxNumBulletItem* pItem = rSet->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false); 416 if(!pItem) 417 { 418 nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE); 419 pItem = rSet->GetItemIfSet(nNumItemId, false); 420 421 if( !pItem ) 422 { 423 pItem = & rSet->Get( nNumItemId ); 424 } 425 426 } 427 pSaveNum.reset( new SvxNumRule(pItem->GetNumRule()) ); 428 429 if(!pActNum) 430 pActNum.reset( new SvxNumRule(*pSaveNum) ); 431 else if(*pSaveNum != *pActNum) 432 *pActNum = *pSaveNum; 433 } 434 435 IMPL_LINK_NOARG(SvxBulletPickTabPage, NumSelectHdl_Impl, ValueSet*, void) 436 { 437 if(!pActNum) 438 return; 439 440 bPreset = false; 441 bModified = true; 442 sal_Unicode cChar = aBulletTypes[m_xExamplesVS->GetSelectedItemId() - 1]; 443 const vcl::Font& rActBulletFont = lcl_GetDefaultBulletFont(); 444 445 sal_uInt16 nMask = 1; 446 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) 447 { 448 if(nActNumLvl & nMask) 449 { 450 SvxNumberFormat aFmt(pActNum->GetLevel(i)); 451 aFmt.SetNumberingType( SVX_NUM_CHAR_SPECIAL ); 452 // #i93908# clear suffix for bullet lists 453 aFmt.SetListFormat("", "", i); 454 aFmt.SetBulletFont(&rActBulletFont); 455 aFmt.SetBulletChar(cChar ); 456 aFmt.SetCharFormatName(sBulletCharFormatName); 457 aFmt.SetBulletRelSize(45); 458 pActNum->SetLevel(i, aFmt); 459 } 460 nMask <<= 1; 461 } 462 } 463 464 IMPL_LINK_NOARG(SvxBulletPickTabPage, DoubleClickHdl_Impl, ValueSet*, void) 465 { 466 NumSelectHdl_Impl(m_xExamplesVS.get()); 467 weld::Button& rOk = GetDialogController()->GetOKButton(); 468 rOk.clicked(); 469 } 470 471 void SvxBulletPickTabPage::PageCreated(const SfxAllItemSet& aSet) 472 { 473 const SfxStringItem* pBulletCharFmt = aSet.GetItem<SfxStringItem>(SID_BULLET_CHAR_FMT, false); 474 475 if (pBulletCharFmt) 476 sBulletCharFormatName = pBulletCharFmt->GetValue(); 477 } 478 479 SvxNumPickTabPage::SvxNumPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet) 480 : SfxTabPage(pPage, pController, "cui/ui/pickoutlinepage.ui", "PickOutlinePage", &rSet) 481 , nActNumLvl(SAL_MAX_UINT16) 482 , nNumItemId(SID_ATTR_NUMBERING_RULE) 483 , bModified(false) 484 , bPreset(false) 485 , m_xExamplesVS(new SvxNumValueSet(m_xBuilder->weld_scrolled_window("valuesetwin", true))) 486 , m_xExamplesVSWin(new weld::CustomWeld(*m_xBuilder, "valueset", *m_xExamplesVS)) 487 { 488 SetExchangeSupport(); 489 490 m_xExamplesVS->init(NumberingPageType::OUTLINE); 491 m_xExamplesVS->SetSelectHdl(LINK(this, SvxNumPickTabPage, NumSelectHdl_Impl)); 492 m_xExamplesVS->SetDoubleClickHdl(LINK(this, SvxNumPickTabPage, DoubleClickHdl_Impl)); 493 494 Reference<XDefaultNumberingProvider> xDefNum = SvxNumOptionsTabPageHelper::GetNumberingProvider(); 495 if(!xDefNum.is()) 496 return; 497 498 Sequence<Reference<XIndexAccess> > aOutlineAccess; 499 const Locale& rLocale = Application::GetSettings().GetLanguageTag().getLocale(); 500 try 501 { 502 aOutlineAccess = xDefNum->getDefaultOutlineNumberings( rLocale ); 503 504 for(sal_Int32 nItem = 0; 505 nItem < aOutlineAccess.getLength() && nItem < NUM_VALUSET_COUNT; 506 nItem++ ) 507 { 508 SvxNumSettingsArr_Impl& rItemArr = aNumSettingsArrays[ nItem ]; 509 510 Reference<XIndexAccess> xLevel = aOutlineAccess.getConstArray()[nItem]; 511 for(sal_Int32 nLevel = 0; nLevel < SVX_MAX_NUM; nLevel++) 512 { 513 // use the last locale-defined level for all remaining levels. 514 sal_Int32 nLocaleLevel = std::min(nLevel, xLevel->getCount() - 1); 515 Sequence<PropertyValue> aLevelProps; 516 if (nLocaleLevel >= 0) 517 xLevel->getByIndex(nLocaleLevel) >>= aLevelProps; 518 519 SvxNumSettings_Impl* pNew = lcl_CreateNumSettingsPtr(aLevelProps); 520 rItemArr.push_back( std::unique_ptr<SvxNumSettings_Impl>(pNew) ); 521 } 522 } 523 } 524 catch(const Exception&) 525 { 526 } 527 Reference<XNumberingFormatter> xFormat(xDefNum, UNO_QUERY); 528 m_xExamplesVS->SetOutlineNumberingSettings(aOutlineAccess, xFormat, rLocale); 529 } 530 531 SvxNumPickTabPage::~SvxNumPickTabPage() 532 { 533 m_xExamplesVSWin.reset(); 534 m_xExamplesVS.reset(); 535 } 536 537 std::unique_ptr<SfxTabPage> SvxNumPickTabPage::Create(weld::Container* pPage, weld::DialogController* pController, 538 const SfxItemSet* rAttrSet) 539 { 540 return std::make_unique<SvxNumPickTabPage>(pPage, pController, *rAttrSet); 541 } 542 543 bool SvxNumPickTabPage::FillItemSet( SfxItemSet* rSet ) 544 { 545 if( (bPreset || bModified) && pActNum) 546 { 547 *pSaveNum = *pActNum; 548 rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId )); 549 rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, bPreset)); 550 } 551 return bModified; 552 } 553 554 void SvxNumPickTabPage::ActivatePage(const SfxItemSet& rSet) 555 { 556 bPreset = false; 557 bool bIsPreset = false; 558 const SfxItemSet* pExampleSet = GetDialogExampleSet(); 559 if(pExampleSet) 560 { 561 if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false)) 562 bIsPreset = pPresetItem->GetValue(); 563 if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false)) 564 nActNumLvl = pLevelItem->GetValue(); 565 } 566 if(const SvxNumBulletItem* pBulletItem = rSet.GetItemIfSet(nNumItemId, false)) 567 { 568 pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) ); 569 } 570 if(pActNum && *pSaveNum != *pActNum) 571 { 572 *pActNum = *pSaveNum; 573 m_xExamplesVS->SetNoSelection(); 574 } 575 576 if(pActNum && (!lcl_IsNumFmtSet(pActNum.get(), nActNumLvl) || bIsPreset)) 577 { 578 m_xExamplesVS->SelectItem(1); 579 NumSelectHdl_Impl(m_xExamplesVS.get()); 580 bPreset = true; 581 } 582 bPreset |= bIsPreset; 583 bModified = false; 584 } 585 586 DeactivateRC SvxNumPickTabPage::DeactivatePage(SfxItemSet *_pSet) 587 { 588 if(_pSet) 589 FillItemSet(_pSet); 590 return DeactivateRC::LeavePage; 591 } 592 593 void SvxNumPickTabPage::Reset( const SfxItemSet* rSet ) 594 { 595 // in Draw the item exists as WhichId, in Writer only as SlotId 596 const SvxNumBulletItem* pItem = rSet->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false); 597 if(!pItem) 598 { 599 nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE); 600 pItem = rSet->GetItemIfSet(nNumItemId, false); 601 602 if( !pItem ) 603 { 604 pItem = & rSet->Get( nNumItemId ); 605 } 606 } 607 pSaveNum.reset( new SvxNumRule(pItem->GetNumRule()) ); 608 609 if(!pActNum) 610 pActNum.reset( new SvxNumRule(*pSaveNum) ); 611 else if(*pSaveNum != *pActNum) 612 *pActNum = *pSaveNum; 613 614 } 615 616 // all levels are changed here 617 IMPL_LINK_NOARG(SvxNumPickTabPage, NumSelectHdl_Impl, ValueSet*, void) 618 { 619 if(!pActNum) 620 return; 621 622 bPreset = false; 623 bModified = true; 624 625 const FontList* pList = nullptr; 626 627 SvxNumSettingsArr_Impl& rItemArr = aNumSettingsArrays[m_xExamplesVS->GetSelectedItemId() - 1]; 628 629 const vcl::Font& rActBulletFont = lcl_GetDefaultBulletFont(); 630 SvxNumSettings_Impl* pLevelSettings = nullptr; 631 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) 632 { 633 if(rItemArr.size() > i) 634 pLevelSettings = rItemArr[i].get(); 635 if(!pLevelSettings) 636 break; 637 SvxNumberFormat aFmt(pActNum->GetLevel(i)); 638 aFmt.SetNumberingType( pLevelSettings->nNumberType ); 639 sal_uInt16 nUpperLevelOrChar = static_cast<sal_uInt16>(pLevelSettings->nParentNumbering); 640 if(aFmt.GetNumberingType() == SVX_NUM_CHAR_SPECIAL) 641 { 642 // #i93908# clear suffix for bullet lists 643 aFmt.SetListFormat("", "", i); 644 if( !pLevelSettings->sBulletFont.isEmpty() && 645 pLevelSettings->sBulletFont != rActBulletFont.GetFamilyName()) 646 { 647 //search for the font 648 if(!pList) 649 { 650 if (SfxObjectShell* pCurDocShell = SfxObjectShell::Current()) 651 { 652 const SvxFontListItem* pFontListItem = 653 static_cast<const SvxFontListItem*>( pCurDocShell 654 ->GetItem( SID_ATTR_CHAR_FONTLIST )); 655 pList = pFontListItem ? pFontListItem->GetFontList() : nullptr; 656 } 657 } 658 if(pList && pList->IsAvailable( pLevelSettings->sBulletFont ) ) 659 { 660 FontMetric aFontMetric = pList->Get( 661 pLevelSettings->sBulletFont,WEIGHT_NORMAL, ITALIC_NONE); 662 vcl::Font aFont(aFontMetric); 663 aFmt.SetBulletFont(&aFont); 664 } 665 else 666 { 667 //if it cannot be found then create a new one 668 vcl::Font aCreateFont( pLevelSettings->sBulletFont, 669 OUString(), Size( 0, 14 ) ); 670 aCreateFont.SetCharSet( RTL_TEXTENCODING_DONTKNOW ); 671 aCreateFont.SetFamily( FAMILY_DONTKNOW ); 672 aCreateFont.SetPitch( PITCH_DONTKNOW ); 673 aCreateFont.SetWeight( WEIGHT_DONTKNOW ); 674 aCreateFont.SetTransparent( true ); 675 aFmt.SetBulletFont( &aCreateFont ); 676 } 677 } 678 else 679 aFmt.SetBulletFont( &rActBulletFont ); 680 681 aFmt.SetBulletChar( !pLevelSettings->sBulletChar.isEmpty() 682 ? pLevelSettings->sBulletChar.iterateCodePoints( 683 &o3tl::temporary(sal_Int32(0))) 684 : 0 ); 685 aFmt.SetCharFormatName( sBulletCharFormatName ); 686 aFmt.SetBulletRelSize(45); 687 } 688 else 689 { 690 aFmt.SetIncludeUpperLevels(sal::static_int_cast< sal_uInt8 >(0 != nUpperLevelOrChar ? pActNum->GetLevelCount() : 1)); 691 aFmt.SetCharFormatName(sNumCharFmtName); 692 aFmt.SetBulletRelSize(100); 693 694 // Completely ignore the Left/Right value provided by the locale outline definition, 695 // because this function doesn't actually modify the indents at all, 696 // and right-adjusted numbering definitely needs a different FirstLineIndent. 697 698 // #i93908# 699 aFmt.SetListFormat(pLevelSettings->sPrefix, pLevelSettings->sSuffix, i); 700 } 701 pActNum->SetLevel(i, aFmt); 702 } 703 } 704 705 IMPL_LINK_NOARG(SvxNumPickTabPage, DoubleClickHdl_Impl, ValueSet*, void) 706 { 707 NumSelectHdl_Impl(m_xExamplesVS.get()); 708 weld::Button& rOk = GetDialogController()->GetOKButton(); 709 rOk.clicked(); 710 } 711 712 void SvxNumPickTabPage::PageCreated(const SfxAllItemSet& aSet) 713 { 714 const SfxStringItem* pNumCharFmt = aSet.GetItem<SfxStringItem>(SID_NUM_CHAR_FMT, false); 715 const SfxStringItem* pBulletCharFmt = aSet.GetItem<SfxStringItem>(SID_BULLET_CHAR_FMT, false); 716 717 718 if (pNumCharFmt &&pBulletCharFmt) 719 SetCharFormatNames( pNumCharFmt->GetValue(),pBulletCharFmt->GetValue()); 720 } 721 722 SvxBitmapPickTabPage::SvxBitmapPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet) 723 : SfxTabPage(pPage, pController, "cui/ui/pickgraphicpage.ui", "PickGraphicPage", &rSet) 724 , nActNumLvl(SAL_MAX_UINT16) 725 , nNumItemId(SID_ATTR_NUMBERING_RULE) 726 , bModified(false) 727 , bPreset(false) 728 , m_xErrorText(m_xBuilder->weld_label("errorft")) 729 , m_xBtBrowseFile(m_xBuilder->weld_button("browseBtn")) 730 , m_xExamplesVS(new SvxBmpNumValueSet(m_xBuilder->weld_scrolled_window("valuesetwin", true))) 731 , m_xExamplesVSWin(new weld::CustomWeld(*m_xBuilder, "valueset", *m_xExamplesVS)) 732 { 733 SetExchangeSupport(); 734 735 m_xExamplesVS->init(); 736 m_xExamplesVS->SetSelectHdl(LINK(this, SvxBitmapPickTabPage, NumSelectHdl_Impl)); 737 m_xExamplesVS->SetDoubleClickHdl(LINK(this, SvxBitmapPickTabPage, DoubleClickHdl_Impl)); 738 m_xBtBrowseFile->connect_clicked(LINK(this, SvxBitmapPickTabPage, ClickAddBrowseHdl_Impl)); 739 740 eCoreUnit = rSet.GetPool()->GetMetric(rSet.GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE)); 741 742 // determine graphic name 743 GalleryExplorer::FillObjList(GALLERY_THEME_BULLETS, aGrfNames); 744 745 size_t i = 0; 746 for (auto & grfName : aGrfNames) 747 { 748 m_xExamplesVS->InsertItem( i + 1, i); 749 750 INetURLObject aObj(grfName); 751 if (aObj.GetProtocol() == INetProtocol::File) 752 { 753 // tdf#114070 - only show the last name of the filename without its extension 754 aObj.removeExtension(); 755 grfName = aObj.GetLastName(INetURLObject::DecodeMechanism::Unambiguous); 756 } 757 758 m_xExamplesVS->SetItemText( i + 1, grfName ); 759 ++i; 760 } 761 762 if(aGrfNames.empty()) 763 { 764 m_xErrorText->show(); 765 } 766 else 767 { 768 m_xExamplesVS->Show(); 769 m_xExamplesVS->SetFormat(); 770 m_xExamplesVS->Invalidate(); 771 } 772 } 773 774 SvxBitmapPickTabPage::~SvxBitmapPickTabPage() 775 { 776 m_xExamplesVSWin.reset(); 777 m_xExamplesVS.reset(); 778 } 779 780 std::unique_ptr<SfxTabPage> SvxBitmapPickTabPage::Create(weld::Container* pPage, weld::DialogController* pController, 781 const SfxItemSet* rAttrSet) 782 { 783 return std::make_unique<SvxBitmapPickTabPage>(pPage, pController, *rAttrSet); 784 } 785 786 void SvxBitmapPickTabPage::ActivatePage(const SfxItemSet& rSet) 787 { 788 bPreset = false; 789 bool bIsPreset = false; 790 const SfxItemSet* pExampleSet = GetDialogExampleSet(); 791 if(pExampleSet) 792 { 793 if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false)) 794 bIsPreset = pPresetItem->GetValue(); 795 if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false)) 796 nActNumLvl = pLevelItem->GetValue(); 797 } 798 if(const SvxNumBulletItem* pBulletItem = rSet.GetItemIfSet(nNumItemId, false)) 799 { 800 pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) ); 801 } 802 if(pActNum && *pSaveNum != *pActNum) 803 { 804 *pActNum = *pSaveNum; 805 m_xExamplesVS->SetNoSelection(); 806 } 807 808 if(!aGrfNames.empty() && 809 (pActNum && (!lcl_IsNumFmtSet(pActNum.get(), nActNumLvl) || bIsPreset))) 810 { 811 m_xExamplesVS->SelectItem(1); 812 NumSelectHdl_Impl(m_xExamplesVS.get()); 813 bPreset = true; 814 } 815 bPreset |= bIsPreset; 816 bModified = false; 817 } 818 819 DeactivateRC SvxBitmapPickTabPage::DeactivatePage(SfxItemSet *_pSet) 820 { 821 if(_pSet) 822 FillItemSet(_pSet); 823 return DeactivateRC::LeavePage; 824 } 825 826 bool SvxBitmapPickTabPage::FillItemSet( SfxItemSet* rSet ) 827 { 828 if ( aGrfNames.empty() ) 829 { 830 return false; 831 } 832 if( (bPreset || bModified) && pActNum) 833 { 834 *pSaveNum = *pActNum; 835 rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ) ); 836 rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, bPreset)); 837 } 838 839 return bModified; 840 } 841 842 void SvxBitmapPickTabPage::Reset( const SfxItemSet* rSet ) 843 { 844 // in Draw the item exists as WhichId, in Writer only as SlotId 845 const SvxNumBulletItem* pItem = rSet->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false); 846 if(!pItem) 847 { 848 nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE); 849 pItem = rSet->GetItemIfSet(nNumItemId, false); 850 851 if( !pItem ) 852 { 853 pItem = & rSet->Get( nNumItemId ); 854 } 855 856 } 857 DBG_ASSERT(pItem, "no item found!"); 858 pSaveNum.reset( new SvxNumRule(pItem->GetNumRule()) ); 859 860 if(!pActNum) 861 pActNum.reset( new SvxNumRule(*pSaveNum) ); 862 else if(*pSaveNum != *pActNum) 863 *pActNum = *pSaveNum; 864 } 865 866 IMPL_LINK_NOARG(SvxBitmapPickTabPage, NumSelectHdl_Impl, ValueSet*, void) 867 { 868 if(!pActNum) 869 return; 870 871 bPreset = false; 872 bModified = true; 873 sal_uInt16 nIdx = m_xExamplesVS->GetSelectedItemId() - 1; 874 875 sal_uInt16 nMask = 1; 876 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) 877 { 878 if(nActNumLvl & nMask) 879 { 880 SvxNumberFormat aFmt(pActNum->GetLevel(i)); 881 aFmt.SetNumberingType(SVX_NUM_BITMAP); 882 aFmt.SetListFormat("", "", i); 883 aFmt.SetCharFormatName( "" ); 884 885 Graphic aGraphic; 886 if(GalleryExplorer::GetGraphicObj( GALLERY_THEME_BULLETS, nIdx, &aGraphic)) 887 { 888 Size aSize = SvxNumberFormat::GetGraphicSizeMM100(&aGraphic); 889 sal_Int16 eOrient = text::VertOrientation::LINE_CENTER; 890 aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(eCoreUnit)); 891 SvxBrushItem aBrush(aGraphic, GPOS_AREA, SID_ATTR_BRUSH ); 892 aFmt.SetGraphicBrush( &aBrush, &aSize, &eOrient ); 893 } 894 else if(aGrfNames.size() > nIdx) 895 aFmt.SetGraphic( aGrfNames[nIdx] ); 896 pActNum->SetLevel(i, aFmt); 897 } 898 nMask <<= 1; 899 } 900 } 901 902 IMPL_LINK_NOARG(SvxBitmapPickTabPage, DoubleClickHdl_Impl, ValueSet*, void) 903 { 904 NumSelectHdl_Impl(m_xExamplesVS.get()); 905 weld::Button& rOk = GetDialogController()->GetOKButton(); 906 rOk.clicked(); 907 } 908 909 IMPL_LINK_NOARG(SvxBitmapPickTabPage, ClickAddBrowseHdl_Impl, weld::Button&, void) 910 { 911 sfx2::FileDialogHelper aFileDialog(0, FileDialogFlags::NONE, GetFrameWeld()); 912 aFileDialog.SetContext(sfx2::FileDialogHelper::BulletsAddImage); 913 aFileDialog.SetTitle(CuiResId(RID_CUISTR_ADD_IMAGE)); 914 if ( aFileDialog.Execute() != ERRCODE_NONE ) 915 return; 916 917 OUString aPath = SvtPathOptions().GetGalleryPath(); 918 std::u16string_view aPathToken = o3tl::getToken(aPath, 1 , SEARCHPATH_DELIMITER ); 919 920 OUString aUserImageURL = aFileDialog.GetPath(); 921 922 OUString aFileName; 923 const sal_Int32 nPos {aUserImageURL.lastIndexOf(SEARCHFILENAME_DELIMITER)+1}; 924 if (nPos<=0) 925 aFileName = aUserImageURL; 926 else if (nPos<aUserImageURL.getLength()) 927 aFileName = aUserImageURL.copy(nPos); 928 929 OUString aUserGalleryURL = OUString::Concat(aPathToken) + "/" + aFileName; 930 INetURLObject aURL( aUserImageURL ); 931 DBG_ASSERT( aURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" ); 932 933 GraphicDescriptor aDescriptor(aURL); 934 if (!aDescriptor.Detect()) 935 return; 936 937 uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory(); 938 uno::Reference<ucb::XSimpleFileAccess3> xSimpleFileAccess( 939 ucb::SimpleFileAccess::create( ::comphelper::getComponentContext(xFactory) ) ); 940 if ( !xSimpleFileAccess->exists( aUserImageURL )) 941 return; 942 943 xSimpleFileAccess->copy( aUserImageURL, aUserGalleryURL ); 944 INetURLObject gURL( aUserGalleryURL ); 945 std::unique_ptr<SvStream> pIn(::utl::UcbStreamHelper::CreateStream( 946 gURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ )); 947 if ( !pIn ) 948 return; 949 950 Graphic aGraphic; 951 GraphicConverter::Import( *pIn, aGraphic ); 952 953 BitmapEx aBitmap = aGraphic.GetBitmapEx(); 954 tools::Long nPixelX = aBitmap.GetSizePixel().Width(); 955 tools::Long nPixelY = aBitmap.GetSizePixel().Height(); 956 double ratio = nPixelY/static_cast<double>(nPixelX); 957 if(nPixelX > 30) 958 { 959 nPixelX = 30; 960 nPixelY = static_cast<tools::Long>(nPixelX*ratio); 961 } 962 if(nPixelY > 30) 963 { 964 nPixelY = 30; 965 nPixelX = static_cast<tools::Long>(nPixelY/ratio); 966 } 967 968 aBitmap.Scale( Size( nPixelX, nPixelY ), BmpScaleFlag::Fast ); 969 Graphic aScaledGraphic( aBitmap ); 970 GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter(); 971 972 Sequence< PropertyValue > aFilterData{ 973 comphelper::makePropertyValue("Compression", sal_Int32(-1)), 974 comphelper::makePropertyValue("Quality", sal_Int32(1)) 975 }; 976 977 sal_uInt16 nFilterFormat = rFilter.GetExportFormatNumberForShortName( gURL.GetFileExtension() ); 978 rFilter.ExportGraphic( aScaledGraphic, gURL , nFilterFormat, &aFilterData ); 979 GalleryExplorer::InsertURL( GALLERY_THEME_BULLETS, aUserGalleryURL ); 980 981 aGrfNames.push_back(aUserGalleryURL); 982 size_t i = 0; 983 for (auto & grfName : aGrfNames) 984 { 985 m_xExamplesVS->InsertItem( i + 1, i); 986 INetURLObject aObj(grfName); 987 if (aObj.GetProtocol() == INetProtocol::File) 988 { 989 // tdf#114070 - only show the last name of the filename without its extension 990 aObj.removeExtension(); 991 grfName = aObj.GetLastName(INetURLObject::DecodeMechanism::Unambiguous); 992 } 993 m_xExamplesVS->SetItemText( i + 1, grfName ); 994 ++i; 995 } 996 997 if(aGrfNames.empty()) 998 { 999 m_xErrorText->show(); 1000 } 1001 else 1002 { 1003 m_xExamplesVS->Show(); 1004 m_xExamplesVS->SetFormat(); 1005 } 1006 } 1007 1008 // tabpage numbering options 1009 SvxNumOptionsTabPage::SvxNumOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, 1010 const SfxItemSet& rSet) 1011 : SfxTabPage(pPage, pController, "cui/ui/numberingoptionspage.ui", "NumberingOptionsPage", &rSet) 1012 , aInvalidateTimer("cui SvxNumOptionsTabPage aInvalidateTimer") 1013 , m_pLevelHdlEvent(nullptr) 1014 , bLastWidthModified(false) 1015 , bModified(false) 1016 , bPreset(false) 1017 , bAutomaticCharStyles(true) 1018 , bHTMLMode(false) 1019 , nBullet(0xff) 1020 , nActNumLvl(1) 1021 , nNumItemId(SID_ATTR_NUMBERING_RULE) 1022 , m_xGrid(m_xBuilder->weld_widget("grid2")) 1023 , m_xLevelLB(m_xBuilder->weld_tree_view("levellb")) 1024 , m_xFmtLB(m_xBuilder->weld_combo_box("numfmtlb")) 1025 , m_xSeparatorFT(m_xBuilder->weld_label("separator")) 1026 , m_xPrefixFT(m_xBuilder->weld_label("prefixft")) 1027 , m_xPrefixED(m_xBuilder->weld_entry("prefix")) 1028 , m_xSuffixFT(m_xBuilder->weld_label("suffixft")) 1029 , m_xSuffixED(m_xBuilder->weld_entry("suffix")) 1030 , m_xCharFmtFT(m_xBuilder->weld_label("charstyleft")) 1031 , m_xCharFmtLB(m_xBuilder->weld_combo_box("charstyle")) 1032 , m_xBulColorFT(m_xBuilder->weld_label("colorft")) 1033 , m_xBulColLB(new ColorListBox(m_xBuilder->weld_menu_button("color"), 1034 [this]{ return GetDialogController()->getDialog(); })) 1035 , m_xBulRelSizeFT(m_xBuilder->weld_label("relsizeft")) 1036 , m_xBulRelSizeMF(m_xBuilder->weld_metric_spin_button("relsize", FieldUnit::PERCENT)) 1037 , m_xAllLevelFT(m_xBuilder->weld_label("sublevelsft")) 1038 , m_xAllLevelNF(m_xBuilder->weld_spin_button("sublevels")) 1039 , m_xStartFT(m_xBuilder->weld_label("startatft")) 1040 , m_xStartED(m_xBuilder->weld_spin_button("startat")) 1041 , m_xBulletFT(m_xBuilder->weld_label("bulletft")) 1042 , m_xBulletPB(m_xBuilder->weld_button("bullet")) 1043 , m_xBitmapFT(m_xBuilder->weld_label("bitmapft")) 1044 , m_xBitmapMB(m_xBuilder->weld_menu_button("bitmap")) 1045 , m_xWidthFT(m_xBuilder->weld_label("widthft")) 1046 , m_xWidthMF(m_xBuilder->weld_metric_spin_button("widthmf", FieldUnit::CM)) 1047 , m_xHeightFT(m_xBuilder->weld_label("heightft")) 1048 , m_xHeightMF(m_xBuilder->weld_metric_spin_button("heightmf", FieldUnit::CM)) 1049 , m_xRatioCB(m_xBuilder->weld_check_button("keepratio")) 1050 , m_xOrientFT(m_xBuilder->weld_label("orientft")) 1051 , m_xOrientLB(m_xBuilder->weld_combo_box("orientlb")) 1052 , m_xAllLevelsFrame(m_xBuilder->weld_widget("levelsframe")) 1053 , m_xSameLevelCB(m_xBuilder->weld_check_button("allsame")) 1054 , m_xPreviewWIN(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWIN)) 1055 { 1056 m_xBulColLB->SetSlotId(SID_ATTR_CHAR_COLOR); 1057 m_xBulRelSizeMF->set_min(SVX_NUM_REL_SIZE_MIN, FieldUnit::PERCENT); 1058 m_xBulRelSizeMF->set_increments(5, 50, FieldUnit::PERCENT); 1059 SetExchangeSupport(); 1060 aActBulletFont = lcl_GetDefaultBulletFont(); 1061 1062 m_xBulletPB->connect_clicked(LINK(this, SvxNumOptionsTabPage, BulletHdl_Impl)); 1063 m_xFmtLB->connect_changed(LINK(this, SvxNumOptionsTabPage, NumberTypeSelectHdl_Impl)); 1064 m_xBitmapMB->connect_selected(LINK(this, SvxNumOptionsTabPage, GraphicHdl_Impl)); 1065 m_xBitmapMB->connect_toggled(LINK(this, SvxNumOptionsTabPage, PopupActivateHdl_Impl)); 1066 m_xLevelLB->set_selection_mode(SelectionMode::Multiple); 1067 m_xLevelLB->connect_changed(LINK(this, SvxNumOptionsTabPage, LevelHdl_Impl)); 1068 m_xCharFmtLB->connect_changed(LINK(this, SvxNumOptionsTabPage, CharFmtHdl_Impl)); 1069 m_xWidthMF->connect_value_changed(LINK(this, SvxNumOptionsTabPage, SizeHdl_Impl)); 1070 m_xHeightMF->connect_value_changed(LINK(this, SvxNumOptionsTabPage, SizeHdl_Impl)); 1071 m_xRatioCB->connect_toggled(LINK(this, SvxNumOptionsTabPage, RatioHdl_Impl)); 1072 m_xStartED->connect_value_changed(LINK(this, SvxNumOptionsTabPage, SpinModifyHdl_Impl)); 1073 m_xPrefixED->connect_changed(LINK(this, SvxNumOptionsTabPage, EditModifyHdl_Impl)); 1074 m_xSuffixED->connect_changed(LINK(this, SvxNumOptionsTabPage, EditModifyHdl_Impl)); 1075 m_xAllLevelNF->connect_value_changed(LINK(this,SvxNumOptionsTabPage, AllLevelHdl_Impl)); 1076 m_xOrientLB->connect_changed(LINK(this, SvxNumOptionsTabPage, OrientHdl_Impl)); 1077 m_xSameLevelCB->connect_toggled(LINK(this, SvxNumOptionsTabPage, SameLevelHdl_Impl)); 1078 m_xBulRelSizeMF->connect_value_changed(LINK(this,SvxNumOptionsTabPage, BulRelSizeHdl_Impl)); 1079 m_xBulColLB->SetSelectHdl(LINK(this, SvxNumOptionsTabPage, BulColorHdl_Impl)); 1080 aInvalidateTimer.SetInvokeHandler(LINK(this, SvxNumOptionsTabPage, PreviewInvalidateHdl_Impl)); 1081 aInvalidateTimer.SetTimeout(50); 1082 1083 eCoreUnit = rSet.GetPool()->GetMetric(rSet.GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE)); 1084 1085 // Fill ListBox with predefined / translated numbering types. 1086 sal_uInt32 nCount = SvxNumberingTypeTable::Count(); 1087 for (sal_uInt32 i = 0; i < nCount; ++i) 1088 { 1089 m_xFmtLB->append(OUString::number(SvxNumberingTypeTable::GetValue(i)), SvxNumberingTypeTable::GetString(i)); 1090 } 1091 1092 // Get advanced numbering types from the component. 1093 // Watch out for the ugly 1094 // 136 == 0x88 == SVX_NUM_BITMAP|0x80 == SVX_NUM_BITMAP|LINK_TOKEN 1095 // to not remove that. 1096 SvxNumOptionsTabPageHelper::GetI18nNumbering( *m_xFmtLB, (SVX_NUM_BITMAP | LINK_TOKEN)); 1097 1098 m_xFmtLB->set_active(0); 1099 1100 m_xCharFmtLB->set_size_request(m_xCharFmtLB->get_approximate_digit_width() * 10, -1); 1101 Size aSize(m_xGrid->get_preferred_size()); 1102 m_xGrid->set_size_request(aSize.Width(), -1); 1103 } 1104 1105 SvxNumOptionsTabPage::~SvxNumOptionsTabPage() 1106 { 1107 m_xPreviewWIN.reset(); 1108 m_xBulColLB.reset(); 1109 pActNum.reset(); 1110 pSaveNum.reset(); 1111 if (m_pLevelHdlEvent) 1112 { 1113 Application::RemoveUserEvent(m_pLevelHdlEvent); 1114 m_pLevelHdlEvent = nullptr; 1115 } 1116 } 1117 1118 void SvxNumOptionsTabPage::SetMetric(FieldUnit eMetric) 1119 { 1120 if(eMetric == FieldUnit::MM) 1121 { 1122 m_xWidthMF->set_digits(1); 1123 m_xHeightMF->set_digits(1); 1124 } 1125 m_xWidthMF->set_unit(eMetric); 1126 m_xHeightMF->set_unit(eMetric); 1127 } 1128 1129 std::unique_ptr<SfxTabPage> SvxNumOptionsTabPage::Create(weld::Container* pPage, weld::DialogController* pController, 1130 const SfxItemSet* rAttrSet) 1131 { 1132 return std::make_unique<SvxNumOptionsTabPage>(pPage, pController, *rAttrSet); 1133 }; 1134 1135 void SvxNumOptionsTabPage::ActivatePage(const SfxItemSet& rSet) 1136 { 1137 const SfxItemSet* pExampleSet = GetDialogExampleSet(); 1138 sal_uInt16 nTmpNumLvl = 1; 1139 if(pExampleSet) 1140 { 1141 if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false)) 1142 bPreset = pPresetItem->GetValue(); 1143 if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false)) 1144 nTmpNumLvl = pLevelItem->GetValue(); 1145 } 1146 if(const SvxNumBulletItem* pBulletItem = rSet.GetItemIfSet(nNumItemId, false)) 1147 { 1148 pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) ); 1149 } 1150 1151 bModified = (!pActNum->Get( 0 ) || bPreset); 1152 if(*pActNum == *pSaveNum && nActNumLvl == nTmpNumLvl) 1153 return; 1154 1155 nActNumLvl = nTmpNumLvl; 1156 sal_uInt16 nMask = 1; 1157 m_xLevelLB->unselect_all(); 1158 if (nActNumLvl == SAL_MAX_UINT16) 1159 m_xLevelLB->select(pActNum->GetLevelCount()); 1160 if(nActNumLvl != SAL_MAX_UINT16) 1161 { 1162 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) 1163 { 1164 if(nActNumLvl & nMask) 1165 m_xLevelLB->select(i); 1166 nMask <<= 1 ; 1167 } 1168 } 1169 *pActNum = *pSaveNum; 1170 1171 InitControls(); 1172 } 1173 1174 DeactivateRC SvxNumOptionsTabPage::DeactivatePage(SfxItemSet * _pSet) 1175 { 1176 if(_pSet) 1177 FillItemSet(_pSet); 1178 return DeactivateRC::LeavePage; 1179 } 1180 1181 bool SvxNumOptionsTabPage::FillItemSet( SfxItemSet* rSet ) 1182 { 1183 rSet->Put(SfxUInt16Item(SID_PARAM_CUR_NUM_LEVEL, nActNumLvl)); 1184 if(bModified && pActNum) 1185 { 1186 *pSaveNum = *pActNum; 1187 rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId )); 1188 rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, false)); 1189 } 1190 return bModified; 1191 }; 1192 1193 void SvxNumOptionsTabPage::Reset( const SfxItemSet* rSet ) 1194 { 1195 // in Draw the item exists as WhichId, in Writer only as SlotId 1196 const SvxNumBulletItem* pBulletItem = 1197 rSet->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false); 1198 if(!pBulletItem) 1199 { 1200 nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE); 1201 pBulletItem = rSet->GetItemIfSet(nNumItemId, false); 1202 1203 if( !pBulletItem ) 1204 { 1205 pBulletItem = & rSet->Get( nNumItemId ); 1206 } 1207 } 1208 DBG_ASSERT(pBulletItem, "no item found!"); 1209 pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) ); 1210 1211 // insert levels 1212 if (!m_xLevelLB->n_children()) 1213 { 1214 for(sal_uInt16 i = 1; i <= pSaveNum->GetLevelCount(); i++) 1215 m_xLevelLB->append_text(OUString::number(i)); 1216 if(pSaveNum->GetLevelCount() > 1) 1217 { 1218 OUString sEntry = "1 - " + OUString::number( pSaveNum->GetLevelCount() ); 1219 m_xLevelLB->append_text(sEntry); 1220 m_xLevelLB->select_text(sEntry); 1221 } 1222 else 1223 m_xLevelLB->select(0); 1224 } 1225 else 1226 m_xLevelLB->select(m_xLevelLB->n_children() - 1); 1227 1228 sal_uInt16 nMask = 1; 1229 m_xLevelLB->unselect_all(); 1230 if (nActNumLvl == SAL_MAX_UINT16) 1231 { 1232 m_xLevelLB->select( pSaveNum->GetLevelCount() ); 1233 } 1234 else 1235 { 1236 for(sal_uInt16 i = 0; i < pSaveNum->GetLevelCount(); i++) 1237 { 1238 if(nActNumLvl & nMask) 1239 m_xLevelLB->select( i ); 1240 nMask <<= 1 ; 1241 } 1242 } 1243 1244 if(!pActNum) 1245 pActNum.reset( new SvxNumRule(*pSaveNum) ); 1246 else if(*pSaveNum != *pActNum) 1247 *pActNum = *pSaveNum; 1248 m_aPreviewWIN.SetNumRule(pActNum.get()); 1249 m_xSameLevelCB->set_active(pActNum->IsContinuousNumbering()); 1250 1251 const SfxUInt16Item* pHtmlModeItem = 1252 rSet->GetItemIfSet( SID_HTML_MODE, false ); 1253 if (!pHtmlModeItem) 1254 { 1255 if (SfxObjectShell* pShell = SfxObjectShell::Current()) 1256 pHtmlModeItem = pShell->GetItem( SID_HTML_MODE ); 1257 } 1258 if ( pHtmlModeItem ) 1259 { 1260 sal_uInt16 nHtmlMode = pHtmlModeItem->GetValue(); 1261 bHTMLMode = 0 != (nHtmlMode&HTMLMODE_ON); 1262 } 1263 1264 bool bCharFmt = pActNum->IsFeatureSupported(SvxNumRuleFlags::CHAR_STYLE); 1265 m_xCharFmtFT->set_visible(bCharFmt); 1266 m_xCharFmtLB->set_visible(bCharFmt); 1267 1268 bool bContinuous = pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS); 1269 1270 bool bAllLevel = bContinuous && !bHTMLMode; 1271 m_xAllLevelFT->set_visible(bAllLevel); 1272 m_xAllLevelNF->set_visible(bAllLevel); 1273 1274 m_xAllLevelsFrame->set_visible(bContinuous); 1275 1276 // again misusage: in Draw there is numeration only until the bitmap 1277 // without SVX_NUM_NUMBER_NONE 1278 //remove types that are unsupported by Draw/Impress 1279 if(!bContinuous) 1280 { 1281 sal_Int32 nFmtCount = m_xFmtLB->get_count(); 1282 for(sal_Int32 i = nFmtCount; i; i--) 1283 { 1284 sal_uInt16 nEntryData = m_xFmtLB->get_id(i - 1).toUInt32(); 1285 if(/*SVX_NUM_NUMBER_NONE == nEntryData ||*/ 1286 (SVX_NUM_BITMAP|LINK_TOKEN) == nEntryData) 1287 m_xFmtLB->remove(i - 1); 1288 } 1289 } 1290 //one must be enabled 1291 if(!pActNum->IsFeatureSupported(SvxNumRuleFlags::ENABLE_LINKED_BMP)) 1292 { 1293 auto nPos = m_xFmtLB->find_id(OUString::number(SVX_NUM_BITMAP|LINK_TOKEN)); 1294 if (nPos != -1) 1295 m_xFmtLB->remove(nPos); 1296 } 1297 else if(!pActNum->IsFeatureSupported(SvxNumRuleFlags::ENABLE_EMBEDDED_BMP)) 1298 { 1299 auto nPos = m_xFmtLB->find_id(OUString::number(SVX_NUM_BITMAP)); 1300 if (nPos != -1) 1301 m_xFmtLB->remove(nPos); 1302 } 1303 1304 // MegaHack: because of a not-fixable 'design mistake/error' in Impress 1305 // delete all kinds of numeric enumerations 1306 if(pActNum->IsFeatureSupported(SvxNumRuleFlags::NO_NUMBERS)) 1307 { 1308 sal_Int32 nFmtCount = m_xFmtLB->get_count(); 1309 for(sal_Int32 i = nFmtCount; i; i--) 1310 { 1311 sal_uInt16 nEntryData = m_xFmtLB->get_id(i - 1).toUInt32(); 1312 if( /*nEntryData >= SVX_NUM_CHARS_UPPER_LETTER &&*/ nEntryData <= SVX_NUM_NUMBER_NONE) 1313 m_xFmtLB->remove(i - 1); 1314 } 1315 } 1316 1317 InitControls(); 1318 bModified = false; 1319 } 1320 1321 void SvxNumOptionsTabPage::InitControls() 1322 { 1323 bool bShowBullet = true; 1324 bool bShowBitmap = true; 1325 bool bSameType = true; 1326 bool bSameStart = true; 1327 bool bSamePrefix = true; 1328 bool bSameSuffix = true; 1329 bool bAllLevel = true; 1330 bool bSameCharFmt = true; 1331 bool bSameVOrient = true; 1332 bool bSameSize = true; 1333 bool bSameBulColor = true; 1334 bool bSameBulRelSize= true; 1335 1336 const SvxNumberFormat* aNumFmtArr[SVX_MAX_NUM]; 1337 OUString sFirstCharFmt; 1338 sal_Int16 eFirstOrient = text::VertOrientation::NONE; 1339 Size aFirstSize(0,0); 1340 sal_uInt16 nMask = 1; 1341 sal_uInt16 nLvl = SAL_MAX_UINT16; 1342 sal_uInt16 nHighestLevel = 0; 1343 1344 bool bBullColor = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_COLOR); 1345 bool bBullRelSize = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_REL_SIZE); 1346 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) 1347 { 1348 if(nActNumLvl & nMask) 1349 { 1350 aNumFmtArr[i] = &pActNum->GetLevel(i); 1351 bShowBullet &= aNumFmtArr[i]->GetNumberingType() == SVX_NUM_CHAR_SPECIAL; 1352 bShowBitmap &= (aNumFmtArr[i]->GetNumberingType()&(~LINK_TOKEN)) == SVX_NUM_BITMAP; 1353 if(SAL_MAX_UINT16 == nLvl) 1354 { 1355 nLvl = i; 1356 sFirstCharFmt = aNumFmtArr[i]->GetCharFormatName(); 1357 eFirstOrient = aNumFmtArr[i]->GetVertOrient(); 1358 if(bShowBitmap) 1359 aFirstSize = aNumFmtArr[i]->GetGraphicSize(); 1360 } 1361 if( i > nLvl) 1362 { 1363 bSameType &= aNumFmtArr[i]->GetNumberingType() == aNumFmtArr[nLvl]->GetNumberingType(); 1364 bSameStart = aNumFmtArr[i]->GetStart() == aNumFmtArr[nLvl]->GetStart(); 1365 1366 bSamePrefix = aNumFmtArr[i]->GetPrefix() == aNumFmtArr[nLvl]->GetPrefix(); 1367 bSameSuffix = aNumFmtArr[i]->GetSuffix() == aNumFmtArr[nLvl]->GetSuffix(); 1368 bAllLevel &= aNumFmtArr[i]->GetIncludeUpperLevels() == aNumFmtArr[nLvl]->GetIncludeUpperLevels(); 1369 bSameCharFmt &= sFirstCharFmt == aNumFmtArr[i]->GetCharFormatName(); 1370 bSameVOrient &= eFirstOrient == aNumFmtArr[i]->GetVertOrient(); 1371 if(bShowBitmap && bSameSize) 1372 bSameSize &= aNumFmtArr[i]->GetGraphicSize() == aFirstSize; 1373 bSameBulColor &= aNumFmtArr[i]->GetBulletColor() == aNumFmtArr[nLvl]->GetBulletColor(); 1374 bSameBulRelSize &= aNumFmtArr[i]->GetBulletRelSize() == aNumFmtArr[nLvl]->GetBulletRelSize(); 1375 } 1376 nHighestLevel = i; 1377 } 1378 else 1379 aNumFmtArr[i] = nullptr; 1380 1381 nMask <<= 1 ; 1382 } 1383 SwitchNumberType(bShowBullet ? 1 : bShowBitmap ? 2 : 0); 1384 1385 sal_uInt16 nNumberingType; 1386 if (nLvl != SAL_MAX_UINT16) 1387 nNumberingType = aNumFmtArr[nLvl]->GetNumberingType(); 1388 else 1389 { 1390 nNumberingType = SVX_NUM_NUMBER_NONE; 1391 bAllLevel = false; 1392 bSameBulRelSize = false; 1393 bSameBulColor = false; 1394 bSameStart = false; 1395 bSamePrefix = false; 1396 bSameSuffix = false; 1397 } 1398 1399 CheckForStartValue_Impl(nNumberingType); 1400 1401 if(bShowBitmap) 1402 { 1403 if(!bSameVOrient || eFirstOrient == text::VertOrientation::NONE) 1404 m_xOrientLB->set_active(-1); 1405 else 1406 m_xOrientLB->set_active( 1407 sal::static_int_cast< sal_Int32 >(eFirstOrient - 1)); 1408 // no text::VertOrientation::NONE 1409 1410 if(bSameSize) 1411 { 1412 SetMetricValue(*m_xHeightMF, aFirstSize.Height(), eCoreUnit); 1413 SetMetricValue(*m_xWidthMF, aFirstSize.Width(), eCoreUnit); 1414 } 1415 else 1416 { 1417 m_xHeightMF->set_text(""); 1418 m_xWidthMF->set_text(""); 1419 } 1420 } 1421 1422 if(bSameType) 1423 { 1424 sal_uInt16 nLBData = nNumberingType; 1425 m_xFmtLB->set_active_id(OUString::number(nLBData)); 1426 } 1427 else 1428 m_xFmtLB->set_active(-1); 1429 1430 m_xAllLevelNF->set_sensitive(nHighestLevel > 0 && !m_xSameLevelCB->get_active()); 1431 m_xAllLevelNF->set_max(nHighestLevel + 1); 1432 if(bAllLevel) 1433 { 1434 m_xAllLevelNF->set_value(aNumFmtArr[nLvl]->GetIncludeUpperLevels()); 1435 } 1436 else 1437 { 1438 m_xAllLevelNF->set_text(""); 1439 } 1440 1441 if(bBullRelSize) 1442 { 1443 if(bSameBulRelSize) 1444 m_xBulRelSizeMF->set_value(aNumFmtArr[nLvl]->GetBulletRelSize(), FieldUnit::PERCENT); 1445 else 1446 m_xBulRelSizeMF->set_text(""); 1447 } 1448 if(bBullColor) 1449 { 1450 if(bSameBulColor) 1451 m_xBulColLB->SelectEntry(aNumFmtArr[nLvl]->GetBulletColor()); 1452 else 1453 m_xBulColLB->SetNoSelection(); 1454 } 1455 switch(nBullet) 1456 { 1457 case SHOW_NUMBERING: 1458 if(bSameStart) 1459 { 1460 m_xStartED->set_value(aNumFmtArr[nLvl]->GetStart()); 1461 } 1462 else 1463 m_xStartED->set_text(""); 1464 break; 1465 case SHOW_BULLET: 1466 break; 1467 case SHOW_BITMAP: 1468 break; 1469 } 1470 1471 if(bSamePrefix) 1472 m_xPrefixED->set_text(aNumFmtArr[nLvl]->GetPrefix()); 1473 else 1474 m_xPrefixED->set_text(""); 1475 if(bSameSuffix) 1476 m_xSuffixED->set_text(aNumFmtArr[nLvl]->GetSuffix()); 1477 else 1478 m_xSuffixED->set_text(""); 1479 1480 if(bSameCharFmt) 1481 { 1482 if (!sFirstCharFmt.isEmpty()) 1483 m_xCharFmtLB->set_active_text(sFirstCharFmt); 1484 else 1485 m_xCharFmtLB->set_active(0); 1486 } 1487 else 1488 m_xCharFmtLB->set_active(-1); 1489 1490 m_aPreviewWIN.SetLevel(nActNumLvl); 1491 m_aPreviewWIN.Invalidate(); 1492 } 1493 1494 // 0 - Number; 1 - Bullet; 2 - Bitmap 1495 void SvxNumOptionsTabPage::SwitchNumberType( sal_uInt8 nType ) 1496 { 1497 if(nBullet == nType) 1498 return; 1499 nBullet = nType; 1500 bool bBullet = (nType == SHOW_BULLET); 1501 bool bBitmap = (nType == SHOW_BITMAP); 1502 bool bEnableBitmap = (nType == SHOW_BITMAP); 1503 bool bNumeric = !(bBitmap||bBullet); 1504 m_xSeparatorFT->set_visible(bNumeric); 1505 m_xPrefixFT->set_visible(bNumeric); 1506 m_xPrefixED->set_visible(bNumeric); 1507 m_xSuffixFT->set_visible(bNumeric); 1508 m_xSuffixED->set_visible(bNumeric); 1509 1510 bool bCharFmt = pActNum->IsFeatureSupported(SvxNumRuleFlags::CHAR_STYLE); 1511 m_xCharFmtFT->set_visible(!bBitmap && bCharFmt); 1512 m_xCharFmtLB->set_visible(!bBitmap && bCharFmt); 1513 1514 // this is rather misusage, as there is no own flag 1515 // for complete numeration 1516 bool bAllLevelFeature = pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS); 1517 bool bAllLevel = bNumeric && bAllLevelFeature && !bHTMLMode; 1518 m_xAllLevelFT->set_visible(bAllLevel); 1519 m_xAllLevelNF->set_visible(bAllLevel); 1520 1521 m_xStartFT->set_visible(!(bBullet||bBitmap)); 1522 m_xStartED->set_visible(!(bBullet||bBitmap)); 1523 1524 m_xBulletFT->set_visible(bBullet); 1525 m_xBulletPB->set_visible(bBullet); 1526 bool bBullColor = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_COLOR); 1527 m_xBulColorFT->set_visible(!bBitmap && bBullColor); 1528 m_xBulColLB->set_visible(!bBitmap && bBullColor); 1529 bool bBullResSize = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_REL_SIZE); 1530 m_xBulRelSizeFT->set_visible(!bBitmap && bBullResSize); 1531 m_xBulRelSizeMF->set_visible(!bBitmap && bBullResSize); 1532 1533 m_xBitmapFT->set_visible(bBitmap); 1534 m_xBitmapMB->set_visible(bBitmap); 1535 1536 m_xWidthFT->set_visible(bBitmap); 1537 m_xWidthMF->set_visible(bBitmap); 1538 m_xHeightFT->set_visible(bBitmap); 1539 m_xHeightMF->set_visible(bBitmap); 1540 m_xRatioCB->set_visible(bBitmap); 1541 1542 m_xOrientFT->set_visible(bBitmap && bAllLevelFeature); 1543 m_xOrientLB->set_visible(bBitmap && bAllLevelFeature); 1544 1545 m_xWidthFT->set_sensitive(bEnableBitmap); 1546 m_xWidthMF->set_sensitive(bEnableBitmap); 1547 m_xHeightFT->set_sensitive(bEnableBitmap); 1548 m_xHeightMF->set_sensitive(bEnableBitmap); 1549 m_xRatioCB->set_sensitive(bEnableBitmap); 1550 m_xOrientFT->set_sensitive(bEnableBitmap); 1551 m_xOrientLB->set_sensitive(bEnableBitmap); 1552 } 1553 1554 IMPL_LINK_NOARG(SvxNumOptionsTabPage, LevelHdl_Impl, weld::TreeView&, void) 1555 { 1556 if (m_pLevelHdlEvent) 1557 return; 1558 // tdf#127112 (borrowing tdf#127120 solution) multiselection may be implemented by deselect follow by select so 1559 // fire off the handler to happen on next event loop and only process the 1560 // final state 1561 m_pLevelHdlEvent = Application::PostUserEvent(LINK(this, SvxNumOptionsTabPage, LevelHdl)); 1562 } 1563 1564 IMPL_LINK_NOARG(SvxNumOptionsTabPage, LevelHdl, void*, void) 1565 { 1566 m_pLevelHdlEvent = nullptr; 1567 1568 sal_uInt16 nSaveNumLvl = nActNumLvl; 1569 nActNumLvl = 0; 1570 std::vector<int> aSelectedRows = m_xLevelLB->get_selected_rows(); 1571 if (std::find(aSelectedRows.begin(), aSelectedRows.end(), pActNum->GetLevelCount()) != aSelectedRows.end() && 1572 (aSelectedRows.size() == 1 || nSaveNumLvl != 0xffff)) 1573 { 1574 nActNumLvl = 0xFFFF; 1575 for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ ) 1576 m_xLevelLB->unselect(i); 1577 } 1578 else if (!aSelectedRows.empty()) 1579 { 1580 sal_uInt16 nMask = 1; 1581 for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ ) 1582 { 1583 if (std::find(aSelectedRows.begin(), aSelectedRows.end(), i) != aSelectedRows.end()) 1584 nActNumLvl |= nMask; 1585 nMask <<= 1; 1586 } 1587 m_xLevelLB->unselect(pActNum->GetLevelCount()); 1588 } 1589 else 1590 { 1591 nActNumLvl = nSaveNumLvl; 1592 sal_uInt16 nMask = 1; 1593 for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ ) 1594 { 1595 if(nActNumLvl & nMask) 1596 { 1597 m_xLevelLB->select(i); 1598 break; 1599 } 1600 nMask <<=1; 1601 } 1602 } 1603 InitControls(); 1604 } 1605 1606 IMPL_LINK_NOARG(SvxNumOptionsTabPage, PreviewInvalidateHdl_Impl, Timer *, void) 1607 { 1608 m_aPreviewWIN.Invalidate(); 1609 } 1610 1611 IMPL_LINK(SvxNumOptionsTabPage, AllLevelHdl_Impl, weld::SpinButton&, rBox, void) 1612 { 1613 sal_uInt16 nMask = 1; 1614 for(sal_uInt16 e = 0; e < pActNum->GetLevelCount(); e++) 1615 { 1616 if(nActNumLvl & nMask) 1617 { 1618 SvxNumberFormat aNumFmt(pActNum->GetLevel(e)); 1619 aNumFmt.SetIncludeUpperLevels(static_cast<sal_uInt8>(std::min(rBox.get_value(), sal_Int64(e + 1))) ); 1620 // Set the same prefix/suffix to generate list format with changed IncludedUpperLevels 1621 aNumFmt.SetListFormat(aNumFmt.GetPrefix(), aNumFmt.GetSuffix(), e); 1622 pActNum->SetLevel(e, aNumFmt); 1623 } 1624 nMask <<= 1; 1625 } 1626 SetModified(); 1627 } 1628 1629 IMPL_LINK(SvxNumOptionsTabPage, NumberTypeSelectHdl_Impl, weld::ComboBox&, rBox, void) 1630 { 1631 OUString sSelectStyle; 1632 bool bShowOrient = false; 1633 bool bBmp = false; 1634 sal_uInt16 nMask = 1; 1635 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) 1636 { 1637 if(nActNumLvl & nMask) 1638 { 1639 SvxNumberFormat aNumFmt(pActNum->GetLevel(i)); 1640 // PAGEDESC does not exist 1641 SvxNumType nNumType = static_cast<SvxNumType>(rBox.get_active_id().toUInt32()); 1642 aNumFmt.SetNumberingType(nNumType); 1643 sal_uInt16 nNumberingType = aNumFmt.GetNumberingType(); 1644 if(SVX_NUM_BITMAP == (nNumberingType&(~LINK_TOKEN))) 1645 { 1646 bBmp |= nullptr != aNumFmt.GetBrush(); 1647 aNumFmt.SetIncludeUpperLevels( 1 ); 1648 aNumFmt.SetListFormat("", "", i); 1649 if(!bBmp) 1650 aNumFmt.SetGraphic(""); 1651 pActNum->SetLevel(i, aNumFmt); 1652 SwitchNumberType(SHOW_BITMAP); 1653 bShowOrient = true; 1654 } 1655 else if( SVX_NUM_CHAR_SPECIAL == nNumberingType ) 1656 { 1657 aNumFmt.SetIncludeUpperLevels( 1 ); 1658 aNumFmt.SetListFormat("", "", i); 1659 if( !aNumFmt.GetBulletFont() ) 1660 aNumFmt.SetBulletFont(&aActBulletFont); 1661 if( !aNumFmt.GetBulletChar() ) 1662 aNumFmt.SetBulletChar( SVX_DEF_BULLET ); 1663 pActNum->SetLevel(i, aNumFmt); 1664 SwitchNumberType(SHOW_BULLET); 1665 // allocation of the drawing pattern is automatic 1666 if(bAutomaticCharStyles) 1667 { 1668 sSelectStyle = m_sBulletCharFormatName; 1669 } 1670 } 1671 else 1672 { 1673 aNumFmt.SetListFormat(m_xPrefixED->get_text(), m_xSuffixED->get_text(), i); 1674 1675 SwitchNumberType(SHOW_NUMBERING); 1676 pActNum->SetLevel(i, aNumFmt); 1677 CheckForStartValue_Impl(nNumberingType); 1678 1679 // allocation of the drawing pattern is automatic 1680 if(bAutomaticCharStyles) 1681 { 1682 sSelectStyle = m_sNumCharFmtName; 1683 } 1684 } 1685 } 1686 nMask <<= 1; 1687 } 1688 bool bAllLevelFeature = pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS); 1689 if(bShowOrient && bAllLevelFeature) 1690 { 1691 m_xOrientFT->show(); 1692 m_xOrientLB->show(); 1693 } 1694 else 1695 { 1696 m_xOrientFT->hide(); 1697 m_xOrientLB->hide(); 1698 } 1699 SetModified(); 1700 if(!sSelectStyle.isEmpty()) 1701 { 1702 m_xCharFmtLB->set_active_text(sSelectStyle); 1703 CharFmtHdl_Impl(*m_xCharFmtLB); 1704 bAutomaticCharStyles = true; 1705 } 1706 } 1707 1708 void SvxNumOptionsTabPage::CheckForStartValue_Impl(sal_uInt16 nNumberingType) 1709 { 1710 bool bIsNull = m_xStartED->get_value() == 0; 1711 bool bNoZeroAllowed = nNumberingType < SVX_NUM_ARABIC || 1712 SVX_NUM_CHARS_UPPER_LETTER_N == nNumberingType || 1713 SVX_NUM_CHARS_LOWER_LETTER_N == nNumberingType; 1714 m_xStartED->set_min(bNoZeroAllowed ? 1 : 0); 1715 if (bIsNull && bNoZeroAllowed) 1716 EditModifyHdl_Impl(*m_xStartED); 1717 } 1718 1719 IMPL_LINK(SvxNumOptionsTabPage, OrientHdl_Impl, weld::ComboBox&, rBox, void) 1720 { 1721 sal_Int32 nPos = rBox.get_active(); 1722 nPos ++; // no VERT_NONE 1723 1724 sal_uInt16 nMask = 1; 1725 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) 1726 { 1727 if(nActNumLvl & nMask) 1728 { 1729 SvxNumberFormat aNumFmt(pActNum->GetLevel(i)); 1730 if(SVX_NUM_BITMAP == (aNumFmt.GetNumberingType()&(~LINK_TOKEN))) 1731 { 1732 const SvxBrushItem* pBrushItem = aNumFmt.GetBrush(); 1733 const Size& rSize = aNumFmt.GetGraphicSize(); 1734 sal_Int16 eOrient = static_cast<sal_Int16>(nPos); 1735 aNumFmt.SetGraphicBrush( pBrushItem, &rSize, &eOrient ); 1736 pActNum->SetLevel(i, aNumFmt); 1737 } 1738 } 1739 nMask <<= 1; 1740 } 1741 SetModified(false); 1742 } 1743 1744 IMPL_LINK(SvxNumOptionsTabPage, SameLevelHdl_Impl, weld::Toggleable&, rBox, void) 1745 { 1746 bool bSet = rBox.get_active(); 1747 pActNum->SetContinuousNumbering(bSet); 1748 bool bRepaint = false; 1749 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) 1750 { 1751 SvxNumberFormat aNumFmt(pActNum->GetLevel(i)); 1752 if(aNumFmt.GetNumberingType() != SVX_NUM_NUMBER_NONE) 1753 { 1754 bRepaint = true; 1755 break; 1756 } 1757 } 1758 SetModified(bRepaint); 1759 InitControls(); 1760 } 1761 1762 IMPL_LINK(SvxNumOptionsTabPage, BulColorHdl_Impl, ColorListBox&, rColorBox, void) 1763 { 1764 Color nSetColor = rColorBox.GetSelectEntryColor(); 1765 1766 sal_uInt16 nMask = 1; 1767 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) 1768 { 1769 if(nActNumLvl & nMask) 1770 { 1771 SvxNumberFormat aNumFmt(pActNum->GetLevel(i)); 1772 aNumFmt.SetBulletColor(nSetColor); 1773 pActNum->SetLevel(i, aNumFmt); 1774 } 1775 nMask <<= 1; 1776 } 1777 SetModified(); 1778 } 1779 1780 IMPL_LINK(SvxNumOptionsTabPage, BulRelSizeHdl_Impl, weld::MetricSpinButton&, rField, void) 1781 { 1782 sal_uInt16 nRelSize = rField.get_value(FieldUnit::PERCENT); 1783 1784 sal_uInt16 nMask = 1; 1785 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) 1786 { 1787 if(nActNumLvl & nMask) 1788 { 1789 SvxNumberFormat aNumFmt(pActNum->GetLevel(i)); 1790 aNumFmt.SetBulletRelSize(nRelSize); 1791 pActNum->SetLevel(i, aNumFmt); 1792 } 1793 nMask <<= 1; 1794 } 1795 SetModified(); 1796 } 1797 1798 IMPL_LINK(SvxNumOptionsTabPage, GraphicHdl_Impl, const OString&, rIdent, void) 1799 { 1800 OUString aGrfName; 1801 Size aSize; 1802 bool bSucc(false); 1803 SvxOpenGraphicDialog aGrfDlg(CuiResId(RID_CUISTR_EDIT_GRAPHIC), GetFrameWeld()); 1804 1805 OString sNumber; 1806 if (rIdent.startsWith("gallery", &sNumber)) 1807 { 1808 auto idx = sNumber.toUInt32(); 1809 if (idx < aGrfNames.size()) 1810 { 1811 aGrfName = aGrfNames[idx]; 1812 Graphic aGraphic; 1813 if(GalleryExplorer::GetGraphicObj( GALLERY_THEME_BULLETS, idx, &aGraphic)) 1814 { 1815 aSize = SvxNumberFormat::GetGraphicSizeMM100(&aGraphic); 1816 bSucc = true; 1817 } 1818 } 1819 } 1820 else if (rIdent == "fromfile") 1821 { 1822 aGrfDlg.EnableLink( false ); 1823 aGrfDlg.AsLink( false ); 1824 if ( !aGrfDlg.Execute() ) 1825 { 1826 // memorize selected filter 1827 aGrfName = aGrfDlg.GetPath(); 1828 1829 Graphic aGraphic; 1830 if( !aGrfDlg.GetGraphic(aGraphic) ) 1831 { 1832 aSize = SvxNumberFormat::GetGraphicSizeMM100(&aGraphic); 1833 bSucc = true; 1834 } 1835 } 1836 } 1837 if(!bSucc) 1838 return; 1839 1840 aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(eCoreUnit)); 1841 1842 sal_uInt16 nMask = 1; 1843 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) 1844 { 1845 if(nActNumLvl & nMask) 1846 { 1847 SvxNumberFormat aNumFmt(pActNum->GetLevel(i)); 1848 aNumFmt.SetCharFormatName(m_sNumCharFmtName); 1849 aNumFmt.SetGraphic(aGrfName); 1850 1851 // set size for a later comparison 1852 const SvxBrushItem* pBrushItem = aNumFmt.GetBrush(); 1853 // initiate asynchronous loading 1854 sal_Int16 eOrient = aNumFmt.GetVertOrient(); 1855 aNumFmt.SetGraphicBrush( pBrushItem, &aSize, &eOrient ); 1856 aInitSize[i] = aNumFmt.GetGraphicSize(); 1857 1858 pActNum->SetLevel(i, aNumFmt); 1859 } 1860 nMask <<= 1; 1861 } 1862 m_xRatioCB->set_sensitive(true); 1863 m_xWidthFT->set_sensitive(true); 1864 m_xHeightFT->set_sensitive(true); 1865 m_xWidthMF->set_sensitive(true); 1866 m_xHeightMF->set_sensitive(true); 1867 SetMetricValue(*m_xWidthMF, aSize.Width(), eCoreUnit); 1868 SetMetricValue(*m_xHeightMF, aSize.Height(), eCoreUnit); 1869 m_xOrientFT->set_sensitive(true); 1870 m_xOrientLB->set_sensitive(true); 1871 SetModified(); 1872 //needed due to asynchronous loading of graphics in the SvxBrushItem 1873 aInvalidateTimer.Start(); 1874 } 1875 1876 IMPL_LINK_NOARG(SvxNumOptionsTabPage, PopupActivateHdl_Impl, weld::Toggleable&, void) 1877 { 1878 if (m_xGalleryMenu) 1879 return; 1880 1881 m_xGalleryMenu = m_xBuilder->weld_menu("gallerysubmenu"); 1882 weld::WaitObject aWait(GetFrameWeld()); 1883 1884 if (!GalleryExplorer::FillObjList(GALLERY_THEME_BULLETS, aGrfNames)) 1885 return; 1886 1887 GalleryExplorer::BeginLocking(GALLERY_THEME_BULLETS); 1888 1889 Graphic aGraphic; 1890 OUString sGrfName; 1891 ScopedVclPtrInstance< VirtualDevice > pVD; 1892 size_t i = 0; 1893 for (const auto & grfName : aGrfNames) 1894 { 1895 sGrfName = grfName; 1896 OUString sItemId = "gallery" + OUString::number(i); 1897 INetURLObject aObj(sGrfName); 1898 if (aObj.GetProtocol() == INetProtocol::File) 1899 { 1900 // tdf#141334 - only show the last name of the filename without its extension 1901 aObj.removeExtension(); 1902 sGrfName = aObj.GetLastName(INetURLObject::DecodeMechanism::Unambiguous); 1903 } 1904 if(GalleryExplorer::GetGraphicObj( GALLERY_THEME_BULLETS, i, &aGraphic)) 1905 { 1906 BitmapEx aBitmap(aGraphic.GetBitmapEx()); 1907 Size aSize(aBitmap.GetSizePixel()); 1908 if(aSize.Width() > MAX_BMP_WIDTH || 1909 aSize.Height() > MAX_BMP_HEIGHT) 1910 { 1911 bool bWidth = aSize.Width() > aSize.Height(); 1912 double nScale = bWidth ? 1913 double(MAX_BMP_WIDTH) / static_cast<double>(aSize.Width()): 1914 double(MAX_BMP_HEIGHT) / static_cast<double>(aSize.Height()); 1915 aBitmap.Scale(nScale, nScale); 1916 } 1917 pVD->SetOutputSizePixel(aBitmap.GetSizePixel(), false); 1918 pVD->DrawBitmapEx(Point(), aBitmap); 1919 m_xGalleryMenu->append(sItemId, sGrfName, *pVD); 1920 } 1921 else 1922 { 1923 m_xGalleryMenu->append(sItemId, sGrfName); 1924 } 1925 ++i; 1926 } 1927 GalleryExplorer::EndLocking(GALLERY_THEME_BULLETS); 1928 } 1929 1930 IMPL_LINK_NOARG(SvxNumOptionsTabPage, BulletHdl_Impl, weld::Button&, void) 1931 { 1932 SvxCharacterMap aMap(GetFrameWeld(), nullptr, nullptr); 1933 1934 sal_uInt16 nMask = 1; 1935 std::optional<vcl::Font> pFmtFont; 1936 bool bSameBullet = true; 1937 sal_UCS4 cBullet = 0; 1938 bool bFirst = true; 1939 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) 1940 { 1941 if(nActNumLvl & nMask) 1942 { 1943 const SvxNumberFormat& rCurFmt = pActNum->GetLevel(i); 1944 if(bFirst) 1945 { 1946 cBullet = rCurFmt.GetBulletChar(); 1947 } 1948 else if(rCurFmt.GetBulletChar() != cBullet ) 1949 { 1950 bSameBullet = false; 1951 break; 1952 } 1953 if(!pFmtFont) 1954 pFmtFont = rCurFmt.GetBulletFont(); 1955 bFirst = false; 1956 } 1957 nMask <<= 1; 1958 1959 } 1960 1961 if (pFmtFont) 1962 aMap.SetCharFont(*pFmtFont); 1963 else 1964 aMap.SetCharFont(aActBulletFont); 1965 if (bSameBullet) 1966 aMap.SetChar(cBullet); 1967 if (aMap.run() != RET_OK) 1968 return; 1969 1970 // change Font Numrules 1971 aActBulletFont = aMap.GetCharFont(); 1972 1973 sal_uInt16 _nMask = 1; 1974 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) 1975 { 1976 if(nActNumLvl & _nMask) 1977 { 1978 SvxNumberFormat aNumFmt(pActNum->GetLevel(i)); 1979 aNumFmt.SetBulletFont(&aActBulletFont); 1980 aNumFmt.SetBulletChar(aMap.GetChar()); 1981 pActNum->SetLevel(i, aNumFmt); 1982 } 1983 _nMask <<= 1; 1984 } 1985 1986 SetModified(); 1987 } 1988 1989 IMPL_LINK( SvxNumOptionsTabPage, SizeHdl_Impl, weld::MetricSpinButton&, rField, void) 1990 { 1991 bool bWidth = &rField == m_xWidthMF.get(); 1992 bLastWidthModified = bWidth; 1993 bool bRatio = m_xRatioCB->get_active(); 1994 tools::Long nWidthVal = static_cast<tools::Long>(m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::MM_100TH))); 1995 tools::Long nHeightVal = static_cast<tools::Long>(m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::MM_100TH))); 1996 nWidthVal = OutputDevice::LogicToLogic( nWidthVal , 1997 MapUnit::Map100thMM, eCoreUnit ); 1998 nHeightVal = OutputDevice::LogicToLogic( nHeightVal, 1999 MapUnit::Map100thMM, eCoreUnit); 2000 double fSizeRatio; 2001 2002 bool bRepaint = false; 2003 sal_uInt16 nMask = 1; 2004 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) 2005 { 2006 if(nActNumLvl & nMask) 2007 { 2008 SvxNumberFormat aNumFmt(pActNum->GetLevel(i)); 2009 if(SVX_NUM_BITMAP == (aNumFmt.GetNumberingType()&(~LINK_TOKEN))) 2010 { 2011 Size aSize(aNumFmt.GetGraphicSize() ); 2012 Size aSaveSize(aSize); 2013 2014 if (aInitSize[i].Height()) 2015 fSizeRatio = static_cast<double>(aInitSize[i].Width()) / static_cast<double>(aInitSize[i].Height()); 2016 else 2017 fSizeRatio = double(1); 2018 2019 if(bWidth) 2020 { 2021 tools::Long nDelta = nWidthVal - aInitSize[i].Width(); 2022 aSize.setWidth( nWidthVal ); 2023 if (bRatio) 2024 { 2025 aSize.setHeight( aInitSize[i].Height() + static_cast<tools::Long>(static_cast<double>(nDelta) / fSizeRatio) ); 2026 m_xHeightMF->set_value(m_xHeightMF->normalize( 2027 OutputDevice::LogicToLogic( aSize.Height(), eCoreUnit, MapUnit::Map100thMM )), 2028 FieldUnit::MM_100TH); 2029 } 2030 } 2031 else 2032 { 2033 tools::Long nDelta = nHeightVal - aInitSize[i].Height(); 2034 aSize.setHeight( nHeightVal ); 2035 if (bRatio) 2036 { 2037 aSize.setWidth( aInitSize[i].Width() + static_cast<tools::Long>(static_cast<double>(nDelta) * fSizeRatio) ); 2038 m_xWidthMF->set_value(m_xWidthMF->normalize( 2039 OutputDevice::LogicToLogic( aSize.Width(), eCoreUnit, MapUnit::Map100thMM )), 2040 FieldUnit::MM_100TH); 2041 } 2042 } 2043 const SvxBrushItem* pBrushItem = aNumFmt.GetBrush(); 2044 sal_Int16 eOrient = aNumFmt.GetVertOrient(); 2045 if(aSize != aSaveSize) 2046 bRepaint = true; 2047 aNumFmt.SetGraphicBrush( pBrushItem, &aSize, &eOrient ); 2048 pActNum->SetLevel(i, aNumFmt); 2049 } 2050 } 2051 nMask <<= 1; 2052 } 2053 SetModified(bRepaint); 2054 } 2055 2056 IMPL_LINK(SvxNumOptionsTabPage, RatioHdl_Impl, weld::Toggleable&, rBox, void) 2057 { 2058 if (rBox.get_active()) 2059 { 2060 if (bLastWidthModified) 2061 SizeHdl_Impl(*m_xWidthMF); 2062 else 2063 SizeHdl_Impl(*m_xHeightMF); 2064 } 2065 } 2066 2067 IMPL_LINK_NOARG(SvxNumOptionsTabPage, CharFmtHdl_Impl, weld::ComboBox&, void) 2068 { 2069 bAutomaticCharStyles = false; 2070 sal_Int32 nEntryPos = m_xCharFmtLB->get_active(); 2071 OUString sEntry = m_xCharFmtLB->get_active_text(); 2072 sal_uInt16 nMask = 1; 2073 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) 2074 { 2075 if(nActNumLvl & nMask) 2076 { 2077 SvxNumberFormat aNumFmt(pActNum->GetLevel(i)); 2078 if( 0 == nEntryPos ) 2079 aNumFmt.SetCharFormatName(""); 2080 else 2081 { 2082 if(SVX_NUM_BITMAP != (aNumFmt.GetNumberingType()&(~LINK_TOKEN))) 2083 aNumFmt.SetCharFormatName(sEntry); 2084 } 2085 pActNum->SetLevel(i, aNumFmt); 2086 } 2087 nMask <<= 1; 2088 } 2089 SetModified(false); 2090 }; 2091 2092 IMPL_LINK(SvxNumOptionsTabPage, EditModifyHdl_Impl, weld::Entry&, rEdit, void) 2093 { 2094 EditModifyHdl_Impl(&rEdit); 2095 } 2096 2097 IMPL_LINK(SvxNumOptionsTabPage, SpinModifyHdl_Impl, weld::SpinButton&, rSpinButton, void) 2098 { 2099 EditModifyHdl_Impl(&rSpinButton); 2100 } 2101 2102 void SvxNumOptionsTabPage::EditModifyHdl_Impl(const weld::Entry* pEdit) 2103 { 2104 bool bPrefixSuffix = (pEdit == m_xPrefixED.get())|| (pEdit == m_xSuffixED.get()); 2105 bool bStart = pEdit == m_xStartED.get(); 2106 sal_uInt16 nMask = 1; 2107 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) 2108 { 2109 if(nActNumLvl & nMask) 2110 { 2111 SvxNumberFormat aNumFmt(pActNum->GetLevel(i)); 2112 if (bPrefixSuffix) 2113 aNumFmt.SetListFormat(m_xPrefixED->get_text(), m_xSuffixED->get_text(), i); 2114 else if(bStart) 2115 aNumFmt.SetStart(m_xStartED->get_value()); 2116 pActNum->SetLevel(i, aNumFmt); 2117 } 2118 nMask <<= 1; 2119 } 2120 SetModified(); 2121 } 2122 2123 static tools::Long lcl_DrawGraphic(VirtualDevice& rVDev, const SvxNumberFormat &rFmt, tools::Long nXStart, 2124 tools::Long nYMiddle, tools::Long nDivision) 2125 { 2126 const SvxBrushItem* pBrushItem = rFmt.GetBrush(); 2127 tools::Long nRet = 0; 2128 if(pBrushItem) 2129 { 2130 const Graphic* pGrf = pBrushItem->GetGraphic(); 2131 if(pGrf) 2132 { 2133 Size aGSize( rFmt.GetGraphicSize() ); 2134 aGSize.setWidth( aGSize.Width() / nDivision ); 2135 nRet = aGSize.Width(); 2136 aGSize.setHeight( aGSize.Height() / nDivision ); 2137 pGrf->Draw(rVDev, Point(nXStart,nYMiddle - ( aGSize.Height() / 2) ), 2138 rVDev.PixelToLogic( aGSize ) ); 2139 } 2140 } 2141 return nRet; 2142 2143 } 2144 2145 static tools::Long lcl_DrawBullet(VirtualDevice* pVDev, 2146 const SvxNumberFormat& rFmt, tools::Long nXStart, 2147 tools::Long nYStart, const Size& rSize) 2148 { 2149 vcl::Font aTmpFont(pVDev->GetFont()); 2150 2151 // via Uno it's possible that no font has been set! 2152 vcl::Font aFont(rFmt.GetBulletFont() ? *rFmt.GetBulletFont() : aTmpFont); 2153 Size aTmpSize(rSize); 2154 aTmpSize.setWidth( aTmpSize.Width() * ( rFmt.GetBulletRelSize()) ); 2155 aTmpSize.setWidth( aTmpSize.Width() / 100 ) ; 2156 aTmpSize.setHeight( aTmpSize.Height() * ( rFmt.GetBulletRelSize()) ); 2157 aTmpSize.setHeight( aTmpSize.Height() / 100 ) ; 2158 // in case of a height of zero it is drawn in original height 2159 if(!aTmpSize.Height()) 2160 aTmpSize.setHeight( 1 ); 2161 aFont.SetFontSize(aTmpSize); 2162 aFont.SetTransparent(true); 2163 Color aBulletColor = rFmt.GetBulletColor(); 2164 if(aBulletColor == COL_AUTO) 2165 aBulletColor = pVDev->GetFillColor().IsDark() ? COL_WHITE : COL_BLACK; 2166 else if(aBulletColor == pVDev->GetFillColor()) 2167 aBulletColor.Invert(); 2168 aFont.SetColor(aBulletColor); 2169 pVDev->SetFont( aFont ); 2170 sal_UCS4 cChar = rFmt.GetBulletChar(); 2171 OUString aText(&cChar, 1); 2172 tools::Long nY = nYStart; 2173 nY -= ((aTmpSize.Height() - rSize.Height())/ 2); 2174 pVDev->DrawText( Point(nXStart, nY), aText ); 2175 tools::Long nRet = pVDev->GetTextWidth(aText); 2176 2177 pVDev->SetFont(aTmpFont); 2178 return nRet; 2179 } 2180 2181 SvxNumberingPreview::SvxNumberingPreview() 2182 : pActNum(nullptr) 2183 , bPosition(false) 2184 , nActLevel(SAL_MAX_UINT16) 2185 { 2186 } 2187 2188 // paint preview of numeration 2189 void SvxNumberingPreview::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& /*rRect*/) 2190 { 2191 Size aSize(rRenderContext.PixelToLogic(GetOutputSizePixel())); 2192 2193 const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings(); 2194 const Color aBackColor = rStyleSettings.GetFieldColor(); 2195 const Color aTextColor = rStyleSettings.GetFieldTextColor(); 2196 2197 ScopedVclPtrInstance<VirtualDevice> pVDev(rRenderContext); 2198 pVDev->EnableRTL(rRenderContext.IsRTLEnabled()); 2199 pVDev->SetMapMode(rRenderContext.GetMapMode()); 2200 pVDev->SetOutputSize(aSize); 2201 2202 Color aLineColor(COL_LIGHTGRAY); 2203 if (aLineColor == aBackColor) 2204 aLineColor.Invert(); 2205 pVDev->SetLineColor(aLineColor); 2206 pVDev->SetFillColor(aBackColor); 2207 2208 if (pActNum) 2209 { 2210 tools::Long nWidthRelation = 30; // chapter dialog 2211 2212 // height per level 2213 tools::Long nXStep = aSize.Width() / (pActNum->GetLevelCount() > 1 ? 3 * pActNum->GetLevelCount() : 3); 2214 if (pActNum->GetLevelCount() < 10) 2215 nXStep /= 2; 2216 tools::Long nYStart = 4; 2217 // the whole height mustn't be used for a single level 2218 tools::Long nYStep = (aSize.Height() - 6)/ (pActNum->GetLevelCount() > 1 ? pActNum->GetLevelCount() : 5); 2219 2220 aStdFont = OutputDevice::GetDefaultFont(DefaultFontType::UI_SANS, MsLangId::getConfiguredSystemLanguage(), GetDefaultFontFlags::OnlyOne); 2221 aStdFont.SetColor(aTextColor); 2222 aStdFont.SetFillColor(aBackColor); 2223 2224 tools::Long nFontHeight = nYStep * 6 / 10; 2225 if (bPosition) 2226 nFontHeight = nYStep * 15 / 10; 2227 aStdFont.SetFontSize(Size( 0, nFontHeight )); 2228 2229 SvxNodeNum aNum; 2230 sal_uInt16 nPreNum = pActNum->GetLevel(0).GetStart(); 2231 2232 if (bPosition) 2233 { 2234 tools::Long nLineHeight = nFontHeight * 8 / 7; 2235 sal_uInt8 nStart = 0; 2236 while (!(nActLevel & (1<<nStart))) 2237 { 2238 nStart++; 2239 } 2240 if (nStart) 2241 nStart--; 2242 sal_uInt8 nEnd = std::min(sal_uInt8(nStart + 3), sal_uInt8(pActNum->GetLevelCount())); 2243 for (sal_uInt8 nLevel = nStart; nLevel < nEnd; ++nLevel) 2244 { 2245 const SvxNumberFormat &rFmt = pActNum->GetLevel(nLevel); 2246 aNum.GetLevelVal()[nLevel] = rFmt.GetStart(); 2247 2248 tools::Long nXStart( 0 ); 2249 short nTextOffset( 0 ); 2250 tools::Long nNumberXPos( 0 ); 2251 if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION) 2252 { 2253 nXStart = rFmt.GetAbsLSpace() / nWidthRelation; 2254 nTextOffset = rFmt.GetCharTextDistance() / nWidthRelation; 2255 nNumberXPos = nXStart; 2256 tools::Long nFirstLineOffset = (-rFmt.GetFirstLineOffset()) / nWidthRelation; 2257 2258 if (nFirstLineOffset <= nNumberXPos) 2259 nNumberXPos = nNumberXPos - nFirstLineOffset; 2260 else 2261 nNumberXPos = 0; 2262 // in draw this is valid 2263 if (nTextOffset < 0) 2264 nNumberXPos = nNumberXPos + nTextOffset; 2265 } 2266 else if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT) 2267 { 2268 const tools::Long nTmpNumberXPos((rFmt.GetIndentAt() + rFmt.GetFirstLineIndent() ) / nWidthRelation); 2269 if (nTmpNumberXPos < 0) 2270 { 2271 nNumberXPos = 0; 2272 } 2273 else 2274 { 2275 nNumberXPos = nTmpNumberXPos; 2276 } 2277 } 2278 2279 tools::Long nBulletWidth = 0; 2280 if (SVX_NUM_BITMAP == (rFmt.GetNumberingType() &(~LINK_TOKEN))) 2281 { 2282 tools::Long nYMiddle = nYStart + ( nFontHeight / 2 ); 2283 nBulletWidth = rFmt.IsShowSymbol() ? lcl_DrawGraphic(*pVDev, rFmt, nNumberXPos, nYMiddle, nWidthRelation) : 0; 2284 } 2285 else if (SVX_NUM_CHAR_SPECIAL == rFmt.GetNumberingType()) 2286 { 2287 nBulletWidth = rFmt.IsShowSymbol() ? lcl_DrawBullet(pVDev.get(), rFmt, nNumberXPos, nYStart, aStdFont.GetFontSize()) : 0; 2288 } 2289 else 2290 { 2291 pVDev->SetFont(aStdFont); 2292 aNum.SetLevel(nLevel); 2293 if (pActNum->IsContinuousNumbering()) 2294 aNum.GetLevelVal()[nLevel] = nPreNum; 2295 OUString aText(pActNum->MakeNumString( aNum )); 2296 vcl::Font aSaveFont = pVDev->GetFont(); 2297 vcl::Font aColorFont(aSaveFont); 2298 Color aTmpBulletColor = rFmt.GetBulletColor(); 2299 if (aTmpBulletColor == COL_AUTO) 2300 aTmpBulletColor = aBackColor.IsDark() ? COL_WHITE : COL_BLACK; 2301 else if (aTmpBulletColor == aBackColor) 2302 aTmpBulletColor.Invert(); 2303 aColorFont.SetColor(aTmpBulletColor); 2304 pVDev->SetFont(aColorFont); 2305 pVDev->DrawText(Point(nNumberXPos, nYStart), aText); 2306 pVDev->SetFont(aSaveFont); 2307 nBulletWidth = pVDev->GetTextWidth(aText); 2308 nPreNum++; 2309 } 2310 if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT && 2311 rFmt.GetLabelFollowedBy() == SvxNumberFormat::SPACE ) 2312 { 2313 pVDev->SetFont(aStdFont); 2314 OUString aText(' '); 2315 pVDev->DrawText( Point(nNumberXPos, nYStart), aText ); 2316 nBulletWidth = nBulletWidth + pVDev->GetTextWidth(aText); 2317 } 2318 2319 tools::Long nTextXPos( 0 ); 2320 if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION) 2321 { 2322 nTextXPos = nXStart; 2323 if (nTextOffset < 0) 2324 nTextXPos = nTextXPos + nTextOffset; 2325 if (nNumberXPos + nBulletWidth + nTextOffset > nTextXPos) 2326 nTextXPos = nNumberXPos + nBulletWidth + nTextOffset; 2327 } 2328 else if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT) 2329 { 2330 switch (rFmt.GetLabelFollowedBy()) 2331 { 2332 case SvxNumberFormat::LISTTAB: 2333 { 2334 nTextXPos = rFmt.GetListtabPos() / nWidthRelation; 2335 if (nTextXPos < nNumberXPos + nBulletWidth) 2336 { 2337 nTextXPos = nNumberXPos + nBulletWidth; 2338 } 2339 } 2340 break; 2341 case SvxNumberFormat::SPACE: 2342 case SvxNumberFormat::NOTHING: 2343 case SvxNumberFormat::NEWLINE: 2344 { 2345 nTextXPos = nNumberXPos + nBulletWidth; 2346 } 2347 break; 2348 } 2349 2350 nXStart = rFmt.GetIndentAt() / nWidthRelation; 2351 } 2352 2353 ::tools::Rectangle aRect1(Point(nTextXPos, nYStart + nFontHeight / 2), Size(aSize.Width() / 2, 2)); 2354 pVDev->SetFillColor(aBackColor); 2355 pVDev->DrawRect(aRect1); 2356 2357 ::tools::Rectangle aRect2(Point(nXStart, nYStart + nLineHeight + nFontHeight / 2 ), Size(aSize.Width() / 2, 2)); 2358 pVDev->DrawRect(aRect2); 2359 nYStart += 2 * nLineHeight; 2360 } 2361 } 2362 else 2363 { 2364 //#i5153# painting gray or black rectangles as 'normal' numbering text 2365 tools::Long nWidth = pVDev->GetTextWidth("Preview"); 2366 tools::Long nTextHeight = pVDev->GetTextHeight(); 2367 tools::Long nRectHeight = nTextHeight * 2 / 3; 2368 tools::Long nTopOffset = nTextHeight - nRectHeight; 2369 Color aBlackColor(COL_BLACK); 2370 if (aBlackColor == aBackColor) 2371 aBlackColor.Invert(); 2372 2373 for (sal_uInt16 nLevel = 0; nLevel < pActNum->GetLevelCount(); ++nLevel, nYStart = nYStart + nYStep) 2374 { 2375 const SvxNumberFormat &rFmt = pActNum->GetLevel(nLevel); 2376 aNum.GetLevelVal()[ nLevel ] = rFmt.GetStart(); 2377 tools::Long nXStart( 0 ); 2378 pVDev->SetFillColor( aBackColor ); 2379 2380 if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION) 2381 { 2382 nXStart = rFmt.GetAbsLSpace() / nWidthRelation; 2383 } 2384 else if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT) 2385 { 2386 const tools::Long nTmpXStart((rFmt.GetIndentAt() + rFmt.GetFirstLineIndent() ) / nWidthRelation); 2387 if (nTmpXStart < 0) 2388 { 2389 nXStart = 0; 2390 } 2391 else 2392 { 2393 nXStart = nTmpXStart; 2394 } 2395 } 2396 nXStart /= 2; 2397 nXStart += 2; 2398 tools::Long nTextOffset = 2 * nXStep; 2399 if (SVX_NUM_BITMAP == (rFmt.GetNumberingType()&(~LINK_TOKEN))) 2400 { 2401 if (rFmt.IsShowSymbol()) 2402 { 2403 tools::Long nYMiddle = nYStart + ( nFontHeight / 2 ); 2404 nTextOffset = lcl_DrawGraphic(*pVDev, rFmt, nXStart, nYMiddle, nWidthRelation); 2405 nTextOffset = nTextOffset + nXStep; 2406 } 2407 } 2408 else if (SVX_NUM_CHAR_SPECIAL == rFmt.GetNumberingType()) 2409 { 2410 if (rFmt.IsShowSymbol()) 2411 { 2412 nTextOffset = lcl_DrawBullet(pVDev.get(), rFmt, nXStart, nYStart, aStdFont.GetFontSize()); 2413 nTextOffset = nTextOffset + nXStep; 2414 } 2415 } 2416 else 2417 { 2418 vcl::Font aFont(aStdFont); 2419 Size aTmpSize(aStdFont.GetFontSize()); 2420 if(pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_REL_SIZE)) 2421 { 2422 aTmpSize.setWidth( aTmpSize.Width() * ( rFmt.GetBulletRelSize()) ); 2423 aTmpSize.setWidth( aTmpSize.Width() / 100 ) ; 2424 aTmpSize.setHeight( aTmpSize.Height() * ( rFmt.GetBulletRelSize()) ); 2425 aTmpSize.setHeight( aTmpSize.Height() / 100 ) ; 2426 } 2427 if(!aTmpSize.Height()) 2428 aTmpSize.setHeight( 1 ); 2429 aFont.SetFontSize(aTmpSize); 2430 Color aTmpBulletColor = rFmt.GetBulletColor(); 2431 if (aTmpBulletColor == COL_AUTO) 2432 aTmpBulletColor = aBackColor.IsDark() ? COL_WHITE : COL_BLACK; 2433 else if (aTmpBulletColor == aBackColor) 2434 aTmpBulletColor.Invert(); 2435 aFont.SetColor(aTmpBulletColor); 2436 pVDev->SetFont(aFont); 2437 aNum.SetLevel( nLevel ); 2438 if (pActNum->IsContinuousNumbering()) 2439 aNum.GetLevelVal()[nLevel] = nPreNum; 2440 OUString aText(pActNum->MakeNumString(aNum)); 2441 tools::Long nY = nYStart; 2442 nY -= (pVDev->GetTextHeight() - nTextHeight - pVDev->GetFontMetric().GetDescent()); 2443 pVDev->DrawText(Point(nXStart, nY), aText); 2444 nTextOffset = pVDev->GetTextWidth(aText); 2445 nTextOffset = nTextOffset + nXStep; 2446 nPreNum++; 2447 pVDev->SetFont(aStdFont); 2448 } 2449 //#i5153# the selected rectangle(s) should be black 2450 if (0 != (nActLevel & (1<<nLevel))) 2451 { 2452 pVDev->SetFillColor( aBlackColor ); 2453 pVDev->SetLineColor( aBlackColor ); 2454 } 2455 else 2456 { 2457 //#i5153# unselected levels are gray 2458 pVDev->SetFillColor( aLineColor ); 2459 pVDev->SetLineColor( aLineColor ); 2460 } 2461 ::tools::Rectangle aRect1(Point(nXStart + nTextOffset, nYStart + nTopOffset), Size(nWidth, nRectHeight)); 2462 pVDev->DrawRect(aRect1); 2463 } 2464 } 2465 } 2466 rRenderContext.DrawOutDev(Point(), aSize, Point(), aSize, *pVDev); 2467 } 2468 2469 2470 //See uiconfig/swriter/ui/outlinepositionpage.ui for effectively a duplicate 2471 //dialog to this one, except with a different preview window impl. 2472 //TODO, determine if SwNumPositionTabPage and SvxNumPositionTabPage can be 2473 //merged 2474 SvxNumPositionTabPage::SvxNumPositionTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet) 2475 : SfxTabPage(pPage, pController, "cui/ui/numberingpositionpage.ui", "NumberingPositionPage", &rSet) 2476 , m_pLevelHdlEvent(nullptr) 2477 , nActNumLvl(1) 2478 , nNumItemId(SID_ATTR_NUMBERING_RULE) 2479 , bModified(false) 2480 , bPreset(false) 2481 , bInInintControl(false) 2482 , bLabelAlignmentPosAndSpaceModeActive(false) 2483 , m_xLevelLB(m_xBuilder->weld_tree_view("levellb")) 2484 , m_xDistBorderFT(m_xBuilder->weld_label("indent")) 2485 , m_xDistBorderMF(m_xBuilder->weld_metric_spin_button("indentmf", FieldUnit::CM)) 2486 , m_xRelativeCB(m_xBuilder->weld_check_button("relative")) 2487 , m_xIndentFT(m_xBuilder->weld_label("numberingwidth")) 2488 , m_xIndentMF(m_xBuilder->weld_metric_spin_button("numberingwidthmf", FieldUnit::CM)) 2489 , m_xDistNumFT(m_xBuilder->weld_label("numdist")) 2490 , m_xDistNumMF(m_xBuilder->weld_metric_spin_button("numdistmf", FieldUnit::CM)) 2491 , m_xAlignFT(m_xBuilder->weld_label("numalign")) 2492 , m_xAlignLB(m_xBuilder->weld_combo_box("numalignlb")) 2493 , m_xLabelFollowedByFT(m_xBuilder->weld_label("numfollowedby")) 2494 , m_xLabelFollowedByLB(m_xBuilder->weld_combo_box("numfollowedbylb")) 2495 , m_xListtabFT(m_xBuilder->weld_label("at")) 2496 , m_xListtabMF(m_xBuilder->weld_metric_spin_button("atmf", FieldUnit::CM)) 2497 , m_xAlign2FT(m_xBuilder->weld_label("num2align")) 2498 , m_xAlign2LB(m_xBuilder->weld_combo_box("num2alignlb")) 2499 , m_xAlignedAtFT(m_xBuilder->weld_label("alignedat")) 2500 , m_xAlignedAtMF(m_xBuilder->weld_metric_spin_button("alignedatmf", FieldUnit::CM)) 2501 , m_xIndentAtFT(m_xBuilder->weld_label("indentat")) 2502 , m_xIndentAtMF(m_xBuilder->weld_metric_spin_button("indentatmf", FieldUnit::CM)) 2503 , m_xStandardPB(m_xBuilder->weld_button("standard")) 2504 , m_xPreviewWIN(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWIN)) 2505 { 2506 SetExchangeSupport(); 2507 2508 // set metric 2509 FieldUnit eFUnit = GetModuleFieldUnit(rSet); 2510 2511 SetFieldUnit( *m_xDistBorderMF, eFUnit ); 2512 SetFieldUnit( *m_xIndentMF, eFUnit ); 2513 SetFieldUnit( *m_xDistNumMF, eFUnit ); 2514 2515 m_xAlignedAtMF->set_range(0, SAL_MAX_INT32, FieldUnit::NONE); 2516 m_xListtabMF->set_range(0, SAL_MAX_INT32, FieldUnit::NONE); 2517 m_xIndentAtMF->set_range(0, SAL_MAX_INT32, FieldUnit::NONE); 2518 2519 m_xRelativeCB->set_active(true); 2520 m_xAlignLB->connect_changed(LINK(this, SvxNumPositionTabPage, EditModifyHdl_Impl)); 2521 m_xAlign2LB->connect_changed(LINK(this, SvxNumPositionTabPage, EditModifyHdl_Impl)); 2522 for ( sal_Int32 i = 0; i < m_xAlignLB->get_count(); ++i ) 2523 { 2524 m_xAlign2LB->append_text(m_xAlignLB->get_text(i)); 2525 } 2526 2527 Link<weld::MetricSpinButton&,void> aLk3 = LINK(this, SvxNumPositionTabPage, DistanceHdl_Impl); 2528 m_xDistBorderMF->connect_value_changed(aLk3); 2529 m_xDistNumMF->connect_value_changed(aLk3); 2530 m_xIndentMF->connect_value_changed(aLk3); 2531 2532 m_xLabelFollowedByLB->connect_changed(LINK(this, SvxNumPositionTabPage, LabelFollowedByHdl_Impl)); 2533 2534 m_xListtabMF->connect_value_changed(LINK(this, SvxNumPositionTabPage, ListtabPosHdl_Impl)); 2535 m_xAlignedAtMF->connect_value_changed(LINK(this, SvxNumPositionTabPage, AlignAtHdl_Impl)); 2536 m_xIndentAtMF->connect_value_changed(LINK(this, SvxNumPositionTabPage, IndentAtHdl_Impl)); 2537 2538 m_xLevelLB->set_selection_mode(SelectionMode::Multiple); 2539 m_xLevelLB->connect_changed(LINK(this, SvxNumPositionTabPage, LevelHdl_Impl)); 2540 m_xRelativeCB->connect_toggled(LINK(this, SvxNumPositionTabPage, RelativeHdl_Impl)); 2541 m_xStandardPB->connect_clicked(LINK(this, SvxNumPositionTabPage, StandardHdl_Impl)); 2542 2543 m_xRelativeCB->set_active(bLastRelative); 2544 m_aPreviewWIN.SetPositionMode(); 2545 eCoreUnit = rSet.GetPool()->GetMetric(rSet.GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE)); 2546 } 2547 2548 SvxNumPositionTabPage::~SvxNumPositionTabPage() 2549 { 2550 if (m_pLevelHdlEvent) 2551 { 2552 Application::RemoveUserEvent(m_pLevelHdlEvent); 2553 m_pLevelHdlEvent = nullptr; 2554 } 2555 m_xPreviewWIN.reset(); 2556 } 2557 2558 /*-------------------------------------------------------*/ 2559 2560 void SvxNumPositionTabPage::InitControls() 2561 { 2562 bInInintControl = true; 2563 const bool bRelative = !bLabelAlignmentPosAndSpaceModeActive && 2564 m_xRelativeCB->get_sensitive() && m_xRelativeCB->get_active(); 2565 const bool bSingleSelection = m_xLevelLB->count_selected_rows() == 1 && 2566 SAL_MAX_UINT16 != nActNumLvl; 2567 2568 m_xDistBorderMF->set_sensitive( !bLabelAlignmentPosAndSpaceModeActive && 2569 ( bSingleSelection || bRelative ) ); 2570 m_xDistBorderFT->set_sensitive( !bLabelAlignmentPosAndSpaceModeActive && 2571 ( bSingleSelection || bRelative ) ); 2572 2573 bool bSetDistEmpty = false; 2574 bool bSameDistBorderNum = !bLabelAlignmentPosAndSpaceModeActive; 2575 bool bSameDist = !bLabelAlignmentPosAndSpaceModeActive; 2576 bool bSameIndent = !bLabelAlignmentPosAndSpaceModeActive; 2577 bool bSameAdjust = true; 2578 2579 bool bSameLabelFollowedBy = bLabelAlignmentPosAndSpaceModeActive; 2580 bool bSameListtab = bLabelAlignmentPosAndSpaceModeActive; 2581 bool bSameAlignAt = bLabelAlignmentPosAndSpaceModeActive; 2582 bool bSameIndentAt = bLabelAlignmentPosAndSpaceModeActive; 2583 2584 const SvxNumberFormat* aNumFmtArr[SVX_MAX_NUM]; 2585 sal_uInt16 nMask = 1; 2586 sal_uInt16 nLvl = SAL_MAX_UINT16; 2587 tools::Long nFirstBorderTextRelative = -1; 2588 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) 2589 { 2590 aNumFmtArr[i] = &pActNum->GetLevel(i); 2591 if(nActNumLvl & nMask) 2592 { 2593 if(SAL_MAX_UINT16 == nLvl) 2594 nLvl = i; 2595 2596 if( i > nLvl) 2597 { 2598 bSameAdjust &= aNumFmtArr[i]->GetNumAdjust() == aNumFmtArr[nLvl]->GetNumAdjust(); 2599 if ( !bLabelAlignmentPosAndSpaceModeActive ) 2600 { 2601 if(bRelative) 2602 { 2603 if(nFirstBorderTextRelative == -1) 2604 nFirstBorderTextRelative = 2605 (aNumFmtArr[i]->GetAbsLSpace() + aNumFmtArr[i]->GetFirstLineOffset() - 2606 aNumFmtArr[i - 1]->GetAbsLSpace() + aNumFmtArr[i - 1]->GetFirstLineOffset()); 2607 else 2608 bSameDistBorderNum &= nFirstBorderTextRelative == 2609 (aNumFmtArr[i]->GetAbsLSpace() + aNumFmtArr[i]->GetFirstLineOffset() - 2610 aNumFmtArr[i - 1]->GetAbsLSpace() + aNumFmtArr[i - 1]->GetFirstLineOffset()); 2611 } 2612 else 2613 bSameDistBorderNum &= 2614 aNumFmtArr[i]->GetAbsLSpace() - aNumFmtArr[i]->GetFirstLineOffset() == 2615 aNumFmtArr[i - 1]->GetAbsLSpace() - aNumFmtArr[i - 1]->GetFirstLineOffset(); 2616 2617 bSameDist &= aNumFmtArr[i]->GetCharTextDistance() == aNumFmtArr[nLvl]->GetCharTextDistance(); 2618 bSameIndent &= aNumFmtArr[i]->GetFirstLineOffset() == aNumFmtArr[nLvl]->GetFirstLineOffset(); 2619 } 2620 else 2621 { 2622 bSameLabelFollowedBy &= 2623 aNumFmtArr[i]->GetLabelFollowedBy() == aNumFmtArr[nLvl]->GetLabelFollowedBy(); 2624 bSameListtab &= 2625 aNumFmtArr[i]->GetListtabPos() == aNumFmtArr[nLvl]->GetListtabPos(); 2626 bSameAlignAt &= 2627 ( ( aNumFmtArr[i]->GetIndentAt() + aNumFmtArr[i]->GetFirstLineIndent() ) 2628 == ( aNumFmtArr[nLvl]->GetIndentAt() + aNumFmtArr[nLvl]->GetFirstLineIndent() ) ); 2629 bSameIndentAt &= 2630 aNumFmtArr[i]->GetIndentAt() == aNumFmtArr[nLvl]->GetIndentAt(); 2631 } 2632 } 2633 } 2634 nMask <<= 1; 2635 2636 } 2637 if (SVX_MAX_NUM <= nLvl) 2638 { 2639 OSL_ENSURE(false, "cannot happen."); 2640 return; 2641 } 2642 2643 if(bSameDistBorderNum) 2644 { 2645 tools::Long nDistBorderNum; 2646 if(bRelative) 2647 { 2648 nDistBorderNum = static_cast<tools::Long>(aNumFmtArr[nLvl]->GetAbsLSpace())+ aNumFmtArr[nLvl]->GetFirstLineOffset(); 2649 if(nLvl) 2650 nDistBorderNum -= static_cast<tools::Long>(aNumFmtArr[nLvl - 1]->GetAbsLSpace())+ aNumFmtArr[nLvl - 1]->GetFirstLineOffset(); 2651 } 2652 else 2653 { 2654 nDistBorderNum = static_cast<tools::Long>(aNumFmtArr[nLvl]->GetAbsLSpace())+ aNumFmtArr[nLvl]->GetFirstLineOffset(); 2655 } 2656 SetMetricValue(*m_xDistBorderMF, nDistBorderNum, eCoreUnit); 2657 } 2658 else 2659 bSetDistEmpty = true; 2660 2661 if(bSameDist) 2662 SetMetricValue(*m_xDistNumMF, aNumFmtArr[nLvl]->GetCharTextDistance(), eCoreUnit); 2663 else 2664 m_xDistNumMF->set_text(""); 2665 if(bSameIndent) 2666 SetMetricValue(*m_xIndentMF, - aNumFmtArr[nLvl]->GetFirstLineOffset(), eCoreUnit); 2667 else 2668 m_xIndentMF->set_text(""); 2669 2670 if(bSameAdjust) 2671 { 2672 sal_Int32 nPos = 1; // centered 2673 if(aNumFmtArr[nLvl]->GetNumAdjust() == SvxAdjust::Left) 2674 nPos = 0; 2675 else if(aNumFmtArr[nLvl]->GetNumAdjust() == SvxAdjust::Right) 2676 nPos = 2; 2677 m_xAlignLB->set_active(nPos); 2678 m_xAlign2LB->set_active(nPos); 2679 } 2680 else 2681 { 2682 m_xAlignLB->set_active(-1); 2683 m_xAlign2LB->set_active(-1); 2684 } 2685 2686 if ( bSameLabelFollowedBy ) 2687 { 2688 sal_Int32 nPos = 0; // LISTTAB 2689 if ( aNumFmtArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::SPACE ) 2690 { 2691 nPos = 1; 2692 } 2693 else if ( aNumFmtArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::NOTHING ) 2694 { 2695 nPos = 2; 2696 } 2697 else if ( aNumFmtArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::NEWLINE ) 2698 { 2699 nPos = 3; 2700 } 2701 m_xLabelFollowedByLB->set_active(nPos); 2702 } 2703 else 2704 { 2705 m_xLabelFollowedByLB->set_active(-1); 2706 } 2707 2708 if ( aNumFmtArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::LISTTAB ) 2709 { 2710 m_xListtabFT->set_sensitive(true); 2711 m_xListtabMF->set_sensitive(true); 2712 if ( bSameListtab ) 2713 { 2714 SetMetricValue(*m_xListtabMF, aNumFmtArr[nLvl]->GetListtabPos(), eCoreUnit); 2715 } 2716 else 2717 { 2718 m_xListtabMF->set_text(""); 2719 } 2720 } 2721 else 2722 { 2723 m_xListtabFT->set_sensitive(false); 2724 m_xListtabMF->set_sensitive(false); 2725 m_xListtabMF->set_text(""); 2726 } 2727 2728 if ( bSameAlignAt ) 2729 { 2730 SetMetricValue(*m_xAlignedAtMF, 2731 aNumFmtArr[nLvl]->GetIndentAt() + aNumFmtArr[nLvl]->GetFirstLineIndent(), 2732 eCoreUnit); 2733 } 2734 else 2735 { 2736 m_xAlignedAtMF->set_text(""); 2737 } 2738 2739 if ( bSameIndentAt ) 2740 { 2741 SetMetricValue(*m_xIndentAtMF, aNumFmtArr[nLvl]->GetIndentAt(), eCoreUnit); 2742 } 2743 else 2744 { 2745 m_xIndentAtMF->set_text(""); 2746 } 2747 2748 if ( bSetDistEmpty ) 2749 m_xDistBorderMF->set_text(""); 2750 2751 bInInintControl = false; 2752 } 2753 2754 void SvxNumPositionTabPage::ActivatePage(const SfxItemSet& rSet) 2755 { 2756 sal_uInt16 nTmpNumLvl = 1; 2757 const SfxItemSet* pExampleSet = GetDialogExampleSet(); 2758 if(pExampleSet) 2759 { 2760 if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false)) 2761 bPreset = pPresetItem->GetValue(); 2762 if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false)) 2763 nTmpNumLvl = pLevelItem->GetValue(); 2764 } 2765 if(const SvxNumBulletItem* pBulletItem = rSet.GetItemIfSet(nNumItemId, false)) 2766 { 2767 pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) ); 2768 } 2769 bModified = (!pActNum->Get( 0 ) || bPreset); 2770 if(*pSaveNum != *pActNum || 2771 nActNumLvl != nTmpNumLvl ) 2772 { 2773 *pActNum = *pSaveNum; 2774 nActNumLvl = nTmpNumLvl; 2775 sal_uInt16 nMask = 1; 2776 m_xLevelLB->unselect_all(); 2777 if (nActNumLvl == SAL_MAX_UINT16) 2778 m_xLevelLB->select(pActNum->GetLevelCount()); 2779 if (nActNumLvl != SAL_MAX_UINT16) 2780 for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) 2781 { 2782 if (nActNumLvl & nMask) 2783 m_xLevelLB->select(i); 2784 nMask <<= 1 ; 2785 } 2786 m_xRelativeCB->set_sensitive(nActNumLvl != 1); 2787 2788 InitPosAndSpaceMode(); 2789 ShowControlsDependingOnPosAndSpaceMode(); 2790 2791 InitControls(); 2792 } 2793 m_aPreviewWIN.SetLevel(nActNumLvl); 2794 m_aPreviewWIN.Invalidate(); 2795 } 2796 2797 DeactivateRC SvxNumPositionTabPage::DeactivatePage(SfxItemSet *_pSet) 2798 { 2799 if(_pSet) 2800 { 2801 if (m_xDistBorderMF->get_sensitive()) 2802 DistanceHdl_Impl(*m_xDistBorderMF); 2803 DistanceHdl_Impl(*m_xIndentMF); 2804 FillItemSet(_pSet); 2805 } 2806 return DeactivateRC::LeavePage; 2807 } 2808 2809 bool SvxNumPositionTabPage::FillItemSet( SfxItemSet* rSet ) 2810 { 2811 rSet->Put(SfxUInt16Item(SID_PARAM_CUR_NUM_LEVEL, nActNumLvl)); 2812 2813 if(bModified && pActNum) 2814 { 2815 *pSaveNum = *pActNum; 2816 rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId )); 2817 rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, false)); 2818 } 2819 return bModified; 2820 } 2821 2822 void SvxNumPositionTabPage::Reset( const SfxItemSet* rSet ) 2823 { 2824 // in Draw the item exists as WhichId, in Writer only as SlotId 2825 const SvxNumBulletItem* pItem = 2826 rSet->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false); 2827 if(!pItem) 2828 { 2829 nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE); 2830 pItem = rSet->GetItemIfSet(nNumItemId, false); 2831 2832 if( !pItem ) 2833 { 2834 pItem = & rSet->Get( nNumItemId ); 2835 } 2836 } 2837 DBG_ASSERT(pItem, "no item found!"); 2838 pSaveNum.reset( new SvxNumRule(pItem->GetNumRule()) ); 2839 2840 // insert levels 2841 if (!m_xLevelLB->count_selected_rows()) 2842 { 2843 for(sal_uInt16 i = 1; i <= pSaveNum->GetLevelCount(); i++) 2844 m_xLevelLB->append_text(OUString::number(i)); 2845 if(pSaveNum->GetLevelCount() > 1) 2846 { 2847 OUString sEntry = "1 - " + OUString::number( pSaveNum->GetLevelCount() ); 2848 m_xLevelLB->append_text(sEntry); 2849 m_xLevelLB->select_text(sEntry); 2850 } 2851 else 2852 m_xLevelLB->select(0); 2853 } 2854 else 2855 m_xLevelLB->select(m_xLevelLB->count_selected_rows() - 1); 2856 sal_uInt16 nMask = 1; 2857 m_xLevelLB->unselect_all(); 2858 if (nActNumLvl == SAL_MAX_UINT16) 2859 { 2860 m_xLevelLB->select(pSaveNum->GetLevelCount()); 2861 } 2862 else 2863 { 2864 for(sal_uInt16 i = 0; i < pSaveNum->GetLevelCount(); i++) 2865 { 2866 if(nActNumLvl & nMask) 2867 m_xLevelLB->select(i); 2868 nMask <<= 1; 2869 } 2870 } 2871 2872 if(!pActNum) 2873 pActNum.reset( new SvxNumRule(*pSaveNum) ); 2874 else if(*pSaveNum != *pActNum) 2875 *pActNum = *pSaveNum; 2876 m_aPreviewWIN.SetNumRule(pActNum.get()); 2877 2878 InitPosAndSpaceMode(); 2879 ShowControlsDependingOnPosAndSpaceMode(); 2880 2881 InitControls(); 2882 bModified = false; 2883 } 2884 2885 void SvxNumPositionTabPage::InitPosAndSpaceMode() 2886 { 2887 if ( pActNum == nullptr ) 2888 { 2889 SAL_WARN( "cui.tabpages", 2890 "<SvxNumPositionTabPage::InitPosAndSpaceMode()> - misusage of method -> <pAktNum> has to be already set!" ); 2891 return; 2892 } 2893 2894 SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode = 2895 SvxNumberFormat::LABEL_ALIGNMENT; 2896 sal_uInt16 nMask = 1; 2897 for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i ) 2898 { 2899 if(nActNumLvl & nMask) 2900 { 2901 SvxNumberFormat aNumFmt( pActNum->GetLevel(i) ); 2902 ePosAndSpaceMode = aNumFmt.GetPositionAndSpaceMode(); 2903 if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT ) 2904 { 2905 break; 2906 } 2907 } 2908 nMask <<= 1; 2909 } 2910 2911 bLabelAlignmentPosAndSpaceModeActive = 2912 ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT; 2913 } 2914 2915 void SvxNumPositionTabPage::ShowControlsDependingOnPosAndSpaceMode() 2916 { 2917 m_xDistBorderFT->set_visible( !bLabelAlignmentPosAndSpaceModeActive ); 2918 m_xDistBorderMF->set_visible( !bLabelAlignmentPosAndSpaceModeActive ); 2919 m_xRelativeCB->set_visible( !bLabelAlignmentPosAndSpaceModeActive ); 2920 m_xIndentFT->set_visible( !bLabelAlignmentPosAndSpaceModeActive ); 2921 m_xIndentMF->set_visible( !bLabelAlignmentPosAndSpaceModeActive ); 2922 m_xDistNumFT->set_visible( !bLabelAlignmentPosAndSpaceModeActive && 2923 pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS) ); 2924 m_xDistNumMF->set_visible( !bLabelAlignmentPosAndSpaceModeActive && 2925 pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS)); 2926 m_xAlignFT->set_visible( !bLabelAlignmentPosAndSpaceModeActive ); 2927 m_xAlignLB->set_visible( !bLabelAlignmentPosAndSpaceModeActive ); 2928 2929 m_xLabelFollowedByFT->set_visible( bLabelAlignmentPosAndSpaceModeActive ); 2930 m_xLabelFollowedByLB->set_visible( bLabelAlignmentPosAndSpaceModeActive ); 2931 m_xListtabFT->set_visible( bLabelAlignmentPosAndSpaceModeActive ); 2932 m_xListtabMF->set_visible( bLabelAlignmentPosAndSpaceModeActive ); 2933 m_xAlign2FT->set_visible( bLabelAlignmentPosAndSpaceModeActive ); 2934 m_xAlign2LB->set_visible( bLabelAlignmentPosAndSpaceModeActive ); 2935 m_xAlignedAtFT->set_visible( bLabelAlignmentPosAndSpaceModeActive ); 2936 m_xAlignedAtMF->set_visible( bLabelAlignmentPosAndSpaceModeActive ); 2937 m_xIndentAtFT->set_visible( bLabelAlignmentPosAndSpaceModeActive ); 2938 m_xIndentAtMF->set_visible( bLabelAlignmentPosAndSpaceModeActive ); 2939 } 2940 2941 std::unique_ptr<SfxTabPage> SvxNumPositionTabPage::Create(weld::Container* pPage, weld::DialogController* pController, 2942 const SfxItemSet* rAttrSet) 2943 { 2944 return std::make_unique<SvxNumPositionTabPage>(pPage, pController, *rAttrSet); 2945 } 2946 2947 void SvxNumPositionTabPage::SetMetric(FieldUnit eMetric) 2948 { 2949 if (eMetric == FieldUnit::MM) 2950 { 2951 m_xDistBorderMF->set_digits(1); 2952 m_xDistNumMF->set_digits(1); 2953 m_xIndentMF->set_digits(1); 2954 m_xListtabMF->set_digits(1); 2955 m_xAlignedAtMF->set_digits(1); 2956 m_xIndentAtMF->set_digits(1); 2957 } 2958 m_xDistBorderMF->set_unit(eMetric); 2959 m_xDistNumMF->set_unit(eMetric); 2960 m_xIndentMF->set_unit(eMetric); 2961 m_xListtabMF->set_unit(eMetric); 2962 m_xAlignedAtMF->set_unit(eMetric); 2963 m_xIndentAtMF->set_unit(eMetric); 2964 } 2965 2966 IMPL_LINK_NOARG(SvxNumPositionTabPage, EditModifyHdl_Impl, weld::ComboBox&, void) 2967 { 2968 sal_uInt16 nMask = 1; 2969 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) 2970 { 2971 if(nActNumLvl & nMask) 2972 { 2973 SvxNumberFormat aNumFmt(pActNum->GetLevel(i)); 2974 2975 const sal_Int32 nPos = m_xAlignLB->get_visible() 2976 ? m_xAlignLB->get_active() 2977 : m_xAlign2LB->get_active(); 2978 SvxAdjust eAdjust = SvxAdjust::Center; 2979 if(nPos == 0) 2980 eAdjust = SvxAdjust::Left; 2981 else if(nPos == 2) 2982 eAdjust = SvxAdjust::Right; 2983 aNumFmt.SetNumAdjust( eAdjust ); 2984 pActNum->SetLevel(i, aNumFmt); 2985 } 2986 nMask <<= 1; 2987 } 2988 SetModified(); 2989 } 2990 2991 IMPL_LINK_NOARG(SvxNumPositionTabPage, LevelHdl_Impl, weld::TreeView&, void) 2992 { 2993 if (m_pLevelHdlEvent) 2994 return; 2995 // tdf#127120 multiselection may be implemented by deselect follow by select so 2996 // fire off the handler to happen on next event loop and only process the 2997 // final state 2998 m_pLevelHdlEvent = Application::PostUserEvent(LINK(this, SvxNumPositionTabPage, LevelHdl)); 2999 } 3000 3001 IMPL_LINK_NOARG(SvxNumPositionTabPage, LevelHdl, void*, void) 3002 { 3003 m_pLevelHdlEvent = nullptr; 3004 3005 sal_uInt16 nSaveNumLvl = nActNumLvl; 3006 nActNumLvl = 0; 3007 std::vector<int> aSelectedRows = m_xLevelLB->get_selected_rows(); 3008 if (std::find(aSelectedRows.begin(), aSelectedRows.end(), pActNum->GetLevelCount()) != aSelectedRows.end() && 3009 (aSelectedRows.size() == 1 || nSaveNumLvl != 0xffff)) 3010 { 3011 nActNumLvl = 0xFFFF; 3012 for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ ) 3013 m_xLevelLB->unselect(i); 3014 } 3015 else if (!aSelectedRows.empty()) 3016 { 3017 sal_uInt16 nMask = 1; 3018 for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ ) 3019 { 3020 if (std::find(aSelectedRows.begin(), aSelectedRows.end(), i) != aSelectedRows.end()) 3021 nActNumLvl |= nMask; 3022 nMask <<= 1; 3023 } 3024 m_xLevelLB->unselect(pActNum->GetLevelCount()); 3025 } 3026 else 3027 { 3028 nActNumLvl = nSaveNumLvl; 3029 sal_uInt16 nMask = 1; 3030 for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ ) 3031 { 3032 if(nActNumLvl & nMask) 3033 { 3034 m_xLevelLB->select(i); 3035 break; 3036 } 3037 nMask <<=1; 3038 } 3039 } 3040 m_xRelativeCB->set_sensitive(nActNumLvl != 1); 3041 SetModified(); 3042 InitPosAndSpaceMode(); 3043 ShowControlsDependingOnPosAndSpaceMode(); 3044 InitControls(); 3045 } 3046 3047 IMPL_LINK(SvxNumPositionTabPage, DistanceHdl_Impl, weld::MetricSpinButton&, rFld, void) 3048 { 3049 if(bInInintControl) 3050 return; 3051 tools::Long nValue = GetCoreValue(rFld, eCoreUnit); 3052 sal_uInt16 nMask = 1; 3053 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) 3054 { 3055 if(nActNumLvl & nMask) 3056 { 3057 SvxNumberFormat aNumFmt( pActNum->GetLevel( i ) ); 3058 if (&rFld == m_xDistBorderMF.get()) 3059 { 3060 3061 if (m_xRelativeCB->get_active()) 3062 { 3063 if(0 == i) 3064 { 3065 auto const nTmp = aNumFmt.GetFirstLineOffset(); 3066 aNumFmt.SetAbsLSpace( nValue - nTmp); 3067 } 3068 else 3069 { 3070 tools::Long nTmp = pActNum->GetLevel( i - 1 ).GetAbsLSpace() + 3071 pActNum->GetLevel( i - 1 ).GetFirstLineOffset() - 3072 pActNum->GetLevel( i ).GetFirstLineOffset(); 3073 3074 aNumFmt.SetAbsLSpace( nValue + nTmp); 3075 } 3076 } 3077 else 3078 { 3079 aNumFmt.SetAbsLSpace( nValue - aNumFmt.GetFirstLineOffset()); 3080 } 3081 } 3082 else if (&rFld == m_xDistNumMF.get()) 3083 { 3084 aNumFmt.SetCharTextDistance( static_cast<short>(nValue) ); 3085 } 3086 else if (&rFld == m_xIndentMF.get()) 3087 { 3088 // together with the FirstLineOffset the AbsLSpace must be changed, too 3089 tools::Long nDiff = nValue + aNumFmt.GetFirstLineOffset(); 3090 auto const nAbsLSpace = aNumFmt.GetAbsLSpace(); 3091 aNumFmt.SetAbsLSpace(nAbsLSpace + nDiff); 3092 aNumFmt.SetFirstLineOffset( -nValue ); 3093 } 3094 3095 pActNum->SetLevel( i, aNumFmt ); 3096 } 3097 nMask <<= 1; 3098 } 3099 3100 SetModified(); 3101 if (!m_xDistBorderMF->get_sensitive()) 3102 { 3103 m_xDistBorderMF->set_text(""); 3104 } 3105 } 3106 3107 IMPL_LINK(SvxNumPositionTabPage, RelativeHdl_Impl, weld::Toggleable&, rBox, void) 3108 { 3109 bool bOn = rBox.get_active(); 3110 bool bSingleSelection = m_xLevelLB->count_selected_rows() == 1 && SAL_MAX_UINT16 != nActNumLvl; 3111 bool bSetValue = false; 3112 tools::Long nValue = 0; 3113 if(bOn || bSingleSelection) 3114 { 3115 sal_uInt16 nMask = 1; 3116 bool bFirst = true; 3117 bSetValue = true; 3118 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) 3119 { 3120 if(nActNumLvl & nMask) 3121 { 3122 const SvxNumberFormat &rNumFmt = pActNum->GetLevel(i); 3123 if(bFirst) 3124 { 3125 nValue = rNumFmt.GetAbsLSpace() + rNumFmt.GetFirstLineOffset(); 3126 if(bOn && i) 3127 nValue -= (pActNum->GetLevel(i - 1).GetAbsLSpace() + pActNum->GetLevel(i - 1).GetFirstLineOffset()); 3128 } 3129 else 3130 bSetValue = nValue == 3131 (rNumFmt.GetAbsLSpace() + rNumFmt.GetFirstLineOffset()) - 3132 (pActNum->GetLevel(i - 1).GetAbsLSpace() + pActNum->GetLevel(i - 1).GetFirstLineOffset()); 3133 bFirst = false; 3134 } 3135 nMask <<= 1; 3136 } 3137 3138 } 3139 if(bSetValue) 3140 SetMetricValue(*m_xDistBorderMF, nValue, eCoreUnit); 3141 else 3142 m_xDistBorderMF->set_text(""); 3143 m_xDistBorderMF->set_sensitive(bOn || bSingleSelection); 3144 m_xDistBorderFT->set_sensitive(bOn || bSingleSelection); 3145 bLastRelative = bOn; 3146 } 3147 3148 IMPL_LINK_NOARG(SvxNumPositionTabPage, LabelFollowedByHdl_Impl, weld::ComboBox&, void) 3149 { 3150 // determine value to be set at the chosen list levels 3151 SvxNumberFormat::LabelFollowedBy eLabelFollowedBy = SvxNumberFormat::LISTTAB; 3152 { 3153 const auto nPos = m_xLabelFollowedByLB->get_active(); 3154 if ( nPos == 1 ) 3155 { 3156 eLabelFollowedBy = SvxNumberFormat::SPACE; 3157 } 3158 else if ( nPos == 2 ) 3159 { 3160 eLabelFollowedBy = SvxNumberFormat::NOTHING; 3161 } 3162 else if ( nPos == 3 ) 3163 { 3164 eLabelFollowedBy = SvxNumberFormat::NEWLINE; 3165 } 3166 } 3167 3168 // set value at the chosen list levels 3169 bool bSameListtabPos = true; 3170 sal_uInt16 nFirstLvl = SAL_MAX_UINT16; 3171 sal_uInt16 nMask = 1; 3172 for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i ) 3173 { 3174 if ( nActNumLvl & nMask ) 3175 { 3176 SvxNumberFormat aNumFmt( pActNum->GetLevel(i) ); 3177 aNumFmt.SetLabelFollowedBy( eLabelFollowedBy ); 3178 pActNum->SetLevel( i, aNumFmt ); 3179 3180 if ( nFirstLvl == SAL_MAX_UINT16 ) 3181 { 3182 nFirstLvl = i; 3183 } 3184 else 3185 { 3186 bSameListtabPos &= aNumFmt.GetListtabPos() == 3187 pActNum->GetLevel( nFirstLvl ).GetListtabPos(); 3188 } 3189 } 3190 nMask <<= 1; 3191 } 3192 3193 // enable/disable metric field for list tab stop position depending on 3194 // selected item following the list label. 3195 m_xListtabFT->set_sensitive( eLabelFollowedBy == SvxNumberFormat::LISTTAB ); 3196 m_xListtabMF->set_sensitive( eLabelFollowedBy == SvxNumberFormat::LISTTAB ); 3197 if ( bSameListtabPos && eLabelFollowedBy == SvxNumberFormat::LISTTAB ) 3198 { 3199 SetMetricValue(*m_xListtabMF, pActNum->GetLevel( nFirstLvl ).GetListtabPos(), eCoreUnit); 3200 } 3201 else 3202 { 3203 m_xListtabMF->set_text(OUString()); 3204 } 3205 3206 SetModified(); 3207 } 3208 3209 IMPL_LINK(SvxNumPositionTabPage, ListtabPosHdl_Impl, weld::MetricSpinButton&, rFld, void) 3210 { 3211 // determine value to be set at the chosen list levels 3212 const tools::Long nValue = GetCoreValue(rFld, eCoreUnit); 3213 3214 // set value at the chosen list levels 3215 sal_uInt16 nMask = 1; 3216 for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i ) 3217 { 3218 if ( nActNumLvl & nMask ) 3219 { 3220 SvxNumberFormat aNumFmt( pActNum->GetLevel(i) ); 3221 aNumFmt.SetListtabPos( nValue ); 3222 pActNum->SetLevel( i, aNumFmt ); 3223 } 3224 nMask <<= 1; 3225 } 3226 3227 SetModified(); 3228 } 3229 3230 IMPL_LINK(SvxNumPositionTabPage, AlignAtHdl_Impl, weld::MetricSpinButton&, rFld, void) 3231 { 3232 // determine value to be set at the chosen list levels 3233 const tools::Long nValue = GetCoreValue(rFld, eCoreUnit); 3234 3235 // set value at the chosen list levels 3236 sal_uInt16 nMask = 1; 3237 for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i ) 3238 { 3239 if ( nActNumLvl & nMask ) 3240 { 3241 SvxNumberFormat aNumFmt( pActNum->GetLevel(i) ); 3242 const tools::Long nFirstLineIndent = nValue - aNumFmt.GetIndentAt(); 3243 aNumFmt.SetFirstLineIndent( nFirstLineIndent ); 3244 pActNum->SetLevel( i, aNumFmt ); 3245 } 3246 nMask <<= 1; 3247 } 3248 3249 SetModified(); 3250 } 3251 3252 IMPL_LINK(SvxNumPositionTabPage, IndentAtHdl_Impl, weld::MetricSpinButton&, rFld, void) 3253 { 3254 // determine value to be set at the chosen list levels 3255 const tools::Long nValue = GetCoreValue(rFld, eCoreUnit); 3256 3257 // set value at the chosen list levels 3258 sal_uInt16 nMask = 1; 3259 for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i ) 3260 { 3261 if ( nActNumLvl & nMask ) 3262 { 3263 SvxNumberFormat aNumFmt( pActNum->GetLevel(i) ); 3264 const tools::Long nAlignedAt = aNumFmt.GetIndentAt() + 3265 aNumFmt.GetFirstLineIndent(); 3266 aNumFmt.SetIndentAt( nValue ); 3267 const tools::Long nNewFirstLineIndent = nAlignedAt - nValue; 3268 aNumFmt.SetFirstLineIndent( nNewFirstLineIndent ); 3269 pActNum->SetLevel( i, aNumFmt ); 3270 } 3271 nMask <<= 1; 3272 } 3273 3274 SetModified(); 3275 } 3276 3277 IMPL_LINK_NOARG(SvxNumPositionTabPage, StandardHdl_Impl, weld::Button&, void) 3278 { 3279 sal_uInt16 nMask = 1; 3280 SvxNumRule aTmpNumRule( pActNum->GetFeatureFlags(), 3281 pActNum->GetLevelCount(), 3282 pActNum->IsContinuousNumbering(), 3283 SvxNumRuleType::NUMBERING, 3284 pActNum->GetLevel( 0 ).GetPositionAndSpaceMode() ); 3285 for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) 3286 { 3287 if(nActNumLvl & nMask) 3288 { 3289 SvxNumberFormat aNumFmt( pActNum->GetLevel( i ) ); 3290 const SvxNumberFormat& aTempFmt(aTmpNumRule.GetLevel( i )); 3291 aNumFmt.SetPositionAndSpaceMode( aTempFmt.GetPositionAndSpaceMode() ); 3292 if ( aTempFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION ) 3293 { 3294 aNumFmt.SetAbsLSpace( aTempFmt.GetAbsLSpace() ); 3295 aNumFmt.SetCharTextDistance( aTempFmt.GetCharTextDistance() ); 3296 aNumFmt.SetFirstLineOffset( aTempFmt.GetFirstLineOffset() ); 3297 } 3298 else if ( aTempFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT ) 3299 { 3300 aNumFmt.SetNumAdjust( aTempFmt.GetNumAdjust() ); 3301 aNumFmt.SetLabelFollowedBy( aTempFmt.GetLabelFollowedBy() ); 3302 aNumFmt.SetListtabPos( aTempFmt.GetListtabPos() ); 3303 aNumFmt.SetFirstLineIndent( aTempFmt.GetFirstLineIndent() ); 3304 aNumFmt.SetIndentAt( aTempFmt.GetIndentAt() ); 3305 } 3306 3307 pActNum->SetLevel( i, aNumFmt ); 3308 } 3309 nMask <<= 1; 3310 } 3311 3312 InitControls(); 3313 SetModified(); 3314 } 3315 3316 void SvxNumPositionTabPage::SetModified() 3317 { 3318 bModified = true; 3319 m_aPreviewWIN.SetLevel(nActNumLvl); 3320 m_aPreviewWIN.Invalidate(); 3321 } 3322 3323 void SvxNumOptionsTabPage::SetModified(bool bRepaint) 3324 { 3325 bModified = true; 3326 if (bRepaint) 3327 { 3328 m_aPreviewWIN.SetLevel(nActNumLvl); 3329 m_aPreviewWIN.Invalidate(); 3330 } 3331 } 3332 3333 void SvxNumOptionsTabPage::PageCreated(const SfxAllItemSet& aSet) 3334 { 3335 const SfxStringListItem* pListItem = aSet.GetItem<SfxStringListItem>(SID_CHAR_FMT_LIST_BOX, false); 3336 const SfxStringItem* pNumCharFmt = aSet.GetItem<SfxStringItem>(SID_NUM_CHAR_FMT, false); 3337 const SfxStringItem* pBulletCharFmt = aSet.GetItem<SfxStringItem>(SID_BULLET_CHAR_FMT, false); 3338 const SfxUInt16Item* pMetricItem = aSet.GetItem<SfxUInt16Item>(SID_METRIC_ITEM, false); 3339 3340 if (pNumCharFmt &&pBulletCharFmt) 3341 SetCharFmts( pNumCharFmt->GetValue(),pBulletCharFmt->GetValue()); 3342 3343 if (pListItem) 3344 { 3345 const std::vector<OUString> &aList = pListItem->GetList(); 3346 sal_uInt32 nCount = aList.size(); 3347 for(sal_uInt32 i = 0; i < nCount; i++) 3348 m_xCharFmtLB->append_text(aList[i]); 3349 } 3350 if (pMetricItem) 3351 SetMetric(static_cast<FieldUnit>(pMetricItem->GetValue())); 3352 } 3353 3354 void SvxNumPositionTabPage::PageCreated(const SfxAllItemSet& aSet) 3355 { 3356 const SfxUInt16Item* pMetricItem = aSet.GetItem<SfxUInt16Item>(SID_METRIC_ITEM, false); 3357 3358 if (pMetricItem) 3359 SetMetric(static_cast<FieldUnit>(pMetricItem->GetValue())); 3360 } 3361 3362 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 3363
