weld OrganizeDialog

Change-Id: I976edb0b49c8439d1723be4544b10a5375b8e1d3
Reviewed-on: https://gerrit.libreoffice.org/73755
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/basctl/source/basicide/basides1.cxx b/basctl/source/basicide/basides1.cxx
index 5fac746..c04f0c3 100644
--- a/basctl/source/basicide/basides1.cxx
+++ b/basctl/source/basicide/basides1.cxx
@@ -328,10 +328,10 @@ void Shell::ExecuteGlobal( SfxRequest& rReq )
            if ( rReq.GetArgs() )
            {
                const SfxUInt16Item &rTabId = rReq.GetArgs()->Get(SID_BASICIDE_ARG_TABID );
                Organize( rTabId.GetValue() );
                Organize(rReq.GetFrameWeld(), rTabId.GetValue());
            }
            else
                Organize( 0 );
                Organize(rReq.GetFrameWeld(), 0);
        }
        break;
        case SID_BASICIDE_CHOOSEMACRO:
diff --git a/basctl/source/basicide/basobj2.cxx b/basctl/source/basicide/basobj2.cxx
index de273c0..694277c3 100644
--- a/basctl/source/basicide/basobj2.cxx
+++ b/basctl/source/basicide/basobj2.cxx
@@ -55,14 +55,14 @@ extern "C" {

        return pScriptURL;
    }
    SAL_DLLPUBLIC_EXPORT void basicide_macro_organizer( sal_Int16 nTabId )
    SAL_DLLPUBLIC_EXPORT void basicide_macro_organizer(void *pParent, sal_Int16 nTabId)
    {
        SAL_INFO("basctl.basicide","in basicide_macro_organizer");
        basctl::Organize( nTabId );
        basctl::Organize(static_cast<weld::Window*>(pParent), nTabId);
    }
}

void Organize( sal_Int16 tabId )
void Organize(weld::Window* pParent, sal_Int16 tabId)
{
    EnsureIde();

@@ -71,8 +71,8 @@ void Organize( sal_Int16 tabId )
        if (BaseWindow* pCurWin = pShell->GetCurWindow())
            aDesc = pCurWin->CreateEntryDescriptor();

    vcl::Window* pParent = Application::GetDefDialogParent();
    VclPtr<OrganizeDialog>::Create(pParent, tabId, aDesc)->StartExecuteAsync(nullptr);
    auto xDlg(std::make_shared<OrganizeDialog>(pParent, tabId, aDesc));
    weld::DialogController::runAsync(xDlg, [](int) {});
}

bool IsValidSbxName( const OUString& rName )
@@ -247,7 +247,7 @@ OUString ChooseMacro(weld::Window* pParent,
    OUString aScriptURL;
    SbMethod* pMethod = nullptr;

    MacroChooser aChooser(pParent, xDocFrame);
    MacroChooser aChooser(pParent, xDocFrame, true);
    if ( bChooseOnly || !SvtModuleOptions::IsBasicIDE() )
        aChooser.SetMode(MacroChooser::ChooseOnly);

diff --git a/basctl/source/basicide/macrodlg.cxx b/basctl/source/basicide/macrodlg.cxx
index 252328f..279aa23 100644
--- a/basctl/source/basicide/macrodlg.cxx
+++ b/basctl/source/basicide/macrodlg.cxx
@@ -50,7 +50,7 @@ using std::map;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;

MacroChooser::MacroChooser(weld::Window* pParnt, const Reference< frame::XFrame >& xDocFrame)
MacroChooser::MacroChooser(weld::Window* pParnt, const Reference< frame::XFrame >& xDocFrame, bool bCreateEntries)
    : SfxDialogController(pParnt, "modules/BasicIDE/ui/basicmacrodialog.ui", "BasicMacroDialog")
    , m_xDocumentFrame(xDocFrame)
    // the Sfx doesn't ask the BasicManager whether modified or not
@@ -107,7 +107,8 @@ MacroChooser::MacroChooser(weld::Window* pParnt, const Reference< frame::XFrame 
    if (SfxDispatcher* pDispatcher = GetDispatcher())
        pDispatcher->Execute( SID_BASICIDE_STOREALLMODULESOURCES );

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

MacroChooser::~MacroChooser()
@@ -742,24 +743,23 @@ IMPL_LINK(MacroChooser, ButtonHdl, weld::Button&, rButton, void)

        m_xBasicBox->get_selected(m_xBasicBoxIter.get());
        EntryDescriptor aDesc = m_xBasicBox->GetEntryDescriptor(m_xBasicBoxIter.get());
        VclPtrInstance< OrganizeDialog > pDlg( nullptr, 0, aDesc ); //TODO
        pDlg->StartExecuteAsync([this](sal_Int32 nRet){
                if ( nRet ) // not only closed
                {
                    m_xDialog->response(Macro_Edit);
                    return;
                }
        auto xDlg(std::make_shared<OrganizeDialog>(m_xDialog.get(), 0, aDesc));
        weld::DialogController::runAsync(xDlg, [this](sal_Int32 nRet) {
            if (nRet == RET_OK) // not only closed
            {
                m_xDialog->response(Macro_Edit);
                return;
            }

                Shell* pShell = GetShell();
                if ( pShell && pShell->IsAppBasicModified() )
                    bForceStoreBasic = true;
            Shell* pShell = GetShell();
            if ( pShell && pShell->IsAppBasicModified() )
                bForceStoreBasic = true;

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


void MacroChooser::UpdateFields()
{
    auto nMacroEntry = m_xMacroBox->get_selected_index();
diff --git a/basctl/source/basicide/macrodlg.hxx b/basctl/source/basicide/macrodlg.hxx
index 9ab71ac..ceacc14 100644
--- a/basctl/source/basicide/macrodlg.hxx
+++ b/basctl/source/basicide/macrodlg.hxx
@@ -89,7 +89,7 @@ private:
    std::unique_ptr<weld::Button> m_xNewLibButton;
    std::unique_ptr<weld::Button> m_xNewModButton;
public:
    MacroChooser(weld::Window *pParent, const ::css::uno::Reference< ::css::frame::XFrame >& xDocFrame);
    MacroChooser(weld::Window *pParent, const ::css::uno::Reference< ::css::frame::XFrame >& xDocFrame, bool bCreateEntries);
    virtual ~MacroChooser() override;

    SbMethod*           GetMacro();
diff --git a/basctl/source/basicide/moduldl2.cxx b/basctl/source/basicide/moduldl2.cxx
index 7352953..00cfe90 100644
--- a/basctl/source/basicide/moduldl2.cxx
+++ b/basctl/source/basicide/moduldl2.cxx
@@ -97,247 +97,22 @@ public:
    }
};

// LibUserData
class LibUserData final
{
private:
    ScriptDocument m_aDocument;

public:
    explicit LibUserData(ScriptDocument const& rDocument)
        : m_aDocument(rDocument)
    {
    }

    const ScriptDocument& GetDocument() const { return m_aDocument; }
};

//  LibLBoxString
class LibLBoxString : public SvLBoxString
{
public:
    explicit LibLBoxString(const OUString& rTxt)
        : SvLBoxString(rTxt)
    {
    }

    virtual void Paint(const Point& rPos, SvTreeListBox& rDev, vcl::RenderContext& rRenderContext,
                       const SvViewDataEntry* pView, const SvTreeListEntry& rEntry) override;
};

void LibLBoxString::Paint(const Point& rPos, SvTreeListBox& /*rDev*/, vcl::RenderContext& rRenderContext,
                          const SvViewDataEntry* /*pView*/, const SvTreeListEntry& rEntry)
{
    // Change text color if library is read only:
    bool bReadOnly = false;
    if (rEntry.GetUserData())
    {
        ScriptDocument aDocument(static_cast<LibUserData*>(rEntry.GetUserData())->GetDocument());

        OUString aLibName = static_cast<const SvLBoxString&>(rEntry.GetItem(1)).GetText();
        Reference<script::XLibraryContainer2> xModLibContainer(aDocument.getLibraryContainer(E_SCRIPTS), UNO_QUERY);
        Reference<script::XLibraryContainer2 > xDlgLibContainer(aDocument.getLibraryContainer(E_DIALOGS), UNO_QUERY);
        bReadOnly = (xModLibContainer.is() && xModLibContainer->hasByName(aLibName) && xModLibContainer->isLibraryReadOnly(aLibName))
                 || (xDlgLibContainer.is() && xDlgLibContainer->hasByName(aLibName) && xDlgLibContainer->isLibraryReadOnly(aLibName));
    }
    if (bReadOnly)
        rRenderContext.DrawCtrlText(rPos, GetText(), 0, -1, DrawTextFlags::Disable);
    else
        rRenderContext.DrawText(rPos, GetText());
}

} // namespace

//  basctl::CheckBox
CheckBox::CheckBox(vcl::Window* pParent, WinBits nStyle)
    : SvTabListBox(pParent, nStyle)
    , eMode(ObjectMode::Module)
    , m_aDocument(ScriptDocument::getApplicationScriptDocument())
namespace
{
    long const aTabPositions[] = { 12 };  // TabPos needs at least one...
                                          // 12 because of the CheckBox
    SetTabs( SAL_N_ELEMENTS(aTabPositions), aTabPositions );
    Init();
}

VCL_BUILDER_FACTORY_CONSTRUCTOR(CheckBox, WB_TABSTOP)

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

void CheckBox::dispose()
{
    pCheckButton.reset();

    // delete user data
    SvTreeListEntry* pEntry = First();
    while ( pEntry )
    int FindEntry(weld::TreeView& rBox, const OUString& rName)
    {
        delete static_cast<LibUserData*>( pEntry->GetUserData() );
        pEntry->SetUserData( nullptr );
        pEntry = Next( pEntry );
    }
    SvTabListBox::dispose();
}

void CheckBox::Init()
{
    pCheckButton.reset(new SvLBoxButtonData(this));

    if (eMode == ObjectMode::Library)
        EnableCheckButton( pCheckButton.get() );
    else
        EnableCheckButton( nullptr );

    SetHighlightRange();
}

void CheckBox::SetMode (ObjectMode e)
{
    eMode = e;

    if (eMode == ObjectMode::Library)
        EnableCheckButton( pCheckButton.get() );
    else
        EnableCheckButton( nullptr );
}

SvTreeListEntry* CheckBox::DoInsertEntry( const OUString& rStr, sal_uLong nPos )
{
    return SvTabListBox::InsertEntryToColumn( rStr, nPos, 0 );
}

SvTreeListEntry* CheckBox::FindEntry( const OUString& rName )
{
    sal_uLong nCount = GetEntryCount();
    for ( sal_uLong i = 0; i < nCount; i++ )
    {
        SvTreeListEntry* pEntry = GetEntry( i );
        DBG_ASSERT( pEntry, "pEntry?!" );
        if ( rName.equalsIgnoreAsciiCase( GetEntryText( pEntry, 0 ) ) )
            return pEntry;
    }
    return nullptr;
}

void CheckBox::InitEntry(SvTreeListEntry* pEntry, const OUString& rTxt,
    const Image& rImg1, const Image& rImg2, SvLBoxButtonKind eButtonKind )
{
    SvTabListBox::InitEntry(pEntry, rTxt, rImg1, rImg2, eButtonKind);

    if (eMode == ObjectMode::Module)
    {
        // initialize all columns with own string class (column 0 == bitmap)
        sal_uInt16 nCount = pEntry->ItemCount();
        for ( sal_uInt16 nCol = 1; nCol < nCount; ++nCol )
        int nCount = rBox.n_children();
        for (int i = 0; i < nCount; ++i)
        {
            SvLBoxString& rCol = static_cast<SvLBoxString&>(pEntry->GetItem( nCol ));
            pEntry->ReplaceItem(std::make_unique<LibLBoxString>( rCol.GetText() ), nCol);
            if (rName.equalsIgnoreAsciiCase(rBox.get_text(i, 0)))
                return i;
        }
        return -1;
    }
}

bool CheckBox::EditingEntry( SvTreeListEntry* pEntry, Selection& )
{
    if (eMode != ObjectMode::Module)
        return false;

    DBG_ASSERT( pEntry, "No entry?" );

    // check, if Standard library
    OUString aLibName = GetEntryText( pEntry, 0 );
    if ( aLibName.equalsIgnoreAsciiCase( "Standard" ) )
    {
        std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(GetFrameWeld(),
                                                       VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_CANNOTCHANGENAMESTDLIB)));
        xErrorBox->run();
        return false;
    }

    // check, if library is readonly
    Reference< script::XLibraryContainer2 > xModLibContainer( m_aDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
    Reference< script::XLibraryContainer2 > xDlgLibContainer( m_aDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
    if ( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryReadOnly( aLibName ) && !xModLibContainer->isLibraryLink( aLibName ) ) ||
         ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) && !xDlgLibContainer->isLibraryLink( aLibName ) ) )
    {
        std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(GetFrameWeld(),
                                                       VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_LIBISREADONLY)));
        xErrorBox->run();
        return false;
    }

    // i24094: Password verification necessary for renaming
    if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && !xModLibContainer->isLibraryLoaded( aLibName ) )
    {
        bool bOK = true;
        // check password
        Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
        if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aLibName ) && !xPasswd->isLibraryPasswordVerified( aLibName ) )
        {
            OUString aPassword;
            Reference< script::XLibraryContainer > xModLibContainer1( xModLibContainer, UNO_QUERY );
            bOK = QueryPassword( xModLibContainer1, aLibName, aPassword );
        }
        if ( !bOK )
            return false;
    }

    // TODO: check if library is reference/link

    return true;
}

bool CheckBox::EditedEntry( SvTreeListEntry* pEntry, const OUString& rNewName )
{
    bool bValid = rNewName.getLength() <= 30 && IsValidSbxName(rNewName);
    OUString aOldName( GetEntryText( pEntry, 0 ) );
    if ( bValid && ( aOldName != rNewName ) )
    {
        try
        {
            Reference< script::XLibraryContainer2 > xModLibContainer( m_aDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
            if ( xModLibContainer.is() )
                xModLibContainer->renameLibrary( aOldName, rNewName );

            Reference< script::XLibraryContainer2 > xDlgLibContainer( m_aDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
            if ( xDlgLibContainer.is() )
                xDlgLibContainer->renameLibrary( aOldName, rNewName );

            MarkDocumentModified( m_aDocument );
            if (SfxBindings* pBindings = GetBindingsPtr())
            {
                pBindings->Invalidate( SID_BASICIDE_LIBSELECTOR );
                pBindings->Update( SID_BASICIDE_LIBSELECTOR );
            }
        }
        catch (const container::ElementExistException& )
        {
            std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(GetFrameWeld(),
                                                           VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_SBXNAMEALLREADYUSED)));
            xErrorBox->run();
            return false;
        }
        catch (const container::NoSuchElementException& )
        {
            DBG_UNHANDLED_EXCEPTION("basctl.basicide");
            return false;
        }
    }

    if ( !bValid )
    {
        OUString sWarning(rNewName.getLength() > 30 ? IDEResId(RID_STR_LIBNAMETOLONG) : IDEResId(RID_STR_BADSBXNAME));
        std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(GetFrameWeld(),
                                                       VclMessageType::Warning, VclButtonsType::Ok, sWarning));
        xErrorBox->run();

    }

    return bValid;
}

// NewObjectDialog
IMPL_LINK_NOARG(NewObjectDialog, OkButtonHandler, weld::Button&, void)
{
@@ -424,125 +199,202 @@ ExportDialog::~ExportDialog()
}

// LibPage
LibPage::LibPage(vcl::Window * pParent)
    : TabPage(pParent, "LibPage",
        "modules/BasicIDE/ui/libpage.ui")
LibPage::LibPage(weld::Container* pParent, OrganizeDialog* pDialog)
    : OrganizePage(pParent, "modules/BasicIDE/ui/libpage.ui", "LibPage", pDialog)
    , m_xBasicsBox(m_xBuilder->weld_combo_box("location"))
    , m_xLibBox(m_xBuilder->weld_tree_view("library"))
    , m_xEditButton(m_xBuilder->weld_button("edit"))
    , m_xPasswordButton(m_xBuilder->weld_button("password"))
    , m_xNewLibButton(m_xBuilder->weld_button("new"))
    , m_xInsertLibButton(m_xBuilder->weld_button("import"))
    , m_xExportButton(m_xBuilder->weld_button("export"))
    , m_xDelButton(m_xBuilder->weld_button("delete"))
    , m_aCurDocument(ScriptDocument::getApplicationScriptDocument())
    , m_eCurLocation(LIBRARY_LOCATION_UNKNOWN)
{
    get(m_pBasicsBox, "location");
    get(m_pLibBox, "library");
    Size aSize(m_pLibBox->LogicToPixel(Size(130, 87), MapMode(MapUnit::MapAppFont)));
    m_pLibBox->set_height_request(aSize.Height());
    m_pLibBox->set_width_request(aSize.Width());
    get(m_pEditButton, "edit");
    get(m_pPasswordButton, "password");
    get(m_pNewLibButton, "new");
    get(m_pInsertLibButton, "import");
    get(m_pExportButton, "export");
    get(m_pDelButton, "delete");
    Size aSize(m_xLibBox->get_approximate_digit_width() * 40,
               m_xLibBox->get_height_rows(10));
    m_xLibBox->set_size_request(aSize.Width(), aSize.Height());

    pTabDlg = nullptr;
    m_xEditButton->connect_clicked( LINK( this, LibPage, ButtonHdl ) );
    m_xNewLibButton->connect_clicked( LINK( this, LibPage, ButtonHdl ) );
    m_xPasswordButton->connect_clicked( LINK( this, LibPage, ButtonHdl ) );
    m_xExportButton->connect_clicked( LINK( this, LibPage, ButtonHdl ) );
    m_xInsertLibButton->connect_clicked( LINK( this, LibPage, ButtonHdl ) );
    m_xDelButton->connect_clicked( LINK( this, LibPage, ButtonHdl ) );
    m_xLibBox->connect_changed( LINK( this, LibPage, TreeListHighlightHdl ) );

    m_pEditButton->SetClickHdl( LINK( this, LibPage, ButtonHdl ) );
    m_pNewLibButton->SetClickHdl( LINK( this, LibPage, ButtonHdl ) );
    m_pPasswordButton->SetClickHdl( LINK( this, LibPage, ButtonHdl ) );
    m_pExportButton->SetClickHdl( LINK( this, LibPage, ButtonHdl ) );
    m_pInsertLibButton->SetClickHdl( LINK( this, LibPage, ButtonHdl ) );
    m_pDelButton->SetClickHdl( LINK( this, LibPage, ButtonHdl ) );
    m_pLibBox->SetSelectHdl( LINK( this, LibPage, TreeListHighlightHdl ) );
    m_xBasicsBox->connect_changed( LINK( this, LibPage, BasicSelectHdl ) );

    m_pBasicsBox->SetSelectHdl( LINK( this, LibPage, BasicSelectHdl ) );

    m_pLibBox->SetMode(ObjectMode::Module);
    m_pLibBox->EnableInplaceEditing(true);
    m_pLibBox->SetStyle( WB_HSCROLL | WB_BORDER | WB_TABSTOP );

    long const aTabPositions[] = { 30, 120 };
    m_pLibBox->SetTabs( SAL_N_ELEMENTS(aTabPositions), aTabPositions, MapUnit::MapPixel );
    m_xLibBox->connect_editing_started( LINK( this, LibPage, EditingEntryHdl ) );
    m_xLibBox->connect_editing_done( LINK( this, LibPage, EditedEntryHdl ) );

    FillListBox();
    m_pBasicsBox->SelectEntryPos( 0 );
    m_xBasicsBox->set_active(0);
    SetCurLib();

    CheckButtons();
}

LibPage::~LibPage()
IMPL_LINK(LibPage, EditingEntryHdl, const weld::TreeIter&, rIter, bool)
{
    disposeOnce();
    // check, if Standard library
    OUString aLibName = m_xLibBox->get_text(rIter, 0);

    if ( aLibName.equalsIgnoreAsciiCase( "Standard" ) )
    {
        std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDialog->getDialog(),
                                                       VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_CANNOTCHANGENAMESTDLIB)));
        xErrorBox->run();
        return false;
    }

    // check, if library is readonly
    Reference< script::XLibraryContainer2 > xModLibContainer( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
    Reference< script::XLibraryContainer2 > xDlgLibContainer( m_aCurDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
    if ( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryReadOnly( aLibName ) && !xModLibContainer->isLibraryLink( aLibName ) ) ||
         ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) && !xDlgLibContainer->isLibraryLink( aLibName ) ) )
    {
        std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDialog->getDialog(),
                                                       VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_LIBISREADONLY)));
        xErrorBox->run();
        return false;
    }

    // i24094: Password verification necessary for renaming
    if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && !xModLibContainer->isLibraryLoaded( aLibName ) )
    {
        bool bOK = true;
        // check password
        Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
        if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aLibName ) && !xPasswd->isLibraryPasswordVerified( aLibName ) )
        {
            OUString aPassword;
            Reference< script::XLibraryContainer > xModLibContainer1( xModLibContainer, UNO_QUERY );
            bOK = QueryPassword( xModLibContainer1, aLibName, aPassword );
        }
        if ( !bOK )
            return false;
    }

    // TODO: check if library is reference/link

    return true;
}

void LibPage::dispose()
IMPL_LINK(LibPage, EditedEntryHdl, const IterString&, rIterString, bool)
{
    if (m_pBasicsBox)
    const weld::TreeIter& rIter = rIterString.first;
    OUString sNewName = rIterString.second;

    bool bValid = sNewName.getLength() <= 30 && IsValidSbxName(sNewName);
    OUString aOldName(m_xLibBox->get_text(rIter, 0));

    if (bValid && aOldName != sNewName)
    {
        const sal_Int32 nCount = m_pBasicsBox->GetEntryCount();
        for ( sal_Int32 i = 0; i < nCount; ++i )
        try
        {
            DocumentEntry* pEntry = static_cast<DocumentEntry*>(m_pBasicsBox->GetEntryData( i ));
            Reference< script::XLibraryContainer2 > xModLibContainer( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
            if ( xModLibContainer.is() )
                xModLibContainer->renameLibrary( aOldName, sNewName );

            Reference< script::XLibraryContainer2 > xDlgLibContainer( m_aCurDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
            if ( xDlgLibContainer.is() )
                xDlgLibContainer->renameLibrary( aOldName, sNewName );

            MarkDocumentModified( m_aCurDocument );
            if (SfxBindings* pBindings = GetBindingsPtr())
            {
                pBindings->Invalidate( SID_BASICIDE_LIBSELECTOR );
                pBindings->Update( SID_BASICIDE_LIBSELECTOR );
            }
        }
        catch (const container::ElementExistException& )
        {
            std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDialog->getDialog(),
                                                           VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_SBXNAMEALLREADYUSED)));
            xErrorBox->run();
            return false;
        }
        catch (const container::NoSuchElementException& )
        {
            DBG_UNHANDLED_EXCEPTION("basctl.basicide");
            return false;
        }
    }

    if ( !bValid )
    {
        OUString sWarning(sNewName.getLength() > 30 ? IDEResId(RID_STR_LIBNAMETOLONG) : IDEResId(RID_STR_BADSBXNAME));
        std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDialog->getDialog(),
                                                       VclMessageType::Warning, VclButtonsType::Ok, sWarning));
        xErrorBox->run();

    }

    return bValid;
}

LibPage::~LibPage()
{
    if (m_xBasicsBox)
    {
        const sal_Int32 nCount = m_xBasicsBox->get_count();
        for (sal_Int32 i = 0; i < nCount; ++i)
        {
            DocumentEntry* pEntry = reinterpret_cast<DocumentEntry*>(m_xBasicsBox->get_id(i).toInt64());
            delete pEntry;
        }
    }
    m_pBasicsBox.clear();
    m_pLibBox.clear();
    m_pEditButton.clear();
    m_pPasswordButton.clear();
    m_pNewLibButton.clear();
    m_pInsertLibButton.clear();
    m_pExportButton.clear();
    m_pDelButton.clear();
    pTabDlg.clear();
    TabPage::dispose();
}

void LibPage::CheckButtons()
{
    SvTreeListEntry* pCur = m_pLibBox->GetCurEntry();
    if ( pCur )
    std::unique_ptr<weld::TreeIter> xCur(m_xLibBox->make_iterator());
    if (m_xLibBox->get_cursor(xCur.get()))
    {
        OUString aLibName = SvTabListBox::GetEntryText( pCur, 0 );
        OUString aLibName = m_xLibBox->get_text(*xCur, 0);
        Reference< script::XLibraryContainer2 > xModLibContainer( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
        Reference< script::XLibraryContainer2 > xDlgLibContainer( m_aCurDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );

        if ( m_eCurLocation == LIBRARY_LOCATION_SHARE )
        {
            m_pPasswordButton->Disable();
            m_pNewLibButton->Disable();
            m_pInsertLibButton->Disable();
            m_pDelButton->Disable();
            m_xPasswordButton->set_sensitive(false);
            m_xNewLibButton->set_sensitive(false);
            m_xInsertLibButton->set_sensitive(false);
            m_xDelButton->set_sensitive(false);
        }
        else if ( aLibName.equalsIgnoreAsciiCase( "Standard" ) )
        {
            m_pPasswordButton->Disable();
            m_pNewLibButton->Enable();
            m_pInsertLibButton->Enable();
            m_pExportButton->Disable();
            m_pDelButton->Disable();
            m_xPasswordButton->set_sensitive(false);
            m_xNewLibButton->set_sensitive(true);
            m_xInsertLibButton->set_sensitive(true);
            m_xExportButton->set_sensitive(false);
            m_xDelButton->set_sensitive(false);
        }
        else if ( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryReadOnly( aLibName ) ) ||
                  ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) ) )
        {
            m_pPasswordButton->Disable();
            m_pNewLibButton->Enable();
            m_pInsertLibButton->Enable();
            m_xPasswordButton->set_sensitive(false);
            m_xNewLibButton->set_sensitive(true);
            m_xInsertLibButton->set_sensitive(true);
            if ( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryReadOnly( aLibName ) && !xModLibContainer->isLibraryLink( aLibName ) ) ||
                 ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) && !xDlgLibContainer->isLibraryLink( aLibName ) ) )
                m_pDelButton->Disable();
                m_xDelButton->set_sensitive(false);
            else
                m_pDelButton->Enable();
                m_xDelButton->set_sensitive(true);
        }
        else
        {
            if ( xModLibContainer.is() && !xModLibContainer->hasByName( aLibName ) )
                m_pPasswordButton->Disable();
                m_xPasswordButton->set_sensitive(false);
            else
                m_pPasswordButton->Enable();
                m_xPasswordButton->set_sensitive(true);

            m_pNewLibButton->Enable();
            m_pInsertLibButton->Enable();
            m_pExportButton->Enable();
            m_pDelButton->Enable();
            m_xNewLibButton->set_sensitive(true);
            m_xInsertLibButton->set_sensitive(true);
            m_xExportButton->set_sensitive(true);
            m_xDelButton->set_sensitive(true);
        }
    }
}
@@ -552,34 +404,31 @@ void LibPage::ActivatePage()
    SetCurLib();
}

void LibPage::DeactivatePage()
IMPL_LINK_NOARG(LibPage, TreeListHighlightHdl, weld::TreeView&, void)
{
    CheckButtons();
}

IMPL_LINK( LibPage, TreeListHighlightHdl, SvTreeListBox *, pBox, void )
{
    if ( pBox->IsSelected( pBox->GetHdlEntry() ) )
        CheckButtons();
}

IMPL_LINK_NOARG( LibPage, BasicSelectHdl, ListBox&, void )
IMPL_LINK_NOARG( LibPage, BasicSelectHdl, weld::ComboBox&, void )
{
    SetCurLib();
    CheckButtons();
}

IMPL_LINK( LibPage, ButtonHdl, Button *, pButton, void )
IMPL_LINK( LibPage, ButtonHdl, weld::Button&, rButton, void )
{
    if (pButton == m_pEditButton)
    if (&rButton == m_xEditButton.get())
    {
        SfxAllItemSet aArgs( SfxGetpApp()->GetPool() );
        SfxRequest aRequest( SID_BASICIDE_APPEAR, SfxCallMode::SYNCHRON, aArgs );
        SfxGetpApp()->ExecuteSlot( aRequest );

        SfxUnoAnyItem aDocItem( SID_BASICIDE_ARG_DOCUMENT_MODEL, Any( m_aCurDocument.getDocumentOrNull() ) );
        SvTreeListEntry* pCurEntry = m_pLibBox->GetCurEntry();
        DBG_ASSERT( pCurEntry, "Entry?!" );
        OUString aLibName( SvTabListBox::GetEntryText( pCurEntry, 0 ) );

        std::unique_ptr<weld::TreeIter> xCurEntry(m_xLibBox->make_iterator());
        if (!m_xLibBox->get_cursor(xCurEntry.get()))
            return;
        OUString aLibName(m_xLibBox->get_text(*xCurEntry, 0));
        SfxStringItem aLibNameItem( SID_BASICIDE_ARG_LIBNAME, aLibName );
        if (SfxDispatcher* pDispatcher = GetDispatcher())
            pDispatcher->ExecuteList( SID_BASICIDE_LIBSELECTED,
@@ -587,18 +436,20 @@ IMPL_LINK( LibPage, ButtonHdl, Button *, pButton, void )
        EndTabDialog();
        return;
    }
    else if (pButton == m_pNewLibButton)
    else if (&rButton == m_xNewLibButton.get())
        NewLib();
    else if (pButton == m_pInsertLibButton)
    else if (&rButton == m_xInsertLibButton.get())
        InsertLib();
    else if (pButton == m_pExportButton)
    else if (&rButton == m_xExportButton.get())
        Export();
    else if (pButton == m_pDelButton)
    else if (&rButton == m_xDelButton.get())
        DeleteCurrent();
    else if (pButton == m_pPasswordButton)
    else if (&rButton == m_xPasswordButton.get())
    {
        SvTreeListEntry* pCurEntry = m_pLibBox->GetCurEntry();
        OUString aLibName( SvTabListBox::GetEntryText( pCurEntry, 0 ) );
        std::unique_ptr<weld::TreeIter> xCurEntry(m_xLibBox->make_iterator());
        if (!m_xLibBox->get_cursor(xCurEntry.get()))
            return;
        OUString aLibName(m_xLibBox->get_text(*xCurEntry, 0));

        // load module library (if not loaded)
        Reference< script::XLibraryContainer > xModLibContainer = m_aCurDocument.getLibraryContainer( E_SCRIPTS );
@@ -633,7 +484,7 @@ IMPL_LINK( LibPage, ButtonHdl, Button *, pButton, void )
                bool const bProtected = xPasswd->isLibraryPasswordProtected( aLibName );

                // change password dialog
                SvxPasswordDialog aDlg(GetFrameWeld(), !bProtected);
                SvxPasswordDialog aDlg(m_pDialog->getDialog(), !bProtected);
                aDlg.SetCheckPasswordHdl(LINK(this, LibPage, CheckPasswordHdl));

                if (aDlg.run() == RET_OK)
@@ -642,10 +493,10 @@ IMPL_LINK( LibPage, ButtonHdl, Button *, pButton, void )

                    if ( bNewProtected != bProtected )
                    {
                        sal_uLong nPos = m_pLibBox->GetModel()->GetAbsPos( pCurEntry );
                        m_pLibBox->GetModel()->Remove( pCurEntry );
                        ImpInsertLibEntry( aLibName, nPos );
                        m_pLibBox->SetCurEntry( m_pLibBox->GetEntry( nPos ) );
                        int nPos = m_xLibBox->get_iter_index_in_parent(*xCurEntry);
                        m_xLibBox->remove(*xCurEntry);
                        ImpInsertLibEntry(aLibName, nPos);
                        m_xLibBox->set_cursor(nPos);
                    }

                    MarkDocumentModified( m_aCurDocument );
@@ -660,8 +511,11 @@ IMPL_LINK( LibPage, CheckPasswordHdl, SvxPasswordDialog *, pDlg, bool )
{
    bool bRet = false;

    SvTreeListEntry* pCurEntry = m_pLibBox->GetCurEntry();
    OUString aLibName( SvTabListBox::GetEntryText( pCurEntry, 0 ) );
    std::unique_ptr<weld::TreeIter> xCurEntry(m_xLibBox->make_iterator());
    if (!m_xLibBox->get_cursor(xCurEntry.get()))
        return bRet;

    OUString aLibName(m_xLibBox->get_text(*xCurEntry, 0));
    Reference< script::XLibraryContainerPassword > xPasswd( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );

    if ( xPasswd.is() )
@@ -683,14 +537,14 @@ IMPL_LINK( LibPage, CheckPasswordHdl, SvxPasswordDialog *, pDlg, bool )

void LibPage::NewLib()
{
    createLibImpl(GetFrameWeld(), m_aCurDocument, m_pLibBox, static_cast<SbTreeListBox*>(nullptr));
    createLibImpl(m_pDialog->getDialog(), m_aCurDocument, m_xLibBox.get(), nullptr);
}

void LibPage::InsertLib()
{
    Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
    // file open dialog
    sfx2::FileDialogHelper aDlg(ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, FileDialogFlags::NONE, pTabDlg ? pTabDlg->GetFrameWeld() : nullptr);
    sfx2::FileDialogHelper aDlg(ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, FileDialogFlags::NONE, m_pDialog->getDialog());
    const Reference <XFilePicker3>& xFP = aDlg.GetFilePicker();

    xFP->setTitle(IDEResId(RID_STR_APPENDLIBS));
@@ -782,7 +636,7 @@ void LibPage::InsertLib()
        // library import dialog
        if (!xLibDlg)
        {
            xLibDlg.reset(new LibDialog(GetFrameWeld()));
            xLibDlg.reset(new LibDialog(m_pDialog->getDialog()));
            xLibDlg->SetStorageName( aURLObj.getName() );
        }

@@ -801,7 +655,7 @@ void LibPage::InsertLib()

    if (!xLibDlg)
    {
        std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(GetFrameWeld(),
        std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDialog->getDialog(),
                                                       VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_NOLIBINSTORAGE)));
        xErrorBox->run();
        return;
@@ -821,7 +675,7 @@ void LibPage::InsertLib()
                return;

            bool bChanges = false;
            sal_uLong nNewPos = m_pLibBox->GetEntryCount();
            int nNewPos = m_xLibBox->n_children();
            bool bRemove = false;
            bool bReplace = xLibDlg->IsReplace();
            bool bReference = xLibDlg->IsReference();
@@ -843,7 +697,7 @@ void LibPage::InsertLib()
                            // check, if the library is the Standard library
                            if ( aLibName == "Standard" )
                            {
                                std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(GetFrameWeld(),
                                std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDialog->getDialog(),
                                                                               VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_REPLACESTDLIB)));
                                xErrorBox->run();
                                continue;
@@ -855,7 +709,7 @@ void LibPage::InsertLib()
                            {
                                OUString aErrStr( IDEResId(RID_STR_REPLACELIB) );
                                aErrStr = aErrStr.replaceAll("XX", aLibName) + "\n" + IDEResId(RID_STR_LIBISREADONLY);
                                std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(GetFrameWeld(),
                                std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDialog->getDialog(),
                                                                               VclMessageType::Warning, VclButtonsType::Ok, aErrStr));
                                xErrorBox->run();
                                continue;
@@ -872,7 +726,7 @@ void LibPage::InsertLib()
                            else
                                aErrStr = IDEResId(RID_STR_IMPORTNOTPOSSIBLE);
                            aErrStr = aErrStr.replaceAll("XX", aLibName) + "\n" +IDEResId(RID_STR_SBXNAMEALLREADYUSED);
                            std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(GetFrameWeld(),
                            std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDialog->getDialog(),
                                                                           VclMessageType::Warning, VclButtonsType::Ok, aErrStr));
                            xErrorBox->run();
                            continue;
@@ -893,7 +747,7 @@ void LibPage::InsertLib()
                            {
                                OUString aErrStr( IDEResId(RID_STR_NOIMPORT) );
                                aErrStr = aErrStr.replaceAll("XX", aLibName);
                                std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(GetFrameWeld(),
                                std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDialog->getDialog(),
                                                                               VclMessageType::Warning, VclButtonsType::Ok, aErrStr));
                                xErrorBox->run();
                                continue;
@@ -905,9 +759,9 @@ void LibPage::InsertLib()
                    if ( bRemove )
                    {
                        // remove listbox entry
                        SvTreeListEntry* pEntry_ = m_pLibBox->FindEntry( aLibName );
                        if ( pEntry_ )
                            m_pLibBox->SvTreeListBox::GetModel()->Remove( pEntry_ );
                        int nEntry_ = FindEntry(*m_xLibBox, aLibName);
                        if (nEntry_ != -1)
                            m_xLibBox->remove(nEntry_);

                        // remove module library
                        if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) )
@@ -1039,14 +893,13 @@ void LibPage::InsertLib()
                    }

                    // insert listbox entry
                    ImpInsertLibEntry( aLibName, m_pLibBox->GetEntryCount() );
                    ImpInsertLibEntry( aLibName, m_xLibBox->n_children() );
                    bChanges = true;
                }
            }

            SvTreeListEntry* pFirstNew = m_pLibBox->GetEntry( nNewPos );
            if ( pFirstNew )
                m_pLibBox->SetCurEntry( pFirstNew );
            if (nNewPos < m_xLibBox->n_children())
                m_xLibBox->set_cursor(nNewPos);

            if ( bChanges )
                MarkDocumentModified( m_aCurDocument );
@@ -1055,8 +908,10 @@ void LibPage::InsertLib()

void LibPage::Export()
{
    SvTreeListEntry* pCurEntry = m_pLibBox->GetCurEntry();
    OUString aLibName( SvTabListBox::GetEntryText( pCurEntry, 0 ) );
    std::unique_ptr<weld::TreeIter> xCurEntry(m_xLibBox->make_iterator());
    if (!m_xLibBox->get_cursor(xCurEntry.get()))
        return;
    OUString aLibName(m_xLibBox->get_text(*xCurEntry, 0));

    // Password verification
    Reference< script::XLibraryContainer2 > xModLibContainer( m_aCurDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
@@ -1077,7 +932,7 @@ void LibPage::Export()
            return;
    }

    std::unique_ptr<ExportDialog> xNewDlg(new ExportDialog(GetFrameWeld()));
    std::unique_ptr<ExportDialog> xNewDlg(new ExportDialog(m_pDialog->getDialog()));
    if (xNewDlg->run() == RET_OK)
    {
        try
@@ -1147,7 +1002,7 @@ Reference< XProgressHandler > OLibCommandEnvironment::getProgressHandler()
void LibPage::ExportAsPackage( const OUString& aLibName )
{
    // file open dialog
    sfx2::FileDialogHelper aDlg(ui::dialogs::TemplateDescription::FILESAVE_SIMPLE, FileDialogFlags::NONE, pTabDlg ? pTabDlg->GetFrameWeld() : nullptr);
    sfx2::FileDialogHelper aDlg(ui::dialogs::TemplateDescription::FILESAVE_SIMPLE, FileDialogFlags::NONE, m_pDialog->getDialog());
    const Reference <XFilePicker3>& xFP = aDlg.GetFilePicker();

    Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
@@ -1292,8 +1147,10 @@ void LibPage::ExportAsBasic( const OUString& aLibName )

void LibPage::DeleteCurrent()
{
    SvTreeListEntry* pCurEntry = m_pLibBox->GetCurEntry();
    OUString aLibName( SvTabListBox::GetEntryText( pCurEntry, 0 ) );
    std::unique_ptr<weld::TreeIter> xCurEntry(m_xLibBox->make_iterator());
    if (!m_xLibBox->get_cursor(xCurEntry.get()))
        return;
    OUString aLibName(m_xLibBox->get_text(*xCurEntry, 0));

    // check, if library is link
    bool bIsLibraryLink = false;
@@ -1305,7 +1162,7 @@ void LibPage::DeleteCurrent()
        bIsLibraryLink = true;
    }

    if (QueryDelLib(aLibName, bIsLibraryLink, GetFrameWeld()))
    if (QueryDelLib(aLibName, bIsLibraryLink, m_pDialog->getDialog()))
    {
        // inform BasicIDE
        SfxUnoAnyItem aDocItem( SID_BASICIDE_ARG_DOCUMENT_MODEL, Any( m_aCurDocument.getDocumentOrNull() ) );
@@ -1320,16 +1177,14 @@ void LibPage::DeleteCurrent()
        if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) )
            xDlgLibContainer->removeLibrary( aLibName );

        static_cast<SvTreeListBox&>(*m_pLibBox).GetModel()->Remove( pCurEntry );
        m_xLibBox->remove(*xCurEntry);
        MarkDocumentModified( m_aCurDocument );
    }
}

void LibPage::EndTabDialog()
{
    DBG_ASSERT( pTabDlg, "TabDlg not set!" );
    if ( pTabDlg )
        pTabDlg->EndDialog( 1 );
    m_pDialog->response(RET_OK);
}

void LibPage::FillListBox()
@@ -1346,16 +1201,15 @@ void LibPage::FillListBox()

void LibPage::InsertListBoxEntry( const ScriptDocument& rDocument, LibraryLocation eLocation )
{
    OUString aEntryText( rDocument.getTitle( eLocation ) );
    const sal_Int32 nPos = m_pBasicsBox->InsertEntry( aEntryText );
    m_pBasicsBox->SetEntryData( nPos, new DocumentEntry(rDocument, eLocation) );
    OUString aEntryText(rDocument.getTitle(eLocation));
    OUString sId(OUString::number(reinterpret_cast<sal_Int64>(new DocumentEntry(rDocument, eLocation))));
    m_xBasicsBox->append(sId,  aEntryText);
}

void LibPage::SetCurLib()
{
    const sal_Int32 nSelPos = m_pBasicsBox->GetSelectedEntryPos();
    DocumentEntry* pEntry = static_cast<DocumentEntry*>(m_pBasicsBox->GetEntryData( nSelPos ));
    if ( pEntry )
    DocumentEntry* pEntry = reinterpret_cast<DocumentEntry*>(m_xBasicsBox->get_active_id().toInt64());
    if (pEntry)
    {
        const ScriptDocument& aDocument( pEntry->GetDocument() );
        DBG_ASSERT( aDocument.isAlive(), "LibPage::SetCurLib: no document, or document is dead!" );
@@ -1366,30 +1220,30 @@ void LibPage::SetCurLib()
        {
            m_aCurDocument = aDocument;
            m_eCurLocation = eLocation;
            m_pLibBox->SetDocument( aDocument );
            m_pLibBox->Clear();
            m_xLibBox->clear();

            // get a sorted list of library names
            Sequence< OUString > aLibNames = aDocument.getLibraryNames();
            sal_Int32 nLibCount = aLibNames.getLength();
            const OUString* pLibNames = aLibNames.getConstArray();

            for ( sal_Int32 i = 0 ; i < nLibCount ; i++ )
            int nEntry = 0;
            for (int i = 0 ; i < nLibCount; ++i)
            {
                OUString aLibName( pLibNames[ i ] );
                if ( eLocation == aDocument.getLibraryLocation( aLibName ) )
                    ImpInsertLibEntry( aLibName, i );
                OUString aLibName(pLibNames[i]);
                if (eLocation == aDocument.getLibraryLocation(aLibName))
                    ImpInsertLibEntry(aLibName, nEntry++);
            }

            SvTreeListEntry* pEntry_ = m_pLibBox->FindEntry( "Standard" );
            if ( !pEntry_ )
                pEntry_ = m_pLibBox->GetEntry( 0 );
            m_pLibBox->SetCurEntry( pEntry_ );
            int nEntry_ = FindEntry(*m_xLibBox, "Standard");
            if (nEntry_ == -1 && m_xLibBox->n_children())
                nEntry_ = 0;
            m_xLibBox->set_cursor(nEntry_);
        }
    }
}

SvTreeListEntry* LibPage::ImpInsertLibEntry( const OUString& rLibName, sal_uLong nPos )
void LibPage::ImpInsertLibEntry( const OUString& rLibName, sal_uLong nPos )
{
    // check, if library is password protected
    bool bProtected = false;
@@ -1403,29 +1257,22 @@ SvTreeListEntry* LibPage::ImpInsertLibEntry( const OUString& rLibName, sal_uLong
        }
    }

    SvTreeListEntry* pNewEntry = m_pLibBox->DoInsertEntry( rLibName, nPos );
    pNewEntry->SetUserData( new LibUserData(m_aCurDocument) );
    m_xLibBox->insert_text(nPos, rLibName);

    if (bProtected)
    {
        Image aImage(StockImage::Yes, RID_BMP_LOCKED);
        m_pLibBox->SetExpandedEntryBmp(pNewEntry, aImage);
        m_pLibBox->SetCollapsedEntryBmp(pNewEntry, aImage);
    }
        m_xLibBox->set_image(nPos, RID_BMP_LOCKED);

    // check, if library is link
    if ( xModLibContainer.is() && xModLibContainer->hasByName( rLibName ) && xModLibContainer->isLibraryLink( rLibName ) )
    {
        OUString aLinkURL = xModLibContainer->getLibraryLinkURL( rLibName );
        m_pLibBox->SetEntryText( aLinkURL, pNewEntry, 1 );
        m_xLibBox->set_text(nPos, aLinkURL, 1);
    }

    return pNewEntry;
}

// Helper function
void createLibImpl(weld::Window* pWin, const ScriptDocument& rDocument,
                   CheckBox* pLibBox, TreeListBox* pBasicBox)
                   weld::TreeView* pLibBox, SbTreeListBox* pBasicBox)
{
    OSL_ENSURE( rDocument.isAlive(), "createLibImpl: invalid document!" );
    if ( !rDocument.isAlive() )
@@ -1479,121 +1326,8 @@ void createLibImpl(weld::Window* pWin, const ScriptDocument& rDocument,

                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 )
                {
                    SvTreeListEntry* pEntry = pBasicBox->GetCurEntry();
                    SvTreeListEntry* pRootEntry = nullptr;
                    while( pEntry )
                    {
                        pRootEntry = pEntry;
                        pEntry = pBasicBox->GetParent( pEntry );
                    }

                    BrowseMode nMode = pBasicBox->GetMode();
                    bool bDlgMode = ( nMode & BrowseMode::Dialogs ) && !( nMode & BrowseMode::Modules );
                    const OUString sId = bDlgMode ? OUStringLiteral(RID_BMP_DLGLIB) : OUStringLiteral(RID_BMP_MODLIB);
                    SvTreeListEntry* pNewLibEntry = pBasicBox->AddEntry(
                        aLibName,
                        Image(StockImage::Yes, sId),
                        pRootEntry, false,
                        std::make_unique<Entry>(OBJ_TYPE_LIBRARY));
                    DBG_ASSERT( pNewLibEntry, "Insert entry failed!" );

                    if( pNewLibEntry )
                    {
                        SvTreeListEntry* pEntry_ = pBasicBox->AddEntry(
                            aModName,
                            Image(StockImage::Yes, RID_BMP_MODULE),
                            pNewLibEntry, false,
                            std::make_unique<Entry>(OBJ_TYPE_MODULE));
                        DBG_ASSERT( pEntry_, "Insert entry failed!" );
                        pBasicBox->SetCurEntry( pEntry_ );
                        pBasicBox->Select( pBasicBox->GetCurEntry() );      // OV-Bug?!
                    }
                }
            }
            catch (const uno::Exception& )
            {
                DBG_UNHANDLED_EXCEPTION("basctl.basicide");
            }
        }
    }
}

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 );
                    pLibBox->append_text(aLibName);
                    pLibBox->set_cursor(pLibBox->n_children() - 1);
                }

                // create a module
diff --git a/basctl/source/basicide/moduldlg.cxx b/basctl/source/basicide/moduldlg.cxx
index 9be10de..d4cb43b 100644
--- a/basctl/source/basicide/moduldlg.cxx
+++ b/basctl/source/basicide/moduldlg.cxx
@@ -50,58 +50,48 @@ using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::resource;


// ExtTreeListBox

ExtTreeListBox::ExtTreeListBox(vcl::Window* pParent, WinBits nStyle)
    : TreeListBox(pParent, nStyle)
{
}

VCL_BUILDER_FACTORY_CONSTRUCTOR(ExtTreeListBox, WB_TABSTOP)

bool ExtTreeListBox::EditingEntry( SvTreeListEntry* pEntry, Selection& )
IMPL_LINK(ObjectPage, EditingEntryHdl, const weld::TreeIter&, rEntry, bool)
{
    bool bRet = false;

    if ( pEntry )
    sal_uInt16 nDepth = m_xBasicBox->get_iter_depth(rEntry);
    if (nDepth >= 2)
    {
        sal_uInt16 nDepth = GetModel()->GetDepth( pEntry );
        if ( nDepth >= 2 )
        EntryDescriptor aDesc = m_xBasicBox->GetEntryDescriptor(&rEntry);
        const ScriptDocument& aDocument( aDesc.GetDocument() );
        const OUString& aLibName( aDesc.GetLibName() );
        Reference< script::XLibraryContainer2 > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
        Reference< script::XLibraryContainer2 > xDlgLibContainer( aDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
        if ( !( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryReadOnly( aLibName ) ) ||
                ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) ) ) )
        {
            EntryDescriptor aDesc = GetEntryDescriptor(pEntry);
            const ScriptDocument& aDocument( aDesc.GetDocument() );
            const OUString& aLibName( aDesc.GetLibName() );
            Reference< script::XLibraryContainer2 > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
            Reference< script::XLibraryContainer2 > xDlgLibContainer( aDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
            if ( !( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryReadOnly( aLibName ) ) ||
                    ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) ) ) )
            {
                // allow editing only for libraries, which are not readonly
                bRet = true;
            }
            // allow editing only for libraries, which are not readonly
            bRet = true;
        }
    }

    return bRet;
}

bool ExtTreeListBox::EditedEntry( SvTreeListEntry* pEntry, const OUString& rNewText )
IMPL_LINK(ObjectPage, EditedEntryHdl, const IterString&, rIterString, bool)
{
    if ( !IsValidSbxName(rNewText) )
    const weld::TreeIter& rEntry = rIterString.first;
    OUString sNewText = rIterString.second;

    if ( !IsValidSbxName(sNewText) )
    {
        std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(GetFrameWeld(),
        std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(m_pDialog->getDialog(),
                                                    VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_BADSBXNAME)));
        xError->run();
        return false;
    }

    OUString aCurText( GetEntryText( pEntry ) );
    if ( aCurText == rNewText )
    OUString aCurText(m_xBasicBox->get_text(rEntry));
    if ( aCurText == sNewText )
        // nothing to do
        return true;

    EntryDescriptor aDesc = GetEntryDescriptor(pEntry);
    EntryDescriptor aDesc = m_xBasicBox->GetEntryDescriptor(&rEntry);
    const ScriptDocument& aDocument( aDesc.GetDocument() );
    DBG_ASSERT( aDocument.isValid(), "ExtTreeListBox::EditedEntry: no document!" );
    if ( !aDocument.isValid() )
@@ -110,8 +100,8 @@ bool ExtTreeListBox::EditedEntry( SvTreeListEntry* pEntry, const OUString& rNewT
    EntryType eType = aDesc.GetType();

    bool bSuccess = eType == OBJ_TYPE_MODULE ?
        RenameModule(GetFrameWeld(), aDocument, aLibName, aCurText, rNewText) :
        RenameDialog(GetFrameWeld(), aDocument, aLibName, aCurText, rNewText);
        RenameModule(m_pDialog->getDialog(), aDocument, aLibName, aCurText, sNewText) :
        RenameDialog(m_pDialog->getDialog(), aDocument, aLibName, aCurText, sNewText);

    if ( !bSuccess )
        return false;
@@ -120,142 +110,20 @@ bool ExtTreeListBox::EditedEntry( SvTreeListEntry* pEntry, const OUString& rNewT

    if (SfxDispatcher* pDispatcher = GetDispatcher())
    {
        SbxItem aSbxItem( SID_BASICIDE_ARG_SBX, aDocument, aLibName, rNewText, ConvertType( eType ) );
        SbxItem aSbxItem(SID_BASICIDE_ARG_SBX, aDocument, aLibName, sNewText, SbTreeListBox::ConvertType(eType));
        pDispatcher->ExecuteList( SID_BASICIDE_SBXRENAMED,
                            SfxCallMode::SYNCHRON, { &aSbxItem });
    }

    // OV-Bug?!
    SetEntryText( pEntry, rNewText );
    SetCurEntry( pEntry );
    SetCurEntry( pEntry );
    Select( pEntry, false );
    Select( pEntry );       // so that handler is called => update edit
    m_xBasicBox->set_text(rEntry, sNewText);
    m_xBasicBox->set_cursor(rEntry);
    m_xBasicBox->unselect(rEntry);
    m_xBasicBox->select(rEntry); // so that handler is called => update edit

    return true;
}


DragDropMode ExtTreeListBox::NotifyStartDrag( TransferDataContainer&, SvTreeListEntry* pEntry )
{
    DragDropMode nMode_ = DragDropMode::NONE;

    if ( pEntry )
    {
        sal_uInt16 nDepth = GetModel()->GetDepth( pEntry );
        if ( nDepth >= 2 )
        {
            nMode_ = DragDropMode::CTRL_COPY;
            EntryDescriptor aDesc = GetEntryDescriptor(pEntry);
            const ScriptDocument& aDocument( aDesc.GetDocument() );
            const OUString& aLibName( aDesc.GetLibName() );
            // allow MOVE mode only for libraries, which are not readonly
            Reference< script::XLibraryContainer2 > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
            Reference< script::XLibraryContainer2 > xDlgLibContainer( aDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
            if ( !( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryReadOnly( aLibName ) ) ||
                    ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) ) ) )
            {
                // Only allow copy for localized libraries
                bool bAllowMove = true;
                if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) )
                {
                    // Get StringResourceManager
                    Reference< container::XNameContainer > xDialogLib( aDocument.getLibrary( E_DIALOGS, aLibName, true ) );
                    Reference< XStringResourceManager > xSourceMgr =
                        LocalizationMgr::getStringResourceFromDialogLibrary( xDialogLib );
                    if( xSourceMgr.is() )
                        bAllowMove = !xSourceMgr->getLocales().hasElements();
                }
                if( bAllowMove )
                    nMode_ |= DragDropMode::CTRL_MOVE;
            }
        }
    }

    return nMode_;
}


bool ExtTreeListBox::NotifyAcceptDrop( SvTreeListEntry* pEntry )
{
    // don't drop on a BasicManager (nDepth == 0)
    sal_uInt16 nDepth = pEntry ? GetModel()->GetDepth( pEntry ) : 0;
    bool bValid = nDepth != 0;

    // don't drop in the same library
    SvTreeListEntry* pSelected = FirstSelected();
    if (!pSelected)
        bValid = false;
    else if ( ( nDepth == 1 ) && ( pEntry == GetParent( pSelected ) ) )
        bValid = false;
    else if ( ( nDepth == 2 ) && ( GetParent( pEntry ) == GetParent( pSelected ) ) )
        bValid = false;

    // don't drop on a library, which is not loaded, readonly or password protected
    // or which already has a module/dialog with this name
    if ( bValid && ( nDepth > 0 ) )
    {
        // get source module/dialog name
        EntryDescriptor aSourceDesc = GetEntryDescriptor(pSelected);
        const OUString& aSourceName = aSourceDesc.GetName();
        EntryType eSourceType = aSourceDesc.GetType();

        // get target shell and target library name
        EntryDescriptor aDestDesc = GetEntryDescriptor(pEntry);
        ScriptDocument const& rDestDoc = aDestDesc.GetDocument();
        const OUString& aDestLibName = aDestDesc.GetLibName();

        // check if module library is not loaded, readonly or password protected
        Reference< script::XLibraryContainer2 > xModLibContainer( rDestDoc.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
        if ( xModLibContainer.is() && xModLibContainer->hasByName( aDestLibName ) )
        {
            if ( !xModLibContainer->isLibraryLoaded( aDestLibName ) )
                bValid = false;

            if ( xModLibContainer->isLibraryReadOnly( aDestLibName ) )
                bValid = false;

            Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
            if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aDestLibName ) && !xPasswd->isLibraryPasswordVerified( aDestLibName ) )
                bValid = false;
        }

        // check if dialog library is not loaded or readonly
        Reference< script::XLibraryContainer2 > xDlgLibContainer( rDestDoc.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
        if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aDestLibName ) )
        {
            if ( !xDlgLibContainer->isLibraryLoaded( aDestLibName ) )
                bValid = false;

            if ( xDlgLibContainer->isLibraryReadOnly( aDestLibName ) )
                bValid = false;
        }

        // check, if module/dialog with this name is already existing in target library
        if ( ( eSourceType == OBJ_TYPE_MODULE && rDestDoc.hasModule( aDestLibName, aSourceName ) ) ||
            ( eSourceType == OBJ_TYPE_DIALOG && rDestDoc.hasDialog( aDestLibName, aSourceName ) ) )
        {
            bValid = false;
        }
    }

    return bValid;
}

TriState ExtTreeListBox::NotifyMoving( SvTreeListEntry* pTarget, SvTreeListEntry* pEntry,
                        SvTreeListEntry*& rpNewParent, sal_uLong& rNewChildPos )
{
    return NotifyCopyingMoving( pTarget, pEntry,
                                    rpNewParent, rNewChildPos, true );
}

TriState ExtTreeListBox::NotifyCopying( SvTreeListEntry* pTarget, SvTreeListEntry* pEntry,
                        SvTreeListEntry*& rpNewParent, sal_uLong& rNewChildPos )
{
    return NotifyCopyingMoving( pTarget, pEntry,
                                    rpNewParent, rNewChildPos, false );
}

void Shell::CopyDialogResources(
    Reference< io::XInputStreamProvider >& io_xISP,
    ScriptDocument const& rSourceDoc,
@@ -312,339 +180,430 @@ void Shell::CopyDialogResources(
    }
}

TriState ExtTreeListBox::NotifyCopyingMoving( SvTreeListEntry* pTarget, SvTreeListEntry const * pEntry,
                        SvTreeListEntry*& rpNewParent, sal_uLong& rNewChildPos, bool bMove )
{
    DBG_ASSERT( pEntry, "No entry?" );   // ASS is ok here, should not be reached
    DBG_ASSERT( pTarget, "No target?" ); // with NULL (right at the beginning)
    sal_uInt16 nDepth = GetModel()->GetDepth( pTarget );
    DBG_ASSERT( nDepth, "Depth?" );
    if ( nDepth == 1 )
    {
        // Target = Basic => put module/dialog under the Basic
        rpNewParent = pTarget;
        rNewChildPos = 0;
    }
    else if ( nDepth >= 2 )
    {
        // Target = module/dialog => put module/dialog under the superordinate Basic
        rpNewParent = GetParent( pTarget );
        rNewChildPos = SvTreeList::GetRelPos( pTarget ) + 1;
    }

    // get target shell and target library name
    EntryDescriptor aDestDesc = GetEntryDescriptor(rpNewParent);
    const ScriptDocument& rDestDoc( aDestDesc.GetDocument() );
    const OUString& aDestLibName( aDestDesc.GetLibName() );

    // get source shell, library name and module/dialog name
    EntryDescriptor aSourceDesc = GetEntryDescriptor(FirstSelected());
    const ScriptDocument& rSourceDoc( aSourceDesc.GetDocument() );
    const OUString& aSourceLibName( aSourceDesc.GetLibName() );
    const OUString& aSourceName( aSourceDesc.GetName() );
    EntryType eType = aSourceDesc.GetType();

    // get dispatcher
    SfxDispatcher* pDispatcher = GetDispatcher();

    if ( bMove )    // move
    {
        // remove source module/dialog window
        if ( rSourceDoc != rDestDoc || aSourceLibName != aDestLibName )
        {
            if( pDispatcher )
            {
                SbxItem aSbxItem( SID_BASICIDE_ARG_SBX, rSourceDoc, aSourceLibName, aSourceName, ConvertType( eType ) );
                pDispatcher->ExecuteList( SID_BASICIDE_SBXDELETED,
                      SfxCallMode::SYNCHRON, { &aSbxItem });
            }
        }

        try
        {
            if ( eType == OBJ_TYPE_MODULE ) // module
            {
                // get module
                OUString aModule;
                if ( rSourceDoc.getModule( aSourceLibName, aSourceName, aModule ) )
                {
                    // remove module from source library
                    if ( rSourceDoc.removeModule( aSourceLibName, aSourceName ) )
                    {
                        MarkDocumentModified( rSourceDoc );

                        // insert module into target library
                        if ( rDestDoc.insertModule( aDestLibName, aSourceName, aModule ) )
                            MarkDocumentModified( rDestDoc );
                    }
                }
            }
            else if ( eType == OBJ_TYPE_DIALOG )    // dialog
            {
                // get dialog
                Reference< io::XInputStreamProvider > xISP;
                if ( rSourceDoc.getDialog( aSourceLibName, aSourceName, xISP ) )
                {
                    Shell::CopyDialogResources( xISP, rSourceDoc,
                        aSourceLibName, rDestDoc, aDestLibName, aSourceName );

                    // remove dialog from source library
                    if (RemoveDialog(rSourceDoc, aSourceLibName, aSourceName))
                    {
                        MarkDocumentModified(rSourceDoc);

                        // insert dialog into target library
                        if ( rDestDoc.insertDialog( aDestLibName, aSourceName, xISP ) )
                            MarkDocumentModified(rDestDoc);
                    }
                }
            }
        }
        catch (const uno::Exception& )
        {
            DBG_UNHANDLED_EXCEPTION("basctl.basicide");
        }
    }
    else    // copy
    {
        try
        {
            if ( eType == OBJ_TYPE_MODULE ) // module
            {
                // get module
                OUString aModule;
                if ( rSourceDoc.getModule( aSourceLibName, aSourceName, aModule ) )
                {
                    // insert module into target library
                    if ( rDestDoc.insertModule( aDestLibName, aSourceName, aModule ) )
                        MarkDocumentModified( rDestDoc );
                }
            }
            else if ( eType == OBJ_TYPE_DIALOG )    // dialog
            {
                // get dialog
                Reference< io::XInputStreamProvider > xISP;
                if ( rSourceDoc.getDialog( aSourceLibName, aSourceName, xISP ) )
                {
                    Shell::CopyDialogResources( xISP, rSourceDoc,
                        aSourceLibName, rDestDoc, aDestLibName, aSourceName );

                    // insert dialog into target library
                    if ( rDestDoc.insertDialog( aDestLibName, aSourceName, xISP ) )
                        MarkDocumentModified( rDestDoc );
                }
            }
        }
        catch ( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION("basctl.basicide");
        }
    }

    // create target module/dialog window
    if ( rSourceDoc != rDestDoc || aSourceLibName != aDestLibName )
    {
        if( pDispatcher )
        {
            SbxItem aSbxItem( SID_BASICIDE_ARG_SBX, rDestDoc, aDestLibName, aSourceName, ConvertType( eType ) );
            pDispatcher->ExecuteList( SID_BASICIDE_SBXINSERTED,
                                  SfxCallMode::SYNCHRON, { &aSbxItem });
        }
    }

    return TRISTATE_INDET;   // open...
}

// OrganizeDialog
OrganizeDialog::OrganizeDialog(vcl::Window* pParent, sal_Int16 tabId,
OrganizeDialog::OrganizeDialog(weld::Window* pParent, sal_Int16 tabId,
    EntryDescriptor const & rDesc )
    : TabDialog( pParent, "OrganizeDialog",
        "modules/BasicIDE/ui/organizedialog.ui" )
    , m_aCurEntry( rDesc )
    : GenericDialogController(pParent, "modules/BasicIDE/ui/organizedialog.ui", "OrganizeDialog")
    , m_xTabCtrl(m_xBuilder->weld_notebook("tabcontrol"))
    , m_xModulePage(new ObjectPage(m_xTabCtrl->get_page("modules"), "ModulePage", BrowseMode::Modules, this))
    , m_xDialogPage(new ObjectPage(m_xTabCtrl->get_page("dialogs"), "DialogPage", BrowseMode::Dialogs, this))
    , m_xLibPage(new LibPage(m_xTabCtrl->get_page("libraries"), this))
    , m_aCurEntry(rDesc)
{
    get(m_pTabCtrl, "tabcontrol");
    m_xTabCtrl->connect_enter_page(LINK(this, OrganizeDialog, ActivatePageHdl));

    sal_uInt16 nPageCount = m_pTabCtrl->GetPageCount();
    for (sal_uInt16 nPage = 0; nPage < nPageCount; ++nPage)
    {
        sal_uInt16 nPageId = m_pTabCtrl->GetPageId(nPage);
        m_pTabCtrl->SetTabPage(nPageId, nullptr);
    }

    m_pTabCtrl->SetActivatePageHdl(LINK(this, OrganizeDialog, ActivatePageHdl));

    if( tabId == 0 )
    {
        m_pTabCtrl->SetCurPageId(m_pTabCtrl->GetPageId("modules"));
    }
    else if ( tabId == 1 )
    {
        m_pTabCtrl->SetCurPageId(m_pTabCtrl->GetPageId("dialogs"));
    }
    if (tabId == 0)
        m_xTabCtrl->set_current_page("modules");
    else if (tabId == 1)
        m_xTabCtrl->set_current_page("dialogs");
    else
    {
        m_pTabCtrl->SetCurPageId(m_pTabCtrl->GetPageId("libraries"));
    }

    ActivatePageHdl(m_pTabCtrl);
        m_xTabCtrl->set_current_page("libraries");

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

IMPL_LINK(OrganizeDialog, ActivatePageHdl, const OString&, rPage, void)
{
    if (rPage == "modules")
        m_xModulePage->ActivatePage();
    else if (rPage == "dialogs")
        m_xDialogPage->ActivatePage();
    else if (rPage == "libraries")
        m_xLibPage->ActivatePage();
}

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

void OrganizeDialog::dispose()
OrganizePage::OrganizePage(weld::Container* pParent, const OUString& rUIFile, const OString &rName, OrganizeDialog* pDialog)
    : m_pDialog(pDialog)
    , m_xBuilder(Application::CreateBuilder(pParent, rUIFile))
    , m_xContainer(m_xBuilder->weld_container(rName))
{
    if (m_pTabCtrl)
    {
        for ( sal_uInt16 i = 0; i < m_pTabCtrl->GetPageCount(); i++ )
            VclPtr<vcl::Window>(m_pTabCtrl->GetTabPage( m_pTabCtrl->GetPageId( i ) )).disposeAndClear();
    }
    m_pTabCtrl.clear();
}

    TabDialog::dispose();
OrganizePage::~OrganizePage()
{
}

class SbTreeListBoxDropTarget : public DropTargetHelper
{
private:
    SbTreeListBox& m_rTreeView;

    virtual sal_Int8 AcceptDrop(const AcceptDropEvent& rEvt) override
    {
        // to enable the autoscroll when we're close to the edges
        weld::TreeView& rWidget = m_rTreeView.get_widget();
        rWidget.get_dest_row_at_pos(rEvt.maPosPixel, nullptr);

        weld::TreeView* pSource = rWidget.get_drag_source();
        if (!pSource)
            return DND_ACTION_NONE;

        sal_Int8 nMode = DND_ACTION_NONE;

        std::unique_ptr<weld::TreeIter> xEntry(pSource->make_iterator());
        if (pSource->get_selected(xEntry.get()))
        {
            sal_uInt16 nDepth = pSource->get_iter_depth(*xEntry);
            if (nDepth >= 2)
            {
                nMode = DND_ACTION_COPY;
                EntryDescriptor aDesc = m_rTreeView.GetEntryDescriptor(xEntry.get());
                const ScriptDocument& aDocument( aDesc.GetDocument() );
                const OUString& aLibName( aDesc.GetLibName() );
                // allow MOVE mode only for libraries, which are not readonly
                Reference< script::XLibraryContainer2 > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
                Reference< script::XLibraryContainer2 > xDlgLibContainer( aDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
                if ( !( ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryReadOnly( aLibName ) ) ||
                        ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryReadOnly( aLibName ) ) ) )
                {
                    // Only allow copy for localized libraries
                    bool bAllowMove = true;
                    if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) )
                    {
                        // Get StringResourceManager
                        Reference< container::XNameContainer > xDialogLib( aDocument.getLibrary( E_DIALOGS, aLibName, true ) );
                        Reference< XStringResourceManager > xSourceMgr =
                            LocalizationMgr::getStringResourceFromDialogLibrary( xDialogLib );
                        if( xSourceMgr.is() )
                            bAllowMove = ( xSourceMgr->getLocales().getLength() == 0 );
                    }
                    if( bAllowMove )
                        nMode |= DND_ACTION_MOVE;
                }
            }
        }
        return nMode;
    }

    virtual sal_Int8 ExecuteDrop(const ExecuteDropEvent& rEvt) override
    {
        weld::TreeView& rWidget = m_rTreeView.get_widget();
        weld::TreeView* pSource = rWidget.get_drag_source();
        if (!pSource)
            return DND_ACTION_NONE;

        std::unique_ptr<weld::TreeIter> xEntry(rWidget.make_iterator());
        bool bEntry = rWidget.get_dest_row_at_pos(rEvt.maPosPixel, xEntry.get());

        // don't drop on a BasicManager (nDepth == 0)
        sal_uInt16 nDepth = bEntry ? m_rTreeView.get_iter_depth(*xEntry) : 0;
        bool bValid = nDepth != 0;
        // don't drop in the same library
        std::unique_ptr<weld::TreeIter> xSelected(pSource->make_iterator());
        bool bSelected = pSource->get_selected(xSelected.get());
        if (!bSelected)
            bValid = false;
        else if (nDepth == 1)
        {
            std::unique_ptr<weld::TreeIter> xSelParent(pSource->make_iterator(xSelected.get()));
            if (pSource->iter_parent(*xSelParent) && pSource->iter_compare(*xEntry, *xSelParent) == 0)
                bValid = false;
        }
        else if (nDepth == 2)
        {
            std::unique_ptr<weld::TreeIter> xParent(pSource->make_iterator(xEntry.get()));
            std::unique_ptr<weld::TreeIter> xSelParent(pSource->make_iterator(xSelected.get()));
            if (pSource->iter_parent(*xParent) && pSource->iter_parent(*xSelParent) && pSource->iter_compare(*xParent, *xSelParent) == 0)
                bValid = false;
        }

        // don't drop on a library, which is not loaded, readonly or password protected
        // or which already has a module/dialog with this name
        if ( bValid && ( nDepth > 0 ) )
        {
            // get source module/dialog name
            EntryDescriptor aSourceDesc = m_rTreeView.GetEntryDescriptor(xSelected.get());
            const OUString& aSourceName = aSourceDesc.GetName();
            EntryType eSourceType = aSourceDesc.GetType();

            // get target shell and target library name
            EntryDescriptor aDestDesc = m_rTreeView.GetEntryDescriptor(xEntry.get());
            ScriptDocument const& rDestDoc = aDestDesc.GetDocument();
            const OUString& aDestLibName = aDestDesc.GetLibName();

            // check if module library is not loaded, readonly or password protected
            Reference< script::XLibraryContainer2 > xModLibContainer( rDestDoc.getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
            if ( xModLibContainer.is() && xModLibContainer->hasByName( aDestLibName ) )
            {
                if ( !xModLibContainer->isLibraryLoaded( aDestLibName ) )
                    bValid = false;

                if ( xModLibContainer->isLibraryReadOnly( aDestLibName ) )
                    bValid = false;

                Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
                if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aDestLibName ) && !xPasswd->isLibraryPasswordVerified( aDestLibName ) )
                    bValid = false;
            }

            // check if dialog library is not loaded or readonly
            Reference< script::XLibraryContainer2 > xDlgLibContainer( rDestDoc.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
            if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aDestLibName ) )
            {
                if ( !xDlgLibContainer->isLibraryLoaded( aDestLibName ) )
                    bValid = false;

                if ( xDlgLibContainer->isLibraryReadOnly( aDestLibName ) )
                    bValid = false;
            }

            // check, if module/dialog with this name is already existing in target library
            if ( ( eSourceType == OBJ_TYPE_MODULE && rDestDoc.hasModule( aDestLibName, aSourceName ) ) ||
                ( eSourceType == OBJ_TYPE_DIALOG && rDestDoc.hasDialog( aDestLibName, aSourceName ) ) )
            {
                bValid = false;
            }
        }

        if (bValid)
            NotifyCopyingMoving(*xEntry, rEvt.mnAction & DND_ACTION_MOVE);

        return DND_ACTION_NONE;
    }

    void NotifyCopyingMoving(weld::TreeIter& rTarget, bool bMove)
    {
        sal_uInt16 nDepth = m_rTreeView.get_iter_depth(rTarget);
        std::unique_ptr<weld::TreeIter> xNewParent(m_rTreeView.make_iterator(&rTarget));
        int nNewChildPos = 0;
        DBG_ASSERT( nDepth, "Depth?" );
        if ( nDepth >= 2 )
        {
            // Target = module/dialog => put module/dialog under the superordinate Basic
            m_rTreeView.iter_parent(*xNewParent);
            nNewChildPos = m_rTreeView.get_iter_index_in_parent(rTarget) + 1;
        }

        // get target shell and target library name
        EntryDescriptor aDestDesc = m_rTreeView.GetEntryDescriptor(xNewParent.get());
        const ScriptDocument& rDestDoc( aDestDesc.GetDocument() );
        const OUString& aDestLibName( aDestDesc.GetLibName() );

        // get source shell, library name and module/dialog name
        std::unique_ptr<weld::TreeIter> xSelected(m_rTreeView.make_iterator());
        if (!m_rTreeView.get_selected(xSelected.get()))
            xSelected.reset();
        EntryDescriptor aSourceDesc = m_rTreeView.GetEntryDescriptor(xSelected.get());
        const ScriptDocument& rSourceDoc( aSourceDesc.GetDocument() );
        const OUString& aSourceLibName( aSourceDesc.GetLibName() );
        const OUString& aSourceName( aSourceDesc.GetName() );
        EntryType eType = aSourceDesc.GetType();

        // get dispatcher
        SfxDispatcher* pDispatcher = GetDispatcher();

        if ( bMove )    // move
        {
            // remove source module/dialog window
            if ( rSourceDoc != rDestDoc || aSourceLibName != aDestLibName )
            {
                if( pDispatcher )
                {
                    SbxItem aSbxItem( SID_BASICIDE_ARG_SBX, rSourceDoc, aSourceLibName, aSourceName, SbTreeListBox::ConvertType(eType) );
                    pDispatcher->ExecuteList( SID_BASICIDE_SBXDELETED,
                          SfxCallMode::SYNCHRON, { &aSbxItem });
                }
            }

            try
            {
                if ( eType == OBJ_TYPE_MODULE ) // module
                {
                    // get module
                    OUString aModule;
                    if ( rSourceDoc.getModule( aSourceLibName, aSourceName, aModule ) )
                    {
                        // remove module from source library
                        if ( rSourceDoc.removeModule( aSourceLibName, aSourceName ) )
                        {
                            MarkDocumentModified( rSourceDoc );

                            // insert module into target library
                            if ( rDestDoc.insertModule( aDestLibName, aSourceName, aModule ) )
                                MarkDocumentModified( rDestDoc );
                        }
                    }
                }
                else if ( eType == OBJ_TYPE_DIALOG )    // dialog
                {
                    // get dialog
                    Reference< io::XInputStreamProvider > xISP;
                    if ( rSourceDoc.getDialog( aSourceLibName, aSourceName, xISP ) )
                    {
                        Shell::CopyDialogResources( xISP, rSourceDoc,
                            aSourceLibName, rDestDoc, aDestLibName, aSourceName );

                        // remove dialog from source library
                        if (RemoveDialog(rSourceDoc, aSourceLibName, aSourceName))
                        {
                            MarkDocumentModified(rSourceDoc);

                            // insert dialog into target library
                            if ( rDestDoc.insertDialog( aDestLibName, aSourceName, xISP ) )
                                MarkDocumentModified(rDestDoc);
                        }
                    }
                }
            }
            catch (const uno::Exception& )
            {
                DBG_UNHANDLED_EXCEPTION("basctl.basicide");
            }
        }
        else    // copy
        {
            try
            {
                if ( eType == OBJ_TYPE_MODULE ) // module
                {
                    // get module
                    OUString aModule;
                    if ( rSourceDoc.getModule( aSourceLibName, aSourceName, aModule ) )
                    {
                        // insert module into target library
                        if ( rDestDoc.insertModule( aDestLibName, aSourceName, aModule ) )
                            MarkDocumentModified( rDestDoc );
                    }
                }
                else if ( eType == OBJ_TYPE_DIALOG )    // dialog
                {
                    // get dialog
                    Reference< io::XInputStreamProvider > xISP;
                    if ( rSourceDoc.getDialog( aSourceLibName, aSourceName, xISP ) )
                    {
                        Shell::CopyDialogResources( xISP, rSourceDoc,
                            aSourceLibName, rDestDoc, aDestLibName, aSourceName );

                        // insert dialog into target library
                        if ( rDestDoc.insertDialog( aDestLibName, aSourceName, xISP ) )
                            MarkDocumentModified( rDestDoc );
                    }
                }
            }
            catch ( const Exception& )
            {
                DBG_UNHANDLED_EXCEPTION("basctl.basicide");
            }
        }

        OUString sText(m_rTreeView.get_text(*xSelected));
        OUString sId(m_rTreeView.get_id(*xSelected));
        std::unique_ptr<weld::TreeIter> xRet(m_rTreeView.make_iterator());
        m_rTreeView.get_widget().insert(xNewParent.get(), nNewChildPos, &sText, &sId, nullptr, nullptr, nullptr, false, xRet.get());
        if (eType == OBJ_TYPE_MODULE)
            m_rTreeView.get_widget().set_image(*xRet, RID_BMP_MODULE);
        else if (eType == OBJ_TYPE_DIALOG)
            m_rTreeView.get_widget().set_image(*xRet, RID_BMP_DIALOG);
        if (!m_rTreeView.get_row_expanded(*xNewParent))
            m_rTreeView.expand_row(*xNewParent);
        m_rTreeView.select(*xRet);

        if (bMove)
            m_rTreeView.remove(*xSelected);

        // create target module/dialog window
        if ( rSourceDoc != rDestDoc || aSourceLibName != aDestLibName )
        {
            if( pDispatcher )
            {
                SbxItem aSbxItem( SID_BASICIDE_ARG_SBX, rDestDoc, aDestLibName, aSourceName, SbTreeListBox::ConvertType(eType) );
                pDispatcher->ExecuteList( SID_BASICIDE_SBXINSERTED,
                                      SfxCallMode::SYNCHRON, { &aSbxItem });
            }
        }
    }

public:
    SbTreeListBoxDropTarget(SbTreeListBox& rTreeView)
        : DropTargetHelper(rTreeView.get_widget().get_drop_target())
        , m_rTreeView(rTreeView)
    {
    }
};

IMPL_LINK( OrganizeDialog, ActivatePageHdl, TabControl *, pTabCtrl, void )
{
    sal_uInt16 nId = pTabCtrl->GetCurPageId();

    if ( !pTabCtrl->GetTabPage( nId ) )
    {
        OString sPageName(pTabCtrl->GetPageName(nId));
        VclPtr<TabPage> pNewTabPage;
        if (sPageName == "modules")
        {
            VclPtrInstance<ObjectPage> pObjectPage(pTabCtrl, "ModulePage", BrowseMode::Modules);
            pNewTabPage.reset(pObjectPage);
            pObjectPage->SetTabDlg(this);
            pObjectPage->SetCurrentEntry(m_aCurEntry);
        }
        else if (sPageName == "dialogs")
        {
            VclPtrInstance<ObjectPage> pObjectPage( pTabCtrl, "DialogPage", BrowseMode::Dialogs );
            pNewTabPage.reset(pObjectPage);
            pObjectPage->SetTabDlg(this);
            pObjectPage->SetCurrentEntry(m_aCurEntry);
        }
        else if (sPageName == "libraries")
        {
            VclPtrInstance<LibPage> pLibPage( pTabCtrl );
            pNewTabPage.reset(pLibPage);
            pLibPage->SetTabDlg( this );
        }
        else
        {
            OSL_FAIL( "PageHdl: Unknown ID" );
        }
        DBG_ASSERT( pNewTabPage, "No page" );
        pTabCtrl->SetTabPage( nId, pNewTabPage );
    }
}


// ObjectPage


ObjectPage::ObjectPage(vcl::Window *pParent, const OString &rName, BrowseMode nMode)
    : TabPage(pParent, rName, "modules/BasicIDE/ui/" +
        OStringToOUString(rName, RTL_TEXTENCODING_UTF8).toAsciiLowerCase() +
        ".ui")
ObjectPage::ObjectPage(weld::Container* pParent, const OString &rName, BrowseMode nMode, OrganizeDialog* pDialog)
    : OrganizePage(pParent, "modules/BasicIDE/ui/" + OStringToOUString(rName, RTL_TEXTENCODING_UTF8).toAsciiLowerCase() + ".ui",
        rName, pDialog)
    , m_xBasicBox(new SbTreeListBox(m_xBuilder->weld_tree_view("library"), pDialog->getDialog()))
    , m_xEditButton(m_xBuilder->weld_button("edit"))
    , m_xNewModButton(m_xBuilder->weld_button("newmodule"))
    , m_xNewDlgButton(m_xBuilder->weld_button("newdialog"))
    , m_xDelButton(m_xBuilder->weld_button("delete"))
{
    get(m_pBasicBox, "library");
    Size aSize(m_pBasicBox->LogicToPixel(Size(130, 117), MapMode(MapUnit::MapAppFont)));
    m_pBasicBox->set_height_request(aSize.Height());
    m_pBasicBox->set_width_request(aSize.Width());
    get(m_pEditButton, "edit");
    get(m_pNewModButton, "newmodule");
    get(m_pNewDlgButton, "newdialog");
    get(m_pDelButton, "delete");
    Size aSize(m_xBasicBox->get_approximate_digit_width() * 40,
               m_xBasicBox->get_height_rows(14));
    m_xBasicBox->set_size_request(aSize.Width(), aSize.Height());

    pTabDlg = nullptr;

    m_pEditButton->SetClickHdl( LINK( this, ObjectPage, ButtonHdl ) );
    m_pDelButton->SetClickHdl( LINK( this, ObjectPage, ButtonHdl ) );
    m_pBasicBox->SetSelectHdl( LINK( this, ObjectPage, BasicBoxHighlightHdl ) );
    m_xEditButton->connect_clicked( LINK( this, ObjectPage, ButtonHdl ) );
    m_xDelButton->connect_clicked( LINK( this, ObjectPage, ButtonHdl ) );
    m_xBasicBox->connect_changed( LINK( this, ObjectPage, BasicBoxHighlightHdl ) );

    if( nMode & BrowseMode::Modules )
    {
        m_pNewModButton->SetClickHdl( LINK( this, ObjectPage, ButtonHdl ) );
        m_pNewDlgButton->Hide();
        m_xNewModButton->connect_clicked( LINK( this, ObjectPage, ButtonHdl ) );
        m_xNewDlgButton->hide();
    }
    else if ( nMode & BrowseMode::Dialogs )
    {
        m_pNewDlgButton->SetClickHdl( LINK( this, ObjectPage, ButtonHdl ) );
        m_pNewModButton->Hide();
        m_xNewDlgButton->connect_clicked( LINK( this, ObjectPage, ButtonHdl ) );
        m_xNewModButton->hide();
    }

    m_pBasicBox->SetDragDropMode( DragDropMode::CTRL_MOVE | DragDropMode::CTRL_COPY );
    m_pBasicBox->EnableInplaceEditing(true);
    m_pBasicBox->SetMode( nMode );
    m_pBasicBox->SetStyle( WB_BORDER | WB_TABSTOP |
                        WB_HASLINES | WB_HASLINESATROOT |
                        WB_HASBUTTONS | WB_HASBUTTONSATROOT |
                        WB_HSCROLL );
    m_pBasicBox->ScanAllEntries();
    m_xDropTarget.reset(new SbTreeListBoxDropTarget(*m_xBasicBox));

    m_pEditButton->GrabFocus();
    m_xBasicBox->connect_editing_started( LINK( this, ObjectPage, EditingEntryHdl ) );
    m_xBasicBox->connect_editing_done( LINK( this, ObjectPage, EditedEntryHdl ) );

    m_xBasicBox->SetMode( nMode );
    m_xBasicBox->ScanAllEntries();

    m_xEditButton->grab_focus();
    CheckButtons();
}

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

void ObjectPage::dispose()
{
    m_pBasicBox.clear();
    m_pEditButton.clear();
    m_pNewModButton.clear();
    m_pNewDlgButton.clear();
    m_pDelButton.clear();
    pTabDlg.clear();
    TabPage::dispose();
}

void ObjectPage::SetCurrentEntry (EntryDescriptor const & rDesc)
{
    m_pBasicBox->SetCurrentEntry( rDesc );
    m_xBasicBox->SetCurrentEntry( rDesc );
}

void ObjectPage::ActivatePage()
{
    m_pBasicBox->UpdateEntries();
}

void ObjectPage::DeactivatePage()
{
    m_xBasicBox->UpdateEntries();
}

void ObjectPage::CheckButtons()
{
    // enable/disable edit button
    SvTreeListEntry* pCurEntry = m_pBasicBox->GetCurEntry();
    EntryDescriptor aDesc = m_pBasicBox->GetEntryDescriptor(pCurEntry);
    std::unique_ptr<weld::TreeIter> xCurEntry(m_xBasicBox->make_iterator());
    if (!m_xBasicBox->get_cursor(xCurEntry.get()))
        xCurEntry.reset();
    EntryDescriptor aDesc = m_xBasicBox->GetEntryDescriptor(xCurEntry.get());
    const ScriptDocument& aDocument( aDesc.GetDocument() );
    const OUString& aLibName( aDesc.GetLibName() );
    const OUString& aLibSubName( aDesc.GetLibSubName() );
    bool bVBAEnabled = aDocument.isInVBAMode();
    BrowseMode nMode = m_pBasicBox->GetMode();
    BrowseMode nMode = m_xBasicBox->GetMode();

    sal_uInt16 nDepth = pCurEntry ? m_pBasicBox->GetModel()->GetDepth( pCurEntry ) : 0;
    sal_uInt16 nDepth = xCurEntry ? m_xBasicBox->get_iter_depth(*xCurEntry) : 0;
    if ( nDepth >= 2 )
    {
        if( bVBAEnabled && ( nMode & BrowseMode::Modules ) && ( nDepth == 2 ) )
            m_pEditButton->Disable();
            m_xEditButton->set_sensitive(false);
        else
        m_pEditButton->Enable();
            m_xEditButton->set_sensitive(true);
    }
    else
        m_pEditButton->Disable();
        m_xEditButton->set_sensitive(false);

    // enable/disable new module/dialog buttons
    LibraryLocation eLocation( aDesc.GetLocation() );
@@ -661,49 +620,48 @@ void ObjectPage::CheckButtons()
    }
    if ( bReadOnly || eLocation == LIBRARY_LOCATION_SHARE )
    {
        m_pNewModButton->Disable();
        m_pNewDlgButton->Disable();
        m_xNewModButton->set_sensitive(false);
        m_xNewDlgButton->set_sensitive(false);
    }
    else
    {
        m_pNewModButton->Enable();
        m_pNewDlgButton->Enable();
        m_xNewModButton->set_sensitive(true);
        m_xNewDlgButton->set_sensitive(true);
    }

    // enable/disable delete button
    if ( nDepth >= 2 && !bReadOnly && eLocation != LIBRARY_LOCATION_SHARE )
    {
        if( bVBAEnabled && ( nMode & BrowseMode::Modules ) && ( ( nDepth == 2 ) || aLibSubName == IDEResId(RID_STR_DOCUMENT_OBJECTS) ) )
            m_pDelButton->Disable();
            m_xDelButton->set_sensitive(false);
        else
        m_pDelButton->Enable();
            m_xDelButton->set_sensitive(true);
    }
    else
        m_pDelButton->Disable();
        m_xDelButton->set_sensitive(false);
}

IMPL_LINK( ObjectPage, BasicBoxHighlightHdl, SvTreeListBox*, pBox, void )
IMPL_LINK_NOARG(ObjectPage, BasicBoxHighlightHdl, weld::TreeView&, void)
{
    if ( !pBox->IsSelected( pBox->GetHdlEntry() ) )
        return;

    CheckButtons();
}

IMPL_LINK( ObjectPage, ButtonHdl, Button *, pButton, void )
IMPL_LINK(ObjectPage, ButtonHdl, weld::Button&, rButton, void)
{
    if (pButton == m_pEditButton)
    if (&rButton == m_xEditButton.get())
    {
        SfxAllItemSet aArgs( SfxGetpApp()->GetPool() );
        SfxRequest aRequest( SID_BASICIDE_APPEAR, SfxCallMode::SYNCHRON, aArgs );
        SfxGetpApp()->ExecuteSlot( aRequest );

        SfxDispatcher* pDispatcher = GetDispatcher();
        SvTreeListEntry* pCurEntry = m_pBasicBox->GetCurEntry();
        DBG_ASSERT( pCurEntry, "Entry?!" );
        if ( m_pBasicBox->GetModel()->GetDepth( pCurEntry ) >= 2 )

        std::unique_ptr<weld::TreeIter> xCurEntry(m_xBasicBox->make_iterator());
        if (!m_xBasicBox->get_cursor(xCurEntry.get()))
            return;
        if (m_xBasicBox->get_iter_depth(*xCurEntry) >= 2)
        {
            EntryDescriptor aDesc = m_pBasicBox->GetEntryDescriptor(pCurEntry);
            EntryDescriptor aDesc = m_xBasicBox->GetEntryDescriptor(xCurEntry.get());
            if ( pDispatcher )
            {
                OUString aModName( aDesc.GetName() );
@@ -713,24 +671,24 @@ IMPL_LINK( ObjectPage, ButtonHdl, Button *, pButton, void )
                    aModName = aModName.getToken( 0, ' ' );
                }
                SbxItem aSbxItem( SID_BASICIDE_ARG_SBX, aDesc.GetDocument(), aDesc.GetLibName(),
                                  aModName, TreeListBox::ConvertType( aDesc.GetType() ) );
                                  aModName, SbTreeListBox::ConvertType( aDesc.GetType() ) );
                pDispatcher->ExecuteList(SID_BASICIDE_SHOWSBX,
                        SfxCallMode::SYNCHRON, { &aSbxItem });
            }
        }
        else    // only Lib selected
        {
            DBG_ASSERT( m_pBasicBox->GetModel()->GetDepth( pCurEntry ) == 1, "No LibEntry?!" );
            DBG_ASSERT( m_xBasicBox->get_iter_depth(*xCurEntry) == 1, "No LibEntry?!" );
            ScriptDocument aDocument( ScriptDocument::getApplicationScriptDocument() );
            SvTreeListEntry* pParentEntry = m_pBasicBox->GetParent( pCurEntry );
            if ( pParentEntry )
            std::unique_ptr<weld::TreeIter> xParentEntry(m_xBasicBox->make_iterator(xCurEntry.get()));
            if (m_xBasicBox->iter_parent(*xParentEntry))
            {
                DocumentEntry* pDocumentEntry = static_cast<DocumentEntry*>(pParentEntry->GetUserData());
                DocumentEntry* pDocumentEntry = reinterpret_cast<DocumentEntry*>(m_xBasicBox->get_id(*xParentEntry).toInt64());
                if (pDocumentEntry)
                    aDocument = pDocumentEntry->GetDocument();
            }
            SfxUnoAnyItem aDocItem( SID_BASICIDE_ARG_DOCUMENT_MODEL, Any( aDocument.getDocumentOrNull() ) );
            OUString aLibName( m_pBasicBox->GetEntryText( pCurEntry ) );
            OUString aLibName(m_xBasicBox->get_text(*xCurEntry));
            SfxStringItem aLibNameItem( SID_BASICIDE_ARG_LIBNAME, aLibName );
            if ( pDispatcher )
            {
@@ -740,11 +698,11 @@ IMPL_LINK( ObjectPage, ButtonHdl, Button *, pButton, void )
        }
        EndTabDialog();
    }
    else if (pButton == m_pNewModButton)
    else if (&rButton == m_xNewModButton.get())
        NewModule();
    else if (pButton == m_pNewDlgButton)
    else if (&rButton == m_xNewDlgButton.get())
        NewDialog();
    else if (pButton == m_pDelButton)
    else if (&rButton == m_xDelButton.get())
        DeleteCurrent();
}

@@ -752,8 +710,10 @@ bool ObjectPage::GetSelection( ScriptDocument& rDocument, OUString& rLibName )
{
    bool bRet = false;

    SvTreeListEntry* pCurEntry = m_pBasicBox->GetCurEntry();
    EntryDescriptor aDesc = m_pBasicBox->GetEntryDescriptor(pCurEntry);
    std::unique_ptr<weld::TreeIter> xCurEntry(m_xBasicBox->make_iterator());
    if (!m_xBasicBox->get_cursor(xCurEntry.get()))
        xCurEntry.reset();
    EntryDescriptor aDesc = m_xBasicBox->GetEntryDescriptor(xCurEntry.get());
    rDocument = aDesc.GetDocument();
    rLibName = aDesc.GetLibName();
    if ( rLibName.isEmpty() )
@@ -804,8 +764,8 @@ void ObjectPage::NewModule()

    if ( GetSelection( aDocument, aLibName ) )
    {
        createModImpl(GetFrameWeld(), aDocument,
                      *m_pBasicBox, aLibName, true);
        createModImpl(m_pDialog->getDialog(), aDocument,
                      *m_xBasicBox, aLibName, OUString(), true);
    }
}

@@ -818,7 +778,7 @@ void ObjectPage::NewDialog()
    {
        aDocument.getOrCreateLibrary( E_DIALOGS, aLibName );

        NewObjectDialog aNewDlg(GetFrameWeld(), ObjectMode::Dialog, true);
        NewObjectDialog aNewDlg(m_pDialog->getDialog(), ObjectMode::Dialog, true);
        aNewDlg.SetObjectName(aDocument.createObjectName(E_DIALOGS, aLibName));

        if (aNewDlg.run() != RET_CANCEL)
@@ -829,7 +789,7 @@ void ObjectPage::NewDialog()

            if ( aDocument.hasDialog( aLibName, aDlgName ) )
            {
                std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(GetFrameWeld(),
                std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(m_pDialog->getDialog(),
                                                            VclMessageType::Warning, VclButtonsType::Ok, IDEResId(RID_STR_SBXNAMEALLREADYUSED2)));
                xError->run();
            }
@@ -846,29 +806,28 @@ void ObjectPage::NewDialog()
                        SfxCallMode::SYNCHRON, { &aSbxItem });
                }
                LibraryLocation eLocation = aDocument.getLibraryLocation( aLibName );
                SvTreeListEntry* pRootEntry = m_pBasicBox->FindRootEntry( aDocument, eLocation );
                if ( pRootEntry )
                std::unique_ptr<weld::TreeIter> xIter(m_xBasicBox->make_iterator());
                bool bRootEntry = m_xBasicBox->FindRootEntry(aDocument, eLocation, *xIter);
                if (bRootEntry)
                {
                    if ( !m_pBasicBox->IsExpanded( pRootEntry ) )
                        m_pBasicBox->Expand( pRootEntry );
                    SvTreeListEntry* pLibEntry = m_pBasicBox->FindEntry( pRootEntry, aLibName, OBJ_TYPE_LIBRARY );
                    DBG_ASSERT( pLibEntry, "LibEntry not found!" );
                    if ( pLibEntry )
                    if (!m_xBasicBox->get_row_expanded(*xIter))
                        m_xBasicBox->expand_row(*xIter);
                    bool bLibEntry = m_xBasicBox->FindEntry(aLibName, OBJ_TYPE_LIBRARY, *xIter);
                    DBG_ASSERT( bLibEntry, "LibEntry not found!" );
                    if (bLibEntry)
                    {
                        if ( !m_pBasicBox->IsExpanded( pLibEntry ) )
                            m_pBasicBox->Expand( pLibEntry );
                        SvTreeListEntry* pEntry = m_pBasicBox->FindEntry( pLibEntry, aDlgName, OBJ_TYPE_DIALOG );
                        if ( !pEntry )
                        if (!m_xBasicBox->get_row_expanded(*xIter))
                            m_xBasicBox->expand_row(*xIter);
                        std::unique_ptr<weld::TreeIter> xSubRootEntry(m_xBasicBox->make_iterator(xIter.get()));
                        bool bDlgEntry = m_xBasicBox->FindEntry(aDlgName, OBJ_TYPE_DIALOG, *xIter);
                        if (!bDlgEntry)
                        {
                            pEntry = m_pBasicBox->AddEntry(
                                aDlgName,
                                Image(StockImage::Yes, RID_BMP_DIALOG),
                                pLibEntry, false,
                                std::make_unique<Entry>(OBJ_TYPE_DIALOG));
                            DBG_ASSERT( pEntry, "Insert entry failed!" );
                            m_xBasicBox->AddEntry(aDlgName, RID_BMP_DIALOG, xSubRootEntry.get(), false,
                                               std::make_unique<Entry>(OBJ_TYPE_DIALOG), xIter.get());
                            assert(xIter.get() && "Insert entry failed!");
                        }
                        m_pBasicBox->SetCurEntry( pEntry );
                        m_pBasicBox->Select( m_pBasicBox->GetCurEntry() );        // OV-Bug?!
                        m_xBasicBox->set_cursor(*xIter);
                        m_xBasicBox->select(*xIter);
                    }
                }
            }
@@ -878,9 +837,11 @@ void ObjectPage::NewDialog()

void ObjectPage::DeleteCurrent()
{
    SvTreeListEntry* pCurEntry = m_pBasicBox->GetCurEntry();
    DBG_ASSERT( pCurEntry, "No current entry!" );
    EntryDescriptor aDesc( m_pBasicBox->GetEntryDescriptor( pCurEntry ) );
    std::unique_ptr<weld::TreeIter> xCurEntry(m_xBasicBox->make_iterator());
    if (!m_xBasicBox->get_cursor(xCurEntry.get()))
        xCurEntry.reset();
    DBG_ASSERT( xCurEntry.get(), "No current entry!" );
    EntryDescriptor aDesc( m_xBasicBox->GetEntryDescriptor( xCurEntry.get() ) );
    const ScriptDocument& aDocument( aDesc.GetDocument() );
    DBG_ASSERT( aDocument.isAlive(), "ObjectPage::DeleteCurrent: no document!" );
    if ( !aDocument.isAlive() )
@@ -889,15 +850,15 @@ void ObjectPage::DeleteCurrent()
    const OUString& aName( aDesc.GetName() );
    EntryType eType = aDesc.GetType();

    if ( ( eType == OBJ_TYPE_MODULE && QueryDelModule(aName, GetFrameWeld()) ) ||
         ( eType == OBJ_TYPE_DIALOG && QueryDelDialog(aName, GetFrameWeld()) ) )
    if ( ( eType == OBJ_TYPE_MODULE && QueryDelModule(aName, m_pDialog->getDialog()) ) ||
         ( eType == OBJ_TYPE_DIALOG && QueryDelDialog(aName, m_pDialog->getDialog()) ) )
    {
        m_pBasicBox->GetModel()->Remove( pCurEntry );
        if ( m_pBasicBox->GetCurEntry() )  // OV-Bug ?
            m_pBasicBox->Select( m_pBasicBox->GetCurEntry() );
        m_xBasicBox->remove(*xCurEntry);
        if (m_xBasicBox->get_cursor(xCurEntry.get()))
            m_xBasicBox->select(*xCurEntry);
        if (SfxDispatcher* pDispatcher = GetDispatcher())
        {
            SbxItem aSbxItem( SID_BASICIDE_ARG_SBX, aDocument, aLibName, aName, TreeListBox::ConvertType( eType ) );
            SbxItem aSbxItem( SID_BASICIDE_ARG_SBX, aDocument, aLibName, aName, SbTreeListBox::ConvertType( eType ) );
            pDispatcher->ExecuteList( SID_BASICIDE_SBXDELETED,
                                  SfxCallMode::SYNCHRON, { &aSbxItem });
        }
@@ -922,9 +883,7 @@ void ObjectPage::DeleteCurrent()

void ObjectPage::EndTabDialog()
{
    DBG_ASSERT( pTabDlg, "TabDlg not set!" );
    if ( pTabDlg )
        pTabDlg->EndDialog( 1 );
    m_pDialog->response(RET_OK);
}

LibDialog::LibDialog(weld::Window* pParent)
@@ -950,100 +909,6 @@ void LibDialog::SetStorageName( const OUString& rName )

// Helper function
SbModule* createModImpl(weld::Window* pWin, const ScriptDocument& rDocument,
    TreeListBox& rBasicBox, const OUString& rLibName, 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 = 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 );
            SvTreeListEntry* pRootEntry = rBasicBox.FindRootEntry( rDocument, eLocation );
            if ( pRootEntry )
            {
                if ( !rBasicBox.IsExpanded( pRootEntry ) )
                    rBasicBox.Expand( pRootEntry );
                SvTreeListEntry* pLibEntry = rBasicBox.FindEntry( pRootEntry, aLibName, OBJ_TYPE_LIBRARY );
                DBG_ASSERT( pLibEntry, "LibEntry not found!" );
                if ( pLibEntry )
                {
                    if ( !rBasicBox.IsExpanded( pLibEntry ) )
                        rBasicBox.Expand( pLibEntry );
                    SvTreeListEntry* pSubRootEntry = pLibEntry;
                    if( pBasic && rDocument.isInVBAMode() )
                    {
                        // add the new module in the "Modules" entry
                        SvTreeListEntry* pLibSubEntry = rBasicBox.FindEntry( pLibEntry, IDEResId(RID_STR_NORMAL_MODULES) , OBJ_TYPE_NORMAL_MODULES );
                        if( pLibSubEntry )
                        {
                            if( !rBasicBox.IsExpanded( pLibSubEntry ) )
                                rBasicBox.Expand( pLibSubEntry );
                            pSubRootEntry = pLibSubEntry;
                        }
                    }

                    SvTreeListEntry* pEntry = rBasicBox.FindEntry( pSubRootEntry, aModName, OBJ_TYPE_MODULE );
                    if ( !pEntry )
                    {
                        pEntry = rBasicBox.AddEntry(
                            aModName,
                            Image(StockImage::Yes, RID_BMP_MODULE),
                            pSubRootEntry, false,
                            std::make_unique<Entry>(OBJ_TYPE_MODULE));
                        DBG_ASSERT( pEntry, "Insert entry failed!" );
                    }
                    rBasicBox.SetCurEntry( pEntry );
                    rBasicBox.Select( rBasicBox.GetCurEntry() );        // OV-Bug?!
                }
            }
        }
        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;
}

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!" );
diff --git a/basctl/source/basicide/moduldlg.hxx b/basctl/source/basicide/moduldlg.hxx
index 7ea30df2..52fa4bf 100644
--- a/basctl/source/basicide/moduldlg.hxx
+++ b/basctl/source/basicide/moduldlg.hxx
@@ -25,7 +25,6 @@
#include <vcl/layout.hxx>
#include <vcl/lstbox.hxx>
#include <vcl/tabctrl.hxx>
#include <vcl/tabdlg.hxx>
#include <vcl/tabpage.hxx>
#include <vcl/weld.hxx>
#include <com/sun/star/task/XInteractionHandler.hpp>
@@ -88,50 +87,6 @@ public:
    bool isExportAsPackage () const { return m_bExportAsPackage; }
};

class ExtTreeListBox final : public TreeListBox
{
    virtual bool    EditingEntry( SvTreeListEntry* pEntry, Selection& rSel  ) override;
    virtual bool    EditedEntry( SvTreeListEntry* pEntry, const OUString& rNewText ) override;

    virtual DragDropMode    NotifyStartDrag( TransferDataContainer& rData, SvTreeListEntry* pEntry ) override;
    virtual bool            NotifyAcceptDrop( SvTreeListEntry* pEntry ) override;

    virtual TriState    NotifyMoving( SvTreeListEntry* pTarget, SvTreeListEntry* pEntry,
                        SvTreeListEntry*& rpNewParent, sal_uLong& rNewChildPos ) override;
    virtual TriState    NotifyCopying( SvTreeListEntry* pTarget, SvTreeListEntry* pEntry,
                        SvTreeListEntry*& rpNewParent, sal_uLong& rNewChildPos ) override;
    TriState            NotifyCopyingMoving( SvTreeListEntry* pTarget, SvTreeListEntry const * pEntry,
                        SvTreeListEntry*& rpNewParent, sal_uLong& rNewChildPos, bool bMove );

public:
    ExtTreeListBox(vcl::Window* pParent, WinBits nStyle);
};

class CheckBox : public SvTabListBox
{
private:
    ObjectMode          eMode;
    std::unique_ptr<SvLBoxButtonData> pCheckButton;
    ScriptDocument      m_aDocument;
    void                Init();

public:
    CheckBox(vcl::Window* pParent, WinBits nStyle);
    virtual ~CheckBox() override;
    virtual void    dispose() override;

    SvTreeListEntry*    DoInsertEntry( const OUString& rStr, sal_uLong nPos = LISTBOX_APPEND );
    SvTreeListEntry*    FindEntry( const OUString& rName );

    virtual void    InitEntry(SvTreeListEntry*, const OUString&, const Image&, const Image&, SvLBoxButtonKind eButtonKind) override;
    virtual bool    EditingEntry( SvTreeListEntry* pEntry, Selection& rSel ) override;
    virtual bool    EditedEntry( SvTreeListEntry* pEntry, const OUString& rNewText ) override;

    void            SetDocument( const ScriptDocument& rDocument ) { m_aDocument = rDocument; }

    void            SetMode(ObjectMode);
};

class LibDialog : public weld::GenericDialogController
{
private:
@@ -153,30 +108,39 @@ public:
    void            EnableReference (bool b)    { m_xReferenceBox->set_sensitive(b); }
};

class OrganizeDialog : public TabDialog
class OrganizeDialog;

class OrganizePage
{
private:
    VclPtr<TabControl> m_pTabCtrl;
    EntryDescriptor    m_aCurEntry;
protected:
    OrganizeDialog* m_pDialog;
    std::unique_ptr<weld::Builder> m_xBuilder;
    std::unique_ptr<weld::Container> m_xContainer;

    OrganizePage(weld::Container* pParent, const OUString& rUIFile, const OString &rName, OrganizeDialog* pDialog);
    virtual ~OrganizePage();

public:
    OrganizeDialog( vcl::Window* pParent, sal_Int16 tabId, EntryDescriptor const & rDesc );
    virtual ~OrganizeDialog() override;
    virtual void    dispose() override;

    DECL_LINK( ActivatePageHdl, TabControl*, void );
    virtual void        ActivatePage() = 0;
};

class ObjectPage final : public TabPage
{
    VclPtr<ExtTreeListBox>     m_pBasicBox;
    VclPtr<PushButton>         m_pEditButton;
    VclPtr<PushButton>         m_pNewModButton;
    VclPtr<PushButton>         m_pNewDlgButton;
    VclPtr<PushButton>         m_pDelButton;
class SbTreeListBoxDropTarget;

    DECL_LINK( BasicBoxHighlightHdl, SvTreeListBox*, void );
    DECL_LINK( ButtonHdl, Button *, void );
class ObjectPage final : public OrganizePage
{
    std::unique_ptr<SbTreeListBox> m_xBasicBox;
    std::unique_ptr<weld::Button> m_xEditButton;
    std::unique_ptr<weld::Button> m_xNewModButton;
    std::unique_ptr<weld::Button> m_xNewDlgButton;
    std::unique_ptr<weld::Button> m_xDelButton;
    std::unique_ptr<SbTreeListBoxDropTarget> m_xDropTarget;

    DECL_LINK( BasicBoxHighlightHdl, weld::TreeView&, void );
    DECL_LINK( ButtonHdl, weld::Button&, void );
    DECL_LINK( EditingEntryHdl, const weld::TreeIter&, bool );
    typedef std::pair<const weld::TreeIter&, OUString> IterString;
    DECL_LINK( EditedEntryHdl, const IterString&, bool );

    void                CheckButtons();
    bool                GetSelection( ScriptDocument& rDocument, OUString& rLibName );
    void                DeleteCurrent();
@@ -184,39 +148,36 @@ class ObjectPage final : public TabPage
    void                NewDialog();
    void                EndTabDialog();

    VclPtr<TabDialog>          pTabDlg;

    virtual void        ActivatePage() override;
    virtual void        DeactivatePage() override;

public:
    ObjectPage(vcl::Window* pParent, const OString& rName, BrowseMode nMode);
    ObjectPage(weld::Container* pParent, const OString& rName, BrowseMode nMode, OrganizeDialog* pDialog);
    virtual ~ObjectPage() override;
    virtual void dispose() override;

    void                SetCurrentEntry( EntryDescriptor const & rDesc );
    void                SetTabDlg( TabDialog* p ) { pTabDlg = p;}
    virtual void        ActivatePage() override;
};


class LibPage final : public TabPage
class LibPage final : public OrganizePage
{
    VclPtr<ListBox>            m_pBasicsBox;
    VclPtr<CheckBox>           m_pLibBox;
    VclPtr<PushButton>         m_pEditButton;
    VclPtr<PushButton>         m_pPasswordButton;
    VclPtr<PushButton>         m_pNewLibButton;
    VclPtr<PushButton>         m_pInsertLibButton;
    VclPtr<PushButton>         m_pExportButton;
    VclPtr<PushButton>         m_pDelButton;
    std::unique_ptr<weld::ComboBox> m_xBasicsBox;
    std::unique_ptr<weld::TreeView> m_xLibBox;
    std::unique_ptr<weld::Button> m_xEditButton;
    std::unique_ptr<weld::Button> m_xPasswordButton;
    std::unique_ptr<weld::Button> m_xNewLibButton;
    std::unique_ptr<weld::Button> m_xInsertLibButton;
    std::unique_ptr<weld::Button> m_xExportButton;
    std::unique_ptr<weld::Button> m_xDelButton;

    ScriptDocument      m_aCurDocument;
    LibraryLocation     m_eCurLocation;

    DECL_LINK( TreeListHighlightHdl, SvTreeListBox *, void );
    DECL_LINK( BasicSelectHdl, ListBox&, void );
    DECL_LINK( ButtonHdl, Button *, void );
    DECL_LINK( TreeListHighlightHdl, weld::TreeView&, void );
    DECL_LINK( BasicSelectHdl, weld::ComboBox&, void );
    DECL_LINK( ButtonHdl, weld::Button&, void );
    DECL_LINK( CheckPasswordHdl, SvxPasswordDialog *, bool );
    DECL_LINK( EditingEntryHdl, const weld::TreeIter&, bool );
    typedef std::pair<const weld::TreeIter&, OUString> IterString;
    DECL_LINK( EditedEntryHdl, const IterString&, bool );

    void                CheckButtons();
    void                DeleteCurrent();
    void                NewLib();
@@ -230,29 +191,35 @@ class LibPage final : public TabPage
    void                FillListBox();
    void                InsertListBoxEntry( const ScriptDocument& rDocument, LibraryLocation eLocation );
    void                SetCurLib();
    SvTreeListEntry*    ImpInsertLibEntry( const OUString& rLibName, sal_uLong nPos );
    virtual void        ActivatePage() override;
    virtual void        DeactivatePage() override;

    VclPtr<TabDialog>          pTabDlg;
    void                ImpInsertLibEntry( const OUString& rLibName, sal_uLong nPos );

public:
    explicit LibPage(vcl::Window* pParent);
    explicit LibPage(weld::Container* pParent, OrganizeDialog* pDialog);
    virtual             ~LibPage() override;
    virtual void        dispose() override;
    virtual void        ActivatePage() override;
};

    void                SetTabDlg( TabDialog* p ) { pTabDlg = p;}
class OrganizeDialog : public weld::GenericDialogController
{
private:
    std::unique_ptr<weld::Notebook> m_xTabCtrl;
    std::unique_ptr<ObjectPage> m_xModulePage;
    std::unique_ptr<ObjectPage> m_xDialogPage;
    std::unique_ptr<LibPage> m_xLibPage;
    EntryDescriptor    m_aCurEntry;

    DECL_LINK(ActivatePageHdl, const OString&, void);

public:
    OrganizeDialog(weld::Window* pParent, sal_Int16 tabId, EntryDescriptor const & rDesc);
    virtual ~OrganizeDialog() override;
};

// 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, 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);
                   weld::TreeView* pLibBox, SbTreeListBox* pBasicBox);

} // namespace basctl

diff --git a/basctl/source/inc/basobj.hxx b/basctl/source/inc/basobj.hxx
index acdb1f0..d31d2e9fd 100644
--- a/basctl/source/inc/basobj.hxx
+++ b/basctl/source/inc/basobj.hxx
@@ -34,7 +34,7 @@ namespace weld { class Widget; class Window; }

namespace basctl
{
    void            Organize( sal_Int16 tabId );
    void            Organize(weld::Window* pParent, sal_Int16 tabId);


    // help methods for the general use:
diff --git a/basctl/source/inc/bastype2.hxx b/basctl/source/inc/bastype2.hxx
index 9777ba7..18c8960 100644
--- a/basctl/source/inc/bastype2.hxx
+++ b/basctl/source/inc/bastype2.hxx
@@ -309,8 +309,13 @@ public:
    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); }
    void unselect(const weld::TreeIter& rIter) { m_xControl->unselect(rIter); }
    void remove(const weld::TreeIter& rIter) { m_xControl->remove(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); }
    OUString get_text(const weld::TreeIter& rIter) const { return m_xControl->get_text(rIter); }
    void set_text(const weld::TreeIter& rIter, const OUString& rText) { m_xControl->set_text(rIter, rText); }
    OUString get_id(const weld::TreeIter& rIter) const { return m_xControl->get_id(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); }
@@ -321,6 +326,15 @@ public:
    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); }
    int get_iter_index_in_parent(const weld::TreeIter& rIter) const { return m_xControl->get_iter_index_in_parent(rIter); }
    void connect_editing_started(const Link<const weld::TreeIter&, bool>& rLink)
    {
        m_xControl->connect_editing_started(rLink);
    }
    void connect_editing_done(const Link<const std::pair<const weld::TreeIter&, OUString>&, bool>& rLink)
    {
        m_xControl->connect_editing_done(rLink);
    }

    void            RemoveEntry(const weld::TreeIter& rIter);
    void            RemoveEntry(const ScriptDocument&);
diff --git a/basctl/uiconfig/basicide/ui/dialogpage.ui b/basctl/uiconfig/basicide/ui/dialogpage.ui
index a52053d..77922d5 100644
--- a/basctl/uiconfig/basicide/ui/dialogpage.ui
+++ b/basctl/uiconfig/basicide/ui/dialogpage.ui
@@ -1,8 +1,17 @@
<?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 expander -->
      <column type="GdkPixbuf"/>
      <!-- column-name text -->
      <column type="gchararray"/>
      <!-- column-name id -->
      <column type="gchararray"/>
    </columns>
  </object>
  <object class="GtkGrid" id="DialogPage">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
@@ -26,10 +35,10 @@
              <object class="GtkLabel" id="label1">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="xalign">0</property>
                <property name="label" translatable="yes" context="dialogpage|label1">Dialog:</property>
                <property name="use_underline">True</property>
                <property name="mnemonic_widget">library:border</property>
                <property name="mnemonic_widget">library</property>
                <property name="xalign">0</property>
              </object>
              <packing>
                <property name="left_attach">0</property>
@@ -37,13 +46,49 @@
              </packing>
            </child>
            <child>
              <object class="basctllo-ExtTreeListBox" id="library:border">
              <object class="GtkScrolledWindow">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="hexpand">True</property>
                <property name="vexpand">True</property>
                <child internal-child="selection">
                  <object class="GtkTreeSelection" id="CheckBox List-selection1"/>
                <property name="shadow_type">in</property>
                <child>
                  <object class="GtkTreeView" id="library">
                    <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="reorderable">True</property>
                    <property name="show_expanders">True</property>
                    <property name="search_column">1</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">0</attribute>
                          </attributes>
                        </child>
                        <child>
                          <object class="GtkCellRendererText" id="cellrenderertext2">
                            <property name="editable">True</property>
                          </object>
                          <attributes>
                            <attribute name="text">1</attribute>
                          </attributes>
                        </child>
                      </object>
                    </child>
                  </object>
                </child>
              </object>
              <packing>
diff --git a/basctl/uiconfig/basicide/ui/libpage.ui b/basctl/uiconfig/basicide/ui/libpage.ui
index c492914..1f1646b 100644
--- a/basctl/uiconfig/basicide/ui/libpage.ui
+++ b/basctl/uiconfig/basicide/ui/libpage.ui
@@ -2,7 +2,18 @@
<!-- Generated with glade 3.18.3 -->
<interface domain="basctl">
  <requires lib="gtk+" version="3.18"/>
  <requires lib="LibreOffice" version="1.0"/>
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name expander -->
      <column type="GdkPixbuf"/>
      <!-- column-name text -->
      <column type="gchararray"/>
      <!-- column-name text1 -->
      <column type="gchararray"/>
      <!-- column-name id -->
      <column type="gchararray"/>
    </columns>
  </object>
  <object class="GtkGrid" id="LibPage">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
@@ -38,7 +49,7 @@
              </packing>
            </child>
            <child>
              <object class="GtkComboBox" id="location">
              <object class="GtkComboBoxText" id="location">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="hexpand">True</property>
@@ -69,7 +80,7 @@
                <property name="xalign">0</property>
                <property name="label" translatable="yes" context="libpage|lingudictsft">_Library:</property>
                <property name="use_underline">True</property>
                <property name="mnemonic_widget">library:border</property>
                <property name="mnemonic_widget">library</property>
              </object>
              <packing>
                <property name="left_attach">0</property>
@@ -77,13 +88,59 @@
              </packing>
            </child>
            <child>
              <object class="basctllo-CheckBox" id="library:border">
              <object class="GtkScrolledWindow">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="hexpand">True</property>
                <property name="vexpand">True</property>
                <child internal-child="selection">
                  <object class="GtkTreeSelection" id="CheckBox List-selection1"/>
                <property name="shadow_type">in</property>
                <child>
                  <object class="GtkTreeView" id="library">
                    <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">1</property>
                    <property name="show_expanders">True</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">0</attribute>
                          </attributes>
                        </child>
                        <child>
                          <object class="GtkCellRendererText" id="cellrenderertext2">
                            <property name="editable">True</property>
                          </object>
                          <attributes>
                            <attribute name="text">1</attribute>
                          </attributes>
                        </child>
                      </object>
                    </child>
                    <child>
                      <object class="GtkTreeViewColumn" id="treeviewcolumn3">
                        <property name="spacing">6</property>
                        <child>
                          <object class="GtkCellRendererText" id="cellrenderertext3"/>
                          <attributes>
                            <attribute name="text">2</attribute>
                          </attributes>
                        </child>
                      </object>
                    </child>
                  </object>
                </child>
              </object>
              <packing>
diff --git a/basctl/uiconfig/basicide/ui/modulepage.ui b/basctl/uiconfig/basicide/ui/modulepage.ui
index 1130dc3..86ea7d9 100644
--- a/basctl/uiconfig/basicide/ui/modulepage.ui
+++ b/basctl/uiconfig/basicide/ui/modulepage.ui
@@ -1,8 +1,17 @@
<?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 expander -->
      <column type="GdkPixbuf"/>
      <!-- column-name text -->
      <column type="gchararray"/>
      <!-- column-name id -->
      <column type="gchararray"/>
    </columns>
  </object>
  <object class="GtkGrid" id="ModulePage">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
@@ -26,10 +35,10 @@
              <object class="GtkLabel" id="label1">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="xalign">0</property>
                <property name="label" translatable="yes" context="modulepage|label1">M_odule:</property>
                <property name="use_underline">True</property>
                <property name="mnemonic_widget">library:border</property>
                <property name="mnemonic_widget">library</property>
                <property name="xalign">0</property>
              </object>
              <packing>
                <property name="left_attach">0</property>
@@ -37,13 +46,49 @@
              </packing>
            </child>
            <child>
              <object class="basctllo-ExtTreeListBox" id="library:border">
              <object class="GtkScrolledWindow">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="hexpand">True</property>
                <property name="vexpand">True</property>
                <child internal-child="selection">
                  <object class="GtkTreeSelection" id="CheckBox List-selection1"/>
                <property name="shadow_type">in</property>
                <child>
                  <object class="GtkTreeView" id="library">
                    <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="reorderable">True</property>
                    <property name="show_expanders">True</property>
                    <property name="search_column">1</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">0</attribute>
                          </attributes>
                        </child>
                        <child>
                          <object class="GtkCellRendererText" id="cellrenderertext2">
                            <property name="editable">True</property>
                          </object>
                          <attributes>
                            <attribute name="text">1</attribute>
                          </attributes>
                        </child>
                      </object>
                    </child>
                  </object>
                </child>
              </object>
              <packing>
diff --git a/basctl/uiconfig/basicide/ui/organizedialog.ui b/basctl/uiconfig/basicide/ui/organizedialog.ui
index 30cb24a..18a15fe 100644
--- a/basctl/uiconfig/basicide/ui/organizedialog.ui
+++ b/basctl/uiconfig/basicide/ui/organizedialog.ui
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<!-- Generated with glade 3.22.1 -->
<interface domain="basctl">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkDialog" id="OrganizeDialog">
@@ -7,7 +7,13 @@
    <property name="border_width">6</property>
    <property name="title" translatable="yes" context="organizedialog|OrganizeDialog">%PRODUCTNAME Basic Macro Organizer</property>
    <property name="resizable">False</property>
    <property name="modal">True</property>
    <property name="default_width">0</property>
    <property name="default_height">0</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>
@@ -71,6 +77,30 @@
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
              </object>
            </child>
            <child type="tab">
@@ -90,6 +120,30 @@
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
              </object>
              <packing>
                <property name="position">1</property>
@@ -113,6 +167,30 @@
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
                <child>
                  <placeholder/>
                </child>
              </object>
              <packing>
                <property name="position">2</property>
diff --git a/compilerplugins/clang/unusedmethods.results b/compilerplugins/clang/unusedmethods.results
index 5fb2ed3..182e24f 100644
--- a/compilerplugins/clang/unusedmethods.results
+++ b/compilerplugins/clang/unusedmethods.results
@@ -742,7 +742,7 @@ include/vcl/svapp.hxx:801
    void Application::AppEvent(const class ApplicationEvent &)
include/vcl/syswin.hxx:172
    void SystemWindow::SetIdleDebugName(const char *)
include/vcl/tabdlg.hxx:48
include/vcl/toolkit/tabdlg.hxx:49
    class vcl::Window * TabDialog::GetViewWindow() const
include/vcl/textrectinfo.hxx:45
    _Bool TextRectInfo::operator!=(const class TextRectInfo &) const
diff --git a/cui/source/dialogs/screenshotannotationdlg.cxx b/cui/source/dialogs/screenshotannotationdlg.cxx
index 1536c19..2ed79d7 100644
--- a/cui/source/dialogs/screenshotannotationdlg.cxx
+++ b/cui/source/dialogs/screenshotannotationdlg.cxx
@@ -638,7 +638,7 @@ IMPL_LINK(ScreenshotAnnotationDlg_Impl, pictureFrameListener, VclWindowEvent&, r
ScreenshotAnnotationDlg::ScreenshotAnnotationDlg(
    vcl::Window* pParent,
    Dialog& rParentDialog)
:   SfxModalDialog(pParent, "ScreenshotAnnotationDialog", "cui/ui/screenshotannotationdialog.ui")
:   ModalDialog(pParent, "ScreenshotAnnotationDialog", "cui/ui/screenshotannotationdialog.ui")
{
    m_pImpl.reset(new ScreenshotAnnotationDlg_Impl(*this, rParentDialog));
}
diff --git a/cui/source/inc/screenshotannotationdlg.hxx b/cui/source/inc/screenshotannotationdlg.hxx
index eaae258..ac9e0ed 100644
--- a/cui/source/inc/screenshotannotationdlg.hxx
+++ b/cui/source/inc/screenshotannotationdlg.hxx
@@ -19,12 +19,12 @@
#ifndef INCLUDED_CUI_SOURCE_INC_SCREENSHANNDLG_HXX
#define INCLUDED_CUI_SOURCE_INC_SCREENSHANNDLG_HXX

#include <sfx2/basedlgs.hxx>
#include <vcl/dialog.hxx>
#include <memory>

class ScreenshotAnnotationDlg_Impl;

class ScreenshotAnnotationDlg : public SfxModalDialog
class ScreenshotAnnotationDlg : public ModalDialog
{
private:
    std::unique_ptr< ScreenshotAnnotationDlg_Impl >  m_pImpl;
diff --git a/extras/source/glade/libreoffice-catalog.xml.in b/extras/source/glade/libreoffice-catalog.xml.in
index 5063da3..71bd5c0 100644
--- a/extras/source/glade/libreoffice-catalog.xml.in
+++ b/extras/source/glade/libreoffice-catalog.xml.in
@@ -191,9 +191,6 @@
    <glade-widget-class title="Address Preview" name="swlo-SwAddressPreview"
                        generic-name="Address Preview" parent="GtkDrawingArea"
                        icon-name="widget-gtk-drawingarea"/>
    <glade-widget-class title="Extended Macro Library" name="basctllo-ExtTreeListBox"
                        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"
                        icon-name="widget-gtk-treeview">
@@ -220,9 +217,6 @@
    <glade-widget-class title="Animation ListBox" name="sdlo-CustomAnimationList"
                        generic-name="Animation ListBox" parent="vcllo-SvTreeListBox"
                        icon-name="widget-gtk-treeview"/>
    <glade-widget-class title="CheckBox List" name="basctllo-CheckBox"
                        generic-name="CheckBox List" parent="vcllo-SvTreeListBox"
                        icon-name="widget-gtk-treeview"/>
    <glade-widget-class title="Page Objs ListBox" name="sdlo-SdPageObjsTLB"
                        generic-name="SdPageObjsTLB" parent="vcllo-SvTreeListBox"
                        icon-name="widget-gtk-treeview"/>
diff --git a/include/sfx2/app.hxx b/include/sfx2/app.hxx
index dce9f2c..e3517d3 100644
--- a/include/sfx2/app.hxx
+++ b/include/sfx2/app.hxx
@@ -146,7 +146,7 @@ public:
    // Basic/Scripting
    static bool                 IsXScriptURL( const OUString& rScriptURL );
    static OUString             ChooseScript(weld::Window *pParent);
    static void                 MacroOrganizer( sal_Int16 nTabId );
    static void                 MacroOrganizer(weld::Window* pParent, sal_Int16 nTabId);
    static ErrCode              CallBasic( const OUString&, BasicManager*, SbxArray *pArgs, SbxValue *pRet );
    static ErrCode              CallAppBasic( const OUString& i_macroName )
                                { return CallBasic( i_macroName, SfxApplication::GetBasicManager(), nullptr, nullptr ); }
diff --git a/include/vcl/tabdlg.hxx b/include/vcl/toolkit/tabdlg.hxx
similarity index 100%
rename from include/vcl/tabdlg.hxx
rename to include/vcl/toolkit/tabdlg.hxx
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 7687501..449190f 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -593,6 +593,8 @@ protected:
    Link<TreeView&, void> m_aRowActivatedHdl;
    Link<int, void> m_aColumnClickedHdl;
    Link<const std::pair<int, int>&, void> m_aRadioToggleHdl;
    Link<const TreeIter&, bool> m_aEditingStartedHdl;
    Link<const std::pair<const TreeIter&, OUString>&, bool> m_aEditingDoneHdl;
    // if handler returns false, the expansion of the row is refused
    Link<const TreeIter&, bool> m_aExpandingHdl;
    Link<TreeView&, void> m_aVisibleRangeChangedHdl;
@@ -615,6 +617,13 @@ protected:
    // arg is pair<row,col>
    void signal_toggled(const std::pair<int, int>& rRowCol) { m_aRadioToggleHdl.Call(rRowCol); }

    bool signal_editing_started(const TreeIter& rIter) { return m_aEditingStartedHdl.Call(rIter); }

    bool signal_editing_done(const std::pair<const TreeIter&, OUString>& rIterText)
    {
        return m_aEditingDoneHdl.Call(rIterText);
    }

public:
    virtual void insert(const TreeIter* pParent, int pos, const OUString* pStr, const OUString* pId,
                        const OUString* pIconName, VirtualDevice* pImageSurface,
@@ -807,6 +816,18 @@ public:

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

    // return true to allow editing, false to disallow
    virtual void connect_editing_started(const Link<const TreeIter&, bool>& rLink)
    {
        m_aEditingStartedHdl = rLink;
    }

    virtual void
    connect_editing_done(const Link<const std::pair<const TreeIter&, OUString>&, bool>& rLink)
    {
        m_aEditingDoneHdl = rLink;
    }

    virtual void connect_visible_range_changed(const Link<TreeView&, void>& rLink)
    {
        assert(!m_aVisibleRangeChangedHdl.IsSet() || !rLink.IsSet());
diff --git a/sfx2/source/appl/app.cxx b/sfx2/source/appl/app.cxx
index 2e84fb1..75ea2ff 100644
--- a/sfx2/source/appl/app.cxx
+++ b/sfx2/source/appl/app.cxx
@@ -414,14 +414,14 @@ void SfxApplication::Invalidate( sal_uInt16 nId )
#ifndef DISABLE_DYNLOADING

typedef long (*basicide_handle_basic_error)(void const *);
typedef void (*basicide_macro_organizer)(sal_Int16);
typedef void (*basicide_macro_organizer)(void const *, sal_Int16);

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

#else

extern "C" long basicide_handle_basic_error(void*);
extern "C" void basicide_macro_organizer(sal_Int16);
extern "C" void basicide_macro_organizer(void*, sal_Int16);

#endif

@@ -520,7 +520,7 @@ SfxApplication::ChooseScript(weld::Window *pParent)
    return aScriptURL;
}

void SfxApplication::MacroOrganizer( sal_Int16 nTabId )
void SfxApplication::MacroOrganizer(weld::Window* pParent, sal_Int16 nTabId)
{
#if !HAVE_FEATURE_SCRIPTING
    (void) nTabId;
@@ -541,11 +541,11 @@ void SfxApplication::MacroOrganizer( sal_Int16 nTabId )
        return;

    // call basicide_macro_organizer in basctl
    pSymbol( nTabId );
    pSymbol(pParent, nTabId);

#else

    basicide_macro_organizer( nTabId );
    basicide_macro_organizer(pParent, nTabId);

#endif

diff --git a/sfx2/source/appl/appserv.cxx b/sfx2/source/appl/appserv.cxx
index a7707b7..1535f0c 100644
--- a/sfx2/source/appl/appserv.cxx
+++ b/sfx2/source/appl/appserv.cxx
@@ -1520,7 +1520,7 @@ void SfxApplication::OfaExec_Impl( SfxRequest& rReq )
                nTabId = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
            }

            SfxApplication::MacroOrganizer( nTabId );
            SfxApplication::MacroOrganizer(rReq.GetFrameWeld(), nTabId);
            rReq.Done();
        }
        break;
diff --git a/solenv/clang-format/blacklist b/solenv/clang-format/blacklist
index ead4321..bd38e52 100644
--- a/solenv/clang-format/blacklist
+++ b/solenv/clang-format/blacklist
@@ -7937,7 +7937,6 @@ include/vcl/syschild.hxx
include/vcl/sysdata.hxx
include/vcl/syswin.hxx
include/vcl/tabctrl.hxx
include/vcl/tabdlg.hxx
include/vcl/tabpage.hxx
include/vcl/task.hxx
include/vcl/taskpanelist.hxx
@@ -7951,6 +7950,7 @@ include/vcl/timer.hxx
include/vcl/toolbox.hxx
include/vcl/toolkit/group.hxx
include/vcl/toolkit/morebtn.hxx
include/vcl/toolkit/tabdlg.hxx
include/vcl/toolkit/unowrap.hxx
include/vcl/transfer.hxx
include/vcl/treelist.hxx
diff --git a/toolkit/source/awt/vclxtoolkit.cxx b/toolkit/source/awt/vclxtoolkit.cxx
index 5b70b8e..398b5b7 100644
--- a/toolkit/source/awt/vclxtoolkit.cxx
+++ b/toolkit/source/awt/vclxtoolkit.cxx
@@ -111,7 +111,7 @@
#include <vcl/svapp.hxx>
#include <vcl/syschild.hxx>
#include <vcl/tabctrl.hxx>
#include <vcl/tabdlg.hxx>
#include <vcl/toolkit/tabdlg.hxx>
#include <vcl/tabpage.hxx>
#include <vcl/toolbox.hxx>
#include <vcl/virdev.hxx>
diff --git a/vcl/inc/treeglue.hxx b/vcl/inc/treeglue.hxx
index 15b95c0..05ebee5 100644
--- a/vcl/inc/treeglue.hxx
+++ b/vcl/inc/treeglue.hxx
@@ -34,6 +34,8 @@ class LclTabListBox : public SvTabListBox
    Link<SvTreeListBox*, void> m_aModelChangedHdl;
    Link<SvTreeListBox*, void> m_aStartDragHdl;
    Link<SvTreeListBox*, void> m_aEndDragHdl;
    Link<SvTreeListEntry*, bool> m_aEditingEntryHdl;
    Link<std::pair<SvTreeListEntry*, OUString>, bool> m_aEditedEntryHdl;

public:
    LclTabListBox(vcl::Window* pParent, WinBits nWinStyle)
@@ -44,6 +46,14 @@ public:
    void SetModelChangedHdl(const Link<SvTreeListBox*, void>& rLink) { m_aModelChangedHdl = rLink; }
    void SetStartDragHdl(const Link<SvTreeListBox*, void>& rLink) { m_aStartDragHdl = rLink; }
    void SetEndDragHdl(const Link<SvTreeListBox*, void>& rLink) { m_aEndDragHdl = rLink; }
    void SetEditingEntryHdl(const Link<SvTreeListEntry*, bool>& rLink)
    {
        m_aEditingEntryHdl = rLink;
    }
    void SetEditedEntryHdl(const Link<std::pair<SvTreeListEntry*, OUString>, bool>& rLink)
    {
        m_aEditedEntryHdl = rLink;
    }

    virtual DragDropMode NotifyStartDrag(TransferDataContainer&, SvTreeListEntry*) override
    {
@@ -114,6 +124,16 @@ public:

        return pTargetEntry;
    }

    virtual bool EditingEntry(SvTreeListEntry* pEntry, Selection&) override
    {
        return m_aEditingEntryHdl.Call(pEntry);
    }

    virtual bool EditedEntry(SvTreeListEntry* pEntry, const OUString& rNewText) override
    {
        return m_aEditedEntryHdl.Call(std::pair<SvTreeListEntry*, OUString>(pEntry, rNewText));
    }
};

/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 9fb6062..58d1422 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -2661,6 +2661,9 @@ private:
    DECL_LINK(ModelChangedHdl, SvTreeListBox*, void);
    DECL_LINK(StartDragHdl, SvTreeListBox*, void);
    DECL_STATIC_LINK(SalInstanceTreeView, FinishDragHdl, SvTreeListBox*, void);
    DECL_LINK(EditingEntryHdl, SvTreeListEntry*, bool);
    typedef std::pair<SvTreeListEntry*, OUString> IterString;
    DECL_LINK(EditedEntryHdl, IterString, bool);
    DECL_LINK(VisibleRangeChangedHdl, SvTreeListBox*, void);
    DECL_LINK(CompareHdl, const SvSortData&, sal_Int32);
    DECL_LINK(PopupMenuHdl, const CommandEvent&, bool);
@@ -2699,6 +2702,8 @@ public:
            static_cast<LclTabListBox&>(*m_xTreeView).SetModelChangedHdl(LINK(this, SalInstanceTreeView, ModelChangedHdl));
            static_cast<LclTabListBox&>(*m_xTreeView).SetStartDragHdl(LINK(this, SalInstanceTreeView, StartDragHdl));
            static_cast<LclTabListBox&>(*m_xTreeView).SetEndDragHdl(LINK(this, SalInstanceTreeView, FinishDragHdl));
            static_cast<LclTabListBox&>(*m_xTreeView).SetEditingEntryHdl(LINK(this, SalInstanceTreeView, EditingEntryHdl));
            static_cast<LclTabListBox&>(*m_xTreeView).SetEditedEntryHdl(LINK(this, SalInstanceTreeView, EditedEntryHdl));
        }
        m_aCheckButtonData.SetLink(LINK(this, SalInstanceTreeView, ToggleHdl));
        m_aRadioButtonData.SetLink(LINK(this, SalInstanceTreeView, ToggleHdl));
@@ -3228,6 +3233,18 @@ public:
        return ::get_text_emphasis(pEntry, col);
    }

    virtual void connect_editing_started(const Link<const weld::TreeIter&, bool>& rLink) override
    {
        m_xTreeView->EnableInplaceEditing(true);
        weld::TreeView::connect_editing_started(rLink);
    }

    virtual void connect_editing_done(const Link<const std::pair<const weld::TreeIter&, OUString>&, bool>& rLink) override
    {
        m_xTreeView->EnableInplaceEditing(true);
        weld::TreeView::connect_editing_done(rLink);
    }

    void set_image(SvTreeListEntry* pEntry, const Image& rImage, int col)
    {
        if (col == -1)
@@ -3929,6 +3946,16 @@ IMPL_LINK(SalInstanceTreeView, PopupMenuHdl, const CommandEvent&, rEvent, bool)
    return m_aPopupMenuHdl.Call(rEvent);
}

IMPL_LINK(SalInstanceTreeView, EditingEntryHdl, SvTreeListEntry*, pEntry, bool)
{
    return signal_editing_started(SalInstanceTreeIter(pEntry));
}

IMPL_LINK(SalInstanceTreeView, EditedEntryHdl, IterString, rIterString, bool)
{
    return signal_editing_done(std::pair<const weld::TreeIter&, OUString>(SalInstanceTreeIter(rIterString.first), rIterString.second));
}

class SalInstanceSpinButton : public SalInstanceEntry, public virtual weld::SpinButton
{
private:
diff --git a/vcl/source/window/tabdlg.cxx b/vcl/source/window/tabdlg.cxx
index 9a6c01d..9ff4c04 100644
--- a/vcl/source/window/tabdlg.cxx
+++ b/vcl/source/window/tabdlg.cxx
@@ -20,7 +20,7 @@
#include <vcl/fixed.hxx>
#include <vcl/layout.hxx>
#include <vcl/tabctrl.hxx>
#include <vcl/tabdlg.hxx>
#include <vcl/toolkit/tabdlg.hxx>
#include <vcl/tabpage.hxx>

void TabDialog::ImplInitTabDialogData()
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 0447ee4..58ea487 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -6651,6 +6651,50 @@ private:
        gtk_tree_path_free(tree_path);
    }

    DECL_LINK(async_stop_cell_editing, void*, void);

    static void signalCellEditingStarted(GtkCellRenderer*, GtkCellEditable*, const gchar *path, gpointer widget)
    {
        GtkInstanceTreeView* pThis = static_cast<GtkInstanceTreeView*>(widget);
        if (!pThis->signal_cell_editing_started(path))
            Application::PostUserEvent(LINK(pThis, GtkInstanceTreeView, async_stop_cell_editing));
    }

    bool signal_cell_editing_started(const gchar *path)
    {
        GtkTreePath *tree_path = gtk_tree_path_new_from_string(path);

        GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore);
        GtkInstanceTreeIter aGtkIter(nullptr);
        gtk_tree_model_get_iter(pModel, &aGtkIter.iter, tree_path);
        gtk_tree_path_free(tree_path);

        return signal_editing_started(aGtkIter);
    }

    static void signalCellEdited(GtkCellRendererText* pCell, const gchar *path, const gchar *pNewText, gpointer widget)
    {
        GtkInstanceTreeView* pThis = static_cast<GtkInstanceTreeView*>(widget);
        pThis->signal_cell_edited(pCell, path, pNewText);
    }

    void signal_cell_edited(GtkCellRendererText* pCell, const gchar *path, const gchar* pNewText)
    {
        GtkTreePath *tree_path = gtk_tree_path_new_from_string(path);

        GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore);
        GtkInstanceTreeIter aGtkIter(nullptr);
        gtk_tree_model_get_iter(pModel, &aGtkIter.iter, tree_path);
        gtk_tree_path_free(tree_path);

        OUString sText = OUString(pNewText, pNewText ? strlen(pNewText) : 0, RTL_TEXTENCODING_UTF8);
        if (signal_editing_done(std::pair<const weld::TreeIter&, OUString>(aGtkIter, sText)))
        {
            void* pData = g_object_get_data(G_OBJECT(pCell), "g-lo-CellIndex");
            set(aGtkIter.iter, reinterpret_cast<sal_IntPtr>(pData), sText);
        }
    }

    void signal_column_clicked(GtkTreeViewColumn* pClickedColumn)
    {
        int nIndex(0);
@@ -6752,15 +6796,17 @@ public:
            for (GList* pRenderer = g_list_first(pRenderers); pRenderer; pRenderer = g_list_next(pRenderer))
            {
                GtkCellRenderer* pCellRenderer = GTK_CELL_RENDERER(pRenderer->data);
                g_object_set_data(G_OBJECT(pCellRenderer), "g-lo-CellIndex", reinterpret_cast<gpointer>(nIndex));
                if (GTK_IS_CELL_RENDERER_TEXT(pCellRenderer))
                {
                    if (m_nTextCol == -1)
                        m_nTextCol = nIndex;
                    m_aWeightMap[nIndex] = -1;
                    g_signal_connect(G_OBJECT(pCellRenderer), "editing-started", G_CALLBACK(signalCellEditingStarted), this);
                    g_signal_connect(G_OBJECT(pCellRenderer), "edited", G_CALLBACK(signalCellEdited), this);
                }
                else if (GTK_IS_CELL_RENDERER_TOGGLE(pCellRenderer))
                {
                    g_object_set_data(G_OBJECT(pCellRenderer), "g-lo-CellIndex", reinterpret_cast<gpointer>(nIndex));
                    g_signal_connect(G_OBJECT(pCellRenderer), "toggled", G_CALLBACK(signalCellToggled), this);
                    m_aToggleVisMap[nIndex] = -1;
                    m_aToggleTriStateMap[nIndex] = -1;
@@ -7318,6 +7364,10 @@ public:

    void set_image(const GtkTreeIter& iter, int col, GdkPixbuf* pixbuf)
    {
        if (col == -1)
            col = m_nExpanderImageCol;
        else
            col = get_model_col(col);
        gtk_tree_store_set(m_pTreeStore, const_cast<GtkTreeIter*>(&iter), col, pixbuf, -1);
        if (pixbuf)
            g_object_unref(pixbuf);
@@ -7351,20 +7401,12 @@ public:
    virtual void set_image(const weld::TreeIter& rIter, const css::uno::Reference<css::graphic::XGraphic>& rImage, int col) override
    {
        const GtkInstanceTreeIter& rGtkIter = static_cast<const GtkInstanceTreeIter&>(rIter);
        if (col == -1)
            col = m_nExpanderImageCol;
        else
            col = get_model_col(col);
        set_image(rGtkIter.iter, col, getPixbuf(rImage));
    }

    virtual void set_image(const weld::TreeIter& rIter, const OUString& rImage, int col) override
    {
        const GtkInstanceTreeIter& rGtkIter = static_cast<const GtkInstanceTreeIter&>(rIter);
        if (col == -1)
            col = m_nExpanderImageCol;
        else
            col = get_model_col(col);
        set_image(rGtkIter.iter, col, getPixbuf(rImage));
    }

@@ -7919,12 +7961,11 @@ public:

    virtual bool get_dest_row_at_pos(const Point &rPos, weld::TreeIter* pResult) override
    {
        gtk_drag_unhighlight(GTK_WIDGET(m_pTreeView));
        gtk_drag_highlight(gtk_widget_get_parent(GTK_WIDGET(m_pTreeView)));
        const bool bAsTree = gtk_tree_view_get_enable_tree_lines(m_pTreeView);

        // to keep it simple we'll default to always drop before the current row
        // except for the special edge cases
        GtkTreeViewDropPosition pos = GTK_TREE_VIEW_DROP_BEFORE;
        GtkTreeViewDropPosition pos = bAsTree ? GTK_TREE_VIEW_DROP_INTO_OR_BEFORE : GTK_TREE_VIEW_DROP_BEFORE;

        // unhighlight current highlighted row
        gtk_tree_view_set_drag_dest_row(m_pTreeView, nullptr, pos);
@@ -7933,7 +7974,7 @@ public:
            gtk_drag_unhighlight(GTK_WIDGET(m_pTreeView));

        GtkTreePath *path = nullptr;
        GtkTreeViewDropPosition gtkpos = GTK_TREE_VIEW_DROP_BEFORE;
        GtkTreeViewDropPosition gtkpos = bAsTree ? GTK_TREE_VIEW_DROP_INTO_OR_BEFORE : GTK_TREE_VIEW_DROP_BEFORE;
        bool ret = gtk_tree_view_get_dest_row_at_pos(m_pTreeView, rPos.X(), rPos.Y(),
                                                     &path, &gtkpos);

@@ -8074,6 +8115,14 @@ IMPL_LINK_NOARG(GtkInstanceTreeView, async_signal_changed, void*, void)
    signal_changed();
}

IMPL_LINK_NOARG(GtkInstanceTreeView, async_stop_cell_editing, void*, void)
{
    GtkTreeViewColumn *focus_column = nullptr;
    gtk_tree_view_get_cursor(m_pTreeView, nullptr, &focus_column);
    if (focus_column)
        gtk_cell_area_stop_editing(gtk_cell_layout_get_area(GTK_CELL_LAYOUT(focus_column)), true);
}

class GtkInstanceSpinButton : public GtkInstanceEntry, public virtual weld::SpinButton
{
private: