summaryrefslogtreecommitdiffstats
path: root/sc/source/ui/dbgui/dpgroupdlg.cxx
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--sc/source/ui/dbgui/dpgroupdlg.cxx353
1 files changed, 353 insertions, 0 deletions
diff --git a/sc/source/ui/dbgui/dpgroupdlg.cxx b/sc/source/ui/dbgui/dpgroupdlg.cxx
new file mode 100644
index 000000000..550695cc3
--- /dev/null
+++ b/sc/source/ui/dbgui/dpgroupdlg.cxx
@@ -0,0 +1,353 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifdef SC_DLLIMPLEMENTATION
+#undef SC_DLLIMPLEMENTATION
+#endif
+
+#include <dpgroupdlg.hxx>
+#include <globstr.hrc>
+#include <scresid.hxx>
+#include <editfield.hxx>
+
+#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
+#include <svtools/ctrlbox.hxx>
+
+namespace {
+
+/** Date part flags in order of the list box entries. */
+const sal_Int32 spnDateParts[] =
+{
+ css::sheet::DataPilotFieldGroupBy::SECONDS,
+ css::sheet::DataPilotFieldGroupBy::MINUTES,
+ css::sheet::DataPilotFieldGroupBy::HOURS,
+ css::sheet::DataPilotFieldGroupBy::DAYS,
+ css::sheet::DataPilotFieldGroupBy::MONTHS,
+ css::sheet::DataPilotFieldGroupBy::QUARTERS,
+ css::sheet::DataPilotFieldGroupBy::YEARS
+};
+
+const TranslateId aDatePartResIds[] =
+{
+ STR_DPFIELD_GROUP_BY_SECONDS,
+ STR_DPFIELD_GROUP_BY_MINUTES,
+ STR_DPFIELD_GROUP_BY_HOURS,
+ STR_DPFIELD_GROUP_BY_DAYS,
+ STR_DPFIELD_GROUP_BY_MONTHS,
+ STR_DPFIELD_GROUP_BY_QUARTERS,
+ STR_DPFIELD_GROUP_BY_YEARS
+};
+
+} // namespace
+
+ScDPGroupEditHelper::ScDPGroupEditHelper(weld::RadioButton& rRbAuto, weld::RadioButton& rRbMan, weld::Widget& rEdValue)
+ : mrRbAuto(rRbAuto)
+ , mrRbMan(rRbMan)
+ , mrEdValue(rEdValue)
+{
+ mrRbAuto.connect_toggled( LINK( this, ScDPGroupEditHelper, ToggleHdl ) );
+ mrRbMan.connect_toggled( LINK( this, ScDPGroupEditHelper, ToggleHdl ) );
+}
+
+bool ScDPGroupEditHelper::IsAuto() const
+{
+ return mrRbAuto.get_active();
+}
+
+double ScDPGroupEditHelper::GetValue() const
+{
+ double fValue;
+ if( !ImplGetValue( fValue ) )
+ fValue = 0.0;
+ return fValue;
+}
+
+void ScDPGroupEditHelper::SetValue( bool bAuto, double fValue )
+{
+ if( bAuto )
+ {
+ mrRbAuto.set_active(true);
+ ToggleHdl(mrRbAuto);
+ }
+ else
+ {
+ mrRbMan.set_active(true);
+ ToggleHdl(mrRbMan);
+ }
+ ImplSetValue( fValue );
+}
+
+IMPL_LINK(ScDPGroupEditHelper, ToggleHdl, weld::Toggleable&, rButton, void)
+{
+ if (!rButton.get_active())
+ return;
+
+ if (mrRbAuto.get_active())
+ {
+ // disable edit field on clicking "automatic" radio button
+ mrEdValue.set_sensitive(false);
+ }
+ else if (mrRbMan.get_active())
+ {
+ // enable and set focus to edit field on clicking "manual" radio button
+ mrEdValue.set_sensitive(true);
+ mrEdValue.grab_focus();
+ }
+}
+
+ScDPNumGroupEditHelper::ScDPNumGroupEditHelper(weld::RadioButton& rRbAuto,
+ weld::RadioButton& rRbMan, ScDoubleField& rEdValue)
+ : ScDPGroupEditHelper(rRbAuto, rRbMan, rEdValue.get_widget())
+ , mrEdValue(rEdValue)
+{
+}
+
+bool ScDPNumGroupEditHelper::ImplGetValue( double& rfValue ) const
+{
+ return mrEdValue.GetValue(rfValue);
+}
+
+void ScDPNumGroupEditHelper::ImplSetValue( double fValue )
+{
+ mrEdValue.SetValue(fValue);
+}
+
+ScDPDateGroupEditHelper::ScDPDateGroupEditHelper(weld::RadioButton& rRbAuto, weld::RadioButton& rRbMan,
+ SvtCalendarBox& rEdValue, const Date& rNullDate)
+ : ScDPGroupEditHelper(rRbAuto, rRbMan, rEdValue.get_button())
+ , mrEdValue(rEdValue)
+ , maNullDate(rNullDate)
+{
+}
+
+bool ScDPDateGroupEditHelper::ImplGetValue( double& rfValue ) const
+{
+ rfValue = mrEdValue.get_date() - maNullDate;
+ return true;
+}
+
+void ScDPDateGroupEditHelper::ImplSetValue( double fValue )
+{
+ Date aDate( maNullDate );
+ aDate.AddDays( fValue );
+ mrEdValue.set_date( aDate );
+}
+
+ScDPNumGroupDlg::ScDPNumGroupDlg(weld::Window* pParent, const ScDPNumGroupInfo& rInfo)
+ : GenericDialogController(pParent, "modules/scalc/ui/groupbynumber.ui", "PivotTableGroupByNumber")
+ , mxRbAutoStart(m_xBuilder->weld_radio_button("auto_start"))
+ , mxRbManStart(m_xBuilder->weld_radio_button("manual_start"))
+ , mxEdStart(new ScDoubleField(m_xBuilder->weld_entry("edit_start")))
+ , mxRbAutoEnd(m_xBuilder->weld_radio_button("auto_end"))
+ , mxRbManEnd(m_xBuilder->weld_radio_button("manual_end"))
+ , mxEdEnd(new ScDoubleField(m_xBuilder->weld_entry("edit_end")))
+ , mxEdBy(new ScDoubleField(m_xBuilder->weld_entry("edit_by")))
+ , maStartHelper(*mxRbAutoStart, *mxRbManStart, *mxEdStart)
+ , maEndHelper(*mxRbAutoEnd, *mxRbManEnd, *mxEdEnd)
+{
+ maStartHelper.SetValue( rInfo.mbAutoStart, rInfo.mfStart );
+ maEndHelper.SetValue( rInfo.mbAutoEnd, rInfo.mfEnd );
+ mxEdBy->SetValue( (rInfo.mfStep <= 0.0) ? 1.0 : rInfo.mfStep );
+
+ /* Set the initial focus, currently it is somewhere after calling all the radio
+ button click handlers. Now the first enabled editable control is focused. */
+ if (mxEdStart->get_sensitive())
+ mxEdStart->grab_focus();
+ else if (mxEdEnd->get_sensitive())
+ mxEdEnd->grab_focus();
+ else
+ mxEdBy->grab_focus();
+}
+
+ScDPNumGroupDlg::~ScDPNumGroupDlg()
+{
+}
+
+ScDPNumGroupInfo ScDPNumGroupDlg::GetGroupInfo() const
+{
+ ScDPNumGroupInfo aInfo;
+ aInfo.mbEnable = true;
+ aInfo.mbDateValues = false;
+ aInfo.mbAutoStart = maStartHelper.IsAuto();
+ aInfo.mbAutoEnd = maEndHelper.IsAuto();
+
+ // get values and silently auto-correct them, if they are not valid
+ // TODO: error messages in OK event?
+ aInfo.mfStart = maStartHelper.GetValue();
+ aInfo.mfEnd = maEndHelper.GetValue();
+ if( !mxEdBy->GetValue( aInfo.mfStep ) || (aInfo.mfStep <= 0.0) )
+ aInfo.mfStep = 1.0;
+ if( aInfo.mfEnd <= aInfo.mfStart )
+ aInfo.mfEnd = aInfo.mfStart + aInfo.mfStep;
+
+ return aInfo;
+}
+
+ScDPDateGroupDlg::ScDPDateGroupDlg(weld::Window* pParent,
+ const ScDPNumGroupInfo& rInfo, sal_Int32 nDatePart, const Date& rNullDate)
+ : GenericDialogController(pParent, "modules/scalc/ui/groupbydate.ui", "PivotTableGroupByDate")
+ , mxRbAutoStart(m_xBuilder->weld_radio_button("auto_start"))
+ , mxRbManStart(m_xBuilder->weld_radio_button("manual_start"))
+ , mxEdStart(new SvtCalendarBox(m_xBuilder->weld_menu_button("start_date")))
+ , mxRbAutoEnd(m_xBuilder->weld_radio_button("auto_end"))
+ , mxRbManEnd(m_xBuilder->weld_radio_button("manual_end"))
+ , mxEdEnd(new SvtCalendarBox(m_xBuilder->weld_menu_button("end_date")))
+ , mxRbNumDays(m_xBuilder->weld_radio_button("days"))
+ , mxRbUnits(m_xBuilder->weld_radio_button("intervals"))
+ , mxEdNumDays(m_xBuilder->weld_spin_button("days_value"))
+ , mxLbUnits(m_xBuilder->weld_tree_view("interval_list"))
+ , mxBtnOk(m_xBuilder->weld_button("ok"))
+ , maStartHelper(*mxRbAutoStart, *mxRbManStart, *mxEdStart, rNullDate)
+ , maEndHelper(*mxRbAutoEnd, *mxRbManEnd, *mxEdEnd, rNullDate)
+{
+ maStartHelper.SetValue( rInfo.mbAutoStart, rInfo.mfStart );
+ maEndHelper.SetValue( rInfo.mbAutoEnd, rInfo.mfEnd );
+
+ mxLbUnits->enable_toggle_buttons(weld::ColumnToggleType::Check);
+
+ if( nDatePart == 0 )
+ nDatePart = css::sheet::DataPilotFieldGroupBy::MONTHS;
+ for (size_t nIdx = 0; nIdx < SAL_N_ELEMENTS(aDatePartResIds); ++nIdx)
+ {
+ mxLbUnits->append();
+ mxLbUnits->set_toggle(nIdx, (nDatePart & spnDateParts[ nIdx ]) ? TRISTATE_TRUE : TRISTATE_FALSE);
+ mxLbUnits->set_text(nIdx, ScResId(aDatePartResIds[nIdx]), 0);
+ }
+
+ if( rInfo.mbDateValues )
+ {
+ mxRbNumDays->set_active(true);
+ ToggleHdl(*mxRbNumDays );
+
+ double fNumDays = rInfo.mfStep;
+ if( fNumDays < 1.0 )
+ fNumDays = 1.0;
+ else if( fNumDays > 32767.0 )
+ fNumDays = 32767.0;
+ mxEdNumDays->set_value(fNumDays);
+ }
+ else
+ {
+ mxRbUnits->set_active(true);
+ ToggleHdl(*mxRbUnits);
+ }
+
+ /* Set the initial focus, currently it is somewhere after calling all the radio
+ button click handlers. Now the first enabled editable control is focused. */
+ if( mxEdStart->get_sensitive() )
+ mxEdStart->grab_focus();
+ else if( mxEdEnd->get_sensitive() )
+ mxEdEnd->grab_focus();
+ else if( mxEdNumDays->get_sensitive() )
+ mxEdNumDays->grab_focus();
+ else if( mxLbUnits->get_sensitive() )
+ mxLbUnits->grab_focus();
+
+ mxRbNumDays->connect_toggled( LINK( this, ScDPDateGroupDlg, ToggleHdl ) );
+ mxRbUnits->connect_toggled( LINK( this, ScDPDateGroupDlg, ToggleHdl ) );
+ mxLbUnits->connect_toggled( LINK( this, ScDPDateGroupDlg, CheckHdl ) );
+}
+
+ScDPDateGroupDlg::~ScDPDateGroupDlg()
+{
+}
+
+ScDPNumGroupInfo ScDPDateGroupDlg::GetGroupInfo() const
+{
+ ScDPNumGroupInfo aInfo;
+ aInfo.mbEnable = true;
+ aInfo.mbDateValues = mxRbNumDays->get_active();
+ aInfo.mbAutoStart = maStartHelper.IsAuto();
+ aInfo.mbAutoEnd = maEndHelper.IsAuto();
+
+ // get values and silently auto-correct them, if they are not valid
+ // TODO: error messages in OK event?
+ aInfo.mfStart = maStartHelper.GetValue();
+ aInfo.mfEnd = maEndHelper.GetValue();
+ sal_Int64 nNumDays = mxEdNumDays->get_value();
+ aInfo.mfStep = static_cast<double>( aInfo.mbDateValues ? nNumDays : 0L );
+ if( aInfo.mfEnd <= aInfo.mfStart )
+ aInfo.mfEnd = aInfo.mfStart + nNumDays;
+
+ return aInfo;
+}
+
+sal_Int32 ScDPDateGroupDlg::GetDatePart() const
+{
+ // return DAYS for special "number of days" mode
+ if( mxRbNumDays->get_active() )
+ return css::sheet::DataPilotFieldGroupBy::DAYS;
+
+ // return listbox contents for "units" mode
+ sal_Int32 nDatePart = 0;
+ for (int nIdx = 0, nCount = mxLbUnits->n_children(); nIdx < nCount; ++nIdx )
+ if (mxLbUnits->get_toggle(nIdx) == TRISTATE_TRUE)
+ nDatePart |= spnDateParts[ nIdx ];
+ return nDatePart;
+}
+
+IMPL_LINK(ScDPDateGroupDlg, ToggleHdl, weld::Toggleable&, rButton, void)
+{
+ if (!rButton.get_active())
+ return;
+ if (mxRbNumDays->get_active())
+ {
+ mxLbUnits->set_sensitive(false);
+ // enable and set focus to edit field on clicking "num of days" radio button
+ mxEdNumDays->set_sensitive(true);
+ mxEdNumDays->grab_focus();
+ mxBtnOk->set_sensitive(true);
+ }
+ else if (mxRbUnits->get_active())
+ {
+ mxEdNumDays->set_sensitive(false);
+ // enable and set focus to listbox on clicking "units" radio button
+ mxLbUnits->set_sensitive(true);
+ mxLbUnits->grab_focus();
+ // disable OK button if no date part selected
+ Check();
+ }
+}
+
+namespace
+{
+ bool HasCheckedEntryCount(const weld::TreeView& rView)
+ {
+ for (int i = 0; i < rView.n_children(); ++i)
+ {
+ if (rView.get_toggle(i) == TRISTATE_TRUE)
+ return true;
+ }
+ return false;
+ }
+}
+
+IMPL_LINK_NOARG(ScDPDateGroupDlg, CheckHdl, const weld::TreeView::iter_col&, void)
+{
+ Check();
+}
+
+void ScDPDateGroupDlg::Check()
+{
+ // enable/disable OK button on modifying check list box
+ mxBtnOk->set_sensitive(HasCheckedEntryCount(*mxLbUnits));
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */