include/vcl/weld.hxx                           |    4 
 sw/qa/uitest/writer_tests2/exchangeDatabase.py |    4 
 sw/source/ui/dialog/swdlgfact.cxx              |    3 
 sw/source/ui/fldui/changedb.cxx                |  200 ++++++++---------
 sw/source/uibase/dbui/dbtree.cxx               |  286 +++++++++++++++++++++++++
 sw/source/uibase/inc/changedb.hxx              |   32 +-
 sw/source/uibase/inc/dbtree.hxx                |   35 +++
 sw/uiconfig/swriter/ui/exchangedatabases.ui    |  134 +++++++++--
 8 files changed, 555 insertions(+), 143 deletions(-)

New commits:
commit e6c422696fa1ee3f94642d94f7aca6743ad1e1e0
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Thu Feb 28 21:22:45 2019 +0000
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Fri Mar 1 22:23:26 2019 +0100

    weld SwChangeDBDlg
    
    Change-Id: Ie0fc6a6346f9c777b7172a0b641a2783cf633c1d
    Reviewed-on: https://gerrit.libreoffice.org/68544
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>
    Tested-by: Caolán McNamara <caol...@redhat.com>

diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 4802713bb086..6000bb53032c 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -552,6 +552,10 @@ public:
     {
         insert(pParent, -1, &rStr, &rId, &rImage, nullptr, nullptr, false, 
nullptr);
     }
+    void append(weld::TreeIter* pParent, const OUString& rStr)
+    {
+        insert(pParent, -1, &rStr, nullptr, nullptr, nullptr, nullptr, false, 
nullptr);
+    }
     void append(const OUString& rId, const OUString& rStr, VirtualDevice& 
rImage)
     {
         insert(nullptr, -1, &rStr, &rId, nullptr, &rImage, nullptr, false, 
nullptr);
diff --git a/sw/qa/uitest/writer_tests2/exchangeDatabase.py 
b/sw/qa/uitest/writer_tests2/exchangeDatabase.py
index 1697a1601add..d255bd15291b 100644
--- a/sw/qa/uitest/writer_tests2/exchangeDatabase.py
+++ b/sw/qa/uitest/writer_tests2/exchangeDatabase.py
@@ -42,7 +42,7 @@ class exchangeDB(UITestCase):
         xTreeEntry2 = xTreeEntry.getChild('0')                 #Available 
Databases
         xTreeEntry2.executeAction("SELECT", tuple())          #Click on the 
biblio
 
-        xDefineBtn = xExDBDlg.getChild("define")
+        xDefineBtn = xExDBDlg.getChild("ok")
         xDefineBtn.executeAction("CLICK", tuple())
 
         self.ui_test.execute_dialog_through_command(".uno:ChangeDatabaseField")
@@ -55,4 +55,4 @@ class exchangeDB(UITestCase):
 
         self.ui_test.close_doc()
 
-# vim: set shiftwidth=4 softtabstop=4 expandtab:
\ No newline at end of file
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/sw/source/ui/dialog/swdlgfact.cxx 
b/sw/source/ui/dialog/swdlgfact.cxx
index 656a6709bc37..b60c775de055 100644
--- a/sw/source/ui/dialog/swdlgfact.cxx
+++ b/sw/source/ui/dialog/swdlgfact.cxx
@@ -789,8 +789,7 @@ VclPtr<AbstractSwBreakDlg> 
SwAbstractDialogFactory_Impl::CreateSwBreakDlg(weld::
 VclPtr<VclAbstractDialog> 
SwAbstractDialogFactory_Impl::CreateSwChangeDBDlg(SwView& rVw)
 {
 #if HAVE_FEATURE_DBCONNECTIVITY
-    VclPtr<Dialog> pDlg = VclPtr<SwChangeDBDlg>::Create(rVw);
-    return VclPtr<VclAbstractDialog_Impl>::Create(pDlg);
+    return 
VclPtr<AbstractGenericDialog_Impl>::Create(std::make_unique<SwChangeDBDlg>(rVw));
 #else
     (void) rVw;
     return nullptr;
diff --git a/sw/source/ui/fldui/changedb.cxx b/sw/source/ui/fldui/changedb.cxx
index 54854cd99699..4ddfff329d92 100644
--- a/sw/source/ui/fldui/changedb.cxx
+++ b/sw/source/ui/fldui/changedb.cxx
@@ -50,35 +50,35 @@ using namespace ::com::sun::star::uno;
 
 // edit insert-field
 SwChangeDBDlg::SwChangeDBDlg(SwView const & rVw)
-    : SvxStandardDialog(&rVw.GetViewFrame()->GetWindow(), 
"ExchangeDatabasesDialog",
-        "modules/swriter/ui/exchangedatabases.ui")
+    : SfxDialogController(rVw.GetViewFrame()->GetWindow().GetFrameWeld(), 
"modules/swriter/ui/exchangedatabases.ui",
+                          "ExchangeDatabasesDialog")
     , pSh(rVw.GetWrtShellPtr())
+    , m_xUsedDBTLB(m_xBuilder->weld_tree_view("inuselb"))
+    , m_xAvailDBTLB(new DBTreeList(m_xBuilder->weld_tree_view("availablelb")))
+    , m_xAddDBPB(m_xBuilder->weld_button("browse"))
+    , m_xDocDBNameFT(m_xBuilder->weld_label("dbnameft"))
+    , m_xDefineBT(m_xBuilder->weld_button("ok"))
 {
-    get(m_pUsedDBTLB, "inuselb");
-    get(m_pAvailDBTLB, "availablelb");
-    get(m_pAddDBPB, "browse");
-    get(m_pDocDBNameFT, "dbnameft");
-    get(m_pDefineBT, "define");
-    m_pAvailDBTLB->SetWrtShell(*pSh);
+    int nWidth = m_xUsedDBTLB->get_approximate_digit_width() * 25;
+    int nHeight = m_xUsedDBTLB->get_height_rows(8);
+    m_xUsedDBTLB->set_size_request(nWidth, nHeight);
+    m_xAvailDBTLB->set_size_request(nWidth, nHeight);
+
+    m_xAvailDBTLB->SetWrtShell(*pSh);
     FillDBPopup();
 
     ShowDBName(pSh->GetDBData());
-    m_pDefineBT->SetClickHdl(LINK(this, SwChangeDBDlg, ButtonHdl));
-    m_pAddDBPB->SetClickHdl(LINK(this, SwChangeDBDlg, AddDBHdl));
-
-    m_pUsedDBTLB->SetSelectionMode(SelectionMode::Multiple);
-    
m_pUsedDBTLB->SetStyle(m_pUsedDBTLB->GetStyle()|WB_HASLINES|WB_CLIPCHILDREN|WB_SORT|WB_HASBUTTONS|WB_HASBUTTONSATROOT|WB_HSCROLL);
-    m_pUsedDBTLB->SetSpaceBetweenEntries(0);
-    m_pUsedDBTLB->SetNodeBitmaps(Image(StockImage::Yes, RID_BMP_COLLAPSE),
-                                 Image(StockImage::Yes, RID_BMP_EXPAND));
-
-    Link<SvTreeListBox*,void> aLink = LINK(this, SwChangeDBDlg, TreeSelectHdl);
-
-    m_pUsedDBTLB->SetSelectHdl(aLink);
-    m_pUsedDBTLB->SetDeselectHdl(aLink);
-    m_pAvailDBTLB->SetSelectHdl(aLink);
-    m_pAvailDBTLB->SetSelectHdl(aLink);
-    TreeSelectHdl(nullptr);
+    m_xDefineBT->connect_clicked(LINK(this, SwChangeDBDlg, ButtonHdl));
+    m_xAddDBPB->connect_clicked(LINK(this, SwChangeDBDlg, AddDBHdl));
+
+    m_xUsedDBTLB->set_selection_mode(SelectionMode::Multiple);
+    m_xUsedDBTLB->make_sorted();
+
+    Link<weld::TreeView&,void> aLink = LINK(this, SwChangeDBDlg, 
TreeSelectHdl);
+
+    m_xUsedDBTLB->connect_changed(aLink);
+    m_xAvailDBTLB->connect_changed(aLink);
+    TreeSelect();
 }
 
 // initialise database listboxes
@@ -87,7 +87,8 @@ void SwChangeDBDlg::FillDBPopup()
     Reference< XComponentContext > xContext( 
::comphelper::getProcessComponentContext() );
     Reference<XDatabaseContext> xDBContext = DatabaseContext::create(xContext);
     const SwDBData& rDBData = pSh->GetDBData();
-    m_pAvailDBTLB->Select(rDBData.sDataSource, rDBData.sCommand, OUString());
+    m_xAvailDBTLB->Select(rDBData.sDataSource, rDBData.sCommand, OUString());
+    TreeSelect();
 
     std::vector<OUString> aAllDBNames;
 
@@ -104,106 +105,101 @@ void SwChangeDBDlg::FillDBPopup()
     pSh->GetAllUsedDB( aDBNameList, &aAllDBNames );
 
     size_t nCount = aDBNameList.size();
-    m_pUsedDBTLB->Clear();
-    SvTreeListEntry *pFirst = nullptr;
-    SvTreeListEntry *pLast = nullptr;
+    m_xUsedDBTLB->clear();
+    std::unique_ptr<weld::TreeIter> xFirst;
 
     for(size_t k = 0; k < nCount; k++)
     {
-        pLast = Insert(aDBNameList[k].getToken(0, ';'));
-        if (!pFirst)
-            pFirst = pLast;
+        std::unique_ptr<weld::TreeIter> xLast = 
Insert(aDBNameList[k].getToken(0, ';'));
+        if (!xFirst)
+            xFirst = std::move(xLast);
     }
 
-    if (pFirst)
+    if (xFirst)
     {
-        m_pUsedDBTLB->MakeVisible(pFirst);
-        m_pUsedDBTLB->Select(pFirst);
+        m_xUsedDBTLB->expand_row(*xFirst);
+        m_xUsedDBTLB->scroll_to_row(*xFirst);
+        m_xUsedDBTLB->select(*xFirst);
     }
-
 }
 
-SvTreeListEntry* SwChangeDBDlg::Insert(const OUString& rDBName)
+std::unique_ptr<weld::TreeIter> SwChangeDBDlg::Insert(const OUString& rDBName)
 {
     sal_Int32 nIdx{ 0 };
     const OUString sDBName(rDBName.getToken(0, DB_DELIM, nIdx));
     const OUString sTableName(rDBName.getToken(0, DB_DELIM, nIdx));
-    sal_IntPtr nCommandType = rDBName.getToken(0, DB_DELIM, nIdx).toInt32();
-    SvTreeListEntry* pParent;
-    SvTreeListEntry* pChild;
-
-    sal_uLong nParent = 0;
-    sal_uLong nChild = 0;
-
-    Image aTableImg(StockImage::Yes, RID_BMP_DBTABLE);
-    Image aDBImg(StockImage::Yes, RID_BMP_DB);
-    Image aQueryImg(StockImage::Yes, RID_BMP_DBQUERY);
-    Image& rToInsert = nCommandType ? aQueryImg : aTableImg;
-    while ((pParent = m_pUsedDBTLB->GetEntry(nParent++)) != nullptr)
+    OUString sUserData = rDBName.getToken(0, DB_DELIM, nIdx);
+    sal_Int32 nCommandType = sUserData.toInt32();
+
+    OUString aTableImg(RID_BMP_DBTABLE);
+    OUString aDBImg(RID_BMP_DB);
+    OUString aQueryImg(RID_BMP_DBQUERY);
+    OUString& rToInsert = nCommandType ? aQueryImg : aTableImg;
+
+    std::unique_ptr<weld::TreeIter> xIter(m_xUsedDBTLB->make_iterator());
+    if (m_xUsedDBTLB->get_iter_first(*xIter))
     {
-        if (sDBName == m_pUsedDBTLB->GetEntryText(pParent))
+        do
         {
-            while ((pChild = m_pUsedDBTLB->GetEntry(pParent, nChild++)) != 
nullptr)
+            if (sDBName == m_xUsedDBTLB->get_text(*xIter))
             {
-                if (sTableName == m_pUsedDBTLB->GetEntryText(pChild))
-                    return pChild;
+                if (m_xUsedDBTLB->iter_children(*xIter))
+                {
+                    do
+                    {
+                        if (sTableName == m_xUsedDBTLB->get_text(*xIter))
+                            return xIter;
+                    } while (m_xUsedDBTLB->iter_next_sibling(*xIter));
+                    m_xUsedDBTLB->iter_parent(*xIter);
+                }
+                m_xUsedDBTLB->insert(xIter.get(), -1, &sTableName, &sUserData, 
nullptr, nullptr,
+                                     &rToInsert, false, xIter.get());
+                return xIter;
             }
-            SvTreeListEntry* pRet = m_pUsedDBTLB->InsertEntry(sTableName, 
rToInsert, rToInsert, pParent);
-            pRet->SetUserData(reinterpret_cast<void*>(nCommandType));
-            return pRet;
-        }
+        } while (m_xUsedDBTLB->iter_next_sibling(*xIter));
     }
-    pParent = m_pUsedDBTLB->InsertEntry(sDBName, aDBImg, aDBImg);
 
-    SvTreeListEntry* pRet = m_pUsedDBTLB->InsertEntry(sTableName, rToInsert, 
rToInsert, pParent);
-    pRet->SetUserData(reinterpret_cast<void*>(nCommandType));
-    return pRet;
+    m_xUsedDBTLB->insert(nullptr, -1, &sDBName, nullptr, nullptr, nullptr,
+                         &aDBImg, false, xIter.get());
+    m_xUsedDBTLB->insert(xIter.get(), -1, &sTableName, &sUserData, nullptr, 
nullptr,
+                         &rToInsert, false, xIter.get());
+    return xIter;
 }
 
 // destroy dialog
 SwChangeDBDlg::~SwChangeDBDlg()
 {
-    disposeOnce();
 }
 
-void SwChangeDBDlg::dispose()
+short SwChangeDBDlg::run()
 {
-    m_pUsedDBTLB.clear();
-    m_pAvailDBTLB.clear();
-    m_pAddDBPB.clear();
-    m_pDocDBNameFT.clear();
-    m_pDefineBT.clear();
-    SvxStandardDialog::dispose();
+    short nRet = SfxDialogController::run();
+    if (nRet == RET_OK)
+        UpdateFields();
+    return nRet;
 }
 
-// close
-void SwChangeDBDlg::Apply()
-{
-    UpdateFields();
-}
 void SwChangeDBDlg::UpdateFields()
 {
     std::vector<OUString> aDBNames;
-    aDBNames.reserve(m_pUsedDBTLB->GetSelectionCount());
-    SvTreeListEntry* pEntry = m_pUsedDBTLB->FirstSelected();
 
-    while( pEntry )
-    {
-        if( m_pUsedDBTLB->GetParent( pEntry ))
+    m_xUsedDBTLB->selected_foreach([this, &aDBNames](weld::TreeIter& rEntry){
+        if (m_xUsedDBTLB->get_iter_depth(rEntry))
         {
-            OUString sTmp(m_pUsedDBTLB->GetEntryText( m_pUsedDBTLB->GetParent( 
pEntry )) +
-                          OUStringLiteral1(DB_DELIM) + 
m_pUsedDBTLB->GetEntryText( pEntry ) + OUStringLiteral1(DB_DELIM) +
-                          
OUString::number(static_cast<int>(reinterpret_cast<sal_uLong>(pEntry->GetUserData()))));
+            std::unique_ptr<weld::TreeIter> 
xIter(m_xUsedDBTLB->make_iterator(&rEntry));
+            m_xUsedDBTLB->iter_parent(*xIter);
+            OUString sTmp(m_xUsedDBTLB->get_text(*xIter) +
+                          OUStringLiteral1(DB_DELIM) + 
m_xUsedDBTLB->get_text(rEntry) + OUStringLiteral1(DB_DELIM) +
+                          m_xUsedDBTLB->get_id(rEntry));
             aDBNames.push_back(sTmp);
         }
-        pEntry = m_pUsedDBTLB->NextSelected(pEntry);
-    }
+    });
 
     pSh->StartAllAction();
     OUString sTableName;
     OUString sColumnName;
     sal_Bool bIsTable = false;
-    const OUString DBName(m_pAvailDBTLB->GetDBName(sTableName, sColumnName, 
&bIsTable));
+    const OUString DBName(m_xAvailDBTLB->GetDBName(sTableName, sColumnName, 
&bIsTable));
     const OUString sTemp = DBName
         + OUStringLiteral1(DB_DELIM)
         + sTableName
@@ -215,52 +211,60 @@ void SwChangeDBDlg::UpdateFields()
     pSh->EndAllAction();
 }
 
-IMPL_LINK_NOARG(SwChangeDBDlg, ButtonHdl, Button*, void)
+IMPL_LINK_NOARG(SwChangeDBDlg, ButtonHdl, weld::Button&, void)
 {
     OUString sTableName;
     OUString sColumnName;
     SwDBData aData;
     sal_Bool bIsTable = false;
-    aData.sDataSource = m_pAvailDBTLB->GetDBName(sTableName, sColumnName, 
&bIsTable);
+    aData.sDataSource = m_xAvailDBTLB->GetDBName(sTableName, sColumnName, 
&bIsTable);
     aData.sCommand = sTableName;
     aData.nCommandType = bIsTable ? 0 : 1;
     pSh->ChgDBData(aData);
     ShowDBName(pSh->GetDBData());
-    EndDialog(RET_OK);
+    m_xDialog->response(RET_OK);
 }
 
-IMPL_LINK_NOARG(SwChangeDBDlg, TreeSelectHdl, SvTreeListBox*, void)
+IMPL_LINK_NOARG(SwChangeDBDlg, TreeSelectHdl, weld::TreeView&, void)
 {
-    SvTreeListEntry* pEntry = m_pAvailDBTLB->GetCurEntry();
+    TreeSelect();
+}
 
-    if (pEntry)
+void SwChangeDBDlg::TreeSelect()
+{
+    bool bEnable = false;
+    std::unique_ptr<weld::TreeIter> xIter(m_xAvailDBTLB->make_iterator());
+    if (m_xAvailDBTLB->get_selected(xIter.get()))
     {
-        bool bEnable = false;
-        if (m_pAvailDBTLB->GetParent(pEntry))
+        if (m_xAvailDBTLB->get_iter_depth(*xIter))
             bEnable = true;
-        m_pDefineBT->Enable( bEnable );
     }
+    m_xDefineBT->set_sensitive(bEnable);
 }
 
+
 // convert database name for display
 void SwChangeDBDlg::ShowDBName(const SwDBData& rDBData)
 {
     if (rDBData.sDataSource.isEmpty() && rDBData.sCommand.isEmpty())
     {
-        m_pDocDBNameFT->SetText(SwResId(SW_STR_NONE));
+        m_xDocDBNameFT->set_label(SwResId(SW_STR_NONE));
     }
     else
     {
         const OUString sName(rDBData.sDataSource + "." + rDBData.sCommand);
-        m_pDocDBNameFT->SetText(sName.replaceAll("~", "~~"));
+        m_xDocDBNameFT->set_label(sName.replaceAll("~", "~~"));
     }
 }
 
-IMPL_LINK_NOARG(SwChangeDBDlg, AddDBHdl, Button*, void)
+IMPL_LINK_NOARG(SwChangeDBDlg, AddDBHdl, weld::Button&, void)
 {
-    const OUString sNewDB = 
SwDBManager::LoadAndRegisterDataSource(GetFrameWeld());
+    const OUString sNewDB = 
SwDBManager::LoadAndRegisterDataSource(m_xDialog.get());
     if (!sNewDB.isEmpty())
-        m_pAvailDBTLB->AddDataSource(sNewDB);
+    {
+        m_xAvailDBTLB->AddDataSource(sNewDB);
+        TreeSelect();
+    }
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/dbui/dbtree.cxx b/sw/source/uibase/dbui/dbtree.cxx
index 8daa167434f5..34840d85261b 100644
--- a/sw/source/uibase/dbui/dbtree.cxx
+++ b/sw/source/uibase/dbui/dbtree.cxx
@@ -486,4 +486,290 @@ void SwDBTreeList::SetWrtShell(SwWrtShell& rSh)
         InitTreeList();
 }
 
+DBTreeList::DBTreeList(std::unique_ptr<weld::TreeView> xTreeView)
+    : bInitialized(false)
+    , bShowColumns(false)
+    , pImpl(new SwDBTreeList_Impl)
+    , m_xTreeView(std::move(xTreeView))
+{
+    m_xTreeView->connect_expanding(LINK(this, DBTreeList, 
RequestingChildrenHdl));
+#if 0
+    if (m_xTreeView->get_visible())
+        InitTreeList();
+#endif
+}
+
+DBTreeList::~DBTreeList()
+{
+}
+
+void DBTreeList::InitTreeList()
+{
+    if (!pImpl->HasContext() && pImpl->GetWrtShell())
+        return;
+
+//TODO    SetDragDropMode(DragDropMode::APP_COPY);
+
+//TODO    GetModel()->SetCompareHdl(LINK(this, DBTreeList, DBCompare));
+
+    Sequence< OUString > aDBNames = pImpl->GetContext()->getElementNames();
+    auto const sort = comphelper::string::NaturalStringSorter(
+        comphelper::getProcessComponentContext(),
+        Application::GetSettings().GetUILanguageTag().getLocale());
+    std::sort(
+        aDBNames.begin(), aDBNames.end(),
+        [&sort](OUString const & x, OUString const & y)
+        { return sort.compare(x, y) < 0; });
+    const OUString* pDBNames = aDBNames.getConstArray();
+    sal_Int32 nCount = aDBNames.getLength();
+
+    OUString aImg(RID_BMP_DB);
+    for (sal_Int32 i = 0; i < nCount; ++i)
+    {
+        OUString sDBName(pDBNames[i]);
+        Reference<XConnection> xConnection = pImpl->GetConnection(sDBName);
+        if (xConnection.is())
+        {
+            m_xTreeView->insert(nullptr, -1, &sDBName, nullptr, nullptr, 
nullptr, &aImg, true, nullptr);
+        }
+    }
+    Select(OUString(), OUString(), OUString());
+
+    bInitialized = true;
+}
+
+void DBTreeList::AddDataSource(const OUString& rSource)
+{
+    OUString aImg(RID_BMP_DB);
+    std::unique_ptr<weld::TreeIter> xIter(m_xTreeView->make_iterator());
+    m_xTreeView->insert(nullptr, -1, &rSource, nullptr, nullptr, nullptr, 
&aImg, true, xIter.get());
+    m_xTreeView->select(*xIter);
+}
+
+IMPL_LINK(DBTreeList, RequestingChildrenHdl, weld::TreeIter&, rParent, bool)
+{
+    if (!m_xTreeView->iter_has_child(rParent))
+    {
+        if (m_xTreeView->get_iter_depth(rParent)) // column names
+        {
+            try
+            {
+                std::unique_ptr<weld::TreeIter> 
xGrandParent(m_xTreeView->make_iterator(&rParent));
+                m_xTreeView->iter_parent(*xGrandParent);
+                OUString sSourceName = m_xTreeView->get_text(*xGrandParent);
+                OUString sTableName = m_xTreeView->get_text(rParent);
+
+                if(!pImpl->GetContext()->hasByName(sSourceName))
+                    return true;
+                Reference<XConnection> xConnection = 
pImpl->GetConnection(sSourceName);
+                bool bTable = m_xTreeView->get_id(rParent).isEmpty();
+                Reference<XColumnsSupplier> xColsSupplier;
+                if(bTable)
+                {
+                    Reference<XTablesSupplier> xTSupplier(xConnection, 
UNO_QUERY);
+                    if(xTSupplier.is())
+                    {
+                        Reference<XNameAccess> xTables = 
xTSupplier->getTables();
+                        OSL_ENSURE(xTables->hasByName(sTableName), "table not 
available anymore?");
+                        try
+                        {
+                            Any aTable = xTables->getByName(sTableName);
+                            Reference<XPropertySet> xPropSet;
+                            aTable >>= xPropSet;
+                            xColsSupplier.set(xPropSet, UNO_QUERY);
+                        }
+                        catch (const Exception&)
+                        {
+                        }
+                    }
+                }
+                else
+                {
+                    Reference<XQueriesSupplier> xQSupplier(xConnection, 
UNO_QUERY);
+                    if(xQSupplier.is())
+                    {
+                        Reference<XNameAccess> xQueries = 
xQSupplier->getQueries();
+                        OSL_ENSURE(xQueries->hasByName(sTableName), "table not 
available anymore?");
+                        try
+                        {
+                            Any aQuery = xQueries->getByName(sTableName);
+                            Reference<XPropertySet> xPropSet;
+                            aQuery >>= xPropSet;
+                            xColsSupplier.set(xPropSet, UNO_QUERY);
+                        }
+                        catch (const Exception&)
+                        {
+                        }
+                    }
+                }
+
+                if(xColsSupplier.is())
+                {
+                    Reference <XNameAccess> xCols = 
xColsSupplier->getColumns();
+                    Sequence< OUString> aColNames = xCols->getElementNames();
+                    const OUString* pColNames = aColNames.getConstArray();
+                    long nCount = aColNames.getLength();
+                    for (long i = 0; i < nCount; i++)
+                    {
+                        OUString sName = pColNames[i];
+                        m_xTreeView->append(&rParent, sName);
+                    }
+                }
+            }
+            catch (const Exception&)
+            {
+            }
+        }
+        else    // table names
+        {
+            try
+            {
+                OUString sSourceName = m_xTreeView->get_text(rParent);
+                if (!pImpl->GetContext()->hasByName(sSourceName))
+                    return true;
+                Reference<XConnection> xConnection = 
pImpl->GetConnection(sSourceName);
+                if (xConnection.is())
+                {
+                    Reference<XTablesSupplier> xTSupplier(xConnection, 
UNO_QUERY);
+                    if(xTSupplier.is())
+                    {
+                        Reference<XNameAccess> xTables = 
xTSupplier->getTables();
+                        Sequence< OUString> aTableNames = 
xTables->getElementNames();
+                        OUString sTableName;
+                        long nCount = aTableNames.getLength();
+                        const OUString* pTableNames = 
aTableNames.getConstArray();
+                        OUString aImg(RID_BMP_DBTABLE);
+                        for (long i = 0; i < nCount; i++)
+                        {
+                            sTableName = pTableNames[i];
+                            m_xTreeView->insert(&rParent, -1, &sTableName, 
nullptr,
+                                                nullptr, nullptr, &aImg, 
bShowColumns, nullptr);
+                        }
+                    }
+
+                    Reference<XQueriesSupplier> xQSupplier(xConnection, 
UNO_QUERY);
+                    if(xQSupplier.is())
+                    {
+                        Reference<XNameAccess> xQueries = 
xQSupplier->getQueries();
+                        Sequence< OUString> aQueryNames = 
xQueries->getElementNames();
+                        OUString sQueryName;
+                        long nCount = aQueryNames.getLength();
+                        const OUString* pQueryNames = 
aQueryNames.getConstArray();
+                        OUString aImg(RID_BMP_DBQUERY);
+                        for (long i = 0; i < nCount; i++)
+                        {
+                            sQueryName = pQueryNames[i];
+                            //to discriminate between queries and tables the 
user data of query entries is set
+                            OUString sId(OUString::number(1));
+                            m_xTreeView->insert(&rParent, -1, &sQueryName, 
&sId,
+                                                nullptr, nullptr, &aImg, 
bShowColumns, nullptr);
+                        }
+                    }
+                }
+            }
+            catch (const Exception&)
+            {
+            }
+        }
+    }
+    return true;
+}
+
+#if 0
+IMPL_LINK( DBTreeList, DBCompare, const SvSortData&, rData, sal_Int32 )
+{
+    SvTreeListEntry* pRight = const_cast<SvTreeListEntry*>(rData.pRight);
+
+    if (GetParent(pRight) && GetParent(GetParent(pRight)))
+        return 1; // don't sort column names
+
+    return DefaultCompare(rData);   // otherwise call base class
+}
+#endif
+
+OUString DBTreeList::GetDBName(OUString& rTableName, OUString& rColumnName, 
sal_Bool* pbIsTable)
+{
+    OUString sDBName;
+    std::unique_ptr<weld::TreeIter> xIter(m_xTreeView->make_iterator());
+    if (m_xTreeView->get_selected(xIter.get()) && 
m_xTreeView->get_iter_depth(*xIter))
+    {
+        if (m_xTreeView->get_iter_depth(*xIter) > 2)
+        {
+            rColumnName = m_xTreeView->get_text(*xIter);
+            m_xTreeView->iter_parent(*xIter); // column name was selected
+        }
+        if (pbIsTable)
+        {
+            *pbIsTable = m_xTreeView->get_id(*xIter).isEmpty();
+        }
+        rTableName = m_xTreeView->get_text(*xIter);
+        m_xTreeView->iter_parent(*xIter);
+        sDBName = m_xTreeView->get_text(*xIter);
+    }
+    return sDBName;
+}
+
+// Format: database.table
+void DBTreeList::Select(const OUString& rDBName, const OUString& rTableName, 
const OUString& rColumnName)
+{
+    std::unique_ptr<weld::TreeIter> xParent(m_xTreeView->make_iterator());
+    if (!m_xTreeView->get_iter_first(*xParent))
+        return;
+
+    do
+    {
+        if (rDBName == m_xTreeView->get_text(*xParent))
+        {
+            if (!m_xTreeView->iter_has_child(*xParent))
+                m_xTreeView->expand_row(*xParent);
+            std::unique_ptr<weld::TreeIter> 
xChild(m_xTreeView->make_iterator(xParent.get()));
+            if (!m_xTreeView->iter_children(*xChild))
+                continue;
+            do
+            {
+                if (rTableName == m_xTreeView->get_text(*xChild))
+                {
+                    m_xTreeView->copy_iterator(*xChild, *xParent);
+
+                    bool bNoChild = false;
+                    if (bShowColumns && !rColumnName.isEmpty())
+                    {
+                        if (!m_xTreeView->iter_has_child(*xParent))
+                            m_xTreeView->expand_row(*xParent);
+
+                        bNoChild = true;
+                        if (m_xTreeView->iter_children(*xChild))
+                        {
+                            do
+                            {
+                                if (rColumnName == 
m_xTreeView->get_text(*xChild))
+                                {
+                                    bNoChild = false;
+                                    break;
+                                }
+                            }
+                            while (m_xTreeView->iter_next_sibling(*xChild));
+                        }
+                    }
+
+                    if (bNoChild)
+                        m_xTreeView->copy_iterator(*xParent, *xChild);
+
+                    m_xTreeView->scroll_to_row(*xChild);
+                    m_xTreeView->select(*xChild);
+                    return;
+                }
+            }
+            while (m_xTreeView->iter_next_sibling(*xChild));
+        }
+    } while (m_xTreeView->iter_next_sibling(*xParent));
+}
+
+void DBTreeList::SetWrtShell(SwWrtShell& rSh)
+{
+    pImpl->SetWrtShell(rSh);
+    if (m_xTreeView->get_visible() && !bInitialized)
+        InitTreeList();
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/inc/changedb.hxx 
b/sw/source/uibase/inc/changedb.hxx
index b2563f0e85c8..9beae0bb1a76 100644
--- a/sw/source/uibase/inc/changedb.hxx
+++ b/sw/source/uibase/inc/changedb.hxx
@@ -19,11 +19,8 @@
 #ifndef INCLUDED_SW_SOURCE_UIBASE_INC_CHANGEDB_HXX
 #define INCLUDED_SW_SOURCE_UIBASE_INC_CHANGEDB_HXX
 
-#include <vcl/bitmap.hxx>
-#include <vcl/button.hxx>
-#include <vcl/fixed.hxx>
-#include <vcl/treelistbox.hxx>
 #include <svx/stddlg.hxx>
+#include <vcl/weld.hxx>
 #include "dbtree.hxx"
 
 class SwFieldMgr;
@@ -32,30 +29,31 @@ class SwWrtShell;
 struct SwDBData;
 
 // exchange database at fields
-class SwChangeDBDlg: public SvxStandardDialog
+class SwChangeDBDlg : public SfxDialogController
 {
-    VclPtr<SvTreeListBox>  m_pUsedDBTLB;
-    VclPtr<SwDBTreeList>   m_pAvailDBTLB;
-    VclPtr<PushButton>     m_pAddDBPB;
-    VclPtr<FixedText>      m_pDocDBNameFT;
-    VclPtr<PushButton>     m_pDefineBT;
-
     SwWrtShell      *pSh;
 
-    DECL_LINK(TreeSelectHdl, SvTreeListBox*, void);
-    DECL_LINK(ButtonHdl, Button*, void);
-    DECL_LINK(AddDBHdl, Button*, void);
+    std::unique_ptr<weld::TreeView> m_xUsedDBTLB;
+    std::unique_ptr<DBTreeList> m_xAvailDBTLB;
+    std::unique_ptr<weld::Button> m_xAddDBPB;
+    std::unique_ptr<weld::Label> m_xDocDBNameFT;
+    std::unique_ptr<weld::Button> m_xDefineBT;
+
+    void TreeSelect();
+
+    DECL_LINK(TreeSelectHdl, weld::TreeView&, void);
+    DECL_LINK(ButtonHdl, weld::Button&, void);
+    DECL_LINK(AddDBHdl, weld::Button&, void);
 
-    virtual void    Apply() override;
     void            UpdateFields();
     void            FillDBPopup();
-    SvTreeListEntry*    Insert(const OUString& rDBName);
+    std::unique_ptr<weld::TreeIter> Insert(const OUString& rDBName);
     void            ShowDBName(const SwDBData& rDBData);
 
 public:
     SwChangeDBDlg(SwView const & rVw);
+    virtual short run() override;
     virtual ~SwChangeDBDlg() override;
-    virtual void dispose() override;
 };
 
 #endif
diff --git a/sw/source/uibase/inc/dbtree.hxx b/sw/source/uibase/inc/dbtree.hxx
index 333f850d2137..c9634b6ed7a7 100644
--- a/sw/source/uibase/inc/dbtree.hxx
+++ b/sw/source/uibase/inc/dbtree.hxx
@@ -21,6 +21,7 @@
 
 #include <memory>
 #include <vcl/treelistbox.hxx>
+#include <vcl/weld.hxx>
 
 #include <swdllapi.h>
 #include <swtypes.hxx>
@@ -62,6 +63,40 @@ public:
     void    AddDataSource(const OUString& rSource);
 };
 
+class SW_DLLPUBLIC DBTreeList
+{
+    bool            bInitialized;
+    bool            bShowColumns;
+
+    rtl::Reference<SwDBTreeList_Impl> pImpl;
+    std::unique_ptr<weld::TreeView> m_xTreeView;
+#if 0
+
+    DECL_DLLPRIVATE_LINK( DBCompare, const SvSortData&, sal_Int32 );
+#endif
+    DECL_DLLPRIVATE_LINK(RequestingChildrenHdl, weld::TreeIter&, bool);
+    SAL_DLLPRIVATE void          InitTreeList();
+
+public:
+    DBTreeList(std::unique_ptr<weld::TreeView> xTreeView);
+    ~DBTreeList();
+
+    OUString GetDBName(OUString& rTableName, OUString& rColumnName, sal_Bool* 
pbIsTable = nullptr);
+
+    void    Select( const OUString& rDBName, const OUString& rTableName,
+                    const OUString& rColumnName );
+
+    void    SetWrtShell(SwWrtShell& rSh);
+
+    void    AddDataSource(const OUString& rSource);
+
+    void connect_changed(const Link<weld::TreeView&, void>& rLink) { 
m_xTreeView->connect_changed(rLink); }
+    std::unique_ptr<weld::TreeIter> make_iterator(const weld::TreeIter* pOrig 
= nullptr) const { return m_xTreeView->make_iterator(pOrig); }
+    bool get_selected(weld::TreeIter* pIter) const { return 
m_xTreeView->get_selected(pIter); }
+    int get_iter_depth(const weld::TreeIter& rIter) const { return 
m_xTreeView->get_iter_depth(rIter); }
+    void set_size_request(int nWidth, int nHeight) { 
m_xTreeView->set_size_request(nWidth, nHeight); }
+};
+
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/uiconfig/swriter/ui/exchangedatabases.ui 
b/sw/uiconfig/swriter/ui/exchangedatabases.ui
index d2a44868d106..44f3285cda33 100644
--- a/sw/uiconfig/swriter/ui/exchangedatabases.ui
+++ b/sw/uiconfig/swriter/ui/exchangedatabases.ui
@@ -1,12 +1,35 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.16.0 -->
+<!-- Generated with glade 3.22.1 -->
 <interface domain="sw">
   <requires lib="gtk+" version="3.18"/>
+  <object class="GtkTreeStore" id="liststore1">
+    <columns>
+      <!-- column-name expander -->
+      <column type="GdkPixbuf"/>
+      <!-- column-name text -->
+      <column type="gchararray"/>
+      <!-- column-name id -->
+      <column type="gchararray"/>
+    </columns>
+  </object>
+  <object class="GtkTreeStore" id="liststore2">
+    <columns>
+      <!-- column-name expander -->
+      <column type="GdkPixbuf"/>
+      <!-- column-name text -->
+      <column type="gchararray"/>
+      <!-- column-name id -->
+      <column type="gchararray"/>
+    </columns>
+  </object>
   <object class="GtkDialog" id="ExchangeDatabasesDialog">
     <property name="can_focus">False</property>
     <property name="border_width">6</property>
     <property name="title" translatable="yes" 
context="exchangedatabases|ExchangeDatabasesDialog">Exchange 
Databases</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>
@@ -17,7 +40,7 @@
             <property name="can_focus">False</property>
             <property name="layout_style">end</property>
             <child>
-              <object class="GtkButton" id="define">
+              <object class="GtkButton" id="ok">
                 <property name="label" translatable="yes" 
context="exchangedatabases|define">Define</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
@@ -57,6 +80,7 @@
                 <property name="expand">False</property>
                 <property name="fill">True</property>
                 <property name="position">2</property>
+                <property name="secondary">True</property>
               </packing>
             </child>
           </object>
@@ -102,32 +126,28 @@
                           <object class="GtkLabel" id="label5">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="xalign">0</property>
                             <property name="label" translatable="yes" 
context="exchangedatabases|label5">Databases in Use</property>
                             <property name="use_underline">True</property>
-                            <property 
name="mnemonic_widget">inuselb:border</property>
+                            <property name="mnemonic_widget">inuselb</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="label6">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="xalign">0</property>
                             <property name="label" translatable="yes" 
context="exchangedatabases|label6">_Available Databases</property>
                             <property name="use_underline">True</property>
-                            <property 
name="mnemonic_widget">availablelb:border</property>
+                            <property 
name="mnemonic_widget">availablelb</property>
+                            <property name="xalign">0</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>
@@ -142,8 +162,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>
@@ -152,45 +170,113 @@
                             <property name="can_focus">False</property>
                             <property name="margin_top">12</property>
                             <property name="margin_bottom">12</property>
-                            <property name="xalign">0</property>
                             <property name="label" translatable="yes" 
context="exchangedatabases|label7">Use this dialog to replace the databases you 
access in your document via database fields, with other databases. You can only 
make one change at a time. Multiple selection is possible in the list on the 
left.
 Use the browse button to select a database file.</property>
                             <property name="wrap">True</property>
+                            <property name="width_chars">72</property>
                             <property name="max_width_chars">72</property>
+                            <property name="xalign">0</property>
                           </object>
                           <packing>
                             <property name="left_attach">0</property>
                             <property name="top_attach">3</property>
                             <property name="width">2</property>
-                            <property name="height">1</property>
                           </packing>
                         </child>
                         <child>
-                          <object class="vcllo-SvTreeListBox" 
id="inuselb:border">
+                          <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="vexpand">True</property>
+                            <property name="shadow_type">in</property>
+                            <child>
+                              <object class="GtkTreeView" id="inuselb">
+                                <property name="width_request">-1</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property 
name="receives_default">True</property>
+                                <property name="hexpand">True</property>
+                                <property name="vexpand">True</property>
+                                <property name="model">liststore1</property>
+                                <property 
name="headers_visible">False</property>
+                                <property name="show_expanders">True</property>
+                                <property name="search_column">1</property>
+                                <property 
name="enable_tree_lines">True</property>
+                                <child internal-child="selection">
+                                  <object class="GtkTreeSelection" id="Macro 
Library List-selection1"/>
+                                </child>
+                                <child>
+                                  <object class="GtkTreeViewColumn" 
id="treeviewcolumn2">
+                                    <property name="spacing">6</property>
+                                    <child>
+                                      <object class="GtkCellRendererPixbuf" 
id="cellrenderertext4"/>
+                                      <attributes>
+                                        <attribute name="pixbuf">0</attribute>
+                                      </attributes>
+                                    </child>
+                                    <child>
+                                      <object class="GtkCellRendererText" 
id="cellrenderertext2"/>
+                                      <attributes>
+                                        <attribute name="text">1</attribute>
+                                      </attributes>
+                                    </child>
+                                  </object>
+                                </child>
+                              </object>
+                            </child>
                           </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="swlo-SwDBTreeList" 
id="availablelb:border">
+                          <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="vexpand">True</property>
+                            <property name="shadow_type">in</property>
+                            <child>
+                              <object class="GtkTreeView" id="availablelb">
+                                <property name="width_request">-1</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property 
name="receives_default">True</property>
+                                <property name="hexpand">True</property>
+                                <property name="vexpand">True</property>
+                                <property name="model">liststore2</property>
+                                <property 
name="headers_visible">False</property>
+                                <property name="show_expanders">True</property>
+                                <property name="search_column">1</property>
+                                <property 
name="enable_tree_lines">True</property>
+                                <child internal-child="selection">
+                                  <object class="GtkTreeSelection" id="Macro 
Library List-selection2"/>
+                                </child>
+                                <child>
+                                  <object class="GtkTreeViewColumn" 
id="treeviewcolumn8">
+                                    <property name="spacing">6</property>
+                                    <child>
+                                      <object class="GtkCellRendererPixbuf" 
id="cellrenderertext5"/>
+                                      <attributes>
+                                        <attribute name="pixbuf">0</attribute>
+                                      </attributes>
+                                    </child>
+                                    <child>
+                                      <object class="GtkCellRendererText" 
id="cellrenderertext6"/>
+                                      <attributes>
+                                        <attribute name="text">1</attribute>
+                                      </attributes>
+                                    </child>
+                                  </object>
+                                </child>
+                              </object>
+                            </child>
                           </object>
                           <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>
@@ -238,7 +324,7 @@ Use the browse button to select a database file.</property>
                   <object class="GtkLabel" id="dbnameft">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="label" 
translatable="no">DataSource.Command</property>
+                    <property name="label">DataSource.Command</property>
                   </object>
                   <packing>
                     <property name="expand">False</property>
@@ -263,7 +349,7 @@ Use the browse button to select a database file.</property>
       </object>
     </child>
     <action-widgets>
-      <action-widget response="0">define</action-widget>
+      <action-widget response="-5">ok</action-widget>
       <action-widget response="-7">close</action-widget>
       <action-widget response="-11">help</action-widget>
     </action-widgets>
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to