tdf#157092 a11y Let only drawing area dispose its ValueSet acc

Don't dispose the a11y object in the `ValueSet` dtor, because it
doesn't own its a11y object, but it is owned by the `weld::DrawingArea`
of the `CustomWeld` that the `ValueSet` (as a sub-class of
`CustomWidgetController`) belongs to.

The `CustomWeld` ctor passes the a11y ref retrieved by
`CustomWidgetController::createAccessible` to `weld_drawing_area`,
which takes ownership and disposes the object.
(For Gtk, see  `GtkInstanceDrawingArea::~GtkInstanceDrawingArea`.
For non-Gtk, see how the `SalInstanceDrawingArea` ctor
passes the reference to `VclInstanceDrawingArea::SetAccessible`/
`vcl::Window::SetAccessible`, so it gets disposed when that
`VclInstanceDrawingArea` gets disposed, s. `vcl::Window::dispose`.)

Other classes derived from `CustomWidgetController`
also don't dispose the a11y object themselves.

Still reset the `ValueSet` pointer in `ValueSetAcc` to
nullptr when the `ValueSet` gets destroyed and turn the
check for a valid pointer from just an `OSL_ASSERT`
to a real assert and throwing a `RuntimeException`.
But still allow getting the a11y context when only
the ValueSet has been deleted but the object has not
been disposed yet.

Fixes a crash due to a `com::sun::star::lang::DisposedException`
being thrown when using the new search feature in the "Tools" ->
"Options" dialog (or when just switching to the "LibreOfficeDev
Writer/Web" -> "Background" page with the qt6 VCL plugin or
on Windows when the NVDA screen reader is running.

This happens when the drawing area is hidden and the a11y layer
is meant to be notified about this (so the a11y object can be
removed).

It still seems a bit odd that the `ValueSet` gets destroyed
(in `SvxColorTabPage::~SvxColorTabPage`, frame 20 in below backtrace)
before the corresponding `vcl::Window` gets hidden (in the base
class dtor, `SfxTabPage::~SfxTabPage`, s. frame 19 in the backtrace).

Backtrace for how the exception gets thrown:

    1   com::sun::star::lang::DisposedException::DisposedException               DisposedException.hpp       40   0x7fa385fd9ca9
    2   ValueSetAcc::ThrowIfDisposed                                             valueacc.cxx                956  0x7fa385fd9342
    3   ValueSetAcc::getAccessibleContext                                        valueacc.cxx                473  0x7fa385fd69fa
    4   VCLXAccessibleComponent::ProcessWindowChildEvent                         vclxaccessiblecomponent.cxx 186  0x7fa3853dc905
    5   VCLXAccessibleComponent::WindowChildEventListener                        vclxaccessiblecomponent.cxx 124  0x7fa3853dc51d
    6   VCLXAccessibleComponent::LinkStubWindowChildEventListener                vclxaccessiblecomponent.cxx 114  0x7fa3853dc43f
    7   Link<VclWindowEvent&, void>::Call                                        link.hxx                    111  0x7fa382c56ccf
    8   vcl::Window::CallEventListeners                                          event.cxx                   296  0x7fa382c53e5b
    9   vcl::Window::ImplResetReallyVisible                                      stacking.cxx                719  0x7fa382b51a49
    10  vcl::Window::ImplResetReallyVisible                                      stacking.cxx                735  0x7fa382b51b0e
    11  vcl::Window::ImplResetReallyVisible                                      stacking.cxx                735  0x7fa382b51b0e
    12  vcl::Window::ImplResetReallyVisible                                      stacking.cxx                735  0x7fa382b51b0e
    13  vcl::Window::ImplResetReallyVisible                                      stacking.cxx                735  0x7fa382b51b0e
    14  vcl::Window::ImplResetReallyVisible                                      stacking.cxx                735  0x7fa382b51b0e
    15  vcl::Window::ImplResetReallyVisible                                      stacking.cxx                735  0x7fa382b51b0e
    16  vcl::Window::Show                                                        window.cxx                  2234 0x7fa382d94f7c
    17  vcl::Window::Hide                                                        window.hxx                  880  0x7fa382b23600
    18  SalInstanceContainer::move                                               salvtables.cxx              1352 0x7fa3834789f3
    19  SfxTabPage::~SfxTabPage                                                  tabdlg.cxx                  157  0x7fa38928ab47
    20  SvxColorTabPage::~SvxColorTabPage                                        tpcolor.cxx                 166  0x7fa350950d3e
    21  SvxColorTabPage::~SvxColorTabPage                                        tpcolor.cxx                 166  0x7fa350950d5a
    22  std::default_delete<SfxTabPage>::operator()                              unique_ptr.h                99   0x7fa350538fdc
    23  std::__uniq_ptr_impl<SfxTabPage, std::default_delete<SfxTabPage>>::reset unique_ptr.h                211  0x7fa35080dcbe
    24  std::unique_ptr<SfxTabPage, std::default_delete<SfxTabPage>>::reset      unique_ptr.h                509  0x7fa350808555
    25  SvxAreaTabPage::SetOptimalSize                                           tparea.cxx                  155  0x7fa35093db3e
    26  SvxBkgTabPage::Create                                                    backgrnd.cxx                230  0x7fa350864dbc
    27  SwModule::CreateTabPage                                                  appopt.cxx                  509  0x7fa339e10973
    28  OfaTreeOptionsDialog::SelectHdl_Impl                                     treeopt.cxx                 1335 0x7fa3507f947a
    29  OfaTreeOptionsDialog::ShowPageHdl_Impl                                   treeopt.cxx                 625  0x7fa3507f4782
    30  OfaTreeOptionsDialog::LinkStubShowPageHdl_Impl                           treeopt.cxx                 623  0x7fa3507f4763
    31  Link<weld::TreeView&, void>::Call                                        link.hxx                    111  0x7fa3834b18f1
    32  weld::TreeView::signal_changed                                           weld.hxx                    953  0x7fa3834aa10d
    33  SalInstanceTreeView::SelectHdl                                           salvtables.cxx              5276 0x7fa38349363e
    34  SalInstanceTreeView::LinkStubSelectHdl                                   salvtables.cxx              5272 0x7fa3834935fb
    35  Link<SvTreeListBox *, void>::Call                                        link.hxx                    111  0x7fa382b8a339
    36  SvTreeListBox::SelectHdl                                                 treelistbox.cxx             452  0x7fa38307f5c2
    37  SvTreeListBox::Select                                                    treelistbox.cxx             2111 0x7fa383085b4a
    38  SvImpLBox::SetCursor                                                     svimpbox.cxx                614  0x7fa3830a66c3
    39  ImpLBSelEng::SetCursorAtPoint                                            svimpbox.cxx                2575 0x7fa3830aeaa8
    40  SelectionEngine::SelMouseButtonDown                                      seleng.cxx                  172  0x7fa382d09354
    41  SvImpLBox::MouseButtonDown                                               svimpbox.cxx                2004 0x7fa3830ac9f8
    42  SvTreeListBox::MouseButtonDown                                           treelistbox.cxx             2260 0x7fa383086422
    43  ImplHandleMouseEvent                                                     winproc.cxx                 707  0x7fa382daed00
    44  ImplHandleSalMouseButtonDown                                             winproc.cxx                 2340 0x7fa382db5c5d
    45  ImplWindowFrameProc                                                      winproc.cxx                 2685 0x7fa382db6f7e
    46  SalFrame::CallCallback                                                   salframe.hxx                310  0x7fa378ca4edc
    47  QtFrame::CallCallback                                                    QtFrame.hxx                 230  0x7fa378ca6418
    48  QtWidget::handleMouseButtonEvent                                         QtWidget.cxx                181  0x7fa378cf959b
    49  QtWidget::mousePressEvent                                                QtWidget.cxx                186  0x7fa378cf95f3
    50  QWidget::event                                                           qwidget.cpp                 8978 0x7fa376a2f327
    51  QtWidget::event                                                          QtWidget.cxx                730  0x7fa378cfb2f6
    52  QApplicationPrivate::notify_helper                                       qapplication.cpp            3287 0x7fa3769a666a
    53  QApplication::notify                                                     qapplication.cpp            2774 0x7fa3769a4539
    54  QCoreApplication::notifyInternal2                                        qcoreapplication.cpp        1125 0x7fa3783a5ed0
    55  QCoreApplication::sendSpontaneousEvent                                   qcoreapplication.cpp        1573 0x7fa3783a6a1d
    56  QApplicationPrivate::sendMouseEvent                                      qapplication.cpp            2358 0x7fa3769a31a2
    57  QWidgetWindow::handleMouseEvent                                          qwidgetwindow.cpp           627  0x7fa376a5f7cb
    58  QWidgetWindow::event                                                     qwidgetwindow.cpp           241  0x7fa376a5dcfd
    59  QApplicationPrivate::notify_helper                                       qapplication.cpp            3287 0x7fa3769a666a
    60  QApplication::notify                                                     qapplication.cpp            3238 0x7fa3769a647a
    61  QCoreApplication::notifyInternal2                                        qcoreapplication.cpp        1125 0x7fa3783a5ed0
    62  QCoreApplication::sendSpontaneousEvent                                   qcoreapplication.cpp        1573 0x7fa3783a6a1d
    63  QGuiApplicationPrivate::processMouseEvent                                qguiapplication.cpp         2315 0x7fa3775f21cd
    64  QGuiApplicationPrivate::processWindowSystemEvent                         qguiapplication.cpp         2061 0x7fa3775f15cf
    65  QWindowSystemInterface::sendWindowSystemEvents                           qwindowsysteminterface.cpp  1109 0x7fa37769ce23
    66  xcbSourceDispatch                                                        qxcbeventdispatcher.cpp     57   0x7fa376064df7
    67  ??                                                                                                        0x7fa37df2b5b4
    68  ??                                                                                                        0x7fa37df2e607
    69  g_main_context_iteration                                                                                  0x7fa37df2ebfc
    70  QEventDispatcherGlib::processEvents                                      qeventdispatcher_glib.cpp   395  0x7fa3787b6b33
    71  QXcbGlibEventDispatcher::processEvents                                   qxcbeventdispatcher.cpp     96   0x7fa37606502c
    72  QtInstance::ImplYield                                                    QtInstance.cxx              421  0x7fa378cc7502
    73  QtInstance::DoYield                                                      QtInstance.cxx              432  0x7fa378cc762b
    74  ImplYield                                                                svapp.cxx                   372  0x7fa3835220ea
    75  Application::Yield                                                       svapp.cxx                   456  0x7fa383522e88
    76  Dialog::Execute                                                          dialog.cxx                  1078 0x7fa382c063e1
    77  SalInstanceDialog::run                                                   salvtables.cxx              1877 0x7fa38347c313
    78  weld::DialogController::run                                              weld.hxx                    2659 0x7fa3504a26e6
    79  OfaTreeOptionsDialog::run                                                treeopt.cxx                 2587 0x7fa3508035fd
    80  CuiAbstractController_Impl::Execute                                      dlgfact.cxx                 144  0x7fa35069d829
    81  SfxApplication::OfaExec_Impl                                             appserv.cxx                 1463 0x7fa388faf85e
    82  SfxStubSfxApplicationOfaExec_Impl                                        sfxslots.hxx                1309 0x7fa388f88faf
    83  SfxDispatcher::Call_Impl                                                 dispatch.cxx                254  0x7fa3890bfb4a
    84  SfxDispatcher::Execute_                                                  dispatch.cxx                753  0x7fa3890c31f4
    85  SfxBindings::Execute_Impl                                                bindings.cxx                1061 0x7fa3890aefa0
    86  SfxDispatchController_Impl::dispatch                                     unoctitm.cxx                688  0x7fa389185ba6
    87  SfxOfficeDispatch::dispatch                                              unoctitm.cxx                250  0x7fa389183867
    88  framework::MenuBarManager::Select                                        menubarmanager.cxx          827  0x7fa38a7e2dff
    89  framework::MenuBarManager::LinkStubSelect                                menubarmanager.cxx          791  0x7fa38a7e2ab7
    90  Link<Menu *, bool>::Call                                                 link.hxx                    111  0x7fa382cb0337
    91  Menu::Select                                                             menu.cxx                    358  0x7fa382ca1c90
    92  Menu::ImplCallSelect                                                     menu.cxx                    2135 0x7fa382caa907
    93  Menu::LinkStubImplCallSelect                                             menu.cxx                    2132 0x7fa382caa8d9
    94  Link<void *, void>::Call                                                 link.hxx                    111  0x7fa382db870d
    95  ImplHandleUserEvent                                                      winproc.cxx                 2287 0x7fa382db57ca
    96  ImplWindowFrameProc                                                      winproc.cxx                 2851 0x7fa382db76f7
    97  SalFrame::CallCallback                                                   salframe.hxx                310  0x7fa378ca4edc
    98  QtInstance::ProcessEvent                                                 QtInstance.cxx              484  0x7fa378cc799b
    99  operator()                                                               salusereventlist.cxx        119  0x7fa383465b7b
    100 SalUserEventList::DispatchUserEvents                                     salusereventlist.cxx        120  0x7fa383465e4f
    101 QtInstance::ImplYield                                                    QtInstance.cxx              410  0x7fa378cc7480
    102 QtInstance::DoYield                                                      QtInstance.cxx              432  0x7fa378cc762b
    103 ImplYield                                                                svapp.cxx                   372  0x7fa3835220ea
    104 Application::Yield                                                       svapp.cxx                   456  0x7fa383522e88
    105 Application::Execute                                                     svapp.cxx                   350  0x7fa383521ddd
    106 desktop::Desktop::Main                                                   app.cxx                     1601 0x7fa38ca36276
    107 ImplSVMain                                                               svmain.cxx                  204  0x7fa383541e84
    108 SVMain                                                                   svmain.cxx                  236  0x7fa383541fb9
    109 soffice_main                                                             sofficemain.cxx             94   0x7fa38caa1b5d
    110 sal_main                                                                 main.c                      51   0x5568fd6859d4
    111 main                                                                     main.c                      49   0x5568fd6859ba

Change-Id: I247648a7a707f02bf1fdd339d3c329694636d835
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156645
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
diff --git a/svtools/source/control/valueacc.cxx b/svtools/source/control/valueacc.cxx
index cdf7596..2f897ae 100644
--- a/svtools/source/control/valueacc.cxx
+++ b/svtools/source/control/valueacc.cxx
@@ -29,6 +29,7 @@
#include <com/sun/star/accessibility/AccessibleRole.hpp>
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
#include <com/sun/star/uno/RuntimeException.hpp>

using namespace ::com::sun::star;

@@ -470,7 +471,8 @@ void ValueSetAcc::LoseFocus()

uno::Reference< accessibility::XAccessibleContext > SAL_CALL ValueSetAcc::getAccessibleContext()
{
    ThrowIfDisposed();
    // still allow retrieving a11y context when not disposed yet, but ValueSet is unset
    ThrowIfDisposed(false);
    return this;
}

@@ -886,16 +888,16 @@ void SAL_CALL ValueSetAcc::deselectAccessibleChild( sal_Int64 nChildIndex )
        mpParent->SetNoSelection();
}

void ValueSetAcc::Invalidate()
{
    mpParent = nullptr;
}

void ValueSetAcc::disposing(std::unique_lock<std::mutex>& rGuard)
{
    // Make a copy of the list and clear the original.
    ::std::vector<uno::Reference<accessibility::XAccessibleEventListener> > aListenerListCopy = std::move(mxEventListeners);

    // Reset the pointer to the parent.  It has to be the one who has
    // disposed us because he is dying.
    mpParent = nullptr;

    if (aListenerListCopy.empty())
        return;

@@ -946,7 +948,7 @@ ValueSetItem* ValueSetAcc::getItem (sal_uInt16 nIndex) const
}


void ValueSetAcc::ThrowIfDisposed()
void ValueSetAcc::ThrowIfDisposed(bool bCheckParent)
{
    if (m_bDisposed)
    {
@@ -955,9 +957,11 @@ void ValueSetAcc::ThrowIfDisposed()
            "object has been already disposed",
            getXWeak());
    }
    else

    if (bCheckParent && !mpParent)
    {
        DBG_ASSERT (mpParent!=nullptr, "ValueSetAcc not disposed but mpParent == NULL");
        assert(false && "ValueSetAcc not disposed but mpParent == NULL");
        throw css::uno::RuntimeException("ValueSetAcc not disposed but mpParent == NULL");
    }
}

diff --git a/svtools/source/control/valueimp.hxx b/svtools/source/control/valueimp.hxx
index ed34aa3..fca4e43 100644
--- a/svtools/source/control/valueimp.hxx
+++ b/svtools/source/control/valueimp.hxx
@@ -97,6 +97,9 @@ public:
    */
    void LoseFocus();

    /** Called by the corresponding ValueSet when it gets destroyed. */
    void Invalidate();

    // XAccessible
    virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext(  ) override;

@@ -167,9 +170,12 @@ private:
        state of being disposed).  If that is the case then
        DisposedException is thrown to inform the (indirect) caller of the
        foul deed.
        @param bCheckValueSet
            Whether to also check that the ValueSet (parent)
            is non-null.
        @throws css::lang::DisposedException
    */
    void ThrowIfDisposed();
    void ThrowIfDisposed(bool bCheckParent = true);

    /** Check whether the value set has a 'none' field, i.e. a field (button)
        that deselects any items (selects none of them).
diff --git a/svtools/source/control/valueset.cxx b/svtools/source/control/valueset.cxx
index e40da61..89ce7f8 100644
--- a/svtools/source/control/valueset.cxx
+++ b/svtools/source/control/valueset.cxx
@@ -124,7 +124,7 @@ Reference<XAccessible> ValueSet::CreateAccessible()
ValueSet::~ValueSet()
{
    if (mxAccessible)
        mxAccessible->dispose();
        mxAccessible->Invalidate();

    ImplDeleteItems();
}