tdf#134038 insert in optimal order

Change-Id: I7b3d2b7bb37f4a7de118b4654f63bcc18a24b855
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96473
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/sc/source/ui/cctrl/checklistmenu.cxx b/sc/source/ui/cctrl/checklistmenu.cxx
index 7a4d834..f095e66 100644
--- a/sc/source/ui/cctrl/checklistmenu.cxx
+++ b/sc/source/ui/cctrl/checklistmenu.cxx
@@ -1161,43 +1161,71 @@ void ScCheckListMenuControl::setHasDates(bool bHasDates)
    mxChecks->set_show_expanders(mbHasDates);
}

namespace
{
    void insertMember(weld::TreeView& rView, weld::TreeIter& rIter, const ScCheckListMember& rMember)
    {
        OUString aLabel = rMember.maName;
        if (aLabel.isEmpty())
            aLabel = ScResId(STR_EMPTYDATA);
        rView.set_toggle(rIter, rMember.mbVisible ? TRISTATE_TRUE : TRISTATE_FALSE);
        rView.set_text(rIter, aLabel, 0);
    }
}

size_t ScCheckListMenuControl::initMembers()
{
    size_t n = maMembers.size();
    size_t nVisMemCount = 0;

    mxChecks->freeze();

    std::unique_ptr<weld::TreeIter> xEntry = mxChecks->make_iterator();
    std::vector<std::unique_ptr<weld::TreeIter>> aExpandRows;

    for (size_t i = 0; i < n; ++i)
    if (!mxChecks->n_children() && !mbHasDates)
    {
        if (maMembers[i].mbDate)
        {
            CheckEntry(maMembers[i].maName, maMembers[i].mxParent.get(), maMembers[i].mbVisible);
            // Expand first node of checked dates
            if (!maMembers[i].mxParent && IsChecked(maMembers[i].maName,  maMembers[i].mxParent.get()))
            {
                std::unique_ptr<weld::TreeIter> xDateEntry = FindEntry(nullptr, maMembers[i].maName);
                if (xDateEntry)
                    aExpandRows.emplace_back(std::move(xDateEntry));
            }
        }
        else
        {
            OUString aLabel = maMembers[i].maName;
            if (aLabel.isEmpty())
                aLabel = ScResId(STR_EMPTYDATA);

            mxChecks->append(xEntry.get());
            mxChecks->set_toggle(*xEntry, maMembers[i].mbVisible ? TRISTATE_TRUE : TRISTATE_FALSE);
            mxChecks->set_text(*xEntry, aLabel, 0);
        }

        if (maMembers[i].mbVisible)
            ++nVisMemCount;
        // tdf#134038 insert in the fastest order, this might be backwards so only do it for
        // the !mbHasDates case where no entry depends on another to exist before getting
        // inserted. We cannot retain pre-existing treeview content, only clear and fill it.
        mxChecks->bulk_insert_for_each(n, [this, &nVisMemCount](weld::TreeIter& rIter, int i) {
            assert(!maMembers[i].mbDate);
            insertMember(*mxChecks, rIter, maMembers[i]);
            if (maMembers[i].mbVisible)
                ++nVisMemCount;
        });
    }
    else
    {
        mxChecks->freeze();

        std::unique_ptr<weld::TreeIter> xEntry = mxChecks->make_iterator();
        std::vector<std::unique_ptr<weld::TreeIter>> aExpandRows;

        for (size_t i = 0; i < n; ++i)
        {
            if (maMembers[i].mbDate)
            {
                CheckEntry(maMembers[i].maName, maMembers[i].mxParent.get(), maMembers[i].mbVisible);
                // Expand first node of checked dates
                if (!maMembers[i].mxParent && IsChecked(maMembers[i].maName,  maMembers[i].mxParent.get()))
                {
                    std::unique_ptr<weld::TreeIter> xDateEntry = FindEntry(nullptr, maMembers[i].maName);
                    if (xDateEntry)
                        aExpandRows.emplace_back(std::move(xDateEntry));
                }
            }
            else
            {
                mxChecks->append(xEntry.get());
                insertMember(*mxChecks, *xEntry, maMembers[i]);
            }

            if (maMembers[i].mbVisible)
                ++nVisMemCount;
        }

        mxChecks->thaw();

        for (auto& rRow : aExpandRows)
            mxChecks->expand_row(*rRow);
    }

    if (nVisMemCount == n)
    {
        // all members visible
@@ -1216,11 +1244,6 @@ size_t ScCheckListMenuControl::initMembers()
        mePrevToggleAllState = TRISTATE_INDET;
    }

    mxChecks->thaw();

    for (auto& rRow : aExpandRows)
        mxChecks->expand_row(*rRow);

    if (nVisMemCount)
        mxChecks->select(0);

diff --git a/sc/uiconfig/scalc/ui/filterdropdown.ui b/sc/uiconfig/scalc/ui/filterdropdown.ui
index c37771a..b6a3e4f 100644
--- a/sc/uiconfig/scalc/ui/filterdropdown.ui
+++ b/sc/uiconfig/scalc/ui/filterdropdown.ui
@@ -198,7 +198,7 @@
                <property name="can_focus">True</property>
                <property name="hexpand">True</property>
                <property name="vexpand">True</property>
                <property name="hscrollbar_policy">never</property>
                <property name="hscrollbar_policy">external</property>
                <property name="shadow_type">in</property>
                <child>
                  <object class="GtkTreeView" id="check_list_box">