basctl/Library_basctl.mk                                             |    1 
 basctl/UIConfig_basicide.mk                                          |    1 
 basctl/inc/strings.hrc                                               |    3 
 basctl/sdi/baside.sdi                                                |    6 
 basctl/source/basicide/baside2.cxx                                   |   12 
 basctl/source/basicide/baside2.hxx                                   |    7 
 basctl/source/basicide/baside3.cxx                                   |    9 
 basctl/source/basicide/basides1.cxx                                  |   26 
 basctl/source/basicide/basides2.cxx                                  |    2 
 basctl/source/basicide/basides3.cxx                                  |    2 
 basctl/source/basicide/basidesh.cxx                                  |   20 
 basctl/source/basicide/basobj3.cxx                                   |    3 
 basctl/source/basicide/idedataprovider.cxx                           |    8 
 basctl/source/basicide/objectbrowser.cxx                             |  207 
++++
 basctl/source/basicide/objectbrowsersearch.cxx                       |   63 +
 basctl/source/inc/baside3.hxx                                        |    9 
 basctl/source/inc/basidesh.hxx                                       |    6 
 basctl/source/inc/idedataprovider.hxx                                |   11 
 basctl/source/inc/objectbrowser.hxx                                  |   88 +-
 basctl/source/inc/objectbrowsersearch.hxx                            |   39 
 basctl/uiconfig/basicide/menubar/menubar.xml                         |    1 
 basctl/uiconfig/basicide/ui/objectbrowser.ui                         |  423 
++++++++++
 include/sfx2/sfxsids.hrc                                             |    1 
 officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu |    5 
 officecfg/registry/schema/org/openoffice/Office/BasicIDE.xcs         |    6 
 sfx2/sdi/sfx.sdi                                                     |   19 
 26 files changed, 957 insertions(+), 21 deletions(-)

New commits:
commit 87a7d94cc35253451e26e789e6243f2c5fd3ac77
Author:     Devansh Varshney <[email protected]>
AuthorDate: Fri Sep 19 20:59:13 2025 +0530
Commit:     Jonathan Clark <[email protected]>
CommitDate: Fri Sep 26 21:46:24 2025 +0200

    tdf#165785: basctl: Integrate blank UI shell for Object Browser
    
    This patch integrates the user interface for the new Object Browser.
    It introduces the UI definition file and the C++ logic to create,
    display, and manage the window's lifecycle within the IDE.
    
    (GSoC 2025 - Object Browser: UI Shell Integration)
    
    Change-Id: I9a2d7c319a7590e44eafe3d575eb3b0aeffb7e86
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191206
    Reviewed-by: Jonathan Clark <[email protected]>
    Tested-by: Jenkins

diff --git a/basctl/Library_basctl.mk b/basctl/Library_basctl.mk
index 37c94edd089a..c9f2bb88bda6 100644
--- a/basctl/Library_basctl.mk
+++ b/basctl/Library_basctl.mk
@@ -108,6 +108,7 @@ $(eval $(call gb_Library_add_exception_objects,basctl,\
        basctl/source/basicide/BasicColorConfig \
        basctl/source/basicide/ColorSchemeDialog \
        basctl/source/basicide/objectbrowser \
+       basctl/source/basicide/objectbrowsersearch \
        basctl/source/basicide/ObjectCatalog \
        basctl/source/basicide/sbxitem \
        basctl/source/basicide/scriptdocument \
diff --git a/basctl/UIConfig_basicide.mk b/basctl/UIConfig_basicide.mk
index 217ea6c01708..9609c5e2571e 100644
--- a/basctl/UIConfig_basicide.mk
+++ b/basctl/UIConfig_basicide.mk
@@ -53,6 +53,7 @@ $(eval $(call gb_UIConfig_add_uifiles,modules/BasicIDE,\
        basctl/uiconfig/basicide/ui/managelanguages \
        basctl/uiconfig/basicide/ui/modulepage \
        basctl/uiconfig/basicide/ui/newlibdialog \
+       basctl/uiconfig/basicide/ui/objectbrowser \
        basctl/uiconfig/basicide/ui/organizedialog \
        basctl/uiconfig/basicide/ui/sortmenu \
 ))
diff --git a/basctl/inc/strings.hrc b/basctl/inc/strings.hrc
index 60cf263b9ac8..72abed45361d 100644
--- a/basctl/inc/strings.hrc
+++ b/basctl/inc/strings.hrc
@@ -102,6 +102,9 @@
 #define RID_STR_CHOOSE                      NC_("RID_STR_CHOOSE", "Choose")
 #define RID_STR_RUN                         NC_("RID_STR_RUN", "Run")
 #define RID_STR_RECORD                      NC_("RID_STR_RECORD", "~Save")
+#define RID_STR_OBJECT_BROWSER              NC_("RID_STR_OBJECT_BROWSER", 
"Object Browser")
+#define RID_STR_OB_SCOPE_ALL                NC_("RID_STR_OB_SCOPE_ALL", "All 
Libraries")
+#define RID_STR_OB_SCOPE_CURRENT            NC_("RID_STR_OB_SCOPE_CURRENT", 
"Current Document")
 #define RID_BASICIDE_OBJCAT                 NC_("RID_BASICIDE_OBJCAT", "Object 
Catalog")
 // Property Browser Headline 
----------------------------------------------------------------
 #define RID_STR_BRWTITLE_PROPERTIES         NC_("RID_STR_BRWTITLE_PROPERTIES", 
"Properties: ")
diff --git a/basctl/sdi/baside.sdi b/basctl/sdi/baside.sdi
index 34f34a6362e2..3818296cb434 100644
--- a/basctl/sdi/baside.sdi
+++ b/basctl/sdi/baside.sdi
@@ -242,6 +242,12 @@ shell basctl_Shell
         StateMethod = GetState;
     ]
 
+    SID_BASICIDE_OBJECT_BROWSER
+    [
+        ExecMethod  = ExecuteGlobal;
+        StateMethod = GetState;
+    ]
+
     SID_BASICIDE_OBJCAT
     [
         ExecMethod  = ExecuteGlobal;
diff --git a/basctl/source/basicide/baside2.cxx 
b/basctl/source/basicide/baside2.cxx
index 5276895999d7..3bf17508e46a 100644
--- a/basctl/source/basicide/baside2.cxx
+++ b/basctl/source/basicide/baside2.cxx
@@ -22,6 +22,7 @@
 #include <basobj.hxx>
 #include <basidesh.hxx>
 #include "brkdlg.hxx"
+#include "idetimer.hxx"
 #include <iderdll.hxx>
 #include <iderid.hxx>
 #include "moduldlg.hxx"
@@ -1464,11 +1465,12 @@ void ModulWindow::SetEditorColorScheme(const OUString& 
rColorScheme)
         rEditWindow.UpdateSyntaxHighlighting();
 }
 
-ModulWindowLayout::ModulWindowLayout (vcl::Window* pParent, ObjectCatalog& 
rObjectCatalog_) :
+ModulWindowLayout::ModulWindowLayout (vcl::Window* pParent, ObjectBrowser& 
rObjectBrowser_, ObjectCatalog& rObjectCatalog_) :
     Layout(pParent),
     pChild(nullptr),
     aWatchWindow(VclPtr<WatchWindow>::Create(this)),
     aStackWindow(VclPtr<StackWindow>::Create(this)),
+    rObjectBrowser(rObjectBrowser_),
     rObjectCatalog(rObjectCatalog_)
 {
     // Get active color scheme from the registry
@@ -1516,6 +1518,10 @@ void ModulWindowLayout::Activating (BaseWindow& rChild)
     pChild = &static_cast<ModulWindow&>(rChild);
     aWatchWindow->Show();
     aStackWindow->Show();
+    IdeTimer 
aTimer(u"Shell::BASIDE2::ModulWindowLayout::Activating::ShowObjectBrowser
"_ustr);
+    rObjectBrowser.Show();
+    rObjectBrowser.SetLayoutWindow(this);
+    rObjectBrowser.RefreshUI();
     rObjectCatalog.Show();
     rObjectCatalog.SetLayoutWindow(this);
     rObjectCatalog.UpdateEntries();
@@ -1530,6 +1536,7 @@ void ModulWindowLayout::Deactivating ()
     Layout::Deactivating();
     aWatchWindow->Hide();
     aStackWindow->Hide();
+    rObjectBrowser.Hide();
     rObjectCatalog.Hide();
     pChild = nullptr;
 }
@@ -1572,7 +1579,8 @@ void ModulWindowLayout::ShowStackWindow(bool bVisible)
 
 void ModulWindowLayout::OnFirstSize (tools::Long const nWidth, tools::Long 
const nHeight)
 {
-    AddToLeft(&rObjectCatalog, Size(nWidth * 0.20, nHeight * 0.75));
+    AddToLeft(&rObjectBrowser, Size(nWidth * 0.25, nHeight * 0.375));
+    AddToLeft(&rObjectCatalog, Size(nWidth * 0.20, nHeight * 0.375));
     AddToBottom(aWatchWindow.get(), Size(nWidth * 0.67, nHeight * 0.25));
     AddToBottom(aStackWindow.get(), Size(nWidth * 0.33, nHeight * 0.25));
 }
diff --git a/basctl/source/basicide/baside2.hxx 
b/basctl/source/basicide/baside2.hxx
index 1dd5d167207a..4cada87fec78 100644
--- a/basctl/source/basicide/baside2.hxx
+++ b/basctl/source/basicide/baside2.hxx
@@ -51,6 +51,7 @@ namespace com::sun::star::beans { class XMultiPropertySet; }
 namespace basctl
 {
 
+class ObjectBrowser;
 class ObjectCatalog;
 class CodeCompleteWindow;
 class ModulWindowLayout;
@@ -406,9 +407,12 @@ public:
 class ModulWindowLayout: public Layout
 {
 public:
-    ModulWindowLayout (vcl::Window* pParent, ObjectCatalog&);
+    ModulWindowLayout (vcl::Window* pParent, ObjectBrowser&, ObjectCatalog&);
     virtual ~ModulWindowLayout() override;
     virtual void dispose() override;
+
+    ModulWindowLayout(const ModulWindowLayout&) = delete;
+    ModulWindowLayout& operator=(const ModulWindowLayout&) = delete;
 public:
     // Layout:
     virtual void Activating (BaseWindow&) override;
@@ -440,6 +444,7 @@ private:
     // dockable windows
     VclPtr<WatchWindow> aWatchWindow;
     VclPtr<StackWindow> aStackWindow;
+    ObjectBrowser& rObjectBrowser;
     ObjectCatalog& rObjectCatalog;
     // Active color scheme ID
     OUString m_sColorSchemeId;
diff --git a/basctl/source/basicide/baside3.cxx 
b/basctl/source/basicide/baside3.cxx
index 037bd3197a7e..5c7bfa4fec7b 100644
--- a/basctl/source/basicide/baside3.cxx
+++ b/basctl/source/basicide/baside3.cxx
@@ -1200,8 +1200,9 @@ SbxItemType DialogWindow::GetSbxType () const
 // DialogWindowLayout
 
 
-DialogWindowLayout::DialogWindowLayout (vcl::Window* pParent, ObjectCatalog& 
rObjectCatalog_) :
+DialogWindowLayout::DialogWindowLayout (vcl::Window* pParent, ObjectBrowser& 
rObjectBrowser_, ObjectCatalog& rObjectCatalog_) :
     Layout(pParent),
+    rObjectBrowser(rObjectBrowser_),
     rObjectCatalog(rObjectCatalog_),
     pPropertyBrowser(nullptr)
 {
@@ -1260,6 +1261,10 @@ void DialogWindowLayout::UpdatePropertyBrowser ()
 void DialogWindowLayout::Activating (BaseWindow& rChild)
 {
     assert(dynamic_cast<DialogWindow*>(&rChild));
+    rObjectBrowser.Show();
+    rObjectBrowser.SetLayoutWindow(this);
+    rObjectBrowser.RefreshUI();
+
     rObjectCatalog.SetLayoutWindow(this);
     rObjectCatalog.UpdateEntries();
     rObjectCatalog.Show();
@@ -1271,6 +1276,7 @@ void DialogWindowLayout::Activating (BaseWindow& rChild)
 void DialogWindowLayout::Deactivating ()
 {
     Layout::Deactivating();
+    rObjectBrowser.Hide();
     rObjectCatalog.Hide();
     if (pPropertyBrowser)
         pPropertyBrowser->Hide();
@@ -1310,6 +1316,7 @@ void DialogWindowLayout::GetState (SfxItemSet& rSet, 
unsigned nWhich)
 
 void DialogWindowLayout::OnFirstSize (tools::Long const nWidth, tools::Long 
const nHeight)
 {
+    AddToLeft(&rObjectBrowser, Size(nWidth * 0.25, nHeight * 0.35));
     AddToLeft(&rObjectCatalog, Size(nWidth * 0.25, nHeight * 0.35));
     if (pPropertyBrowser)
         AddPropertyBrowser();
diff --git a/basctl/source/basicide/basides1.cxx 
b/basctl/source/basicide/basides1.cxx
index 626362473e0e..8cc67c9c1b08 100644
--- a/basctl/source/basicide/basides1.cxx
+++ b/basctl/source/basicide/basides1.cxx
@@ -422,6 +422,23 @@ void Shell::ExecuteGlobal( SfxRequest& rReq )
         }
         break;
 
+        case SID_BASICIDE_OBJECT_BROWSER:
+        {
+            bool bIsNowVisible = !aObjectBrowser->IsVisible();
+            aObjectBrowser->Show(bIsNowVisible);
+
+            if (pLayout)
+                pLayout->ArrangeWindows();
+
+            if (SfxBindings* pBindings = GetBindingsPtr())
+                pBindings->Invalidate(SID_BASICIDE_OBJECT_BROWSER);
+
+            auto pChanges = comphelper::ConfigurationChanges::create();
+            
officecfg::Office::BasicIDE::EditorSettings::ObjectBrowser::set(bIsNowVisible, 
pChanges);
+            pChanges->commit();
+        }
+        break;
+
         case SID_BASICIDE_OBJCAT:
         {
             // Toggle the visibility of the object catalog
@@ -959,6 +976,15 @@ void Shell::GetState(SfxItemSet &rSet)
             }
             break;
 
+            case SID_BASICIDE_OBJECT_BROWSER:
+            {
+                if (pLayout)
+                    rSet.Put(SfxBoolItem(nWh, aObjectBrowser->IsVisible()));
+                else
+                    rSet.Put(SfxVisibilityItem(nWh, false));
+            }
+            break;
+
             case SID_BASICIDE_OBJCAT:
             {
                 if (pLayout)
diff --git a/basctl/source/basicide/basides2.cxx 
b/basctl/source/basicide/basides2.cxx
index 249b3e6f43c7..92dee60a4386 100644
--- a/basctl/source/basicide/basides2.cxx
+++ b/basctl/source/basicide/basides2.cxx
@@ -165,7 +165,7 @@ VclPtr<ModulWindow> Shell::CreateBasWin( const 
ScriptDocument& rDocument, const
             {
                 // new module window
                 if (!pModulLayout)
-                    
pModulLayout.reset(VclPtr<ModulWindowLayout>::Create(&GetViewFrame().GetWindow(),
 *aObjectCatalog));
+                    
pModulLayout.reset(VclPtr<ModulWindowLayout>::Create(&GetViewFrame().GetWindow(),
 *aObjectBrowser, *aObjectCatalog));
                 pWin = VclPtr<ModulWindow>::Create(pModulLayout.get(), 
rDocument, aLibName, aModName, aModule);
                 nKey = InsertWindowInTable( pWin );
             }
diff --git a/basctl/source/basicide/basides3.cxx 
b/basctl/source/basicide/basides3.cxx
index 2c9ba2bc1099..37c4b2fe13da 100644
--- a/basctl/source/basicide/basides3.cxx
+++ b/basctl/source/basicide/basides3.cxx
@@ -81,7 +81,7 @@ VclPtr<DialogWindow> Shell::CreateDlgWin( const 
ScriptDocument& rDocument, const
 
                 // new dialog window
                 if (!pDialogLayout)
-                    
pDialogLayout.reset(VclPtr<DialogWindowLayout>::Create(&GetViewFrame().GetWindow(),
 *aObjectCatalog));
+                    
pDialogLayout.reset(VclPtr<DialogWindowLayout>::Create(&GetViewFrame().GetWindow(),
 *aObjectBrowser, *aObjectCatalog));
                 pWin = VclPtr<DialogWindow>::Create(pDialogLayout.get(), 
rDocument, aLibName, aDlgName, xDialogModel);
                 nKey = InsertWindowInTable( pWin );
             }
diff --git a/basctl/source/basicide/basidesh.cxx 
b/basctl/source/basicide/basidesh.cxx
index ef3e89a78f8f..06f58a9b97fa 100644
--- a/basctl/source/basicide/basidesh.cxx
+++ b/basctl/source/basicide/basidesh.cxx
@@ -170,6 +170,7 @@ Shell::Shell( SfxViewFrame& rFrame_, SfxViewShell* /* 
pOldShell */ ) :
     aHScrollBar( VclPtr<ScrollAdaptor>::Create(&GetViewFrame().GetWindow(), 
true) ),
     aVScrollBar( VclPtr<ScrollAdaptor>::Create(&GetViewFrame().GetWindow(), 
false) ),
     pLayout(nullptr),
+    aObjectBrowser(VclPtr<ObjectBrowser>::Create(*this, 
&GetViewFrame().GetWindow())),
     aObjectCatalog(VclPtr<ObjectCatalog>::Create(&GetViewFrame().GetWindow())),
     m_bAppBasicModified( false ),
     m_aNotifier( *this )
@@ -214,6 +215,11 @@ void Shell::Init()
     InitTabBar();
     InitZoomLevel();
 
+    // Initialize the visibility of the Object Browser
+    bool bObjBrowserVisible = 
::officecfg::Office::BasicIDE::EditorSettings::ObjectBrowser::get();
+    if (!bObjBrowserVisible)
+        aObjectBrowser->Show(bObjBrowserVisible);
+
     // Initialize the visibility of the Object Catalog
     bool bObjCatVisible = 
::officecfg::Office::BasicIDE::EditorSettings::ObjectCatalog::get();
     if (!bObjCatVisible)
@@ -248,6 +254,7 @@ Shell::~Shell()
     SetWindow( nullptr );
     SetCurWindow( nullptr );
 
+    aObjectBrowser.disposeAndClear();
     aObjectCatalog.disposeAndClear();
     aVScrollBar.disposeAndClear();
     aHScrollBar.disposeAndClear();
@@ -529,6 +536,10 @@ void Shell::Notify( SfxBroadcaster& rBC, const SfxHint& 
rHint )
     if (rHint.GetId() == SfxHintId::Dying)
     {
         EndListening( rBC, true /* log off all */ );
+
+        if (aObjectBrowser)
+            aObjectBrowser->RefreshUI(/*bForceKeepUno=*/true);
+
         aObjectCatalog->UpdateEntries();
     }
 
@@ -862,6 +873,7 @@ void Shell::InvalidateBasicIDESlots()
     pBindings->Invalidate( SID_SIGNATURE );
     pBindings->Invalidate( SID_BASICIDE_CHOOSEMACRO );
     pBindings->Invalidate( SID_BASICIDE_MODULEDLG );
+    pBindings->Invalidate( SID_BASICIDE_OBJECT_BROWSER );
     pBindings->Invalidate( SID_BASICIDE_OBJCAT );
     pBindings->Invalidate( SID_BASICSTOP );
     pBindings->Invalidate( SID_BASICRUN );
@@ -983,6 +995,14 @@ void Shell::SetCurLibForLocalization( const 
ScriptDocument& rDocument, const OUS
     m_pCurLocalizationMgr->handleTranslationbar();
 }
 
+void Shell::UpdateObjectBrowser()
+{
+    if (aObjectBrowser)
+    {
+        aObjectBrowser->RefreshUI();
+    }
+}
+
 } // namespace basctl
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basctl/source/basicide/basobj3.cxx 
b/basctl/source/basicide/basobj3.cxx
index b5cdbf364ebb..6b0d241e7e45 100644
--- a/basctl/source/basicide/basobj3.cxx
+++ b/basctl/source/basicide/basobj3.cxx
@@ -260,6 +260,9 @@ void MarkDocumentModified( const ScriptDocument& rDocument )
         rDocument.setDocumentModified();
     }
 
+    if (pShell)
+        pShell->UpdateObjectBrowser();
+
     // tdf#130161 in all cases call UpdateObjectCatalog
     if (pShell)
         pShell->UpdateObjectCatalog();
diff --git a/basctl/source/basicide/idedataprovider.cxx 
b/basctl/source/basicide/idedataprovider.cxx
index 3c094c751426..7cd4458ba6e8 100644
--- a/basctl/source/basicide/idedataprovider.cxx
+++ b/basctl/source/basicide/idedataprovider.cxx
@@ -8,6 +8,7 @@
  */
 
 #include <idedataprovider.hxx>
+#include <vcl/svapp.hxx>
 
 namespace basctl
 {
@@ -15,6 +16,13 @@ IdeDataProvider::IdeDataProvider() {}
 
 IdeDataProvider::~IdeDataProvider() = default;
 
+void IdeDataProvider::AsyncInitialize(const Link<void*, void>& rFinishCallback)
+{
+    Application::PostUserEvent(rFinishCallback);
+}
+
+bool IdeDataProvider::IsInitialized() const { return m_bInitialized; }
+
 } // namespace basctl
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/basctl/source/basicide/objectbrowser.cxx 
b/basctl/source/basicide/objectbrowser.cxx
index ec4d8a811394..8b7c9f411ed9 100644
--- a/basctl/source/basicide/objectbrowser.cxx
+++ b/basctl/source/basicide/objectbrowser.cxx
@@ -7,30 +7,223 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-#include <iderid.hxx>
-#include "idetimer.hxx"
+#include <basidesh.hxx>
 #include <objectbrowser.hxx>
-
+#include <objectbrowsersearch.hxx>
+#include <idedataprovider.hxx>
+#include <iderid.hxx>
 #include <strings.hrc>
 
+#include <vcl/svapp.hxx>
+#include <vcl/taskpanelist.hxx>
+#include <sal/log.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <sfx2/viewfrm.hxx>
+
 namespace basctl
 {
-ObjectBrowser::ObjectBrowser(vcl::Window* pParent)
-    : basctl::DockingWindow(pParent, u""_ustr, u"ObjectBrowser"_ustr)
+ObjectBrowser::ObjectBrowser(Shell& rShell, vcl::Window* pParent)
+    : basctl::DockingWindow(pParent, 
u"modules/BasicIDE/ui/objectbrowser.ui"_ustr,
+                            u"ObjectBrowser"_ustr)
+    , m_pShell(&rShell)
     , m_pDataProvider(std::make_unique<IdeDataProvider>())
+    , m_bDisposed(false)
+    , m_bUIInitialized(false)
+    , m_pDocNotifier(std::make_unique<DocumentEventNotifier>(*this))
 {
+    SetText(IDEResId(RID_STR_OBJECT_BROWSER));
+    SetBackground(GetSettings().GetStyleSettings().GetWindowColor());
+    EnableInput(true, true);
+
+    Initialize();
 }
 
-ObjectBrowser::~ObjectBrowser() {}
+ObjectBrowser::~ObjectBrowser() { disposeOnce(); }
+
+void ObjectBrowser::Initialize()
+{
+    if (m_eInitState != ObjectBrowserInitState::NotInitialized)
+        return;
+
+    // Set state to initializing
+    m_eInitState = ObjectBrowserInitState::Initializing;
+
+    // Handles to all our widgets
+    m_xScopeSelector = m_xBuilder->weld_combo_box(u"ScopeSelector"_ustr);
+    m_pFilterBox = m_xBuilder->weld_entry(u"FilterBox"_ustr);
+    m_xLeftTreeView = m_xBuilder->weld_tree_view(u"LeftTreeView"_ustr);
+    m_xRightMembersView = m_xBuilder->weld_tree_view(u"RightMembersView"_ustr);
+    m_xDetailPane = m_xBuilder->weld_text_view(u"DetailPane"_ustr);
+    m_xStatusLabel = m_xBuilder->weld_label(u"StatusLabel"_ustr);
+    m_xRightPaneHeaderLabel = 
m_xBuilder->weld_label(u"RightPaneHeaderLabel"_ustr);
+    m_xBackButton = m_xBuilder->weld_button(u"BackButton"_ustr);
+    m_xForwardButton = m_xBuilder->weld_button(u"ForwardButton"_ustr);
+    m_xClearSearchButton = m_xBuilder->weld_button(u"ClearSearchButton"_ustr);
+
+    m_pSearchHandler = std::make_unique<ObjectBrowserSearch>(*this);
+    m_pSearchHandler->Initialize();
+
+    if (m_xScopeSelector)
+    {
+        m_xScopeSelector->append(IDEResId(RID_STR_OB_SCOPE_ALL), 
u"ALL_LIBRARIES"_ustr);
+        m_xScopeSelector->append(IDEResId(RID_STR_OB_SCOPE_CURRENT), 
u"CURRENT_DOCUMENT"_ustr);
+        m_xScopeSelector->set_active(0);
+        m_xScopeSelector->connect_changed(LINK(this, ObjectBrowser, 
OnScopeChanged));
+    }
+
+    if (m_xLeftTreeView)
+    {
+        m_xLeftTreeView->connect_selection_changed(LINK(this, ObjectBrowser, 
OnLeftTreeSelect));
+        m_xLeftTreeView->connect_expanding(LINK(this, ObjectBrowser, 
OnNodeExpand));
+    }
+    if (m_xRightMembersView)
+    {
+        m_xRightMembersView->connect_selection_changed(
+            LINK(this, ObjectBrowser, OnRightTreeSelect));
+    }
 
-void ObjectBrowser::Initialize() { m_pDataProvider = 
std::make_unique<IdeDataProvider>(); }
+    if (m_xBackButton)
+        m_xBackButton->set_sensitive(false);
+    if (m_xForwardButton)
+        m_xForwardButton->set_sensitive(false);
+
+    if (GetParent() && GetParent()->GetSystemWindow())
+    {
+        GetParent()->GetSystemWindow()->GetTaskPaneList()->AddWindow(this);
+    }
+
+    m_bUIInitialized = true;
+    m_eInitState = ObjectBrowserInitState::Initialized;
+}
 
 void ObjectBrowser::dispose()
 {
+    if (m_bDisposed)
+    {
+        return;
+    }
+
+    m_eInitState = ObjectBrowserInitState::Disposed;
+
+    if (GetParent() && GetParent()->GetSystemWindow())
+    {
+        if (auto* pTaskPaneList = 
GetParent()->GetSystemWindow()->GetTaskPaneList())
+            pTaskPaneList->RemoveWindow(this);
+    }
+
+    // Disconnect all signals
+    if (m_xScopeSelector)
+        m_xScopeSelector->connect_changed(Link<weld::ComboBox&, void>());
+    if (m_xLeftTreeView)
+    {
+        m_xLeftTreeView->connect_selection_changed(Link<weld::TreeView&, 
void>());
+        m_xLeftTreeView->connect_expanding(Link<const weld::TreeIter&, 
bool>());
+    }
+    if (m_xRightMembersView)
+        m_xRightMembersView->connect_selection_changed(Link<weld::TreeView&, 
void>());
+
+    if (m_pDocNotifier)
+    {
+        m_pDocNotifier->dispose();
+        m_pDocNotifier.reset();
+    }
+
+    if (m_pSearchHandler)
+    {
+        m_pSearchHandler.reset();
+    }
+
     m_pDataProvider.reset();
+
+    // Destroy widgets
+    m_xScopeSelector.reset();
+    m_pFilterBox.reset();
+    m_xLeftTreeView.reset();
+    m_xRightMembersView.reset();
+    m_xDetailPane.reset();
+    m_xStatusLabel.reset();
+    m_xRightPaneHeaderLabel.reset();
+    m_xBackButton.reset();
+    m_xForwardButton.reset();
+    m_xClearSearchButton.reset();
+
     DockingWindow::dispose();
 }
 
+bool ObjectBrowser::Close()
+{
+    Show(false);
+
+    SfxBindings& rBindings = m_pShell->GetViewFrame().GetBindings();
+    rBindings.Invalidate(SID_BASICIDE_OBJECT_BROWSER);
+
+    return false;
+}
+
+void ObjectBrowser::Show(bool bVisible)
+{
+    DockingWindow::Show(bVisible);
+
+    if (bVisible)
+    {
+        if (m_eInitState == ObjectBrowserInitState::NotInitialized)
+        {
+            Initialize();
+        }
+
+        if (!m_pDataProvider->IsInitialized())
+        {
+            ShowLoadingState();
+            m_pDataProvider->AsyncInitialize(LINK(this, ObjectBrowser, 
OnDataProviderInitialized));
+        }
+    }
+}
+
+void ObjectBrowser::RefreshUI(bool /*bForceKeepUno*/)
+{
+    if (!m_pDataProvider->IsInitialized())
+    {
+        ShowLoadingState();
+    }
+}
+
+void ObjectBrowser::ShowLoadingState()
+{
+    if (m_xLeftTreeView)
+    {
+        m_xLeftTreeView->freeze();
+        ClearTreeView(*m_xLeftTreeView, m_aLeftTreeSymbolStore);
+        m_xLeftTreeView->thaw();
+    }
+}
+
+void ObjectBrowser::ClearTreeView(weld::TreeView& rTree,
+                                  
std::vector<std::shared_ptr<basctl::IdeSymbolInfo>>& rStore)
+{
+    rTree.clear();
+    rStore.clear();
+}
+
+void ObjectBrowser::onDocumentCreated(const ScriptDocument&) { /* STUB */}
+void ObjectBrowser::onDocumentOpened(const ScriptDocument&) { /* STUB */}
+void ObjectBrowser::onDocumentSave(const ScriptDocument&) { /* STUB */}
+void ObjectBrowser::onDocumentSaveDone(const ScriptDocument&) { /* STUB */}
+void ObjectBrowser::onDocumentSaveAs(const ScriptDocument&) { /* STUB */}
+void ObjectBrowser::onDocumentSaveAsDone(const ScriptDocument&) { /* STUB */}
+void ObjectBrowser::onDocumentClosed(const ScriptDocument&) { /* STUB */}
+void ObjectBrowser::onDocumentTitleChanged(const ScriptDocument&) { /* STUB */}
+void ObjectBrowser::onDocumentModeChanged(const ScriptDocument&) { /* STUB */}
+
+IMPL_STATIC_LINK(ObjectBrowser, OnDataProviderInitialized, void*, /*p*/, void) 
{ /* STUB */}
+IMPL_STATIC_LINK(ObjectBrowser, OnLeftTreeSelect, weld::TreeView&, /*rTree*/, 
void) { /* STUB */}
+IMPL_STATIC_LINK(ObjectBrowser, OnRightTreeSelect, weld::TreeView&, /*rTree*/, 
void) { /* STUB */}
+IMPL_STATIC_LINK(ObjectBrowser, OnNodeExpand, const weld::TreeIter&, 
/*rParentIter*/, bool)
+{
+    return false;
+}
+IMPL_STATIC_LINK(ObjectBrowser, OnScopeChanged, weld::ComboBox&, 
/*rComboBox*/, void) { /* STUB */}
+
 } // namespace basctl
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/basctl/source/basicide/objectbrowsersearch.cxx 
b/basctl/source/basicide/objectbrowsersearch.cxx
new file mode 100644
index 000000000000..6efb2df034da
--- /dev/null
+++ b/basctl/source/basicide/objectbrowsersearch.cxx
@@ -0,0 +1,63 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL.2.0/.
+ */
+
+#include <objectbrowser.hxx>
+#include <objectbrowsersearch.hxx>
+#include <sal/log.hxx>
+
+namespace basctl
+{
+ObjectBrowserSearch::ObjectBrowserSearch(ObjectBrowser& rBrowser)
+    : m_aDebounceTimer("ObjectBrowserSearchDebounce")
+    , m_rBrowser(rBrowser)
+{
+    m_aDebounceTimer.SetInvokeHandler(LINK(this, ObjectBrowserSearch, 
DebounceTimerHandler));
+    m_aDebounceTimer.SetTimeout(350);
+}
+
+ObjectBrowserSearch::~ObjectBrowserSearch() {}
+
+void ObjectBrowserSearch::Initialize()
+{
+    SAL_INFO("basctl", "ObjectBrowserSearch::Initialize: Starting 
initialization");
+
+    if (m_rBrowser.GetFilterBox())
+    {
+        m_rBrowser.GetFilterBox()->connect_changed(
+            LINK(this, ObjectBrowserSearch, OnFilterChanged));
+        SAL_INFO("basctl", "ObjectBrowserSearch::Initialize: Connected to 
filter box");
+    }
+
+    if (m_rBrowser.GetClearSearchButton())
+    {
+        m_rBrowser.GetClearSearchButton()->connect_clicked(
+            LINK(this, ObjectBrowserSearch, OnClearSearchClicked));
+        SAL_INFO("basctl", "ObjectBrowserSearch::Initialize: Connected to 
clear button");
+    }
+}
+
+IMPL_STATIC_LINK(basctl::ObjectBrowserSearch, OnFilterChanged, weld::Entry&, 
/*rBox*/, void)
+{
+    // STUB
+}
+
+IMPL_STATIC_LINK(basctl::ObjectBrowserSearch, OnClearSearchClicked, 
weld::Button&, /*rButton*/,
+                 void)
+{
+    // STUB
+}
+
+IMPL_STATIC_LINK(basctl::ObjectBrowserSearch, DebounceTimerHandler, Timer*, 
/*pTimer*/, void)
+{
+    // STUB
+}
+
+} // namespace basctl
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/basctl/source/inc/baside3.hxx b/basctl/source/inc/baside3.hxx
index 7e68e2636960..6a805863901f 100644
--- a/basctl/source/inc/baside3.hxx
+++ b/basctl/source/inc/baside3.hxx
@@ -36,6 +36,7 @@ class DlgEdPage;
 class DlgEdView;
 
 class DialogWindowLayout;
+class ObjectBrowser;
 class ObjectCatalog;
 
 bool implImportDialog(weld::Window* pWin, const ScriptDocument& rDocument, 
const OUString& rLibName);
@@ -112,9 +113,12 @@ public:
 class DialogWindowLayout : public Layout
 {
 public:
-    DialogWindowLayout (vcl::Window* pParent, ObjectCatalog&);
+    DialogWindowLayout (vcl::Window* pParent, ObjectBrowser&, ObjectCatalog&);
     virtual ~DialogWindowLayout() override;
     virtual void dispose() override;
+
+    DialogWindowLayout(const DialogWindowLayout&) = delete;
+    DialogWindowLayout& operator=(const DialogWindowLayout&) = delete;
 public:
     void ShowPropertyBrowser ();
     void UpdatePropertyBrowser ();
@@ -132,7 +136,8 @@ protected:
 
 private:
     // dockable windows:
-    // object catalog (owned by Shell)
+    // object browser & catalog (owned by Shell)
+    ObjectBrowser& rObjectBrowser;
     ObjectCatalog& rObjectCatalog;
     // property browser (created by this, deleted by toolkit)
     VclPtr<PropBrw> pPropertyBrowser;
diff --git a/basctl/source/inc/basidesh.hxx b/basctl/source/inc/basidesh.hxx
index 6502558f81c5..427d0636d879 100644
--- a/basctl/source/inc/basidesh.hxx
+++ b/basctl/source/inc/basidesh.hxx
@@ -20,6 +20,7 @@
 
 #include "doceventnotifier.hxx"
 #include <basctl/sbxitem.hxx>
+#include "objectbrowser.hxx"
 #include "ObjectCatalog.hxx"
 
 #include <sfx2/viewsh.hxx>
@@ -85,7 +86,8 @@ private:
     VclPtr<ModulWindowLayout>   pModulLayout;
     VclPtr<DialogWindowLayout>  pDialogLayout;
     VclPtr<Layout>              pLayout;    // the active layout window
-    // common object catalog window
+    // common object browser & catalog window
+    VclPtr<ObjectBrowser>       aObjectBrowser;
     VclPtr<ObjectCatalog>       aObjectCatalog;
 
     bool    m_bAppBasicModified;
@@ -217,6 +219,8 @@ public:
     virtual css::uno::Reference< css::frame::XModel >
                         GetCurrentDocument() const override;
 
+    void UpdateObjectBrowser();
+
     void UpdateObjectCatalog () { aObjectCatalog->UpdateEntries(); }
 
     void RemoveWindow (BaseWindow* pWindow, bool bDestroy, bool 
bAllowChangeCurWindow = true);
diff --git a/basctl/source/inc/idedataprovider.hxx 
b/basctl/source/inc/idedataprovider.hxx
index 21294f2015bc..73d46badf140 100644
--- a/basctl/source/inc/idedataprovider.hxx
+++ b/basctl/source/inc/idedataprovider.hxx
@@ -9,15 +9,19 @@
 
 #pragma once
 
-#include <memory>
 #include <basctl/idecodecompletiontypes.hxx>
 
+#include <memory>
+#include <tools/link.hxx>
+
 namespace basctl
 {
 class IdeDataProviderInterface
 {
 public:
     virtual ~IdeDataProviderInterface() = default;
+    virtual void AsyncInitialize(const Link<void*, void>& rFinishCallback) = 0;
+    virtual bool IsInitialized() const = 0;
 };
 
 class IdeDataProvider : public IdeDataProviderInterface
@@ -25,6 +29,11 @@ class IdeDataProvider : public IdeDataProviderInterface
 public:
     IdeDataProvider();
     ~IdeDataProvider() override;
+    void AsyncInitialize(const Link<void*, void>& rFinishCallback) override;
+    bool IsInitialized() const override;
+
+private:
+    bool m_bInitialized = false;
 };
 
 } // namespace basctl
diff --git a/basctl/source/inc/objectbrowser.hxx 
b/basctl/source/inc/objectbrowser.hxx
index b5c01e2833e2..d280b395b524 100644
--- a/basctl/source/inc/objectbrowser.hxx
+++ b/basctl/source/inc/objectbrowser.hxx
@@ -10,28 +10,108 @@
 #pragma once
 
 #include "bastypes.hxx"
+#include "doceventnotifier.hxx"
 #include "idedataprovider.hxx"
 
 #include <basctl/idecodecompletiontypes.hxx>
+
+#include <atomic>
 #include <memory>
+#include <set>
+#include <vector>
+
+#include <vcl/status.hxx>
+#include <vcl/weld.hxx>
 
 namespace basctl
 {
 class Shell;
 class IdeDataProviderInterface;
+class ObjectBrowserSearch;
+class ObjectBrowserNavigation;
+
+enum class ObjectBrowserInitState
+{
+    NotInitialized,
+    Initializing,
+    Initialized,
+    Failed,
+    Disposed
+};
 
-class ObjectBrowser : public basctl::DockingWindow
+class ObjectBrowser : public basctl::DockingWindow, public 
basctl::DocumentEventListener
 {
 public:
-    ObjectBrowser(vcl::Window* pParent);
+    ObjectBrowser(Shell& rShell, vcl::Window* pParent);
     ~ObjectBrowser() override;
 
-    void Initialize();
-    void dispose() override;
+    virtual void dispose() override;
+    virtual bool Close() override;
+
+    void Show(bool bVisible = true);
+    void RefreshUI(bool bForceKeepUno = false);
+
+    void onDocumentCreated(const ScriptDocument& _rDocument) override;
+    void onDocumentOpened(const ScriptDocument& _rDocument) override;
+    void onDocumentSave(const ScriptDocument& _rDocument) override;
+    void onDocumentSaveDone(const ScriptDocument& _rDocument) override;
+    void onDocumentSaveAs(const ScriptDocument& _rDocument) override;
+    void onDocumentSaveAsDone(const ScriptDocument& _rDocument) override;
+    void onDocumentClosed(const ScriptDocument& _rDocument) override;
+    void onDocumentTitleChanged(const ScriptDocument& _rDocument) override;
+    void onDocumentModeChanged(const ScriptDocument& _rDocument) override;
+
+    weld::Entry* GetFilterBox() { return m_pFilterBox.get(); }
+    weld::Button* GetClearSearchButton() { return m_xClearSearchButton.get(); }
 
 private:
+    void Initialize();
+
+    // Core tree management methods
+    static void ClearTreeView(weld::TreeView& rTree,
+                              
std::vector<std::shared_ptr<basctl::IdeSymbolInfo>>& rStore);
+    void ShowLoadingState();
+
+    // Core References
+    Shell* m_pShell;
+
     // Data Provider
     std::unique_ptr<IdeDataProviderInterface> m_pDataProvider;
+
+    // State Management
+    bool m_bDisposed = false;
+    ObjectBrowserInitState m_eInitState = 
ObjectBrowserInitState::NotInitialized;
+    bool m_bUIInitialized = false;
+
+    // UI Widgets
+    std::unique_ptr<weld::ComboBox> m_xScopeSelector;
+    std::unique_ptr<weld::Entry> m_pFilterBox;
+    std::unique_ptr<weld::TreeView> m_xLeftTreeView;
+    std::unique_ptr<weld::TreeView> m_xRightMembersView;
+    std::unique_ptr<weld::TextView> m_xDetailPane;
+    std::unique_ptr<weld::Label> m_xStatusLabel;
+    std::unique_ptr<weld::Label> m_xRightPaneHeaderLabel;
+    std::unique_ptr<weld::Button> m_xBackButton;
+    std::unique_ptr<weld::Button> m_xForwardButton;
+    std::unique_ptr<weld::Button> m_xClearSearchButton;
+
+    // Data Storage
+    std::vector<std::shared_ptr<basctl::IdeSymbolInfo>> m_aLeftTreeSymbolStore;
+    std::vector<std::shared_ptr<basctl::IdeSymbolInfo>> 
m_aRightTreeSymbolStore;
+    std::map<OUString, size_t> m_aNextChunk; // For lazy-loading nodes
+
+    // Search Handler
+    std::unique_ptr<ObjectBrowserSearch> m_pSearchHandler;
+
+    // Event Handling
+    std::unique_ptr<basctl::DocumentEventNotifier> m_pDocNotifier;
+
+    // Event Handlers
+    DECL_STATIC_LINK(ObjectBrowser, OnDataProviderInitialized, void*, void);
+    DECL_STATIC_LINK(ObjectBrowser, OnLeftTreeSelect, weld::TreeView&, void);
+    DECL_STATIC_LINK(ObjectBrowser, OnRightTreeSelect, weld::TreeView&, void);
+    DECL_STATIC_LINK(ObjectBrowser, OnNodeExpand, const weld::TreeIter&, bool);
+    DECL_STATIC_LINK(ObjectBrowser, OnScopeChanged, weld::ComboBox&, void);
 };
 
 } // namespace basctl
diff --git a/basctl/source/inc/objectbrowsersearch.hxx 
b/basctl/source/inc/objectbrowsersearch.hxx
new file mode 100644
index 000000000000..30d1d6d5dc96
--- /dev/null
+++ b/basctl/source/inc/objectbrowsersearch.hxx
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL.2.0/.
+ */
+
+#pragma once
+
+#include <vcl/timer.hxx>
+#include <vcl/weld.hxx>
+
+namespace basctl
+{
+class ObjectBrowser;
+
+class ObjectBrowserSearch
+{
+public:
+    explicit ObjectBrowserSearch(ObjectBrowser& rBrowser);
+    ~ObjectBrowserSearch();
+
+    void Initialize();
+
+private:
+    // Event handlers for the UI widgets
+    DECL_STATIC_LINK(ObjectBrowserSearch, OnFilterChanged, weld::Entry&, void);
+    DECL_STATIC_LINK(ObjectBrowserSearch, OnClearSearchClicked, weld::Button&, 
void);
+    DECL_STATIC_LINK(ObjectBrowserSearch, DebounceTimerHandler, Timer*, void);
+
+    Timer m_aDebounceTimer;
+    ObjectBrowser& m_rBrowser;
+};
+
+} // namespace basctl
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/basctl/uiconfig/basicide/menubar/menubar.xml 
b/basctl/uiconfig/basicide/menubar/menubar.xml
index bf41ce562bec..8e2fba9947fc 100644
--- a/basctl/uiconfig/basicide/menubar/menubar.xml
+++ b/basctl/uiconfig/basicide/menubar/menubar.xml
@@ -70,6 +70,7 @@
             <menu:menuseparator/>
             <menu:menuitem menu:id=".uno:ShowLines"/>
             <menu:menuitem menu:id=".uno:ShowPropBrowser"/>
+            <menu:menuitem menu:id=".uno:ObjectBrowser"/>
             <menu:menuitem menu:id=".uno:ObjectCatalog"/>
             <menu:menuitem menu:id=".uno:WatchWindow"/>
             <menu:menuitem menu:id=".uno:StackWindow"/>
diff --git a/basctl/uiconfig/basicide/ui/objectbrowser.ui 
b/basctl/uiconfig/basicide/ui/objectbrowser.ui
new file mode 100644
index 000000000000..9ea9c21e5189
--- /dev/null
+++ b/basctl/uiconfig/basicide/ui/objectbrowser.ui
@@ -0,0 +1,423 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.40.0 -->
+<interface domain="basctl">
+  <requires lib="gtk+" version="3.20"/><!--actual version="3.24"-->
+  <object class="GtkTreeStore" id="LeftTreeStore">
+    <columns>
+      <column type="gchararray"/>
+      <column type="gchararray"/>
+      <column type="gchararray"/>
+      <column type="gchararray"/>
+      <column type="gchararray"/>
+    </columns>
+  </object>
+  <object class="GtkTreeStore" id="RightMembersStore">
+    <columns>
+      <column type="gchararray"/>
+      <column type="gchararray"/>
+      <column type="gchararray"/>
+      <column type="gchararray"/>
+      <column type="gchararray"/>
+    </columns>
+  </object>
+    <object class="GtkBox" id="ObjectBrowser">
+    <property name="name">ObjectBrowser</property>
+    <property name="visible">True</property>
+    <property name="can-focus">False</property>
+    <property name="orientation">vertical</property>
+    <property name="spacing">6</property>
+    <!-- Search Bar Container -->
+    <child>
+      <object class="GtkBox" id="SearchBoxContainer">
+        <property name="name">SearchBoxContainer</property>
+        <property name="visible">True</property>
+        <property name="can-focus">False</property>
+        <property name="orientation">horizontal</property>
+        <property name="spacing">6</property>
+        <!-- Search Entry -->
+        <child>
+          <object class="GtkEntry" id="FilterBox">
+            <property name="name">FilterBox</property>
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="hexpand">True</property>
+            <property name="placeholder-text" translatable="yes" 
context="objectbrowser|FilterBox">Search objects and members...</property>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <!-- Clear Button -->
+        <child>
+          <object class="GtkButton" id="ClearSearchButton">
+            <property name="label" translatable="yes" 
context="objectbrowser|ClearSearchButton">✕</property>
+            <property name="name">ClearSearchButton</property>
+            <property name="visible">False</property> <!-- Initially hidden -->
+            <property name="can-focus">True</property>
+            <property name="receives-default">True</property>
+            <property name="tooltip-text" translatable="yes" 
context="objectbrowser|ClearSearchButton">Clear Search</property>
+            <style>
+              <class name="flat"/>
+            </style>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">0</property>
+      </packing>
+    </child>
+    <!-- Controls Row -->
+    <child>
+      <object class="GtkBox">
+        <property name="visible">True</property>
+        <property name="can-focus">False</property>
+        <property name="spacing">6</property>
+        <!-- Label -->
+        <child>
+          <object class="GtkLabel" id="ScopeSelectorLabel">
+            <property name="name">ScopeSelectorLabel</property>
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="label" translatable="yes" 
context="objectbrowser|ScopeSelectorLabel">Scope:</property>
+            <accessibility>
+              <relation type="label-for" target="ScopeSelector"/>
+            </accessibility>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <!-- ComboBox -->
+        <child>
+          <object class="GtkComboBoxText" id="ScopeSelector">
+            <property name="name">ScopeSelector</property>
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <accessibility>
+              <relation type="labelled-by" target="ScopeSelectorLabel"/>
+            </accessibility>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <!-- Spacer to push buttons to the right -->
+        <child>
+          <object class="GtkBox">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="hexpand">True</property>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+        <!-- Back Button -->
+        <child>
+          <object class="GtkButton" id="BackButton">
+            <property name="label" translatable="yes" 
context="objectbrowser|BackButton">◀</property>
+            <property name="name">BackButton</property>
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="receives-default">True</property>
+            <property name="tooltip-text" translatable="yes" 
context="objectbrowser|BackButtonTip">Back in Navigation History</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">3</property>
+          </packing>
+        </child>
+        <!-- Forward Button -->
+        <child>
+          <object class="GtkButton" id="ForwardButton">
+            <property name="label" translatable="yes" 
context="objectbrowser|ForwardButton">▶</property>
+            <property name="name">ForwardButton</property>
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="receives-default">True</property>
+            <property name="tooltip-text" translatable="yes" 
context="objectbrowser|ForwardButtonTip">Forward in Navigation 
History</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">4</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">1</property>
+      </packing>
+    </child>
+    <!-- Main Content Area -->
+    <child>
+      <object class="GtkPaned" id="MainVerticalSplitter">
+        <property name="name">MainVerticalSplitter</property>
+        <property name="visible">True</property>
+        <property name="can-focus">True</property>
+        <property name="vexpand">True</property>
+        <property name="orientation">vertical</property>
+        <property name="position">400</property>
+        <property name="position-set">True</property>
+        <child>
+          <object class="GtkPaned" id="MainHorizontalSplitter">
+            <property name="name">MainHorizontalSplitter</property>
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="hexpand">True</property>
+            <property name="position">320</property>
+            <property name="position-set">True</property>
+            <child>
+              <object class="GtkBox" id="LeftPaneContainer">
+                <property name="name">LeftPaneContainer</property>
+                <property name="visible">True</property>
+                <property name="can-focus">False</property>
+                <property name="vexpand">True</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">6</property>
+                <child>
+                  <object class="GtkLabel" id="LeftPaneLabel">
+                    <property name="name">LeftPaneLabel</property>
+                    <property name="visible">True</property>
+                    <property name="can-focus">False</property>
+                    <property name="halign">start</property>
+                    <property name="label" translatable="yes" 
context="objectbrowser|LeftPaneLabel">Objects</property>
+                    <accessibility>
+                      <relation type="label-for" target="LeftTreeView"/>
+                    </accessibility>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkScrolledWindow" id="LeftScroller">
+                    <property name="name">LeftTreeWindow</property>
+                    <property name="visible">True</property>
+                    <property name="can-focus">True</property>
+                    <property name="vexpand">True</property>
+                    <property name="shadow-type">in</property>
+                    <child>
+                      <object class="GtkTreeView" id="LeftTreeView">
+                        <property name="name">LeftTreeView</property>
+                        <property name="visible">True</property>
+                        <property name="can-focus">True</property>
+                        <property name="model">LeftTreeStore</property>
+                        <property name="headers-visible">False</property>
+                        <child>
+                          <object class="GtkTreeViewColumn" 
id="LeftTreeColumn">
+                            <property name="title" translatable="yes" 
context="ObjectBrowserPanel">Objects</property>
+                            <child>
+                              <object class="GtkCellRendererText" 
id="LeftTreeCellRenderer"/>
+                            </child>
+                          </object>
+                        </child>
+                        <child internal-child="selection">
+                          <object class="GtkTreeSelection"/>
+                        </child>
+                        <accessibility>
+                          <relation type="labelled-by" target="LeftPaneLabel"/>
+                        </accessibility>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="resize">True</property>
+                <property name="shrink">True</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkBox" id="RightPaneContainer">
+                <property name="name">RightPaneContainer</property>
+                <property name="visible">True</property>
+                <property name="can-focus">False</property>
+                <property name="vexpand">True</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">6</property>
+                <child>
+                  <object class="GtkLabel" id="RightPaneHeaderLabel">
+                    <property name="name">RightPaneHeaderLabel</property>
+                    <property name="visible">True</property>
+                    <property name="can-focus">False</property>
+                    <property name="halign">start</property>
+                    <property name="label" translatable="yes" 
context="objectbrowser|RightPaneHeaderLabel">Members</property>
+                    <accessibility>
+                      <relation type="label-for" target="RightMembersView"/>
+                    </accessibility>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkScrolledWindow" id="RightScroller">
+                    <property name="name">RightMembersWindow</property>
+                    <property name="visible">True</property>
+                    <property name="can-focus">True</property>
+                    <property name="vexpand">True</property>
+                    <property name="shadow-type">in</property>
+                    <child>
+                      <object class="GtkTreeView" id="RightMembersView">
+                        <property name="name">RightMembersView</property>
+                        <property name="visible">True</property>
+                        <property name="can-focus">True</property>
+                        <property name="model">RightMembersStore</property>
+                        <property name="headers-visible">False</property>
+                        <child>
+                          <object class="GtkTreeViewColumn" 
id="RightTreeColumn">
+                            <property name="title" translatable="yes" 
context="ObjectBrowserMembers">Members</property>
+                            <child>
+                              <object class="GtkCellRendererText" 
id="RightTreeCellRenderer"/>
+                            </child>
+                          </object>
+                        </child>
+                        <child internal-child="selection">
+                          <object class="GtkTreeSelection"/>
+                        </child>
+                        <accessibility>
+                          <relation type="labelled-by" 
target="RightPaneHeaderLabel"/>
+                        </accessibility>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="resize">True</property>
+                <property name="shrink">True</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="resize">True</property>
+            <property name="shrink">False</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="DetailPaneContainer">
+            <property name="name">DetailPaneContainer</property>
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="vexpand">True</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">6</property>
+            <child>
+              <object class="GtkLabel" id="DetailPaneLabel">
+                <property name="name">DetailPaneLabel</property>
+                <property name="visible">True</property>
+                <property name="can-focus">False</property>
+                <property name="halign">start</property>
+                <property name="label" translatable="yes" 
context="objectbrowser|DetailPaneLabel">Details</property>
+                <accessibility>
+                  <relation type="label-for" target="DetailPane"/>
+                </accessibility>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkScrolledWindow" id="DetailScroller">
+                <property name="height-request">100</property>
+                <property name="visible">True</property>
+                <property name="can-focus">True</property>
+                <property name="vexpand">True</property>
+                <property name="shadow-type">in</property>
+                <child>
+                  <object class="GtkTextView" id="DetailPane">
+                    <property name="name">DetailPane</property>
+                    <property name="visible">True</property>
+                    <property name="can-focus">True</property>
+                    <property name="editable">False</property>
+                    <property name="wrap-mode">word</property>
+                    <property name="cursor-visible">False</property>
+                    <accessibility>
+                      <relation type="labelled-by" target="DetailPaneLabel"/>
+                    </accessibility>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="resize">False</property>
+            <property name="shrink">True</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">True</property>
+        <property name="fill">True</property>
+        <property name="position">2</property>
+      </packing>
+    </child>
+    <!-- Status Bar -->
+    <child>
+      <object class="GtkStatusbar" id="StatusBar">
+        <property name="visible">True</property>
+        <property name="can-focus">False</property>
+        <property name="spacing">2</property>
+        <child>
+          <object class="GtkLabel" id="StatusLabel">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="label" translatable="yes" 
context="objectbrowser|StatusLabel">Ready</property>
+            <property name="halign">start</property>
+            <property name="hexpand">True</property>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">3</property>
+      </packing>
+    </child>
+  </object>
+</interface>
+
diff --git a/include/sfx2/sfxsids.hrc b/include/sfx2/sfxsids.hrc
index b2364a1001ec..16dfaa129b7e 100644
--- a/include/sfx2/sfxsids.hrc
+++ b/include/sfx2/sfxsids.hrc
@@ -674,6 +674,7 @@ class SvxZoomItem;
 #define SID_BASICIDE_STACK                  TypedWhichId<SfxBoolItem>( 
SID_BASICIDE_START + 56 )
 #define SID_BASICIDE_COLOR_SCHEME_DLG       ( SID_BASICIDE_START + 57 )
 #define SID_TOGGLE_COMMENT                  ( SID_BASICIDE_START + 58 )
+#define SID_BASICIDE_OBJECT_BROWSER         ( SID_BASICIDE_START + 59 )
 #define SID_OPTIONS_TREEDIALOG              ( SID_BASICIDE_START + 862)
 #define SID_OPTIONS_SECURITY                ( SID_BASICIDE_START + 863)
 
diff --git 
a/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu 
b/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu
index 606109cb1549..fe7dc89621ab 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu
@@ -1673,6 +1673,11 @@ bit 3 (0x8): #define 
UICOMMANDDESCRIPTION_PROPERTIES_TOGGLEBUTTON 8
           <value>9</value>
         </prop>
       </node>
+      <node oor:name=".uno:ObjectBrowser" oor:op="replace">
+        <prop oor:name="Label" oor:type="xs:string">
+          <value xml:lang="en-US">Object ~Browser</value>
+        </prop>
+      </node>
       <node oor:name=".uno:ObjectCatalog" oor:op="replace">
         <prop oor:name="Label" oor:type="xs:string">
           <value xml:lang="en-US">Object Catalog</value>
diff --git a/officecfg/registry/schema/org/openoffice/Office/BasicIDE.xcs 
b/officecfg/registry/schema/org/openoffice/Office/BasicIDE.xcs
index cc783b837046..c1e33e781461 100644
--- a/officecfg/registry/schema/org/openoffice/Office/BasicIDE.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/BasicIDE.xcs
@@ -192,6 +192,12 @@
         </info>
         <value>true</value>
       </prop>
+      <prop oor:name="ObjectBrowser" oor:type="xs:boolean" 
oor:nillable="false">
+        <info>
+          <desc>Sets the visibility of the Object Browser window.</desc>
+        </info>
+        <value>true</value>
+      </prop>
       <prop oor:name="ObjectCatalog" oor:type="xs:boolean" 
oor:nillable="false">
         <info>
           <desc>Sets the visibility of the Object Catalog window.</desc>
diff --git a/sfx2/sdi/sfx.sdi b/sfx2/sdi/sfx.sdi
index 15238490292e..567b06c2d367 100644
--- a/sfx2/sdi/sfx.sdi
+++ b/sfx2/sdi/sfx.sdi
@@ -2797,6 +2797,25 @@ SfxVoidItem NewWindow SID_NEWWINDOW
 ]
 
 
+SfxVoidItem ObjectBrowser SID_BASICIDE_OBJECT_BROWSER
+()
+[
+    AutoUpdate = FALSE,
+    FastCall = FALSE,
+    ReadOnlyDoc = TRUE,
+    Toggle = FALSE,
+    Container = TRUE,
+    RecordAbsolute = FALSE,
+    RecordPerSet;
+    Asynchron;
+
+    AccelConfig = TRUE,
+    MenuConfig = TRUE,
+    ToolBoxConfig = TRUE,
+    GroupId = SfxGroupId::Macro;
+]
+
+
 SfxVoidItem ObjectCatalog SID_BASICIDE_OBJCAT
 ()
 [

Reply via email to