summaryrefslogtreecommitdiff
path: root/vcl/source
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2018-11-21 15:13:49 +0000
committerCaolán McNamara <caolanm@redhat.com>2018-11-21 22:10:00 +0100
commit6d250d56ed9b6755a3f8131be39fc0537c3d862c (patch)
tree1ba55f2c90cb88f546825af5a0a8de57a50e5c66 /vcl/source
parentc986c8852cd1156aee870d21cfb4044d3b05a933 (diff)
add TreeView header support
Change-Id: If3dd296e962b08120e07c35065bc18441691b7fd Reviewed-on: https://gerrit.libreoffice.org/63730 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl/source')
-rw-r--r--vcl/source/app/salvtables.cxx34
-rw-r--r--vcl/source/treelist/headbar.cxx5
-rw-r--r--vcl/source/treelist/svtabbx.cxx5
-rw-r--r--vcl/source/window/builder.cxx84
4 files changed, 116 insertions, 12 deletions
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)
{