Resolves: tdf#127120 double selection in B&N dialog

because the list wants to ensure that at least one thing is selected and the
multiselect is implemented with two events of deselect-all followed by select.

post a user event on getting either deselect or select and process it
once when the dust has settled

Change-Id: I553bf23d7a8c4625a8706fb2df4b169d91b7ad32
Reviewed-on: https://gerrit.libreoffice.org/78542
Tested-by: Jenkins
Tested-by: Xisco Faulí <xiscofauli@libreoffice.org>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/cui/source/inc/numpages.hxx b/cui/source/inc/numpages.hxx
index 183f1d7..6582a81 100644
--- a/cui/source/inc/numpages.hxx
+++ b/cui/source/inc/numpages.hxx
@@ -331,8 +331,9 @@ class SvxNumPositionTabPage : public SfxTabPage
    std::unique_ptr<SvxNumRule> pActNum;
    std::unique_ptr<SvxNumRule> pSaveNum;

    sal_uInt16              nActNumLvl;
    sal_uInt16              nNumItemId;
    ImplSVEvent*        m_pLevelHdlEvent;
    sal_uInt16          nActNumLvl;
    sal_uInt16          nNumItemId;
    MapUnit             eCoreUnit;

    bool                bModified           : 1;
@@ -371,6 +372,7 @@ class SvxNumPositionTabPage : public SfxTabPage
    void                InitControls();

    DECL_LINK(LevelHdl_Impl, weld::TreeView&, void);
    DECL_LINK(LevelHdl, void *, void);
    DECL_LINK(EditModifyHdl_Impl, weld::ComboBox&, void);
    DECL_LINK(DistanceHdl_Impl, weld::MetricSpinButton&, void);
    DECL_LINK(DistanceFocusHdl_Impl, Control&, void);
diff --git a/cui/source/tabpages/numpages.cxx b/cui/source/tabpages/numpages.cxx
index 89c4373..d7985b5e 100644
--- a/cui/source/tabpages/numpages.cxx
+++ b/cui/source/tabpages/numpages.cxx
@@ -2497,6 +2497,7 @@ void SvxNumberingPreview::Paint(vcl::RenderContext& rRenderContext, const ::tool
//merged
SvxNumPositionTabPage::SvxNumPositionTabPage(TabPageParent pParent, const SfxItemSet& rSet)
    : SfxTabPage(pParent, "cui/ui/numberingpositionpage.ui", "NumberingPositionPage", &rSet)
    , m_pLevelHdlEvent(nullptr)
    , nActNumLvl(1)
    , nNumItemId(SID_ATTR_NUMBERING_RULE)
    , bModified(false)
@@ -2568,6 +2569,11 @@ SvxNumPositionTabPage::~SvxNumPositionTabPage()

void SvxNumPositionTabPage::dispose()
{
    if (m_pLevelHdlEvent)
    {
        Application::RemoveUserEvent(m_pLevelHdlEvent);
        m_pLevelHdlEvent = nullptr;
    }
    m_xPreviewWIN.reset();
    SfxTabPage::dispose();
}
@@ -3008,17 +3014,29 @@ IMPL_LINK_NOARG(SvxNumPositionTabPage, EditModifyHdl_Impl, weld::ComboBox&, void
    SetModified();
}

IMPL_LINK(SvxNumPositionTabPage, LevelHdl_Impl, weld::TreeView&, rBox, void)
IMPL_LINK_NOARG(SvxNumPositionTabPage, LevelHdl_Impl, weld::TreeView&, void)
{
    if (m_pLevelHdlEvent)
        return;
    // tdf#127120 multiselection may be implemented by deselect follow by select so
    // fire off the handler to happen on next event loop and only process the
    // final state
    m_pLevelHdlEvent = Application::PostUserEvent(LINK(this, SvxNumPositionTabPage, LevelHdl));
}

IMPL_LINK_NOARG(SvxNumPositionTabPage, LevelHdl, void*, void)
{
    m_pLevelHdlEvent = nullptr;

    sal_uInt16 nSaveNumLvl = nActNumLvl;
    nActNumLvl = 0;
    std::vector<int> aSelectedRows = rBox.get_selected_rows();
    std::vector<int> aSelectedRows = m_xLevelLB->get_selected_rows();
    if (std::find(aSelectedRows.begin(), aSelectedRows.end(), pActNum->GetLevelCount()) != aSelectedRows.end() &&
            (aSelectedRows.size() == 1 || nSaveNumLvl != 0xffff))
    {
        nActNumLvl = 0xFFFF;
        for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
            rBox.unselect(i);
            m_xLevelLB->unselect(i);
    }
    else if (!aSelectedRows.empty())
    {
@@ -3029,7 +3047,7 @@ IMPL_LINK(SvxNumPositionTabPage, LevelHdl_Impl, weld::TreeView&, rBox, void)
                nActNumLvl |= nMask;
            nMask <<= 1;
        }
        rBox.unselect(pActNum->GetLevelCount());
        m_xLevelLB->unselect(pActNum->GetLevelCount());
    }
    else
    {
@@ -3039,7 +3057,7 @@ IMPL_LINK(SvxNumPositionTabPage, LevelHdl_Impl, weld::TreeView&, rBox, void)
        {
            if(nActNumLvl & nMask)
            {
                rBox.select(i);
                m_xLevelLB->select(i);
                break;
            }
            nMask <<=1;