[Libreoffice-commits] core.git: cui/source cui/uiconfig extras/source include/sfx2 include/vcl sc/source sd/source sw/source vcl/source vcl/unx

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Mon Feb 11 15:35:09 UTC 2019


 cui/source/dialogs/linkdlg.cxx                 |  420 ++++++++++---------------
 cui/source/factory/dlgfact.cxx                 |   16 
 cui/source/factory/dlgfact.hxx                 |   10 
 cui/source/inc/linkdlg.hxx                     |   59 +--
 cui/uiconfig/ui/baselinksdialog.ui             |  248 ++++++--------
 extras/source/glade/libreoffice-catalog.xml.in |    5 
 include/sfx2/sfxdlg.hxx                        |    2 
 include/vcl/weld.hxx                           |   27 +
 sc/source/ui/view/tabvwshb.cxx                 |    2 
 sd/source/ui/func/fulink.cxx                   |    2 
 sw/source/uibase/shells/textfld.cxx            |    3 
 sw/source/uibase/uiview/view2.cxx              |    2 
 vcl/source/app/salvtables.cxx                  |   73 +++-
 vcl/source/treelist/svtabbx.cxx                |    2 
 vcl/unx/gtk3/gtk3gtkinst.cxx                   |   90 ++++-
 15 files changed, 520 insertions(+), 441 deletions(-)

New commits:
commit 4bb482cc2e65a10fd4f38cddfab405169cf192e4
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Sun Feb 10 14:59:03 2019 +0000
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Mon Feb 11 16:34:44 2019 +0100

    weld SvBaseLinksDlg
    
    Change-Id: I40afcb99ae0e8fd27387077aea688906f037d6f4
    Reviewed-on: https://gerrit.libreoffice.org/67676
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/cui/source/dialogs/linkdlg.cxx b/cui/source/dialogs/linkdlg.cxx
index 2ce9b4e3ce4c..b4b7410909df 100644
--- a/cui/source/dialogs/linkdlg.cxx
+++ b/cui/source/dialogs/linkdlg.cxx
@@ -76,144 +76,122 @@ public:
     }
 };
 
-// attention, this array is indexed directly (0, 1, ...) in the code
-static long nTabs[] =
-    {
-        0, 77, 144, 209
-    };
-
-
-SvBaseLinksDlg::SvBaseLinksDlg( vcl::Window * pParent, LinkManager* pMgr, bool bHtmlMode )
-    : ModalDialog( pParent, "BaseLinksDialog", "cui/ui/baselinksdialog.ui"),
-    aStrAutolink( CuiResId( STR_AUTOLINK ) ),
-    aStrManuallink( CuiResId( STR_MANUALLINK ) ),
-    aStrBrokenlink( CuiResId( STR_BROKENLINK ) ),
-    aStrCloselinkmsg( CuiResId( STR_CLOSELINKMSG ) ),
-    aStrCloselinkmsgMulti( CuiResId( STR_CLOSELINKMSG_MULTI ) ),
-    aStrWaitinglink( CuiResId( STR_WAITINGLINK ) ),
-    pLinkMgr( nullptr ),
-    aUpdateIdle("cui SvBaseLinksDlg UpdateIdle")
+SvBaseLinksDlg::SvBaseLinksDlg(weld::Window * pParent, LinkManager* pMgr, bool bHtmlMode)
+    : GenericDialogController(pParent, "cui/ui/baselinksdialog.ui", "BaseLinksDialog")
+    , aStrAutolink( CuiResId( STR_AUTOLINK ) )
+    , aStrManuallink( CuiResId( STR_MANUALLINK ) )
+    , aStrBrokenlink( CuiResId( STR_BROKENLINK ) )
+    , aStrCloselinkmsg( CuiResId( STR_CLOSELINKMSG ) )
+    , aStrCloselinkmsgMulti( CuiResId( STR_CLOSELINKMSG_MULTI ) )
+    , aStrWaitinglink( CuiResId( STR_WAITINGLINK ) )
+    , pLinkMgr( nullptr )
+    , aUpdateIdle("cui SvBaseLinksDlg UpdateIdle")
+    , m_xTbLinks(m_xBuilder->weld_tree_view("TB_LINKS"))
+    , m_xFtFullFileName(m_xBuilder->weld_link_button("FULL_FILE_NAME"))
+    , m_xFtFullSourceName(m_xBuilder->weld_label("FULL_SOURCE_NAME"))
+    , m_xFtFullTypeName(m_xBuilder->weld_label("FULL_TYPE_NAME"))
+    , m_xRbAutomatic(m_xBuilder->weld_radio_button("AUTOMATIC"))
+    , m_xRbManual(m_xBuilder->weld_radio_button("MANUAL"))
+    , m_xPbUpdateNow(m_xBuilder->weld_button("UPDATE_NOW"))
+    , m_xPbChangeSource(m_xBuilder->weld_button("CHANGE_SOURCE"))
+    , m_xPbBreakLink(m_xBuilder->weld_button("BREAK_LINK"))
+    , m_xVirDev(VclPtr<VirtualDevice>::Create())
 {
-    get(m_pTbLinks, "TB_LINKS");
-    Size aSize(LogicToPixel(Size(257, 87), MapMode(MapUnit::MapAppFont)));
-    m_pTbLinks->set_width_request(aSize.Width());
-    m_pTbLinks->set_height_request(aSize.Height());
-    get(m_pFtFullFileName, "FULL_FILE_NAME");
-    get(m_pFtFullSourceName, "FULL_SOURCE_NAME");
-    get(m_pFtFullTypeName, "FULL_TYPE_NAME");
-    get(m_pRbAutomatic, "AUTOMATIC");
-    get(m_pRbManual, "MANUAL");
-    get(m_pPbUpdateNow, "UPDATE_NOW");
-    get(m_pPbChangeSource, "CHANGE_SOURCE");
-    get(m_pPbBreakLink, "BREAK_LINK");
-
-    m_pTbLinks->SetSelectionMode( SelectionMode::Multiple );
-    m_pTbLinks->SetTabs( SAL_N_ELEMENTS(nTabs), nTabs );
-    FixedText *pFtFiles = get<FixedText>("FILES");
-    pFtFiles->set_width_request(LogicToPixel(Size(nTabs[1] - nTabs[0] - 2, 0), MapMode(MapUnit::MapAppFont)).Width());
-    FixedText *pFtLinks = get<FixedText>("LINKS");
-    pFtLinks->set_width_request(LogicToPixel(Size(nTabs[2] - nTabs[1] - 2, 0), MapMode(MapUnit::MapAppFont)).Width());
-    FixedText *pFtTypes = get<FixedText>("TYPE");
-    pFtTypes->set_width_request(LogicToPixel(Size(nTabs[3] - nTabs[2] - 2, 0), MapMode(MapUnit::MapAppFont)).Width());
-    m_pTbLinks->Resize();  // OS: hack for correct selection
+    // expand the point size of the desired font to the equivalent pixel size
+    if (vcl::Window* pDefaultDevice = dynamic_cast<vcl::Window*>(Application::GetDefaultDevice()))
+        pDefaultDevice->SetPointFont(*m_xVirDev, m_xTbLinks->get_font());
+    m_xTbLinks->set_size_request(m_xTbLinks->get_approximate_digit_width() * 90,
+                                 m_xTbLinks->get_height_rows(12));
+
+    m_xTbLinks->set_selection_mode(SelectionMode::Multiple);
+
+    std::vector<int> aWidths;
+    aWidths.push_back(m_xTbLinks->get_approximate_digit_width() * 30);
+    aWidths.push_back(m_xTbLinks->get_approximate_digit_width() * 20);
+    aWidths.push_back(m_xTbLinks->get_approximate_digit_width() * 20);
+    m_xTbLinks->set_column_fixed_widths(aWidths);
 
     // UpdateTimer for DDE-/Grf-links, which are waited for
     aUpdateIdle.SetInvokeHandler( LINK( this, SvBaseLinksDlg, UpdateWaitingHdl ) );
     aUpdateIdle.SetPriority( TaskPriority::LOWEST );
 
-    m_pTbLinks->SetSelectHdl( LINK( this, SvBaseLinksDlg, LinksSelectHdl ) );
-    m_pTbLinks->SetDoubleClickHdl( LINK( this, SvBaseLinksDlg, LinksDoubleClickHdl ) );
-    m_pRbAutomatic->SetClickHdl( LINK( this, SvBaseLinksDlg, AutomaticClickHdl ) );
-    m_pRbManual->SetClickHdl( LINK( this, SvBaseLinksDlg, ManualClickHdl ) );
-    m_pPbUpdateNow->SetClickHdl( LINK( this, SvBaseLinksDlg, UpdateNowClickHdl ) );
-    m_pPbChangeSource->SetClickHdl( LINK( this, SvBaseLinksDlg, ChangeSourceClickHdl ) );
+    m_xTbLinks->connect_changed( LINK( this, SvBaseLinksDlg, LinksSelectHdl ) );
+    m_xTbLinks->connect_row_activated( LINK( this, SvBaseLinksDlg, LinksDoubleClickHdl ) );
+    m_xRbAutomatic->connect_clicked( LINK( this, SvBaseLinksDlg, AutomaticClickHdl ) );
+    m_xRbManual->connect_clicked( LINK( this, SvBaseLinksDlg, ManualClickHdl ) );
+    m_xPbUpdateNow->connect_clicked( LINK( this, SvBaseLinksDlg, UpdateNowClickHdl ) );
+    m_xPbChangeSource->connect_clicked( LINK( this, SvBaseLinksDlg, ChangeSourceClickHdl ) );
     if(!bHtmlMode)
-        m_pPbBreakLink->SetClickHdl( LINK( this, SvBaseLinksDlg, BreakLinkClickHdl ) );
+        m_xPbBreakLink->connect_clicked( LINK( this, SvBaseLinksDlg, BreakLinkClickHdl ) );
     else
-        m_pPbBreakLink->Hide();
+        m_xPbBreakLink->hide();
 
     SetManager( pMgr );
 }
 
 SvBaseLinksDlg::~SvBaseLinksDlg()
 {
-    disposeOnce();
-}
-
-void SvBaseLinksDlg::dispose()
-{
-    m_pTbLinks.clear();
-    m_pFtFullFileName.clear();
-    m_pFtFullSourceName.clear();
-    m_pFtFullTypeName.clear();
-    m_pRbAutomatic.clear();
-    m_pRbManual.clear();
-    m_pPbUpdateNow.clear();
-    m_pPbChangeSource.clear();
-    m_pPbBreakLink.clear();
-    ModalDialog::dispose();
 }
 
 /*************************************************************************
 |*    SvBaseLinksDlg::Handler()
 *************************************************************************/
-IMPL_LINK( SvBaseLinksDlg, LinksSelectHdl, SvTreeListBox *, pSvTabListBox, void )
+IMPL_LINK(SvBaseLinksDlg, LinksSelectHdl, weld::TreeView&, rTreeView, void)
+{
+    LinksSelectHdl(&rTreeView);
+}
+
+void SvBaseLinksDlg::LinksSelectHdl(weld::TreeView* pSvTabListBox)
 {
-    const sal_uLong nSelectionCount = pSvTabListBox ?
-        pSvTabListBox->GetSelectionCount() : 0;
-    if(nSelectionCount > 1)
+    const int nSelectionCount = pSvTabListBox ?
+        pSvTabListBox->count_selected_rows() : 0;
+    if (nSelectionCount > 1)
     {
         // possibly deselect old entries in case of multi-selection
-        SvTreeListEntry* pEntry = pSvTabListBox->GetHdlEntry();
-        SvBaseLink* pLink = static_cast<SvBaseLink*>(pEntry->GetUserData());
+        int nSelEntry = pSvTabListBox->get_selected_index();
+        SvBaseLink* pLink = reinterpret_cast<SvBaseLink*>(pSvTabListBox->get_id(nSelEntry).toInt64());
         sal_uInt16 nObjectType = pLink->GetObjType();
         if((OBJECT_CLIENT_FILE & nObjectType) != OBJECT_CLIENT_FILE)
         {
-            pSvTabListBox->SelectAll(false);
-            pSvTabListBox->Select(pEntry);
+            pSvTabListBox->unselect_all();
+            pSvTabListBox->select(nSelEntry);
         }
         else
         {
-            for( sal_uLong i = 0; i < nSelectionCount; i++)
+            std::vector<int> aRows = pSvTabListBox->get_selected_rows();
+            for (auto nEntry : aRows)
             {
-                pEntry = i == 0 ? pSvTabListBox->FirstSelected() :
-                                    pSvTabListBox->NextSelected(pEntry);
-                DBG_ASSERT(pEntry, "Where is the Entry?");
-                if (!pEntry)
-                    continue;
-                pLink = static_cast<SvBaseLink*>(pEntry->GetUserData());
+                pLink = reinterpret_cast<SvBaseLink*>(pSvTabListBox->get_id(nEntry).toInt64());
                 DBG_ASSERT(pLink, "Where is the Link?");
                 if (!pLink)
                     continue;
                 if( (OBJECT_CLIENT_FILE & pLink->GetObjType()) != OBJECT_CLIENT_FILE )
-                    pSvTabListBox->Select( pEntry, false );
-
+                    pSvTabListBox->unselect(nEntry);
             }
         }
 
-        m_pPbUpdateNow->Enable();
-
-        m_pRbAutomatic->Disable();
-        m_pRbManual->Check();
-        m_pRbManual->Disable();
+        m_xPbUpdateNow->set_sensitive(true);
+        m_xRbAutomatic->set_sensitive(false);
+        m_xRbManual->set_active(true);
+        m_xRbManual->set_sensitive(false);
     }
     else
     {
-        sal_uLong nPos;
+        int nPos;
         SvBaseLink* pLink = GetSelEntry( &nPos );
         if( !pLink )
             return;
 
-        m_pPbUpdateNow->Enable();
+        m_xPbUpdateNow->set_sensitive(true);
 
         OUString sType, sLink;
         OUString *pLinkNm = &sLink, *pFilter = nullptr;
 
         if( FILEOBJECT & pLink->GetObjType() )
         {
-            m_pRbAutomatic->Disable();
-            m_pRbManual->Check();
-            m_pRbManual->Disable();
+            m_xRbAutomatic->set_sensitive(false);
+            m_xRbManual->set_active(true);
+            m_xRbManual->set_sensitive(false);
             if( OBJECT_CLIENT_GRF == pLink->GetObjType() )
             {
                 pLinkNm = nullptr;
@@ -222,66 +200,58 @@ IMPL_LINK( SvBaseLinksDlg, LinksSelectHdl, SvTreeListBox *, pSvTabListBox, void
         }
         else
         {
-            m_pRbAutomatic->Enable();
-            m_pRbManual->Enable();
+            m_xRbAutomatic->set_sensitive(true);
+            m_xRbManual->set_sensitive(true);
 
             if( SfxLinkUpdateMode::ALWAYS == pLink->GetUpdateMode() )
-                m_pRbAutomatic->Check();
+                m_xRbAutomatic->set_active(true);
             else
-                m_pRbManual->Check();
+                m_xRbManual->set_active(true);
         }
 
         OUString aFileName;
         sfx2::LinkManager::GetDisplayNames( pLink, &sType, &aFileName, pLinkNm, pFilter );
         aFileName = INetURLObject::decode(aFileName, INetURLObject::DecodeMechanism::Unambiguous);
-        m_pFtFullFileName->SetText( aFileName );
-        m_pFtFullFileName->SetURL( aFileName );
-        m_pFtFullSourceName->SetText( sLink );
-        m_pFtFullTypeName->SetText( sType );
+        m_xFtFullFileName->set_label( aFileName );
+        m_xFtFullFileName->set_uri( aFileName );
+        m_xFtFullSourceName->set_label( sLink );
+        m_xFtFullTypeName->set_label( sType );
     }
 }
 
-IMPL_LINK_NOARG( SvBaseLinksDlg, LinksDoubleClickHdl, SvTreeListBox *, bool )
+IMPL_LINK_NOARG( SvBaseLinksDlg, LinksDoubleClickHdl, weld::TreeView&, void )
 {
-    ChangeSourceClickHdl( nullptr );
-    return false;
+    ChangeSourceClickHdl(*m_xPbChangeSource);
 }
 
-IMPL_LINK_NOARG( SvBaseLinksDlg, AutomaticClickHdl, Button*, void )
+IMPL_LINK_NOARG( SvBaseLinksDlg, AutomaticClickHdl, weld::Button&, void )
 {
-    sal_uLong nPos;
+    int nPos;
     SvBaseLink* pLink = GetSelEntry( &nPos );
     if( pLink && !( FILEOBJECT & pLink->GetObjType() ) &&
         SfxLinkUpdateMode::ALWAYS != pLink->GetUpdateMode() )
         SetType( *pLink, nPos, SfxLinkUpdateMode::ALWAYS );
 }
 
-IMPL_LINK_NOARG( SvBaseLinksDlg, ManualClickHdl, Button*, void )
+IMPL_LINK_NOARG( SvBaseLinksDlg, ManualClickHdl, weld::Button&, void )
 {
-    sal_uLong nPos;
+    int nPos;
     SvBaseLink* pLink = GetSelEntry( &nPos );
     if( pLink && !( FILEOBJECT & pLink->GetObjType() ) &&
         SfxLinkUpdateMode::ONCALL != pLink->GetUpdateMode())
         SetType( *pLink, nPos, SfxLinkUpdateMode::ONCALL );
 }
 
-IMPL_LINK_NOARG(SvBaseLinksDlg, UpdateNowClickHdl, Button*, void)
+IMPL_LINK_NOARG(SvBaseLinksDlg, UpdateNowClickHdl, weld::Button&, void)
 {
-    SvTabListBox& rListBox = *m_pTbLinks;
-
     std::vector< SvBaseLink* > aLnkArr;
     std::vector< sal_Int16 > aPosArr;
 
-    SvTreeListEntry* pE = rListBox.FirstSelected();
-    while( pE )
+    std::vector<int> aRows = m_xTbLinks->get_selected_rows();
+    for (int nFndPos : aRows)
     {
-        sal_uLong nFndPos = rListBox.GetModel()->GetAbsPos( pE );
-        if( TREELIST_ENTRY_NOTFOUND != nFndPos )
-        {
-            aLnkArr.push_back( static_cast< SvBaseLink* >( pE->GetUserData() ) );
-            aPosArr.push_back( nFndPos );
-        }
-        pE = rListBox.NextSelected( pE );
+        aLnkArr.push_back( reinterpret_cast<SvBaseLink*>( m_xTbLinks->get_id(nFndPos).toInt64() ) );
+        aPosArr.push_back( nFndPos );
     }
 
     if( !aLnkArr.empty() )
@@ -305,39 +275,24 @@ IMPL_LINK_NOARG(SvBaseLinksDlg, UpdateNowClickHdl, Button*, void)
         SetManager( pNewMgr );
 
 
-        if( nullptr == (pE = rListBox.GetEntry( aPosArr[ 0 ] )) ||
-            pE->GetUserData() != aLnkArr[ 0 ] )
-        {
-            // search the link
-            pE = rListBox.First();
-            while( pE )
-            {
-                if( pE->GetUserData() == aLnkArr[ 0 ] )
-                    break;
-                pE = rListBox.Next( pE );
-            }
-
-            if( !pE )
-                pE = rListBox.FirstSelected();
-        }
-
-        if( pE )
-        {
-            SvTreeListEntry* pSelEntry = rListBox.FirstSelected();
-            if( pE != pSelEntry )
-                rListBox.Select( pSelEntry, false );
-            rListBox.Select( pE );
-            rListBox.MakeVisible( pE );
-        }
+        OUString sId = OUString::number(reinterpret_cast<sal_Int64>(aLnkArr[0]));
+        int nE = m_xTbLinks->find_id(sId);
+        if (nE == -1)
+            nE = m_xTbLinks->get_selected_index();
+        int nSelEntry = m_xTbLinks->get_selected_index();
+        if (nE != nSelEntry)
+            m_xTbLinks->unselect(nSelEntry);
+        m_xTbLinks->select(nE);
+        m_xTbLinks->scroll_to_row(nE);
 
         pNewMgr->CloseCachedComps();
     }
 }
 
-IMPL_LINK_NOARG( SvBaseLinksDlg, ChangeSourceClickHdl, Button *, void )
+IMPL_LINK_NOARG(SvBaseLinksDlg, ChangeSourceClickHdl, weld::Button&, void)
 {
-    sal_uLong nSelectionCount = m_pTbLinks->GetSelectionCount();
-    if(nSelectionCount > 1)
+    std::vector<int> aRows = m_xTbLinks->get_selected_rows();
+    if (aRows.size() > 1)
     {
         try
         {
@@ -345,8 +300,7 @@ IMPL_LINK_NOARG( SvBaseLinksDlg, ChangeSourceClickHdl, Button *, void )
 
             OUString sType, sFile, sLinkName;
             OUString sFilter;
-            SvTreeListEntry* pEntry = m_pTbLinks->FirstSelected();
-            SvBaseLink* pLink = static_cast<SvBaseLink*>(pEntry->GetUserData());
+            SvBaseLink* pLink = reinterpret_cast<SvBaseLink*>(m_xTbLinks->get_id(aRows[0]).toInt64());
             sfx2::LinkManager::GetDisplayNames( pLink, &sType, &sFile );
             INetURLObject aUrl(sFile);
             if(aUrl.GetProtocol() == INetProtocol::File)
@@ -360,15 +314,9 @@ IMPL_LINK_NOARG( SvBaseLinksDlg, ChangeSourceClickHdl, Button *, void )
             {
                 OUString aPath = xFolderPicker->getDirectory();
 
-                for( sal_uLong i = 0; i < nSelectionCount; i++)
+                for (auto nRow : aRows)
                 {
-                    pEntry = i==0 ?
-                        m_pTbLinks->FirstSelected() :
-                        m_pTbLinks->NextSelected( pEntry );
-                    DBG_ASSERT(pEntry,"Where is the entry?");
-                    if (!pEntry)
-                        continue;
-                    pLink = static_cast<SvBaseLink*>(pEntry->GetUserData());
+                    pLink = reinterpret_cast<SvBaseLink*>(m_xTbLinks->get_id(nRow).toInt64());
                     DBG_ASSERT(pLink,"Where is the link?");
                     if (!pLink)
                         continue;
@@ -396,31 +344,31 @@ IMPL_LINK_NOARG( SvBaseLinksDlg, ChangeSourceClickHdl, Button *, void )
     }
     else
     {
-        sal_uLong nPos;
+        int nPos;
         SvBaseLink* pLink = GetSelEntry( &nPos );
         if ( pLink && !pLink->GetLinkSourceName().isEmpty() )
-            pLink->Edit( GetFrameWeld(), LINK( this, SvBaseLinksDlg, EndEditHdl ) );
+            pLink->Edit(m_xDialog.get(), LINK(this, SvBaseLinksDlg, EndEditHdl));
     }
 }
 
-IMPL_LINK_NOARG( SvBaseLinksDlg, BreakLinkClickHdl, Button*, void )
+IMPL_LINK_NOARG( SvBaseLinksDlg, BreakLinkClickHdl, weld::Button&, void )
 {
     bool bModified = false;
-    if(m_pTbLinks->GetSelectionCount() <= 1)
+    if (m_xTbLinks->count_selected_rows() <= 1)
     {
-        sal_uLong nPos;
+        int nPos;
         tools::SvRef<SvBaseLink> xLink = GetSelEntry( &nPos );
         if( !xLink.is() )
             return;
 
-        std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetFrameWeld(),
+        std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(m_xDialog.get(),
                                                        VclMessageType::Question, VclButtonsType::YesNo,
                                                        aStrCloselinkmsg));
         xQueryBox->set_default_response(RET_YES);
 
         if (RET_YES == xQueryBox->run())
         {
-            m_pTbLinks->GetModel()->Remove( m_pTbLinks->GetEntry( nPos ) );
+            m_xTbLinks->remove(nPos);
 
             // close object, if it's still existing
             bool bNewLnkMgr = OBJECT_CLIENT_FILE == xLink->GetObjType();
@@ -437,35 +385,32 @@ IMPL_LINK_NOARG( SvBaseLinksDlg, BreakLinkClickHdl, Button*, void )
                 LinkManager* pNewMgr = pLinkMgr;
                 pLinkMgr = nullptr;
                 SetManager( pNewMgr );
-
-                SvTreeListEntry* pEntry = m_pTbLinks->GetEntry( nPos ? --nPos : 0 );
-                if( pEntry )
-                    m_pTbLinks->SetCurEntry( pEntry );
+                m_xTbLinks->set_cursor(nPos ? --nPos : 0);
             }
             bModified = true;
         }
     }
     else
     {
-        std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetFrameWeld(),
+        std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(m_xDialog.get(),
                                                        VclMessageType::Question, VclButtonsType::YesNo,
                                                        aStrCloselinkmsgMulti));
         xQueryBox->set_default_response(RET_YES);
 
         if (RET_YES == xQueryBox->run())
         {
-
+            std::vector<int> aRows = m_xTbLinks->get_selected_rows();
             SvBaseLinkMemberList aLinkList;
-            SvTreeListEntry* pEntry = m_pTbLinks->FirstSelected();
-            while ( pEntry )
+            for (auto nRow : aRows)
             {
-                void * pUD = pEntry->GetUserData();
-                if( pUD )
-                    aLinkList.push_back( static_cast<SvBaseLink*>(pUD) );
-                pEntry = m_pTbLinks->NextSelected(pEntry);
+                SvBaseLink* pLink = reinterpret_cast<SvBaseLink*>(m_xTbLinks->get_id(nRow).toInt64());
+                if (pLink)
+                    aLinkList.push_back(pLink);
             }
-            m_pTbLinks->RemoveSelection();
-            for( sal_uLong i = 0; i < aLinkList.size(); i++ )
+            std::sort(aRows.begin(), aRows.end());
+            for (auto it = aRows.rbegin(); it != aRows.rend(); ++it)
+                m_xTbLinks->remove(*it);
+            for (size_t i = 0; i < aLinkList.size(); ++i)
             {
                 tools::SvRef<SvBaseLink> xLink = aLinkList[i];
                 // tell the link that it will be resolved!
@@ -480,16 +425,16 @@ IMPL_LINK_NOARG( SvBaseLinksDlg, BreakLinkClickHdl, Button*, void )
     }
     if(bModified)
     {
-        if( !m_pTbLinks->GetEntryCount() )
+        if (!m_xTbLinks->n_children())
         {
-            m_pRbAutomatic->Disable();
-            m_pRbManual->Disable();
-            m_pPbUpdateNow->Disable();
-            m_pPbChangeSource->Disable();
-            m_pPbBreakLink->Disable();
-
-            m_pFtFullSourceName->SetText( "" );
-            m_pFtFullTypeName->SetText( "" );
+            m_xRbAutomatic->set_sensitive(false);
+            m_xRbManual->set_sensitive(false);
+            m_xPbUpdateNow->set_sensitive(false);
+            m_xPbChangeSource->set_sensitive(false);
+            m_xPbBreakLink->set_sensitive(false);
+
+            m_xFtFullSourceName->set_label( "" );
+            m_xFtFullTypeName->set_label( "" );
         }
         if( pLinkMgr && pLinkMgr->GetPersist() )
             pLinkMgr->GetPersist()->SetModified();
@@ -498,25 +443,24 @@ IMPL_LINK_NOARG( SvBaseLinksDlg, BreakLinkClickHdl, Button*, void )
 
 IMPL_LINK_NOARG( SvBaseLinksDlg, UpdateWaitingHdl, Timer*, void )
 {
-    m_pTbLinks->SetUpdateMode(false);
-    for( sal_uLong nPos = m_pTbLinks->GetEntryCount(); nPos; )
+    m_xTbLinks->freeze();
+    for (int nPos = m_xTbLinks->n_children(); nPos; --nPos)
     {
-        SvTreeListEntry* pBox = m_pTbLinks->GetEntry( --nPos );
-        tools::SvRef<SvBaseLink> xLink( static_cast<SvBaseLink*>(pBox->GetUserData()) );
+        tools::SvRef<SvBaseLink> xLink( reinterpret_cast<SvBaseLink*>(m_xTbLinks->get_id(nPos).toInt64()) );
         if( xLink.is() )
         {
             OUString sCur( ImplGetStateStr( *xLink ) ),
-                    sOld( SvTabListBox::GetEntryText( pBox, 3 ) );
+                    sOld( m_xTbLinks->get_text(nPos, 3) );
             if( sCur != sOld )
-                m_pTbLinks->SetEntryText( sCur, pBox, 3 );
+                m_xTbLinks->set_text(nPos, sCur, 3);
         }
     }
-    m_pTbLinks->SetUpdateMode(true);
+    m_xTbLinks->thaw();
 }
 
 IMPL_LINK( SvBaseLinksDlg, EndEditHdl, sfx2::SvBaseLink&, _rLink, void )
 {
-    sal_uLong nPos;
+    int nPos;
     GetSelEntry( &nPos );
 
     if( _rLink.WasLastEditOK() )
@@ -535,13 +479,11 @@ IMPL_LINK( SvBaseLinksDlg, EndEditHdl, sfx2::SvBaseLink&, _rLink, void )
 
         if( bLinkFnd )
         {
-            m_pTbLinks->SetUpdateMode(false);
-            m_pTbLinks->GetModel()->Remove( m_pTbLinks->GetEntry( nPos ) );
-            SvTreeListEntry* pToUnselect = m_pTbLinks->FirstSelected();
-            InsertEntry( _rLink, nPos, true );
-            if(pToUnselect)
-                m_pTbLinks->Select(pToUnselect, false);
-            m_pTbLinks->SetUpdateMode(true);
+            m_xTbLinks->remove(nPos);
+            int nToUnselect = m_xTbLinks->get_selected_index();
+            InsertEntry(_rLink, nPos, true);
+            if (nToUnselect != -1)
+                m_xTbLinks->unselect(nToUnselect);
         }
         else
         {
@@ -577,11 +519,13 @@ void SvBaseLinksDlg::SetManager( LinkManager* pNewMgr )
     if( pLinkMgr == pNewMgr )
         return;
 
-    if( pNewMgr )
+    if (pNewMgr)
+    {
         // update has to be stopped before clear
-        m_pTbLinks->SetUpdateMode( false );
+        m_xTbLinks->freeze();
+    }
 
-    m_pTbLinks->Clear();
+    m_xTbLinks->clear();
     pLinkMgr = pNewMgr;
 
     if( pLinkMgr )
@@ -600,30 +544,25 @@ void SvBaseLinksDlg::SetManager( LinkManager* pNewMgr )
                 InsertEntry( *rLinkRef );
         }
 
+        m_xTbLinks->thaw();
+
         if( !rLnks.empty() )
         {
-            SvTreeListEntry* pEntry = m_pTbLinks->GetEntry( 0 );
-            m_pTbLinks->SetCurEntry( pEntry );
-            m_pTbLinks->Select( pEntry );
+            m_xTbLinks->set_cursor(0);
+            m_xTbLinks->select(0);
             LinksSelectHdl( nullptr );
         }
-        m_pTbLinks->SetUpdateMode( true );
-        m_pTbLinks->Invalidate();
     }
 }
 
-
-void SvBaseLinksDlg::InsertEntry( const SvBaseLink& rLink, sal_uLong nPos, bool bSelect )
+void SvBaseLinksDlg::InsertEntry(const SvBaseLink& rLink, int nPos, bool bSelect)
 {
-    OUString aEntry, sFileNm, sLinkNm, sTypeNm, sFilter;
+    OUString sFileNm, sLinkNm, sTypeNm, sFilter;
 
     sfx2::LinkManager::GetDisplayNames( &rLink, &sTypeNm, &sFileNm, &sLinkNm, &sFilter );
 
-    // GetTab(0) gives the position of the bitmap which is automatically inserted by the TabListBox.
-    // So the first text column's width is Tab(2)-Tab(1).
-    long nWidthPixel = m_pTbLinks->GetLogicTab( 2 ) - m_pTbLinks->GetLogicTab( 1 );
-    nWidthPixel -= SV_TAB_BORDER;
-    OUString aTxt = m_pTbLinks->GetEllipsisString( sFileNm, nWidthPixel, DrawTextFlags::PathEllipsis );
+    auto nWidthPixel = m_xTbLinks->get_column_width(0);
+    OUString aTxt = m_xVirDev->GetEllipsisString(sFileNm, nWidthPixel, DrawTextFlags::PathEllipsis);
     INetURLObject aPath( sFileNm, INetProtocol::File );
     OUString aFileName = aPath.getName();
     aFileName = INetURLObject::decode(aFileName, INetURLObject::DecodeMechanism::Unambiguous);
@@ -634,44 +573,43 @@ void SvBaseLinksDlg::InsertEntry( const SvBaseLink& rLink, sal_uLong nPos, bool
         // filename not in string
         aTxt = aFileName;
 
-    aEntry = aTxt + "\t";
+    if (nPos == -1)
+        nPos = m_xTbLinks->n_children();
+    m_xTbLinks->insert(nullptr, nPos, nullptr, nullptr, nullptr,
+                       nullptr, nullptr, false);
+
+    m_xTbLinks->set_id(nPos, OUString::number(reinterpret_cast<sal_Int64>(&rLink)));
+    m_xTbLinks->set_text(nPos, aTxt, 0);
     if( OBJECT_CLIENT_GRF == rLink.GetObjType() )
-        aEntry += sFilter;
+        m_xTbLinks->set_text(nPos, sFilter, 1);
     else
-        aEntry += sLinkNm;
-    aEntry += "\t" + sTypeNm + "\t" + ImplGetStateStr( rLink );
-
-    SvTreeListEntry * pE = m_pTbLinks->InsertEntryToColumn( aEntry, nPos );
-    pE->SetUserData( const_cast<SvBaseLink *>(&rLink) );
-    if(bSelect)
-        m_pTbLinks->Select(pE);
+        m_xTbLinks->set_text(nPos, sLinkNm, 1);
+    m_xTbLinks->set_text(nPos, sTypeNm, 2);
+    m_xTbLinks->set_text(nPos, ImplGetStateStr(rLink), 3);
+    if (bSelect)
+        m_xTbLinks->select(nPos);
 }
 
-SvBaseLink* SvBaseLinksDlg::GetSelEntry( sal_uLong* pPos )
+SvBaseLink* SvBaseLinksDlg::GetSelEntry(int* pPos)
 {
-    SvTreeListEntry* pE = m_pTbLinks->FirstSelected();
-    sal_uLong nPos;
-    if( pE && TREELIST_ENTRY_NOTFOUND !=
-        ( nPos = m_pTbLinks->GetModel()->GetAbsPos( pE ) ) )
+    int nPos = m_xTbLinks->get_selected_index();
+    if (nPos != -1)
     {
-        DBG_ASSERT( pE, "Where does the empty entry come from?" );
-
-        if( pPos )
+        if (pPos)
             *pPos = nPos;
-        return static_cast<SvBaseLink*>(pE->GetUserData());
+        return reinterpret_cast<SvBaseLink*>(m_xTbLinks->get_id(nPos).toInt64());
     }
     return nullptr;
 }
 
-void SvBaseLinksDlg::SetType( SvBaseLink& rLink,
-                                    sal_uLong nSelPos,
-                                    SfxLinkUpdateMode nType )
+void SvBaseLinksDlg::SetType(SvBaseLink& rLink,
+                             int nSelPos,
+                             SfxLinkUpdateMode nType)
 {
     rLink.SetUpdateMode( nType );
     rLink.Update();
-    SvTreeListEntry* pBox = m_pTbLinks->GetEntry( nSelPos );
-    m_pTbLinks->SetEntryText( ImplGetStateStr( rLink ), pBox, 3 );
-    if( pLinkMgr->GetPersist() )
+    m_xTbLinks->set_text(nSelPos, ImplGetStateStr(rLink), 3);
+    if (pLinkMgr->GetPersist())
         pLinkMgr->GetPersist()->SetModified();
 }
 
@@ -680,7 +618,7 @@ void SvBaseLinksDlg::SetActLink( SvBaseLink const * pLink )
     if( pLinkMgr )
     {
         const SvBaseLinks& rLnks = pLinkMgr->GetLinks();
-        sal_uLong nSelect = 0;
+        int nSelect = 0;
         for(const auto & rLinkRef : rLnks)
         {
             // #109573# only visible links have been inserted into the TreeListBox,
@@ -689,11 +627,11 @@ void SvBaseLinksDlg::SetActLink( SvBaseLink const * pLink )
             {
                 if( pLink == rLinkRef.get() )
                 {
-                    m_pTbLinks->Select( m_pTbLinks->GetEntry( nSelect ) );
+                    m_xTbLinks->select(nSelect);
                     LinksSelectHdl( nullptr );
                     return ;
                 }
-                nSelect++;
+                ++nSelect;
             }
         }
     }
diff --git a/cui/source/factory/dlgfact.cxx b/cui/source/factory/dlgfact.cxx
index 483e4352be73..6a244b16daa5 100644
--- a/cui/source/factory/dlgfact.cxx
+++ b/cui/source/factory/dlgfact.cxx
@@ -248,7 +248,11 @@ short AbstractInsertObjectDialog_Impl::Execute()
     return m_xDlg->run();
 }
 
-IMPL_ABSTDLG_BASE(AbstractLinksDialog_Impl);
+short AbstractLinksDialog_Impl::Execute()
+{
+    return m_xDlg->run();
+}
+
 IMPL_ABSTDLG_BASE(AbstractSpellDialog_Impl);
 
 short AbstractSvxPostItDialog_Impl::Execute()
@@ -1580,12 +1584,12 @@ VclPtr<SfxAbstractPasteDialog> AbstractDialogFactory_Impl::CreatePasteDialog(wel
     return VclPtr<AbstractPasteDialog_Impl>::Create(std::make_unique<SvPasteObjectDialog>(pParent));
 }
 
-VclPtr<SfxAbstractLinksDialog> AbstractDialogFactory_Impl::CreateLinksDialog( vcl::Window* pParent, sfx2::LinkManager* pMgr, bool bHTML, sfx2::SvBaseLink* p)
+VclPtr<SfxAbstractLinksDialog> AbstractDialogFactory_Impl::CreateLinksDialog(weld::Window* pParent, sfx2::LinkManager* pMgr, bool bHTML, sfx2::SvBaseLink* p)
 {
-    VclPtrInstance<SvBaseLinksDlg> pLinkDlg( pParent, pMgr, bHTML );
-    if ( p )
-        pLinkDlg->SetActLink(p);
-    return VclPtr<AbstractLinksDialog_Impl>::Create( pLinkDlg );
+    auto xLinkDlg(std::make_unique<SvBaseLinksDlg>(pParent, pMgr, bHTML));
+    if (p)
+        xLinkDlg->SetActLink(p);
+    return VclPtr<AbstractLinksDialog_Impl>::Create(std::move(xLinkDlg));
 }
 
 VclPtr<SfxAbstractTabDialog> AbstractDialogFactory_Impl::CreateSvxFormatCellsDialog(weld::Window* pParent, const SfxItemSet* pAttr, const SdrModel& rModel, const SdrObject* /*pObj*/)
diff --git a/cui/source/factory/dlgfact.hxx b/cui/source/factory/dlgfact.hxx
index ed27c2c8b6c6..8d48168cf329 100644
--- a/cui/source/factory/dlgfact.hxx
+++ b/cui/source/factory/dlgfact.hxx
@@ -584,8 +584,14 @@ public:
 
 class AbstractLinksDialog_Impl : public SfxAbstractLinksDialog
 {
+protected:
+    std::unique_ptr<SvBaseLinksDlg> m_xDlg;
 public:
-    DECL_ABSTDLG_BASE(AbstractLinksDialog_Impl, SvBaseLinksDlg )
+    explicit AbstractLinksDialog_Impl(std::unique_ptr<SvBaseLinksDlg> p)
+        : m_xDlg(std::move(p))
+    {
+    }
+    virtual short Execute() override;
 };
 
 class SvxPostItDialog;
@@ -722,7 +728,7 @@ public:
     virtual VclPtr<VclAbstractDialog>      CreateEditObjectDialog(weld::Window* pParent, const OUString& rCommmand,
                                             const css::uno::Reference < css::embed::XEmbeddedObject >& xObj ) override;
     virtual VclPtr<SfxAbstractPasteDialog> CreatePasteDialog(weld::Window* pParent) override;
-    virtual VclPtr<SfxAbstractLinksDialog> CreateLinksDialog( vcl::Window* pParent, sfx2::LinkManager* pMgr, bool bHTML = false, sfx2::SvBaseLink* p=nullptr  ) override;
+    virtual VclPtr<SfxAbstractLinksDialog> CreateLinksDialog(weld::Window* pParent, sfx2::LinkManager* pMgr, bool bHTML = false, sfx2::SvBaseLink* p=nullptr) override;
 
     virtual VclPtr<AbstractHangulHanjaConversionDialog> CreateHangulHanjaConversionDialog( vcl::Window* _pParent,
                                             editeng::HangulHanjaConversion::ConversionDirection _ePrimaryDirection ) override;
diff --git a/cui/source/inc/linkdlg.hxx b/cui/source/inc/linkdlg.hxx
index 2e6f6fc2069e..5ef41e9b05e1 100644
--- a/cui/source/inc/linkdlg.hxx
+++ b/cui/source/inc/linkdlg.hxx
@@ -20,15 +20,9 @@
 #ifndef INCLUDED_CUI_SOURCE_INC_LINKDLG_HXX
 #define INCLUDED_CUI_SOURCE_INC_LINKDLG_HXX
 
-#include <vcl/dialog.hxx>
-#include <vcl/fixed.hxx>
-#include <vcl/button.hxx>
-#include <vcl/edit.hxx>
 #include <vcl/idle.hxx>
-#include <vcl/fixedhyper.hxx>
-
-#include <svtools/svmedit.hxx>
-#include <vcl/svtabbx.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/weld.hxx>
 
 /********************** SvUpdateLinksDialog ******************************
 *************************************************************************/
@@ -40,19 +34,8 @@ namespace sfx2
 
 enum class SfxLinkUpdateMode;
 
-class SvBaseLinksDlg : public ModalDialog
+class SvBaseLinksDlg : public weld::GenericDialogController
 {
-    using Window::SetType;
-
-    VclPtr<SvTabListBox> m_pTbLinks;
-    VclPtr<FixedHyperlink> m_pFtFullFileName;
-    VclPtr<FixedText> m_pFtFullSourceName;
-    VclPtr<FixedText> m_pFtFullTypeName;
-    VclPtr<RadioButton> m_pRbAutomatic;
-    VclPtr<RadioButton> m_pRbManual;
-    VclPtr<PushButton> m_pPbUpdateNow;
-    VclPtr<PushButton> m_pPbChangeSource;
-    VclPtr<PushButton> m_pPbBreakLink;
     OUString aStrAutolink;
     OUString aStrManuallink;
     OUString aStrBrokenlink;
@@ -62,26 +45,38 @@ class SvBaseLinksDlg : public ModalDialog
     sfx2::LinkManager*  pLinkMgr;
     Idle aUpdateIdle;
 
-    DECL_LINK( LinksSelectHdl, SvTreeListBox*, void );
-    DECL_LINK( LinksDoubleClickHdl, SvTreeListBox*, bool );
-    DECL_LINK( AutomaticClickHdl, Button *, void );
-    DECL_LINK( ManualClickHdl, Button *, void );
-    DECL_LINK( UpdateNowClickHdl, Button *, void);
-    DECL_LINK( ChangeSourceClickHdl, Button *, void );
-    DECL_LINK( BreakLinkClickHdl, Button *, void );
+    std::unique_ptr<weld::TreeView> m_xTbLinks;
+    std::unique_ptr<weld::LinkButton> m_xFtFullFileName;
+    std::unique_ptr<weld::Label> m_xFtFullSourceName;
+    std::unique_ptr<weld::Label> m_xFtFullTypeName;
+    std::unique_ptr<weld::RadioButton> m_xRbAutomatic;
+    std::unique_ptr<weld::RadioButton> m_xRbManual;
+    std::unique_ptr<weld::Button> m_xPbUpdateNow;
+    std::unique_ptr<weld::Button> m_xPbChangeSource;
+    std::unique_ptr<weld::Button> m_xPbBreakLink;
+
+    ScopedVclPtr<VirtualDevice> m_xVirDev;
+
+    DECL_LINK( LinksSelectHdl, weld::TreeView&, void );
+    DECL_LINK( LinksDoubleClickHdl, weld::TreeView&, void );
+    DECL_LINK( AutomaticClickHdl, weld::Button&, void );
+    DECL_LINK( ManualClickHdl, weld::Button&, void );
+    DECL_LINK( UpdateNowClickHdl, weld::Button&, void);
+    DECL_LINK( ChangeSourceClickHdl, weld::Button&, void );
+    DECL_LINK( BreakLinkClickHdl, weld::Button&, void );
     DECL_LINK( UpdateWaitingHdl, Timer *, void );
     DECL_LINK( EndEditHdl, sfx2::SvBaseLink&, void );
-    sfx2::SvBaseLink* GetSelEntry( sal_uLong* pPos );
+    void LinksSelectHdl(weld::TreeView* pTreeView);
+    sfx2::SvBaseLink* GetSelEntry(int* pPos);
     OUString ImplGetStateStr( const sfx2::SvBaseLink& );
-    void SetType( sfx2::SvBaseLink& rLink, sal_uLong nPos, SfxLinkUpdateMode nType );
-    void InsertEntry( const sfx2::SvBaseLink& rLink, sal_uLong nPos = TREELIST_APPEND, bool bSelect = false);
+    void SetType(sfx2::SvBaseLink& rLink, int nPos, SfxLinkUpdateMode nType);
+    void InsertEntry(const sfx2::SvBaseLink& rLink, int nPos = -1, bool bSelect = false);
 
     void SetManager( sfx2::LinkManager* );
 
 public:
-    SvBaseLinksDlg( vcl::Window * pParent, sfx2::LinkManager*, bool bHtml );
+    SvBaseLinksDlg(weld::Window * pParent, sfx2::LinkManager*, bool bHtml);
     virtual ~SvBaseLinksDlg() override;
-    virtual void dispose() override;
     void SetActLink( sfx2::SvBaseLink const * pLink );
 };
 
diff --git a/cui/uiconfig/ui/baselinksdialog.ui b/cui/uiconfig/ui/baselinksdialog.ui
index 2573d738bc06..512fc1cdfc50 100644
--- a/cui/uiconfig/ui/baselinksdialog.ui
+++ b/cui/uiconfig/ui/baselinksdialog.ui
@@ -1,29 +1,46 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.16.1 -->
+<!-- Generated with glade 3.22.1 -->
 <interface domain="cui">
   <requires lib="gtk+" version="3.18"/>
-  <requires lib="LibreOffice" version="1.0"/>
+  <object class="GtkTreeStore" id="liststore1">
+    <columns>
+      <!-- column-name text -->
+      <column type="gchararray"/>
+      <!-- column-name text2 -->
+      <column type="gchararray"/>
+      <!-- column-name text3 -->
+      <column type="gchararray"/>
+      <!-- column-name text4 -->
+      <column type="gchararray"/>
+      <!-- column-name id -->
+      <column type="gchararray"/>
+    </columns>
+  </object>
   <object class="GtkDialog" id="BaseLinksDialog">
     <property name="can_focus">False</property>
     <property name="border_width">6</property>
     <property name="title" translatable="yes" context="baselinksdialog|BaseLinksDialog">Edit Links</property>
+    <property name="modal">True</property>
+    <property name="default_width">0</property>
+    <property name="default_height">0</property>
     <property name="type_hint">dialog</property>
+    <child>
+      <placeholder/>
+    </child>
     <child internal-child="vbox">
       <object class="GtkBox" id="dialog-vbox1">
         <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
         <property name="spacing">12</property>
         <child internal-child="action_area">
           <object class="GtkButtonBox" id="dialog-action_area1">
             <property name="can_focus">False</property>
-            <property name="orientation">vertical</property>
-            <property name="layout_style">start</property>
+            <property name="layout_style">end</property>
             <child>
-              <object class="GtkButton" id="close">
-                <property name="label">gtk-close</property>
+              <object class="GtkButton" id="help">
+                <property name="label">gtk-help</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
-                <property name="can_default">True</property>
-                <property name="has_default">True</property>
                 <property name="receives_default">True</property>
                 <property name="use_stock">True</property>
               </object>
@@ -31,15 +48,16 @@
                 <property name="expand">False</property>
                 <property name="fill">True</property>
                 <property name="position">0</property>
+                <property name="secondary">True</property>
               </packing>
             </child>
             <child>
-              <object class="GtkButton" id="help">
-                <property name="label">gtk-help</property>
+              <object class="GtkButton" id="CHANGE_SOURCE">
+                <property name="label" translatable="yes" context="baselinksdialog|CHANGE_SOURCE">_Modify...</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
-                <property name="use_stock">True</property>
+                <property name="use_underline">True</property>
               </object>
               <packing>
                 <property name="expand">False</property>
@@ -48,8 +66,8 @@
               </packing>
             </child>
             <child>
-              <object class="GtkButton" id="UPDATE_NOW">
-                <property name="label" translatable="yes" context="baselinksdialog|UPDATE_NOW">_Update</property>
+              <object class="GtkButton" id="BREAK_LINK">
+                <property name="label" translatable="yes" context="baselinksdialog|BREAK_LINK">_Break Link</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
@@ -62,8 +80,8 @@
               </packing>
             </child>
             <child>
-              <object class="GtkButton" id="CHANGE_SOURCE">
-                <property name="label" translatable="yes" context="baselinksdialog|CHANGE_SOURCE">_Modify...</property>
+              <object class="GtkButton" id="UPDATE_NOW">
+                <property name="label" translatable="yes" context="baselinksdialog|UPDATE_NOW">_Update</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
@@ -76,12 +94,14 @@
               </packing>
             </child>
             <child>
-              <object class="GtkButton" id="BREAK_LINK">
-                <property name="label" translatable="yes" context="baselinksdialog|BREAK_LINK">_Break Link</property>
+              <object class="GtkButton" id="close">
+                <property name="label">gtk-close</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="has_default">True</property>
                 <property name="receives_default">True</property>
-                <property name="use_underline">True</property>
+                <property name="use_stock">True</property>
               </object>
               <packing>
                 <property name="expand">False</property>
@@ -113,88 +133,77 @@
                 <property name="orientation">vertical</property>
                 <property name="spacing">6</property>
                 <child>
-                  <object class="GtkGrid" id="grid1">
+                  <object class="GtkScrolledWindow">
                     <property name="visible">True</property>
-                    <property name="can_focus">False</property>
+                    <property name="can_focus">True</property>
                     <property name="hexpand">True</property>
-                    <property name="row_spacing">6</property>
-                    <property name="column_spacing">6</property>
-                    <child>
-                      <object class="GtkLabel" id="FILES">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="xalign">0</property>
-                        <property name="label" translatable="yes" context="baselinksdialog|FILES">Source file</property>
-                      </object>
-                      <packing>
-                        <property name="left_attach">0</property>
-                        <property name="top_attach">0</property>
-                        <property name="width">1</property>
-                        <property name="height">1</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="LINKS">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="xalign">0</property>
-                        <property name="label" translatable="yes" context="baselinksdialog|LINKS">Element:</property>
-                      </object>
-                      <packing>
-                        <property name="left_attach">1</property>
-                        <property name="top_attach">0</property>
-                        <property name="width">1</property>
-                        <property name="height">1</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="TYPE">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="xalign">0</property>
-                        <property name="label" translatable="yes" context="baselinksdialog|TYPE">Type</property>
-                      </object>
-                      <packing>
-                        <property name="left_attach">2</property>
-                        <property name="top_attach">0</property>
-                        <property name="width">1</property>
-                        <property name="height">1</property>
-                      </packing>
-                    </child>
+                    <property name="vexpand">True</property>
+                    <property name="shadow_type">in</property>
                     <child>
-                      <object class="GtkLabel" id="STATUS">
+                      <object class="GtkTreeView" id="TB_LINKS">
                         <property name="visible">True</property>
-                        <property name="can_focus">False</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
                         <property name="hexpand">True</property>
-                        <property name="xalign">0</property>
-                        <property name="label" translatable="yes" context="baselinksdialog|STATUS">Status</property>
-                      </object>
-                      <packing>
-                        <property name="left_attach">3</property>
-                        <property name="top_attach">0</property>
-                        <property name="width">1</property>
-                        <property name="height">1</property>
-                      </packing>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="vcllo-SvTabListBox" id="TB_LINKS:border">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="hexpand">True</property>
-                    <property name="vexpand">True</property>
-                    <child internal-child="selection">
-                      <object class="GtkTreeSelection" id="Tab List-selection1"/>
-                    </child>
-                    <child internal-child="accessible">
-                      <object class="AtkObject" id="TB_LINKS:border-atkobject">
-                        <property name="AtkObject::accessible-name" translatable="yes" context="baselinksdialog|TB_LINKS-atkobject">Edit Links</property>
+                        <property name="vexpand">True</property>
+                        <property name="model">liststore1</property>
+                        <property name="search_column">0</property>
+                        <property name="show_expanders">False</property>
+                        <child internal-child="selection">
+                          <object class="GtkTreeSelection" id="Macro Library List-selection1"/>
+                        </child>
+                        <child>
+                          <object class="GtkTreeViewColumn" id="treeviewcolumn0">
+                            <property name="resizable">True</property>
+                            <property name="spacing">6</property>
+                            <property name="title" translatable="yes" context="baselinksdialog|FILES">Source file</property>
+                            <child>
+                              <object class="GtkCellRendererText" id="cellrenderer0"/>
+                              <attributes>
+                                <attribute name="text">0</attribute>
+                              </attributes>
+                            </child>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+                            <property name="resizable">True</property>
+                            <property name="spacing">6</property>
+                            <property name="title" translatable="yes" context="baselinksdialog|LINKS">Element</property>
+                            <child>
+                              <object class="GtkCellRendererText" id="cellrenderer1"/>
+                              <attributes>
+                                <attribute name="text">1</attribute>
+                              </attributes>
+                            </child>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+                            <property name="resizable">True</property>
+                            <property name="spacing">6</property>
+                            <property name="title" translatable="yes" context="baselinksdialog|TYPE">Type</property>
+                            <child>
+                              <object class="GtkCellRendererText" id="cellrenderer2"/>
+                              <attributes>
+                                <attribute name="text">2</attribute>
+                              </attributes>
+                            </child>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkTreeViewColumn" id="treeviewcolumn3">
+                            <property name="resizable">True</property>
+                            <property name="spacing">6</property>
+                            <property name="title" translatable="yes" context="baselinksdialog|STATUS">Status</property>
+                            <child>
+                              <object class="GtkCellRendererText" id="cellrenderer3"/>
+                              <attributes>
+                                <attribute name="text">3</attribute>
+                              </attributes>
+                            </child>
+                          </object>
+                        </child>
                       </object>
                     </child>
                   </object>
@@ -222,58 +231,50 @@
                   <object class="GtkLabel" id="FILES2">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="xalign">0</property>
                     <property name="label" translatable="yes" context="baselinksdialog|FILES2">Source file</property>
                     <property name="use_underline">True</property>
-                    <property name="mnemonic_widget">TB_LINKS:border</property>
+                    <property name="mnemonic_widget">TB_LINKS</property>
+                    <property name="xalign">0</property>
                   </object>
                   <packing>
                     <property name="left_attach">0</property>
                     <property name="top_attach">0</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
                   </packing>
                 </child>
                 <child>
                   <object class="GtkLabel" id="SOURCE2">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="xalign">0</property>
                     <property name="label" translatable="yes" context="baselinksdialog|SOURCE2">Element:</property>
+                    <property name="xalign">0</property>
                   </object>
                   <packing>
                     <property name="left_attach">0</property>
                     <property name="top_attach">1</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
                   </packing>
                 </child>
                 <child>
                   <object class="GtkLabel" id="TYPE2">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="xalign">0</property>
                     <property name="label" translatable="yes" context="baselinksdialog|TYPE2">Type:</property>
+                    <property name="xalign">0</property>
                   </object>
                   <packing>
                     <property name="left_attach">0</property>
                     <property name="top_attach">2</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
                   </packing>
                 </child>
                 <child>
                   <object class="GtkLabel" id="UPDATE">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="xalign">0</property>
                     <property name="label" translatable="yes" context="baselinksdialog|UPDATE">Update:</property>
+                    <property name="xalign">0</property>
                   </object>
                   <packing>
                     <property name="left_attach">0</property>
                     <property name="top_attach">3</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
                   </packing>
                 </child>
                 <child>
@@ -285,30 +286,24 @@
                     <property name="spacing">6</property>
                     <child>
                       <object class="GtkLinkButton" id="FULL_FILE_NAME">
-                        <property name="label"></property>
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
+                        <property name="focus_on_click">False</property>
                         <property name="receives_default">True</property>
                         <property name="has_tooltip">True</property>
                         <property name="relief">none</property>
-                        <property name="focus_on_click">False</property>
                         <property name="xalign">0</property>
-                        <property name="uri"></property>
                       </object>
                       <packing>
-                        <property name="width">1</property>
-                        <property name="height">1</property>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
                       </packing>
                     </child>
                   </object>
                   <packing>
                     <property name="left_attach">1</property>
                     <property name="top_attach">0</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
                   </packing>
                 </child>
                 <child>
@@ -320,8 +315,6 @@
                   <packing>
                     <property name="left_attach">1</property>
                     <property name="top_attach">1</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
                   </packing>
                 </child>
                 <child>
@@ -333,8 +326,6 @@
                   <packing>
                     <property name="left_attach">1</property>
                     <property name="top_attach">2</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
                   </packing>
                 </child>
                 <child>
@@ -352,13 +343,10 @@
                         <property name="xalign">0</property>
                         <property name="active">True</property>
                         <property name="draw_indicator">True</property>
-                        <property name="group">MANUAL</property>
                       </object>
                       <packing>
                         <property name="left_attach">0</property>
                         <property name="top_attach">0</property>
-                        <property name="width">1</property>
-                        <property name="height">1</property>
                       </packing>
                     </child>
                     <child>
@@ -369,23 +357,18 @@
                         <property name="receives_default">False</property>
                         <property name="use_underline">True</property>
                         <property name="xalign">0</property>
-                        <property name="active">True</property>
                         <property name="draw_indicator">True</property>
                         <property name="group">AUTOMATIC</property>
                       </object>
                       <packing>
                         <property name="left_attach">1</property>
                         <property name="top_attach">0</property>
-                        <property name="width">1</property>
-                        <property name="height">1</property>
                       </packing>
                     </child>
                   </object>
                   <packing>
                     <property name="left_attach">1</property>
                     <property name="top_attach">3</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
                   </packing>
                 </child>
               </object>
@@ -405,11 +388,8 @@
       </object>
     </child>
     <action-widgets>
-      <action-widget response="-7">close</action-widget>
       <action-widget response="-11">help</action-widget>
-      <action-widget response="0">UPDATE_NOW</action-widget>
-      <action-widget response="0">CHANGE_SOURCE</action-widget>
-      <action-widget response="0">BREAK_LINK</action-widget>
+      <action-widget response="-7">close</action-widget>
     </action-widgets>
   </object>
 </interface>
diff --git a/extras/source/glade/libreoffice-catalog.xml.in b/extras/source/glade/libreoffice-catalog.xml.in
index eebb7938cbc2..3bf825820cd8 100644
--- a/extras/source/glade/libreoffice-catalog.xml.in
+++ b/extras/source/glade/libreoffice-catalog.xml.in
@@ -282,11 +282,8 @@
     <glade-widget-class title="Animation ListBox" name="sdlo-CustomAnimationList"
                         generic-name="Animation ListBox" parent="vcllo-SvTreeListBox"
                         icon-name="widget-gtk-treeview"/>
-    <glade-widget-class title="Tab List" name="vcllo-SvTabListBox"
-                        generic-name="Tab List" parent="vcllo-SvTreeListBox"
-                        icon-name="widget-gtk-treeview"/>
     <glade-widget-class title="CheckBox List" name="basctllo-CheckBox"
-                        generic-name="CheckBox List" parent="vcllo-SvTabListBox"
+                        generic-name="CheckBox List" parent="vcllo-SvTreeListBox"
                         icon-name="widget-gtk-treeview"/>
     <glade-widget-class title="Tooltip Tree List" name="swuilo-SwFldRefTreeListBox"
                         generic-name="Tooltip Tree List" parent="vcllo-SvTreeListBox"
diff --git a/include/sfx2/sfxdlg.hxx b/include/sfx2/sfxdlg.hxx
index 0a5fef9efb87..0fc11ca86fea 100644
--- a/include/sfx2/sfxdlg.hxx
+++ b/include/sfx2/sfxdlg.hxx
@@ -139,7 +139,7 @@ public:
     virtual VclPtr<VclAbstractDialog>          CreateEditObjectDialog(weld::Window* pParent, const OUString& rCommand,
             const css::uno::Reference < css::embed::XEmbeddedObject >& xObj )=0;
     virtual VclPtr<SfxAbstractPasteDialog>    CreatePasteDialog(weld::Window* pParent) = 0;
-    virtual VclPtr<SfxAbstractLinksDialog>    CreateLinksDialog( vcl::Window* pParent, sfx2::LinkManager* pMgr, bool bHTML=false, sfx2::SvBaseLink* p=nullptr )=0;
+    virtual VclPtr<SfxAbstractLinksDialog>    CreateLinksDialog(weld::Window* pParent, sfx2::LinkManager* pMgr, bool bHTML=false, sfx2::SvBaseLink* p=nullptr) = 0;
     virtual VclPtr<VclAbstractDialog>         CreateSvxScriptOrgDialog( vcl::Window* pParent,  const OUString& rLanguage ) = 0;
 
     virtual VclPtr<AbstractScriptSelectorDialog>
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index e4248c61a314..0e90ea50f2c5 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -158,6 +158,9 @@ public:
     virtual bool has_grab() const = 0;
     virtual void grab_remove() = 0;
 
+    // font size is in points, not pixels, e.g. see Window::[G]etPointFont
+    virtual vcl::Font get_font() = 0;
+
     //true for rtl, false otherwise
     virtual bool get_direction() const = 0;
     virtual void set_direction(bool bRTL) = 0;
@@ -608,6 +611,7 @@ public:
     virtual int get_height_rows(int nRows) const = 0;
 
     virtual void set_column_fixed_widths(const std::vector<int>& rWidths) = 0;
+    virtual int get_column_width(int nCol) const = 0;
     virtual OUString get_column_title(int nColumn) const = 0;
     virtual void set_column_title(int nColumn, const OUString& rTitle) = 0;
 
@@ -731,6 +735,24 @@ class VCL_DLLPUBLIC RadioButton : virtual public ToggleButton
 {
 };
 
+class VCL_DLLPUBLIC LinkButton : virtual public Container
+{
+protected:
+    Link<LinkButton&, void> m_aClickHdl;
+
+    void signal_clicked() { m_aClickHdl.Call(*this); }
+
+public:
+    virtual void set_label(const OUString& rText) = 0;
+    virtual OUString get_label() const = 0;
+    virtual void set_uri(const OUString& rUri) = 0;
+    virtual OUString get_uri() const = 0;
+
+    void clicked() { signal_clicked(); }
+
+    void connect_clicked(const Link<LinkButton&, void>& rLink) { m_aClickHdl = rLink; }
+};
+
 class VCL_DLLPUBLIC Scale : virtual public Widget
 {
 protected:
@@ -782,7 +804,7 @@ public:
     virtual bool get_editable() const = 0;
     virtual void set_error(bool bShowError) = 0;
 
-    virtual vcl::Font get_font() = 0;
+    // font size is in points, not pixels, e.g. see Window::[G]etPointFont
     virtual void set_font(const vcl::Font& rFont) = 0;
 
     void connect_changed(const Link<Entry&, void>& rLink) { m_aChangeHdl = rLink; }
@@ -1405,6 +1427,9 @@ public:
     virtual std::unique_ptr<CheckButton> weld_check_button(const OString& id,
                                                            bool bTakeOwnership = false)
         = 0;
+    virtual std::unique_ptr<LinkButton> weld_link_button(const OString& id,
+                                                         bool bTakeOwnership = false)
+        = 0;
     virtual std::unique_ptr<SpinButton> weld_spin_button(const OString& id,
                                                          bool bTakeOwnership = false)
         = 0;
diff --git a/sc/source/ui/view/tabvwshb.cxx b/sc/source/ui/view/tabvwshb.cxx
index 44861192705c..eb1dd71c30be 100644
--- a/sc/source/ui/view/tabvwshb.cxx
+++ b/sc/source/ui/view/tabvwshb.cxx
@@ -407,7 +407,7 @@ void ScTabViewShell::ExecDrawIns(SfxRequest& rReq)
         case SID_LINKS:
             {
                 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
-                ScopedVclPtr<SfxAbstractLinksDialog> pDlg(pFact->CreateLinksDialog( pWin, rDoc.GetLinkManager() ));
+                ScopedVclPtr<SfxAbstractLinksDialog> pDlg(pFact->CreateLinksDialog(pWin->GetFrameWeld(), rDoc.GetLinkManager()));
                 pDlg->Execute();
                 rBindings.Invalidate( nSlot );
                 SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScAreaLinksChanged ) );     // Navigator
diff --git a/sd/source/ui/func/fulink.cxx b/sd/source/ui/func/fulink.cxx
index 4a9027ac4b03..5b21bb3a0402 100644
--- a/sd/source/ui/func/fulink.cxx
+++ b/sd/source/ui/func/fulink.cxx
@@ -58,7 +58,7 @@ void FuLink::DoExecute( SfxRequest& )
     sfx2::LinkManager* pLinkManager = mpDoc->GetLinkManager();
 
     SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
-    ScopedVclPtr<SfxAbstractLinksDialog> pDlg(pFact->CreateLinksDialog( mpViewShell->GetActiveWindow(), pLinkManager ));
+    ScopedVclPtr<SfxAbstractLinksDialog> pDlg(pFact->CreateLinksDialog(mpViewShell->GetFrameWeld(), pLinkManager));
     pDlg->Execute();
     mpViewShell->GetViewFrame()->GetBindings().Invalidate( SID_MANAGE_LINKS );
 }
diff --git a/sw/source/uibase/shells/textfld.cxx b/sw/source/uibase/shells/textfld.cxx
index 23b295ead89c..5a278df6dd01 100644
--- a/sw/source/uibase/shells/textfld.cxx
+++ b/sw/source/uibase/shells/textfld.cxx
@@ -114,7 +114,6 @@ void SwTextShell::ExecField(SfxRequest &rReq)
     if(pArgs)
         pArgs->GetItemState(GetPool().GetWhich(nSlot), false, &pItem);
 
-    vcl::Window *pMDI = &GetView().GetViewFrame()->GetWindow();
     bool bMore = false;
     bool bIsText = true;
     sal_uInt16 nInsertType = 0;
@@ -137,7 +136,7 @@ void SwTextShell::ExecField(SfxRequest &rReq)
                         if(rLink.IsVisible())
                         {
                             SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
-                            ScopedVclPtr<SfxAbstractLinksDialog> pDlg(pFact->CreateLinksDialog( pMDI, &rSh.GetLinkManager(), false, &rLink ));
+                            ScopedVclPtr<SfxAbstractLinksDialog> pDlg(pFact->CreateLinksDialog(GetView().GetFrameWeld(), &rSh.GetLinkManager(), false, &rLink));
                             pDlg->Execute();
                         }
                         break;
diff --git a/sw/source/uibase/uiview/view2.cxx b/sw/source/uibase/uiview/view2.cxx
index 11ba7904f18d..8acdc25983ac 100644
--- a/sw/source/uibase/uiview/view2.cxx
+++ b/sw/source/uibase/uiview/view2.cxx
@@ -1906,7 +1906,7 @@ void SwView::EditLinkDlg()
 {
     bool bWeb = dynamic_cast<SwWebView*>( this ) !=  nullptr;
     SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
-    ScopedVclPtr<SfxAbstractLinksDialog> pDlg(pFact->CreateLinksDialog( &GetViewFrame()->GetWindow(), &GetWrtShell().GetLinkManager(), bWeb ));
+    ScopedVclPtr<SfxAbstractLinksDialog> pDlg(pFact->CreateLinksDialog(GetViewFrame()->GetWindow().GetFrameWeld(), &GetWrtShell().GetLinkManager(), bWeb));
     pDlg->Execute();
 }
 
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 4f54a0e18e86..230875e737f9 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -40,6 +40,7 @@
 #include <vcl/lstbox.hxx>
 #include <vcl/dialog.hxx>
 #include <vcl/fixed.hxx>
+#include <vcl/fixedhyper.hxx>
 #include <vcl/fmtfield.hxx>
 #include <vcl/headbar.hxx>
 #include <vcl/layout.hxx>
@@ -358,6 +359,11 @@ public:
         return Size(m_xWidget->GetTextWidth(rText), m_xWidget->GetTextHeight());
     }
 
+    virtual vcl::Font get_font() override
+    {
+        return m_xWidget->GetPointFont(*m_xWidget);
+    }
+
     virtual OString get_buildable_name() const override
     {
         return m_xWidget->get_id().toUtf8();
@@ -1491,6 +1497,51 @@ IMPL_LINK_NOARG(SalInstanceMenuButton, ActivateHdl, ::MenuButton*, void)
     signal_toggled();
 }
 
+class SalInstanceLinkButton : public SalInstanceContainer, public virtual weld::LinkButton
+{
+private:
+    VclPtr<FixedHyperlink> m_xButton;
+
+    DECL_LINK(ClickHdl, FixedHyperlink&, void);
+public:
+    SalInstanceLinkButton(FixedHyperlink* pButton, bool bTakeOwnership)
+        : SalInstanceContainer(pButton, bTakeOwnership)
+        , m_xButton(pButton)
+    {
+        m_xButton->SetClickHdl(LINK(this, SalInstanceLinkButton, ClickHdl));
+    }
+
+    virtual void set_label(const OUString& rText) override
+    {
+        m_xButton->SetText(rText);
+    }
+
+    virtual OUString get_label() const override
+    {
+        return m_xButton->GetText();
+    }
+
+    virtual void set_uri(const OUString& rUri) override
+    {
+        m_xButton->SetURL(rUri);
+    }
+
+    virtual OUString get_uri() const override
+    {
+        return m_xButton->GetURL();
+    }
+
+    virtual ~SalInstanceLinkButton() override
+    {
+        m_xButton->SetClickHdl(Link<FixedHyperlink&,void>());
+    }
+};
+
+IMPL_LINK_NOARG(SalInstanceLinkButton, ClickHdl, FixedHyperlink&, void)
+{
+    signal_clicked();
+}
+
 class SalInstanceRadioButton : public SalInstanceButton, public virtual weld::RadioButton
 {
 private:
@@ -1868,14 +1919,9 @@ public:
         }
     }
 
-    virtual vcl::Font get_font() override
-    {
-        return m_xEntry->GetFont();
-    }
-
     virtual void set_font(const vcl::Font& rFont) override
     {
-        m_xEntry->SetFont(rFont);
+        m_xEntry->SetPointFont(*m_xEntry, rFont);
         m_xEntry->Invalidate();
     }
 
@@ -1990,6 +2036,15 @@ public:
         m_xTreeView->Resize();
     }
 
+    virtual int get_column_width(int nColumn) const override
+    {
+        // GetTab(0) gives the position of the bitmap which is automatically inserted by the TabListBox.
+        // So the first text column's width is Tab(2)-Tab(1).
+        auto nWidthPixel = m_xTreeView->GetLogicTab(nColumn + 2) - m_xTreeView->GetLogicTab(nColumn + 1);
+        nWidthPixel -= SV_TAB_BORDER;
+        return nWidthPixel;
+    }
+
     virtual OUString get_column_title(int nColumn) const override
     {
         SvHeaderTabListBox* pHeaderBox = dynamic_cast<SvHeaderTabListBox*>(m_xTreeView.get());
@@ -3688,6 +3743,12 @@ public:
         return pButton ? std::make_unique<SalInstanceMenuButton>(pButton, bTakeOwnership) : nullptr;
     }
 
+    virtual std::unique_ptr<weld::LinkButton> weld_link_button(const OString &id, bool bTakeOwnership) override
+    {
+        FixedHyperlink* pButton = m_xBuilder->get<FixedHyperlink>(id);
+        return pButton ? std::make_unique<SalInstanceLinkButton>(pButton, bTakeOwnership) : nullptr;
+    }
+
     virtual std::unique_ptr<weld::ToggleButton> weld_toggle_button(const OString &id, bool bTakeOwnership) override
     {
         PushButton* pToggleButton = m_xBuilder->get<PushButton>(id);
diff --git a/vcl/source/treelist/svtabbx.cxx b/vcl/source/treelist/svtabbx.cxx
index 5b026ffbf195..e89ac8ad723a 100644
--- a/vcl/source/treelist/svtabbx.cxx
+++ b/vcl/source/treelist/svtabbx.cxx
@@ -98,8 +98,6 @@ SvTabListBox::SvTabListBox( vcl::Window* pParent, WinBits nBits )
     SetHighlightRange();    // select full width
 }
 
-VCL_BUILDER_FACTORY_CONSTRUCTOR(SvTabListBox, WB_TABSTOP)
-
 SvTabListBox::~SvTabListBox()
 {
     disposeOnce();
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 76132642c21a..35fe3d03a0f7 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -1402,6 +1402,13 @@ public:
         return Size(nWidth, nHeight);
     }
 
+    virtual vcl::Font get_font() override
+    {
+        PangoContext* pContext = gtk_widget_get_pango_context(m_pWidget);
+        return pango_to_vcl(pango_context_get_font_description(pContext),
+                            Application::GetSettings().GetUILanguageTag().getLocale());
+    }
+
     virtual void set_grid_left_attach(int nAttach) override
     {
         GtkContainer* pParent = GTK_CONTAINER(gtk_widget_get_parent(m_pWidget));
@@ -4411,6 +4418,66 @@ public:
     }
 };
 
+class GtkInstanceLinkButton : public GtkInstanceContainer, public virtual weld::LinkButton
+{
+private:
+    GtkLinkButton* m_pButton;
+    gulong m_nSignalId;
+
+    static void signalClicked(GtkButton*, gpointer widget)
+    {
+        GtkInstanceLinkButton* pThis = static_cast<GtkInstanceLinkButton*>(widget);
+        SolarMutexGuard aGuard;
+        pThis->signal_clicked();
+    }
+
+public:
+    GtkInstanceLinkButton(GtkLinkButton* pButton, bool bTakeOwnership)
+        : GtkInstanceContainer(GTK_CONTAINER(pButton), bTakeOwnership)
+        , m_pButton(pButton)
+        , m_nSignalId(g_signal_connect(pButton, "clicked", G_CALLBACK(signalClicked), this))
+    {
+    }
+
+    virtual void set_label(const OUString& rText) override
+    {
+        ::set_label(GTK_BUTTON(m_pButton), rText);
+    }
+
+    virtual OUString get_label() const override
+    {
+        return ::get_label(GTK_BUTTON(m_pButton));
+    }
+
+    virtual void set_uri(const OUString& rText) override
+    {
+        gtk_link_button_set_uri(m_pButton, OUStringToOString(rText, RTL_TEXTENCODING_UTF8).getStr());
+    }
+
+    virtual OUString get_uri() const override
+    {
+        const gchar* pStr = gtk_link_button_get_uri(m_pButton);
+        return OUString(pStr, pStr ? strlen(pStr) : 0, RTL_TEXTENCODING_UTF8);
+    }
+
+    virtual void disable_notify_events() override
+    {
+        g_signal_handler_block(m_pButton, m_nSignalId);
+        GtkInstanceContainer::disable_notify_events();
+    }
+
+    virtual void enable_notify_events() override
+    {
+        GtkInstanceContainer::enable_notify_events();
+        g_signal_handler_unblock(m_pButton, m_nSignalId);
+    }
+
+    virtual ~GtkInstanceLinkButton() override
+    {
+        g_signal_handler_disconnect(m_pButton, m_nSignalId);
+    }
+};
+
 class GtkInstanceRadioButton : public GtkInstanceToggleButton, public virtual weld::RadioButton
 {
 public:
@@ -4698,13 +4765,6 @@ public:
         g_signal_handler_unblock(m_pEntry, m_nActivateSignalId);
     }
 
-    virtual vcl::Font get_font() override
-    {
-        PangoContext* pContext = gtk_widget_get_pango_context(m_pWidget);
-        return pango_to_vcl(pango_context_get_font_description(pContext),
-                            Application::GetSettings().GetUILanguageTag().getLocale());
-    }
-
     virtual void set_font(const vcl::Font& rFont) override
     {
         PangoAttrList* pAttrList = pango_attr_list_new();
@@ -5256,6 +5316,13 @@ public:
         }
     }
 
+    virtual int get_column_width(int nColumn) const override
+    {
+        GtkTreeViewColumn* pColumn = GTK_TREE_VIEW_COLUMN(g_list_nth_data(m_pColumns, nColumn));
+        assert(pColumn && "wrong count");
+        return gtk_tree_view_column_get_fixed_width(pColumn) - gtk_tree_view_column_get_spacing(pColumn);
+    }
+
     virtual OUString get_column_title(int nColumn) const override
     {
         GtkTreeViewColumn* pColumn = GTK_TREE_VIEW_COLUMN(g_list_nth_data(m_pColumns, nColumn));
@@ -8072,6 +8139,15 @@ public:
         return std::make_unique<GtkInstanceMenuButton>(pButton, bTakeOwnership);
     }
 
+    virtual std::unique_ptr<weld::LinkButton> weld_link_button(const OString &id, bool bTakeOwnership) override
+    {
+        GtkLinkButton* pButton = GTK_LINK_BUTTON(gtk_builder_get_object(m_pBuilder, id.getStr()));
+        if (!pButton)
+            return nullptr;
+        auto_add_parentless_widgets_to_container(GTK_WIDGET(pButton));
+        return std::make_unique<GtkInstanceLinkButton>(pButton, bTakeOwnership);
+    }
+
     virtual std::unique_ptr<weld::ToggleButton> weld_toggle_button(const OString &id, bool bTakeOwnership) override
     {
         GtkToggleButton* pToggleButton = GTK_TOGGLE_BUTTON(gtk_builder_get_object(m_pBuilder, id.getStr()));


More information about the Libreoffice-commits mailing list