desktop/source/lib/init.cxx | 24 include/vcl/jsdialog/executor.hxx | 8 include/vcl/layout.hxx | 1 include/vcl/toolkit/edit.hxx | 2 include/vcl/toolkit/svtabbx.hxx | 2 include/vcl/weld.hxx | 4 sc/source/ui/app/inputwin.cxx | 24 sc/source/ui/cctrl/checklistmenu.cxx | 34 sc/source/ui/inc/checklistmenu.hxx | 5 sc/source/ui/view/gridwin.cxx | 9 sc/uiconfig/scalc/ui/notebookbar.ui | 59 sfx2/source/doc/objserv.cxx | 25 vcl/inc/jsdialog/jsdialogbuilder.hxx | 143 + vcl/inc/salvtables.hxx | 400 +++ vcl/jsdialog/executor.cxx | 80 vcl/jsdialog/jsdialogbuilder.cxx | 404 +++- vcl/source/app/salvtables.cxx | 2504 ++++++++++++------------- vcl/source/control/WeldedTabbedNotebookbar.cxx | 4 vcl/source/control/edit.cxx | 10 vcl/source/treelist/svtabbx.cxx | 49 vcl/source/window/builder.cxx | 10 vcl/source/window/layout.cxx | 6 22 files changed, 2314 insertions(+), 1493 deletions(-)
New commits: commit 18f441fe1c819d5c9c55734172844e68bf8dcc86 Author: Szymon Kłos <[email protected]> AuthorDate: Tue Nov 17 14:32:04 2020 +0100 Commit: Andras Timar <[email protected]> CommitDate: Tue Apr 6 21:49:35 2021 +0200 jsdialog: implemented Expander widget Change-Id: Ib0aee0e01c662a4d6a9231d9a1a951c9fa68eff4 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106693 Tested-by: Jenkins Reviewed-by: Szymon Kłos <[email protected]> diff --git a/vcl/inc/jsdialog/jsdialogbuilder.hxx b/vcl/inc/jsdialog/jsdialogbuilder.hxx index 5d7df8086ae4..4b9e042960f4 100644 --- a/vcl/inc/jsdialog/jsdialogbuilder.hxx +++ b/vcl/inc/jsdialog/jsdialogbuilder.hxx @@ -113,6 +113,7 @@ public: virtual std::unique_ptr<weld::Toolbar> weld_toolbar(const OString& id) override; virtual std::unique_ptr<weld::TextView> weld_text_view(const OString& id) override; virtual std::unique_ptr<weld::TreeView> weld_tree_view(const OString& id) override; + virtual std::unique_ptr<weld::Expander> weld_expander(const OString& id) override; static weld::MessageDialog* CreateMessageDialog(weld::Widget* pParent, VclMessageType eMessageType, @@ -310,4 +311,14 @@ public: virtual void select(int pos) override; }; +class JSExpander : public JSWidget<SalInstanceExpander, ::VclExpander> +{ +public: + JSExpander(VclPtr<vcl::Window> aNotifierWindow, VclPtr<vcl::Window> aContentWindow, + ::VclExpander* pExpander, SalInstanceBuilder* pBuilder, bool bTakeOwnership, + std::string sTypeOfJSON); + + virtual void set_expanded(bool bExpand) override; +}; + /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/vcl/jsdialog/executor.cxx b/vcl/jsdialog/executor.cxx index 6ded26055270..24e3eb1f14d3 100644 --- a/vcl/jsdialog/executor.cxx +++ b/vcl/jsdialog/executor.cxx @@ -209,6 +209,18 @@ bool ExecuteAction(sal_uInt64 nWindowId, const OString& rWidget, StringMap& rDat } } } + else if (sControlType == "expander") + { + auto pExpander = dynamic_cast<weld::Expander*>(pWidget); + if (pExpander) + { + if (sAction == "toggle") + { + pExpander->set_expanded(!pExpander->get_expanded()); + return true; + } + } + } } return false; diff --git a/vcl/jsdialog/jsdialogbuilder.cxx b/vcl/jsdialog/jsdialogbuilder.cxx index b72dae272500..4fb351b5439f 100644 --- a/vcl/jsdialog/jsdialogbuilder.cxx +++ b/vcl/jsdialog/jsdialogbuilder.cxx @@ -452,6 +452,20 @@ std::unique_ptr<weld::TreeView> JSInstanceBuilder::weld_tree_view(const OString& return pWeldWidget; } +std::unique_ptr<weld::Expander> JSInstanceBuilder::weld_expander(const OString& id) +{ + VclExpander* pExpander = m_xBuilder->get<VclExpander>(id); + auto pWeldWidget = pExpander + ? std::make_unique<JSExpander>(GetNotifierWindow(), GetContentWindow(), + pExpander, this, false, m_sTypeOfJSON) + : nullptr; + + if (pWeldWidget) + RememberWidget(id, pWeldWidget.get()); + + return pWeldWidget; +} + weld::MessageDialog* JSInstanceBuilder::CreateMessageDialog(weld::Widget* pParent, VclMessageType eMessageType, VclButtonsType eButtonType, @@ -779,4 +793,18 @@ void JSTreeView::select(int pos) enable_notify_events(); } +JSExpander::JSExpander(VclPtr<vcl::Window> aNotifierWindow, VclPtr<vcl::Window> aContentWindow, + ::VclExpander* pExpander, SalInstanceBuilder* pBuilder, bool bTakeOwnership, + std::string sTypeOfJSON) + : JSWidget<SalInstanceExpander, ::VclExpander>(aNotifierWindow, aContentWindow, pExpander, + pBuilder, bTakeOwnership, sTypeOfJSON) +{ +} + +void JSExpander::set_expanded(bool bExpand) +{ + SalInstanceExpander::set_expanded(bExpand); + notifyDialogState(); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ commit a71e7ee9b1a15c2e9ee3064d18c6fbe3523bc382 Author: Szymon Kłos <[email protected]> AuthorDate: Thu Nov 26 10:55:12 2020 +0100 Commit: Andras Timar <[email protected]> CommitDate: Tue Apr 6 21:49:18 2021 +0200 Move SalInstanceExpander decl to header file Change-Id: I5399f5aca07dd27dfc668cad66cf347936bbba7a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106664 Tested-by: Jenkins Reviewed-by: Szymon Kłos <[email protected]> diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx index c7d85b24d106..caf72be5f3de 100644 --- a/vcl/inc/salvtables.hxx +++ b/vcl/inc/salvtables.hxx @@ -1672,4 +1672,29 @@ public: virtual ~SalInstanceTreeView() override; }; +class SalInstanceExpander : public SalInstanceContainer, public virtual weld::Expander +{ +private: + VclPtr<VclExpander> m_xExpander; + + DECL_LINK(ExpandedHdl, VclExpander&, void); + +public: + SalInstanceExpander(VclExpander* pExpander, SalInstanceBuilder* pBuilder, bool bTakeOwnership); + + virtual void set_label(const OUString& rText) override; + + virtual OUString get_label() const override; + + virtual bool get_expanded() const override; + + virtual void set_expanded(bool bExpand) override; + + virtual bool has_focus() const override; + + virtual void grab_focus() override; + + virtual ~SalInstanceExpander() override; +}; + /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index abf265720383..f80d51e605ef 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -5683,43 +5683,32 @@ IMPL_LINK(SalInstanceTextView, CursorListener, VclWindowEvent&, rEvent, void) signal_cursor_position(); } -namespace -{ -class SalInstanceExpander : public SalInstanceContainer, public virtual weld::Expander +SalInstanceExpander::SalInstanceExpander(VclExpander* pExpander, SalInstanceBuilder* pBuilder, + bool bTakeOwnership) + : SalInstanceContainer(pExpander, pBuilder, bTakeOwnership) + , m_xExpander(pExpander) { -private: - VclPtr<VclExpander> m_xExpander; - - DECL_LINK(ExpandedHdl, VclExpander&, void); - -public: - SalInstanceExpander(VclExpander* pExpander, SalInstanceBuilder* pBuilder, bool bTakeOwnership) - : SalInstanceContainer(pExpander, pBuilder, bTakeOwnership) - , m_xExpander(pExpander) - { - m_xExpander->SetExpandedHdl(LINK(this, SalInstanceExpander, ExpandedHdl)); - } + m_xExpander->SetExpandedHdl(LINK(this, SalInstanceExpander, ExpandedHdl)); +} - virtual void set_label(const OUString& rText) override { m_xExpander->set_label(rText); } +void SalInstanceExpander::set_label(const OUString& rText) { m_xExpander->set_label(rText); } - virtual OUString get_label() const override { return m_xExpander->get_label(); } +OUString SalInstanceExpander::get_label() const { return m_xExpander->get_label(); } - virtual bool get_expanded() const override { return m_xExpander->get_expanded(); } +bool SalInstanceExpander::get_expanded() const { return m_xExpander->get_expanded(); } - virtual void set_expanded(bool bExpand) override { m_xExpander->set_expanded(bExpand); } +void SalInstanceExpander::set_expanded(bool bExpand) { m_xExpander->set_expanded(bExpand); } - virtual bool has_focus() const override - { - return m_xExpander->get_label_widget()->HasFocus() || SalInstanceContainer::has_focus(); - } +bool SalInstanceExpander::has_focus() const +{ + return m_xExpander->get_label_widget()->HasFocus() || SalInstanceContainer::has_focus(); +} - virtual void grab_focus() override { return m_xExpander->get_label_widget()->GrabFocus(); } +void SalInstanceExpander::grab_focus() { return m_xExpander->get_label_widget()->GrabFocus(); } - virtual ~SalInstanceExpander() override - { - m_xExpander->SetExpandedHdl(Link<VclExpander&, void>()); - } -}; +SalInstanceExpander::~SalInstanceExpander() +{ + m_xExpander->SetExpandedHdl(Link<VclExpander&, void>()); } IMPL_LINK_NOARG(SalInstanceExpander, ExpandedHdl, VclExpander&, void) { signal_expanded(); } commit 7c483346349f469598a107f508b5af4a815d1f3c Author: Szymon Kłos <[email protected]> AuthorDate: Fri Nov 13 12:30:51 2020 +0100 Commit: Andras Timar <[email protected]> CommitDate: Tue Apr 6 21:49:05 2021 +0200 autofilter: make working with multiple users in online Change-Id: Ib0255178112fae5d964cd6155d42848e7c7c51e8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106660 Tested-by: Jenkins Reviewed-by: Szymon Kłos <[email protected]> diff --git a/sc/source/ui/cctrl/checklistmenu.cxx b/sc/source/ui/cctrl/checklistmenu.cxx index ecb5dad0d744..6312b2062a16 100644 --- a/sc/source/ui/cctrl/checklistmenu.cxx +++ b/sc/source/ui/cctrl/checklistmenu.cxx @@ -554,11 +554,14 @@ ScCheckListMenuControl::~ScCheckListMenuControl() } ScCheckListMenuWindow::ScCheckListMenuWindow(vcl::Window* pParent, ScDocument* pDoc, bool bCanHaveSubMenu, - bool bTreeMode, int nWidth, ScCheckListMenuWindow* pParentMenu) + bool bTreeMode, int nWidth, ScCheckListMenuWindow* pParentMenu, + vcl::ILibreOfficeKitNotifier* pNotifier) : DockingWindow(pParent, "InterimDockParent", "svx/ui/interimdockparent.ui") , mxParentMenu(pParentMenu) , mxBox(get("box")) { + if (pNotifier) + SetLOKNotifier(pNotifier); setDeferredProperties(); mxControl.reset(new ScCheckListMenuControl(this, mxBox.get(), pDoc, bCanHaveSubMenu, bTreeMode, nWidth)); SetBackground(Application::GetSettings().GetStyleSettings().GetMenuColor()); diff --git a/sc/source/ui/inc/checklistmenu.hxx b/sc/source/ui/inc/checklistmenu.hxx index 49d4822ecd3b..5d4d6a6abd33 100644 --- a/sc/source/ui/inc/checklistmenu.hxx +++ b/sc/source/ui/inc/checklistmenu.hxx @@ -304,7 +304,8 @@ class ScCheckListMenuWindow : public DockingWindow public: explicit ScCheckListMenuWindow(vcl::Window* pParent, ScDocument* pDoc, bool bCanHaveSubMenu, bool bTreeMode, int nWidth = -1, - ScCheckListMenuWindow* pParentMenu = nullptr); + ScCheckListMenuWindow* pParentMenu = nullptr, + vcl::ILibreOfficeKitNotifier* pNotifier = nullptr); virtual void dispose() override; virtual ~ScCheckListMenuWindow() override; diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index b27d3e35e877..6da788a78fc1 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -607,9 +607,14 @@ void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow) ScFilterEntries aFilterEntries; rDoc.GetFilterEntries(nCol, nRow, nTab, aFilterEntries); + vcl::ILibreOfficeKitNotifier* pNotifier = nullptr; + if (bLOKActive) + pNotifier = SfxViewShell::Current(); + int nColWidth = ScViewData::ToPixel(rDoc.GetColWidth(nCol, nTab), mrViewData.GetPPTX()); mpAutoFilterPopup.reset(VclPtr<ScCheckListMenuWindow>::Create(this, &rDoc, false, - aFilterEntries.mbHasDates, nColWidth)); + aFilterEntries.mbHasDates, nColWidth, + nullptr, pNotifier)); ScCheckListMenuControl& rControl = mpAutoFilterPopup->get_widget(); int nMaxTextWidth = 0; @@ -645,8 +650,6 @@ void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow) nWindowWidth = rControl.IncreaseWindowWidthToFitText(nWindowWidth); nMaxTextWidth = std::max<int>(nMaxTextWidth, nWindowWidth - 70); - if (bLOKActive) - mpAutoFilterPopup->SetLOKNotifier(SfxViewShell::Current()); rControl.setOKAction(new AutoFilterAction(this, AutoFilterMode::Normal)); rControl.setPopupEndAction( new AutoFilterPopupEndAction(this, ScAddress(nCol, nRow, nTab))); commit 705253396ed534cf8680787978d7394000836d37 Author: Szymon Kłos <[email protected]> AuthorDate: Thu Nov 12 14:48:35 2020 +0100 Commit: Andras Timar <[email protected]> CommitDate: Tue Apr 6 21:48:52 2021 +0200 jsdialog: handle close for autofilter menu Change-Id: Iea30bac99e521bc629999e7fd3cb1c13422704e7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106659 Tested-by: Jenkins Reviewed-by: Szymon Kłos <[email protected]> diff --git a/sc/source/ui/cctrl/checklistmenu.cxx b/sc/source/ui/cctrl/checklistmenu.cxx index b3de30c28a9f..ecb5dad0d744 100644 --- a/sc/source/ui/cctrl/checklistmenu.cxx +++ b/sc/source/ui/cctrl/checklistmenu.cxx @@ -396,6 +396,9 @@ void ScCheckListMenuControl::StartPopupMode(const tools::Rectangle& rRect, Float void ScCheckListMenuControl::terminateAllPopupMenus() { + if (comphelper::LibreOfficeKit::isActive()) + NotifyCloseLOK(); + EndPopupMode(); ScCheckListMenuWindow* pParentMenu = mxFrame->GetParentMenu(); if (pParentMenu) @@ -1383,7 +1386,7 @@ void ScCheckListMenuControl::NotifyCloseLOK() if (pNotifier) { tools::JsonWriter aJsonWriter; - aJsonWriter.put("jsontype", "dockingwindow"); + aJsonWriter.put("jsontype", "autofilter"); aJsonWriter.put("action", "close"); const std::string message = aJsonWriter.extractAsStdString(); commit c9b6b0d299073104d688f7f799b1ac73f826f909 Author: Szymon Kłos <[email protected]> AuthorDate: Thu Nov 12 14:28:47 2020 +0100 Commit: Andras Timar <[email protected]> CommitDate: Tue Apr 6 21:48:18 2021 +0200 jsdialog: signal when treeview element is toggled Change-Id: If69eac02db386fd94420aff5a8b082281e913c15 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106658 Tested-by: Jenkins Reviewed-by: Szymon Kłos <[email protected]> diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx index f3549dd13edc..c7d85b24d106 100644 --- a/vcl/inc/salvtables.hxx +++ b/vcl/inc/salvtables.hxx @@ -1300,6 +1300,23 @@ public: virtual ~SalInstanceTextView() override; }; +struct SalInstanceTreeIter : public weld::TreeIter +{ + SalInstanceTreeIter(const SalInstanceTreeIter* pOrig) + : iter(pOrig ? pOrig->iter : nullptr) + { + } + SalInstanceTreeIter(SvTreeListEntry* pIter) + : iter(pIter) + { + } + virtual bool equal(const TreeIter& rOther) const override + { + return iter == static_cast<const SalInstanceTreeIter&>(rOther).iter; + } + SvTreeListEntry* iter; +}; + class SalInstanceTreeView : public SalInstanceContainer, public virtual weld::TreeView { protected: diff --git a/vcl/jsdialog/jsdialogbuilder.cxx b/vcl/jsdialog/jsdialogbuilder.cxx index 1ad0f6e73e90..b72dae272500 100644 --- a/vcl/jsdialog/jsdialogbuilder.cxx +++ b/vcl/jsdialog/jsdialogbuilder.cxx @@ -749,7 +749,12 @@ void JSTreeView::set_toggle(int pos, TriState eState, int col) pEntry = m_xTreeView->Next(pEntry); if (pEntry) + { SalInstanceTreeView::set_toggle(pEntry, eState, col); + signal_toggled(iter_col(SalInstanceTreeIter(pEntry), col)); + + notifyDialogState(); + } } void JSTreeView::select(int pos) diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index e8f2e96eae72..abf265720383 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -3263,26 +3263,6 @@ IMPL_LINK(SalInstanceEntry, CursorListener, VclWindowEvent&, rEvent, void) IMPL_LINK_NOARG(SalInstanceEntry, ActivateHdl, Edit&, bool) { return m_aActivateHdl.Call(*this); } -namespace -{ -struct SalInstanceTreeIter : public weld::TreeIter -{ - SalInstanceTreeIter(const SalInstanceTreeIter* pOrig) - : iter(pOrig ? pOrig->iter : nullptr) - { - } - SalInstanceTreeIter(SvTreeListEntry* pIter) - : iter(pIter) - { - } - virtual bool equal(const TreeIter& rOther) const override - { - return iter == static_cast<const SalInstanceTreeIter&>(rOther).iter; - } - SvTreeListEntry* iter; -}; -} - class SalInstanceTreeView; static SalInstanceTreeView* g_DragSource; commit 8fa49135acba6701a98cfc35c943339629dbd58c Author: Szymon Kłos <[email protected]> AuthorDate: Wed Nov 4 11:37:15 2020 +0100 Commit: Andras Timar <[email protected]> CommitDate: Tue Apr 6 21:48:07 2021 +0200 jsdialog: notify about autofilter dropdown close Change-Id: If6eb585f04f2d7441a7950bbdca378cc92ba641b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106592 Tested-by: Jenkins Reviewed-by: Szymon Kłos <[email protected]> diff --git a/sc/source/ui/cctrl/checklistmenu.cxx b/sc/source/ui/cctrl/checklistmenu.cxx index a55547cbc12b..b3de30c28a9f 100644 --- a/sc/source/ui/cctrl/checklistmenu.cxx +++ b/sc/source/ui/cctrl/checklistmenu.cxx @@ -32,6 +32,9 @@ #include <rtl/math.hxx> #include <tools/wintypes.hxx> #include <unotools/charclass.hxx> +#include <comphelper/lok.hxx> +#include <LibreOfficeKit/LibreOfficeKitEnums.h> +#include <tools/json_writer.hxx> #include <document.hxx> @@ -1372,11 +1375,31 @@ void ScCheckListMenuControl::launch(const tools::Rectangle& rRect) StartPopupMode(aRect, FloatWinPopupFlags::Down); } +void ScCheckListMenuControl::NotifyCloseLOK() +{ + VclPtr<vcl::Window> aNotifierWindow = mxFrame->GetParentWithLOKNotifier(); + if (aNotifierWindow) { + const vcl::ILibreOfficeKitNotifier* pNotifier = aNotifierWindow->GetLOKNotifier(); + if (pNotifier) + { + tools::JsonWriter aJsonWriter; + aJsonWriter.put("jsontype", "dockingwindow"); + aJsonWriter.put("action", "close"); + + const std::string message = aJsonWriter.extractAsStdString(); + pNotifier->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG, message.c_str()); + } + } +} + void ScCheckListMenuControl::close(bool bOK) { if (bOK && mxOKAction) mxOKAction->execute(); EndPopupMode(); + + if (comphelper::LibreOfficeKit::isActive()) + NotifyCloseLOK(); } void ScCheckListMenuControl::setExtendedData(std::unique_ptr<ExtendedData> p) @@ -1404,6 +1427,9 @@ IMPL_LINK_NOARG(ScCheckListMenuControl, PopupModeEndHdl, FloatingWindow*, void) clearSelectedMenuItem(); if (mxPopupEndAction) mxPopupEndAction->execute(); + + if (comphelper::LibreOfficeKit::isActive()) + NotifyCloseLOK(); } int ScCheckListMenuControl::GetTextWidth(const OUString& rsName) const diff --git a/sc/source/ui/inc/checklistmenu.hxx b/sc/source/ui/inc/checklistmenu.hxx index eb5c418a3cad..49d4822ecd3b 100644 --- a/sc/source/ui/inc/checklistmenu.hxx +++ b/sc/source/ui/inc/checklistmenu.hxx @@ -209,6 +209,8 @@ private: void CreateDropDown(); + void NotifyCloseLOK(); + DECL_LINK(ButtonHdl, weld::Button&, void); DECL_LINK(TriStateHdl, weld::ToggleButton&, void); commit 09b42555087c085a49a39a1177d2ebacdfefb56d Author: Szymon Kłos <[email protected]> AuthorDate: Mon Nov 2 12:24:49 2020 +0100 Commit: Andras Timar <[email protected]> CommitDate: Tue Apr 6 21:47:32 2021 +0200 jsdialog: execute checkbox action Change-Id: Ib19997f600404cc9555acbfaf87acac32f8aa5fc Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106904 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Szymon Kłos <[email protected]> diff --git a/include/vcl/jsdialog/executor.hxx b/include/vcl/jsdialog/executor.hxx index e49190f31e5f..5dde733a3823 100644 --- a/include/vcl/jsdialog/executor.hxx +++ b/include/vcl/jsdialog/executor.hxx @@ -22,6 +22,8 @@ public: static void trigger_changed(weld::ComboBox& rComboBox) { rComboBox.signal_changed(); } + static void trigger_toggled(weld::ToggleButton& rButton) { rButton.signal_toggled(); } + static void trigger_row_activated(weld::TreeView& rTreeView) { rTreeView.signal_row_activated(); diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx index 70c8fb74cae7..28b851801a12 100644 --- a/include/vcl/weld.hxx +++ b/include/vcl/weld.hxx @@ -1322,6 +1322,8 @@ public: class VCL_DLLPUBLIC ToggleButton : virtual public Button { + friend class ::LOKTrigger; + protected: Link<ToggleButton&, void> m_aToggleHdl; TriState m_eSavedValue = TRISTATE_FALSE; diff --git a/vcl/jsdialog/executor.cxx b/vcl/jsdialog/executor.cxx index 0409e6e51ae8..6ded26055270 100644 --- a/vcl/jsdialog/executor.cxx +++ b/vcl/jsdialog/executor.cxx @@ -97,6 +97,20 @@ bool ExecuteAction(sal_uInt64 nWindowId, const OString& rWidget, StringMap& rDat } } } + else if (sControlType == "checkbox") + { + auto pCheckButton = dynamic_cast<weld::CheckButton*>(pWidget); + if (pCheckButton) + { + if (sAction == "change") + { + bool bChecked = rData["data"] == "true"; + pCheckButton->set_state(bChecked ? TRISTATE_TRUE : TRISTATE_FALSE); + LOKTrigger::trigger_toggled(*static_cast<weld::ToggleButton*>(pCheckButton)); + return true; + } + } + } else if (sControlType == "drawingarea") { auto pArea = dynamic_cast<weld::DrawingArea*>(pWidget); commit ed7ee1bc58ee86cdb765b27a256a7e0eadacf3a0 Author: Szymon Kłos <[email protected]> AuthorDate: Fri Oct 30 10:51:08 2020 +0100 Commit: Andras Timar <[email protected]> CommitDate: Tue Apr 6 21:47:11 2021 +0200 jsdialog: implement TreeView Change-Id: I7c1cc683e8c5d5bdc00c1e3d3d0a2c85846bbda0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106560 Tested-by: Jenkins Reviewed-by: Szymon Kłos <[email protected]> diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index d46b780169fa..ad1edb322425 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -441,24 +441,6 @@ std::vector<beans::PropertyValue> desktop::jsonToPropertyValuesVector(const char } -static StringMap jsonToStringMap(const char* pJSON) -{ - StringMap aArgs; - if (pJSON && pJSON[0] != '\0') - { - std::stringstream aStream(pJSON); - boost::property_tree::ptree aTree; - boost::property_tree::read_json(aStream, aTree); - - for (const auto& rPair : aTree) - { - aArgs[OUString::fromUtf8(rPair.first.c_str())] = OUString::fromUtf8(rPair.second.get_value<std::string>(".").c_str()); - } - } - return aArgs; -} - - static boost::property_tree::ptree unoAnyToPropertyTree(const uno::Any& anyItem) { boost::property_tree::ptree aTree; @@ -3719,7 +3701,7 @@ static void lcl_sendDialogEvent(unsigned long long int nWindowId, const char* pA { SolarMutexGuard aGuard; - StringMap aMap(jsonToStringMap(pArguments)); + StringMap aMap(jsdialog::jsonToStringMap(pArguments)); VclPtr<Window> pWindow = vcl::Window::FindLOKWindow(nWindowId); if (!pWindow && nWindowId >= 1000000000 /* why unsigned? */) @@ -5706,7 +5688,7 @@ static void doc_sendFormFieldEvent(LibreOfficeKitDocument* pThis, const char* pA if (doc_getDocumentType(pThis) != LOK_DOCTYPE_TEXT) return; - StringMap aMap(jsonToStringMap(pArguments)); + StringMap aMap(jsdialog::jsonToStringMap(pArguments)); ITiledRenderable* pDoc = getTiledRenderable(pThis); if (!pDoc) { diff --git a/include/vcl/jsdialog/executor.hxx b/include/vcl/jsdialog/executor.hxx index 1cfa24c28a8a..e49190f31e5f 100644 --- a/include/vcl/jsdialog/executor.hxx +++ b/include/vcl/jsdialog/executor.hxx @@ -22,6 +22,11 @@ public: static void trigger_changed(weld::ComboBox& rComboBox) { rComboBox.signal_changed(); } + static void trigger_row_activated(weld::TreeView& rTreeView) + { + rTreeView.signal_row_activated(); + } + static void trigger_clicked(weld::Toolbar& rToolbar, const OString& rIdent) { rToolbar.signal_clicked(rIdent); @@ -36,6 +41,7 @@ public: namespace jsdialog { VCL_DLLPUBLIC bool ExecuteAction(sal_uInt64 nWindowId, const OString& rWidget, StringMap& rData); +VCL_DLLPUBLIC StringMap jsonToStringMap(const char* pJSON); }; /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx index 15236af38c3a..70c8fb74cae7 100644 --- a/include/vcl/weld.hxx +++ b/include/vcl/weld.hxx @@ -803,6 +803,8 @@ public: */ class VCL_DLLPUBLIC TreeView : virtual public Container { + friend class ::LOKTrigger; + public: typedef std::pair<const TreeIter&, int> iter_col; typedef std::pair<const TreeIter&, OUString> iter_string; diff --git a/vcl/inc/jsdialog/jsdialogbuilder.hxx b/vcl/inc/jsdialog/jsdialogbuilder.hxx index 41dc88aa9cdf..5d7df8086ae4 100644 --- a/vcl/inc/jsdialog/jsdialogbuilder.hxx +++ b/vcl/inc/jsdialog/jsdialogbuilder.hxx @@ -22,6 +22,7 @@ class ToolBox; class ComboBox; class VclMultiLineEdit; +class SvTabListBox; typedef std::map<OString, weld::Widget*> WidgetMap; @@ -109,8 +110,9 @@ public: weld_drawing_area(const OString& id, const a11yref& rA11yImpl = nullptr, FactoryFunction pUITestFactoryFunction = nullptr, void* pUserData = nullptr) override; - std::unique_ptr<weld::Toolbar> weld_toolbar(const OString& id) override; - std::unique_ptr<weld::TextView> weld_text_view(const OString& id) override; + virtual std::unique_ptr<weld::Toolbar> weld_toolbar(const OString& id) override; + virtual std::unique_ptr<weld::TextView> weld_text_view(const OString& id) override; + virtual std::unique_ptr<weld::TreeView> weld_tree_view(const OString& id) override; static weld::MessageDialog* CreateMessageDialog(weld::Widget* pParent, VclMessageType eMessageType, @@ -146,6 +148,7 @@ public: notifyDialogState(); } + using BaseInstanceClass::set_sensitive; virtual void set_sensitive(bool sensitive) override { BaseInstanceClass::set_sensitive(sensitive); @@ -291,4 +294,20 @@ public: virtual void set_text(const OUString& rText) override; }; +class JSTreeView : public JSWidget<SalInstanceTreeView, ::SvTabListBox> +{ +public: + JSTreeView(VclPtr<vcl::Window> aNotifierWindow, VclPtr<vcl::Window> aContentWindow, + ::SvTabListBox* pTextView, SalInstanceBuilder* pBuilder, bool bTakeOwnership, + std::string sTypeOfJSON); + + using SalInstanceTreeView::set_toggle; + /// pos is used differently here, it defines how many steps of iterator we need to perform to take entry + virtual void set_toggle(int pos, TriState eState, int col = -1) override; + + using SalInstanceTreeView::select; + /// pos is used differently here, it defines how many steps of iterator we need to perform to take entry + virtual void select(int pos) override; +}; + /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx index 9c6590431a22..f3549dd13edc 100644 --- a/vcl/inc/salvtables.hxx +++ b/vcl/inc/salvtables.hxx @@ -1302,7 +1302,7 @@ public: class SalInstanceTreeView : public SalInstanceContainer, public virtual weld::TreeView { -private: +protected: // owner for UserData std::vector<std::unique_ptr<OUString>> m_aUserData; VclPtr<SvTabListBox> m_xTreeView; diff --git a/vcl/jsdialog/executor.cxx b/vcl/jsdialog/executor.cxx index 27d61d65209a..0409e6e51ae8 100644 --- a/vcl/jsdialog/executor.cxx +++ b/vcl/jsdialog/executor.cxx @@ -11,9 +11,29 @@ #include <vcl/weld.hxx> #include <vcl/jsdialog/executor.hxx> #include <sal/log.hxx> +#include <rtl/uri.hxx> +#include <boost/property_tree/json_parser.hpp> namespace jsdialog { +StringMap jsonToStringMap(const char* pJSON) +{ + StringMap aArgs; + if (pJSON && pJSON[0] != '\0') + { + std::stringstream aStream(pJSON); + boost::property_tree::ptree aTree; + boost::property_tree::read_json(aStream, aTree); + + for (const auto& rPair : aTree) + { + aArgs[OUString::fromUtf8(rPair.first.c_str())] + = OUString::fromUtf8(rPair.second.get_value<std::string>(".").c_str()); + } + } + return aArgs; +} + bool ExecuteAction(sal_uInt64 nWindowId, const OString& rWidget, StringMap& rData) { weld::Widget* pWidget = JSInstanceBuilder::FindWeldWidgetsMap(nWindowId, rWidget); @@ -143,6 +163,38 @@ bool ExecuteAction(sal_uInt64 nWindowId, const OString& rWidget, StringMap& rDat } } } + else if (sControlType == "treeview") + { + auto pTreeView = dynamic_cast<weld::TreeView*>(pWidget); + if (pTreeView) + { + if (sAction == "change") + { + OUString sDataJSON = rtl::Uri::decode( + rData["data"], rtl_UriDecodeMechanism::rtl_UriDecodeWithCharset, + RTL_TEXTENCODING_UTF8); + StringMap aMap(jsonToStringMap( + OUStringToOString(sDataJSON, RTL_TEXTENCODING_ASCII_US).getStr())); + + OString nRowString = OUStringToOString(aMap["row"], RTL_TEXTENCODING_ASCII_US); + int nRow = std::atoi(nRowString.getStr()); + bool bValue = aMap["value"] == "true"; + + pTreeView->set_toggle(nRow, bValue ? TRISTATE_TRUE : TRISTATE_FALSE); + + return true; + } + else if (sAction == "select") + { + OString nRowString + = OUStringToOString(rData["data"], RTL_TEXTENCODING_ASCII_US); + int nRow = std::atoi(nRowString.getStr()); + + pTreeView->select(nRow); + LOKTrigger::trigger_row_activated(*pTreeView); + } + } + } } return false; diff --git a/vcl/jsdialog/jsdialogbuilder.cxx b/vcl/jsdialog/jsdialogbuilder.cxx index 4039aad2606b..1ad0f6e73e90 100644 --- a/vcl/jsdialog/jsdialogbuilder.cxx +++ b/vcl/jsdialog/jsdialogbuilder.cxx @@ -22,6 +22,8 @@ #include <vcl/toolbox.hxx> #include <vcl/toolkit/vclmedit.hxx> #include <boost/property_tree/json_parser.hpp> +#include <vcl/toolkit/treelistentry.hxx> +#include <vcl/jsdialog/executor.hxx> JSDialogNotifyIdle::JSDialogNotifyIdle(VclPtr<vcl::Window> aNotifierWindow, VclPtr<vcl::Window> aContentWindow, std::string sTypeOfJSON) @@ -39,30 +41,42 @@ void JSDialogNotifyIdle::ForceUpdate() { m_bForce = true; } void JSDialogNotifyIdle::Invoke() { - try + if (!m_aNotifierWindow) + return; + + const vcl::ILibreOfficeKitNotifier* pNotifier = m_aNotifierWindow->GetLOKNotifier(); + if (pNotifier) { - if (!m_aNotifierWindow) - return; + tools::JsonWriter aJsonWriter; + m_aContentWindow->DumpAsPropertyTree(aJsonWriter); + aJsonWriter.put("id", m_aNotifierWindow->GetLOKWindowId()); + aJsonWriter.put("jsontype", m_sTypeOfJSON); - const vcl::ILibreOfficeKitNotifier* pNotifier = m_aNotifierWindow->GetLOKNotifier(); - if (pNotifier) + if (m_sTypeOfJSON == "autofilter") { - tools::JsonWriter aJsonWriter; - m_aContentWindow->DumpAsPropertyTree(aJsonWriter); - aJsonWriter.put("id", m_aNotifierWindow->GetLOKWindowId()); - aJsonWriter.put("jsontype", m_sTypeOfJSON); - if (m_bForce || !aJsonWriter.isDataEquals(m_LastNotificationMessage)) + vcl::Window* pWindow = m_aContentWindow.get(); + DockingWindow* pDockingWIndow = dynamic_cast<DockingWindow*>(pWindow); + while (pWindow && !pDockingWIndow) + { + pWindow = pWindow->GetParent(); + pDockingWIndow = dynamic_cast<DockingWindow*>(pWindow); + } + + if (pDockingWIndow) { - m_bForce = false; - m_LastNotificationMessage = aJsonWriter.extractAsStdString(); - pNotifier->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG, - m_LastNotificationMessage.c_str()); + Point aPos = pDockingWIndow->GetFloatingPos(); + aJsonWriter.put("posx", aPos.getX()); + aJsonWriter.put("posy", aPos.getY()); } } - } - catch (boost::property_tree::json_parser::json_parser_error& rError) - { - SAL_WARN("vcl", rError.message()); + + if (m_bForce || !aJsonWriter.isDataEquals(m_LastNotificationMessage)) + { + m_bForce = false; + m_LastNotificationMessage = aJsonWriter.extractAsStdString(); + pNotifier->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG, + m_LastNotificationMessage.c_str()); + } } } @@ -424,6 +438,20 @@ std::unique_ptr<weld::TextView> JSInstanceBuilder::weld_text_view(const OString& return pWeldWidget; } +std::unique_ptr<weld::TreeView> JSInstanceBuilder::weld_tree_view(const OString& id) +{ + SvTabListBox* pTreeView = m_xBuilder->get<SvTabListBox>(id); + auto pWeldWidget = pTreeView + ? std::make_unique<JSTreeView>(GetNotifierWindow(), GetContentWindow(), + pTreeView, this, false, m_sTypeOfJSON) + : nullptr; + + if (pWeldWidget) + RememberWidget(id, pWeldWidget.get()); + + return pWeldWidget; +} + weld::MessageDialog* JSInstanceBuilder::CreateMessageDialog(weld::Widget* pParent, VclMessageType eMessageType, VclButtonsType eButtonType, @@ -705,4 +733,45 @@ void JSTextView::set_text(const OUString& rText) notifyDialogState(); } +JSTreeView::JSTreeView(VclPtr<vcl::Window> aNotifierWindow, VclPtr<vcl::Window> aContentWindow, + ::SvTabListBox* pTreeView, SalInstanceBuilder* pBuilder, bool bTakeOwnership, + std::string sTypeOfJSON) + : JSWidget<SalInstanceTreeView, ::SvTabListBox>(aNotifierWindow, aContentWindow, pTreeView, + pBuilder, bTakeOwnership, sTypeOfJSON) +{ +} + +void JSTreeView::set_toggle(int pos, TriState eState, int col) +{ + SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, 0); + + while (pEntry && pos--) + pEntry = m_xTreeView->Next(pEntry); + + if (pEntry) + SalInstanceTreeView::set_toggle(pEntry, eState, col); +} + +void JSTreeView::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 + { + SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, 0); + + while (pEntry && pos--) + pEntry = m_xTreeView->Next(pEntry); + + if (pEntry) + { + m_xTreeView->Select(pEntry, true); + m_xTreeView->MakeVisible(pEntry); + } + } + enable_notify_events(); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ commit b394d533958d8ecb0e60efae6e593c9048cbcde1 Author: Szymon Kłos <[email protected]> AuthorDate: Tue Nov 24 16:31:40 2020 +0100 Commit: Andras Timar <[email protected]> CommitDate: Tue Apr 6 21:46:45 2021 +0200 Move SalInstanceTreeView decl to header file Change-Id: Ie49f4113332de5c4fa825f93dde46bb408187fe4 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106536 Tested-by: Jenkins Reviewed-by: Szymon Kłos <[email protected]> diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx index 0702cb103a5f..9c6590431a22 100644 --- a/vcl/inc/salvtables.hxx +++ b/vcl/inc/salvtables.hxx @@ -24,6 +24,9 @@ #include <vcl/tabctrl.hxx> #include <vcl/layout.hxx> #include "messagedialog.hxx" +#include <vcl/toolkit/svtabbx.hxx> +#include <vcl/toolkit/svlbitm.hxx> +#include <o3tl/sorted_vector.hxx> class SalInstanceBuilder : public weld::Builder { @@ -1297,4 +1300,359 @@ public: virtual ~SalInstanceTextView() 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; + // currently expanding parent that logically, but not currently physically, + // contain placeholders + o3tl::sorted_vector<SvTreeListEntry*> m_aExpandingPlaceHolderParents; + // which columns should be custom rendered + o3tl::sorted_vector<int> m_aCustomRenders; + bool m_bTogglesAsRadio; + int m_nSortColumn; + + DECL_LINK(SelectHdl, SvTreeListBox*, void); + DECL_LINK(DeSelectHdl, SvTreeListBox*, void); + DECL_LINK(DoubleClickHdl, SvTreeListBox*, bool); + DECL_LINK(ExpandingHdl, SvTreeListBox*, bool); + DECL_LINK(EndDragHdl, HeaderBar*, void); + DECL_LINK(HeaderBarClickedHdl, HeaderBar*, void); + DECL_LINK(ToggleHdl, SvLBoxButtonData*, void); + DECL_LINK(ModelChangedHdl, SvTreeListBox*, void); + DECL_LINK(StartDragHdl, SvTreeListBox*, bool); + DECL_STATIC_LINK(SalInstanceTreeView, FinishDragHdl, SvTreeListBox*, void); + DECL_LINK(EditingEntryHdl, SvTreeListEntry*, bool); + typedef std::pair<SvTreeListEntry*, OUString> IterString; + DECL_LINK(EditedEntryHdl, IterString, bool); + DECL_LINK(VisibleRangeChangedHdl, SvTreeListBox*, void); + DECL_LINK(CompareHdl, const SvSortData&, sal_Int32); + DECL_LINK(PopupMenuHdl, const CommandEvent&, bool); + DECL_LINK(TooltipHdl, const HelpEvent&, bool); + DECL_LINK(CustomRenderHdl, svtree_render_args, void); + DECL_LINK(CustomMeasureHdl, svtree_measure_args, Size); + + // Each row has a cell for the expander image, (and an optional cell for a + // checkbutton if enable_toggle_buttons has been called) which precede + // index 0 + int to_internal_model(int col) const; + + int to_external_model(int col) const; + + bool IsDummyEntry(SvTreeListEntry* pEntry) const; + + SvTreeListEntry* GetPlaceHolderChild(SvTreeListEntry* pEntry) const; + + static void set_font_color(SvTreeListEntry* pEntry, const Color& rColor); + + void AddStringItem(SvTreeListEntry* pEntry, const OUString& rStr, int nCol); + + void do_insert(const weld::TreeIter* pParent, int pos, const OUString* pStr, + const OUString* pId, const OUString* pIconName, + const VirtualDevice* pImageSurface, bool bChildrenOnDemand, weld::TreeIter* pRet, + bool bIsSeparator); + + void update_checkbutton_column_width(SvTreeListEntry* pEntry); + + void InvalidateModelEntry(SvTreeListEntry* pEntry); + + void do_set_toggle(SvTreeListEntry* pEntry, TriState eState, int col); + + static TriState do_get_toggle(SvTreeListEntry* pEntry, int col); + + TriState get_toggle(SvTreeListEntry* pEntry, int col) const; + + void set_toggle(SvTreeListEntry* pEntry, TriState eState, int col); + + bool get_text_emphasis(SvTreeListEntry* pEntry, int col) const; + + void set_header_item_width(const std::vector<int>& rWidths); + +public: + SalInstanceTreeView(SvTabListBox* pTreeView, SalInstanceBuilder* pBuilder, bool bTakeOwnership); + + virtual void connect_query_tooltip(const Link<const weld::TreeIter&, OUString>& rLink) override; + + virtual void columns_autosize() override; + + virtual void freeze() override; + + virtual void thaw() override; + + virtual void set_column_fixed_widths(const std::vector<int>& rWidths) override; + + virtual void set_column_editables(const std::vector<bool>& rEditables) override; + + virtual void set_centered_column(int nCol) 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 set_column_custom_renderer(int nColumn, bool bEnable) override; + + virtual void queue_draw() override; + + virtual void show() override; + + virtual void hide() override; + + virtual void insert(const weld::TreeIter* pParent, int pos, const OUString* pStr, + const OUString* pId, const OUString* pIconName, + VirtualDevice* pImageSurface, bool bChildrenOnDemand, + weld::TreeIter* pRet) override; + + virtual void insert_separator(int pos, const OUString& /*rId*/) override; + + virtual void + bulk_insert_for_each(int nSourceCount, + const std::function<void(weld::TreeIter&, int nSourceIndex)>& func, + const std::vector<int>* pFixedWidths = nullptr) override; + + virtual void set_font_color(int pos, const Color& rColor) override; + + virtual void set_font_color(const weld::TreeIter& rIter, const Color& rColor) 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 swap(int pos1, int pos2) override; + + virtual void clear() override; + + virtual int n_children() const override; + + virtual int iter_n_children(const weld::TreeIter& rIter) const override; + + virtual void select(int pos) override; + + virtual int get_cursor_index() const override; + + virtual void set_cursor(int pos) override; + + virtual void scroll_to_row(int pos) override; + + virtual bool is_selected(int pos) const override; + + virtual void unselect(int pos) override; + + virtual std::vector<int> get_selected_rows() const override; + + OUString get_text(SvTreeListEntry* pEntry, int col) const; + + virtual OUString get_text(int pos, int col = -1) const override; + + void set_text(SvTreeListEntry* pEntry, const OUString& rText, int col); + + virtual void set_text(int pos, const OUString& rText, int col = -1) override; + + void set_sensitive(SvTreeListEntry* pEntry, bool bSensitive, int col); + + using SalInstanceWidget::set_sensitive; + + virtual void set_sensitive(int pos, bool bSensitive, int col = -1) override; + + virtual void set_sensitive(const weld::TreeIter& rIter, bool bSensitive, int col = -1) override; + + virtual TriState get_toggle(int pos, int col = -1) const override; + + virtual TriState get_toggle(const weld::TreeIter& rIter, int col = -1) const override; + + virtual void enable_toggle_buttons(weld::ColumnToggleType eType) override; + + virtual void set_toggle(int pos, TriState eState, int col = -1) override; + + virtual void set_toggle(const weld::TreeIter& rIter, TriState eState, int col = -1) override; + + virtual void set_extra_row_indent(const weld::TreeIter& rIter, int nIndentLevel) override; + + void set_text_emphasis(SvTreeListEntry* pEntry, bool bOn, int col = -1); + + virtual void set_text_emphasis(const weld::TreeIter& rIter, bool bOn, int col) override; + + virtual void set_text_emphasis(int pos, bool bOn, int col) override; + + virtual bool get_text_emphasis(const weld::TreeIter& rIter, int col) const override; + + virtual bool get_text_emphasis(int pos, int col) const override; + + void set_text_align(SvTreeListEntry* pEntry, double fAlign, int col); + + virtual void set_text_align(const weld::TreeIter& rIter, double fAlign, int col) override; + + virtual void set_text_align(int pos, double fAlign, int col) override; + + virtual void connect_editing(const Link<const weld::TreeIter&, bool>& rStartLink, + const Link<const iter_string&, bool>& rEndLink) override; + + virtual void start_editing(const weld::TreeIter& rIter) override; + + virtual void end_editing() override; + + void set_image(SvTreeListEntry* pEntry, const Image& rImage, int col); + + virtual void set_image(int pos, const OUString& rImage, int col = -1) override; + + virtual void set_image(int pos, const css::uno::Reference<css::graphic::XGraphic>& rImage, + int col = -1) override; + + virtual void set_image(int pos, VirtualDevice& rImage, int col = -1) override; + + virtual void set_image(const weld::TreeIter& rIter, const OUString& rImage, + int col = -1) override; + + virtual void set_image(const weld::TreeIter& rIter, + const css::uno::Reference<css::graphic::XGraphic>& rImage, + int col = -1) override; + + virtual void set_image(const weld::TreeIter& rIter, VirtualDevice& rImage, + int col = -1) override; + + const OUString* getEntryData(int index) const; + + virtual OUString get_id(int pos) const override; + + void set_id(SvTreeListEntry* pEntry, const OUString& rId); + + virtual void set_id(int pos, const OUString& rId) override; + + virtual int get_selected_index() const override; + + virtual OUString get_selected_text() const override; + + virtual OUString get_selected_id() 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_previous_sibling(weld::TreeIter& rIter) const override; + + virtual bool iter_next(weld::TreeIter& rIter) const override; + + virtual bool iter_previous(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 bool get_children_on_demand(const weld::TreeIter& rIter) const override; + + virtual void set_children_on_demand(const weld::TreeIter& rIter, + bool bChildrenOnDemand) override; + + virtual void expand_row(const weld::TreeIter& rIter) override; + + virtual void collapse_row(const weld::TreeIter& rIter) override; + + virtual OUString get_text(const weld::TreeIter& rIter, int col = -1) const override; + + virtual void set_text(const weld::TreeIter& rIter, const OUString& rText, + int col = -1) override; + + virtual OUString get_id(const weld::TreeIter& rIter) const override; + + virtual void set_id(const weld::TreeIter& rIter, const OUString& rId) override; + + virtual void enable_drag_source(rtl::Reference<TransferDataContainer>& rHelper, + sal_uInt8 eDNDConstants) override; + + virtual void set_selection_mode(SelectionMode eMode) override; + + virtual void all_foreach(const std::function<bool(weld::TreeIter&)>& func) override; + + virtual void selected_foreach(const std::function<bool(weld::TreeIter&)>& func) override; + + virtual void visible_foreach(const std::function<bool(weld::TreeIter&)>& func) override; + + virtual void connect_visible_range_changed(const Link<weld::TreeView&, void>& rLink) override; + + virtual void remove_selection() override; + + virtual bool is_selected(const weld::TreeIter& rIter) const override; + + virtual int get_iter_index_in_parent(const weld::TreeIter& rIter) const override; + + virtual int iter_compare(const weld::TreeIter& a, const weld::TreeIter& b) const override; + + virtual void move_subtree(weld::TreeIter& rNode, const weld::TreeIter* pNewParent, + int nIndexInNewParent) override; + + virtual int count_selected_rows() const override; + + virtual int get_height_rows(int nRows) const override; + + virtual void make_sorted() override; + + virtual void set_sort_func( + const std::function<int(const weld::TreeIter&, const weld::TreeIter&)>& func) override; + + virtual void make_unsorted() override; + + virtual void set_sort_order(bool bAscending) override; + + virtual bool get_sort_order() const override; + + virtual void set_sort_indicator(TriState eState, int col) override; + + virtual TriState get_sort_indicator(int col) const override; + + virtual int get_sort_column() const override; + + virtual void set_sort_column(int nColumn) override; + + SvTabListBox& getTreeView(); + + virtual bool get_dest_row_at_pos(const Point& rPos, weld::TreeIter* pResult, + bool bDnDMode) override; + + virtual void unset_drag_dest_row() override; + + virtual tools::Rectangle get_row_area(const weld::TreeIter& rIter) const override; + + virtual TreeView* get_drag_source() const override; + + virtual int vadjustment_get_value() const override; + + virtual void vadjustment_set_value(int nValue) override; + + void set_show_expanders(bool bShow) override; + + virtual ~SalInstanceTreeView() override; +}; + /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index 317770c367c3..e8f2e96eae72 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -3323,1523 +3323,1478 @@ public: }; } -class SalInstanceTreeView : public SalInstanceContainer, public virtual weld::TreeView +// Each row has a cell for the expander image, (and an optional cell for a +// checkbutton if enable_toggle_buttons has been called) which precede +// index 0 +int SalInstanceTreeView::to_internal_model(int col) const { -private: - // owner for UserData - std::vector<std::unique_ptr<OUString>> m_aUserData; - VclPtr<SvTabListBox> m_xTreeView; - SvLBoxButtonData m_aCheckButtonData; - SvLBoxButtonData m_aRadioButtonData; - // currently expanding parent that logically, but not currently physically, - // contain placeholders - o3tl::sorted_vector<SvTreeListEntry*> m_aExpandingPlaceHolderParents; - // which columns should be custom rendered - o3tl::sorted_vector<int> m_aCustomRenders; - bool m_bTogglesAsRadio; - int m_nSortColumn; + if (m_xTreeView->nTreeFlags & SvTreeFlags::CHKBTN) + ++col; // skip checkbutton column + ++col; //skip expander column + return col; +} - DECL_LINK(SelectHdl, SvTreeListBox*, void); - DECL_LINK(DeSelectHdl, SvTreeListBox*, void); - DECL_LINK(DoubleClickHdl, SvTreeListBox*, bool); - DECL_LINK(ExpandingHdl, SvTreeListBox*, bool); - DECL_LINK(EndDragHdl, HeaderBar*, void); - DECL_LINK(HeaderBarClickedHdl, HeaderBar*, void); - DECL_LINK(ToggleHdl, SvLBoxButtonData*, void); - DECL_LINK(ModelChangedHdl, SvTreeListBox*, void); - DECL_LINK(StartDragHdl, SvTreeListBox*, bool); - DECL_STATIC_LINK(SalInstanceTreeView, FinishDragHdl, SvTreeListBox*, void); - DECL_LINK(EditingEntryHdl, SvTreeListEntry*, bool); - typedef std::pair<SvTreeListEntry*, OUString> IterString; - DECL_LINK(EditedEntryHdl, IterString, bool); - DECL_LINK(VisibleRangeChangedHdl, SvTreeListBox*, void); - DECL_LINK(CompareHdl, const SvSortData&, sal_Int32); - DECL_LINK(PopupMenuHdl, const CommandEvent&, bool); - DECL_LINK(TooltipHdl, const HelpEvent&, bool); - DECL_LINK(CustomRenderHdl, svtree_render_args, void); - DECL_LINK(CustomMeasureHdl, svtree_measure_args, Size); +int SalInstanceTreeView::to_external_model(int col) const +{ + if (m_xTreeView->nTreeFlags & SvTreeFlags::CHKBTN) + --col; // skip checkbutton column + --col; //skip expander column + return col; +} - // Each row has a cell for the expander image, (and an optional cell for a - // checkbutton if enable_toggle_buttons has been called) which precede - // index 0 - int to_internal_model(int col) const - { - if (m_xTreeView->nTreeFlags & SvTreeFlags::CHKBTN) - ++col; // skip checkbutton column - ++col; //skip expander column - return col; - } +bool SalInstanceTreeView::IsDummyEntry(SvTreeListEntry* pEntry) const +{ + return m_xTreeView->GetEntryText(pEntry).trim() == "<dummy>"; +} - int to_external_model(int col) const +SvTreeListEntry* SalInstanceTreeView::GetPlaceHolderChild(SvTreeListEntry* pEntry) const +{ + if (pEntry->HasChildren()) { - if (m_xTreeView->nTreeFlags & SvTreeFlags::CHKBTN) - --col; // skip checkbutton column - --col; //skip expander column - return col; + auto pChild = m_xTreeView->FirstChild(pEntry); + assert(pChild); + if (IsDummyEntry(pChild)) + return pChild; } + return nullptr; +} - bool IsDummyEntry(SvTreeListEntry* pEntry) const +void SalInstanceTreeView::set_font_color(SvTreeListEntry* pEntry, const Color& rColor) +{ + if (rColor == COL_AUTO) + pEntry->SetTextColor(std::optional<Color>()); + else + pEntry->SetTextColor(rColor); +} + +void SalInstanceTreeView::AddStringItem(SvTreeListEntry* pEntry, const OUString& rStr, int nCol) +{ + auto xCell = std::make_unique<SvLBoxString>(rStr); + if (m_aCustomRenders.count(nCol)) + xCell->SetCustomRender(); + pEntry->AddItem(std::move(xCell)); +} + +void SalInstanceTreeView::do_insert(const weld::TreeIter* pParent, int pos, const OUString* pStr, + const OUString* pId, const OUString* pIconName, + const VirtualDevice* pImageSurface, bool bChildrenOnDemand, + weld::TreeIter* pRet, bool bIsSeparator) +{ + disable_notify_events(); + const SalInstanceTreeIter* pVclIter = static_cast<const SalInstanceTreeIter*>(pParent); + SvTreeListEntry* iter = pVclIter ? pVclIter->iter : nullptr; + auto nInsertPos = pos == -1 ? TREELIST_APPEND : pos; + void* pUserData; + if (pId) { - return m_xTreeView->GetEntryText(pEntry).trim() == "<dummy>"; + m_aUserData.emplace_back(std::make_unique<OUString>(*pId)); + pUserData = m_aUserData.back().get(); } + else + pUserData = nullptr; + + SvTreeListEntry* pEntry = new SvTreeListEntry; + if (bIsSeparator) + pEntry->SetFlags(pEntry->GetFlags() | SvTLEntryFlags::IS_SEPARATOR); - SvTreeListEntry* GetPlaceHolderChild(SvTreeListEntry* pEntry) const + if (m_xTreeView->nTreeFlags & SvTreeFlags::CHKBTN) + AddStringItem(pEntry, "", -1); + + if (pIconName || pImageSurface) { - if (pEntry->HasChildren()) - { - auto pChild = m_xTreeView->FirstChild(pEntry); - assert(pChild); - if (IsDummyEntry(pChild)) - return pChild; - } - return nullptr; + Image aImage(pIconName ? createImage(*pIconName) : createImage(*pImageSurface)); + pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(aImage, aImage, false)); } - - static void set_font_color(SvTreeListEntry* pEntry, const Color& rColor) + else { - if (rColor == COL_AUTO) - pEntry->SetTextColor(std::optional<Color>()); - else - pEntry->SetTextColor(rColor); + Image aDummy; + pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(aDummy, aDummy, false)); } + if (pStr) + AddStringItem(pEntry, *pStr, 0); + pEntry->SetUserData(pUserData); + m_xTreeView->Insert(pEntry, iter, nInsertPos); - void AddStringItem(SvTreeListEntry* pEntry, const OUString& rStr, int nCol) + if (pRet) { - auto xCell = std::make_unique<SvLBoxString>(rStr); - if (m_aCustomRenders.count(nCol)) - xCell->SetCustomRender(); - pEntry->AddItem(std::move(xCell)); + SalInstanceTreeIter* pVclRetIter = static_cast<SalInstanceTreeIter*>(pRet); + pVclRetIter->iter = pEntry; } - void do_insert(const weld::TreeIter* pParent, int pos, const OUString* pStr, - const OUString* pId, const OUString* pIconName, - const VirtualDevice* pImageSurface, bool bChildrenOnDemand, weld::TreeIter* pRet, - bool bIsSeparator) + if (bChildrenOnDemand) { - disable_notify_events(); - const SalInstanceTreeIter* pVclIter = static_cast<const SalInstanceTreeIter*>(pParent); - SvTreeListEntry* iter = pVclIter ? pVclIter->iter : nullptr; - auto nInsertPos = pos == -1 ? TREELIST_APPEND : pos; - void* pUserData; - if (pId) - { - m_aUserData.emplace_back(std::make_unique<OUString>(*pId)); - pUserData = m_aUserData.back().get(); - } - else - pUserData = nullptr; - - SvTreeListEntry* pEntry = new SvTreeListEntry; - if (bIsSeparator) - pEntry->SetFlags(pEntry->GetFlags() | SvTLEntryFlags::IS_SEPARATOR); - - if (m_xTreeView->nTreeFlags & SvTreeFlags::CHKBTN) - AddStringItem(pEntry, "", -1); - - if (pIconName || pImageSurface) - { - Image aImage(pIconName ? createImage(*pIconName) : createImage(*pImageSurface)); - pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(aImage, aImage, false)); - } - else - { - Image aDummy; - pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(aDummy, aDummy, false)); - } - if (pStr) - AddStringItem(pEntry, *pStr, 0); - pEntry->SetUserData(pUserData); - m_xTreeView->Insert(pEntry, iter, nInsertPos); - - if (pRet) - { - SalInstanceTreeIter* pVclRetIter = static_cast<SalInstanceTreeIter*>(pRet); - pVclRetIter->iter = pEntry; - } - - if (bChildrenOnDemand) - { - SvTreeListEntry* pPlaceHolder - = m_xTreeView->InsertEntry("<dummy>", pEntry, false, 0, nullptr); - SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pPlaceHolder); - pViewData->SetSelectable(false); - } - - if (bIsSeparator) - { - SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry); - pViewData->SetSelectable(false); - } - - enable_notify_events(); + SvTreeListEntry* pPlaceHolder + = m_xTreeView->InsertEntry("<dummy>", pEntry, false, 0, nullptr); + SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pPlaceHolder); + pViewData->SetSelectable(false); } - void update_checkbutton_column_width(SvTreeListEntry* pEntry) + if (bIsSeparator) { SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry); - m_xTreeView->InitViewData(pViewData, pEntry); - m_xTreeView->CheckBoxInserted(pEntry); + pViewData->SetSelectable(false); } - void InvalidateModelEntry(SvTreeListEntry* pEntry) - { - if (!m_xTreeView->GetModel()->IsEnableInvalidate()) - return; - m_xTreeView->ModelHasEntryInvalidated(pEntry); - } + enable_notify_events(); +} - void do_set_toggle(SvTreeListEntry* pEntry, TriState eState, int col) - { - assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount()); - // if its the placeholder to allow a blank column, replace it now - if (pEntry->GetItem(col).GetType() != SvLBoxItemType::Button) - { - SvLBoxButtonData* pData = m_bTogglesAsRadio ? &m_aRadioButtonData : &m_aCheckButtonData; - pEntry->ReplaceItem(std::make_unique<SvLBoxButton>(pData), 0); - update_checkbutton_column_width(pEntry); - } - SvLBoxItem& rItem = pEntry->GetItem(col); - assert(dynamic_cast<SvLBoxButton*>(&rItem)); - switch (eState) - { - case TRISTATE_TRUE: - static_cast<SvLBoxButton&>(rItem).SetStateChecked(); - break; - case TRISTATE_FALSE: - static_cast<SvLBoxButton&>(rItem).SetStateUnchecked(); - break; - case TRISTATE_INDET: - static_cast<SvLBoxButton&>(rItem).SetStateTristate(); - break; - } +void SalInstanceTreeView::update_checkbutton_column_width(SvTreeListEntry* pEntry) +{ + SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry); + m_xTreeView->InitViewData(pViewData, pEntry); + m_xTreeView->CheckBoxInserted(pEntry); +} - InvalidateModelEntry(pEntry); - } +void SalInstanceTreeView::InvalidateModelEntry(SvTreeListEntry* pEntry) +{ + if (!m_xTreeView->GetModel()->IsEnableInvalidate()) + return; + m_xTreeView->ModelHasEntryInvalidated(pEntry); +} - static TriState do_get_toggle(SvTreeListEntry* pEntry, int col) +void SalInstanceTreeView::do_set_toggle(SvTreeListEntry* pEntry, TriState eState, int col) +{ + assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount()); + // if its the placeholder to allow a blank column, replace it now + if (pEntry->GetItem(col).GetType() != SvLBoxItemType::Button) { - if (static_cast<size_t>(col) == pEntry->ItemCount()) - return TRISTATE_FALSE; - - assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount()); - SvLBoxItem& rItem = pEntry->GetItem(col); - assert(dynamic_cast<SvLBoxButton*>(&rItem)); - SvLBoxButton& rToggle = static_cast<SvLBoxButton&>(rItem); - if (rToggle.IsStateTristate()) - return TRISTATE_INDET; - else if (rToggle.IsStateChecked()) - return TRISTATE_TRUE; - return TRISTATE_FALSE; + SvLBoxButtonData* pData = m_bTogglesAsRadio ? &m_aRadioButtonData : &m_aCheckButtonData; + pEntry->ReplaceItem(std::make_unique<SvLBoxButton>(pData), 0); + update_checkbutton_column_width(pEntry); } - - TriState get_toggle(SvTreeListEntry* pEntry, int col) const + SvLBoxItem& rItem = pEntry->GetItem(col); + assert(dynamic_cast<SvLBoxButton*>(&rItem)); + switch (eState) { - if (col == -1) - { - assert(m_xTreeView->nTreeFlags & SvTreeFlags::CHKBTN); - return do_get_toggle(pEntry, 0); - } - col = to_internal_model(col); - return do_get_toggle(pEntry, col); + case TRISTATE_TRUE: + static_cast<SvLBoxButton&>(rItem).SetStateChecked(); + break; + case TRISTATE_FALSE: + static_cast<SvLBoxButton&>(rItem).SetStateUnchecked(); + break; + case TRISTATE_INDET: + static_cast<SvLBoxButton&>(rItem).SetStateTristate(); + break; } - void set_toggle(SvTreeListEntry* pEntry, TriState eState, int col) - { - if (col == -1) - { - assert(m_xTreeView->nTreeFlags & SvTreeFlags::CHKBTN); - do_set_toggle(pEntry, eState, 0); - return; - } - - col = to_internal_model(col); - - // blank out missing entries - for (int i = pEntry->ItemCount(); i < col; ++i) - AddStringItem(pEntry, "", i - 1); + InvalidateModelEntry(pEntry); +} - if (static_cast<size_t>(col) == pEntry->ItemCount()) - { - SvLBoxButtonData* pData = m_bTogglesAsRadio ? &m_aRadioButtonData : &m_aCheckButtonData; - pEntry->AddItem(std::make_unique<SvLBoxButton>(pData)); - update_checkbutton_column_width(pEntry); - } +TriState SalInstanceTreeView::do_get_toggle(SvTreeListEntry* pEntry, int col) +{ + if (static_cast<size_t>(col) == pEntry->ItemCount()) + return TRISTATE_FALSE; - do_set_toggle(pEntry, eState, col); - } + assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount()); + SvLBoxItem& rItem = pEntry->GetItem(col); + assert(dynamic_cast<SvLBoxButton*>(&rItem)); + SvLBoxButton& rToggle = static_cast<SvLBoxButton&>(rItem); + if (rToggle.IsStateTristate()) + return TRISTATE_INDET; + else if (rToggle.IsStateChecked()) + return TRISTATE_TRUE; + return TRISTATE_FALSE; +} - bool get_text_emphasis(SvTreeListEntry* pEntry, int col) const +TriState SalInstanceTreeView::get_toggle(SvTreeListEntry* pEntry, int col) const +{ + if (col == -1) { - col = to_internal_model(col); - - assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount()); - SvLBoxItem& rItem = pEntry->GetItem(col); - assert(dynamic_cast<SvLBoxString*>(&rItem)); - return static_cast<SvLBoxString&>(rItem).IsEmphasized(); + assert(m_xTreeView->nTreeFlags & SvTreeFlags::CHKBTN); + return do_get_toggle(pEntry, 0); } + col = to_internal_model(col); + return do_get_toggle(pEntry, col); +} - void set_header_item_width(const std::vector<int>& rWidths) +void SalInstanceTreeView::set_toggle(SvTreeListEntry* pEntry, TriState eState, int col) +{ + if (col == -1) { - LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(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]); - } + assert(m_xTreeView->nTreeFlags & SvTreeFlags::CHKBTN); + do_set_toggle(pEntry, eState, 0); + return; } -public: - SalInstanceTreeView(SvTabListBox* pTreeView, SalInstanceBuilder* pBuilder, bool bTakeOwnership) - : SalInstanceContainer(pTreeView, pBuilder, bTakeOwnership) - , m_xTreeView(pTreeView) - , m_aCheckButtonData(pTreeView, false) - , m_aRadioButtonData(pTreeView, true) - , m_bTogglesAsRadio(false) - , m_nSortColumn(-1) - { - m_xTreeView->SetNodeDefaultImages(); - m_xTreeView->SetForceMakeVisible(true); - m_xTreeView->SetSelectHdl(LINK(this, SalInstanceTreeView, SelectHdl)); - m_xTreeView->SetDeselectHdl(LINK(this, SalInstanceTreeView, DeSelectHdl)); - m_xTreeView->SetDoubleClickHdl(LINK(this, SalInstanceTreeView, DoubleClickHdl)); - m_xTreeView->SetExpandingHdl(LINK(this, SalInstanceTreeView, ExpandingHdl)); - m_xTreeView->SetPopupMenuHdl(LINK(this, SalInstanceTreeView, PopupMenuHdl)); - m_xTreeView->SetCustomRenderHdl(LINK(this, SalInstanceTreeView, CustomRenderHdl)); - m_xTreeView->SetCustomMeasureHdl(LINK(this, SalInstanceTreeView, CustomMeasureHdl)); - const tools::Long aTabPositions[] = { 0 }; - m_xTreeView->SetTabs(SAL_N_ELEMENTS(aTabPositions), aTabPositions); - LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get()); - - if (pHeaderBox) - { - if (HeaderBar* pHeaderBar = pHeaderBox->GetHeaderBar()) - { - //make the last entry fill available space - pHeaderBar->SetItemSize(pHeaderBar->GetItemId(pHeaderBar->GetItemCount() - 1), - HEADERBAR_FULLSIZE); - pHeaderBar->SetEndDragHdl(LINK(this, SalInstanceTreeView, EndDragHdl)); - pHeaderBar->SetSelectHdl(LINK(this, SalInstanceTreeView, HeaderBarClickedHdl)); - } - pHeaderBox->SetEditingEntryHdl(LINK(this, SalInstanceTreeView, EditingEntryHdl)); - pHeaderBox->SetEditedEntryHdl(LINK(this, SalInstanceTreeView, EditedEntryHdl)); - } - else - { - static_cast<LclTabListBox&>(*m_xTreeView) - .SetModelChangedHdl(LINK(this, SalInstanceTreeView, ModelChangedHdl)); - static_cast<LclTabListBox&>(*m_xTreeView) - .SetStartDragHdl(LINK(this, SalInstanceTreeView, StartDragHdl)); - static_cast<LclTabListBox&>(*m_xTreeView) - .SetEndDragHdl(LINK(this, SalInstanceTreeView, FinishDragHdl)); - static_cast<LclTabListBox&>(*m_xTreeView) - .SetEditingEntryHdl(LINK(this, SalInstanceTreeView, EditingEntryHdl)); - static_cast<LclTabListBox&>(*m_xTreeView) - .SetEditedEntryHdl(LINK(this, SalInstanceTreeView, EditedEntryHdl)); - } - m_aCheckButtonData.SetLink(LINK(this, SalInstanceTreeView, ToggleHdl)); - m_aRadioButtonData.SetLink(LINK(this, SalInstanceTreeView, ToggleHdl)); - } + col = to_internal_model(col); - virtual void connect_query_tooltip(const Link<const weld::TreeIter&, OUString>& rLink) override - { - weld::TreeView::connect_query_tooltip(rLink); - m_xTreeView->SetTooltipHdl(LINK(this, SalInstanceTreeView, TooltipHdl)); - } + // blank out missing entries + for (int i = pEntry->ItemCount(); i < col; ++i) + AddStringItem(pEntry, "", i - 1); - virtual void columns_autosize() override + if (static_cast<size_t>(col) == pEntry->ItemCount()) { - std::vector<tools::Long> aWidths; - m_xTreeView->getPreferredDimensions(aWidths); - if (aWidths.size() > 2) - { - std::vector<int> aColWidths; - for (size_t i = 1; i < aWidths.size() - 1; ++i) - aColWidths.push_back(aWidths[i] - aWidths[i - 1]); - set_column_fixed_widths(aColWidths); - } + SvLBoxButtonData* pData = m_bTogglesAsRadio ? &m_aRadioButtonData : &m_aCheckButtonData; + pEntry->AddItem(std::make_unique<SvLBoxButton>(pData)); + update_checkbutton_column_width(pEntry); } - virtual void freeze() override - { - SalInstanceWidget::freeze(); - m_xTreeView->SetUpdateMode(false); - m_xTreeView->GetModel()->EnableInvalidate(false); - } + do_set_toggle(pEntry, eState, col); +} - virtual void thaw() override - { - m_xTreeView->GetModel()->EnableInvalidate(true); - m_xTreeView->SetUpdateMode(true); - SalInstanceWidget::thaw(); - } +bool SalInstanceTreeView::get_text_emphasis(SvTreeListEntry* pEntry, int col) const +{ + col = to_internal_model(col); + + assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount()); + SvLBoxItem& rItem = pEntry->GetItem(col); + assert(dynamic_cast<SvLBoxString*>(&rItem)); + return static_cast<SvLBoxString&>(rItem).IsEmphasized(); +} - virtual void set_column_fixed_widths(const std::vector<int>& rWidths) override +void SalInstanceTreeView::set_header_item_width(const std::vector<int>& rWidths) +{ + LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get()); + if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr) { - std::vector<tools::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); - set_header_item_width(rWidths); - // call Resize to recalculate based on the new tabs - m_xTreeView->Resize(); + pHeaderBar->SetItemSize(pHeaderBar->GetItemId(i), rWidths[i]); } +} - virtual void set_column_editables(const std::vector<bool>& rEditables) override - { - size_t nTabCount = rEditables.size(); - for (size_t i = 0; i < nTabCount; ++i) - m_xTreeView->SetTabEditable(i, rEditables[i]); +SalInstanceTreeView::SalInstanceTreeView(SvTabListBox* pTreeView, SalInstanceBuilder* pBuilder, + bool bTakeOwnership) + : SalInstanceContainer(pTreeView, pBuilder, bTakeOwnership) + , m_xTreeView(pTreeView) + , m_aCheckButtonData(pTreeView, false) + , m_aRadioButtonData(pTreeView, true) + , m_bTogglesAsRadio(false) + , m_nSortColumn(-1) +{ + m_xTreeView->SetNodeDefaultImages(); + m_xTreeView->SetForceMakeVisible(true); + m_xTreeView->SetSelectHdl(LINK(this, SalInstanceTreeView, SelectHdl)); + m_xTreeView->SetDeselectHdl(LINK(this, SalInstanceTreeView, DeSelectHdl)); + m_xTreeView->SetDoubleClickHdl(LINK(this, SalInstanceTreeView, DoubleClickHdl)); + m_xTreeView->SetExpandingHdl(LINK(this, SalInstanceTreeView, ExpandingHdl)); + m_xTreeView->SetPopupMenuHdl(LINK(this, SalInstanceTreeView, PopupMenuHdl)); + m_xTreeView->SetCustomRenderHdl(LINK(this, SalInstanceTreeView, CustomRenderHdl)); + m_xTreeView->SetCustomMeasureHdl(LINK(this, SalInstanceTreeView, CustomMeasureHdl)); + const tools::Long aTabPositions[] = { 0 }; + m_xTreeView->SetTabs(SAL_N_ELEMENTS(aTabPositions), aTabPositions); + LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get()); + + if (pHeaderBox) + { + if (HeaderBar* pHeaderBar = pHeaderBox->GetHeaderBar()) + { + //make the last entry fill available space + pHeaderBar->SetItemSize(pHeaderBar->GetItemId(pHeaderBar->GetItemCount() - 1), + HEADERBAR_FULLSIZE); + pHeaderBar->SetEndDragHdl(LINK(this, SalInstanceTreeView, EndDragHdl)); + pHeaderBar->SetSelectHdl(LINK(this, SalInstanceTreeView, HeaderBarClickedHdl)); + } + pHeaderBox->SetEditingEntryHdl(LINK(this, SalInstanceTreeView, EditingEntryHdl)); + pHeaderBox->SetEditedEntryHdl(LINK(this, SalInstanceTreeView, EditedEntryHdl)); } - - virtual void set_centered_column(int nCol) override + else { - m_xTreeView->SetTabJustify(nCol, SvTabJustify::AdjustCenter); + static_cast<LclTabListBox&>(*m_xTreeView) + .SetModelChangedHdl(LINK(this, SalInstanceTreeView, ModelChangedHdl)); + static_cast<LclTabListBox&>(*m_xTreeView) + .SetStartDragHdl(LINK(this, SalInstanceTreeView, StartDragHdl)); + static_cast<LclTabListBox&>(*m_xTreeView) + .SetEndDragHdl(LINK(this, SalInstanceTreeView, FinishDragHdl)); + static_cast<LclTabListBox&>(*m_xTreeView) + .SetEditingEntryHdl(LINK(this, SalInstanceTreeView, EditingEntryHdl)); + static_cast<LclTabListBox&>(*m_xTreeView) + .SetEditedEntryHdl(LINK(this, SalInstanceTreeView, EditedEntryHdl)); } + m_aCheckButtonData.SetLink(LINK(this, SalInstanceTreeView, ToggleHdl)); + m_aRadioButtonData.SetLink(LINK(this, SalInstanceTreeView, ToggleHdl)); +} - virtual int get_column_width(int nColumn) const override - { - LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get()); - if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr) - return pHeaderBar->GetItemSize(pHeaderBar->GetItemId(nColumn)); - // 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; - } +void SalInstanceTreeView::connect_query_tooltip(const Link<const weld::TreeIter&, OUString>& rLink) +{ + weld::TreeView::connect_query_tooltip(rLink); + m_xTreeView->SetTooltipHdl(LINK(this, SalInstanceTreeView, TooltipHdl)); +} - virtual OUString get_column_title(int nColumn) const override +void SalInstanceTreeView::columns_autosize() +{ + std::vector<tools::Long> aWidths; + m_xTreeView->getPreferredDimensions(aWidths); + if (aWidths.size() > 2) { - LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get()); - if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr) - { - return pHeaderBar->GetItemText(pHeaderBar->GetItemId(nColumn)); - } - return OUString(); + std::vector<int> aColWidths; + for (size_t i = 1; i < aWidths.size() - 1; ++i) + aColWidths.push_back(aWidths[i] - aWidths[i - 1]); + set_column_fixed_widths(aColWidths); } +} - virtual void set_column_title(int nColumn, const OUString& rTitle) override - { - LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get()); - if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr) - { - return pHeaderBar->SetItemText(pHeaderBar->GetItemId(nColumn), rTitle); - } - } +void SalInstanceTreeView::freeze() +{ + SalInstanceWidget::freeze(); + m_xTreeView->SetUpdateMode(false); + m_xTreeView->GetModel()->EnableInvalidate(false); +} - virtual void set_column_custom_renderer(int nColumn, bool bEnable) override - { - assert(n_children() == 0 && "tree must be empty"); - if (bEnable) - m_aCustomRenders.insert(nColumn); - else - m_aCustomRenders.erase(nColumn); - } +void SalInstanceTreeView::thaw() +{ + m_xTreeView->GetModel()->EnableInvalidate(true); + m_xTreeView->SetUpdateMode(true); + SalInstanceWidget::thaw(); +} - virtual void queue_draw() override - { - // invalidate the entries - SvTreeList* pModel = m_xTreeView->GetModel(); - for (SvTreeListEntry* pEntry = m_xTreeView->First(); pEntry; - pEntry = m_xTreeView->Next(pEntry)) - pModel->InvalidateEntry(pEntry); - } +void SalInstanceTreeView::set_column_fixed_widths(const std::vector<int>& rWidths) +{ + std::vector<tools::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); + set_header_item_width(rWidths); + // call Resize to recalculate based on the new tabs + m_xTreeView->Resize(); +} - virtual void show() override - { - if (LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get())) - pHeaderBox->GetParent()->Show(); - SalInstanceContainer::show(); - } +void SalInstanceTreeView::set_column_editables(const std::vector<bool>& rEditables) +{ + size_t nTabCount = rEditables.size(); + for (size_t i = 0; i < nTabCount; ++i) + m_xTreeView->SetTabEditable(i, rEditables[i]); +} - virtual void hide() override - { - if (LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get())) - pHeaderBox->GetParent()->Hide(); - SalInstanceContainer::hide(); - } +void SalInstanceTreeView::set_centered_column(int nCol) +{ + m_xTreeView->SetTabJustify(nCol, SvTabJustify::AdjustCenter); +} + +int SalInstanceTreeView::get_column_width(int nColumn) const +{ + LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get()); + if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr) + return pHeaderBar->GetItemSize(pHeaderBar->GetItemId(nColumn)); + // 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 void insert(const weld::TreeIter* pParent, int pos, const OUString* pStr, - const OUString* pId, const OUString* pIconName, - VirtualDevice* pImageSurface, bool bChildrenOnDemand, - weld::TreeIter* pRet) override +OUString SalInstanceTreeView::get_column_title(int nColumn) const +{ + LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get()); + if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr) { - do_insert(pParent, pos, pStr, pId, pIconName, pImageSurface, bChildrenOnDemand, pRet, - false); + return pHeaderBar->GetItemText(pHeaderBar->GetItemId(nColumn)); } + return OUString(); +} - virtual void insert_separator(int pos, const OUString& /*rId*/) override +void SalInstanceTreeView::set_column_title(int nColumn, const OUString& rTitle) +{ + LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get()); + if (HeaderBar* pHeaderBar = pHeaderBox ? pHeaderBox->GetHeaderBar() : nullptr) { - OUString sSep(VclResId(STR_SEPARATOR)); - do_insert(nullptr, pos, &sSep, nullptr, nullptr, nullptr, false, nullptr, true); + return pHeaderBar->SetItemText(pHeaderBar->GetItemId(nColumn), rTitle); } +} - virtual void - bulk_insert_for_each(int nSourceCount, - const std::function<void(weld::TreeIter&, int nSourceIndex)>& func, - const std::vector<int>* pFixedWidths) override - { - freeze(); - clear(); - SalInstanceTreeIter aVclIter(static_cast<SvTreeListEntry*>(nullptr)); +void SalInstanceTreeView::set_column_custom_renderer(int nColumn, bool bEnable) +{ + assert(n_children() == 0 && "tree must be empty"); + if (bEnable) + m_aCustomRenders.insert(nColumn); + else + m_aCustomRenders.erase(nColumn); +} + +void SalInstanceTreeView::queue_draw() +{ + // invalidate the entries + SvTreeList* pModel = m_xTreeView->GetModel(); + for (SvTreeListEntry* pEntry = m_xTreeView->First(); pEntry; pEntry = m_xTreeView->Next(pEntry)) + pModel->InvalidateEntry(pEntry); +} + +void SalInstanceTreeView::show() +{ + if (LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get())) + pHeaderBox->GetParent()->Show(); + SalInstanceContainer::show(); +} - m_xTreeView->nTreeFlags |= SvTreeFlags::MANINS; +void SalInstanceTreeView::hide() +{ + if (LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get())) + pHeaderBox->GetParent()->Hide(); + SalInstanceContainer::hide(); +} - if (pFixedWidths) - set_header_item_width(*pFixedWidths); +void SalInstanceTreeView::insert(const weld::TreeIter* pParent, int pos, const OUString* pStr, + const OUString* pId, const OUString* pIconName, + VirtualDevice* pImageSurface, bool bChildrenOnDemand, + weld::TreeIter* pRet) +{ + do_insert(pParent, pos, pStr, pId, pIconName, pImageSurface, bChildrenOnDemand, pRet, false); +} - bool bHasAutoCheckButton(m_xTreeView->nTreeFlags & SvTreeFlags::CHKBTN); - size_t nExtraCols = bHasAutoCheckButton ? 2 : 1; +void SalInstanceTreeView::insert_separator(int pos, const OUString& /*rId*/) +{ + OUString sSep(VclResId(STR_SEPARATOR)); + do_insert(nullptr, pos, &sSep, nullptr, nullptr, nullptr, false, nullptr, true); +} - Image aDummy; - for (int i = 0; i < nSourceCount; ++i) - { - aVclIter.iter = new SvTreeListEntry; - if (bHasAutoCheckButton) - AddStringItem(aVclIter.iter, "", -1); - aVclIter.iter->AddItem(std::make_unique<SvLBoxContextBmp>(aDummy, aDummy, false)); - m_xTreeView->Insert(aVclIter.iter, nullptr, TREELIST_APPEND); - func(aVclIter, i); - - if (!pFixedWidths) - continue; - - size_t nFixedWidths = std::min(pFixedWidths->size(), aVclIter.iter->ItemCount()); - for (size_t j = 0; j < nFixedWidths; ++j) - { - SvLBoxItem& rItem = aVclIter.iter->GetItem(j + nExtraCols); - SvViewDataItem* pViewDataItem = m_xTreeView->GetViewDataItem(aVclIter.iter, &rItem); - pViewDataItem->mnWidth = (*pFixedWidths)[j]; - } - } +void SalInstanceTreeView::bulk_insert_for_each( + int nSourceCount, const std::function<void(weld::TreeIter&, int nSourceIndex)>& func, + const std::vector<int>* pFixedWidths) +{ + freeze(); + clear(); + SalInstanceTreeIter aVclIter(static_cast<SvTreeListEntry*>(nullptr)); - m_xTreeView->nTreeFlags &= ~SvTreeFlags::MANINS; + m_xTreeView->nTreeFlags |= SvTreeFlags::MANINS; - thaw(); - } + if (pFixedWidths) + set_header_item_width(*pFixedWidths); - virtual void set_font_color(int pos, const Color& rColor) override - { - SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos); - set_font_color(pEntry, rColor); - } + bool bHasAutoCheckButton(m_xTreeView->nTreeFlags & SvTreeFlags::CHKBTN); + size_t nExtraCols = bHasAutoCheckButton ? 2 : 1; - virtual void set_font_color(const weld::TreeIter& rIter, const Color& rColor) override + Image aDummy; + for (int i = 0; i < nSourceCount; ++i) { - const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter); - set_font_color(rVclIter.iter, rColor); - } + aVclIter.iter = new SvTreeListEntry; + if (bHasAutoCheckButton) + AddStringItem(aVclIter.iter, "", -1); + aVclIter.iter->AddItem(std::make_unique<SvLBoxContextBmp>(aDummy, aDummy, false)); + m_xTreeView->Insert(aVclIter.iter, nullptr, TREELIST_APPEND); + func(aVclIter, i); - virtual void remove(int pos) override - { - disable_notify_events(); - SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos); - m_xTreeView->RemoveEntry(pEntry); - enable_notify_events(); - } + if (!pFixedWidths) + continue; - virtual int find_text(const OUString& rText) const override - { - for (SvTreeListEntry* pEntry = m_xTreeView->First(); pEntry; - pEntry = m_xTreeView->Next(pEntry)) + size_t nFixedWidths = std::min(pFixedWidths->size(), aVclIter.iter->ItemCount()); + for (size_t j = 0; j < nFixedWidths; ++j) { - if (SvTabListBox::GetEntryText(pEntry, 0) == rText) - return SvTreeList::GetRelPos(pEntry); + SvLBoxItem& rItem = aVclIter.iter->GetItem(j + nExtraCols); + SvViewDataItem* pViewDataItem = m_xTreeView->GetViewDataItem(aVclIter.iter, &rItem); + pViewDataItem->mnWidth = (*pFixedWidths)[j]; } - return -1; } - virtual int find_id(const OUString& rId) const override - { - 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 SvTreeList::GetRelPos(pEntry); - } - return -1; - } + m_xTreeView->nTreeFlags &= ~SvTreeFlags::MANINS; - virtual void swap(int pos1, int pos2) override - { - int min = std::min(pos1, pos2); - int max = std::max(pos1, pos2); - SvTreeList* pModel = m_xTreeView->GetModel(); - SvTreeListEntry* pEntry1 = pModel->GetEntry(nullptr, min); - SvTreeListEntry* pEntry2 = pModel->GetEntry(nullptr, max); - pModel->Move(pEntry1, pEntry2); - } + thaw(); +} - virtual void clear() override - { - disable_notify_events(); - m_xTreeView->Clear(); - m_aUserData.clear(); - enable_notify_events(); - } +void SalInstanceTreeView::set_font_color(int pos, const Color& rColor) +{ + SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos); + set_font_color(pEntry, rColor); +} - virtual int n_children() const override - { - return m_xTreeView->GetModel()->GetChildList(nullptr).size(); - } +void SalInstanceTreeView::set_font_color(const weld::TreeIter& rIter, const Color& rColor) +{ + const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter); + set_font_color(rVclIter.iter, rColor); +} - virtual int iter_n_children(const weld::TreeIter& rIter) const override - { - const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter); - return m_xTreeView->GetModel()->GetChildList(rVclIter.iter).size(); - } +void SalInstanceTreeView::remove(int pos) +{ + disable_notify_events(); + SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos); + m_xTreeView->RemoveEntry(pEntry); + enable_notify_events(); +} - virtual void select(int pos) override +int SalInstanceTreeView::find_text(const OUString& rText) const +{ + for (SvTreeListEntry* pEntry = m_xTreeView->First(); pEntry; pEntry = m_xTreeView->Next(pEntry)) { - assert(m_xTreeView->IsUpdateMode() - && "don't select when frozen, select after thaw. Note selection doesn't survive a " - "freeze"); - 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(); + if (SvTabListBox::GetEntryText(pEntry, 0) == rText) + return SvTreeList::GetRelPos(pEntry); } + return -1; +} - virtual int get_cursor_index() const override +int SalInstanceTreeView::find_id(const OUString& rId) const +{ + for (SvTreeListEntry* pEntry = m_xTreeView->First(); pEntry; pEntry = m_xTreeView->Next(pEntry)) { - SvTreeListEntry* pEntry = m_xTreeView->GetCurEntry(); - if (!pEntry) - return -1; - return SvTreeList::GetRelPos(pEntry); + const OUString* pId = static_cast<const OUString*>(pEntry->GetUserData()); + if (!pId) + continue; + if (rId == *pId) + return SvTreeList::GetRelPos(pEntry); } + return -1; +} - virtual void set_cursor(int pos) override - { - disable_notify_events(); - if (pos == -1) - m_xTreeView->SetCurEntry(nullptr); - else - { - SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos); - m_xTreeView->SetCurEntry(pEntry); - } - enable_notify_events(); - } +void SalInstanceTreeView::swap(int pos1, int pos2) +{ + int min = std::min(pos1, pos2); + int max = std::max(pos1, pos2); + SvTreeList* pModel = m_xTreeView->GetModel(); + SvTreeListEntry* pEntry1 = pModel->GetEntry(nullptr, min); + SvTreeListEntry* pEntry2 = pModel->GetEntry(nullptr, max); + pModel->Move(pEntry1, pEntry2); +} + +void SalInstanceTreeView::clear() +{ + disable_notify_events(); + m_xTreeView->Clear(); + m_aUserData.clear(); + enable_notify_events(); +} + +int SalInstanceTreeView::n_children() const +{ + return m_xTreeView->GetModel()->GetChildList(nullptr).size(); +} + +int SalInstanceTreeView::iter_n_children(const weld::TreeIter& rIter) const +{ + const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter); + return m_xTreeView->GetModel()->GetChildList(rVclIter.iter).size(); +} - virtual void scroll_to_row(int pos) override +void SalInstanceTreeView::select(int pos) +{ + assert(m_xTreeView->IsUpdateMode() + && "don't select when frozen, select after thaw. Note selection doesn't survive a " + "freeze"); + 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, select after thaw. Note selection doesn't survive a " - "freeze"); - 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(); +} + +int SalInstanceTreeView::get_cursor_index() const +{ + SvTreeListEntry* pEntry = m_xTreeView->GetCurEntry(); + if (!pEntry) + return -1; + return SvTreeList::GetRelPos(pEntry); +} - virtual bool is_selected(int pos) const override +void SalInstanceTreeView::set_cursor(int pos) +{ + disable_notify_events(); + if (pos == -1) + m_xTreeView->SetCurEntry(nullptr); + else { SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos); - return m_xTreeView->IsSelected(pEntry); + m_xTreeView->SetCurEntry(pEntry); } + enable_notify_events(); +} - virtual void unselect(int pos) override +void SalInstanceTreeView::scroll_to_row(int pos) +{ + assert(m_xTreeView->IsUpdateMode() + && "don't select when frozen, select after thaw. Note selection doesn't survive a " + "freeze"); + disable_notify_events(); + SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos); + m_xTreeView->MakeVisible(pEntry); + enable_notify_events(); +} + +bool SalInstanceTreeView::is_selected(int pos) const +{ + SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos); + return m_xTreeView->IsSelected(pEntry); +} + +void SalInstanceTreeView::unselect(int pos) +{ + assert(m_xTreeView->IsUpdateMode() + && "don't select when frozen, select after thaw. Note selection doesn't survive a " + "freeze"); + disable_notify_events(); + if (pos == -1) + m_xTreeView->SelectAll(true); + else { - assert(m_xTreeView->IsUpdateMode() - && "don't select when frozen, select after thaw. Note selection doesn't survive a " - "freeze"); - 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->Select(pEntry, false); } + enable_notify_events(); +} - virtual std::vector<int> get_selected_rows() const override - { - std::vector<int> aRows; +std::vector<int> SalInstanceTreeView::get_selected_rows() const +{ + std::vector<int> aRows; - aRows.reserve(m_xTreeView->GetSelectionCount()); - for (SvTreeListEntry* pEntry = m_xTreeView->FirstSelected(); pEntry; - pEntry = m_xTreeView->NextSelected(pEntry)) - aRows.push_back(SvTreeList::GetRelPos(pEntry)); + aRows.reserve(m_xTreeView->GetSelectionCount()); + for (SvTreeListEntry* pEntry = m_xTreeView->FirstSelected(); pEntry; + pEntry = m_xTreeView->NextSelected(pEntry)) + aRows.push_back(SvTreeList::GetRelPos(pEntry)); - return aRows; - } + return aRows; +} - OUString get_text(SvTreeListEntry* pEntry, int col) const - { - if (col == -1) - return SvTabListBox::GetEntryText(pEntry, 0); +OUString SalInstanceTreeView::get_text(SvTreeListEntry* pEntry, int col) const +{ + if (col == -1) + return SvTabListBox::GetEntryText(pEntry, 0); - col = to_internal_model(col); + col = to_internal_model(col); - if (static_cast<size_t>(col) == pEntry->ItemCount()) - return OUString(); + if (static_cast<size_t>(col) == pEntry->ItemCount()) + return OUString(); - assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount()); - SvLBoxItem& rItem = pEntry->GetItem(col); - assert(dynamic_cast<SvLBoxString*>(&rItem)); - return static_cast<SvLBoxString&>(rItem).GetText(); - } + assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount()); + SvLBoxItem& rItem = pEntry->GetItem(col); + assert(dynamic_cast<SvLBoxString*>(&rItem)); + return static_cast<SvLBoxString&>(rItem).GetText(); +} - virtual OUString get_text(int pos, int col) const override - { - SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos); - return get_text(pEntry, col); - } +OUString SalInstanceTreeView::get_text(int pos, int col) const +{ + SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos); + return get_text(pEntry, col); +} - void set_text(SvTreeListEntry* pEntry, const OUString& rText, int col) +void SalInstanceTreeView::set_text(SvTreeListEntry* pEntry, const OUString& rText, int col) +{ + if (col == -1) { - if (col == -1) - { - m_xTreeView->SetEntryText(pEntry, rText); - return; - } - - col = to_internal_model(col); - - // blank out missing entries - for (int i = pEntry->ItemCount(); i < col; ++i) - AddStringItem(pEntry, "", i - 1); + m_xTreeView->SetEntryText(pEntry, rText); + return; + } - if (static_cast<size_t>(col) == pEntry->ItemCount()) - { - AddStringItem(pEntry, rText, col - 1); - SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry); - m_xTreeView->InitViewData(pViewData, pEntry); - } - else - { - assert(col >= 0 && o3tl::make_unsigned(col) < pEntry->ItemCount()); - SvLBoxItem& rItem = pEntry->GetItem(col); - assert(dynamic_cast<SvLBoxString*>(&rItem)); - static_cast<SvLBoxString&>(rItem).SetText(rText); - } + col = to_internal_model(col); - InvalidateModelEntry(pEntry); - } + // blank out missing entries + for (int i = pEntry->ItemCount(); i < col; ++i) + AddStringItem(pEntry, "", i - 1); ... etc. - the rest is truncated _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
