weld TreeView

a) use GtkTreeStores for GtkTreeViews
b) ironically can't store GtkTreeStore contents in .ui apparently
c) set show_expanders for all non-trees and unconverted cases
d) on-demand subtrees

Change-Id: I3c1036a222daba2c129b1a22ffeb3fe35005ae31
Reviewed-on: https://gerrit.libreoffice.org/63336
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/basctl/source/basicide/baside2.cxx b/basctl/source/basicide/baside2.cxx
index 1725324..81efba1 100644
--- a/basctl/source/basicide/baside2.cxx
+++ b/basctl/source/basicide/baside2.cxx
@@ -339,7 +339,7 @@ void ModulWindow::BasicExecute()
            if ( !pMethod )
            {
                // If not in a method then prompt the user
                ChooseMacro( uno::Reference< frame::XModel >() );
                ChooseMacro(GetFrameWeld(), uno::Reference<frame::XModel>());
                return;
            }
            pMethod->SetDebugFlags(m_aStatus.nBasicFlags);
diff --git a/basctl/source/basicide/basides1.cxx b/basctl/source/basicide/basides1.cxx
index 0d7ff9c..2bb3aacd 100644
--- a/basctl/source/basicide/basides1.cxx
+++ b/basctl/source/basicide/basides1.cxx
@@ -331,7 +331,7 @@ void Shell::ExecuteGlobal( SfxRequest& rReq )
        break;
        case SID_BASICIDE_CHOOSEMACRO:
        {
            ChooseMacro( nullptr );
            ChooseMacro(rReq.GetFrameWeld(), nullptr);
        }
        break;
        case SID_BASICIDE_CREATEMACRO:
diff --git a/basctl/source/basicide/basobj2.cxx b/basctl/source/basicide/basobj2.cxx
index be25e26..c127446 100644
--- a/basctl/source/basicide/basobj2.cxx
+++ b/basctl/source/basicide/basobj2.cxx
@@ -45,11 +45,11 @@ using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::container;

extern "C" {
    SAL_DLLPUBLIC_EXPORT rtl_uString* basicide_choose_macro( void* pOnlyInDocument_AsXModel, void* pDocFrame_AsXFrame, sal_Bool bChooseOnly )
    SAL_DLLPUBLIC_EXPORT rtl_uString* basicide_choose_macro(void* pParent, void* pOnlyInDocument_AsXModel, void* pDocFrame_AsXFrame, sal_Bool bChooseOnly )
    {
        Reference< frame::XModel > aDocument( static_cast< frame::XModel* >( pOnlyInDocument_AsXModel ) );
        Reference< frame::XFrame > aDocFrame( static_cast< frame::XFrame* >( pDocFrame_AsXFrame ) );
        OUString aScriptURL = basctl::ChooseMacro( aDocument, aDocFrame, bChooseOnly );
        OUString aScriptURL = basctl::ChooseMacro(static_cast<weld::Window*>(pParent), aDocument, aDocFrame, bChooseOnly);
        rtl_uString* pScriptURL = aScriptURL.pData;
        rtl_uString_acquire( pScriptURL );

@@ -235,9 +235,10 @@ namespace
    }
}

OUString ChooseMacro( const uno::Reference< frame::XModel >& rxLimitToDocument,
                      const uno::Reference< frame::XFrame >& xDocFrame,
                      bool bChooseOnly )
OUString ChooseMacro(weld::Window* pParent,
                     const uno::Reference< frame::XModel >& rxLimitToDocument,
                     const uno::Reference< frame::XFrame >& xDocFrame,
                     bool bChooseOnly)
{
    EnsureIde();

@@ -246,15 +247,17 @@ OUString ChooseMacro( const uno::Reference< frame::XModel >& rxLimitToDocument,
    OUString aScriptURL;
    SbMethod* pMethod = nullptr;

    ScopedVclPtrInstance< MacroChooser > pChooser( nullptr, xDocFrame, true );
    MacroChooser aChooser(pParent, xDocFrame, true);
    if ( bChooseOnly || !SvtModuleOptions::IsBasicIDE() )
        pChooser->SetMode(MacroChooser::ChooseOnly);
        aChooser.SetMode(MacroChooser::ChooseOnly);

    if ( !bChooseOnly && rxLimitToDocument.is() )
    {
        // Hack!
        pChooser->SetMode(MacroChooser::Recording);
        aChooser.SetMode(MacroChooser::Recording);
    }

    short nRetValue = pChooser->Execute();
    short nRetValue = aChooser.run();

    GetExtraData()->ChoosingMacro() = false;

@@ -264,9 +267,9 @@ OUString ChooseMacro( const uno::Reference< frame::XModel >& rxLimitToDocument,
        {
            bool bError = false;

            pMethod = pChooser->GetMacro();
            if ( !pMethod && pChooser->GetMode() == MacroChooser::Recording )
                pMethod = pChooser->CreateMacro();
            pMethod = aChooser.GetMacro();
            if ( !pMethod && aChooser.GetMode() == MacroChooser::Recording )
                pMethod = aChooser.CreateMacro();

            if ( !pMethod )
                break;
diff --git a/basctl/source/basicide/bastype2.cxx b/basctl/source/basicide/bastype2.cxx
index 8066cf2..b143924 100644
--- a/basctl/source/basicide/bastype2.cxx
+++ b/basctl/source/basicide/bastype2.cxx
@@ -895,6 +895,690 @@ bool TreeListBox::OpenCurrent()
    return false;
}

SbTreeListBox::SbTreeListBox(std::unique_ptr<weld::TreeView> xControl, weld::Window* pTopLevel)
    : m_xControl(std::move(xControl))
    , m_xIter(m_xControl->make_iterator())
    , m_pTopLevel(pTopLevel)
    , m_aNotifier(*this)
{
    m_xControl->connect_row_activated(LINK(this, SbTreeListBox, OpenCurrentHdl));
    m_xControl->connect_expanding(LINK(this, SbTreeListBox, RequestingChildrenHdl));
    nMode = BrowseMode::All;   // everything
}

SbTreeListBox::~SbTreeListBox()
{
    m_aNotifier.dispose();

    bool bValidIter = m_xControl->get_iter_first(*m_xIter);
    while (bValidIter)
    {
        Entry* pBasicEntry = reinterpret_cast<Entry*>(m_xControl->get_id(*m_xIter).toInt64());
        delete pBasicEntry;
        bValidIter = m_xControl->iter_next(*m_xIter);
    }
}

void SbTreeListBox::ScanEntry( const ScriptDocument& rDocument, LibraryLocation eLocation )
{
    OSL_ENSURE( rDocument.isAlive(), "TreeListBox::ScanEntry: illegal document!" );
    if ( !rDocument.isAlive() )
        return;

    // can be called multiple times for updating!

    // actually test if basic's in the tree already?!
    m_xControl->freeze();
    // level 1: BasicManager (application, document, ...)
    bool bDocumentRootEntry = FindRootEntry(rDocument, eLocation, *m_xIter);
    if (bDocumentRootEntry && m_xControl->get_row_expanded(*m_xIter))
        ImpCreateLibEntries(*m_xIter, rDocument, eLocation);
    if (!bDocumentRootEntry)
    {
        OUString aRootName(GetRootEntryName(rDocument, eLocation));
        OUString aImage(GetRootEntryBitmaps(rDocument));
        AddEntry(aRootName, aImage, nullptr, true, o3tl::make_unique<DocumentEntry>(rDocument, eLocation));
    }
    m_xControl->thaw();
}

void SbTreeListBox::ImpCreateLibEntries(weld::TreeIter& rIter, const ScriptDocument& rDocument, LibraryLocation eLocation)
{
    // get a sorted list of library names
    Sequence< OUString > aLibNames( rDocument.getLibraryNames() );
    sal_Int32 nLibCount = aLibNames.getLength();
    const OUString* pLibNames = aLibNames.getConstArray();

    for ( sal_Int32 i = 0 ; i < nLibCount ; i++ )
    {
        OUString aLibName = pLibNames[ i ];

        if ( eLocation == rDocument.getLibraryLocation( aLibName ) )
        {
            // check, if the module library is loaded
            bool bModLibLoaded = false;
            Reference< script::XLibraryContainer > xModLibContainer( rDocument.getLibraryContainer( E_SCRIPTS ) );
            if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryLoaded( aLibName ) )
                bModLibLoaded = true;

            // check, if the dialog library is loaded
            bool bDlgLibLoaded = false;
            Reference< script::XLibraryContainer > xDlgLibContainer( rDocument.getLibraryContainer( E_DIALOGS ) );
            if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryLoaded( aLibName ) )
                bDlgLibLoaded = true;

            bool bLoaded = bModLibLoaded || bDlgLibLoaded;

            // if only one of the libraries is loaded, load also the other
            if ( bLoaded )
            {
                if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && !xModLibContainer->isLibraryLoaded( aLibName ) )
                    xModLibContainer->loadLibrary( aLibName );

                if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && !xDlgLibContainer->isLibraryLoaded( aLibName ) )
                    xDlgLibContainer->loadLibrary( aLibName );
            }

            // create tree list box entry
            OUString sId;
            if ( ( nMode & BrowseMode::Dialogs ) && !( nMode & BrowseMode::Modules ) )
                sId = bLoaded ? OUStringLiteral(RID_BMP_DLGLIB) : OUStringLiteral(RID_BMP_DLGLIBNOTLOADED);
            else
                sId = bLoaded ? OUStringLiteral(RID_BMP_MODLIB) : OUStringLiteral(RID_BMP_MODLIBNOTLOADED);
            std::unique_ptr<weld::TreeIter> xLibRootEntry(m_xControl->make_iterator(&rIter));
            bool bLibRootEntry = FindEntry(aLibName, OBJ_TYPE_LIBRARY, *xLibRootEntry);
            if (bLibRootEntry)
            {
                SetEntryBitmaps(*xLibRootEntry, sId);
                if (m_xControl->get_row_expanded(*xLibRootEntry))
                    ImpCreateLibSubEntries(*xLibRootEntry, rDocument, aLibName);
            }
            else
            {
                AddEntry(aLibName, sId, &rIter, true, o3tl::make_unique<Entry>(OBJ_TYPE_LIBRARY));
            }
        }
    }
}

void SbTreeListBox::ImpCreateLibSubEntries(weld::TreeIter& rLibRootEntry, const ScriptDocument& rDocument, const OUString& rLibName)
{
    // modules
    if ( nMode & BrowseMode::Modules )
    {
        Reference< script::XLibraryContainer > xModLibContainer( rDocument.getLibraryContainer( E_SCRIPTS ) );

        if ( xModLibContainer.is() && xModLibContainer->hasByName( rLibName ) && xModLibContainer->isLibraryLoaded( rLibName ) )
        {
            try
            {
                if( rDocument.isInVBAMode() )
                {
                    ImpCreateLibSubEntriesInVBAMode(rLibRootEntry, rDocument, rLibName);
                }
                else
                {
                    // get a sorted list of module names
                    Sequence< OUString > aModNames = rDocument.getObjectNames( E_SCRIPTS, rLibName );
                    sal_Int32 nModCount = aModNames.getLength();
                    const OUString* pModNames = aModNames.getConstArray();

                    auto xTreeIter = m_xControl->make_iterator();

                    for ( sal_Int32 i = 0 ; i < nModCount ; i++ )
                    {
                        OUString aModName = pModNames[ i ];
                        m_xControl->copy_iterator(rLibRootEntry, *xTreeIter);
                        bool bModuleEntry = FindEntry(aModName, OBJ_TYPE_MODULE, *xTreeIter);
                        if (!bModuleEntry)
                        {
                            AddEntry(aModName, RID_BMP_MODULE, &rLibRootEntry, false, o3tl::make_unique<Entry>(OBJ_TYPE_MODULE));
                        }

                        // methods
                        if ( nMode & BrowseMode::Subs )
                        {
                            Sequence< OUString > aNames = GetMethodNames( rDocument, rLibName, aModName );
                            sal_Int32 nCount = aNames.getLength();
                            const OUString* pNames = aNames.getConstArray();

                            auto xSubTreeIter = m_xControl->make_iterator();

                            for ( sal_Int32 j = 0 ; j < nCount ; j++ )
                            {
                                OUString aName = pNames[ j ];
                                m_xControl->copy_iterator(*xTreeIter, *xSubTreeIter);
                                bool bEntry = FindEntry(aName, OBJ_TYPE_METHOD, *xSubTreeIter);
                                if (!bEntry)
                                {
                                    AddEntry(aName, RID_BMP_MACRO, xTreeIter.get(), false, o3tl::make_unique<Entry>(OBJ_TYPE_METHOD));
                                }
                            }
                        }
                    }
                }
            }
            catch ( const container::NoSuchElementException& )
            {
                DBG_UNHANDLED_EXCEPTION("basctl.basicide");
            }
        }
    }

    // dialogs
    if ( nMode & BrowseMode::Dialogs )
    {
         Reference< script::XLibraryContainer > xDlgLibContainer( rDocument.getLibraryContainer( E_DIALOGS ) );

         if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( rLibName ) && xDlgLibContainer->isLibraryLoaded( rLibName ) )
         {
            try
            {
                // get a sorted list of dialog names
                Sequence< OUString > aDlgNames( rDocument.getObjectNames( E_DIALOGS, rLibName ) );
                sal_Int32 nDlgCount = aDlgNames.getLength();
                const OUString* pDlgNames = aDlgNames.getConstArray();

                auto xTreeIter = m_xControl->make_iterator();

                for ( sal_Int32 i = 0 ; i < nDlgCount ; i++ )
                {
                    OUString aDlgName = pDlgNames[ i ];
                    m_xControl->copy_iterator(rLibRootEntry, *xTreeIter);
                    bool bDialogEntry = FindEntry(aDlgName, OBJ_TYPE_DIALOG, *xTreeIter);
                    if (!bDialogEntry)
                    {
                        AddEntry(aDlgName, RID_BMP_DIALOG, &rLibRootEntry, false, o3tl::make_unique<Entry>(OBJ_TYPE_DIALOG));
                    }
                }
            }
            catch (const container::NoSuchElementException& )
            {
                DBG_UNHANDLED_EXCEPTION("basctl.basicide");
            }
        }
    }
}

void SbTreeListBox::ImpCreateLibSubEntriesInVBAMode(weld::TreeIter& rLibRootEntry, const ScriptDocument& rDocument, const OUString& rLibName )
{
    auto const aEntries = {
        std::make_pair( OBJ_TYPE_DOCUMENT_OBJECTS, IDEResId(RID_STR_DOCUMENT_OBJECTS) ),
        std::make_pair( OBJ_TYPE_USERFORMS, IDEResId(RID_STR_USERFORMS) ),
        std::make_pair( OBJ_TYPE_NORMAL_MODULES, IDEResId(RID_STR_NORMAL_MODULES) ),
        std::make_pair( OBJ_TYPE_CLASS_MODULES, IDEResId(RID_STR_CLASS_MODULES) ) };
    for( auto const & iter: aEntries )
    {
        EntryType eType = iter.first;
        OUString const & aEntryName = iter.second;
        std::unique_ptr<weld::TreeIter> xLibSubRootEntry(m_xControl->make_iterator(&rLibRootEntry));
        bool bLibSubRootEntry = FindEntry(aEntryName, eType, *xLibSubRootEntry);
        if (bLibSubRootEntry)
        {
            SetEntryBitmaps(*xLibSubRootEntry, RID_BMP_MODLIB);
            if (m_xControl->get_row_expanded(*xLibSubRootEntry))
                ImpCreateLibSubSubEntriesInVBAMode(*xLibSubRootEntry, rDocument, rLibName);
        }
        else
        {
            m_xControl->copy_iterator(rLibRootEntry, *xLibSubRootEntry);
            AddEntry(aEntryName, RID_BMP_MODLIB, xLibSubRootEntry.get(), true, o3tl::make_unique<Entry>(eType));
        }
    }
}

void SbTreeListBox::ImpCreateLibSubSubEntriesInVBAMode(weld::TreeIter& rLibSubRootEntry, const ScriptDocument& rDocument, const OUString& rLibName)
{
    uno::Reference< container::XNameContainer > xLib = rDocument.getOrCreateLibrary( E_SCRIPTS, rLibName );
    if( !xLib.is() )
        return;

    try
    {
        // get a sorted list of module names
        Sequence< OUString > aModNames = rDocument.getObjectNames( E_SCRIPTS, rLibName );
        sal_Int32 nModCount = aModNames.getLength();
        const OUString* pModNames = aModNames.getConstArray();

        EntryDescriptor aDesc(GetEntryDescriptor(&rLibSubRootEntry));
        EntryType eCurrentType(aDesc.GetType());

        for ( sal_Int32 i = 0 ; i < nModCount ; i++ )
        {
            OUString aModName = pModNames[ i ];
            EntryType eType = OBJ_TYPE_UNKNOWN;
            switch( ModuleInfoHelper::getModuleType( xLib, aModName ) )
            {
                case script::ModuleType::DOCUMENT:
                    eType = OBJ_TYPE_DOCUMENT_OBJECTS;
                    break;
                case script::ModuleType::FORM:
                    eType = OBJ_TYPE_USERFORMS;
                    break;
                case script::ModuleType::NORMAL:
                    eType = OBJ_TYPE_NORMAL_MODULES;
                    break;
                case script::ModuleType::CLASS:
                    eType = OBJ_TYPE_CLASS_MODULES;
                    break;
            }
            if( eType != eCurrentType )
                continue;

            // display a nice friendly name in the ObjectModule tab,
               // combining the objectname and module name, e.g. Sheet1 ( Financials )
            OUString aEntryName = aModName;
            if( eType == OBJ_TYPE_DOCUMENT_OBJECTS )
            {
                OUString sObjName;
                ModuleInfoHelper::getObjectName( xLib, aModName, sObjName );
                if( !sObjName.isEmpty() )
                {
                    aEntryName += " (" + sObjName + ")";
                }
            }
            std::unique_ptr<weld::TreeIter> xModuleEntry(m_xControl->make_iterator(&rLibSubRootEntry));
            bool bModuleEntry = FindEntry(aEntryName, OBJ_TYPE_MODULE, *xModuleEntry);
            if (!bModuleEntry)
            {
                m_xControl->copy_iterator(rLibSubRootEntry, *xModuleEntry);
                AddEntry(aEntryName, RID_BMP_MODULE, xModuleEntry.get(), false,
                         o3tl::make_unique<Entry>(OBJ_TYPE_MODULE));
            }

            // methods
            if ( nMode & BrowseMode::Subs )
            {
                Sequence< OUString > aNames = GetMethodNames( rDocument, rLibName, aModName );
                sal_Int32 nCount = aNames.getLength();
                const OUString* pNames = aNames.getConstArray();

                for ( sal_Int32 j = 0 ; j < nCount ; j++ )
                {
                    OUString aName = pNames[ j ];
                    std::unique_ptr<weld::TreeIter> xEntry(m_xControl->make_iterator(xModuleEntry.get()));
                    bool bEntry = FindEntry(aName, OBJ_TYPE_METHOD, *xEntry);
                    if (!bEntry)
                    {
                        AddEntry(aName, RID_BMP_MACRO, xModuleEntry.get(), false, o3tl::make_unique<Entry>(OBJ_TYPE_METHOD));
                    }
                }
            }
        }
    }
    catch ( const container::NoSuchElementException& )
    {
        DBG_UNHANDLED_EXCEPTION("basctl.basicide");
    }
}

bool SbTreeListBox::ImpFindEntry(weld::TreeIter& rIter, const OUString& rText)
{
    bool bValidIter = m_xControl->iter_children(rIter);
    while (bValidIter)
    {
        if (rText == m_xControl->get_text(rIter))
            return true;
        bValidIter = m_xControl->iter_next_sibling(rIter);
    }
    return false;
}

void SbTreeListBox::onDocumentCreated( const ScriptDocument& /*_rDocument*/ )
{
    UpdateEntries();
}

void SbTreeListBox::onDocumentOpened( const ScriptDocument& /*_rDocument*/ )
{
    UpdateEntries();
}

void SbTreeListBox::onDocumentSave( const ScriptDocument& /*_rDocument*/ )
{
    // not interested in
}

void SbTreeListBox::onDocumentSaveDone( const ScriptDocument& /*_rDocument*/ )
{
    // not interested in
}

void SbTreeListBox::onDocumentSaveAs( const ScriptDocument& /*_rDocument*/ )
{
    // not interested in
}

void SbTreeListBox::onDocumentSaveAsDone( const ScriptDocument& /*_rDocument*/ )
{
    UpdateEntries();
}

void SbTreeListBox::onDocumentClosed( const ScriptDocument& rDocument )
{
    UpdateEntries();
    // The document is not yet actually deleted, so we need to remove its entry
    // manually.
    RemoveEntry(rDocument);
}

void SbTreeListBox::onDocumentTitleChanged( const ScriptDocument& /*_rDocument*/ )
{
    // not interested in
}

void SbTreeListBox::onDocumentModeChanged( const ScriptDocument& /*_rDocument*/ )
{
    // not interested in
}

void SbTreeListBox::UpdateEntries()
{
    bool bValidIter = m_xControl->get_selected(m_xIter.get());
    EntryDescriptor aCurDesc(GetEntryDescriptor(bValidIter ? m_xIter.get() : nullptr));

    // removing the invalid entries
    std::unique_ptr<weld::TreeIter> xLastValid(m_xControl->make_iterator(nullptr));
    bool bLastValid = false;
    bValidIter = m_xControl->get_iter_first(*m_xIter);
    while (bValidIter)
    {
        if (IsValidEntry(*m_xIter))
        {
            m_xControl->copy_iterator(*m_xIter, *xLastValid);
            bLastValid = true;
        }
        else
            RemoveEntry(*m_xIter);
        if (bLastValid)
        {
            m_xControl->copy_iterator(*xLastValid, *m_xIter);
            bValidIter = m_xControl->iter_next(*m_xIter);
        }
        else
            bValidIter = m_xControl->get_iter_first(*m_xIter);
    }

    ScanAllEntries();

    SetCurrentEntry( aCurDesc );
}

// Removes the entry from the tree.
void SbTreeListBox::RemoveEntry(const weld::TreeIter& rIter)
{
    // removing the associated user data
    Entry* pBasicEntry = reinterpret_cast<Entry*>(m_xControl->get_id(rIter).toInt64());
    delete pBasicEntry;
    // removing the entry
    m_xControl->remove(rIter);
}

// Removes the entry of rDocument.
void SbTreeListBox::RemoveEntry (ScriptDocument const& rDocument)
{
    // finding the entry of rDocument
    bool bValidIter = m_xControl->get_iter_first(*m_xIter);
    while (bValidIter)
    {
        if (rDocument == GetEntryDescriptor(m_xIter.get()).GetDocument())
        {
            RemoveEntry(*m_xIter);
            break;
        }
        bValidIter = m_xControl->iter_next(*m_xIter);
    }
}

bool SbTreeListBox::FindEntry(const OUString& rText, EntryType eType, weld::TreeIter& rIter)
{
    bool bValidIter = m_xControl->iter_children(rIter);
    while (bValidIter)
    {
        Entry* pBasicEntry = reinterpret_cast<Entry*>(m_xControl->get_id(rIter).toInt64());
        assert(pBasicEntry && "FindEntry: no Entry ?!");
        if (pBasicEntry->GetType() == eType && rText == m_xControl->get_text(rIter))
            return true;
        bValidIter = m_xControl->iter_next_sibling(rIter);
    }
    return false;
}

bool SbTreeListBox::IsEntryProtected(weld::TreeIter* pEntry)
{
    bool bProtected = false;
    if (pEntry && m_xControl->get_iter_depth(*pEntry) == 1)
    {
        EntryDescriptor aDesc(GetEntryDescriptor(pEntry));
        const ScriptDocument& rDocument( aDesc.GetDocument() );
        OSL_ENSURE( rDocument.isAlive(), "TreeListBox::IsEntryProtected: no document, or document is dead!" );
        if ( rDocument.isAlive() )
        {
            const OUString& aOULibName( aDesc.GetLibName() );
            Reference< script::XLibraryContainer > xModLibContainer( rDocument.getLibraryContainer( E_SCRIPTS ) );
            if ( xModLibContainer.is() && xModLibContainer->hasByName( aOULibName ) )
            {
                Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
                if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aOULibName ) && !xPasswd->isLibraryPasswordVerified( aOULibName ) )
                {
                    bProtected = true;
                }
            }
        }
    }
    return bProtected;
}

void SbTreeListBox::AddEntry(
    const OUString& rText,
    const OUString& rImage,
    weld::TreeIter* pParent,
    bool bChildrenOnDemand,
    std::unique_ptr<Entry>&& rUserData)
{
    OUString sId(OUString::number(reinterpret_cast<sal_uInt64>(rUserData.release())));
    m_xControl->insert(pParent, -1, rText, &sId, nullptr, nullptr, &rImage, bChildrenOnDemand);
}

void SbTreeListBox::SetEntryBitmaps(weld::TreeIter& rIter, const OUString& rImage)
{
    m_xControl->set_expander_image(rIter, rImage);
}

LibraryType SbTreeListBox::GetLibraryType() const
{
    LibraryType eType = LibraryType::All;
    if ( ( nMode & BrowseMode::Modules ) && !( nMode & BrowseMode::Dialogs ) )
        eType = LibraryType::Module;
    else if ( !( nMode & BrowseMode::Modules ) && ( nMode & BrowseMode::Dialogs ) )
        eType = LibraryType::Dialog;
    return eType;
}

OUString SbTreeListBox::GetRootEntryName( const ScriptDocument& rDocument, LibraryLocation eLocation ) const
{
    return rDocument.getTitle( eLocation, GetLibraryType() );
}

OUString SbTreeListBox::GetRootEntryBitmaps(const ScriptDocument& rDocument)
{
    OSL_ENSURE( rDocument.isValid(), "TreeListBox::GetRootEntryBitmaps: illegal document!" );
    if (!rDocument.isValid())
        return OUString();

    if ( rDocument.isDocument() )
    {
        OUString sFactoryURL;
        Reference<uno::XComponentContext> xContext( ::comphelper::getProcessComponentContext() );
        Reference< frame::XModuleManager2 > xModuleManager( frame::ModuleManager::create(xContext) );
        try
        {
            OUString sModule( xModuleManager->identify( rDocument.getDocument() ) );
            Reference< container::XNameAccess > xModuleConfig( xModuleManager, UNO_QUERY );
            if ( xModuleConfig.is() )
            {
                Sequence< beans::PropertyValue > aModuleDescr;
                xModuleConfig->getByName( sModule ) >>= aModuleDescr;
                sal_Int32 nCount = aModuleDescr.getLength();
                const beans::PropertyValue* pModuleDescr = aModuleDescr.getConstArray();
                for ( sal_Int32 i = 0; i < nCount; ++i )
                {
                    if ( pModuleDescr[ i ].Name == "ooSetupFactoryEmptyDocumentURL" )
                    {
                        pModuleDescr[ i ].Value >>= sFactoryURL;
                        break;
                    }
                }
            }
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION("basctl.basicide");
        }

        if ( !sFactoryURL.isEmpty() )
        {
            return SvFileInformationManager::GetFileImageId(INetURLObject(sFactoryURL));
        }
        else
        {
            // default icon
            return OUString(RID_BMP_DOCUMENT);
        }
    }
    return OUString(RID_BMP_INSTALLATION);
}

void SbTreeListBox::SetCurrentEntry (EntryDescriptor const & rDesc)
{
    bool bCurEntry = false;
    auto xCurIter = m_xControl->make_iterator();
    EntryDescriptor aDesc = rDesc;
    if ( aDesc.GetType() == OBJ_TYPE_UNKNOWN )
    {
        aDesc = EntryDescriptor(
            ScriptDocument::getApplicationScriptDocument(),
            LIBRARY_LOCATION_USER, "Standard",
            OUString(), ".", OBJ_TYPE_UNKNOWN
        );
    }
    ScriptDocument aDocument = aDesc.GetDocument();
    OSL_ENSURE( aDocument.isValid(), "TreeListBox::SetCurrentEntry: invalid document!" );
    LibraryLocation eLocation = aDesc.GetLocation();
    bool bRootEntry = FindRootEntry(aDocument, eLocation, *m_xIter);
    if (bRootEntry)
    {
        m_xControl->copy_iterator(*m_xIter, *xCurIter);
        bCurEntry = true;
        const OUString& aLibName( aDesc.GetLibName() );
        if ( !aLibName.isEmpty() )
        {
            m_xControl->expand_row(*m_xIter);
            auto xLibIter = m_xControl->make_iterator(m_xIter.get());
            bool bLibEntry = FindEntry(aLibName, OBJ_TYPE_LIBRARY, *xLibIter);
            if (bLibEntry)
            {
                m_xControl->copy_iterator(*xLibIter, *xCurIter);
                const OUString& aLibSubName( aDesc.GetLibSubName() );
                if( !aLibSubName.isEmpty() )
                {
                    m_xControl->expand_row(*xLibIter);
                    auto xSubLibIter = m_xControl->make_iterator(xLibIter.get());
                    bool bSubLibEntry = ImpFindEntry(*xSubLibIter, aLibSubName);
                    if (bSubLibEntry)
                    {
                        m_xControl->copy_iterator(*xSubLibIter, *xCurIter);
                    }
                }
                const OUString& aName( aDesc.GetName() );
                if ( !aName.isEmpty() )
                {
                    m_xControl->expand_row(*xCurIter);
                    EntryType eType = OBJ_TYPE_MODULE;
                    if ( aDesc.GetType() == OBJ_TYPE_DIALOG )
                        eType = OBJ_TYPE_DIALOG;
                    auto xEntryIter = m_xControl->make_iterator(xCurIter.get());
                    bool bEntry = FindEntry(aName, eType, *xEntryIter);
                    if (bEntry)
                    {
                        m_xControl->copy_iterator(*xEntryIter, *xCurIter);
                        const OUString& aMethodName( aDesc.GetMethodName() );
                        if (!aMethodName.isEmpty())
                        {
                            m_xControl->expand_row(*xCurIter);
                            auto xSubEntryIter = m_xControl->make_iterator(xCurIter.get());
                            bool bSubEntry = FindEntry(aMethodName, OBJ_TYPE_METHOD, *xSubEntryIter);
                            if (bSubEntry)
                            {
                                m_xControl->copy_iterator(*xSubEntryIter, *xCurIter);
                            }
                            else
                            {
                                m_xControl->copy_iterator(*xCurIter, *xSubEntryIter);
                                if (m_xControl->iter_children(*xSubEntryIter))
                                    m_xControl->copy_iterator(*xSubEntryIter, *xCurIter);
                            }
                        }
                    }
                    else
                    {
                        auto xSubEntryIter = m_xControl->make_iterator(xCurIter.get());
                        if (m_xControl->iter_children(*xSubEntryIter))
                            m_xControl->copy_iterator(*xSubEntryIter, *xCurIter);
                    }
                }
            }
            else
            {
                auto xSubLibIter = m_xControl->make_iterator(m_xIter.get());
                if (m_xControl->iter_children(*xSubLibIter))
                    m_xControl->copy_iterator(*xLibIter, *xCurIter);
            }
        }
    }
    else
    {
        bCurEntry = m_xControl->get_iter_first(*xCurIter);
    }

    if (!bCurEntry)
        return;

    m_xControl->set_cursor(*xCurIter);
}

IMPL_LINK_NOARG(SbTreeListBox, OpenCurrentHdl, weld::TreeView&, void)
{
    bool bValidIter = m_xControl->get_cursor(m_xIter.get());
    if (!bValidIter)
        return;
    EntryDescriptor aDesc = GetEntryDescriptor(m_xIter.get());
    switch (aDesc.GetType())
    {
        case OBJ_TYPE_METHOD:
        case OBJ_TYPE_MODULE:
        case OBJ_TYPE_DIALOG:
            if (SfxDispatcher* pDispatcher = GetDispatcher())
            {
                SbxItem aSbxItem(
                    SID_BASICIDE_ARG_SBX, aDesc.GetDocument(),
                    aDesc.GetLibName(), aDesc.GetName(), aDesc.GetMethodName(),
                    ConvertType(aDesc.GetType())
                );
                pDispatcher->ExecuteList(
                    SID_BASICIDE_SHOWSBX, SfxCallMode::SYNCHRON,
                    { &aSbxItem }
                );
                return;
            }
            break;

        default:
            m_xControl->expand_row(*m_xIter);
            break;
    }
}

} // namespace basctl

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basctl/source/basicide/bastype3.cxx b/basctl/source/basicide/bastype3.cxx
index c4ce7d8..d891994 100644
--- a/basctl/source/basicide/bastype3.cxx
+++ b/basctl/source/basicide/bastype3.cxx
@@ -129,6 +129,93 @@ void TreeListBox::RequestingChildren( SvTreeListEntry* pEntry )
    }
}

IMPL_LINK(SbTreeListBox, RequestingChildrenHdl, weld::TreeIter&, rEntry, bool)
{
    EntryDescriptor aDesc = GetEntryDescriptor(&rEntry);
    const ScriptDocument& aDocument = aDesc.GetDocument();
    OSL_ENSURE( aDocument.isAlive(), "basctl::TreeListBox::RequestingChildren: invalid document!" );
    if (!aDocument.isAlive())
        return false;

    LibraryLocation eLocation = aDesc.GetLocation();
    EntryType eType = aDesc.GetType();

    if ( eType == OBJ_TYPE_DOCUMENT )
    {
        ImpCreateLibEntries( rEntry, aDocument, eLocation );
    }
    else if ( eType == OBJ_TYPE_LIBRARY )
    {
        const OUString& aOULibName( aDesc.GetLibName() );

        // check password
        bool bOK = true;
        Reference< script::XLibraryContainer > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ) );
        if ( xModLibContainer.is() && xModLibContainer->hasByName( aOULibName ) )
        {
            Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
            if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aOULibName ) && !xPasswd->isLibraryPasswordVerified( aOULibName ) )
            {
                OUString aPassword;
                bOK = QueryPassword( xModLibContainer, aOULibName, aPassword );
            }
        }

        if ( bOK )
        {
            // load module library
            bool bModLibLoaded = false;
            if ( xModLibContainer.is() && xModLibContainer->hasByName( aOULibName ) )
            {
                if ( !xModLibContainer->isLibraryLoaded( aOULibName ) )
                {
                    weld::WaitObject aWait(m_pTopLevel);
                    xModLibContainer->loadLibrary( aOULibName );
                }
                bModLibLoaded = xModLibContainer->isLibraryLoaded( aOULibName );
            }

            // load dialog library
            bool bDlgLibLoaded = false;
            Reference< script::XLibraryContainer > xDlgLibContainer( aDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
            if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aOULibName ) )
            {
                if ( !xDlgLibContainer->isLibraryLoaded( aOULibName ) )
                {
                    weld::WaitObject aWait(m_pTopLevel);
                    xDlgLibContainer->loadLibrary( aOULibName );
                }
                bDlgLibLoaded = xDlgLibContainer->isLibraryLoaded( aOULibName );
            }

            if ( bModLibLoaded || bDlgLibLoaded )
            {
                // create the sub entries
                ImpCreateLibSubEntries( rEntry, aDocument, aOULibName );

                // exchange image
                const bool bDlgMode = (nMode & BrowseMode::Dialogs) && !(nMode & BrowseMode::Modules);
                OUString aImage(bDlgMode ? OUStringLiteral(RID_BMP_DLGLIB) : OUStringLiteral(RID_BMP_MODLIB));
                SetEntryBitmaps(rEntry, aImage);
            }
            else
            {
                OSL_FAIL( "basctl::TreeListBox::RequestingChildren: Error loading library!" );
            }
        }
    }
    else if ( eType == OBJ_TYPE_DOCUMENT_OBJECTS
            || eType == OBJ_TYPE_USERFORMS
            || eType == OBJ_TYPE_NORMAL_MODULES
            || eType == OBJ_TYPE_CLASS_MODULES )
    {
        const OUString& aLibName( aDesc.GetLibName() );
        ImpCreateLibSubSubEntriesInVBAMode( rEntry, aDocument, aLibName );
    }

    return true;
}

void TreeListBox::ExpandedHdl()
{
    SvTreeListEntry* pEntry = GetHdlEntry();
@@ -157,6 +244,19 @@ void TreeListBox::ScanAllEntries()
    }
}

void SbTreeListBox::ScanAllEntries()
{
    ScanEntry( ScriptDocument::getApplicationScriptDocument(), LIBRARY_LOCATION_USER );
    ScanEntry( ScriptDocument::getApplicationScriptDocument(), LIBRARY_LOCATION_SHARE );

    ScriptDocuments aDocuments( ScriptDocument::getAllScriptDocuments( ScriptDocument::DocumentsSorted ) );
    for (auto const& doc : aDocuments)
    {
        if ( doc.isAlive() )
            ScanEntry(doc, LIBRARY_LOCATION_DOCUMENT);
    }
}

SbxVariable* TreeListBox::FindVariable( SvTreeListEntry* pEntry )
{
    if ( !pEntry )
@@ -250,6 +350,100 @@ SbxVariable* TreeListBox::FindVariable( SvTreeListEntry* pEntry )
    return pVar;
}

SbxVariable* SbTreeListBox::FindVariable(weld::TreeIter* pEntry)
{
    if ( !pEntry )
        return nullptr;

    ScriptDocument aDocument( ScriptDocument::getApplicationScriptDocument() );
    std::unique_ptr<weld::TreeIter> xIter(m_xControl->make_iterator(pEntry));
    std::vector<std::pair<Entry*, OUString>> aEntries;
    bool bValidIter = true;
    do
    {
        sal_uInt16 nDepth = m_xControl->get_iter_depth(*xIter);
        Entry* pBE = reinterpret_cast<Entry*>(m_xControl->get_id(*xIter).toInt64());
        switch (nDepth)
        {
            case 4:
            case 3:
            case 2:
            case 1:
            {
                aEntries.emplace_back(pBE, m_xControl->get_text(*xIter));
            }
            break;
            case 0:
            {
                aDocument = static_cast<DocumentEntry*>(pBE)->GetDocument();
            }
            break;
        }
        bValidIter = m_xControl->iter_parent(*xIter);
    } while (bValidIter);

    SbxVariable* pVar = nullptr;
    if (!aEntries.empty())
    {
        std::reverse(aEntries.begin(), aEntries.end());
        bool bDocumentObjects = false;
        for (auto& pair : aEntries)
        {
            Entry* pBE = pair.first;
            assert(pBE && "No data found in entry!");
            OUString aName(pair.second);

            switch ( pBE->GetType() )
            {
            case OBJ_TYPE_LIBRARY:
                if (BasicManager* pBasMgr = aDocument.getBasicManager())
                    pVar = pBasMgr->GetLib( aName );
                break;
            case OBJ_TYPE_MODULE:
                DBG_ASSERT(dynamic_cast<StarBASIC*>(pVar), "FindVariable: invalid Basic");
                if(!pVar)
                {
                    break;
                }
                // extract the module name from the string like "Sheet1 (Example1)"
                if( bDocumentObjects )
                {
                    sal_Int32 nIndex = 0;
                    aName = aName.getToken( 0, ' ', nIndex );
                }
                pVar = static_cast<StarBASIC*>(pVar)->FindModule( aName );
                break;
            case OBJ_TYPE_METHOD:
                DBG_ASSERT(dynamic_cast<SbxObject*>(pVar), "FindVariable: invalid module/object");
                if(!pVar)
                {
                    break;
                }
                pVar = static_cast<SbxObject*>(pVar)->GetMethods()->Find(aName, SbxClassType::Method);
                break;
            case OBJ_TYPE_DIALOG:
                // sbx dialogs removed
                break;
            case OBJ_TYPE_DOCUMENT_OBJECTS:
                bDocumentObjects = true;
                SAL_FALLTHROUGH;
            case OBJ_TYPE_USERFORMS:
            case OBJ_TYPE_NORMAL_MODULES:
            case OBJ_TYPE_CLASS_MODULES:
                // skip, to find the child entry.
                continue;
            default:
                OSL_FAIL( "FindVariable: unknown type" );
                pVar = nullptr;
                break;
            }
            if ( !pVar )
                break;
        }
    }
    return pVar;
}

EntryDescriptor TreeListBox::GetEntryDescriptor( SvTreeListEntry* pEntry )
{
    ScriptDocument aDocument( ScriptDocument::getApplicationScriptDocument() );
@@ -351,6 +545,111 @@ EntryDescriptor TreeListBox::GetEntryDescriptor( SvTreeListEntry* pEntry )
    return EntryDescriptor( aDocument, eLocation, aLibName, aLibSubName, aName, aMethodName, eType );
}

EntryDescriptor SbTreeListBox::GetEntryDescriptor(weld::TreeIter* pEntry)
{
    ScriptDocument aDocument( ScriptDocument::getApplicationScriptDocument() );
    LibraryLocation eLocation = LIBRARY_LOCATION_UNKNOWN;
    OUString aLibName;
    OUString aLibSubName;
    OUString aName;
    OUString aMethodName;
    EntryType eType = OBJ_TYPE_UNKNOWN;

    if ( !pEntry )
        return EntryDescriptor( aDocument, eLocation, aLibName, aLibSubName, aName, aMethodName, eType );

    std::vector<std::pair<Entry*, OUString>> aEntries;

    m_xControl->get_text(*pEntry);
    std::unique_ptr<weld::TreeIter> xIter(m_xControl->make_iterator(pEntry));
    m_xControl->get_text(*xIter);
    bool bValidIter = true;
    do
    {
        sal_uInt16 nDepth = m_xControl->get_iter_depth(*xIter);
        Entry* pBE = reinterpret_cast<Entry*>(m_xControl->get_id(*xIter).toInt64());
        switch (nDepth)
        {
            case 4:
            case 3:
            case 2:
            case 1:
            {
                aEntries.emplace_back(pBE, m_xControl->get_text(*xIter));
            }
            break;
            case 0:
            {
                if (DocumentEntry* pDocumentEntry = static_cast<DocumentEntry*>(pBE))
                {
                    aDocument = pDocumentEntry->GetDocument();
                    eLocation = pDocumentEntry->GetLocation();
                    eType = OBJ_TYPE_DOCUMENT;
                }
            }
            break;
        }
        bValidIter = m_xControl->iter_parent(*xIter);
    } while (bValidIter);

    if ( !aEntries.empty() )
    {
        for (auto& pair : aEntries)
        {
            Entry* pBE = pair.first;
            assert(pBE && "No data found in entry!");

            switch ( pBE->GetType() )
            {
                case OBJ_TYPE_LIBRARY:
                {
                    aLibName = pair.second;
                    eType = pBE->GetType();
                }
                break;
                case OBJ_TYPE_MODULE:
                {
                    aName = pair.second;
                    eType = pBE->GetType();
                }
                break;
                case OBJ_TYPE_METHOD:
                {
                    aMethodName = pair.second;
                    eType = pBE->GetType();
                }
                break;
                case OBJ_TYPE_DIALOG:
                {
                    aName = pair.second;
                    eType = pBE->GetType();
                }
                break;
                case OBJ_TYPE_DOCUMENT_OBJECTS:
                case OBJ_TYPE_USERFORMS:
                case OBJ_TYPE_NORMAL_MODULES:
                case OBJ_TYPE_CLASS_MODULES:
                {
                    aLibSubName = pair.second;
                    eType = pBE->GetType();
                }
                break;
                default:
                {
                    OSL_FAIL( "GetEntryDescriptor: unknown type" );
                    eType = OBJ_TYPE_UNKNOWN;
                }
                break;
            }

            if ( eType == OBJ_TYPE_UNKNOWN )
                break;
        }
    }

    return EntryDescriptor( aDocument, eLocation, aLibName, aLibSubName, aName, aMethodName, eType );
}

ItemType TreeListBox::ConvertType (EntryType eType)
{
    switch (eType)
@@ -365,6 +664,20 @@ ItemType TreeListBox::ConvertType (EntryType eType)
    }
}

ItemType SbTreeListBox::ConvertType (EntryType eType)
{
    switch (eType)
    {
        case OBJ_TYPE_DOCUMENT:  return TYPE_SHELL;
        case OBJ_TYPE_LIBRARY:   return TYPE_LIBRARY;
        case OBJ_TYPE_MODULE:    return TYPE_MODULE;
        case OBJ_TYPE_DIALOG:    return TYPE_DIALOG;
        case OBJ_TYPE_METHOD:    return TYPE_METHOD;
        default:
            return static_cast<ItemType>(OBJ_TYPE_UNKNOWN);
    }
}

bool TreeListBox::IsValidEntry( SvTreeListEntry* pEntry )
{
    bool bIsValid = false;
@@ -420,11 +733,71 @@ bool TreeListBox::IsValidEntry( SvTreeListEntry* pEntry )
    return bIsValid;
}

bool SbTreeListBox::IsValidEntry(weld::TreeIter& rEntry)
{
    bool bIsValid = false;

    EntryDescriptor aDesc(GetEntryDescriptor(&rEntry));
    const ScriptDocument& aDocument( aDesc.GetDocument() );
    LibraryLocation eLocation( aDesc.GetLocation() );
    const OUString& aLibName( aDesc.GetLibName() );
    const OUString& aName( aDesc.GetName() );
    const OUString& aMethodName( aDesc.GetMethodName() );
    EntryType eType( aDesc.GetType() );

    switch ( eType )
    {
        case OBJ_TYPE_DOCUMENT:
        {
            bIsValid = aDocument.isAlive()
                && (aDocument.isApplication()
                    || GetRootEntryName(aDocument, eLocation) == m_xControl->get_text(rEntry));
        }
        break;
        case OBJ_TYPE_LIBRARY:
        {
            bIsValid = aDocument.hasLibrary( E_SCRIPTS, aLibName ) || aDocument.hasLibrary( E_DIALOGS, aLibName );
        }
        break;
        case OBJ_TYPE_MODULE:
        {
            bIsValid = aDocument.hasModule( aLibName, aName );
        }
        break;
        case OBJ_TYPE_DIALOG:
        {
            bIsValid = aDocument.hasDialog( aLibName, aName );
        }
        break;
        case OBJ_TYPE_METHOD:
        {
            bIsValid = HasMethod( aDocument, aLibName, aName, aMethodName );
        }
        break;
        case OBJ_TYPE_DOCUMENT_OBJECTS:
        case OBJ_TYPE_USERFORMS:
        case OBJ_TYPE_NORMAL_MODULES:
        case OBJ_TYPE_CLASS_MODULES:
        {
            bIsValid = true;
        }
        break;
        default: ;
    }

    return bIsValid;
}

SbModule* TreeListBox::FindModule( SvTreeListEntry* pEntry )
{
    return dynamic_cast<SbModule*>(FindVariable(pEntry));
}

SbModule* SbTreeListBox::FindModule(weld::TreeIter* pEntry)
{
    return dynamic_cast<SbModule*>(FindVariable(pEntry));
}

SvTreeListEntry* TreeListBox::FindRootEntry( const ScriptDocument& rDocument, LibraryLocation eLocation )
{
    OSL_ENSURE( rDocument.isValid(), "basctl::TreeListBox::FindRootEntry: invalid document!" );
@@ -441,6 +814,20 @@ SvTreeListEntry* TreeListBox::FindRootEntry( const ScriptDocument& rDocument, Li
    return nullptr;
}

bool SbTreeListBox::FindRootEntry( const ScriptDocument& rDocument, LibraryLocation eLocation, weld::TreeIter& rIter)
{
    OSL_ENSURE( rDocument.isValid(), "basctl::TreeListBox::FindRootEntry: invalid document!" );
    bool bValidIter = m_xControl->get_iter_first(rIter);
    while (bValidIter)
    {
        DocumentEntry* pBDEntry = reinterpret_cast<DocumentEntry*>(m_xControl->get_id(rIter).toInt64());
        if (pBDEntry && pBDEntry->GetDocument() == rDocument && pBDEntry->GetLocation() == eLocation)
            return true;
        bValidIter = m_xControl->iter_next_sibling(rIter);
    }
    return false;
}

OUString CreateMgrAndLibStr( const OUString& rMgrName, const OUString& rLibName )
{
    return "[" + rMgrName + "]." + rLibName;
diff --git a/basctl/source/basicide/macrodlg.cxx b/basctl/source/basicide/macrodlg.cxx
index 25f94c5..1826275 100644
--- a/basctl/source/basicide/macrodlg.cxx
+++ b/basctl/source/basicide/macrodlg.cxx
@@ -45,108 +45,85 @@ using std::map;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;

MacroChooser::MacroChooser( vcl::Window* pParnt, const Reference< frame::XFrame >& xDocFrame, bool bCreateEntries )
    : SfxModalDialog(pParnt, "BasicMacroDialog", "modules/BasicIDE/ui/basicmacrodialog.ui")
MacroChooser::MacroChooser(weld::Window* pParnt, const Reference< frame::XFrame >& xDocFrame, bool bCreateEntries)
    : SfxDialogController(pParnt, "modules/BasicIDE/ui/basicmacrodialog.ui", "BasicMacroDialog")
    , m_xDocumentFrame(xDocFrame)
    , bNewDelIsDel(true)
    // the Sfx doesn't ask the BasicManager whether modified or not
    // => start saving in case of a change without a into the BasicIDE.
    , bForceStoreBasic(false)
    , nMode(All)
    , m_xMacroNameEdit(m_xBuilder->weld_entry("macronameedit"))
    , m_xMacroFromTxT(m_xBuilder->weld_label("macrofromft"))
    , m_xMacrosSaveInTxt(m_xBuilder->weld_label("macrotoft"))
    , m_xBasicBox(new SbTreeListBox(m_xBuilder->weld_tree_view("libraries"), m_xDialog.get()))
    , m_xBasicBoxIter(m_xBasicBox->make_iterator())
    , m_xMacrosInTxt(m_xBuilder->weld_label("existingmacrosft"))
    , m_xMacroBox(m_xBuilder->weld_tree_view("macros"))
    , m_xMacroBoxIter(m_xMacroBox->make_iterator())
    , m_xRunButton(m_xBuilder->weld_button("ok"))
    , m_xCloseButton(m_xBuilder->weld_button("close"))
    , m_xAssignButton(m_xBuilder->weld_button("assign"))
    , m_xEditButton(m_xBuilder->weld_button("edit"))
    , m_xDelButton(m_xBuilder->weld_button("delete"))
    , m_xNewButton(m_xBuilder->weld_button("new"))
    , m_xOrganizeButton(m_xBuilder->weld_button("organize"))
    , m_xNewLibButton(m_xBuilder->weld_button("newlibrary"))
    , m_xNewModButton(m_xBuilder->weld_button("newmodule"))
{
    get(m_pMacroNameEdit, "macronameedit");
    get(m_pMacroFromTxT, "macrofromft");
    get(m_pMacrosSaveInTxt, "macrotoft");
    get(m_pBasicBox, "libraries");
    get(m_pMacrosInTxt, "existingmacrosft");
    m_aMacrosInTxtBaseStr = m_pMacrosInTxt->GetText();
    get(m_pMacroBox, "macros");
    get(m_pRunButton, "run");
    get(m_pCloseButton, "close");
    get(m_pAssignButton, "assign");
    get(m_pEditButton, "edit");
    get(m_pDelButton, "delete");
    get(m_pOrganizeButton, "organize");
    get(m_pNewLibButton, "newlibrary");
    get(m_pNewModButton, "newmodule");
    m_xBasicBox->set_size_request(m_xBasicBox->get_approximate_digit_width() * 30, m_xBasicBox->get_height_rows(18));
    m_xMacroBox->set_size_request(m_xMacroBox->get_approximate_digit_width() * 30, m_xMacroBox->get_height_rows(18));

    m_pMacroBox->SetSelectionMode( SelectionMode::Single );
    m_pMacroBox->SetHighlightRange(); // select over the whole width
    m_aMacrosInTxtBaseStr = m_xMacrosInTxt->get_label();

    m_pRunButton->SetClickHdl( LINK( this, MacroChooser, ButtonHdl ) );
    m_pCloseButton->SetClickHdl( LINK( this, MacroChooser, ButtonHdl ) );
    m_pAssignButton->SetClickHdl( LINK( this, MacroChooser, ButtonHdl ) );
    m_pEditButton->SetClickHdl( LINK( this, MacroChooser, ButtonHdl ) );
    m_pDelButton->SetClickHdl( LINK( this, MacroChooser, ButtonHdl ) );
    m_pOrganizeButton->SetClickHdl( LINK( this, MacroChooser, ButtonHdl ) );
    m_xRunButton->connect_clicked( LINK( this, MacroChooser, ButtonHdl ) );
    m_xCloseButton->connect_clicked( LINK( this, MacroChooser, ButtonHdl ) );
    m_xAssignButton->connect_clicked( LINK( this, MacroChooser, ButtonHdl ) );
    m_xEditButton->connect_clicked( LINK( this, MacroChooser, ButtonHdl ) );
    m_xDelButton->connect_clicked( LINK( this, MacroChooser, ButtonHdl ) );
    m_xNewButton->connect_clicked( LINK( this, MacroChooser, ButtonHdl ) );
    m_xOrganizeButton->connect_clicked( LINK( this, MacroChooser, ButtonHdl ) );

    // Buttons only for MacroChooser::Recording
    m_pNewLibButton->SetClickHdl( LINK( this, MacroChooser, ButtonHdl ) );
    m_pNewModButton->SetClickHdl( LINK( this, MacroChooser, ButtonHdl ) );
    m_pNewLibButton->Hide();       // default
    m_pNewModButton->Hide();       // default
    m_pMacrosSaveInTxt->Hide();    // default
    m_xNewLibButton->connect_clicked( LINK( this, MacroChooser, ButtonHdl ) );
    m_xNewModButton->connect_clicked( LINK( this, MacroChooser, ButtonHdl ) );
    m_xNewLibButton->hide();       // default
    m_xNewModButton->hide();       // default
    m_xMacrosSaveInTxt->hide();    // default

    m_pMacrosInTxt->SetStyle( WB_NOMULTILINE | WB_PATHELLIPSIS );
    m_xMacroNameEdit->connect_changed( LINK( this, MacroChooser, EditModifyHdl ) );

    m_pMacroNameEdit->SetModifyHdl( LINK( this, MacroChooser, EditModifyHdl ) );
    m_xBasicBox->connect_changed( LINK( this, MacroChooser, BasicSelectHdl ) );

    m_pBasicBox->SetSelectHdl( LINK( this, MacroChooser, BasicSelectHdl ) );
    m_xMacroBox->connect_row_activated( LINK( this, MacroChooser, MacroDoubleClickHdl ) );
    m_xMacroBox->connect_changed( LINK( this, MacroChooser, MacroSelectHdl ) );

    m_pMacroBox->SetDoubleClickHdl( LINK( this, MacroChooser, MacroDoubleClickHdl ) );
    m_pMacroBox->SetSelectHdl( LINK( this, MacroChooser, MacroSelectHdl ) );

    m_pBasicBox->SetMode( BrowseMode::Modules );
    m_pBasicBox->SetStyle( WB_TABSTOP | WB_BORDER |
                        WB_HASLINES | WB_HASLINESATROOT |
                        WB_HASBUTTONS | WB_HASBUTTONSATROOT |
                        WB_HSCROLL );
    m_xBasicBox->SetMode( BrowseMode::Modules );

    if (SfxDispatcher* pDispatcher = GetDispatcher())
        pDispatcher->Execute( SID_BASICIDE_STOREALLMODULESOURCES );

    if ( bCreateEntries )
        m_pBasicBox->ScanAllEntries();
    if (bCreateEntries)
        m_xBasicBox->ScanAllEntries();
}

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

void MacroChooser::dispose()
{
    if ( bForceStoreBasic )
    if (bForceStoreBasic)
    {
        SfxGetpApp()->SaveBasicAndDialogContainer();
        bForceStoreBasic = false;
    }
    m_pMacroNameEdit.clear();
    m_pMacroFromTxT.clear();
    m_pMacrosSaveInTxt.clear();
    m_pBasicBox.clear();
    m_pMacrosInTxt.clear();
    m_pMacroBox.clear();
    m_pRunButton.clear();
    m_pCloseButton.clear();
    m_pAssignButton.clear();
    m_pEditButton.clear();
    m_pDelButton.clear();
    m_pOrganizeButton.clear();
    m_pNewLibButton.clear();
    m_pNewModButton.clear();
    SfxModalDialog::dispose();
}

void MacroChooser::StoreMacroDescription()
{
    EntryDescriptor aDesc = m_pBasicBox->GetEntryDescriptor(m_pBasicBox->FirstSelected());
    m_xBasicBox->get_selected(m_xBasicBoxIter.get());
    EntryDescriptor aDesc = m_xBasicBox->GetEntryDescriptor(m_xBasicBoxIter.get());
    OUString aMethodName;
    SvTreeListEntry* pEntry = m_pMacroBox->FirstSelected();
    if ( pEntry )
        aMethodName = m_pMacroBox->GetEntryText( pEntry );
    if (m_xMacroBox->get_selected(m_xMacroBoxIter.get()))
        aMethodName = m_xMacroBox->get_text(*m_xMacroBoxIter);
    else
        aMethodName = m_pMacroNameEdit->GetText();
        aMethodName = m_xMacroNameEdit->get_text();
    if ( !aMethodName.isEmpty() )
    {
        aDesc.SetMethodName( aMethodName );
@@ -171,68 +148,57 @@ void MacroChooser::RestoreMacroDescription()
            aDesc = pData->GetLastEntryDescriptor();
    }

    m_pBasicBox->SetCurrentEntry( aDesc );
    m_xBasicBox->SetCurrentEntry( aDesc );

    OUString aLastMacro( aDesc.GetMethodName() );
    if ( !aLastMacro.isEmpty() )
    if (!aLastMacro.isEmpty())
    {
        // find entry in macro box
        SvTreeListEntry* pEntry = nullptr;
        sal_uLong nPos = 0;
        SvTreeListEntry* pE = m_pMacroBox->GetEntry( nPos );
        while ( pE )
        {
            if ( m_pMacroBox->GetEntryText( pE ) == aLastMacro )
            {
                pEntry = pE;
                break;
            }
            pE = m_pMacroBox->GetEntry( ++nPos );
        }

        if ( pEntry )
            m_pMacroBox->SetCurEntry( pEntry );
        auto nIndex = m_xMacroBox->find_text(aLastMacro);
        if (nIndex != -1)
            m_xMacroBox->select(nIndex);
        else
        {
            m_pMacroNameEdit->SetText( aLastMacro );
            m_pMacroNameEdit->SetSelection( Selection( 0, 0 ) );
            m_xMacroNameEdit->set_text(aLastMacro);
            m_xMacroNameEdit->select_region(0, 0);
        }
    }
}

short MacroChooser::Execute()
short MacroChooser::run()
{
    RestoreMacroDescription();
    m_pRunButton->GrabFocus();
    m_xRunButton->grab_focus();

    // #104198 Check if "wrong" document is active
    SvTreeListEntry* pSelectedEntry = m_pBasicBox->GetCurEntry();
    EntryDescriptor aDesc( m_pBasicBox->GetEntryDescriptor( pSelectedEntry ) );
    const ScriptDocument& rSelectedDoc( aDesc.GetDocument() );
    bool bSelectedEntry = m_xBasicBox->get_cursor(m_xBasicBoxIter.get());
    EntryDescriptor aDesc(m_xBasicBox->GetEntryDescriptor(bSelectedEntry ? m_xBasicBoxIter.get() : nullptr));
    const ScriptDocument& rSelectedDoc(aDesc.GetDocument());

    // App Basic is always ok, so only check if shell was found
    if( rSelectedDoc.isDocument() && !rSelectedDoc.isActive() )
    {
        // Search for the right entry
        sal_uLong nRootPos = 0;
        SvTreeListEntry* pRootEntry = m_pBasicBox->GetEntry( nRootPos );
        while( pRootEntry )
        bool bValidIter = m_xBasicBox->get_iter_first(*m_xBasicBoxIter);
        while (bValidIter)
        {
            EntryDescriptor aCmpDesc( m_pBasicBox->GetEntryDescriptor( pRootEntry ) );
            EntryDescriptor aCmpDesc(m_xBasicBox->GetEntryDescriptor(m_xBasicBoxIter.get()));
            const ScriptDocument& rCmpDoc( aCmpDesc.GetDocument() );
            if ( rCmpDoc.isDocument() && rCmpDoc.isActive() )
            if (rCmpDoc.isDocument() && rCmpDoc.isActive())
            {
                SvTreeListEntry* pEntry = pRootEntry;
                SvTreeListEntry* pLastValid = pEntry;
                while ( pEntry )
                std::unique_ptr<weld::TreeIter> xEntry(m_xBasicBox->make_iterator());
                m_xBasicBox->copy_iterator(*m_xBasicBoxIter, *xEntry);
                std::unique_ptr<weld::TreeIter> xLastValid(m_xBasicBox->make_iterator());
                bool bValidEntryIter = true;
                do
                {
                    pLastValid = pEntry;
                    pEntry = m_pBasicBox->FirstChild( pEntry );
                    m_xBasicBox->copy_iterator(*xEntry, *xLastValid);
                    bValidEntryIter = m_xBasicBox->iter_children(*xEntry);
                }
                if( pLastValid )
                    m_pBasicBox->SetCurEntry( pLastValid );
                while (bValidEntryIter);
                m_xBasicBox->set_cursor(*xLastValid);
            }
            pRootEntry = m_pBasicBox->GetEntry( ++nRootPos );
            bValidIter = m_xBasicBox->iter_next_sibling(*m_xBasicBoxIter);
        }
    }

@@ -240,36 +206,35 @@ short MacroChooser::Execute()
    UpdateFields();

    if ( StarBASIC::IsRunning() )
        m_pCloseButton->GrabFocus();
        m_xCloseButton->grab_focus();

    return ModalDialog::Execute();
    return SfxDialogController::run();
}

void MacroChooser::EnableButton( Button& rButton, bool bEnable )
void MacroChooser::EnableButton(weld::Button& rButton, bool bEnable)
{
    if ( bEnable )
    {
        if (nMode == ChooseOnly || nMode == Recording)
            rButton.Enable(&rButton == m_pRunButton);
            rButton.set_sensitive(&rButton == m_xRunButton.get());
        else
            rButton.Enable();
            rButton.set_sensitive(true);
    }
    else
        rButton.Disable();
        rButton.set_sensitive(false);
}


SbMethod* MacroChooser::GetMacro()
{
    SbMethod* pMethod = nullptr;
    SbModule* pModule = m_pBasicBox->FindModule( m_pBasicBox->GetCurEntry() );
    if ( pModule )
    m_xBasicBox->get_cursor(m_xBasicBoxIter.get());
    SbModule* pModule = m_xBasicBox->FindModule(m_xBasicBoxIter.get());
    if (pModule)
    {
        SvTreeListEntry* pEntry = m_pMacroBox->FirstSelected();
        if ( pEntry )
        if (m_xMacroBox->get_selected(m_xMacroBoxIter.get()))
        {
            OUString aMacroName( m_pMacroBox->GetEntryText( pEntry ) );
            pMethod = pModule->FindMethod( aMacroName, SbxClassType::Method );
            OUString aMacroName(m_xMacroBox->get_text(*m_xMacroBoxIter));
            pMethod = pModule->FindMethod(aMacroName, SbxClassType::Method);
        }
    }
    return pMethod;
@@ -280,7 +245,7 @@ void MacroChooser::DeleteMacro()
{
    SbMethod* pMethod = GetMacro();
    DBG_ASSERT( pMethod, "DeleteMacro: No Macro !" );
    if (pMethod && QueryDelMacro(pMethod->GetName(), GetFrameWeld()))
    if (pMethod && QueryDelMacro(pMethod->GetName(), m_xDialog.get()))
    {
        if (SfxDispatcher* pDispatcher = GetDispatcher())
            pDispatcher->Execute( SID_BASICIDE_STOREALLMODULESOURCES );
@@ -312,9 +277,9 @@ void MacroChooser::DeleteMacro()
        OUString aModName = pModule->GetName();
        OSL_VERIFY( aDocument.updateModule( aLibName, aModName, aSource ) );

        SvTreeListEntry* pEntry = m_pMacroBox->FirstSelected();
        DBG_ASSERT( pEntry, "DeleteMacro: Entry ?!" );
        m_pMacroBox->GetModel()->Remove( pEntry );
        bool bSelected = m_xMacroBox->get_selected(m_xMacroBoxIter.get());
        DBG_ASSERT(bSelected, "DeleteMacro: Entry ?!");
        m_xMacroBox->remove(*m_xMacroBoxIter);
        bForceStoreBasic = true;
    }
}
@@ -322,8 +287,8 @@ void MacroChooser::DeleteMacro()
SbMethod* MacroChooser::CreateMacro()
{
    SbMethod* pMethod = nullptr;
    SvTreeListEntry* pCurEntry = m_pBasicBox->GetCurEntry();
    EntryDescriptor aDesc = m_pBasicBox->GetEntryDescriptor(pCurEntry);
    m_xBasicBox->get_cursor(m_xBasicBoxIter.get());
    EntryDescriptor aDesc = m_xBasicBox->GetEntryDescriptor(m_xBasicBoxIter.get());
    const ScriptDocument& aDocument( aDesc.GetDocument() );
    OSL_ENSURE( aDocument.isAlive(), "MacroChooser::CreateMacro: no document!" );
    if ( !aDocument.isAlive() )
@@ -365,11 +330,11 @@ SbMethod* MacroChooser::CreateMacro()

        // Retain the desired macro name before the macro dialog box is forced to close
        // by opening the module name dialog window when no module exists in the current library.
        OUString aSubName = m_pMacroNameEdit->GetText();
        OUString aSubName = m_xMacroNameEdit->get_text();

        if ( !pModule )
        {
            pModule = createModImpl(GetFrameWeld(), aDocument, *m_pBasicBox, aLibName, aModName, false);
            pModule = createModImpl(m_xDialog.get(), aDocument, *m_xBasicBox, aLibName, aModName, false);
        }

        DBG_ASSERT( !pModule || !pModule->FindMethod( aSubName, SbxClassType::Method ), "Macro exists already!" );
@@ -379,28 +344,30 @@ SbMethod* MacroChooser::CreateMacro()
    return pMethod;
}

void MacroChooser::SaveSetCurEntry( SvTreeListBox& rBox, SvTreeListEntry* pEntry )
void MacroChooser::SaveSetCurEntry(weld::TreeView& rBox, weld::TreeIter& rEntry)
{
    // the edit would be killed by the highlight otherwise:

    OUString aSaveText( m_pMacroNameEdit->GetText() );
    Selection aCurSel( m_pMacroNameEdit->GetSelection() );
    OUString aSaveText(m_xMacroNameEdit->get_text());
    int nStartPos, nEndPos;
    m_xMacroNameEdit->get_selection_bounds(nStartPos, nEndPos);

    rBox.SetCurEntry( pEntry );
    m_pMacroNameEdit->SetText( aSaveText );
    m_pMacroNameEdit->SetSelection( aCurSel );
    rBox.set_cursor(rEntry);

    m_xMacroNameEdit->set_text(aSaveText);
    m_xMacroNameEdit->select_region(nStartPos, nEndPos);
}

void MacroChooser::CheckButtons()
{
    SvTreeListEntry* pCurEntry = m_pBasicBox->GetCurEntry();
    EntryDescriptor aDesc = m_pBasicBox->GetEntryDescriptor(pCurEntry);
    SvTreeListEntry* pMacroEntry = m_pMacroBox->FirstSelected();
    const bool bCurEntry = m_xBasicBox->get_cursor(m_xBasicBoxIter.get());
    EntryDescriptor aDesc = m_xBasicBox->GetEntryDescriptor(bCurEntry ? m_xBasicBoxIter.get() : nullptr);
    const bool bMacroEntry = m_xMacroBox->get_selected(nullptr);
    SbMethod* pMethod = GetMacro();

    // check, if corresponding libraries are readonly
    bool bReadOnly = false;
    sal_uInt16 nDepth = pCurEntry ? m_pBasicBox->GetModel()->GetDepth( pCurEntry ) : 0;
    sal_uInt16 nDepth = bCurEntry ? m_xBasicBox->get_iter_depth(*m_xBasicBoxIter) : 0;
    if ( nDepth == 1 || nDepth == 2 )
    {
        const ScriptDocument& aDocument( aDesc.GetDocument() );
@@ -420,45 +387,52 @@ void MacroChooser::CheckButtons()
        bool bEnable = pMethod != nullptr;
        if (nMode != ChooseOnly && StarBASIC::IsRunning())
            bEnable = false;
        EnableButton(*m_pRunButton, bEnable);
        EnableButton(*m_xRunButton, bEnable);
    }

    // organising still possible?

    // Assign...
    EnableButton(*m_pAssignButton, pMethod != nullptr);
    EnableButton(*m_xAssignButton, pMethod != nullptr);

    // Edit...
    EnableButton(*m_pEditButton, pMacroEntry != nullptr);
    EnableButton(*m_xEditButton, bMacroEntry);

    // Organizer...
    EnableButton(*m_pOrganizeButton, !StarBASIC::IsRunning() && nMode == All);
    EnableButton(*m_xOrganizeButton, !StarBASIC::IsRunning() && nMode == All);

    // m_pDelButton->...
    bool bProtected = m_pBasicBox->IsEntryProtected( pCurEntry );
    // m_xDelButton/m_xNewButton ->...
    bool bProtected = bCurEntry && m_xBasicBox->IsEntryProtected(m_xBasicBoxIter.get());
    bool bShare = ( aDesc.GetLocation() == LIBRARY_LOCATION_SHARE );
    EnableButton(*m_pDelButton, !StarBASIC::IsRunning() && nMode == All && !bProtected && !bReadOnly && !bShare);
    bool bPrev = bNewDelIsDel;
    bNewDelIsDel = pMethod != nullptr;
    if (bPrev != bNewDelIsDel && nMode == All)
    bool bEnable = !StarBASIC::IsRunning() && nMode == All && !bProtected && !bReadOnly && !bShare;
    EnableButton(*m_xDelButton, bEnable);
    EnableButton(*m_xNewButton, bEnable);
    if (nMode == All)
    {
        OUString aBtnText( bNewDelIsDel ? IDEResId(RID_STR_BTNDEL) : IDEResId(RID_STR_BTNNEW) );
        m_pDelButton->SetText( aBtnText );
        if (pMethod)
        {
            m_xDelButton->show();
            m_xNewButton->hide();
        }
        else
        {
            m_xNewButton->show();
            m_xDelButton->hide();
        }
    }

    if (nMode == Recording)
    {
        // save button
        m_pRunButton->Enable(!bProtected && !bReadOnly && !bShare);
        m_xRunButton->set_sensitive(!bProtected && !bReadOnly && !bShare);
        // new library button
        m_pNewLibButton->Enable(!bShare);
        m_xNewLibButton->set_sensitive(!bShare);
        // new module button
        m_pNewModButton->Enable(!bProtected && !bReadOnly && !bShare);
        m_xNewModButton->set_sensitive(!bProtected && !bReadOnly && !bShare);
    }
}


IMPL_LINK_NOARG(MacroChooser, MacroDoubleClickHdl, SvTreeListBox*, bool)
IMPL_LINK_NOARG(MacroChooser, MacroDoubleClickHdl, weld::TreeView&, void)
{
    SbMethod* pMethod = GetMacro();
    SbModule* pModule = pMethod ? pMethod->GetModule() : nullptr;
@@ -468,51 +442,36 @@ IMPL_LINK_NOARG(MacroChooser, MacroDoubleClickHdl, SvTreeListBox*, bool)
    if (aDocument.isDocument() && !aDocument.allowMacros())
    {
        std::unique_ptr<weld::MessageDialog> xError(
            Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Warning,
            Application::CreateMessageDialog(m_xDialog.get(), VclMessageType::Warning,
                                             VclButtonsType::Ok, IDEResId(RID_STR_CANNOTRUNMACRO)));
        xError->run();
        return false;
        return;
    }

    StoreMacroDescription();
    if (nMode == Recording)
    {
        if (pMethod && !QueryReplaceMacro(pMethod->GetName(), GetFrameWeld()))
            return false;
        if (pMethod && !QueryReplaceMacro(pMethod->GetName(), m_xDialog.get()))
            return;
    }

    EndDialog(Macro_OkRun);
    return false;
    m_xDialog->response(Macro_OkRun);
}

IMPL_LINK( MacroChooser, MacroSelectHdl, SvTreeListBox *, pBox, void )
IMPL_LINK_NOARG(MacroChooser, MacroSelectHdl, weld::TreeView&, void)
{
    // Is also called if deselected!
    // Two function calls in every SelectHdl because
    // there's no separate DeselectHDL.
    // So find out if select or deselect:
    if ( pBox->IsSelected( pBox->GetHdlEntry() ) )
    {
        UpdateFields();
        CheckButtons();
    }
    UpdateFields();
    CheckButtons();
}

IMPL_LINK( MacroChooser, BasicSelectHdl, SvTreeListBox *, pBox, void )
IMPL_LINK_NOARG(MacroChooser, BasicSelectHdl, weld::TreeView&, void)
{
    // Is also called if deselected!
    // Two function calls in every SelectHdl because
    // there's no separate DeselectHDL.
    // So find out if select or deselect:
    if ( !pBox->IsSelected( pBox->GetHdlEntry() ) )
        return;

    SbModule* pModule = m_pBasicBox->FindModule( m_pBasicBox->GetCurEntry() );

    m_pMacroBox->Clear();
    if ( pModule )
    m_xBasicBox->get_cursor(m_xBasicBoxIter.get());
    SbModule* pModule = m_xBasicBox->FindModule(m_xBasicBoxIter.get());
    m_xMacroBox->clear();
    if (pModule)
    {
        m_pMacrosInTxt->SetText( m_aMacrosInTxtBaseStr + " " + pModule->GetName() );
        m_xMacrosInTxt->set_label(m_aMacrosInTxtBaseStr + " " + pModule->GetName());

        // The macros should be called in the same order that they
        // are written down in the module.
@@ -530,16 +489,15 @@ IMPL_LINK( MacroChooser, BasicSelectHdl, SvTreeListBox *, pBox, void )
            aMacros.emplace( nStart, pMethod );
        }

        m_pMacroBox->SetUpdateMode(false);
        m_xMacroBox->freeze();
        for (auto const& macro : aMacros)
            m_pMacroBox->InsertEntry( macro.second->GetName() );
        m_pMacroBox->SetUpdateMode(true);
            m_xMacroBox->append_text(macro.second->GetName());
        m_xMacroBox->thaw();

        if ( m_pMacroBox->GetEntryCount() )
        if (m_xMacroBox->n_children())
        {
            SvTreeListEntry* pEntry = m_pMacroBox->GetEntry( 0 );
            DBG_ASSERT( pEntry, "Entry ?!" );
            m_pMacroBox->SetCurEntry( pEntry );
            m_xMacroBox->get_iter_first(*m_xMacroBoxIter);
            m_xMacroBox->set_cursor(*m_xMacroBoxIter);
        }
    }

@@ -547,56 +505,58 @@ IMPL_LINK( MacroChooser, BasicSelectHdl, SvTreeListBox *, pBox, void )
    CheckButtons();
}


IMPL_LINK_NOARG( MacroChooser, EditModifyHdl, Edit&, void )
IMPL_LINK_NOARG(MacroChooser, EditModifyHdl, weld::Entry&, void)
{
    // select the module in which the macro is put at "new",
    // if BasicManager or Lib is selecting
    SvTreeListEntry* pCurEntry = m_pBasicBox->GetCurEntry();
    if ( pCurEntry )
    if (m_xBasicBox->get_cursor(m_xBasicBoxIter.get()))
    {
        sal_uInt16 nDepth = m_pBasicBox->GetModel()->GetDepth( pCurEntry );
        if ( ( nDepth == 1 ) && ( m_pBasicBox->IsEntryProtected( pCurEntry ) ) )
        sal_uInt16 nDepth = m_xBasicBox->get_iter_depth(*m_xBasicBoxIter);
        if (nDepth == 1 && m_xBasicBox->IsEntryProtected(m_xBasicBoxIter.get()))
        {
            // then put to the respective Std-Lib...
            SvTreeListEntry* pManagerEntry = m_pBasicBox->GetModel()->GetParent( pCurEntry );
            pCurEntry = m_pBasicBox->GetModel()->FirstChild( pManagerEntry );
            m_xBasicBox->iter_parent(*m_xBasicBoxIter);
            m_xBasicBox->iter_children(*m_xBasicBoxIter);
        }
        if ( nDepth < 2 )
        if (nDepth < 2)
        {
            SvTreeListEntry* pNewEntry = pCurEntry;
            while ( pCurEntry && ( nDepth < 2 ) )
            std::unique_ptr<weld::TreeIter> xNewEntry(m_xBasicBox->make_iterator());
            m_xBasicBox->copy_iterator(*m_xBasicBoxIter, *xNewEntry);
            bool bCurEntry = true;
            do
            {
                pCurEntry = m_pBasicBox->FirstChild( pCurEntry );
                if ( pCurEntry )
                bCurEntry = m_xBasicBox->iter_children(*m_xBasicBoxIter);
                if (bCurEntry)
                {
                    pNewEntry = pCurEntry;
                    nDepth = m_pBasicBox->GetModel()->GetDepth( pCurEntry );
                    m_xBasicBox->copy_iterator(*m_xBasicBoxIter, *xNewEntry);
                    nDepth = m_xBasicBox->get_iter_depth(*m_xBasicBoxIter);
                }
            }
            SaveSetCurEntry( *m_pBasicBox, pNewEntry );
            while (bCurEntry && (nDepth < 2));
            SaveSetCurEntry(m_xBasicBox->get_widget(), *xNewEntry);
        }
        if ( m_pMacroBox->GetEntryCount() )
        auto nCount = m_xMacroBox->n_children();
        if (nCount)
        {
            OUString aEdtText( m_pMacroNameEdit->GetText() );
            OUString aEdtText(m_xMacroNameEdit->get_text());
            bool bFound = false;
            for ( sal_uLong n = 0; n < m_pMacroBox->GetEntryCount(); n++ )
            bool bValidIter = m_xMacroBox->get_iter_first(*m_xMacroBoxIter);
            while (bValidIter)
            {
                SvTreeListEntry* pEntry = m_pMacroBox->GetEntry( n );
                DBG_ASSERT( pEntry, "Entry ?!" );
                if ( m_pMacroBox->GetEntryText( pEntry ).equalsIgnoreAsciiCase( aEdtText ) )
                if (m_xMacroBox->get_text(*m_xMacroBoxIter).equalsIgnoreAsciiCase(aEdtText))
                {
                    SaveSetCurEntry(*m_pMacroBox, pEntry);
                    SaveSetCurEntry(*m_xMacroBox, *m_xMacroBoxIter);
                    bFound = true;
                    break;
                }
                bValidIter = m_xMacroBox->iter_next_sibling(*m_xMacroBoxIter);
            }
            if ( !bFound )
            if (!bFound)
            {
                SvTreeListEntry* pEntry = m_pMacroBox->FirstSelected();
                bValidIter = m_xMacroBox->get_selected(m_xMacroBoxIter.get());
                // if the entry exists ->Select ->Description...
                if ( pEntry )
                    m_pMacroBox->Select( pEntry, false );
                if (bValidIter)
                    m_xMacroBox->unselect(*m_xMacroBoxIter);
            }
        }
    }
@@ -604,11 +564,10 @@ IMPL_LINK_NOARG( MacroChooser, EditModifyHdl, Edit&, void )
    CheckButtons();
}


IMPL_LINK( MacroChooser, ButtonHdl, Button *, pButton, void )
IMPL_LINK(MacroChooser, ButtonHdl, weld::Button&, rButton, void)
{
    // apart from New/Record the Description is done by LoseFocus
    if (pButton == m_pRunButton)
    if (&rButton == m_xRunButton.get())
    {
        StoreMacroDescription();

@@ -624,7 +583,7 @@ IMPL_LINK( MacroChooser, ButtonHdl, Button *, pButton, void )
                ScriptDocument aDocument( ScriptDocument::getDocumentForBasicManager( pBasMgr ) );
                if ( aDocument.isDocument() && !aDocument.allowMacros() )
                {
                    std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(GetFrameWeld(),
                    std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(m_xDialog.get(),
                                                                VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_CANNOTRUNMACRO)));
                    xError->run();
                    return;
@@ -633,32 +592,32 @@ IMPL_LINK( MacroChooser, ButtonHdl, Button *, pButton, void )
        }
        else if (nMode == Recording )
        {
            if ( !IsValidSbxName(m_pMacroNameEdit->GetText()) )
            if ( !IsValidSbxName(m_xMacroNameEdit->get_text()) )
            {
                std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(GetFrameWeld(),
                std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(m_xDialog.get(),
                                                            VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_BADSBXNAME)));
                xError->run();
                m_pMacroNameEdit->SetSelection( Selection( 0, m_pMacroNameEdit->GetText().getLength() ) );
                m_pMacroNameEdit->GrabFocus();
                m_xMacroNameEdit->select_region(0, -1);
                m_xMacroNameEdit->grab_focus();
                return;
            }

            SbMethod* pMethod = GetMacro();
            if (pMethod && !QueryReplaceMacro(pMethod->GetName(), GetFrameWeld()))
            if (pMethod && !QueryReplaceMacro(pMethod->GetName(), m_xDialog.get()))
                return;
        }

        EndDialog(Macro_OkRun);
        m_xDialog->response(Macro_OkRun);
    }
    else if (pButton == m_pCloseButton)
    else if (&rButton == m_xCloseButton.get())
    {
        StoreMacroDescription();
        EndDialog(Macro_Close);
        m_xDialog->response(Macro_Close);
    }
    else if ((pButton == m_pEditButton) || (pButton == m_pDelButton))
    else if (&rButton == m_xEditButton.get() || &rButton == m_xDelButton.get() || &rButton == m_xNewButton.get())
    {
        SvTreeListEntry* pCurEntry = m_pBasicBox->GetCurEntry();
        EntryDescriptor aDesc = m_pBasicBox->GetEntryDescriptor(pCurEntry);
        m_xBasicBox->get_cursor(m_xBasicBoxIter.get());
        EntryDescriptor aDesc = m_xBasicBox->GetEntryDescriptor(m_xBasicBoxIter.get());
        const ScriptDocument& aDocument( aDesc.GetDocument() );
        DBG_ASSERT( aDocument.isAlive(), "MacroChooser::ButtonHdl: no document, or document is dead!" );
        if ( !aDocument.isAlive() )
@@ -674,11 +633,10 @@ IMPL_LINK( MacroChooser, ButtonHdl, Button *, pButton, void )
        }
        const OUString& aSub( aDesc.GetMethodName() );
        SfxMacroInfoItem aInfoItem( SID_BASICIDE_ARG_MACROINFO, pBasMgr, aLib, aMod, aSub, OUString() );
        if (pButton == m_pEditButton)
        if (&rButton == m_xEditButton.get())
        {
            SvTreeListEntry* pEntry = m_pMacroBox->FirstSelected();
            if ( pEntry )
                aInfoItem.SetMethod( m_pMacroBox->GetEntryText( pEntry ) );
            if (m_xMacroBox->get_selected(m_xMacroBoxIter.get()))
                aInfoItem.SetMethod(m_xMacroBox->get_text(*m_xMacroBoxIter));
            StoreMacroDescription();
            SfxAllItemSet aArgs( SfxGetpApp()->GetPool() );
            SfxRequest aRequest( SID_BASICIDE_APPEAR, SfxCallMode::SYNCHRON, aArgs );
@@ -689,11 +647,11 @@ IMPL_LINK( MacroChooser, ButtonHdl, Button *, pButton, void )
                pDispatcher->ExecuteList(SID_BASICIDE_EDITMACRO,
                        SfxCallMode::ASYNCHRON, { &aInfoItem });
            }
            EndDialog(Macro_Edit);
            m_xDialog->response(Macro_Edit);
        }
        else
        {
            if ( bNewDelIsDel )
            if (&rButton == m_xDelButton.get())
            {
                DeleteMacro();
                if (SfxDispatcher* pDispatcher = GetDispatcher())
@@ -703,18 +661,18 @@ IMPL_LINK( MacroChooser, ButtonHdl, Button *, pButton, void )
                }
                CheckButtons();
                UpdateFields();
                //if ( m_pMacroBox->GetCurEntry() )    // OV-Bug ?
                //  m_pMacroBox->Select( m_pMacroBox->GetCurEntry() );
                //if ( m_xMacroBox->GetCurEntry() )    // OV-Bug ?
                //  m_xMacroBox->Select( m_xMacroBox->GetCurEntry() );
            }
            else
            {
                if ( !IsValidSbxName(m_pMacroNameEdit->GetText()) )
                if ( !IsValidSbxName(m_xMacroNameEdit->get_text()) )
                {
                    std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(GetFrameWeld(),
                    std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(m_xDialog.get(),
                                                                VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_BADSBXNAME)));
                    xError->run();
                    m_pMacroNameEdit->SetSelection( Selection( 0, m_pMacroNameEdit->GetText().getLength() ) );
                    m_pMacroNameEdit->GrabFocus();
                    m_xMacroNameEdit->select_region(0, -1);
                    m_xMacroNameEdit->grab_focus();
                    return;
                }
                SbMethod* pMethod = CreateMacro();
@@ -733,15 +691,15 @@ IMPL_LINK( MacroChooser, ButtonHdl, Button *, pButton, void )
                                SfxCallMode::ASYNCHRON, { &aInfoItem });
                    }
                    StoreMacroDescription();
                    EndDialog(Macro_New);
                    m_xDialog->response(Macro_New);
                }
            }
        }
    }
    else if (pButton == m_pAssignButton)
    else if (&rButton == m_xAssignButton.get())
    {
        SvTreeListEntry* pCurEntry = m_pBasicBox->GetCurEntry();
        EntryDescriptor aDesc = m_pBasicBox->GetEntryDescriptor(pCurEntry);
        m_xBasicBox->get_cursor(m_xBasicBoxIter.get());
        EntryDescriptor aDesc = m_xBasicBox->GetEntryDescriptor(m_xBasicBoxIter.get());
        const ScriptDocument& aDocument( aDesc.GetDocument() );
        DBG_ASSERT( aDocument.isAlive(), "MacroChooser::ButtonHdl: no document, or document is dead!" );
        if ( !aDocument.isAlive() )
@@ -749,7 +707,7 @@ IMPL_LINK( MacroChooser, ButtonHdl, Button *, pButton, void )
        BasicManager* pBasMgr = aDocument.getBasicManager();
        const OUString& aLib( aDesc.GetLibName() );
        const OUString& aMod( aDesc.GetName() );
        OUString aSub( m_pMacroNameEdit->GetText() );
        OUString aSub( m_xMacroNameEdit->get_text() );
        SbMethod* pMethod = GetMacro();
        DBG_ASSERT( pBasMgr, "BasMgr?" );
        DBG_ASSERT( pMethod, "Method?" );
@@ -765,33 +723,34 @@ IMPL_LINK( MacroChooser, ButtonHdl, Button *, pButton, void )
        aRequest.AppendItem( aItem );
        SfxGetpApp()->ExecuteSlot( aRequest );
    }
    else if (pButton == m_pNewLibButton)
    else if (&rButton == m_xNewLibButton.get())
    {
        SvTreeListEntry* pCurEntry = m_pBasicBox->GetCurEntry();
        EntryDescriptor aDesc = m_pBasicBox->GetEntryDescriptor(pCurEntry);
        m_xBasicBox->get_cursor(m_xBasicBoxIter.get());
        EntryDescriptor aDesc = m_xBasicBox->GetEntryDescriptor(m_xBasicBoxIter.get());
        const ScriptDocument& aDocument( aDesc.GetDocument() );
        createLibImpl(GetFrameWeld(), aDocument, nullptr, m_pBasicBox);
        createLibImpl(m_xDialog.get(), aDocument, nullptr, m_xBasicBox.get());
    }
    else if (pButton == m_pNewModButton)
    else if (&rButton == m_xNewModButton.get())
    {
        SvTreeListEntry* pCurEntry = m_pBasicBox->GetCurEntry();
        EntryDescriptor aDesc = m_pBasicBox->GetEntryDescriptor(pCurEntry);
        m_xBasicBox->get_cursor(m_xBasicBoxIter.get());
        EntryDescriptor aDesc = m_xBasicBox->GetEntryDescriptor(m_xBasicBoxIter.get());
        const ScriptDocument& aDocument( aDesc.GetDocument() );
        const OUString& aLibName( aDesc.GetLibName() );
        createModImpl(GetFrameWeld(), aDocument, *m_pBasicBox, aLibName, OUString(), true);
        createModImpl(m_xDialog.get(), aDocument, *m_xBasicBox, aLibName, OUString(), true);
    }
    else if (pButton == m_pOrganizeButton)
    else if (&rButton == m_xOrganizeButton.get())
    {
        StoreMacroDescription();

        EntryDescriptor aDesc = m_pBasicBox->GetEntryDescriptor(m_pBasicBox->FirstSelected());
        VclPtrInstance< OrganizeDialog > pDlg( this, 0, aDesc );
        m_xBasicBox->get_selected(m_xBasicBoxIter.get());
        EntryDescriptor aDesc = m_xBasicBox->GetEntryDescriptor(m_xBasicBoxIter.get());
        VclPtrInstance< OrganizeDialog > pDlg( nullptr, 0, aDesc ); //TODO
        sal_uInt16 nRet = pDlg->Execute();
        pDlg.reset();

        if ( nRet ) // not only closed
        {
            EndDialog(Macro_Edit);
            m_xDialog->response(Macro_Edit);
            return;
        }

@@ -799,18 +758,17 @@ IMPL_LINK( MacroChooser, ButtonHdl, Button *, pButton, void )
        if ( pShell && pShell->IsAppBasicModified() )
            bForceStoreBasic = true;

        m_pBasicBox->UpdateEntries();
        m_xBasicBox->UpdateEntries();
    }
}


void MacroChooser::UpdateFields()
{
    SvTreeListEntry*    pMacroEntry = m_pMacroBox->GetCurEntry();

    m_pMacroNameEdit->SetText( "" );
    if ( pMacroEntry )
        m_pMacroNameEdit->SetText( m_pMacroBox->GetEntryText( pMacroEntry ) );
    auto nMacroEntry = m_xMacroBox->get_selected_index();
    m_xMacroNameEdit->set_text("");
    if (nMacroEntry != -1)
        m_xMacroNameEdit->set_text(m_xMacroBox->get_text(nMacroEntry));
}

void MacroChooser::SetMode (Mode nM)
@@ -820,35 +778,39 @@ void MacroChooser::SetMode (Mode nM)
    {
        case All:
        {
            m_pRunButton->SetText(IDEResId(RID_STR_RUN));
            EnableButton(*m_pDelButton, true);
            EnableButton(*m_pOrganizeButton, true);
            m_xRunButton->set_label(IDEResId(RID_STR_RUN));
            EnableButton(*m_xDelButton, true);
            EnableButton(*m_xNewButton, true);
            EnableButton(*m_xOrganizeButton, true);
            break;
        }

        case ChooseOnly:
        {
            m_pRunButton->SetText(IDEResId(RID_STR_CHOOSE));
            EnableButton(*m_pDelButton, false);
            EnableButton(*m_pOrganizeButton, false);
            m_xRunButton->set_label(IDEResId(RID_STR_CHOOSE));
            EnableButton(*m_xDelButton, false);
            EnableButton(*m_xNewButton, false);
            EnableButton(*m_xOrganizeButton, false);
            break;
        }

        case Recording:
        {
            m_pRunButton->SetText(IDEResId(RID_STR_RECORD));
            EnableButton(*m_pDelButton, false);
            EnableButton(*m_pOrganizeButton, false);
            m_xRunButton->set_label(IDEResId(RID_STR_RECORD));
            EnableButton(*m_xDelButton, false);
            EnableButton(*m_xNewButton, false);
            EnableButton(*m_xOrganizeButton, false);

            m_pAssignButton->Hide();
            m_pEditButton->Hide();
            m_pDelButton->Hide();
            m_pOrganizeButton->Hide();
            m_pMacroFromTxT->Hide();
            m_xAssignButton->hide();
            m_xEditButton->hide();
            m_xDelButton->hide();
            m_xNewButton->hide();
            m_xOrganizeButton->hide();
            m_xMacroFromTxT->hide();

            m_pNewLibButton->Show();
            m_pNewModButton->Show();
            m_pMacrosSaveInTxt->Show();
            m_xNewLibButton->show();
            m_xNewModButton->show();
            m_xMacrosSaveInTxt->show();

            break;
        }
diff --git a/basctl/source/basicide/macrodlg.hxx b/basctl/source/basicide/macrodlg.hxx
index 8a0e1ff..35e5479 100644
--- a/basctl/source/basicide/macrodlg.hxx
+++ b/basctl/source/basicide/macrodlg.hxx
@@ -22,22 +22,20 @@

#include <bastype2.hxx>
#include <sfx2/basedlgs.hxx>

#include <com/sun/star/frame/XFrame.hpp>

#include <vcl/button.hxx>
#include <vcl/weld.hxx>

namespace basctl
{

enum MacroExitCode {
    Macro_Close = 10,
    Macro_OkRun = 11,
    Macro_New   = 12,
    Macro_Edit  = 14,
    Macro_Close = 110,
    Macro_OkRun = 111,
    Macro_New   = 112,
    Macro_Edit  = 114,
};

class MacroChooser : public SfxModalDialog
class MacroChooser : public SfxDialogController
{
public:
    enum Mode {
@@ -47,58 +45,58 @@ public:
    };

private:
    VclPtr<Edit>                   m_pMacroNameEdit;
    VclPtr<FixedText>              m_pMacroFromTxT;
    VclPtr<FixedText>              m_pMacrosSaveInTxt;
    VclPtr<TreeListBox>            m_pBasicBox;
    VclPtr<FixedText>              m_pMacrosInTxt;
    OUString                       m_aMacrosInTxtBaseStr;
    VclPtr<SvTreeListBox>          m_pMacroBox;

    VclPtr<PushButton>             m_pRunButton;
    VclPtr<CloseButton>            m_pCloseButton;
    VclPtr<PushButton>             m_pAssignButton;
    VclPtr<PushButton>             m_pEditButton;
    VclPtr<PushButton>             m_pDelButton;
    VclPtr<PushButton>             m_pOrganizeButton;
    VclPtr<PushButton>             m_pNewLibButton;
    VclPtr<PushButton>             m_pNewModButton;

    // For forwarding to Assign dialog
    ::css::uno::Reference< ::css::frame::XFrame > m_xDocumentFrame;

    bool                    bNewDelIsDel;
    bool                    bForceStoreBasic;

    Mode                    nMode;

    DECL_LINK( MacroSelectHdl, SvTreeListBox *, void );
    DECL_LINK( MacroDoubleClickHdl, SvTreeListBox*, bool );
    DECL_LINK( BasicSelectHdl, SvTreeListBox *, void );
    DECL_LINK( EditModifyHdl, Edit&, void );
    DECL_LINK( ButtonHdl, Button *, void );
    DECL_LINK(MacroSelectHdl, weld::TreeView&, void);
    DECL_LINK(MacroDoubleClickHdl, weld::TreeView&, void);
    DECL_LINK(BasicSelectHdl, weld::TreeView&, void);
    DECL_LINK(EditModifyHdl, weld::Entry&, void);
    DECL_LINK(ButtonHdl, weld::Button&, void);

    void                CheckButtons();
    void                SaveSetCurEntry( SvTreeListBox& rBox, SvTreeListEntry* pEntry );
    void                SaveSetCurEntry(weld::TreeView& rBox, weld::TreeIter& rEntry);
    void                UpdateFields();

    void                EnableButton( Button& rButton, bool bEnable );
    void                EnableButton(weld::Button& rButton, bool bEnable);

    static OUString     GetInfo( SbxVariable* pVar );

    void                StoreMacroDescription();
    void                RestoreMacroDescription();

    std::unique_ptr<weld::Entry> m_xMacroNameEdit;
    std::unique_ptr<weld::Label> m_xMacroFromTxT;
    std::unique_ptr<weld::Label> m_xMacrosSaveInTxt;
    std::unique_ptr<SbTreeListBox> m_xBasicBox;
    std::unique_ptr<weld::TreeIter> m_xBasicBoxIter;
    std::unique_ptr<weld::Label> m_xMacrosInTxt;
    std::unique_ptr<weld::TreeView> m_xMacroBox;
    std::unique_ptr<weld::TreeIter> m_xMacroBoxIter;
    std::unique_ptr<weld::Button> m_xRunButton;
    std::unique_ptr<weld::Button> m_xCloseButton;
    std::unique_ptr<weld::Button> m_xAssignButton;
    std::unique_ptr<weld::Button> m_xEditButton;
    std::unique_ptr<weld::Button> m_xDelButton;
    std::unique_ptr<weld::Button> m_xNewButton;
    std::unique_ptr<weld::Button> m_xOrganizeButton;
    std::unique_ptr<weld::Button> m_xNewLibButton;
    std::unique_ptr<weld::Button> m_xNewModButton;
public:
                        MacroChooser( vcl::Window* pParent, const ::css::uno::Reference< ::css::frame::XFrame >& xDocFrame, bool bCreateEntries );
                        virtual ~MacroChooser() override;
    virtual void        dispose() override;
    MacroChooser(weld::Window *pParent, const ::css::uno::Reference< ::css::frame::XFrame >& xDocFrame, bool bCreateEntries);
    virtual ~MacroChooser() override;

    SbMethod*           GetMacro();
    void                DeleteMacro();
    SbMethod*           CreateMacro();

    virtual short       Execute() override;
    virtual short       run() override;

    void                SetMode (Mode);
    Mode                GetMode () const { return nMode; }
diff --git a/basctl/source/basicide/moduldl2.cxx b/basctl/source/basicide/moduldl2.cxx
index 2e13017..7c16245 100644
--- a/basctl/source/basicide/moduldl2.cxx
+++ b/basctl/source/basicide/moduldl2.cxx
@@ -698,7 +698,7 @@ IMPL_LINK( LibPage, CheckPasswordHdl, SvxPasswordDialog *, pDlg, bool )

void LibPage::NewLib()
{
    createLibImpl(GetFrameWeld(), m_aCurDocument, m_pLibBox, nullptr);
    createLibImpl(GetFrameWeld(), m_aCurDocument, m_pLibBox, static_cast<SbTreeListBox*>(nullptr));
}

void LibPage::InsertLib()
@@ -1552,6 +1552,106 @@ void createLibImpl(weld::Window* pWin, const ScriptDocument& rDocument,
        }
    }
}

void createLibImpl(weld::Window* pWin, const ScriptDocument& rDocument,
                   CheckBox* pLibBox, SbTreeListBox* pBasicBox)
{
    OSL_ENSURE( rDocument.isAlive(), "createLibImpl: invalid document!" );
    if ( !rDocument.isAlive() )
        return;

    // create library name
    OUString aLibName;
    bool bValid = false;
    sal_Int32 i = 1;
    while ( !bValid )
    {
        aLibName = "Library" + OUString::number( i );
        if ( !rDocument.hasLibrary( E_SCRIPTS, aLibName ) && !rDocument.hasLibrary( E_DIALOGS, aLibName ) )
            bValid = true;
        i++;
    }

    NewObjectDialog aNewDlg(pWin, ObjectMode::Library);
    aNewDlg.SetObjectName(aLibName);

    if (aNewDlg.run())
    {
        if (!aNewDlg.GetObjectName().isEmpty())
            aLibName = aNewDlg.GetObjectName();

        if ( aLibName.getLength() > 30 )
        {
            std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(pWin,
                                                           VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_LIBNAMETOLONG)));
            xErrorBox->run();
        }
        else if ( !IsValidSbxName( aLibName ) )
        {
            std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(pWin,
                                                           VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_BADSBXNAME)));
            xErrorBox->run();
        }
        else if ( rDocument.hasLibrary( E_SCRIPTS, aLibName ) || rDocument.hasLibrary( E_DIALOGS, aLibName ) )
        {
            std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(pWin,
                                                           VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_SBXNAMEALLREADYUSED2)));
            xErrorBox->run();
        }
        else
        {
            try
            {
                // create module and dialog library
                Reference< container::XNameContainer > xModLib( rDocument.getOrCreateLibrary( E_SCRIPTS, aLibName ) );
                Reference< container::XNameContainer > xDlgLib( rDocument.getOrCreateLibrary( E_DIALOGS, aLibName ) );

                if( pLibBox )
                {
                    SvTreeListEntry* pEntry = pLibBox->DoInsertEntry( aLibName );
                    pEntry->SetUserData( new LibUserData( rDocument ) );
                    pLibBox->SetCurEntry( pEntry );
                }

                // create a module
                OUString aModName = rDocument.createObjectName( E_SCRIPTS, aLibName );
                OUString sModuleCode;
                if ( !rDocument.createModule( aLibName, aModName, true, sModuleCode ) )
                    throw Exception("could not create module " + aModName, nullptr);

                SbxItem aSbxItem( SID_BASICIDE_ARG_SBX, rDocument, aLibName, aModName, TYPE_MODULE );
                if (SfxDispatcher* pDispatcher = GetDispatcher())
                    pDispatcher->ExecuteList(SID_BASICIDE_SBXINSERTED,
                                          SfxCallMode::SYNCHRON, { &aSbxItem });

                if( pBasicBox )
                {
                    std::unique_ptr<weld::TreeIter> xIter(pBasicBox->make_iterator(nullptr));
                    bool bValidIter = pBasicBox->get_cursor(xIter.get());
                    std::unique_ptr<weld::TreeIter> xRootEntry(pBasicBox->make_iterator(xIter.get()));
                    while (bValidIter)
                    {
                        pBasicBox->copy_iterator(*xIter, *xRootEntry);
                        bValidIter = pBasicBox->iter_parent(*xIter);
                    }

                    BrowseMode nMode = pBasicBox->GetMode();
                    bool bDlgMode = ( nMode & BrowseMode::Dialogs ) && !( nMode & BrowseMode::Modules );
                    const OUString sId = bDlgMode ? OUStringLiteral(RID_BMP_DLGLIB) : OUStringLiteral(RID_BMP_MODLIB);
                    pBasicBox->AddEntry(aLibName, sId, xRootEntry.get(), false, o3tl::make_unique<Entry>(OBJ_TYPE_LIBRARY));
                    pBasicBox->AddEntry(aModName, RID_BMP_MODULE, xRootEntry.get(), false, o3tl::make_unique<Entry>(OBJ_TYPE_MODULE));
                    pBasicBox->set_cursor(*xRootEntry);
                    pBasicBox->select(*xRootEntry);
                }
            }
            catch (const uno::Exception& )
            {
                DBG_UNHANDLED_EXCEPTION("basctl.basicide");
            }
        }
    }
}

} // namespace basctl

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basctl/source/basicide/moduldlg.cxx b/basctl/source/basicide/moduldlg.cxx
index 1a2af91d..1f525be 100644
--- a/basctl/source/basicide/moduldlg.cxx
+++ b/basctl/source/basicide/moduldlg.cxx
@@ -1055,6 +1055,102 @@ SbModule* createModImpl(weld::Window* pWin, const ScriptDocument& rDocument,
    return pModule;
}

SbModule* createModImpl(weld::Window* pWin, const ScriptDocument& rDocument,
    SbTreeListBox& rBasicBox, const OUString& rLibName, const OUString& _aModName, bool bMain )
{
    OSL_ENSURE( rDocument.isAlive(), "createModImpl: invalid document!" );
    if ( !rDocument.isAlive() )
        return nullptr;

    SbModule* pModule = nullptr;

    OUString aLibName( rLibName );
    if ( aLibName.isEmpty() )
        aLibName = "Standard" ;
    rDocument.getOrCreateLibrary( E_SCRIPTS, aLibName );
    OUString aModName = _aModName;
    if ( aModName.isEmpty() )
        aModName = rDocument.createObjectName( E_SCRIPTS, aLibName );

    NewObjectDialog aNewDlg(pWin, ObjectMode::Module, true);
    aNewDlg.SetObjectName(aModName);

    if (aNewDlg.run() != RET_CANCEL)
    {
        if (!aNewDlg.GetObjectName().isEmpty())
            aModName = aNewDlg.GetObjectName();

        try
        {
            OUString sModuleCode;
            // the module has existed
            if( rDocument.hasModule( aLibName, aModName ) )
                return nullptr;
            rDocument.createModule( aLibName, aModName, bMain, sModuleCode );
            BasicManager* pBasMgr = rDocument.getBasicManager();
            StarBASIC* pBasic = pBasMgr? pBasMgr->GetLib( aLibName ) : nullptr;
                if ( pBasic )
                    pModule = pBasic->FindModule( aModName );
                SbxItem aSbxItem( SID_BASICIDE_ARG_SBX, rDocument, aLibName, aModName, TYPE_MODULE );
            if (SfxDispatcher* pDispatcher = GetDispatcher())
            {
                pDispatcher->ExecuteList( SID_BASICIDE_SBXINSERTED,
                      SfxCallMode::SYNCHRON, { &aSbxItem });
            }
            LibraryLocation eLocation = rDocument.getLibraryLocation( aLibName );
            std::unique_ptr<weld::TreeIter> xIter(rBasicBox.make_iterator());
            bool bRootEntry = rBasicBox.FindRootEntry(rDocument, eLocation, *xIter);
            if (bRootEntry)
            {
                if (!rBasicBox.get_row_expanded(*xIter))
                    rBasicBox.expand_row(*xIter);
                bool bLibEntry = rBasicBox.FindEntry(aLibName, OBJ_TYPE_LIBRARY, *xIter);
                DBG_ASSERT( bLibEntry, "LibEntry not found!" );
                if (bLibEntry)
                {
                    if (!rBasicBox.get_row_expanded(*xIter))
                        rBasicBox.expand_row(*xIter);
                    std::unique_ptr<weld::TreeIter> xSubRootEntry(rBasicBox.make_iterator(xIter.get()));
                    if (pBasic && rDocument.isInVBAMode())
                    {
                        // add the new module in the "Modules" entry
                        std::unique_ptr<weld::TreeIter> xLibSubEntry(rBasicBox.make_iterator(xIter.get()));
                        bool bLibSubEntry = rBasicBox.FindEntry(IDEResId(RID_STR_NORMAL_MODULES) , OBJ_TYPE_NORMAL_MODULES, *xLibSubEntry);
                        if (bLibSubEntry)
                        {
                            if (!rBasicBox.get_row_expanded(*xLibSubEntry))
                                rBasicBox.expand_row(*xLibSubEntry);
                            rBasicBox.copy_iterator(*xLibSubEntry, *xSubRootEntry);
                        }
                    }

                    std::unique_ptr<weld::TreeIter> xEntry(rBasicBox.make_iterator(xSubRootEntry.get()));
                    bool bEntry = rBasicBox.FindEntry(aModName, OBJ_TYPE_MODULE, *xEntry);
                    if (!bEntry)
                    {
                        rBasicBox.AddEntry(aModName, RID_BMP_MODULE, xEntry.get(), false,
                                           o3tl::make_unique<Entry>(OBJ_TYPE_MODULE));
                    }
                    rBasicBox.set_cursor(*xEntry);
                    rBasicBox.select(*xEntry);
                }
            }
        }
        catch (const container::ElementExistException& )
        {
            std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(pWin,
                                                        VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_SBXNAMEALLREADYUSED2)));
            xError->run();
        }
        catch (const container::NoSuchElementException& )
        {
            DBG_UNHANDLED_EXCEPTION("basctl.basicide");
        }
    }
    return pModule;
}


} // namespace basctl

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basctl/source/basicide/moduldlg.hxx b/basctl/source/basicide/moduldlg.hxx
index cbd8b5c..3da0ff1 100644
--- a/basctl/source/basicide/moduldlg.hxx
+++ b/basctl/source/basicide/moduldlg.hxx
@@ -250,9 +250,13 @@ public:

// Helper functions
SbModule* createModImpl(weld::Window* pWin, const ScriptDocument& rDocument,
                        SbTreeListBox& rBasicBox, const OUString& rLibName, const OUString& aModName, bool bMain);
SbModule* createModImpl(weld::Window* pWin, const ScriptDocument& rDocument,
                        TreeListBox& rBasicBox, const OUString& rLibName, const OUString& aModName, bool bMain);
void createLibImpl(weld::Window* pWin, const ScriptDocument& rDocument,
                   CheckBox* pLibBox, TreeListBox* pBasicBox);
void createLibImpl(weld::Window* pWin, const ScriptDocument& rDocument,
                   CheckBox* pLibBox, SbTreeListBox* pBasicBox);

} // namespace basctl

diff --git a/basctl/source/inc/basobj.hxx b/basctl/source/inc/basobj.hxx
index 7b84c2f..acdb1f0 100644
--- a/basctl/source/inc/basobj.hxx
+++ b/basctl/source/inc/basobj.hxx
@@ -30,7 +30,7 @@ class StarBASIC;
class SfxUInt16Item;
class SfxBindings;
class SfxDispatcher;
namespace weld { class Widget; }
namespace weld { class Widget; class Window; }

namespace basctl
{
@@ -73,12 +73,11 @@ namespace basctl

    // new methods for macros

    OUString        ChooseMacro(
    OUString        ChooseMacro(weld::Window* pParent,
        const css::uno::Reference< css::frame::XModel >& rxLimitToDocument, const css::uno::Reference< css::frame::XFrame >& xDocFrame,
        bool bChooseOnly );
    inline OUString ChooseMacro(
        const css::uno::Reference< css::frame::XModel >& rxLimitToDocument )
    { return ChooseMacro(rxLimitToDocument, css::uno::Reference< css::frame::XFrame >(), false/*bChooseOnly*/); }
    inline OUString ChooseMacro(weld::Window* pParent, const css::uno::Reference<css::frame::XModel>& rLimitToDocument)
    { return ChooseMacro(pParent, rLimitToDocument, css::uno::Reference< css::frame::XFrame >(), false/*bChooseOnly*/); }

    /// @throws css::container::NoSuchElementException
    /// @throws css::uno::RuntimeException
diff --git a/basctl/source/inc/bastype2.hxx b/basctl/source/inc/bastype2.hxx
index 5dccdb1..7115e6f 100644
--- a/basctl/source/inc/bastype2.hxx
+++ b/basctl/source/inc/bastype2.hxx
@@ -27,6 +27,7 @@
#include "doceventnotifier.hxx"

#include <vcl/treelistbox.hxx>
#include <vcl/weld.hxx>
#include <basic/sbstar.hxx>
#include "sbxitem.hxx"
#include "basobj.hxx"
@@ -181,7 +182,7 @@ private:
    BrowseMode            nMode;
    DocumentEventNotifier m_aNotifier;
    void            SetEntryBitmaps( SvTreeListEntry * pEntry, const Image& rImage );
    virtual void    MouseButtonDown( const MouseEvent& rMEvt ) override;
    virtual void    MouseButtonDown(const MouseEvent& rMEvt) override;

protected:
    virtual void            RequestingChildren( SvTreeListEntry* pParent ) override;
@@ -251,6 +252,93 @@ private:
    LibraryType     GetLibraryType() const;
};

class SbTreeListBox : public DocumentEventListener
{
private:
    std::unique_ptr<weld::TreeView> m_xControl;
    std::unique_ptr<weld::TreeIter> m_xIter;
    weld::Window* m_pTopLevel;
    BrowseMode nMode;
    DocumentEventNotifier m_aNotifier;
    void            SetEntryBitmaps(weld::TreeIter& rIter, const OUString& rImage);

protected:
    DECL_LINK(RequestingChildrenHdl, weld::TreeIter&, bool);
    DECL_LINK(OpenCurrentHdl, weld::TreeView&, void);
    void                    ImpCreateLibEntries(weld::TreeIter& rShellRootEntry, const ScriptDocument& rDocument, LibraryLocation eLocation);
    void                    ImpCreateLibSubEntries(weld::TreeIter& rLibRootEntry, const ScriptDocument& rDocument, const OUString& rLibName);
    void                    ImpCreateLibSubEntriesInVBAMode(weld::TreeIter& rLibRootEntry, const ScriptDocument& rDocument, const OUString& rLibName );
    void                    ImpCreateLibSubSubEntriesInVBAMode(weld::TreeIter& rLibRootEntry, const ScriptDocument& rDocument, const OUString& rLibName);
    bool                    ImpFindEntry(weld::TreeIter& rIter, const OUString& rText);

    // DocumentEventListener
    virtual void onDocumentCreated( const ScriptDocument& _rDocument ) override;
    virtual void onDocumentOpened( const ScriptDocument& _rDocument ) override;
    virtual void onDocumentSave( const ScriptDocument& _rDocument ) override;
    virtual void onDocumentSaveDone( const ScriptDocument& _rDocument ) override;
    virtual void onDocumentSaveAs( const ScriptDocument& _rDocument ) override;
    virtual void onDocumentSaveAsDone( const ScriptDocument& _rDocument ) override;
    virtual void onDocumentClosed( const ScriptDocument& _rDocument ) override;
    virtual void onDocumentTitleChanged( const ScriptDocument& _rDocument ) override;
    virtual void onDocumentModeChanged( const ScriptDocument& _rDocument ) override;

public:
    SbTreeListBox(std::unique_ptr<weld::TreeView> xControl, weld::Window* pTopLevel);
    virtual ~SbTreeListBox() override;

    void            ScanEntry( const ScriptDocument& rDocument, LibraryLocation eLocation );
    void            ScanAllEntries();
    void            UpdateEntries();

    bool            IsEntryProtected(weld::TreeIter* pEntry);

    void            SetMode( BrowseMode nM ) { nMode = nM; }
    BrowseMode      GetMode() const { return nMode; }

    SbModule*       FindModule(weld::TreeIter* pEntry);
    SbxVariable*    FindVariable(weld::TreeIter* pEntry);
    bool            FindRootEntry(const ScriptDocument& rDocument, LibraryLocation eLocation, weld::TreeIter& rIter);
    bool            FindEntry(const OUString& rText, EntryType eType, weld::TreeIter& rIter);
    EntryDescriptor GetEntryDescriptor(weld::TreeIter* pEntry);

    static ItemType ConvertType (EntryType eType);
    bool            IsValidEntry(weld::TreeIter& rEntry);
    void AddEntry(const OUString& rText, const OUString& rImage,
                  weld::TreeIter* pIter, bool bChildrenOnDemand, std::unique_ptr<Entry>&& rUserData);

    void connect_changed(const Link<weld::TreeView&, void>& rLink) { m_xControl->connect_changed(rLink); }
    std::unique_ptr<weld::TreeIter> make_iterator(weld::TreeIter* pIter = nullptr) const { return m_xControl->make_iterator(pIter); }
    void copy_iterator(const weld::TreeIter& rSource, weld::TreeIter& rDest) const { m_xControl->copy_iterator(rSource, rDest); }
    bool get_selected(weld::TreeIter* pIter) const { return m_xControl->get_selected(pIter); }
    void select(const weld::TreeIter& rIter) { m_xControl->select(rIter); }
    bool get_cursor(weld::TreeIter* pIter) const { return m_xControl->get_cursor(pIter); }
    void set_cursor(const weld::TreeIter& rIter) { m_xControl->set_cursor(rIter); }
    bool get_iter_first(weld::TreeIter& rIter) const { return m_xControl->get_iter_first(rIter); }
    bool iter_next_sibling(weld::TreeIter& rIter) const { return m_xControl->iter_next_sibling(rIter); }
    bool iter_children(weld::TreeIter& rIter) const { return m_xControl->iter_children(rIter); }
    bool iter_parent(weld::TreeIter& rIter) const { return m_xControl->iter_parent(rIter); }
    int get_iter_depth(const weld::TreeIter& rIter) const { return m_xControl->get_iter_depth(rIter); }
    OUString get_text(const weld::TreeIter& rIter) const { return m_xControl->get_text(rIter); }
    bool get_row_expanded(const weld::TreeIter& rIter) const { return m_xControl->get_row_expanded(rIter); }
    void expand_row(weld::TreeIter& rIter) { m_xControl->expand_row(rIter); }
    void set_size_request(int nWidth, int nHeight) { m_xControl->set_size_request(nWidth, nHeight); }
    float get_approximate_digit_width() const { return m_xControl->get_approximate_digit_width(); }
    int get_height_rows(int nRows) const { return m_xControl->get_height_rows(nRows); }

    void            RemoveEntry(const weld::TreeIter& rIter);
    void            RemoveEntry(const ScriptDocument&);

    OUString        GetRootEntryName(const ScriptDocument& rDocument, LibraryLocation eLocation) const;
    static OUString GetRootEntryBitmaps(const ScriptDocument& rDocument);

    void            SetCurrentEntry (EntryDescriptor const &);

    weld::TreeView& get_widget() { return *m_xControl; }

private:
    LibraryType     GetLibraryType() const;
};

} // namespace basctl

#endif // INCLUDED_BASCTL_SOURCE_INC_BASTYPE2_HXX
diff --git a/basctl/uiconfig/basicide/ui/basicmacrodialog.ui b/basctl/uiconfig/basicide/ui/basicmacrodialog.ui
index fb5331c..9548679 100644
--- a/basctl/uiconfig/basicide/ui/basicmacrodialog.ui
+++ b/basctl/uiconfig/basicide/ui/basicmacrodialog.ui
@@ -1,13 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<!-- Generated with glade 3.22.1 -->
<interface domain="basctl">
  <requires lib="gtk+" version="3.18"/>
  <requires lib="LibreOffice" version="1.0"/>
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
      <!-- column-name id -->
      <column type="gchararray"/>
      <!-- column-name image -->
      <column type="GdkPixbuf"/>
      <!-- column-name surface -->
      <column type="CairoSurface"/>
      <!-- column-name expander -->
      <column type="GdkPixbuf"/>
    </columns>
  </object>
  <object class="GtkTreeStore" id="liststore2">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
      <!-- column-name id -->
      <column type="gchararray"/>
      <!-- column-name image -->
      <column type="GdkPixbuf"/>
      <!-- column-name surface -->
      <column type="CairoSurface"/>
      <!-- column-name expander -->
      <column type="GdkPixbuf"/>
    </columns>
  </object>
  <object class="GtkDialog" id="BasicMacroDialog">
    <property name="can_focus">False</property>
    <property name="border_width">6</property>
    <property name="title" translatable="yes" context="basicmacrodialog|BasicMacroDialog">%PRODUCTNAME Basic Macros</property>
    <property name="modal">True</property>
    <property name="type_hint">dialog</property>
    <child>
      <placeholder/>
    </child>
    <child internal-child="vbox">
      <object class="GtkBox" id="dialog-vbox1">
        <property name="can_focus">False</property>
@@ -21,13 +52,14 @@
            <property name="homogeneous">True</property>
            <property name="layout_style">end</property>
            <child>
              <object class="GtkButton" id="run">
              <object class="GtkButton" id="ok">
                <property name="label" translatable="yes" context="basicmacrodialog|run">Run</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="can_default">True</property>
                <property name="has_default">True</property>
                <property name="receives_default">True</property>
                <property name="use_underline">True</property>
              </object>
              <packing>
                <property name="expand">False</property>
@@ -46,7 +78,7 @@
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">7</property>
                <property name="position">1</property>
              </packing>
            </child>
            <child>
@@ -101,16 +133,37 @@
                        <property name="top_padding">6</property>
                        <property name="left_padding">12</property>
                        <child>
                          <object class="vcllo-SvTreeListBox" id="macros:border">
                            <property name="width_request">280</property>
                            <property name="height_request">300</property>
                          <object class="GtkScrolledWindow">
                            <property name="visible">True</property>
                            <property name="can_focus">True</property>
                            <property name="receives_default">True</property>
                            <property name="hexpand">True</property>
                            <property name="vexpand">True</property>
                            <child internal-child="selection">
                              <object class="GtkTreeSelection" id="Tree List-selection1"/>
                            <property name="shadow_type">in</property>
                            <child>
                              <object class="GtkTreeView" id="macros">
                                <property name="visible">True</property>
                                <property name="can_focus">True</property>
                                <property name="receives_default">True</property>
                                <property name="hexpand">True</property>
                                <property name="vexpand">True</property>
                                <property name="model">liststore2</property>
                                <property name="headers_visible">False</property>
                                <property name="search_column">0</property>
                                <property name="show_expanders">False</property>
                                <child internal-child="selection">
                                  <object class="GtkTreeSelection" id="Tree List-selection1"/>
                                </child>
                                <child>
                                  <object class="GtkTreeViewColumn" id="treeviewcolumn1">
                                    <child>
                                      <object class="GtkCellRendererText" id="cellrenderertext1"/>
                                      <attributes>
                                        <attribute name="text">0</attribute>
                                      </attributes>
                                    </child>
                                  </object>
                                </child>
                              </object>
                            </child>
                          </object>
                        </child>
@@ -149,17 +202,45 @@
                        <property name="top_padding">6</property>
                        <property name="left_padding">12</property>
                        <child>
                          <object class="basctllo-TreeListBox" id="libraries:border">
                            <property name="width_request">280</property>
                            <property name="height_request">300</property>
                          <object class="GtkScrolledWindow">
                            <property name="visible">True</property>
                            <property name="can_focus">True</property>
                            <property name="receives_default">True</property>
                            <property name="opacity">0.91000000000000003</property>
                            <property name="hexpand">True</property>
                            <property name="vexpand">True</property>
                            <child internal-child="selection">
                              <object class="GtkTreeSelection" id="Macro Library List-selection1"/>
                            <property name="shadow_type">in</property>
                            <child>
                              <object class="GtkTreeView" id="libraries">
                                <property name="width_request">-1</property>
                                <property name="visible">True</property>
                                <property name="can_focus">True</property>
                                <property name="receives_default">True</property>
                                <property name="hexpand">True</property>
                                <property name="vexpand">True</property>
                                <property name="model">liststore1</property>
                                <property name="headers_visible">False</property>
                                <property name="search_column">0</property>
                                <property name="enable_tree_lines">True</property>
                                <child internal-child="selection">
                                  <object class="GtkTreeSelection" id="Macro Library List-selection1"/>
                                </child>
                                <child>
                                  <object class="GtkTreeViewColumn" id="treeviewcolumn2">
                                    <property name="spacing">6</property>
                                    <child>
                                      <object class="GtkCellRendererPixbuf" id="cellrenderertext4"/>
                                      <attributes>
                                        <attribute name="pixbuf">4</attribute>
                                      </attributes>
                                    </child>
                                    <child>
                                      <object class="GtkCellRendererText" id="cellrenderertext2"/>
                                      <attributes>
                                        <attribute name="text">0</attribute>
                                      </attributes>
                                    </child>
                                  </object>
                                </child>
                              </object>
                            </child>
                          </object>
                        </child>
@@ -221,7 +302,6 @@
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="hexpand">True</property>
                        <property name="vexpand">True</property>
                        <property name="top_padding">6</property>
                        <property name="left_padding">12</property>
                        <child>
@@ -229,7 +309,6 @@
                            <property name="visible">True</property>
                            <property name="can_focus">True</property>
                            <property name="hexpand">True</property>
                            <property name="vexpand">True</property>
                          </object>
                        </child>
                      </object>
@@ -257,6 +336,7 @@
                    <property name="resize_mode">immediate</property>
                    <property name="orientation">vertical</property>
                    <property name="spacing">5</property>
                    <property name="homogeneous">True</property>
                    <property name="layout_style">start</property>
                    <child>
                      <object class="GtkButton" id="assign">
@@ -264,6 +344,7 @@
                        <property name="visible">True</property>
                        <property name="can_focus">True</property>
                        <property name="receives_default">True</property>
                        <property name="use_underline">True</property>
                      </object>
                      <packing>
                        <property name="expand">False</property>
@@ -277,6 +358,7 @@
                        <property name="visible">True</property>
                        <property name="can_focus">True</property>
                        <property name="receives_default">True</property>
                        <property name="use_underline">True</property>
                      </object>
                      <packing>
                        <property name="expand">False</property>
@@ -286,11 +368,11 @@
                    </child>
                    <child>
                      <object class="GtkButton" id="delete">
                        <property name="label">gtk-delete</property>
                        <property name="label">_Delete</property>
                        <property name="visible">True</property>
                        <property name="can_focus">True</property>
                        <property name="receives_default">True</property>
                        <property name="use_stock">True</property>
                        <property name="use_underline">True</property>
                      </object>
                      <packing>
                        <property name="expand">False</property>
@@ -299,11 +381,12 @@
                      </packing>
                    </child>
                    <child>
                      <object class="GtkButton" id="organize">
                        <property name="label" translatable="yes" context="basicmacrodialog|organize">Organizer...</property>
                        <property name="visible">True</property>
                      <object class="GtkButton" id="new">
                        <property name="label">_New</property>
                        <property name="can_focus">True</property>
                        <property name="receives_default">True</property>
                        <property name="no_show_all">True</property>
                        <property name="use_underline">True</property>
                      </object>
                      <packing>
                        <property name="expand">False</property>
@@ -312,11 +395,12 @@
                      </packing>
                    </child>
                    <child>
                      <object class="GtkButton" id="newlibrary">
                        <property name="label" translatable="yes" context="basicmacrodialog|newlibrary">New Library</property>
                      <object class="GtkButton" id="organize">
                        <property name="label" translatable="yes" context="basicmacrodialog|organize">Organizer...</property>
                        <property name="visible">True</property>
                        <property name="can_focus">True</property>
                        <property name="receives_default">True</property>
                        <property name="no_show_all">True</property>
                        <property name="use_underline">True</property>
                      </object>
                      <packing>
                        <property name="expand">False</property>
@@ -325,11 +409,12 @@
                      </packing>
                    </child>
                    <child>
                      <object class="GtkButton" id="newmodule">
                        <property name="label" translatable="yes" context="basicmacrodialog|newmodule">New Module</property>
                      <object class="GtkButton" id="newlibrary">
                        <property name="label" translatable="yes" context="basicmacrodialog|newlibrary">New Library</property>
                        <property name="can_focus">True</property>
                        <property name="receives_default">True</property>
                        <property name="no_show_all">True</property>
                        <property name="use_underline">True</property>
                      </object>
                      <packing>
                        <property name="expand">False</property>
@@ -337,6 +422,20 @@
                        <property name="position">5</property>
                      </packing>
                    </child>
                    <child>
                      <object class="GtkButton" id="newmodule">
                        <property name="label" translatable="yes" context="basicmacrodialog|newmodule">New Module</property>
                        <property name="can_focus">True</property>
                        <property name="receives_default">True</property>
                        <property name="no_show_all">True</property>
                        <property name="use_underline">True</property>
                      </object>
                      <packing>
                        <property name="expand">False</property>
                        <property name="fill">True</property>
                        <property name="position">6</property>
                      </packing>
                    </child>
                  </object>
                  <packing>
                    <property name="left_attach">2</property>
@@ -366,7 +465,7 @@
      </object>
    </child>
    <action-widgets>
      <action-widget response="0">run</action-widget>
      <action-widget response="-5">ok</action-widget>
      <action-widget response="-7">close</action-widget>
      <action-widget response="-11">help</action-widget>
    </action-widgets>
diff --git a/basctl/uiconfig/basicide/ui/managebreakpoints.ui b/basctl/uiconfig/basicide/ui/managebreakpoints.ui
index 1f82466..66cbb93 100644
--- a/basctl/uiconfig/basicide/ui/managebreakpoints.ui
+++ b/basctl/uiconfig/basicide/ui/managebreakpoints.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.22.1 -->
<interface domain="basctl">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
@@ -182,6 +182,7 @@
                                <property name="headers_clickable">False</property>
                                <property name="search_column">0</property>
                                <property name="show_expanders">False</property>
                                <property name="show_expanders">False</property>
                                <child internal-child="selection">
                                  <object class="GtkTreeSelection" id="treeview-selection1"/>
                                </child>
diff --git a/basctl/uiconfig/basicide/ui/managelanguages.ui b/basctl/uiconfig/basicide/ui/managelanguages.ui
index 510fcab..eac6607 100644
--- a/basctl/uiconfig/basicide/ui/managelanguages.ui
+++ b/basctl/uiconfig/basicide/ui/managelanguages.ui
@@ -158,6 +158,7 @@
                    <property name="can_focus">True</property>
                    <property name="hexpand">True</property>
                    <property name="vexpand">True</property>
                    <property name="show_expanders">False</property>
                    <child internal-child="selection">
                      <object class="GtkTreeSelection" id="treeview-selection1"/>
                    </child>
diff --git a/chart2/inc/chart.hrc b/chart2/inc/chart.hrc
new file mode 100644
index 0000000..8a11956
--- /dev/null
+++ b/chart2/inc/chart.hrc
@@ -0,0 +1,25 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
 * 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/.
 */

#ifndef INCLUDED_CHART_INC_CHART_HRC
#define INCLUDED_CHART_INC_CHART_HRC

#define NC_(Context, String) reinterpret_cast<char const *>(Context "\004" u8##String)

const char* CHART_TYPE[] =
{
    NC_("tp_ChartType|liststore1", "Bar"),
    NC_("tp_ChartType|liststore1", "Cylinder"),
    NC_("tp_ChartType|liststore1", "Cone"),
    NC_("tp_ChartType|liststore1", "Pyramid")
};

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/chart2/source/controller/dialogs/res_BarGeometry.cxx b/chart2/source/controller/dialogs/res_BarGeometry.cxx
index 132422b..d067ae7 100644
--- a/chart2/source/controller/dialogs/res_BarGeometry.cxx
+++ b/chart2/source/controller/dialogs/res_BarGeometry.cxx
@@ -19,6 +19,8 @@

#include "res_BarGeometry.hxx"
#include <vcl/builder.hxx>
#include <ResId.hxx>
#include <chart.hrc>

namespace chart
{
@@ -27,6 +29,8 @@ BarGeometryResources::BarGeometryResources(weld::Builder* pBuilder)
    : m_xFT_Geometry(pBuilder->weld_label("shapeft"))
    , m_xLB_Geometry(pBuilder->weld_tree_view("shape"))
{
    for (size_t i = 0; i < SAL_N_ELEMENTS(CHART_TYPE); ++i)
        m_xLB_Geometry->append_text(SchResId(CHART_TYPE[i]));
    m_xLB_Geometry->set_size_request(-1, m_xLB_Geometry->get_height_rows(4));
}

diff --git a/chart2/uiconfig/ui/tp_ChartType.ui b/chart2/uiconfig/ui/tp_ChartType.ui
index 987a709..9e00c32 100644
--- a/chart2/uiconfig/ui/tp_ChartType.ui
+++ b/chart2/uiconfig/ui/tp_ChartType.ui
@@ -9,29 +9,15 @@
    <property name="step_increment">1</property>
    <property name="page_increment">10</property>
  </object>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
      <!-- column-name id -->
      <column type="gchararray"/>
    </columns>
    <data>
      <row>
        <col id="0" translatable="yes" context="tp_ChartType|liststore1">Bar</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="tp_ChartType|liststore1">Cylinder</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="tp_ChartType|liststore1">Cone</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="tp_ChartType|liststore1">Pyramid</col>
      </row>
    </data>
  </object>
  <object class="GtkListStore" id="liststore2">
  <object class="GtkTreeStore" id="liststore2">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/cui/inc/numcategories.hrc b/cui/inc/numcategories.hrc
new file mode 100644
index 0000000..be72fce
--- /dev/null
+++ b/cui/inc/numcategories.hrc
@@ -0,0 +1,32 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
 * 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/.
 */

#ifndef INCLUDED_CUI_INC_NUM_CATEGORIES_HRC
#define INCLUDED_CUI_INC_NUM_CATEGORIES_HRC

#define NC_(Context, String) reinterpret_cast<char const *>(Context "\004" u8##String)

const char* NUM_CATEGORIES[] =
{
    NC_("numberingformatpage|liststore1", "All"),
    NC_("numberingformatpage|liststore1", "User-defined"),
    NC_("numberingformatpage|liststore1", "Number"),
    NC_("numberingformatpage|liststore1", "Percent"),
    NC_("numberingformatpage|liststore1", "Currency"),
    NC_("numberingformatpage|liststore1", "Date"),
    NC_("numberingformatpage|liststore1", "Time"),
    NC_("numberingformatpage|liststore1", "Scientific"),
    NC_("numberingformatpage|liststore1", "Fraction"),
    NC_("numberingformatpage|liststore1", "Boolean Value"),
    NC_("numberingformatpage|liststore1", "Text")
};

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/inc/twolines.hrc b/cui/inc/twolines.hrc
new file mode 100644
index 0000000..d77f9ab
--- /dev/null
+++ b/cui/inc/twolines.hrc
@@ -0,0 +1,44 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
 * 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/.
 */

#ifndef INCLUDED_CUI_INC_TWO_LINES_HRC
#define INCLUDED_CUI_INC_TWO_LINES_HRC

#define NC_(Context, String) reinterpret_cast<char const *>(Context "\004" u8##String)

#define CHRDLG_ENCLOSE_NONE                 0
#define CHRDLG_ENCLOSE_ROUND                1
#define CHRDLG_ENCLOSE_SQUARE               2
#define CHRDLG_ENCLOSE_POINTED              3
#define CHRDLG_ENCLOSE_CURVED               4
#define CHRDLG_ENCLOSE_SPECIAL_CHAR         5

const std::pair<const char*, sal_uInt16> TWOLINE_OPEN[] =
{
    { NC_("twolinespage|liststore1", "(None)"), CHRDLG_ENCLOSE_NONE },
    { NC_("twolinespage|liststore1", "("), CHRDLG_ENCLOSE_ROUND },
    { NC_("twolinespage|liststore1", "["), CHRDLG_ENCLOSE_SQUARE },
    { NC_("twolinespage|liststore1", "<"), CHRDLG_ENCLOSE_POINTED },
    { NC_("twolinespage|liststore1", "{"), CHRDLG_ENCLOSE_CURVED },
    { NC_("twolinespage|liststore1", "Other Characters..."), CHRDLG_ENCLOSE_SPECIAL_CHAR }
};

const std::pair<const char*, sal_uInt16> TWOLINE_CLOSE[] =
{
    { NC_("twolinespage|liststore2", "(None)"), CHRDLG_ENCLOSE_NONE },
    { NC_("twolinespage|liststore2", ")"), CHRDLG_ENCLOSE_ROUND },
    { NC_("twolinespage|liststore2", "]"), CHRDLG_ENCLOSE_SQUARE },
    { NC_("twolinespage|liststore2", ">"), CHRDLG_ENCLOSE_POINTED },
    { NC_("twolinespage|liststore2", "}"), CHRDLG_ENCLOSE_CURVED },
    { NC_("twolinespage|liststore2", "Other Characters..."), CHRDLG_ENCLOSE_SPECIAL_CHAR }
};

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/tabpages/chardlg.cxx b/cui/source/tabpages/chardlg.cxx
index a49714e..8ac25399 100644
--- a/cui/source/tabpages/chardlg.cxx
+++ b/cui/source/tabpages/chardlg.cxx
@@ -66,6 +66,7 @@
#include <officecfg/Office/Common.hxx>
#include <svx/svxdlg.hxx>
#include <strings.hrc>
#include <twolines.hrc>
#include <svl/intitem.hxx>
#include <sfx2/request.hxx>
#include <svx/flagsdef.hxx>
@@ -3060,6 +3061,11 @@ SvxCharTwoLinesPage::SvxCharTwoLinesPage(TabPageParent pParent, const SfxItemSet
    , m_xStartBracketLB(m_xBuilder->weld_tree_view("startbracket"))
    , m_xEndBracketLB(m_xBuilder->weld_tree_view("endbracket"))
{
    for (size_t i = 0; i < SAL_N_ELEMENTS(TWOLINE_OPEN); ++i)
        m_xStartBracketLB->append(OUString::number(TWOLINE_OPEN[i].second), CuiResId(TWOLINE_OPEN[i].first));
    for (size_t i = 0; i < SAL_N_ELEMENTS(TWOLINE_CLOSE); ++i)
        m_xEndBracketLB->append(OUString::number(TWOLINE_CLOSE[i].second), CuiResId(TWOLINE_CLOSE[i].first));

    m_xPreviewWin.reset(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWin));
    Initialize();
}
diff --git a/cui/source/tabpages/chardlg.h b/cui/source/tabpages/chardlg.h
index 57751b6..b72beae 100644
--- a/cui/source/tabpages/chardlg.h
+++ b/cui/source/tabpages/chardlg.h
@@ -21,13 +21,6 @@

// define ----------------------------------------------------------------

#define CHRDLG_ENCLOSE_NONE                 0
#define CHRDLG_ENCLOSE_ROUND                1
#define CHRDLG_ENCLOSE_SQUARE               2
#define CHRDLG_ENCLOSE_POINTED              3
#define CHRDLG_ENCLOSE_CURVED               4
#define CHRDLG_ENCLOSE_SPECIAL_CHAR         5

#define CHRDLG_POSITION_OVER                0
#define CHRDLG_POSITION_UNDER               1

diff --git a/cui/source/tabpages/numfmt.cxx b/cui/source/tabpages/numfmt.cxx
index bbd756c..a134030 100644
--- a/cui/source/tabpages/numfmt.cxx
+++ b/cui/source/tabpages/numfmt.cxx
@@ -30,6 +30,7 @@
#include <svx/dialogs.hrc>
#include <svtools/colorcfg.hxx>

#include <numcategories.hrc>
#include <strings.hrc>

#include <svx/numinf.hxx>
@@ -218,6 +219,9 @@ SvxNumberFormatTabPage::SvxNumberFormatTabPage(TabPageParent pParent,
    , m_xLbLanguage(new LanguageBox(m_xBuilder->weld_combo_box("languagelb")))
    , m_xWndPreview(new weld::CustomWeld(*m_xBuilder, "preview", m_aWndPreview))
{
    for (size_t i = 0; i < SAL_N_ELEMENTS(NUM_CATEGORIES); ++i)
        m_xLbCategory->append_text(CuiResId(NUM_CATEGORIES[i]));

    auto nWidth = approximate_char_width() * 26;
    m_xLbCategory->set_size_request(nWidth, m_xLbCategory->get_height_rows(7));
    m_xLbFormat->set_size_request(nWidth, m_xLbFormat->get_height_rows(5));
diff --git a/cui/uiconfig/ui/acorexceptpage.ui b/cui/uiconfig/ui/acorexceptpage.ui
index c7848cd..9fa20b5 100644
--- a/cui/uiconfig/ui/acorexceptpage.ui
+++ b/cui/uiconfig/ui/acorexceptpage.ui
@@ -142,6 +142,7 @@
                    <property name="shadow_type">in</property>
                    <child>
                      <object class="GtkTreeView" id="abbrevlist:border">
                        <property name="show_expanders">False</property>
                        <property name="visible">True</property>
                        <property name="can_focus">True</property>
                        <property name="hexpand">True</property>
@@ -312,6 +313,7 @@
                    <property name="shadow_type">in</property>
                    <child>
                      <object class="GtkTreeView" id="doublelist:border">
                        <property name="show_expanders">False</property>
                        <property name="visible">True</property>
                        <property name="can_focus">True</property>
                        <property name="hexpand">True</property>
diff --git a/cui/uiconfig/ui/charnamepage.ui b/cui/uiconfig/ui/charnamepage.ui
index 2f68c6a..25cfe43 100644
--- a/cui/uiconfig/ui/charnamepage.ui
+++ b/cui/uiconfig/ui/charnamepage.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.22.1 -->
<interface domain="cui">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
@@ -18,7 +18,7 @@
    <property name="popup_set_width">False</property>
    <property name="popup_single_match">False</property>
  </object>
  <object class="GtkListStore" id="liststore2">
  <object class="GtkTreeStore" id="liststore2">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
@@ -34,7 +34,7 @@
    <property name="popup_set_width">False</property>
    <property name="popup_single_match">False</property>
  </object>
  <object class="GtkListStore" id="liststore3">
  <object class="GtkTreeStore" id="liststore3">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/cui/uiconfig/ui/galleryfilespage.ui b/cui/uiconfig/ui/galleryfilespage.ui
index c74a0118..9fd436d 100644
--- a/cui/uiconfig/ui/galleryfilespage.ui
+++ b/cui/uiconfig/ui/galleryfilespage.ui
@@ -67,6 +67,7 @@
            <property name="can_focus">True</property>
            <property name="hexpand">True</property>
            <property name="vexpand">True</property>
            <property name="show_expanders">False</property>
            <child internal-child="selection">
              <object class="GtkTreeSelection" id="treeview-selection1">
                <property name="mode">multiple</property>
diff --git a/cui/uiconfig/ui/hyperlinknewdocpage.ui b/cui/uiconfig/ui/hyperlinknewdocpage.ui
index 8657276..980c967 100644
--- a/cui/uiconfig/ui/hyperlinknewdocpage.ui
+++ b/cui/uiconfig/ui/hyperlinknewdocpage.ui
@@ -139,6 +139,7 @@
                    <property name="visible">True</property>
                    <property name="can_focus">True</property>
                    <property name="vexpand">True</property>
                    <property name="show_expanders">False</property>
                    <child internal-child="selection">
                      <object class="GtkTreeSelection" id="treeview-selection1"/>
                    </child>
diff --git a/cui/uiconfig/ui/insertoleobject.ui b/cui/uiconfig/ui/insertoleobject.ui
index 711a1c2..2a34863 100644
--- a/cui/uiconfig/ui/insertoleobject.ui
+++ b/cui/uiconfig/ui/insertoleobject.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.20.4 -->
<interface domain="cui">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/cui/uiconfig/ui/javaclasspathdialog.ui b/cui/uiconfig/ui/javaclasspathdialog.ui
index 7dd2d20..130fd4b 100644
--- a/cui/uiconfig/ui/javaclasspathdialog.ui
+++ b/cui/uiconfig/ui/javaclasspathdialog.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.20.4 -->
<interface domain="cui">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/cui/uiconfig/ui/javastartparametersdialog.ui b/cui/uiconfig/ui/javastartparametersdialog.ui
index 14bdff1..f83d261 100644
--- a/cui/uiconfig/ui/javastartparametersdialog.ui
+++ b/cui/uiconfig/ui/javastartparametersdialog.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.22.1 -->
<interface domain="cui">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/cui/uiconfig/ui/movemenu.ui b/cui/uiconfig/ui/movemenu.ui
index fdeb1ee..0dc7c58 100644
--- a/cui/uiconfig/ui/movemenu.ui
+++ b/cui/uiconfig/ui/movemenu.ui
@@ -12,7 +12,7 @@
    <property name="can_focus">False</property>
    <property name="stock">gtk-go-down</property>
  </object>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/cui/uiconfig/ui/numberingformatpage.ui b/cui/uiconfig/ui/numberingformatpage.ui
index 060a02b..e454bbd 100644
--- a/cui/uiconfig/ui/numberingformatpage.ui
+++ b/cui/uiconfig/ui/numberingformatpage.ui
@@ -32,48 +32,21 @@
    <property name="can_focus">False</property>
    <property name="icon_name">svx/res/nu03.png</property>
  </object>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name gchararray1 -->
      <!-- column-name text -->
      <column type="gchararray"/>
      <!-- column-name id -->
      <column type="gchararray"/>
      <!-- column-name image -->
      <column type="GdkPixbuf"/>
      <!-- column-name image -->
      <column type="CairoSurface"/>
      <!-- column-name textcolor -->
      <column type="GdkRGBA"/>
    </columns>
    <data>
      <row>
        <col id="0" translatable="yes" context="numberingformatpage|liststore1">All</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="numberingformatpage|liststore1">User-defined</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="numberingformatpage|liststore1">Number</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="numberingformatpage|liststore1">Percent</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="numberingformatpage|liststore1">Currency</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="numberingformatpage|liststore1">Date</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="numberingformatpage|liststore1">Time</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="numberingformatpage|liststore1">Scientific</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="numberingformatpage|liststore1">Fraction</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="numberingformatpage|liststore1">Boolean Value</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="numberingformatpage|liststore1">Text</col>
      </row>
    </data>
  </object>
  <object class="GtkListStore" id="liststore3">
  <object class="GtkTreeStore" id="liststore3">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/cui/uiconfig/ui/numberingoptionspage.ui b/cui/uiconfig/ui/numberingoptionspage.ui
index 7b64b2e..3baf861 100644
--- a/cui/uiconfig/ui/numberingoptionspage.ui
+++ b/cui/uiconfig/ui/numberingoptionspage.ui
@@ -58,7 +58,7 @@
      </object>
    </child>
  </object>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/cui/uiconfig/ui/numberingpositionpage.ui b/cui/uiconfig/ui/numberingpositionpage.ui
index e369e68..ce7b85b 100644
--- a/cui/uiconfig/ui/numberingpositionpage.ui
+++ b/cui/uiconfig/ui/numberingpositionpage.ui
@@ -33,7 +33,7 @@
    <property name="step_increment">0.01</property>
    <property name="page_increment">10</property>
  </object>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/cui/uiconfig/ui/optchartcolorspage.ui b/cui/uiconfig/ui/optchartcolorspage.ui
index cb83724..331eaff 100644
--- a/cui/uiconfig/ui/optchartcolorspage.ui
+++ b/cui/uiconfig/ui/optchartcolorspage.ui
@@ -31,6 +31,7 @@
                <property name="can_focus">True</property>
                <property name="hexpand">True</property>
                <property name="vexpand">True</property>
                <property name="show_expanders">False</property>
              </object>
            </child>
          </object>
diff --git a/cui/uiconfig/ui/paratabspage.ui b/cui/uiconfig/ui/paratabspage.ui
index c57876b..cf7e369 100644
--- a/cui/uiconfig/ui/paratabspage.ui
+++ b/cui/uiconfig/ui/paratabspage.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.22.1 -->
<interface domain="cui">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/cui/uiconfig/ui/pastespecial.ui b/cui/uiconfig/ui/pastespecial.ui
index 8931e42..6fd410d 100644
--- a/cui/uiconfig/ui/pastespecial.ui
+++ b/cui/uiconfig/ui/pastespecial.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.20.4 -->
<interface domain="cui">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/cui/uiconfig/ui/personalization_tab.ui b/cui/uiconfig/ui/personalization_tab.ui
index 36f41a4..afa4c5e 100644
--- a/cui/uiconfig/ui/personalization_tab.ui
+++ b/cui/uiconfig/ui/personalization_tab.ui
@@ -255,6 +255,7 @@
                    <child>
                      <object class="GtkTreeView" id="installed_personas:border">
                        <property name="can_focus">True</property>
                        <property name="show_expanders">False</property>
                        <child internal-child="selection">
                          <object class="GtkTreeSelection" id="treeview-selection2"/>
                        </child>
diff --git a/cui/uiconfig/ui/selectpathdialog.ui b/cui/uiconfig/ui/selectpathdialog.ui
index c8ac090..0900c1f 100644
--- a/cui/uiconfig/ui/selectpathdialog.ui
+++ b/cui/uiconfig/ui/selectpathdialog.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.20.4 -->
<interface domain="cui">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/cui/uiconfig/ui/showcoldialog.ui b/cui/uiconfig/ui/showcoldialog.ui
index 8d2d951..fb109b4 100644
--- a/cui/uiconfig/ui/showcoldialog.ui
+++ b/cui/uiconfig/ui/showcoldialog.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.22.1 -->
<interface domain="cui">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore2">
  <object class="GtkTreeStore" id="liststore2">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/cui/uiconfig/ui/spellingdialog.ui b/cui/uiconfig/ui/spellingdialog.ui
index 0173391..6ac62ae4 100644
--- a/cui/uiconfig/ui/spellingdialog.ui
+++ b/cui/uiconfig/ui/spellingdialog.ui
@@ -303,6 +303,7 @@
                <property name="can_focus">True</property>
                <property name="hexpand">True</property>
                <property name="vexpand">True</property>
                <property name="show_expanders">False</property>
                <child internal-child="selection">
                  <object class="GtkTreeSelection" id="treeview-selection1"/>
                </child>
diff --git a/cui/uiconfig/ui/tsaurldialog.ui b/cui/uiconfig/ui/tsaurldialog.ui
index 5991ad2..d1e330f 100644
--- a/cui/uiconfig/ui/tsaurldialog.ui
+++ b/cui/uiconfig/ui/tsaurldialog.ui
@@ -145,6 +145,7 @@
                        <property name="can_focus">True</property>
                        <property name="hexpand">True</property>
                        <property name="vexpand">True</property>
                        <property name="show_expanders">False</property>
                        <child internal-child="selection">
                          <object class="GtkTreeSelection" id="treeview-selection3"/>
                        </child>
diff --git a/cui/uiconfig/ui/twolinespage.ui b/cui/uiconfig/ui/twolinespage.ui
index e5cb2f9..2f6f428 100644
--- a/cui/uiconfig/ui/twolinespage.ui
+++ b/cui/uiconfig/ui/twolinespage.ui
@@ -2,73 +2,21 @@
<!-- Generated with glade 3.20.4 -->
<interface domain="cui">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
      <!-- column-name id -->
      <column type="gchararray"/>
    </columns>
    <data>
      <row>
        <col id="0" translatable="yes" context="twolinespage|liststore1">(None)</col>
        <col id="1">0</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="twolinespage|liststore1">(</col>
        <col id="1">1</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="twolinespage|liststore1">[</col>
        <col id="1">2</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="twolinespage|liststore1">&lt;</col>
        <col id="1">3</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="twolinespage|liststore1">{</col>
        <col id="1">4</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="twolinespage|liststore1">Other Characters...</col>
        <col id="1">5</col>
      </row>
    </data>
  </object>
  <object class="GtkListStore" id="liststore2">
  <object class="GtkTreeStore" id="liststore2">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
      <!-- column-name id -->
      <column type="gchararray"/>
    </columns>
    <data>
      <row>
        <col id="0" translatable="yes" context="twolinespage|liststore2">(None)</col>
        <col id="1">0</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="twolinespage|liststore2">)</col>
        <col id="1">1</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="twolinespage|liststore2">]</col>
        <col id="1">2</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="twolinespage|liststore2">&gt;</col>
        <col id="1">3</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="twolinespage|liststore2">}</col>
        <col id="1">4</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="twolinespage|liststore2">Other Characters...</col>
        <col id="1">5</col>
      </row>
    </data>
  </object>
  <object class="GtkBox" id="TwoLinesPage">
    <property name="visible">True</property>
diff --git a/dbaccess/uiconfig/ui/applycolpage.ui b/dbaccess/uiconfig/ui/applycolpage.ui
index 058f837..7def149 100644
--- a/dbaccess/uiconfig/ui/applycolpage.ui
+++ b/dbaccess/uiconfig/ui/applycolpage.ui
@@ -55,6 +55,7 @@
                    <property name="can_focus">True</property>
                    <property name="hexpand">True</property>
                    <property name="vexpand">True</property>
                    <property name="show_expanders">False</property>
                    <child internal-child="selection">
                      <object class="GtkTreeSelection" id="treeview-selection1"/>
                    </child>
@@ -72,6 +73,7 @@
                    <property name="can_focus">True</property>
                    <property name="hexpand">True</property>
                    <property name="vexpand">True</property>
                    <property name="show_expanders">False</property>
                    <child internal-child="selection">
                      <object class="GtkTreeSelection" id="treeview-selection3"/>
                    </child>
diff --git a/dbaccess/uiconfig/ui/choosedatasourcedialog.ui b/dbaccess/uiconfig/ui/choosedatasourcedialog.ui
index 6d05e65..b0e3db8 100644
--- a/dbaccess/uiconfig/ui/choosedatasourcedialog.ui
+++ b/dbaccess/uiconfig/ui/choosedatasourcedialog.ui
@@ -112,6 +112,7 @@
                <property name="can_focus">True</property>
                <property name="hexpand">True</property>
                <property name="vexpand">True</property>
                <property name="show_expanders">False</property>
                <child internal-child="selection">
                  <object class="GtkTreeSelection" id="treeview-selection1"/>
                </child>
diff --git a/dbaccess/uiconfig/ui/dbaseindexdialog.ui b/dbaccess/uiconfig/ui/dbaseindexdialog.ui
index 819d7ba..aaf6894 100644
--- a/dbaccess/uiconfig/ui/dbaseindexdialog.ui
+++ b/dbaccess/uiconfig/ui/dbaseindexdialog.ui
@@ -22,7 +22,7 @@
    <property name="can_focus">False</property>
    <property name="icon_name">dbaccess/res/all_right.png</property>
  </object>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
@@ -30,7 +30,7 @@
      <column type="gchararray"/>
    </columns>
  </object>
  <object class="GtkListStore" id="liststore2">
  <object class="GtkTreeStore" id="liststore2">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/dbaccess/uiconfig/ui/parametersdialog.ui b/dbaccess/uiconfig/ui/parametersdialog.ui
index 07a6c07..f86166d 100644
--- a/dbaccess/uiconfig/ui/parametersdialog.ui
+++ b/dbaccess/uiconfig/ui/parametersdialog.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.22.1 -->
<interface domain="dba">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/dbaccess/uiconfig/ui/sqlexception.ui b/dbaccess/uiconfig/ui/sqlexception.ui
index 7e0b751..488f78e 100644
--- a/dbaccess/uiconfig/ui/sqlexception.ui
+++ b/dbaccess/uiconfig/ui/sqlexception.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.20.2 -->
<interface domain="dba">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/desktop/uiconfig/ui/dependenciesdialog.ui b/desktop/uiconfig/ui/dependenciesdialog.ui
index ecb0faf..e3f2ddc 100644
--- a/desktop/uiconfig/ui/dependenciesdialog.ui
+++ b/desktop/uiconfig/ui/dependenciesdialog.ui
@@ -72,6 +72,7 @@
                <property name="can_focus">True</property>
                <property name="hexpand">True</property>
                <property name="vexpand">True</property>
                <property name="show_expanders">False</property>
                <child internal-child="selection">
                  <object class="GtkTreeSelection" id="treeview-selection1"/>
                </child>
diff --git a/extensions/uiconfig/sabpilot/ui/contentfieldpage.ui b/extensions/uiconfig/sabpilot/ui/contentfieldpage.ui
index 49d70a0..411d6bb 100644
--- a/extensions/uiconfig/sabpilot/ui/contentfieldpage.ui
+++ b/extensions/uiconfig/sabpilot/ui/contentfieldpage.ui
@@ -47,6 +47,7 @@
                <property name="can_focus">True</property>
                <property name="hexpand">True</property>
                <property name="vexpand">True</property>
                <property name="show_expanders">False</property>
                <child internal-child="selection">
                  <object class="GtkTreeSelection" id="treeview-selection1"/>
                </child>
diff --git a/extensions/uiconfig/sabpilot/ui/contenttablepage.ui b/extensions/uiconfig/sabpilot/ui/contenttablepage.ui
index 3df96fe..ee4ec76e3 100644
--- a/extensions/uiconfig/sabpilot/ui/contenttablepage.ui
+++ b/extensions/uiconfig/sabpilot/ui/contenttablepage.ui
@@ -212,6 +212,7 @@ Choose the table from which the data should be used as basis for the list conten
                    <property name="can_focus">True</property>
                    <property name="hexpand">True</property>
                    <property name="vexpand">True</property>
                    <property name="show_expanders">False</property>
                    <child internal-child="selection">
                      <object class="GtkTreeSelection" id="treeview-selection1"/>
                    </child>
diff --git a/extensions/uiconfig/sabpilot/ui/gridfieldsselectionpage.ui b/extensions/uiconfig/sabpilot/ui/gridfieldsselectionpage.ui
index 382f94f..2900629 100644
--- a/extensions/uiconfig/sabpilot/ui/gridfieldsselectionpage.ui
+++ b/extensions/uiconfig/sabpilot/ui/gridfieldsselectionpage.ui
@@ -186,6 +186,7 @@
                    <property name="can_focus">True</property>
                    <property name="hexpand">True</property>
                    <property name="vexpand">True</property>
                    <property name="show_expanders">False</property>
                    <child internal-child="selection">
                      <object class="GtkTreeSelection" id="treeview-selection1"/>
                    </child>
@@ -313,6 +314,7 @@
                    <property name="can_focus">True</property>
                    <property name="hexpand">True</property>
                    <property name="vexpand">True</property>
                    <property name="show_expanders">False</property>
                    <child internal-child="selection">
                      <object class="GtkTreeSelection" id="treeview-selection"/>
                    </child>
diff --git a/extensions/uiconfig/sabpilot/ui/groupradioselectionpage.ui b/extensions/uiconfig/sabpilot/ui/groupradioselectionpage.ui
index 7ada988..0e02c2c 100644
--- a/extensions/uiconfig/sabpilot/ui/groupradioselectionpage.ui
+++ b/extensions/uiconfig/sabpilot/ui/groupradioselectionpage.ui
@@ -189,6 +189,7 @@
                    <property name="can_focus">True</property>
                    <property name="hexpand">True</property>
                    <property name="vexpand">True</property>
                    <property name="show_expanders">False</property>
                    <child internal-child="selection">
                      <object class="GtkTreeSelection" id="treeview-selection"/>
                    </child>
diff --git a/extensions/uiconfig/sabpilot/ui/optionvaluespage.ui b/extensions/uiconfig/sabpilot/ui/optionvaluespage.ui
index 97c4fe5..360f338 100644
--- a/extensions/uiconfig/sabpilot/ui/optionvaluespage.ui
+++ b/extensions/uiconfig/sabpilot/ui/optionvaluespage.ui
@@ -106,6 +106,7 @@
            <property name="can_focus">True</property>
            <property name="hexpand">True</property>
            <property name="vexpand">True</property>
            <property name="show_expanders">False</property>
            <child internal-child="selection">
              <object class="GtkTreeSelection" id="treeview-selection1"/>
            </child>
diff --git a/extensions/uiconfig/sabpilot/ui/selecttablepage.ui b/extensions/uiconfig/sabpilot/ui/selecttablepage.ui
index 2f7ff28..a1c87bf 100644
--- a/extensions/uiconfig/sabpilot/ui/selecttablepage.ui
+++ b/extensions/uiconfig/sabpilot/ui/selecttablepage.ui
@@ -34,6 +34,7 @@ Please select the one you mainly want to work with:</property>
        <property name="can_focus">True</property>
        <property name="hexpand">True</property>
        <property name="vexpand">True</property>
        <property name="show_expanders">False</property>
        <child internal-child="selection">
          <object class="GtkTreeSelection" id="treeview-selection2"/>
        </child>
diff --git a/extensions/uiconfig/sabpilot/ui/tableselectionpage.ui b/extensions/uiconfig/sabpilot/ui/tableselectionpage.ui
index 7866d1f..45be3b6 100644
--- a/extensions/uiconfig/sabpilot/ui/tableselectionpage.ui
+++ b/extensions/uiconfig/sabpilot/ui/tableselectionpage.ui
@@ -88,6 +88,7 @@ Please note that the settings made on this page will take effect immediately upo
                        <property name="can_focus">True</property>
                        <property name="hexpand">True</property>
                        <property name="vexpand">True</property>
                        <property name="show_expanders">False</property>
                        <child internal-child="selection">
                          <object class="GtkTreeSelection" id="treeview-selection2"/>
                        </child>
@@ -148,6 +149,7 @@ Please note that the settings made on this page will take effect immediately upo
                        <property name="can_focus">True</property>
                        <property name="hexpand">True</property>
                        <property name="vexpand">True</property>
                        <property name="show_expanders">False</property>
                        <child internal-child="selection">
                          <object class="GtkTreeSelection" id="treeview-selection"/>
                        </child>
diff --git a/extensions/uiconfig/sbibliography/ui/choosedatasourcedialog.ui b/extensions/uiconfig/sbibliography/ui/choosedatasourcedialog.ui
index 2af0d25..6039efd 100644
--- a/extensions/uiconfig/sbibliography/ui/choosedatasourcedialog.ui
+++ b/extensions/uiconfig/sbibliography/ui/choosedatasourcedialog.ui
@@ -76,6 +76,7 @@
                    <property name="can_focus">True</property>
                    <property name="hexpand">True</property>
                    <property name="vexpand">True</property>
                    <property name="show_expanders">False</property>
                    <child internal-child="selection">
                      <object class="GtkTreeSelection" id="treeview-selection1"/>
                    </child>
diff --git a/extensions/uiconfig/spropctrlr/ui/listselectdialog.ui b/extensions/uiconfig/spropctrlr/ui/listselectdialog.ui
index 19a3740..30eab96 100644
--- a/extensions/uiconfig/spropctrlr/ui/listselectdialog.ui
+++ b/extensions/uiconfig/spropctrlr/ui/listselectdialog.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.22.1 -->
<interface domain="pcr">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore2">
  <object class="GtkTreeStore" id="liststore2">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/extras/source/glade/libreoffice-catalog.xml.in b/extras/source/glade/libreoffice-catalog.xml.in
index 1f1e3cd..294ed10 100644
--- a/extras/source/glade/libreoffice-catalog.xml.in
+++ b/extras/source/glade/libreoffice-catalog.xml.in
@@ -280,11 +280,8 @@
    <glade-widget-class title="Glossary List" name="swuilo-SwGlossaryGroupTLB"
                        generic-name="Glossary List" parent="GtkTreeView"
                        icon-name="widget-gtk-treeview"/>
    <glade-widget-class title="Macro Library" name="basctllo-TreeListBox"
                        generic-name="Macro Library List" parent="GtkTreeView"
                        icon-name="widget-gtk-treeview"/>
    <glade-widget-class title="Extended Macro Library" name="basctllo-ExtTreeListBox"
                        generic-name="Extended Macro Library List" parent="basctllo-TreeListBox"
                        generic-name="Extended Macro Library List" parent="GtkTreeView"
                        icon-name="widget-gtk-treeview"/>
    <glade-widget-class title="Tree List" name="vcllo-SvTreeListBox"
                        generic-name="Tree List" parent="GtkTreeView"
diff --git a/filter/uiconfig/ui/warnpdfdialog.ui b/filter/uiconfig/ui/warnpdfdialog.ui
index c63953a..ef3c80e 100644
--- a/filter/uiconfig/ui/warnpdfdialog.ui
+++ b/filter/uiconfig/ui/warnpdfdialog.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.20.2 -->
<interface domain="flt">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/include/sfx2/strings.hrc b/include/sfx2/strings.hrc
index 6eee034..f02efc5 100644
--- a/include/sfx2/strings.hrc
+++ b/include/sfx2/strings.hrc
@@ -156,6 +156,7 @@
#define STR_STANDARD                            NC_("STR_STANDARD", "Standard")
#define RID_SVXSTR_FILELINK                     NC_("RID_SVXSTR_FILELINK", "Document")
#define STR_NONE                                NC_("STR_NONE", "- None -")
#define STR_CATEGORY_NONE                       NC_("saveastemplatedlg|categorylist", "None")
#define RID_SVXSTR_GRAFIKLINK                   NC_("RID_SVXSTR_GRAFIKLINK", "Image")
#define STR_SFX_FILTERNAME_ALL                  NC_("STR_SFX_FILTERNAME_ALL", "All files")
#define STR_SFX_FILTERNAME_PDF                  NC_("STR_SFX_FILTERNAME_PDF", "PDF files")
diff --git a/include/vcl/builder.hxx b/include/vcl/builder.hxx
index 74fc3b4..5cc4c20 100644
--- a/include/vcl/builder.hxx
+++ b/include/vcl/builder.hxx
@@ -375,7 +375,7 @@ private:
    void        handleMenuChild(PopupMenu *pParent, xmlreader::XmlReader &reader);
    void        handleMenuObject(PopupMenu *pParent, xmlreader::XmlReader &reader);

    void        handleListStore(xmlreader::XmlReader &reader, const OString &rID);
    void        handleListStore(xmlreader::XmlReader &reader, const OString &rID, const OString &rClass);
    void        handleRow(xmlreader::XmlReader &reader, const OString &rID);
    void        handleTabChild(vcl::Window *pParent, xmlreader::XmlReader &reader);
    void        handleMenu(xmlreader::XmlReader &reader, const OString &rID);
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index a5a0c7c..0d3db5f 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -42,8 +42,8 @@ protected:
    Link<Widget&, void> m_aFocusInHdl;
    Link<Widget&, void> m_aFocusOutHdl;

    void signal_focus_in() { return m_aFocusInHdl.Call(*this); }
    void signal_focus_out() { return m_aFocusOutHdl.Call(*this); }
    void signal_focus_in() { m_aFocusInHdl.Call(*this); }
    void signal_focus_out() { m_aFocusOutHdl.Call(*this); }

public:
    virtual void set_sensitive(bool sensitive) = 0;
@@ -366,35 +366,65 @@ public:
    bool get_value_changed_from_saved() const { return m_sSavedValue != get_active_text(); }
};

class VCL_DLLPUBLIC TreeIter
{
private:
    TreeIter(const TreeIter&) = delete;
    TreeIter& operator=(const TreeIter&) = delete;

public:
    TreeIter() {}
    virtual ~TreeIter() {}
};

class VCL_DLLPUBLIC TreeView : virtual public Container
{
protected:
    Link<TreeView&, void> m_aChangeHdl;
    Link<TreeView&, void> m_aRowActivatedHdl;
    Link<TreeIter&, bool> m_aExpandingHdl;

    void signal_changed() { m_aChangeHdl.Call(*this); }
    void signal_row_activated() { m_aRowActivatedHdl.Call(*this); }
    bool signal_expanding(TreeIter& rIter) { return m_aExpandingHdl.Call(rIter); }

public:
    virtual void insert(int pos, const OUString& rStr, const OUString* pId,
                        const OUString* pIconName, VirtualDevice* pImageSurface)
    virtual void insert(weld::TreeIter* pParent, int pos, const OUString& rStr, const OUString* pId,
                        const OUString* pIconName, VirtualDevice* pImageSurface,
                        const OUString* pExpanderName, bool bChildrenOnDemand)
        = 0;

    virtual void set_expander_image(const weld::TreeIter& rIter, const OUString& rExpanderName) = 0;

    void insert(int pos, const OUString& rStr, const OUString* pId, const OUString* pIconName,
                VirtualDevice* pImageSurface)
    {
        insert(nullptr, pos, rStr, pId, pIconName, pImageSurface, nullptr, false);
    }
    void insert_text(int pos, const OUString& rStr)
    {
        insert(pos, rStr, nullptr, nullptr, nullptr);
        insert(nullptr, pos, rStr, nullptr, nullptr, nullptr, nullptr, false);
    }
    void append_text(const OUString& rStr) { insert(-1, rStr, nullptr, nullptr, nullptr); }
    void append_text(const OUString& rStr)
    {
        insert(nullptr, -1, rStr, nullptr, nullptr, nullptr, nullptr, false);
    }
    void append(const OUString& rId, const OUString& rStr)
    {
        insert(-1, rStr, &rId, nullptr, nullptr);
        insert(nullptr, -1, rStr, &rId, nullptr, nullptr, nullptr, false);
    }
    void append(const OUString& rId, const OUString& rStr, const OUString& rImage)
    {
        insert(-1, rStr, &rId, &rImage, nullptr);
        insert(nullptr, -1, rStr, &rId, &rImage, nullptr, nullptr, false);
    }
    void append(weld::TreeIter* pParent, const OUString& rId, const OUString& rStr,
                const OUString& rImage)
    {
        insert(pParent, -1, rStr, &rId, &rImage, nullptr, nullptr, false);
    }
    void append(const OUString& rId, const OUString& rStr, VirtualDevice& rImage)
    {
        insert(-1, rStr, &rId, nullptr, &rImage);
        insert(nullptr, -1, rStr, &rId, nullptr, &rImage, nullptr, false);
    }

    void connect_changed(const Link<TreeView&, void>& rLink) { m_aChangeHdl = rLink; }
@@ -435,6 +465,31 @@ public:
    OUString get_selected_id() const { return get_id(get_selected_index()); }
    void select_id(const OUString& rId) { select(find_id(rId)); }

    //via iter
    virtual std::unique_ptr<TreeIter> make_iterator(const TreeIter* pOrig = nullptr) const = 0;
    virtual void copy_iterator(const TreeIter& rSource, TreeIter& rDest) const = 0;
    virtual bool get_selected(TreeIter* pIter) const = 0;
    virtual bool get_cursor(TreeIter* pIter) const = 0;
    virtual void set_cursor(const TreeIter& rIter) = 0;
    virtual bool get_iter_first(TreeIter& rIter) const = 0;
    // set iter to point to next node at the current level
    virtual bool iter_next_sibling(TreeIter& rIter) const = 0;
    // set iter to point to next node, depth first, then sibling
    virtual bool iter_next(TreeIter& rIter) const = 0;
    virtual bool iter_children(TreeIter& rIter) const = 0;
    virtual bool iter_parent(TreeIter& rIter) const = 0;
    virtual int get_iter_depth(const TreeIter& rIter) const = 0;
    virtual bool iter_has_child(const TreeIter& rIter) const = 0;
    virtual void remove(const TreeIter& rIter) = 0;
    virtual void select(const TreeIter& rIter) = 0;
    virtual void unselect(const TreeIter& rIter) = 0;
    virtual bool get_row_expanded(const TreeIter& rIter) const = 0;
    virtual void expand_row(TreeIter& rIter) = 0;
    virtual OUString get_text(const TreeIter& rIter) const = 0;
    virtual OUString get_id(const TreeIter& rIter) const = 0;

    void connect_expanding(const Link<TreeIter&, bool>& rLink) { m_aExpandingHdl = rLink; }

    //all of them
    void select_all() { unselect(-1); }
    void unselect_all() { select(-1); }
diff --git a/sc/inc/subtotals.hrc b/sc/inc/subtotals.hrc
new file mode 100644
index 0000000..233d47f
--- /dev/null
+++ b/sc/inc/subtotals.hrc
@@ -0,0 +1,42 @@
/* -*- 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/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#ifndef INCLUDED_SC_INC_SUBTOTALS_HRC
#define INCLUDED_SC_INC_SUBTOTALS_HRC

#define NC_(Context, String) reinterpret_cast<char const *>(Context "\004" u8##String)

const char* SCSTR_SUBTOTALS[] =
{
    NC_("subtotalgrppage|liststore1", "Sum"),
    NC_("subtotalgrppage|liststore1", "Count"),
    NC_("subtotalgrppage|liststore1", "Average"),
    NC_("subtotalgrppage|liststore1", "Max"),
    NC_("subtotalgrppage|liststore1", "Min"),
    NC_("subtotalgrppage|liststore1", "Product"),
    NC_("subtotalgrppage|liststore1", "Count (numbers only)"),
    NC_("subtotalgrppage|liststore1", "StDev (Sample)"),
    NC_("subtotalgrppage|liststore1", "StDevP (Population)"),
    NC_("subtotalgrppage|liststore1", "Var (Sample)"),
    NC_("subtotalgrppage|liststore1", "VarP (Population)")
};

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/dbgui/tpsubt.cxx b/sc/source/ui/dbgui/tpsubt.cxx
index 36b1d8a..8d02700 100644
--- a/sc/source/ui/dbgui/tpsubt.cxx
+++ b/sc/source/ui/dbgui/tpsubt.cxx
@@ -28,6 +28,7 @@
#include <scresid.hxx>
#include <sc.hrc>
#include <strings.hrc>
#include <subtotals.hrc>

#include <subtdlg.hxx>
#include <tpsubt.hxx>
@@ -54,6 +55,9 @@ ScTpSubTotalGroup::ScTpSubTotalGroup( vcl::Window* pParent,
    get(mpLbColumns, "columns");
    get(mpLbFunctions, "functions");

    for (size_t i = 0; i < SAL_N_ELEMENTS(SCSTR_SUBTOTALS); ++i)
        mpLbFunctions->InsertEntry(ScResId(SCSTR_SUBTOTALS[i]));

    long nHeight = mpLbColumns->GetTextHeight() * 14;
    mpLbColumns->set_height_request(nHeight);
    mpLbFunctions->set_height_request(nHeight);
diff --git a/sc/uiconfig/scalc/ui/autoformattable.ui b/sc/uiconfig/scalc/ui/autoformattable.ui
index cddccf1..eedb299 100644
--- a/sc/uiconfig/scalc/ui/autoformattable.ui
+++ b/sc/uiconfig/scalc/ui/autoformattable.ui
@@ -162,6 +162,7 @@
                                <property name="visible">True</property>
                                <property name="can_focus">True</property>
                                <property name="vexpand">True</property>
                                <property name="show_expanders">False</property>
                                <child internal-child="selection">
                                  <object class="GtkTreeSelection" id="treeview-selection1"/>
                                </child>
diff --git a/sc/uiconfig/scalc/ui/consolidatedialog.ui b/sc/uiconfig/scalc/ui/consolidatedialog.ui
index a73e899..384b5d2 100644
--- a/sc/uiconfig/scalc/ui/consolidatedialog.ui
+++ b/sc/uiconfig/scalc/ui/consolidatedialog.ui
@@ -148,6 +148,7 @@
                <property name="can_focus">True</property>
                <property name="hexpand">True</property>
                <property name="vexpand">True</property>
                <property name="show_expanders">False</property>
                <child internal-child="selection">
                  <object class="GtkTreeSelection" id="treeview-selection1">
                    <property name="mode">multiple</property>
diff --git a/sc/uiconfig/scalc/ui/externaldata.ui b/sc/uiconfig/scalc/ui/externaldata.ui
index 449cce7..5f43901 100644
--- a/sc/uiconfig/scalc/ui/externaldata.ui
+++ b/sc/uiconfig/scalc/ui/externaldata.ui
@@ -9,7 +9,7 @@
    <property name="step_increment">1</property>
    <property name="page_increment">10</property>
  </object>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/sc/uiconfig/scalc/ui/functionpanel.ui b/sc/uiconfig/scalc/ui/functionpanel.ui
index a6a7264..2c8f2f2 100644
--- a/sc/uiconfig/scalc/ui/functionpanel.ui
+++ b/sc/uiconfig/scalc/ui/functionpanel.ui
@@ -89,6 +89,7 @@
                    <property name="can_focus">True</property>
                    <property name="hexpand">True</property>
                    <property name="vexpand">True</property>
                    <property name="show_expanders">False</property>
                    <child internal-child="selection">
                      <object class="GtkTreeSelection"/>
                    </child>
diff --git a/sc/uiconfig/scalc/ui/insertsheet.ui b/sc/uiconfig/scalc/ui/insertsheet.ui
index 1df67c6..c6a54c8 100644
--- a/sc/uiconfig/scalc/ui/insertsheet.ui
+++ b/sc/uiconfig/scalc/ui/insertsheet.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.22.1 -->
<interface domain="sc">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/sc/uiconfig/scalc/ui/movecopysheet.ui b/sc/uiconfig/scalc/ui/movecopysheet.ui
index f3e21cc..1da0b27 100644
--- a/sc/uiconfig/scalc/ui/movecopysheet.ui
+++ b/sc/uiconfig/scalc/ui/movecopysheet.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.20.4 -->
<interface domain="sc">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/sc/uiconfig/scalc/ui/namerangesdialog.ui b/sc/uiconfig/scalc/ui/namerangesdialog.ui
index 9f5588b..667ed4a 100644
--- a/sc/uiconfig/scalc/ui/namerangesdialog.ui
+++ b/sc/uiconfig/scalc/ui/namerangesdialog.ui
@@ -281,6 +281,7 @@
                        <property name="can_focus">True</property>
                        <property name="hexpand">True</property>
                        <property name="vexpand">True</property>
                        <property name="show_expanders">False</property>
                        <child internal-child="selection">
                          <object class="GtkTreeSelection" id="treeview-selection1"/>
                        </child>
diff --git a/sc/uiconfig/scalc/ui/optsortlists.ui b/sc/uiconfig/scalc/ui/optsortlists.ui
index 3703245..a471882 100644
--- a/sc/uiconfig/scalc/ui/optsortlists.ui
+++ b/sc/uiconfig/scalc/ui/optsortlists.ui
@@ -134,6 +134,7 @@
                <property name="can_focus">True</property>
                <property name="hexpand">True</property>
                <property name="vexpand">True</property>
                <property name="show_expanders">False</property>
                <child internal-child="selection">
                  <object class="GtkTreeSelection" id="treeview-selection1"/>
                </child>
diff --git a/sc/uiconfig/scalc/ui/selectrange.ui b/sc/uiconfig/scalc/ui/selectrange.ui
index 23944b5..7528240 100644
--- a/sc/uiconfig/scalc/ui/selectrange.ui
+++ b/sc/uiconfig/scalc/ui/selectrange.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.22.1 -->
<interface domain="sc">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/sc/uiconfig/scalc/ui/showdetaildialog.ui b/sc/uiconfig/scalc/ui/showdetaildialog.ui
index 75b7257..13fdb58 100644
--- a/sc/uiconfig/scalc/ui/showdetaildialog.ui
+++ b/sc/uiconfig/scalc/ui/showdetaildialog.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.20.4 -->
<interface domain="sc">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/sc/uiconfig/scalc/ui/showsheetdialog.ui b/sc/uiconfig/scalc/ui/showsheetdialog.ui
index a881055..a26d155 100644
--- a/sc/uiconfig/scalc/ui/showsheetdialog.ui
+++ b/sc/uiconfig/scalc/ui/showsheetdialog.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.20.4 -->
<interface domain="sc">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/sc/uiconfig/scalc/ui/subtotalgrppage.ui b/sc/uiconfig/scalc/ui/subtotalgrppage.ui
index fffa2f7..add6750 100644
--- a/sc/uiconfig/scalc/ui/subtotalgrppage.ui
+++ b/sc/uiconfig/scalc/ui/subtotalgrppage.ui
@@ -2,46 +2,11 @@
<interface domain="sc">
  <requires lib="gtk+" version="3.18"/>
  <requires lib="LibreOffice" version="1.0"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name gchararray1 -->
      <column type="gchararray"/>
    </columns>
    <data>
      <row>
        <col id="0" translatable="yes" context="subtotalgrppage|liststore1">Sum</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="subtotalgrppage|liststore1">Count</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="subtotalgrppage|liststore1">Average</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="subtotalgrppage|liststore1">Max</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="subtotalgrppage|liststore1">Min</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="subtotalgrppage|liststore1">Product</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="subtotalgrppage|liststore1">Count (numbers only)</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="subtotalgrppage|liststore1">StDev (Sample)</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="subtotalgrppage|liststore1">StDevP (Population)</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="subtotalgrppage|liststore1">Var (Sample)</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="subtotalgrppage|liststore1">VarP (Population)</col>
      </row>
    </data>
  </object>
  <object class="GtkBox" id="SubTotalGrpPage">
    <property name="visible">True</property>
@@ -152,6 +117,7 @@
            <property name="vexpand">True</property>
            <property name="model">liststore1</property>
            <property name="search_column">0</property>
            <property name="show_expanders">False</property>
            <child internal-child="selection">
              <object class="GtkTreeSelection" id="treeview-selection2"/>
            </child>
diff --git a/sd/source/core/sdpage.cxx b/sd/source/core/sdpage.cxx
index 55edc02..6475a93 100644
--- a/sd/source/core/sdpage.cxx
+++ b/sd/source/core/sdpage.cxx
@@ -551,7 +551,7 @@ SdrObject* SdPage::CreatePresObj(PresObjKind eObjKind, bool bVertical, const ::t
                SfxStyleSheet* pSheet = static_cast<SfxStyleSheet*>(getSdrModelFromSdrPage().GetStyleSheetPool()->Find(aName, SfxStyleFamily::Page));
                DBG_ASSERT(pSheet, "StyleSheet for outline object not found");
                if (pSheet)
                    pSdrObj->StartListening(*pSheet);
                    pSdrObj->StartListening(*pSheet, DuplicateHandling::Allow);
            }
        }

diff --git a/sd/uiconfig/simpress/ui/customslideshows.ui b/sd/uiconfig/simpress/ui/customslideshows.ui
index 8397a58..e40a0bd 100644
--- a/sd/uiconfig/simpress/ui/customslideshows.ui
+++ b/sd/uiconfig/simpress/ui/customslideshows.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.20.4 -->
<interface domain="sd">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/sd/uiconfig/simpress/ui/definecustomslideshow.ui b/sd/uiconfig/simpress/ui/definecustomslideshow.ui
index e6dbd89..2bb4e3a 100644
--- a/sd/uiconfig/simpress/ui/definecustomslideshow.ui
+++ b/sd/uiconfig/simpress/ui/definecustomslideshow.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.20.4 -->
<interface domain="sd">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
@@ -10,7 +10,7 @@
      <column type="gchararray"/>
    </columns>
  </object>
  <object class="GtkListStore" id="liststore2">
  <object class="GtkTreeStore" id="liststore2">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/sd/uiconfig/simpress/ui/interactionpage.ui b/sd/uiconfig/simpress/ui/interactionpage.ui
index 0c7135f..6c921d0 100644
--- a/sd/uiconfig/simpress/ui/interactionpage.ui
+++ b/sd/uiconfig/simpress/ui/interactionpage.ui
@@ -116,6 +116,7 @@
                        <property name="can_focus">True</property>
                        <property name="hexpand">True</property>
                        <property name="vexpand">True</property>
                        <property name="show_expanders">False</property>
                        <child internal-child="selection">
                          <object class="GtkTreeSelection" id="treeview-selection1"/>
                        </child>
diff --git a/sd/uiconfig/simpress/ui/photoalbum.ui b/sd/uiconfig/simpress/ui/photoalbum.ui
index 9ef2c28..9a5ed96 100644
--- a/sd/uiconfig/simpress/ui/photoalbum.ui
+++ b/sd/uiconfig/simpress/ui/photoalbum.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.20.4 -->
<interface domain="sd">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/sd/uiconfig/simpress/ui/publishingdialog.ui b/sd/uiconfig/simpress/ui/publishingdialog.ui
index 71c351f..2d372a7 100644
--- a/sd/uiconfig/simpress/ui/publishingdialog.ui
+++ b/sd/uiconfig/simpress/ui/publishingdialog.ui
@@ -93,6 +93,7 @@
                                <property name="can_focus">True</property>
                                <property name="hexpand">True</property>
                                <property name="vexpand">True</property>
                                <property name="show_expanders">False</property>
                                <child internal-child="selection">
                                  <object class="GtkTreeSelection" id="treeview-selection"/>
                                </child>
diff --git a/sfx2/source/appl/appserv.cxx b/sfx2/source/appl/appserv.cxx
index 2a95052..10e2f177 100644
--- a/sfx2/source/appl/appserv.cxx
+++ b/sfx2/source/appl/appserv.cxx
@@ -1229,17 +1229,17 @@ void SfxApplication::MiscState_Impl(SfxItemSet &rSet)

#ifndef DISABLE_DYNLOADING

typedef rtl_uString* (*basicide_choose_macro)(void*, void*, sal_Bool);
typedef rtl_uString* (*basicide_choose_macro)(void*, void*, void*, sal_Bool);

extern "C" { static void thisModule() {} }

#else

extern "C" rtl_uString* basicide_choose_macro(void*, void*, sal_Bool);
extern "C" rtl_uString* basicide_choose_macro(void*, void*, void*, sal_Bool);

#endif

static OUString ChooseMacro( const Reference< XModel >& rxLimitToDocument, const Reference< XFrame >& xDocFrame, bool bChooseOnly )
static OUString ChooseMacro(weld::Window* pParent, const Reference<XModel>& rxLimitToDocument, const Reference<XFrame>& xDocFrame, bool bChooseOnly)
{
#ifndef DISABLE_DYNLOADING
    osl::Module aMod;
@@ -1258,7 +1258,7 @@ static OUString ChooseMacro( const Reference< XModel >& rxLimitToDocument, const
#endif

    // call basicide_choose_macro in basctl
    rtl_uString* pScriptURL = pSymbol( rxLimitToDocument.get(), xDocFrame.get(), bChooseOnly );
    rtl_uString* pScriptURL = pSymbol(pParent, rxLimitToDocument.get(), xDocFrame.get(), bChooseOnly);
    OUString aScriptURL( pScriptURL );
    rtl_uString_release( pScriptURL );
    return aScriptURL;
@@ -1493,7 +1493,7 @@ void SfxApplication::OfaExec_Impl( SfxRequest& rReq )
            }

            Reference <XFrame> xFrame(GetRequestFrame(rReq));
            rReq.SetReturnValue(SfxStringItem(rReq.GetSlot(), ChooseMacro(xLimitToModel, xFrame, bChooseOnly)));
            rReq.SetReturnValue(SfxStringItem(rReq.GetSlot(), ChooseMacro(rReq.GetFrameWeld(), xLimitToModel, xFrame, bChooseOnly)));
            rReq.Done();
        }
        break;
diff --git a/sfx2/source/doc/saveastemplatedlg.cxx b/sfx2/source/doc/saveastemplatedlg.cxx
index a7af9dd..2b7dad5 100644
--- a/sfx2/source/doc/saveastemplatedlg.cxx
+++ b/sfx2/source/doc/saveastemplatedlg.cxx
@@ -44,6 +44,7 @@ SfxSaveAsTemplateDialog::SfxSaveAsTemplateDialog(weld::Window* pParent, const un
    , mnRegionPos(0)
    , m_xModel(rModel)
{
    m_xLBCategory->append_text(SfxResId(STR_CATEGORY_NONE));
    initialize();
    SetCategoryLBEntries(msCategories);

diff --git a/sfx2/source/doc/templatedlg.cxx b/sfx2/source/doc/templatedlg.cxx
index 2d0776b..c78cf5b 100644
--- a/sfx2/source/doc/templatedlg.cxx
+++ b/sfx2/source/doc/templatedlg.cxx
@@ -1328,6 +1328,7 @@ SfxTemplateCategoryDialog::SfxTemplateCategoryDialog(weld::Window* pParent)
    , mxCreateLabel(m_xBuilder->weld_label("create_label"))
    , mxOKButton(m_xBuilder->weld_button("ok"))
{
    mxLBCategory->append_text(SfxResId(STR_CATEGORY_NONE));
    mxNewCategoryEdit->connect_changed(LINK(this, SfxTemplateCategoryDialog, NewCategoryEditHdl));
    mxLBCategory->set_size_request(mxLBCategory->get_approximate_digit_width() * 32,
                                   mxLBCategory->get_height_rows(8));
diff --git a/sfx2/uiconfig/ui/loadtemplatedialog.ui b/sfx2/uiconfig/ui/loadtemplatedialog.ui
index 4329834..5c3fecf 100644
--- a/sfx2/uiconfig/ui/loadtemplatedialog.ui
+++ b/sfx2/uiconfig/ui/loadtemplatedialog.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.20.2 -->
<interface domain="sfx">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
@@ -10,7 +10,7 @@
      <column type="gchararray"/>
    </columns>
  </object>
  <object class="GtkListStore" id="liststore2">
  <object class="GtkTreeStore" id="liststore2">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/sfx2/uiconfig/ui/newstyle.ui b/sfx2/uiconfig/ui/newstyle.ui
index bd22a87..9761b00 100644
--- a/sfx2/uiconfig/ui/newstyle.ui
+++ b/sfx2/uiconfig/ui/newstyle.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.22.1 -->
<interface domain="sfx">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/sfx2/uiconfig/ui/saveastemplatedlg.ui b/sfx2/uiconfig/ui/saveastemplatedlg.ui
index 9362b98..8566b32 100644
--- a/sfx2/uiconfig/ui/saveastemplatedlg.ui
+++ b/sfx2/uiconfig/ui/saveastemplatedlg.ui
@@ -2,16 +2,11 @@
<!-- Generated with glade 3.20.0 -->
<interface domain="sfx">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="categorylist">
  <object class="GtkTreeStore" id="categorylist">
    <columns>
      <!-- column-name gchararray1 -->
      <column type="gchararray"/>
    </columns>
    <data>
      <row>
        <col id="0" translatable="yes" context="saveastemplatedlg|categorylist">None</col>
      </row>
    </data>
  </object>
  <object class="GtkDialog" id="SaveAsTemplateDialog">
    <property name="can_focus">False</property>
diff --git a/sfx2/uiconfig/ui/templatecategorydlg.ui b/sfx2/uiconfig/ui/templatecategorydlg.ui
index 106c5a1..7641e4e 100644
--- a/sfx2/uiconfig/ui/templatecategorydlg.ui
+++ b/sfx2/uiconfig/ui/templatecategorydlg.ui
@@ -2,18 +2,13 @@
<!-- Generated with glade 3.20.0 -->
<interface domain="sfx">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="categorylist">
  <object class="GtkTreeStore" id="categorylist">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
      <!-- column-name id -->
      <column type="gchararray"/>
    </columns>
    <data>
      <row>
        <col id="0" translatable="yes" context="templatecategorydlg|categorylist">None</col>
      </row>
    </data>
  </object>
  <object class="GtkDialog" id="TemplatesCategoryDialog">
    <property name="can_focus">False</property>
diff --git a/solenv/sanitizers/ui/modules/BasicIDE.suppr b/solenv/sanitizers/ui/modules/BasicIDE.suppr
index 6546c4d..01d3c33 100644
--- a/solenv/sanitizers/ui/modules/BasicIDE.suppr
+++ b/solenv/sanitizers/ui/modules/BasicIDE.suppr
@@ -1,4 +1,3 @@
basctl/uiconfig/basicide/ui/basicmacrodialog.ui://basctllo-TreeListBox[@id='libraries:border'] no-labelled-by
basctl/uiconfig/basicide/ui/basicmacrodialog.ui://GtkLabel[@id='macrofromft'] orphan-label
basctl/uiconfig/basicide/ui/basicmacrodialog.ui://GtkLabel[@id='macrotoft'] orphan-label
basctl/uiconfig/basicide/ui/basicmacrodialog.ui://GtkEntry[@id='macronameedit'] no-labelled-by
diff --git a/starmath/uiconfig/smath/ui/fontdialog.ui b/starmath/uiconfig/smath/ui/fontdialog.ui
index fed8a48..d57b8e0 100644
--- a/starmath/uiconfig/smath/ui/fontdialog.ui
+++ b/starmath/uiconfig/smath/ui/fontdialog.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.20.4 -->
<interface domain="sm">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/svx/uiconfig/ui/classificationdialog.ui b/svx/uiconfig/ui/classificationdialog.ui
index 4e730ac..47c4130 100644
--- a/svx/uiconfig/ui/classificationdialog.ui
+++ b/svx/uiconfig/ui/classificationdialog.ui
@@ -169,6 +169,7 @@
                    <property name="can_focus">True</property>
                    <property name="hexpand">True</property>
                    <property name="vexpand">True</property>
                    <property name="show_expanders">False</property>
                    <child internal-child="selection">
                      <object class="GtkTreeSelection"/>
                    </child>
@@ -337,6 +338,7 @@
                        <property name="can_focus">True</property>
                        <property name="hexpand">True</property>
                        <property name="vexpand">True</property>
                        <property name="show_expanders">False</property>
                        <child internal-child="selection">
                          <object class="GtkTreeSelection"/>
                        </child>
@@ -352,6 +354,7 @@
                        <property name="can_focus">True</property>
                        <property name="hexpand">True</property>
                        <property name="vexpand">True</property>
                        <property name="show_expanders">False</property>
                        <child internal-child="selection">
                          <object class="GtkTreeSelection"/>
                        </child>
diff --git a/svx/uiconfig/ui/docrecoverybrokendialog.ui b/svx/uiconfig/ui/docrecoverybrokendialog.ui
index a1626b1..ebf1bdd 100644
--- a/svx/uiconfig/ui/docrecoverybrokendialog.ui
+++ b/svx/uiconfig/ui/docrecoverybrokendialog.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.22.1 -->
<interface domain="svx">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/svx/uiconfig/ui/docrecoverysavedialog.ui b/svx/uiconfig/ui/docrecoverysavedialog.ui
index 297d7fa..e61d938 100644
--- a/svx/uiconfig/ui/docrecoverysavedialog.ui
+++ b/svx/uiconfig/ui/docrecoverysavedialog.ui
@@ -93,6 +93,7 @@
                        <property name="can_focus">True</property>
                        <property name="hexpand">True</property>
                        <property name="vexpand">True</property>
                        <property name="show_expanders">False</property>
                        <child internal-child="selection">
                          <object class="GtkTreeSelection" id="treeview-selection"/>
                        </child>
diff --git a/svx/uiconfig/ui/floatingundoredo.ui b/svx/uiconfig/ui/floatingundoredo.ui
index 7790151..d9a2598 100644
--- a/svx/uiconfig/ui/floatingundoredo.ui
+++ b/svx/uiconfig/ui/floatingundoredo.ui
@@ -25,6 +25,7 @@
            <property name="can_focus">True</property>
            <property name="hexpand">True</property>
            <property name="vexpand">True</property>
            <property name="show_expanders">False</property>
            <child internal-child="selection">
              <object class="GtkTreeSelection" id="treeview-selection1"/>
            </child>
diff --git a/sw/inc/flddinf.hrc b/sw/inc/flddinf.hrc
new file mode 100644
index 0000000..c9b1f3f
--- /dev/null
+++ b/sw/inc/flddinf.hrc
@@ -0,0 +1,35 @@
/* -*- 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/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#ifndef INCLUDED_SW_INC_FLDDINF_HRC
#define INCLUDED_SW_INC_FLDDINF_HRC

#define NC_(Context, String) reinterpret_cast<char const *>(Context "\004" u8##String)

const char* FLD_SELECT[] =
{
    NC_("flddocinfopage|liststore1", "Author"),
    NC_("flddocinfopage|liststore1", "Time"),
    NC_("flddocinfopage|liststore1", "Date"),
    NC_("flddocinfopage|liststore1", "Date Time Author"),
};

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/inc/fldref.hrc b/sw/inc/fldref.hrc
new file mode 100644
index 0000000..9dca24f
--- /dev/null
+++ b/sw/inc/fldref.hrc
@@ -0,0 +1,36 @@
/* -*- 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/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#ifndef INCLUDED_SW_INC_FLDREF_HRC
#define INCLUDED_SW_INC_FLDREF_HRC

#define NC_(Context, String) reinterpret_cast<char const *>(Context "\004" u8##String)

const char* FLD_REF_PAGE_TYPES[] =
{
    NC_("fldrefpage|liststore1", "Bookmarks"),
    NC_("fldrefpage|liststore1", "Footnotes"),
    NC_("fldrefpage|liststore1", "Endnotes"),
    NC_("fldrefpage|liststore1", "Headings"),
    NC_("fldrefpage|liststore1", "Numbered Paragraphs"),
};

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/inc/outline.hrc b/sw/inc/outline.hrc
new file mode 100644
index 0000000..c3202a3
--- /dev/null
+++ b/sw/inc/outline.hrc
@@ -0,0 +1,40 @@
/* -*- 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/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#ifndef INCLUDED_SW_INC_OUTLINE_HRC
#define INCLUDED_SW_INC_OUTLINE_HRC

#define NC_(Context, String) reinterpret_cast<char const *>(Context "\004" u8##String)

const char* OUTLINE_STYLE[] =
{
    NC_("numberingnamedialog|liststore1", "Untitled 1"),
    NC_("numberingnamedialog|liststore1", "Untitled 2"),
    NC_("numberingnamedialog|liststore1", "Untitled 3"),
    NC_("numberingnamedialog|liststore1", "Untitled 4"),
    NC_("numberingnamedialog|liststore1", "Untitled 5"),
    NC_("numberingnamedialog|liststore1", "Untitled 6"),
    NC_("numberingnamedialog|liststore1", "Untitled 7"),
    NC_("numberingnamedialog|liststore1", "Untitled 8"),
    NC_("numberingnamedialog|liststore1", "Untitled 9"),
};

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/flddinf.cxx b/sw/source/ui/fldui/flddinf.cxx
index 9b8f1b6..5eafa45 100644
--- a/sw/source/ui/fldui/flddinf.cxx
+++ b/sw/source/ui/fldui/flddinf.cxx
@@ -25,6 +25,7 @@
#include <vcl/treelistentry.hxx>

#include <swtypes.hxx>
#include <flddinf.hrc>
#include <globals.hrc>
#include <strings.hrc>
#include <fldbas.hxx>
@@ -45,6 +46,12 @@
using namespace nsSwDocInfoSubType;
using namespace com::sun::star;

void FillFieldSelect(ListBox& rListBox)
{
    for (size_t i = 0; i < SAL_N_ELEMENTS(FLD_SELECT); ++i)
        rListBox.InsertEntry(SwResId(FLD_SELECT[i]));
}

SwFieldDokInfPage::SwFieldDokInfPage(vcl::Window* pParent, const SfxItemSet *const pCoreSet)
    :  SwFieldPage(pParent, "FieldDocInfoPage",
        "modules/swriter/ui/flddocinfopage.ui", pCoreSet)
@@ -56,6 +63,7 @@ SwFieldDokInfPage::SwFieldDokInfPage(vcl::Window* pParent, const SfxItemSet *con
    get(m_pSelection, "selectframe");
    get(m_pFormat, "formatframe");
    get(m_pSelectionLB, "select");
    FillFieldSelect(*m_pSelectionLB);
    get(m_pFormatLB, "format");
    get(m_pFixedCB, "fixed");

diff --git a/sw/source/ui/fldui/flddinf.hxx b/sw/source/ui/fldui/flddinf.hxx
index 5353cd8..2347a6d 100644
--- a/sw/source/ui/fldui/flddinf.hxx
+++ b/sw/source/ui/fldui/flddinf.hxx
@@ -71,6 +71,8 @@ public:
    virtual void        FillUserData() override;
};

void FillFieldSelect(ListBox& rListBox);

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/fldfunc.cxx b/sw/source/ui/fldui/fldfunc.cxx
index 05c17ab..f70a551 100644
--- a/sw/source/ui/fldui/fldfunc.cxx
+++ b/sw/source/ui/fldui/fldfunc.cxx
@@ -30,6 +30,7 @@
#include <wrtsh.hxx>
#include <swmodule.hxx>
#include "fldfunc.hxx"
#include "flddinf.hxx"
#include <flddropdown.hxx>

#define USER_DATA_VERSION_1 "1"
@@ -46,7 +47,9 @@ SwFieldFuncPage::SwFieldFuncPage(vcl::Window* pParent, const SfxItemSet *const p
    get(m_pTypeLB, "type");
    get(m_pFormat, "formatframe");
    get(m_pSelectionLB, "select");
    FillFieldSelect(*m_pSelectionLB);
    get(m_pFormatLB, "format");
    FillFieldSelect(*m_pFormatLB);
    get(m_pNameFT, "nameft");
    get(m_pNameED, "condFunction");
    get(m_pValueGroup, "valuegroup");
diff --git a/sw/source/ui/fldui/fldref.cxx b/sw/source/ui/fldui/fldref.cxx
index 47f5cc9..71afb52 100644
--- a/sw/source/ui/fldui/fldref.cxx
+++ b/sw/source/ui/fldui/fldref.cxx
@@ -26,6 +26,7 @@
#include <reffld.hxx>
#include <wrtsh.hxx>

#include <fldref.hrc>
#include <globals.hrc>
#include <strings.hrc>
#include <SwNodeNum.hxx>
@@ -68,6 +69,11 @@ SwFieldRefPage::SwFieldRefPage(vcl::Window* pParent, const SfxItemSet *const pCo
    get(m_pSelectionToolTipLB, "selecttip");
    get(m_pFormat, "formatframe");
    get(m_pFormatLB, "format");
    for (size_t i = 0; i < SAL_N_ELEMENTS(FLD_REF_PAGE_TYPES); ++i)
    {
        m_pTypeLB->InsertEntry(SwResId(FLD_REF_PAGE_TYPES[i]));
        m_pFormatLB->InsertEntry(SwResId(FLD_REF_PAGE_TYPES[i]));
    }
    get(m_pNameFT, "nameft");
    get(m_pNameED, "name");
    get(m_pValueED, "value");
diff --git a/sw/source/ui/fldui/fldvar.cxx b/sw/source/ui/fldui/fldvar.cxx
index 4f38ce4..1bc8682 100644
--- a/sw/source/ui/fldui/fldvar.cxx
+++ b/sw/source/ui/fldui/fldvar.cxx
@@ -31,6 +31,7 @@
#include <docary.hxx>
#include <swmodule.hxx>
#include "fldvar.hxx"
#include "flddinf.hxx"
#include <calc.hxx>
#include <svl/zformat.hxx>
#include <globals.hrc>
@@ -46,6 +47,7 @@ SwFieldVarPage::SwFieldVarPage(vcl::Window* pParent, const SfxItemSet *const pCo
    , bInit(true)
{
    get(m_pTypeLB, "type");
    FillFieldSelect(*m_pTypeLB);
    get(m_pSelection, "selectframe");
    get(m_pSelectionLB, "select");
    m_pSelectionLB->SetStyle(m_pSelectionLB->GetStyle() | WB_SORT);
@@ -57,6 +59,7 @@ SwFieldVarPage::SwFieldVarPage(vcl::Window* pParent, const SfxItemSet *const pCo
    get(m_pValueED, "value");
    get(m_pNumFormatLB, "numformat");
    get(m_pFormatLB, "format");
    FillFieldSelect(*m_pFormatLB);
    get(m_pChapterLevelLB, "level");
    get(m_pInvisibleCB, "invisible");
    get(m_pSeparatorFT, "separatorft");
diff --git a/sw/source/ui/misc/outline.cxx b/sw/source/ui/misc/outline.cxx
index d0588a3..39fa5cf 100644
--- a/sw/source/ui/misc/outline.cxx
+++ b/sw/source/ui/misc/outline.cxx
@@ -43,6 +43,7 @@
#include <viewopt.hxx>
#include <svtools/ctrlbox.hxx>
#include <globals.hrc>
#include <outline.hrc>
#include <strings.hrc>
#include <paratr.hxx>

@@ -120,6 +121,9 @@ SwNumNamesDlg::SwNumNamesDlg(weld::Window *pParent)
    , m_xFormBox(m_xBuilder->weld_tree_view("form"))
    , m_xOKBtn(m_xBuilder->weld_button("ok"))
{
    for (size_t i = 0; i < SAL_N_ELEMENTS(OUTLINE_STYLE); ++i)
        m_xFormBox->append_text(SwResId(OUTLINE_STYLE[i]));

    m_xFormEdit->connect_changed(LINK(this, SwNumNamesDlg, ModifyHdl));
    m_xFormBox->connect_changed(LINK(this, SwNumNamesDlg, SelectHdl));
    m_xFormBox->connect_row_activated(LINK(this, SwNumNamesDlg, DoubleClickHdl));
diff --git a/sw/uiconfig/swriter/ui/autoformattable.ui b/sw/uiconfig/swriter/ui/autoformattable.ui
index 65e4b88..2455c9b 100644
--- a/sw/uiconfig/swriter/ui/autoformattable.ui
+++ b/sw/uiconfig/swriter/ui/autoformattable.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.20.2 -->
<interface domain="sw">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/sw/uiconfig/swriter/ui/conditionpage.ui b/sw/uiconfig/swriter/ui/conditionpage.ui
index 8d76230..fc1bc0d 100644
--- a/sw/uiconfig/swriter/ui/conditionpage.ui
+++ b/sw/uiconfig/swriter/ui/conditionpage.ui
@@ -178,6 +178,7 @@
                        <property name="can_focus">True</property>
                        <property name="hexpand">True</property>
                        <property name="vexpand">True</property>
                        <property name="show_expanders">False</property>
                        <child internal-child="selection">
                          <object class="GtkTreeSelection" id="treeview-selection1"/>
                        </child>
diff --git a/sw/uiconfig/swriter/ui/customizeaddrlistdialog.ui b/sw/uiconfig/swriter/ui/customizeaddrlistdialog.ui
index e4dda17..46fa20f 100644
--- a/sw/uiconfig/swriter/ui/customizeaddrlistdialog.ui
+++ b/sw/uiconfig/swriter/ui/customizeaddrlistdialog.ui
@@ -12,7 +12,7 @@
    <property name="can_focus">False</property>
    <property name="stock">gtk-go-down</property>
  </object>
  <object class="GtkListStore" id="liststore2">
  <object class="GtkTreeStore" id="liststore2">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/sw/uiconfig/swriter/ui/dropdownfielddialog.ui b/sw/uiconfig/swriter/ui/dropdownfielddialog.ui
index df026fe..6b5bb19 100644
--- a/sw/uiconfig/swriter/ui/dropdownfielddialog.ui
+++ b/sw/uiconfig/swriter/ui/dropdownfielddialog.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.22.1 -->
<interface domain="sw">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/sw/uiconfig/swriter/ui/flddbpage.ui b/sw/uiconfig/swriter/ui/flddbpage.ui
index 3c8975c..6c0d908 100644
--- a/sw/uiconfig/swriter/ui/flddbpage.ui
+++ b/sw/uiconfig/swriter/ui/flddbpage.ui
@@ -42,6 +42,7 @@
                        <property name="can_focus">True</property>
                        <property name="vexpand">True</property>
                        <property name="search_column">0</property>
                        <property name="show_expanders">False</property>
                        <child internal-child="selection">
                          <object class="GtkTreeSelection" id="treeview-selection"/>
                        </child>
diff --git a/sw/uiconfig/swriter/ui/flddocinfopage.ui b/sw/uiconfig/swriter/ui/flddocinfopage.ui
index a4c1e7e..f27cc67 100644
--- a/sw/uiconfig/swriter/ui/flddocinfopage.ui
+++ b/sw/uiconfig/swriter/ui/flddocinfopage.ui
@@ -73,6 +73,7 @@
                <property name="hexpand">True</property>
                <property name="vexpand">True</property>
                <property name="model">liststore1</property>
                <property name="show_expanders">False</property>
                <child internal-child="selection">
                  <object class="GtkTreeSelection" id="treeview-selection3"/>
                </child>
@@ -173,25 +174,11 @@
      </packing>
    </child>
  </object>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name gchararray1 -->
      <column type="gchararray"/>
    </columns>
    <data>
      <row>
        <col id="0" translatable="yes" context="flddocinfopage|liststore1">Author</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="flddocinfopage|liststore1">Time</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="flddocinfopage|liststore1">Date</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="flddocinfopage|liststore1">Date Time Author</col>
      </row>
    </data>
  </object>
  <object class="GtkSizeGroup" id="sizegroup1">
    <property name="mode">both</property>
diff --git a/sw/uiconfig/swriter/ui/flddocumentpage.ui b/sw/uiconfig/swriter/ui/flddocumentpage.ui
index f00188e8..ff1a8de 100644
--- a/sw/uiconfig/swriter/ui/flddocumentpage.ui
+++ b/sw/uiconfig/swriter/ui/flddocumentpage.ui
@@ -35,6 +35,7 @@
                <property name="hexpand">True</property>
                <property name="vexpand">True</property>
                <property name="search_column">0</property>
                <property name="show_expanders">False</property>
                <child internal-child="selection">
                  <object class="GtkTreeSelection" id="treeview-selection1"/>
                </child>
@@ -80,6 +81,7 @@
                <property name="can_focus">True</property>
                <property name="hexpand">True</property>
                <property name="vexpand">True</property>
                <property name="show_expanders">False</property>
                <child internal-child="selection">
                  <object class="GtkTreeSelection" id="treeview-selection3"/>
                </child>
@@ -141,6 +143,7 @@
                        <property name="hexpand">True</property>
                        <property name="vexpand">True</property>
                        <property name="search_column">0</property>
                        <property name="show_expanders">False</property>
                        <child internal-child="selection">
                          <object class="GtkTreeSelection" id="treeview-selection5"/>
                        </child>
diff --git a/sw/uiconfig/swriter/ui/fldfuncpage.ui b/sw/uiconfig/swriter/ui/fldfuncpage.ui
index e41e952..b8ba4c0 100644
--- a/sw/uiconfig/swriter/ui/fldfuncpage.ui
+++ b/sw/uiconfig/swriter/ui/fldfuncpage.ui
@@ -27,6 +27,7 @@
                <property name="can_focus">True</property>
                <property name="hexpand">True</property>
                <property name="vexpand">True</property>
                <property name="show_expanders">False</property>
                <child internal-child="selection">
                  <object class="GtkTreeSelection" id="treeview-selection1"/>
                </child>
@@ -74,6 +75,7 @@
                <property name="vexpand">True</property>
                <property name="model">liststore1</property>
                <property name="search_column">0</property>
                <property name="show_expanders">False</property>
                <child internal-child="selection">
                  <object class="GtkTreeSelection" id="treeview-selection4"/>
                </child>
@@ -120,6 +122,7 @@
                <property name="hexpand">True</property>
                <property name="vexpand">True</property>
                <property name="model">liststore1</property>
                <property name="show_expanders">False</property>
                <child internal-child="selection">
                  <object class="GtkTreeSelection" id="treeview-selection3"/>
                </child>
@@ -429,6 +432,7 @@
                    <property name="visible">True</property>
                    <property name="can_focus">True</property>
                    <property name="hexpand">True</property>
                    <property name="show_expanders">False</property>
                    <child internal-child="selection">
                      <object class="GtkTreeSelection" id="treeview-selection5"/>
                    </child>
@@ -565,25 +569,11 @@
      </packing>
    </child>
  </object>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name gchararray1 -->
      <column type="gchararray"/>
    </columns>
    <data>
      <row>
        <col id="0" translatable="yes" context="fldfuncpage|liststore1">Author</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="fldfuncpage|liststore1">Time</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="fldfuncpage|liststore1">Date</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="fldfuncpage|liststore1">Date Time Author</col>
      </row>
    </data>
  </object>
  <object class="GtkSizeGroup" id="sizegroup1">
    <property name="mode">both</property>
diff --git a/sw/uiconfig/swriter/ui/fldrefpage.ui b/sw/uiconfig/swriter/ui/fldrefpage.ui
index a7340b3..042b373 100644
--- a/sw/uiconfig/swriter/ui/fldrefpage.ui
+++ b/sw/uiconfig/swriter/ui/fldrefpage.ui
@@ -3,28 +3,11 @@
<interface domain="sw">
  <requires lib="gtk+" version="3.18"/>
  <requires lib="LibreOffice" version="1.0"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name gchararray1 -->
      <column type="gchararray"/>
    </columns>
    <data>
      <row>
        <col id="0" translatable="yes" context="fldrefpage|liststore1">Bookmarks</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="fldrefpage|liststore1">Footnotes</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="fldrefpage|liststore1">Endnotes</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="fldrefpage|liststore1">Headings</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="fldrefpage|liststore1">Numbered Paragraphs</col>
      </row>
    </data>
  </object>
  <object class="GtkBox" id="FieldRefPage">
    <property name="visible">True</property>
@@ -66,6 +49,7 @@
                        <property name="can_focus">True</property>
                        <property name="model">liststore1</property>
                        <property name="search_column">0</property>
                        <property name="show_expanders">False</property>
                        <child internal-child="selection">
                          <object class="GtkTreeSelection" id="treeview-selection"/>
                        </child>
@@ -111,6 +95,7 @@
                        <property name="can_focus">True</property>
                        <property name="model">liststore1</property>
                        <property name="search_column">0</property>
                        <property name="show_expanders">False</property>
                        <child internal-child="selection">
                          <object class="GtkTreeSelection" id="treeview-selection2"/>
                        </child>
@@ -247,6 +232,7 @@
                            <property name="can_focus">True</property>
                            <property name="hexpand">True</property>
                            <property name="vexpand">True</property>
                            <property name="show_expanders">False</property>
                            <child internal-child="selection">
                              <object class="GtkTreeSelection" id="treeview-selection4"/>
                            </child>
diff --git a/sw/uiconfig/swriter/ui/fldvarpage.ui b/sw/uiconfig/swriter/ui/fldvarpage.ui
index a4a8111..8ce32e3 100644
--- a/sw/uiconfig/swriter/ui/fldvarpage.ui
+++ b/sw/uiconfig/swriter/ui/fldvarpage.ui
@@ -37,6 +37,7 @@
                    <property name="vexpand">True</property>
                    <property name="model">liststore1</property>
                    <property name="search_column">0</property>
                    <property name="show_expanders">False</property>
                    <child internal-child="selection">
                      <object class="GtkTreeSelection" id="treeview-selection3"/>
                    </child>
@@ -271,6 +272,7 @@
                            <property name="vexpand">True</property>
                            <property name="model">liststore1</property>
                            <property name="search_column">0</property>
                            <property name="show_expanders">False</property>
                            <child internal-child="selection">
                              <object class="GtkTreeSelection" id="treeview-selection2"/>
                            </child>
@@ -513,25 +515,11 @@
      </packing>
    </child>
  </object>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name gchararray1 -->
      <column type="gchararray"/>
    </columns>
    <data>
      <row>
        <col id="0" translatable="yes" context="fldvarpage|liststore1">Author</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="fldvarpage|liststore1">Time</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="fldvarpage|liststore1">Date</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="fldvarpage|liststore1">Date Time Author</col>
      </row>
    </data>
  </object>
  <object class="GtkSizeGroup" id="sizegroup1">
    <property name="mode">both</property>
diff --git a/sw/uiconfig/swriter/ui/insertautotextdialog.ui b/sw/uiconfig/swriter/ui/insertautotextdialog.ui
index 7844158..f7eb03e 100644
--- a/sw/uiconfig/swriter/ui/insertautotextdialog.ui
+++ b/sw/uiconfig/swriter/ui/insertautotextdialog.ui
@@ -103,6 +103,7 @@
                        <property name="can_focus">True</property>
                        <property name="hexpand">True</property>
                        <property name="vexpand">True</property>
                        <property name="show_expanders">False</property>
                        <child internal-child="selection">
                          <object class="GtkTreeSelection" id="treeview-selection1"/>
                        </child>
diff --git a/sw/uiconfig/swriter/ui/insertdbcolumnsdialog.ui b/sw/uiconfig/swriter/ui/insertdbcolumnsdialog.ui
index f869c06..d632c09 100644
--- a/sw/uiconfig/swriter/ui/insertdbcolumnsdialog.ui
+++ b/sw/uiconfig/swriter/ui/insertdbcolumnsdialog.ui
@@ -333,6 +333,7 @@
                                <property name="no_show_all">True</property>
                                <property name="hexpand">True</property>
                                <property name="vexpand">True</property>
                                <property name="show_expanders">False</property>
                                <child internal-child="selection">
                                  <object class="GtkTreeSelection" id="treeview-selection2"/>
                                </child>
@@ -384,6 +385,7 @@
                                <property name="can_focus">True</property>
                                <property name="hexpand">True</property>
                                <property name="vexpand">True</property>
                                <property name="show_expanders">False</property>
                                <child internal-child="selection">
                                  <object class="GtkTreeSelection" id="treeview-selection4"/>
                                </child>
@@ -400,6 +402,7 @@
                                <property name="can_focus">True</property>
                                <property name="hexpand">True</property>
                                <property name="vexpand">True</property>
                                <property name="show_expanders">False</property>
                                <child internal-child="selection">
                                  <object class="GtkTreeSelection" id="treeview-selection3"/>
                                </child>
diff --git a/sw/uiconfig/swriter/ui/inserttable.ui b/sw/uiconfig/swriter/ui/inserttable.ui
index 3128884..7ce4f86 100644
--- a/sw/uiconfig/swriter/ui/inserttable.ui
+++ b/sw/uiconfig/swriter/ui/inserttable.ui
@@ -23,7 +23,7 @@
    <property name="step_increment">1</property>
    <property name="page_increment">10</property>
  </object>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/sw/uiconfig/swriter/ui/numberingnamedialog.ui b/sw/uiconfig/swriter/ui/numberingnamedialog.ui
index 003f0bf..97f4509 100644
--- a/sw/uiconfig/swriter/ui/numberingnamedialog.ui
+++ b/sw/uiconfig/swriter/ui/numberingnamedialog.ui
@@ -2,42 +2,13 @@
<!-- Generated with glade 3.20.4 -->
<interface domain="sw">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
      <!-- column-name id -->
      <column type="gchararray"/>
    </columns>
    <data>
      <row>
        <col id="0" translatable="yes" context="numberingnamedialog|liststore1">Untitled 1</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="numberingnamedialog|liststore1">Untitled 2</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="numberingnamedialog|liststore1">Untitled 3</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="numberingnamedialog|liststore1">Untitled 4</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="numberingnamedialog|liststore1">Untitled 5</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="numberingnamedialog|liststore1">Untitled 6</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="numberingnamedialog|liststore1">Untitled 7</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="numberingnamedialog|liststore1">Untitled 8</col>
      </row>
      <row>
        <col id="0" translatable="yes" context="numberingnamedialog|liststore1">Untitled 9</col>
      </row>
    </data>
  </object>
  <object class="GtkDialog" id="NumberingNameDialog">
    <property name="can_focus">False</property>
diff --git a/sw/uiconfig/swriter/ui/outlinenumberingpage.ui b/sw/uiconfig/swriter/ui/outlinenumberingpage.ui
index 63ca632..b198445 100644
--- a/sw/uiconfig/swriter/ui/outlinenumberingpage.ui
+++ b/sw/uiconfig/swriter/ui/outlinenumberingpage.ui
@@ -14,7 +14,7 @@
    <property name="step_increment">1</property>
    <property name="page_increment">1</property>
  </object>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/sw/uiconfig/swriter/ui/outlinepositionpage.ui b/sw/uiconfig/swriter/ui/outlinepositionpage.ui
index d0f356a..e5ba315 100644
--- a/sw/uiconfig/swriter/ui/outlinepositionpage.ui
+++ b/sw/uiconfig/swriter/ui/outlinepositionpage.ui
@@ -33,7 +33,7 @@
    <property name="step_increment">0.01</property>
    <property name="page_increment">1</property>
  </object>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/sw/uiconfig/swriter/ui/selectautotextdialog.ui b/sw/uiconfig/swriter/ui/selectautotextdialog.ui
index 973b6dc..c077493 100644
--- a/sw/uiconfig/swriter/ui/selectautotextdialog.ui
+++ b/sw/uiconfig/swriter/ui/selectautotextdialog.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.20.4 -->
<interface domain="sw">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/sw/uiconfig/swriter/ui/selectindexdialog.ui b/sw/uiconfig/swriter/ui/selectindexdialog.ui
index 50b9401..ebd59fd 100644
--- a/sw/uiconfig/swriter/ui/selectindexdialog.ui
+++ b/sw/uiconfig/swriter/ui/selectindexdialog.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.20.4 -->
<interface domain="sw">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/sw/uiconfig/swriter/ui/sidebarstylepresets.ui b/sw/uiconfig/swriter/ui/sidebarstylepresets.ui
index 4a4e0d1..170df55 100644
--- a/sw/uiconfig/swriter/ui/sidebarstylepresets.ui
+++ b/sw/uiconfig/swriter/ui/sidebarstylepresets.ui
@@ -23,6 +23,7 @@
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="hexpand">True</property>
                <property name="show_expanders">False</property>
                <child internal-child="selection">
                  <object class="GtkTreeSelection" id="treeview-selection1"/>
                </child>
diff --git a/sw/uiconfig/swriter/ui/sidebartheme.ui b/sw/uiconfig/swriter/ui/sidebartheme.ui
index 5cc4309..b93c650 100644
--- a/sw/uiconfig/swriter/ui/sidebartheme.ui
+++ b/sw/uiconfig/swriter/ui/sidebartheme.ui
@@ -36,6 +36,7 @@
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="hexpand">True</property>
                <property name="show_expanders">False</property>
                <child internal-child="selection">
                  <object class="GtkTreeSelection" id="treeview-selection1"/>
                </child>
diff --git a/sw/uiconfig/swriter/ui/tocstylespage.ui b/sw/uiconfig/swriter/ui/tocstylespage.ui
index 95decc9..5d34067 100644
--- a/sw/uiconfig/swriter/ui/tocstylespage.ui
+++ b/sw/uiconfig/swriter/ui/tocstylespage.ui
@@ -7,7 +7,7 @@
    <property name="can_focus">False</property>
    <property name="icon_name">sw/res/one_left.png</property>
  </object>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
@@ -15,7 +15,7 @@
      <column type="gchararray"/>
    </columns>
  </object>
  <object class="GtkListStore" id="liststore2">
  <object class="GtkTreeStore" id="liststore2">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/uui/uiconfig/ui/filterselect.ui b/uui/uiconfig/ui/filterselect.ui
index 09b298d..6f7ebf7 100644
--- a/uui/uiconfig/ui/filterselect.ui
+++ b/uui/uiconfig/ui/filterselect.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.22.1 -->
<interface domain="uui">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index ade8338..67ac7ed 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -1750,6 +1750,17 @@ IMPL_LINK(SalInstanceEntry, CursorListener, VclWindowEvent&, rEvent, void)
        signal_cursor_position();
}

struct SalInstanceTreeIter : public weld::TreeIter
{
    SalInstanceTreeIter(const SalInstanceTreeIter* pOrig)
    {
        if (!pOrig)
            return;
        iter = pOrig->iter;
    }
    SvTreeListEntry* iter;
};

class SalInstanceTreeView : public SalInstanceContainer, public virtual weld::TreeView
{
private:
@@ -1759,19 +1770,26 @@ private:

    DECL_LINK(SelectHdl, SvTreeListBox*, void);
    DECL_LINK(DoubleClickHdl, SvTreeListBox*, bool);
    DECL_LINK(ExpandingHdl, SvTreeListBox*, bool);

public:
    SalInstanceTreeView(SvTreeListBox* pTreeView, bool bTakeOwnership)
        : SalInstanceContainer(pTreeView, bTakeOwnership)
        , m_xTreeView(pTreeView)
    {
        m_xTreeView->SetNodeDefaultImages();
        m_xTreeView->SetSelectHdl(LINK(this, SalInstanceTreeView, SelectHdl));
        m_xTreeView->SetDoubleClickHdl(LINK(this, SalInstanceTreeView, DoubleClickHdl));
        m_xTreeView->SetExpandingHdl(LINK(this, SalInstanceTreeView, ExpandingHdl));
    }

    virtual void insert(int pos, const OUString& rStr, const OUString* pId, const OUString* pIconName, VirtualDevice* pImageSurface) override
    virtual void insert(weld::TreeIter* pParent, int pos, const OUString& rStr, const OUString* pId,
                        const OUString* pIconName, VirtualDevice* pImageSurface, const OUString* pExpanderName,
                        bool bChildrenOnDemand) override
    {
        auto nInsertPos = pos == -1 ? COMBOBOX_APPEND : pos;
        SalInstanceTreeIter* pVclIter = static_cast<SalInstanceTreeIter*>(pParent);
        SvTreeListEntry* iter = pVclIter ? pVclIter->iter : nullptr;
        auto nInsertPos = pos == -1 ? TREELIST_APPEND : pos;
        void* pUserData;
        if (pId)
        {
@@ -1781,8 +1799,9 @@ public:
        else
            pUserData = nullptr;

        SvTreeListEntry* pResult;
        if (!pIconName && !pImageSurface)
            m_xTreeView->InsertEntry(rStr, nullptr, false, nInsertPos, pUserData);
            pResult = m_xTreeView->InsertEntry(rStr, iter, false, nInsertPos, pUserData);
        else
        {
            SvTreeListEntry* pEntry = new SvTreeListEntry;
@@ -1790,7 +1809,20 @@ public:
            pEntry->AddItem(o3tl::make_unique<SvLBoxContextBmp>(aImage, aImage, false));
            pEntry->AddItem(o3tl::make_unique<SvLBoxString>(rStr));
            pEntry->SetUserData(pUserData);
            m_xTreeView->Insert(pEntry, nInsertPos);
            m_xTreeView->Insert(pEntry, iter, nInsertPos);
            pResult = pEntry;
        }

        if (pExpanderName)
        {
            Image aImage(createImage(*pExpanderName));
            m_xTreeView->SetExpandedEntryBmp(pResult, aImage);
            m_xTreeView->SetCollapsedEntryBmp(pResult, aImage);
        }

        if (bChildrenOnDemand)
        {
            m_xTreeView->InsertEntry("<dummy>", pResult, false, 0, nullptr);
        }
    }

@@ -1914,6 +1946,157 @@ public:
        return m_xTreeView->GetAbsPos(pEntry);
    }

    virtual std::unique_ptr<weld::TreeIter> make_iterator(const weld::TreeIter* pOrig) const override
    {
        return std::unique_ptr<weld::TreeIter>(new SalInstanceTreeIter(static_cast<const SalInstanceTreeIter*>(pOrig)));
    }

    virtual void copy_iterator(const weld::TreeIter& rSource, weld::TreeIter& rDest) const override
    {
        const SalInstanceTreeIter& rVclSource(static_cast<const SalInstanceTreeIter&>(rSource));
        SalInstanceTreeIter& rVclDest(static_cast<SalInstanceTreeIter&>(rDest));
        rVclDest.iter = rVclSource.iter;
    }

    virtual bool get_selected(weld::TreeIter* pIter) const override
    {
        SvTreeListEntry* pEntry = m_xTreeView->FirstSelected();
        auto pVclIter = static_cast<SalInstanceTreeIter*>(pIter);
        if (pVclIter)
            pVclIter->iter = pEntry;
        return pEntry != nullptr;
    }

    virtual bool get_cursor(weld::TreeIter* pIter) const override
    {
        SvTreeListEntry* pEntry = m_xTreeView->GetCurEntry();
        auto pVclIter = static_cast<SalInstanceTreeIter*>(pIter);
        if (pVclIter)
            pVclIter->iter = pEntry;
        return pEntry != nullptr;
    }

    virtual void set_cursor(const weld::TreeIter& rIter) override
    {
        const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
        m_xTreeView->SetCurEntry(rVclIter.iter);
    }

    virtual bool get_iter_first(weld::TreeIter& rIter) const override
    {
        SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
        rVclIter.iter = m_xTreeView->GetEntry(0);
        return rVclIter.iter != nullptr;
    }

    virtual bool iter_next_sibling(weld::TreeIter& rIter) const override
    {
        SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
        rVclIter.iter = rVclIter.iter->NextSibling();
        return rVclIter.iter != nullptr;
    }

    virtual bool iter_next(weld::TreeIter& rIter) const override
    {
        SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
        rVclIter.iter = m_xTreeView->Next(rVclIter.iter);
        if (rVclIter.iter && m_xTreeView->GetEntryText(rVclIter.iter) == "<dummy>")
            return iter_next(rVclIter);
        return rVclIter.iter != nullptr;
    }

    virtual bool iter_children(weld::TreeIter& rIter) const override
    {
        SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
        rVclIter.iter = m_xTreeView->FirstChild(rVclIter.iter);
        bool bRet = rVclIter.iter != nullptr;
        if (bRet)
        {
            //on-demand dummy entry doesn't count
            return m_xTreeView->GetEntryText(rVclIter.iter) != "<dummy>";
        }
        return bRet;
    }

    virtual bool iter_parent(weld::TreeIter& rIter) const override
    {
        SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
        rVclIter.iter = m_xTreeView->GetParent(rVclIter.iter);
        return rVclIter.iter != nullptr;
    }

    virtual void remove(const weld::TreeIter& rIter) override
    {
        const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
        m_xTreeView->RemoveEntry(rVclIter.iter);
    }

    virtual void select(const weld::TreeIter& rIter) override
    {
        assert(m_xTreeView->IsUpdateMode() && "don't select when frozen");
        disable_notify_events();
        const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
        m_xTreeView->Select(rVclIter.iter, true);
        enable_notify_events();
    }

    virtual void unselect(const weld::TreeIter& rIter) override
    {
        assert(m_xTreeView->IsUpdateMode() && "don't unselect when frozen");
        disable_notify_events();
        const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
        m_xTreeView->Select(rVclIter.iter, false);
        enable_notify_events();
    }

    virtual int get_iter_depth(const weld::TreeIter& rIter) const override
    {
        const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
        return m_xTreeView->GetModel()->GetDepth(rVclIter.iter);
    }

    virtual bool iter_has_child(const weld::TreeIter& rIter) const override
    {
        const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
        return rVclIter.iter->HasChildren();
    }

    virtual bool get_row_expanded(const weld::TreeIter& rIter) const override
    {
        const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
        return m_xTreeView->IsExpanded(rVclIter.iter);
    }

    virtual void expand_row(weld::TreeIter& rIter) override
    {
        SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
        if (!m_xTreeView->IsExpanded(rVclIter.iter) && signal_expanding(rIter))
            m_xTreeView->Expand(rVclIter.iter);
    }

    virtual OUString get_text(const weld::TreeIter& rIter) const override
    {
        const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
        return m_xTreeView->GetEntryText(rVclIter.iter);
    }

    virtual OUString get_id(const weld::TreeIter& rIter) const override
    {
        const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
        const OUString* pStr = static_cast<const OUString*>(rVclIter.iter->GetUserData());
        if (pStr)
            return *pStr;
        return OUString();
    }

    virtual void set_expander_image(const weld::TreeIter& rIter, const OUString& rImage) override
    {
        const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
        Image aImage(createImage(rImage));
        m_xTreeView->SetExpandedEntryBmp(rVclIter.iter, aImage);
        m_xTreeView->SetCollapsedEntryBmp(rVclIter.iter, aImage);
    }

    virtual void set_selection_mode(bool bMultiple) override
    {
        m_xTreeView->SetSelectionMode(bMultiple ? SelectionMode::Multiple : SelectionMode::Single);
@@ -1941,6 +2124,7 @@ public:

    virtual ~SalInstanceTreeView() override
    {
        m_xTreeView->SetExpandingHdl(Link<SvTreeListBox*, bool>());
        m_xTreeView->SetDoubleClickHdl(Link<SvTreeListBox*, bool>());
        m_xTreeView->SetSelectHdl(Link<SvTreeListBox*, void>());
    }
@@ -1961,6 +2145,41 @@ IMPL_LINK_NOARG(SalInstanceTreeView, DoubleClickHdl, SvTreeListBox*, bool)
    return false;
}

IMPL_LINK_NOARG(SalInstanceTreeView, ExpandingHdl, SvTreeListBox*, bool)
{
    SvTreeListEntry* pEntry = m_xTreeView->GetHdlEntry();
    if (m_xTreeView->IsExpanded(pEntry))
    {
        //collapsing;
        return true;
    }

    // if there's a preexisting placeholder child, required to make this
    // potentially expandable in the first place, now we remove it
    bool bPlaceHolder = false;
    if (pEntry->HasChildren())
    {
        auto pChild = m_xTreeView->FirstChild(pEntry);
        if (m_xTreeView->GetEntryText(pChild) == "<dummy>")
        {
            m_xTreeView->RemoveEntry(pChild);
            bPlaceHolder = true;
        }
    }

    SalInstanceTreeIter aIter(nullptr);
    aIter.iter = pEntry;
    bool bRet = signal_expanding(aIter);

    //expand disallowed, restore placeholder
    if (!bRet && bPlaceHolder)
    {
        m_xTreeView->InsertEntry("<dummy>", pEntry, false, 0, nullptr);
    }

    return bRet;
}

class SalInstanceSpinButton : public SalInstanceEntry, public virtual weld::SpinButton
{
private:
diff --git a/vcl/source/treelist/treelistbox.cxx b/vcl/source/treelist/treelistbox.cxx
index a581fd5..e51363b 100644
--- a/vcl/source/treelist/treelistbox.cxx
+++ b/vcl/source/treelist/treelistbox.cxx
@@ -2137,9 +2137,11 @@ bool SvTreeListBox::Expand( SvTreeListEntry* pParent )

    if( pParent->HasChildrenOnDemand() )
        RequestingChildren( pParent );
    if( pParent->HasChildren() )
    bool bExpandAllowed = pParent->HasChildren() && ExpandingHdl();
    // double check if the expander callback ended up removing all children
    if (pParent->HasChildren())
    {
        if( ExpandingHdl() )
        if (bExpandAllowed)
        {
            bExpanded = true;
            ExpandListEntry( pParent );
@@ -3649,7 +3651,7 @@ bool SvTreeListBox::set_property(const OString &rKey, const OUString &rValue)
    {
        set_min_width_in_chars(rValue.toInt32());
    }
    if (rKey == "enable-tree-lines")
    else if (rKey == "enable-tree-lines")
    {
        auto nStyle = GetStyle();
        nStyle &= ~(WB_HASLINES | WB_HASLINESATROOT);
@@ -3657,6 +3659,14 @@ bool SvTreeListBox::set_property(const OString &rKey, const OUString &rValue)
            nStyle |= (WB_HASLINES | WB_HASLINESATROOT);
        SetStyle(nStyle);
    }
    else if (rKey == "show-expanders")
    {
        auto nStyle = GetStyle();
        nStyle &= ~(WB_HASBUTTONS | WB_HASBUTTONSATROOT);
        if (toBool(rValue))
            nStyle |= (WB_HASBUTTONS | WB_HASBUTTONSATROOT);
        SetStyle(nStyle);
    }
    else
        return Control::set_property(rKey, rValue);
    return true;
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index b2dbeba..edb7398 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -1892,7 +1892,7 @@ VclPtr<vcl::Window> VclBuilder::makeObject(vcl::Window *pParent, const OString &
            xWindow = VclPtr<ListBox>::Create(pRealParent, nWinStyle);
        else
        {
            VclPtrInstance<SvTreeListBox> xBox(pRealParent, nWinStyle);
            VclPtrInstance<SvTreeListBox> xBox(pRealParent, nWinStyle | WB_HASBUTTONS | WB_HASBUTTONSATROOT);
            xBox->SetNoAutoCurEntry(true);
            xBox->SetHighlightRange(); // select over the whole width
            xWindow = xBox;
@@ -2909,10 +2909,9 @@ void VclBuilder::handleRow(xmlreader::XmlReader &reader, const OString &rID)
    m_pParserState->m_aModels[rID].m_aEntries.push_back(aRow);
}

void VclBuilder::handleListStore(xmlreader::XmlReader &reader, const OString &rID)
void VclBuilder::handleListStore(xmlreader::XmlReader &reader, const OString &rID, const OString &rClass)
{
    int nLevel = 1;
    sal_Int32 nRowIndex = 0;

    while(true)
    {
@@ -2929,8 +2928,10 @@ void VclBuilder::handleListStore(xmlreader::XmlReader &reader, const OString &rI
        {
            if (name.equals("row"))
            {
                handleRow(reader, rID);
                nRowIndex++;
                bool bNotTreeStore = rClass != "GtkTreeStore";
                if (bNotTreeStore)
                    handleRow(reader, rID);
                assert(bNotTreeStore && "gtk, as the time of writing, doesn't support data in GtkTreeStore serialization");
            }
            else
                ++nLevel;
@@ -3433,9 +3434,9 @@ VclPtr<vcl::Window> VclBuilder::handleObject(vcl::Window *pParent, xmlreader::Xm
        }
    }

    if (sClass == "GtkListStore")
    if (sClass == "GtkListStore" || sClass == "GtkTreeStore")
    {
        handleListStore(reader, sID);
        handleListStore(reader, sID, sClass);
        return nullptr;
    }
    else if (sClass == "GtkMenu")
diff --git a/vcl/uiconfig/ui/printdialog.ui b/vcl/uiconfig/ui/printdialog.ui
index 2c2061c..d832944 100644
--- a/vcl/uiconfig/ui/printdialog.ui
+++ b/vcl/uiconfig/ui/printdialog.ui
@@ -456,6 +456,7 @@
                                    <property name="visible">True</property>
                                    <property name="can_focus">True</property>
                                    <property name="vexpand">True</property>
                                    <property name="show_expanders">False</property>
                                    <child internal-child="selection">
                                      <object class="GtkTreeSelection" id="treeview-selection"/>
                                    </child>
diff --git a/vcl/uiconfig/ui/printerdevicepage.ui b/vcl/uiconfig/ui/printerdevicepage.ui
index 1dc801f..48ea728f 100644
--- a/vcl/uiconfig/ui/printerdevicepage.ui
+++ b/vcl/uiconfig/ui/printerdevicepage.ui
@@ -2,7 +2,7 @@
<!-- Generated with glade 3.20.4 -->
<interface domain="vcl">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkListStore" id="liststore1">
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
@@ -10,7 +10,7 @@
      <column type="gchararray"/>
    </columns>
  </object>
  <object class="GtkListStore" id="liststore2">
  <object class="GtkTreeStore" id="liststore2">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 2ffe595..7e613bd 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -4023,6 +4023,89 @@ namespace
            }
        }
    }

    GdkPixbuf* getPixbuf(const OUString& rIconName)
    {
        GdkPixbuf* pixbuf = nullptr;

        if (rIconName.lastIndexOf('.') != rIconName.getLength() - 4)
        {
            assert((rIconName== "dialog-warning" || rIconName== "dialog-error" || rIconName== "dialog-information") &&
                   "unknown stock image");

            GError *error = nullptr;
            GtkIconTheme *icon_theme = gtk_icon_theme_get_default();
            pixbuf = gtk_icon_theme_load_icon(icon_theme, OUStringToOString(rIconName, RTL_TEXTENCODING_UTF8).getStr(),
                                              16, GTK_ICON_LOOKUP_USE_BUILTIN, &error);
        }
        else
        {
            const AllSettings& rSettings = Application::GetSettings();
            pixbuf = load_icon_by_name(rIconName,
                                       rSettings.GetStyleSettings().DetermineIconTheme(),
                                       rSettings.GetUILanguageTag().getBcp47());
        }

        return pixbuf;
    }

    void insert_row(GtkTreeStore* pTreeStore, GtkTreeIter& iter, GtkTreeIter* parent, int pos, const OUString* pId, const OUString& rText,
                    const OUString* pIconName, VirtualDevice* pDevice, const OUString* pExpanderName)
    {
        if (!pIconName && !pDevice)
        {
            gtk_tree_store_insert_with_values(pTreeStore, &iter, parent, pos,
                                              0, OUStringToOString(rText, RTL_TEXTENCODING_UTF8).getStr(),
                                              1, !pId ? nullptr : OUStringToOString(*pId, RTL_TEXTENCODING_UTF8).getStr(),
                                              -1);
        }
        else
        {
            if (pIconName)
            {
                GdkPixbuf* pixbuf = getPixbuf(*pIconName);

                gtk_tree_store_insert_with_values(pTreeStore, &iter, parent, pos,
                                                  0, OUStringToOString(rText, RTL_TEXTENCODING_UTF8).getStr(),
                                                  1, !pId ? nullptr : OUStringToOString(*pId, RTL_TEXTENCODING_UTF8).getStr(),
                                                  2, pixbuf,
                                                  -1);

                if (pixbuf)
                    g_object_unref(pixbuf);
            }
            else
            {
                cairo_surface_t* surface = get_underlying_cairo_surface(*pDevice);

                Size aSize(pDevice->GetOutputSizePixel());
                cairo_surface_t* target = cairo_surface_create_similar(surface,
                                                                        cairo_surface_get_content(surface),
                                                                        aSize.Width(),
                                                                        aSize.Height());

                cairo_t* cr = cairo_create(target);
                cairo_set_source_surface(cr, surface, 0, 0);
                cairo_paint(cr);
                cairo_destroy(cr);

                gtk_tree_store_insert_with_values(pTreeStore, &iter, parent, pos,
                                                  0, OUStringToOString(rText, RTL_TEXTENCODING_UTF8).getStr(),
                                                  1, !pId ? nullptr : OUStringToOString(*pId, RTL_TEXTENCODING_UTF8).getStr(),
                                                  3, target,
                                                  -1);
                cairo_surface_destroy(target);
            }
        }

        if (pExpanderName)
        {
            GdkPixbuf* pixbuf = getPixbuf(*pExpanderName);
            gtk_tree_store_set(pTreeStore, &iter, 4, pixbuf, -1);
            if (pixbuf)
                g_object_unref(pixbuf);
        }
    }
}

namespace
@@ -4042,14 +4125,26 @@ namespace
    }
}

struct GtkInstanceTreeIter : public weld::TreeIter
{
    GtkInstanceTreeIter(const GtkInstanceTreeIter* pOrig)
    {
        if (!pOrig)
            return;
        iter = pOrig->iter;
    }
    GtkTreeIter iter;
};

class GtkInstanceTreeView : public GtkInstanceContainer, public virtual weld::TreeView
{
private:
    GtkTreeView* m_pTreeView;
    GtkListStore* m_pListStore;
    GtkTreeStore* m_pTreeStore;
    std::unique_ptr<comphelper::string::NaturalStringSorter> m_xSorter;
    gulong m_nChangedSignalId;
    gulong m_nRowActivatedSignalId;
    gulong m_nTestExpandRowSignalId;

    DECL_LINK(async_signal_changed, void*, void);

@@ -4075,7 +4170,7 @@ private:
    OUString get(int pos, int col) const
    {
        OUString sRet;
        GtkTreeModel *pModel = GTK_TREE_MODEL(m_pListStore);
        GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore);
        GtkTreeIter iter;
        if (gtk_tree_model_iter_nth_child(pModel, &iter, nullptr, pos))
        {
@@ -4087,53 +4182,99 @@ private:
        return sRet;
    }

    static gboolean signalTestExpandRow(GtkTreeView*, GtkTreeIter* iter, GtkTreePath*, gpointer widget)
    {
        GtkInstanceTreeView* pThis = static_cast<GtkInstanceTreeView*>(widget);
        return !pThis->signal_test_expand_row(*iter);
    }

    bool signal_test_expand_row(GtkTreeIter& iter)
    {
        GtkInstanceTreeIter aIter(nullptr);

        // if there's a preexisting placeholder child, required to make this
        // potentially expandable in the first place, now we remove it
        bool bPlaceHolder = false;
        GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore);
        GtkTreeIter tmp;
        if (gtk_tree_model_iter_children(pModel, &tmp, &iter))
        {
            aIter.iter = tmp;
            if (get_text(aIter) == "<dummy>")
            {
                gtk_tree_store_remove(m_pTreeStore, &tmp);
                bPlaceHolder = true;
            }
        }

        aIter.iter = iter;
        bool bRet = signal_expanding(aIter);

        //expand disallowed, restore placeholder
        if (!bRet && bPlaceHolder)
        {
            GtkTreeIter subiter;
            insert_row(m_pTreeStore, subiter, &iter, -1, nullptr, "<dummy>", nullptr, nullptr, nullptr);
        }

        return bRet;
    }

public:
    GtkInstanceTreeView(GtkTreeView* pTreeView, bool bTakeOwnership)
        : GtkInstanceContainer(GTK_CONTAINER(pTreeView), bTakeOwnership)
        , m_pTreeView(pTreeView)
        , m_pListStore(GTK_LIST_STORE(gtk_tree_view_get_model(m_pTreeView)))
        , m_pTreeStore(GTK_TREE_STORE(gtk_tree_view_get_model(m_pTreeView)))
        , m_nChangedSignalId(g_signal_connect(gtk_tree_view_get_selection(pTreeView), "changed",
                             G_CALLBACK(signalChanged), this))
        , m_nRowActivatedSignalId(g_signal_connect(pTreeView, "row-activated", G_CALLBACK(signalRowActivated), this))
        , m_nTestExpandRowSignalId(g_signal_connect(pTreeView, "test-expand-row", G_CALLBACK(signalTestExpandRow), this))
    {
    }

    virtual void insert(int pos, const OUString& rText, const OUString* pId, const OUString* pIconName, VirtualDevice* pImageSurface) override
    virtual void insert(weld::TreeIter* pParent, int pos, const OUString& rText, const OUString* pId, const OUString* pIconName,
                        VirtualDevice* pImageSurface, const OUString* pExpanderName, bool bChildrenOnDemand) override
    {
        disable_notify_events();
        GtkTreeIter iter;
        insert_row(m_pListStore, iter, pos, pId, rText, pIconName, pImageSurface);
        GtkInstanceTreeIter* pGtkIter = static_cast<GtkInstanceTreeIter*>(pParent);
        insert_row(m_pTreeStore, iter, pGtkIter ? &pGtkIter->iter : nullptr, pos, pId, rText, pIconName, pImageSurface, pExpanderName);
        if (bChildrenOnDemand)
        {
            GtkTreeIter subiter;
            insert_row(m_pTreeStore, subiter, &iter, -1, nullptr, "<dummy>", nullptr, nullptr, nullptr);
        }
        enable_notify_events();
    }

    virtual void set_font_color(int pos, const Color& rColor) const override
    {
        GtkTreeIter iter;
        gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(m_pListStore), &iter, nullptr, pos);
        gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(m_pTreeStore), &iter, nullptr, pos);
        GdkRGBA aColor{rColor.GetRed()/255.0, rColor.GetGreen()/255.0, rColor.GetBlue()/255.0, 0};
        gtk_list_store_set(m_pListStore, &iter, 4, &aColor, -1);
        gtk_tree_store_set(m_pTreeStore, &iter, 4, &aColor, -1);
    }

    virtual void remove(int pos) override
    {
        disable_notify_events();
        GtkTreeIter iter;
        gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(m_pListStore), &iter, nullptr, pos);
        gtk_list_store_remove(m_pListStore, &iter);
        gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(m_pTreeStore), &iter, nullptr, pos);
        gtk_tree_store_remove(m_pTreeStore, &iter);
        enable_notify_events();
    }

    virtual int find_text(const OUString& rText) const override
    {
        Search aSearch(rText, 0);
        gtk_tree_model_foreach(GTK_TREE_MODEL(m_pListStore), foreach_find, &aSearch);
        gtk_tree_model_foreach(GTK_TREE_MODEL(m_pTreeStore), foreach_find, &aSearch);
        return aSearch.index;
    }

    virtual int find_id(const OUString& rId) const override
    {
        Search aSearch(rId, 1);
        gtk_tree_model_foreach(GTK_TREE_MODEL(m_pListStore), foreach_find, &aSearch);
        gtk_tree_model_foreach(GTK_TREE_MODEL(m_pTreeStore), foreach_find, &aSearch);
        return aSearch.index;
    }

@@ -4142,14 +4283,16 @@ public:
        if (pos == before)
            return;

        GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore);

        disable_notify_events();
        GtkTreeIter iter;
        gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(m_pListStore), &iter, nullptr, pos);
        gtk_tree_model_iter_nth_child(pModel, &iter, nullptr, pos);

        GtkTreeIter position;
        gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(m_pListStore), &position, nullptr, before);
        gtk_tree_model_iter_nth_child(pModel, &position, nullptr, before);

        gtk_list_store_move_before(m_pListStore, &iter, &position);
        gtk_tree_store_move_before(m_pTreeStore, &iter, &position);
        enable_notify_events();
    }

@@ -4163,7 +4306,7 @@ public:
    virtual void clear() override
    {
        disable_notify_events();
        gtk_list_store_clear(m_pListStore);
        gtk_tree_store_clear(m_pTreeStore);
        enable_notify_events();
    }

@@ -4172,14 +4315,14 @@ public:
        m_xSorter.reset(new comphelper::string::NaturalStringSorter(
                            ::comphelper::getProcessComponentContext(),
                            Application::GetSettings().GetUILanguageTag().getLocale()));
        GtkTreeSortable* pSortable = GTK_TREE_SORTABLE(m_pListStore);
        GtkTreeSortable* pSortable = GTK_TREE_SORTABLE(m_pTreeStore);
        gtk_tree_sortable_set_sort_func(pSortable, 0, sort_func, m_xSorter.get(), nullptr);
        gtk_tree_sortable_set_sort_column_id(pSortable, 0, GTK_SORT_ASCENDING);
    }

    virtual int n_children() const override
    {
        return gtk_tree_model_iter_n_children(GTK_TREE_MODEL(m_pListStore), nullptr);
        return gtk_tree_model_iter_n_children(GTK_TREE_MODEL(m_pTreeStore), nullptr);
    }

    virtual void select(int pos) override
@@ -4257,15 +4400,214 @@ public:
        return nRet;
    }

    virtual std::unique_ptr<weld::TreeIter> make_iterator(const weld::TreeIter* pOrig) const override
    {
        return std::unique_ptr<weld::TreeIter>(new GtkInstanceTreeIter(static_cast<const GtkInstanceTreeIter*>(pOrig)));
    }

    virtual void copy_iterator(const weld::TreeIter& rSource, weld::TreeIter& rDest) const override
    {
        const GtkInstanceTreeIter& rGtkSource(static_cast<const GtkInstanceTreeIter&>(rSource));
        GtkInstanceTreeIter& rGtkDest(static_cast<GtkInstanceTreeIter&>(rDest));
        rGtkDest.iter = rGtkSource.iter;
    }

    virtual bool get_selected(weld::TreeIter* pIter) const override
    {
        GtkInstanceTreeIter* pGtkIter = static_cast<GtkInstanceTreeIter*>(pIter);
        return gtk_tree_selection_get_selected(gtk_tree_view_get_selection(m_pTreeView), nullptr, pGtkIter ? &pGtkIter->iter : nullptr);
    }

    virtual bool get_cursor(weld::TreeIter* pIter) const override
    {
        GtkInstanceTreeIter* pGtkIter = static_cast<GtkInstanceTreeIter*>(pIter);
        GtkTreePath* path;
        gtk_tree_view_get_cursor(m_pTreeView, &path, nullptr);
        if (pGtkIter && path)
        {
            GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore);
            gtk_tree_model_get_iter(pModel, &pGtkIter->iter, path);
        }
        return path != nullptr;
    }

    virtual void set_cursor(const weld::TreeIter& rIter) override
    {
        const GtkInstanceTreeIter& rGtkIter = static_cast<const GtkInstanceTreeIter&>(rIter);
        GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore);
        GtkTreePath* path = gtk_tree_model_get_path(pModel, const_cast<GtkTreeIter*>(&rGtkIter.iter));
        gtk_tree_view_set_cursor(m_pTreeView, path, nullptr, false);
        gtk_tree_path_free(path);
    }

    virtual bool get_iter_first(weld::TreeIter& rIter) const override
    {
        GtkInstanceTreeIter& rGtkIter = static_cast<GtkInstanceTreeIter&>(rIter);
        GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore);
        return gtk_tree_model_get_iter_first(pModel, &rGtkIter.iter);
    }

    virtual bool iter_next_sibling(weld::TreeIter& rIter) const override
    {
        GtkInstanceTreeIter& rGtkIter = static_cast<GtkInstanceTreeIter&>(rIter);
        GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore);
        return gtk_tree_model_iter_next(pModel, &rGtkIter.iter);
    }

    virtual bool iter_next(weld::TreeIter& rIter) const override
    {
        GtkInstanceTreeIter& rGtkIter = static_cast<GtkInstanceTreeIter&>(rIter);
        GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore);
        GtkTreeIter iter = rGtkIter.iter;
        if (iter_children(rGtkIter))
            return true;
        GtkTreeIter tmp = iter;
        if (gtk_tree_model_iter_next(pModel, &tmp))
        {
            rGtkIter.iter = tmp;
            return true;
        }
        if (!gtk_tree_model_iter_parent(pModel, &tmp, &iter))
            return false;
        tmp = iter;
        if (gtk_tree_model_iter_next(pModel, &tmp))
        {
            rGtkIter.iter = tmp;
            return true;
        }
        return false;
    }

    virtual bool iter_children(weld::TreeIter& rIter) const override
    {
        GtkInstanceTreeIter& rGtkIter = static_cast<GtkInstanceTreeIter&>(rIter);
        GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore);
        GtkTreeIter tmp;
        gboolean ret = gtk_tree_model_iter_children(pModel, &tmp, &rGtkIter.iter);
        rGtkIter.iter = tmp;
        if (ret)
        {
            //on-demand dummy entry doesn't count
            return get_text(rGtkIter) != "<dummy>";
        }
        return ret;
    }

    virtual bool iter_parent(weld::TreeIter& rIter) const override
    {
        GtkInstanceTreeIter& rGtkIter = static_cast<GtkInstanceTreeIter&>(rIter);
        GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore);
        GtkTreeIter tmp;
        auto ret = gtk_tree_model_iter_parent(pModel, &tmp, &rGtkIter.iter);
        rGtkIter.iter = tmp;
        return ret;
    }

    virtual void remove(const weld::TreeIter& rIter) override
    {
        disable_notify_events();
        const GtkInstanceTreeIter& rGtkIter = static_cast<const GtkInstanceTreeIter&>(rIter);
        gtk_tree_store_remove(m_pTreeStore, const_cast<GtkTreeIter*>(&rGtkIter.iter));
        enable_notify_events();
    }

    virtual void select(const weld::TreeIter& rIter) override
    {
        assert(gtk_tree_view_get_model(m_pTreeView) && "don't select when frozen");
        disable_notify_events();
        const GtkInstanceTreeIter& rGtkIter = static_cast<const GtkInstanceTreeIter&>(rIter);
        gtk_tree_selection_select_iter(gtk_tree_view_get_selection(m_pTreeView), const_cast<GtkTreeIter*>(&rGtkIter.iter));
        enable_notify_events();
    }

    virtual void unselect(const weld::TreeIter& rIter) override
    {
        assert(gtk_tree_view_get_model(m_pTreeView) && "don't select when frozen");
        disable_notify_events();
        const GtkInstanceTreeIter& rGtkIter = static_cast<const GtkInstanceTreeIter&>(rIter);
        gtk_tree_selection_unselect_iter(gtk_tree_view_get_selection(m_pTreeView), const_cast<GtkTreeIter*>(&rGtkIter.iter));
        enable_notify_events();
    }

    virtual int get_iter_depth(const weld::TreeIter& rIter) const override
    {
        const GtkInstanceTreeIter& rGtkIter = static_cast<const GtkInstanceTreeIter&>(rIter);
        GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore);
        GtkTreePath* path = gtk_tree_model_get_path(pModel, const_cast<GtkTreeIter*>(&rGtkIter.iter));
        int ret = gtk_tree_path_get_depth(path) - 1;
        gtk_tree_path_free(path);
        return ret;
    }

    virtual bool iter_has_child(const weld::TreeIter& rIter) const override
    {
        const GtkInstanceTreeIter& rGtkIter = static_cast<const GtkInstanceTreeIter&>(rIter);
        GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore);
        return gtk_tree_model_iter_has_child(pModel, const_cast<GtkTreeIter*>(&rGtkIter.iter));
    }

    virtual bool get_row_expanded(const weld::TreeIter& rIter) const override
    {
        const GtkInstanceTreeIter& rGtkIter = static_cast<const GtkInstanceTreeIter&>(rIter);
        GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore);
        GtkTreePath* path = gtk_tree_model_get_path(pModel, const_cast<GtkTreeIter*>(&rGtkIter.iter));
        bool ret = gtk_tree_view_row_expanded(m_pTreeView, path);
        gtk_tree_path_free(path);
        return ret;
    }

    virtual void expand_row(weld::TreeIter& rIter) override
    {
        GtkInstanceTreeIter& rGtkIter = static_cast<GtkInstanceTreeIter&>(rIter);
        GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore);
        GtkTreePath* path = gtk_tree_model_get_path(pModel, &rGtkIter.iter);
        if (!gtk_tree_view_row_expanded(m_pTreeView, path))
            gtk_tree_view_expand_row(m_pTreeView, path, false);
        gtk_tree_path_free(path);
    }

    virtual OUString get_text(const weld::TreeIter& rIter) const override
    {
        const GtkInstanceTreeIter& rGtkIter = static_cast<const GtkInstanceTreeIter&>(rIter);
        GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore);
        gchar* pStr;
        gtk_tree_model_get(pModel, const_cast<GtkTreeIter*>(&rGtkIter.iter), 0, &pStr, -1);
        OUString sRet(pStr, pStr ? strlen(pStr) : 0, RTL_TEXTENCODING_UTF8);
        g_free(pStr);
        return sRet;
    }

    virtual OUString get_id(const weld::TreeIter& rIter) const override
    {
        const GtkInstanceTreeIter& rGtkIter = static_cast<const GtkInstanceTreeIter&>(rIter);
        GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore);
        gchar* pStr;
        gtk_tree_model_get(pModel, const_cast<GtkTreeIter*>(&rGtkIter.iter), 1, &pStr, -1);
        OUString sRet(pStr, pStr ? strlen(pStr) : 0, RTL_TEXTENCODING_UTF8);
        g_free(pStr);
        return sRet;
    }

    virtual void set_expander_image(const weld::TreeIter& rIter, const OUString& rExpanderName) override
    {
        const GtkInstanceTreeIter& rGtkIter = static_cast<const GtkInstanceTreeIter&>(rIter);
        disable_notify_events();
        GdkPixbuf* pixbuf = getPixbuf(rExpanderName);
        gtk_tree_store_set(m_pTreeStore, const_cast<GtkTreeIter*>(&rGtkIter.iter), 4, pixbuf, -1);
        if (pixbuf)
            g_object_unref(pixbuf);
        enable_notify_events();
    }

    virtual void freeze() override
    {
        disable_notify_events();
        g_object_ref(m_pListStore);
        g_object_ref(m_pTreeStore);
        GtkInstanceContainer::freeze();
        gtk_tree_view_set_model(m_pTreeView, nullptr);
        if (m_xSorter)
        {
            GtkTreeSortable* pSortable = GTK_TREE_SORTABLE(m_pListStore);
            GtkTreeSortable* pSortable = GTK_TREE_SORTABLE(m_pTreeStore);
            gtk_tree_sortable_set_sort_column_id(pSortable, GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
        }
        enable_notify_events();
@@ -4276,12 +4618,12 @@ public:
        disable_notify_events();
        if (m_xSorter)
        {
            GtkTreeSortable* pSortable = GTK_TREE_SORTABLE(m_pListStore);
            GtkTreeSortable* pSortable = GTK_TREE_SORTABLE(m_pTreeStore);
            gtk_tree_sortable_set_sort_column_id(pSortable, 0, GTK_SORT_ASCENDING);
        }
        gtk_tree_view_set_model(m_pTreeView, GTK_TREE_MODEL(m_pListStore));
        gtk_tree_view_set_model(m_pTreeView, GTK_TREE_MODEL(m_pTreeStore));
        GtkInstanceContainer::thaw();
        g_object_unref(m_pListStore);
        g_object_unref(m_pTreeStore);
        enable_notify_events();
    }

@@ -4371,8 +4713,9 @@ public:

    virtual ~GtkInstanceTreeView() override
    {
        g_signal_handler_disconnect(gtk_tree_view_get_selection(m_pTreeView), m_nChangedSignalId);
        g_signal_handler_disconnect(m_pTreeView, m_nTestExpandRowSignalId);
        g_signal_handler_disconnect(m_pTreeView, m_nRowActivatedSignalId);
        g_signal_handler_disconnect(gtk_tree_view_get_selection(m_pTreeView), m_nChangedSignalId);
    }
};

diff --git a/xmlsecurity/uiconfig/ui/securitytrustpage.ui b/xmlsecurity/uiconfig/ui/securitytrustpage.ui
index 488828c..c6c13f8 100644
--- a/xmlsecurity/uiconfig/ui/securitytrustpage.ui
+++ b/xmlsecurity/uiconfig/ui/securitytrustpage.ui
@@ -280,6 +280,7 @@
                        <property name="can_focus">True</property>
                        <property name="hexpand">True</property>
                        <property name="vexpand">True</property>
                        <property name="show_expanders">False</property>
                        <child internal-child="selection">
                          <object class="GtkTreeSelection" id="treeview-selection1"/>
                        </child>