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 10 #include <memory> 11 #include <condformatdlg.hxx> 12 #include <condformatdlgentry.hxx> 13 #include <conditio.hxx> 14 #include <compiler.hxx> 15 #include <colorscale.hxx> 16 #include <condformathelper.hxx> 17 18 #include <document.hxx> 19 20 #include <svl/style.hxx> 21 #include <sfx2/dispatch.hxx> 22 #include <sfx2/frame.hxx> 23 #include <svl/stritem.hxx> 24 #include <svl/intitem.hxx> 25 #include <svx/colorbox.hxx> 26 #include <vcl/settings.hxx> 27 #include <vcl/svapp.hxx> 28 #include <formula/token.hxx> 29 #include <formula/errorcodes.hxx> 30 #include <tokenarray.hxx> 31 #include <stlpool.hxx> 32 #include <tabvwsh.hxx> 33 #include <unotools/charclass.hxx> 34 35 #include <colorformat.hxx> 36 #include <scresid.hxx> 37 #include <globstr.hrc> 38 #include <strings.hrc> 39 40 #include <set> 41 42 ScCondFrmtEntry::ScCondFrmtEntry(ScCondFormatList* pParent, ScDocument* pDoc, const ScAddress& rPos) 43 : mpParent(pParent) 44 , mxBuilder(Application::CreateBuilder(pParent->GetContainer(), "modules/scalc/ui/conditionalentry.ui")) 45 , mxBorder(mxBuilder->weld_widget("border")) 46 , mxGrid(mxBuilder->weld_container("grid")) 47 , mxFtCondNr(mxBuilder->weld_label("number")) 48 , mxFtCondition(mxBuilder->weld_label("condition")) 49 , mbActive(false) 50 , maStrCondition(ScResId(SCSTR_CONDITION)) 51 , mxLbType(mxBuilder->weld_combo_box("type")) 52 , mpDoc(pDoc) 53 , maPos(rPos) 54 { 55 mxLbType->connect_changed(LINK(pParent, ScCondFormatList, TypeListHdl)); 56 mxGrid->connect_mouse_press(LINK(this, ScCondFrmtEntry, EntrySelectHdl)); 57 maClickHdl = LINK( pParent, ScCondFormatList, EntrySelectHdl ); 58 59 Show(); 60 } 61 62 ScCondFrmtEntry::~ScCondFrmtEntry() 63 { 64 mpParent->GetContainer()->move(mxBorder.get(), nullptr); 65 } 66 67 IMPL_LINK_NOARG(ScCondFrmtEntry, EntrySelectHdl, const MouseEvent&, bool) 68 { 69 maClickHdl.Call(*this); 70 return false; 71 } 72 73 void ScCondFrmtEntry::SetIndex(sal_Int32 nIndex) 74 { 75 mxFtCondNr->set_label(maStrCondition + OUString::number(nIndex)); 76 } 77 78 void ScCondFrmtEntry::Select() 79 { 80 mxFtCondition->set_label(OUString()); 81 mxFtCondition->hide(); 82 mxLbType->show(); 83 mbActive = true; 84 } 85 86 void ScCondFrmtEntry::Deselect() 87 { 88 OUString aCondText = GetExpressionString(); 89 mxFtCondition->set_label(aCondText); 90 mxFtCondition->show(); 91 mxLbType->hide(); 92 mbActive = false; 93 } 94 95 //condition 96 97 namespace { 98 99 void FillStyleListBox( const ScDocument* pDoc, weld::ComboBox& rLbStyle ) 100 { 101 std::set<OUString> aStyleNames; 102 SfxStyleSheetIterator aStyleIter( pDoc->GetStyleSheetPool(), SfxStyleFamily::Para ); 103 for ( SfxStyleSheetBase* pStyle = aStyleIter.First(); pStyle; pStyle = aStyleIter.Next() ) 104 { 105 aStyleNames.insert(pStyle->GetName()); 106 } 107 for(const auto& rStyleName : aStyleNames) 108 { 109 rLbStyle.append_text(rStyleName); 110 } 111 } 112 113 } 114 115 const ScConditionMode ScConditionFrmtEntry::mpEntryToCond[ScConditionFrmtEntry::NUM_COND_ENTRIES] = { 116 ScConditionMode::Equal, 117 ScConditionMode::Less, 118 ScConditionMode::Greater, 119 ScConditionMode::EqLess, 120 ScConditionMode::EqGreater, 121 ScConditionMode::NotEqual, 122 ScConditionMode::Between, 123 ScConditionMode::NotBetween, 124 ScConditionMode::Duplicate, 125 ScConditionMode::NotDuplicate, 126 ScConditionMode::Top10, 127 ScConditionMode::Bottom10, 128 ScConditionMode::TopPercent, 129 ScConditionMode::BottomPercent, 130 ScConditionMode::AboveAverage, 131 ScConditionMode::BelowAverage, 132 ScConditionMode::AboveEqualAverage, 133 ScConditionMode::BelowEqualAverage, 134 ScConditionMode::Error, 135 ScConditionMode::NoError, 136 ScConditionMode::BeginsWith, 137 ScConditionMode::EndsWith, 138 ScConditionMode::ContainsText, 139 ScConditionMode::NotContainsText 140 }; 141 142 ScConditionFrmtEntry::ScConditionFrmtEntry(ScCondFormatList* pParent, ScDocument* pDoc, ScCondFormatDlg* pDialogParent, 143 const ScAddress& rPos, const ScCondFormatEntry* pFormatEntry) 144 : ScCondFrmtEntry(pParent, pDoc, rPos) 145 , mxLbCondType(mxBuilder->weld_combo_box("typeis")) 146 , mxEdVal1(new formula::RefEdit(mxBuilder->weld_entry("val1"))) 147 , mxEdVal2(new formula::RefEdit(mxBuilder->weld_entry("val2"))) 148 , mxFtVal(mxBuilder->weld_label("valueft")) 149 , mxFtStyle(mxBuilder->weld_label("styleft")) 150 , mxLbStyle(mxBuilder->weld_combo_box("style")) 151 , mxWdPreviewWin(mxBuilder->weld_widget("previewwin")) 152 , mxWdPreview(new weld::CustomWeld(*mxBuilder, "preview", maWdPreview)) 153 , mbIsInStyleCreate(false) 154 { 155 mxWdPreview->set_size_request(-1, mxLbStyle->get_preferred_size().Height()); 156 157 mxLbType->set_active(1); 158 159 Init(pDialogParent); 160 161 StartListening(*pDoc->GetStyleSheetPool(), DuplicateHandling::Prevent); 162 163 if(pFormatEntry) 164 { 165 mxLbStyle->set_active_text(pFormatEntry->GetStyle()); 166 StyleSelectHdl(*mxLbStyle); 167 ScConditionMode eMode = pFormatEntry->GetOperation(); 168 169 mxLbCondType->set_active(ConditionModeToEntryPos(eMode)); 170 171 switch(GetNumberEditFields(eMode)) 172 { 173 case 0: 174 mxEdVal1->GetWidget()->hide(); 175 mxEdVal2->GetWidget()->hide(); 176 break; 177 case 1: 178 mxEdVal1->GetWidget()->show(); 179 mxEdVal1->SetText(pFormatEntry->GetExpression(maPos, 0)); 180 mxEdVal2->GetWidget()->hide(); 181 OnEdChanged(*mxEdVal1); 182 break; 183 case 2: 184 mxEdVal1->GetWidget()->show(); 185 mxEdVal1->SetText(pFormatEntry->GetExpression(maPos, 0)); 186 OnEdChanged(*mxEdVal1); 187 mxEdVal2->GetWidget()->show(); 188 mxEdVal2->SetText(pFormatEntry->GetExpression(maPos, 1)); 189 OnEdChanged(*mxEdVal2); 190 break; 191 } 192 } 193 else 194 { 195 mxLbCondType->set_active(0); 196 mxEdVal2->GetWidget()->hide(); 197 mxLbStyle->set_active(1); 198 } 199 } 200 201 ScConditionFrmtEntry::~ScConditionFrmtEntry() 202 { 203 } 204 205 void ScConditionFrmtEntry::Init(ScCondFormatDlg* pDialogParent) 206 { 207 mxEdVal1->SetGetFocusHdl( LINK( pDialogParent, ScCondFormatDlg, RangeGetFocusHdl ) ); 208 mxEdVal2->SetGetFocusHdl( LINK( pDialogParent, ScCondFormatDlg, RangeGetFocusHdl ) ); 209 210 mxEdVal1->SetModifyHdl( LINK( this, ScConditionFrmtEntry, OnEdChanged ) ); 211 mxEdVal2->SetModifyHdl( LINK( this, ScConditionFrmtEntry, OnEdChanged ) ); 212 213 FillStyleListBox( mpDoc, *mxLbStyle ); 214 mxLbStyle->connect_changed( LINK( this, ScConditionFrmtEntry, StyleSelectHdl ) ); 215 216 mxLbCondType->connect_changed( LINK( this, ScConditionFrmtEntry, ConditionTypeSelectHdl ) ); 217 } 218 219 ScFormatEntry* ScConditionFrmtEntry::createConditionEntry() const 220 { 221 ScConditionMode eMode = EntryPosToConditionMode(mxLbCondType->get_active()); 222 OUString aExpr1 = mxEdVal1->GetText(); 223 OUString aExpr2; 224 if (GetNumberEditFields(eMode) == 2) 225 { 226 aExpr2 = mxEdVal2->GetText(); 227 if (aExpr2.isEmpty()) 228 { 229 return nullptr; 230 } 231 } 232 233 ScFormatEntry* pEntry = new ScCondFormatEntry(eMode, aExpr1, aExpr2, mpDoc, maPos, mxLbStyle->get_active_text()); 234 return pEntry; 235 } 236 237 IMPL_LINK(ScConditionFrmtEntry, OnEdChanged, formula::RefEdit&, rRefEdit, void) 238 { 239 weld::Entry& rEdit = *rRefEdit.GetWidget(); 240 OUString aFormula = rEdit.get_text(); 241 242 if( aFormula.isEmpty() ) 243 { 244 mxFtVal->set_label(ScResId(STR_ENTER_VALUE)); 245 return; 246 } 247 248 ScCompiler aComp( mpDoc, maPos, mpDoc->GetGrammar() ); 249 std::unique_ptr<ScTokenArray> ta(aComp.CompileString(aFormula)); 250 251 // Error, warn the user 252 if( ta->GetCodeError() != FormulaError::NONE || ( ta->GetLen() == 0 ) ) 253 { 254 rEdit.set_message_type(weld::EntryMessageType::Error); 255 mxFtVal->set_label(ScResId(STR_VALID_DEFERROR)); 256 return; 257 } 258 259 // Recognized col/row name or string token, warn the user 260 formula::FormulaToken* token = ta->FirstToken(); 261 formula::StackVar t = token->GetType(); 262 OpCode op = token->GetOpCode(); 263 if( ( op == ocColRowName ) || 264 ( ( op == ocBad ) && ( t == formula::svString ) ) 265 ) 266 { 267 rEdit.set_message_type(weld::EntryMessageType::Warning); 268 mxFtVal->set_label(ScResId(STR_UNQUOTED_STRING)); 269 return; 270 } 271 272 rEdit.set_message_type(weld::EntryMessageType::Normal); 273 mxFtVal->set_label(""); 274 } 275 276 void ScConditionFrmtEntry::Select() 277 { 278 mxFtVal->show(); 279 ScCondFrmtEntry::Select(); 280 } 281 282 void ScConditionFrmtEntry::Deselect() 283 { 284 mxFtVal->hide(); 285 ScCondFrmtEntry::Deselect(); 286 } 287 288 sal_Int32 ScConditionFrmtEntry::ConditionModeToEntryPos( ScConditionMode eMode ) 289 { 290 for ( sal_Int32 i = 0; i < NUM_COND_ENTRIES; ++i ) 291 { 292 if (mpEntryToCond[i] == eMode) 293 { 294 return i; 295 } 296 } 297 assert(false); // should never get here 298 return 0; 299 } 300 301 ScConditionMode ScConditionFrmtEntry::EntryPosToConditionMode( sal_Int32 aEntryPos ) 302 { 303 assert( 0 <= aEntryPos && aEntryPos < NUM_COND_ENTRIES ); 304 return mpEntryToCond[aEntryPos]; 305 } 306 307 sal_Int32 ScConditionFrmtEntry::GetNumberEditFields( ScConditionMode eMode ) 308 { 309 switch(eMode) 310 { 311 case ScConditionMode::Equal: 312 case ScConditionMode::Less: 313 case ScConditionMode::Greater: 314 case ScConditionMode::EqLess: 315 case ScConditionMode::EqGreater: 316 case ScConditionMode::NotEqual: 317 case ScConditionMode::Top10: 318 case ScConditionMode::Bottom10: 319 case ScConditionMode::TopPercent: 320 case ScConditionMode::BottomPercent: 321 case ScConditionMode::BeginsWith: 322 case ScConditionMode::EndsWith: 323 case ScConditionMode::ContainsText: 324 case ScConditionMode::NotContainsText: 325 case ScConditionMode::Error: 326 case ScConditionMode::NoError: 327 return 1; 328 case ScConditionMode::AboveAverage: 329 case ScConditionMode::BelowAverage: 330 case ScConditionMode::AboveEqualAverage: 331 case ScConditionMode::BelowEqualAverage: 332 case ScConditionMode::Duplicate: 333 case ScConditionMode::NotDuplicate: 334 return 0; 335 case ScConditionMode::Between: 336 case ScConditionMode::NotBetween: 337 return 2; 338 default: 339 assert(false); // should never get here 340 return 0; 341 } 342 } 343 344 OUString ScConditionFrmtEntry::GetExpressionString() 345 { 346 return ScCondFormatHelper::GetExpression(CONDITION, mxLbCondType->get_active(), mxEdVal1->GetText(), mxEdVal2->GetText()); 347 } 348 349 ScFormatEntry* ScConditionFrmtEntry::GetEntry() const 350 { 351 return createConditionEntry(); 352 } 353 354 void ScConditionFrmtEntry::SetActive() 355 { 356 ScConditionMode eMode = EntryPosToConditionMode(mxLbCondType->get_active()); 357 mxLbCondType->show(); 358 switch(GetNumberEditFields(eMode)) 359 { 360 case 1: 361 mxEdVal1->GetWidget()->show(); 362 break; 363 case 2: 364 mxEdVal1->GetWidget()->show(); 365 mxEdVal2->GetWidget()->show(); 366 break; 367 } 368 mxFtStyle->show(); 369 mxLbStyle->show(); 370 mxWdPreviewWin->show(); 371 372 Select(); 373 } 374 375 void ScConditionFrmtEntry::SetInactive() 376 { 377 mxLbCondType->hide(); 378 mxEdVal1->GetWidget()->hide(); 379 mxEdVal2->GetWidget()->hide(); 380 mxFtStyle->hide(); 381 mxLbStyle->hide(); 382 mxWdPreviewWin->hide(); 383 384 Deselect(); 385 } 386 387 namespace { 388 389 void UpdateStyleList(weld::ComboBox& rLbStyle, const ScDocument* pDoc) 390 { 391 OUString aSelectedStyle = rLbStyle.get_active_text(); 392 for (sal_Int32 i = rLbStyle.get_count(); i > 1; --i) 393 rLbStyle.remove(i - 1); 394 FillStyleListBox(pDoc, rLbStyle); 395 rLbStyle.set_active_text(aSelectedStyle); 396 } 397 398 } 399 400 void ScConditionFrmtEntry::Notify(SfxBroadcaster&, const SfxHint& rHint) 401 { 402 if(rHint.GetId() == SfxHintId::StyleSheetModified) 403 { 404 if(!mbIsInStyleCreate) 405 UpdateStyleList(*mxLbStyle, mpDoc); 406 } 407 } 408 409 namespace { 410 411 void StyleSelect(weld::Window* pDialogParent, weld::ComboBox& rLbStyle, const ScDocument* pDoc, FontPrevWindow& rWdPreview) 412 { 413 if (rLbStyle.get_active() == 0) 414 { 415 // call new style dialog 416 SfxUInt16Item aFamilyItem( SID_STYLE_FAMILY, sal_uInt16(SfxStyleFamily::Para) ); 417 SfxStringItem aRefItem( SID_STYLE_REFERENCE, ScResId(STR_STYLENAME_STANDARD) ); 418 css::uno::Any aAny(pDialogParent->GetXWindow()); 419 SfxUnoAnyItem aDialogParent( SID_DIALOG_PARENT, aAny ); 420 421 // unlock the dispatcher so SID_STYLE_NEW can be executed 422 // (SetDispatcherLock would affect all Calc documents) 423 ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell(); 424 SfxDispatcher* pDisp = pViewShell->GetDispatcher(); 425 bool bLocked = pDisp->IsLocked(); 426 if (bLocked) 427 pDisp->Lock(false); 428 429 // Execute the "new style" slot, complete with undo and all necessary updates. 430 // The return value (SfxUInt16Item) is ignored, look for new styles instead. 431 pDisp->ExecuteList(SID_STYLE_NEW, 432 SfxCallMode::SYNCHRON | SfxCallMode::RECORD, 433 { &aFamilyItem, &aRefItem }, { &aDialogParent }); 434 435 if (bLocked) 436 pDisp->Lock(true); 437 438 // Find the new style and add it into the style list boxes 439 SfxStyleSheetIterator aStyleIter( pDoc->GetStyleSheetPool(), SfxStyleFamily::Para ); 440 bool bFound = false; 441 for ( SfxStyleSheetBase* pStyle = aStyleIter.First(); pStyle && !bFound; pStyle = aStyleIter.Next() ) 442 { 443 const OUString& aName = pStyle->GetName(); 444 if (rLbStyle.find_text(aName) == -1) // all lists contain the same entries 445 { 446 for( sal_Int32 i = 1, n = rLbStyle.get_count(); i <= n && !bFound; ++i) 447 { 448 OUString aStyleName = ScGlobal::pCharClass->uppercase(rLbStyle.get_text(i)); 449 if( i == n ) 450 { 451 rLbStyle.append_text(aName); 452 rLbStyle.set_active_text(aName); 453 bFound = true; 454 } 455 else if( aStyleName > ScGlobal::pCharClass->uppercase(aName) ) 456 { 457 rLbStyle.insert_text(i, aName); 458 rLbStyle.set_active_text(aName); 459 bFound = true; 460 } 461 } 462 } 463 } 464 } 465 466 OUString aStyleName = rLbStyle.get_active_text(); 467 SfxStyleSheetBase* pStyleSheet = pDoc->GetStyleSheetPool()->Find( aStyleName, SfxStyleFamily::Para ); 468 if(pStyleSheet) 469 { 470 const SfxItemSet& rSet = pStyleSheet->GetItemSet(); 471 rWdPreview.SetFromItemSet(rSet, false); 472 } 473 } 474 475 } 476 477 IMPL_LINK_NOARG(ScConditionFrmtEntry, StyleSelectHdl, weld::ComboBox&, void) 478 { 479 mbIsInStyleCreate = true; 480 StyleSelect(mpParent->GetFrameWeld(), *mxLbStyle, mpDoc, maWdPreview); 481 mbIsInStyleCreate = false; 482 } 483 484 // formula 485 486 ScFormulaFrmtEntry::ScFormulaFrmtEntry(ScCondFormatList* pParent, ScDocument* pDoc, ScCondFormatDlg* pDialogParent, const ScAddress& rPos, const ScCondFormatEntry* pFormat) 487 : ScCondFrmtEntry(pParent, pDoc, rPos) 488 , mxFtStyle(mxBuilder->weld_label("styleft")) 489 , mxLbStyle(mxBuilder->weld_combo_box("style")) 490 , mxWdPreviewWin(mxBuilder->weld_widget("previewwin")) 491 , mxWdPreview(new weld::CustomWeld(*mxBuilder, "preview", maWdPreview)) 492 , mxEdFormula(new formula::RefEdit(mxBuilder->weld_entry("formula"))) 493 { 494 mxWdPreview->set_size_request(-1, mxLbStyle->get_preferred_size().Height()); 495 496 Init(pDialogParent); 497 498 mxLbType->set_active(2); 499 500 if(pFormat) 501 { 502 mxEdFormula->SetText(pFormat->GetExpression(rPos, 0, 0, pDoc->GetGrammar())); 503 mxLbStyle->set_active_text(pFormat->GetStyle()); 504 } 505 else 506 { 507 mxLbStyle->set_active(1); 508 } 509 510 StyleSelectHdl(*mxLbStyle); 511 } 512 513 ScFormulaFrmtEntry::~ScFormulaFrmtEntry() 514 { 515 } 516 517 void ScFormulaFrmtEntry::Init(ScCondFormatDlg* pDialogParent) 518 { 519 mxEdFormula->SetGetFocusHdl( LINK( pDialogParent, ScCondFormatDlg, RangeGetFocusHdl ) ); 520 521 FillStyleListBox( mpDoc, *mxLbStyle ); 522 mxLbStyle->connect_changed( LINK( this, ScFormulaFrmtEntry, StyleSelectHdl ) ); 523 } 524 525 IMPL_LINK_NOARG(ScFormulaFrmtEntry, StyleSelectHdl, weld::ComboBox&, void) 526 { 527 StyleSelect(mpParent->GetFrameWeld(), *mxLbStyle, mpDoc, maWdPreview); 528 } 529 530 ScFormatEntry* ScFormulaFrmtEntry::createFormulaEntry() const 531 { 532 OUString aFormula = mxEdFormula->GetText(); 533 if(aFormula.isEmpty()) 534 return nullptr; 535 536 ScFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct, aFormula, OUString(), mpDoc, maPos, mxLbStyle->get_active_text()); 537 return pEntry; 538 } 539 540 ScFormatEntry* ScFormulaFrmtEntry::GetEntry() const 541 { 542 return createFormulaEntry(); 543 } 544 545 OUString ScFormulaFrmtEntry::GetExpressionString() 546 { 547 return ScCondFormatHelper::GetExpression(FORMULA, 0, mxEdFormula->GetText()); 548 } 549 550 void ScFormulaFrmtEntry::SetActive() 551 { 552 mxWdPreviewWin->show(); 553 mxFtStyle->show(); 554 mxLbStyle->show(); 555 mxEdFormula->GetWidget()->show(); 556 557 Select(); 558 } 559 560 void ScFormulaFrmtEntry::SetInactive() 561 { 562 mxWdPreviewWin->hide(); 563 mxFtStyle->hide(); 564 mxLbStyle->hide(); 565 mxEdFormula->GetWidget()->hide(); 566 567 Deselect(); 568 } 569 570 //color scale 571 572 namespace { 573 574 OUString convertNumberToString(double nVal, const ScDocument* pDoc) 575 { 576 SvNumberFormatter* pNumberFormatter = pDoc->GetFormatTable(); 577 OUString aText; 578 pNumberFormatter->GetInputLineString(nVal, 0, aText); 579 return aText; 580 } 581 582 const struct 583 { 584 ScColorScaleEntryType eType; 585 const char* sId; 586 } TypeIdMap[] = { 587 { COLORSCALE_AUTO, "auto" }, 588 { COLORSCALE_MIN, "min" }, 589 { COLORSCALE_MAX, "max" }, 590 { COLORSCALE_PERCENTILE, "percentil" }, 591 { COLORSCALE_VALUE, "value" }, 592 { COLORSCALE_PERCENT, "percent" }, 593 { COLORSCALE_FORMULA, "formula" }, 594 }; 595 596 ScColorScaleEntryType getTypeForId(const OUString& sId) 597 { 598 for (auto& r : TypeIdMap) 599 { 600 if (sId.equalsAscii(r.sId)) 601 return r.eType; 602 } 603 assert(false); // The id is not in TypeIdMap - something not in sync? 604 return COLORSCALE_AUTO; // invalid id - use default 605 } 606 607 // Item ids are imported from .ui into OUString* and are referenced by entry data. 608 // See commit 83cefb5ceb4428d61a5b9fae80d1e673131e9bfe 609 610 ScColorScaleEntryType getSelectedType(const weld::ComboBox& rListBox) 611 { 612 return getTypeForId(rListBox.get_active_id()); 613 } 614 615 sal_Int32 getEntryPos(const weld::ComboBox& rListBox, ScColorScaleEntryType eType) 616 { 617 const sal_Int32 nSize = rListBox.get_count(); 618 for (sal_Int32 i = 0; i < nSize; ++i) 619 { 620 if (getTypeForId(rListBox.get_id(i)) == eType) 621 return i; 622 } 623 return -1; 624 } 625 626 void selectType(weld::ComboBox& rListBox, ScColorScaleEntryType eType) 627 { 628 const sal_Int32 nPos = getEntryPos(rListBox, eType); 629 if (nPos >= 0) 630 rListBox.set_active(nPos); 631 } 632 633 void removeType(weld::ComboBox& rListBox, ScColorScaleEntryType eType) 634 { 635 const sal_Int32 nPos = getEntryPos(rListBox, eType); 636 if (nPos >= 0) 637 rListBox.remove(nPos); 638 } 639 640 void SetColorScaleEntryTypes( const ScColorScaleEntry& rEntry, weld::ComboBox& rLbType, weld::Entry& rEdit, ColorListBox& rLbCol, const ScDocument* pDoc ) 641 { 642 // entry Automatic is not available for color scales 643 assert(rEntry.GetType() > COLORSCALE_AUTO); 644 selectType(rLbType, rEntry.GetType()); 645 switch(rEntry.GetType()) 646 { 647 case COLORSCALE_MIN: 648 case COLORSCALE_MAX: 649 break; 650 case COLORSCALE_PERCENTILE: 651 case COLORSCALE_VALUE: 652 case COLORSCALE_PERCENT: 653 { 654 double nVal = rEntry.GetValue(); 655 rEdit.set_text(convertNumberToString(nVal, pDoc)); 656 } 657 break; 658 case COLORSCALE_FORMULA: 659 rEdit.set_text(rEntry.GetFormula(formula::FormulaGrammar::GRAM_DEFAULT)); 660 break; 661 case COLORSCALE_AUTO: 662 abort(); 663 break; 664 } 665 rLbCol.SelectEntry(rEntry.GetColor()); 666 } 667 668 void SetColorScaleEntry(ScColorScaleEntry* pEntry, const weld::ComboBox& rType, const weld::Entry& rValue, 669 ScDocument* pDoc, const ScAddress& rPos) 670 { 671 ScColorScaleEntryType eType = getSelectedType(rType); 672 673 pEntry->SetType(eType); 674 switch (eType) 675 { 676 case COLORSCALE_AUTO: 677 case COLORSCALE_MIN: 678 case COLORSCALE_MAX: 679 break; 680 case COLORSCALE_PERCENTILE: 681 case COLORSCALE_VALUE: 682 case COLORSCALE_PERCENT: 683 { 684 sal_uInt32 nIndex = 0; 685 double nVal = 0; 686 SvNumberFormatter* pNumberFormatter = pDoc->GetFormatTable(); 687 (void)pNumberFormatter->IsNumberFormat(rValue.get_text(), nIndex, nVal); 688 pEntry->SetValue(nVal); 689 } 690 break; 691 case COLORSCALE_FORMULA: 692 pEntry->SetFormula(rValue.get_text(), pDoc, rPos); 693 break; 694 default: 695 break; 696 } 697 } 698 699 ScColorScaleEntry* createColorScaleEntry( const weld::ComboBox& rType, const ColorListBox& rColor, const weld::Entry& rValue, ScDocument* pDoc, const ScAddress& rPos ) 700 { 701 ScColorScaleEntry* pEntry = new ScColorScaleEntry(); 702 703 SetColorScaleEntry(pEntry, rType, rValue, pDoc, rPos); 704 Color aColor = rColor.GetSelectEntryColor(); 705 pEntry->SetColor(aColor); 706 return pEntry; 707 } 708 709 } 710 711 ScColorScale2FrmtEntry::ScColorScale2FrmtEntry(ScCondFormatList* pParent, ScDocument* pDoc, const ScAddress& rPos, const ScColorScaleFormat* pFormat) 712 : ScCondFrmtEntry(pParent, pDoc, rPos) 713 , mxLbColorFormat(mxBuilder->weld_combo_box("colorformat")) 714 , mxLbEntryTypeMin(mxBuilder->weld_combo_box("colscalemin")) 715 , mxLbEntryTypeMax(mxBuilder->weld_combo_box("colscalemax")) 716 , mxEdMin(mxBuilder->weld_entry("edcolscalemin")) 717 , mxEdMax(mxBuilder->weld_entry("edcolscalemax")) 718 , mxLbColMin(new ColorListBox(mxBuilder->weld_menu_button("lbcolmin"), pParent->GetFrameWeld())) 719 , mxLbColMax(new ColorListBox(mxBuilder->weld_menu_button("lbcolmax"), pParent->GetFrameWeld())) 720 , mxFtMin(mxBuilder->weld_label("Label_minimum")) 721 , mxFtMax(mxBuilder->weld_label("Label_maximum")) 722 { 723 mxFtMin->show(); 724 mxFtMax->show(); 725 726 // remove the automatic entry from color scales 727 removeType(*mxLbEntryTypeMin, COLORSCALE_AUTO); 728 removeType(*mxLbEntryTypeMax, COLORSCALE_AUTO); 729 // "min" selector doesn't need "max" entry, and vice versa 730 removeType(*mxLbEntryTypeMin, COLORSCALE_MAX); 731 removeType(*mxLbEntryTypeMax, COLORSCALE_MIN); 732 733 mxLbType->set_active(0); 734 mxLbColorFormat->set_active(0); 735 Init(); 736 if(pFormat) 737 { 738 ScColorScaleEntries::const_iterator itr = pFormat->begin(); 739 SetColorScaleEntryTypes(*itr[0], *mxLbEntryTypeMin, *mxEdMin, *mxLbColMin, pDoc); 740 ++itr; 741 SetColorScaleEntryTypes(*itr[0], *mxLbEntryTypeMax, *mxEdMax, *mxLbColMax, pDoc); 742 } 743 else 744 { 745 selectType(*mxLbEntryTypeMin, COLORSCALE_MIN); 746 selectType(*mxLbEntryTypeMax, COLORSCALE_MAX); 747 } 748 749 mxLbColorFormat->connect_changed( LINK( pParent, ScCondFormatList, ColFormatTypeHdl ) ); 750 751 EntryTypeHdl(*mxLbEntryTypeMin); 752 EntryTypeHdl(*mxLbEntryTypeMax); 753 } 754 755 ScColorScale2FrmtEntry::~ScColorScale2FrmtEntry() 756 { 757 } 758 759 void ScColorScale2FrmtEntry::Init() 760 { 761 mxLbEntryTypeMin->connect_changed( LINK( this, ScColorScale2FrmtEntry, EntryTypeHdl ) ); 762 mxLbEntryTypeMax->connect_changed( LINK( this, ScColorScale2FrmtEntry, EntryTypeHdl ) ); 763 mxLbColMin->SelectEntry(Color(0xFFF685)); // Light Yellow 2 764 mxLbColMax->SelectEntry(Color(0x65C295)); // Light Green 2 765 } 766 767 ScFormatEntry* ScColorScale2FrmtEntry::createColorscaleEntry() const 768 { 769 ScColorScaleFormat* pColorScale = new ScColorScaleFormat(mpDoc); 770 pColorScale->AddEntry(createColorScaleEntry(*mxLbEntryTypeMin, *mxLbColMin, *mxEdMin, mpDoc, maPos)); 771 pColorScale->AddEntry(createColorScaleEntry(*mxLbEntryTypeMax, *mxLbColMax, *mxEdMax, mpDoc, maPos)); 772 return pColorScale; 773 } 774 775 OUString ScColorScale2FrmtEntry::GetExpressionString() 776 { 777 return ScCondFormatHelper::GetExpression( COLORSCALE, 0 ); 778 } 779 780 ScFormatEntry* ScColorScale2FrmtEntry::GetEntry() const 781 { 782 return createColorscaleEntry(); 783 } 784 785 void ScColorScale2FrmtEntry::SetActive() 786 { 787 mxLbColorFormat->show(); 788 789 mxLbEntryTypeMin->show(); 790 mxLbEntryTypeMax->show(); 791 792 mxEdMin->show(); 793 mxEdMax->show(); 794 795 mxLbColMin->show(); 796 mxLbColMax->show(); 797 798 Select(); 799 } 800 801 void ScColorScale2FrmtEntry::SetInactive() 802 { 803 mxLbColorFormat->hide(); 804 805 mxLbEntryTypeMin->hide(); 806 mxLbEntryTypeMax->hide(); 807 808 mxEdMin->hide(); 809 mxEdMax->hide(); 810 811 mxLbColMin->hide(); 812 mxLbColMax->hide(); 813 814 Deselect(); 815 } 816 817 IMPL_LINK( ScColorScale2FrmtEntry, EntryTypeHdl, weld::ComboBox&, rBox, void ) 818 { 819 weld::Entry* pEd = nullptr; 820 if (&rBox == mxLbEntryTypeMin.get()) 821 pEd = mxEdMin.get(); 822 else if (&rBox == mxLbEntryTypeMax.get()) 823 pEd = mxEdMax.get(); 824 825 if (!pEd) 826 return; 827 828 bool bEnableEdit = true; 829 if (getSelectedType(rBox) <= COLORSCALE_MAX) 830 { 831 bEnableEdit = false; 832 } 833 834 if (bEnableEdit) 835 pEd->set_sensitive(true); 836 else 837 pEd->set_sensitive(false); 838 } 839 840 ScColorScale3FrmtEntry::ScColorScale3FrmtEntry(ScCondFormatList* pParent, ScDocument* pDoc, const ScAddress& rPos, const ScColorScaleFormat* pFormat) 841 : ScCondFrmtEntry(pParent, pDoc, rPos) 842 , mxLbColorFormat(mxBuilder->weld_combo_box("colorformat")) 843 , mxLbEntryTypeMin(mxBuilder->weld_combo_box("colscalemin")) 844 , mxLbEntryTypeMiddle(mxBuilder->weld_combo_box("colscalemiddle")) 845 , mxLbEntryTypeMax(mxBuilder->weld_combo_box("colscalemax")) 846 , mxEdMin(mxBuilder->weld_entry("edcolscalemin")) 847 , mxEdMiddle(mxBuilder->weld_entry("edcolscalemiddle")) 848 , mxEdMax(mxBuilder->weld_entry("edcolscalemax")) 849 , mxLbColMin(new ColorListBox(mxBuilder->weld_menu_button("lbcolmin"), pParent->GetFrameWeld())) 850 , mxLbColMiddle(new ColorListBox(mxBuilder->weld_menu_button("lbcolmiddle"), pParent->GetFrameWeld())) 851 , mxLbColMax(new ColorListBox(mxBuilder->weld_menu_button("lbcolmax"), pParent->GetFrameWeld())) 852 , mxFtMin(mxBuilder->weld_label("Label_minimum")) 853 , mxFtMax(mxBuilder->weld_label("Label_maximum")) 854 { 855 mxFtMin->show(); 856 mxFtMax->show(); 857 858 // remove the automatic entry from color scales 859 removeType(*mxLbEntryTypeMin, COLORSCALE_AUTO); 860 removeType(*mxLbEntryTypeMiddle, COLORSCALE_AUTO); 861 removeType(*mxLbEntryTypeMax, COLORSCALE_AUTO); 862 // "min" selector doesn't need "max" entry, and vice versa 863 removeType(*mxLbEntryTypeMin, COLORSCALE_MAX); 864 removeType(*mxLbEntryTypeMax, COLORSCALE_MIN); 865 mxLbColorFormat->set_active(1); 866 867 Init(); 868 mxLbType->set_active(0); 869 if(pFormat) 870 { 871 ScColorScaleEntries::const_iterator itr = pFormat->begin(); 872 SetColorScaleEntryTypes(*itr[0], *mxLbEntryTypeMin, *mxEdMin, *mxLbColMin, pDoc); 873 assert(pFormat->size() == 3); 874 ++itr; 875 SetColorScaleEntryTypes(*itr[0], *mxLbEntryTypeMiddle, *mxEdMiddle, *mxLbColMiddle, pDoc); 876 ++itr; 877 SetColorScaleEntryTypes(*itr[0], *mxLbEntryTypeMax, *mxEdMax, *mxLbColMax, pDoc); 878 } 879 else 880 { 881 mxLbColorFormat->set_active(1); 882 selectType(*mxLbEntryTypeMin, COLORSCALE_MIN); 883 selectType(*mxLbEntryTypeMiddle, COLORSCALE_PERCENTILE); 884 selectType(*mxLbEntryTypeMax, COLORSCALE_MAX); 885 mxEdMiddle->set_text(OUString::number(50)); 886 } 887 888 mxLbColorFormat->connect_changed( LINK( pParent, ScCondFormatList, ColFormatTypeHdl ) ); 889 EntryTypeHdl(*mxLbEntryTypeMin); 890 EntryTypeHdl(*mxLbEntryTypeMiddle); 891 EntryTypeHdl(*mxLbEntryTypeMax); 892 } 893 894 ScColorScale3FrmtEntry::~ScColorScale3FrmtEntry() 895 { 896 } 897 898 void ScColorScale3FrmtEntry::Init() 899 { 900 mxLbEntryTypeMin->connect_changed( LINK( this, ScColorScale3FrmtEntry, EntryTypeHdl ) ); 901 mxLbEntryTypeMax->connect_changed( LINK( this, ScColorScale3FrmtEntry, EntryTypeHdl ) ); 902 mxLbEntryTypeMiddle->connect_changed( LINK( this, ScColorScale3FrmtEntry, EntryTypeHdl ) ); 903 mxLbColMin->SelectEntry(COL_LIGHTRED); 904 mxLbColMiddle->SelectEntry(COL_YELLOW); 905 mxLbColMax->SelectEntry(Color(0x00CC00)); 906 } 907 908 ScFormatEntry* ScColorScale3FrmtEntry::createColorscaleEntry() const 909 { 910 ScColorScaleFormat* pColorScale = new ScColorScaleFormat(mpDoc); 911 pColorScale->AddEntry(createColorScaleEntry(*mxLbEntryTypeMin, *mxLbColMin, *mxEdMin, mpDoc, maPos)); 912 if (mxLbColorFormat->get_active() == 1) 913 pColorScale->AddEntry(createColorScaleEntry(*mxLbEntryTypeMiddle, *mxLbColMiddle, *mxEdMiddle, mpDoc, maPos)); 914 pColorScale->AddEntry(createColorScaleEntry(*mxLbEntryTypeMax, *mxLbColMax, *mxEdMax, mpDoc, maPos)); 915 return pColorScale; 916 } 917 918 OUString ScColorScale3FrmtEntry::GetExpressionString() 919 { 920 return ScCondFormatHelper::GetExpression( COLORSCALE, 0 ); 921 } 922 923 ScFormatEntry* ScColorScale3FrmtEntry::GetEntry() const 924 { 925 return createColorscaleEntry(); 926 } 927 928 void ScColorScale3FrmtEntry::SetActive() 929 { 930 mxLbColorFormat->show(); 931 mxLbEntryTypeMin->show(); 932 mxLbEntryTypeMiddle->show(); 933 mxLbEntryTypeMax->show(); 934 935 mxEdMin->show(); 936 mxEdMiddle->show(); 937 mxEdMax->show(); 938 939 mxLbColMin->show(); 940 mxLbColMiddle->show(); 941 mxLbColMax->show(); 942 943 Select(); 944 } 945 946 void ScColorScale3FrmtEntry::SetInactive() 947 { 948 mxLbColorFormat->hide(); 949 950 mxLbEntryTypeMin->hide(); 951 mxLbEntryTypeMiddle->hide(); 952 mxLbEntryTypeMax->hide(); 953 954 mxEdMin->hide(); 955 mxEdMiddle->hide(); 956 mxEdMax->hide(); 957 958 mxLbColMin->hide(); 959 mxLbColMiddle->hide(); 960 mxLbColMax->hide(); 961 962 Deselect(); 963 } 964 965 IMPL_LINK( ScColorScale3FrmtEntry, EntryTypeHdl, weld::ComboBox&, rBox, void ) 966 { 967 weld::Entry* pEd = nullptr; 968 if(&rBox == mxLbEntryTypeMin.get()) 969 pEd = mxEdMin.get(); 970 else if(&rBox == mxLbEntryTypeMiddle.get()) 971 pEd = mxEdMiddle.get(); 972 else if(&rBox == mxLbEntryTypeMax.get()) 973 pEd = mxEdMax.get(); 974 975 if (!pEd) 976 return; 977 978 bool bEnableEdit = true; 979 if (getSelectedType(rBox) <= COLORSCALE_MAX) 980 { 981 bEnableEdit = false; 982 } 983 984 if(bEnableEdit) 985 pEd->set_sensitive(true); 986 else 987 pEd->set_sensitive(false); 988 } 989 990 IMPL_LINK_NOARG(ScConditionFrmtEntry, ConditionTypeSelectHdl, weld::ComboBox&, void) 991 { 992 sal_Int32 nSelectPos = mxLbCondType->get_active(); 993 ScConditionMode eMode = EntryPosToConditionMode(nSelectPos); 994 switch(GetNumberEditFields(eMode)) 995 { 996 case 0: 997 mxEdVal1->GetWidget()->hide(); 998 mxEdVal2->GetWidget()->hide(); 999 mxFtVal->hide(); 1000 break; 1001 case 1: 1002 mxEdVal1->GetWidget()->show(); 1003 mxEdVal2->GetWidget()->hide(); 1004 mxFtVal->show(); 1005 break; 1006 case 2: 1007 mxEdVal1->GetWidget()->show(); 1008 mxEdVal2->GetWidget()->show(); 1009 mxFtVal->show(); 1010 break; 1011 } 1012 } 1013 1014 //databar 1015 1016 namespace { 1017 1018 void SetDataBarEntryTypes( const ScColorScaleEntry& rEntry, weld::ComboBox& rLbType, weld::Entry& rEdit, const ScDocument* pDoc ) 1019 { 1020 selectType(rLbType, rEntry.GetType()); 1021 switch(rEntry.GetType()) 1022 { 1023 case COLORSCALE_AUTO: 1024 case COLORSCALE_MIN: 1025 case COLORSCALE_MAX: 1026 break; 1027 case COLORSCALE_VALUE: 1028 case COLORSCALE_PERCENT: 1029 case COLORSCALE_PERCENTILE: 1030 { 1031 double nVal = rEntry.GetValue(); 1032 SvNumberFormatter* pNumberFormatter = pDoc->GetFormatTable(); 1033 OUString aText; 1034 pNumberFormatter->GetInputLineString(nVal, 0, aText); 1035 rEdit.set_text(aText); 1036 } 1037 break; 1038 case COLORSCALE_FORMULA: 1039 rEdit.set_text(rEntry.GetFormula(formula::FormulaGrammar::GRAM_DEFAULT)); 1040 break; 1041 } 1042 } 1043 1044 } 1045 1046 ScDataBarFrmtEntry::ScDataBarFrmtEntry(ScCondFormatList* pParent, ScDocument* pDoc, const ScAddress& rPos, const ScDataBarFormat* pFormat) 1047 : ScCondFrmtEntry(pParent, pDoc, rPos) 1048 , mxLbColorFormat(mxBuilder->weld_combo_box("colorformat")) 1049 , mxLbDataBarMinType(mxBuilder->weld_combo_box("colscalemin")) 1050 , mxLbDataBarMaxType(mxBuilder->weld_combo_box("colscalemax")) 1051 , mxEdDataBarMin(mxBuilder->weld_entry("edcolscalemin")) 1052 , mxEdDataBarMax(mxBuilder->weld_entry("edcolscalemax")) 1053 , mxBtOptions(mxBuilder->weld_button("options")) 1054 , mxFtMin(mxBuilder->weld_label("Label_minimum")) 1055 , mxFtMax(mxBuilder->weld_label("Label_maximum")) 1056 { 1057 // "min" selector doesn't need "max" entry, and vice versa 1058 removeType(*mxLbDataBarMinType, COLORSCALE_MAX); 1059 removeType(*mxLbDataBarMaxType, COLORSCALE_MIN); 1060 1061 mxFtMin->show(); 1062 mxFtMax->show(); 1063 1064 mxLbColorFormat->set_active(2); 1065 mxLbType->set_active(0); 1066 if(pFormat) 1067 { 1068 mpDataBarData.reset(new ScDataBarFormatData(*pFormat->GetDataBarData())); 1069 SetDataBarEntryTypes(*mpDataBarData->mpLowerLimit, *mxLbDataBarMinType, *mxEdDataBarMin, pDoc); 1070 SetDataBarEntryTypes(*mpDataBarData->mpUpperLimit, *mxLbDataBarMaxType, *mxEdDataBarMax, pDoc); 1071 DataBarTypeSelectHdl(*mxLbDataBarMinType); 1072 } 1073 else 1074 { 1075 selectType(*mxLbDataBarMinType, COLORSCALE_AUTO); 1076 selectType(*mxLbDataBarMaxType, COLORSCALE_AUTO); 1077 DataBarTypeSelectHdl(*mxLbDataBarMinType); 1078 } 1079 Init(); 1080 1081 mxLbColorFormat->connect_changed( LINK( pParent, ScCondFormatList, ColFormatTypeHdl ) ); 1082 } 1083 1084 ScDataBarFrmtEntry::~ScDataBarFrmtEntry() 1085 { 1086 } 1087 1088 ScFormatEntry* ScDataBarFrmtEntry::GetEntry() const 1089 { 1090 return createDatabarEntry(); 1091 } 1092 1093 void ScDataBarFrmtEntry::Init() 1094 { 1095 mxLbDataBarMinType->connect_changed( LINK( this, ScDataBarFrmtEntry, DataBarTypeSelectHdl ) ); 1096 mxLbDataBarMaxType->connect_changed( LINK( this, ScDataBarFrmtEntry, DataBarTypeSelectHdl ) ); 1097 1098 mxBtOptions->connect_clicked( LINK( this, ScDataBarFrmtEntry, OptionBtnHdl ) ); 1099 1100 if(!mpDataBarData) 1101 { 1102 mpDataBarData.reset(new ScDataBarFormatData()); 1103 mpDataBarData->mpUpperLimit.reset(new ScColorScaleEntry()); 1104 mpDataBarData->mpLowerLimit.reset(new ScColorScaleEntry()); 1105 mpDataBarData->mpLowerLimit->SetType(COLORSCALE_AUTO); 1106 mpDataBarData->mpUpperLimit->SetType(COLORSCALE_AUTO); 1107 mpDataBarData->maPositiveColor = COL_LIGHTBLUE; 1108 } 1109 } 1110 1111 ScFormatEntry* ScDataBarFrmtEntry::createDatabarEntry() const 1112 { 1113 SetColorScaleEntry(mpDataBarData->mpLowerLimit.get(), *mxLbDataBarMinType, 1114 *mxEdDataBarMin, mpDoc, maPos); 1115 SetColorScaleEntry(mpDataBarData->mpUpperLimit.get(), *mxLbDataBarMaxType, 1116 *mxEdDataBarMax, mpDoc, maPos); 1117 ScDataBarFormat* pDataBar = new ScDataBarFormat(mpDoc); 1118 pDataBar->SetDataBarData(new ScDataBarFormatData(*mpDataBarData)); 1119 return pDataBar; 1120 } 1121 1122 OUString ScDataBarFrmtEntry::GetExpressionString() 1123 { 1124 return ScCondFormatHelper::GetExpression( DATABAR, 0 ); 1125 } 1126 1127 void ScDataBarFrmtEntry::SetActive() 1128 { 1129 mxLbColorFormat->show(); 1130 1131 mxLbDataBarMinType->show(); 1132 mxLbDataBarMaxType->show(); 1133 mxEdDataBarMin->show(); 1134 mxEdDataBarMax->show(); 1135 mxBtOptions->show(); 1136 1137 Select(); 1138 } 1139 1140 void ScDataBarFrmtEntry::SetInactive() 1141 { 1142 mxLbColorFormat->hide(); 1143 1144 mxLbDataBarMinType->hide(); 1145 mxLbDataBarMaxType->hide(); 1146 mxEdDataBarMin->hide(); 1147 mxEdDataBarMax->hide(); 1148 mxBtOptions->hide(); 1149 1150 Deselect(); 1151 } 1152 1153 IMPL_LINK_NOARG( ScDataBarFrmtEntry, DataBarTypeSelectHdl, weld::ComboBox&, void ) 1154 { 1155 if (getSelectedType(*mxLbDataBarMinType) <= COLORSCALE_MAX) 1156 mxEdDataBarMin->set_sensitive(false); 1157 else 1158 mxEdDataBarMin->set_sensitive(true); 1159 1160 if (getSelectedType(*mxLbDataBarMaxType) <= COLORSCALE_MAX) 1161 mxEdDataBarMax->set_sensitive(false); 1162 else 1163 mxEdDataBarMax->set_sensitive(true); 1164 } 1165 1166 IMPL_LINK_NOARG( ScDataBarFrmtEntry, OptionBtnHdl, weld::Button&, void ) 1167 { 1168 SetColorScaleEntry(mpDataBarData->mpLowerLimit.get(), *mxLbDataBarMinType, 1169 *mxEdDataBarMin, mpDoc, maPos); 1170 SetColorScaleEntry(mpDataBarData->mpUpperLimit.get(), *mxLbDataBarMaxType, 1171 *mxEdDataBarMax, mpDoc, maPos); 1172 ScDataBarSettingsDlg aDlg(mpParent->GetFrameWeld(), *mpDataBarData, mpDoc, maPos); 1173 if (aDlg.run() == RET_OK) 1174 { 1175 mpDataBarData.reset(aDlg.GetData()); 1176 SetDataBarEntryTypes(*mpDataBarData->mpLowerLimit, *mxLbDataBarMinType, *mxEdDataBarMin, mpDoc); 1177 SetDataBarEntryTypes(*mpDataBarData->mpUpperLimit, *mxLbDataBarMaxType, *mxEdDataBarMax, mpDoc); 1178 DataBarTypeSelectHdl(*mxLbDataBarMinType); 1179 } 1180 } 1181 1182 ScDateFrmtEntry::ScDateFrmtEntry(ScCondFormatList* pParent, ScDocument* pDoc, const ScCondDateFormatEntry* pFormat) 1183 : ScCondFrmtEntry(pParent, pDoc, ScAddress()) 1184 , mxLbDateEntry(mxBuilder->weld_combo_box("datetype")) 1185 , mxFtStyle(mxBuilder->weld_label("styleft")) 1186 , mxLbStyle(mxBuilder->weld_combo_box("style")) 1187 , mxWdPreviewWin(mxBuilder->weld_widget("previewwin")) 1188 , mxWdPreview(new weld::CustomWeld(*mxBuilder, "preview", maWdPreview)) 1189 , mbIsInStyleCreate(false) 1190 { 1191 mxWdPreview->set_size_request(mxLbStyle->get_preferred_size().Height(), -1); 1192 1193 Init(); 1194 1195 StartListening(*pDoc->GetStyleSheetPool(), DuplicateHandling::Prevent); 1196 1197 if(pFormat) 1198 { 1199 sal_Int32 nPos = static_cast<sal_Int32>(pFormat->GetDateType()); 1200 mxLbDateEntry->set_active(nPos); 1201 1202 mxLbStyle->set_active_text(pFormat->GetStyleName()); 1203 } 1204 1205 StyleSelectHdl(*mxLbStyle); 1206 } 1207 1208 ScDateFrmtEntry::~ScDateFrmtEntry() 1209 { 1210 } 1211 1212 void ScDateFrmtEntry::Init() 1213 { 1214 mxLbDateEntry->set_active(0); 1215 mxLbType->set_active(3); 1216 1217 FillStyleListBox( mpDoc, *mxLbStyle ); 1218 mxLbStyle->connect_changed( LINK( this, ScDateFrmtEntry, StyleSelectHdl ) ); 1219 mxLbStyle->set_active(1); 1220 } 1221 1222 void ScDateFrmtEntry::SetActive() 1223 { 1224 mxLbDateEntry->show(); 1225 mxFtStyle->show(); 1226 mxWdPreviewWin->show(); 1227 mxLbStyle->show(); 1228 1229 Select(); 1230 } 1231 1232 void ScDateFrmtEntry::SetInactive() 1233 { 1234 mxLbDateEntry->hide(); 1235 mxFtStyle->hide(); 1236 mxWdPreviewWin->hide(); 1237 mxLbStyle->hide(); 1238 1239 Deselect(); 1240 } 1241 1242 void ScDateFrmtEntry::Notify( SfxBroadcaster&, const SfxHint& rHint ) 1243 { 1244 if(rHint.GetId() == SfxHintId::StyleSheetModified) 1245 { 1246 if(!mbIsInStyleCreate) 1247 UpdateStyleList(*mxLbStyle, mpDoc); 1248 } 1249 } 1250 1251 ScFormatEntry* ScDateFrmtEntry::GetEntry() const 1252 { 1253 ScCondDateFormatEntry* pNewEntry = new ScCondDateFormatEntry(mpDoc); 1254 condformat::ScCondFormatDateType eType = static_cast<condformat::ScCondFormatDateType>(mxLbDateEntry->get_active()); 1255 pNewEntry->SetDateType(eType); 1256 pNewEntry->SetStyleName(mxLbStyle->get_active_text()); 1257 return pNewEntry; 1258 } 1259 1260 OUString ScDateFrmtEntry::GetExpressionString() 1261 { 1262 return ScCondFormatHelper::GetExpression(DATE, 0); 1263 } 1264 1265 IMPL_LINK_NOARG( ScDateFrmtEntry, StyleSelectHdl, weld::ComboBox&, void ) 1266 { 1267 mbIsInStyleCreate = true; 1268 StyleSelect(mpParent->GetFrameWeld(), *mxLbStyle, mpDoc, maWdPreview); 1269 mbIsInStyleCreate = false; 1270 } 1271 1272 class ScIconSetFrmtDataEntry 1273 { 1274 protected: 1275 std::unique_ptr<weld::Builder> mxBuilder; 1276 private: 1277 std::unique_ptr<weld::Container> mxGrid; 1278 std::unique_ptr<weld::Image> mxImgIcon; 1279 std::unique_ptr<weld::Label> mxFtEntry; 1280 std::unique_ptr<weld::Entry> mxEdEntry; 1281 std::unique_ptr<weld::ComboBox> mxLbEntryType; 1282 1283 public: 1284 ScIconSetFrmtDataEntry(weld::Container* pParent, ScIconSetType eType, ScDocument* pDoc, 1285 sal_Int32 i, const ScColorScaleEntry* pEntry = nullptr); 1286 void Show() { mxGrid->show(); } 1287 void Hide() { mxGrid->hide(); } 1288 void set_grid_top_attach(int nTop) 1289 { 1290 mxGrid->set_grid_left_attach(0); 1291 mxGrid->set_grid_top_attach(nTop); 1292 } 1293 1294 ScColorScaleEntry* CreateEntry(ScDocument* pDoc, const ScAddress& rPos) const; 1295 1296 void SetFirstEntry(); 1297 }; 1298 1299 ScIconSetFrmtDataEntry::ScIconSetFrmtDataEntry(weld::Container* pParent, ScIconSetType eType, ScDocument* pDoc, sal_Int32 i, const ScColorScaleEntry* pEntry) 1300 : mxBuilder(Application::CreateBuilder(pParent, "modules/scalc/ui/conditionaliconset.ui")) 1301 , mxGrid(mxBuilder->weld_container("ConditionalIconSet")) 1302 , mxImgIcon(mxBuilder->weld_image("icon")) 1303 , mxFtEntry(mxBuilder->weld_label("label")) 1304 , mxEdEntry(mxBuilder->weld_entry("entry")) 1305 , mxLbEntryType(mxBuilder->weld_combo_box("listbox")) 1306 { 1307 mxImgIcon->set_from_icon_name(ScIconSetFormat::getIconName(eType, i)); 1308 if(pEntry) 1309 { 1310 switch(pEntry->GetType()) 1311 { 1312 case COLORSCALE_VALUE: 1313 mxLbEntryType->set_active(0); 1314 mxEdEntry->set_text(convertNumberToString(pEntry->GetValue(), pDoc)); 1315 break; 1316 case COLORSCALE_PERCENTILE: 1317 mxLbEntryType->set_active(2); 1318 mxEdEntry->set_text(convertNumberToString(pEntry->GetValue(), pDoc)); 1319 break; 1320 case COLORSCALE_PERCENT: 1321 mxLbEntryType->set_active(1); 1322 mxEdEntry->set_text(convertNumberToString(pEntry->GetValue(), pDoc)); 1323 break; 1324 case COLORSCALE_FORMULA: 1325 mxLbEntryType->set_active(3); 1326 mxEdEntry->set_text(pEntry->GetFormula(formula::FormulaGrammar::GRAM_DEFAULT)); 1327 break; 1328 default: 1329 assert(false); 1330 } 1331 } 1332 else 1333 { 1334 mxLbEntryType->set_active(1); 1335 } 1336 } 1337 1338 ScColorScaleEntry* ScIconSetFrmtDataEntry::CreateEntry(ScDocument* pDoc, const ScAddress& rPos) const 1339 { 1340 sal_Int32 nPos = mxLbEntryType->get_active(); 1341 OUString aText = mxEdEntry->get_text(); 1342 ScColorScaleEntry* pEntry = new ScColorScaleEntry(); 1343 1344 sal_uInt32 nIndex = 0; 1345 double nVal = 0; 1346 SvNumberFormatter* pNumberFormatter = pDoc->GetFormatTable(); 1347 (void)pNumberFormatter->IsNumberFormat(aText, nIndex, nVal); 1348 pEntry->SetValue(nVal); 1349 1350 switch(nPos) 1351 { 1352 case 0: 1353 pEntry->SetType(COLORSCALE_VALUE); 1354 break; 1355 case 1: 1356 pEntry->SetType(COLORSCALE_PERCENT); 1357 break; 1358 case 2: 1359 pEntry->SetType(COLORSCALE_PERCENTILE); 1360 break; 1361 case 3: 1362 pEntry->SetType(COLORSCALE_FORMULA); 1363 pEntry->SetFormula(aText, pDoc, rPos, pDoc->GetGrammar()); 1364 break; 1365 default: 1366 assert(false); 1367 } 1368 1369 return pEntry; 1370 } 1371 1372 void ScIconSetFrmtDataEntry::SetFirstEntry() 1373 { 1374 mxEdEntry->hide(); 1375 mxLbEntryType->hide(); 1376 mxFtEntry->hide(); 1377 mxEdEntry->set_text("0"); 1378 mxLbEntryType->set_active(1); 1379 } 1380 1381 ScIconSetFrmtEntry::ScIconSetFrmtEntry(ScCondFormatList* pParent, ScDocument* pDoc, const ScAddress& rPos, const ScIconSetFormat* pFormat) 1382 : ScCondFrmtEntry(pParent, pDoc, rPos) 1383 , mxLbColorFormat(mxBuilder->weld_combo_box("colorformat")) 1384 , mxLbIconSetType(mxBuilder->weld_combo_box("iconsettype")) 1385 , mxIconParent(mxBuilder->weld_container("iconparent")) 1386 { 1387 Init(); 1388 mxLbColorFormat->connect_changed(LINK(pParent, ScCondFormatList, ColFormatTypeHdl)); 1389 1390 if(pFormat) 1391 { 1392 const ScIconSetFormatData* pIconSetFormatData = pFormat->GetIconSetData(); 1393 ScIconSetType eType = pIconSetFormatData->eIconSetType; 1394 sal_Int32 nType = static_cast<sal_Int32>(eType); 1395 mxLbIconSetType->set_active(nType); 1396 1397 for (size_t i = 0, n = pIconSetFormatData->m_Entries.size(); 1398 i < n; ++i) 1399 { 1400 maEntries.emplace_back(new ScIconSetFrmtDataEntry( 1401 mxIconParent.get(), eType, pDoc, i, pIconSetFormatData->m_Entries[i].get())); 1402 maEntries[i]->set_grid_top_attach(i); 1403 } 1404 maEntries[0]->SetFirstEntry(); 1405 } 1406 else 1407 IconSetTypeHdl(*mxLbIconSetType); 1408 } 1409 1410 ScIconSetFrmtEntry::~ScIconSetFrmtEntry() 1411 { 1412 } 1413 1414 void ScIconSetFrmtEntry::Init() 1415 { 1416 mxLbColorFormat->set_active(3); 1417 mxLbType->set_active(0); 1418 mxLbIconSetType->set_active(0); 1419 1420 mxLbIconSetType->connect_changed(LINK(this, ScIconSetFrmtEntry, IconSetTypeHdl)); 1421 } 1422 1423 IMPL_LINK_NOARG( ScIconSetFrmtEntry, IconSetTypeHdl, weld::ComboBox&, void ) 1424 { 1425 const ScIconSetMap* pMap = ScIconSetFormat::g_IconSetMap; 1426 1427 sal_Int32 nPos = mxLbIconSetType->get_active(); 1428 sal_uInt32 nElements = pMap[nPos].nElements; 1429 1430 maEntries.clear(); 1431 1432 for(size_t i = 0; i < nElements; ++i) 1433 { 1434 maEntries.emplace_back(new ScIconSetFrmtDataEntry(mxIconParent.get(), static_cast<ScIconSetType>(nPos), mpDoc, i)); 1435 maEntries[i]->set_grid_top_attach(i); 1436 maEntries[i]->Show(); 1437 } 1438 maEntries[0]->SetFirstEntry(); 1439 } 1440 1441 OUString ScIconSetFrmtEntry::GetExpressionString() 1442 { 1443 return ScCondFormatHelper::GetExpression(ICONSET, 0); 1444 } 1445 1446 void ScIconSetFrmtEntry::SetActive() 1447 { 1448 mxLbColorFormat->show(); 1449 mxLbIconSetType->show(); 1450 for(auto& rxEntry : maEntries) 1451 { 1452 rxEntry->Show(); 1453 } 1454 1455 Select(); 1456 } 1457 1458 void ScIconSetFrmtEntry::SetInactive() 1459 { 1460 mxLbColorFormat->hide(); 1461 mxLbIconSetType->hide(); 1462 for(auto& rxEntry : maEntries) 1463 { 1464 rxEntry->Hide(); 1465 } 1466 1467 Deselect(); 1468 } 1469 1470 ScFormatEntry* ScIconSetFrmtEntry::GetEntry() const 1471 { 1472 ScIconSetFormat* pFormat = new ScIconSetFormat(mpDoc); 1473 1474 ScIconSetFormatData* pData = new ScIconSetFormatData; 1475 pData->eIconSetType = static_cast<ScIconSetType>(mxLbIconSetType->get_active()); 1476 for(const auto& rxEntry : maEntries) 1477 { 1478 pData->m_Entries.push_back(std::unique_ptr<ScColorScaleEntry>(rxEntry->CreateEntry(mpDoc, maPos))); 1479 } 1480 pFormat->SetIconSetData(pData); 1481 1482 return pFormat; 1483 } 1484 1485 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 1486
