    /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
    /*
     * This file is part of the LibreOffice project.
     *
     * This Source Code Form is subject to the terms of the Mozilla Public
     * License, v. 2.0. If a copy of the MPL was not distributed with this
     * file, You can obtain one at http://mozilla.org/MPL/2.0/.
     */

    #include <memory>
    #include <condformatdlg.hxx>
    #include <condformatdlgentry.hxx>
    #include <conditio.hxx>

    #include <document.hxx>

    #include <vcl/vclevent.hxx>
    #include <svl/style.hxx>
    #include <sfx2/dispatch.hxx>
    #include <svl/stritem.hxx>
    #include <svl/intitem.hxx>
    #include <svx/colorbox.hxx>
    #include <svx/xtable.hxx>
    #include <svx/drawitem.hxx>
    #include <vcl/settings.hxx>
    #include <formula/token.hxx>
    #include <formula/errorcodes.hxx>
    #include <tokenarray.hxx>
    #include <stlpool.hxx>
    #include <tabvwsh.hxx>
    #include <simpleformulacalc.hxx>

    #include <colorformat.hxx>
    #include <scresid.hxx>
    #include <globstr.hrc>
    #include <strings.hrc>

    #include <set>

    ScCondFrmtEntry::ScCondFrmtEntry(vcl::Window* pParent, ScDocument* pDoc, const ScAddress& rPos)
        : VclContainer(pParent, WB_CLIPCHILDREN | WB_BORDER | WB_CHILDDLGCTRL)
        , mbActive(false)
        , maStrCondition(ScResId(SCSTR_CONDITION))
        , mpDoc(pDoc)
        , maPos(rPos)
    {
        m_pUIBuilder.reset(new VclBuilder(this, getUIRootDir(), "modules/scalc/ui/conditionalentry.ui"));

        get(maGrid, "grid");
        get(maFtCondNr, "number");
        get(maFtCondition, "condition");
        get(maLbType, "type");

        Color aBack(GetSettings().GetStyleSettings().GetWindowColor());

        SetControlBackground(aBack);
        SetBackground(GetControlBackground());

        maFtCondNr->SetControlBackground(aBack);
        maFtCondNr->SetBackground(maFtCondNr->GetControlBackground());

        maFtCondition->SetControlBackground(aBack);
        maFtCondition->SetBackground(maFtCondition->GetControlBackground());

        maLbType->SetSelectHdl( LINK( pParent, ScCondFormatList, TypeListHdl ) );
        maClickHdl = LINK( pParent, ScCondFormatList, EntrySelectHdl );

        Show();
    }

    ScCondFrmtEntry::~ScCondFrmtEntry()
    {
        disposeOnce();
    }

    Size ScCondFrmtEntry::calculateRequisition() const
    {
        return getLayoutRequisition(*maGrid);
    }

    void ScCondFrmtEntry::setAllocation(const Size &rAllocation)
    {
        setLayoutPosSize(*maGrid, Point(0, 0), rAllocation);
    }

    void ScCondFrmtEntry::dispose()
    {
        maFtCondNr.clear();
        maFtCondition.clear();
        maLbType.clear();
        maGrid.clear();
        disposeBuilder();
        VclContainer::dispose();
    }

    bool ScCondFrmtEntry::EventNotify( NotifyEvent& rNEvt )
    {
        if (rNEvt.GetType() == MouseNotifyEvent::MOUSEBUTTONDOWN)
        {
            maClickHdl.Call(*this);
        }
        return VclContainer::EventNotify(rNEvt);
    }

    void ScCondFrmtEntry::SetIndex(sal_Int32 nIndex)
    {
        maFtCondNr->SetText(maStrCondition + OUString::number(nIndex));
    }

    void ScCondFrmtEntry::SetHeight()
    {
        const long nMaxHeight = get_preferred_size().Height();
        if (nMaxHeight > 0)
        {
            Size aSize = GetSizePixel();
            const long nPad = LogicToPixel(Size(0, 2), MapMode(MapUnit::MapAppFont)).getHeight();
            aSize.setHeight( nMaxHeight + nPad );
            SetSizePixel(aSize);
        }
    }

    void ScCondFrmtEntry::Select()
    {
        maFtCondition->SetText(OUString());
        maFtCondition->Hide();
        maLbType->Show();
        mbActive = true;
        SetHeight();
    }

    void ScCondFrmtEntry::Deselect()
    {
        OUString aCondText = GetExpressionString();
        maFtCondition->SetText(aCondText);
        maFtCondition->Show();
        maLbType->Hide();
        mbActive = false;
        SetHeight();
    }

    //condition

    namespace {

    void FillStyleListBox( const ScDocument* pDoc, ListBox& rLbStyle )
    {
        rLbStyle.SetSeparatorPos(0);
        std::set<OUString> aStyleNames;
        SfxStyleSheetIterator aStyleIter( pDoc->GetStyleSheetPool(), SfxStyleFamily::Para );
        for ( SfxStyleSheetBase* pStyle = aStyleIter.First(); pStyle; pStyle = aStyleIter.Next() )
        {
            OUString aName = pStyle->GetName();
            aStyleNames.insert(aName);
        }
        for(std::set<OUString>::const_iterator itr = aStyleNames.begin(), itrEnd = aStyleNames.end();
                            itr != itrEnd; ++itr)
        {
            rLbStyle.InsertEntry( *itr );
        }
    }

    }

    const ScConditionMode ScConditionFrmtEntry::mpEntryToCond[ScConditionFrmtEntry::NUM_COND_ENTRIES] = {
        ScConditionMode::Equal,
        ScConditionMode::Less,
        ScConditionMode::Greater,
        ScConditionMode::EqLess,
        ScConditionMode::EqGreater,
        ScConditionMode::NotEqual,
        ScConditionMode::Between,
        ScConditionMode::NotBetween,
        ScConditionMode::Duplicate,
        ScConditionMode::NotDuplicate,
        ScConditionMode::Top10,
        ScConditionMode::Bottom10,
        ScConditionMode::TopPercent,
        ScConditionMode::BottomPercent,
        ScConditionMode::AboveAverage,
        ScConditionMode::BelowAverage,
        ScConditionMode::AboveEqualAverage,
        ScConditionMode::BelowEqualAverage,
        ScConditionMode::Error,
        ScConditionMode::NoError,
        ScConditionMode::BeginsWith,
        ScConditionMode::EndsWith,
        ScConditionMode::ContainsText,
        ScConditionMode::NotContainsText
    };

    ScConditionFrmtEntry::ScConditionFrmtEntry(vcl::Window* pParent, ScDocument* pDoc, ScCondFormatDlg* pDialogParent,
            const ScAddress& rPos, const ScCondFormatEntry* pFormatEntry)
        : ScCondFrmtEntry(pParent, pDoc, rPos)
        , mbIsInStyleCreate(false)
    {
        get(maLbCondType, "typeis");
        get(maEdVal1, "val1");
        get(maEdVal2, "val2");
        get(maFtVal, "valueft");
        get(maFtStyle, "styleft");
        get(maLbStyle, "style");
        get(maWdPreview, "preview");
        maWdPreview->set_height_request(maLbStyle->get_preferred_size().Height());

        maLbType->SelectEntryPos(1);

        Init(pDialogParent);

        StartListening(*pDoc->GetStyleSheetPool(), DuplicateHandling::Prevent);

        if(pFormatEntry)
        {
            OUString aStyleName = pFormatEntry->GetStyle();
            maLbStyle->SelectEntry(aStyleName);
            StyleSelectHdl(*maLbStyle.get());
            ScConditionMode eMode = pFormatEntry->GetOperation();

            maLbCondType->SelectEntryPos(ConditionModeToEntryPos(eMode));

            switch(GetNumberEditFields(eMode))
            {
                case 0:
                    maEdVal1->Hide();
                    maEdVal2->Hide();
                    break;
                case 1:
                    maEdVal1->Show();
                    maEdVal1->SetText(pFormatEntry->GetExpression(maPos, 0));
                    maEdVal2->Hide();
                    OnEdChanged(*maEdVal1);
                    break;
                case 2:
                    maEdVal1->Show();
                    maEdVal1->SetText(pFormatEntry->GetExpression(maPos, 0));
                    OnEdChanged(*maEdVal1);
                    maEdVal2->Show();
                    maEdVal2->SetText(pFormatEntry->GetExpression(maPos, 1));
                    OnEdChanged(*maEdVal2);
                    break;
            }
        }
        else
        {
            maLbCondType->SelectEntryPos(0);
            maEdVal2->Hide();
            maLbStyle->SelectEntryPos(1);
        }
    }

    ScConditionFrmtEntry::~ScConditionFrmtEntry()
    {
        disposeOnce();
    }

    void ScConditionFrmtEntry::dispose()
    {
        maLbCondType.clear();
        maEdVal1.clear();
        maEdVal2.clear();
        maFtVal.clear();
        maFtStyle.clear();
        maLbStyle.clear();
        maWdPreview.clear();
        ScCondFrmtEntry::dispose();
    }

    void ScConditionFrmtEntry::Init(ScCondFormatDlg* pDialogParent)
    {
        maEdVal1->SetGetFocusHdl( LINK( pDialogParent, ScCondFormatDlg, RangeGetFocusHdl ) );
        maEdVal2->SetGetFocusHdl( LINK( pDialogParent, ScCondFormatDlg, RangeGetFocusHdl ) );

        maEdVal1->SetForceControlBackground(true);
        maEdVal2->SetForceControlBackground(true);

        maEdVal1->SetModifyHdl( LINK( this, ScConditionFrmtEntry, OnEdChanged ) );
        maEdVal2->SetModifyHdl( LINK( this, ScConditionFrmtEntry, OnEdChanged ) );

        FillStyleListBox( mpDoc, *maLbStyle.get() );
        maLbStyle->SetSelectHdl( LINK( this, ScConditionFrmtEntry, StyleSelectHdl ) );

        maLbCondType->SetSelectHdl( LINK( this, ScConditionFrmtEntry, ConditionTypeSelectHdl ) );
    }

    ScFormatEntry* ScConditionFrmtEntry::createConditionEntry() const
    {
        ScConditionMode eMode = EntryPosToConditionMode(maLbCondType->GetSelectedEntryPos());
        OUString aExpr1 = maEdVal1->GetText();
        OUString aExpr2;
        if (GetNumberEditFields(eMode) == 2)
        {
            aExpr2 = maEdVal2->GetText();
            if (aExpr2.isEmpty())
            {
                return nullptr;
            }
        }

        ScFormatEntry* pEntry = new ScCondFormatEntry(eMode, aExpr1, aExpr2, mpDoc, maPos, maLbStyle->GetSelectedEntry());
        return pEntry;
    }

    IMPL_LINK(ScConditionFrmtEntry, OnEdChanged, Edit&, rEdit, void)
    {
        OUString aFormula = rEdit.GetText();

        if( aFormula.isEmpty() )
        {
            maFtVal->SetText(ScResId(STR_ENTER_VALUE));
            return;
        }

        ScCompiler aComp( mpDoc, maPos, mpDoc->GetGrammar() );
        std::unique_ptr<ScTokenArray> ta(aComp.CompileString(aFormula));

        // Error, warn the user
        if( ta->GetCodeError() != FormulaError::NONE || ( ta->GetLen() == 0 ) )
        {
            rEdit.SetControlBackground(COL_LIGHTRED);
            maFtVal->SetText(ScResId(STR_VALID_DEFERROR));
            return;
        }

        // Recognized col/row name or string token, warn the user
        formula::FormulaToken* token = ta->FirstToken();
        formula::StackVar t = token->GetType();
        OpCode op = token->GetOpCode();
        if( ( op == ocColRowName ) ||
            ( ( op == ocBad ) && ( t == formula::svString ) )
          )
        {
            rEdit.SetControlBackground(COL_YELLOW);
            maFtVal->SetText(ScResId(STR_UNQUOTED_STRING));
            return;
        }

        rEdit.SetControlBackground(GetSettings().GetStyleSettings().GetWindowColor());
        maFtVal->SetText("");
    }

    void ScConditionFrmtEntry::Select()
    {
        maFtVal->Show();
        ScCondFrmtEntry::Select();
    }

    void ScConditionFrmtEntry::Deselect()
    {
        maFtVal->Hide();
        ScCondFrmtEntry::Deselect();
    }

    sal_Int32 ScConditionFrmtEntry::ConditionModeToEntryPos( ScConditionMode eMode )
    {
        for ( sal_Int32 i = 0; i < NUM_COND_ENTRIES; ++i )
        {
            if (mpEntryToCond[i] == eMode)
            {
                return i;
            }
        }
        assert(false); // should never get here
        return 0;
    }

    ScConditionMode ScConditionFrmtEntry::EntryPosToConditionMode( sal_Int32 aEntryPos )
    {
        assert( 0 <= aEntryPos && aEntryPos < NUM_COND_ENTRIES );
        return mpEntryToCond[aEntryPos];
    }

    sal_Int32 ScConditionFrmtEntry::GetNumberEditFields( ScConditionMode eMode )
    {
        switch(eMode)
        {
            case ScConditionMode::Equal:
            case ScConditionMode::Less:
            case ScConditionMode::Greater:
            case ScConditionMode::EqLess:
            case ScConditionMode::EqGreater:
            case ScConditionMode::NotEqual:
            case ScConditionMode::Top10:
            case ScConditionMode::Bottom10:
            case ScConditionMode::TopPercent:
            case ScConditionMode::BottomPercent:
            case ScConditionMode::BeginsWith:
            case ScConditionMode::EndsWith:
            case ScConditionMode::ContainsText:
            case ScConditionMode::NotContainsText:
            case ScConditionMode::Error:
            case ScConditionMode::NoError:
                return 1;
            case ScConditionMode::AboveAverage:
            case ScConditionMode::BelowAverage:
            case ScConditionMode::AboveEqualAverage:
            case ScConditionMode::BelowEqualAverage:
            case ScConditionMode::Duplicate:
            case ScConditionMode::NotDuplicate:
                return 0;
            case ScConditionMode::Between:
            case ScConditionMode::NotBetween:
                return 2;
            default:
                assert(false); // should never get here
                return 0;
        }
    }

    OUString ScConditionFrmtEntry::GetExpressionString()
    {
        return ScCondFormatHelper::GetExpression(CONDITION, maLbCondType->GetSelectedEntryPos(), maEdVal1->GetText(), maEdVal2->GetText());
    }

    ScFormatEntry* ScConditionFrmtEntry::GetEntry() const
    {
        return createConditionEntry();
    }

    void ScConditionFrmtEntry::SetActive()
    {
        ScConditionMode eMode = EntryPosToConditionMode(maLbCondType->GetSelectedEntryPos());
        maLbCondType->Show();
        switch(GetNumberEditFields(eMode))
        {
            case 1:
                maEdVal1->Show();
                break;
            case 2:
                maEdVal1->Show();
                maEdVal2->Show();
                break;
        }
        maFtStyle->Show();
        maLbStyle->Show();
        maWdPreview->Show();

        Select();
    }

    void ScConditionFrmtEntry::SetInactive()
    {
        maLbCondType->Hide();
        maEdVal1->Hide();
        maEdVal2->Hide();
        maFtStyle->Hide();
        maLbStyle->Hide();
        maWdPreview->Hide();

        Deselect();
    }

    namespace {

    void UpdateStyleList(ListBox& rLbStyle, const ScDocument* pDoc)
    {
        OUString aSelectedStyle = rLbStyle.GetSelectedEntry();
        for(sal_Int32 i = rLbStyle.GetEntryCount(); i >= 1; --i)
        {
            rLbStyle.RemoveEntry(i);
        }
        FillStyleListBox(pDoc, rLbStyle);
        rLbStyle.SelectEntry(aSelectedStyle);
    }

    }

    void ScConditionFrmtEntry::Notify(SfxBroadcaster&, const SfxHint& rHint)
    {
        if(rHint.GetId() == SfxHintId::StyleSheetModified)
        {
            if(!mbIsInStyleCreate)
                UpdateStyleList(*maLbStyle.get(), mpDoc);
        }
    }

    namespace {

    void StyleSelect( ListBox& rLbStyle, const ScDocument* pDoc, SvxFontPrevWindow& rWdPreview )
    {
        if(rLbStyle.GetSelectedEntryPos() == 0)
        {
            // call new style dialog
            SfxUInt16Item aFamilyItem( SID_STYLE_FAMILY, sal_uInt16(SfxStyleFamily::Para) );
            SfxStringItem aRefItem( SID_STYLE_REFERENCE, ScResId(STR_STYLENAME_STANDARD) );

            // unlock the dispatcher so SID_STYLE_NEW can be executed
            // (SetDispatcherLock would affect all Calc documents)
            ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
            SfxDispatcher* pDisp = pViewShell->GetDispatcher();
            bool bLocked = pDisp->IsLocked();
            if (bLocked)
                pDisp->Lock(false);

            // Execute the "new style" slot, complete with undo and all necessary updates.
            // The return value (SfxUInt16Item) is ignored, look for new styles instead.
            pDisp->ExecuteList(SID_STYLE_NEW,
                SfxCallMode::SYNCHRON | SfxCallMode::RECORD | SfxCallMode::MODAL,
                { &aFamilyItem, &aRefItem });

            if (bLocked)
                pDisp->Lock(true);

            // Find the new style and add it into the style list boxes
            SfxStyleSheetIterator aStyleIter( pDoc->GetStyleSheetPool(), SfxStyleFamily::Para );
            bool bFound = false;
            for ( SfxStyleSheetBase* pStyle = aStyleIter.First(); pStyle && !bFound; pStyle = aStyleIter.Next() )
            {
                OUString aName = pStyle->GetName();
                if ( rLbStyle.GetEntryPos(aName) == LISTBOX_ENTRY_NOTFOUND )    // all lists contain the same entries
                {
                    for( sal_Int32 i = 1, n = rLbStyle.GetEntryCount(); i <= n && !bFound; ++i)
                    {
                        OUString aStyleName = ScGlobal::pCharClass->uppercase(rLbStyle.GetEntry(i));
                        if( i == n )
                        {
                            rLbStyle.InsertEntry(aName);
                            rLbStyle.SelectEntry(aName);
                            bFound = true;
                        }
                        else if( aStyleName > ScGlobal::pCharClass->uppercase(aName) )
                        {
                            rLbStyle.InsertEntry(aName, i);
                            rLbStyle.SelectEntry(aName);
                            bFound = true;
                        }
                    }
                }
            }
        }

        OUString aStyleName = rLbStyle.GetSelectedEntry();
        SfxStyleSheetBase* pStyleSheet = pDoc->GetStyleSheetPool()->Find( aStyleName, SfxStyleFamily::Para );
        if(pStyleSheet)
        {
            const SfxItemSet& rSet = pStyleSheet->GetItemSet();
            rWdPreview.Init( rSet );
        }
    }

    }

    IMPL_LINK_NOARG(ScConditionFrmtEntry, StyleSelectHdl, ListBox&, void)
    {
        mbIsInStyleCreate = true;
        StyleSelect( *maLbStyle.get(), mpDoc, *maWdPreview.get() );
        mbIsInStyleCreate = false;
    }

    // formula

    ScFormulaFrmtEntry::ScFormulaFrmtEntry( vcl::Window* pParent, ScDocument* pDoc, ScCondFormatDlg* pDialogParent, const ScAddress& rPos, const ScCondFormatEntry* pFormat )
        : ScCondFrmtEntry(pParent, pDoc, rPos)
    {
        get(maFtStyle, "styleft");
        get(maLbStyle, "style");
        get(maWdPreview, "preview");
        maWdPreview->set_height_request(maLbStyle->get_preferred_size().Height());
        get(maEdFormula, "formula");

        Init(pDialogParent);

        maLbType->SelectEntryPos(2);

        if(pFormat)
        {
            maEdFormula->SetText(pFormat->GetExpression(rPos, 0, 0, pDoc->GetGrammar()));
            maLbStyle->SelectEntry(pFormat->GetStyle());
        }
        else
        {
            maLbStyle->SelectEntryPos(1);
        }

        StyleSelectHdl(*maLbStyle.get());
    }

    ScFormulaFrmtEntry::~ScFormulaFrmtEntry()
    {
        disposeOnce();
    }

    void ScFormulaFrmtEntry::dispose()
    {
        maFtStyle.clear();
        maLbStyle.clear();
        maWdPreview.clear();
        maEdFormula.clear();
        ScCondFrmtEntry::dispose();
    }

    void ScFormulaFrmtEntry::Init(ScCondFormatDlg* pDialogParent)
    {
        maEdFormula->SetGetFocusHdl( LINK( pDialogParent, ScCondFormatDlg, RangeGetFocusHdl ) );

        FillStyleListBox( mpDoc, *maLbStyle.get() );
        maLbStyle->SetSelectHdl( LINK( this, ScFormulaFrmtEntry, StyleSelectHdl ) );
    }

    IMPL_LINK_NOARG(ScFormulaFrmtEntry, StyleSelectHdl, ListBox&, void)
    {
        StyleSelect( *maLbStyle.get(), mpDoc, *maWdPreview.get() );
    }

    ScFormatEntry* ScFormulaFrmtEntry::createFormulaEntry() const
    {
        OUString aFormula = maEdFormula->GetText();
        if(aFormula.isEmpty())
            return nullptr;

        ScFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct, aFormula, OUString(), mpDoc, maPos, maLbStyle->GetSelectedEntry());
        return pEntry;
    }

    ScFormatEntry* ScFormulaFrmtEntry::GetEntry() const
    {
        return createFormulaEntry();
    }

    OUString ScFormulaFrmtEntry::GetExpressionString()
    {
        return ScCondFormatHelper::GetExpression(FORMULA, 0, maEdFormula->GetText());
    }

    void ScFormulaFrmtEntry::SetActive()
    {
        maWdPreview->Show();
        maFtStyle->Show();
        maLbStyle->Show();
        maEdFormula->Show();

        Select();
    }

    void ScFormulaFrmtEntry::SetInactive()
    {
        maWdPreview->Hide();
        maFtStyle->Hide();
        maLbStyle->Hide();
        maEdFormula->Hide();

        Deselect();
    }

    //color scale

    namespace {

    OUString convertNumberToString(double nVal, const ScDocument* pDoc)
    {
        SvNumberFormatter* pNumberFormatter = pDoc->GetFormatTable();
        OUString aText;
        pNumberFormatter->GetInputLineString(nVal, 0, aText);
        return aText;
    }

    void SetColorScaleEntryTypes( const ScColorScaleEntry& rEntry, ListBox& rLbType, Edit& rEdit, SvxColorListBox& rLbCol, const ScDocument* pDoc )
    {
        // entry Automatic is not available for color scales
        sal_Int32 nIndex = static_cast<sal_Int32>(rEntry.GetType());
        assert(nIndex > 0);
        rLbType.SelectEntryPos(nIndex - 1);
        switch(rEntry.GetType())
        {
            case COLORSCALE_MIN:
            case COLORSCALE_MAX:
                break;
            case COLORSCALE_PERCENTILE:
            case COLORSCALE_VALUE:
            case COLORSCALE_PERCENT:
                {
                    double nVal = rEntry.GetValue();
                    rEdit.SetText(convertNumberToString(nVal, pDoc));
                }
                break;
            case COLORSCALE_FORMULA:
                rEdit.SetText(rEntry.GetFormula(formula::FormulaGrammar::GRAM_DEFAULT));
                break;
            case COLORSCALE_AUTO:
                abort();
                break;
        }
        rLbCol.SelectEntry(rEntry.GetColor());
    }

    void SetColorScaleEntry( ScColorScaleEntry* pEntry, const ListBox& rType, const Edit& rValue, ScDocument* pDoc, const ScAddress& rPos, bool bDataBar )
    {

        // color scale does not have the automatic entry
        sal_Int32 nPos = rType.GetSelectedEntryPos();
        if(!bDataBar)
            ++nPos;

        pEntry->SetType(static_cast<ScColorScaleEntryType>(nPos));
        switch(nPos)
        {
            case COLORSCALE_AUTO:
            case COLORSCALE_MIN:
            case COLORSCALE_MAX:
                break;
            case COLORSCALE_PERCENTILE:
            case COLORSCALE_VALUE:
            case COLORSCALE_PERCENT:
                {
                    sal_uInt32 nIndex = 0;
                    double nVal = 0;
                    SvNumberFormatter* pNumberFormatter = pDoc->GetFormatTable();
                    (void)pNumberFormatter->IsNumberFormat(rValue.GetText(), nIndex, nVal);
                    pEntry->SetValue(nVal);
                }
                break;
            case COLORSCALE_FORMULA:
                pEntry->SetFormula(rValue.GetText(), pDoc, rPos);
                break;
            default:
                break;
        }
    }

    ScColorScaleEntry* createColorScaleEntry( const ListBox& rType, const SvxColorListBox& rColor, const Edit& rValue, ScDocument* pDoc, const ScAddress& rPos )
    {
        ScColorScaleEntry* pEntry = new ScColorScaleEntry();

        SetColorScaleEntry( pEntry, rType, rValue, pDoc, rPos, false );
        Color aColor = rColor.GetSelectEntryColor();
        pEntry->SetColor(aColor);
        return pEntry;
    }

    }

    ScColorScale2FrmtEntry::ScColorScale2FrmtEntry( vcl::Window* pParent, ScDocument* pDoc, const ScAddress& rPos, const ScColorScaleFormat* pFormat )
        : ScCondFrmtEntry(pParent, pDoc, rPos)
    {
        get(maLbColorFormat, "colorformat");
        get(maLbEntryTypeMin, "colscalemin");
        get(maLbEntryTypeMax, "colscalemax");
        get(maEdMin, "edcolscalemin");
        get(maEdMax, "edcolscalemax");
        get(maLbColMin, "lbcolmin");
        get(maLbColMax, "lbcolmax");

        // remove the automatic entry from color scales
        maLbEntryTypeMin->RemoveEntry(0);
        maLbEntryTypeMax->RemoveEntry(0);

        maLbType->SelectEntryPos(0);
        maLbColorFormat->SelectEntryPos(0);
        Init();
        if(pFormat)
        {
            ScColorScaleEntries::const_iterator itr = pFormat->begin();
            SetColorScaleEntryTypes(*itr[0], *maLbEntryTypeMin.get(), *maEdMin.get(), *maLbColMin.get(), pDoc);
            ++itr;
            SetColorScaleEntryTypes(*itr[0], *maLbEntryTypeMax.get(), *maEdMax.get(), *maLbColMax.get(), pDoc);
        }
        else
        {
            maLbEntryTypeMin->SelectEntryPos(0);
            maLbEntryTypeMax->SelectEntryPos(1);
        }

        maLbColorFormat->SetSelectHdl( LINK( pParent, ScCondFormatList, ColFormatTypeHdl ) );

        EntryTypeHdl(*maLbEntryTypeMin.get());
        EntryTypeHdl(*maLbEntryTypeMax.get());
    }

    ScColorScale2FrmtEntry::~ScColorScale2FrmtEntry()
    {
        disposeOnce();
    }

    void ScColorScale2FrmtEntry::dispose()
    {
        maLbColorFormat.clear();
        maLbEntryTypeMin.clear();
        maLbEntryTypeMax.clear();
        maEdMin.clear();
        maEdMax.clear();
        maLbColMin.clear();
        maLbColMax.clear();
        ScCondFrmtEntry::dispose();
    }

    void ScColorScale2FrmtEntry::Init()
    {
        maLbEntryTypeMin->SetSelectHdl( LINK( this, ScColorScale2FrmtEntry, EntryTypeHdl ) );
        maLbEntryTypeMax->SetSelectHdl( LINK( this, ScColorScale2FrmtEntry, EntryTypeHdl ) );
        maLbColMin->SelectEntry(Color(0xFFF685)); // Light Yellow 2
        maLbColMax->SelectEntry(Color(0x65C295)); // Light Green 2
    }

    ScFormatEntry* ScColorScale2FrmtEntry::createColorscaleEntry() const
    {
        ScColorScaleFormat* pColorScale = new ScColorScaleFormat(mpDoc);
        pColorScale->AddEntry(createColorScaleEntry(*maLbEntryTypeMin.get(), *maLbColMin.get(), *maEdMin.get(), mpDoc, maPos));
        pColorScale->AddEntry(createColorScaleEntry(*maLbEntryTypeMax.get(), *maLbColMax.get(), *maEdMax.get(), mpDoc, maPos));
        return pColorScale;
    }

    OUString ScColorScale2FrmtEntry::GetExpressionString()
    {
        return ScCondFormatHelper::GetExpression( COLORSCALE, 0 );
    }

    ScFormatEntry* ScColorScale2FrmtEntry::GetEntry() const
    {
        return createColorscaleEntry();
    }

    void ScColorScale2FrmtEntry::SetActive()
    {
        maLbColorFormat->Show();

        maLbEntryTypeMin->Show();
        maLbEntryTypeMax->Show();

        maEdMin->Show();
        maEdMax->Show();

        maLbColMin->Show();
        maLbColMax->Show();

        Select();
    }

    void ScColorScale2FrmtEntry::SetInactive()
    {
        maLbColorFormat->Hide();

        maLbEntryTypeMin->Hide();
        maLbEntryTypeMax->Hide();

        maEdMin->Hide();
        maEdMax->Hide();

        maLbColMin->Hide();
        maLbColMax->Hide();

        Deselect();
    }

    IMPL_LINK( ScColorScale2FrmtEntry, EntryTypeHdl, ListBox&, rBox, void )
    {
        Edit* pEd = nullptr;
        if (&rBox == maLbEntryTypeMin.get())
            pEd = maEdMin;
        else if (&rBox == maLbEntryTypeMax.get())
            pEd = maEdMax.get();

        if (!pEd)
            return;

        bool bEnableEdit = true;
        sal_Int32 nPos = rBox.GetSelectedEntryPos();
        if(nPos < 2)
        {
            bEnableEdit = false;
        }

        if (bEnableEdit)
            pEd->Enable();
        else
            pEd->Disable();
    }

    ScColorScale3FrmtEntry::ScColorScale3FrmtEntry( vcl::Window* pParent, ScDocument* pDoc, const ScAddress& rPos, const ScColorScaleFormat* pFormat )
        : ScCondFrmtEntry(pParent, pDoc, rPos)
    {
        get(maLbColorFormat, "colorformat");
        get(maLbEntryTypeMin, "colscalemin");
        get(maLbEntryTypeMiddle, "colscalemiddle");
        get(maLbEntryTypeMax, "colscalemax");
        get(maEdMin, "edcolscalemin");
        get(maEdMiddle, "edcolscalemiddle");
        get(maEdMax, "edcolscalemax");
        get(maLbColMin, "lbcolmin");
        get(maLbColMiddle, "lbcolmiddle");
        get(maLbColMax, "lbcolmax");

        // remove the automatic entry from color scales
        maLbEntryTypeMin->RemoveEntry(0);
        maLbEntryTypeMiddle->RemoveEntry(0);
        maLbEntryTypeMax->RemoveEntry(0);
        maLbColorFormat->SelectEntryPos(1);

        Init();
        maLbType->SelectEntryPos(0);
        if(pFormat)
        {
            ScColorScaleEntries::const_iterator itr = pFormat->begin();
            SetColorScaleEntryTypes(*itr[0], *maLbEntryTypeMin.get(), *maEdMin.get(), *maLbColMin.get(), pDoc);
            assert(pFormat->size() == 3);
            ++itr;
            SetColorScaleEntryTypes(*itr[0], *maLbEntryTypeMiddle.get(), *maEdMiddle.get(), *maLbColMiddle.get(), pDoc);
            ++itr;
            SetColorScaleEntryTypes(*itr[0], *maLbEntryTypeMax.get(), *maEdMax.get(), *maLbColMax.get(), pDoc);
        }
        else
        {
            maLbColorFormat->SelectEntryPos(1);
            maLbEntryTypeMin->SelectEntryPos(0);
            maLbEntryTypeMiddle->SelectEntryPos(2);
            maLbEntryTypeMax->SelectEntryPos(1);
            maEdMiddle->SetText(OUString::number(50));
        }

        maLbColorFormat->SetSelectHdl( LINK( pParent, ScCondFormatList, ColFormatTypeHdl ) );
        EntryTypeHdl(*maLbEntryTypeMin.get());
        EntryTypeHdl(*maLbEntryTypeMiddle.get());
        EntryTypeHdl(*maLbEntryTypeMax.get());
    }

    ScColorScale3FrmtEntry::~ScColorScale3FrmtEntry()
    {
        disposeOnce();
    }

    void ScColorScale3FrmtEntry::dispose()
    {
        maLbColorFormat.clear();
        maLbEntryTypeMin.clear();
        maLbEntryTypeMiddle.clear();
        maLbEntryTypeMax.clear();
        maEdMin.clear();
        maEdMiddle.clear();
        maEdMax.clear();
        maLbColMin.clear();
        maLbColMiddle.clear();
        maLbColMax.clear();
        ScCondFrmtEntry::dispose();
    }

    void ScColorScale3FrmtEntry::Init()
    {
        maLbEntryTypeMin->SetSelectHdl( LINK( this, ScColorScale3FrmtEntry, EntryTypeHdl ) );
        maLbEntryTypeMax->SetSelectHdl( LINK( this, ScColorScale3FrmtEntry, EntryTypeHdl ) );
        maLbEntryTypeMiddle->SetSelectHdl( LINK( this, ScColorScale3FrmtEntry, EntryTypeHdl ) );
        maLbColMin->SelectEntry(COL_LIGHTRED);
        maLbColMiddle->SelectEntry(COL_YELLOW);
        maLbColMax->SelectEntry(Color(0x00CC00));
    }

    ScFormatEntry* ScColorScale3FrmtEntry::createColorscaleEntry() const
    {
        ScColorScaleFormat* pColorScale = new ScColorScaleFormat(mpDoc);
        pColorScale->AddEntry(createColorScaleEntry(*maLbEntryTypeMin.get(), *maLbColMin.get(), *maEdMin.get(), mpDoc, maPos));
        if(maLbColorFormat->GetSelectedEntryPos() == 1)
            pColorScale->AddEntry(createColorScaleEntry(*maLbEntryTypeMiddle.get(), *maLbColMiddle.get(), *maEdMiddle.get(), mpDoc, maPos));
        pColorScale->AddEntry(createColorScaleEntry(*maLbEntryTypeMax.get(), *maLbColMax.get(), *maEdMax.get(), mpDoc, maPos));
        return pColorScale;
    }

    OUString ScColorScale3FrmtEntry::GetExpressionString()
    {
        return ScCondFormatHelper::GetExpression( COLORSCALE, 0 );
    }

    ScFormatEntry* ScColorScale3FrmtEntry::GetEntry() const
    {
        return createColorscaleEntry();
    }

    void ScColorScale3FrmtEntry::SetActive()
    {
        maLbColorFormat->Show();
        maLbEntryTypeMin->Show();
        maLbEntryTypeMiddle->Show();
        maLbEntryTypeMax->Show();

        maEdMin->Show();
        maEdMiddle->Show();
        maEdMax->Show();

        maLbColMin->Show();
        maLbColMiddle->Show();
        maLbColMax->Show();

        Select();
    }

    void ScColorScale3FrmtEntry::SetInactive()
    {
        maLbColorFormat->Hide();

        maLbEntryTypeMin->Hide();
        maLbEntryTypeMiddle->Hide();
        maLbEntryTypeMax->Hide();

        maEdMin->Hide();
        maEdMiddle->Hide();
        maEdMax->Hide();

        maLbColMin->Hide();
        maLbColMiddle->Hide();
        maLbColMax->Hide();

        Deselect();
    }

    IMPL_LINK( ScColorScale3FrmtEntry, EntryTypeHdl, ListBox&, rBox, void )
    {
        Edit* pEd = nullptr;
        if(&rBox == maLbEntryTypeMin.get())
            pEd = maEdMin.get();
        else if(&rBox == maLbEntryTypeMiddle.get())
            pEd = maEdMiddle.get();
        else if(&rBox == maLbEntryTypeMax.get())
            pEd = maEdMax.get();

        if (!pEd)
            return;

        bool bEnableEdit = true;
        sal_Int32 nPos = rBox.GetSelectedEntryPos();
        if(nPos < 2)
        {
            bEnableEdit = false;
        }

        if(bEnableEdit)
            pEd->Enable();
        else
            pEd->Disable();
    }

    IMPL_LINK_NOARG( ScConditionFrmtEntry, ConditionTypeSelectHdl, ListBox&, void )
    {
        sal_Int32 nSelectPos = maLbCondType->GetSelectedEntryPos();
        ScConditionMode eMode = EntryPosToConditionMode(nSelectPos);
        switch(GetNumberEditFields(eMode))
        {
            case 0:
                maEdVal1->Hide();
                maEdVal2->Hide();
                maFtVal->Hide();
                break;
            case 1:
                maEdVal1->Show();
                maEdVal2->Hide();
                maFtVal->Show();
                break;
            case 2:
                maEdVal1->Show();
                maEdVal2->Show();
                maFtVal->Show();
                break;
        }
    }

    //databar

    namespace {

    void SetDataBarEntryTypes( const ScColorScaleEntry& rEntry, ListBox& rLbType, Edit& rEdit, const ScDocument* pDoc )
    {
        rLbType.SelectEntryPos(rEntry.GetType());
        switch(rEntry.GetType())
        {
            case COLORSCALE_AUTO:
            case COLORSCALE_MIN:
            case COLORSCALE_MAX:
                break;
            case COLORSCALE_VALUE:
            case COLORSCALE_PERCENT:
            case COLORSCALE_PERCENTILE:
                {
                    double nVal = rEntry.GetValue();
                    SvNumberFormatter* pNumberFormatter = pDoc->GetFormatTable();
                    OUString aText;
                    pNumberFormatter->GetInputLineString(nVal, 0, aText);
                    rEdit.SetText(aText);
                }
                break;
            case COLORSCALE_FORMULA:
                rEdit.SetText(rEntry.GetFormula(formula::FormulaGrammar::GRAM_DEFAULT));
                break;
        }
    }

    }

    ScDataBarFrmtEntry::ScDataBarFrmtEntry( vcl::Window* pParent, ScDocument* pDoc, const ScAddress& rPos, const ScDataBarFormat* pFormat )
        : ScCondFrmtEntry(pParent, pDoc, rPos)
    {
        get(maLbColorFormat, "colorformat");
        get(maLbDataBarMinType, "colscalemin");
        get(maLbDataBarMaxType, "colscalemax");
        get(maEdDataBarMin, "edcolscalemin");
        get(maEdDataBarMax, "edcolscalemax");
        get(maBtOptions, "options");

        maLbColorFormat->SelectEntryPos(2);
        maLbType->SelectEntryPos(0);
        if(pFormat)
        {
            mpDataBarData.reset(new ScDataBarFormatData(*pFormat->GetDataBarData()));
            SetDataBarEntryTypes(*mpDataBarData->mpLowerLimit, *maLbDataBarMinType.get(), *maEdDataBarMin.get(), pDoc);
            SetDataBarEntryTypes(*mpDataBarData->mpUpperLimit, *maLbDataBarMaxType.get(), *maEdDataBarMax.get(), pDoc);
            DataBarTypeSelectHdl(*maLbDataBarMinType.get());
        }
        else
        {
            maLbDataBarMinType->SelectEntryPos(0);
            maLbDataBarMaxType->SelectEntryPos(0);
            DataBarTypeSelectHdl(*maLbDataBarMinType.get());
        }
        Init();

        maLbColorFormat->SetSelectHdl( LINK( pParent, ScCondFormatList, ColFormatTypeHdl ) );
    }

    ScDataBarFrmtEntry::~ScDataBarFrmtEntry()
    {
        disposeOnce();
    }

    void ScDataBarFrmtEntry::dispose()
    {
        maLbColorFormat.clear();
        maLbDataBarMinType.clear();
        maLbDataBarMaxType.clear();
        maEdDataBarMin.clear();
        maEdDataBarMax.clear();
        maBtOptions.clear();
        ScCondFrmtEntry::dispose();
    }

    ScFormatEntry* ScDataBarFrmtEntry::GetEntry() const
    {
        return createDatabarEntry();
    }

    void ScDataBarFrmtEntry::Init()
    {
        maLbDataBarMinType->SetSelectHdl( LINK( this, ScDataBarFrmtEntry, DataBarTypeSelectHdl ) );
        maLbDataBarMaxType->SetSelectHdl( LINK( this, ScDataBarFrmtEntry, DataBarTypeSelectHdl ) );

        maBtOptions->SetClickHdl( LINK( this, ScDataBarFrmtEntry, OptionBtnHdl ) );

        if(!mpDataBarData)
        {
            mpDataBarData.reset(new ScDataBarFormatData());
            mpDataBarData->mpUpperLimit.reset(new ScColorScaleEntry());
            mpDataBarData->mpLowerLimit.reset(new ScColorScaleEntry());
            mpDataBarData->mpLowerLimit->SetType(COLORSCALE_AUTO);
            mpDataBarData->mpUpperLimit->SetType(COLORSCALE_AUTO);
            mpDataBarData->maPositiveColor = COL_LIGHTBLUE;
        }
    }

    ScFormatEntry* ScDataBarFrmtEntry::createDatabarEntry() const
    {
        SetColorScaleEntry(mpDataBarData->mpLowerLimit.get(), *maLbDataBarMinType.get(), *maEdDataBarMin.get(), mpDoc, maPos, true);
        SetColorScaleEntry(mpDataBarData->mpUpperLimit.get(), *maLbDataBarMaxType.get(), *maEdDataBarMax.get(), mpDoc, maPos, true);
        ScDataBarFormat* pDataBar = new ScDataBarFormat(mpDoc);
        pDataBar->SetDataBarData(new ScDataBarFormatData(*mpDataBarData.get()));
        return pDataBar;
    }

    OUString ScDataBarFrmtEntry::GetExpressionString()
    {
        return ScCondFormatHelper::GetExpression( DATABAR, 0 );
    }

    void ScDataBarFrmtEntry::SetActive()
    {
        maLbColorFormat->Show();

        maLbDataBarMinType->Show();
        maLbDataBarMaxType->Show();
        maEdDataBarMin->Show();
        maEdDataBarMax->Show();
        maBtOptions->Show();

        Select();
    }

    void ScDataBarFrmtEntry::SetInactive()
    {
        maLbColorFormat->Hide();

        maLbDataBarMinType->Hide();
        maLbDataBarMaxType->Hide();
        maEdDataBarMin->Hide();
        maEdDataBarMax->Hide();
        maBtOptions->Hide();

        Deselect();
    }

    IMPL_LINK_NOARG( ScDataBarFrmtEntry, DataBarTypeSelectHdl, ListBox&, void )
    {
        sal_Int32 nSelectPos = maLbDataBarMinType->GetSelectedEntryPos();
        if(nSelectPos <= COLORSCALE_MAX)
            maEdDataBarMin->Disable();
        else
            maEdDataBarMin->Enable();

        nSelectPos = maLbDataBarMaxType->GetSelectedEntryPos();
        if(nSelectPos <= COLORSCALE_MAX)
            maEdDataBarMax->Disable();
        else
            maEdDataBarMax->Enable();
    }

    IMPL_LINK_NOARG( ScDataBarFrmtEntry, OptionBtnHdl, Button*, void )
    {
        SetColorScaleEntry(mpDataBarData->mpLowerLimit.get(), *maLbDataBarMinType.get(), *maEdDataBarMin.get(), mpDoc, maPos, true);
        SetColorScaleEntry(mpDataBarData->mpUpperLimit.get(), *maLbDataBarMaxType.get(), *maEdDataBarMax.get(), mpDoc, maPos, true);
        ScopedVclPtrInstance<ScDataBarSettingsDlg> pDlg(this, *mpDataBarData, mpDoc, maPos);
        if( pDlg->Execute() == RET_OK)
        {
            mpDataBarData.reset(pDlg->GetData());
            SetDataBarEntryTypes(*mpDataBarData->mpLowerLimit, *maLbDataBarMinType, *maEdDataBarMin.get(), mpDoc);
            SetDataBarEntryTypes(*mpDataBarData->mpUpperLimit, *maLbDataBarMaxType.get(), *maEdDataBarMax.get(), mpDoc);
            DataBarTypeSelectHdl(*maLbDataBarMinType.get());
        }
    }

    ScDateFrmtEntry::ScDateFrmtEntry(vcl::Window* pParent, ScDocument* pDoc, const ScCondDateFormatEntry* pFormat)
        : ScCondFrmtEntry(pParent, pDoc, ScAddress())
        , mbIsInStyleCreate(false)
    {
        get(maLbDateEntry, "datetype");
        get(maFtStyle, "styleft");
        get(maLbStyle, "style");
        get(maWdPreview, "preview");
        maWdPreview->set_height_request(maLbStyle->get_preferred_size().Height());

        Init();

        StartListening(*pDoc->GetStyleSheetPool(), DuplicateHandling::Prevent);

        if(pFormat)
        {
            sal_Int32 nPos = static_cast<sal_Int32>(pFormat->GetDateType());
            maLbDateEntry->SelectEntryPos(nPos);

            OUString aStyleName = pFormat->GetStyleName();
            maLbStyle->SelectEntry(aStyleName);
        }

        StyleSelectHdl(*maLbStyle.get());
    }

    ScDateFrmtEntry::~ScDateFrmtEntry()
    {
        disposeOnce();
    }

    void ScDateFrmtEntry::dispose()
    {
        maLbDateEntry.clear();
        maFtStyle.clear();
        maLbStyle.clear();
        maWdPreview.clear();
        ScCondFrmtEntry::dispose();
    }

    void ScDateFrmtEntry::Init()
    {
        maLbDateEntry->SelectEntryPos(0);
        maLbType->SelectEntryPos(3);

        FillStyleListBox( mpDoc, *maLbStyle.get() );
        maLbStyle->SetSelectHdl( LINK( this, ScDateFrmtEntry, StyleSelectHdl ) );
        maLbStyle->SelectEntryPos(1);
    }

    void ScDateFrmtEntry::SetActive()
    {
        maLbDateEntry->Show();
        maFtStyle->Show();
        maWdPreview->Show();
        maLbStyle->Show();

        Select();
    }

    void ScDateFrmtEntry::SetInactive()
    {
        maLbDateEntry->Hide();
        maFtStyle->Hide();
        maWdPreview->Hide();
        maLbStyle->Hide();

        Deselect();
    }

    void ScDateFrmtEntry::Notify( SfxBroadcaster&, const SfxHint& rHint )
    {
        if(rHint.GetId() == SfxHintId::StyleSheetModified)
        {
            if(!mbIsInStyleCreate)
                UpdateStyleList(*maLbStyle.get(), mpDoc);
        }
    }

    ScFormatEntry* ScDateFrmtEntry::GetEntry() const
    {
        ScCondDateFormatEntry* pNewEntry = new ScCondDateFormatEntry(mpDoc);
        condformat::ScCondFormatDateType eType = static_cast<condformat::ScCondFormatDateType>(maLbDateEntry->GetSelectedEntryPos());
        pNewEntry->SetDateType(eType);
        pNewEntry->SetStyleName(maLbStyle->GetSelectedEntry());
        return pNewEntry;
    }

    OUString ScDateFrmtEntry::GetExpressionString()
    {
        return ScCondFormatHelper::GetExpression(DATE, 0);
    }

    IMPL_LINK_NOARG( ScDateFrmtEntry, StyleSelectHdl, ListBox&, void )
    {
        mbIsInStyleCreate = true;
        StyleSelect( *maLbStyle.get(), mpDoc, *maWdPreview.get() );
        mbIsInStyleCreate = false;
    }

    class ScIconSetFrmtDataEntry : public VclContainer
                                 , public VclBuilderContainer
    {
    private:
        VclPtr<VclGrid> maGrid;
        VclPtr<FixedImage> maImgIcon;
        VclPtr<FixedText> maFtEntry;
        VclPtr<Edit> maEdEntry;
        VclPtr<ListBox> maLbEntryType;

    public:
        ScIconSetFrmtDataEntry( vcl::Window* pParent, ScIconSetType eType, ScDocument* pDoc,
                sal_Int32 i, const ScColorScaleEntry* pEntry = nullptr );
        virtual ~ScIconSetFrmtDataEntry() override;
        virtual Size calculateRequisition() const override;
        virtual void setAllocation(const Size &rAllocation) override;
        virtual void dispose() override;

        ScColorScaleEntry* CreateEntry(ScDocument* pDoc, const ScAddress& rPos) const;

        void SetFirstEntry();
    };

    ScIconSetFrmtDataEntry::ScIconSetFrmtDataEntry(vcl::Window* pParent, ScIconSetType eType, ScDocument* pDoc, sal_Int32 i, const ScColorScaleEntry* pEntry)
        : VclContainer(pParent)
    {
        m_pUIBuilder.reset(new VclBuilder(this, getUIRootDir(), "modules/scalc/ui/conditionaliconset.ui"));
        get(maGrid, "ConditionalIconSet");
        get(maImgIcon, "icon");
        get(maFtEntry, "label");
        get(maEdEntry, "entry");
        get(maLbEntryType, "listbox");
        maImgIcon->SetImage(Image(ScIconSetFormat::getBitmap(pDoc->GetIconSetBitmapMap(), eType, i)));
        if(pEntry)
        {
            switch(pEntry->GetType())
            {
                case COLORSCALE_VALUE:
                    maLbEntryType->SelectEntryPos(0);
                    maEdEntry->SetText(convertNumberToString(pEntry->GetValue(), pDoc));
                    break;
                case COLORSCALE_PERCENTILE:
                    maLbEntryType->SelectEntryPos(2);
                    maEdEntry->SetText(convertNumberToString(pEntry->GetValue(), pDoc));
                    break;
                case COLORSCALE_PERCENT:
                    maLbEntryType->SelectEntryPos(1);
                    maEdEntry->SetText(convertNumberToString(pEntry->GetValue(), pDoc));
                    break;
                case COLORSCALE_FORMULA:
                    maLbEntryType->SelectEntryPos(3);
                    maEdEntry->SetText(pEntry->GetFormula(formula::FormulaGrammar::GRAM_DEFAULT));
                    break;
                default:
                    assert(false);
            }
        }
        else
        {
            maLbEntryType->SelectEntryPos(1);
        }
    }

    Size ScIconSetFrmtDataEntry::calculateRequisition() const
    {
        if (!maGrid) //during dispose
            return Size();
        return getLayoutRequisition(*maGrid);
    }

    void ScIconSetFrmtDataEntry::setAllocation(const Size &rAllocation)
    {
        if (!maGrid) //during dispose
            return;
        setLayoutPosSize(*maGrid, Point(0, 0), rAllocation);
    }

    ScIconSetFrmtDataEntry::~ScIconSetFrmtDataEntry()
    {
        disposeOnce();
    }

    void ScIconSetFrmtDataEntry::dispose()
    {
        maImgIcon.clear();
        maFtEntry.clear();
        maEdEntry.clear();
        maLbEntryType.clear();
        maGrid.clear();
        disposeBuilder();
        VclContainer::dispose();
    }

    ScColorScaleEntry* ScIconSetFrmtDataEntry::CreateEntry(ScDocument* pDoc, const ScAddress& rPos) const
    {
        sal_Int32 nPos = maLbEntryType->GetSelectedEntryPos();
        OUString aText = maEdEntry->GetText();
        ScColorScaleEntry* pEntry = new ScColorScaleEntry();

        sal_uInt32 nIndex = 0;
        double nVal = 0;
        SvNumberFormatter* pNumberFormatter = pDoc->GetFormatTable();
        (void)pNumberFormatter->IsNumberFormat(aText, nIndex, nVal);
        pEntry->SetValue(nVal);

        switch(nPos)
        {
            case 0:
                pEntry->SetType(COLORSCALE_VALUE);
                break;
            case 1:
                pEntry->SetType(COLORSCALE_PERCENT);
                break;
            case 2:
                pEntry->SetType(COLORSCALE_PERCENTILE);
                break;
            case 3:
                pEntry->SetType(COLORSCALE_FORMULA);
                pEntry->SetFormula(aText, pDoc, rPos, pDoc->GetGrammar());
                break;
            default:
                assert(false);
        }

        return pEntry;
    }

    void ScIconSetFrmtDataEntry::SetFirstEntry()
    {
        maEdEntry->Hide();
        maLbEntryType->Hide();
        maFtEntry->Hide();
        maEdEntry->SetText("0");
        maLbEntryType->SelectEntryPos(1);
    }

    ScIconSetFrmtEntry::ScIconSetFrmtEntry(vcl::Window* pParent, ScDocument* pDoc, const ScAddress& rPos, const ScIconSetFormat* pFormat)
        : ScCondFrmtEntry(pParent, pDoc, rPos)
    {
        get(maLbColorFormat, "colorformat");
        get(maLbIconSetType, "iconsettype");
        get(maIconParent, "iconparent");

        Init();
        maLbColorFormat->SetSelectHdl( LINK( pParent, ScCondFormatList, ColFormatTypeHdl ) );

        if(pFormat)
        {
            const ScIconSetFormatData* pIconSetFormatData = pFormat->GetIconSetData();
            ScIconSetType eType = pIconSetFormatData->eIconSetType;
            sal_Int32 nType = static_cast<sal_Int32>(eType);
            maLbIconSetType->SelectEntryPos(nType);

            for (size_t i = 0, n = pIconSetFormatData->m_Entries.size();
                    i < n; ++i)
            {
                maEntries.push_back(VclPtr<ScIconSetFrmtDataEntry>::Create(
                    maIconParent, eType, pDoc, i, pIconSetFormatData->m_Entries[i].get()));
                maEntries[i]->set_grid_top_attach(i);
            }
            maEntries[0]->SetFirstEntry();
        }
        else
            IconSetTypeHdl(*maLbIconSetType.get());
    }

    ScIconSetFrmtEntry::~ScIconSetFrmtEntry()
    {
        disposeOnce();
    }

    void ScIconSetFrmtEntry::dispose()
    {
        for (auto it = maEntries.begin(); it != maEntries.end(); ++it)
            it->disposeAndClear();
        maEntries.clear();
        maIconParent.clear();
        maLbColorFormat.clear();
        maLbIconSetType.clear();
        ScCondFrmtEntry::dispose();
    }

    void ScIconSetFrmtEntry::Init()
    {
        maLbColorFormat->SelectEntryPos(3);
        maLbType->SelectEntryPos(0);
        maLbIconSetType->SelectEntryPos(0);

        maLbIconSetType->SetSelectHdl( LINK( this, ScIconSetFrmtEntry, IconSetTypeHdl ) );
    }

    IMPL_LINK_NOARG( ScIconSetFrmtEntry, IconSetTypeHdl, ListBox&, void )
    {
        const ScIconSetMap* pMap = ScIconSetFormat::g_IconSetMap;

        sal_Int32 nPos = maLbIconSetType->GetSelectedEntryPos();
        sal_uInt32 nElements = pMap[nPos].nElements;

        for (auto it = maEntries.begin(); it != maEntries.end(); ++it)
            it->disposeAndClear();
        maEntries.clear();

        for(size_t i = 0; i < nElements; ++i)
        {
            maEntries.push_back(VclPtr<ScIconSetFrmtDataEntry>::Create(maIconParent, static_cast<ScIconSetType>(nPos), mpDoc, i));
            maEntries[i]->set_grid_top_attach(i);
            maEntries[i]->Show();
        }
        maEntries[0]->SetFirstEntry();

        SetHeight();
    }

    OUString ScIconSetFrmtEntry::GetExpressionString()
    {
        return ScCondFormatHelper::GetExpression(ICONSET, 0);
    }

    void ScIconSetFrmtEntry::SetActive()
    {
        maLbColorFormat->Show();
        maLbIconSetType->Show();
        for(ScIconSetFrmtDataEntriesType::iterator itr = maEntries.begin(),
                itrEnd = maEntries.end(); itr != itrEnd; ++itr)
        {
            (*itr)->Show();
        }

        Select();
    }

    void ScIconSetFrmtEntry::SetInactive()
    {
        maLbColorFormat->Hide();
        maLbIconSetType->Hide();
        for(ScIconSetFrmtDataEntriesType::iterator itr = maEntries.begin(),
                itrEnd = maEntries.end(); itr != itrEnd; ++itr)
        {
            (*itr)->Hide();
        }

        Deselect();
    }

    ScFormatEntry* ScIconSetFrmtEntry::GetEntry() const
    {
        ScIconSetFormat* pFormat = new ScIconSetFormat(mpDoc);

        ScIconSetFormatData* pData = new ScIconSetFormatData;
        pData->eIconSetType = static_cast<ScIconSetType>(maLbIconSetType->GetSelectedEntryPos());
        for(ScIconSetFrmtDataEntriesType::const_iterator itr = maEntries.begin(),
                itrEnd = maEntries.end(); itr != itrEnd; ++itr)
        {
            pData->m_Entries.push_back(std::unique_ptr<ScColorScaleEntry>((*itr)->CreateEntry(mpDoc, maPos)));
        }
        pFormat->SetIconSetData(pData);

        return pFormat;
    }

    /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

↑ V778 Two similar code fragments were found. Perhaps, this is a typo and 'Show' variable should be used instead of 'Hide'.