summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2019-04-04 14:30:03 +0100
committerCaolán McNamara <caolanm@redhat.com>2019-04-06 19:53:00 +0200
commit5c32ba63163d9556ff89782a8074924cdf9dc554 (patch)
tree66acbb3b4c298c9f0cbff75f9e36bf3d759b7a0f /vcl
parent6f31c63e35abef03e6f938bbddc8778b70a62d43 (diff)
weld OTableSubscriptionPage
Change-Id: I55c23448480384c9a7d78cd55550bb4812ebde72 Reviewed-on: https://gerrit.libreoffice.org/70314 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/source/app/salvtables.cxx145
-rw-r--r--vcl/source/treelist/svlbitm.cxx28
-rw-r--r--vcl/source/treelist/treelistbox.cxx27
-rw-r--r--vcl/unx/gtk3/gtk3gtkinst.cxx116
4 files changed, 267 insertions, 49 deletions
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 5b60f02d47d4..361b8d7830a7 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -51,6 +51,7 @@
#include <vcl/ptrstyle.hxx>
#include <vcl/slider.hxx>
#include <vcl/sysdata.hxx>
+#include <vcl/svimpbox.hxx>
#include <vcl/svlbitm.hxx>
#include <vcl/svtabbx.hxx>
#include <vcl/tabctrl.hxx>
@@ -2265,9 +2266,44 @@ struct SalInstanceTreeIter : public weld::TreeIter
: iter(pOrig ? pOrig->iter : nullptr)
{
}
+ virtual bool equal(const TreeIter& rOther) const override
+ {
+ return iter == static_cast<const SalInstanceTreeIter&>(rOther).iter;
+ }
SvTreeListEntry* iter;
};
+namespace
+{
+ TriState get_toggle(SvTreeListEntry* pEntry, int col)
+ {
+ ++col; //skip dummy/expander column
+
+ if (static_cast<size_t>(col) == pEntry->ItemCount())
+ return TRISTATE_FALSE;
+
+ assert(col >= 0 && static_cast<size_t>(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)
+ {
+ ++col; //skip dummy/expander column
+
+ assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
+ SvLBoxItem& rItem = pEntry->GetItem(col);
+ assert(dynamic_cast<SvLBoxString*>(&rItem));
+ return static_cast<SvLBoxString&>(rItem).IsEmphasized();
+ }
+}
+
class SalInstanceTreeView : public SalInstanceContainer, public virtual weld::TreeView
{
private:
@@ -2276,6 +2312,7 @@ private:
VclPtr<SvTabListBox> m_xTreeView;
SvLBoxButtonData m_aCheckButtonData;
SvLBoxButtonData m_aRadioButtonData;
+ bool m_bDisableCheckBoxAutoWidth;
int m_nSortColumn;
DECL_LINK(SelectHdl, SvTreeListBox*, void);
@@ -2294,6 +2331,7 @@ public:
, m_xTreeView(pTreeView)
, m_aCheckButtonData(pTreeView, false)
, m_aRadioButtonData(pTreeView, true)
+ , m_bDisableCheckBoxAutoWidth(false)
, m_nSortColumn(-1)
{
m_xTreeView->SetNodeDefaultImages();
@@ -2338,6 +2376,7 @@ public:
virtual void set_column_fixed_widths(const std::vector<int>& rWidths) override
{
+ m_bDisableCheckBoxAutoWidth = true;
std::vector<long> aTabPositions;
aTabPositions.push_back(0);
for (size_t i = 0; i < rWidths.size(); ++i)
@@ -2670,25 +2709,20 @@ public:
set_sensitive(pEntry, bSensitive, col);
}
- virtual bool get_toggle(int pos, int col) const override
+ virtual TriState get_toggle(int pos, int col) const override
{
SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
-
- ++col; //skip dummy/expander column
-
- if (static_cast<size_t>(col) == pEntry->ItemCount())
- return false;
-
- assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
- SvLBoxItem& rItem = pEntry->GetItem(col);
- assert(dynamic_cast<SvLBoxButton*>(&rItem));
- return static_cast<SvLBoxButton&>(rItem).IsStateChecked();
+ return ::get_toggle(pEntry, col);
}
- virtual void set_toggle(int pos, bool bOn, int col) override
+ virtual TriState get_toggle(const weld::TreeIter& rIter, int col) const override
{
- SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
+ const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
+ return ::get_toggle(rVclIter.iter, col);
+ }
+ void set_toggle(SvTreeListEntry* pEntry, TriState eState, int col)
+ {
bool bRadio = std::find(m_aRadioIndexes.begin(), m_aRadioIndexes.end(), col) != m_aRadioIndexes.end();
++col; //skip dummy/expander column
@@ -2698,23 +2732,86 @@ public:
if (static_cast<size_t>(col) == pEntry->ItemCount())
{
- pEntry->AddItem(std::make_unique<SvLBoxButton>(SvLBoxButtonKind::EnabledCheckbox,
- bRadio ? &m_aRadioButtonData : &m_aCheckButtonData));
+ SvLBoxButtonData* pData = bRadio ? &m_aRadioButtonData : &m_aCheckButtonData;
+
+ // if we want to have the implicit auto-sizing of the checkbox
+ // column we need to call EnableCheckButton and CheckBoxInserted to
+ // let it figure out that width. But we don't want to override any
+ // explicitly set column width, so disable this if we've set
+ // explicit column widths
+ if (!m_bDisableCheckBoxAutoWidth)
+ {
+ if (!(m_xTreeView->GetTreeFlags() & SvTreeFlags::CHKBTN))
+ {
+ m_xTreeView->EnableCheckButton(pData);
+ // EnableCheckButton clobbered this, restore it
+ pData->SetLink(LINK(this, SalInstanceTreeView, ToggleHdl));
+ }
+ }
+
+ pEntry->AddItem(std::make_unique<SvLBoxButton>(SvLBoxButtonKind::EnabledCheckbox, pData));
SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
m_xTreeView->InitViewData(pViewData, pEntry);
+
+ if (!m_bDisableCheckBoxAutoWidth)
+ m_xTreeView->CheckBoxInserted(pEntry);
}
assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
SvLBoxItem& rItem = pEntry->GetItem(col);
assert(dynamic_cast<SvLBoxButton*>(&rItem));
- if (bOn)
- static_cast<SvLBoxButton&>(rItem).SetStateChecked();
- else
- static_cast<SvLBoxButton&>(rItem).SetStateUnchecked();
+ 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;
+ }
+
+ m_xTreeView->ModelHasEntryInvalidated(pEntry);
+ }
+
+ virtual void set_toggle(int pos, TriState eState, int col) override
+ {
+ SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
+ set_toggle(pEntry, eState, col);
+ }
+
+ virtual void set_toggle(const weld::TreeIter& rIter, TriState eState, int col) override
+ {
+ const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
+ set_toggle(rVclIter.iter, eState, col);
+ }
+
+ void set_text_emphasis(SvTreeListEntry* pEntry, bool bOn, int col)
+ {
+ ++col; //skip dummy/expander column
+
+ assert(col >= 0 && static_cast<size_t>(col) < pEntry->ItemCount());
+ SvLBoxItem& rItem = pEntry->GetItem(col);
+ assert(dynamic_cast<SvLBoxString*>(&rItem));
+ static_cast<SvLBoxString&>(rItem).Emphasize(bOn);
m_xTreeView->ModelHasEntryInvalidated(pEntry);
}
+ virtual void set_text_emphasis(const weld::TreeIter& rIter, bool bOn, int col) override
+ {
+ const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
+ set_text_emphasis(rVclIter.iter, bOn, col);
+ }
+
+ virtual bool get_text_emphasis(const weld::TreeIter& rIter, int col) const override
+ {
+ const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter);
+ return ::get_text_emphasis(rVclIter.iter, col);
+ }
+
void set_image(SvTreeListEntry* pEntry, const Image& rImage, int col)
{
if (col == -1)
@@ -3244,7 +3341,15 @@ IMPL_LINK(SalInstanceTreeView, ToggleHdl, SvLBoxButtonData*, pData, void)
// tdf#122874 Select the row, calling SelectHdl, before handling
// the toggle
- m_xTreeView->Select(pEntry, true);
+ if (!m_xTreeView->IsSelected(pEntry))
+ {
+ m_xTreeView->SelectAll(false);
+ m_xTreeView->Select(pEntry, true);
+ }
+
+ // toggled signal handlers can query get_cursor to get which
+ // node was clicked
+ m_xTreeView->pImpl->pCursor = pEntry;
for (int i = 1, nCount = pEntry->ItemCount(); i < nCount; ++i)
{
diff --git a/vcl/source/treelist/svlbitm.cxx b/vcl/source/treelist/svlbitm.cxx
index 76d67ff36b49..e7732f687d5b 100644
--- a/vcl/source/treelist/svlbitm.cxx
+++ b/vcl/source/treelist/svlbitm.cxx
@@ -173,11 +173,13 @@ bool SvLBoxButtonData::IsRadio() {
SvLBoxString::SvLBoxString(const OUString& rStr)
- : maText(rStr)
+ : mbEmphasized(false)
+ , maText(rStr)
{
}
SvLBoxString::SvLBoxString()
+ : mbEmphasized(false)
{
}
@@ -203,7 +205,19 @@ void SvLBoxString::Paint(
nStyle |= DrawTextFlags::PathEllipsis | DrawTextFlags::Center;
aSize.setWidth( rDev.GetEntryWidth() );
}
+
+ if (mbEmphasized)
+ {
+ rRenderContext.Push();
+ vcl::Font aFont(rRenderContext.GetFont());
+ aFont.SetWeight(WEIGHT_BOLD);
+ rRenderContext.SetFont(aFont);
+ }
+
rRenderContext.DrawText(tools::Rectangle(rPos, aSize), maText, nStyle);
+
+ if (mbEmphasized)
+ rRenderContext.Pop();
}
std::unique_ptr<SvLBoxItem> SvLBoxString::Clone(SvLBoxItem const * pSource) const
@@ -218,7 +232,19 @@ void SvLBoxString::InitViewData(
{
if( !pViewData )
pViewData = pView->GetViewDataItem( pEntry, this );
+
+ if (mbEmphasized)
+ {
+ pView->Push();
+ vcl::Font aFont( pView->GetFont());
+ aFont.SetWeight(WEIGHT_BOLD);
+ pView->Control::SetFont( aFont );
+ }
+
pViewData->maSize = Size(pView->GetTextWidth(maText), pView->GetTextHeight());
+
+ if (mbEmphasized)
+ pView->Pop();
}
// ***************************************************************
diff --git a/vcl/source/treelist/treelistbox.cxx b/vcl/source/treelist/treelistbox.cxx
index 1a2bb1e9d65f..5bd2a6fb3d0b 100644
--- a/vcl/source/treelist/treelistbox.cxx
+++ b/vcl/source/treelist/treelistbox.cxx
@@ -1679,6 +1679,20 @@ void SvTreeListBox::SetCollapsedEntryBmp(SvTreeListEntry* pEntry,const Image& aB
}
}
+void SvTreeListBox::CheckBoxInserted(SvTreeListEntry* pEntry)
+{
+ SvLBoxButton* pItem = static_cast<SvLBoxButton*>(pEntry->GetFirstItem(SvLBoxItemType::Button));
+ if( pItem )
+ {
+ long nWidth = pItem->GetSize(this, pEntry).Width();
+ if( mnCheckboxItemWidth < nWidth )
+ {
+ mnCheckboxItemWidth = nWidth;
+ nTreeFlags |= SvTreeFlags::RECALCTABS;
+ }
+ }
+}
+
void SvTreeListBox::ImpEntryInserted( SvTreeListEntry* pEntry )
{
@@ -1712,19 +1726,9 @@ void SvTreeListBox::ImpEntryInserted( SvTreeListEntry* pEntry )
if( !(nTreeFlags & SvTreeFlags::CHKBTN) )
return;
- SvLBoxButton* pItem = static_cast<SvLBoxButton*>(pEntry->GetFirstItem(SvLBoxItemType::Button));
- if( pItem )
- {
- long nWidth = pItem->GetSize(this, pEntry).Width();
- if( mnCheckboxItemWidth < nWidth )
- {
- mnCheckboxItemWidth = nWidth;
- nTreeFlags |= SvTreeFlags::RECALCTABS;
- }
- }
+ CheckBoxInserted(pEntry);
}
-
void SvTreeListBox::SetCheckButtonState( SvTreeListEntry* pEntry, SvButtonState eState)
{
if( !(nTreeFlags & SvTreeFlags::CHKBTN) )
@@ -1846,7 +1850,6 @@ void SvTreeListBox::SetDefaultCollapsedEntryBmp( const Image& aBmp )
void SvTreeListBox::EnableCheckButton( SvLBoxButtonData* pData )
{
- DBG_ASSERT(!GetEntryCount(),"EnableCheckButton: Entry count != 0");
if( !pData )
nTreeFlags &= ~SvTreeFlags::CHKBTN;
else
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 853b2827bb07..06a2ba5a705c 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -5634,6 +5634,10 @@ struct GtkInstanceTreeIter : public weld::TreeIter
else
memset(&iter, 0, sizeof(iter));
}
+ virtual bool equal(const TreeIter& rOther) const override
+ {
+ return memcmp(&iter, &static_cast<const GtkInstanceTreeIter&>(rOther).iter, sizeof(GtkTreeIter)) == 0;
+ }
GtkTreeIter iter;
};
@@ -5647,6 +5651,10 @@ private:
std::vector<gulong> m_aColumnSignalIds;
// map from toggle column to toggle visibility column
std::map<int, int> m_aToggleVisMap;
+ // map from toggle column to tristate column
+ std::map<int, int> m_aToggleTriStateMap;
+ // map from text column to text weight column
+ std::map<int, int> m_aWeightMap;
std::vector<GtkSortType> m_aSavedSortTypes;
std::vector<int> m_aSavedSortColumns;
std::vector<int> m_aViewColToModelCol;
@@ -5745,15 +5753,29 @@ private:
return sRet;
}
+ gint get_int(const GtkTreeIter& iter, int col) const
+ {
+ gint nRet(-1);
+ GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore);
+ gtk_tree_model_get(pModel, const_cast<GtkTreeIter*>(&iter), col, &nRet, -1);
+ return nRet;
+ }
+
+ bool get_bool(const GtkTreeIter& iter, int col) const
+ {
+ gboolean bRet(false);
+ GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore);
+ gtk_tree_model_get(pModel, const_cast<GtkTreeIter*>(&iter), col, &bRet, -1);
+ return bRet;
+ }
+
bool get_bool(int pos, int col) const
{
gboolean bRet(false);
GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore);
GtkTreeIter iter;
if (gtk_tree_model_iter_nth_child(pModel, &iter, nullptr, pos))
- {
- gtk_tree_model_get(pModel, &iter, col, &bRet, -1);
- }
+ bRet = get_bool(iter, col);
return bRet;
}
@@ -5768,9 +5790,12 @@ private:
GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore);
GtkTreeIter iter;
if (gtk_tree_model_iter_nth_child(pModel, &iter, nullptr, pos))
- {
set(iter, col, rText);
- }
+ }
+
+ void set(const GtkTreeIter& iter, int col, bool bOn)
+ {
+ gtk_tree_store_set(m_pTreeStore, const_cast<GtkTreeIter*>(&iter), col, bOn, -1);
}
void set(int pos, int col, bool bOn)
@@ -5778,9 +5803,12 @@ private:
GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore);
GtkTreeIter iter;
if (gtk_tree_model_iter_nth_child(pModel, &iter, nullptr, pos))
- {
- gtk_tree_store_set(m_pTreeStore, &iter, col, bOn, -1);
- }
+ set(iter, col, bOn);
+ }
+
+ void set(const GtkTreeIter& iter, int col, gint bInt)
+ {
+ gtk_tree_store_set(m_pTreeStore, const_cast<GtkTreeIter*>(&iter), col, bInt, -1);
}
static gboolean signalTestExpandRow(GtkTreeView*, GtkTreeIter* iter, GtkTreePath*, gpointer widget)
@@ -5926,15 +5954,18 @@ public:
for (GList* pRenderer = g_list_first(pRenderers); pRenderer; pRenderer = g_list_next(pRenderer))
{
GtkCellRenderer* pCellRenderer = GTK_CELL_RENDERER(pRenderer->data);
- if (m_nTextCol == -1 && GTK_IS_CELL_RENDERER_TEXT(pCellRenderer))
+ if (GTK_IS_CELL_RENDERER_TEXT(pCellRenderer))
{
- m_nTextCol = nIndex;
+ if (m_nTextCol == -1)
+ m_nTextCol = nIndex;
+ m_aWeightMap[nIndex] = -1;
}
else if (GTK_IS_CELL_RENDERER_TOGGLE(pCellRenderer))
{
g_object_set_data(G_OBJECT(pCellRenderer), "g-lo-CellIndex", reinterpret_cast<gpointer>(nIndex));
g_signal_connect(G_OBJECT(pCellRenderer), "toggled", G_CALLBACK(signalCellToggled), this);
m_aToggleVisMap[nIndex] = -1;
+ m_aToggleTriStateMap[nIndex] = -1;
}
else if (GTK_IS_CELL_RENDERER_PIXBUF(pCellRenderer))
{
@@ -5950,11 +5981,15 @@ public:
g_list_free(pRenderers);
m_aViewColToModelCol.push_back(nIndex - 1);
}
+
m_nIdCol = nIndex++;
+
for (auto& a : m_aToggleVisMap)
- {
a.second = nIndex++;
- }
+ for (auto& a : m_aToggleTriStateMap)
+ a.second = nIndex++;
+ for (auto& a : m_aWeightMap)
+ a.second = nIndex++;
GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore);
m_nRowDeletedSignalId = g_signal_connect(pModel, "row-deleted", G_CALLBACK(signalRowDeleted), this);
@@ -6337,17 +6372,64 @@ public:
set(pos, col, rText);
}
- virtual bool get_toggle(int pos, int col) const override
+ virtual TriState get_toggle(int pos, int col) const override
{
- return get_bool(pos, get_model_col(col));
+ col = get_model_col(col);
+ if (get_bool(pos, m_aToggleTriStateMap.find(col)->second))
+ return TRISTATE_INDET;
+ return get_bool(pos, col) ? TRISTATE_TRUE : TRISTATE_FALSE;
+ }
+
+ virtual TriState get_toggle(const weld::TreeIter& rIter, int col) const override
+ {
+ col = get_model_col(col);
+ const GtkInstanceTreeIter& rGtkIter = static_cast<const GtkInstanceTreeIter&>(rIter);
+ if (get_bool(rGtkIter.iter, m_aToggleTriStateMap.find(col)->second))
+ return TRISTATE_INDET;
+ return get_bool(rGtkIter.iter, col) ? TRISTATE_TRUE : TRISTATE_FALSE;
}
- virtual void set_toggle(int pos, bool bOn, int col) override
+ virtual void set_toggle(int pos, TriState eState, int col) override
{
col = get_model_col(col);
// checkbuttons are invisible until toggled on or off
set(pos, m_aToggleVisMap[col], true);
- set(pos, col, bOn);
+ if (eState == TRISTATE_INDET)
+ set(pos, m_aToggleTriStateMap[col], true);
+ else
+ {
+ set(pos, m_aToggleTriStateMap[col], false);
+ set(pos, col, eState == TRISTATE_TRUE);
+ }
+ }
+
+ virtual void set_toggle(const weld::TreeIter& rIter, TriState eState, int col) override
+ {
+ const GtkInstanceTreeIter& rGtkIter = static_cast<const GtkInstanceTreeIter&>(rIter);
+ col = get_model_col(col);
+ // checkbuttons are invisible until toggled on or off
+ set(rGtkIter.iter, m_aToggleVisMap[col], true);
+ if (eState == TRISTATE_INDET)
+ set(rGtkIter.iter, m_aToggleTriStateMap[col], true);
+ else
+ {
+ set(rGtkIter.iter, m_aToggleTriStateMap[col], false);
+ set(rGtkIter.iter, col, eState == TRISTATE_TRUE);
+ }
+ }
+
+ virtual void set_text_emphasis(const weld::TreeIter& rIter, bool bOn, int col) override
+ {
+ const GtkInstanceTreeIter& rGtkIter = static_cast<const GtkInstanceTreeIter&>(rIter);
+ col = get_model_col(col);
+ set(rGtkIter.iter, m_aWeightMap[col], bOn ? PANGO_WEIGHT_BOLD : -1);
+ }
+
+ virtual bool get_text_emphasis(const weld::TreeIter& rIter, int col) const override
+ {
+ const GtkInstanceTreeIter& rGtkIter = static_cast<const GtkInstanceTreeIter&>(rIter);
+ col = get_model_col(col);
+ return get_int(rGtkIter.iter, m_aWeightMap.find(col)->second) == PANGO_WEIGHT_BOLD;
}
using GtkInstanceWidget::set_sensitive;
@@ -6360,6 +6442,8 @@ public:
col = get_model_col(col);
col += m_nIdCol + 1; // skip over id column
col += m_aToggleVisMap.size(); // skip over toggle columns
+ col += m_aToggleTriStateMap.size(); // skip over tristate columns
+ col += m_aWeightMap.size(); // skip over weight columns
set(pos, col, bSensitive);
}