1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 20 #include <sal/config.h> 21 22 #include <o3tl/safeint.hxx> 23 #include <svl/eitem.hxx> 24 #include <svl/intitem.hxx> 25 #include <sfx2/objsh.hxx> 26 #include <vcl/outdev.hxx> 27 #include <vcl/svapp.hxx> 28 #include <vcl/settings.hxx> 29 #include <i18nlangtag/lang.h> 30 #include <svx/svxids.hrc> 31 #include <svtools/colorcfg.hxx> 32 33 #include <numcategories.hrc> 34 #include <strings.hrc> 35 36 #include <svx/numinf.hxx> 37 38 #include <numfmt.hxx> 39 #include <svx/numfmtsh.hxx> 40 #include <dialmgr.hxx> 41 #include <sfx2/basedlgs.hxx> 42 #include <svx/flagsdef.hxx> 43 #include <vector> 44 #include <com/sun/star/frame/XModel.hpp> 45 #include <com/sun/star/lang/XServiceInfo.hpp> 46 #include <limits> 47 #include <memory> 48 49 using ::com::sun::star::uno::Reference; 50 using ::com::sun::star::lang::XServiceInfo; 51 using ::com::sun::star::uno::UNO_QUERY; 52 53 #define NUMKEY_UNDEFINED SAL_MAX_UINT32 54 55 // static ---------------------------------------------------------------- 56 57 const WhichRangesContainer SvxNumberFormatTabPage::pRanges( 58 svl::Items< 59 SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_INFO, 60 SID_ATTR_NUMBERFORMAT_ONE_AREA, SID_ATTR_NUMBERFORMAT_ONE_AREA, 61 SID_ATTR_NUMBERFORMAT_NOLANGUAGE, SID_ATTR_NUMBERFORMAT_NOLANGUAGE, 62 SID_ATTR_NUMBERFORMAT_SOURCE, SID_ATTR_NUMBERFORMAT_SOURCE>); 63 64 /************************************************************************* 65 #* Method: SvxNumberPreview 66 #*------------------------------------------------------------------------ 67 #* 68 #* Class: SvxNumberPreview 69 #* Function: Constructor of the class SvxNumberPreview 70 #* Input: Window, Resource-ID 71 #* Output: --- 72 #* 73 #************************************************************************/ 74 75 SvxNumberPreview::SvxNumberPreview() 76 : mnPos(-1) 77 , mnChar(0x0) 78 { 79 } 80 81 /************************************************************************* 82 #* Method: NotifyChange 83 #*------------------------------------------------------------------------ 84 #* 85 #* Class: SvxNumberPreview 86 #* Function: Function for changing the preview string 87 #* Input: String, color 88 #* Output: --- 89 #* 90 #************************************************************************/ 91 92 void SvxNumberPreview::NotifyChange( const OUString& rPrevStr, 93 const Color* pColor ) 94 { 95 // detect and strip out '*' related placeholders 96 aPrevStr = rPrevStr; 97 mnPos = aPrevStr.indexOf( 0x1B ); 98 if ( mnPos != -1 ) 99 { 100 // Right during user input the star symbol is the very 101 // last character before the user enters another one. 102 if (mnPos < aPrevStr.getLength() - 1) 103 { 104 mnChar = aPrevStr[ mnPos + 1 ]; 105 // delete placeholder and char to repeat 106 aPrevStr = aPrevStr.replaceAt( mnPos, 2, "" ); 107 } 108 else 109 { 110 // delete placeholder 111 aPrevStr = aPrevStr.replaceAt( mnPos, 1, "" ); 112 // do not attempt to draw a 0 fill character 113 mnPos = -1; 114 } 115 } 116 svtools::ColorConfig aColorConfig; 117 Color aWindowTextColor( aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor ); 118 aPrevCol = pColor ? *pColor : aWindowTextColor; 119 Invalidate(); 120 } 121 122 /************************************************************************* 123 #* Method: Paint 124 #*------------------------------------------------------------------------ 125 #* 126 #* Class: SvxNumberPreview 127 #* Function: Function for repainting the window. 128 #* Input: --- 129 #* Output: --- 130 #* 131 #************************************************************************/ 132 133 void SvxNumberPreview::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle&) 134 { 135 rRenderContext.Push(vcl::PushFlags::ALL); 136 137 svtools::ColorConfig aColorConfig; 138 rRenderContext.SetTextColor(aColorConfig.GetColorValue(svtools::FONTCOLOR).nColor); 139 rRenderContext.SetBackground(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor); 140 141 vcl::Font aDrawFont = rRenderContext.GetFont(); 142 Size aSzWnd(GetOutputSizePixel()); 143 OUString aTmpStr(aPrevStr); 144 tools::Long nLeadSpace = (aSzWnd.Width() - rRenderContext.GetTextWidth(aTmpStr)) / 2; 145 146 aDrawFont.SetTransparent(true); 147 aDrawFont.SetColor(aPrevCol); 148 rRenderContext.SetFont(aDrawFont); 149 150 if (mnPos != -1) 151 { 152 tools::Long nCharWidth = rRenderContext.GetTextWidth(OUString(mnChar)); 153 154 int nNumCharsToInsert = 0; 155 if (nCharWidth > 0) 156 nNumCharsToInsert = nLeadSpace / nCharWidth; 157 158 if (nNumCharsToInsert > 0) 159 { 160 for (int i = 0; i < nNumCharsToInsert; ++i) 161 aTmpStr = aTmpStr.replaceAt(mnPos, 0, OUString(mnChar)); 162 } 163 } 164 165 tools::Long nX = 0; 166 if (mnPos == -1 && nLeadSpace > 0) //tdf#122120 if it won't fit anyway, then left align it 167 { 168 nX = nLeadSpace; 169 } 170 171 Point aPosText(nX, (aSzWnd.Height() - GetTextHeight()) / 2); 172 rRenderContext.DrawText(aPosText, aTmpStr); 173 rRenderContext.Pop(); 174 } 175 176 // class SvxNumberFormatTabPage ------------------------------------------ 177 178 #define REMOVE_DONTKNOW() \ 179 if (!m_xFtLanguage->get_sensitive()) \ 180 { \ 181 m_xFtLanguage->set_sensitive(true); \ 182 m_xLbLanguage->set_sensitive(true); \ 183 m_xLbLanguage->set_active_id(pNumFmtShell->GetCurLanguage()); \ 184 } 185 186 SvxNumberFormatTabPage::SvxNumberFormatTabPage(weld::Container* pPage, weld::DialogController* pController, 187 const SfxItemSet& rCoreAttrs) 188 : SfxTabPage(pPage, pController, "cui/ui/numberingformatpage.ui", "NumberingFormatPage", &rCoreAttrs) 189 , nInitFormat(std::numeric_limits<sal_uInt32>::max()) 190 , m_nLbFormatSelPosEdComment(SELPOS_NONE) 191 , bLegacyAutomaticCurrency(false) 192 , sAutomaticLangEntry(CuiResId(RID_SVXSTR_AUTO_ENTRY)) 193 , m_xFtCategory(m_xBuilder->weld_label("categoryft")) 194 , m_xLbCategory(m_xBuilder->weld_tree_view("categorylb")) 195 , m_xFtFormat(m_xBuilder->weld_label("formatft")) 196 , m_xLbCurrency(m_xBuilder->weld_combo_box("currencylb")) 197 , m_xLbFormat(m_xBuilder->weld_tree_view("formatlb")) 198 , m_xFtLanguage(m_xBuilder->weld_label("languageft")) 199 , m_xCbSourceFormat(m_xBuilder->weld_check_button("sourceformat")) 200 , m_xFtOptions(m_xBuilder->weld_label("optionsft")) 201 , m_xFtDecimals(m_xBuilder->weld_label("decimalsft")) 202 , m_xEdDecimals(m_xBuilder->weld_spin_button("decimalsed")) 203 , m_xFtDenominator(m_xBuilder->weld_label("denominatorft")) 204 , m_xEdDenominator(m_xBuilder->weld_spin_button("denominatored")) 205 , m_xBtnNegRed(m_xBuilder->weld_check_button("negnumred")) 206 , m_xFtLeadZeroes(m_xBuilder->weld_label("leadzerosft")) 207 , m_xEdLeadZeroes(m_xBuilder->weld_spin_button("leadzerosed")) 208 , m_xBtnThousand(m_xBuilder->weld_check_button("thousands")) 209 , m_xBtnEngineering(m_xBuilder->weld_check_button("engineering")) 210 , m_xFormatCodeFrame(m_xBuilder->weld_widget("formatcode")) 211 , m_xEdFormat(m_xBuilder->weld_entry("formatted")) 212 , m_xIbAdd(m_xBuilder->weld_button("add")) 213 , m_xIbInfo(m_xBuilder->weld_button("edit")) 214 , m_xIbRemove(m_xBuilder->weld_button("delete")) 215 , m_xFtComment(m_xBuilder->weld_label("commentft")) 216 , m_xEdComment(m_xBuilder->weld_entry("commented")) 217 , m_xLbLanguage(new SvxLanguageBox(m_xBuilder->weld_combo_box("languagelb"))) 218 , m_xWndPreview(new weld::CustomWeld(*m_xBuilder, "preview", m_aWndPreview)) 219 { 220 for (size_t i = 0; i < SAL_N_ELEMENTS(NUM_CATEGORIES); ++i) 221 m_xLbCategory->append_text(CuiResId(NUM_CATEGORIES[i])); 222 223 auto nWidth = m_xLbCategory->get_approximate_digit_width() * 22; 224 m_xLbCategory->set_size_request(nWidth, m_xLbCategory->get_height_rows(7)); 225 m_xLbFormat->set_size_request(nWidth, m_xLbFormat->get_height_rows(5)); 226 m_xLbCurrency->set_size_request(nWidth, -1); // force using (narrower) width of its LbFormat sibling 227 228 // Initially remove the "Automatically" entry. 229 m_xLbCurrency->set_active(-1); // First ensure that nothing is selected. 230 sAutomaticCurrencyEntry = m_xLbCurrency->get_text(0); 231 m_xLbCurrency->remove(0); 232 233 Init_Impl(); 234 SetExchangeSupport(); // this page needs ExchangeSupport 235 nFixedCategory=-1; 236 } 237 238 SvxNumberFormatTabPage::~SvxNumberFormatTabPage() 239 { 240 pNumFmtShell.reset(); 241 pNumItem.reset(); 242 m_xWndPreview.reset(); 243 m_xLbLanguage.reset(); 244 } 245 246 void SvxNumberFormatTabPage::Init_Impl() 247 { 248 bNumItemFlag=true; 249 bOneAreaFlag=false; 250 251 m_xIbAdd->set_sensitive(false ); 252 m_xIbRemove->set_sensitive(false ); 253 m_xIbInfo->set_sensitive(false ); 254 255 m_xEdComment->set_text(m_xLbCategory->get_text(1)); // string for user defined 256 257 m_xEdComment->hide(); 258 259 m_xCbSourceFormat->set_active( false ); 260 m_xCbSourceFormat->set_sensitive(false); 261 m_xCbSourceFormat->hide(); 262 263 Link<weld::TreeView&,void> aLink2 = LINK(this, SvxNumberFormatTabPage, SelFormatTreeListBoxHdl_Impl); 264 Link<weld::ComboBox&,void> aLink3 = LINK(this, SvxNumberFormatTabPage, SelFormatListBoxHdl_Impl); 265 m_xLbCategory->connect_changed(aLink2); 266 m_xLbCategory->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl)); 267 m_xLbFormat->connect_changed(aLink2); 268 m_xLbFormat->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl)); 269 m_xLbLanguage->connect_changed(aLink3); 270 m_xLbLanguage->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl)); 271 m_xLbCurrency->connect_changed(aLink3); 272 m_xLbCurrency->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl)); 273 m_xCbSourceFormat->connect_toggled(LINK(this, SvxNumberFormatTabPage, SelFormatClickHdl_Impl)); 274 m_xCbSourceFormat->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl)); 275 276 Link<weld::SpinButton&,void> aLink = LINK( this, SvxNumberFormatTabPage, OptEditHdl_Impl ); 277 278 m_xEdDecimals->connect_value_changed(aLink); 279 m_xEdDecimals->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl)); 280 m_xEdDenominator->connect_value_changed(aLink); 281 m_xEdDenominator->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl)); 282 m_xEdLeadZeroes->connect_value_changed(aLink); 283 m_xEdLeadZeroes->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl)); 284 285 m_xBtnNegRed->connect_toggled(LINK(this, SvxNumberFormatTabPage, OptClickHdl_Impl)); 286 m_xBtnNegRed->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl)); 287 m_xBtnThousand->connect_toggled(LINK(this, SvxNumberFormatTabPage, OptClickHdl_Impl)); 288 m_xBtnThousand->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl)); 289 m_xBtnEngineering->connect_toggled(LINK(this, SvxNumberFormatTabPage, OptClickHdl_Impl)); 290 m_xBtnEngineering->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl)); 291 m_xLbFormat->connect_row_activated(LINK(this, SvxNumberFormatTabPage, DoubleClickHdl_Impl)); 292 m_xEdFormat->connect_changed(LINK(this, SvxNumberFormatTabPage, EditModifyHdl_Impl)); 293 m_xEdFormat->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl)); 294 m_xIbAdd->connect_clicked(LINK(this, SvxNumberFormatTabPage, ClickHdl_Impl)); 295 m_xIbAdd->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl)); 296 m_xIbRemove->connect_clicked(LINK(this, SvxNumberFormatTabPage, ClickHdl_Impl)); 297 m_xIbRemove->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl)); 298 m_xIbInfo->connect_clicked(LINK(this, SvxNumberFormatTabPage, ClickHdl_Impl)); 299 UpdateThousandEngineeringCheckBox(); 300 UpdateDecimalsDenominatorEditBox(); 301 302 // initialize language ListBox 303 304 m_xLbLanguage->SetLanguageList(SvxLanguageListFlags::ALL | SvxLanguageListFlags::ONLY_KNOWN, 305 false, false, false, true, LANGUAGE_SYSTEM, 306 css::i18n::ScriptType::WEAK); 307 } 308 309 std::unique_ptr<SfxTabPage> SvxNumberFormatTabPage::Create( weld::Container* pPage, weld::DialogController* pController, 310 const SfxItemSet* rAttrSet ) 311 { 312 return std::make_unique<SvxNumberFormatTabPage>(pPage, pController, *rAttrSet); 313 } 314 315 316 /************************************************************************* 317 #* Method: Reset 318 #*------------------------------------------------------------------------ 319 #* 320 #* Class: SvxNumberFormatTabPage 321 #* Function: The dialog's attributes are reset 322 #* using the Itemset. 323 #* Input: SfxItemSet 324 #* Output: --- 325 #* 326 #************************************************************************/ 327 328 void SvxNumberFormatTabPage::set_active_currency(sal_Int32 nPos) 329 { 330 static_assert(SELPOS_NONE == -1, "SELPOS_NONE was -1 at time of writing"); 331 if (nPos == 0 && !bLegacyAutomaticCurrency) 332 { 333 // Insert "Automatically" if currently used so it is selectable. 334 m_xLbCurrency->insert_text(0, sAutomaticCurrencyEntry); 335 bLegacyAutomaticCurrency = true; 336 } 337 if (nPos != -1 && !bLegacyAutomaticCurrency) 338 --nPos; 339 m_xLbCurrency->set_active(nPos); 340 } 341 342 sal_uInt32 SvxNumberFormatTabPage::get_active_currency() const 343 { 344 static_assert(SELPOS_NONE == -1, "SELPOS_NONE was -1 at time of writing"); 345 sal_Int32 nCurrencyPos = m_xLbCurrency->get_active(); 346 if (nCurrencyPos != -1 && !bLegacyAutomaticCurrency) 347 ++nCurrencyPos; 348 return nCurrencyPos; 349 } 350 351 void SvxNumberFormatTabPage::Reset( const SfxItemSet* rSet ) 352 { 353 const SfxUInt32Item* pValFmtAttr = nullptr; 354 const SfxPoolItem* pItem = nullptr; 355 const SfxBoolItem* pAutoEntryAttr = nullptr; 356 357 sal_uInt16 nCatLbSelPos = 0; 358 sal_uInt16 nFmtLbSelPos = 0; 359 LanguageType eLangType = LANGUAGE_DONTKNOW; 360 std::vector<OUString> aFmtEntryList; 361 SvxNumberValueType eValType = SvxNumberValueType::Undefined; 362 double nValDouble = 0; 363 OUString aValString; 364 365 SfxItemState eState = rSet->GetItemState( GetWhich( SID_ATTR_NUMBERFORMAT_NOLANGUAGE ),true,&pItem); 366 367 if(eState==SfxItemState::SET) 368 { 369 const SfxBoolItem* pBoolLangItem = static_cast<const SfxBoolItem*>( 370 GetItem( *rSet, SID_ATTR_NUMBERFORMAT_NOLANGUAGE)); 371 372 if(pBoolLangItem!=nullptr && pBoolLangItem->GetValue()) 373 { 374 HideLanguage(); 375 } 376 else 377 { 378 HideLanguage(false); 379 } 380 381 } 382 383 eState = rSet->GetItemState( GetWhich( SID_ATTR_NUMBERFORMAT_INFO ),true,&pItem); 384 385 if(eState==SfxItemState::SET) 386 { 387 if(pNumItem==nullptr) 388 { 389 bNumItemFlag=true; 390 pNumItem.reset( static_cast<SvxNumberInfoItem *>(pItem->Clone()) ); 391 } 392 else 393 { 394 bNumItemFlag=false; 395 } 396 } 397 else 398 { 399 bNumItemFlag=false; 400 } 401 402 403 eState = rSet->GetItemState( GetWhich( SID_ATTR_NUMBERFORMAT_ONE_AREA )); 404 405 if(eState==SfxItemState::SET) 406 { 407 const SfxBoolItem* pBoolItem = static_cast<const SfxBoolItem*>( 408 GetItem( *rSet, SID_ATTR_NUMBERFORMAT_ONE_AREA)); 409 410 if(pBoolItem!=nullptr) 411 { 412 bOneAreaFlag= pBoolItem->GetValue(); 413 } 414 } 415 416 eState = rSet->GetItemState( GetWhich( SID_ATTR_NUMBERFORMAT_SOURCE ) ); 417 418 if ( eState == SfxItemState::SET ) 419 { 420 const SfxBoolItem* pBoolItem = static_cast<const SfxBoolItem*>( 421 GetItem( *rSet, SID_ATTR_NUMBERFORMAT_SOURCE )); 422 if ( pBoolItem ) 423 m_xCbSourceFormat->set_active(pBoolItem->GetValue()); 424 else 425 m_xCbSourceFormat->set_active( false ); 426 m_xCbSourceFormat->set_sensitive(true); 427 m_xCbSourceFormat->show(); 428 } 429 else 430 { 431 bool bInit = false; // set to sal_True for debug test 432 m_xCbSourceFormat->set_active( bInit ); 433 m_xCbSourceFormat->set_sensitive( bInit ); 434 m_xCbSourceFormat->set_visible( bInit ); 435 } 436 437 // pNumItem must have been set from outside! 438 DBG_ASSERT( pNumItem, "No NumberInfo, no NumberFormatter, goodbye. CRASH. :-(" ); 439 440 eState = rSet->GetItemState( GetWhich( SID_ATTR_NUMBERFORMAT_VALUE ) ); 441 442 if ( SfxItemState::DONTCARE != eState ) 443 pValFmtAttr = GetItem( *rSet, SID_ATTR_NUMBERFORMAT_VALUE ); 444 445 eValType = pNumItem->GetValueType(); 446 447 switch ( eValType ) 448 { 449 case SvxNumberValueType::String: 450 aValString = pNumItem->GetValueString(); 451 break; 452 case SvxNumberValueType::Number: 453 // #50441# string may be set in addition to the value 454 aValString = pNumItem->GetValueString(); 455 nValDouble = pNumItem->GetValueDouble(); 456 break; 457 case SvxNumberValueType::Undefined: 458 default: 459 break; 460 } 461 462 pNumFmtShell.reset(); // delete old shell if applicable (== reset) 463 464 nInitFormat = pValFmtAttr // memorize init key 465 ? pValFmtAttr->GetValue() // (for FillItemSet()) 466 : std::numeric_limits<sal_uInt32>::max(); // == DONT_KNOW 467 468 469 if ( eValType == SvxNumberValueType::String ) 470 pNumFmtShell.reset( SvxNumberFormatShell::Create( 471 pNumItem->GetNumberFormatter(), 472 pValFmtAttr ? nInitFormat : 0, 473 eValType, 474 aValString ) ); 475 else 476 pNumFmtShell.reset( SvxNumberFormatShell::Create( 477 pNumItem->GetNumberFormatter(), 478 pValFmtAttr ? nInitFormat : 0, 479 eValType, 480 nValDouble, 481 &aValString ) ); 482 483 484 bool bUseStarFormat = false; 485 SfxObjectShell* pDocSh = SfxObjectShell::Current(); 486 if ( pDocSh ) 487 { 488 // is this a calc document 489 Reference< XServiceInfo > xSI( pDocSh->GetModel(), UNO_QUERY ); 490 if ( xSI.is() ) 491 bUseStarFormat = xSI->supportsService("com.sun.star.sheet.SpreadsheetDocument"); 492 } 493 pNumFmtShell->SetUseStarFormat( bUseStarFormat ); 494 495 FillCurrencyBox(); 496 497 OUString aPrevString; 498 const Color* pDummy = nullptr; 499 pNumFmtShell->GetInitSettings( nCatLbSelPos, eLangType, nFmtLbSelPos, 500 aFmtEntryList, aPrevString, pDummy ); 501 502 if (nCatLbSelPos==CAT_CURRENCY) 503 set_active_currency(pNumFmtShell->GetCurrencySymbol()); 504 505 nFixedCategory=nCatLbSelPos; 506 if(bOneAreaFlag) 507 { 508 OUString sFixedCategory = m_xLbCategory->get_text(nFixedCategory); 509 m_xLbCategory->clear(); 510 m_xLbCategory->append_text(sFixedCategory); 511 SetCategory(0); 512 } 513 else 514 { 515 SetCategory(nCatLbSelPos ); 516 } 517 eState = rSet->GetItemState( GetWhich( SID_ATTR_NUMBERFORMAT_ADD_AUTO ) ); 518 if(SfxItemState::SET == eState) 519 pAutoEntryAttr = static_cast<const SfxBoolItem*>( 520 GetItem( *rSet, SID_ATTR_NUMBERFORMAT_ADD_AUTO )); 521 // no_NO is an alias for nb_NO and normally isn't listed, we need it for 522 // backwards compatibility, but only if the format passed is of 523 // LanguageType no_NO. 524 if ( eLangType == LANGUAGE_NORWEGIAN ) 525 { 526 m_xLbLanguage->remove_id(eLangType); // in case we're already called 527 m_xLbLanguage->InsertLanguage( eLangType ); 528 } 529 m_xLbLanguage->set_active_id(eLangType); 530 if(pAutoEntryAttr) 531 AddAutomaticLanguage_Impl(eLangType, pAutoEntryAttr->GetValue()); 532 UpdateFormatListBox_Impl(false,true); 533 534 //! This spoils everything because it rematches currency formats based on 535 //! the selected m_xLbCurrency entry instead of the current format. 536 //! Besides that everything seems to be initialized by now, so why call it? 537 // SelFormatHdl_Impl(m_xLbCategory.get()); 538 539 if ( pValFmtAttr ) 540 { 541 EditHdl_Impl(m_xEdFormat.get()); // UpdateOptions_Impl() as a side effect 542 } 543 else // DONT_KNOW 544 { 545 // everything disabled except direct input or changing the category 546 Obstructing(); 547 } 548 549 if ( m_xCbSourceFormat->get_active() ) 550 { 551 // everything disabled except SourceFormat checkbox 552 EnableBySourceFormat_Impl(); 553 } 554 } 555 556 /************************************************************************* 557 #* Method: Obstructing 558 #*------------------------------------------------------------------------ 559 #* 560 #* Class: SvxNumberFormatTabPage 561 #* Function: Disable the controls except from changing the category 562 #* and direct input. 563 #* Input: --- 564 #* Output: --- 565 #* 566 #************************************************************************/ 567 void SvxNumberFormatTabPage::Obstructing() 568 { 569 m_xLbFormat->select(-1); 570 m_xLbLanguage->set_active(-1); 571 m_xFtLanguage->set_sensitive(false); 572 m_xLbLanguage->set_sensitive(false); 573 574 m_xIbAdd->set_sensitive(false ); 575 m_xIbRemove->set_sensitive(false ); 576 m_xIbInfo->set_sensitive(false ); 577 578 m_xBtnNegRed->set_sensitive(false); 579 m_xBtnThousand->set_sensitive(false); 580 m_xBtnEngineering->set_sensitive(false); 581 m_xFtLeadZeroes->set_sensitive(false); 582 m_xFtDecimals->set_sensitive(false); 583 m_xFtDenominator->set_sensitive(false); 584 m_xEdLeadZeroes->set_sensitive(false); 585 m_xEdDecimals->set_sensitive(false); 586 m_xEdDenominator->set_sensitive(false); 587 m_xFtOptions->set_sensitive(false); 588 m_xEdDecimals->set_text( OUString() ); 589 m_xEdLeadZeroes->set_text( OUString() ); 590 m_xBtnNegRed->set_active( false ); 591 m_xBtnThousand->set_active( false ); 592 m_xBtnEngineering->set_active( false ); 593 m_aWndPreview.NotifyChange( OUString() ); 594 595 m_xLbCategory->select(0); 596 m_xEdFormat->set_text( OUString() ); 597 m_xFtComment->set_label( OUString() ); 598 m_xEdComment->set_text(m_xLbCategory->get_text(1)); // string for user defined 599 600 m_xEdFormat->grab_focus(); 601 } 602 603 604 /************************************************************************* 605 #* Enable/Disable dialog parts depending on the value of the SourceFormat 606 #* checkbox. 607 #************************************************************************/ 608 void SvxNumberFormatTabPage::EnableBySourceFormat_Impl() 609 { 610 bool bEnable = !m_xCbSourceFormat->get_active(); 611 if ( !bEnable ) 612 m_xCbSourceFormat->grab_focus(); 613 m_xFtCategory->set_sensitive( bEnable ); 614 m_xLbCategory->set_sensitive( bEnable ); 615 m_xFtFormat->set_sensitive( bEnable ); 616 m_xLbCurrency->set_sensitive( bEnable ); 617 m_xLbFormat->set_sensitive( bEnable ); 618 m_xFtLanguage->set_sensitive( bEnable ); 619 m_xLbLanguage->set_sensitive( bEnable ); 620 m_xFtDecimals->set_sensitive( bEnable ); 621 m_xEdDecimals->set_sensitive( bEnable ); 622 m_xFtDenominator->set_sensitive( bEnable ); 623 m_xEdDenominator->set_sensitive( bEnable ); 624 m_xFtLeadZeroes->set_sensitive( bEnable ); 625 m_xEdLeadZeroes->set_sensitive( bEnable ); 626 m_xBtnNegRed->set_sensitive( bEnable ); 627 m_xBtnThousand->set_sensitive( bEnable ); 628 m_xBtnEngineering->set_sensitive( bEnable ); 629 m_xFtOptions->set_sensitive( bEnable ); 630 m_xFormatCodeFrame->set_sensitive( bEnable ); 631 } 632 633 634 /************************************************************************* 635 #* Method: HideLanguage 636 #*------------------------------------------------------------------------ 637 #* 638 #* Class: SvxNumberFormatTabPage 639 #* Function: Hides the language settings: 640 #* Input: sal_Bool nFlag 641 #* Output: --- 642 #* 643 #************************************************************************/ 644 645 void SvxNumberFormatTabPage::HideLanguage(bool bFlag) 646 { 647 m_xFtLanguage->set_visible(!bFlag); 648 m_xLbLanguage->set_visible(!bFlag); 649 } 650 651 /************************************************************************* 652 #* Method: FillItemSet 653 #*------------------------------------------------------------------------ 654 #* 655 #* Class: SvxNumberFormatTabPage 656 #* Function: Adjusts the attributes in the ItemSet, 657 #* and - if bNumItemFlag is not set - the 658 #* numItem in the DocShell. 659 #* Input: SfxItemSet 660 #* Output: --- 661 #* 662 #************************************************************************/ 663 664 bool SvxNumberFormatTabPage::FillItemSet( SfxItemSet* rCoreAttrs ) 665 { 666 bool bDataChanged = m_xFtLanguage->get_sensitive() || m_xCbSourceFormat->get_sensitive(); 667 if ( bDataChanged ) 668 { 669 const SfxItemSet& rMyItemSet = GetItemSet(); 670 sal_uInt16 nWhich = GetWhich( SID_ATTR_NUMBERFORMAT_VALUE ); 671 SfxItemState eItemState = rMyItemSet.GetItemState( nWhich, false ); 672 673 // OK chosen - Is format code input entered already taken over? 674 // If not, simulate Add. Upon syntax error ignore input and prevent Put. 675 OUString aFormat = m_xEdFormat->get_text(); 676 sal_uInt32 nCurKey = pNumFmtShell->GetCurNumFmtKey(); 677 678 if ( m_xIbAdd->get_sensitive() || pNumFmtShell->IsTmpCurrencyFormat(aFormat) ) 679 { // #79599# It is not sufficient to just add the format code (or 680 // delete it in case of bOneAreaFlag and resulting category change). 681 // Upon switching tab pages we need all settings to be consistent 682 // in case this page will be redisplayed later. 683 bDataChanged = Click_Impl(*m_xIbAdd); 684 nCurKey = pNumFmtShell->GetCurNumFmtKey(); 685 } 686 else if(nCurKey == NUMKEY_UNDEFINED) 687 { // something went wrong, e.g. in Writer #70281# 688 pNumFmtShell->FindEntry(aFormat, &nCurKey); 689 } 690 691 692 // Chosen format: 693 694 if ( bDataChanged ) 695 { 696 bDataChanged = ( nInitFormat != nCurKey ); 697 698 if (bDataChanged) 699 { 700 rCoreAttrs->Put( SfxUInt32Item( nWhich, nCurKey ) ); 701 } 702 else if(SfxItemState::DEFAULT == eItemState) 703 { 704 rCoreAttrs->ClearItem( nWhich ); 705 } 706 } 707 708 709 // List of changed user defined formats: 710 711 std::vector<sal_uInt32> const & aDelFormats = pNumFmtShell->GetUpdateData(); 712 713 if ( !aDelFormats.empty() ) 714 { 715 716 pNumItem->SetDelFormats( std::vector(aDelFormats) ); 717 718 if(bNumItemFlag) 719 { 720 rCoreAttrs->Put( *pNumItem ); 721 } 722 else 723 { 724 SfxObjectShell* pDocSh = SfxObjectShell::Current(); 725 726 DBG_ASSERT( pDocSh, "DocShell not found!" ); 727 728 729 if ( pDocSh ) 730 pDocSh->PutItem( *pNumItem ); 731 } 732 } 733 734 735 // Whether source format is to be taken or not: 736 737 if ( m_xCbSourceFormat->get_sensitive() ) 738 { 739 sal_uInt16 _nWhich = GetWhich( SID_ATTR_NUMBERFORMAT_SOURCE ); 740 SfxItemState _eItemState = rMyItemSet.GetItemState( _nWhich, false ); 741 const SfxBoolItem* pBoolItem = static_cast<const SfxBoolItem*>( 742 GetItem( rMyItemSet, SID_ATTR_NUMBERFORMAT_SOURCE )); 743 bool bOld = pBoolItem && pBoolItem->GetValue(); 744 rCoreAttrs->Put( SfxBoolItem( _nWhich, m_xCbSourceFormat->get_active() ) ); 745 if ( !bDataChanged ) 746 bDataChanged = (bOld != m_xCbSourceFormat->get_active() || 747 _eItemState != SfxItemState::SET); 748 } 749 750 // FillItemSet is only called on OK, here we can notify the 751 // NumberFormatShell that all new user defined formats are valid. 752 pNumFmtShell->ValidateNewEntries(); 753 if(m_xLbLanguage->get_visible() && 754 m_xLbLanguage->find_text(sAutomaticLangEntry) != -1) 755 rCoreAttrs->Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_ADD_AUTO, 756 m_xLbLanguage->get_active_text() == sAutomaticLangEntry)); 757 } 758 759 return bDataChanged; 760 } 761 762 763 DeactivateRC SvxNumberFormatTabPage::DeactivatePage( SfxItemSet* _pSet ) 764 { 765 if ( _pSet ) 766 FillItemSet( _pSet ); 767 return DeactivateRC::LeavePage; 768 } 769 770 void SvxNumberFormatTabPage::FillFormatListBox_Impl( std::vector<OUString>& rEntries ) 771 { 772 OUString aEntry; 773 OUString aTmpString; 774 size_t i = 0; 775 short nTmpCatPos; 776 777 m_xLbFormat->clear(); 778 if (rEntries.empty()) 779 return; 780 781 m_xLbFormat->freeze(); 782 783 if(bOneAreaFlag) 784 { 785 nTmpCatPos=nFixedCategory; 786 } 787 else 788 { 789 nTmpCatPos=m_xLbCategory->get_selected_index(); 790 } 791 792 switch (nTmpCatPos) 793 { 794 case CAT_ALL: 795 case CAT_TEXT: 796 case CAT_NUMBER: i=1; 797 aEntry=rEntries[0]; 798 if (nTmpCatPos == CAT_TEXT) 799 aTmpString=aEntry; 800 else 801 aTmpString = pNumFmtShell->GetStandardName(); 802 m_xLbFormat->append_text(aTmpString); 803 break; 804 805 default: break; 806 } 807 808 if(pNumFmtShell!=nullptr) 809 { 810 for ( ; i < rEntries.size(); ++i ) 811 { 812 aEntry = rEntries[i]; 813 short aPrivCat = pNumFmtShell->GetCategory4Entry( static_cast<short>(i) ); 814 if(aPrivCat!=CAT_TEXT) 815 { 816 const Color* pPreviewColor = nullptr; 817 OUString aPreviewString( GetExpColorString( pPreviewColor, aEntry, aPrivCat ) ); 818 m_xLbFormat->append_text(aPreviewString); 819 if (pPreviewColor) 820 m_xLbFormat->set_font_color(m_xLbFormat->n_children() - 1, *pPreviewColor); 821 } 822 else 823 { 824 m_xLbFormat->append_text(aEntry); 825 } 826 } 827 } 828 m_xLbFormat->thaw(); 829 rEntries.clear(); 830 } 831 832 /************************************************************************* 833 #* Method: UpdateOptions_Impl 834 #*------------------------------------------------------------------------ 835 #* 836 #* Class: SvxNumberFormatTabPage 837 #* Function: Adjusts the options attributes 838 #* depending on the selected format. 839 #* Input: Flag, whether the category has changed. 840 #* Output: --- 841 #* 842 #************************************************************************/ 843 844 void SvxNumberFormatTabPage::UpdateOptions_Impl( bool bCheckCatChange /*= sal_False*/ ) 845 { 846 OUString theFormat = m_xEdFormat->get_text(); 847 sal_Int32 nCurCategory = m_xLbCategory->get_selected_index(); 848 sal_uInt16 nCategory = static_cast<sal_uInt16>(nCurCategory); 849 sal_uInt16 nDecimals = 0; 850 sal_uInt16 nZeroes = 0; 851 bool bNegRed = false; 852 bool bThousand = false; 853 sal_Int32 nCurrencyPos = get_active_currency(); 854 855 if(bOneAreaFlag) 856 nCurCategory=nFixedCategory; 857 858 859 pNumFmtShell->GetOptions( theFormat, 860 bThousand, bNegRed, 861 nDecimals, nZeroes, 862 nCategory ); 863 bool bDoIt=false; 864 if(nCategory==CAT_CURRENCY) 865 { 866 sal_uInt16 nTstPos=pNumFmtShell->FindCurrencyFormat(theFormat); 867 if(nCurrencyPos!=static_cast<sal_Int32>(nTstPos) && nTstPos!=sal_uInt16(-1)) 868 { 869 set_active_currency(nTstPos); 870 pNumFmtShell->SetCurrencySymbol(nTstPos); 871 bDoIt=true; 872 } 873 } 874 875 if ( nCategory != nCurCategory || bDoIt) 876 { 877 if ( bCheckCatChange ) 878 { 879 if(bOneAreaFlag) 880 SetCategory(0); 881 else 882 SetCategory(nCategory ); 883 884 UpdateFormatListBox_Impl( true, false ); 885 } 886 } 887 else if ( m_xLbFormat->n_children() > 0 ) 888 { 889 sal_uInt32 nCurEntryKey=NUMKEY_UNDEFINED; 890 if(!pNumFmtShell->FindEntry( m_xEdFormat->get_text(),&nCurEntryKey)) 891 { 892 m_xLbFormat->select(-1); 893 } 894 } 895 if(bOneAreaFlag) 896 { 897 nCategory=nFixedCategory; 898 } 899 900 UpdateThousandEngineeringCheckBox(); 901 UpdateDecimalsDenominatorEditBox(); 902 switch ( nCategory ) 903 { 904 case CAT_SCIENTIFIC: // bThousand is for Engineering notation 905 { 906 sal_uInt16 nIntDigits = pNumFmtShell->GetFormatIntegerDigits(theFormat); 907 bThousand = (nIntDigits > 0) && (nIntDigits % 3 == 0); 908 m_xBtnEngineering->set_sensitive(true); 909 m_xBtnEngineering->set_active( bThousand ); 910 } 911 [[fallthrough]]; 912 case CAT_NUMBER: 913 case CAT_PERCENT: 914 case CAT_CURRENCY: 915 case CAT_FRACTION: 916 case CAT_TIME: 917 m_xFtOptions->set_sensitive(true); 918 if ( nCategory == CAT_FRACTION ) 919 { 920 m_xFtDenominator->set_sensitive(true); 921 m_xEdDenominator->set_sensitive(true); 922 } 923 else 924 { 925 m_xFtDecimals->set_sensitive(true); 926 m_xEdDecimals->set_sensitive(true); 927 } 928 m_xFtLeadZeroes->set_sensitive( nCategory != CAT_TIME ); 929 m_xEdLeadZeroes->set_sensitive( nCategory != CAT_TIME ); 930 m_xBtnNegRed->set_sensitive(true); 931 if ( nCategory == CAT_NUMBER && m_xLbFormat->get_selected_index() == 0 ) 932 m_xEdDecimals->set_text( "" ); //General format tdf#44399 933 else 934 if ( nCategory == CAT_FRACTION ) 935 m_xEdDenominator->set_value( nDecimals ); 936 else 937 m_xEdDecimals->set_value( nDecimals ); 938 if ( nCategory != CAT_TIME ) 939 m_xEdLeadZeroes->set_value( nZeroes ); 940 m_xBtnNegRed->set_active( bNegRed ); 941 if ( nCategory != CAT_SCIENTIFIC ) 942 { 943 m_xBtnThousand->set_sensitive( nCategory != CAT_TIME ); 944 m_xBtnThousand->set_active( bThousand && nCategory != CAT_TIME ); 945 } 946 break; 947 948 case CAT_ALL: 949 case CAT_USERDEFINED: 950 case CAT_TEXT: 951 case CAT_DATE: 952 case CAT_BOOLEAN: 953 default: 954 m_xFtOptions->set_sensitive(false); 955 m_xFtDecimals->set_sensitive(false); 956 m_xEdDecimals->set_sensitive(false); 957 m_xFtDenominator->set_sensitive(false); 958 m_xEdDenominator->set_sensitive(false); 959 m_xFtLeadZeroes->set_sensitive(false); 960 m_xEdLeadZeroes->set_sensitive(false); 961 m_xBtnNegRed->set_sensitive(false); 962 m_xBtnThousand->set_sensitive(false); 963 m_xBtnEngineering->set_sensitive(false); 964 m_xEdDecimals->set_text( OUString() ); 965 m_xEdLeadZeroes->set_text( OUString() ); 966 m_xBtnNegRed->set_active( false ); 967 m_xBtnThousand->set_active( false ); 968 m_xBtnEngineering->set_active( false ); 969 } 970 } 971 972 973 /************************************************************************* 974 #* Method: UpdateFormatListBox_Impl 975 #*------------------------------------------------------------------------ 976 #* 977 #* Class: SvxNumberFormatTabPage 978 #* Function: Updates the format listbox and additionally the 979 #* string in the editbox is changed depending on 980 #* the bUpdateEdit flag. 981 #* Input: Flags for category and editbox. 982 #* Output: --- 983 #* 984 #************************************************************************/ 985 986 void SvxNumberFormatTabPage::UpdateFormatListBox_Impl 987 ( 988 bool bCat, // Category or country/language ListBox? 989 bool bUpdateEdit 990 ) 991 { 992 std::vector<OUString> aEntryList; 993 short nFmtLbSelPos = 0; 994 short nTmpCatPos; 995 996 if(bOneAreaFlag) 997 { 998 nTmpCatPos=nFixedCategory; 999 } 1000 else 1001 { 1002 nTmpCatPos=m_xLbCategory->get_selected_index(); 1003 } 1004 1005 1006 if ( bCat ) 1007 { 1008 if(nTmpCatPos!=CAT_CURRENCY) 1009 m_xLbCurrency->hide(); 1010 else 1011 m_xLbCurrency->show(); 1012 1013 pNumFmtShell->CategoryChanged(nTmpCatPos,nFmtLbSelPos, aEntryList); 1014 } 1015 else 1016 pNumFmtShell->LanguageChanged(m_xLbLanguage->get_active_id(), 1017 nFmtLbSelPos,aEntryList); 1018 1019 REMOVE_DONTKNOW() // possibly UI-Enable 1020 1021 1022 if ( (!aEntryList.empty()) && (nFmtLbSelPos != SELPOS_NONE) ) 1023 { 1024 if(bUpdateEdit) 1025 { 1026 OUString aFormat=aEntryList[nFmtLbSelPos]; 1027 m_xEdFormat->set_text(aFormat); 1028 m_xFtComment->set_label(pNumFmtShell->GetComment4Entry(nFmtLbSelPos)); 1029 } 1030 1031 if(!bOneAreaFlag || !bCat) 1032 { 1033 FillFormatListBox_Impl( aEntryList ); 1034 m_xLbFormat->select(nFmtLbSelPos); 1035 1036 m_xFtComment->set_label(pNumFmtShell->GetComment4Entry(nFmtLbSelPos)); 1037 if(pNumFmtShell->GetUserDefined4Entry(nFmtLbSelPos)) 1038 { 1039 if(pNumFmtShell->GetComment4Entry(nFmtLbSelPos).isEmpty()) 1040 { 1041 m_xFtComment->set_label(m_xLbCategory->get_text(1)); 1042 } 1043 } 1044 ChangePreviewText( static_cast<sal_uInt16>(nFmtLbSelPos) ); 1045 } 1046 1047 } 1048 else 1049 { 1050 FillFormatListBox_Impl( aEntryList ); 1051 if(nFmtLbSelPos != SELPOS_NONE) 1052 { 1053 m_xLbFormat->select(static_cast<sal_uInt16>(nFmtLbSelPos)); 1054 1055 m_xFtComment->set_label(pNumFmtShell->GetComment4Entry(nFmtLbSelPos)); 1056 if(pNumFmtShell->GetUserDefined4Entry(nFmtLbSelPos)) 1057 { 1058 if(pNumFmtShell->GetComment4Entry(nFmtLbSelPos).isEmpty()) 1059 { 1060 m_xFtComment->set_label(m_xLbCategory->get_text(1)); 1061 } 1062 } 1063 } 1064 else 1065 { 1066 m_xLbFormat->select(-1); 1067 } 1068 1069 if ( bUpdateEdit ) 1070 { 1071 m_xEdFormat->set_text( OUString() ); 1072 m_aWndPreview.NotifyChange( OUString() ); 1073 } 1074 } 1075 1076 aEntryList.clear(); 1077 } 1078 1079 1080 /** 1081 * Change visible checkbox according to category format 1082 * if scientific format "Engineering notation" 1083 * else "Thousands separator" 1084 */ 1085 1086 void SvxNumberFormatTabPage::UpdateThousandEngineeringCheckBox() 1087 { 1088 bool bIsScientific = m_xLbCategory->get_selected_index() == CAT_SCIENTIFIC; 1089 m_xBtnThousand->set_visible( !bIsScientific ); 1090 m_xBtnEngineering->set_visible( bIsScientific ); 1091 } 1092 1093 1094 /** 1095 * Change visible Edit box and Fixed text according to category format 1096 * if fraction format "Denominator places" 1097 * else "Decimal places" 1098 */ 1099 1100 void SvxNumberFormatTabPage::UpdateDecimalsDenominatorEditBox() 1101 { 1102 bool bIsFraction = m_xLbCategory->get_selected_index() == CAT_FRACTION; 1103 m_xFtDecimals->set_visible( !bIsFraction ); 1104 m_xEdDecimals->set_visible( !bIsFraction ); 1105 m_xFtDenominator->set_visible( bIsFraction ); 1106 m_xEdDenominator->set_visible( bIsFraction ); 1107 } 1108 1109 1110 /************************************************************************* 1111 #* Handle: DoubleClickHdl_Impl 1112 #*------------------------------------------------------------------------ 1113 #* 1114 #* Class: SvxNumberFormatTabPage 1115 #* Function: On a double click in the format listbox the 1116 #* value is adopted and the OK button pushed. 1117 #* Input: Pointer on the Listbox 1118 #* Output: --- 1119 #* 1120 #************************************************************************/ 1121 IMPL_LINK(SvxNumberFormatTabPage, DoubleClickHdl_Impl, weld::TreeView&, rLb, bool) 1122 { 1123 SelFormatHdl_Impl(&rLb); 1124 1125 SfxOkDialogController* pController = GetDialogController(); 1126 assert(pController); 1127 weld::Button& rOkButton = pController->GetOKButton(); 1128 rOkButton.clicked(); 1129 1130 return true; 1131 } 1132 1133 /************************************************************************* 1134 #* Method: SelFormatHdl_Impl 1135 #*------------------------------------------------------------------------ 1136 #* 1137 #* Class: SvxNumberFormatTabPage 1138 #* Function: Is called when the language, the category or the format 1139 #* is changed. Accordingly the settings are adjusted. 1140 #* Input: Pointer on the Listbox 1141 #* Output: --- 1142 #* 1143 #************************************************************************/ 1144 1145 IMPL_LINK(SvxNumberFormatTabPage, SelFormatClickHdl_Impl, weld::Toggleable&, rLb, void) 1146 { 1147 SelFormatHdl_Impl(&rLb); 1148 } 1149 1150 IMPL_LINK(SvxNumberFormatTabPage, SelFormatTreeListBoxHdl_Impl, weld::TreeView&, rLb, void) 1151 { 1152 SelFormatHdl_Impl(&rLb); 1153 } 1154 1155 IMPL_LINK(SvxNumberFormatTabPage, SelFormatListBoxHdl_Impl, weld::ComboBox&, rLb, void) 1156 { 1157 SelFormatHdl_Impl(&rLb); 1158 } 1159 1160 void SvxNumberFormatTabPage::SelFormatHdl_Impl(weld::Widget* pLb) 1161 { 1162 if (m_nLbFormatSelPosEdComment != SELPOS_NONE) 1163 { 1164 // Click handler is called before focus change handler, so finish 1165 // comment editing of previous format, otherwise a new format will have 1166 // the old comment displayed after LostFocusHdl_Impl() is called 1167 // later. Also, clicking into another category invalidates the format 1168 // list and SvxNumberFormatShell::SetComment4Entry() could either 1169 // access a wrong format from aCurEntryList[nEntry] or crash there if 1170 // the new vector has less elements. 1171 LostFocusHdl_Impl(*pLb); 1172 } 1173 1174 if (pLb == m_xCbSourceFormat.get()) 1175 { 1176 EnableBySourceFormat_Impl(); // enable/disable everything else 1177 if ( m_xCbSourceFormat->get_active() ) 1178 return; // just disabled everything else 1179 1180 // Reinit options enable/disable for current selection. 1181 1182 // Current category may be UserDefined with no format entries defined. 1183 if (m_xLbFormat->get_selected_index() == -1) 1184 pLb = m_xLbCategory.get(); // continue with the current category selected 1185 else 1186 pLb = m_xLbFormat.get(); // continue with the current format selected 1187 } 1188 1189 sal_Int32 nTmpCatPos; 1190 1191 if(bOneAreaFlag) 1192 { 1193 nTmpCatPos=nFixedCategory; 1194 } 1195 else 1196 { 1197 nTmpCatPos=m_xLbCategory->get_selected_index(); 1198 } 1199 1200 if (nTmpCatPos==CAT_CURRENCY && pLb == m_xLbCurrency.get()) 1201 pNumFmtShell->SetCurrencySymbol(get_active_currency()); 1202 1203 // Format-ListBox ---------------------------------------------------- 1204 if (pLb == m_xLbFormat.get()) 1205 { 1206 int nSelPos = m_xLbFormat->get_selected_index(); 1207 short nFmtLbSelPos = static_cast<short>(nSelPos); 1208 1209 OUString aFormat = pNumFmtShell->GetFormat4Entry(nFmtLbSelPos); 1210 OUString aComment = pNumFmtShell->GetComment4Entry(nFmtLbSelPos); 1211 1212 if(pNumFmtShell->GetUserDefined4Entry(nFmtLbSelPos)) 1213 { 1214 if(aComment.isEmpty()) 1215 { 1216 aComment = m_xLbCategory->get_text(1); 1217 } 1218 } 1219 1220 if ( !aFormat.isEmpty() ) 1221 { 1222 if (!m_xEdFormat->has_focus()) 1223 m_xEdFormat->set_text( aFormat ); 1224 m_xFtComment->set_label(aComment); 1225 ChangePreviewText( static_cast<sal_uInt16>(nSelPos) ); 1226 } 1227 1228 REMOVE_DONTKNOW() // possibly UI-Enable 1229 1230 if ( pNumFmtShell->FindEntry( aFormat) ) 1231 { 1232 m_xIbAdd->set_sensitive(false ); 1233 bool bIsUserDef=pNumFmtShell->IsUserDefined( aFormat ); 1234 m_xIbRemove->set_sensitive(bIsUserDef); 1235 m_xIbInfo->set_sensitive(bIsUserDef); 1236 1237 } 1238 else 1239 { 1240 m_xIbAdd->set_sensitive(true); 1241 m_xIbInfo->set_sensitive(true); 1242 m_xIbRemove->set_sensitive(false ); 1243 m_xFtComment->set_label(m_xEdComment->get_text()); 1244 1245 } 1246 UpdateOptions_Impl( false ); 1247 1248 return; 1249 } 1250 1251 1252 // category-ListBox ------------------------------------------------- 1253 if (pLb == m_xLbCategory.get() || pLb == m_xLbCurrency.get()) 1254 { 1255 UpdateFormatListBox_Impl( true, true ); 1256 EditHdl_Impl( nullptr ); 1257 UpdateOptions_Impl( false ); 1258 1259 return; 1260 } 1261 1262 1263 // language/country-ListBox ---------------------------------------------- 1264 if (pLb == m_xLbLanguage->get_widget()) 1265 { 1266 UpdateFormatListBox_Impl( false, true ); 1267 EditHdl_Impl(m_xEdFormat.get()); 1268 1269 return; 1270 } 1271 } 1272 1273 1274 /************************************************************************* 1275 #* Method: ClickHdl_Impl, weld::Button& rIB 1276 #*------------------------------------------------------------------------ 1277 #* 1278 #* Class: SvxNumberFormatTabPage 1279 #* Function: Called when the add or delete button is pushed, 1280 #* adjusts the number format list. 1281 #* Input: Toolbox- Button 1282 #* Output: --- 1283 #* 1284 #************************************************************************/ 1285 1286 IMPL_LINK( SvxNumberFormatTabPage, ClickHdl_Impl, weld::Button&, rIB, void) 1287 { 1288 Click_Impl(rIB); 1289 } 1290 1291 bool SvxNumberFormatTabPage::Click_Impl(const weld::Button& rIB) 1292 { 1293 sal_uLong nReturn = 0; 1294 constexpr sal_uLong nReturnChanged = 0x1; // THE boolean return value 1295 constexpr sal_uLong nReturnAdded = 0x2; // temp: format added 1296 constexpr sal_uLong nReturnOneArea = 0x4; // temp: one area but category changed => ignored 1297 1298 if (&rIB == m_xIbAdd.get()) 1299 { // Also called from FillItemSet() if a temporary currency format has 1300 // to be added, not only if the Add button is enabled. 1301 OUString aFormat = m_xEdFormat->get_text(); 1302 std::vector<OUString> aEntryList; 1303 std::vector<OUString> a2EntryList; 1304 sal_uInt16 nCatLbSelPos = 0; 1305 short nFmtLbSelPos = SELPOS_NONE; 1306 sal_Int32 nErrPos=0; 1307 1308 pNumFmtShell->SetCurCurrencyEntry(nullptr); 1309 bool bAdded = pNumFmtShell->AddFormat( aFormat, nErrPos, 1310 nCatLbSelPos, nFmtLbSelPos, 1311 aEntryList); 1312 if ( bAdded ) 1313 nReturn |= nReturnChanged | nReturnAdded; 1314 1315 if (m_xEdComment->get_visible()) 1316 { 1317 m_xEdFormat->grab_focus(); 1318 m_xEdComment->hide(); 1319 m_xFtComment->show(); 1320 m_xFtComment->set_label(m_xEdComment->get_text()); 1321 } 1322 1323 if ( !nErrPos ) // Syntax ok? 1324 { 1325 // May be sorted under a different locale if LCID was parsed. 1326 if (bAdded) 1327 m_xLbLanguage->set_active_id(pNumFmtShell->GetCurLanguage()); 1328 1329 if (nCatLbSelPos==CAT_CURRENCY) 1330 set_active_currency(pNumFmtShell->GetCurrencySymbol()); 1331 1332 if(bOneAreaFlag && (nFixedCategory!=nCatLbSelPos)) 1333 { 1334 if(bAdded) aEntryList.clear(); 1335 pNumFmtShell->RemoveFormat( aFormat, 1336 nCatLbSelPos, 1337 nFmtLbSelPos, 1338 a2EntryList); 1339 a2EntryList.clear(); 1340 m_xEdFormat->grab_focus(); 1341 m_xEdFormat->select_region(0, -1); 1342 nReturn |= nReturnOneArea; 1343 } 1344 else 1345 { 1346 if ( bAdded && (nFmtLbSelPos != SELPOS_NONE) ) 1347 { 1348 // everything all right 1349 if(bOneAreaFlag) //@@ ??? 1350 SetCategory(0); 1351 else 1352 SetCategory(nCatLbSelPos ); 1353 1354 FillFormatListBox_Impl( aEntryList ); 1355 if (m_xEdComment->get_text()!=m_xLbCategory->get_text(1)) 1356 { 1357 pNumFmtShell->SetComment4Entry(nFmtLbSelPos, 1358 m_xEdComment->get_text()); 1359 } 1360 else 1361 { 1362 pNumFmtShell->SetComment4Entry(nFmtLbSelPos, 1363 OUString()); 1364 } 1365 m_xLbFormat->select(static_cast<sal_uInt16>(nFmtLbSelPos)); 1366 m_xEdFormat->set_text( aFormat ); 1367 1368 m_xEdComment->set_text(m_xLbCategory->get_text(1)); // String for user defined 1369 1370 ChangePreviewText( static_cast<sal_uInt16>(nFmtLbSelPos) ); 1371 } 1372 } 1373 } 1374 else // syntax error 1375 { 1376 m_xEdFormat->grab_focus(); 1377 m_xEdFormat->select_region(nErrPos == -1 ? m_xEdFormat->get_text().getLength() : nErrPos, -1); 1378 } 1379 EditHdl_Impl(m_xEdFormat.get()); 1380 nReturn = ((nReturn & nReturnOneArea) ? 0 : (nReturn & nReturnChanged)); 1381 1382 aEntryList.clear(); 1383 a2EntryList.clear(); 1384 } 1385 else if (&rIB == m_xIbRemove.get()) 1386 { 1387 OUString aFormat = m_xEdFormat->get_text(); 1388 std::vector<OUString> aEntryList; 1389 sal_uInt16 nCatLbSelPos = 0; 1390 short nFmtLbSelPos = SELPOS_NONE; 1391 1392 pNumFmtShell->RemoveFormat( aFormat, 1393 nCatLbSelPos, 1394 nFmtLbSelPos, 1395 aEntryList ); 1396 1397 m_xEdComment->set_text(m_xLbCategory->get_text(1)); 1398 1399 if( nFmtLbSelPos>=0 && o3tl::make_unsigned(nFmtLbSelPos)<aEntryList.size() ) 1400 { 1401 aFormat = aEntryList[nFmtLbSelPos]; 1402 } 1403 1404 FillFormatListBox_Impl( aEntryList ); 1405 1406 if ( nFmtLbSelPos != SELPOS_NONE ) 1407 { 1408 if(bOneAreaFlag) //@@ ??? 1409 SetCategory(0); 1410 else 1411 SetCategory(nCatLbSelPos ); 1412 1413 m_xLbFormat->select(static_cast<sal_uInt16>(nFmtLbSelPos)); 1414 m_xEdFormat->set_text( aFormat ); 1415 ChangePreviewText( static_cast<sal_uInt16>(nFmtLbSelPos) ); 1416 } 1417 else 1418 { 1419 // set to "all/standard" 1420 SetCategory(0); 1421 SelFormatHdl_Impl(m_xLbCategory.get()); 1422 } 1423 1424 EditHdl_Impl(m_xEdFormat.get()); 1425 1426 aEntryList.clear(); 1427 } 1428 else if (&rIB == m_xIbInfo.get()) 1429 { 1430 if (!m_xEdComment->get_visible()) 1431 { 1432 if (!m_xIbAdd->get_sensitive()) 1433 // Editing for existing format. 1434 m_nLbFormatSelPosEdComment = m_xLbFormat->get_selected_index(); 1435 1436 m_xEdComment->set_text(m_xFtComment->get_label()); 1437 m_xEdComment->show(); 1438 m_xFtComment->hide(); 1439 m_xEdComment->grab_focus(); 1440 } 1441 else 1442 { 1443 m_xEdFormat->grab_focus(); 1444 m_xFtComment->set_label( m_xEdComment->get_text()); 1445 m_xEdComment->hide(); 1446 m_xFtComment->show(); 1447 } 1448 } 1449 1450 return nReturn; 1451 } 1452 1453 1454 /************************************************************************* 1455 #* Method: EditHdl_Impl 1456 #*------------------------------------------------------------------------ 1457 #* 1458 #* Class: SvxNumberFormatTabPage 1459 #* Function: When the entry in the edit field is changed 1460 #* the preview is updated and 1461 #* Input: Pointer on Editbox 1462 #* Output: --- 1463 #* 1464 #************************************************************************/ 1465 1466 IMPL_LINK(SvxNumberFormatTabPage, EditModifyHdl_Impl, weld::Entry&, rEdit, void) 1467 { 1468 EditHdl_Impl(&rEdit); 1469 } 1470 1471 void SvxNumberFormatTabPage::EditHdl_Impl(const weld::Entry* pEdFormat) 1472 { 1473 sal_uInt32 nCurKey = NUMKEY_UNDEFINED; 1474 1475 if ( m_xEdFormat->get_text().isEmpty() ) 1476 { 1477 m_xIbAdd->set_sensitive(false ); 1478 m_xIbRemove->set_sensitive(false ); 1479 m_xIbInfo->set_sensitive(false ); 1480 m_xFtComment->set_label(OUString()); 1481 } 1482 else 1483 { 1484 OUString aFormat = m_xEdFormat->get_text(); 1485 MakePreviewText( aFormat ); 1486 1487 if ( pNumFmtShell->FindEntry( aFormat, &nCurKey ) ) 1488 { 1489 m_xIbAdd->set_sensitive(false ); 1490 bool bUserDef=pNumFmtShell->IsUserDefined( aFormat ); 1491 1492 m_xIbRemove->set_sensitive(bUserDef); 1493 m_xIbInfo->set_sensitive(bUserDef); 1494 1495 if(bUserDef) 1496 { 1497 sal_uInt16 nTmpCurPos=pNumFmtShell->FindCurrencyFormat(aFormat ); 1498 if (nTmpCurPos != sal_uInt16(-1)) 1499 set_active_currency(nTmpCurPos); 1500 } 1501 short nPosi=pNumFmtShell->GetListPos4Entry( nCurKey, aFormat); 1502 if(nPosi>=0) 1503 m_xLbFormat->select(static_cast<sal_uInt16>(nPosi)); 1504 1505 } 1506 else 1507 { 1508 1509 m_xIbAdd->set_sensitive(true); 1510 m_xIbInfo->set_sensitive(true); 1511 m_xIbRemove->set_sensitive(false ); 1512 1513 m_xFtComment->set_label(m_xEdComment->get_text()); 1514 1515 } 1516 } 1517 1518 if (pEdFormat) 1519 { 1520 pNumFmtShell->SetCurNumFmtKey( nCurKey ); 1521 UpdateOptions_Impl( true ); 1522 } 1523 } 1524 1525 1526 /************************************************************************* 1527 #* Method: NotifyChange 1528 #*------------------------------------------------------------------------ 1529 #* 1530 #* Class: SvxNumberFormatTabPage 1531 #* Function: Does changes in the number attributes. 1532 #* Input: Options- Controls 1533 #* Output: --- 1534 #* 1535 #************************************************************************/ 1536 1537 IMPL_LINK(SvxNumberFormatTabPage, OptClickHdl_Impl, weld::Toggleable&, rOptCtrl, void) 1538 { 1539 OptHdl_Impl(&rOptCtrl); 1540 } 1541 1542 IMPL_LINK(SvxNumberFormatTabPage, OptEditHdl_Impl, weld::SpinButton&, rEdit, void) 1543 { 1544 OptHdl_Impl(&rEdit); 1545 } 1546 1547 void SvxNumberFormatTabPage::OptHdl_Impl(const weld::Widget* pOptCtrl) 1548 { 1549 if ( !(pOptCtrl == m_xEdLeadZeroes.get() 1550 || pOptCtrl == m_xEdDecimals.get() 1551 || pOptCtrl == m_xEdDenominator.get() 1552 || pOptCtrl == m_xBtnNegRed.get() 1553 || pOptCtrl == m_xBtnThousand.get() 1554 || pOptCtrl == m_xBtnEngineering.get())) 1555 return; 1556 1557 OUString aFormat; 1558 bool bThousand = ( m_xBtnThousand->get_visible() && m_xBtnThousand->get_sensitive() && m_xBtnThousand->get_active() ) 1559 || ( m_xBtnEngineering->get_visible() && m_xBtnEngineering->get_sensitive() && m_xBtnEngineering->get_active() ); 1560 bool bNegRed = m_xBtnNegRed->get_sensitive() && m_xBtnNegRed->get_active(); 1561 sal_uInt16 nPrecision = (m_xEdDecimals->get_sensitive() && m_xEdDecimals->get_visible()) 1562 ? static_cast<sal_uInt16>(m_xEdDecimals->get_value()) 1563 : ( (m_xEdDenominator->get_sensitive() && m_xEdDenominator->get_visible()) 1564 ? static_cast<sal_uInt16>(m_xEdDenominator->get_value()) 1565 : sal_uInt16(0) ); 1566 sal_uInt16 nLeadZeroes = (m_xEdLeadZeroes->get_sensitive()) 1567 ? static_cast<sal_uInt16>(m_xEdLeadZeroes->get_value()) 1568 : sal_uInt16(0); 1569 if ( pNumFmtShell->GetStandardName() == m_xEdFormat->get_text() ) 1570 { 1571 m_xEdDecimals->set_value(nPrecision); 1572 } 1573 1574 pNumFmtShell->MakeFormat( aFormat, 1575 bThousand, bNegRed, 1576 nPrecision, nLeadZeroes, 1577 static_cast<sal_uInt16>(m_xLbFormat->get_selected_index()) ); 1578 1579 m_xEdFormat->set_text( aFormat ); 1580 MakePreviewText( aFormat ); 1581 1582 if ( pNumFmtShell->FindEntry( aFormat ) ) 1583 { 1584 m_xIbAdd->set_sensitive(false ); 1585 bool bUserDef=pNumFmtShell->IsUserDefined( aFormat ); 1586 m_xIbRemove->set_sensitive(bUserDef); 1587 m_xIbInfo->set_sensitive(bUserDef); 1588 EditHdl_Impl(m_xEdFormat.get()); 1589 1590 } 1591 else 1592 { 1593 EditHdl_Impl( nullptr ); 1594 m_xLbFormat->select(-1); 1595 } 1596 } 1597 1598 /************************************************************************* 1599 #* Method: LostFocusHdl_Impl 1600 #*------------------------------------------------------------------------ 1601 #* 1602 #* Class: SvxNumberFormatTabPage 1603 #* Function: Does changes in the number attributes. 1604 #* Input: Options- Controls 1605 #* Output: --- 1606 #* 1607 #************************************************************************/ 1608 1609 IMPL_LINK_NOARG(SvxNumberFormatTabPage, LostFocusHdl_Impl, weld::Widget&, void) 1610 { 1611 if (!pNumFmtShell) 1612 return; 1613 1614 const bool bAddSensitive = m_xIbAdd->get_sensitive(); 1615 if (bAddSensitive || m_nLbFormatSelPosEdComment != SELPOS_NONE) 1616 // Comment editing was possible. 1617 m_xFtComment->set_label(m_xEdComment->get_text()); 1618 1619 m_xEdComment->hide(); 1620 m_xFtComment->show(); 1621 if (m_nLbFormatSelPosEdComment != SELPOS_NONE) 1622 { 1623 // Save edited comment of existing format. 1624 pNumFmtShell->SetComment4Entry( m_nLbFormatSelPosEdComment, m_xEdComment->get_text()); 1625 m_nLbFormatSelPosEdComment = SELPOS_NONE; 1626 } 1627 if (!bAddSensitive) 1628 { 1629 // String for user defined, if present 1630 OUString sEntry = m_xLbCategory->n_children() > 1 ? m_xLbCategory->get_text(1) : OUString(); 1631 m_xEdComment->set_text(sEntry); 1632 } 1633 } 1634 1635 /************************************************************************* 1636 #* Method: NotifyChange 1637 #*------------------------------------------------------------------------ 1638 #* 1639 #* Class: SvxNumberFormatTabPage 1640 #* Function: Does changes in the number attributes. 1641 #* Input: Options- Controls 1642 #* Output: --- 1643 #* 1644 #************************************************************************/ 1645 1646 OUString SvxNumberFormatTabPage::GetExpColorString( 1647 const Color*& rpPreviewColor, const OUString& rFormatStr, short nTmpCatPos) 1648 { 1649 SvxNumValCategory i; 1650 switch (nTmpCatPos) 1651 { 1652 case CAT_ALL: i=SvxNumValCategory::Standard; break; 1653 1654 case CAT_NUMBER: i=SvxNumValCategory::Standard; break; 1655 1656 case CAT_PERCENT: i=SvxNumValCategory::Percent; break; 1657 1658 case CAT_CURRENCY: i=SvxNumValCategory::Currency; break; 1659 1660 case CAT_DATE: i=SvxNumValCategory::Date; break; 1661 1662 case CAT_TIME: i=SvxNumValCategory::Time; break; 1663 1664 case CAT_SCIENTIFIC: i=SvxNumValCategory::Scientific; break; 1665 1666 case CAT_FRACTION: i=SvxNumValCategory::Fraction; break; 1667 1668 case CAT_BOOLEAN: i=SvxNumValCategory::Boolean; break; 1669 1670 case CAT_USERDEFINED: i=SvxNumValCategory::Standard; break; 1671 1672 case CAT_TEXT: 1673 default: i=SvxNumValCategory::NoValue;break; 1674 } 1675 double fVal = fSvxNumValConst[i]; 1676 1677 OUString aPreviewString; 1678 pNumFmtShell->MakePrevStringFromVal( rFormatStr, aPreviewString, rpPreviewColor, fVal ); 1679 return aPreviewString; 1680 } 1681 1682 void SvxNumberFormatTabPage::MakePreviewText( const OUString& rFormat ) 1683 { 1684 OUString aPreviewString; 1685 const Color* pPreviewColor = nullptr; 1686 pNumFmtShell->MakePreviewString( rFormat, aPreviewString, pPreviewColor ); 1687 m_aWndPreview.NotifyChange( aPreviewString, pPreviewColor ); 1688 } 1689 1690 void SvxNumberFormatTabPage::ChangePreviewText( sal_uInt16 nPos ) 1691 { 1692 OUString aPreviewString; 1693 const Color* pPreviewColor = nullptr; 1694 pNumFmtShell->FormatChanged( nPos, aPreviewString, pPreviewColor ); 1695 m_aWndPreview.NotifyChange( aPreviewString, pPreviewColor ); 1696 } 1697 1698 void SvxNumberFormatTabPage::FillCurrencyBox() 1699 { 1700 std::vector<OUString> aList; 1701 1702 sal_uInt16 nSelPos=0; 1703 pNumFmtShell->GetCurrencySymbols(aList, &nSelPos); 1704 1705 m_xLbCurrency->freeze(); 1706 m_xLbCurrency->clear(); 1707 bLegacyAutomaticCurrency = false; 1708 for (std::vector<OUString>::iterator i = aList.begin() + 1;i != aList.end(); ++i) 1709 m_xLbCurrency->append_text(*i); 1710 m_xLbCurrency->thaw(); 1711 1712 set_active_currency(nSelPos); 1713 } 1714 1715 void SvxNumberFormatTabPage::SetCategory(sal_uInt16 nPos) 1716 { 1717 int nCurCategory = m_xLbCategory->get_selected_index(); 1718 sal_uInt16 nTmpCatPos; 1719 1720 if (bOneAreaFlag) 1721 { 1722 nTmpCatPos=nFixedCategory; 1723 } 1724 else 1725 { 1726 nTmpCatPos=nPos; 1727 } 1728 1729 if(m_xLbCategory->n_children()==1 || nCurCategory!=nPos) 1730 { 1731 if(nTmpCatPos!=CAT_CURRENCY) 1732 m_xLbCurrency->hide(); 1733 else 1734 m_xLbCurrency->show(); 1735 } 1736 m_xLbCategory->select(nPos); 1737 } 1738 1739 /* to support Writer text field language handling an 1740 additional entry needs to be inserted into the ListBox 1741 which marks a certain language as automatically detected 1742 Additionally the "Default" language is removed 1743 */ 1744 void SvxNumberFormatTabPage::AddAutomaticLanguage_Impl(LanguageType eAutoLang, bool bSelect) 1745 { 1746 m_xLbLanguage->remove_id(LANGUAGE_SYSTEM); 1747 m_xLbLanguage->append(eAutoLang, sAutomaticLangEntry); 1748 if (bSelect) 1749 m_xLbLanguage->set_active_id(eAutoLang); 1750 } 1751 1752 void SvxNumberFormatTabPage::PageCreated(const SfxAllItemSet& aSet) 1753 { 1754 const SvxNumberInfoItem* pNumberInfoItem = aSet.GetItem<SvxNumberInfoItem>(SID_ATTR_NUMBERFORMAT_INFO, false); 1755 if (pNumberInfoItem && !pNumItem) 1756 pNumItem.reset(pNumberInfoItem->Clone()); 1757 } 1758 1759 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 1760
