include/vcl/builder.hxx | 4 - include/vcl/headbar.hxx | 2 include/vcl/svtabbx.hxx | 3 - sw/source/ui/chrdlg/swuiccoll.cxx | 6 -- sw/source/uibase/inc/swuiccoll.hxx | 3 - sw/uiconfig/swriter/ui/conditionpage.ui | 56 +++------------------ vcl/source/app/salvtables.cxx | 34 +++++++++++- vcl/source/treelist/headbar.cxx | 5 + vcl/source/treelist/svtabbx.cxx | 5 + vcl/source/window/builder.cxx | 84 ++++++++++++++++++++++++++++---- 10 files changed, 131 insertions(+), 71 deletions(-)
New commits: commit 6d250d56ed9b6755a3f8131be39fc0537c3d862c Author: Caolán McNamara <caol...@redhat.com> AuthorDate: Wed Nov 21 15:13:49 2018 +0000 Commit: Caolán McNamara <caol...@redhat.com> CommitDate: Wed Nov 21 22:10:00 2018 +0100 add TreeView header support Change-Id: If3dd296e962b08120e07c35065bc18441691b7fd Reviewed-on: https://gerrit.libreoffice.org/63730 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caol...@redhat.com> Tested-by: Caolán McNamara <caol...@redhat.com> diff --git a/include/vcl/builder.hxx b/include/vcl/builder.hxx index 5fdb061f7b1e..a1a47b9f7047 100644 --- a/include/vcl/builder.hxx +++ b/include/vcl/builder.hxx @@ -38,7 +38,7 @@ class PopupMenu; class SalInstanceBuilder; class ScreenshotTest; class ScrollBar; -class SvTabListBox; +class SvHeaderTabListBox; class Slider; class DateField; class TimeField; @@ -220,7 +220,7 @@ private: const ListStore* get_model_by_name(const OString& sID) const; void mungeModel(ListBox &rTarget, const ListStore &rStore, sal_uInt16 nActiveId); void mungeModel(ComboBox &rTarget, const ListStore &rStore, sal_uInt16 nActiveId); - void mungeModel(SvTabListBox &rTarget, const ListStore &rStore, sal_uInt16 nActiveId); + void mungeModel(SvHeaderTabListBox &rTarget, const ListStore &rStore, sal_uInt16 nActiveId); typedef stringmap TextBuffer; const TextBuffer* get_buffer_by_name(const OString& sID) const; diff --git a/include/vcl/headbar.hxx b/include/vcl/headbar.hxx index 046ad7079a24..af6c99a56625 100644 --- a/include/vcl/headbar.hxx +++ b/include/vcl/headbar.hxx @@ -277,6 +277,8 @@ public: virtual void StateChanged( StateChangedType nStateChange ) override; virtual void DataChanged( const DataChangedEvent& rDCEvt ) override; + virtual Size GetOptimalSize() const override; + virtual void EndDrag(); virtual void Select(); virtual void DoubleClick(); diff --git a/include/vcl/svtabbx.hxx b/include/vcl/svtabbx.hxx index a49ca16bc992..066bbb929158 100644 --- a/include/vcl/svtabbx.hxx +++ b/include/vcl/svtabbx.hxx @@ -141,7 +141,8 @@ public: virtual void Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& ) override; - void InitHeaderBar( HeaderBar* pHeaderBar ); + void InitHeaderBar(HeaderBar* pHeaderBar); + HeaderBar* GetHeaderBar(); static bool IsItemChecked( SvTreeListEntry* pEntry, sal_uInt16 nCol ); virtual SvTreeListEntry* InsertEntryToColumn( const OUString&, sal_uLong nPos = TREELIST_APPEND, diff --git a/sw/source/ui/chrdlg/swuiccoll.cxx b/sw/source/ui/chrdlg/swuiccoll.cxx index 66ba6f6d2f97..16fa6e1761db 100644 --- a/sw/source/ui/chrdlg/swuiccoll.cxx +++ b/sw/source/ui/chrdlg/swuiccoll.cxx @@ -51,10 +51,7 @@ SwCondCollPage::SwCondCollPage(TabPageParent pParent, const SfxItemSet &rSet) , m_pFormat(nullptr) , m_bNewTemplate(false) , m_xConditionCB(m_xBuilder->weld_check_button("condstyle")) - , m_xContextFT(m_xBuilder->weld_label("contextft")) - , m_xUsedFT(m_xBuilder->weld_label("usedft")) , m_xTbLinks(m_xBuilder->weld_tree_view("links")) - , m_xStyleFT(m_xBuilder->weld_label("styleft")) , m_xStyleLB(m_xBuilder->weld_tree_view("styles")) , m_xFilterLB(m_xBuilder->weld_combo_box("filter")) , m_xRemovePB(m_xBuilder->weld_button("remove")) @@ -179,10 +176,7 @@ void SwCondCollPage::Reset(const SfxItemSet *) IMPL_LINK(SwCondCollPage, OnOffHdl, weld::ToggleButton&, rBox, void) { const bool bEnable = rBox.get_active(); - m_xContextFT->set_sensitive(bEnable); - m_xUsedFT->set_sensitive(bEnable); m_xTbLinks->set_sensitive(bEnable); - m_xStyleFT->set_sensitive(bEnable); m_xStyleLB->set_sensitive(bEnable); m_xFilterLB->set_sensitive(bEnable); m_xRemovePB->set_sensitive(bEnable); diff --git a/sw/source/uibase/inc/swuiccoll.hxx b/sw/source/uibase/inc/swuiccoll.hxx index f8e2449c2577..aa5eeae370d8 100644 --- a/sw/source/uibase/inc/swuiccoll.hxx +++ b/sw/source/uibase/inc/swuiccoll.hxx @@ -36,10 +36,7 @@ class SwCondCollPage : public SfxTabPage bool m_bNewTemplate; std::unique_ptr<weld::CheckButton> m_xConditionCB; - std::unique_ptr<weld::Label> m_xContextFT; - std::unique_ptr<weld::Label> m_xUsedFT; std::unique_ptr<weld::TreeView> m_xTbLinks; - std::unique_ptr<weld::Label> m_xStyleFT; std::unique_ptr<weld::TreeView> m_xStyleLB; std::unique_ptr<weld::ComboBox> m_xFilterLB; std::unique_ptr<weld::Button> m_xRemovePB; diff --git a/sw/uiconfig/swriter/ui/conditionpage.ui b/sw/uiconfig/swriter/ui/conditionpage.ui index bce9a36205d8..dc06111e704f 100644 --- a/sw/uiconfig/swriter/ui/conditionpage.ui +++ b/sw/uiconfig/swriter/ui/conditionpage.ui @@ -73,45 +73,6 @@ </packing> </child> <child> - <object class="GtkLabel" id="contextft"> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes" context="conditionpage|contextft">Conte_xt</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="usedft"> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes" context="conditionpage|usedft">Applied Styles</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="styleft"> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes" context="conditionpage|styleft">_Paragraph Styles</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">styles</property> - </object> - <packing> - <property name="left_attach">2</property> - <property name="top_attach">1</property> - </packing> - </child> - <child> <object class="GtkScrolledWindow"> <property name="visible">True</property> <property name="can_focus">True</property> @@ -120,14 +81,12 @@ <property name="shadow_type">in</property> <child> <object class="GtkTreeView" id="links"> - <property name="width_request">-1</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> <property name="hexpand">True</property> <property name="vexpand">True</property> <property name="model">liststore1</property> - <property name="headers_visible">False</property> <property name="search_column">0</property> <property name="show_expanders">False</property> <child internal-child="selection"> @@ -137,6 +96,7 @@ <object class="GtkTreeViewColumn" id="treeviewcolumn1"> <property name="resizable">True</property> <property name="spacing">6</property> + <property name="title" translatable="yes" context="conditionpage|contextft">Context</property> <child> <object class="GtkCellRendererText" id="cellrenderer1"/> <attributes> @@ -149,6 +109,7 @@ <object class="GtkTreeViewColumn" id="treeviewcolumn2"> <property name="resizable">True</property> <property name="spacing">6</property> + <property name="title" translatable="yes" context="conditionpage|usedft">Applied Styles</property> <child> <object class="GtkCellRendererText" id="cellrenderer2"/> <attributes> @@ -165,7 +126,7 @@ </object> <packing> <property name="left_attach">0</property> - <property name="top_attach">2</property> + <property name="top_attach">1</property> <property name="width">2</property> </packing> </child> @@ -209,7 +170,7 @@ </object> <packing> <property name="left_attach">0</property> - <property name="top_attach">3</property> + <property name="top_attach">2</property> <property name="width">3</property> </packing> </child> @@ -217,6 +178,8 @@ <object class="GtkBox" id="box1"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="hexpand">False</property> + <property name="vexpand">True</property> <property name="orientation">vertical</property> <property name="spacing">6</property> <child> @@ -228,14 +191,12 @@ <property name="shadow_type">in</property> <child> <object class="GtkTreeView" id="styles"> - <property name="width_request">-1</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> <property name="hexpand">True</property> <property name="vexpand">True</property> <property name="model">liststore2</property> - <property name="headers_visible">False</property> <property name="search_column">0</property> <property name="show_expanders">False</property> <child internal-child="selection"> @@ -244,6 +205,7 @@ <child> <object class="GtkTreeViewColumn" id="treeviewcolumn3"> <property name="spacing">6</property> + <property name="title" translatable="yes" context="conditionpage|styleft">Paragraph Styles</property> <child> <object class="GtkCellRendererText" id="cellrenderer4"/> <attributes> @@ -256,7 +218,7 @@ </child> </object> <packing> - <property name="expand">False</property> + <property name="expand">True</property> <property name="fill">True</property> <property name="position">0</property> </packing> @@ -306,7 +268,7 @@ </object> <packing> <property name="left_attach">2</property> - <property name="top_attach">2</property> + <property name="top_attach">1</property> </packing> </child> </object> diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index 248ea5b0fef1..c04ca82d1a37 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -39,6 +39,7 @@ #include <vcl/dialog.hxx> #include <vcl/fixed.hxx> #include <vcl/fmtfield.hxx> +#include <vcl/headbar.hxx> #include <vcl/layout.hxx> #include <vcl/menubtn.hxx> #include <vcl/prgsbar.hxx> @@ -1764,14 +1765,15 @@ class SalInstanceTreeView : public SalInstanceContainer, public virtual weld::Tr private: // owner for UserData std::vector<std::unique_ptr<OUString>> m_aUserData; - VclPtr<SvTabListBox> m_xTreeView; + VclPtr<SvHeaderTabListBox> m_xTreeView; DECL_LINK(SelectHdl, SvTreeListBox*, void); DECL_LINK(DoubleClickHdl, SvTreeListBox*, bool); DECL_LINK(ExpandingHdl, SvTreeListBox*, bool); + DECL_LINK(EndDragHdl, HeaderBar*, void); public: - SalInstanceTreeView(SvTabListBox* pTreeView, bool bTakeOwnership) + SalInstanceTreeView(SvHeaderTabListBox* pTreeView, bool bTakeOwnership) : SalInstanceContainer(pTreeView, bTakeOwnership) , m_xTreeView(pTreeView) { @@ -1781,6 +1783,12 @@ public: m_xTreeView->SetExpandingHdl(LINK(this, SalInstanceTreeView, ExpandingHdl)); const long aTabPositions[] = { 0 }; m_xTreeView->SetTabs(SAL_N_ELEMENTS(aTabPositions), aTabPositions); + if (HeaderBar* pHeaderBar = m_xTreeView->GetHeaderBar()) + { + //make the last entry fill available space + pHeaderBar->SetItemSize(pHeaderBar->GetItemId(pHeaderBar->GetItemCount() - 1 ), HEADERBAR_FULLSIZE); + pHeaderBar->SetEndDragHdl(LINK(this, SalInstanceTreeView, EndDragHdl)); + } } virtual void set_column_fixed_widths(const std::vector<int>& rWidths) override @@ -1789,6 +1797,11 @@ public: aTabPositions.push_back(0); aTabPositions.insert(aTabPositions.end(), rWidths.begin(), rWidths.end()); m_xTreeView->SetTabs(aTabPositions.size(), aTabPositions.data(), MapUnit::MapPixel); + if (HeaderBar* pHeaderBar = m_xTreeView->GetHeaderBar()) + { + for (size_t i = 0; i < rWidths.size(); ++i) + pHeaderBar->SetItemSize(pHeaderBar->GetItemId(i), rWidths[i]); + } } virtual void insert(weld::TreeIter* pParent, int pos, const OUString& rStr, const OUString* pId, @@ -2159,13 +2172,17 @@ public: m_xTreeView->SetStyle(m_xTreeView->GetStyle() | WB_SORT); } - SvTabListBox& getTreeView() + SvHeaderTabListBox& getTreeView() { return *m_xTreeView; } virtual ~SalInstanceTreeView() override { + if (HeaderBar* pHeaderBar = m_xTreeView->GetHeaderBar()) + { + pHeaderBar->SetEndDragHdl(Link<HeaderBar*, void>()); + } m_xTreeView->SetExpandingHdl(Link<SvTreeListBox*, bool>()); m_xTreeView->SetDoubleClickHdl(Link<SvTreeListBox*, bool>()); m_xTreeView->SetSelectHdl(Link<SvTreeListBox*, void>()); @@ -2187,6 +2204,15 @@ IMPL_LINK_NOARG(SalInstanceTreeView, DoubleClickHdl, SvTreeListBox*, bool) return false; } +IMPL_LINK(SalInstanceTreeView, EndDragHdl, HeaderBar*, pHeaderBar, void) +{ + std::vector<long> aTabPositions; + aTabPositions.push_back(0); + for (int i = 0; i < pHeaderBar->GetItemCount() - 1; ++i) + aTabPositions.push_back(pHeaderBar->GetItemSize(pHeaderBar->GetItemId(i))); + m_xTreeView->SetTabs(aTabPositions.size(), aTabPositions.data(), MapUnit::MapPixel); +} + IMPL_LINK_NOARG(SalInstanceTreeView, ExpandingHdl, SvTreeListBox*, bool) { SvTreeListEntry* pEntry = m_xTreeView->GetHdlEntry(); @@ -3292,7 +3318,7 @@ public: virtual std::unique_ptr<weld::TreeView> weld_tree_view(const OString &id, bool bTakeOwnership) override { - SvTabListBox* pTreeView = m_xBuilder->get<SvTabListBox>(id); + SvHeaderTabListBox* pTreeView = m_xBuilder->get<SvHeaderTabListBox>(id); return pTreeView ? o3tl::make_unique<SalInstanceTreeView>(pTreeView, bTakeOwnership) : nullptr; } diff --git a/vcl/source/treelist/headbar.cxx b/vcl/source/treelist/headbar.cxx index 95d6584d166a..07f32358af54 100644 --- a/vcl/source/treelist/headbar.cxx +++ b/vcl/source/treelist/headbar.cxx @@ -103,6 +103,11 @@ HeaderBar::HeaderBar(vcl::Window* pParent, WinBits nWinStyle) SetSizePixel( CalcWindowSizePixel() ); } +Size HeaderBar::GetOptimalSize() const +{ + return CalcWindowSizePixel(); +} + HeaderBar::~HeaderBar() = default; void HeaderBar::ApplySettings(vcl::RenderContext& rRenderContext) diff --git a/vcl/source/treelist/svtabbx.cxx b/vcl/source/treelist/svtabbx.cxx index 72c7a8f50926..8713a21ce541 100644 --- a/vcl/source/treelist/svtabbx.cxx +++ b/vcl/source/treelist/svtabbx.cxx @@ -517,6 +517,11 @@ void SvHeaderTabListBox::InitHeaderBar( HeaderBar* pHeaderBar ) m_pImpl->m_pHeaderBar->SetCreateAccessibleHdl( LINK( this, SvHeaderTabListBox, CreateAccessibleHdl_Impl ) ); } +HeaderBar* SvHeaderTabListBox::GetHeaderBar() +{ + return m_pImpl ? m_pImpl->m_pHeaderBar : nullptr; +} + bool SvHeaderTabListBox::IsItemChecked( SvTreeListEntry* pEntry, sal_uInt16 nCol ) { SvButtonState eState = SvButtonState::Unchecked; diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx index acd8195b4a1b..25e7e36e5c03 100644 --- a/vcl/source/window/builder.cxx +++ b/vcl/source/window/builder.cxx @@ -28,6 +28,7 @@ #include <vcl/fmtfield.hxx> #include <vcl/fixed.hxx> #include <vcl/fixedhyper.hxx> +#include <vcl/headbar.hxx> #include <vcl/IPrioritable.hxx> #include <vcl/layout.hxx> #include <vcl/lstbox.hxx> @@ -518,7 +519,7 @@ VclBuilder::VclBuilder(vcl::Window *pParent, const OUString& sUIDir, const OUStr vcl::Window* pTarget = get<vcl::Window>(elem.m_sID); ListBox *pListBoxTarget = dynamic_cast<ListBox*>(pTarget); ComboBox *pComboBoxTarget = dynamic_cast<ComboBox*>(pTarget); - SvTabListBox *pTreeBoxTarget = dynamic_cast<SvTabListBox*>(pTarget); + SvHeaderTabListBox *pTreeBoxTarget = dynamic_cast<SvHeaderTabListBox*>(pTarget); // pStore may be empty const ListStore *pStore = get_model_by_name(elem.m_sValue.toUtf8()); SAL_WARN_IF(!pListBoxTarget && !pComboBoxTarget && !pTreeBoxTarget, "vcl", "missing elements of combobox"); @@ -1110,6 +1111,30 @@ namespace return sTooltipText; } + OUString extractTitle(VclBuilder::stringmap &rMap) + { + OUString sTitle; + VclBuilder::stringmap::iterator aFind = rMap.find(OString("title")); + if (aFind != rMap.end()) + { + sTitle = aFind->second; + rMap.erase(aFind); + } + return sTitle; + } + + bool extractHeadersVisible(VclBuilder::stringmap &rMap) + { + bool bHeadersVisible = true; + VclBuilder::stringmap::iterator aFind = rMap.find(OString("headers-visible")); + if (aFind != rMap.end()) + { + bHeadersVisible = toBool(aFind->second); + rMap.erase(aFind); + } + return bHeadersVisible; + } + void setupFromActionName(Button *pButton, VclBuilder::stringmap &rMap, const css::uno::Reference<css::frame::XFrame>& rFrame) { if (!rFrame.is()) @@ -1871,10 +1896,12 @@ VclPtr<vcl::Window> VclBuilder::makeObject(vcl::Window *pParent, const OString & } else if (name == "GtkTreeView") { + //window we want to apply the packing props for this GtkTreeView to + VclPtr<vcl::Window> xWindowForPackingProps; //To-Do - //a) make SvTabListBox the default target for GtkTreeView + //a) make SvHeaderTabListBox the default target for GtkTreeView //b) remove the non-drop down mode of ListBox and convert - // everything over to SvTabListBox + // everything over to SvHeaderTabListBox //c) remove the users of makeSvTabListBox and makeSvTreeListBox extractModel(id, rMap); WinBits nWinStyle = WB_CLIPCHILDREN|WB_LEFT|WB_VCENTER|WB_3DLOOK|WB_SIMPLEMODE; @@ -1884,21 +1911,62 @@ VclPtr<vcl::Window> VclBuilder::makeObject(vcl::Window *pParent, const OString & if (!sBorder.isEmpty()) nWinStyle |= WB_BORDER; } - //ListBox/SvTabListBox manages its own scrolling, + //ListBox/SvHeaderTabListBox manages its own scrolling, vcl::Window *pRealParent = prepareWidgetOwnScrolling(pParent, nWinStyle); if (pRealParent != pParent) nWinStyle |= WB_BORDER; if (m_bLegacy) + { xWindow = VclPtr<ListBox>::Create(pRealParent, nWinStyle); + xWindowForPackingProps = xWindow; + } else { - VclPtrInstance<SvTabListBox> xBox(pRealParent, nWinStyle); + VclPtr<SvHeaderTabListBox> xBox; + bool bHeadersVisible = extractHeadersVisible(rMap); + if (bHeadersVisible) + { + VclPtr<VclVBox> xContainer = VclPtr<VclVBox>::Create(pRealParent); + OString containerid(id + "-container"); + xContainer->SetHelpId(m_sHelpRoot + containerid); + m_aChildren.emplace_back(containerid, xContainer, true); + + VclPtrInstance<HeaderBar> xHeader(xContainer, WB_BUTTONSTYLE | WB_BORDER | WB_TABSTOP | WB_3DLOOK); + OString headerid(id + "-header"); + xHeader->SetHelpId(m_sHelpRoot + headerid); + m_aChildren.emplace_back(headerid, xHeader, true); + + xBox = VclPtr<SvHeaderTabListBox>::Create(xContainer, nWinStyle); + xBox->InitHeaderBar(xHeader); + xContainer->set_expand(true); + xHeader->Show(); + xContainer->Show(); + xWindowForPackingProps = xContainer; + } + else + { + xBox = VclPtr<SvHeaderTabListBox>::Create(pRealParent, nWinStyle); + xWindowForPackingProps = xBox; + } + xWindow = xBox; xBox->SetNoAutoCurEntry(true); xBox->SetHighlightRange(); // select over the whole width - xWindow = xBox; } if (pRealParent != pParent) - cleanupWidgetOwnScrolling(pParent, xWindow, rMap); + cleanupWidgetOwnScrolling(pParent, xWindowForPackingProps, rMap); + } + else if (name == "GtkTreeViewColumn") + { + if (!m_bLegacy) + { + SvHeaderTabListBox* pTreeView = static_cast<SvHeaderTabListBox*>(pParent); + if (HeaderBar* pHeaderBar = pTreeView->GetHeaderBar()) + { + OUString sTitle(extractTitle(rMap)); + auto nItemId = pHeaderBar->GetItemCount() + 1; + pHeaderBar->InsertItem(nItemId, sTitle, 100); + } + } } else if (name == "GtkLabel") { @@ -4081,7 +4149,7 @@ void VclBuilder::mungeModel(ListBox &rTarget, const ListStore &rStore, sal_uInt1 rTarget.SelectEntryPos(nActiveId); } -void VclBuilder::mungeModel(SvTabListBox &rTarget, const ListStore &rStore, sal_uInt16 nActiveId) +void VclBuilder::mungeModel(SvHeaderTabListBox& rTarget, const ListStore &rStore, sal_uInt16 nActiveId) { for (auto const& entry : rStore.m_aEntries) { _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits