summaryrefslogtreecommitdiff
path: root/sc/source/ui/cctrl
diff options
context:
space:
mode:
authorDennis Francis <dennis.francis@collabora.com>2023-01-25 13:51:17 +0530
committerDennis Francis <dennis.francis@collabora.com>2023-04-27 08:35:59 +0200
commit2f8d10b0b9baa03b8a713e9fd1342fe6c8094fb4 (patch)
treef008321e237e02ca032178711e27a16969718312 /sc/source/ui/cctrl
parent292f422c421336c43bafe5ee048832137d617436 (diff)
sc: pivot table compact layout
This implements compact layout for pivot tables. In ooxml each row field can have a compact layout setting. Support for any such "mixed" layout of tabular/outline/compact per field is also implemented. This also implements expand/collpse toggle buttons to field labels to make pivot tables with compact layout more usable. Such buttons are also available if other layouts are used. Conflicts: sc/qa/unit/pivottable_filters_test.cxx sc/source/ui/cctrl/checklistmenu.cxx sc/source/ui/inc/checklistmenu.hxx Change-Id: Ieaa1f3bd282ebdec804d0b45a0af7b3d95a2027f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151057 Tested-by: Jenkins Reviewed-by: Dennis Francis <dennis.francis@collabora.com>
Diffstat (limited to 'sc/source/ui/cctrl')
-rw-r--r--sc/source/ui/cctrl/checklistmenu.cxx58
-rw-r--r--sc/source/ui/cctrl/dpcontrol.cxx74
2 files changed, 130 insertions, 2 deletions
diff --git a/sc/source/ui/cctrl/checklistmenu.cxx b/sc/source/ui/cctrl/checklistmenu.cxx
index 456b0fe8b76a..2ff0e4a4dc00 100644
--- a/sc/source/ui/cctrl/checklistmenu.cxx
+++ b/sc/source/ui/cctrl/checklistmenu.cxx
@@ -373,6 +373,27 @@ void ScCheckListMenuControl::endSubMenu(ScListSubMenuControl& rSubMenu)
}
}
+void ScCheckListMenuControl::addFields(const std::vector<OUString>& aFields)
+{
+ if (!mbIsMultiField)
+ return;
+
+ mxFieldsCombo->clear();
+
+ for (auto& aField: aFields)
+ mxFieldsCombo->append_text(aField);
+
+ mxFieldsCombo->set_active(0);
+}
+
+tools::Long ScCheckListMenuControl::getField()
+{
+ if (!mbIsMultiField)
+ return -1;
+
+ return mxFieldsCombo->get_active();
+}
+
void ScCheckListMenuControl::selectMenuItem(size_t nPos, bool bSubMenuTimer)
{
mxMenu->select(nPos == MENU_NOT_SELECTED ? -1 : nPos);
@@ -476,13 +497,15 @@ constexpr int nCheckListVisibleRows = 9;
constexpr int nColorListVisibleRows = 9;
ScCheckListMenuControl::ScCheckListMenuControl(weld::Widget* pParent, ScViewData& rViewData,
- bool bHasDates, int nWidth)
+ bool bHasDates, int nWidth, bool bIsMultiField)
: mxBuilder(Application::CreateBuilder(pParent, "modules/scalc/ui/filterdropdown.ui"))
, mxPopover(mxBuilder->weld_popover("FilterDropDown"))
, mxContainer(mxBuilder->weld_container("container"))
, mxMenu(mxBuilder->weld_tree_view("menu"))
, mxScratchIter(mxMenu->make_iterator())
, mxNonMenu(mxBuilder->weld_widget("nonmenu"))
+ , mxFieldsComboLabel(mxBuilder->weld_label("select_field_label"))
+ , mxFieldsCombo(mxBuilder->weld_combo_box("multi_field_combo"))
, mxEdSearch(mxBuilder->weld_entry("search_edit"))
, mxBox(mxBuilder->weld_widget("box"))
, mxListChecks(mxBuilder->weld_tree_view("check_list_box"))
@@ -508,6 +531,7 @@ ScCheckListMenuControl::ScCheckListMenuControl(weld::Widget* pParent, ScViewData
, maOpenTimer(this)
, maCloseTimer(this)
, maSearchEditTimer("ScCheckListMenuControl maSearchEditTimer")
+ , mbIsMultiField(bIsMultiField)
{
mxTreeChecks->set_clicks_to_toggle(1);
mxListChecks->set_clicks_to_toggle(1);
@@ -556,6 +580,16 @@ ScCheckListMenuControl::ScCheckListMenuControl(weld::Widget* pParent, ScViewData
mxListChecks->enable_toggle_buttons(weld::ColumnToggleType::Check);
mxBox->show();
+ if (mbIsMultiField)
+ {
+ mxFieldsComboLabel->show();
+ mxFieldsCombo->show();
+ }
+ else
+ {
+ mxFieldsComboLabel->hide();
+ mxFieldsCombo->hide();
+ }
mxEdSearch->show();
mxButtonBox->show();
@@ -565,6 +599,8 @@ ScCheckListMenuControl::ScCheckListMenuControl(weld::Widget* pParent, ScViewData
mxBtnOk->connect_clicked(LINK(this, ScCheckListMenuControl, ButtonHdl));
mxBtnCancel->connect_clicked(LINK(this, ScCheckListMenuControl, ButtonHdl));
+ if (mbIsMultiField)
+ mxFieldsCombo->connect_changed(LINK(this, ScCheckListMenuControl, ComboChangedHdl));
mxEdSearch->connect_changed(LINK(this, ScCheckListMenuControl, EdModifyHdl));
mxEdSearch->connect_activate(LINK(this, ScCheckListMenuControl, EdActivateHdl));
mxTreeChecks->connect_toggled(LINK(this, ScCheckListMenuControl, CheckHdl));
@@ -744,6 +780,12 @@ namespace
}
}
+IMPL_LINK_NOARG(ScCheckListMenuControl, ComboChangedHdl, weld::ComboBox&, void)
+{
+ if (mbIsMultiField && mxFieldChangedAction)
+ mxFieldChangedAction->execute();
+}
+
IMPL_LINK_NOARG(ScCheckListMenuControl, SearchEditTimeoutHdl, Timer*, void)
{
OUString aSearchText = mxEdSearch->get_text();
@@ -1078,6 +1120,15 @@ void ScCheckListMenuControl::addMember(const OUString& rName, const double nVal,
maMembers.emplace_back(std::move(aMember));
}
+void ScCheckListMenuControl::clearMembers()
+{
+ maMembers.clear();
+
+ mpChecks->freeze();
+ mpChecks->clear();
+ mpChecks->thaw();
+}
+
std::unique_ptr<weld::TreeIter> ScCheckListMenuControl::FindEntry(const weld::TreeIter* pParent, std::u16string_view sNode)
{
std::unique_ptr<weld::TreeIter> xEntry = mpChecks->make_iterator(pParent);
@@ -1501,6 +1552,11 @@ void ScCheckListMenuControl::setPopupEndAction(Action* p)
mxPopupEndAction.reset(p);
}
+void ScCheckListMenuControl::setFieldChangedAction(Action* p)
+{
+ mxFieldChangedAction.reset(p);
+}
+
IMPL_LINK_NOARG(ScCheckListMenuControl, PopupModeEndHdl, weld::Popover&, void)
{
mbIsPoppedUp = false;
diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx
index b7d61ce002c7..34eea011ee05 100644
--- a/sc/source/ui/cctrl/dpcontrol.cxx
+++ b/sc/source/ui/cctrl/dpcontrol.cxx
@@ -32,8 +32,12 @@ ScDPFieldButton::ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pSt
mpDoc(pDoc),
mpOutDev(pOutDev),
mpStyle(pStyle),
+ mnToggleIndent(0),
mbBaseButton(true),
mbPopupButton(false),
+ mbPopupButtonMulti(false),
+ mbToggleButton(false),
+ mbToggleCollapse(false),
mbHasHiddenMember(false),
mbPopupPressed(false),
mbPopupLeft(false)
@@ -74,6 +78,18 @@ void ScDPFieldButton::setDrawPopupButton(bool b)
mbPopupButton = b;
}
+void ScDPFieldButton::setDrawPopupButtonMulti(bool b)
+{
+ mbPopupButtonMulti = b;
+}
+
+void ScDPFieldButton::setDrawToggleButton(bool b, bool bCollapse, sal_Int32 nIndent)
+{
+ mbToggleButton = b;
+ mbToggleCollapse = bCollapse;
+ mnToggleIndent = nIndent;
+}
+
void ScDPFieldButton::setHasHiddenMember(bool b)
{
mbHasHiddenMember = b;
@@ -140,9 +156,12 @@ void ScDPFieldButton::draw()
mpOutDev->Pop();
}
- if (mbPopupButton)
+ if (mbPopupButton || mbPopupButtonMulti)
drawPopupButton();
+ if (mbToggleButton)
+ drawToggleButton();
+
mpOutDev->EnableMapMode(bOldMapEnabled);
}
@@ -174,6 +193,34 @@ void ScDPFieldButton::getPopupBoundingBox(Point& rPos, Size& rSize) const
rSize.setHeight(nH);
}
+void ScDPFieldButton::getToggleBoundingBox(Point& rPos, Size& rSize) const
+{
+ const float fScaleFactor = mpOutDev->GetDPIScaleFactor();
+
+ tools::Long nMaxSize = 13 * fScaleFactor; // Button max size in either dimension
+ tools::Long nMargin = 3 * fScaleFactor;
+
+ tools::Long nIndent = fScaleFactor * o3tl::convert(mnToggleIndent, o3tl::Length::twip, o3tl::Length::px);
+ tools::Long nW = std::min(maSize.getWidth() / 2, nMaxSize);
+ tools::Long nH = std::min(maSize.getHeight(), nMaxSize);
+ nIndent = std::min(nIndent, maSize.getWidth());
+
+ double fZoom = static_cast<double>(maZoomY) > 1.0 ? static_cast<double>(maZoomY) : 1.0;
+ if (fZoom > 1.0)
+ {
+ nW = fZoom * (nW - 1);
+ nH = fZoom * (nH - 1);
+ nIndent = fZoom * (nIndent -1);
+ nMargin = fZoom * (nMargin - 1);
+ }
+
+ // FIXME: RTL case ?
+ rPos.setX(maPos.getX() + nIndent - nW + nMargin);
+ rPos.setY(maPos.getY() + maSize.getHeight() / 2 - nH / 2 + nMargin);
+ rSize.setWidth(nW - nMargin - 1);
+ rSize.setHeight(nH - nMargin - 1);
+}
+
void ScDPFieldButton::drawPopupButton()
{
Point aPos;
@@ -226,4 +273,29 @@ void ScDPFieldButton::drawPopupButton()
}
}
+void ScDPFieldButton::drawToggleButton()
+{
+ Point aPos;
+ Size aSize;
+ getToggleBoundingBox(aPos, aSize);
+
+ // Background & outer black border
+ mpOutDev->SetLineColor(COL_BLACK);
+ mpOutDev->SetFillColor();
+ mpOutDev->DrawRect(tools::Rectangle(aPos, aSize));
+
+ Point aCenter(aPos.X() + aSize.getWidth() / 2, aPos.Y() + aSize.getHeight() / 2);
+
+ mpOutDev->DrawLine(
+ Point(aPos.X() + 2, aCenter.Y()),
+ Point(aPos.X() + aSize.getWidth() - 2, aCenter.Y()));
+
+ if (!mbToggleCollapse)
+ {
+ mpOutDev->DrawLine(
+ Point(aCenter.X(), aPos.Y() + 2),
+ Point(aCenter.X(), aPos.Y() + aSize.getHeight() - 2));
+ }
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */