[Libreoffice-commits] core.git: basctl/inc basctl/source basctl/uiconfig basctl/UIConfig_basicide.mk include/vcl solenv/clang-format solenv/sanitizers vcl/source vcl/unx

Caolán McNamara (via logerrit) logerrit at kemper.freedesktop.org
Wed Feb 19 08:53:32 UTC 2020


 basctl/UIConfig_basicide.mk                 |    1 
 basctl/inc/bitmaps.hlst                     |    1 
 basctl/inc/pch/precompiled_basctl.hxx       |    8 
 basctl/inc/strings.hrc                      |    3 
 basctl/source/basicide/baside2.cxx          |    1 
 basctl/source/basicide/baside2.hxx          |   65 +--
 basctl/source/basicide/baside2b.cxx         |  535 ++++++++++++----------------
 basctl/source/basicide/basides2.cxx         |    1 
 basctl/source/basicide/basidesh.cxx         |    1 
 basctl/source/basicide/bastype3.hxx         |   45 --
 basctl/source/basicide/bastypes.cxx         |   23 -
 basctl/uiconfig/basicide/ui/dockingwatch.ui |  161 ++++++++
 include/vcl/svtabbx.hxx                     |    1 
 include/vcl/weld.hxx                        |    2 
 solenv/clang-format/blacklist               |    1 
 solenv/sanitizers/ui/modules/BasicIDE.suppr |    1 
 vcl/source/app/salvtables.cxx               |   23 +
 vcl/source/treelist/svtabbx.cxx             |   12 
 vcl/unx/gtk3/gtk3gtkinst.cxx                |   48 ++
 19 files changed, 517 insertions(+), 416 deletions(-)

New commits:
commit 4e07b178f58b1dabbb48bc9f26155b8270a4a72d
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Tue Feb 18 10:16:40 2020 +0000
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Wed Feb 19 09:52:51 2020 +0100

    weld WatchWindow panel
    
    Change-Id: Idb43d7bd168ce37fce8694946be6c7de7ca5a2c3
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/88930
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/basctl/UIConfig_basicide.mk b/basctl/UIConfig_basicide.mk
index 411223416500..9c879545044d 100644
--- a/basctl/UIConfig_basicide.mk
+++ b/basctl/UIConfig_basicide.mk
@@ -42,6 +42,7 @@ $(eval $(call gb_UIConfig_add_uifiles,modules/BasicIDE,\
 	basctl/uiconfig/basicide/ui/dialogpage \
 	basctl/uiconfig/basicide/ui/dockingorganizer \
 	basctl/uiconfig/basicide/ui/dockingstack \
+	basctl/uiconfig/basicide/ui/dockingwatch \
 	basctl/uiconfig/basicide/ui/exportdialog \
 	basctl/uiconfig/basicide/ui/gotolinedialog \
 	basctl/uiconfig/basicide/ui/importlibdialog \
diff --git a/basctl/inc/bitmaps.hlst b/basctl/inc/bitmaps.hlst
index 3dd019785a67..997760aaf326 100644
--- a/basctl/inc/bitmaps.hlst
+++ b/basctl/inc/bitmaps.hlst
@@ -24,7 +24,6 @@
 #define RID_BMP_DLGLIB          "res/dialogfolder_16.png"
 #define RID_BMP_DLGLIBNOTLOADED "res/dialogfoldernot_16.png"
 #define RID_BMP_DIALOG          "res/im30823.png"
-#define RID_BMP_REMOVEWATCH     "res/baswatr.png"
 
 #endif
 
diff --git a/basctl/inc/pch/precompiled_basctl.hxx b/basctl/inc/pch/precompiled_basctl.hxx
index 6a8c8065274b..3601ccaf130f 100644
--- a/basctl/inc/pch/precompiled_basctl.hxx
+++ b/basctl/inc/pch/precompiled_basctl.hxx
@@ -13,7 +13,7 @@
  manual changes will be rewritten by the next run of update_pch.sh (which presumably
  also fixes all possible problems, so it's usually better to use it).
 
- Generated on 2020-02-16 15:31:09 using:
+ Generated on 2020-02-18 11:59:52 using:
  ./bin/update_pch basctl basctl --cutoff=3 --exclude:system --include:module --exclude:local
 
  If after updating build fails, use the following command to locate conflicting headers:
@@ -101,7 +101,6 @@
 #include <vcl/IDialogRenderable.hxx>
 #include <vcl/NotebookBarAddonsMerger.hxx>
 #include <vcl/Scanline.hxx>
-#include <vcl/accel.hxx>
 #include <vcl/alpha.hxx>
 #include <vcl/animate/Animation.hxx>
 #include <vcl/animate/AnimationBitmap.hxx>
@@ -137,12 +136,10 @@
 #include <vcl/menu.hxx>
 #include <vcl/metaactiontypes.hxx>
 #include <vcl/metric.hxx>
-#include <vcl/mnemonicengine.hxx>
 #include <vcl/outdev.hxx>
 #include <vcl/outdevmap.hxx>
 #include <vcl/outdevstate.hxx>
 #include <vcl/prntypes.hxx>
-#include <vcl/quickselectionengine.hxx>
 #include <vcl/region.hxx>
 #include <vcl/salgtype.hxx>
 #include <vcl/salnativewidgets.hxx>
@@ -156,8 +153,6 @@
 #include <vcl/textview.hxx>
 #include <vcl/timer.hxx>
 #include <vcl/transfer.hxx>
-#include <vcl/treelist.hxx>
-#include <vcl/treelistentries.hxx>
 #include <vcl/uitest/factory.hxx>
 #include <vcl/vclenum.hxx>
 #include <vcl/vclevent.hxx>
@@ -471,7 +466,6 @@
 #include <toolkit/dllapi.h>
 #include <toolkit/helper/vclunohelper.hxx>
 #include <tools/color.hxx>
-#include <tools/contnr.hxx>
 #include <tools/date.hxx>
 #include <tools/datetime.hxx>
 #include <tools/debug.hxx>
diff --git a/basctl/inc/strings.hrc b/basctl/inc/strings.hrc
index 6487c607694a..b31ddd20922d 100644
--- a/basctl/inc/strings.hrc
+++ b/basctl/inc/strings.hrc
@@ -61,9 +61,6 @@
 #define RID_STR_REPLACESTDLIB               NC_("RID_STR_REPLACESTDLIB", "The default library cannot be replaced.")
 #define RID_STR_REFNOTPOSSIBLE              NC_("RID_STR_REFNOTPOSSIBLE", "Reference to 'XX' not possible.")
 #define RID_STR_WATCHNAME                   NC_("RID_STR_WATCHNAME", "Watch")
-#define RID_STR_WATCHVARIABLE               NC_("RID_STR_WATCHVARIABLE", "Variable")
-#define RID_STR_WATCHVALUE                  NC_("RID_STR_WATCHVALUE", "Value")
-#define RID_STR_WATCHTYPE                   NC_("RID_STR_WATCHTYPE", "Type")
 #define RID_STR_STACKNAME                   NC_("RID_STR_STACKNAME", "Call Stack")
 #define RID_STR_STDDIALOGNAME               NC_("RID_STR_STDDIALOGNAME", "Dialog")
 #define RID_STR_NEWLIB                      NC_("RID_STR_NEWLIB", "New Library")
diff --git a/basctl/source/basicide/baside2.cxx b/basctl/source/basicide/baside2.cxx
index 476ade8dc40a..d07aa96dda2f 100644
--- a/basctl/source/basicide/baside2.cxx
+++ b/basctl/source/basicide/baside2.cxx
@@ -53,6 +53,7 @@
 #include <svl/visitem.hxx>
 #include <svl/whiter.hxx>
 #include <svx/svxids.hrc>
+#include <tools/debug.hxx>
 #include <vcl/waitobj.hxx>
 #include <vcl/errinf.hxx>
 #include <vcl/event.hxx>
diff --git a/basctl/source/basicide/baside2.hxx b/basctl/source/basicide/baside2.hxx
index 312b2765c105..03eebc402771 100644
--- a/basctl/source/basicide/baside2.hxx
+++ b/basctl/source/basicide/baside2.hxx
@@ -21,14 +21,9 @@
 
 #include <memory>
 #include <layout.hxx>
-#include "bastype3.hxx"
 #include "breakpoint.hxx"
 #include "linenumberwindow.hxx"
 
-#include <vcl/svtabbx.hxx>
-#include <vcl/headbar.hxx>
-
-#include <vcl/button.hxx>
 #include <basic/sbmod.hxx>
 #include <basic/sbstar.hxx>
 #include <vcl/lstbox.hxx>
@@ -157,7 +152,6 @@ public:
     bool            GetProcedureName(OUString const & rLine, OUString& rProcType, OUString& rProcName) const;
 };
 
-
 class BreakPointWindow final : public vcl::Window
 {
     ModulWindow&    rModulWindow;
@@ -191,45 +185,37 @@ public:
     BreakPointList& GetBreakPoints()        { return aBreakPointList; }
 };
 
-
-class WatchTreeListBox final : public SvHeaderTabListBox
-{
-    OUString aEditingRes;
-
-    virtual bool    EditingEntry( SvTreeListEntry* pEntry, Selection& rSel  ) override;
-    virtual bool    EditedEntry( SvTreeListEntry* pEntry, const OUString& rNewText ) override;
-
-    SbxBase*        ImplGetSBXForEntry( SvTreeListEntry* pEntry, bool& rbArrayElement );
-
-public:
-    WatchTreeListBox( vcl::Window* pParent, WinBits nWinBits );
-    virtual ~WatchTreeListBox() override;
-    virtual void    dispose() override;
-
-    void            RequestingChildren( SvTreeListEntry * pParent ) override;
-    void            UpdateWatches( bool bBasicStopped = false );
-
-    using           SvTabListBox::SetTabs;
-    virtual void    SetTabs() override;
-};
-
-
 class WatchWindow final : public DockingWindow
 {
-    OUString            aWatchStr;
-    VclPtr<ExtendedEdit>        aXEdit;
-    VclPtr<ImageButton>         aRemoveWatchButton;
-    VclPtr<WatchTreeListBox>    aTreeListBox;
-    VclPtr<HeaderBar>           aHeaderBar;
+private:
+    std::unique_ptr<weld::Builder> m_xBuilder;
+    VclPtr<vcl::Window> m_xVclContentArea;
+    std::unique_ptr<weld::Container> m_xContainer;
+    std::unique_ptr<weld::Container> m_xTitleArea;
+    std::unique_ptr<weld::Label> m_xTitle;
+    std::unique_ptr<weld::Entry> m_xEdit;
+    std::unique_ptr<weld::Button> m_xRemoveWatchButton;
+    std::unique_ptr<weld::TreeView> m_xTreeListBox;
+
+    ImplSVEvent* m_nUpdateWatchesId;
+    OUString aEditingRes;
 
     virtual void    Resize() override;
     virtual void    Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) override;
 
-    DECL_LINK( ButtonHdl, Button *, void );
-    DECL_LINK(TreeListHdl, SvTreeListBox*, void);
-    DECL_LINK( implEndDragHdl, HeaderBar *, void );
-    DECL_LINK( EditAccHdl, Accelerator&, void );
+    SbxBase* ImplGetSBXForEntry(const weld::TreeIter& rEntry, bool& rbArrayElement);
+
+    void implEnableChildren(weld::TreeIter& rEntry, bool bEnable);
 
+    DECL_STATIC_LINK(WatchWindow, ButtonHdl, weld::Button&, void);
+    DECL_LINK(TreeListHdl, weld::TreeView&, void);
+    DECL_LINK(RequestingChildrenHdl, const weld::TreeIter&, bool);
+    DECL_LINK(ActivateHdl, weld::Entry&, bool);
+    DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
+    DECL_LINK(EditingEntryHdl, const weld::TreeIter&, bool);
+    typedef std::pair<const weld::TreeIter&, OUString> IterString;
+    DECL_LINK(EditedEntryHdl, const IterString&, bool);
+    DECL_LINK(ExecuteUpdateWatches, void*, void);
 
 public:
     explicit WatchWindow (Layout* pParent);
@@ -238,10 +224,9 @@ public:
 
     void            AddWatch( const OUString& rVName );
     void            RemoveSelectedWatch();
-    void            UpdateWatches( bool bBasicStopped );
+    void            UpdateWatches(bool bBasicStopped = false);
 };
 
-
 class StackWindow : public DockingWindow
 {
 private:
diff --git a/basctl/source/basicide/baside2b.cxx b/basctl/source/basicide/baside2b.cxx
index 1d52ce1160b8..cf5b0aec42d0 100644
--- a/basctl/source/basicide/baside2b.cxx
+++ b/basctl/source/basicide/baside2b.cxx
@@ -42,6 +42,7 @@
 #include <sfx2/dispatch.hxx>
 #include <sfx2/progress.hxx>
 #include <sfx2/viewfrm.hxx>
+#include <tools/debug.hxx>
 #include <vcl/layout.hxx>
 #include <vcl/weld.hxx>
 #include <svl/urihelper.hxx>
@@ -55,7 +56,6 @@
 #include <vcl/event.hxx>
 #include <vcl/svapp.hxx>
 #include <svtools/textwindowpeer.hxx>
-#include <vcl/treelistentry.hxx>
 #include <vcl/taskpanelist.hxx>
 #include <vcl/help.hxx>
 #include <cppuhelper/implbase.hxx>
@@ -77,7 +77,6 @@ long const nBasePad = 2;
 long const nCursorPad = 5;
 
 long nVirtToolBoxHeight;    // inited in WatchWindow, used in Stackwindow
-static const long nHeaderBarHeight = 16;
 
 // Returns pBase converted to SbxVariable if valid and is not an SbxMethod.
 SbxVariable* IsSbxVariable (SbxBase* pBase)
@@ -1550,79 +1549,89 @@ void BreakPointWindow::dispose()
     Window::dispose();
 }
 
-namespace
+namespace {
+
+struct WatchItem
+{
+    OUString        maName;
+    OUString        maDisplayName;
+    SbxObjectRef    mpObject;
+    std::vector<OUString> maMemberList;
+
+    SbxDimArrayRef  mpArray;
+    int             nDimLevel;  // 0 = Root
+    int             nDimCount;
+    std::vector<sal_Int32> vIndices;
+
+    WatchItem*      mpArrayParentItem;
+
+    explicit WatchItem (OUString const& rName):
+        maName(rName),
+        nDimLevel(0),
+        nDimCount(0),
+        mpArrayParentItem(nullptr)
+    { }
+
+    void clearWatchItem ()
+    {
+        maMemberList.clear();
+    }
+
+    WatchItem* GetRootItem();
+    SbxDimArray* GetRootArray();
+};
+
+}
+
+WatchWindow::WatchWindow(Layout* pParent)
+    : DockingWindow(pParent, "DockingWindow", "sfx/ui/dockingwindow.ui")
+    , m_nUpdateWatchesId(nullptr)
 {
-    const sal_uInt16 ITEM_ID_VARIABLE = 1;
-    const sal_uInt16 ITEM_ID_VALUE = 2;
-    const sal_uInt16 ITEM_ID_TYPE = 3;
-}
-
-WatchWindow::WatchWindow (Layout* pParent)
-    : DockingWindow(pParent)
-    , aWatchStr(IDEResId( RID_STR_REMOVEWATCH))
-    , aXEdit(VclPtr<ExtendedEdit>::Create(this, WB_BORDER | WB_3DLOOK))
-    , aRemoveWatchButton(VclPtr<ImageButton>::Create(this, WB_SMALLSTYLE))
-    , aTreeListBox(VclPtr<WatchTreeListBox>::Create(this, WB_BORDER | WB_3DLOOK | WB_HASBUTTONS |
-                                                          WB_HASLINES | WB_HSCROLL | WB_TABSTOP |
-                                                          WB_HASLINESATROOT | WB_HASBUTTONSATROOT))
-    , aHeaderBar(VclPtr<HeaderBar>::Create(this, WB_BUTTONSTYLE | WB_BORDER))
-{
-    aXEdit->SetAccessibleName(IDEResId(RID_STR_WATCHNAME));
-    aXEdit->SetHelpId(HID_BASICIDE_WATCHWINDOW_EDIT);
-    aXEdit->SetSizePixel(aXEdit->LogicToPixel(Size(80, 12), MapMode(MapUnit::MapAppFont)));
-    aTreeListBox->SetAccessibleName(IDEResId(RID_STR_WATCHNAME));
-
-    long nTextLen = GetTextWidth( aWatchStr ) + DWBORDER + 3;
-    aXEdit->SetPosPixel( Point( nTextLen, 3 ) );
-    aXEdit->SetAccHdl( LINK( this, WatchWindow, EditAccHdl ) );
-    aXEdit->GetAccelerator().InsertItem( 1, vcl::KeyCode( KEY_RETURN ) );
-    aXEdit->GetAccelerator().InsertItem( 2, vcl::KeyCode( KEY_ESCAPE ) );
-    aXEdit->Show();
-
-    aRemoveWatchButton->Disable();
-    aRemoveWatchButton->SetClickHdl( LINK( this, WatchWindow, ButtonHdl ) );
-    aRemoveWatchButton->SetPosPixel( Point( nTextLen + aXEdit->GetSizePixel().Width() + 4, 2 ) );
-    aRemoveWatchButton->SetHelpId(HID_BASICIDE_REMOVEWATCH);
-    aRemoveWatchButton->SetModeImage(Image(StockImage::Yes, RID_BMP_REMOVEWATCH));
-    aRemoveWatchButton->SetQuickHelpText(IDEResId(RID_STR_REMOVEWATCHTIP));
-    Size aSz( aRemoveWatchButton->GetModeImage().GetSizePixel() );
-    aSz.AdjustWidth(6 );
-    aSz.AdjustHeight(6 );
-    aRemoveWatchButton->SetSizePixel( aSz );
-    aRemoveWatchButton->Show();
-
-    long nRWBtnSize = aRemoveWatchButton->GetModeImage().GetSizePixel().Height() + 10;
-    nVirtToolBoxHeight = aXEdit->GetSizePixel().Height() + 7;
-
-    if ( nRWBtnSize > nVirtToolBoxHeight )
-        nVirtToolBoxHeight = nRWBtnSize;
-
-    aTreeListBox->SetHelpId(HID_BASICIDE_WATCHWINDOW_LIST);
-    aTreeListBox->EnableInplaceEditing(true);
-    aTreeListBox->SetSelectHdl( LINK( this, WatchWindow, TreeListHdl ) );
-    aTreeListBox->SetPosPixel( Point( DWBORDER, nVirtToolBoxHeight + nHeaderBarHeight ) );
-    aTreeListBox->SetHighlightRange( 1, 5 );
-
-    Point aPnt( DWBORDER, nVirtToolBoxHeight + 1 );
-    aHeaderBar->SetPosPixel( aPnt );
-    aHeaderBar->SetEndDragHdl( LINK( this, WatchWindow, implEndDragHdl ) );
-
-    long nVarTabWidth = 220;
-    long nValueTabWidth = 100;
-    long const nTypeTabWidth = 1250;
-    aHeaderBar->InsertItem( ITEM_ID_VARIABLE, IDEResId(RID_STR_WATCHVARIABLE), nVarTabWidth );
-    aHeaderBar->InsertItem( ITEM_ID_VALUE, IDEResId(RID_STR_WATCHVALUE), nValueTabWidth );
-    aHeaderBar->InsertItem( ITEM_ID_TYPE, IDEResId(RID_STR_WATCHTYPE), nTypeTabWidth );
-
-    long aTabPositions[] = { 0, nVarTabWidth, nVarTabWidth + nValueTabWidth };
-    aTreeListBox->SvHeaderTabListBox::SetTabs( SAL_N_ELEMENTS(aTabPositions), aTabPositions, MapUnit::MapPixel );
-    aTreeListBox->InitHeaderBar( aHeaderBar.get() );
-
-    aTreeListBox->SetNodeDefaultImages( );
-
-    aHeaderBar->Show();
-
-    aTreeListBox->Show();
+    m_xVclContentArea = VclPtr<VclVBox>::Create(this);
+    m_xVclContentArea->Show();
+    m_xBuilder.reset(Application::CreateInterimBuilder(m_xVclContentArea,
+                                                       "modules/BasicIDE/ui/dockingwatch.ui"));
+    m_xContainer = m_xBuilder->weld_container("DockingWatch");
+
+    m_xTitleArea = m_xBuilder->weld_container("titlearea");
+
+    nVirtToolBoxHeight = m_xTitleArea->get_preferred_size().Height();
+
+    m_xTitle = m_xBuilder->weld_label("title");
+    m_xTitle->set_label(IDEResId(RID_STR_REMOVEWATCH));
+
+    m_xEdit = m_xBuilder->weld_entry("edit");
+    m_xRemoveWatchButton = m_xBuilder->weld_button("remove");
+    m_xTreeListBox = m_xBuilder->weld_tree_view("treeview");
+
+    m_xEdit->set_accessible_name(IDEResId(RID_STR_WATCHNAME));
+    m_xEdit->set_help_id(HID_BASICIDE_WATCHWINDOW_EDIT);
+    m_xEdit->set_size_request(LogicToPixel(Size(80, 0), MapMode(MapUnit::MapAppFont)).Width(), -1);
+    m_xEdit->connect_activate(LINK( this, WatchWindow, ActivateHdl));
+    m_xEdit->connect_key_press(LINK( this, WatchWindow, KeyInputHdl));
+    m_xTreeListBox->set_accessible_name(IDEResId(RID_STR_WATCHNAME));
+
+    m_xRemoveWatchButton->set_sensitive(false);
+    m_xRemoveWatchButton->connect_clicked(LINK( this, WatchWindow, ButtonHdl));
+    m_xRemoveWatchButton->set_help_id(HID_BASICIDE_REMOVEWATCH);
+    m_xRemoveWatchButton->set_tooltip_text(IDEResId(RID_STR_REMOVEWATCHTIP));
+
+    m_xTreeListBox->set_help_id(HID_BASICIDE_WATCHWINDOW_LIST);
+    m_xTreeListBox->connect_editing(LINK(this, WatchWindow, EditingEntryHdl),
+                                    LINK(this, WatchWindow, EditedEntryHdl));
+    m_xTreeListBox->connect_changed( LINK( this, WatchWindow, TreeListHdl ) );
+    m_xTreeListBox->connect_expanding(LINK(this, WatchWindow, RequestingChildrenHdl));
+
+    std::vector<int> aWidths;
+    std::vector<bool> aEditables;
+    aWidths.push_back(220);  // VarTabWidth
+    aEditables.push_back(false);
+    aWidths.push_back(100);  // ValueTabWidth
+    aEditables.push_back(true);
+    aWidths.push_back(1250); // TypeTabWidth
+    aEditables.push_back(false);
+    m_xTreeListBox->set_column_fixed_widths(aWidths);
+    m_xTreeListBox->set_column_editables(aEditables);
 
     SetText(IDEResId(RID_STR_WATCHNAME));
 
@@ -1632,7 +1641,6 @@ WatchWindow::WatchWindow (Layout* pParent)
     GetSystemWindow()->GetTaskPaneList()->AddWindow( this );
 }
 
-
 WatchWindow::~WatchWindow()
 {
     disposeOnce();
@@ -1640,10 +1648,27 @@ WatchWindow::~WatchWindow()
 
 void WatchWindow::dispose()
 {
-    aXEdit.disposeAndClear();
-    aRemoveWatchButton.disposeAndClear();
-    aHeaderBar.disposeAndClear();
-    aTreeListBox.disposeAndClear();
+    if (m_nUpdateWatchesId)
+    {
+        Application::RemoveUserEvent(m_nUpdateWatchesId);
+        m_nUpdateWatchesId = nullptr;
+    }
+
+    // Destroy user data
+    m_xTreeListBox->all_foreach([this](weld::TreeIter& rEntry){
+        WatchItem* pItem = reinterpret_cast<WatchItem*>(m_xTreeListBox->get_id(rEntry).toInt64());
+        delete pItem;
+        return false;
+    });
+
+    m_xTitle.reset();
+    m_xEdit.reset();
+    m_xRemoveWatchButton.reset();
+    m_xTitleArea.reset();
+    m_xTreeListBox.reset();
+    m_xContainer.reset();
+    m_xBuilder.reset();
+    m_xVclContentArea.disposeAndClear();
     if (!IsDisposed())
         GetSystemWindow()->GetTaskPaneList()->RemoveWindow( this );
     DockingWindow::dispose();
@@ -1651,64 +1676,24 @@ void WatchWindow::dispose()
 
 void WatchWindow::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
 {
-    rRenderContext.DrawText(Point(DWBORDER, 7), aWatchStr);
     lcl_DrawIDEWindowFrame(this, rRenderContext);
 }
 
 void WatchWindow::Resize()
 {
     Size aSz = GetOutputSizePixel();
-    Size aBoxSz( aSz.Width() - 2*DWBORDER, aSz.Height() - nVirtToolBoxHeight - DWBORDER );
+    Size aBoxSz(aSz.Width() - 2*DWBORDER, aSz.Height() - 2*DWBORDER);
 
     if ( aBoxSz.Width() < 4 )
         aBoxSz.setWidth( 0 );
     if ( aBoxSz.Height() < 4 )
         aBoxSz.setHeight( 0 );
 
-    aBoxSz.AdjustHeight( -nHeaderBarHeight );
-    aTreeListBox->SetSizePixel( aBoxSz );
-    aTreeListBox->GetHScroll()->SetPageSize( aTreeListBox->GetHScroll()->GetVisibleSize() );
-
-    aBoxSz.setHeight( nHeaderBarHeight );
-    aHeaderBar->SetSizePixel( aBoxSz );
+    m_xVclContentArea->SetPosSizePixel(Point(DWBORDER, DWBORDER), aBoxSz);
 
     Invalidate();
 }
 
-namespace {
-
-struct WatchItem
-{
-    OUString        maName;
-    OUString        maDisplayName;
-    SbxObjectRef    mpObject;
-    std::vector<OUString> maMemberList;
-
-    SbxDimArrayRef  mpArray;
-    int             nDimLevel;  // 0 = Root
-    int             nDimCount;
-    std::vector<sal_Int32> vIndices;
-
-    WatchItem*      mpArrayParentItem;
-
-    explicit WatchItem (OUString const& rName):
-        maName(rName),
-        nDimLevel(0),
-        nDimCount(0),
-        mpArrayParentItem(nullptr)
-    { }
-
-    void clearWatchItem ()
-    {
-        maMemberList.clear();
-    }
-
-    WatchItem* GetRootItem();
-    SbxDimArray* GetRootArray();
-};
-
-}
-
 WatchItem* WatchItem::GetRootItem()
 {
     WatchItem* pItem = mpArrayParentItem;
@@ -1736,103 +1721,78 @@ void WatchWindow::AddWatch( const OUString& rVName )
     lcl_SeparateNameAndIndex( rVName, aVar, aIndex );
     WatchItem* pWatchItem = new WatchItem(aVar);
 
-    OUString aWatchStr_ = aVar + "\t\t";
-    SvTreeListEntry* pNewEntry = aTreeListBox->InsertEntry( aWatchStr_, nullptr, true );
-    pNewEntry->SetUserData( pWatchItem );
+    OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pWatchItem)));
+    std::unique_ptr<weld::TreeIter> xRet = m_xTreeListBox->make_iterator();
+    m_xTreeListBox->insert(nullptr, -1, &aVar, &sId, nullptr, nullptr, nullptr, false, xRet.get());
+    m_xTreeListBox->set_text(*xRet, "", 1);
+    m_xTreeListBox->set_text(*xRet, "", 2);
 
-    aTreeListBox->Select(pNewEntry);
-    aTreeListBox->MakeVisible(pNewEntry);
-    aRemoveWatchButton->Enable();
+    m_xTreeListBox->set_cursor(*xRet);
+    m_xTreeListBox->select(*xRet);
+    m_xTreeListBox->scroll_to_row(*xRet);
+    m_xRemoveWatchButton->set_sensitive(true);
 
     UpdateWatches(false);
 }
 
 void WatchWindow::RemoveSelectedWatch()
 {
-    SvTreeListEntry* pEntry = aTreeListBox->GetCurEntry();
-    if ( pEntry )
+    std::unique_ptr<weld::TreeIter> xEntry = m_xTreeListBox->make_iterator();
+    bool bEntry = m_xTreeListBox->get_cursor(xEntry.get());
+    if (bEntry)
     {
-        aTreeListBox->GetModel()->Remove( pEntry );
-        pEntry = aTreeListBox->GetCurEntry();
-        if ( pEntry )
-            aXEdit->SetText( static_cast<WatchItem*>(pEntry->GetUserData())->maName );
+        m_xTreeListBox->remove(*xEntry);
+        bEntry = m_xTreeListBox->get_cursor(xEntry.get());
+        if (bEntry)
+            m_xEdit->set_text(reinterpret_cast<WatchItem*>(m_xTreeListBox->get_id(*xEntry).toInt64())->maName);
         else
-            aXEdit->SetText( OUString() );
-        if ( !aTreeListBox->GetEntryCount() )
-            aRemoveWatchButton->Disable();
+            m_xEdit->set_text(OUString());
+        if ( !m_xTreeListBox->n_children() )
+            m_xRemoveWatchButton->set_sensitive(false);
     }
 }
 
-
-IMPL_LINK( WatchWindow, ButtonHdl, Button *, pButton, void )
+IMPL_STATIC_LINK_NOARG(WatchWindow, ButtonHdl, weld::Button&, void)
 {
-    if (pButton == aRemoveWatchButton.get())
-        if (SfxDispatcher* pDispatcher = GetDispatcher())
-            pDispatcher->Execute(SID_BASICIDE_REMOVEWATCH);
+    if (SfxDispatcher* pDispatcher = GetDispatcher())
+        pDispatcher->Execute(SID_BASICIDE_REMOVEWATCH);
 }
 
-IMPL_LINK_NOARG(WatchWindow, TreeListHdl, SvTreeListBox*, void)
+IMPL_LINK_NOARG(WatchWindow, TreeListHdl, weld::TreeView&, void)
 {
-    SvTreeListEntry* pCurEntry = aTreeListBox->GetCurEntry();
-    if ( pCurEntry && pCurEntry->GetUserData() )
-        aXEdit->SetText( static_cast<WatchItem*>(pCurEntry->GetUserData())->maName );
+    std::unique_ptr<weld::TreeIter> xCurEntry = m_xTreeListBox->make_iterator();
+    bool bCurEntry = m_xTreeListBox->get_cursor(xCurEntry.get());
+    if (!bCurEntry)
+        return;
+    WatchItem* pItem = reinterpret_cast<WatchItem*>(m_xTreeListBox->get_id(*xCurEntry).toInt64());
+    if (!pItem)
+        return;
+    m_xEdit->set_text(pItem->maName);
 }
 
-IMPL_LINK_NOARG( WatchWindow, implEndDragHdl, HeaderBar *, void )
+IMPL_LINK_NOARG(WatchWindow, ActivateHdl, weld::Entry&, bool)
 {
-    const sal_Int32 TAB_WIDTH_MIN = 10;
-    sal_Int32 nMaxWidth =
-        aHeaderBar->GetSizePixel().getWidth() - 2 * TAB_WIDTH_MIN;
-
-    sal_Int32 nVariableWith = aHeaderBar->GetItemSize( ITEM_ID_VARIABLE );
-    if( nVariableWith < TAB_WIDTH_MIN )
-        aHeaderBar->SetItemSize( ITEM_ID_VARIABLE, TAB_WIDTH_MIN );
-    else if( nVariableWith > nMaxWidth )
-        aHeaderBar->SetItemSize( ITEM_ID_VARIABLE, nMaxWidth );
-
-    sal_Int32 nValueWith = aHeaderBar->GetItemSize( ITEM_ID_VALUE );
-    if( nValueWith < TAB_WIDTH_MIN )
-        aHeaderBar->SetItemSize( ITEM_ID_VALUE, TAB_WIDTH_MIN );
-    else if( nValueWith > nMaxWidth )
-        aHeaderBar->SetItemSize( ITEM_ID_VALUE, nMaxWidth );
-
-    if (aHeaderBar->GetItemSize( ITEM_ID_TYPE ) < TAB_WIDTH_MIN)
-        aHeaderBar->SetItemSize( ITEM_ID_TYPE, TAB_WIDTH_MIN );
-
-    sal_Int32 nPos = 0;
-    sal_uInt16 nTabs = aHeaderBar->GetItemCount();
-    for( sal_uInt16 i = 1 ; i < nTabs ; ++i )
+    OUString aCurText(m_xEdit->get_text());
+    if (!aCurText.isEmpty())
     {
-        nPos += aHeaderBar->GetItemSize( i );
-        aTreeListBox->SetTab( i, nPos, MapUnit::MapPixel );
+        AddWatch(aCurText);
+        m_xEdit->select_region(0, -1);
     }
+    return true;
 }
 
-IMPL_LINK( WatchWindow, EditAccHdl, Accelerator&, rAcc, void )
+IMPL_LINK(WatchWindow, KeyInputHdl, const KeyEvent&, rKEvt, bool)
 {
-    switch ( rAcc.GetCurKeyCode().GetCode() )
+    bool bHandled = false;
+
+    sal_uInt16 nKeyCode = rKEvt.GetKeyCode().GetCode();
+    if (nKeyCode == KEY_ESCAPE)
     {
-        case KEY_RETURN:
-        {
-            OUString aCurText( aXEdit->GetText() );
-            if ( !aCurText.isEmpty() )
-            {
-                AddWatch( aCurText );
-                aXEdit->SetSelection( Selection( 0, 0xFFFF ) );
-            }
-        }
-        break;
-        case KEY_ESCAPE:
-        {
-            aXEdit->SetText( OUString() );
-        }
-        break;
+        m_xEdit->set_text(OUString());
+        bHandled = true;
     }
-}
 
-void WatchWindow::UpdateWatches( bool bBasicStopped )
-{
-    aTreeListBox->UpdateWatches( bBasicStopped );
+    return bHandled;
 }
 
 // StackWindow
@@ -1847,6 +1807,9 @@ StackWindow::StackWindow(Layout* pParent)
 
     m_xTitle = m_xBuilder->weld_label("title");
     m_xTitle->set_label(IDEResId(RID_STR_STACK));
+
+    m_xTitle->set_size_request(-1, nVirtToolBoxHeight); // so the two title areas are the same height
+
     m_xTreeListBox = m_xBuilder->weld_tree_view("stack");
 
     m_xTreeListBox->set_help_id(HID_BASICIDE_STACKWINDOW_LIST);
@@ -2088,46 +2051,6 @@ EditorWindow::GetComponentInterface(bool bCreate)
     return xPeer;
 }
 
-
-// WatchTreeListBox
-
-
-WatchTreeListBox::WatchTreeListBox( vcl::Window* pParent, WinBits nWinBits )
-    : SvHeaderTabListBox( pParent, nWinBits )
-{}
-
-WatchTreeListBox::~WatchTreeListBox()
-{
-    disposeOnce();
-}
-
-void WatchTreeListBox::dispose()
-{
-    // Destroy user data
-    SvTreeListEntry* pEntry = First();
-    while ( pEntry )
-    {
-        delete static_cast<WatchItem*>(pEntry->GetUserData());
-        pEntry->SetUserData(nullptr);
-        pEntry = Next( pEntry );
-    }
-    SvHeaderTabListBox::dispose();
-}
-
-void WatchTreeListBox::SetTabs()
-{
-    SvHeaderTabListBox::SetTabs();
-    sal_uInt16 nTabCount_ = aTabs.size();
-    for( sal_uInt16 i = 0 ; i < nTabCount_ ; i++ )
-    {
-        SvLBoxTab* pTab = aTabs[i].get();
-        if( i == 2 )
-            pTab->nFlags |= SvLBoxTabFlags::EDITABLE;
-        else
-            pTab->nFlags &= ~SvLBoxTabFlags::EDITABLE;
-    }
-}
-
 static sal_uInt32 getCorrectedPropCount(SbxArray* p)
 {
     sal_uInt32 nPropCount = p->Count32();
@@ -2141,16 +2064,16 @@ static sal_uInt32 getCorrectedPropCount(SbxArray* p)
     return nPropCount;
 }
 
-void WatchTreeListBox::RequestingChildren( SvTreeListEntry * pParent )
+IMPL_LINK(WatchWindow, RequestingChildrenHdl, const weld::TreeIter&, rParent, bool)
 {
     if( !StarBASIC::IsRunning() )
-        return;
+        return true;
 
-    if( GetChildCount( pParent ) > 0 )
-        return;
+    if (m_xTreeListBox->iter_has_child(rParent))
+        return true;
 
-    SvTreeListEntry* pEntry = pParent;
-    WatchItem* pItem = static_cast<WatchItem*>(pEntry->GetUserData());
+    WatchItem* pItem = reinterpret_cast<WatchItem*>(m_xTreeListBox->get_id(rParent).toInt64());
+    std::unique_ptr<weld::TreeIter> xRet = m_xTreeListBox->make_iterator();
 
     SbxDimArray* pArray = pItem->mpArray.get();
     SbxDimArray* pRootArray = pItem->GetRootArray();
@@ -2175,12 +2098,18 @@ void WatchTreeListBox::RequestingChildren( SvTreeListEntry * pParent )
 
             pItem->maMemberList.push_back(pVar->GetName());
             OUString const& rName = pItem->maMemberList.back();
-            SvTreeListEntry* pChildEntry = SvTreeListBox::InsertEntry( rName, pEntry );
-            pChildEntry->SetUserData(new WatchItem(rName));
+
+            WatchItem* pWatchItem = new WatchItem(rName);
+            OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pWatchItem)));
+
+            m_xTreeListBox->insert(&rParent, -1, &rName, &sId, nullptr, nullptr, nullptr, false, xRet.get());
+            m_xTreeListBox->set_text(*xRet, "", 1);
+            m_xTreeListBox->set_text(*xRet, "", 2);
         }
-        if( nPropCount > 0 )
+
+        if (nPropCount > 0 && !m_nUpdateWatchesId)
         {
-            UpdateWatches();
+            m_nUpdateWatchesId = Application::PostUserEvent(LINK(this, WatchWindow, ExecuteUpdateWatches));
         }
     }
     else if( pArray )
@@ -2221,27 +2150,40 @@ void WatchTreeListBox::RequestingChildren( SvTreeListEntry * pParent )
             aDisplayName += aIndexStr;
             pChildItem->maDisplayName = aDisplayName;
 
-            SvTreeListEntry* pChildEntry = SvTreeListBox::InsertEntry( aDisplayName, pEntry );
+            OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pChildItem)));
+
+            m_xTreeListBox->insert(&rParent, -1, &aDisplayName, &sId, nullptr, nullptr, nullptr, false, xRet.get());
+            m_xTreeListBox->set_text(*xRet, "", 1);
+            m_xTreeListBox->set_text(*xRet, "", 2);
+
             nElementCount++;
-            pChildEntry->SetUserData( pChildItem );
         }
-        if( nElementCount > 0 )
+        if (nElementCount > 0 && !m_nUpdateWatchesId)
         {
-            UpdateWatches();
+            m_nUpdateWatchesId = Application::PostUserEvent(LINK(this, WatchWindow, ExecuteUpdateWatches));
         }
     }
+
+    return true;
+}
+
+IMPL_LINK_NOARG(WatchWindow, ExecuteUpdateWatches, void*, void)
+{
+    m_nUpdateWatchesId = nullptr;
+    UpdateWatches();
 }
 
-SbxBase* WatchTreeListBox::ImplGetSBXForEntry( SvTreeListEntry* pEntry, bool& rbArrayElement )
+SbxBase* WatchWindow::ImplGetSBXForEntry(const weld::TreeIter& rEntry, bool& rbArrayElement)
 {
     SbxBase* pSBX = nullptr;
     rbArrayElement = false;
 
-    WatchItem* pItem = static_cast<WatchItem*>(pEntry->GetUserData());
+    WatchItem* pItem = reinterpret_cast<WatchItem*>(m_xTreeListBox->get_id(rEntry).toInt64());
     OUString aVName( pItem->maName );
 
-    SvTreeListEntry* pParentEntry = GetParent( pEntry );
-    WatchItem* pParentItem = pParentEntry ? static_cast<WatchItem*>(pParentEntry->GetUserData()) : nullptr;
+    std::unique_ptr<weld::TreeIter> xParentEntry = m_xTreeListBox->make_iterator(&rEntry);
+    bool bParentEntry = m_xTreeListBox->iter_parent(*xParentEntry);
+    WatchItem* pParentItem = bParentEntry ? reinterpret_cast<WatchItem*>(m_xTreeListBox->get_id(*xParentEntry).toInt64()) : nullptr;
     if( pParentItem )
     {
         SbxObject* pObj = pParentItem->mpObject.get();
@@ -2272,22 +2214,22 @@ SbxBase* WatchTreeListBox::ImplGetSBXForEntry( SvTreeListEntry* pEntry, bool& rb
     return pSBX;
 }
 
-bool WatchTreeListBox::EditingEntry( SvTreeListEntry* pEntry, Selection& )
+IMPL_LINK(WatchWindow, EditingEntryHdl, const weld::TreeIter&, rIter, bool)
 {
-    WatchItem* pItem = static_cast<WatchItem*>(pEntry->GetUserData());
+    WatchItem* pItem = reinterpret_cast<WatchItem*>(m_xTreeListBox->get_id(rIter).toInt64());
 
     bool bEdit = false;
-    if ( StarBASIC::IsRunning() && StarBASIC::GetActiveMethod() && !SbxBase::IsError() )
+    if (StarBASIC::IsRunning() && StarBASIC::GetActiveMethod() && !SbxBase::IsError())
     {
         // No out of scope entries
         bool bArrayElement;
-        SbxBase* pSbx = ImplGetSBXForEntry( pEntry, bArrayElement );
+        SbxBase* pSbx = ImplGetSBXForEntry(rIter, bArrayElement);
         if (IsSbxVariable(pSbx) || bArrayElement)
         {
             // Accept no objects and only end nodes of arrays for editing
             if( !pItem->mpObject.is() && ( !pItem->mpArray.is() || pItem->nDimLevel == pItem->nDimCount ) )
             {
-                aEditingRes = SvHeaderTabListBox::GetEntryText( pEntry, ITEM_ID_VALUE-1 );
+                aEditingRes = m_xTreeListBox->get_text(rIter, 1);
                 aEditingRes = comphelper::string::strip(aEditingRes, ' ');
                 bEdit = true;
             }
@@ -2297,9 +2239,10 @@ bool WatchTreeListBox::EditingEntry( SvTreeListEntry* pEntry, Selection& )
     return bEdit;
 }
 
-bool WatchTreeListBox::EditedEntry( SvTreeListEntry* pEntry, const OUString& rNewText )
+IMPL_LINK(WatchWindow, EditedEntryHdl, const IterString&, rIterString, bool)
 {
-    OUString aResult = comphelper::string::strip(rNewText, ' ');
+    const weld::TreeIter& rIter = rIterString.first;
+    OUString aResult = comphelper::string::strip(rIterString.second, ' ');
 
     sal_uInt16 nResultLen = aResult.getLength();
     sal_Unicode cFirst = aResult[0];
@@ -2311,7 +2254,7 @@ bool WatchTreeListBox::EditedEntry( SvTreeListEntry* pEntry, const OUString& rNe
         return false;
 
     bool bArrayElement;
-    SbxBase* pSBX = ImplGetSBXForEntry( pEntry, bArrayElement );
+    SbxBase* pSBX = ImplGetSBXForEntry(rIter, bArrayElement);
 
     if (SbxVariable* pVar = IsSbxVariable(pSBX))
     {
@@ -2337,22 +2280,23 @@ bool WatchTreeListBox::EditedEntry( SvTreeListEntry* pEntry, const OUString& rNe
     return false;
 }
 
-
 namespace
 {
 
-void implCollapseModifiedObjectEntry( SvTreeListEntry* pParent, WatchTreeListBox* pThis )
+void implCollapseModifiedObjectEntry(weld::TreeIter& rParent, weld::TreeView& rTree)
 {
-    pThis->Collapse( pParent );
+    rTree.collapse_row(rParent);
+
+    std::unique_ptr<weld::TreeIter> xDeleteEntry = rTree.make_iterator(&rParent);
 
-    SvTreeList* pModel = pThis->GetModel();
-    SvTreeListEntry* pDeleteEntry;
-    while( (pDeleteEntry = pThis->SvTreeListBox::GetEntry( pParent, 0 )) != nullptr )
+    while (rTree.iter_children(*xDeleteEntry))
     {
-        implCollapseModifiedObjectEntry( pDeleteEntry, pThis );
+        implCollapseModifiedObjectEntry(*xDeleteEntry, rTree);
 
-        delete static_cast<WatchItem*>(pDeleteEntry->GetUserData());
-        pModel->Remove( pDeleteEntry );
+        WatchItem* pItem = reinterpret_cast<WatchItem*>(rTree.get_id(*xDeleteEntry).toInt64());
+        delete pItem;
+        rTree.remove(*xDeleteEntry);
+        rTree.copy_iterator(rParent, *xDeleteEntry);
     }
 }
 
@@ -2384,40 +2328,41 @@ OUString implCreateTypeStringForDimArray( WatchItem* pItem, SbxDataType eType )
     return aRetStr;
 }
 
-void implEnableChildren( SvTreeListEntry* pEntry, bool bEnable )
+} // namespace
+
+void WatchWindow::implEnableChildren(weld::TreeIter& rEntry, bool bEnable)
 {
-    if( bEnable )
+    if (bEnable)
     {
-        pEntry->SetFlags(
-            (pEntry->GetFlags() & ~SvTLEntryFlags(SvTLEntryFlags::NO_NODEBMP | SvTLEntryFlags::HAD_CHILDREN))
-            | SvTLEntryFlags::CHILDREN_ON_DEMAND );
+        if (!m_xTreeListBox->get_row_expanded(rEntry))
+            m_xTreeListBox->set_children_on_demand(rEntry, true);
     }
     else
     {
-        pEntry->SetFlags( pEntry->GetFlags() & ~SvTLEntryFlags::CHILDREN_ON_DEMAND );
+        assert(!m_xTreeListBox->get_row_expanded(rEntry));
+        m_xTreeListBox->set_children_on_demand(rEntry, false);
     }
 }
 
-} // namespace
-
-void WatchTreeListBox::UpdateWatches( bool bBasicStopped )
+void WatchWindow::UpdateWatches(bool bBasicStopped)
 {
     SbMethod* pCurMethod = StarBASIC::GetActiveMethod();
 
     ErrCode eOld = SbxBase::GetError();
     setBasicWatchMode( true );
 
-    SvTreeListEntry* pEntry = First();
-    while ( pEntry )
-    {
-        WatchItem* pItem = static_cast<WatchItem*>(pEntry->GetUserData());
+    m_xTreeListBox->all_foreach([this, pCurMethod, bBasicStopped](weld::TreeIter& rEntry){
+        WatchItem* pItem = reinterpret_cast<WatchItem*>(m_xTreeListBox->get_id(rEntry).toInt64());
         DBG_ASSERT( !pItem->maName.isEmpty(), "Var? - Must not be empty!" );
         OUString aWatchStr;
         OUString aTypeStr;
         if ( pCurMethod )
         {
+            bool bCollapse = false;
+            TriState eEnableChildren = TRISTATE_INDET;
+
             bool bArrayElement;
-            SbxBase* pSBX = ImplGetSBXForEntry( pEntry, bArrayElement );
+            SbxBase* pSBX = ImplGetSBXForEntry(rEntry, bArrayElement);
 
             // Array? If no end node create type string
             if( bArrayElement && pItem->nDimLevel < pItem->nDimCount )
@@ -2425,10 +2370,9 @@ void WatchTreeListBox::UpdateWatches( bool bBasicStopped )
                 SbxDimArray* pRootArray = pItem->GetRootArray();
                 SbxDataType eType = pRootArray->GetType();
                 aTypeStr = implCreateTypeStringForDimArray( pItem, eType );
-                implEnableChildren( pEntry, true );
+                eEnableChildren = TRISTATE_TRUE;
             }
 
-            bool bCollapse = false;
             if (SbxVariable const* pVar = IsSbxVariable(pSBX))
             {
                 // extra treatment of arrays
@@ -2472,12 +2416,12 @@ void WatchTreeListBox::UpdateWatches( bool bBasicStopped )
                         {
                             bArrayChanged = true;
                         }
-                        implEnableChildren(pEntry, true);
+                        eEnableChildren = TRISTATE_TRUE;
                         // #i37227 Clear always and replace array
                         if( pNewArray != pOldArray )
                         {
                             pItem->clearWatchItem();
-                            implEnableChildren(pEntry, true);
+                            eEnableChildren = TRISTATE_TRUE;
 
                             pItem->mpArray = pNewArray;
                             sal_Int32 nDims = pNewArray->GetDims32();
@@ -2515,7 +2459,7 @@ void WatchTreeListBox::UpdateWatches( bool bBasicStopped )
                         }
 
                         pItem->mpObject = pObj;
-                        implEnableChildren( pEntry, true );
+                        eEnableChildren = TRISTATE_TRUE;
                         aTypeStr = getBasicObjectTypeName( pObj );
                     }
                     else
@@ -2524,7 +2468,7 @@ void WatchTreeListBox::UpdateWatches( bool bBasicStopped )
                         if( pItem->mpObject.is() )
                         {
                             bCollapse = true;
-                            implEnableChildren( pEntry, false );
+                            eEnableChildren = TRISTATE_FALSE;
                         }
                     }
                 }
@@ -2533,7 +2477,7 @@ void WatchTreeListBox::UpdateWatches( bool bBasicStopped )
                     if( pItem->mpObject.is() )
                     {
                         bCollapse = true;
-                        implEnableChildren( pEntry, false );
+                        eEnableChildren = TRISTATE_FALSE;
                     }
 
                     bool bString = (static_cast<sal_uInt8>(eType) == sal_uInt8(SbxSTRING));
@@ -2564,30 +2508,29 @@ void WatchTreeListBox::UpdateWatches( bool bBasicStopped )
 
             if( bCollapse )
             {
-                implCollapseModifiedObjectEntry( pEntry, this );
+                implCollapseModifiedObjectEntry(rEntry, *m_xTreeListBox);
                 pItem->clearWatchItem();
             }
 
+            if (eEnableChildren != TRISTATE_INDET)
+                implEnableChildren(rEntry, eEnableChildren == TRISTATE_TRUE);
         }
         else if( bBasicStopped )
         {
             if( pItem->mpObject.is() || pItem->mpArray.is() )
             {
-                implCollapseModifiedObjectEntry( pEntry, this );
+                implCollapseModifiedObjectEntry(rEntry, *m_xTreeListBox);
                 pItem->mpObject.clear();
                 pItem->mpArray.clear();
             }
             pItem->clearWatchItem();
         }
 
-        SvHeaderTabListBox::SetEntryText( aWatchStr, pEntry, ITEM_ID_VALUE-1 );
-        SvHeaderTabListBox::SetEntryText( aTypeStr, pEntry, ITEM_ID_TYPE-1 );
+        m_xTreeListBox->set_text(rEntry, aWatchStr, 1);
+        m_xTreeListBox->set_text(rEntry, aTypeStr, 2);
 
-        pEntry = Next( pEntry );
-    }
-
-    // Force redraw
-    Invalidate();
+        return false;
+    });
 
     SbxBase::ResetError();
     if( eOld != ERRCODE_NONE )
diff --git a/basctl/source/basicide/basides2.cxx b/basctl/source/basicide/basides2.cxx
index 4c3e8505cab4..ebf8245089c5 100644
--- a/basctl/source/basicide/basides2.cxx
+++ b/basctl/source/basicide/basides2.cxx
@@ -28,6 +28,7 @@
 #include "baside2.hxx"
 #include "basdoc.hxx"
 #include <basidesh.hxx>
+#include <tools/debug.hxx>
 #include <vcl/texteng.hxx>
 #include <vcl/textview.hxx>
 #include <sfx2/signaturestate.hxx>
diff --git a/basctl/source/basicide/basidesh.cxx b/basctl/source/basicide/basidesh.cxx
index 75f0fe35bf90..b2394690c08c 100644
--- a/basctl/source/basicide/basidesh.cxx
+++ b/basctl/source/basicide/basidesh.cxx
@@ -42,6 +42,7 @@
 #include <sfx2/objface.hxx>
 #include <sfx2/viewfrm.hxx>
 #include <svl/srchitem.hxx>
+#include <tools/debug.hxx>
 
 #if defined(DISABLE_DYNLOADING) || ENABLE_MERGELIBS
 /* Avoid clash with the ones from svx/source/form/typemap.cxx */
diff --git a/basctl/source/basicide/bastype3.hxx b/basctl/source/basicide/bastype3.hxx
deleted file mode 100644
index 3c79e0bea56f..000000000000
--- a/basctl/source/basicide/bastype3.hxx
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- *   Licensed to the Apache Software Foundation (ASF) under one or more
- *   contributor license agreements. See the NOTICE file distributed
- *   with this work for additional information regarding copyright
- *   ownership. The ASF licenses this file to you under the Apache
- *   License, Version 2.0 (the "License"); you may not use this file
- *   except in compliance with the License. You may obtain a copy of
- *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-#pragma once
-
-#include <vcl/accel.hxx>
-#include <vcl/edit.hxx>
-
-namespace basctl
-{
-
-class ExtendedEdit final : public Edit
-{
-    Accelerator               aAcc;
-    Link<Accelerator&,void>   aAccHdl;
-
-    DECL_LINK( EditAccHdl, Accelerator&, void );
-    DECL_LINK( ImplGetFocusHdl, Control&, void );
-    DECL_LINK( ImplLoseFocusHdl, Control&, void );
-
-public:
-    ExtendedEdit(vcl::Window* pParent, WinBits nStyle);
-
-    void            SetAccHdl( const Link<Accelerator&,void>& rLink )         { aAccHdl = rLink; }
-    Accelerator&    GetAccelerator()                                          { return aAcc; }
-};
-
-} // namespace basctl
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basctl/source/basicide/bastypes.cxx b/basctl/source/basicide/bastypes.cxx
index 6c54d770ee58..0d7deb290ab7 100644
--- a/basctl/source/basicide/bastypes.cxx
+++ b/basctl/source/basicide/bastypes.cxx
@@ -418,29 +418,6 @@ void DockingWindow::DockThis ()
     }
 }
 
-ExtendedEdit::ExtendedEdit(vcl::Window* pParent, WinBits nStyle)
-    : Edit(pParent, nStyle)
-{
-    aAcc.SetSelectHdl( LINK( this, ExtendedEdit, EditAccHdl ) );
-    Control::SetGetFocusHdl( LINK( this, ExtendedEdit, ImplGetFocusHdl ) );
-    Control::SetLoseFocusHdl( LINK( this, ExtendedEdit, ImplLoseFocusHdl ) );
-}
-
-IMPL_LINK_NOARG(ExtendedEdit, ImplGetFocusHdl, Control&, void)
-{
-    Application::InsertAccel( &aAcc );
-}
-
-IMPL_LINK_NOARG(ExtendedEdit, ImplLoseFocusHdl, Control&, void)
-{
-    Application::RemoveAccel( &aAcc );
-}
-
-IMPL_LINK( ExtendedEdit, EditAccHdl, Accelerator&, rAcc, void )
-{
-    aAccHdl.Call( rAcc );
-}
-
 TabBar::TabBar( vcl::Window* pParent ) :
     ::TabBar( pParent, WinBits( WB_3DLOOK | WB_SCROLL | WB_BORDER | WB_SIZEABLE | WB_DRAG ) )
 {
diff --git a/basctl/uiconfig/basicide/ui/dockingwatch.ui b/basctl/uiconfig/basicide/ui/dockingwatch.ui
new file mode 100644
index 000000000000..72819bf7ca2a
--- /dev/null
+++ b/basctl/uiconfig/basicide/ui/dockingwatch.ui
@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="basctl">
+  <requires lib="gtk+" version="3.18"/>
+  <object class="GtkImage" id="image1">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="icon_name">res/baswatr.png</property>
+    <property name="icon_size">2</property>
+  </object>
+  <object class="GtkTreeStore" id="liststore1">
+    <columns>
+      <!-- column-name text -->
+      <column type="gchararray"/>
+      <!-- column-name text1 -->
+      <column type="gchararray"/>
+      <!-- column-name text2 -->
+      <column type="gchararray"/>
+      <!-- column-name id -->
+      <column type="gchararray"/>
+    </columns>
+  </object>
+  <object class="GtkGrid" id="DockingWatch">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="hexpand">True</property>
+    <property name="vexpand">True</property>
+    <property name="row_spacing">6</property>
+    <property name="column_spacing">12</property>
+    <child>
+      <object class="GtkGrid" id="titlearea">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="hexpand">True</property>
+        <property name="column_spacing">6</property>
+        <child>
+          <object class="GtkButton" id="remove">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">True</property>
+            <property name="image">image1</property>
+            <property name="use_underline">True</property>
+            <property name="always_show_image">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">2</property>
+            <property name="top_attach">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="edit">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="valign">center</property>
+            <property name="vexpand">False</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="title">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">edit</property>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">0</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkBox">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="hexpand">True</property>
+        <property name="vexpand">True</property>
+        <property name="orientation">vertical</property>
+        <child>
+          <object class="GtkScrolledWindow">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="hexpand">True</property>
+            <property name="vexpand">True</property>
+            <property name="shadow_type">in</property>
+            <child>
+              <object class="GtkTreeView" id="treeview">
+                <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="search_column">1</property>
+                <property name="enable_tree_lines">True</property>
+                <child internal-child="selection">
+                  <object class="GtkTreeSelection"/>
+                </child>
+                <child>
+                  <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+                    <property name="resizable">True</property>
+                    <property name="title" translatable="yes" context="dockingwatch|RID_STR_WATCHVARIABLE">Variable</property>
+                    <child>
+                      <object class="GtkCellRendererText" id="cellrenderertext1"/>
+                      <attributes>
+                        <attribute name="text">0</attribute>
+                      </attributes>
+                    </child>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+                    <property name="resizable">True</property>
+                    <property name="title" translatable="yes" context="dockingwatch|RID_STR_WATCHVALUE">Value</property>
+                    <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="resizable">True</property>
+                    <property name="title" translatable="yes" context="dockingwatch|RID_STR_WATCHTYPE">Type</property>
+                    <child>
+                      <object class="GtkCellRendererText" id="cellrenderertext3"/>
+                      <attributes>
+                        <attribute name="text">2</attribute>
+                      </attributes>
+                    </child>
+                  </object>
+                </child>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">1</property>
+      </packing>
+    </child>
+  </object>
+</interface>
diff --git a/include/vcl/svtabbx.hxx b/include/vcl/svtabbx.hxx
index d59a4cfb9920..ddd8520baad3 100644
--- a/include/vcl/svtabbx.hxx
+++ b/include/vcl/svtabbx.hxx
@@ -86,6 +86,7 @@ public:
     sal_uLong        GetEntryPos( const SvTreeListEntry* pEntry ) const;
 
     void             SetTabJustify( sal_uInt16 nTab, SvTabJustify );
+    void             SetTabEditable( sal_uInt16 nTab, bool bEditable );
 };
 
 // class SvHeaderTabListBox ---------------------------------------------------
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 8621a7415615..a6d9978850c5 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -915,6 +915,7 @@ public:
     virtual void unselect(const TreeIter& rIter) = 0;
     virtual bool get_row_expanded(const TreeIter& rIter) const = 0;
     virtual bool get_children_on_demand(const TreeIter& rIter) const = 0;
+    virtual void set_children_on_demand(const TreeIter& rIter, bool bChildrenOnDemand) = 0;
     virtual void expand_row(const TreeIter& rIter) = 0;
     virtual void collapse_row(const TreeIter& rIter) = 0;
     virtual void set_text(const TreeIter& rIter, const OUString& rStr, int col = -1) = 0;
@@ -1023,6 +1024,7 @@ public:
 
     virtual void columns_autosize() = 0;
     virtual void set_column_fixed_widths(const std::vector<int>& rWidths) = 0;
+    virtual void set_column_editables(const std::vector<bool>& rEditables) = 0;
     virtual int get_column_width(int nCol) const = 0;
     virtual void set_centered_column(int nCol) = 0;
     virtual OUString get_column_title(int nColumn) const = 0;
diff --git a/solenv/clang-format/blacklist b/solenv/clang-format/blacklist
index 1e6c83b9f158..3a59c481e0f9 100644
--- a/solenv/clang-format/blacklist
+++ b/solenv/clang-format/blacklist
@@ -242,7 +242,6 @@ basctl/source/basicide/basobj2.cxx
 basctl/source/basicide/basobj3.cxx
 basctl/source/basicide/bastype2.cxx
 basctl/source/basicide/bastype3.cxx
-basctl/source/basicide/bastype3.hxx
 basctl/source/basicide/bastypes.cxx
 basctl/source/basicide/breakpoint.cxx
 basctl/source/basicide/brkdlg.cxx
diff --git a/solenv/sanitizers/ui/modules/BasicIDE.suppr b/solenv/sanitizers/ui/modules/BasicIDE.suppr
index 01d3c335da04..770d73150b53 100644
--- a/solenv/sanitizers/ui/modules/BasicIDE.suppr
+++ b/solenv/sanitizers/ui/modules/BasicIDE.suppr
@@ -4,5 +4,6 @@ basctl/uiconfig/basicide/ui/basicmacrodialog.ui://GtkEntry[@id='macronameedit']
 basctl/uiconfig/basicide/ui/defaultlanguage.ui://GtkLabel[@id='defined'] orphan-label
 basctl/uiconfig/basicide/ui/defaultlanguage.ui://GtkLabel[@id='added'] orphan-label
 basctl/uiconfig/basicide/ui/defaultlanguage.ui://GtkLabel[@id='alttitle'] orphan-label
+basctl/uiconfig/basicide/ui/dockingwatch.ui://GtkButton[@id='remove'] button-no-label
 basctl/uiconfig/basicide/ui/managelanguages.ui://GtkLabel[@id='label2'] orphan-label
 basctl/uiconfig/basicide/ui/managebreakpoints.ui://GtkEntry[@id='entries'] no-labelled-by
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index de67f950cdfb..06dab9d22380 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -3757,6 +3757,13 @@ public:
         m_xTreeView->Resize();
     }
 
+    virtual void set_column_editables(const std::vector<bool>& rEditables) override
+    {
+        size_t nTabCount = rEditables.size();
+        for (size_t i = 0 ; i < nTabCount; ++i)
+            m_xTreeView->SetTabEditable(i, rEditables[i]);
+    }
+
     virtual void set_centered_column(int nCol) override
     {
         m_xTreeView->SetTabJustify(nCol, SvTabJustify::AdjustCenter);
@@ -4539,6 +4546,22 @@ public:
         return GetPlaceHolderChild(rVclIter.iter) != nullptr;
     }
 
+    virtual void set_children_on_demand(const weld::TreeIter& rIter, bool bChildrenOnDemand) override
+    {
+        disable_notify_events();
+
+        const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
+
+        SvTreeListEntry* pPlaceHolder = GetPlaceHolderChild(rVclIter.iter);
+
+        if (bChildrenOnDemand && !pPlaceHolder)
+            m_xTreeView->InsertEntry("<dummy>", rVclIter.iter, false, 0, nullptr);
+        else if (!bChildrenOnDemand && pPlaceHolder)
+            m_xTreeView->RemoveEntry(pPlaceHolder);
+
+        enable_notify_events();
+    }
+
     virtual void expand_row(const weld::TreeIter& rIter) override
     {
         assert(m_xTreeView->IsUpdateMode() && "don't expand when frozen");
diff --git a/vcl/source/treelist/svtabbx.cxx b/vcl/source/treelist/svtabbx.cxx
index ab4e5ba70fa1..52ade983e94a 100644
--- a/vcl/source/treelist/svtabbx.cxx
+++ b/vcl/source/treelist/svtabbx.cxx
@@ -426,6 +426,18 @@ void SvTabListBox::SetTabJustify( sal_uInt16 nTab, SvTabJustify eJustify)
         Invalidate();
 }
 
+void SvTabListBox::SetTabEditable(sal_uInt16 nTab, bool bEditable)
+{
+    DBG_ASSERT(nTab<mvTabList.size(),"GetTabPos:Invalid Tab");
+    if( nTab >= mvTabList.size() )
+        return;
+    SvLBoxTab& rTab = mvTabList[ nTab ];
+    if (bEditable)
+        rTab.nFlags |= SvLBoxTabFlags::EDITABLE;
+    else
+        rTab.nFlags &= ~SvLBoxTabFlags::EDITABLE;
+}
+
 long SvTabListBox::GetLogicTab( sal_uInt16 nTab )
 {
     if( SvTreeListBox::nTreeFlags & SvTreeFlags::RECALCTABS )
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 9e023d4b2c3a..bdfe4fe1ced0 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -8909,6 +8909,26 @@ private:
         return m_aModelColToViewCol[modelcol];
     }
 
+    void set_column_editable(int nCol, bool bEditable)
+    {
+        for (GList* pEntry = g_list_first(m_pColumns); pEntry; pEntry = g_list_next(pEntry))
+        {
+            GtkTreeViewColumn* pColumn = GTK_TREE_VIEW_COLUMN(pEntry->data);
+            GList *pRenderers = gtk_cell_layout_get_cells(GTK_CELL_LAYOUT(pColumn));
+            for (GList* pRenderer = g_list_first(pRenderers); pRenderer; pRenderer = g_list_next(pRenderer))
+            {
+                GtkCellRenderer* pCellRenderer = GTK_CELL_RENDERER(pRenderer->data);
+                void* pData = g_object_get_data(G_OBJECT(pCellRenderer), "g-lo-CellIndex");
+                if (reinterpret_cast<sal_IntPtr>(pData) == nCol)
+                {
+                    g_object_set(G_OBJECT(pCellRenderer), "editable", bEditable, "editable-set", true, nullptr);
+                    break;
+                }
+            }
+            g_list_free(pRenderers);
+        }
+    }
+
     static void signalRowDeleted(GtkTreeModel*, GtkTreePath*, gpointer widget)
     {
         GtkInstanceTreeView* pThis = static_cast<GtkInstanceTreeView*>(widget);
@@ -9099,6 +9119,13 @@ public:
         }
     }
 
+    virtual void set_column_editables(const std::vector<bool>& rEditables) override
+    {
+        size_t nTabCount = rEditables.size();
+        for (size_t i = 0 ; i < nTabCount; ++i)
+            set_column_editable(i, rEditables[i]);
+    }
+
     virtual void set_centered_column(int nCol) override
     {
         for (GList* pEntry = g_list_first(m_pColumns); pEntry; pEntry = g_list_next(pEntry))
@@ -10060,6 +10087,27 @@ public:
         return child_is_placeholder(aIter);
     }
 
+    virtual void set_children_on_demand(const weld::TreeIter& rIter, bool bChildrenOnDemand) override
+    {
+        disable_notify_events();
+
+        const GtkInstanceTreeIter& rGtkIter = static_cast<const GtkInstanceTreeIter&>(rIter);
+        GtkInstanceTreeIter aPlaceHolderIter(&rGtkIter);
+
+        bool bPlaceHolder = child_is_placeholder(aPlaceHolderIter);
+
+        if (bChildrenOnDemand && !bPlaceHolder)
+        {
+            GtkTreeIter subiter;
+            OUString sDummy("<dummy>");
+            insert_row(subiter, &rGtkIter.iter, -1, nullptr, &sDummy, nullptr, nullptr, nullptr);
+        }
+        else if (!bChildrenOnDemand && bPlaceHolder)
+            remove(aPlaceHolderIter);
+
+        enable_notify_events();
+    }
+
     virtual void expand_row(const weld::TreeIter& rIter) override
     {
         assert(gtk_tree_view_get_model(m_pTreeView) && "don't expand when frozen");


More information about the Libreoffice-commits mailing list