[Libreoffice-commits] core.git: Branch 'feature/jsdialogs' - 12 commits - cui/Library_cui.mk cui/source cui/uiconfig desktop/source editeng/source extras/source include/editeng include/sfx2 include/svx include/vcl sc/source sd/inc sd/source sfx2/source solenv/bin solenv/sanitizers svx/source svx/uiconfig sw/source vcl/jsdialog vcl/source vcl/unx

Szymon KÅ‚os (via logerrit) logerrit at kemper.freedesktop.org
Wed Apr 1 10:18:59 UTC 2020


Rebased ref, commits from common ancestor:
commit 5f5f2c30580b60bee4aba0a8c414c48088861d5d
Author:     Szymon Kłos <szymon.klos at collabora.com>
AuthorDate: Tue Mar 31 15:42:28 2020 +0200
Commit:     Szymon Kłos <szymon.klos at collabora.com>
CommitDate: Wed Apr 1 12:13:28 2020 +0200

    jsdialog: use Idle timer to send updates
    
    Change-Id: Ib4f18bab1279c622b576dca53169b40c4a2526bc

diff --git a/include/vcl/jsdialog/jsdialogbuilder.hxx b/include/vcl/jsdialog/jsdialogbuilder.hxx
index d01d878828c2..4a9b4e1d6fbc 100644
--- a/include/vcl/jsdialog/jsdialogbuilder.hxx
+++ b/include/vcl/jsdialog/jsdialogbuilder.hxx
@@ -14,12 +14,24 @@
 
 typedef std::map<OString, weld::Widget*> WidgetMap;
 
+class JSDialogNotifyIdle : public Idle
+{
+    VclPtr<vcl::Window> m_aWindow;
+    std::string m_LastNotificationMessage;
+
+public:
+    JSDialogNotifyIdle(VclPtr<vcl::Window> aWindow);
+
+    void Invoke() override;
+};
+
 class VCL_DLLPUBLIC JSDialogSender
 {
-    VclPtr<vcl::Window> m_aOwnedToplevel;
+    std::unique_ptr<JSDialogNotifyIdle> mpIdleNotify;
+
 public:
     JSDialogSender(VclPtr<vcl::Window> aOwnedToplevel)
-    : m_aOwnedToplevel(aOwnedToplevel)
+    : mpIdleNotify(new JSDialogNotifyIdle(aOwnedToplevel))
     {}
 
     void notifyDialogState();
diff --git a/vcl/jsdialog/jsdialogbuilder.cxx b/vcl/jsdialog/jsdialogbuilder.cxx
index 7db752b77045..bfc58fa09076 100644
--- a/vcl/jsdialog/jsdialogbuilder.cxx
+++ b/vcl/jsdialog/jsdialogbuilder.cxx
@@ -7,23 +7,47 @@
 
 using namespace weld;
 
-void JSDialogSender::notifyDialogState()
+JSDialogNotifyIdle::JSDialogNotifyIdle(VclPtr<vcl::Window> aWindow)
+: Idle("JSDialog notify")
+, m_aWindow(aWindow)
+, m_LastNotificationMessage()
 {
-    if (!m_aOwnedToplevel)
-        return;
+    SetPriority(TaskPriority::POST_PAINT);
+}
 
-    const vcl::ILibreOfficeKitNotifier* pNotifier = m_aOwnedToplevel->GetLOKNotifier();
-    if (pNotifier)
+void JSDialogNotifyIdle::Invoke()
+{
+    try
     {
-        std::stringstream aStream;
-        boost::property_tree::ptree aTree = m_aOwnedToplevel->DumpAsPropertyTree();
-        aTree.put("id", m_aOwnedToplevel->GetLOKWindowId());
-        boost::property_tree::write_json(aStream, aTree);
-        const std::string message = aStream.str();
-        pNotifier->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG, message.c_str());
+        if (!m_aWindow)
+            return;
+
+        const vcl::ILibreOfficeKitNotifier* pNotifier = m_aWindow->GetLOKNotifier();
+        if (pNotifier)
+        {
+            std::stringstream aStream;
+            boost::property_tree::ptree aTree = m_aWindow->DumpAsPropertyTree();
+            aTree.put("id", m_aWindow->GetLOKWindowId());
+            boost::property_tree::write_json(aStream, aTree);
+            const std::string message = aStream.str();
+            if (message != m_LastNotificationMessage)
+            {
+                m_LastNotificationMessage = message;
+                pNotifier->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG, message.c_str());
+            }
+        }
+    }
+    catch (boost::property_tree::json_parser::json_parser_error& rError)
+    {
+        SAL_WARN("vcl.jsdialog", rError.message());
     }
 }
 
+void JSDialogSender::notifyDialogState()
+{
+    mpIdleNotify->Start();
+}
+
 JSInstanceBuilder::JSInstanceBuilder(weld::Widget* pParent, const OUString& rUIRoot, const OUString& rUIFile)
         : SalInstanceBuilder(
             dynamic_cast<SalInstanceWidget*>(pParent) ?
commit e4328fa7d1a408739033bba87e59508e7955d140
Author:     Szymon Kłos <szymon.klos at collabora.com>
AuthorDate: Thu Mar 26 11:49:24 2020 +0100
Commit:     Szymon Kłos <szymon.klos at collabora.com>
CommitDate: Wed Apr 1 12:13:28 2020 +0200

    jsdialog: mobile version of spell dialog
    
    Change-Id: I611b09a8ffb6eb1972ba8702a7a76c9e6ab25fb4

diff --git a/cui/source/dialogs/SpellDialog.cxx b/cui/source/dialogs/SpellDialog.cxx
index 68ef370f65e7..416f2118b522 100644
--- a/cui/source/dialogs/SpellDialog.cxx
+++ b/cui/source/dialogs/SpellDialog.cxx
@@ -60,6 +60,8 @@
 #include <svtools/langtab.hxx>
 #include <cppuhelper/exc_hlp.hxx>
 #include <sal/log.hxx>
+#include <comphelper/lok.hxx>
+#include <sfx2/lokhelper.hxx>
 
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::uno;
@@ -192,9 +194,23 @@ SpellDialog::SpellDialog(SpellDialogChildWindow* pChildWindow,
     , m_xOptionsPB(m_xBuilder->weld_button("options"))
     , m_xUndoPB(m_xBuilder->weld_button("undo"))
     , m_xClosePB(m_xBuilder->weld_button("close"))
+    , m_xHelpPB(m_xBuilder->weld_button("help"))
     , m_xToolbar(m_xBuilder->weld_toolbar("toolbar"))
     , m_xSentenceEDWeld(new weld::CustomWeld(*m_xBuilder, "sentence", *m_xSentenceED))
+    , m_xMobileError(m_xBuilder->weld_label("mobile-spell-error"))
 {
+    m_xSentenceED->SetMobileErrorLabel(m_xMobileError);
+
+    if (comphelper::LibreOfficeKit::isActive()
+        && comphelper::LibreOfficeKit::isMobile(SfxLokHelper::getView()))
+    {
+        m_xClosePB->hide();
+        m_xHelpPB->hide();
+        m_xOptionsPB->hide();
+        m_xSentenceEDWeld->hide();
+        m_xMobileError->set_visible(true);
+    }
+
     m_xSentenceED->SetSpellDialog(this);
     m_xSentenceED->Init(m_xToolbar.get());
 
@@ -1667,6 +1683,8 @@ bool SentenceEditWindow_Impl::MarkNextError( bool bIgnoreCurrentError, const css
         if (pEECharAttrib)
         {
             ExtractErrorDescription(*pEECharAttrib, aSpellErrorDescription);
+            if (m_xMobileError)
+                m_xMobileError->set_label(aSpellErrorDescription.sErrorText);
 
             bGrammarError = aSpellErrorDescription.bIsGrammarError;
             m_nErrorStart = pEECharAttrib->nStart;
diff --git a/cui/source/inc/SpellDialog.hxx b/cui/source/inc/SpellDialog.hxx
index 30d8627084cb..92d4a9ed6391 100644
--- a/cui/source/inc/SpellDialog.hxx
+++ b/cui/source/inc/SpellDialog.hxx
@@ -65,6 +65,7 @@ class SentenceEditWindow_Impl : public weld::CustomWidgetController
 private:
     std::unique_ptr<EditEngine> m_xEditEngine;
     std::unique_ptr<EditView> m_xEdView;
+    std::shared_ptr<weld::Label> m_xMobileError;
 
     std::set<sal_Int32> m_aIgnoreErrorsAt;
     SpellDialog*        m_pSpellDialog;
@@ -155,6 +156,8 @@ public:
     void            MoveErrorEnd(long nOffset);
 
     void            ResetIgnoreErrorsAt()   { m_aIgnoreErrorsAt.clear(); }
+
+    void            SetMobileErrorLabel(std::shared_ptr<weld::Label> xMobileError) { m_xMobileError = xMobileError; }
 };
 
 // class SvxSpellDialog ---------------------------------------------
@@ -206,8 +209,10 @@ private:
     std::unique_ptr<weld::Button> m_xOptionsPB;
     std::unique_ptr<weld::Button> m_xUndoPB;
     std::unique_ptr<weld::Button> m_xClosePB;
+    std::unique_ptr<weld::Button> m_xHelpPB;
     std::unique_ptr<weld::Toolbar> m_xToolbar;
     std::unique_ptr<weld::CustomWeld> m_xSentenceEDWeld;
+    std::shared_ptr<weld::Label> m_xMobileError;
 
     DECL_LINK(ChangeHdl, weld::Button&, void);
     DECL_LINK(DoubleClickChangeHdl, weld::TreeView&, void);
diff --git a/cui/uiconfig/ui/spellingdialog.ui b/cui/uiconfig/ui/spellingdialog.ui
index ccc6a30e7a46..f80e6ec80d82 100644
--- a/cui/uiconfig/ui/spellingdialog.ui
+++ b/cui/uiconfig/ui/spellingdialog.ui
@@ -81,6 +81,7 @@
                 <property name="receives_default">True</property>
                 <property name="use_underline">True</property>
                 <property name="use_stock">True</property>
+                <property name="sensitive">False</property>
               </object>
               <packing>
                 <property name="expand">False</property>
@@ -425,6 +426,16 @@
                 <property name="top_attach">2</property>
               </packing>
             </child>
+            <child>
+              <object class="GtkLabel" id="mobile-spell-error">
+                <property name="visible">False</property>
+                <property name="can_focus">False</property>
+              </object>
+              <packing>
+                <property name="left_attach">2</property>
+                <property name="top_attach">2</property>
+              </packing>
+            </child>
             <child>
               <object class="GtkScrolledWindow">
                 <property name="visible">True</property>
diff --git a/solenv/sanitizers/ui/cui.suppr b/solenv/sanitizers/ui/cui.suppr
index 59f22233ff39..549954c47a90 100644
--- a/solenv/sanitizers/ui/cui.suppr
+++ b/solenv/sanitizers/ui/cui.suppr
@@ -460,6 +460,7 @@ cui/uiconfig/ui/spellingdialog.ui://GtkLabel[@id='explain'] orphan-label
 cui/uiconfig/ui/spellingdialog.ui://GtkLabel[@id='resumeft'] orphan-label
 cui/uiconfig/ui/spellingdialog.ui://GtkLabel[@id='nosuggestionsft'] orphan-label
 cui/uiconfig/ui/spellingdialog.ui://GtkLabel[@id='alttitleft'] orphan-label
+cui/uiconfig/ui/spellingdialog.ui://GtkLabel[@id='mobile-spell-error'] orphan-label
 cui/uiconfig/ui/storedwebconnectiondialog.ui://GtkLabel[@id='label1'] orphan-label
 cui/uiconfig/ui/storedwebconnectiondialog.ui://GtkLabel[@id='website'] orphan-label
 cui/uiconfig/ui/storedwebconnectiondialog.ui://GtkLabel[@id='username'] orphan-label
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index efd46f9adec0..d9786bc4d70b 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -154,6 +154,7 @@ weld::Builder* Application::CreateBuilder(weld::Widget* pParent, const OUString
             rUIFile == "modules/scalc/ui/validationcriteriapage.ui" ||
             rUIFile == "modules/scalc/ui/validationhelptabpage-mobile.ui" ||
             rUIFile == "modules/scalc/ui/erroralerttabpage-mobile.ui" ||
+            rUIFile == "cui/ui/spellingdialog.ui" ||
             rUIFile == "modules/swriter/ui/watermarkdialog.ui")
             bUseJSBuilder = true;
     }
commit c7acbd9f5e38682128b3d10614f815b215f909cb
Author:     Szymon Kłos <szymon.klos at collabora.com>
AuthorDate: Wed Mar 25 13:04:08 2020 +0100
Commit:     Szymon Kłos <szymon.klos at collabora.com>
CommitDate: Wed Apr 1 12:13:27 2020 +0200

    jsdialog: resend JSON only if changed
    
    Change-Id: I80a0faf7544c66e30576d2342315a1f9f508fc12

diff --git a/include/vcl/jsdialog/jsdialogbuilder.hxx b/include/vcl/jsdialog/jsdialogbuilder.hxx
index de9c383328a1..d01d878828c2 100644
--- a/include/vcl/jsdialog/jsdialogbuilder.hxx
+++ b/include/vcl/jsdialog/jsdialogbuilder.hxx
@@ -64,24 +64,21 @@ public:
     , JSDialogSender(aOwnedToplevel)
     {}
 
-    virtual void show() override
+    virtual void set_visible(bool visible) override
     {
-        BaseInstanceClass::show();
-        notifyDialogState();
-    }
-
-    virtual void hide() override
-    {
-        BaseInstanceClass::hide();
-        notifyDialogState();
+        bool change = visible != BaseInstanceClass::get_visible();
+        BaseInstanceClass::set_visible(visible);
+        if (change)
+            notifyDialogState();
     }
 
     virtual void set_sensitive(bool sensitive) override
     {
         bool change = sensitive != BaseInstanceClass::get_sensitive();
         BaseInstanceClass::set_sensitive(sensitive);
-        if (change)
+        if (change) {
             notifyDialogState();
+        }
     }
 };
 
diff --git a/vcl/jsdialog/jsdialogbuilder.cxx b/vcl/jsdialog/jsdialogbuilder.cxx
index dc84dbe814c2..7db752b77045 100644
--- a/vcl/jsdialog/jsdialogbuilder.cxx
+++ b/vcl/jsdialog/jsdialogbuilder.cxx
@@ -283,8 +283,10 @@ JSLabel::JSLabel(VclPtr<vcl::Window> aOwnedToplevel, FixedText* pLabel,
 
 void JSLabel::set_label(const OUString& rText)
 {
+    bool change = get_label() != rText;
     SalInstanceLabel::set_label(rText);
-    notifyDialogState();
+    if (change)
+        notifyDialogState();
 };
 
 JSButton::JSButton(VclPtr<vcl::Window> aOwnedToplevel, ::Button* pButton,
@@ -302,8 +304,10 @@ JSEntry::JSEntry(VclPtr<vcl::Window> aOwnedToplevel, ::Edit* pEntry,
 
 void JSEntry::set_text(const OUString& rText)
 {
+    bool change = get_text() != rText;
     SalInstanceEntry::set_text(rText);
-    notifyDialogState();
+    if (change)
+        notifyDialogState();
 }
 
 JSListBox::JSListBox(VclPtr<vcl::Window> aOwnedToplevel, ::ListBox* pListBox,
@@ -430,8 +434,10 @@ JSCheckButton::JSCheckButton(VclPtr<vcl::Window> aOwnedToplevel, ::CheckBox* pCh
 
 void JSCheckButton::set_state(TriState eState)
 {
+    bool change = get_state() != eState;
     SalInstanceCheckButton::set_state(eState);
-    notifyDialogState();
+    if (change)
+        notifyDialogState();
 }
 
 JSTreeView::JSTreeView(VclPtr<vcl::Window> aOwnedToplevel, ::SvTabListBox* pTreeView,
commit d5dbd0bb7a9e24ffe30c126c21409bfc7a197485
Author:     Szymon Kłos <szymon.klos at collabora.com>
AuthorDate: Thu Mar 26 13:31:04 2020 +0100
Commit:     Szymon Kłos <szymon.klos at collabora.com>
CommitDate: Wed Apr 1 12:13:27 2020 +0200

    jsdialog: weld spellcheck complete messagedialog
    
    Change-Id: I5c77bcba9f5f45b83da7f175f4f333cf20e65b11

diff --git a/sw/source/uibase/dialog/SwSpellDialogChildWindow.cxx b/sw/source/uibase/dialog/SwSpellDialogChildWindow.cxx
index 00d5ba9b2ce9..69328eb00886 100644
--- a/sw/source/uibase/dialog/SwSpellDialogChildWindow.cxx
+++ b/sw/source/uibase/dialog/SwSpellDialogChildWindow.cxx
@@ -52,6 +52,8 @@
 #include <unotextrange.hxx>
 #include <strings.hrc>
 #include <cmdid.h>
+#include <comphelper/lok.hxx>
+#include <sfx2/lokhelper.hxx>
 
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::uno;
@@ -376,6 +378,8 @@ The code below would only be part of the solution.
         // now only the rest of the body text can be spelled -
         // if the spelling started inside of the body
         bool bCloseMessage = true;
+        bool bMobile = comphelper::LibreOfficeKit::isActive()
+                        && comphelper::LibreOfficeKit::isMobile(SfxLokHelper::getView());
         if(aRet.empty() && !m_pSpellState->m_bStartedInSelection)
         {
             OSL_ENSURE(m_pSpellState->m_bDrawingsSpelled &&
@@ -385,7 +389,7 @@ The code below would only be part of the solution.
             {
                 LockFocusNotification( true );
                 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetController()->getDialog(),
-                                                                                        VclMessageType::Question, VclButtonsType::YesNo, SwResId(STR_QUERY_SPELL_CONTINUE)));
+                                                                                        VclMessageType::Question, VclButtonsType::YesNo, SwResId(STR_QUERY_SPELL_CONTINUE), bMobile));
                 sal_uInt16 nRet = xBox->run();
                 if (RET_YES == nRet)
                 {
@@ -417,7 +421,7 @@ The code below would only be part of the solution.
                 Application::CreateMessageDialog( xSpellController->getDialog(),
                                                   VclMessageType::Info,
                                                   VclButtonsType::Ok,
-                                                  sInfo ) );
+                                                  sInfo, bMobile ) );
             xBox->run();
             LockFocusNotification( false );
             // take care that the now valid selection is stored
commit 4b2e729197428366668413b06f398c42c5dbe2e7
Author:     Szymon Kłos <szymon.klos at collabora.com>
AuthorDate: Thu Mar 26 13:05:18 2020 +0100
Commit:     Szymon Kłos <szymon.klos at collabora.com>
CommitDate: Wed Apr 1 12:13:26 2020 +0200

    jsdialog: handle events for TreeView
    
    TreeView is presented as listbox/combobox
    
    Change-Id: I2273829d77bfc49c8536d2ef561dbab3a0fc1f9e

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 215979d0d5d0..b28e903daba1 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -3610,6 +3610,22 @@ static void doc_sendDialogEvent(LibreOfficeKitDocument* /*pThis*/, unsigned nWin
                         else
                             bContinueWithLOKWindow = true;
                     }
+                    else if (auto pTreeView = dynamic_cast<weld::TreeView*>(pWidget))
+                    {
+                        if (sAction == "selected")
+                        {
+                            int separatorPos = aMap["data"].indexOf(';');
+                            if (separatorPos)
+                            {
+                                OUString entryPos = aMap["data"].copy(0, separatorPos);
+                                OString posString = OUStringToOString(entryPos, RTL_TEXTENCODING_ASCII_US);
+                                int pos = std::atoi(posString.getStr());
+                                pTreeView->select(pos);
+                            }
+                        }
+                        else
+                            bContinueWithLOKWindow = true;
+                    }
                 }
                 else if (sControlType == "pushbutton")
                 {
commit 4ee0932b02c13d562dc0a34fe57409386475b49b
Author:     Szymon Kłos <szymon.klos at collabora.com>
AuthorDate: Thu Mar 26 12:59:22 2020 +0100
Commit:     Szymon Kłos <szymon.klos at collabora.com>
CommitDate: Wed Apr 1 12:13:26 2020 +0200

    jsdialog: weld TreeView
    
    Change-Id: Idd3a7a39622688d34fe7d7cbd2f446850b33a9aa

diff --git a/include/vcl/jsdialog/jsdialogbuilder.hxx b/include/vcl/jsdialog/jsdialogbuilder.hxx
index 6e7324edc6b9..de9c383328a1 100644
--- a/include/vcl/jsdialog/jsdialogbuilder.hxx
+++ b/include/vcl/jsdialog/jsdialogbuilder.hxx
@@ -10,6 +10,7 @@
 #include <vcl/combobox.hxx>
 #include <vcl/button.hxx>
 #include <vcl/fmtfield.hxx>
+#include <vcl/svtabbx.hxx>
 
 typedef std::map<OString, weld::Widget*> WidgetMap;
 
@@ -46,6 +47,7 @@ public:
     virtual std::unique_ptr<weld::Notebook> weld_notebook(const OString &id, bool bTakeOwnership = false) override;
     virtual std::unique_ptr<weld::SpinButton> weld_spin_button(const OString &id, bool bTakeOwnership = false) override;
     virtual std::unique_ptr<weld::CheckButton> weld_check_button(const OString &id, bool bTakeOwnership = false) override;
+    virtual std::unique_ptr<weld::TreeView> weld_tree_view(const OString &id, bool bTakeOwnership = false) override;
 
     static weld::MessageDialog* CreateMessageDialog(weld::Widget* pParent, VclMessageType eMessageType,
                                                      VclButtonsType eButtonType, const OUString& rPrimaryMessage);
@@ -182,4 +184,16 @@ public:
     virtual void set_state(TriState eState) override;
 };
 
+class VCL_DLLPUBLIC JSTreeView : public JSWidget<SalInstanceTreeView, ::SvTabListBox>
+{
+public:
+    JSTreeView(VclPtr<vcl::Window> aOwnedToplevel, ::SvTabListBox* pTreeView,
+                SalInstanceBuilder* pBuilder, bool bTakeOwnership);
+    virtual void insert(weld::TreeIter* pParent, int pos, const OUString* pStr, const OUString* pId,
+                        const OUString* pIconName, VirtualDevice* pImageSurface, const OUString* pExpanderName,
+                        bool bChildrenOnDemand) override;
+    virtual void remove(int pos) override;
+    virtual void select(int pos) override;
+};
+
 #endif
diff --git a/vcl/jsdialog/jsdialogbuilder.cxx b/vcl/jsdialog/jsdialogbuilder.cxx
index c0d56198bfdd..dc84dbe814c2 100644
--- a/vcl/jsdialog/jsdialogbuilder.cxx
+++ b/vcl/jsdialog/jsdialogbuilder.cxx
@@ -222,6 +222,19 @@ std::unique_ptr<weld::CheckButton> JSInstanceBuilder::weld_check_button(const OS
     return pWeldWidget;
 }
 
+std::unique_ptr<weld::TreeView> JSInstanceBuilder::weld_tree_view(const OString &id, bool bTakeOwnership)
+{
+    SvTabListBox* pTreeView = m_xBuilder->get<SvTabListBox>(id);
+    auto pWeldWidget = pTreeView ?
+            std::make_unique<JSTreeView>(m_bHasTopLevelDialog ? m_aOwnedToplevel : m_aParentDialog,
+                                            pTreeView, this, bTakeOwnership) : nullptr;
+
+    if (pWeldWidget)
+        RememberWidget(id, pWeldWidget.get());
+
+    return pWeldWidget;
+}
+
 weld::MessageDialog* JSInstanceBuilder::CreateMessageDialog(weld::Widget* pParent, VclMessageType eMessageType,
                                                      VclButtonsType eButtonType, const OUString& rPrimaryMessage)
 {
@@ -420,3 +433,30 @@ void JSCheckButton::set_state(TriState eState)
     SalInstanceCheckButton::set_state(eState);
     notifyDialogState();
 }
+
+JSTreeView::JSTreeView(VclPtr<vcl::Window> aOwnedToplevel, ::SvTabListBox* pTreeView,
+                SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+: JSWidget<SalInstanceTreeView, ::SvTabListBox>(aOwnedToplevel, pTreeView, pBuilder, bTakeOwnership)
+{
+}
+
+void JSTreeView::insert(weld::TreeIter* pParent, int pos, const OUString* pStr, const OUString* pId,
+                        const OUString* pIconName, VirtualDevice* pImageSurface, const OUString* pExpanderName,
+                        bool bChildrenOnDemand)
+{
+    SalInstanceTreeView::insert(pParent, pos, pStr, pId,
+                        pIconName, pImageSurface, pExpanderName, bChildrenOnDemand);
+    notifyDialogState();
+}
+
+void JSTreeView::remove(int pos)
+{
+    SalInstanceTreeView::remove(pos);
+    notifyDialogState();
+}
+
+void JSTreeView::select(int pos)
+{
+    SalInstanceTreeView::select(pos);
+    notifyDialogState();
+}
\ No newline at end of file
commit 11d5aeed1242f39d3ae7b30e3b30d22828e3554b
Author:     Szymon Kłos <szymon.klos at collabora.com>
AuthorDate: Thu Mar 26 12:17:59 2020 +0100
Commit:     Szymon Kłos <szymon.klos at collabora.com>
CommitDate: Wed Apr 1 12:13:21 2020 +0200

    Move SalInstanceTreeView to header file
    
    Change-Id: Iedc34867ad5371a31f5ca56a0ff3def75dc2163d

diff --git a/include/vcl/salvtables.hxx b/include/vcl/salvtables.hxx
index 4419d4a59204..35812aa4afca 100644
--- a/include/vcl/salvtables.hxx
+++ b/include/vcl/salvtables.hxx
@@ -14,6 +14,9 @@
 #include <vcl/tabctrl.hxx>
 #include <vcl/layout.hxx>
 #include <vcl/messagedialog.hxx>
+#include <vcl/treelistentry.hxx>
+#include <vcl/svlbitm.hxx>
+#include <vcl/headbar.hxx>
 
 class SalInstanceBuilder : public weld::Builder
 {
@@ -757,4 +760,138 @@ public:
     virtual ~SalInstanceCheckButton() override;
 };
 
+class SalInstanceTreeView : public SalInstanceContainer, public virtual weld::TreeView
+{
+private:
+    // owner for UserData
+    std::vector<std::unique_ptr<OUString>> m_aUserData;
+    VclPtr<SvTabListBox> m_xTreeView;
+    SvLBoxButtonData m_aCheckButtonData;
+    SvLBoxButtonData m_aRadioButtonData;
+
+    DECL_LINK(SelectHdl, SvTreeListBox*, void);
+    DECL_LINK(DoubleClickHdl, SvTreeListBox*, bool);
+    DECL_LINK(ExpandingHdl, SvTreeListBox*, bool);
+    DECL_LINK(EndDragHdl, HeaderBar*, void);
+    DECL_LINK(ToggleHdl, SvLBoxButtonData*, void);
+public:
+    SalInstanceTreeView(SvTabListBox* pTreeView, SalInstanceBuilder* pBuilder, bool bTakeOwnership);
+
+    virtual void freeze() override;
+
+    virtual void thaw() override;
+
+    virtual void set_column_fixed_widths(const std::vector<int>& rWidths) override;
+
+    virtual int get_column_width(int nColumn) const override;
+
+    virtual OUString get_column_title(int nColumn) const override;
+
+    virtual void set_column_title(int nColumn, const OUString& rTitle) override;
+
+    virtual void show() override;
+
+    virtual void hide() override;
+
+    virtual void insert(weld::TreeIter* pParent, int pos, const OUString* pStr, const OUString* pId,
+                        const OUString* pIconName, VirtualDevice* pImageSurface, const OUString* pExpanderName,
+                        bool bChildrenOnDemand) override;
+
+    virtual void set_font_color(int pos, const Color& rColor) const override;
+
+    virtual void remove(int pos) override;
+
+    virtual int find_text(const OUString& rText) const override;
+
+    virtual int find_id(const OUString& rId) const override;
+
+    virtual void set_top_entry(int pos) override;
+
+    virtual void clear() override;
+
+    virtual int n_children() const override;
+
+    virtual void select(int pos) override;
+
+    virtual void set_cursor(int pos) override;
+
+    virtual void scroll_to_row(int pos) override;
+
+    virtual void unselect(int pos) override;
+
+    virtual std::vector<int> get_selected_rows() const override;
+
+    virtual OUString get_text(int pos, int col = -1) const override;
+
+    virtual void set_text(int pos, const OUString& rText, int col = -1) override;
+
+    virtual bool get_toggle(int pos, int col) const override;
+
+    virtual void set_toggle(int pos, bool bOn, int col) override;
+
+    const OUString* getEntryData(int index) const;
+
+    virtual OUString get_id(int pos) const override;
+
+    virtual void set_id(int pos, const OUString& rId) override;
+
+    virtual int get_selected_index() const override;
+
+    virtual std::unique_ptr<weld::TreeIter> make_iterator(const weld::TreeIter* pOrig = nullptr) const override;
+
+    virtual void copy_iterator(const weld::TreeIter& rSource, weld::TreeIter& rDest) const override;
+
+    virtual bool get_selected(weld::TreeIter* pIter) const override;
+
+    virtual bool get_cursor(weld::TreeIter* pIter) const override;
+
+    virtual void set_cursor(const weld::TreeIter& rIter) override;
+
+    virtual bool get_iter_first(weld::TreeIter& rIter) const override;
+
+    virtual bool iter_next_sibling(weld::TreeIter& rIter) const override;
+
+    virtual bool iter_next(weld::TreeIter& rIter) const override;
+
+    virtual bool iter_children(weld::TreeIter& rIter) const override;
+
+    virtual bool iter_parent(weld::TreeIter& rIter) const override;
+
+    virtual void remove(const weld::TreeIter& rIter) override;
+
+    virtual void select(const weld::TreeIter& rIter) override;
+
+    virtual void scroll_to_row(const weld::TreeIter& rIter) override;
+
+    virtual void unselect(const weld::TreeIter& rIter) override;
+
+    virtual int get_iter_depth(const weld::TreeIter& rIter) const override;
+
+    virtual bool iter_has_child(const weld::TreeIter& rIter) const override;
+
+    virtual bool get_row_expanded(const weld::TreeIter& rIter) const override;
+
+    virtual void expand_row(weld::TreeIter& rIter) override;
+
+    virtual void collapse_row(weld::TreeIter& rIter) override;
+
+    virtual OUString get_text(const weld::TreeIter& rIter) const override;
+
+    virtual OUString get_id(const weld::TreeIter& rIter) const override;
+
+    virtual void set_expander_image(const weld::TreeIter& rIter, const OUString& rImage) override;
+
+    virtual void set_selection_mode(SelectionMode eMode) override;
+
+    virtual int count_selected_rows() const override;
+
+    virtual int get_height_rows(int nRows) const override;
+
+    virtual void make_sorted() override;
+
+    SvTabListBox& getTreeView();
+
+    virtual ~SalInstanceTreeView() override;
+};
+
 #endif
\ No newline at end of file
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 25ead2168b44..a0ac90e9a2bb 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -39,18 +39,15 @@
 #include <vcl/fixed.hxx>
 #include <vcl/fixedhyper.hxx>
 #include <vcl/fmtfield.hxx>
-#include <vcl/headbar.hxx>
 #include <vcl/layout.hxx>
 #include <vcl/menubtn.hxx>
 #include <vcl/prgsbar.hxx>
 #include <vcl/ptrstyle.hxx>
 #include <vcl/slider.hxx>
 #include <vcl/sysdata.hxx>
-#include <vcl/svlbitm.hxx>
 #include <vcl/svtabbx.hxx>
 #include <vcl/tabctrl.hxx>
 #include <vcl/tabpage.hxx>
-#include <vcl/treelistentry.hxx>
 #include <vcl/toolkit/unowrap.hxx>
 #include <vcl/weld.hxx>
 #include <bitmaps.hlst>
@@ -2233,611 +2230,595 @@ struct SalInstanceTreeIter : public weld::TreeIter
     SvTreeListEntry* iter;
 };
 
-class SalInstanceTreeView : public SalInstanceContainer, public virtual weld::TreeView
+SalInstanceTreeView::SalInstanceTreeView(SvTabListBox* pTreeView, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+    : SalInstanceContainer(pTreeView, pBuilder, bTakeOwnership)
+    , m_xTreeView(pTreeView)
+    , m_aCheckButtonData(pTreeView, false)
+    , m_aRadioButtonData(pTreeView, true)
 {
-private:
-    // owner for UserData
-    std::vector<std::unique_ptr<OUString>> m_aUserData;
-    VclPtr<SvTabListBox> m_xTreeView;
-    SvLBoxButtonData m_aCheckButtonData;
-    SvLBoxButtonData m_aRadioButtonData;
-
-    DECL_LINK(SelectHdl, SvTreeListBox*, void);
-    DECL_LINK(DoubleClickHdl, SvTreeListBox*, bool);
-    DECL_LINK(ExpandingHdl, SvTreeListBox*, bool);
-    DECL_LINK(EndDragHdl, HeaderBar*, void);
-    DECL_LINK(ToggleHdl, SvLBoxButtonData*, void);
-public:
-    SalInstanceTreeView(SvTabListBox* pTreeView, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
-        : SalInstanceContainer(pTreeView, pBuilder, bTakeOwnership)
-        , m_xTreeView(pTreeView)
-        , m_aCheckButtonData(pTreeView, false)
-        , m_aRadioButtonData(pTreeView, true)
-    {
-        m_xTreeView->SetNodeDefaultImages();
-        m_xTreeView->SetSelectHdl(LINK(this, SalInstanceTreeView, SelectHdl));
-        m_xTreeView->SetDoubleClickHdl(LINK(this, SalInstanceTreeView, DoubleClickHdl));
-        m_xTreeView->SetExpandingHdl(LINK(this, SalInstanceTreeView, ExpandingHdl));
-        const long aTabPositions[] = { 0 };
-        m_xTreeView->SetTabs(SAL_N_ELEMENTS(aTabPositions), aTabPositions);
-        SvHeaderTabListBox* pHeaderBox = dynamic_cast<SvHeaderTabListBox*>(m_xTreeView.get());
-        if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
-        {
-            //make the last entry fill available space
-            pHeaderBar->SetItemSize(pHeaderBar->GetItemId(pHeaderBar->GetItemCount() - 1 ), HEADERBAR_FULLSIZE);
-            pHeaderBar->SetEndDragHdl(LINK(this, SalInstanceTreeView, EndDragHdl));
-        }
-        m_aCheckButtonData.SetLink(LINK(this, SalInstanceTreeView, ToggleHdl));
-        m_aRadioButtonData.SetLink(LINK(this, SalInstanceTreeView, ToggleHdl));
-    }
-
-    virtual void freeze() override
+    m_xTreeView->SetNodeDefaultImages();
+    m_xTreeView->SetSelectHdl(LINK(this, SalInstanceTreeView, SelectHdl));
+    m_xTreeView->SetDoubleClickHdl(LINK(this, SalInstanceTreeView, DoubleClickHdl));
+    m_xTreeView->SetExpandingHdl(LINK(this, SalInstanceTreeView, ExpandingHdl));
+    const long aTabPositions[] = { 0 };
+    m_xTreeView->SetTabs(SAL_N_ELEMENTS(aTabPositions), aTabPositions);
+    SvHeaderTabListBox* pHeaderBox = dynamic_cast<SvHeaderTabListBox*>(m_xTreeView.get());
+    if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
     {
-        SalInstanceWidget::freeze();
-        m_xTreeView->SetUpdateMode(false);
+        //make the last entry fill available space
+        pHeaderBar->SetItemSize(pHeaderBar->GetItemId(pHeaderBar->GetItemCount() - 1 ), HEADERBAR_FULLSIZE);
+        pHeaderBar->SetEndDragHdl(LINK(this, SalInstanceTreeView, EndDragHdl));
     }
+    m_aCheckButtonData.SetLink(LINK(this, SalInstanceTreeView, ToggleHdl));
+    m_aRadioButtonData.SetLink(LINK(this, SalInstanceTreeView, ToggleHdl));
+}
 
-    virtual void thaw() override
-    {
-        m_xTreeView->SetUpdateMode(true);
-        SalInstanceWidget::thaw();
-    }
+void SalInstanceTreeView::freeze()
+{
+    SalInstanceWidget::freeze();
+    m_xTreeView->SetUpdateMode(false);
+}
 
-    virtual void set_column_fixed_widths(const std::vector<int>& rWidths) override
+void SalInstanceTreeView::thaw()
+{
+    m_xTreeView->SetUpdateMode(true);
+    SalInstanceWidget::thaw();
+}
+
+void SalInstanceTreeView::set_column_fixed_widths(const std::vector<int>& rWidths)
+{
+    std::vector<long> aTabPositions;
+    aTabPositions.push_back(0);
+    for (size_t i = 0; i < rWidths.size(); ++i)
+        aTabPositions.push_back(aTabPositions[i] + rWidths[i]);
+    m_xTreeView->SetTabs(aTabPositions.size(), aTabPositions.data(), MapUnit::MapPixel);
+    SvHeaderTabListBox* pHeaderBox = dynamic_cast<SvHeaderTabListBox*>(m_xTreeView.get());
+    if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
     {
-        std::vector<long> aTabPositions;
-        aTabPositions.push_back(0);
         for (size_t i = 0; i < rWidths.size(); ++i)
-            aTabPositions.push_back(aTabPositions[i] + rWidths[i]);
-        m_xTreeView->SetTabs(aTabPositions.size(), aTabPositions.data(), MapUnit::MapPixel);
-        SvHeaderTabListBox* pHeaderBox = dynamic_cast<SvHeaderTabListBox*>(m_xTreeView.get());
-        if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
-        {
-            for (size_t i = 0; i < rWidths.size(); ++i)
-                pHeaderBar->SetItemSize(pHeaderBar->GetItemId(i), rWidths[i]);
-        }
-        // call Resize to recalculate based on the new tabs
-        m_xTreeView->Resize();
+            pHeaderBar->SetItemSize(pHeaderBar->GetItemId(i), rWidths[i]);
     }
+    // call Resize to recalculate based on the new tabs
+    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;
-    }
+int SalInstanceTreeView::get_column_width(int nColumn) const
+{
+    // 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
+OUString SalInstanceTreeView::get_column_title(int nColumn) const
+{
+    SvHeaderTabListBox* pHeaderBox = dynamic_cast<SvHeaderTabListBox*>(m_xTreeView.get());
+    if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
     {
-        SvHeaderTabListBox* pHeaderBox = dynamic_cast<SvHeaderTabListBox*>(m_xTreeView.get());
-        if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
-        {
-            return pHeaderBar->GetItemText(pHeaderBar->GetItemId(nColumn));
-        }
-        return OUString();
+        return pHeaderBar->GetItemText(pHeaderBar->GetItemId(nColumn));
     }
+    return OUString();
+}
 
-    virtual void set_column_title(int nColumn, const OUString& rTitle) override
+void SalInstanceTreeView::set_column_title(int nColumn, const OUString& rTitle)
+{
+    SvHeaderTabListBox* pHeaderBox = dynamic_cast<SvHeaderTabListBox*>(m_xTreeView.get());
+    if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
     {
-        SvHeaderTabListBox* pHeaderBox = dynamic_cast<SvHeaderTabListBox*>(m_xTreeView.get());
-        if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
-        {
-            return pHeaderBar->SetItemText(pHeaderBar->GetItemId(nColumn), rTitle);
-        }
+        return pHeaderBar->SetItemText(pHeaderBar->GetItemId(nColumn), rTitle);
     }
+}
 
-    virtual void show() override
+void SalInstanceTreeView::show()
+{
+    SvHeaderTabListBox* pHeaderBox = dynamic_cast<SvHeaderTabListBox*>(m_xTreeView.get());
+    if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
     {
-        SvHeaderTabListBox* pHeaderBox = dynamic_cast<SvHeaderTabListBox*>(m_xTreeView.get());
-        if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
-        {
-            pHeaderBar->Show();
-        }
-        SalInstanceContainer::show();
+        pHeaderBar->Show();
     }
+    SalInstanceContainer::show();
+}
 
-    virtual void hide() override
+void SalInstanceTreeView::hide()
+{
+    SvHeaderTabListBox* pHeaderBox = dynamic_cast<SvHeaderTabListBox*>(m_xTreeView.get());
+    if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
     {
-        SvHeaderTabListBox* pHeaderBox = dynamic_cast<SvHeaderTabListBox*>(m_xTreeView.get());
-        if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
-        {
-            pHeaderBar->Hide();
-        }
-        SalInstanceContainer::hide();
+        pHeaderBar->Hide();
     }
+    SalInstanceContainer::hide();
+}
 
-    virtual void insert(weld::TreeIter* pParent, int pos, const OUString* pStr, const OUString* pId,
-                        const OUString* pIconName, VirtualDevice* pImageSurface, const OUString* pExpanderName,
-                        bool bChildrenOnDemand) override
+void SalInstanceTreeView::insert(weld::TreeIter* pParent, int pos, const OUString* pStr, const OUString* pId,
+                    const OUString* pIconName, VirtualDevice* pImageSurface, const OUString* pExpanderName,
+                    bool bChildrenOnDemand)
+{
+    SalInstanceTreeIter* pVclIter = static_cast<SalInstanceTreeIter*>(pParent);
+    SvTreeListEntry* iter = pVclIter ? pVclIter->iter : nullptr;
+    auto nInsertPos = pos == -1 ? TREELIST_APPEND : pos;
+    void* pUserData;
+    if (pId)
     {
-        SalInstanceTreeIter* pVclIter = static_cast<SalInstanceTreeIter*>(pParent);
-        SvTreeListEntry* iter = pVclIter ? pVclIter->iter : nullptr;
-        auto nInsertPos = pos == -1 ? TREELIST_APPEND : pos;
-        void* pUserData;
-        if (pId)
-        {
-            m_aUserData.emplace_back(o3tl::make_unique<OUString>(*pId));
-            pUserData = m_aUserData.back().get();
-        }
-        else
-            pUserData = nullptr;
-
-        SvTreeListEntry* pEntry = new SvTreeListEntry;
-        if (pIconName || pImageSurface)
-        {
-            Image aImage(pIconName ? createImage(*pIconName) : createImage(*pImageSurface));
-            pEntry->AddItem(o3tl::make_unique<SvLBoxContextBmp>(aImage, aImage, false));
-        }
-        else
-        {
-            Image aDummy;
-            pEntry->AddItem(o3tl::make_unique<SvLBoxContextBmp>(aDummy, aDummy, false));
-        }
-        if (pStr)
-            pEntry->AddItem(o3tl::make_unique<SvLBoxString>(*pStr));
-        pEntry->SetUserData(pUserData);
-        m_xTreeView->Insert(pEntry, iter, nInsertPos);
-
-        if (pExpanderName)
-        {
-            Image aImage(createImage(*pExpanderName));
-            m_xTreeView->SetExpandedEntryBmp(pEntry, aImage);
-            m_xTreeView->SetCollapsedEntryBmp(pEntry, aImage);
-        }
-
-        if (bChildrenOnDemand)
-        {
-            m_xTreeView->InsertEntry("<dummy>", pEntry, false, 0, nullptr);
-        }
+        m_aUserData.emplace_back(o3tl::make_unique<OUString>(*pId));
+        pUserData = m_aUserData.back().get();
     }
+    else
+        pUserData = nullptr;
 
-    virtual void set_font_color(int pos, const Color& rColor) const override
+    SvTreeListEntry* pEntry = new SvTreeListEntry;
+    if (pIconName || pImageSurface)
     {
-        SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
-        pEntry->SetTextColor(&rColor);
+        Image aImage(pIconName ? createImage(*pIconName) : createImage(*pImageSurface));
+        pEntry->AddItem(o3tl::make_unique<SvLBoxContextBmp>(aImage, aImage, false));
     }
-
-    virtual void remove(int pos) override
+    else
     {
-        SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
-        m_xTreeView->RemoveEntry(pEntry);
+        Image aDummy;
+        pEntry->AddItem(o3tl::make_unique<SvLBoxContextBmp>(aDummy, aDummy, false));
     }
+    if (pStr)
+        pEntry->AddItem(o3tl::make_unique<SvLBoxString>(*pStr));
+    pEntry->SetUserData(pUserData);
+    m_xTreeView->Insert(pEntry, iter, nInsertPos);
 
-    virtual int find_text(const OUString& rText) const override
+    if (pExpanderName)
     {
-        for (SvTreeListEntry* pEntry = m_xTreeView->First(); pEntry; pEntry = m_xTreeView->Next(pEntry))
-        {
-            if (SvTabListBox::GetEntryText(pEntry, 0) == rText)
-                return m_xTreeView->GetAbsPos(pEntry);
-        }
-        return -1;
+        Image aImage(createImage(*pExpanderName));
+        m_xTreeView->SetExpandedEntryBmp(pEntry, aImage);
+        m_xTreeView->SetCollapsedEntryBmp(pEntry, aImage);
     }
 
-    virtual int find_id(const OUString& rId) const override
+    if (bChildrenOnDemand)
     {
-        for (SvTreeListEntry* pEntry = m_xTreeView->First(); pEntry; pEntry = m_xTreeView->Next(pEntry))
-        {
-            const OUString* pId = static_cast<const OUString*>(pEntry->GetUserData());
-            if (!pId)
-                continue;
-            if (rId == *pId)
-                return m_xTreeView->GetAbsPos(pEntry);
-        }
-        return -1;
+        m_xTreeView->InsertEntry("<dummy>", pEntry, false, 0, nullptr);
     }
+}
 
-    virtual void set_top_entry(int pos) override
-    {
-        SvTreeList* pModel = m_xTreeView->GetModel();
-        SvTreeListEntry* pEntry = pModel->GetEntry(nullptr, pos);
-        pModel->Move(pEntry, nullptr, 0);
-    }
+void SalInstanceTreeView::set_font_color(int pos, const Color& rColor) const
+{
+    SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
+    pEntry->SetTextColor(&rColor);
+}
 
-    virtual void clear() override
-    {
-        m_xTreeView->Clear();
-        m_aUserData.clear();
-    }
+void SalInstanceTreeView::remove(int pos)
+{
+    SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
+    m_xTreeView->RemoveEntry(pEntry);
+}
 
-    virtual int n_children() const override
+int SalInstanceTreeView::find_text(const OUString& rText) const
+{
+    for (SvTreeListEntry* pEntry = m_xTreeView->First(); pEntry; pEntry = m_xTreeView->Next(pEntry))
     {
-        return m_xTreeView->GetEntryCount();
+        if (SvTabListBox::GetEntryText(pEntry, 0) == rText)
+            return m_xTreeView->GetAbsPos(pEntry);
     }
+    return -1;
+}
 
-    virtual void select(int pos) override
+int SalInstanceTreeView::find_id(const OUString& rId) const
+{
+    for (SvTreeListEntry* pEntry = m_xTreeView->First(); pEntry; pEntry = m_xTreeView->Next(pEntry))
     {
-        assert(m_xTreeView->IsUpdateMode() && "don't select when frozen");
-        disable_notify_events();
-        if (pos == -1 || (pos == 0 && n_children() == 0))
-            m_xTreeView->SelectAll(false);
-        else
-        {
-            SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
-            m_xTreeView->Select(pEntry, true);
-            m_xTreeView->MakeVisible(pEntry);
-        }
-        enable_notify_events();
+        const OUString* pId = static_cast<const OUString*>(pEntry->GetUserData());
+        if (!pId)
+            continue;
+        if (rId == *pId)
+            return m_xTreeView->GetAbsPos(pEntry);
     }
+    return -1;
+}
 
-    virtual void set_cursor(int pos) override
-    {
-        if (pos == -1)
-            m_xTreeView->SetCurEntry(nullptr);
-        else
-        {
-            SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
-            m_xTreeView->SetCurEntry(pEntry);
-        }
-    }
+void SalInstanceTreeView::set_top_entry(int pos)
+{
+    SvTreeList* pModel = m_xTreeView->GetModel();
+    SvTreeListEntry* pEntry = pModel->GetEntry(nullptr, pos);
+    pModel->Move(pEntry, nullptr, 0);
+}
 
-    virtual void scroll_to_row(int pos) override
+void SalInstanceTreeView::clear()
+{
+    m_xTreeView->Clear();
+    m_aUserData.clear();
+}
+
+int SalInstanceTreeView::n_children() const
+{
+    return m_xTreeView->GetEntryCount();
+}
+
+void SalInstanceTreeView::select(int pos)
+{
+    assert(m_xTreeView->IsUpdateMode() && "don't select when frozen");
+    disable_notify_events();
+    if (pos == -1 || (pos == 0 && n_children() == 0))
+        m_xTreeView->SelectAll(false);
+    else
     {
-        assert(m_xTreeView->IsUpdateMode() && "don't select when frozen");
-        disable_notify_events();
         SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
+        m_xTreeView->Select(pEntry, true);
         m_xTreeView->MakeVisible(pEntry);
-        enable_notify_events();
     }
+    enable_notify_events();
+}
 
-    virtual void unselect(int pos) override
+void SalInstanceTreeView::set_cursor(int pos)
+{
+    if (pos == -1)
+        m_xTreeView->SetCurEntry(nullptr);
+    else
     {
-        assert(m_xTreeView->IsUpdateMode() && "don't select when frozen");
-        disable_notify_events();
-        if (pos == -1)
-            m_xTreeView->SelectAll(true);
-        else
-        {
-            SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
-            m_xTreeView->Select(pEntry, false);
-        }
-        enable_notify_events();
+        SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
+        m_xTreeView->SetCurEntry(pEntry);
     }
+}
 
-    virtual std::vector<int> get_selected_rows() const override
-    {
-        std::vector<int> aRows;
-
-        aRows.reserve(m_xTreeView->GetSelectionCount());
-        for (SvTreeListEntry* pEntry = m_xTreeView->FirstSelected(); pEntry; pEntry = m_xTreeView->NextSelected(pEntry))
-            aRows.push_back(m_xTreeView->GetAbsPos(pEntry));
-
-        return aRows;
-    }
+void SalInstanceTreeView::scroll_to_row(int pos)
+{
+    assert(m_xTreeView->IsUpdateMode() && "don't select when frozen");
+    disable_notify_events();
+    SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
+    m_xTreeView->MakeVisible(pEntry);
+    enable_notify_events();
+}
 
-    virtual OUString get_text(int pos, int col) const override
+void SalInstanceTreeView::unselect(int pos)
+{
+    assert(m_xTreeView->IsUpdateMode() && "don't select when frozen");
+    disable_notify_events();
+    if (pos == -1)
+        m_xTreeView->SelectAll(true);
+    else
     {
         SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
-        if (col == -1)
-            return SvTabListBox::GetEntryText(pEntry, 0);
+        m_xTreeView->Select(pEntry, false);
+    }
+    enable_notify_events();
+}
 
-        ++col; //skip dummy/expander column
+std::vector<int> SalInstanceTreeView::get_selected_rows() const
+{
+    std::vector<int> aRows;
 
-        if (static_cast<size_t>(col) == pEntry->ItemCount())
-            return OUString();
+    aRows.reserve(m_xTreeView->GetSelectionCount());
+    for (SvTreeListEntry* pEntry = m_xTreeView->FirstSelected(); pEntry; pEntry = m_xTreeView->NextSelected(pEntry))
+        aRows.push_back(m_xTreeView->GetAbsPos(pEntry));
 
-        assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
-        SvLBoxItem& rItem = pEntry->GetItem(col);
-        assert(dynamic_cast<SvLBoxString*>(&rItem));
-        return static_cast<SvLBoxString&>(rItem).GetText();
-    }
+    return aRows;
+}
 
-    virtual void set_text(int pos, const OUString& rText, int col) override
-    {
-        SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
-        if (col == -1)
-        {
-            m_xTreeView->SetEntryText(pEntry, rText);
-            return;
-        }
+OUString SalInstanceTreeView::get_text(int pos, int col) const
+{
+    SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
+    if (col == -1)
+        return SvTabListBox::GetEntryText(pEntry, 0);
 
-        ++col; //skip dummy/expander column
+    ++col; //skip dummy/expander column
 
-        // blank out missing entries
-        for (int i = pEntry->ItemCount(); i < col ; ++i)
-            pEntry->AddItem(o3tl::make_unique<SvLBoxString>(""));
+    if (static_cast<size_t>(col) == pEntry->ItemCount())
+        return OUString();
 
-        if (static_cast<size_t>(col) == pEntry->ItemCount())
-        {
-            pEntry->AddItem(o3tl::make_unique<SvLBoxString>(rText));
-            SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
-            m_xTreeView->InitViewData(pViewData, pEntry);
-        }
-        else
-        {
-            assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
-            SvLBoxItem& rItem = pEntry->GetItem(col);
-            assert(dynamic_cast<SvLBoxString*>(&rItem));
-            static_cast<SvLBoxString&>(rItem).SetText(rText);
-        }
-        m_xTreeView->ModelHasEntryInvalidated(pEntry);
-    }
+    assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
+    SvLBoxItem& rItem = pEntry->GetItem(col);
+    assert(dynamic_cast<SvLBoxString*>(&rItem));
+    return static_cast<SvLBoxString&>(rItem).GetText();
+}
 
-    virtual bool get_toggle(int pos, int col) const override
+void SalInstanceTreeView::set_text(int pos, const OUString& rText, int col)
+{
+    SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
+    if (col == -1)
     {
-        SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
+        m_xTreeView->SetEntryText(pEntry, rText);
+        return;
+    }
 
-        ++col; //skip dummy/expander column
+    ++col; //skip dummy/expander column
 
-        if (static_cast<size_t>(col) == pEntry->ItemCount())
-            return false;
+    // blank out missing entries
+    for (int i = pEntry->ItemCount(); i < col ; ++i)
+        pEntry->AddItem(o3tl::make_unique<SvLBoxString>(""));
 
+    if (static_cast<size_t>(col) == pEntry->ItemCount())
+    {
+        pEntry->AddItem(o3tl::make_unique<SvLBoxString>(rText));
+        SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
+        m_xTreeView->InitViewData(pViewData, pEntry);
+    }
+    else
+    {
         assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
         SvLBoxItem& rItem = pEntry->GetItem(col);
-        assert(dynamic_cast<SvLBoxButton*>(&rItem));
-        return static_cast<SvLBoxButton&>(rItem).IsStateChecked();
+        assert(dynamic_cast<SvLBoxString*>(&rItem));
+        static_cast<SvLBoxString&>(rItem).SetText(rText);
     }
+    m_xTreeView->ModelHasEntryInvalidated(pEntry);
+}
 
-    virtual void set_toggle(int pos, bool bOn, int col) override
-    {
-        SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
+bool SalInstanceTreeView::get_toggle(int pos, int col) const
+{
+    SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
 
-        bool bRadio = std::find(m_aRadioIndexes.begin(), m_aRadioIndexes.end(), col) != m_aRadioIndexes.end();
-        ++col; //skip dummy/expander column
+    ++col; //skip dummy/expander column
 
-        // blank out missing entries
-        for (int i = pEntry->ItemCount(); i < col ; ++i)
-            pEntry->AddItem(o3tl::make_unique<SvLBoxString>(""));
+    if (static_cast<size_t>(col) == pEntry->ItemCount())
+        return false;
 
-        if (static_cast<size_t>(col) == pEntry->ItemCount())
-        {
-            pEntry->AddItem(o3tl::make_unique<SvLBoxButton>(SvLBoxButtonKind::EnabledCheckbox,
-                                                            bRadio ? &m_aRadioButtonData : &m_aCheckButtonData));
-            SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
-            m_xTreeView->InitViewData(pViewData, pEntry);
-        }
+    assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
+    SvLBoxItem& rItem = pEntry->GetItem(col);
+    assert(dynamic_cast<SvLBoxButton*>(&rItem));
+    return static_cast<SvLBoxButton&>(rItem).IsStateChecked();
+}
 
-        assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
-        SvLBoxItem& rItem = pEntry->GetItem(col);
-        assert(dynamic_cast<SvLBoxButton*>(&rItem));
-        if (bOn)
-            static_cast<SvLBoxButton&>(rItem).SetStateChecked();
-        else
-            static_cast<SvLBoxButton&>(rItem).SetStateUnchecked();
+void SalInstanceTreeView::set_toggle(int pos, bool bOn, int col)
+{
+    SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
 
-        m_xTreeView->ModelHasEntryInvalidated(pEntry);
-    }
+    bool bRadio = std::find(m_aRadioIndexes.begin(), m_aRadioIndexes.end(), col) != m_aRadioIndexes.end();
+    ++col; //skip dummy/expander column
 
-    const OUString* getEntryData(int index) const
-    {
-        SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, index);
-        return static_cast<const OUString*>(pEntry->GetUserData());
-    }
+    // blank out missing entries
+    for (int i = pEntry->ItemCount(); i < col ; ++i)
+        pEntry->AddItem(o3tl::make_unique<SvLBoxString>(""));
 
-    virtual OUString get_id(int pos) const override
+    if (static_cast<size_t>(col) == pEntry->ItemCount())
     {
-        const OUString* pRet = getEntryData(pos);
-        if (!pRet)
-            return OUString();
-        return *pRet;
+        pEntry->AddItem(o3tl::make_unique<SvLBoxButton>(SvLBoxButtonKind::EnabledCheckbox,
+                                                        bRadio ? &m_aRadioButtonData : &m_aCheckButtonData));
+        SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
+        m_xTreeView->InitViewData(pViewData, pEntry);
     }
 
-    virtual void set_id(int pos, const OUString& rId) override
-    {
-        SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
-        m_aUserData.emplace_back(o3tl::make_unique<OUString>(rId));
-        pEntry->SetUserData(m_aUserData.back().get());
-    }
+    assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
+    SvLBoxItem& rItem = pEntry->GetItem(col);
+    assert(dynamic_cast<SvLBoxButton*>(&rItem));
+    if (bOn)
+        static_cast<SvLBoxButton&>(rItem).SetStateChecked();
+    else
+        static_cast<SvLBoxButton&>(rItem).SetStateUnchecked();
 
-    virtual int get_selected_index() const override
-    {
-        assert(m_xTreeView->IsUpdateMode() && "don't request selection when frozen");
-        SvTreeListEntry* pEntry = m_xTreeView->FirstSelected();
-        if (!pEntry)
-            return -1;
-        return m_xTreeView->GetAbsPos(pEntry);
-    }
+    m_xTreeView->ModelHasEntryInvalidated(pEntry);
+}
 
-    virtual std::unique_ptr<weld::TreeIter> make_iterator(const weld::TreeIter* pOrig) const override
-    {
-        return std::unique_ptr<weld::TreeIter>(new SalInstanceTreeIter(static_cast<const SalInstanceTreeIter*>(pOrig)));
-    }
+const OUString* SalInstanceTreeView::getEntryData(int index) const
+{
+    SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, index);
+    return static_cast<const OUString*>(pEntry->GetUserData());
+}
 
-    virtual void copy_iterator(const weld::TreeIter& rSource, weld::TreeIter& rDest) const override
-    {
-        const SalInstanceTreeIter& rVclSource(static_cast<const SalInstanceTreeIter&>(rSource));
-        SalInstanceTreeIter& rVclDest(static_cast<SalInstanceTreeIter&>(rDest));
-        rVclDest.iter = rVclSource.iter;
-    }
+OUString SalInstanceTreeView::get_id(int pos) const
+{
+    const OUString* pRet = getEntryData(pos);
+    if (!pRet)
+        return OUString();
+    return *pRet;
+}
 
-    virtual bool get_selected(weld::TreeIter* pIter) const override
-    {
-        SvTreeListEntry* pEntry = m_xTreeView->FirstSelected();
-        auto pVclIter = static_cast<SalInstanceTreeIter*>(pIter);
-        if (pVclIter)
-            pVclIter->iter = pEntry;
-        return pEntry != nullptr;
-    }
+void SalInstanceTreeView::set_id(int pos, const OUString& rId)
+{
+    SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
+    m_aUserData.emplace_back(o3tl::make_unique<OUString>(rId));
+    pEntry->SetUserData(m_aUserData.back().get());
+}
 
-    virtual bool get_cursor(weld::TreeIter* pIter) const override
-    {
-        SvTreeListEntry* pEntry = m_xTreeView->GetCurEntry();
-        auto pVclIter = static_cast<SalInstanceTreeIter*>(pIter);
-        if (pVclIter)
-            pVclIter->iter = pEntry;
-        return pEntry != nullptr;
-    }
+int SalInstanceTreeView::get_selected_index() const
+{
+    assert(m_xTreeView->IsUpdateMode() && "don't request selection when frozen");
+    SvTreeListEntry* pEntry = m_xTreeView->FirstSelected();
+    if (!pEntry)
+        return -1;
+    return m_xTreeView->GetAbsPos(pEntry);
+}
 
-    virtual void set_cursor(const weld::TreeIter& rIter) override
-    {
-        const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
-        m_xTreeView->SetCurEntry(rVclIter.iter);
-    }
+std::unique_ptr<weld::TreeIter> SalInstanceTreeView::make_iterator(const weld::TreeIter* pOrig) const
+{
+    return std::unique_ptr<weld::TreeIter>(new SalInstanceTreeIter(static_cast<const SalInstanceTreeIter*>(pOrig)));
+}
 
-    virtual bool get_iter_first(weld::TreeIter& rIter) const override
-    {
-        SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
-        rVclIter.iter = m_xTreeView->GetEntry(0);
-        return rVclIter.iter != nullptr;
-    }
+void SalInstanceTreeView::copy_iterator(const weld::TreeIter& rSource, weld::TreeIter& rDest) const
+{
+    const SalInstanceTreeIter& rVclSource(static_cast<const SalInstanceTreeIter&>(rSource));
+    SalInstanceTreeIter& rVclDest(static_cast<SalInstanceTreeIter&>(rDest));
+    rVclDest.iter = rVclSource.iter;
+}
 
-    virtual bool iter_next_sibling(weld::TreeIter& rIter) const override
-    {
-        SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
-        rVclIter.iter = rVclIter.iter->NextSibling();
-        return rVclIter.iter != nullptr;
-    }
+bool SalInstanceTreeView::get_selected(weld::TreeIter* pIter) const
+{
+    SvTreeListEntry* pEntry = m_xTreeView->FirstSelected();
+    auto pVclIter = static_cast<SalInstanceTreeIter*>(pIter);
+    if (pVclIter)
+        pVclIter->iter = pEntry;
+    return pEntry != nullptr;
+}
 
-    virtual bool iter_next(weld::TreeIter& rIter) const override
-    {
-        SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
-        rVclIter.iter = m_xTreeView->Next(rVclIter.iter);
-        if (rVclIter.iter && m_xTreeView->GetEntryText(rVclIter.iter) == "<dummy>")
-            return iter_next(rVclIter);
-        return rVclIter.iter != nullptr;
-    }
+bool SalInstanceTreeView::get_cursor(weld::TreeIter* pIter) const
+{
+    SvTreeListEntry* pEntry = m_xTreeView->GetCurEntry();
+    auto pVclIter = static_cast<SalInstanceTreeIter*>(pIter);
+    if (pVclIter)
+        pVclIter->iter = pEntry;
+    return pEntry != nullptr;
+}
 
-    virtual bool iter_children(weld::TreeIter& rIter) const override
-    {
-        SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
-        rVclIter.iter = m_xTreeView->FirstChild(rVclIter.iter);
-        bool bRet = rVclIter.iter != nullptr;
-        if (bRet)
-        {
-            //on-demand dummy entry doesn't count
-            return m_xTreeView->GetEntryText(rVclIter.iter) != "<dummy>";
-        }
-        return bRet;
-    }
+void SalInstanceTreeView::set_cursor(const weld::TreeIter& rIter)
+{
+    const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
+    m_xTreeView->SetCurEntry(rVclIter.iter);
+}
 
-    virtual bool iter_parent(weld::TreeIter& rIter) const override
-    {
-        SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
-        rVclIter.iter = m_xTreeView->GetParent(rVclIter.iter);
-        return rVclIter.iter != nullptr;
-    }
+bool SalInstanceTreeView::get_iter_first(weld::TreeIter& rIter) const
+{
+    SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
+    rVclIter.iter = m_xTreeView->GetEntry(0);
+    return rVclIter.iter != nullptr;
+}
 
-    virtual void remove(const weld::TreeIter& rIter) override
-    {
-        const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
-        m_xTreeView->RemoveEntry(rVclIter.iter);
-    }
+bool SalInstanceTreeView::iter_next_sibling(weld::TreeIter& rIter) const
+{
+    SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
+    rVclIter.iter = rVclIter.iter->NextSibling();
+    return rVclIter.iter != nullptr;
+}
 
-    virtual void select(const weld::TreeIter& rIter) override
-    {
-        assert(m_xTreeView->IsUpdateMode() && "don't select when frozen");
-        disable_notify_events();
-        const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
-        m_xTreeView->Select(rVclIter.iter, true);
-        enable_notify_events();
-    }
+bool SalInstanceTreeView::iter_next(weld::TreeIter& rIter) const
+{
+    SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
+    rVclIter.iter = m_xTreeView->Next(rVclIter.iter);
+    if (rVclIter.iter && m_xTreeView->GetEntryText(rVclIter.iter) == "<dummy>")
+        return iter_next(rVclIter);
+    return rVclIter.iter != nullptr;
+}
 
-    virtual void scroll_to_row(const weld::TreeIter& rIter) override
+bool SalInstanceTreeView::iter_children(weld::TreeIter& rIter) const
+{
+    SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
+    rVclIter.iter = m_xTreeView->FirstChild(rVclIter.iter);
+    bool bRet = rVclIter.iter != nullptr;
+    if (bRet)
     {
-        assert(m_xTreeView->IsUpdateMode() && "don't select when frozen");
-        disable_notify_events();
-        const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
-        m_xTreeView->MakeVisible(rVclIter.iter);
-        enable_notify_events();
+        //on-demand dummy entry doesn't count
+        return m_xTreeView->GetEntryText(rVclIter.iter) != "<dummy>";
     }
+    return bRet;
+}
 
-    virtual void unselect(const weld::TreeIter& rIter) override
-    {
-        assert(m_xTreeView->IsUpdateMode() && "don't unselect when frozen");
-        disable_notify_events();
-        const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
-        m_xTreeView->Select(rVclIter.iter, false);
-        enable_notify_events();
-    }
+bool SalInstanceTreeView::iter_parent(weld::TreeIter& rIter) const
+{
+    SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
+    rVclIter.iter = m_xTreeView->GetParent(rVclIter.iter);
+    return rVclIter.iter != nullptr;
+}
 
-    virtual int get_iter_depth(const weld::TreeIter& rIter) const override
-    {
-        const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
-        return m_xTreeView->GetModel()->GetDepth(rVclIter.iter);
-    }
+void SalInstanceTreeView::remove(const weld::TreeIter& rIter)
+{
+    const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
+    m_xTreeView->RemoveEntry(rVclIter.iter);
+}
 
-    virtual bool iter_has_child(const weld::TreeIter& rIter) const override
-    {
-        weld::TreeIter& rNonConstIter = const_cast<weld::TreeIter&>(rIter);
-        SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rNonConstIter);
-        SvTreeListEntry* restore(rVclIter.iter);
-        bool ret = iter_children(rNonConstIter);
-        rVclIter.iter = restore;
-        return ret;
-    }
+void SalInstanceTreeView::select(const weld::TreeIter& rIter)
+{
+    assert(m_xTreeView->IsUpdateMode() && "don't select when frozen");
+    disable_notify_events();
+    const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
+    m_xTreeView->Select(rVclIter.iter, true);
+    enable_notify_events();
+}
 
-    virtual bool get_row_expanded(const weld::TreeIter& rIter) const override
-    {
-        const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
-        return m_xTreeView->IsExpanded(rVclIter.iter);
-    }
+void SalInstanceTreeView::scroll_to_row(const weld::TreeIter& rIter)
+{
+    assert(m_xTreeView->IsUpdateMode() && "don't select when frozen");
+    disable_notify_events();
+    const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
+    m_xTreeView->MakeVisible(rVclIter.iter);
+    enable_notify_events();
+}
 
-    virtual void expand_row(weld::TreeIter& rIter) override
-    {
-        SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
-        if (!m_xTreeView->IsExpanded(rVclIter.iter) && signal_expanding(rIter))
-            m_xTreeView->Expand(rVclIter.iter);
-    }
+void SalInstanceTreeView::unselect(const weld::TreeIter& rIter)
+{
+    assert(m_xTreeView->IsUpdateMode() && "don't unselect when frozen");
+    disable_notify_events();
+    const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
+    m_xTreeView->Select(rVclIter.iter, false);
+    enable_notify_events();
+}
 
-    virtual void collapse_row(weld::TreeIter& rIter) override
-    {
-        SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
-        if (m_xTreeView->IsExpanded(rVclIter.iter))
-            m_xTreeView->Collapse(rVclIter.iter);
-    }
+int SalInstanceTreeView::get_iter_depth(const weld::TreeIter& rIter) const
+{
+    const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
+    return m_xTreeView->GetModel()->GetDepth(rVclIter.iter);
+}
 
-    virtual OUString get_text(const weld::TreeIter& rIter) const override
-    {
-        const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
-        return SvTabListBox::GetEntryText(rVclIter.iter, 0);
-    }
+bool SalInstanceTreeView::iter_has_child(const weld::TreeIter& rIter) const
+{
+    weld::TreeIter& rNonConstIter = const_cast<weld::TreeIter&>(rIter);
+    SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rNonConstIter);
+    SvTreeListEntry* restore(rVclIter.iter);
+    bool ret = iter_children(rNonConstIter);
+    rVclIter.iter = restore;
+    return ret;
+}
 
-    virtual OUString get_id(const weld::TreeIter& rIter) const override
-    {
-        const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
-        const OUString* pStr = static_cast<const OUString*>(rVclIter.iter->GetUserData());
-        if (pStr)
-            return *pStr;
-        return OUString();
-    }
+bool SalInstanceTreeView::get_row_expanded(const weld::TreeIter& rIter) const
+{
+    const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
+    return m_xTreeView->IsExpanded(rVclIter.iter);
+}
 
-    virtual void set_expander_image(const weld::TreeIter& rIter, const OUString& rImage) override
-    {
-        const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
-        Image aImage(createImage(rImage));
-        m_xTreeView->SetExpandedEntryBmp(rVclIter.iter, aImage);
-        m_xTreeView->SetCollapsedEntryBmp(rVclIter.iter, aImage);
-    }
+void SalInstanceTreeView::expand_row(weld::TreeIter& rIter)
+{
+    SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
+    if (!m_xTreeView->IsExpanded(rVclIter.iter) && signal_expanding(rIter))
+        m_xTreeView->Expand(rVclIter.iter);
+}
 
-    virtual void set_selection_mode(SelectionMode eMode) override
-    {
-        m_xTreeView->SetSelectionMode(eMode);
-    }
+void SalInstanceTreeView::collapse_row(weld::TreeIter& rIter)
+{
+    SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter);
+    if (m_xTreeView->IsExpanded(rVclIter.iter))
+        m_xTreeView->Collapse(rVclIter.iter);
+}
 
-    virtual int count_selected_rows() const override
-    {
-        return m_xTreeView->GetSelectionCount();
-    }
+OUString SalInstanceTreeView::get_text(const weld::TreeIter& rIter) const
+{
+    const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
+    return SvTabListBox::GetEntryText(rVclIter.iter, 0);
+}
 
-    virtual int get_height_rows(int nRows) const override
-    {
-        return m_xTreeView->GetEntryHeight() * nRows;
-    }
+OUString SalInstanceTreeView::get_id(const weld::TreeIter& rIter) const
+{
+    const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
+    const OUString* pStr = static_cast<const OUString*>(rVclIter.iter->GetUserData());
+    if (pStr)
+        return *pStr;
+    return OUString();
+}
 
-    virtual void make_sorted() override
-    {
-        m_xTreeView->SetStyle(m_xTreeView->GetStyle() | WB_SORT);
-        m_xTreeView->GetModel()->Resort();
-    }
+void SalInstanceTreeView::set_expander_image(const weld::TreeIter& rIter, const OUString& rImage)
+{
+    const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
+    Image aImage(createImage(rImage));
+    m_xTreeView->SetExpandedEntryBmp(rVclIter.iter, aImage);
+    m_xTreeView->SetCollapsedEntryBmp(rVclIter.iter, aImage);
+}
 
-    SvTabListBox& getTreeView()
-    {
-        return *m_xTreeView;
-    }
+void SalInstanceTreeView::set_selection_mode(SelectionMode eMode)
+{
+    m_xTreeView->SetSelectionMode(eMode);
+}
+
+int SalInstanceTreeView::count_selected_rows() const
+{
+    return m_xTreeView->GetSelectionCount();
+}
+
+int SalInstanceTreeView::get_height_rows(int nRows) const
+{
+    return m_xTreeView->GetEntryHeight() * nRows;
+}
+
+void SalInstanceTreeView::make_sorted()
+{
+    m_xTreeView->SetStyle(m_xTreeView->GetStyle() | WB_SORT);
+    m_xTreeView->GetModel()->Resort();
+}
+
+SvTabListBox& SalInstanceTreeView::getTreeView()
+{
+    return *m_xTreeView;
+}
 
-    virtual ~SalInstanceTreeView() override
+SalInstanceTreeView::~SalInstanceTreeView()
+{
+    SvHeaderTabListBox* pHeaderBox = dynamic_cast<SvHeaderTabListBox*>(m_xTreeView.get());
+    if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
     {
-        SvHeaderTabListBox* pHeaderBox = dynamic_cast<SvHeaderTabListBox*>(m_xTreeView.get());
-        if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr)
-        {
-            pHeaderBar->SetEndDragHdl(Link<HeaderBar*, void>());
-        }
-        m_xTreeView->SetExpandingHdl(Link<SvTreeListBox*, bool>());
-        m_xTreeView->SetDoubleClickHdl(Link<SvTreeListBox*, bool>());
-        m_xTreeView->SetSelectHdl(Link<SvTreeListBox*, void>());
+        pHeaderBar->SetEndDragHdl(Link<HeaderBar*, void>());
     }
-};
+    m_xTreeView->SetExpandingHdl(Link<SvTreeListBox*, bool>());
+    m_xTreeView->SetDoubleClickHdl(Link<SvTreeListBox*, bool>());
+    m_xTreeView->SetSelectHdl(Link<SvTreeListBox*, void>());
+}
 
 IMPL_LINK(SalInstanceTreeView, ToggleHdl, SvLBoxButtonData*, pData, void)
 {
commit 99f435add4481eb8c9073b3ef673c014332c08cd
Author:     Szymon Kłos <szymon.klos at collabora.com>
AuthorDate: Tue Mar 24 14:54:18 2020 +0100
Commit:     Szymon Kłos <szymon.klos at collabora.com>
CommitDate: Wed Apr 1 12:08:57 2020 +0200

    jsdialog: export entries for treelistbox
    
    Change-Id: I19767d8971b39741208c1a50c63fc91101184e9b

diff --git a/include/vcl/treelistbox.hxx b/include/vcl/treelistbox.hxx
index cfb6b8cf7de8..3f6d70794424 100644
--- a/include/vcl/treelistbox.hxx
+++ b/include/vcl/treelistbox.hxx
@@ -765,6 +765,8 @@ public:
     void            SetForceMakeVisible(bool bEnable);
 
     virtual FactoryFunction GetUITestFactory() const override;
+
+    virtual boost::property_tree::ptree DumpAsPropertyTree() override;
 };
 
 class SvInplaceEdit2
diff --git a/vcl/source/treelist/treelistbox.cxx b/vcl/source/treelist/treelistbox.cxx
index a276f3002922..ac270538e5c4 100644
--- a/vcl/source/treelist/treelistbox.cxx
+++ b/vcl/source/treelist/treelistbox.cxx
@@ -3704,6 +3704,44 @@ bool SvTreeListBox::set_property(const OString &rKey, const OUString &rValue)
     return true;
 }
 
+boost::property_tree::ptree SvTreeListBox::DumpAsPropertyTree()
+{
+    boost::property_tree::ptree aTree = Control::DumpAsPropertyTree();
+
+    boost::property_tree::ptree aEntries;
+
+    SvTreeListEntry* pEntry = First();
+    for(sal_uLong i = 0; i < GetEntryCount() && pEntry; ++i)
+    {
+        boost::property_tree::ptree aEntry;
+        aEntry.put("", GetEntryText(pEntry));
+
+        aEntries.push_back(std::make_pair("", aEntry));
+
+        pEntry = Next(pEntry);
+    }
+
+    aTree.add_child("entries", aEntries);
+
+    boost::property_tree::ptree aSelected;
+
+    SvTreeListEntry* pSelected = FirstSelected();
+    for (sal_uLong i = 0; i < GetSelectionCount() && pSelected; ++i)
+    {
+        boost::property_tree::ptree aEntry;
+        aEntry.put("", GetEntryText(pSelected));
+
+        aSelected.push_back(std::make_pair("", aEntry));
+
+        pSelected = NextSelected(pSelected);
+    }
+
+    aTree.put("selectedCount", GetSelectionCount());
+    aTree.add_child("selectedEntries", aSelected);
+
+    return aTree;
+}
+
 FactoryFunction SvTreeListBox::GetUITestFactory() const
 {
     return TreeListUIObject::create;
commit dc1af580a4de2dc82fbcbc05ca0593493b07008e
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Tue Jun 18 14:04:27 2019 +0100
Commit:     Szymon Kłos <szymon.klos at collabora.com>
CommitDate: Wed Apr 1 12:08:56 2020 +0200

    fix crash in header/footer calc dialog
    
    cut and paste can happen when the EditView isn't in a vcl::Window
    
    Change-Id: I9fdbfe28c5ca5dd680b821ff8ce4e0133ab203aa
    Reviewed-on: https://gerrit.libreoffice.org/74279
    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/uiconfig/ui/spellingdialog.ui b/cui/uiconfig/ui/spellingdialog.ui
index 742f9a130aa2..ccc6a30e7a46 100644
--- a/cui/uiconfig/ui/spellingdialog.ui
+++ b/cui/uiconfig/ui/spellingdialog.ui
@@ -509,8 +509,6 @@
     </child>
     <action-widgets>
       <action-widget response="-11">help</action-widget>
-      <action-widget response="0">options</action-widget>
-      <action-widget response="0">undo</action-widget>
       <action-widget response="-7">close</action-widget>
     </action-widgets>
   </object>
diff --git a/editeng/source/editeng/impedit.cxx b/editeng/source/editeng/impedit.cxx
index 8936acfef0d0..85f9ad95ffbd 100644
--- a/editeng/source/editeng/impedit.cxx
+++ b/editeng/source/editeng/impedit.cxx
@@ -28,6 +28,7 @@
 #include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
 #include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp>
 #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
+#include <com/sun/star/datatransfer/clipboard/SystemClipboard.hpp>
 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
 #include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
 #include <comphelper/lok.hxx>
@@ -37,8 +38,9 @@
 #include <sot/exchange.hxx>
 #include <sot/formats.hxx>
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
-#include <comphelper/string.hxx>
 #include <comphelper/lok.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
 #include <sfx2/lokhelper.hxx>
 #include <boost/property_tree/json_parser.hpp>
 
@@ -1371,6 +1373,13 @@ Pair ImpEditView::Scroll( long ndX, long ndY, ScrollRangeCheck nRangeCheck )
     return Pair( nRealDiffX, nRealDiffY );
 }
 
+Reference<css::datatransfer::clipboard::XClipboard> ImpEditView::GetClipboard()
+{
+    if (vcl::Window* pWindow = GetWindow())
+        return pWindow->GetClipboard();
+    return css::datatransfer::clipboard::SystemClipboard::create(comphelper::getProcessComponentContext());
+}
+
 bool ImpEditView::PostKeyEvent( const KeyEvent& rKeyEvent, vcl::Window const * pFrameWin )
 {
     bool bDone = false;
@@ -1384,7 +1393,7 @@ bool ImpEditView::PostKeyEvent( const KeyEvent& rKeyEvent, vcl::Window const * p
             {
                 if ( !bReadOnly )
                 {
-                    Reference<css::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetClipboard());
+                    Reference<css::datatransfer::clipboard::XClipboard> aClipBoard(GetClipboard());
                     CutCopy( aClipBoard, true );
                     bDone = true;
                 }
@@ -1392,7 +1401,7 @@ bool ImpEditView::PostKeyEvent( const KeyEvent& rKeyEvent, vcl::Window const * p
             break;
             case KeyFuncType::COPY:
             {
-                Reference<css::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetClipboard());
+                Reference<css::datatransfer::clipboard::XClipboard> aClipBoard(GetClipboard());
                 CutCopy( aClipBoard, false );
                 bDone = true;
             }
@@ -1402,7 +1411,7 @@ bool ImpEditView::PostKeyEvent( const KeyEvent& rKeyEvent, vcl::Window const * p
                 if ( !bReadOnly && IsPasteEnabled() )
                 {
                     pEditEngine->pImpEditEngine->UndoActionStart( EDITUNDO_PASTE );
-                    Reference<css::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetClipboard());
+                    Reference<css::datatransfer::clipboard::XClipboard> aClipBoard(GetClipboard());
                     Paste( aClipBoard, pEditEngine->pImpEditEngine->GetStatus().AllowPasteSpecial() );
                     pEditEngine->pImpEditEngine->UndoActionEnd();
                     bDone = true;
@@ -1440,12 +1449,12 @@ bool ImpEditView::MouseButtonUp( const MouseEvent& rMouseEvent )
         if ( rMouseEvent.IsMiddle() && !bReadOnly &&
              ( pWindow->GetSettings().GetMouseSettings().GetMiddleButtonAction() == MouseMiddleButtonAction::PasteSelection ) )
         {
-            Reference<css::datatransfer::clipboard::XClipboard> aClipBoard(pWindow->GetPrimarySelection());
+            Reference<css::datatransfer::clipboard::XClipboard> aClipBoard(GetClipboard());
             Paste( aClipBoard );
         }
         else if ( rMouseEvent.IsLeft() && GetEditSelection().HasRange() )
         {
-            Reference<css::datatransfer::clipboard::XClipboard> aClipBoard(pWindow->GetPrimarySelection());
+            Reference<css::datatransfer::clipboard::XClipboard> aClipBoard(GetClipboard());
             CutCopy( aClipBoard, false );
         }
     }
diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx
index 8d9450f6d5c6..b37d0ee72bb0 100644
--- a/editeng/source/editeng/impedit.hxx
+++ b/editeng/source/editeng/impedit.hxx
@@ -280,6 +280,8 @@ private:
 
     void InvalidateAtWindow(const tools::Rectangle& rRect);
 
+    css::uno::Reference<css::datatransfer::clipboard::XClipboard> GetClipboard();
+
 protected:
 
     // DragAndDropClient
commit 307e43b70b24117a2c6ece40bfe7fb12845e1026
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Wed Jun 19 12:10:12 2019 +0100
Commit:     Szymon Kłos <szymon.klos at collabora.com>
CommitDate: Wed Apr 1 12:08:56 2020 +0200

    allow copy/paste when not hosted in vcl::Window
    
    Change-Id: I1b30cb700461fa66192a4b86bf577d1babc76cb7
    Reviewed-on: https://gerrit.libreoffice.org/74353
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/editeng/source/editeng/editview.cxx b/editeng/source/editeng/editview.cxx
index 4ae8e26fc6cb..7c78557dc7a8 100644
--- a/editeng/source/editeng/editview.cxx
+++ b/editeng/source/editeng/editview.cxx
@@ -597,7 +597,7 @@ ErrCode EditView::Read( SvStream& rInput, EETextFormat eFormat, SvKeyValueIterat
 
 void EditView::Cut()
 {
-    Reference<css::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetClipboard());
+    Reference<css::datatransfer::clipboard::XClipboard> aClipBoard(pImpEditView->GetClipboard());
     pImpEditView->CutCopy( aClipBoard, true );
 }
 
@@ -610,19 +610,19 @@ css::uno::Reference< css::datatransfer::XTransferable > EditView::GetTransferabl
 
 void EditView::Copy()
 {
-    Reference<css::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetClipboard());
+    Reference<css::datatransfer::clipboard::XClipboard> aClipBoard(pImpEditView->GetClipboard());
     pImpEditView->CutCopy( aClipBoard, false );
 }
 
 void EditView::Paste()
 {
-    Reference<css::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetClipboard());
+    Reference<css::datatransfer::clipboard::XClipboard> aClipBoard(pImpEditView->GetClipboard());
     pImpEditView->Paste( aClipBoard );
 }
 
 void EditView::PasteSpecial()
 {
-    Reference<css::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetClipboard());
+    Reference<css::datatransfer::clipboard::XClipboard> aClipBoard(pImpEditView->GetClipboard());
     pImpEditView->Paste(aClipBoard, true );
 }
 
commit 57077d1cb6ca9bc2157527df2ab3e18a15299da7
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Fri Jun 14 21:56:44 2019 +0100
Commit:     Szymon Kłos <szymon.klos at collabora.com>
CommitDate: Wed Apr 1 12:08:55 2020 +0200

    weld SpellDialog
    
    a) use EditEngine instead of TextEngine as the former can be hosted in a
       foreign widget
    b) use a SfxGrabBagItem to hold the custom spellchecking info inside the
       EditEngine
    c) in longer paragraphs the current word is now auto-scrolled into view
    d) rename Invalidate to InvalidateDialog
    
    Change-Id: Ic6db019c32cdfd5f354c58ee7394fdaa040b86e1
    Reviewed-on: https://gerrit.libreoffice.org/74119
    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/Library_cui.mk b/cui/Library_cui.mk
index 4db46539816c..04e82bdd8b0d 100644
--- a/cui/Library_cui.mk
+++ b/cui/Library_cui.mk
@@ -131,7 +131,6 @@ $(eval $(call gb_Library_add_exception_objects,cui,\
     cui/source/dialogs/SignSignatureLineDialog \
     cui/source/dialogs/sdrcelldlg \
     cui/source/dialogs/showcols \
-    cui/source/dialogs/SpellAttrib \
     cui/source/dialogs/SpellDialog \
     cui/source/dialogs/splitcelldlg \
     cui/source/dialogs/srchxtra \
diff --git a/cui/source/dialogs/SpellAttrib.cxx b/cui/source/dialogs/SpellAttrib.cxx
deleted file mode 100644
index 9d761a55b3f1..000000000000
--- a/cui/source/dialogs/SpellAttrib.cxx
+++ /dev/null
@@ -1,105 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- *   Licensed to the Apache Software Foundation (ASF) under one or more
- *   contributor license agreements. See the NOTICE file distributed
- *   with this work for additional information regarding copyright
- *   ownership. The ASF licenses this file to you under the Apache
- *   License, Version 2.0 (the "License"); you may not use this file
- *   except in compliance with the License. You may obtain a copy of
- *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#include "SpellAttrib.hxx"
-#include <vcl/font.hxx>
-
-using namespace svx;
-using namespace com::sun::star::linguistic2;
-using namespace com::sun::star::uno;
-
-
-SpellErrorAttrib::SpellErrorAttrib( const SpellErrorDescription& rDesc ) :
-    TextAttrib(TEXTATTR_SPELL_ERROR),
-    m_aSpellErrorDescription( rDesc )
-{
-}
-
-
-void SpellErrorAttrib::SetFont( vcl::Font&  ) const
-{
-    //this attribute doesn't have a visual effect
-}
-
-
-std::unique_ptr<TextAttrib> SpellErrorAttrib::Clone() const
-{
-    return std::unique_ptr<TextAttrib>(new SpellErrorAttrib(*this));
-}
-
-
-bool SpellErrorAttrib::operator==( const TextAttrib& rAttr ) const
-{
-    return Which() == rAttr.Which() &&
-            m_aSpellErrorDescription == static_cast<const SpellErrorAttrib&>(rAttr).m_aSpellErrorDescription;
-}
-
-
-SpellLanguageAttrib::SpellLanguageAttrib(LanguageType eLang) :
-    TextAttrib(TEXTATTR_SPELL_LANGUAGE),
-    m_eLanguage(eLang)
-{
-}
-
-
-void SpellLanguageAttrib::SetFont( vcl::Font&  ) const
-{
-    //no visual effect
-}
-
-
-std::unique_ptr<TextAttrib> SpellLanguageAttrib::Clone() const
-{
-    return std::unique_ptr<TextAttrib>(new SpellLanguageAttrib(*this));
-}
-
-
-bool SpellLanguageAttrib::operator==( const TextAttrib& rAttr ) const
-{
-    return Which() == rAttr.Which() &&
-            m_eLanguage == static_cast<const SpellLanguageAttrib&>(rAttr).m_eLanguage;
-}
-
-
-SpellBackgroundAttrib::SpellBackgroundAttrib(const Color& rCol) :
-    TextAttrib(TEXTATTR_SPELL_BACKGROUND),
-    m_aBackgroundColor(rCol)
-{
-}
-
-
-void SpellBackgroundAttrib::SetFont( vcl::Font& rFont ) const
-{
-    rFont.SetFillColor(m_aBackgroundColor);
-}
-
-
-std::unique_ptr<TextAttrib> SpellBackgroundAttrib::Clone() const
-{
-    return std::unique_ptr<TextAttrib>(new SpellBackgroundAttrib(*this));
-}
-
-
-bool SpellBackgroundAttrib::operator==( const TextAttrib& rAttr ) const
-{
-    return Which() == rAttr.Which() &&
-            m_aBackgroundColor == static_cast<const SpellBackgroundAttrib&>(rAttr).m_aBackgroundColor;
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/SpellAttrib.hxx b/cui/source/dialogs/SpellAttrib.hxx
index 2a458166b42d..a106bce963b6 100644
--- a/cui/source/dialogs/SpellAttrib.hxx
+++ b/cui/source/dialogs/SpellAttrib.hxx
@@ -19,7 +19,6 @@
 #ifndef INCLUDED_CUI_SOURCE_DIALOGS_SPELLATTRIB_HXX
 #define INCLUDED_CUI_SOURCE_DIALOGS_SPELLATTRIB_HXX
 
-#include <vcl/txtattr.hxx>
 #include <i18nlangtag/lang.h>
 #include <com/sun/star/uno/Reference.h>
 #include <com/sun/star/uno/Sequence.h>
@@ -27,10 +26,6 @@
 #include <com/sun/star/linguistic2/XProofreader.hpp>
 #include <tools/color.hxx>
 
-#define TEXTATTR_SPELL_ERROR            (TEXTATTR_USER_START + 1)
-#define TEXTATTR_SPELL_LANGUAGE         (TEXTATTR_USER_START + 2)
-#define TEXTATTR_SPELL_BACKGROUND       (TEXTATTR_USER_START + 3)
-
 namespace svx{
 struct SpellErrorDescription
 {
@@ -61,16 +56,21 @@ struct SpellErrorDescription
         aLocale( rLocale ),
         xGrammarChecker( rxGrammarChecker ),
         aSuggestions( rSuggestions )
-        {
-            if( pDialogTitle )
-                sDialogTitle = *pDialogTitle;
-            if( pExplanation )
-                sExplanation = *pExplanation;
-            if( pExplanationURL )
-                sExplanationURL = *pExplanationURL;
-            if( pRuleId )
-                sRuleId = *pRuleId;
-        };
+    {
+        if( pDialogTitle )
+            sDialogTitle = *pDialogTitle;
+        if( pExplanation )
+            sExplanation = *pExplanation;
+        if( pExplanationURL )
+            sExplanationURL = *pExplanationURL;
+        if( pRuleId )
+            sRuleId = *pRuleId;
+    };
+
+    SpellErrorDescription()
+        : bIsGrammarError(false)
+    {
+    }
 
     bool operator==( const SpellErrorDescription& rDesc ) const
     {
@@ -86,54 +86,36 @@ struct SpellErrorDescription
                 sExplanationURL == rDesc.sExplanationURL &&
                 sRuleId == rDesc.sRuleId;
     }
-};
-
-
-class SpellErrorAttrib : public TextAttrib
-{
-public:
-
-private:
-    SpellErrorDescription        m_aSpellErrorDescription;
-
-public:
-                            SpellErrorAttrib( const SpellErrorDescription& );
-
-    const SpellErrorDescription& GetErrorDescription() const { return m_aSpellErrorDescription; }
-
-
-    virtual void            SetFont( vcl::Font& rFont ) const override;
-    virtual std::unique_ptr<TextAttrib> Clone() const override;
-    virtual bool            operator==( const TextAttrib& rAttr ) const override;
-};
 
+    css::uno::Sequence<css::uno::Any> toSequence() const
+    {
+        css::uno::Sequence<css::uno::Any> aEntries(9);
+        aEntries[0] <<= bIsGrammarError;
+        aEntries[1] <<= sErrorText;
+        aEntries[2] <<= sDialogTitle;
+        aEntries[3] <<= sExplanation;
+        aEntries[4] <<= sExplanationURL;
+        aEntries[5] <<= aLocale;
+        aEntries[6] <<= xGrammarChecker;
+        aEntries[7] <<= aSuggestions;
+        aEntries[8] <<= sRuleId;
+        return aEntries;
+    }
 
-class SpellLanguageAttrib : public TextAttrib
-{
-    LanguageType m_eLanguage;
-
-public:
-                            SpellLanguageAttrib(LanguageType eLanguage);
-
-    LanguageType            GetLanguage() const {return m_eLanguage;}
-
-    virtual void            SetFont( vcl::Font& rFont ) const override;
-    virtual std::unique_ptr<TextAttrib> Clone() const override;
-    virtual bool            operator==( const TextAttrib& rAttr ) const override;
+    void fromSequence(const css::uno::Sequence<css::uno::Any>& rEntries)
+    {
+        rEntries[0] >>= bIsGrammarError;
+        rEntries[1] >>= sErrorText;
+        rEntries[2] >>= sDialogTitle;
+        rEntries[3] >>= sExplanation;
+        rEntries[4] >>= sExplanationURL;
+        rEntries[5] >>= aLocale;
+        rEntries[6] >>= xGrammarChecker;
+        rEntries[7] >>= aSuggestions;
+        rEntries[8] >>= sRuleId;
+    }
 };
 
-
-class SpellBackgroundAttrib : public TextAttrib
-{
-    Color   m_aBackgroundColor;
-
-public:
-                            SpellBackgroundAttrib(const Color& rCol);
-
-    virtual void            SetFont( vcl::Font& rFont ) const override;
-    virtual std::unique_ptr<TextAttrib> Clone() const override;
-    virtual bool            operator==( const TextAttrib& rAttr ) const override;
-};
 }//namespace svx
 #endif
 
diff --git a/cui/source/dialogs/SpellDialog.cxx b/cui/source/dialogs/SpellDialog.cxx
index 6c4e36645772..68ef370f65e7 100644
--- a/cui/source/dialogs/SpellDialog.cxx
+++ b/cui/source/dialogs/SpellDialog.cxx
@@ -18,21 +18,20 @@
  */
 
 #include <memory>
-#include <vcl/weld.hxx>
-#include <vcl/wrkwin.hxx>
-#include <vcl/menu.hxx>
-#include <vcl/layout.hxx>
-#include <vcl/scrbar.hxx>
-#include <vcl/settings.hxx>
 #include "SpellAttrib.hxx"
 #include <sfx2/dispatch.hxx>
 #include <sfx2/bindings.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <sfx2/viewfrm.hxx>
+#include <svl/grabbagitem.hxx>
 #include <svl/undo.hxx>
 #include <unotools/lingucfg.hxx>
-#include <vcl/textdata.hxx>
-#include <vcl/graphicfilter.hxx>
-#include <editeng/unolingu.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/langitem.hxx>
 #include <editeng/splwrap.hxx>
+#include <editeng/unolingu.hxx>
+#include <editeng/wghtitem.hxx>
 #include <linguistic/lngprops.hxx>
 #include <linguistic/misc.hxx>
 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
@@ -40,9 +39,15 @@
 #include <com/sun/star/lang/XServiceDisplayName.hpp>
 #include <com/sun/star/frame/XStorable.hpp>
 #include <sfx2/app.hxx>
-#include <vcl/help.hxx>
+#include <vcl/cursor.hxx>
+#include <vcl/event.hxx>
 #include <vcl/graph.hxx>
-#include <vcl/builderfactory.hxx>
+#include <vcl/help.hxx>
+#include <vcl/graphicfilter.hxx>
+#include <vcl/ptrstyle.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
 #include <osl/file.hxx>
 #include <editeng/optitems.hxx>
 #include <editeng/svxenum.hxx>
@@ -157,80 +162,72 @@ sal_uInt16 SpellUndoAction_Impl::GetId()const
 // class SvxSpellCheckDialog ---------------------------------------------
 
 SpellDialog::SpellDialog(SpellDialogChildWindow* pChildWindow,
-    vcl::Window * pParent, SfxBindings* _pBindings)
-    : SfxModelessDialog (_pBindings, pChildWindow,
-        pParent, "SpellingDialog", "cui/ui/spellingdialog.ui")
+    weld::Window * pParent, SfxBindings* _pBindings)
+    : SfxModelessDialogController (_pBindings, pChildWindow,
+        pParent, "cui/ui/spellingdialog.ui", "SpellingDialog")
     , aDialogUndoLink(LINK (this, SpellDialog, DialogUndoHdl))
     , bFocusLocked(true)
     , rParent(*pChildWindow)
     , pImpl( new SpellDialog_Impl )
-{
-    m_sTitleSpellingGrammar = GetText();
-    m_sTitleSpelling = get<FixedText>("alttitleft")->GetText();
+    , m_xAltTitle(m_xBuilder->weld_label("alttitleft"))
+    , m_xResumeFT(m_xBuilder->weld_label("resumeft"))
+    , m_xNoSuggestionsFT(m_xBuilder->weld_label("nosuggestionsft"))
+    , m_xLanguageFT(m_xBuilder->weld_label("languageft"))
+    , m_xLanguageLB(new LanguageBox(m_xBuilder->weld_combo_box("languagelb")))
+    , m_xExplainFT(m_xBuilder->weld_label("explain"))
+    , m_xExplainLink(m_xBuilder->weld_link_button("explainlink"))
+    , m_xNotInDictFT(m_xBuilder->weld_label("notindictft"))
+    , m_xSentenceED(new SentenceEditWindow_Impl)
+    , m_xSuggestionFT(m_xBuilder->weld_label("suggestionsft"))
+    , m_xSuggestionLB(m_xBuilder->weld_tree_view("suggestionslb"))
+    , m_xIgnorePB(m_xBuilder->weld_button("ignore"))
+    , m_xIgnoreAllPB(m_xBuilder->weld_button("ignoreall"))
+    , m_xIgnoreRulePB(m_xBuilder->weld_button("ignorerule"))
+    , m_xAddToDictPB(m_xBuilder->weld_button("add"))
+    , m_xAddToDictMB(m_xBuilder->weld_menu_button("addmb"))
+    , m_xChangePB(m_xBuilder->weld_button("change"))
+    , m_xChangeAllPB(m_xBuilder->weld_button("changeall"))
+    , m_xAutoCorrPB(m_xBuilder->weld_button("autocorrect"))
+    , m_xCheckGrammarCB(m_xBuilder->weld_check_button("checkgrammar"))
+    , m_xOptionsPB(m_xBuilder->weld_button("options"))
+    , m_xUndoPB(m_xBuilder->weld_button("undo"))
+    , m_xClosePB(m_xBuilder->weld_button("close"))
+    , m_xToolbar(m_xBuilder->weld_toolbar("toolbar"))
+    , m_xSentenceEDWeld(new weld::CustomWeld(*m_xBuilder, "sentence", *m_xSentenceED))
+{
+    m_xSentenceED->SetSpellDialog(this);
+    m_xSentenceED->Init(m_xToolbar.get());
+
+    m_sTitleSpellingGrammar = m_xDialog->get_title();
+    m_sTitleSpelling = m_xAltTitle->get_label();
 
     // fdo#68794 set initial title for cases where no text has been processed
     // yet to show its language attributes
     OUString sTitle = rParent.HasGrammarChecking() ? m_sTitleSpellingGrammar : m_sTitleSpelling;
-    SetText(sTitle.replaceFirst("$LANGUAGE ($LOCATION)", ""));
-
-    m_sResumeST = get<FixedText>("resumeft")->GetText();
-    m_sNoSuggestionsST = get<FixedText>("nosuggestionsft")->GetText();
-
-    get(m_pLanguageFT, "languageft");
-    get(m_pLanguageLB, "languagelb");
-    get(m_pExplainFT, "explain");
-    get(m_pExplainLink, "explainlink");
-    get(m_pNotInDictFT, "notindictft");
-    get(m_pSentenceED, "sentence");
-    Size aEdSize(LogicToPixel(Size(197, 48), MapMode(MapUnit::MapAppFont)));
-    m_pSentenceED->set_width_request(aEdSize.Width());
-    m_pSentenceED->set_height_request(aEdSize.Height());
-    get(m_pSuggestionFT, "suggestionsft");
-    get(m_pSuggestionLB, "suggestionslb");
-    m_pSuggestionLB->SetDropDownLineCount(5);
-    m_pSuggestionLB->set_width_request(aEdSize.Width());
-    get(m_pIgnorePB, "ignore");
-    m_sIgnoreOnceST = m_pIgnorePB->GetText();
-    get(m_pIgnoreAllPB, "ignoreall");
-    get(m_pIgnoreRulePB, "ignorerule");
-    get(m_pAddToDictPB, "add");
-    get(m_pAddToDictMB, "addmb");
-    m_pAddToDictMB->SetHelpId(m_pAddToDictPB->GetHelpId());
-    get(m_pChangePB, "change");
-    get(m_pChangeAllPB, "changeall");
-    get(m_pAutoCorrPB, "autocorrect");
-    get(m_pCheckGrammarCB, "checkgrammar");
-    get(m_pOptionsPB, "options");
-    get(m_pUndoPB, "undo");
-    get(m_pClosePB, "close");
-    get(m_pToolbar, "toolbar");
-    m_pSentenceED->Init(m_pToolbar);
-    xSpell = LinguMgr::GetSpellChecker();
+    m_xDialog->set_title(m_xDialog->strip_mnemonic(sTitle.replaceFirst("$LANGUAGE ($LOCATION)", "")));
 
-    const StyleSettings& rSettings = GetSettings().GetStyleSettings();
-    Color aCol = rSettings.GetHelpColor();
-    Wallpaper aWall( aCol );
-    m_pExplainLink->SetBackground( aWall );
-    m_pExplainFT->SetBackground( aWall );
+    m_sResumeST = m_xResumeFT->get_label();
+    m_sNoSuggestionsST = m_xNoSuggestionsFT->strip_mnemonic(m_xNoSuggestionsFT->get_label());
+
+    Size aEdSize(m_xSuggestionLB->get_approximate_digit_width() * 60,
+                 m_xSuggestionLB->get_height_rows(6));
+    m_xSuggestionLB->set_size_request(aEdSize.Width(), -1);
+    m_sIgnoreOnceST = m_xIgnorePB->get_label();
+    m_xAddToDictMB->set_help_id(m_xAddToDictPB->get_help_id());
+    xSpell = LinguMgr::GetSpellChecker();
 
     Init_Impl();
 
     // disable controls if service is missing
-    Enable(xSpell.is());
+    m_xDialog->set_sensitive(xSpell.is());
 
     //InitHdl wants to use virtual methods, so it
     //can't be called during the ctor, so init
     //it on next event cycle post-ctor
-    Application::PostUserEvent(
-        LINK( this, SpellDialog, InitHdl ), nullptr, true );
+    Application::PostUserEvent(LINK(this, SpellDialog, InitHdl));
 }
 
 SpellDialog::~SpellDialog()
-{
-    disposeOnce();
-}
-
-void SpellDialog::dispose()
 {
     if (pImpl)
     {
@@ -241,90 +238,69 @@ void SpellDialog::dispose()
 
         pImpl.reset();
     }
-    m_pLanguageFT.clear();
-    m_pLanguageLB.clear();
-    m_pExplainFT.clear();
-    m_pExplainLink.clear();
-    m_pNotInDictFT.clear();
-    m_pSentenceED.clear();
-    m_pSuggestionFT.clear();
-    m_pSuggestionLB.clear();
-    m_pIgnorePB.clear();
-    m_pIgnoreAllPB.clear();
-    m_pIgnoreRulePB.clear();
-    m_pAddToDictPB.clear();
-    m_pAddToDictMB.clear();
-    m_pChangePB.clear();
-    m_pChangeAllPB.clear();
-    m_pAutoCorrPB.clear();
-    m_pCheckGrammarCB.clear();
-    m_pOptionsPB.clear();
-    m_pUndoPB.clear();
-    m_pClosePB.clear();
-    m_pToolbar.clear();
-    SfxModelessDialog::dispose();
 }
 
 void SpellDialog::Init_Impl()
 {
     // initialize handler
-    m_pClosePB->SetClickHdl(LINK( this, SpellDialog, CancelHdl ) );
-    m_pChangePB->SetClickHdl(LINK( this, SpellDialog, ChangeHdl ) );
-    m_pChangeAllPB->SetClickHdl(LINK( this, SpellDialog, ChangeAllHdl ) );
-    m_pIgnorePB->SetClickHdl(LINK( this, SpellDialog, IgnoreHdl ) );
-    m_pIgnoreAllPB->SetClickHdl(LINK( this, SpellDialog, IgnoreAllHdl ) );
-    m_pIgnoreRulePB->SetClickHdl(LINK( this, SpellDialog, IgnoreAllHdl ) );
-    m_pUndoPB->SetClickHdl(LINK( this, SpellDialog, UndoHdl ) );
+    m_xClosePB->connect_clicked(LINK( this, SpellDialog, CancelHdl ) );
+    m_xChangePB->connect_clicked(LINK( this, SpellDialog, ChangeHdl ) );
+    m_xChangeAllPB->connect_clicked(LINK( this, SpellDialog, ChangeAllHdl ) );
+    m_xIgnorePB->connect_clicked(LINK( this, SpellDialog, IgnoreHdl ) );
+    m_xIgnoreAllPB->connect_clicked(LINK( this, SpellDialog, IgnoreAllHdl ) );
+    m_xIgnoreRulePB->connect_clicked(LINK( this, SpellDialog, IgnoreAllHdl ) );
+    m_xUndoPB->connect_clicked(LINK( this, SpellDialog, UndoHdl ) );
 
-    m_pAutoCorrPB->SetClickHdl( LINK( this, SpellDialog, ExtClickHdl ) );
-    m_pCheckGrammarCB->SetClickHdl( LINK( this, SpellDialog, CheckGrammarHdl ));
-    m_pOptionsPB->SetClickHdl( LINK( this, SpellDialog, ExtClickHdl ) );
+    m_xAutoCorrPB->connect_clicked( LINK( this, SpellDialog, ExtClickHdl ) );
+    m_xCheckGrammarCB->connect_clicked( LINK( this, SpellDialog, CheckGrammarHdl ));
+    m_xOptionsPB->connect_clicked( LINK( this, SpellDialog, ExtClickHdl ) );
 
-    m_pSuggestionLB->SetDoubleClickHdl( LINK( this, SpellDialog, DoubleClickChangeHdl ) );
+    m_xSuggestionLB->connect_row_activated( LINK( this, SpellDialog, DoubleClickChangeHdl ) );
 
-    m_pSentenceED->SetModifyHdl(LINK ( this, SpellDialog, ModifyHdl) );
+    m_xSentenceED->SetModifyHdl(LINK ( this, SpellDialog, ModifyHdl) );
 
-    m_pAddToDictMB->SetSelectHdl(LINK ( this, SpellDialog, AddToDictSelectHdl ) );
-    m_pAddToDictPB->SetClickHdl(LINK ( this, SpellDialog, AddToDictClickHdl ) );
+    m_xAddToDictMB->connect_selected(LINK ( this, SpellDialog, AddToDictSelectHdl ) );
+    m_xAddToDictPB->connect_clicked(LINK ( this, SpellDialog, AddToDictClickHdl ) );
 
-    m_pLanguageLB->SetSelectHdl(LINK( this, SpellDialog, LanguageSelectHdl ) );
+    m_xLanguageLB->connect_changed(LINK( this, SpellDialog, LanguageSelectHdl ) );
 
     // initialize language ListBox
-    m_pLanguageLB->SetLanguageList( SvxLanguageListFlags::SPELL_USED, false, false, true );
+    m_xLanguageLB->SetLanguageList(SvxLanguageListFlags::SPELL_USED, false, false, true);
 
-    m_pSentenceED->ClearModifyFlag();
+    m_xSentenceED->ClearModifyFlag();
     LinguMgr::GetChangeAllList()->clear();
 }
 
 void SpellDialog::UpdateBoxes_Impl(bool bCallFromSelectHdl)
 {

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list